Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

make-****-input-stream

4 views
Skip to first unread message

Bulent Murtezaoglu

unread,
Mar 31, 2002, 9:59:28 PM3/31/02
to

I am whipping up little code to extract image dimension information from
jpeg images. The images will sometimes be in arrays of (byte 8) sometimes
on disk files. This entails scanning for specific markers until you get
to the size info (there is no set place in the header you have to scan).
Anyhow, I thought it would be good if I could just write the routine for
streams and use the analogue of make-string-input-stream for (byte 8)
except that such a thing doesn't seem to exist. The Hyperspec seems to give
no clue about turning arrays into a streams. Where do I find clues about
how one might do it w/o going into extensions? Or is this where I finally
get the motivation to read about Gray streams and simple streams?

thanks,

BM


Kent M Pitman

unread,
Apr 1, 2002, 3:12:27 AM4/1/02
to
Bulent Murtezaoglu <b...@acm.org> writes:

> I am whipping up little code to extract image dimension information from
> jpeg images. The images will sometimes be in arrays of (byte 8) sometimes
> on disk files. This entails scanning for specific markers until you get
> to the size info (there is no set place in the header you have to scan).
> Anyhow, I thought it would be good if I could just write the routine for
> streams and use the analogue of make-string-input-stream for (byte 8)
> except that such a thing doesn't seem to exist. The Hyperspec seems to give
> no clue about turning arrays into a streams.

Because it has nothing to offer, I think. :(

> Where do I find clues about how one might do it w/o going into
> extensions?

This space left intentionally (almost) blank.

> Or is this where I finally get the motivation to read
> about Gray streams and simple streams?

Yes, Gray streams or the Franz simple streams are your
friend here. It's quite sad CL doesn't have this. I agree it'd be
quite useful...

If you want portability, you want to use READ-SEQUENCE to grab blocks
of data out of files and then put the core of your scanner into a function
that takes an array and the option to ask for another array when it wants
more, and then use array operations.

e.g.,

(defun parse-jpeg (data-fn)
(let (...state...)
(loop for data = (funcall data-fn)
for state = (make-jpeg-state)
while data
do (dotimes (i (length data))
(let ((byte (aref data i)))
...)))))

Then have your file parser do something that passes
#'(lambda () ... (read-sequence ...) ...)
do the parser while having your in-core array processor just do
#'(lambda () the-whole-array)

This maybe isn't the structural organization of first choice, but
probably works portably ...


Erik Naggum

unread,
Apr 1, 2002, 4:18:51 AM4/1/02
to
* Bulent Murtezaoglu

| Anyhow, I thought it would be good if I could just write the routine for
| streams and use the analogue of make-string-input-stream for (byte 8)
| except that such a thing doesn't seem to exist. The Hyperspec seems to
| give no clue about turning arrays into a streams.

The string-stream is basically a stream that has a string for buffer.
Buffer management is not part of Common Lisp, which I personally think is
a tragedy, so there is no way you can make a (standard) stream with a
buffer that utilizes an existing object. That would have been so very
useful in so many cases. *sigh*

| Where do I find clues about how one might do it w/o going into
| extensions?

Look around in the internals of your implementation to find out how you
can create a specialized-vector-stream based on how string-streams are
made. It should actually not be too hard to find out. From a cursory
look at the source code that comes with a supported Allegro CL license
(i.e., not the Trial editions), it should be doable at user level. I am
quite certain that CMUCL and CLISP come with a sufficiently good streams
class hierarchy that you can whip together your own vector-stream in no
time.

| Or is this where I finally get the motivation to read about Gray streams
| and simple streams?

Yes, you would do this with Gray streams if you were to roll your own,
but I would strongly suggest poking around in your systems internals
first. Remember: portable code depends on unportable support code, so if
you look for a portable way to do something like this, you will not find
it, but if you write unportable code to support something that could be
implemented with the same functionality everywhere, you are in business.

///
--
In a fight against something, the fight has value, victory has none.
In a fight for something, the fight is a loss, victory merely relief.

Bulent Murtezaoglu

unread,
Apr 1, 2002, 12:33:10 PM4/1/02
to
>>>>> "KMP" == Kent M Pitman <pit...@world.std.com> writes:

Back as promised and immediately back to being informative. Thanks!

[workable skeleton deleted]
KMP> This maybe isn't the structural organization of first choice,
KMP> but probably works portably ...

Yes it would, I think. I am leaning towards just renaming the sequential
access functions used inside the header parser and wrapping a CLOS class
that adds a next-unread pointer around the array. Then the sequential
access generic functions can dispatch appropriately based on what the
"stream" argument actually is. I think that's a least effort kludge
though, and I agree with Erik (and yourself) that this omission from CL
is unfortunate. Of course if I weren't just playing and obsessing about
out-of-the box portability, Erik's suggested solution would be the cleanest.

Thank you both.

cheers,

BM

0 new messages