?? tif_dir.c
字號:
*va_arg(ap, double*) = *(double *)val; ret_val = 1; break; default: ret_val = 0; break; } } } } break; } } } return(ret_val);}/* * Return the value of a field in the * internal directory structure. */intTIFFGetField(TIFF* tif, ttag_t tag, ...){ int status; va_list ap; va_start(ap, tag); status = TIFFVGetField(tif, tag, ap); va_end(ap); return (status);}/* * Like TIFFGetField, but taking a varargs * parameter list. This routine is useful * for building higher-level interfaces on * top of the library. */intTIFFVGetField(TIFF* tif, ttag_t tag, va_list ap){ const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);}#define CleanupField(member) { \ if (td->member) { \ _TIFFfree(td->member); \ td->member = 0; \ } \}/* * Release storage associated with a directory. */voidTIFFFreeDirectory(TIFF* tif){ TIFFDirectory *td = &tif->tif_dir; int i; _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS); CleanupField(td_colormap[0]); CleanupField(td_colormap[1]); CleanupField(td_colormap[2]); CleanupField(td_sampleinfo); CleanupField(td_subifd); CleanupField(td_inknames); CleanupField(td_transferfunction[0]); CleanupField(td_transferfunction[1]); CleanupField(td_transferfunction[2]); CleanupField(td_stripoffset); CleanupField(td_stripbytecount); TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); /* 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;TIFFExtendProcTIFFSetTagExtender(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. */intTIFFCreateDirectory(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. */intTIFFDefaultDirectory(TIFF* tif){ register TIFFDirectory* td = &tif->tif_dir; size_t tiffFieldInfoCount; const TIFFFieldInfo *tiffFieldInfo = _TIFFGetFieldInfo(&tiffFieldInfoCount); _TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount); _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; 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 intTIFFAdvanceDirectory(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) { TIFFErrorExt(tif->tif_clientdata, 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) { TIFFErrorExt(tif->tif_clientdata, 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))) { TIFFErrorExt(tif->tif_clientdata, 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))) { TIFFErrorExt(tif->tif_clientdata, 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_tTIFFNumberOfDirectories(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. */intTIFFSetDirectory(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). */intTIFFSetSubDirectory(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. */uint32TIFFCurrentDirOffset(TIFF* tif){ return (tif->tif_diroff);}/* * Return an indication of whether or not we are * at the last directory in the file. */intTIFFLastDirectory(TIFF* tif){ return (tif->tif_nextdiroff == 0);}/* * Unlink the specified directory from the directory chain. */intTIFFUnlinkDirectory(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) { TIFFErrorExt(tif->tif_clientdata, 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) { TIFFErrorExt(tif->tif_clientdata, 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))) { TIFFErrorExt(tif->tif_clientdata, 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. * * FIXME: this is never used properly. Should be removed in the future. */intTIFFReassignTagToIgnore (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 + -