Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentif_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
1.7.6.1
|