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

📄 tif_dirread.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 3 页
字号:
	case TIFF_SBYTE:		if (!TIFFFetchByteArray(tif, dir, (uint16*) v))			return (0);		if (dir->tdir_type == TIFF_BYTE) {			uint16* vp = (uint16*) v;			for (i = dir->tdir_count-1; i >= 0; i--)				v[i] = vp[i];		} else {			int16* vp = (int16*) v;			for (i = dir->tdir_count-1; i >= 0; i--)				v[i] = vp[i];		}		break;	case TIFF_SHORT:	case TIFF_SSHORT:		if (!TIFFFetchShortArray(tif, dir, (uint16*) v))			return (0);		if (dir->tdir_type == TIFF_SHORT) {			uint16* vp = (uint16*) v;			for (i = dir->tdir_count-1; i >= 0; i--)				v[i] = vp[i];		} else {			int16* vp = (int16*) v;			for (i = dir->tdir_count-1; i >= 0; i--)				v[i] = vp[i];		}		break;	case TIFF_LONG:	case TIFF_SLONG:		if (!TIFFFetchLongArray(tif, dir, (uint32*) v))			return (0);		if (dir->tdir_type == TIFF_LONG) {			uint32* vp = (uint32*) v;			for (i = dir->tdir_count-1; i >= 0; i--)				v[i] = vp[i];		} else {			int32* vp = (int32*) v;			for (i = dir->tdir_count-1; i >= 0; i--)				v[i] = vp[i];		}		break;	case TIFF_RATIONAL:	case TIFF_SRATIONAL:		if (!TIFFFetchRationalArray(tif, dir, (float*) v))			return (0);		{ float* vp = (float*) v;		  for (i = dir->tdir_count-1; i >= 0; i--)			v[i] = vp[i];		}		break;	case TIFF_FLOAT:		if (!TIFFFetchFloatArray(tif, dir, (float*) v))			return (0);		{ float* vp = (float*) v;		  for (i = dir->tdir_count-1; i >= 0; i--)			v[i] = vp[i];		}		break;	case TIFF_DOUBLE:		return (TIFFFetchDoubleArray(tif, dir, (double*) v));	default:		/* TIFF_NOTYPE */		/* TIFF_ASCII */		/* TIFF_UNDEFINED */		TIFFError(tif->tif_name,		    "Cannot read TIFF_ANY type %d for field \"%s\"",		    _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);		return (0);	}	return (1);}/* * Fetch a tag that is not handled by special case code. */static intTIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp){	static const char mesg[] = "to fetch tag value";	int ok = 0;	const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag);	if (dp->tdir_count > 1) {		/* array of values */		char* cp = NULL;		switch (dp->tdir_type) {		case TIFF_BYTE:		case TIFF_SBYTE:			/* NB: always expand BYTE values to shorts */			cp = CheckMalloc(tif,			    dp->tdir_count * sizeof (uint16), mesg);			ok = cp && TIFFFetchByteArray(tif, dp, (uint16*) cp);			break;		case TIFF_SHORT:		case TIFF_SSHORT:			cp = CheckMalloc(tif,			    dp->tdir_count * sizeof (uint16), mesg);			ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp);			break;		case TIFF_LONG:		case TIFF_SLONG:			cp = CheckMalloc(tif,			    dp->tdir_count * sizeof (uint32), mesg);			ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp);			break;		case TIFF_RATIONAL:		case TIFF_SRATIONAL:			cp = CheckMalloc(tif,			    dp->tdir_count * sizeof (float), mesg);			ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp);			break;		case TIFF_FLOAT:			cp = CheckMalloc(tif,			    dp->tdir_count * sizeof (float), mesg);			ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp);			break;		case TIFF_DOUBLE:			cp = CheckMalloc(tif,			    dp->tdir_count * sizeof (double), mesg);			ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp);			break;		case TIFF_ASCII:		case TIFF_UNDEFINED:		/* bit of a cheat... */			/*			 * Some vendors write strings w/o the trailing			 * NULL byte, so always append one just in case.			 */			cp = CheckMalloc(tif, dp->tdir_count+1, mesg);			if( (ok = (cp && TIFFFetchString(tif, dp, cp))) != 0 )				cp[dp->tdir_count] = '\0';	/* XXX */			break;		}		if (ok) {			ok = (fip->field_passcount ?			    TIFFSetField(tif, dp->tdir_tag, dp->tdir_count, cp)			  : TIFFSetField(tif, dp->tdir_tag, cp));		}		if (cp != NULL)			_TIFFfree(cp);	} else if (CheckDirCount(tif, dp, 1)) {	/* singleton value */		switch (dp->tdir_type) {		case TIFF_BYTE:		case TIFF_SBYTE:		case TIFF_SHORT:		case TIFF_SSHORT:			/*			 * If the tag is also acceptable as a LONG or SLONG			 * then TIFFSetField will expect an uint32 parameter			 * passed to it (through varargs).  Thus, for machines			 * where sizeof (int) != sizeof (uint32) we must do			 * a careful check here.  It's hard to say if this			 * is worth optimizing.			 *			 * NB: We use TIFFFieldWithTag here knowing that			 *     it returns us the first entry in the table			 *     for the tag and that that entry is for the			 *     widest potential data type the tag may have.			 */			{ TIFFDataType type = fip->field_type;			  if (type != TIFF_LONG && type != TIFF_SLONG) {				uint16 v = (uint16)			   TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);				ok = (fip->field_passcount ?				    TIFFSetField(tif, dp->tdir_tag, 1, &v)				  : TIFFSetField(tif, dp->tdir_tag, v));				break;			  }			}			/* fall thru... */		case TIFF_LONG:		case TIFF_SLONG:			{ uint32 v32 =		    TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);			  ok = (fip->field_passcount ? 			      TIFFSetField(tif, dp->tdir_tag, 1, &v32)			    : TIFFSetField(tif, dp->tdir_tag, v32));			}			break;		case TIFF_RATIONAL:		case TIFF_SRATIONAL:		case TIFF_FLOAT:			{ float v = (dp->tdir_type == TIFF_FLOAT ? 			      TIFFFetchFloat(tif, dp)			    : TIFFFetchRational(tif, dp));			  ok = (fip->field_passcount ?			      TIFFSetField(tif, dp->tdir_tag, 1, &v)			    : TIFFSetField(tif, dp->tdir_tag, v));			}			break;		case TIFF_DOUBLE:			{ double v;			  ok = (TIFFFetchDoubleArray(tif, dp, &v) &&			    (fip->field_passcount ?			      TIFFSetField(tif, dp->tdir_tag, 1, &v)			    : TIFFSetField(tif, dp->tdir_tag, v))			  );			}			break;		case TIFF_ASCII:		case TIFF_UNDEFINED:		/* bit of a cheat... */			{ char c[2];			  if( (ok = (TIFFFetchString(tif, dp, c) != 0)) != 0 ){				c[1] = '\0';		/* XXX paranoid */				ok = TIFFSetField(tif, dp->tdir_tag, c);			  }			}			break;		}	}	return (ok);}#define	NITEMS(x)	(sizeof (x) / sizeof (x[0]))/* * Fetch samples/pixel short values for  * the specified tag and verify that * all values are the same. */static intTIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, int* pl){	int samples = tif->tif_dir.td_samplesperpixel;	int status = 0;	if (CheckDirCount(tif, dir, (uint32) samples)) {		uint16 buf[10];		uint16* v = buf;		if (samples > NITEMS(buf))			v = (uint16*) _TIFFmalloc(samples * sizeof (uint16));		if (TIFFFetchShortArray(tif, dir, v)) {			int i;			for (i = 1; i < samples; i++)				if (v[i] != v[0]) {					TIFFError(tif->tif_name,		"Cannot handle different per-sample values for field \"%s\"",			   _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);					goto bad;				}			*pl = v[0];			status = 1;		}	bad:		if (v != buf)			_TIFFfree((char*) v);	}	return (status);}/* * Fetch samples/pixel ANY values for  * the specified tag and verify that * all values are the same. */static intTIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl){	int samples = (int) tif->tif_dir.td_samplesperpixel;	int status = 0;	if (CheckDirCount(tif, dir, (uint32) samples)) {		double buf[10];		double* v = buf;		if (samples > NITEMS(buf))			v = (double*) _TIFFmalloc(samples * sizeof (double));		if (TIFFFetchAnyArray(tif, dir, v)) {			int i;			for (i = 1; i < samples; i++)				if (v[i] != v[0]) {					TIFFError(tif->tif_name,		"Cannot handle different per-sample values for field \"%s\"",			   _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);					goto bad;				}			*pl = v[0];			status = 1;		}	bad:		if (v != buf)			_TIFFfree(v);	}	return (status);}#undef NITEMS/* * Fetch a set of offsets or lengths. * While this routine says "strips", * in fact it's also used for tiles. */static intTIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, long nstrips, uint32** lpp){	register uint32* lp;	int status;	if (!CheckDirCount(tif, dir, (uint32) nstrips))		return (0);	/*	 * Allocate space for strip information.	 */	if (*lpp == NULL &&	    (*lpp = (uint32 *)CheckMalloc(tif,	      nstrips * sizeof (uint32), "for strip array")) == NULL)		return (0);	lp = *lpp;	if (dir->tdir_type == (int)TIFF_SHORT) {		/*		 * Handle uint16->uint32 expansion.		 */		uint16* dp = (uint16*) CheckMalloc(tif,		    dir->tdir_count* sizeof (uint16), "to fetch strip tag");		if (dp == NULL)			return (0);		if( (status = TIFFFetchShortArray(tif, dir, dp)) != 0 ) {			register uint16* wp = dp;			while (nstrips-- > 0)				*lp++ = *wp++;		}		_TIFFfree((char*) dp);	} else		status = TIFFFetchLongArray(tif, dir, lp);	return (status);}#define	NITEMS(x)	(sizeof (x) / sizeof (x[0]))/* * Fetch and set the ExtraSamples tag. */static intTIFFFetchExtraSamples(TIFF* tif, TIFFDirEntry* dir){	uint16 buf[10];	uint16* v = buf;	int status;	if (dir->tdir_count > NITEMS(buf))		v = (uint16*) _TIFFmalloc(dir->tdir_count * sizeof (uint16));	if (dir->tdir_type == TIFF_BYTE)		status = TIFFFetchByteArray(tif, dir, v);	else		status = TIFFFetchShortArray(tif, dir, v);	if (status)		status = TIFFSetField(tif, dir->tdir_tag, dir->tdir_count, v);	if (v != buf)		_TIFFfree((char*) v);	return (status);}#undef NITEMS#ifdef COLORIMETRY_SUPPORT/* * Fetch and set the RefBlackWhite tag. */static intTIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir){	static const char mesg[] = "for \"ReferenceBlackWhite\" array";	char* cp;	int ok;	if (dir->tdir_type == TIFF_RATIONAL)		return (TIFFFetchNormalTag(tif, dir));	/*	 * Handle LONG's for backward compatibility.	 */	cp = CheckMalloc(tif, dir->tdir_count * sizeof (uint32), mesg);	if( (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) != 0) {		float* fp = (float*)		    CheckMalloc(tif, dir->tdir_count * sizeof (float), mesg);		if( (ok = (fp != NULL)) != 0 ) {			uint32 i;			for (i = 0; i < dir->tdir_count; i++)				fp[i] = (float)((uint32*) cp)[i];			ok = TIFFSetField(tif, dir->tdir_tag, fp);			_TIFFfree((char*) fp);		}	}	if (cp)		_TIFFfree(cp);	return (ok);}#endif/* * Replace a single strip (tile) of uncompressed data by * multiple strips (tiles), each approximately 8Kbytes. * This is useful for dealing with large images or * for dealing with machines with a limited amount * memory. */static voidChopUpSingleUncompressedStrip(TIFF* tif){	register TIFFDirectory *td = &tif->tif_dir;	uint32 bytecount = td->td_stripbytecount[0];	uint32 offset = td->td_stripoffset[0];	tsize_t rowbytes = TIFFVTileSize(tif, 1), stripbytes;	tstrip_t strip, nstrips, rowsperstrip;	uint32* newcounts;	uint32* newoffsets;	/*	 * Make the rows hold at least one	 * scanline, but fill 8k if possible.	 */	if (rowbytes > 8192) {		stripbytes = rowbytes;		rowsperstrip = 1;	} else {		rowsperstrip = 8192 / rowbytes;		stripbytes = rowbytes * rowsperstrip;	}	/* never increase the number of strips in an image */	if (rowsperstrip >= td->td_rowsperstrip)		return;	nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes);	newcounts = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32),				"for chopped \"StripByteCounts\" array");	newoffsets = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32),				"for chopped \"StripOffsets\" array");	if (newcounts == NULL || newoffsets == NULL) {	        /*		 * Unable to allocate new strip information, give		 * up and use the original one strip information.		 */		if (newcounts != NULL)			_TIFFfree(newcounts);		if (newoffsets != NULL)			_TIFFfree(newoffsets);		return;	}	/*	 * Fill the strip information arrays with	 * new bytecounts and offsets that reflect	 * the broken-up format.	 */	for (strip = 0; strip < nstrips; strip++) {		if (stripbytes > (tsize_t) bytecount)			stripbytes = bytecount;		newcounts[strip] = stripbytes;		newoffsets[strip] = offset;		offset += stripbytes;		bytecount -= stripbytes;	}	/*	 * Replace old single strip info with multi-strip info.	 */	td->td_stripsperimage = td->td_nstrips = nstrips;	TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);	_TIFFfree(td->td_stripbytecount);	_TIFFfree(td->td_stripoffset);	td->td_stripbytecount = newcounts;	td->td_stripoffset = newoffsets;}

⌨️ 快捷键说明

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