tif_read.c

来自「支持各种栅格图像和矢量图像读取的库」· C语言 代码 · 共 704 行 · 第 1/2 页

C
704
字号
	if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))		return (-1);	return (TIFFReadEncodedTile(tif,	    TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1));}/* * Read a tile of data and decompress the specified * amount into the user-supplied buffer. */tsize_tTIFFReadEncodedTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size){	TIFFDirectory *td = &tif->tif_dir;	tsize_t tilesize = tif->tif_tilesize;	if (!TIFFCheckRead(tif, 1))		return (-1);	if (tile >= td->td_nstrips) {		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "%ld: Tile out of range, max %ld",		    (long) tile, (unsigned long) td->td_nstrips);		return (-1);	}	if (size == (tsize_t) -1)		size = tilesize;	else if (size > tilesize)		size = tilesize;	if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif,	    (tidata_t) buf, size, (tsample_t)(tile/td->td_stripsperimage))) {		(*tif->tif_postdecode)(tif, (tidata_t) buf, size);		return (size);	} else		return (-1);}static tsize_tTIFFReadRawTile1(TIFF* tif,    ttile_t tile, tdata_t buf, tsize_t size, const char* module){	TIFFDirectory *td = &tif->tif_dir;	assert((tif->tif_flags&TIFF_NOREADRAW)==0);	if (!isMapped(tif)) {		tsize_t cc;		if (!SeekOK(tif, td->td_stripoffset[tile])) {			TIFFErrorExt(tif->tif_clientdata, module,			    "%s: Seek error at row %ld, col %ld, tile %ld",			    tif->tif_name,			    (long) tif->tif_row,			    (long) tif->tif_col,			    (long) tile);			return ((tsize_t) -1);		}		cc = TIFFReadFile(tif, buf, size);		if (cc != size) {			TIFFErrorExt(tif->tif_clientdata, module,	    "%s: Read error at row %ld, col %ld; got %lu bytes, expected %lu",			    tif->tif_name,			    (long) tif->tif_row,			    (long) tif->tif_col,			    (unsigned long) cc,			    (unsigned long) size);			return ((tsize_t) -1);		}	} else {		if (td->td_stripoffset[tile] + size > tif->tif_size) {			TIFFErrorExt(tif->tif_clientdata, module,    "%s: Read error at row %ld, col %ld, tile %ld; got %lu bytes, expected %lu",			    tif->tif_name,			    (long) tif->tif_row,			    (long) tif->tif_col,			    (long) tile,			    (unsigned long) tif->tif_size - td->td_stripoffset[tile],			    (unsigned long) size);			return ((tsize_t) -1);		}		_TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[tile], size);	}	return (size);}/* * Read a tile of data from the file. */tsize_tTIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size){	static const char module[] = "TIFFReadRawTile";	TIFFDirectory *td = &tif->tif_dir;	tsize_t bytecount;	if (!TIFFCheckRead(tif, 1))		return ((tsize_t) -1);	if (tile >= td->td_nstrips) {		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "%lu: Tile out of range, max %lu",		    (unsigned long) tile, (unsigned long) td->td_nstrips);		return ((tsize_t) -1);	}	if (tif->tif_flags&TIFF_NOREADRAW)	{		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Compression scheme does not support access to raw uncompressed data");		return ((tsize_t) -1);	}	bytecount = td->td_stripbytecount[tile];	if (size != (tsize_t) -1 && size < bytecount)		bytecount = size;	return (TIFFReadRawTile1(tif, tile, buf, bytecount, module));}/* * Read the specified tile and setup for decoding. The data buffer is * expanded, as necessary, to hold the tile's data. */intTIFFFillTile(TIFF* tif, ttile_t tile){	static const char module[] = "TIFFFillTile";	TIFFDirectory *td = &tif->tif_dir;	if ((tif->tif_flags&TIFF_NOREADRAW)==0)	{		tsize_t bytecount = td->td_stripbytecount[tile];		if (bytecount <= 0) {			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,			    "%lu: Invalid tile byte count, tile %lu",			    (unsigned long) bytecount, (unsigned long) tile);			return (0);		}		if (isMapped(tif) &&		    (isFillOrder(tif, td->td_fillorder)		     || (tif->tif_flags & TIFF_NOBITREV))) {			/*			 * The image is mapped into memory and we either don't			 * need to flip bits or the compression routine is			 * going to handle this operation itself.  In this			 * case, avoid copying the raw data and instead just			 * reference the data from the memory mapped file			 * image.  This assumes that the decompression			 * routines do not modify the contents of the raw data			 * buffer (if they try to, the application will get a			 * fault since the file is mapped read-only).			 */			if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)				_TIFFfree(tif->tif_rawdata);			tif->tif_flags &= ~TIFF_MYBUFFER;			/*			 * We must check for overflow, potentially causing			 * an OOB read. Instead of simple			 *			 *  td->td_stripoffset[tile]+bytecount > tif->tif_size			 *			 * comparison (which can overflow) we do the following			 * two comparisons:			 */			if (bytecount > tif->tif_size ||			    td->td_stripoffset[tile] > tif->tif_size - bytecount) {				tif->tif_curtile = NOTILE;				return (0);			}			tif->tif_rawdatasize = bytecount;			tif->tif_rawdata = tif->tif_base + td->td_stripoffset[tile];		} else {			/*			 * Expand raw data buffer, if needed, to hold data			 * tile coming from file (perhaps should set upper			 * bound on the size of a buffer we'll use?).			 */			if (bytecount > tif->tif_rawdatasize) {				tif->tif_curtile = NOTILE;				if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {					TIFFErrorExt(tif->tif_clientdata, module,					"%s: Data buffer too small to hold tile %ld",					    tif->tif_name, (long) tile);					return (0);				}				if (!TIFFReadBufferSetup(tif, 0,				    TIFFroundup(bytecount, 1024)))					return (0);			}			if (TIFFReadRawTile1(tif, tile,			    (unsigned char *)tif->tif_rawdata,			    bytecount, module) != bytecount)				return (0);			if (!isFillOrder(tif, td->td_fillorder) &&			    (tif->tif_flags & TIFF_NOBITREV) == 0)				TIFFReverseBits(tif->tif_rawdata, bytecount);		}	}	return (TIFFStartTile(tif, tile));}/* * Setup the raw data buffer in preparation for * reading a strip of raw data.  If the buffer * is specified as zero, then a buffer of appropriate * size is allocated by the library.  Otherwise, * the client must guarantee that the buffer is * large enough to hold any individual strip of * raw data. */intTIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size){	static const char module[] = "TIFFReadBufferSetup";	assert((tif->tif_flags&TIFF_NOREADRAW)==0);	if (tif->tif_rawdata) {		if (tif->tif_flags & TIFF_MYBUFFER)			_TIFFfree(tif->tif_rawdata);		tif->tif_rawdata = NULL;	}	if (bp) {		tif->tif_rawdatasize = size;		tif->tif_rawdata = (tidata_t) bp;		tif->tif_flags &= ~TIFF_MYBUFFER;	} else {		tif->tif_rawdatasize = TIFFroundup(size, 1024);		tif->tif_rawdata = (tidata_t) _TIFFmalloc(tif->tif_rawdatasize);		tif->tif_flags |= TIFF_MYBUFFER;	}	if (tif->tif_rawdata == NULL) {		TIFFErrorExt(tif->tif_clientdata, module,		    "%s: No space for data buffer at scanline %ld",		    tif->tif_name, (long) tif->tif_row);		tif->tif_rawdatasize = 0;		return (0);	}	return (1);}/* * Set state to appear as if a * strip has just been read in. */static intTIFFStartStrip(TIFF* tif, tstrip_t strip){	TIFFDirectory *td = &tif->tif_dir;	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {		if (!(*tif->tif_setupdecode)(tif))			return (0);		tif->tif_flags |= TIFF_CODERSETUP;	}	tif->tif_curstrip = strip;	tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;	if (tif->tif_flags&TIFF_NOREADRAW)	{		tif->tif_rawcp = NULL;		tif->tif_rawcc = 0;	}	else	{		tif->tif_rawcp = tif->tif_rawdata;		tif->tif_rawcc = td->td_stripbytecount[strip];	}	return ((*tif->tif_predecode)(tif,			(tsample_t)(strip / td->td_stripsperimage)));}/* * Set state to appear as if a * tile has just been read in. */static intTIFFStartTile(TIFF* tif, ttile_t tile){	TIFFDirectory *td = &tif->tif_dir;	if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {		if (!(*tif->tif_setupdecode)(tif))			return (0);		tif->tif_flags |= TIFF_CODERSETUP;	}	tif->tif_curtile = tile;	tif->tif_row =	    (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) *		td->td_tilelength;	tif->tif_col =	    (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength)) *		td->td_tilewidth;	if (tif->tif_flags&TIFF_NOREADRAW)	{		tif->tif_rawcp = NULL;		tif->tif_rawcc = 0;	}	else	{		tif->tif_rawcp = tif->tif_rawdata;		tif->tif_rawcc = td->td_stripbytecount[tile];	}	return ((*tif->tif_predecode)(tif,			(tsample_t)(tile/td->td_stripsperimage)));}static intTIFFCheckRead(TIFF* tif, int tiles){	if (tif->tif_mode == O_WRONLY) {		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");		return (0);	}	if (tiles ^ isTiled(tif)) {		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?		    "Can not read tiles from a stripped image" :		    "Can not read scanlines from a tiled image");		return (0);	}	return (1);}void_TIFFNoPostDecode(TIFF* tif, tidata_t buf, tsize_t cc){    (void) tif; (void) buf; (void) cc;}void_TIFFSwab16BitData(TIFF* tif, tidata_t buf, tsize_t cc){    (void) tif;    assert((cc & 1) == 0);    TIFFSwabArrayOfShort((uint16*) buf, cc/2);}void_TIFFSwab24BitData(TIFF* tif, tidata_t buf, tsize_t cc){    (void) tif;    assert((cc % 3) == 0);    TIFFSwabArrayOfTriples((uint8*) buf, cc/3);}void_TIFFSwab32BitData(TIFF* tif, tidata_t buf, tsize_t cc){    (void) tif;    assert((cc & 3) == 0);    TIFFSwabArrayOfLong((uint32*) buf, cc/4);}void_TIFFSwab64BitData(TIFF* tif, tidata_t buf, tsize_t cc){    (void) tif;    assert((cc & 7) == 0);    TIFFSwabArrayOfDouble((double*) buf, cc/8);}/* vim: set ts=8 sts=8 sw=8 noet: */

⌨️ 快捷键说明

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