2006.08.29 20:44 "[Tiff] TiffReadEncodedStrip", by Richard Nolde

2006.08.31 00:36 "Re: [Tiff] TiffReadEncodedStrip", by Joris Van Damme


I would deduce from this that your row and column numbers are zero referenced as in C arrays.

That is correct. One could be tempted to say that very often, such indexing leads to least complication in calculation, so it seems almost 'natural'.

My usage, for reasons related to the code that defines the zones to be extracted, runs row from 1 to IMAGE_LENGTH and column from 1 to IMAGE_WIDTH so I have to subtract one in each case.

Yes, the correct way to deal with such coordinates, would be to replace 'row' with 'myrow-1' and 'column' with 'mycolumn-1' in the offset calculations I mentioned earlier.

The snippet below is the code to extract the data bytes from the input image and write them to an output image. My code now gets the right bytes, but I am confused by your comment on the bit offset. Assuming an image of 1658 pixels wide with 1 bit per sample, 1 sample per pixel, there will be 207 "full bytes" and two extra bits. Will these last bits be in the highorder bits or loworder bits, ie 128 and 64 or 2 and 1

I myself am always consistently confused by words such as 'highorder' and 'bigendian'. Reminds me of 'left' and 'right', couldn't keep those apart either until I was a teenager and found a little trick. 'right' and 'writing' both share the letter 'r'. Yes, that trick works in dutch just like it does in english. ;-)

Now I'm 36, but I still haven't thought of a way to get 'high order' and 'big endian' in my head... I always refer to Intel and Motorola byte order. People think that's because I'm a TIFF freak. Well, I'm not about to tell them the real reason is that I'm simply stupid. Whenever they drag their big and little endians and low and high orders onto the table, I just pull an emperor's clothes, and say 'wow, that's neat'. ;-)

Let's do the maths, hey, that'll make things clear. In your example, 1658 pixels with 1 bits per pixel, the row byte count is (1658*1+7)/8=208.

Let's look at bit offset for pixel 0. It's (0*1)%8=0. With 'bit offset' I mean indexing from left to right, just like we index bytes. This is inverse to how we usually index them, the bit offset 0 equals the bit usually named 7, the bit that presents the value 128.

If you want to go from bit offset as I defined it here, to actual pixel value, you'll have to shift and mask. Assuming bitsperpixel is smaller then 8, and 8 is a multiple of bitsperpixel, the shift count to the right is 8-bitoffset-bitsperpixel, and the mask is ((1<<bitsperpixel)-1). So for pixel 0 in a row in your example, byteoffset equals 0 (in that row), bitoffset equals 0 (in that byte), you'll thus have to shift the value at that byte offset right 7 bits, and bitwise and the result with 1.

Now let's do the calculation for your the two bits that confuse you.

pixel 1656 in a row
byteoffset = (1656*1)/8 = 207
bitoffset = (1656*1)%8 = 0
shiftcount = 8-0-1 = 7
mask = (1<<1)-1 = 1

pixel 1657 in a row
byteoffset = (1657*1)/8 = 207
bitoffset = (1657*1)%8 = 1
shiftcount = 8-1-1 = 6
mask = (1<<1)-1 = 1

Yes, pixel 0 will be in the 128 bit, ans so will pixel 8, and 16, and 24, and... and 1656.

does the fill order matter when the image has been extracted by ReadEncodedStrip?

No, it does not. Fillordering happens after compression, before writing, and defillordering happens after reading, before decompression. In other words, fillorder applies to the compressed data, and is resolved already before decompression, so long before the data is the way it is returned by ReadEncodedStrip.

I had assumed a continuous bit stream with the padding in the low order bits and planned on reading the trailing bits followed by zeros if it is the end of the line.

If your use of the word 'low order' is consistent with what you wrote before, meaning you expect padding to go in the bits with 'binary weights' 1, 2, 4, 8...x, and the last couple of pixel values in the bits with 'binary weights' 128,64,32,16...x*2, that is correct.

Of course, when cropping from within the line, the remaining bits need to be masked off and converted to fill bits

> too

Asuming you mean you may have to mask out some of the last bits on each row to turn 'm into padding bits, yes, that is correct. Plus, you might need to shift the complete row in order to crop, for example if you cut away one column on the left side, and bitsperpixel is 1, you'll have to shift the complete data line 1 bit to the 'left' (that's without 'r' :-)).

for (i = 0; i < crop->zones; i++)

Too tired right now, I'll have a look tomorrow if someone else hasn't by then.

Best regards,

Joris Van Damme
Download your free TIFF tag viewer for windows here: