⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tif_dirread.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 4 页
字号:
					goto bad;			}			break;		case TIFFTAG_STRIPOFFSETS:		case TIFFTAG_TILEOFFSETS:			if (!TIFFFetchStripThing(tif, dp,			    td->td_nstrips, &td->td_stripoffset))				goto bad;			break;		case TIFFTAG_STRIPBYTECOUNTS:		case TIFFTAG_TILEBYTECOUNTS:			if (!TIFFFetchStripThing(tif, dp,			    td->td_nstrips, &td->td_stripbytecount))				goto bad;			break;		case TIFFTAG_COLORMAP:		case TIFFTAG_TRANSFERFUNCTION:			{				char* cp;				/*				 * TransferFunction can have either 1x or 3x				 * data values; Colormap can have only 3x				 * items.				 */				v = 1L<<td->td_bitspersample;				if (dp->tdir_tag == TIFFTAG_COLORMAP ||				    dp->tdir_count != v) {					if (!CheckDirCount(tif, dp, 3 * v))						break;				}				v *= sizeof(uint16);				cp = (char *)_TIFFCheckMalloc(tif,							      dp->tdir_count,							      sizeof (uint16),					"to read \"TransferFunction\" tag");				if (cp != NULL) {					if (TIFFFetchData(tif, dp, cp)) {						/*						 * This deals with there being						 * only one array to apply to						 * all samples.						 */						uint32 c = 1L << td->td_bitspersample;						if (dp->tdir_count == c)							v = 0L;						TIFFSetField(tif, dp->tdir_tag,						    cp, cp+v, cp+2*v);					}					_TIFFfree(cp);				}				break;			}		case TIFFTAG_PAGENUMBER:		case TIFFTAG_HALFTONEHINTS:		case TIFFTAG_YCBCRSUBSAMPLING:		case TIFFTAG_DOTRANGE:			(void) TIFFFetchShortPair(tif, dp);			break;		case TIFFTAG_REFERENCEBLACKWHITE:			(void) TIFFFetchRefBlackWhite(tif, dp);			break;/* BEGIN REV 4.0 COMPATIBILITY */		case TIFFTAG_OSUBFILETYPE:			v = 0L;			switch (TIFFExtractData(tif, dp->tdir_type,			    dp->tdir_offset)) {			case OFILETYPE_REDUCEDIMAGE:				v = FILETYPE_REDUCEDIMAGE;				break;			case OFILETYPE_PAGE:				v = FILETYPE_PAGE;				break;			}			if (v)				TIFFSetField(tif, TIFFTAG_SUBFILETYPE, v);			break;/* END REV 4.0 COMPATIBILITY */		default:			(void) TIFFFetchNormalTag(tif, dp);			break;		}	}	/*	 * Verify Palette image has a Colormap.	 */	if (td->td_photometric == PHOTOMETRIC_PALETTE &&	    !TIFFFieldSet(tif, FIELD_COLORMAP)) {		MissingRequired(tif, "Colormap");		goto bad;	}	/*	 * Attempt to deal with a missing StripByteCounts tag.	 */	if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {		/*		 * Some manufacturers violate the spec by not giving		 * the size of the strips.  In this case, assume there		 * is one uncompressed strip of data.		 */		if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&		    td->td_nstrips > 1) ||		    (td->td_planarconfig == PLANARCONFIG_SEPARATE &&		     td->td_nstrips != td->td_samplesperpixel)) {		    MissingRequired(tif, "StripByteCounts");		    goto bad;		}		TIFFWarningExt(tif->tif_clientdata, module,			"%s: TIFF directory is missing required "			"\"%s\" field, calculating from imagelength",			tif->tif_name,		        _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);		if (EstimateStripByteCounts(tif, dir, dircount) < 0)		    goto bad;/*  * Assume we have wrong StripByteCount value (in case of single strip) in * following cases: *   - it is equal to zero along with StripOffset; *   - it is larger than file itself (in case of uncompressed image); *   - it is smaller than the size of the bytes per row multiplied on the *     number of rows.  The last case should not be checked in the case of *     writing new image, because we may do not know the exact strip size *     until the whole image will be written and directory dumped out. */#define	BYTECOUNTLOOKSBAD \    ( (td->td_stripbytecount[0] == 0 && td->td_stripoffset[0] != 0) || \      (td->td_compression == COMPRESSION_NONE && \       td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0]) || \      (tif->tif_mode == O_RDONLY && \       td->td_compression == COMPRESSION_NONE && \       td->td_stripbytecount[0] < TIFFScanlineSize(tif) * td->td_imagelength) )	} else if (td->td_nstrips == 1                    && td->td_stripoffset[0] != 0                    && BYTECOUNTLOOKSBAD) {		/*		 * XXX: Plexus (and others) sometimes give a value of zero for		 * a tag when they don't know what the correct value is!  Try		 * and handle the simple case of estimating the size of a one		 * strip image.		 */		TIFFWarningExt(tif->tif_clientdata, module,	"%s: Bogus \"%s\" field, ignoring and calculating from imagelength",                            tif->tif_name,		            _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);		if(EstimateStripByteCounts(tif, dir, dircount) < 0)		    goto bad;	} else if (td->td_planarconfig == PLANARCONFIG_CONTIG		   && td->td_nstrips > 2		   && td->td_compression == COMPRESSION_NONE		   && td->td_stripbytecount[0] != td->td_stripbytecount[1]) {		/*		 * XXX: Some vendors fill StripByteCount array with absolutely		 * wrong values (it can be equal to StripOffset array, for		 * example). Catch this case here.		 */		TIFFWarningExt(tif->tif_clientdata, module,	"%s: Wrong \"%s\" field, ignoring and calculating from imagelength",                            tif->tif_name,		            _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);		if (EstimateStripByteCounts(tif, dir, dircount) < 0)		    goto bad;	}	if (dir) {		_TIFFfree((char *)dir);		dir = NULL;	}	if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))		td->td_maxsamplevalue = (uint16)((1L<<td->td_bitspersample)-1);	/*	 * Setup default compression scheme.	 */	/*	 * XXX: We can optimize checking for the strip bounds using the sorted	 * bytecounts array. See also comments for TIFFAppendToStrip()	 * function in tif_write.c.	 */	if (td->td_nstrips > 1) {		tstrip_t strip;		td->td_stripbytecountsorted = 1;		for (strip = 1; strip < td->td_nstrips; strip++) {			if (td->td_stripoffset[strip - 1] >			    td->td_stripoffset[strip]) {				td->td_stripbytecountsorted = 0;				break;			}		}	}	if (!TIFFFieldSet(tif, FIELD_COMPRESSION))		TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);        /*         * Some manufacturers make life difficult by writing	 * large amounts of uncompressed data as a single strip.	 * This is contrary to the recommendations of the spec.         * The following makes an attempt at breaking such images	 * into strips closer to the recommended 8k bytes.  A	 * side effect, however, is that the RowsPerStrip tag	 * value may be changed.         */	if (td->td_nstrips == 1 && td->td_compression == COMPRESSION_NONE &&	    (tif->tif_flags & (TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP)		ChopUpSingleUncompressedStrip(tif);	/*	 * Reinitialize i/o since we are starting on a new directory.	 */	tif->tif_row = (uint32) -1;	tif->tif_curstrip = (tstrip_t) -1;	tif->tif_col = (uint32) -1;	tif->tif_curtile = (ttile_t) -1;	tif->tif_tilesize = (tsize_t) -1;	tif->tif_scanlinesize = TIFFScanlineSize(tif);	if (!tif->tif_scanlinesize) {		TIFFErrorExt(tif->tif_clientdata, module, "%s: cannot handle zero scanline size",			  tif->tif_name);		return (0);	}	if (isTiled(tif)) {		tif->tif_tilesize = TIFFTileSize(tif);		if (!tif->tif_tilesize) {			TIFFErrorExt(tif->tif_clientdata, module, "%s: cannot handle zero tile size",				  tif->tif_name);			return (0);		}	} else {		if (!TIFFStripSize(tif)) {			TIFFErrorExt(tif->tif_clientdata, module, "%s: cannot handle zero strip size",				  tif->tif_name);			return (0);		}	}	return (1);bad:	if (dir)		_TIFFfree(dir);	return (0);}/*  * Read custom directory from the arbitarry offset. * The code is very similar to TIFFReadDirectory(). */intTIFFReadCustomDirectory(TIFF* tif, toff_t diroff,			const TIFFFieldInfo info[], size_t n){	static const char module[] = "TIFFReadCustomDirectory";	TIFFDirectory* td = &tif->tif_dir;	TIFFDirEntry *dp, *dir = NULL;	const TIFFFieldInfo* fip;	size_t fix;	uint16 i, dircount;	_TIFFSetupFieldInfo(tif, info, n);	tif->tif_diroff = diroff;	if (!isMapped(tif)) {		if (!SeekOK(tif, diroff)) {			TIFFErrorExt(tif->tif_clientdata, module,			    "%s: Seek error accessing TIFF directory",                            tif->tif_name);			return (0);		}		if (!ReadOK(tif, &dircount, sizeof (uint16))) {			TIFFErrorExt(tif->tif_clientdata, module,			    "%s: Can not read TIFF directory count",                            tif->tif_name);			return (0);		}		if (tif->tif_flags & TIFF_SWAB)			TIFFSwabShort(&dircount);		dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,						       sizeof (TIFFDirEntry),					"to read TIFF custom directory");		if (dir == NULL)			return (0);		if (!ReadOK(tif, dir, dircount * sizeof (TIFFDirEntry))) {			TIFFErrorExt(tif->tif_clientdata, module,                                  "%.100s: Can not read TIFF directory",                                  tif->tif_name);			goto bad;		}	} else {		toff_t off = diroff;		if (off + sizeof (uint16) > tif->tif_size) {			TIFFErrorExt(tif->tif_clientdata, module,			    "%s: Can not read TIFF directory count",                            tif->tif_name);			return (0);		} else			_TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16));		off += sizeof (uint16);		if (tif->tif_flags & TIFF_SWAB)			TIFFSwabShort(&dircount);		dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,						       sizeof (TIFFDirEntry),					"to read TIFF custom directory");		if (dir == NULL)			return (0);		if (off + dircount * sizeof (TIFFDirEntry) > tif->tif_size) {			TIFFErrorExt(tif->tif_clientdata, module,                                  "%s: Can not read TIFF directory",                                  tif->tif_name);			goto bad;		} else {			_TIFFmemcpy(dir, tif->tif_base + off,				    dircount * sizeof (TIFFDirEntry));		}	}	TIFFFreeDirectory(tif);	fix = 0;	for (dp = dir, i = dircount; i > 0; i--, dp++) {		if (tif->tif_flags & TIFF_SWAB) {			TIFFSwabArrayOfShort(&dp->tdir_tag, 2);			TIFFSwabArrayOfLong(&dp->tdir_count, 2);		}		if (fix >= tif->tif_nfields || dp->tdir_tag == IGNORE)			continue;		while (fix < tif->tif_nfields &&		       tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)			fix++;		if (fix >= tif->tif_nfields ||		    tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {			TIFFWarningExt(tif->tif_clientdata, module,                        "%s: unknown field with tag %d (0x%x) encountered",				    tif->tif_name, dp->tdir_tag, dp->tdir_tag,				    dp->tdir_type);			TIFFMergeFieldInfo(tif,					   _TIFFCreateAnonFieldInfo(tif,						dp->tdir_tag,						(TIFFDataType)dp->tdir_type),					   1);			fix = 0;			while (fix < tif->tif_nfields &&			       tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)				fix++;		}		/*		 * Null out old tags that we ignore.		 */		if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {	ignore:			dp->tdir_tag = IGNORE;			continue;		}		/*		 * Check data type.		 */		fip = tif->tif_fieldinfo[fix];		while (dp->tdir_type != (unsigned short) fip->field_type                       && fix < tif->tif_nfields) {			if (fip->field_type == TIFF_ANY)	/* wildcard */				break;                        fip = tif->tif_fieldinfo[++fix];			if (fix >= tif->tif_nfields ||			    fip->field_tag != dp->tdir_tag) {				TIFFWarningExt(tif->tif_clientdata, module,			"%s: wrong data type %d for \"%s\"; tag ignored",					    tif->tif_name, dp->tdir_type,					    tif->tif_fieldinfo[fix-1]->field_name);				goto ignore;			}		}		/*		 * Check count if known in advance.		 */		if (fip->field_readcount != TIFF_VARIABLE		    && fip->field_readcount != TIFF_VARIABLE2) {			uint32 expected = (fip->field_readcount == TIFF_SPP) ?			    (uint32) td->td_samplesperpixel :			    (uint32) fip->field_readcount;			if (!CheckDirCount(tif, dp, expected))				goto ignore;		}		(void) TIFFFetchNormalTag(tif, dp);	}		if (dir)		_TIFFfree(dir);	return 1;bad:	if (dir)		_TIFFfree(dir);	return 0;}/* * EXIF is important special case of custom IFD, so we have a special * function to read it. */intTIFFReadEXIFDirectory(TIFF* tif, toff_t diroff){	size_t exifFieldInfoCount;	const TIFFFieldInfo *exifFieldInfo =		_TIFFGetExifFieldInfo(&exifFieldInfoCount);	return TIFFReadCustomDirectory(tif, diroff, exifFieldInfo,				       exifFieldInfoCount);}static intEstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount){	static const char module[] = "EstimateStripByteCounts";	register TIFFDirEntry *dp;	register TIFFDirectory *td = &tif->tif_dir;	uint16 i;	if (td->td_stripbytecount)		_TIFFfree(td->td_stripbytecount);	td->td_stripbytecount = (uint32*)	    _TIFFCheckMalloc(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 = TIFFDataWidth((TIFFDataType) dp->tdir_type);			if (cc == 0) {				TIFFErrorExt(tif->tif_clientdata, module,			"%s: Cannot determine size of unknown tag type %d",					  tif->tif_name, dp->tdir_type);				return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -