- 2007.08.07 03:46 "[Tiff] bilevel image scrambling when size not divisible by 8", by Lee Cooper
- 2007.08.07 14:48 "Re: [Tiff] Indexed Images", by Toby Thain
- 2007.08.07 15:23 "Re: [Tiff] Indexed Images", by Frank Warmerdam
- 2007.08.13 22:43 "[Tiff] 16-bit palette image", by Christian Henning
2007.08.07 03:46 "[Tiff] bilevel image scrambling when size not divisible by 8", by Lee Cooper
I'm developing an image processing toolbox in C/C++ based on the TIFF library and I have one function that converts grayscale TIFF data to B&W by thresholding and another function to write the result to disk. When the number of pixels in the image isn't evenly divisible by 8 the result TIFF's contents are scrambled somewhere in the writing process.
For example a 200x100 image of a single narrow vertical strip writes
OK, the same image at 201x100 appears as a series of diagonal bands and some seemingly random garbage at the bottom. The thresholding portion seems to be working OK, I have verified this by writing its result in ASCII and checking manually in Matlab.
Apparently I have some misunderstanding about how bilevel images are handled in TIFF but I can't find much info on the subject. When the number of pixels isn't a multiple of eight how is the remainder of the byte handled? I feel like this will probably be a simple answer but I'm stuck and really need to make some progress. I've included some code snippets below.
---------------------------------------------------------------------------------------------------------------------- int TIFFwriteBW(uint8* image, char* filename, uint32 width, uint32 height) {
TIFF* out = TIFFOpen(filename, "w");
TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField( TIFFTAG_IMAGELENGTH , height );out,
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1);
TIFFSetField(out, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
TIFFSetField(out, TIFFTAG_ORIENTATION,
ORIENTATION_TOPLEFT); TIFFSetField(out, TIFFTAG_PLANARCONFIG,
PLANARCONFIG_CONTIG);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
TIFFSetField( TIFFTAG_ROWSPERSTRIP , height ); out,
TIFFWriteEncodedStrip(out, 0, image, (uint32)ceil((height * width) / 8.0);
TIFFClose(out);
return(1);
}
uint8* gray2BW(uint8* image, uint32 npixels, uint8 thresh) {
uint8* bw = (uint8*) malloc((uint32) ceil(npixels / 8.0) * sizeof(uint8));
if(bw != NULL) {
uint8 *grayptr = image;
int i, j;
for(i = 0; i < npixels; i++) {
*(bw + i/8) <<= 1; //shift byte contents
left by one
if(*grayptr >= thresh) { //test threshold
each pixel
*(bw
+ i/8) |= 01;
}
grayptr++;
}
return(bw);
}
else {
return(NULL);
}
}