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
July 1998

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!



1998.07.30 08:35 "libtiff fixes", by <tim@sierra.auriga.ru>

Hi!
I have two patches for LIBTIFF.
In fact they are about bugs in my sample files, not in the library
but these twicked data files exist already so I have to manage them
and I see no harm in the changes, so it would be nice to see the
changes in the library in some future.

Basically the changes do the following
- enhance workaround for bogus stripbytecounts;
- allow to read (not write) long tag data instead of short.
The patches itself are appended to the end of message.

Finally, I have a problem and a question.

I have couple of samples with stripbytecount too small, i.e. data are
really present in the file and if you try to read after the end of
strip the file is decoded Ok. I'm not sure if it is worth implementing
in the library, (at the moment I did it in home-made CCITT decoder).

By the way, the code to read CCITT images in libtiff looks really
unpleasant for me, and, from my own point of view of course, the above
home-made decoder is somewhat better (as far as I could see it might
also solve the problem with "lazy decoding" although I'm not sure).
Is anybody interested in such a beast? Let's discuss if so.

Regards,
				Tim

*** tif_dirread.old	Tue Sep  2 21:54:24 1997
--- tif_dirread.c	Mon Jul 27 12:50:19 1998
***************
*** 252,257 ****
--- 252,265 ----
  		 * Check data type.
  		 */
  		fip = tif->tif_fieldinfo[fix];
+ 		if (fip->field_type == TIFF_SHORT &&
+ 		    dp->tdir_type == TIFF_LONG) {
+ 			/* Allow longs to be read instead of shorts */
+ 			TIFFWarning(tif->tif_name,
+ 				"wrong data type %d for \"%s\"",
+ 				dp->tdir_type, fip[-1].field_name);
+ 			/*fip->field_tag = TIFF_LONG;*/ /* Hm-m */
+ 		} else
  		while (dp->tdir_type != (u_short) fip->field_type) {
  			if (fip->field_type == TIFF_ANY)	/* wildcard */
  				break;
***************
*** 489,494 ****
--- 497,504 ----
  		 * is one uncompressed strip of data.
  		 */
  		if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
+ 		    (td->td_compression != COMPRESSION_NONE ||
+ 		     !TIFFFieldSet(tif, FIELD_ROWSPERSTRIP)) &&
  		    td->td_nstrips > 1) ||
  		    (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
  		     td->td_nstrips != td->td_samplesperpixel)) {
***************
*** 566,583 ****
  	    CheckMalloc(tif, td->td_nstrips * sizeof (uint32),
  		"for \"StripByteCounts\" array");
  	if (td->td_compression != COMPRESSION_NONE) {
! 		uint32 space = (uint32)(sizeof (TIFFHeader)
! 		    + sizeof (uint16)
! 		    + (dircount * sizeof (TIFFDirEntry))
! 		    + sizeof (uint32));
  		toff_t filesize = TIFFGetFileSize(tif);
- 		uint16 n;
  
  		/* calculate amount of space used by indirect values */
! 		for (dp = dir, n = dircount; n > 0; n--, dp++) {
  			uint32 cc = dp->tdir_count*tiffDataWidth[dp->tdir_type];
! 			if (cc > sizeof (uint32))
  				space += cc;
  		}
  		space = filesize - space;
  		if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
--- 576,604 ----
  	    CheckMalloc(tif, td->td_nstrips * sizeof (uint32),
  		"for \"StripByteCounts\" array");
  	if (td->td_compression != COMPRESSION_NONE) {
! 
! /* sizeof() sometimes gives strange results, so specify 'em directly */
! #define HEADER_SIZE	4
! #define COUNTER_SIZE	2
! #define DIR_ENTRY_SIZE	12
! #define OFFSET_SIZE	4
! 		uint32 space = HEADER_SIZE + COUNTER_SIZE +
! 			(dircount * DIR_ENTRY_SIZE) + OFFSET_SIZE;
  		toff_t filesize = TIFFGetFileSize(tif);
  
  		/* calculate amount of space used by indirect values */
! 		for (dp = dir; dp-dir < dircount; dp++) {
  			uint32 cc = dp->tdir_count*tiffDataWidth[dp->tdir_type];
! 			if (cc > sizeof (uint32)) {
! 				/* did we see this data chunk? */
! 				register TIFFDirEntry *d;
! 				for (d=dir; d<dp; d++)
! 					if (d->tdir_offset == dp->tdir_offset &&
! 					    d->tdir_type == dp->tdir_type)
! 						goto next;
  				space += cc;
+ 			next:	;
+ 			}
  		}
  		space = filesize - space;
  		if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
***************
*** 596,605 ****
  			td->td_stripbytecount[i] =
  			    filesize - td->td_stripoffset[i];
  	} else {
! 		uint32 rowbytes = TIFFScanlineSize(tif);
! 		uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
! 		for (i = 0; i < td->td_nstrips; i++)
! 			td->td_stripbytecount[i] = rowbytes*rowsperstrip;
  	}
  	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
  	if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
--- 617,640 ----
  			td->td_stripbytecount[i] =
  			    filesize - td->td_stripoffset[i];
  	} else {
! 		uint32 bytecount, rows;
! 		uint32 rowsperstrip =
! 			TIFFFieldSet(tif, FIELD_ROWSPERSTRIP) &&
! 			td->td_rowsperstrip != (uint32)-1 ?
! 			td->td_rowsperstrip :
! 			(td->td_imagelength+td->td_stripsperimage-1) /
! 				td->td_stripsperimage;
! 
! 		bytecount = rowsperstrip * TIFFScanlineSize(tif);
! 		for (i=0; ++i < td->td_nstrips;)
! 			td->td_stripbytecount[i-1] = bytecount;
! 
! 		if (td->td_nstrips > 0) { /* the last strip */
! 			i = td->td_nstrips - 1;
! 			rows = td->td_imagelength - i*rowsperstrip;
! 			td->td_stripbytecount[i] = rows < rowsperstrip ?
! 				rows * TIFFScanlineSize(tif) : bytecount;
! 		}
  	}
  	TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
  	if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
*** tif_read.old	Tue Sep  2 21:54:29 1997
--- tif_read.c	Thu Jul 16 11:49:59 1998
***************
*** 257,262 ****
--- 257,272 ----
  			_TIFFfree(tif->tif_rawdata);
  		tif->tif_flags &= ~TIFF_MYBUFFER;
  		if (td->td_stripoffset[strip] + bytecount > tif->tif_size) {
+ 		    if (strip == td->td_nstrips-1 &&
+ 			td->td_stripoffset[strip] < tif->tif_size) {
+ 			bytecount = tif->tif_size - td->td_stripoffset[strip];
+ 			TIFFWarning(tif->tif_name,
+ 		    "bogus byte count %lu on strip %lu adjusted to %lu",
+ 				(u_long) td->td_stripbytecount[strip],
+ 				(u_long) strip,
+ 				(u_long) bytecount);
+ 			td->td_stripbytecount[strip] = bytecount;
+ 		    } else {
  			/*
  			 * This error message might seem strange, but it's
  			 * what would happen if a read were done instead.
***************
*** 269,274 ****
--- 279,285 ----
  			    (u_long) bytecount);
  			tif->tif_curstrip = NOSTRIP;
  			return (0);
+ 		    }
  		}
  		tif->tif_rawdatasize = bytecount;
  		tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip];
---------- the end ----------