[gambit-list] Reading data from mixed ASCII/binary files

Bradley Lucier lucier at math.purdue.edu
Thu Jan 12 00:59:01 EST 2006


Marc:

The file formats used by the image library netpbm (pbm, pgm, ppm,  
pnm, ...) are mixed ascii/binary format; the first few lines are  
ASCII that have a magic number for the file, the size of the image  
(rows and columns) and the maximum value of the pixels (for greyscale  
images).  Then, after a single newline, comes the binary data.

So:

[lindv2:Arrays/srfi2/stacey] lucier% head -3 2314.pgm
P5
1605 2244
255
<binary data follows here>

Now, in beta 16 and beta 17, I get the error:

> [lindv2:Arrays/srfi2/stacey] lucier% gsc
> Gambit Version 4.0 beta 17
>
> > (load "convex2.scm")
> *** ERROR IN #<procedure #2>, "../generic-arrays.scm"@1171.44 --  
> Input port character buffer is not empty
> (read-u8 '#<input-port #3 "/Users/lucier/lang/scheme/Arrays/srfi2/ 
> stacey/2314.pgm">)
> 1> ,b
> 0  #<procedure #2>           "../generic-arrays.scm"@1171:44  
> (domain-getter i j)
> 1  #<procedure #4>           "../generic-arrays.scm"@283:9 (f i j)
> 2  Array->Fixed-array        "../generic-arrays.scm"@1169:6  
> (Interval-for-each (case (##Interval-dimension domain) ((1) (lambda  
> (i) (range-setter (domain-...
> 3  #<procedure #5>           "../pgm.scm"@44:5       (Array->Fixed- 
> array generic-array-manipulators (build-Array (build-Interval '#(0  
> 0) (vector rows colu...
> 4  call-with-input-file
> 5  (interaction)             "convex2.scm"@77:21     (read-pgm  
> (string-append name ".pgm"))
> 6  ##load
> 7  ##load
> 8  (interaction)             (console)@1:1           (load  
> "convex2.scm")
> 1> ,e
> i = 0
> j = 0
> range-setter = (lambda (value i j) (manipulator-setter body  
> (indexer i j) value))
> domain-getter = (lambda (i j) (read-u8 port))
> result = '#<Array-base #6 domain: #<Interval #7 lower-bounds: #(0  
> 0) upper-bounds: #(2244 1605)> getter: #<procedure #8> setter:  
> #<procedure #9> manipulat...
> domain = '#<Interval #7 lower-bounds: #(0 0) upper-bounds: #(2244  
> 1605)>
> result-manipulators = '#<Array-manipulators #10 getter: #<procedure  
> #11> setter: #<procedure #12> maker: #<procedure #13 make-vector>  
> length: #<procedure ...
> array = '#<Array-base #15 domain: #<Interval #7 lower-bounds: #(0  
> 0) upper-bounds: #(2244 1605)> getter: #<procedure #16> setter: #f  
> manipulators: #f body...
> (current-exception-handler) = primordial-exception-handler
> (current-input-port) = '#<input-output-port #17 (console)>
> (current-output-port) = '#<input-output-port #17 (console)>
> (current-directory) = "/Users/lucier/lang/scheme/Arrays/srfi2/stacey/"
> 1>

and I read from the manual:

> procedure: read-u8 [port]
>
>     This procedure reads the byte input-port port and returns the  
> byte at the current byte location and advances the current byte  
> location to the next byte, unless the port is already at end-of- 
> file in which case read-u8 returns the end-of-file object. If it is  
> not specified, port defaults to the current input-port.
>
>     This procedure must be called before any use of the port in a  
> character input operation (i.e. a call to the procedures read, read- 
> char, peek-char, etc) because otherwise the character-stream and  
> byte-stream may be out of sync due to the port buffering.

So, how do I deal with meta-data like this?  Read the u8 numbers,  
call integer->char, put them all into a string, call read on the  
string, ...?  Why should I have to do this instead of the runtime  
doing this?  Or perhaps you have a better suggestion.

Brad



More information about the Gambit-list mailing list