📄 tif_dir.c
字号:
CleanupField(td_matrixWorldToScreen);
CleanupField(td_matrixWorldToCamera);
/* End Pixar Tags */
/* Cleanup custom tag values */
for( i = 0; i < td->td_customValueCount; i++ ) {
if (td->td_customValues[i].value)
_TIFFfree(td->td_customValues[i].value);
}
td->td_customValueCount = 0;
CleanupField(td_customValues);
}
#undef CleanupField
/*
* Client Tag extension support (from Niles Ritter).
*/
static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
TIFFExtendProc
TIFFSetTagExtender(TIFFExtendProc extender)
{
TIFFExtendProc prev = _TIFFextender;
_TIFFextender = extender;
return (prev);
}
/*
* Setup for a new directory. Should we automatically call
* TIFFWriteDirectory() if the current one is dirty?
*
* The newly created directory will not exist on the file till
* TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
*/
int
TIFFCreateDirectory(TIFF* tif)
{
TIFFDefaultDirectory(tif);
tif->tif_diroff = 0;
tif->tif_nextdiroff = 0;
tif->tif_curoff = 0;
tif->tif_row = (uint32) -1;
tif->tif_curstrip = (tstrip_t) -1;
return 0;
}
/*
* Setup a default directory structure.
*/
int
TIFFDefaultDirectory(TIFF* tif)
{
register TIFFDirectory* td = &tif->tif_dir;
_TIFFSetupFieldInfo(tif);
_TIFFmemset(td, 0, sizeof (*td));
td->td_fillorder = FILLORDER_MSB2LSB;
td->td_bitspersample = 1;
td->td_threshholding = THRESHHOLD_BILEVEL;
td->td_orientation = ORIENTATION_TOPLEFT;
td->td_samplesperpixel = 1;
td->td_rowsperstrip = (uint32) -1;
td->td_tilewidth = 0;
td->td_tilelength = 0;
td->td_tiledepth = 1;
td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
td->td_resolutionunit = RESUNIT_INCH;
td->td_sampleformat = SAMPLEFORMAT_UINT;
td->td_imagedepth = 1;
td->td_ycbcrsubsampling[0] = 2;
td->td_ycbcrsubsampling[1] = 2;
td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
td->td_inkset = INKSET_CMYK;
td->td_ninks = 4;
tif->tif_postdecode = _TIFFNoPostDecode;
tif->tif_foundfield = NULL;
tif->tif_tagmethods.vsetfield = _TIFFVSetField;
tif->tif_tagmethods.vgetfield = _TIFFVGetField;
tif->tif_tagmethods.printdir = NULL;
/*
* Give client code a chance to install their own
* tag extensions & methods, prior to compression overloads.
*/
if (_TIFFextender)
(*_TIFFextender)(tif);
(void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
/*
* NB: The directory is marked dirty as a result of setting
* up the default compression scheme. However, this really
* isn't correct -- we want TIFF_DIRTYDIRECT to be set only
* if the user does something. We could just do the setup
* by hand, but it seems better to use the normal mechanism
* (i.e. TIFFSetField).
*/
tif->tif_flags &= ~TIFF_DIRTYDIRECT;
/*
* As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
* we clear the ISTILED flag when setting up a new directory.
* Should we also be clearing stuff like INSUBIFD?
*/
tif->tif_flags &= ~TIFF_ISTILED;
return (1);
}
static int
TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off)
{
static const char module[] = "TIFFAdvanceDirectory";
uint16 dircount;
if (isMapped(tif))
{
toff_t poff=*nextdir;
if (poff+sizeof(uint16) > tif->tif_size)
{
TIFFError(module, "%s: Error fetching directory count",
tif->tif_name);
return (0);
}
_TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16));
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabShort(&dircount);
poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry);
if (off != NULL)
*off = poff;
if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size)
{
TIFFError(module, "%s: Error fetching directory link",
tif->tif_name);
return (0);
}
_TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32));
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabLong(nextdir);
return (1);
}
else
{
if (!SeekOK(tif, *nextdir) ||
!ReadOK(tif, &dircount, sizeof (uint16))) {
TIFFError(module, "%s: Error fetching directory count",
tif->tif_name);
return (0);
}
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabShort(&dircount);
if (off != NULL)
*off = TIFFSeekFile(tif,
dircount*sizeof (TIFFDirEntry), SEEK_CUR);
else
(void) TIFFSeekFile(tif,
dircount*sizeof (TIFFDirEntry), SEEK_CUR);
if (!ReadOK(tif, nextdir, sizeof (uint32))) {
TIFFError(module, "%s: Error fetching directory link",
tif->tif_name);
return (0);
}
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabLong(nextdir);
return (1);
}
}
/*
* Count the number of directories in a file.
*/
tdir_t
TIFFNumberOfDirectories(TIFF* tif)
{
toff_t nextdir = tif->tif_header.tiff_diroff;
tdir_t n = 0;
while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
n++;
return (n);
}
/*
* Set the n-th directory as the current directory.
* NB: Directories are numbered starting at 0.
*/
int
TIFFSetDirectory(TIFF* tif, tdir_t dirn)
{
toff_t nextdir;
tdir_t n;
nextdir = tif->tif_header.tiff_diroff;
for (n = dirn; n > 0 && nextdir != 0; n--)
if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
return (0);
tif->tif_nextdiroff = nextdir;
/*
* Set curdir to the actual directory index. The
* -1 is because TIFFReadDirectory will increment
* tif_curdir after successfully reading the directory.
*/
tif->tif_curdir = (dirn - n) - 1;
/*
* Reset tif_dirnumber counter and start new list of seen directories.
* We need this to prevent IFD loops.
*/
tif->tif_dirnumber = 0;
return (TIFFReadDirectory(tif));
}
/*
* Set the current directory to be the directory
* located at the specified file offset. This interface
* is used mainly to access directories linked with
* the SubIFD tag (e.g. thumbnail images).
*/
int
TIFFSetSubDirectory(TIFF* tif, uint32 diroff)
{
tif->tif_nextdiroff = diroff;
/*
* Reset tif_dirnumber counter and start new list of seen directories.
* We need this to prevent IFD loops.
*/
tif->tif_dirnumber = 0;
return (TIFFReadDirectory(tif));
}
/*
* Return file offset of the current directory.
*/
uint32
TIFFCurrentDirOffset(TIFF* tif)
{
return (tif->tif_diroff);
}
/*
* Return an indication of whether or not we are
* at the last directory in the file.
*/
int
TIFFLastDirectory(TIFF* tif)
{
return (tif->tif_nextdiroff == 0);
}
/*
* Unlink the specified directory from the directory chain.
*/
int
TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn)
{
static const char module[] = "TIFFUnlinkDirectory";
toff_t nextdir;
toff_t off;
tdir_t n;
if (tif->tif_mode == O_RDONLY) {
TIFFError(module, "Can not unlink directory in read-only file");
return (0);
}
/*
* Go to the directory before the one we want
* to unlink and nab the offset of the link
* field we'll need to patch.
*/
nextdir = tif->tif_header.tiff_diroff;
off = sizeof (uint16) + sizeof (uint16);
for (n = dirn-1; n > 0; n--) {
if (nextdir == 0) {
TIFFError(module, "Directory %d does not exist", dirn);
return (0);
}
if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
return (0);
}
/*
* Advance to the directory to be unlinked and fetch
* the offset of the directory that follows.
*/
if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
return (0);
/*
* Go back and patch the link field of the preceding
* directory to point to the offset of the directory
* that follows.
*/
(void) TIFFSeekFile(tif, off, SEEK_SET);
if (tif->tif_flags & TIFF_SWAB)
TIFFSwabLong(&nextdir);
if (!WriteOK(tif, &nextdir, sizeof (uint32))) {
TIFFError(module, "Error writing directory link");
return (0);
}
/*
* Leave directory state setup safely. We don't have
* facilities for doing inserting and removing directories,
* so it's safest to just invalidate everything. This
* means that the caller can only append to the directory
* chain.
*/
(*tif->tif_cleanup)(tif);
if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
_TIFFfree(tif->tif_rawdata);
tif->tif_rawdata = NULL;
tif->tif_rawcc = 0;
}
tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE);
TIFFFreeDirectory(tif);
TIFFDefaultDirectory(tif);
tif->tif_diroff = 0; /* force link on next write */
tif->tif_nextdiroff = 0; /* next write must be at end */
tif->tif_curoff = 0;
tif->tif_row = (uint32) -1;
tif->tif_curstrip = (tstrip_t) -1;
return (1);
}
/* [BFC]
*
* Author: Bruce Cameron <cameron@petris.com>
*
* Set a table of tags that are to be replaced during directory process by the
* 'IGNORE' state - or return TRUE/FALSE for the requested tag such that
* 'ReadDirectory' can use the stored information.
*/
int
TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID)
{
static int TIFFignoretags [FIELD_LAST];
static int tagcount = 0 ;
int i; /* Loop index */
int j; /* Loop index */
switch (task)
{
case TIS_STORE:
if ( tagcount < (FIELD_LAST - 1) )
{
for ( j = 0 ; j < tagcount ; ++j )
{ /* Do not add duplicate tag */
if ( TIFFignoretags [j] == TIFFtagID )
return (TRUE) ;
}
TIFFignoretags [tagcount++] = TIFFtagID ;
return (TRUE) ;
}
break ;
case TIS_EXTRACT:
for ( i = 0 ; i < tagcount ; ++i )
{
if ( TIFFignoretags [i] == TIFFtagID )
return (TRUE) ;
}
break;
case TIS_EMPTY:
tagcount = 0 ; /* Clear the list */
return (TRUE) ;
default:
break;
}
return (FALSE);
}
/* vim: set ts=8 sts=8 sw=8 noet: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -