AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
August 2007

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



Thread

2007.08.07 03:46 "bilevel image scrambling when size not divisible by 8", by Lee Cooper
2007.08.07 05:02 "Re: bilevel image scrambling when size not divisible by 8", by Bob Friesenhahn

2007.08.07 03:46 "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(out, TIFFTAG_IMAGELENGTH, height);
	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(out, TIFFTAG_ROWSPERSTRIP, height);

	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);
	}
}