TIFF decoder

I did not plan to display TIFF images in my homebrew OS. The only reason was to test the LZW-decompressor for the TIFF LZW-variant.

Test TIFF image from Pixar:

probably not displayed by the browser

TIFF converted to PNG and the BPM output of the decoder:

Image data decompression succeeds, but obviously TIFF used transparency for those black background pixels - not supported at the moment.

Lets look at decoder's output:

Opening strike.tif
Header: big-endian
IFD: 16 entries:
  IFD-Entry: 256
    ImageWidth: 256
  IFD-Entry: 257
    ImageLength: 200
  IFD-Entry: 258
    4 x BitsPerSample: 8 8 8 8
  IFD-Entry: 259
    Compression: 5 (LZW)
  IFD-Entry: 262
  IFD-Entry: 273
    Number of Strips: 25
  IFD-Entry: 277
    SamplesPerPixel: 4
  IFD-Entry: 278
    RowsPerStrip: 8
  IFD-Entry: 279
  IFD-Entry: 282
  IFD-Entry: 283
  IFD-Entry: 284
  IFD-Entry: 286
  IFD-Entry: 287
  IFD-Entry: 296
  IFD-Entry: 338
Decoding...
  00000008: strip 1 (compressed data of 147 bytes)
  0000009b: strip 2 (compressed data of 147 bytes)
  0000012e: strip 3 (compressed data of 814 bytes)
  0000045c: strip 4 (compressed data of 2634 bytes)
  00000ea6: strip 5 (compressed data of 3637 bytes)
  00001cdb: strip 6 (compressed data of 3454 bytes)
  00002a59: strip 7 (compressed data of 3262 bytes)
  00003717: strip 8 (compressed data of 4095 bytes)
  00004716: strip 9 (compressed data of 4714 bytes)
  00005980: strip 10 (compressed data of 5226 bytes)
  00006dea: strip 11 (compressed data of 5571 bytes)
  000083ad: strip 12 (compressed data of 6633 bytes)
  00009d96: strip 13 (compressed data of 6565 bytes)
  0000b73b: strip 14 (compressed data of 6082 bytes)
  0000cefd: strip 15 (compressed data of 5717 bytes)
  0000e552: strip 16 (compressed data of 5884 bytes)
  0000fc4e: strip 17 (compressed data of 6288 bytes)
  000114de: strip 18 (compressed data of 6128 bytes)
  00012cce: strip 19 (compressed data of 5211 bytes)
  00014129: strip 20 (compressed data of 4903 bytes)
  00015450: strip 21 (compressed data of 5064 bytes)
  00016818: strip 22 (compressed data of 5200 bytes)
  00017c68: strip 23 (compressed data of 5265 bytes)
  000190f9: strip 24 (compressed data of 5398 bytes)
  0001a60f: strip 25 (compressed data of 2159 bytes)
Writing strike.bmp.

The image is 256 x 200 pixels. 4 samples per pixel, some form of RGBA. 25 strips, 8 rows each strip = 200. LZW compression.

When LZW writes directly into BMP pixel data, the image showed up like this:

This is because there are a few possibilities how to store packed RGBA pixels, and it varies from standard to platform and software:

A R G B ..
R G B A ..
A B G R ..
B G R A ..   (BM format)

The decoder, being a dummy TIFF reader, simply ignores the alpha component (it seems like this TIFF used alpha for transparency only).

TIFF structure

TIFF image data is compressed in units of strips, located anywhere in the TIFF file. Each strip covers RowsPerStrip of image data:

+-------------------------------------+
|                                     |
|              STRIP                  |
|                                     |
+-------------------------------------+
|     ............................... |
|         ..........RowsPerStrip..... |
|              ...................... |
+-------------------------------------+
|                                     |
|                                     |
|                                     |
+-------------------------------------+
|                                     |
|                                     |
|                                     |
+-------------------------------------+
|                                     |
|                                     |
|                                     |
+-------------------------------------+

Indeed, for the first strip: 8 + 147 = 155 (9Bhex), the start offset of the next strip.

TIFF LZW-variant

LZW data per Strip.

TIFF pixel structure

TIFF compression


20120410 A. Tarpai