ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tif_dirread.c
Go to the documentation of this file.
00001 /* $Id: tif_dirread.c,v 1.92.2.9 2010-06-14 00:21:46 fwarmerdam Exp $ */
00002 
00003 /*
00004  * Copyright (c) 1988-1997 Sam Leffler
00005  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
00006  *
00007  * Permission to use, copy, modify, distribute, and sell this software and 
00008  * its documentation for any purpose is hereby granted without fee, provided
00009  * that (i) the above copyright notices and this permission notice appear in
00010  * all copies of the software and related documentation, and (ii) the names of
00011  * Sam Leffler and Silicon Graphics may not be used in any advertising or
00012  * publicity relating to the software without the specific, prior written
00013  * permission of Sam Leffler and Silicon Graphics.
00014  * 
00015  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
00016  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
00017  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
00018  * 
00019  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
00020  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
00021  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00022  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
00023  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
00024  * OF THIS SOFTWARE.
00025  */
00026 
00027 /*
00028  * TIFF Library.
00029  *
00030  * Directory Read Support Routines.
00031  */
00032 #include "tiffiop.h"
00033 
00034 #define IGNORE  0       /* tag placeholder used below */
00035 
00036 #ifdef HAVE_IEEEFP
00037 # define    TIFFCvtIEEEFloatToNative(tif, n, fp)
00038 # define    TIFFCvtIEEEDoubleToNative(tif, n, dp)
00039 #else
00040 extern  void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
00041 extern  void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
00042 #endif
00043 
00044 static  TIFFDirEntry* TIFFReadDirectoryFind(TIFFDirEntry* dir,
00045                         uint16 dircount, uint16 tagid);
00046 static  int EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16);
00047 static  void MissingRequired(TIFF*, const char*);
00048 static  int TIFFCheckDirOffset(TIFF*, toff_t);
00049 static  int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
00050 static  uint16 TIFFFetchDirectory(TIFF*, toff_t, TIFFDirEntry**, toff_t *);
00051 static  tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
00052 static  tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
00053 static  float TIFFFetchRational(TIFF*, TIFFDirEntry*);
00054 static  int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*);
00055 static  int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, uint16*);
00056 static  int TIFFFetchPerSampleLongs(TIFF*, TIFFDirEntry*, uint32*);
00057 static  int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*);
00058 static  int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*);
00059 static  int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**);
00060 static  int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*);
00061 static  int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
00062 static  float TIFFFetchFloat(TIFF*, TIFFDirEntry*);
00063 static  int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*);
00064 static  int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*);
00065 static  int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*);
00066 static  int TIFFFetchShortPair(TIFF*, TIFFDirEntry*);
00067 static  void ChopUpSingleUncompressedStrip(TIFF*);
00068 
00069 /*
00070  * Read the next TIFF directory from a file and convert it to the internal
00071  * format. We read directories sequentially.
00072  */
00073 int
00074 TIFFReadDirectory(TIFF* tif)
00075 {
00076     static const char module[] = "TIFFReadDirectory";
00077 
00078     int n;
00079     TIFFDirectory* td;
00080     TIFFDirEntry *dp, *dir = NULL;
00081     uint16 iv;
00082     uint32 v;
00083     const TIFFFieldInfo* fip;
00084     size_t fix;
00085     uint16 dircount;
00086     int diroutoforderwarning = 0, compressionknown = 0;
00087     int haveunknowntags = 0;
00088 
00089     tif->tif_diroff = tif->tif_nextdiroff;
00090     /*
00091      * Check whether we have the last offset or bad offset (IFD looping).
00092      */
00093     if (!TIFFCheckDirOffset(tif, tif->tif_nextdiroff))
00094         return 0;
00095     /*
00096      * Cleanup any previous compression state.
00097      */
00098     (*tif->tif_cleanup)(tif);
00099     tif->tif_curdir++;
00100     dircount = TIFFFetchDirectory(tif, tif->tif_nextdiroff,
00101                       &dir, &tif->tif_nextdiroff);
00102     if (!dircount) {
00103         TIFFErrorExt(tif->tif_clientdata, module,
00104                  "%s: Failed to read directory at offset %u",
00105                  tif->tif_name, tif->tif_nextdiroff);
00106         return 0;
00107     }
00108 
00109     tif->tif_flags &= ~TIFF_BEENWRITING;    /* reset before new dir */
00110     /*
00111      * Setup default value and then make a pass over
00112      * the fields to check type and tag information,
00113      * and to extract info required to size data
00114      * structures.  A second pass is made afterwards
00115      * to read in everthing not taken in the first pass.
00116      */
00117     td = &tif->tif_dir;
00118     /* free any old stuff and reinit */
00119     TIFFFreeDirectory(tif);
00120     TIFFDefaultDirectory(tif);
00121     /*
00122      * Electronic Arts writes gray-scale TIFF files
00123      * without a PlanarConfiguration directory entry.
00124      * Thus we setup a default value here, even though
00125      * the TIFF spec says there is no default value.
00126      */
00127     TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
00128 
00129     /*
00130      * Sigh, we must make a separate pass through the
00131      * directory for the following reason:
00132      *
00133      * We must process the Compression tag in the first pass
00134      * in order to merge in codec-private tag definitions (otherwise
00135      * we may get complaints about unknown tags).  However, the
00136      * Compression tag may be dependent on the SamplesPerPixel
00137      * tag value because older TIFF specs permited Compression
00138      * to be written as a SamplesPerPixel-count tag entry.
00139      * Thus if we don't first figure out the correct SamplesPerPixel
00140      * tag value then we may end up ignoring the Compression tag
00141      * value because it has an incorrect count value (if the
00142      * true value of SamplesPerPixel is not 1).
00143      *
00144      * It sure would have been nice if Aldus had really thought
00145      * this stuff through carefully.
00146      */
00147     for (dp = dir, n = dircount; n > 0; n--, dp++) {
00148         if (tif->tif_flags & TIFF_SWAB) {
00149             TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
00150             TIFFSwabArrayOfLong(&dp->tdir_count, 2);
00151         }
00152         if (dp->tdir_tag == TIFFTAG_SAMPLESPERPIXEL) {
00153             if (!TIFFFetchNormalTag(tif, dp))
00154                 goto bad;
00155             dp->tdir_tag = IGNORE;
00156         }
00157     }
00158     /*
00159      * First real pass over the directory.
00160      */
00161     fix = 0;
00162     for (dp = dir, n = dircount; n > 0; n--, dp++) {
00163 
00164         if (dp->tdir_tag == IGNORE)
00165             continue;
00166         if (fix >= tif->tif_nfields)
00167             fix = 0;
00168 
00169         /*
00170          * Silicon Beach (at least) writes unordered
00171          * directory tags (violating the spec).  Handle
00172          * it here, but be obnoxious (maybe they'll fix it?).
00173          */
00174         if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) {
00175             if (!diroutoforderwarning) {
00176                 TIFFWarningExt(tif->tif_clientdata, module,
00177     "%s: invalid TIFF directory; tags are not sorted in ascending order",
00178                         tif->tif_name);
00179                 diroutoforderwarning = 1;
00180             }
00181             fix = 0;            /* O(n^2) */
00182         }
00183         while (fix < tif->tif_nfields &&
00184             tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
00185             fix++;
00186         if (fix >= tif->tif_nfields ||
00187             tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
00188             /* Unknown tag ... we'll deal with it below */
00189             haveunknowntags = 1;
00190             continue;
00191         }
00192         /*
00193          * Null out old tags that we ignore.
00194          */
00195         if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {
00196     ignore:
00197             dp->tdir_tag = IGNORE;
00198             continue;
00199         }
00200         /*
00201          * Check data type.
00202          */
00203         fip = tif->tif_fieldinfo[fix];
00204         while (dp->tdir_type != (unsigned short) fip->field_type
00205             && fix < tif->tif_nfields) {
00206             if (fip->field_type == TIFF_ANY)    /* wildcard */
00207                 break;
00208             fip = tif->tif_fieldinfo[++fix];
00209             if (fix >= tif->tif_nfields ||
00210                 fip->field_tag != dp->tdir_tag) {
00211                 TIFFWarningExt(tif->tif_clientdata, module,
00212             "%s: wrong data type %d for \"%s\"; tag ignored",
00213                         tif->tif_name, dp->tdir_type,
00214                         tif->tif_fieldinfo[fix-1]->field_name);
00215                 goto ignore;
00216             }
00217         }
00218         /*
00219          * Check count if known in advance.
00220          */
00221         if (fip->field_readcount != TIFF_VARIABLE
00222             && fip->field_readcount != TIFF_VARIABLE2) {
00223             uint32 expected = (fip->field_readcount == TIFF_SPP) ?
00224                 (uint32) td->td_samplesperpixel :
00225                 (uint32) fip->field_readcount;
00226             if (!CheckDirCount(tif, dp, expected))
00227                 goto ignore;
00228         }
00229 
00230         switch (dp->tdir_tag) {
00231         case TIFFTAG_COMPRESSION:
00232             /*
00233              * The 5.0 spec says the Compression tag has
00234              * one value, while earlier specs say it has
00235              * one value per sample.  Because of this, we
00236              * accept the tag if one value is supplied.
00237              */
00238             if (dp->tdir_count == 1) {
00239                 v = TIFFExtractData(tif,
00240                     dp->tdir_type, dp->tdir_offset);
00241                 if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v))
00242                     goto bad;
00243                 else
00244                     compressionknown = 1;
00245                 break;
00246             /* XXX: workaround for broken TIFFs */
00247             } else if (dp->tdir_type == TIFF_LONG) {
00248                 if (!TIFFFetchPerSampleLongs(tif, dp, &v) ||
00249                     !TIFFSetField(tif, dp->tdir_tag, (uint16)v))
00250                     goto bad;
00251             } else {
00252                 if (!TIFFFetchPerSampleShorts(tif, dp, &iv)
00253                     || !TIFFSetField(tif, dp->tdir_tag, iv))
00254                     goto bad;
00255             }
00256             dp->tdir_tag = IGNORE;
00257             break;
00258         case TIFFTAG_STRIPOFFSETS:
00259         case TIFFTAG_STRIPBYTECOUNTS:
00260         case TIFFTAG_TILEOFFSETS:
00261         case TIFFTAG_TILEBYTECOUNTS:
00262             TIFFSetFieldBit(tif, fip->field_bit);
00263             break;
00264         case TIFFTAG_IMAGEWIDTH:
00265         case TIFFTAG_IMAGELENGTH:
00266         case TIFFTAG_IMAGEDEPTH:
00267         case TIFFTAG_TILELENGTH:
00268         case TIFFTAG_TILEWIDTH:
00269         case TIFFTAG_TILEDEPTH:
00270         case TIFFTAG_PLANARCONFIG:
00271         case TIFFTAG_ROWSPERSTRIP:
00272         case TIFFTAG_EXTRASAMPLES:
00273             if (!TIFFFetchNormalTag(tif, dp))
00274                 goto bad;
00275             dp->tdir_tag = IGNORE;
00276             break;
00277         }
00278     }
00279 
00280     /*
00281      * If we saw any unknown tags, make an extra pass over the directory
00282      * to deal with them.  This must be done separately because the tags
00283      * could have become known when we registered a codec after finding
00284      * the Compression tag.  In a correctly-sorted directory there's
00285      * no problem because Compression will come before any codec-private
00286      * tags, but if the sorting is wrong that might not hold.
00287      */
00288     if (haveunknowntags) {
00289         fix = 0;
00290         for (dp = dir, n = dircount; n > 0; n--, dp++) {
00291         if (dp->tdir_tag == IGNORE)
00292             continue;
00293         if (fix >= tif->tif_nfields ||
00294             dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag)
00295             fix = 0;            /* O(n^2) */
00296         while (fix < tif->tif_nfields &&
00297             tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
00298             fix++;
00299         if (fix >= tif->tif_nfields ||
00300             tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
00301 
00302                     TIFFWarningExt(tif->tif_clientdata,
00303                                module,
00304                         "%s: unknown field with tag %d (0x%x) encountered",
00305                                tif->tif_name,
00306                                dp->tdir_tag,
00307                                dp->tdir_tag);
00308 
00309                     if (!_TIFFMergeFieldInfo(tif,
00310                         _TIFFCreateAnonFieldInfo(tif,
00311                         dp->tdir_tag,
00312                         (TIFFDataType) dp->tdir_type),
00313                         1))
00314                     {
00315                     TIFFWarningExt(tif->tif_clientdata,
00316                                module,
00317             "Registering anonymous field with tag %d (0x%x) failed",
00318                                dp->tdir_tag,
00319                                dp->tdir_tag);
00320                     dp->tdir_tag = IGNORE;
00321                     continue;
00322                     }
00323             fix = 0;
00324             while (fix < tif->tif_nfields &&
00325                    tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
00326                 fix++;
00327         }
00328         /*
00329          * Check data type.
00330          */
00331         fip = tif->tif_fieldinfo[fix];
00332         while (dp->tdir_type != (unsigned short) fip->field_type
00333             && fix < tif->tif_nfields) {
00334             if (fip->field_type == TIFF_ANY)    /* wildcard */
00335                 break;
00336             fip = tif->tif_fieldinfo[++fix];
00337             if (fix >= tif->tif_nfields ||
00338                 fip->field_tag != dp->tdir_tag) {
00339                 TIFFWarningExt(tif->tif_clientdata, module,
00340             "%s: wrong data type %d for \"%s\"; tag ignored",
00341                         tif->tif_name, dp->tdir_type,
00342                         tif->tif_fieldinfo[fix-1]->field_name);
00343                 dp->tdir_tag = IGNORE;
00344                 break;
00345             }
00346         }
00347         }
00348     }
00349 
00350     /*
00351      * XXX: OJPEG hack.
00352      * If a) compression is OJPEG, b) planarconfig tag says it's separate,
00353      * c) strip offsets/bytecounts tag are both present and
00354      * d) both contain exactly one value, then we consistently find
00355      * that the buggy implementation of the buggy compression scheme
00356      * matches contig planarconfig best. So we 'fix-up' the tag here
00357      */
00358     if ((td->td_compression==COMPRESSION_OJPEG) &&
00359         (td->td_planarconfig==PLANARCONFIG_SEPARATE)) {
00360         dp = TIFFReadDirectoryFind(dir,dircount,TIFFTAG_STRIPOFFSETS);
00361         if ((dp!=0) && (dp->tdir_count==1)) {
00362             dp = TIFFReadDirectoryFind(dir, dircount,
00363                            TIFFTAG_STRIPBYTECOUNTS);
00364             if ((dp!=0) && (dp->tdir_count==1)) {
00365                 td->td_planarconfig=PLANARCONFIG_CONTIG;
00366                 TIFFWarningExt(tif->tif_clientdata,
00367                            "TIFFReadDirectory",
00368                 "Planarconfig tag value assumed incorrect, "
00369                 "assuming data is contig instead of chunky");
00370             }
00371         }
00372     }
00373 
00374     /*
00375      * Allocate directory structure and setup defaults.
00376      */
00377     if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
00378         MissingRequired(tif, "ImageLength");
00379         goto bad;
00380     }
00381     /* 
00382      * Setup appropriate structures (by strip or by tile)
00383      */
00384     if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
00385         td->td_nstrips = TIFFNumberOfStrips(tif);
00386         td->td_tilewidth = td->td_imagewidth;
00387         td->td_tilelength = td->td_rowsperstrip;
00388         td->td_tiledepth = td->td_imagedepth;
00389         tif->tif_flags &= ~TIFF_ISTILED;
00390     } else {
00391         td->td_nstrips = TIFFNumberOfTiles(tif);
00392         tif->tif_flags |= TIFF_ISTILED;
00393     }
00394     if (!td->td_nstrips) {
00395         TIFFErrorExt(tif->tif_clientdata, module,
00396                  "%s: cannot handle zero number of %s",
00397                  tif->tif_name, isTiled(tif) ? "tiles" : "strips");
00398         goto bad;
00399     }
00400     td->td_stripsperimage = td->td_nstrips;
00401     if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
00402         td->td_stripsperimage /= td->td_samplesperpixel;
00403     if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
00404         if ((td->td_compression==COMPRESSION_OJPEG) &&
00405             (isTiled(tif)==0) &&
00406             (td->td_nstrips==1)) {
00407             /*
00408              * XXX: OJPEG hack.
00409              * If a) compression is OJPEG, b) it's not a tiled TIFF,
00410              * and c) the number of strips is 1,
00411              * then we tolerate the absence of stripoffsets tag,
00412              * because, presumably, all required data is in the
00413              * JpegInterchangeFormat stream.
00414              */
00415             TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
00416         } else {
00417             MissingRequired(tif,
00418                 isTiled(tif) ? "TileOffsets" : "StripOffsets");
00419             goto bad;
00420         }
00421     }
00422 
00423     /*
00424      * Second pass: extract other information.
00425      */
00426     for (dp = dir, n = dircount; n > 0; n--, dp++) {
00427         if (dp->tdir_tag == IGNORE)
00428             continue;
00429         switch (dp->tdir_tag) {
00430         case TIFFTAG_MINSAMPLEVALUE:
00431         case TIFFTAG_MAXSAMPLEVALUE:
00432         case TIFFTAG_BITSPERSAMPLE:
00433         case TIFFTAG_DATATYPE:
00434         case TIFFTAG_SAMPLEFORMAT:
00435             /*
00436              * The 5.0 spec says the Compression tag has
00437              * one value, while earlier specs say it has
00438              * one value per sample.  Because of this, we
00439              * accept the tag if one value is supplied.
00440              *
00441              * The MinSampleValue, MaxSampleValue, BitsPerSample
00442              * DataType and SampleFormat tags are supposed to be
00443              * written as one value/sample, but some vendors
00444              * incorrectly write one value only -- so we accept
00445              * that as well (yech). Other vendors write correct
00446              * value for NumberOfSamples, but incorrect one for
00447              * BitsPerSample and friends, and we will read this
00448              * too.
00449              */
00450             if (dp->tdir_count == 1) {
00451                 v = TIFFExtractData(tif,
00452                     dp->tdir_type, dp->tdir_offset);
00453                 if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v))
00454                     goto bad;
00455             /* XXX: workaround for broken TIFFs */
00456             } else if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE
00457                    && dp->tdir_type == TIFF_LONG) {
00458                 if (!TIFFFetchPerSampleLongs(tif, dp, &v) ||
00459                     !TIFFSetField(tif, dp->tdir_tag, (uint16)v))
00460                     goto bad;
00461             } else {
00462                 if (!TIFFFetchPerSampleShorts(tif, dp, &iv) ||
00463                     !TIFFSetField(tif, dp->tdir_tag, iv))
00464                     goto bad;
00465             }
00466             break;
00467         case TIFFTAG_SMINSAMPLEVALUE:
00468         case TIFFTAG_SMAXSAMPLEVALUE:
00469             {
00470                 double dv = 0.0;
00471                 if (!TIFFFetchPerSampleAnys(tif, dp, &dv) ||
00472                     !TIFFSetField(tif, dp->tdir_tag, dv))
00473                     goto bad;
00474             }
00475             break;
00476         case TIFFTAG_STRIPOFFSETS:
00477         case TIFFTAG_TILEOFFSETS:
00478             if (!TIFFFetchStripThing(tif, dp,
00479                 td->td_nstrips, &td->td_stripoffset))
00480                 goto bad;
00481             break;
00482         case TIFFTAG_STRIPBYTECOUNTS:
00483         case TIFFTAG_TILEBYTECOUNTS:
00484             if (!TIFFFetchStripThing(tif, dp,
00485                 td->td_nstrips, &td->td_stripbytecount))
00486                 goto bad;
00487             break;
00488         case TIFFTAG_COLORMAP:
00489         case TIFFTAG_TRANSFERFUNCTION:
00490             {
00491                 char* cp;
00492                 /*
00493                  * TransferFunction can have either 1x or 3x
00494                  * data values; Colormap can have only 3x
00495                  * items.
00496                  */
00497                 v = 1L<<td->td_bitspersample;
00498                 if (dp->tdir_tag == TIFFTAG_COLORMAP ||
00499                     dp->tdir_count != v) {
00500                     if (!CheckDirCount(tif, dp, 3 * v))
00501                         break;
00502                 }
00503                 v *= sizeof(uint16);
00504                 cp = (char *)_TIFFCheckMalloc(tif,
00505                                   dp->tdir_count,
00506                                   sizeof (uint16),
00507                     "to read \"TransferFunction\" tag");
00508                 if (cp != NULL) {
00509                     if (TIFFFetchData(tif, dp, cp)) {
00510                         /*
00511                          * This deals with there being
00512                          * only one array to apply to
00513                          * all samples.
00514                          */
00515                         uint32 c = 1L << td->td_bitspersample;
00516                         if (dp->tdir_count == c)
00517                             v = 0L;
00518                         TIFFSetField(tif, dp->tdir_tag,
00519                             cp, cp+v, cp+2*v);
00520                     }
00521                     _TIFFfree(cp);
00522                 }
00523                 break;
00524             }
00525         case TIFFTAG_PAGENUMBER:
00526         case TIFFTAG_HALFTONEHINTS:
00527         case TIFFTAG_YCBCRSUBSAMPLING:
00528         case TIFFTAG_DOTRANGE:
00529             (void) TIFFFetchShortPair(tif, dp);
00530             break;
00531         case TIFFTAG_REFERENCEBLACKWHITE:
00532             (void) TIFFFetchRefBlackWhite(tif, dp);
00533             break;
00534 /* BEGIN REV 4.0 COMPATIBILITY */
00535         case TIFFTAG_OSUBFILETYPE:
00536             v = 0L;
00537             switch (TIFFExtractData(tif, dp->tdir_type,
00538                 dp->tdir_offset)) {
00539             case OFILETYPE_REDUCEDIMAGE:
00540                 v = FILETYPE_REDUCEDIMAGE;
00541                 break;
00542             case OFILETYPE_PAGE:
00543                 v = FILETYPE_PAGE;
00544                 break;
00545             }
00546             if (v)
00547                 TIFFSetField(tif, TIFFTAG_SUBFILETYPE, v);
00548             break;
00549 /* END REV 4.0 COMPATIBILITY */
00550         default:
00551             (void) TIFFFetchNormalTag(tif, dp);
00552             break;
00553         }
00554     }
00555     /*
00556      * OJPEG hack:
00557      * - If a) compression is OJPEG, and b) photometric tag is missing,
00558      * then we consistently find that photometric should be YCbCr
00559      * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
00560      * then we consistently find that the buggy implementation of the
00561      * buggy compression scheme matches photometric YCbCr instead.
00562      * - If a) compression is OJPEG, and b) bitspersample tag is missing,
00563      * then we consistently find bitspersample should be 8.
00564      * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
00565      * and c) photometric is RGB or YCbCr, then we consistently find
00566      * samplesperpixel should be 3
00567      * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
00568      * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
00569      * find samplesperpixel should be 3
00570      */
00571     if (td->td_compression==COMPRESSION_OJPEG)
00572     {
00573         if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
00574         {
00575             TIFFWarningExt(tif->tif_clientdata, "TIFFReadDirectory",
00576             "Photometric tag is missing, assuming data is YCbCr");
00577             if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR))
00578                 goto bad;
00579         }
00580         else if (td->td_photometric==PHOTOMETRIC_RGB)
00581         {
00582             td->td_photometric=PHOTOMETRIC_YCBCR;
00583             TIFFWarningExt(tif->tif_clientdata, "TIFFReadDirectory",
00584             "Photometric tag value assumed incorrect, "
00585             "assuming data is YCbCr instead of RGB");
00586         }
00587         if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
00588         {
00589             TIFFWarningExt(tif->tif_clientdata,"TIFFReadDirectory",
00590         "BitsPerSample tag is missing, assuming 8 bits per sample");
00591             if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8))
00592                 goto bad;
00593         }
00594         if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
00595         {
00596             if ((td->td_photometric==PHOTOMETRIC_RGB)
00597                 || (td->td_photometric==PHOTOMETRIC_YCBCR))
00598             {
00599                 TIFFWarningExt(tif->tif_clientdata,
00600                            "TIFFReadDirectory",
00601                 "SamplesPerPixel tag is missing, "
00602                 "assuming correct SamplesPerPixel value is 3");
00603                 if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
00604                     goto bad;
00605             }
00606             else if ((td->td_photometric==PHOTOMETRIC_MINISWHITE)
00607                  || (td->td_photometric==PHOTOMETRIC_MINISBLACK))
00608             {
00609                 TIFFWarningExt(tif->tif_clientdata,
00610                            "TIFFReadDirectory",
00611                 "SamplesPerPixel tag is missing, "
00612                 "assuming correct SamplesPerPixel value is 1");
00613                 if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1))
00614                     goto bad;
00615             }
00616         }
00617     }
00618     /*
00619      * Verify Palette image has a Colormap.
00620      */
00621     if (td->td_photometric == PHOTOMETRIC_PALETTE &&
00622         !TIFFFieldSet(tif, FIELD_COLORMAP)) {
00623         MissingRequired(tif, "Colormap");
00624         goto bad;
00625     }
00626     /*
00627      * OJPEG hack:
00628      * We do no further messing with strip/tile offsets/bytecounts in OJPEG
00629      * TIFFs
00630      */
00631     if (td->td_compression!=COMPRESSION_OJPEG)
00632     {
00633         /*
00634          * Attempt to deal with a missing StripByteCounts tag.
00635          */
00636         if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
00637             /*
00638              * Some manufacturers violate the spec by not giving
00639              * the size of the strips.  In this case, assume there
00640              * is one uncompressed strip of data.
00641              */
00642             if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
00643                 td->td_nstrips > 1) ||
00644                 (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
00645                  td->td_nstrips != td->td_samplesperpixel)) {
00646                 MissingRequired(tif, "StripByteCounts");
00647                 goto bad;
00648             }
00649             TIFFWarningExt(tif->tif_clientdata, module,
00650                 "%s: TIFF directory is missing required "
00651                 "\"%s\" field, calculating from imagelength",
00652                 tif->tif_name,
00653                 _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
00654             if (EstimateStripByteCounts(tif, dir, dircount) < 0)
00655                 goto bad;
00656         /*
00657          * Assume we have wrong StripByteCount value (in case
00658          * of single strip) in following cases:
00659          *   - it is equal to zero along with StripOffset;
00660          *   - it is larger than file itself (in case of uncompressed
00661          *     image);
00662          *   - it is smaller than the size of the bytes per row
00663          *     multiplied on the number of rows.  The last case should
00664          *     not be checked in the case of writing new image,
00665          *     because we may do not know the exact strip size
00666          *     until the whole image will be written and directory
00667          *     dumped out.
00668          */
00669         #define BYTECOUNTLOOKSBAD \
00670             ( (td->td_stripbytecount[0] == 0 && td->td_stripoffset[0] != 0) || \
00671               (td->td_compression == COMPRESSION_NONE && \
00672                td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0]) || \
00673               (tif->tif_mode == O_RDONLY && \
00674                td->td_compression == COMPRESSION_NONE && \
00675                td->td_stripbytecount[0] < TIFFScanlineSize(tif) * td->td_imagelength) )
00676 
00677         } else if (td->td_nstrips == 1
00678                && td->td_stripoffset[0] != 0
00679                && BYTECOUNTLOOKSBAD) {
00680             /*
00681              * XXX: Plexus (and others) sometimes give a value of
00682              * zero for a tag when they don't know what the
00683              * correct value is!  Try and handle the simple case
00684              * of estimating the size of a one strip image.
00685              */
00686             TIFFWarningExt(tif->tif_clientdata, module,
00687     "%s: Bogus \"%s\" field, ignoring and calculating from imagelength",
00688                     tif->tif_name,
00689                     _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
00690             if(EstimateStripByteCounts(tif, dir, dircount) < 0)
00691                 goto bad;
00692         } else if (td->td_planarconfig == PLANARCONFIG_CONTIG
00693                && td->td_nstrips > 2
00694                && td->td_compression == COMPRESSION_NONE
00695                && td->td_stripbytecount[0] != td->td_stripbytecount[1]
00696                            && td->td_stripbytecount[0] != 0 
00697                            && td->td_stripbytecount[1] != 0 ) {
00698             /*
00699              * XXX: Some vendors fill StripByteCount array with 
00700                          * absolutely wrong values (it can be equal to 
00701                          * StripOffset array, for example). Catch this case 
00702                          * here.
00703              */
00704             TIFFWarningExt(tif->tif_clientdata, module,
00705     "%s: Wrong \"%s\" field, ignoring and calculating from imagelength",
00706                     tif->tif_name,
00707                     _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
00708             if (EstimateStripByteCounts(tif, dir, dircount) < 0)
00709                 goto bad;
00710         }
00711     }
00712     if (dir) {
00713         _TIFFfree((char *)dir);
00714         dir = NULL;
00715     }
00716     if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
00717         td->td_maxsamplevalue = (uint16)((1L<<td->td_bitspersample)-1);
00718     /*
00719      * Setup default compression scheme.
00720      */
00721 
00722     /*
00723      * XXX: We can optimize checking for the strip bounds using the sorted
00724      * bytecounts array. See also comments for TIFFAppendToStrip()
00725      * function in tif_write.c.
00726      */
00727     if (td->td_nstrips > 1) {
00728         tstrip_t strip;
00729 
00730         td->td_stripbytecountsorted = 1;
00731         for (strip = 1; strip < td->td_nstrips; strip++) {
00732             if (td->td_stripoffset[strip - 1] >
00733                 td->td_stripoffset[strip]) {
00734                 td->td_stripbytecountsorted = 0;
00735                 break;
00736             }
00737         }
00738     }
00739 
00740     if (!TIFFFieldSet(tif, FIELD_COMPRESSION))
00741         TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
00742     /*
00743      * Some manufacturers make life difficult by writing
00744      * large amounts of uncompressed data as a single strip.
00745      * This is contrary to the recommendations of the spec.
00746      * The following makes an attempt at breaking such images
00747      * into strips closer to the recommended 8k bytes.  A
00748      * side effect, however, is that the RowsPerStrip tag
00749      * value may be changed.
00750      */
00751     if (td->td_nstrips == 1 && td->td_compression == COMPRESSION_NONE &&
00752         (tif->tif_flags & (TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP)
00753         ChopUpSingleUncompressedStrip(tif);
00754 
00755     /*
00756      * Reinitialize i/o since we are starting on a new directory.
00757      */
00758     tif->tif_row = (uint32) -1;
00759     tif->tif_curstrip = (tstrip_t) -1;
00760     tif->tif_col = (uint32) -1;
00761     tif->tif_curtile = (ttile_t) -1;
00762     tif->tif_tilesize = (tsize_t) -1;
00763 
00764     tif->tif_scanlinesize = TIFFScanlineSize(tif);
00765     if (!tif->tif_scanlinesize) {
00766         TIFFErrorExt(tif->tif_clientdata, module,
00767                  "%s: cannot handle zero scanline size",
00768                  tif->tif_name);
00769         return (0);
00770     }
00771 
00772     if (isTiled(tif)) {
00773         tif->tif_tilesize = TIFFTileSize(tif);
00774         if (!tif->tif_tilesize) {
00775             TIFFErrorExt(tif->tif_clientdata, module,
00776                      "%s: cannot handle zero tile size",
00777                      tif->tif_name);
00778             return (0);
00779         }
00780     } else {
00781         if (!TIFFStripSize(tif)) {
00782             TIFFErrorExt(tif->tif_clientdata, module,
00783                      "%s: cannot handle zero strip size",
00784                      tif->tif_name);
00785             return (0);
00786         }
00787     }
00788     return (1);
00789 bad:
00790     if (dir)
00791         _TIFFfree(dir);
00792     return (0);
00793 }
00794 
00795 static TIFFDirEntry*
00796 TIFFReadDirectoryFind(TIFFDirEntry* dir, uint16 dircount, uint16 tagid)
00797 {
00798     TIFFDirEntry* m;
00799     uint16 n;
00800     for (m=dir, n=0; n<dircount; m++, n++)
00801     {
00802         if (m->tdir_tag==tagid)
00803             return(m);
00804     }
00805     return(0);
00806 }
00807 
00808 /*
00809  * Read custom directory from the arbitarry offset.
00810  * The code is very similar to TIFFReadDirectory().
00811  */
00812 int
00813 TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
00814             const TIFFFieldInfo info[], size_t n)
00815 {
00816     static const char module[] = "TIFFReadCustomDirectory";
00817 
00818     TIFFDirectory* td = &tif->tif_dir;
00819     TIFFDirEntry *dp, *dir = NULL;
00820     const TIFFFieldInfo* fip;
00821     size_t fix;
00822     uint16 i, dircount;
00823 
00824     _TIFFSetupFieldInfo(tif, info, n);
00825 
00826     dircount = TIFFFetchDirectory(tif, diroff, &dir, NULL);
00827     if (!dircount) {
00828         TIFFErrorExt(tif->tif_clientdata, module,
00829             "%s: Failed to read custom directory at offset %u",
00830                  tif->tif_name, diroff);
00831         return 0;
00832     }
00833 
00834     TIFFFreeDirectory(tif);
00835         _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
00836 
00837     fix = 0;
00838     for (dp = dir, i = dircount; i > 0; i--, dp++) {
00839         if (tif->tif_flags & TIFF_SWAB) {
00840             TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
00841             TIFFSwabArrayOfLong(&dp->tdir_count, 2);
00842         }
00843 
00844         if (fix >= tif->tif_nfields || dp->tdir_tag == IGNORE)
00845             continue;
00846 
00847         while (fix < tif->tif_nfields &&
00848                tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
00849             fix++;
00850 
00851         if (fix >= tif->tif_nfields ||
00852             tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
00853 
00854             TIFFWarningExt(tif->tif_clientdata, module,
00855                         "%s: unknown field with tag %d (0x%x) encountered",
00856                     tif->tif_name, dp->tdir_tag, dp->tdir_tag);
00857             if (!_TIFFMergeFieldInfo(tif,
00858                          _TIFFCreateAnonFieldInfo(tif,
00859                          dp->tdir_tag,
00860                          (TIFFDataType) dp->tdir_type),
00861                          1))
00862             {
00863                 TIFFWarningExt(tif->tif_clientdata, module,
00864             "Registering anonymous field with tag %d (0x%x) failed",
00865                         dp->tdir_tag, dp->tdir_tag);
00866                 goto ignore;
00867             }
00868 
00869             fix = 0;
00870             while (fix < tif->tif_nfields &&
00871                    tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
00872                 fix++;
00873         }
00874         /*
00875          * Null out old tags that we ignore.
00876          */
00877         if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {
00878     ignore:
00879             dp->tdir_tag = IGNORE;
00880             continue;
00881         }
00882         /*
00883          * Check data type.
00884          */
00885         fip = tif->tif_fieldinfo[fix];
00886         while (dp->tdir_type != (unsigned short) fip->field_type
00887                        && fix < tif->tif_nfields) {
00888             if (fip->field_type == TIFF_ANY)    /* wildcard */
00889                 break;
00890                         fip = tif->tif_fieldinfo[++fix];
00891             if (fix >= tif->tif_nfields ||
00892                 fip->field_tag != dp->tdir_tag) {
00893                 TIFFWarningExt(tif->tif_clientdata, module,
00894             "%s: wrong data type %d for \"%s\"; tag ignored",
00895                         tif->tif_name, dp->tdir_type,
00896                         tif->tif_fieldinfo[fix-1]->field_name);
00897                 goto ignore;
00898             }
00899         }
00900         /*
00901          * Check count if known in advance.
00902          */
00903         if (fip->field_readcount != TIFF_VARIABLE
00904             && fip->field_readcount != TIFF_VARIABLE2) {
00905             uint32 expected = (fip->field_readcount == TIFF_SPP) ?
00906                 (uint32) td->td_samplesperpixel :
00907                 (uint32) fip->field_readcount;
00908             if (!CheckDirCount(tif, dp, expected))
00909                 goto ignore;
00910         }
00911 
00912         /*
00913          * EXIF tags which need to be specifically processed.
00914          */
00915         switch (dp->tdir_tag) {
00916             case EXIFTAG_SUBJECTDISTANCE:
00917                 (void) TIFFFetchSubjectDistance(tif, dp);
00918                 break;
00919             default:
00920                 (void) TIFFFetchNormalTag(tif, dp);
00921                 break;
00922         }
00923     }
00924     
00925     if (dir)
00926         _TIFFfree(dir);
00927     return 1;
00928 }
00929 
00930 /*
00931  * EXIF is important special case of custom IFD, so we have a special
00932  * function to read it.
00933  */
00934 int
00935 TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
00936 {
00937     size_t exifFieldInfoCount;
00938     const TIFFFieldInfo *exifFieldInfo =
00939         _TIFFGetExifFieldInfo(&exifFieldInfoCount);
00940     return TIFFReadCustomDirectory(tif, diroff, exifFieldInfo,
00941                        exifFieldInfoCount);
00942 }
00943 
00944 static int
00945 EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
00946 {
00947     static const char module[] = "EstimateStripByteCounts";
00948 
00949     TIFFDirEntry *dp;
00950     TIFFDirectory *td = &tif->tif_dir;
00951     uint32 strip;
00952 
00953     if (td->td_stripbytecount)
00954         _TIFFfree(td->td_stripbytecount);
00955     td->td_stripbytecount = (uint32*)
00956         _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint32),
00957         "for \"StripByteCounts\" array");
00958         if( td->td_stripbytecount == NULL )
00959             return -1;
00960 
00961     if (td->td_compression != COMPRESSION_NONE) {
00962         uint32 space = (uint32)(sizeof (TIFFHeader)
00963             + sizeof (uint16)
00964             + (dircount * sizeof (TIFFDirEntry))
00965             + sizeof (uint32));
00966         toff_t filesize = TIFFGetFileSize(tif);
00967         uint16 n;
00968 
00969         /* calculate amount of space used by indirect values */
00970         for (dp = dir, n = dircount; n > 0; n--, dp++)
00971         {
00972             uint32 cc = TIFFDataWidth((TIFFDataType) dp->tdir_type);
00973             if (cc == 0) {
00974                 TIFFErrorExt(tif->tif_clientdata, module,
00975             "%s: Cannot determine size of unknown tag type %d",
00976                       tif->tif_name, dp->tdir_type);
00977                 return -1;
00978             }
00979             cc = cc * dp->tdir_count;
00980             if (cc > sizeof (uint32))
00981                 space += cc;
00982         }
00983         space = filesize - space;
00984         if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
00985             space /= td->td_samplesperpixel;
00986         for (strip = 0; strip < td->td_nstrips; strip++)
00987             td->td_stripbytecount[strip] = space;
00988         /*
00989          * This gross hack handles the case were the offset to
00990          * the last strip is past the place where we think the strip
00991          * should begin.  Since a strip of data must be contiguous,
00992          * it's safe to assume that we've overestimated the amount
00993          * of data in the strip and trim this number back accordingly.
00994          */ 
00995         strip--;
00996         if (((toff_t)(td->td_stripoffset[strip]+
00997                   td->td_stripbytecount[strip])) > filesize)
00998             td->td_stripbytecount[strip] =
00999                 filesize - td->td_stripoffset[strip];
01000     } else if (isTiled(tif)) {
01001         uint32 bytespertile = TIFFTileSize(tif);
01002 
01003         for (strip = 0; strip < td->td_nstrips; strip++)
01004                     td->td_stripbytecount[strip] = bytespertile;
01005     } else {
01006         uint32 rowbytes = TIFFScanlineSize(tif);
01007         uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
01008         for (strip = 0; strip < td->td_nstrips; strip++)
01009             td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
01010     }
01011     TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
01012     if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
01013         td->td_rowsperstrip = td->td_imagelength;
01014     return 1;
01015 }
01016 
01017 static void
01018 MissingRequired(TIFF* tif, const char* tagname)
01019 {
01020     static const char module[] = "MissingRequired";
01021 
01022     TIFFErrorExt(tif->tif_clientdata, module,
01023           "%s: TIFF directory is missing required \"%s\" field",
01024           tif->tif_name, tagname);
01025 }
01026 
01027 /*
01028  * Check the directory offset against the list of already seen directory
01029  * offsets. This is a trick to prevent IFD looping. The one can create TIFF
01030  * file with looped directory pointers. We will maintain a list of already
01031  * seen directories and check every IFD offset against that list.
01032  */
01033 static int
01034 TIFFCheckDirOffset(TIFF* tif, toff_t diroff)
01035 {
01036     uint16 n;
01037 
01038     if (diroff == 0)            /* no more directories */
01039         return 0;
01040 
01041     for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
01042         if (tif->tif_dirlist[n] == diroff)
01043             return 0;
01044     }
01045 
01046     tif->tif_dirnumber++;
01047 
01048     if (tif->tif_dirnumber > tif->tif_dirlistsize) {
01049         toff_t* new_dirlist;
01050 
01051         /*
01052          * XXX: Reduce memory allocation granularity of the dirlist
01053          * array.
01054          */
01055         new_dirlist = (toff_t *)_TIFFCheckRealloc(tif,
01056                               tif->tif_dirlist,
01057                               tif->tif_dirnumber,
01058                               2 * sizeof(toff_t),
01059                               "for IFD list");
01060         if (!new_dirlist)
01061             return 0;
01062         tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
01063         tif->tif_dirlist = new_dirlist;
01064     }
01065 
01066     tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff;
01067 
01068     return 1;
01069 }
01070 
01071 /*
01072  * Check the count field of a directory entry against a known value.  The
01073  * caller is expected to skip/ignore the tag if there is a mismatch.
01074  */
01075 static int
01076 CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
01077 {
01078     if (count > dir->tdir_count) {
01079         TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
01080     "incorrect count for field \"%s\" (%u, expecting %u); tag ignored",
01081             _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
01082             dir->tdir_count, count);
01083         return (0);
01084     } else if (count < dir->tdir_count) {
01085         TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
01086     "incorrect count for field \"%s\" (%u, expecting %u); tag trimmed",
01087             _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
01088             dir->tdir_count, count);
01089         return (1);
01090     }
01091     return (1);
01092 }
01093 
01094 /*
01095  * Read IFD structure from the specified offset. If the pointer to
01096  * nextdiroff variable has been specified, read it too. Function returns a
01097  * number of fields in the directory or 0 if failed.
01098  */
01099 static uint16
01100 TIFFFetchDirectory(TIFF* tif, toff_t diroff, TIFFDirEntry **pdir,
01101            toff_t *nextdiroff)
01102 {
01103     static const char module[] = "TIFFFetchDirectory";
01104 
01105     TIFFDirEntry *dir;
01106     uint16 dircount;
01107 
01108     assert(pdir);
01109 
01110     tif->tif_diroff = diroff;
01111     if (nextdiroff)
01112         *nextdiroff = 0;
01113     if (!isMapped(tif)) {
01114         if (!SeekOK(tif, tif->tif_diroff)) {
01115             TIFFErrorExt(tif->tif_clientdata, module,
01116                 "%s: Seek error accessing TIFF directory",
01117                 tif->tif_name);
01118             return 0;
01119         }
01120         if (!ReadOK(tif, &dircount, sizeof (uint16))) {
01121             TIFFErrorExt(tif->tif_clientdata, module,
01122                 "%s: Can not read TIFF directory count",
01123                 tif->tif_name);
01124             return 0;
01125         }
01126         if (tif->tif_flags & TIFF_SWAB)
01127             TIFFSwabShort(&dircount);
01128         dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
01129                         sizeof (TIFFDirEntry),
01130                         "to read TIFF directory");
01131         if (dir == NULL)
01132             return 0;
01133         if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) {
01134             TIFFErrorExt(tif->tif_clientdata, module,
01135                 "%.100s: Can not read TIFF directory",
01136                 tif->tif_name);
01137             _TIFFfree(dir);
01138             return 0;
01139         }
01140         /*
01141          * Read offset to next directory for sequential scans if
01142          * needed.
01143          */
01144         if (nextdiroff)
01145             (void) ReadOK(tif, nextdiroff, sizeof(uint32));
01146     } else {
01147         toff_t off = tif->tif_diroff;
01148 
01149         /*
01150          * Check for integer overflow when validating the dir_off,
01151          * otherwise a very high offset may cause an OOB read and
01152          * crash the client. Make two comparisons instead of
01153          *
01154          *  off + sizeof(uint16) > tif->tif_size
01155          *
01156          * to avoid overflow.
01157          */
01158         if (tif->tif_size < sizeof (uint16) ||
01159             off > tif->tif_size - sizeof(uint16)) {
01160             TIFFErrorExt(tif->tif_clientdata, module,
01161                 "%s: Can not read TIFF directory count",
01162                 tif->tif_name);
01163             return 0;
01164         } else {
01165             _TIFFmemcpy(&dircount, tif->tif_base + off,
01166                     sizeof(uint16));
01167         }
01168         off += sizeof (uint16);
01169         if (tif->tif_flags & TIFF_SWAB)
01170             TIFFSwabShort(&dircount);
01171         dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
01172                         sizeof(TIFFDirEntry),
01173                         "to read TIFF directory");
01174         if (dir == NULL)
01175             return 0;
01176         if (off + dircount * sizeof (TIFFDirEntry) > tif->tif_size) {
01177             TIFFErrorExt(tif->tif_clientdata, module,
01178                      "%s: Can not read TIFF directory",
01179                      tif->tif_name);
01180             _TIFFfree(dir);
01181             return 0;
01182         } else {
01183             _TIFFmemcpy(dir, tif->tif_base + off,
01184                     dircount * sizeof(TIFFDirEntry));
01185         }
01186         if (nextdiroff) {
01187             off += dircount * sizeof (TIFFDirEntry);
01188             if (off + sizeof (uint32) <= tif->tif_size) {
01189                 _TIFFmemcpy(nextdiroff, tif->tif_base + off,
01190                         sizeof (uint32));
01191             }
01192         }
01193     }
01194     if (nextdiroff && tif->tif_flags & TIFF_SWAB)
01195         TIFFSwabLong(nextdiroff);
01196     *pdir = dir;
01197     return dircount;
01198 }
01199 
01200 /*
01201  * Fetch a contiguous directory item.
01202  */
01203 static tsize_t
01204 TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp)
01205 {
01206     uint32 w = TIFFDataWidth((TIFFDataType) dir->tdir_type);
01207     /* 
01208      * FIXME: butecount should have tsize_t type, but for now libtiff
01209      * defines tsize_t as a signed 32-bit integer and we are losing
01210      * ability to read arrays larger than 2^31 bytes. So we are using
01211      * uint32 instead of tsize_t here.
01212      */
01213     uint32 cc = dir->tdir_count * w;
01214 
01215     /* Check for overflow. */
01216     if (!dir->tdir_count || !w || cc / w != dir->tdir_count)
01217         goto bad;
01218 
01219     if (!isMapped(tif)) {
01220         if (!SeekOK(tif, dir->tdir_offset))
01221             goto bad;
01222         if (!ReadOK(tif, cp, cc))
01223             goto bad;
01224     } else {
01225         /* Check for overflow. */
01226         if (dir->tdir_offset + cc < dir->tdir_offset
01227             || dir->tdir_offset + cc < cc
01228             || dir->tdir_offset + cc > tif->tif_size)
01229             goto bad;
01230         _TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc);
01231     }
01232     if (tif->tif_flags & TIFF_SWAB) {
01233         switch (dir->tdir_type) {
01234         case TIFF_SHORT:
01235         case TIFF_SSHORT:
01236             TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
01237             break;
01238         case TIFF_LONG:
01239         case TIFF_SLONG:
01240         case TIFF_FLOAT:
01241             TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
01242             break;
01243         case TIFF_RATIONAL:
01244         case TIFF_SRATIONAL:
01245             TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
01246             break;
01247         case TIFF_DOUBLE:
01248             TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
01249             break;
01250         }
01251     }
01252     return (cc);
01253 bad:
01254     TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
01255              "Error fetching data for field \"%s\"",
01256              _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
01257     return (tsize_t) 0;
01258 }
01259 
01260 /*
01261  * Fetch an ASCII item from the file.
01262  */
01263 static tsize_t
01264 TIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp)
01265 {
01266     if (dir->tdir_count <= 4) {
01267         uint32 l = dir->tdir_offset;
01268         if (tif->tif_flags & TIFF_SWAB)
01269             TIFFSwabLong(&l);
01270         _TIFFmemcpy(cp, &l, dir->tdir_count);
01271         return (1);
01272     }
01273     return (TIFFFetchData(tif, dir, cp));
01274 }
01275 
01276 /*
01277  * Convert numerator+denominator to float.
01278  */
01279 static int
01280 cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv)
01281 {
01282     if (denom == 0) {
01283         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
01284             "%s: Rational with zero denominator (num = %u)",
01285             _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num);
01286         return (0);
01287     } else {
01288         if (dir->tdir_type == TIFF_RATIONAL)
01289             *rv = ((float)num / (float)denom);
01290         else
01291             *rv = ((float)(int32)num / (float)(int32)denom);
01292         return (1);
01293     }
01294 }
01295 
01296 /*
01297  * Fetch a rational item from the file at offset off and return the value as a
01298  * floating point number.
01299  */
01300 static float
01301 TIFFFetchRational(TIFF* tif, TIFFDirEntry* dir)
01302 {
01303     uint32 l[2];
01304     float v;
01305 
01306     return (!TIFFFetchData(tif, dir, (char *)l) ||
01307         !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v);
01308 }
01309 
01310 /*
01311  * Fetch a single floating point value from the offset field and return it as
01312  * a native float.
01313  */
01314 static float
01315 TIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir)
01316 {
01317     float v;
01318     int32 l = TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset);
01319         _TIFFmemcpy(&v, &l, sizeof(float));
01320     TIFFCvtIEEEFloatToNative(tif, 1, &v);
01321     return (v);
01322 }
01323 
01324 /*
01325  * Fetch an array of BYTE or SBYTE values.
01326  */
01327 static int
01328 TIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint8* v)
01329 {
01330     if (dir->tdir_count <= 4) {
01331         /*
01332          * Extract data from offset field.
01333          */
01334         if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
01335         if (dir->tdir_type == TIFF_SBYTE)
01336                 switch (dir->tdir_count) {
01337                     case 4: v[3] = dir->tdir_offset & 0xff;
01338                     case 3: v[2] = (dir->tdir_offset >> 8) & 0xff;
01339                     case 2: v[1] = (dir->tdir_offset >> 16) & 0xff;
01340             case 1: v[0] = dir->tdir_offset >> 24;
01341                 }
01342         else
01343                 switch (dir->tdir_count) {
01344                     case 4: v[3] = dir->tdir_offset & 0xff;
01345                     case 3: v[2] = (dir->tdir_offset >> 8) & 0xff;
01346                     case 2: v[1] = (dir->tdir_offset >> 16) & 0xff;
01347             case 1: v[0] = dir->tdir_offset >> 24;
01348                 }
01349     } else {
01350         if (dir->tdir_type == TIFF_SBYTE)
01351                 switch (dir->tdir_count) {
01352                     case 4: v[3] = dir->tdir_offset >> 24;
01353                     case 3: v[2] = (dir->tdir_offset >> 16) & 0xff;
01354                     case 2: v[1] = (dir->tdir_offset >> 8) & 0xff;
01355                     case 1: v[0] = dir->tdir_offset & 0xff;
01356         }
01357         else
01358                 switch (dir->tdir_count) {
01359                     case 4: v[3] = dir->tdir_offset >> 24;
01360                     case 3: v[2] = (dir->tdir_offset >> 16) & 0xff;
01361                     case 2: v[1] = (dir->tdir_offset >> 8) & 0xff;
01362                     case 1: v[0] = dir->tdir_offset & 0xff;
01363         }
01364     }
01365         return (1);
01366     } else
01367         return (TIFFFetchData(tif, dir, (char*) v) != 0);   /* XXX */
01368 }
01369 
01370 /*
01371  * Fetch an array of SHORT or SSHORT values.
01372  */
01373 static int
01374 TIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
01375 {
01376     if (dir->tdir_count <= 2) {
01377         if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
01378             switch (dir->tdir_count) {
01379             case 2: v[1] = (uint16) (dir->tdir_offset & 0xffff);
01380             case 1: v[0] = (uint16) (dir->tdir_offset >> 16);
01381             }
01382         } else {
01383             switch (dir->tdir_count) {
01384             case 2: v[1] = (uint16) (dir->tdir_offset >> 16);
01385             case 1: v[0] = (uint16) (dir->tdir_offset & 0xffff);
01386             }
01387         }
01388         return (1);
01389     } else
01390         return (TIFFFetchData(tif, dir, (char *)v) != 0);
01391 }
01392 
01393 /*
01394  * Fetch a pair of SHORT or BYTE values. Some tags may have either BYTE
01395  * or SHORT type and this function works with both ones.
01396  */
01397 static int
01398 TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir)
01399 {
01400     /*
01401      * Prevent overflowing the v stack arrays below by performing a sanity
01402      * check on tdir_count, this should never be greater than two.
01403      */
01404     if (dir->tdir_count > 2) {
01405         TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
01406         "unexpected count for field \"%s\", %u, expected 2; ignored",
01407             _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
01408             dir->tdir_count);
01409         return 0;
01410     }
01411 
01412     switch (dir->tdir_type) {
01413         case TIFF_BYTE:
01414         case TIFF_SBYTE:
01415             {
01416             uint8 v[4];
01417             return TIFFFetchByteArray(tif, dir, v)
01418                 && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
01419             }
01420         case TIFF_SHORT:
01421         case TIFF_SSHORT:
01422             {
01423             uint16 v[2];
01424             return TIFFFetchShortArray(tif, dir, v)
01425                 && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
01426             }
01427         default:
01428             return 0;
01429     }
01430 }
01431 
01432 /*
01433  * Fetch an array of LONG or SLONG values.
01434  */
01435 static int
01436 TIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
01437 {
01438     if (dir->tdir_count == 1) {
01439         v[0] = dir->tdir_offset;
01440         return (1);
01441     } else
01442         return (TIFFFetchData(tif, dir, (char*) v) != 0);
01443 }
01444 
01445 /*
01446  * Fetch an array of RATIONAL or SRATIONAL values.
01447  */
01448 static int
01449 TIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
01450 {
01451     int ok = 0;
01452     uint32* l;
01453 
01454     l = (uint32*)_TIFFCheckMalloc(tif,
01455         dir->tdir_count, TIFFDataWidth((TIFFDataType) dir->tdir_type),
01456         "to fetch array of rationals");
01457     if (l) {
01458         if (TIFFFetchData(tif, dir, (char *)l)) {
01459             uint32 i;
01460             for (i = 0; i < dir->tdir_count; i++) {
01461                 ok = cvtRational(tif, dir,
01462                     l[2*i+0], l[2*i+1], &v[i]);
01463                 if (!ok)
01464                     break;
01465             }
01466         }
01467         _TIFFfree((char *)l);
01468     }
01469     return (ok);
01470 }
01471 
01472 /*
01473  * Fetch an array of FLOAT values.
01474  */
01475 static int
01476 TIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
01477 {
01478 
01479     if (dir->tdir_count == 1) {
01480             union
01481         {
01482           float  f;
01483           uint32 i;
01484         } float_union;
01485 
01486         float_union.i=dir->tdir_offset;
01487         v[0]=float_union.f;
01488         TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
01489         return (1);
01490     } else  if (TIFFFetchData(tif, dir, (char*) v)) {
01491         TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
01492         return (1);
01493     } else
01494         return (0);
01495 }
01496 
01497 /*
01498  * Fetch an array of DOUBLE values.
01499  */
01500 static int
01501 TIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
01502 {
01503     if (TIFFFetchData(tif, dir, (char*) v)) {
01504         TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v);
01505         return (1);
01506     } else
01507         return (0);
01508 }
01509 
01510 /*
01511  * Fetch an array of ANY values.  The actual values are returned as doubles
01512  * which should be able hold all the types.  Yes, there really should be an
01513  * tany_t to avoid this potential non-portability ...  Note in particular that
01514  * we assume that the double return value vector is large enough to read in
01515  * any fundamental type.  We use that vector as a buffer to read in the base
01516  * type vector and then convert it in place to double (from end to front of
01517  * course).
01518  */
01519 static int
01520 TIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v)
01521 {
01522     int i;
01523 
01524     switch (dir->tdir_type) {
01525     case TIFF_BYTE:
01526     case TIFF_SBYTE:
01527         if (!TIFFFetchByteArray(tif, dir, (uint8*) v))
01528             return (0);
01529         if (dir->tdir_type == TIFF_BYTE) {
01530             uint8* vp = (uint8*) v;
01531             for (i = dir->tdir_count-1; i >= 0; i--)
01532                 v[i] = vp[i];
01533         } else {
01534             int8* vp = (int8*) v;
01535             for (i = dir->tdir_count-1; i >= 0; i--)
01536                 v[i] = vp[i];
01537         }
01538         break;
01539     case TIFF_SHORT:
01540     case TIFF_SSHORT:
01541         if (!TIFFFetchShortArray(tif, dir, (uint16*) v))
01542             return (0);
01543         if (dir->tdir_type == TIFF_SHORT) {
01544             uint16* vp = (uint16*) v;
01545             for (i = dir->tdir_count-1; i >= 0; i--)
01546                 v[i] = vp[i];
01547         } else {
01548             int16* vp = (int16*) v;
01549             for (i = dir->tdir_count-1; i >= 0; i--)
01550                 v[i] = vp[i];
01551         }
01552         break;
01553     case TIFF_LONG:
01554     case TIFF_SLONG:
01555         if (!TIFFFetchLongArray(tif, dir, (uint32*) v))
01556             return (0);
01557         if (dir->tdir_type == TIFF_LONG) {
01558             uint32* vp = (uint32*) v;
01559             for (i = dir->tdir_count-1; i >= 0; i--)
01560                 v[i] = vp[i];
01561         } else {
01562             int32* vp = (int32*) v;
01563             for (i = dir->tdir_count-1; i >= 0; i--)
01564                 v[i] = vp[i];
01565         }
01566         break;
01567     case TIFF_RATIONAL:
01568     case TIFF_SRATIONAL:
01569         if (!TIFFFetchRationalArray(tif, dir, (float*) v))
01570             return (0);
01571         { float* vp = (float*) v;
01572           for (i = dir->tdir_count-1; i >= 0; i--)
01573             v[i] = vp[i];
01574         }
01575         break;
01576     case TIFF_FLOAT:
01577         if (!TIFFFetchFloatArray(tif, dir, (float*) v))
01578             return (0);
01579         { float* vp = (float*) v;
01580           for (i = dir->tdir_count-1; i >= 0; i--)
01581             v[i] = vp[i];
01582         }
01583         break;
01584     case TIFF_DOUBLE:
01585         return (TIFFFetchDoubleArray(tif, dir, (double*) v));
01586     default:
01587         /* TIFF_NOTYPE */
01588         /* TIFF_ASCII */
01589         /* TIFF_UNDEFINED */
01590         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
01591                  "cannot read TIFF_ANY type %d for field \"%s\"",
01592                  dir->tdir_type,
01593                  _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
01594         return (0);
01595     }
01596     return (1);
01597 }
01598 
01599 /*
01600  * Fetch a tag that is not handled by special case code.
01601  */
01602 static int
01603 TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp)
01604 {
01605     static const char mesg[] = "to fetch tag value";
01606     int ok = 0;
01607     const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag);
01608 
01609     if (dp->tdir_count > 1) {       /* array of values */
01610         char* cp = NULL;
01611 
01612         switch (dp->tdir_type) {
01613         case TIFF_BYTE:
01614         case TIFF_SBYTE:
01615             cp = (char *)_TIFFCheckMalloc(tif,
01616                 dp->tdir_count, sizeof (uint8), mesg);
01617             ok = cp && TIFFFetchByteArray(tif, dp, (uint8*) cp);
01618             break;
01619         case TIFF_SHORT:
01620         case TIFF_SSHORT:
01621             cp = (char *)_TIFFCheckMalloc(tif,
01622                 dp->tdir_count, sizeof (uint16), mesg);
01623             ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp);
01624             break;
01625         case TIFF_LONG:
01626         case TIFF_SLONG:
01627             cp = (char *)_TIFFCheckMalloc(tif,
01628                 dp->tdir_count, sizeof (uint32), mesg);
01629             ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp);
01630             break;
01631         case TIFF_RATIONAL:
01632         case TIFF_SRATIONAL:
01633             cp = (char *)_TIFFCheckMalloc(tif,
01634                 dp->tdir_count, sizeof (float), mesg);
01635             ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp);
01636             break;
01637         case TIFF_FLOAT:
01638             cp = (char *)_TIFFCheckMalloc(tif,
01639                 dp->tdir_count, sizeof (float), mesg);
01640             ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp);
01641             break;
01642         case TIFF_DOUBLE:
01643             cp = (char *)_TIFFCheckMalloc(tif,
01644                 dp->tdir_count, sizeof (double), mesg);
01645             ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp);
01646             break;
01647         case TIFF_ASCII:
01648         case TIFF_UNDEFINED:        /* bit of a cheat... */
01649             /*
01650              * Some vendors write strings w/o the trailing
01651              * NULL byte, so always append one just in case.
01652              */
01653             cp = (char *)_TIFFCheckMalloc(tif, dp->tdir_count + 1,
01654                               1, mesg);
01655             if( (ok = (cp && TIFFFetchString(tif, dp, cp))) != 0 )
01656                 cp[dp->tdir_count] = '\0';  /* XXX */
01657             break;
01658         }
01659         if (ok) {
01660             ok = (fip->field_passcount ?
01661                 TIFFSetField(tif, dp->tdir_tag, dp->tdir_count, cp)
01662               : TIFFSetField(tif, dp->tdir_tag, cp));
01663         }
01664         if (cp != NULL)
01665             _TIFFfree(cp);
01666     } else if (CheckDirCount(tif, dp, 1)) { /* singleton value */
01667         switch (dp->tdir_type) {
01668         case TIFF_BYTE:
01669         case TIFF_SBYTE:
01670         case TIFF_SHORT:
01671         case TIFF_SSHORT:
01672             /*
01673              * If the tag is also acceptable as a LONG or SLONG
01674              * then TIFFSetField will expect an uint32 parameter
01675              * passed to it (through varargs).  Thus, for machines
01676              * where sizeof (int) != sizeof (uint32) we must do
01677              * a careful check here.  It's hard to say if this
01678              * is worth optimizing.
01679              *
01680              * NB: We use TIFFFieldWithTag here knowing that
01681              *     it returns us the first entry in the table
01682              *     for the tag and that that entry is for the
01683              *     widest potential data type the tag may have.
01684              */
01685             { TIFFDataType type = fip->field_type;
01686               if (type != TIFF_LONG && type != TIFF_SLONG) {
01687                 uint16 v = (uint16)
01688                TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
01689                 ok = (fip->field_passcount ?
01690                     TIFFSetField(tif, dp->tdir_tag, 1, &v)
01691                   : TIFFSetField(tif, dp->tdir_tag, v));
01692                 break;
01693               }
01694             }
01695             /* fall thru... */
01696         case TIFF_LONG:
01697         case TIFF_SLONG:
01698             { uint32 v32 =
01699             TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
01700               ok = (fip->field_passcount ? 
01701                   TIFFSetField(tif, dp->tdir_tag, 1, &v32)
01702                 : TIFFSetField(tif, dp->tdir_tag, v32));
01703             }
01704             break;
01705         case TIFF_RATIONAL:
01706         case TIFF_SRATIONAL:
01707         case TIFF_FLOAT:
01708             { float v = (dp->tdir_type == TIFF_FLOAT ? 
01709                   TIFFFetchFloat(tif, dp)
01710                 : TIFFFetchRational(tif, dp));
01711               ok = (fip->field_passcount ?
01712                   TIFFSetField(tif, dp->tdir_tag, 1, &v)
01713                 : TIFFSetField(tif, dp->tdir_tag, v));
01714             }
01715             break;
01716         case TIFF_DOUBLE:
01717             { double v;
01718               ok = (TIFFFetchDoubleArray(tif, dp, &v) &&
01719                 (fip->field_passcount ?
01720                   TIFFSetField(tif, dp->tdir_tag, 1, &v)
01721                 : TIFFSetField(tif, dp->tdir_tag, v))
01722               );
01723             }
01724             break;
01725         case TIFF_ASCII:
01726         case TIFF_UNDEFINED:        /* bit of a cheat... */
01727             { char c[2];
01728               if( (ok = (TIFFFetchString(tif, dp, c) != 0)) != 0 ) {
01729                 c[1] = '\0';        /* XXX paranoid */
01730                 ok = (fip->field_passcount ?
01731                     TIFFSetField(tif, dp->tdir_tag, 1, c)
01732                       : TIFFSetField(tif, dp->tdir_tag, c));
01733               }
01734             }
01735             break;
01736         }
01737     }
01738     return (ok);
01739 }
01740 
01741 #define NITEMS(x)   (sizeof (x) / sizeof (x[0]))
01742 /*
01743  * Fetch samples/pixel short values for 
01744  * the specified tag and verify that
01745  * all values are the same.
01746  */
01747 static int
01748 TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, uint16* pl)
01749 {
01750     uint16 samples = tif->tif_dir.td_samplesperpixel;
01751     int status = 0;
01752 
01753     if (CheckDirCount(tif, dir, (uint32) samples)) {
01754         uint16 buf[10];
01755         uint16* v = buf;
01756 
01757         if (dir->tdir_count > NITEMS(buf))
01758             v = (uint16*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof(uint16),
01759                                       "to fetch per-sample values");
01760         if (v && TIFFFetchShortArray(tif, dir, v)) {
01761             uint16 i;
01762             int check_count = dir->tdir_count;
01763             if( samples < check_count )
01764                 check_count = samples;
01765 
01766             for (i = 1; i < check_count; i++)
01767                 if (v[i] != v[0]) {
01768             TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
01769                 "Cannot handle different per-sample values for field \"%s\"",
01770             _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
01771             goto bad;
01772                 }
01773             *pl = v[0];
01774             status = 1;
01775         }
01776       bad:
01777         if (v && v != buf)
01778             _TIFFfree(v);
01779     }
01780     return (status);
01781 }
01782 
01783 /*
01784  * Fetch samples/pixel long values for 
01785  * the specified tag and verify that
01786  * all values are the same.
01787  */
01788 static int
01789 TIFFFetchPerSampleLongs(TIFF* tif, TIFFDirEntry* dir, uint32* pl)
01790 {
01791     uint16 samples = tif->tif_dir.td_samplesperpixel;
01792     int status = 0;
01793 
01794     if (CheckDirCount(tif, dir, (uint32) samples)) {
01795         uint32 buf[10];
01796         uint32* v = buf;
01797 
01798         if (dir->tdir_count > NITEMS(buf))
01799             v = (uint32*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof(uint32),
01800                                       "to fetch per-sample values");
01801         if (v && TIFFFetchLongArray(tif, dir, v)) {
01802             uint16 i;
01803             int check_count = dir->tdir_count;
01804 
01805             if( samples < check_count )
01806                 check_count = samples;
01807             for (i = 1; i < check_count; i++)
01808                 if (v[i] != v[0]) {
01809             TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
01810                 "Cannot handle different per-sample values for field \"%s\"",
01811             _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
01812             goto bad;
01813                 }
01814             *pl = v[0];
01815             status = 1;
01816         }
01817       bad:
01818         if (v && v != buf)
01819             _TIFFfree(v);
01820     }
01821     return (status);
01822 }
01823 
01824 /*
01825  * Fetch samples/pixel ANY values for the specified tag and verify that all
01826  * values are the same.
01827  */
01828 static int
01829 TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl)
01830 {
01831     uint16 samples = tif->tif_dir.td_samplesperpixel;
01832     int status = 0;
01833 
01834     if (CheckDirCount(tif, dir, (uint32) samples)) {
01835         double buf[10];
01836         double* v = buf;
01837 
01838         if (dir->tdir_count > NITEMS(buf))
01839             v = (double*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof (double),
01840                                       "to fetch per-sample values");
01841         if (v && TIFFFetchAnyArray(tif, dir, v)) {
01842             uint16 i;
01843             int check_count = dir->tdir_count;
01844             if( samples < check_count )
01845                 check_count = samples;
01846 
01847             for (i = 1; i < check_count; i++)
01848                 if (v[i] != v[0]) {
01849             TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
01850         "Cannot handle different per-sample values for field \"%s\"",
01851             _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
01852             goto bad;
01853                 }
01854             *pl = v[0];
01855             status = 1;
01856         }
01857       bad:
01858         if (v && v != buf)
01859             _TIFFfree(v);
01860     }
01861     return (status);
01862 }
01863 #undef NITEMS
01864 
01865 /*
01866  * Fetch a set of offsets or lengths.
01867  * While this routine says "strips", in fact it's also used for tiles.
01868  */
01869 static int
01870 TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, long nstrips, uint32** lpp)
01871 {
01872     register uint32* lp;
01873     int status;
01874 
01875         CheckDirCount(tif, dir, (uint32) nstrips);
01876 
01877     /*
01878      * Allocate space for strip information.
01879      */
01880     if (*lpp == NULL &&
01881         (*lpp = (uint32 *)_TIFFCheckMalloc(tif,
01882           nstrips, sizeof (uint32), "for strip array")) == NULL)
01883         return (0);
01884     lp = *lpp;
01885         _TIFFmemset( lp, 0, sizeof(uint32) * nstrips );
01886 
01887     if (dir->tdir_type == (int)TIFF_SHORT) {
01888         /*
01889          * Handle uint16->uint32 expansion.
01890          */
01891         uint16* dp = (uint16*) _TIFFCheckMalloc(tif,
01892             dir->tdir_count, sizeof (uint16), "to fetch strip tag");
01893         if (dp == NULL)
01894             return (0);
01895         if( (status = TIFFFetchShortArray(tif, dir, dp)) != 0 ) {
01896                     int i;
01897                     
01898                     for( i = 0; i < nstrips && i < (int) dir->tdir_count; i++ )
01899                     {
01900                         lp[i] = dp[i];
01901                     }
01902         }
01903         _TIFFfree((char*) dp);
01904 
01905         } else if( nstrips != (int) dir->tdir_count ) {
01906             /* Special case to correct length */
01907 
01908             uint32* dp = (uint32*) _TIFFCheckMalloc(tif,
01909             dir->tdir_count, sizeof (uint32), "to fetch strip tag");
01910             if (dp == NULL)
01911                 return (0);
01912 
01913             status = TIFFFetchLongArray(tif, dir, dp);
01914             if( status != 0 ) {
01915                 int i;
01916 
01917                 for( i = 0; i < nstrips && i < (int) dir->tdir_count; i++ )
01918                 {
01919                     lp[i] = dp[i];
01920                 }
01921             }
01922 
01923             _TIFFfree( (char *) dp );
01924     } else
01925             status = TIFFFetchLongArray(tif, dir, lp);
01926         
01927     return (status);
01928 }
01929 
01930 /*
01931  * Fetch and set the RefBlackWhite tag.
01932  */
01933 static int
01934 TIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir)
01935 {
01936     static const char mesg[] = "for \"ReferenceBlackWhite\" array";
01937     char* cp;
01938     int ok;
01939 
01940     if (dir->tdir_type == TIFF_RATIONAL)
01941         return (TIFFFetchNormalTag(tif, dir));
01942     /*
01943      * Handle LONG's for backward compatibility.
01944      */
01945     cp = (char *)_TIFFCheckMalloc(tif, dir->tdir_count,
01946                       sizeof (uint32), mesg);
01947     if( (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) != 0) {
01948         float* fp = (float*)
01949             _TIFFCheckMalloc(tif, dir->tdir_count, sizeof (float), mesg);
01950         if( (ok = (fp != NULL)) != 0 ) {
01951             uint32 i;
01952             for (i = 0; i < dir->tdir_count; i++)
01953                 fp[i] = (float)((uint32*) cp)[i];
01954             ok = TIFFSetField(tif, dir->tdir_tag, fp);
01955             _TIFFfree((char*) fp);
01956         }
01957     }
01958     if (cp)
01959         _TIFFfree(cp);
01960     return (ok);
01961 }
01962 
01963 /*
01964  * Fetch and set the SubjectDistance EXIF tag.
01965  */
01966 static int
01967 TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
01968 {
01969     uint32 l[2];
01970     float v;
01971     int ok = 0;
01972 
01973     if( dir->tdir_count != 1 || dir->tdir_type != TIFF_RATIONAL )
01974     {
01975         TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
01976                        "incorrect count or type for SubjectDistance, tag ignored" );
01977         return (0);
01978     }
01979 
01980     if (TIFFFetchData(tif, dir, (char *)l)
01981         && cvtRational(tif, dir, l[0], l[1], &v)) {
01982         /*
01983          * XXX: Numerator 0xFFFFFFFF means that we have infinite
01984          * distance. Indicate that with a negative floating point
01985          * SubjectDistance value.
01986          */
01987         ok = TIFFSetField(tif, dir->tdir_tag,
01988                   (l[0] != 0xFFFFFFFF) ? v : -v);
01989     }
01990 
01991     return ok;
01992 }
01993 
01994 /*
01995  * Replace a single strip (tile) of uncompressed data by multiple strips
01996  * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
01997  * dealing with large images or for dealing with machines with a limited
01998  * amount memory.
01999  */
02000 static void
02001 ChopUpSingleUncompressedStrip(TIFF* tif)
02002 {
02003     register TIFFDirectory *td = &tif->tif_dir;
02004     uint32 bytecount = td->td_stripbytecount[0];
02005     uint32 offset = td->td_stripoffset[0];
02006     tsize_t rowbytes = TIFFVTileSize(tif, 1), stripbytes;
02007     tstrip_t strip, nstrips, rowsperstrip;
02008     uint32* newcounts;
02009     uint32* newoffsets;
02010 
02011     /*
02012      * Make the rows hold at least one scanline, but fill specified amount
02013      * of data if possible.
02014      */
02015     if (rowbytes > STRIP_SIZE_DEFAULT) {
02016         stripbytes = rowbytes;
02017         rowsperstrip = 1;
02018     } else if (rowbytes > 0 ) {
02019         rowsperstrip = STRIP_SIZE_DEFAULT / rowbytes;
02020         stripbytes = rowbytes * rowsperstrip;
02021     }
02022         else
02023             return;
02024 
02025     /* 
02026      * never increase the number of strips in an image
02027      */
02028     if (rowsperstrip >= td->td_rowsperstrip)
02029         return;
02030     nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes);
02031         if( nstrips == 0 ) /* something is wonky, do nothing. */
02032             return;
02033 
02034     newcounts = (uint32*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint32),
02035                 "for chopped \"StripByteCounts\" array");
02036     newoffsets = (uint32*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint32),
02037                 "for chopped \"StripOffsets\" array");
02038     if (newcounts == NULL || newoffsets == NULL) {
02039             /*
02040          * Unable to allocate new strip information, give up and use
02041          * the original one strip information.
02042          */
02043         if (newcounts != NULL)
02044             _TIFFfree(newcounts);
02045         if (newoffsets != NULL)
02046             _TIFFfree(newoffsets);
02047         return;
02048     }
02049     /*
02050      * Fill the strip information arrays with new bytecounts and offsets
02051      * that reflect the broken-up format.
02052      */
02053     for (strip = 0; strip < nstrips; strip++) {
02054         if ((uint32)stripbytes > bytecount)
02055             stripbytes = bytecount;
02056         newcounts[strip] = stripbytes;
02057         newoffsets[strip] = offset;
02058         offset += stripbytes;
02059         bytecount -= stripbytes;
02060     }
02061     /*
02062      * Replace old single strip info with multi-strip info.
02063      */
02064     td->td_stripsperimage = td->td_nstrips = nstrips;
02065     TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
02066 
02067     _TIFFfree(td->td_stripbytecount);
02068     _TIFFfree(td->td_stripoffset);
02069     td->td_stripbytecount = newcounts;
02070     td->td_stripoffset = newoffsets;
02071     td->td_stripbytecountsorted = 1;
02072 }
02073 
02074 /* vim: set ts=8 sts=8 sw=8 noet: */
02075 /*
02076  * Local Variables:
02077  * mode: c
02078  * c-basic-offset: 8
02079  * fill-column: 78
02080  * End:
02081  */

Generated on Mon May 28 2012 04:19:21 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.