2005.09.12 21:22 "[Tiff] read-by-scan-line buffers full strip, part 2", by Mark Pilon

2005.09.13 16:54 "Re: [Tiff] read-by-scan-line buffers full strip, part 3", by Joris Van Damme

Mark Pilon wrote:

> i.e. using libtiff part-way to get access to the compressed data, but > perform the decompression in smaller increments than the whole strip.

Much of my first reply stands. And you're fortunate: the LZW compression codec isn't very complicated. Neither is your type of image, it's just a single plane, single strip, without any subsampling or prediction or whatever... Still, though, this will keep you occupied for at least a few days I guess... ;-)

Use TIFFGetField to get the offsets and bytecount of the single strip as detailed.

The next part of your code should be thought of as a pulling pipeline scheme. Whatever the destination of the scanlines is, this pulls the scanlines from the LZW decoder as they are needed. This decoder pulls data from the strip as it needs it, small buffer at a time (say 2K).

'Pulling from the strip' may be implemented as calls to the seek and read proc that are given in TIFFClientOpen, and pointed to in the LibTiff TIFF structure. That way, it'll work whatever IO layer is used added to LibTiff. The LZW decoder, you'll have to build. Use tif_lzw.c as a source of documentation. There is also a good deal of detail on the LZW codec in the TIFF spec (section 13, page 57 and below), but do make sure to also peek at tif_lzw.c as this documents also an older pre-6.0 LZW encoding that is not detailed in the spec and that you may or may not need to include.

Essentially, what you want to do is rework the decoder in tif_lzw.c, such that

memory, it makes a call to a reading helper procedure instead. This helper procedure will check whether data is available still in the small buffer, and if it's not, refill it

A particular issue to keep in mind is that neither your input buffer nor your output buffer of your own LZW decoder respects scanline boundaries. For your input buffer, this is normal, of course, since you can't predict how much input you'll need to output a scanline. Thus, simply keep the input buffer around, without changing its state from one scanline-pulling call to the next.

For your output buffer, this is because the LZW compression doesn't 'stop and restart' at scanline boundaries. It may very well be that a particular LZW compressed code resolves to five uncompressed bytes, where your scanline has only 2 bytes left, and the next three bytes are the first three of the next scanline. This is a nasty issue, that is resolved on tif_lzw with 'restart logic' with the aid of such state variables as 'dec_restart' and related.

Good luck!

Joris Van Damme
info@awaresystems.be
http://www.awaresystems.be/
Download your free TIFF tag viewer for windows here:
http://www.awaresystems.be/imaging/tiff/astifftagviewer.html