📄 tif_dir.c
字号:
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_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){ register TIFFDirectory *td = &tif->tif_dir; CleanupField(td_colormap[0]); CleanupField(td_colormap[1]); CleanupField(td_colormap[2]); CleanupField(td_documentname); CleanupField(td_artist); CleanupField(td_datetime); CleanupField(td_hostcomputer); CleanupField(td_imagedescription); CleanupField(td_make); CleanupField(td_model); CleanupField(td_software); CleanupField(td_copyright); CleanupField(td_pagename); CleanupField(td_sampleinfo);#if SUBIFD_SUPPORT CleanupField(td_subifd);#endif#ifdef YCBCR_SUPPORT CleanupField(td_ycbcrcoeffs);#endif#ifdef CMYK_SUPPORT CleanupField(td_inknames); CleanupField(td_targetprinter);#endif#ifdef COLORIMETRY_SUPPORT CleanupField(td_whitepoint); CleanupField(td_primarychromas); CleanupField(td_refblackwhite); CleanupField(td_transferfunction[0]); CleanupField(td_transferfunction[1]); CleanupField(td_transferfunction[2]);#endif#ifdef ICC_SUPPORT CleanupField(td_profileData);#endif#ifdef PHOTOSHOP_SUPPORT CleanupField(td_photoshopData);#endif#ifdef IPTC_SUPPORT CleanupField(td_richtiffiptcData);#endif CleanupField(td_stripoffset); CleanupField(td_stripbytecount); /* Begin Pixar Tags */ CleanupField(td_textureformat); CleanupField(td_wrapmodes); CleanupField(td_matrixWorldToScreen); CleanupField(td_matrixWorldToCamera); /* End Pixar Tags */}#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; _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 = (uint32) -1; td->td_tilelength = (uint32) -1; td->td_tiledepth = 1; td->td_resolutionunit = RESUNIT_INCH; td->td_sampleformat = SAMPLEFORMAT_UINT; td->td_imagedepth = 1;#ifdef YCBCR_SUPPORT td->td_ycbcrsubsampling[0] = 2; td->td_ycbcrsubsampling[1] = 2; td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;#endif#ifdef CMYK_SUPPORT td->td_inkset = INKSET_CMYK; td->td_ninks = 4;#endif tif->tif_postdecode = _TIFFNoPostDecode; tif->tif_vsetfield = _TIFFVSetField; tif->tif_vgetfield = _TIFFVGetField; tif->tif_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) { 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_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; 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; 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) { 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. */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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -