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

📄 tif_dirread.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 3 页
字号:
			v = 0;			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)				(void) TIFFSetField(tif,				    TIFFTAG_SUBFILETYPE, (int)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;		}		TIFFWarning(tif->tif_name,			"TIFF directory is missing required \"%s\" field, calculating from imagelength",		    _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
		EstimateStripByteCounts(tif, dir, dircount);#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]))	} else if (td->td_nstrips == 1 && BYTECOUNTLOOKSBAD) {		/*		 * 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.		 */		TIFFWarning(tif->tif_name,	    "Bogus \"%s\" field, ignoring and calculating from imagelength",		    _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);		EstimateStripByteCounts(tif, dir, dircount);	}	if (dir)		_TIFFfree((char *)dir);	if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))		td->td_maxsamplevalue = (uint16)((1L<<td->td_bitspersample)-1);	/*	 * Setup default compression scheme.	 */	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 = TIFFTileSize(tif);	tif->tif_scanlinesize = TIFFScanlineSize(tif);	return (1);bad:	if (dir)		_TIFFfree(dir);	return (0);}static voidEstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount){	register TIFFDirEntry *dp;	register TIFFDirectory *td = &tif->tif_dir;	uint16 i;	if (td->td_stripbytecount)		_TIFFfree(td->td_stripbytecount);	td->td_stripbytecount = (uint32*)	    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)			space /= td->td_samplesperpixel;		for (i = 0; i < td->td_nstrips; i++)			td->td_stripbytecount[i] = space;		/*		 * This gross hack handles the case were the offset to		 * the last strip is past the place where we think the strip		 * should begin.  Since a strip of data must be contiguous,		 * it's safe to assume that we've overestimated the amount		 * of data in the strip and trim this number back accordingly.		 */ 		i--;		if (((toff_t)(td->td_stripoffset[i]+td->td_stripbytecount[i]))                                                               > filesize)			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))		td->td_rowsperstrip = td->td_imagelength;}static voidMissingRequired(TIFF* tif, const char* tagname){	TIFFError(tif->tif_name,	    "TIFF directory is missing required \"%s\" field", tagname);}/* * Check the count field of a directory * entry against a known value.  The caller * is expected to skip/ignore the tag if * there is a mismatch. */static intCheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count){	if (count != dir->tdir_count) {		TIFFWarning(tif->tif_name,	"incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,		    dir->tdir_count, count);		return (0);	}	return (1);}/* * Fetch a contiguous directory item. */static tsize_tTIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp){	int w = tiffDataWidth[dir->tdir_type];	tsize_t cc = dir->tdir_count * w;	if (!isMapped(tif)) {		if (!SeekOK(tif, dir->tdir_offset))			goto bad;		if (!ReadOK(tif, cp, cc))			goto bad;	} else {		if (dir->tdir_offset + cc > tif->tif_size)			goto bad;		_TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc);	}	if (tif->tif_flags & TIFF_SWAB) {		switch (dir->tdir_type) {		case TIFF_SHORT:		case TIFF_SSHORT:			TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);			break;		case TIFF_LONG:		case TIFF_SLONG:		case TIFF_FLOAT:			TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);			break;		case TIFF_RATIONAL:		case TIFF_SRATIONAL:			TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);			break;		case TIFF_DOUBLE:			TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);			break;		}	}	return (cc);bad:	TIFFError(tif->tif_name, "Error fetching data for field \"%s\"",	    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);	return ((tsize_t) 0);}/* * Fetch an ASCII item from the file. */static tsize_tTIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp){	if (dir->tdir_count <= 4) {		uint32 l = dir->tdir_offset;		if (tif->tif_flags & TIFF_SWAB)			TIFFSwabLong(&l);		_TIFFmemcpy(cp, &l, dir->tdir_count);		return (1);	}	return (TIFFFetchData(tif, dir, cp));}/* * Convert numerator+denominator to float. */static intcvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv){	if (denom == 0) {		TIFFError(tif->tif_name,		    "%s: Rational with zero denominator (num = %lu)",		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num);		return (0);	} else {		if (dir->tdir_type == TIFF_RATIONAL)			*rv = ((float)num / (float)denom);		else			*rv = ((float)(int32)num / (float)(int32)denom);		return (1);	}}/* * Fetch a rational item from the file * at offset off and return the value * as a floating point number. */static floatTIFFFetchRational(TIFF* tif, TIFFDirEntry* dir){	uint32 l[2];	float v;	return (!TIFFFetchData(tif, dir, (char *)l) ||	    !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v);}/* * Fetch a single floating point value * from the offset field and return it * as a native float. */static floatTIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir){	long l = TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset);	float v = *(float*) &l;	TIFFCvtIEEEFloatToNative(tif, 1, &v);	return (v);}/* * Fetch an array of BYTE or SBYTE values. */static intTIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint16* v){    if (dir->tdir_count <= 4) {        /*         * Extract data from offset field.         */        if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {            switch (dir->tdir_count) {                case 4: v[3] = (uint16)(dir->tdir_offset & 0xff);                case 3: v[2] = (uint16)((dir->tdir_offset >> 8) & 0xff);                case 2: v[1] = (uint16)((dir->tdir_offset >> 16) & 0xff);                case 1: v[0] = (uint16)(dir->tdir_offset >> 24);            }        } else {            switch (dir->tdir_count) {                case 4: v[3] = (uint16)(dir->tdir_offset >> 24);                case 3: v[2] = (uint16)((dir->tdir_offset >> 16) & 0xff);                case 2: v[1] = (uint16)((dir->tdir_offset >> 8) & 0xff);                case 1: v[0] = (uint16)(dir->tdir_offset & 0xff);            }        }        return (1);    } else        return (TIFFFetchData(tif, dir, (char*) v) != 0);	/* XXX */}/* * Fetch an array of SHORT or SSHORT values. */static intTIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v){	if (dir->tdir_count <= 2) {		if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {			switch (dir->tdir_count) {			case 2: v[1] = (uint16) (dir->tdir_offset & 0xffff);			case 1: v[0] = (uint16) (dir->tdir_offset >> 16);			}		} else {			switch (dir->tdir_count) {			case 2: v[1] = (uint16) (dir->tdir_offset >> 16);			case 1: v[0] = (uint16) (dir->tdir_offset & 0xffff);			}		}		return (1);	} else		return (TIFFFetchData(tif, dir, (char *)v) != 0);}/* * Fetch a pair of SHORT or BYTE values. */static intTIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir){	uint16 v[2];	int ok = 0;	switch (dir->tdir_type) {	case TIFF_SHORT:	case TIFF_SSHORT:		ok = TIFFFetchShortArray(tif, dir, v);		break;	case TIFF_BYTE:	case TIFF_SBYTE:		ok  = TIFFFetchByteArray(tif, dir, v);		break;	}	if (ok)		TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);	return (ok);}/* * Fetch an array of LONG or SLONG values. */static intTIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v){	if (dir->tdir_count == 1) {		v[0] = dir->tdir_offset;		return (1);	} else		return (TIFFFetchData(tif, dir, (char*) v) != 0);}/* * Fetch an array of RATIONAL or SRATIONAL values. */static intTIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v){	int ok = 0;	uint32* l;	l = (uint32*)CheckMalloc(tif,	    dir->tdir_count*tiffDataWidth[dir->tdir_type],	    "to fetch array of rationals");	if (l) {		if (TIFFFetchData(tif, dir, (char *)l)) {			uint32 i;			for (i = 0; i < dir->tdir_count; i++) {				ok = cvtRational(tif, dir,				    l[2*i+0], l[2*i+1], &v[i]);				if (!ok)					break;			}		}		_TIFFfree((char *)l);	}	return (ok);}/* * Fetch an array of FLOAT values. */static intTIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v){	if (dir->tdir_count == 1) {		v[0] = *(float*) &dir->tdir_offset;		TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);		return (1);	} else	if (TIFFFetchData(tif, dir, (char*) v)) {		TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);		return (1);	} else		return (0);}/* * Fetch an array of DOUBLE values. */static intTIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v){	if (TIFFFetchData(tif, dir, (char*) v)) {		TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v);		return (1);	} else		return (0);}/* * Fetch an array of ANY values.  The actual values are * returned as doubles which should be able hold all the * types.  Yes, there really should be an tany_t to avoid * this potential non-portability ...  Note in particular * that we assume that the double return value vector is * large enough to read in any fundamental type.  We use * that vector as a buffer to read in the base type vector * and then convert it in place to double (from end * to front of course). */static intTIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v){	int i;	switch (dir->tdir_type) {	case TIFF_BYTE:

⌨️ 快捷键说明

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