| OLD | NEW |
| (Empty) |
| 1 /* $Id: tif_dir.c,v 1.113 2012-06-14 20:32:53 fwarmerdam Exp $ */ | |
| 2 | |
| 3 /* | |
| 4 * Copyright (c) 1988-1997 Sam Leffler | |
| 5 * Copyright (c) 1991-1997 Silicon Graphics, Inc. | |
| 6 * | |
| 7 * Permission to use, copy, modify, distribute, and sell this software and | |
| 8 * its documentation for any purpose is hereby granted without fee, provided | |
| 9 * that (i) the above copyright notices and this permission notice appear in | |
| 10 * all copies of the software and related documentation, and (ii) the names of | |
| 11 * Sam Leffler and Silicon Graphics may not be used in any advertising or | |
| 12 * publicity relating to the software without the specific, prior written | |
| 13 * permission of Sam Leffler and Silicon Graphics. | |
| 14 * | |
| 15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | |
| 16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | |
| 17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |
| 18 * | |
| 19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR | |
| 20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | |
| 21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
| 22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | |
| 23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
| 24 * OF THIS SOFTWARE. | |
| 25 */ | |
| 26 | |
| 27 /* | |
| 28 * TIFF Library. | |
| 29 * | |
| 30 * Directory Tag Get & Set Routines. | |
| 31 * (and also some miscellaneous stuff) | |
| 32 */ | |
| 33 #include "tiffiop.h" | |
| 34 | |
| 35 /* | |
| 36 * These are used in the backwards compatibility code... | |
| 37 */ | |
| 38 #define DATATYPE_VOID 0 /* !untyped data */ | |
| 39 #define DATATYPE_INT 1 /* !signed integer data */ | |
| 40 #define DATATYPE_UINT 2 /* !unsigned integer data */ | |
| 41 #define DATATYPE_IEEEFP 3 /* !IEEE floating point data */ | |
| 42 | |
| 43 static void | |
| 44 setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) | |
| 45 { | |
| 46 if (*vpp) | |
| 47 _TIFFfree(*vpp), *vpp = 0; | |
| 48 if (vp) { | |
| 49 tmsize_t bytes = (tmsize_t)(nmemb * elem_size); | |
| 50 if (elem_size && bytes / elem_size == nmemb) | |
| 51 *vpp = (void*) _TIFFmalloc(bytes); | |
| 52 if (*vpp) | |
| 53 _TIFFmemcpy(*vpp, vp, bytes); | |
| 54 } | |
| 55 } | |
| 56 void _TIFFsetByteArray(void** vpp, void* vp, uint32 n) | |
| 57 { setByteArray(vpp, vp, n, 1); } | |
| 58 void _TIFFsetString(char** cpp, char* cp) | |
| 59 { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); } | |
| 60 void _TIFFsetNString(char** cpp, char* cp, uint32 n) | |
| 61 { setByteArray((void**) cpp, (void*) cp, n, 1); } | |
| 62 void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n) | |
| 63 { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); } | |
| 64 void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n) | |
| 65 { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); } | |
| 66 void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n) | |
| 67 { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); } | |
| 68 void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n) | |
| 69 { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); } | |
| 70 void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n) | |
| 71 { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); } | |
| 72 | |
| 73 static void | |
| 74 setDoubleArrayOneValue(double** vpp, double value, size_t nmemb) | |
| 75 { | |
| 76 if (*vpp) | |
| 77 _TIFFfree(*vpp); | |
| 78 *vpp = _TIFFmalloc(nmemb*sizeof(double)); | |
| 79 if (*vpp) | |
| 80 { | |
| 81 while (nmemb--) | |
| 82 ((double*)*vpp)[nmemb] = value; | |
| 83 } | |
| 84 } | |
| 85 | |
| 86 /* | |
| 87 * Install extra samples information. | |
| 88 */ | |
| 89 static int | |
| 90 setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v) | |
| 91 { | |
| 92 /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */ | |
| 93 #define EXTRASAMPLE_COREL_UNASSALPHA 999 | |
| 94 | |
| 95 uint16* va; | |
| 96 uint32 i; | |
| 97 | |
| 98 *v = (uint16) va_arg(ap, uint16_vap); | |
| 99 if ((uint16) *v > td->td_samplesperpixel) | |
| 100 return 0; | |
| 101 va = va_arg(ap, uint16*); | |
| 102 if (*v > 0 && va == NULL) /* typically missing param */ | |
| 103 return 0; | |
| 104 for (i = 0; i < *v; i++) { | |
| 105 if (va[i] > EXTRASAMPLE_UNASSALPHA) { | |
| 106 /* | |
| 107 * XXX: Corel Draw is known to produce incorrect | |
| 108 * ExtraSamples tags which must be patched here if we | |
| 109 * want to be able to open some of the damaged TIFF | |
| 110 * files: | |
| 111 */ | |
| 112 if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA) | |
| 113 va[i] = EXTRASAMPLE_UNASSALPHA; | |
| 114 else | |
| 115 return 0; | |
| 116 } | |
| 117 } | |
| 118 td->td_extrasamples = (uint16) *v; | |
| 119 _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples); | |
| 120 return 1; | |
| 121 | |
| 122 #undef EXTRASAMPLE_COREL_UNASSALPHA | |
| 123 } | |
| 124 | |
| 125 /* | |
| 126 * Confirm we have "samplesperpixel" ink names separated by \0. Returns | |
| 127 * zero if the ink names are not as expected. | |
| 128 */ | |
| 129 static uint32 | |
| 130 checkInkNamesString(TIFF* tif, uint32 slen, const char* s) | |
| 131 { | |
| 132 TIFFDirectory* td = &tif->tif_dir; | |
| 133 uint16 i = td->td_samplesperpixel; | |
| 134 | |
| 135 if (slen > 0) { | |
| 136 const char* ep = s+slen; | |
| 137 const char* cp = s; | |
| 138 for (; i > 0; i--) { | |
| 139 for (; cp < ep && *cp != '\0'; cp++) {} | |
| 140 if (cp >= ep) | |
| 141 goto bad; | |
| 142 cp++; /* skip \0 */ | |
| 143 } | |
| 144 return ((uint32)(cp-s)); | |
| 145 } | |
| 146 bad: | |
| 147 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", | |
| 148 "%s: Invalid InkNames value; expecting %d names, found %d", | |
| 149 tif->tif_name, | |
| 150 td->td_samplesperpixel, | |
| 151 td->td_samplesperpixel-i); | |
| 152 return (0); | |
| 153 } | |
| 154 | |
| 155 static int | |
| 156 _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) | |
| 157 { | |
| 158 static const char module[] = "_TIFFVSetField"; | |
| 159 | |
| 160 TIFFDirectory* td = &tif->tif_dir; | |
| 161 int status = 1; | |
| 162 uint32 v32, i, v; | |
| 163 char* s; | |
| 164 const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY); | |
| 165 uint32 standard_tag = tag; | |
| 166 | |
| 167 /* | |
| 168 * We want to force the custom code to be used for custom | |
| 169 * fields even if the tag happens to match a well known | |
| 170 * one - important for reinterpreted handling of standard | |
| 171 * tag values in custom directories (ie. EXIF) | |
| 172 */ | |
| 173 if (fip->field_bit == FIELD_CUSTOM) { | |
| 174 standard_tag = 0; | |
| 175 } | |
| 176 | |
| 177 switch (standard_tag) { | |
| 178 case TIFFTAG_SUBFILETYPE: | |
| 179 td->td_subfiletype = (uint32) va_arg(ap, uint32); | |
| 180 break; | |
| 181 case TIFFTAG_IMAGEWIDTH: | |
| 182 td->td_imagewidth = (uint32) va_arg(ap, uint32); | |
| 183 break; | |
| 184 case TIFFTAG_IMAGELENGTH: | |
| 185 td->td_imagelength = (uint32) va_arg(ap, uint32); | |
| 186 break; | |
| 187 case TIFFTAG_BITSPERSAMPLE: | |
| 188 td->td_bitspersample = (uint16) va_arg(ap, uint16_vap); | |
| 189 /* | |
| 190 * If the data require post-decoding processing to byte-swap | |
| 191 * samples, set it up here. Note that since tags are required | |
| 192 * to be ordered, compression code can override this behaviour | |
| 193 * in the setup method if it wants to roll the post decoding | |
| 194 * work in with its normal work. | |
| 195 */ | |
| 196 if (tif->tif_flags & TIFF_SWAB) { | |
| 197 if (td->td_bitspersample == 8) | |
| 198 tif->tif_postdecode = _TIFFNoPostDecode; | |
| 199 else if (td->td_bitspersample == 16) | |
| 200 tif->tif_postdecode = _TIFFSwab16BitData; | |
| 201 else if (td->td_bitspersample == 24) | |
| 202 tif->tif_postdecode = _TIFFSwab24BitData; | |
| 203 else if (td->td_bitspersample == 32) | |
| 204 tif->tif_postdecode = _TIFFSwab32BitData; | |
| 205 else if (td->td_bitspersample == 64) | |
| 206 tif->tif_postdecode = _TIFFSwab64BitData; | |
| 207 else if (td->td_bitspersample == 128) /* two 64's */ | |
| 208 tif->tif_postdecode = _TIFFSwab64BitData; | |
| 209 } | |
| 210 break; | |
| 211 case TIFFTAG_COMPRESSION: | |
| 212 v = (uint16) va_arg(ap, uint16_vap); | |
| 213 /* | |
| 214 * If we're changing the compression scheme, the notify the | |
| 215 * previous module so that it can cleanup any state it's | |
| 216 * setup. | |
| 217 */ | |
| 218 if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { | |
| 219 if ((uint32)td->td_compression == v) | |
| 220 break; | |
| 221 (*tif->tif_cleanup)(tif); | |
| 222 tif->tif_flags &= ~TIFF_CODERSETUP; | |
| 223 } | |
| 224 /* | |
| 225 * Setup new compression routine state. | |
| 226 */ | |
| 227 if( (status = TIFFSetCompressionScheme(tif, v)) != 0 ) | |
| 228 td->td_compression = (uint16) v; | |
| 229 else | |
| 230 status = 0; | |
| 231 break; | |
| 232 case TIFFTAG_PHOTOMETRIC: | |
| 233 td->td_photometric = (uint16) va_arg(ap, uint16_vap); | |
| 234 break; | |
| 235 case TIFFTAG_THRESHHOLDING: | |
| 236 td->td_threshholding = (uint16) va_arg(ap, uint16_vap); | |
| 237 break; | |
| 238 case TIFFTAG_FILLORDER: | |
| 239 v = (uint16) va_arg(ap, uint16_vap); | |
| 240 if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) | |
| 241 goto badvalue; | |
| 242 td->td_fillorder = (uint16) v; | |
| 243 break; | |
| 244 case TIFFTAG_ORIENTATION: | |
| 245 v = (uint16) va_arg(ap, uint16_vap); | |
| 246 if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) | |
| 247 goto badvalue; | |
| 248 else | |
| 249 td->td_orientation = (uint16) v; | |
| 250 break; | |
| 251 case TIFFTAG_SAMPLESPERPIXEL: | |
| 252 v = (uint16) va_arg(ap, uint16_vap); | |
| 253 if (v == 0) | |
| 254 goto badvalue; | |
| 255 td->td_samplesperpixel = (uint16) v; | |
| 256 break; | |
| 257 case TIFFTAG_ROWSPERSTRIP: | |
| 258 v32 = (uint32) va_arg(ap, uint32); | |
| 259 if (v32 == 0) | |
| 260 goto badvalue32; | |
| 261 td->td_rowsperstrip = v32; | |
| 262 if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { | |
| 263 td->td_tilelength = v32; | |
| 264 td->td_tilewidth = td->td_imagewidth; | |
| 265 } | |
| 266 break; | |
| 267 case TIFFTAG_MINSAMPLEVALUE: | |
| 268 td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap); | |
| 269 break; | |
| 270 case TIFFTAG_MAXSAMPLEVALUE: | |
| 271 td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap); | |
| 272 break; | |
| 273 case TIFFTAG_SMINSAMPLEVALUE: | |
| 274 if (tif->tif_flags & TIFF_PERSAMPLE) | |
| 275 _TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap,
double*), td->td_samplesperpixel); | |
| 276 else | |
| 277 setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(a
p, double), td->td_samplesperpixel); | |
| 278 break; | |
| 279 case TIFFTAG_SMAXSAMPLEVALUE: | |
| 280 if (tif->tif_flags & TIFF_PERSAMPLE) | |
| 281 _TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap,
double*), td->td_samplesperpixel); | |
| 282 else | |
| 283 setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(a
p, double), td->td_samplesperpixel); | |
| 284 break; | |
| 285 case TIFFTAG_XRESOLUTION: | |
| 286 td->td_xresolution = (float) va_arg(ap, double); | |
| 287 break; | |
| 288 case TIFFTAG_YRESOLUTION: | |
| 289 td->td_yresolution = (float) va_arg(ap, double); | |
| 290 break; | |
| 291 case TIFFTAG_PLANARCONFIG: | |
| 292 v = (uint16) va_arg(ap, uint16_vap); | |
| 293 if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) | |
| 294 goto badvalue; | |
| 295 td->td_planarconfig = (uint16) v; | |
| 296 break; | |
| 297 case TIFFTAG_XPOSITION: | |
| 298 td->td_xposition = (float) va_arg(ap, double); | |
| 299 break; | |
| 300 case TIFFTAG_YPOSITION: | |
| 301 td->td_yposition = (float) va_arg(ap, double); | |
| 302 break; | |
| 303 case TIFFTAG_RESOLUTIONUNIT: | |
| 304 v = (uint16) va_arg(ap, uint16_vap); | |
| 305 if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) | |
| 306 goto badvalue; | |
| 307 td->td_resolutionunit = (uint16) v; | |
| 308 break; | |
| 309 case TIFFTAG_PAGENUMBER: | |
| 310 td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap); | |
| 311 td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap); | |
| 312 break; | |
| 313 case TIFFTAG_HALFTONEHINTS: | |
| 314 td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap); | |
| 315 td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap); | |
| 316 break; | |
| 317 case TIFFTAG_COLORMAP: | |
| 318 v32 = (uint32)(1L<<td->td_bitspersample); | |
| 319 _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32
); | |
| 320 _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32
); | |
| 321 _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32
); | |
| 322 break; | |
| 323 case TIFFTAG_EXTRASAMPLES: | |
| 324 if (!setExtraSamples(td, ap, &v)) | |
| 325 goto badvalue; | |
| 326 break; | |
| 327 case TIFFTAG_MATTEING: | |
| 328 td->td_extrasamples = (((uint16) va_arg(ap, uint16_vap)) != 0); | |
| 329 if (td->td_extrasamples) { | |
| 330 uint16 sv = EXTRASAMPLE_ASSOCALPHA; | |
| 331 _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1); | |
| 332 } | |
| 333 break; | |
| 334 case TIFFTAG_TILEWIDTH: | |
| 335 v32 = (uint32) va_arg(ap, uint32); | |
| 336 if (v32 % 16) { | |
| 337 if (tif->tif_mode != O_RDONLY) | |
| 338 goto badvalue32; | |
| 339 TIFFWarningExt(tif->tif_clientdata, tif->tif_name, | |
| 340 "Nonstandard tile width %d, convert file", v32); | |
| 341 } | |
| 342 td->td_tilewidth = v32; | |
| 343 tif->tif_flags |= TIFF_ISTILED; | |
| 344 break; | |
| 345 case TIFFTAG_TILELENGTH: | |
| 346 v32 = (uint32) va_arg(ap, uint32); | |
| 347 if (v32 % 16) { | |
| 348 if (tif->tif_mode != O_RDONLY) | |
| 349 goto badvalue32; | |
| 350 TIFFWarningExt(tif->tif_clientdata, tif->tif_name, | |
| 351 "Nonstandard tile length %d, convert file", v32); | |
| 352 } | |
| 353 td->td_tilelength = v32; | |
| 354 tif->tif_flags |= TIFF_ISTILED; | |
| 355 break; | |
| 356 case TIFFTAG_TILEDEPTH: | |
| 357 v32 = (uint32) va_arg(ap, uint32); | |
| 358 if (v32 == 0) | |
| 359 goto badvalue32; | |
| 360 td->td_tiledepth = v32; | |
| 361 break; | |
| 362 case TIFFTAG_DATATYPE: | |
| 363 v = (uint16) va_arg(ap, uint16_vap); | |
| 364 switch (v) { | |
| 365 case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; | |
| 366 case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; | |
| 367 case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break; | |
| 368 case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break; | |
| 369 default: goto badvalue; | |
| 370 } | |
| 371 td->td_sampleformat = (uint16) v; | |
| 372 break; | |
| 373 case TIFFTAG_SAMPLEFORMAT: | |
| 374 v = (uint16) va_arg(ap, uint16_vap); | |
| 375 if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) | |
| 376 goto badvalue; | |
| 377 td->td_sampleformat = (uint16) v; | |
| 378 | |
| 379 /* Try to fix up the SWAB function for complex data. */ | |
| 380 if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT | |
| 381 && td->td_bitspersample == 32 | |
| 382 && tif->tif_postdecode == _TIFFSwab32BitData ) | |
| 383 tif->tif_postdecode = _TIFFSwab16BitData; | |
| 384 else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT | |
| 385 || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) | |
| 386 && td->td_bitspersample == 64 | |
| 387 && tif->tif_postdecode == _TIFFSwab64BitData ) | |
| 388 tif->tif_postdecode = _TIFFSwab32BitData; | |
| 389 break; | |
| 390 case TIFFTAG_IMAGEDEPTH: | |
| 391 td->td_imagedepth = (uint32) va_arg(ap, uint32); | |
| 392 break; | |
| 393 case TIFFTAG_SUBIFD: | |
| 394 if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { | |
| 395 td->td_nsubifd = (uint16) va_arg(ap, uint16_vap); | |
| 396 _TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap,
uint64*), | |
| 397 (long) td->td_nsubifd); | |
| 398 } else { | |
| 399 TIFFErrorExt(tif->tif_clientdata, module, | |
| 400 "%s: Sorry, cannot nest SubIFDs", | |
| 401 tif->tif_name); | |
| 402 status = 0; | |
| 403 } | |
| 404 break; | |
| 405 case TIFFTAG_YCBCRPOSITIONING: | |
| 406 td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap); | |
| 407 break; | |
| 408 case TIFFTAG_YCBCRSUBSAMPLING: | |
| 409 td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap); | |
| 410 td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap); | |
| 411 break; | |
| 412 case TIFFTAG_TRANSFERFUNCTION: | |
| 413 v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; | |
| 414 for (i = 0; i < v; i++) | |
| 415 _TIFFsetShortArray(&td->td_transferfunction[i], | |
| 416 va_arg(ap, uint16*), 1L<<td->td_bitspersample); | |
| 417 break; | |
| 418 case TIFFTAG_REFERENCEBLACKWHITE: | |
| 419 /* XXX should check for null range */ | |
| 420 _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6)
; | |
| 421 break; | |
| 422 case TIFFTAG_INKNAMES: | |
| 423 v = (uint16) va_arg(ap, uint16_vap); | |
| 424 s = va_arg(ap, char*); | |
| 425 v = checkInkNamesString(tif, v, s); | |
| 426 status = v > 0; | |
| 427 if( v > 0 ) { | |
| 428 _TIFFsetNString(&td->td_inknames, s, v); | |
| 429 td->td_inknameslen = v; | |
| 430 } | |
| 431 break; | |
| 432 case TIFFTAG_PERSAMPLE: | |
| 433 v = (uint16) va_arg(ap, uint16_vap); | |
| 434 if( v == PERSAMPLE_MULTI ) | |
| 435 tif->tif_flags |= TIFF_PERSAMPLE; | |
| 436 else | |
| 437 tif->tif_flags &= ~TIFF_PERSAMPLE; | |
| 438 break; | |
| 439 default: { | |
| 440 TIFFTagValue *tv; | |
| 441 int tv_size, iCustom; | |
| 442 | |
| 443 /* | |
| 444 * This can happen if multiple images are open with different | |
| 445 * codecs which have private tags. The global tag information | |
| 446 * table may then have tags that are valid for one file but not | |
| 447 * the other. If the client tries to set a tag that is not valid | |
| 448 * for the image's codec then we'll arrive here. This | |
| 449 * happens, for example, when tiffcp is used to convert between | |
| 450 * compression schemes and codec-specific tags are blindly copie
d. | |
| 451 */ | |
| 452 if(fip == NULL || fip->field_bit != FIELD_CUSTOM) { | |
| 453 TIFFErrorExt(tif->tif_clientdata, module, | |
| 454 "%s: Invalid %stag \"%s\" (not supported by codec)", | |
| 455 tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", | |
| 456 fip ? fip->field_name : "Unknown"); | |
| 457 status = 0; | |
| 458 break; | |
| 459 } | |
| 460 | |
| 461 /* | |
| 462 * Find the existing entry for this custom value. | |
| 463 */ | |
| 464 tv = NULL; | |
| 465 for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
{ | |
| 466 if (td->td_customValues[iCustom].info->field_tag == tag)
{ | |
| 467 tv = td->td_customValues + iCustom; | |
| 468 if (tv->value != NULL) { | |
| 469 _TIFFfree(tv->value); | |
| 470 tv->value = NULL; | |
| 471 } | |
| 472 break; | |
| 473 } | |
| 474 } | |
| 475 | |
| 476 /* | |
| 477 * Grow the custom list if the entry was not found. | |
| 478 */ | |
| 479 if(tv == NULL) { | |
| 480 TIFFTagValue *new_customValues; | |
| 481 | |
| 482 td->td_customValueCount++; | |
| 483 new_customValues = (TIFFTagValue *) | |
| 484 _TIFFrealloc(td->td_customValues, | |
| 485 sizeof(TIFFTagValue) * td->td_customValueCount); | |
| 486 if (!new_customValues) { | |
| 487 TIFFErrorExt(tif->tif_clientdata, module, | |
| 488 "%s: Failed to allocate space for list of cu
stom values", | |
| 489 tif->tif_name); | |
| 490 status = 0; | |
| 491 goto end; | |
| 492 } | |
| 493 | |
| 494 td->td_customValues = new_customValues; | |
| 495 | |
| 496 tv = td->td_customValues + (td->td_customValueCount - 1)
; | |
| 497 tv->info = fip; | |
| 498 tv->value = NULL; | |
| 499 tv->count = 0; | |
| 500 } | |
| 501 | |
| 502 /* | |
| 503 * Set custom value ... save a copy of the custom tag value. | |
| 504 */ | |
| 505 tv_size = _TIFFDataSize(fip->field_type); | |
| 506 if (tv_size == 0) { | |
| 507 status = 0; | |
| 508 TIFFErrorExt(tif->tif_clientdata, module, | |
| 509 "%s: Bad field type %d for \"%s\"", | |
| 510 tif->tif_name, fip->field_type, | |
| 511 fip->field_name); | |
| 512 goto end; | |
| 513 } | |
| 514 | |
| 515 if (fip->field_type == TIFF_ASCII) | |
| 516 { | |
| 517 uint32 ma; | |
| 518 char* mb; | |
| 519 if (fip->field_passcount) | |
| 520 { | |
| 521 assert(fip->field_writecount==TIFF_VARIABLE2); | |
| 522 ma=(uint32)va_arg(ap,uint32); | |
| 523 mb=(char*)va_arg(ap,char*); | |
| 524 } | |
| 525 else | |
| 526 { | |
| 527 mb=(char*)va_arg(ap,char*); | |
| 528 ma=(uint32)(strlen(mb)+1); | |
| 529 } | |
| 530 tv->count=ma; | |
| 531 setByteArray(&tv->value,mb,ma,1); | |
| 532 } | |
| 533 else | |
| 534 { | |
| 535 if (fip->field_passcount) { | |
| 536 if (fip->field_writecount == TIFF_VARIABLE2) | |
| 537 tv->count = (uint32) va_arg(ap, uint32); | |
| 538 else | |
| 539 tv->count = (int) va_arg(ap, int); | |
| 540 } else if (fip->field_writecount == TIFF_VARIABLE | |
| 541 || fip->field_writecount == TIFF_VARIABLE2) | |
| 542 tv->count = 1; | |
| 543 else if (fip->field_writecount == TIFF_SPP) | |
| 544 tv->count = td->td_samplesperpixel; | |
| 545 else | |
| 546 tv->count = fip->field_writecount; | |
| 547 | |
| 548 if (tv->count == 0) { | |
| 549 status = 0; | |
| 550 TIFFErrorExt(tif->tif_clientdata, module, | |
| 551 "%s: Null count for \"%s\" (type " | |
| 552 "%d, writecount %d, passcount %d)", | |
| 553 tif->tif_name, | |
| 554 fip->field_name, | |
| 555 fip->field_type, | |
| 556 fip->field_writecount, | |
| 557 fip->field_passcount); | |
| 558 goto end; | |
| 559 } | |
| 560 | |
| 561 tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size, | |
| 562 "custom tag binary object"); | |
| 563 if (!tv->value) { | |
| 564 status = 0; | |
| 565 goto end; | |
| 566 } | |
| 567 | |
| 568 if (fip->field_tag == TIFFTAG_DOTRANGE | |
| 569 && strcmp(fip->field_name,"DotRange") == 0) { | |
| 570 /* TODO: This is an evil exception and should no
t have been | |
| 571 handled this way ... likely best if we move i
t into | |
| 572 the directory structure with an explicit fiel
d in | |
| 573 libtiff 4.1 and assign it a FIELD_ value */ | |
| 574 uint16 v[2]; | |
| 575 v[0] = (uint16)va_arg(ap, int); | |
| 576 v[1] = (uint16)va_arg(ap, int); | |
| 577 _TIFFmemcpy(tv->value, &v, 4); | |
| 578 } | |
| 579 | |
| 580 else if (fip->field_passcount | |
| 581 || fip->field_writecount == TIFF_VARIABLE | |
| 582 || fip->field_writecount == TIFF_VARIABLE2 | |
| 583 || fip->field_writecount == TIFF_SPP | |
| 584 || tv->count > 1) { | |
| 585 _TIFFmemcpy(tv->value, va_arg(ap, void *), | |
| 586 tv->count * tv_size); | |
| 587 } else { | |
| 588 char *val = (char *)tv->value; | |
| 589 assert( tv->count == 1 ); | |
| 590 | |
| 591 switch (fip->field_type) { | |
| 592 case TIFF_BYTE: | |
| 593 case TIFF_UNDEFINED: | |
| 594 { | |
| 595 uint8 v = (uint8)va_arg(ap, int)
; | |
| 596 _TIFFmemcpy(val, &v, tv_size); | |
| 597 } | |
| 598 break; | |
| 599 case TIFF_SBYTE: | |
| 600 { | |
| 601 int8 v = (int8)va_arg(ap, int); | |
| 602 _TIFFmemcpy(val, &v, tv_size); | |
| 603 } | |
| 604 break; | |
| 605 case TIFF_SHORT: | |
| 606 { | |
| 607 uint16 v = (uint16)va_arg(ap, in
t); | |
| 608 _TIFFmemcpy(val, &v, tv_size); | |
| 609 } | |
| 610 break; | |
| 611 case TIFF_SSHORT: | |
| 612 { | |
| 613 int16 v = (int16)va_arg(ap, int)
; | |
| 614 _TIFFmemcpy(val, &v, tv_size); | |
| 615 } | |
| 616 break; | |
| 617 case TIFF_LONG: | |
| 618 case TIFF_IFD: | |
| 619 { | |
| 620 uint32 v = va_arg(ap, uint32); | |
| 621 _TIFFmemcpy(val, &v, tv_size); | |
| 622 } | |
| 623 break; | |
| 624 case TIFF_SLONG: | |
| 625 { | |
| 626 int32 v = va_arg(ap, int32); | |
| 627 _TIFFmemcpy(val, &v, tv_size); | |
| 628 } | |
| 629 break; | |
| 630 case TIFF_LONG8: | |
| 631 case TIFF_IFD8: | |
| 632 { | |
| 633 uint64 v = va_arg(ap, uint64); | |
| 634 _TIFFmemcpy(val, &v, tv_size); | |
| 635 } | |
| 636 break; | |
| 637 case TIFF_SLONG8: | |
| 638 { | |
| 639 int64 v = va_arg(ap, int64); | |
| 640 _TIFFmemcpy(val, &v, tv_size); | |
| 641 } | |
| 642 break; | |
| 643 case TIFF_RATIONAL: | |
| 644 case TIFF_SRATIONAL: | |
| 645 case TIFF_FLOAT: | |
| 646 { | |
| 647 float v = (float)va_arg(ap, doub
le); | |
| 648 _TIFFmemcpy(val, &v, tv_size); | |
| 649 } | |
| 650 break; | |
| 651 case TIFF_DOUBLE: | |
| 652 { | |
| 653 double v = va_arg(ap, double); | |
| 654 _TIFFmemcpy(val, &v, tv_size); | |
| 655 } | |
| 656 break; | |
| 657 default: | |
| 658 _TIFFmemset(val, 0, tv_size); | |
| 659 status = 0; | |
| 660 break; | |
| 661 } | |
| 662 } | |
| 663 } | |
| 664 } | |
| 665 } | |
| 666 if (status) { | |
| 667 const TIFFField* fip=TIFFFieldWithTag(tif,tag); | |
| 668 if (fip) | |
| 669 TIFFSetFieldBit(tif, fip->field_bit); | |
| 670 tif->tif_flags |= TIFF_DIRTYDIRECT; | |
| 671 } | |
| 672 | |
| 673 end: | |
| 674 va_end(ap); | |
| 675 return (status); | |
| 676 badvalue: | |
| 677 { | |
| 678 const TIFFField* fip=TIFFFieldWithTag(tif,tag); | |
| 679 TIFFErrorExt(tif->tif_clientdata, module, | |
| 680 "%s: Bad value %u for \"%s\" tag", | |
| 681 tif->tif_name, v, | |
| 682 fip ? fip->field_name : "Unknown"); | |
| 683 va_end(ap); | |
| 684 } | |
| 685 return (0); | |
| 686 badvalue32: | |
| 687 { | |
| 688 const TIFFField* fip=TIFFFieldWithTag(tif,tag); | |
| 689 TIFFErrorExt(tif->tif_clientdata, module, | |
| 690 "%s: Bad value %u for \"%s\" tag", | |
| 691 tif->tif_name, v32, | |
| 692 fip ? fip->field_name : "Unknown"); | |
| 693 va_end(ap); | |
| 694 } | |
| 695 return (0); | |
| 696 } | |
| 697 | |
| 698 /* | |
| 699 * Return 1/0 according to whether or not | |
| 700 * it is permissible to set the tag's value. | |
| 701 * Note that we allow ImageLength to be changed | |
| 702 * so that we can append and extend to images. | |
| 703 * Any other tag may not be altered once writing | |
| 704 * has commenced, unless its value has no effect | |
| 705 * on the format of the data that is written. | |
| 706 */ | |
| 707 static int | |
| 708 OkToChangeTag(TIFF* tif, uint32 tag) | |
| 709 { | |
| 710 const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); | |
| 711 if (!fip) { /* unknown tag */ | |
| 712 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %
stag %u", | |
| 713 tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); | |
| 714 return (0); | |
| 715 } | |
| 716 if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && | |
| 717 !fip->field_oktochange) { | |
| 718 /* | |
| 719 * Consult info table to see if tag can be changed | |
| 720 * after we've started writing. We only allow changes | |
| 721 * to those tags that don't/shouldn't affect the | |
| 722 * compression and/or format of the data. | |
| 723 */ | |
| 724 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", | |
| 725 "%s: Cannot modify tag \"%s\" while writing", | |
| 726 tif->tif_name, fip->field_name); | |
| 727 return (0); | |
| 728 } | |
| 729 return (1); | |
| 730 } | |
| 731 | |
| 732 /* | |
| 733 * Record the value of a field in the | |
| 734 * internal directory structure. The | |
| 735 * field will be written to the file | |
| 736 * when/if the directory structure is | |
| 737 * updated. | |
| 738 */ | |
| 739 int | |
| 740 TIFFSetField(TIFF* tif, uint32 tag, ...) | |
| 741 { | |
| 742 va_list ap; | |
| 743 int status; | |
| 744 | |
| 745 va_start(ap, tag); | |
| 746 status = TIFFVSetField(tif, tag, ap); | |
| 747 va_end(ap); | |
| 748 return (status); | |
| 749 } | |
| 750 | |
| 751 /* | |
| 752 * Clear the contents of the field in the internal structure. | |
| 753 */ | |
| 754 int | |
| 755 TIFFUnsetField(TIFF* tif, uint32 tag) | |
| 756 { | |
| 757 const TIFFField *fip = TIFFFieldWithTag(tif, tag); | |
| 758 TIFFDirectory* td = &tif->tif_dir; | |
| 759 | |
| 760 if( !fip ) | |
| 761 return 0; | |
| 762 | |
| 763 if( fip->field_bit != FIELD_CUSTOM ) | |
| 764 TIFFClrFieldBit(tif, fip->field_bit); | |
| 765 else | |
| 766 { | |
| 767 TIFFTagValue *tv = NULL; | |
| 768 int i; | |
| 769 | |
| 770 for (i = 0; i < td->td_customValueCount; i++) { | |
| 771 | |
| 772 tv = td->td_customValues + i; | |
| 773 if( tv->info->field_tag == tag ) | |
| 774 break; | |
| 775 } | |
| 776 | |
| 777 if( i < td->td_customValueCount ) | |
| 778 { | |
| 779 _TIFFfree(tv->value); | |
| 780 for( ; i < td->td_customValueCount-1; i++) { | |
| 781 td->td_customValues[i] = td->td_customValues[i+1]; | |
| 782 } | |
| 783 td->td_customValueCount--; | |
| 784 } | |
| 785 } | |
| 786 | |
| 787 tif->tif_flags |= TIFF_DIRTYDIRECT; | |
| 788 | |
| 789 return (1); | |
| 790 } | |
| 791 | |
| 792 /* | |
| 793 * Like TIFFSetField, but taking a varargs | |
| 794 * parameter list. This routine is useful | |
| 795 * for building higher-level interfaces on | |
| 796 * top of the library. | |
| 797 */ | |
| 798 int | |
| 799 TIFFVSetField(TIFF* tif, uint32 tag, va_list ap) | |
| 800 { | |
| 801 return OkToChangeTag(tif, tag) ? | |
| 802 (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0; | |
| 803 } | |
| 804 | |
| 805 static int | |
| 806 _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) | |
| 807 { | |
| 808 TIFFDirectory* td = &tif->tif_dir; | |
| 809 int ret_val = 1; | |
| 810 uint32 standard_tag = tag; | |
| 811 const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); | |
| 812 | |
| 813 /* | |
| 814 * We want to force the custom code to be used for custom | |
| 815 * fields even if the tag happens to match a well known | |
| 816 * one - important for reinterpreted handling of standard | |
| 817 * tag values in custom directories (ie. EXIF) | |
| 818 */ | |
| 819 if (fip->field_bit == FIELD_CUSTOM) { | |
| 820 standard_tag = 0; | |
| 821 } | |
| 822 | |
| 823 switch (standard_tag) { | |
| 824 case TIFFTAG_SUBFILETYPE: | |
| 825 *va_arg(ap, uint32*) = td->td_subfiletype; | |
| 826 break; | |
| 827 case TIFFTAG_IMAGEWIDTH: | |
| 828 *va_arg(ap, uint32*) = td->td_imagewidth; | |
| 829 break; | |
| 830 case TIFFTAG_IMAGELENGTH: | |
| 831 *va_arg(ap, uint32*) = td->td_imagelength; | |
| 832 break; | |
| 833 case TIFFTAG_BITSPERSAMPLE: | |
| 834 *va_arg(ap, uint16*) = td->td_bitspersample; | |
| 835 break; | |
| 836 case TIFFTAG_COMPRESSION: | |
| 837 *va_arg(ap, uint16*) = td->td_compression; | |
| 838 break; | |
| 839 case TIFFTAG_PHOTOMETRIC: | |
| 840 *va_arg(ap, uint16*) = td->td_photometric; | |
| 841 break; | |
| 842 case TIFFTAG_THRESHHOLDING: | |
| 843 *va_arg(ap, uint16*) = td->td_threshholding; | |
| 844 break; | |
| 845 case TIFFTAG_FILLORDER: | |
| 846 *va_arg(ap, uint16*) = td->td_fillorder; | |
| 847 break; | |
| 848 case TIFFTAG_ORIENTATION: | |
| 849 *va_arg(ap, uint16*) = td->td_orientation; | |
| 850 break; | |
| 851 case TIFFTAG_SAMPLESPERPIXEL: | |
| 852 *va_arg(ap, uint16*) = td->td_samplesperpixel; | |
| 853 break; | |
| 854 case TIFFTAG_ROWSPERSTRIP: | |
| 855 *va_arg(ap, uint32*) = td->td_rowsperstrip; | |
| 856 break; | |
| 857 case TIFFTAG_MINSAMPLEVALUE: | |
| 858 *va_arg(ap, uint16*) = td->td_minsamplevalue; | |
| 859 break; | |
| 860 case TIFFTAG_MAXSAMPLEVALUE: | |
| 861 *va_arg(ap, uint16*) = td->td_maxsamplevalue; | |
| 862 break; | |
| 863 case TIFFTAG_SMINSAMPLEVALUE: | |
| 864 if (tif->tif_flags & TIFF_PERSAMPLE) | |
| 865 *va_arg(ap, double**) = td->td_sminsamplevalue; | |
| 866 else | |
| 867 { | |
| 868 /* libtiff historially treats this as a single v
alue. */ | |
| 869 uint16 i; | |
| 870 double v = td->td_sminsamplevalue[0]; | |
| 871 for (i=1; i < td->td_samplesperpixel; ++i) | |
| 872 if( td->td_sminsamplevalue[i] < v ) | |
| 873 v = td->td_sminsamplevalue[i]; | |
| 874 *va_arg(ap, double*) = v; | |
| 875 } | |
| 876 break; | |
| 877 case TIFFTAG_SMAXSAMPLEVALUE: | |
| 878 if (tif->tif_flags & TIFF_PERSAMPLE) | |
| 879 *va_arg(ap, double**) = td->td_smaxsamplevalue; | |
| 880 else | |
| 881 { | |
| 882 /* libtiff historially treats this as a single v
alue. */ | |
| 883 uint16 i; | |
| 884 double v = td->td_smaxsamplevalue[0]; | |
| 885 for (i=1; i < td->td_samplesperpixel; ++i) | |
| 886 if( td->td_smaxsamplevalue[i] > v ) | |
| 887 v = td->td_smaxsamplevalue[i]; | |
| 888 *va_arg(ap, double*) = v; | |
| 889 } | |
| 890 break; | |
| 891 case TIFFTAG_XRESOLUTION: | |
| 892 *va_arg(ap, float*) = td->td_xresolution; | |
| 893 break; | |
| 894 case TIFFTAG_YRESOLUTION: | |
| 895 *va_arg(ap, float*) = td->td_yresolution; | |
| 896 break; | |
| 897 case TIFFTAG_PLANARCONFIG: | |
| 898 *va_arg(ap, uint16*) = td->td_planarconfig; | |
| 899 break; | |
| 900 case TIFFTAG_XPOSITION: | |
| 901 *va_arg(ap, float*) = td->td_xposition; | |
| 902 break; | |
| 903 case TIFFTAG_YPOSITION: | |
| 904 *va_arg(ap, float*) = td->td_yposition; | |
| 905 break; | |
| 906 case TIFFTAG_RESOLUTIONUNIT: | |
| 907 *va_arg(ap, uint16*) = td->td_resolutionunit; | |
| 908 break; | |
| 909 case TIFFTAG_PAGENUMBER: | |
| 910 *va_arg(ap, uint16*) = td->td_pagenumber[0]; | |
| 911 *va_arg(ap, uint16*) = td->td_pagenumber[1]; | |
| 912 break; | |
| 913 case TIFFTAG_HALFTONEHINTS: | |
| 914 *va_arg(ap, uint16*) = td->td_halftonehints[0]; | |
| 915 *va_arg(ap, uint16*) = td->td_halftonehints[1]; | |
| 916 break; | |
| 917 case TIFFTAG_COLORMAP: | |
| 918 *va_arg(ap, uint16**) = td->td_colormap[0]; | |
| 919 *va_arg(ap, uint16**) = td->td_colormap[1]; | |
| 920 *va_arg(ap, uint16**) = td->td_colormap[2]; | |
| 921 break; | |
| 922 case TIFFTAG_STRIPOFFSETS: | |
| 923 case TIFFTAG_TILEOFFSETS: | |
| 924 _TIFFFillStriles( tif ); | |
| 925 *va_arg(ap, uint64**) = td->td_stripoffset; | |
| 926 break; | |
| 927 case TIFFTAG_STRIPBYTECOUNTS: | |
| 928 case TIFFTAG_TILEBYTECOUNTS: | |
| 929 _TIFFFillStriles( tif ); | |
| 930 *va_arg(ap, uint64**) = td->td_stripbytecount; | |
| 931 break; | |
| 932 case TIFFTAG_MATTEING: | |
| 933 *va_arg(ap, uint16*) = | |
| 934 (td->td_extrasamples == 1 && | |
| 935 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); | |
| 936 break; | |
| 937 case TIFFTAG_EXTRASAMPLES: | |
| 938 *va_arg(ap, uint16*) = td->td_extrasamples; | |
| 939 *va_arg(ap, uint16**) = td->td_sampleinfo; | |
| 940 break; | |
| 941 case TIFFTAG_TILEWIDTH: | |
| 942 *va_arg(ap, uint32*) = td->td_tilewidth; | |
| 943 break; | |
| 944 case TIFFTAG_TILELENGTH: | |
| 945 *va_arg(ap, uint32*) = td->td_tilelength; | |
| 946 break; | |
| 947 case TIFFTAG_TILEDEPTH: | |
| 948 *va_arg(ap, uint32*) = td->td_tiledepth; | |
| 949 break; | |
| 950 case TIFFTAG_DATATYPE: | |
| 951 switch (td->td_sampleformat) { | |
| 952 case SAMPLEFORMAT_UINT: | |
| 953 *va_arg(ap, uint16*) = DATATYPE_UINT; | |
| 954 break; | |
| 955 case SAMPLEFORMAT_INT: | |
| 956 *va_arg(ap, uint16*) = DATATYPE_INT; | |
| 957 break; | |
| 958 case SAMPLEFORMAT_IEEEFP: | |
| 959 *va_arg(ap, uint16*) = DATATYPE_IEEEFP; | |
| 960 break; | |
| 961 case SAMPLEFORMAT_VOID: | |
| 962 *va_arg(ap, uint16*) = DATATYPE_VOID; | |
| 963 break; | |
| 964 } | |
| 965 break; | |
| 966 case TIFFTAG_SAMPLEFORMAT: | |
| 967 *va_arg(ap, uint16*) = td->td_sampleformat; | |
| 968 break; | |
| 969 case TIFFTAG_IMAGEDEPTH: | |
| 970 *va_arg(ap, uint32*) = td->td_imagedepth; | |
| 971 break; | |
| 972 case TIFFTAG_SUBIFD: | |
| 973 *va_arg(ap, uint16*) = td->td_nsubifd; | |
| 974 *va_arg(ap, uint64**) = td->td_subifd; | |
| 975 break; | |
| 976 case TIFFTAG_YCBCRPOSITIONING: | |
| 977 *va_arg(ap, uint16*) = td->td_ycbcrpositioning; | |
| 978 break; | |
| 979 case TIFFTAG_YCBCRSUBSAMPLING: | |
| 980 *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0]; | |
| 981 *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1]; | |
| 982 break; | |
| 983 case TIFFTAG_TRANSFERFUNCTION: | |
| 984 *va_arg(ap, uint16**) = td->td_transferfunction[0]; | |
| 985 if (td->td_samplesperpixel - td->td_extrasamples > 1) { | |
| 986 *va_arg(ap, uint16**) = td->td_transferfunction[
1]; | |
| 987 *va_arg(ap, uint16**) = td->td_transferfunction[
2]; | |
| 988 } | |
| 989 break; | |
| 990 case TIFFTAG_REFERENCEBLACKWHITE: | |
| 991 *va_arg(ap, float**) = td->td_refblackwhite; | |
| 992 break; | |
| 993 case TIFFTAG_INKNAMES: | |
| 994 *va_arg(ap, char**) = td->td_inknames; | |
| 995 break; | |
| 996 default: | |
| 997 { | |
| 998 int i; | |
| 999 | |
| 1000 /* | |
| 1001 * This can happen if multiple images are open | |
| 1002 * with different codecs which have private | |
| 1003 * tags. The global tag information table may | |
| 1004 * then have tags that are valid for one file | |
| 1005 * but not the other. If the client tries to | |
| 1006 * get a tag that is not valid for the image's | |
| 1007 * codec then we'll arrive here. | |
| 1008 */ | |
| 1009 if( fip == NULL || fip->field_bit != FIELD_CUSTO
M ) | |
| 1010 { | |
| 1011 TIFFErrorExt(tif->tif_clientdata, "_TIFF
VGetField", | |
| 1012 "%s: Invalid %stag \"%s\" " | |
| 1013 "(not supported by codec)", | |
| 1014 tif->tif_name, | |
| 1015 isPseudoTag(tag) ? "pseudo-" : "", | |
| 1016 fip ? fip->field_name : "Unknown"); | |
| 1017 ret_val = 0; | |
| 1018 break; | |
| 1019 } | |
| 1020 | |
| 1021 /* | |
| 1022 * Do we have a custom value? | |
| 1023 */ | |
| 1024 ret_val = 0; | |
| 1025 for (i = 0; i < td->td_customValueCount; i++) { | |
| 1026 TIFFTagValue *tv = td->td_customValues +
i; | |
| 1027 | |
| 1028 if (tv->info->field_tag != tag) | |
| 1029 continue; | |
| 1030 | |
| 1031 if (fip->field_passcount) { | |
| 1032 if (fip->field_readcount == TIFF
_VARIABLE2) | |
| 1033 *va_arg(ap, uint32*) = (
uint32)tv->count; | |
| 1034 else /* Assume TIFF_VARIABLE */ | |
| 1035 *va_arg(ap, uint16*) = (
uint16)tv->count; | |
| 1036 *va_arg(ap, void **) = tv->value
; | |
| 1037 ret_val = 1; | |
| 1038 } else if (fip->field_tag == TIFFTAG_DOT
RANGE | |
| 1039 && strcmp(fip->field_name,"Do
tRange") == 0) { | |
| 1040 /* TODO: This is an evil excepti
on and should not have been | |
| 1041 handled this way ... likely b
est if we move it into | |
| 1042 the directory structure with
an explicit field in | |
| 1043 libtiff 4.1 and assign it a F
IELD_ value */ | |
| 1044 *va_arg(ap, uint16*) = ((uint16
*)tv->value)[0]; | |
| 1045 *va_arg(ap, uint16*) = ((uint16
*)tv->value)[1]; | |
| 1046 ret_val = 1; | |
| 1047 } else { | |
| 1048 if (fip->field_type == TIFF_ASCI
I | |
| 1049 || fip->field_readcount == T
IFF_VARIABLE | |
| 1050 || fip->field_readcount == T
IFF_VARIABLE2 | |
| 1051 || fip->field_readcount == T
IFF_SPP | |
| 1052 || tv->count > 1) { | |
| 1053 *va_arg(ap, void **) = t
v->value; | |
| 1054 ret_val = 1; | |
| 1055 } else { | |
| 1056 char *val = (char *)tv->
value; | |
| 1057 assert( tv->count == 1 )
; | |
| 1058 switch (fip->field_type)
{ | |
| 1059 case TIFF_BYTE: | |
| 1060 case TIFF_UNDEFINED: | |
| 1061 *va_arg(ap, uint
8*) = | |
| 1062 *(uint8
*)val; | |
| 1063 ret_val = 1; | |
| 1064 break; | |
| 1065 case TIFF_SBYTE: | |
| 1066 *va_arg(ap, int8
*) = | |
| 1067 *(int8 *
)val; | |
| 1068 ret_val = 1; | |
| 1069 break; | |
| 1070 case TIFF_SHORT: | |
| 1071 *va_arg(ap, uint
16*) = | |
| 1072 *(uint16
*)val; | |
| 1073 ret_val = 1; | |
| 1074 break; | |
| 1075 case TIFF_SSHORT: | |
| 1076 *va_arg(ap, int1
6*) = | |
| 1077 *(int16
*)val; | |
| 1078 ret_val = 1; | |
| 1079 break; | |
| 1080 case TIFF_LONG: | |
| 1081 case TIFF_IFD: | |
| 1082 *va_arg(ap, uint
32*) = | |
| 1083 *(uint32
*)val; | |
| 1084 ret_val = 1; | |
| 1085 break; | |
| 1086 case TIFF_SLONG: | |
| 1087 *va_arg(ap, int3
2*) = | |
| 1088 *(int32
*)val; | |
| 1089 ret_val = 1; | |
| 1090 break; | |
| 1091 case TIFF_LONG8: | |
| 1092 case TIFF_IFD8: | |
| 1093 *va_arg(ap, uint
64*) = | |
| 1094 *(uint64
*)val; | |
| 1095 ret_val = 1; | |
| 1096 break; | |
| 1097 case TIFF_SLONG8: | |
| 1098 *va_arg(ap, int6
4*) = | |
| 1099 *(int64
*)val; | |
| 1100 ret_val = 1; | |
| 1101 break; | |
| 1102 case TIFF_RATIONAL: | |
| 1103 case TIFF_SRATIONAL: | |
| 1104 case TIFF_FLOAT: | |
| 1105 *va_arg(ap, floa
t*) = | |
| 1106 *(float
*)val; | |
| 1107 ret_val = 1; | |
| 1108 break; | |
| 1109 case TIFF_DOUBLE: | |
| 1110 *va_arg(ap, doub
le*) = | |
| 1111 *(double
*)val; | |
| 1112 ret_val = 1; | |
| 1113 break; | |
| 1114 default: | |
| 1115 ret_val = 0; | |
| 1116 break; | |
| 1117 } | |
| 1118 } | |
| 1119 } | |
| 1120 break; | |
| 1121 } | |
| 1122 } | |
| 1123 } | |
| 1124 return(ret_val); | |
| 1125 } | |
| 1126 | |
| 1127 /* | |
| 1128 * Return the value of a field in the | |
| 1129 * internal directory structure. | |
| 1130 */ | |
| 1131 int | |
| 1132 TIFFGetField(TIFF* tif, uint32 tag, ...) | |
| 1133 { | |
| 1134 int status; | |
| 1135 va_list ap; | |
| 1136 | |
| 1137 va_start(ap, tag); | |
| 1138 status = TIFFVGetField(tif, tag, ap); | |
| 1139 va_end(ap); | |
| 1140 return (status); | |
| 1141 } | |
| 1142 | |
| 1143 /* | |
| 1144 * Like TIFFGetField, but taking a varargs | |
| 1145 * parameter list. This routine is useful | |
| 1146 * for building higher-level interfaces on | |
| 1147 * top of the library. | |
| 1148 */ | |
| 1149 int | |
| 1150 TIFFVGetField(TIFF* tif, uint32 tag, va_list ap) | |
| 1151 { | |
| 1152 const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY); | |
| 1153 return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? | |
| 1154 (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0); | |
| 1155 } | |
| 1156 | |
| 1157 #define CleanupField(member) { \ | |
| 1158 if (td->member) { \ | |
| 1159 _TIFFfree(td->member); \ | |
| 1160 td->member = 0; \ | |
| 1161 } \ | |
| 1162 } | |
| 1163 | |
| 1164 /* | |
| 1165 * Release storage associated with a directory. | |
| 1166 */ | |
| 1167 void | |
| 1168 TIFFFreeDirectory(TIFF* tif) | |
| 1169 { | |
| 1170 TIFFDirectory *td = &tif->tif_dir; | |
| 1171 int i; | |
| 1172 | |
| 1173 _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS); | |
| 1174 CleanupField(td_sminsamplevalue); | |
| 1175 CleanupField(td_smaxsamplevalue); | |
| 1176 CleanupField(td_colormap[0]); | |
| 1177 CleanupField(td_colormap[1]); | |
| 1178 CleanupField(td_colormap[2]); | |
| 1179 CleanupField(td_sampleinfo); | |
| 1180 CleanupField(td_subifd); | |
| 1181 CleanupField(td_inknames); | |
| 1182 CleanupField(td_refblackwhite); | |
| 1183 CleanupField(td_transferfunction[0]); | |
| 1184 CleanupField(td_transferfunction[1]); | |
| 1185 CleanupField(td_transferfunction[2]); | |
| 1186 CleanupField(td_stripoffset); | |
| 1187 CleanupField(td_stripbytecount); | |
| 1188 TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); | |
| 1189 TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); | |
| 1190 | |
| 1191 /* Cleanup custom tag values */ | |
| 1192 for( i = 0; i < td->td_customValueCount; i++ ) { | |
| 1193 if (td->td_customValues[i].value) | |
| 1194 _TIFFfree(td->td_customValues[i].value); | |
| 1195 } | |
| 1196 | |
| 1197 td->td_customValueCount = 0; | |
| 1198 CleanupField(td_customValues); | |
| 1199 | |
| 1200 #if defined(DEFER_STRILE_LOAD) | |
| 1201 _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry)); | |
| 1202 _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry)); | |
| 1203 #endif | |
| 1204 } | |
| 1205 #undef CleanupField | |
| 1206 | |
| 1207 /* | |
| 1208 * Client Tag extension support (from Niles Ritter). | |
| 1209 */ | |
| 1210 static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL; | |
| 1211 | |
| 1212 TIFFExtendProc | |
| 1213 TIFFSetTagExtender(TIFFExtendProc extender) | |
| 1214 { | |
| 1215 TIFFExtendProc prev = _TIFFextender; | |
| 1216 _TIFFextender = extender; | |
| 1217 return (prev); | |
| 1218 } | |
| 1219 | |
| 1220 /* | |
| 1221 * Setup for a new directory. Should we automatically call | |
| 1222 * TIFFWriteDirectory() if the current one is dirty? | |
| 1223 * | |
| 1224 * The newly created directory will not exist on the file till | |
| 1225 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called. | |
| 1226 */ | |
| 1227 int | |
| 1228 TIFFCreateDirectory(TIFF* tif) | |
| 1229 { | |
| 1230 TIFFDefaultDirectory(tif); | |
| 1231 tif->tif_diroff = 0; | |
| 1232 tif->tif_nextdiroff = 0; | |
| 1233 tif->tif_curoff = 0; | |
| 1234 tif->tif_row = (uint32) -1; | |
| 1235 tif->tif_curstrip = (uint32) -1; | |
| 1236 | |
| 1237 return 0; | |
| 1238 } | |
| 1239 | |
| 1240 int | |
| 1241 TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray) | |
| 1242 { | |
| 1243 TIFFDefaultDirectory(tif); | |
| 1244 | |
| 1245 /* | |
| 1246 * Reset the field definitions to match the application provided list. | |
| 1247 * Hopefully TIFFDefaultDirectory() won't have done anything irreversabl
e | |
| 1248 * based on it's assumption this is an image directory. | |
| 1249 */ | |
| 1250 _TIFFSetupFields(tif, infoarray); | |
| 1251 | |
| 1252 tif->tif_diroff = 0; | |
| 1253 tif->tif_nextdiroff = 0; | |
| 1254 tif->tif_curoff = 0; | |
| 1255 tif->tif_row = (uint32) -1; | |
| 1256 tif->tif_curstrip = (uint32) -1; | |
| 1257 | |
| 1258 return 0; | |
| 1259 } | |
| 1260 | |
| 1261 int | |
| 1262 TIFFCreateEXIFDirectory(TIFF* tif) | |
| 1263 { | |
| 1264 const TIFFFieldArray* exifFieldArray; | |
| 1265 exifFieldArray = _TIFFGetExifFields(); | |
| 1266 return TIFFCreateCustomDirectory(tif, exifFieldArray); | |
| 1267 } | |
| 1268 | |
| 1269 /* | |
| 1270 * Setup a default directory structure. | |
| 1271 */ | |
| 1272 int | |
| 1273 TIFFDefaultDirectory(TIFF* tif) | |
| 1274 { | |
| 1275 register TIFFDirectory* td = &tif->tif_dir; | |
| 1276 const TIFFFieldArray* tiffFieldArray; | |
| 1277 | |
| 1278 tiffFieldArray = _TIFFGetFields(); | |
| 1279 _TIFFSetupFields(tif, tiffFieldArray); | |
| 1280 | |
| 1281 _TIFFmemset(td, 0, sizeof (*td)); | |
| 1282 td->td_fillorder = FILLORDER_MSB2LSB; | |
| 1283 td->td_bitspersample = 1; | |
| 1284 td->td_threshholding = THRESHHOLD_BILEVEL; | |
| 1285 td->td_orientation = ORIENTATION_TOPLEFT; | |
| 1286 td->td_samplesperpixel = 1; | |
| 1287 td->td_rowsperstrip = (uint32) -1; | |
| 1288 td->td_tilewidth = 0; | |
| 1289 td->td_tilelength = 0; | |
| 1290 td->td_tiledepth = 1; | |
| 1291 td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ | |
| 1292 td->td_resolutionunit = RESUNIT_INCH; | |
| 1293 td->td_sampleformat = SAMPLEFORMAT_UINT; | |
| 1294 td->td_imagedepth = 1; | |
| 1295 td->td_ycbcrsubsampling[0] = 2; | |
| 1296 td->td_ycbcrsubsampling[1] = 2; | |
| 1297 td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; | |
| 1298 tif->tif_postdecode = _TIFFNoPostDecode; | |
| 1299 tif->tif_foundfield = NULL; | |
| 1300 tif->tif_tagmethods.vsetfield = _TIFFVSetField; | |
| 1301 tif->tif_tagmethods.vgetfield = _TIFFVGetField; | |
| 1302 tif->tif_tagmethods.printdir = NULL; | |
| 1303 /* | |
| 1304 * Give client code a chance to install their own | |
| 1305 * tag extensions & methods, prior to compression overloads. | |
| 1306 */ | |
| 1307 if (_TIFFextender) | |
| 1308 (*_TIFFextender)(tif); | |
| 1309 (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); | |
| 1310 /* | |
| 1311 * NB: The directory is marked dirty as a result of setting | |
| 1312 * up the default compression scheme. However, this really | |
| 1313 * isn't correct -- we want TIFF_DIRTYDIRECT to be set only | |
| 1314 * if the user does something. We could just do the setup | |
| 1315 * by hand, but it seems better to use the normal mechanism | |
| 1316 * (i.e. TIFFSetField). | |
| 1317 */ | |
| 1318 tif->tif_flags &= ~TIFF_DIRTYDIRECT; | |
| 1319 | |
| 1320 /* | |
| 1321 * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 | |
| 1322 * we clear the ISTILED flag when setting up a new directory. | |
| 1323 * Should we also be clearing stuff like INSUBIFD? | |
| 1324 */ | |
| 1325 tif->tif_flags &= ~TIFF_ISTILED; | |
| 1326 | |
| 1327 return (1); | |
| 1328 } | |
| 1329 | |
| 1330 static int | |
| 1331 TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off) | |
| 1332 { | |
| 1333 static const char module[] = "TIFFAdvanceDirectory"; | |
| 1334 if (isMapped(tif)) | |
| 1335 { | |
| 1336 uint64 poff=*nextdir; | |
| 1337 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
| 1338 { | |
| 1339 tmsize_t poffa,poffb,poffc,poffd; | |
| 1340 uint16 dircount; | |
| 1341 uint32 nextdir32; | |
| 1342 poffa=(tmsize_t)poff; | |
| 1343 poffb=poffa+sizeof(uint16); | |
| 1344 if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize
_t)sizeof(uint16))||(poffb>tif->tif_size)) | |
| 1345 { | |
| 1346 TIFFErrorExt(tif->tif_clientdata,module,"Error f
etching directory count"); | |
| 1347 return(0); | |
| 1348 } | |
| 1349 _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16)
); | |
| 1350 if (tif->tif_flags&TIFF_SWAB) | |
| 1351 TIFFSwabShort(&dircount); | |
| 1352 poffc=poffb+dircount*12; | |
| 1353 poffd=poffc+sizeof(uint32); | |
| 1354 if ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(
poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->tif_size)) | |
| 1355 { | |
| 1356 TIFFErrorExt(tif->tif_clientdata,module,"Error f
etching directory link"); | |
| 1357 return(0); | |
| 1358 } | |
| 1359 if (off!=NULL) | |
| 1360 *off=(uint64)poffc; | |
| 1361 _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32
)); | |
| 1362 if (tif->tif_flags&TIFF_SWAB) | |
| 1363 TIFFSwabLong(&nextdir32); | |
| 1364 *nextdir=nextdir32; | |
| 1365 } | |
| 1366 else | |
| 1367 { | |
| 1368 tmsize_t poffa,poffb,poffc,poffd; | |
| 1369 uint64 dircount64; | |
| 1370 uint16 dircount16; | |
| 1371 poffa=(tmsize_t)poff; | |
| 1372 poffb=poffa+sizeof(uint64); | |
| 1373 if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize
_t)sizeof(uint64))||(poffb>tif->tif_size)) | |
| 1374 { | |
| 1375 TIFFErrorExt(tif->tif_clientdata,module,"Error f
etching directory count"); | |
| 1376 return(0); | |
| 1377 } | |
| 1378 _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint6
4)); | |
| 1379 if (tif->tif_flags&TIFF_SWAB) | |
| 1380 TIFFSwabLong8(&dircount64); | |
| 1381 if (dircount64>0xFFFF) | |
| 1382 { | |
| 1383 TIFFErrorExt(tif->tif_clientdata,module,"Sanity
check on directory count failed"); | |
| 1384 return(0); | |
| 1385 } | |
| 1386 dircount16=(uint16)dircount64; | |
| 1387 poffc=poffb+dircount16*20; | |
| 1388 poffd=poffc+sizeof(uint64); | |
| 1389 if ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)|
|(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->tif_size)) | |
| 1390 { | |
| 1391 TIFFErrorExt(tif->tif_clientdata,module,"Error f
etching directory link"); | |
| 1392 return(0); | |
| 1393 } | |
| 1394 if (off!=NULL) | |
| 1395 *off=(uint64)poffc; | |
| 1396 _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64)); | |
| 1397 if (tif->tif_flags&TIFF_SWAB) | |
| 1398 TIFFSwabLong8(nextdir); | |
| 1399 } | |
| 1400 return(1); | |
| 1401 } | |
| 1402 else | |
| 1403 { | |
| 1404 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
| 1405 { | |
| 1406 uint16 dircount; | |
| 1407 uint32 nextdir32; | |
| 1408 if (!SeekOK(tif, *nextdir) || | |
| 1409 !ReadOK(tif, &dircount, sizeof (uint16))) { | |
| 1410 TIFFErrorExt(tif->tif_clientdata, module, "%s: E
rror fetching directory count", | |
| 1411 tif->tif_name); | |
| 1412 return (0); | |
| 1413 } | |
| 1414 if (tif->tif_flags & TIFF_SWAB) | |
| 1415 TIFFSwabShort(&dircount); | |
| 1416 if (off != NULL) | |
| 1417 *off = TIFFSeekFile(tif, | |
| 1418 dircount*12, SEEK_CUR); | |
| 1419 else | |
| 1420 (void) TIFFSeekFile(tif, | |
| 1421 dircount*12, SEEK_CUR); | |
| 1422 if (!ReadOK(tif, &nextdir32, sizeof (uint32))) { | |
| 1423 TIFFErrorExt(tif->tif_clientdata, module, "%s: E
rror fetching directory link", | |
| 1424 tif->tif_name); | |
| 1425 return (0); | |
| 1426 } | |
| 1427 if (tif->tif_flags & TIFF_SWAB) | |
| 1428 TIFFSwabLong(&nextdir32); | |
| 1429 *nextdir=nextdir32; | |
| 1430 } | |
| 1431 else | |
| 1432 { | |
| 1433 uint64 dircount64; | |
| 1434 uint16 dircount16; | |
| 1435 if (!SeekOK(tif, *nextdir) || | |
| 1436 !ReadOK(tif, &dircount64, sizeof (uint64))) { | |
| 1437 TIFFErrorExt(tif->tif_clientdata, module, "%s: E
rror fetching directory count", | |
| 1438 tif->tif_name); | |
| 1439 return (0); | |
| 1440 } | |
| 1441 if (tif->tif_flags & TIFF_SWAB) | |
| 1442 TIFFSwabLong8(&dircount64); | |
| 1443 if (dircount64>0xFFFF) | |
| 1444 { | |
| 1445 TIFFErrorExt(tif->tif_clientdata, module, "Error
fetching directory count"); | |
| 1446 return(0); | |
| 1447 } | |
| 1448 dircount16 = (uint16)dircount64; | |
| 1449 if (off != NULL) | |
| 1450 *off = TIFFSeekFile(tif, | |
| 1451 dircount16*20, SEEK_CUR); | |
| 1452 else | |
| 1453 (void) TIFFSeekFile(tif, | |
| 1454 dircount16*20, SEEK_CUR); | |
| 1455 if (!ReadOK(tif, nextdir, sizeof (uint64))) { | |
| 1456 TIFFErrorExt(tif->tif_clientdata, module, "%s: E
rror fetching directory link", | |
| 1457 tif->tif_name); | |
| 1458 return (0); | |
| 1459 } | |
| 1460 if (tif->tif_flags & TIFF_SWAB) | |
| 1461 TIFFSwabLong8(nextdir); | |
| 1462 } | |
| 1463 return (1); | |
| 1464 } | |
| 1465 } | |
| 1466 | |
| 1467 /* | |
| 1468 * Count the number of directories in a file. | |
| 1469 */ | |
| 1470 uint16 | |
| 1471 TIFFNumberOfDirectories(TIFF* tif) | |
| 1472 { | |
| 1473 uint64 nextdir; | |
| 1474 uint16 n; | |
| 1475 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
| 1476 nextdir = tif->tif_header.classic.tiff_diroff; | |
| 1477 else | |
| 1478 nextdir = tif->tif_header.big.tiff_diroff; | |
| 1479 n = 0; | |
| 1480 while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) | |
| 1481 n++; | |
| 1482 return (n); | |
| 1483 } | |
| 1484 | |
| 1485 /* | |
| 1486 * Set the n-th directory as the current directory. | |
| 1487 * NB: Directories are numbered starting at 0. | |
| 1488 */ | |
| 1489 int | |
| 1490 TIFFSetDirectory(TIFF* tif, uint16 dirn) | |
| 1491 { | |
| 1492 uint64 nextdir; | |
| 1493 uint16 n; | |
| 1494 | |
| 1495 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
| 1496 nextdir = tif->tif_header.classic.tiff_diroff; | |
| 1497 else | |
| 1498 nextdir = tif->tif_header.big.tiff_diroff; | |
| 1499 for (n = dirn; n > 0 && nextdir != 0; n--) | |
| 1500 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) | |
| 1501 return (0); | |
| 1502 tif->tif_nextdiroff = nextdir; | |
| 1503 /* | |
| 1504 * Set curdir to the actual directory index. The | |
| 1505 * -1 is because TIFFReadDirectory will increment | |
| 1506 * tif_curdir after successfully reading the directory. | |
| 1507 */ | |
| 1508 tif->tif_curdir = (dirn - n) - 1; | |
| 1509 /* | |
| 1510 * Reset tif_dirnumber counter and start new list of seen directories. | |
| 1511 * We need this to prevent IFD loops. | |
| 1512 */ | |
| 1513 tif->tif_dirnumber = 0; | |
| 1514 return (TIFFReadDirectory(tif)); | |
| 1515 } | |
| 1516 | |
| 1517 /* | |
| 1518 * Set the current directory to be the directory | |
| 1519 * located at the specified file offset. This interface | |
| 1520 * is used mainly to access directories linked with | |
| 1521 * the SubIFD tag (e.g. thumbnail images). | |
| 1522 */ | |
| 1523 int | |
| 1524 TIFFSetSubDirectory(TIFF* tif, uint64 diroff) | |
| 1525 { | |
| 1526 tif->tif_nextdiroff = diroff; | |
| 1527 /* | |
| 1528 * Reset tif_dirnumber counter and start new list of seen directories. | |
| 1529 * We need this to prevent IFD loops. | |
| 1530 */ | |
| 1531 tif->tif_dirnumber = 0; | |
| 1532 return (TIFFReadDirectory(tif)); | |
| 1533 } | |
| 1534 | |
| 1535 /* | |
| 1536 * Return file offset of the current directory. | |
| 1537 */ | |
| 1538 uint64 | |
| 1539 TIFFCurrentDirOffset(TIFF* tif) | |
| 1540 { | |
| 1541 return (tif->tif_diroff); | |
| 1542 } | |
| 1543 | |
| 1544 /* | |
| 1545 * Return an indication of whether or not we are | |
| 1546 * at the last directory in the file. | |
| 1547 */ | |
| 1548 int | |
| 1549 TIFFLastDirectory(TIFF* tif) | |
| 1550 { | |
| 1551 return (tif->tif_nextdiroff == 0); | |
| 1552 } | |
| 1553 | |
| 1554 /* | |
| 1555 * Unlink the specified directory from the directory chain. | |
| 1556 */ | |
| 1557 int | |
| 1558 TIFFUnlinkDirectory(TIFF* tif, uint16 dirn) | |
| 1559 { | |
| 1560 static const char module[] = "TIFFUnlinkDirectory"; | |
| 1561 uint64 nextdir; | |
| 1562 uint64 off; | |
| 1563 uint16 n; | |
| 1564 | |
| 1565 if (tif->tif_mode == O_RDONLY) { | |
| 1566 TIFFErrorExt(tif->tif_clientdata, module, | |
| 1567 "Can not unlink directory in read-only file"); | |
| 1568 return (0); | |
| 1569 } | |
| 1570 /* | |
| 1571 * Go to the directory before the one we want | |
| 1572 * to unlink and nab the offset of the link | |
| 1573 * field we'll need to patch. | |
| 1574 */ | |
| 1575 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
| 1576 { | |
| 1577 nextdir = tif->tif_header.classic.tiff_diroff; | |
| 1578 off = 4; | |
| 1579 } | |
| 1580 else | |
| 1581 { | |
| 1582 nextdir = tif->tif_header.big.tiff_diroff; | |
| 1583 off = 8; | |
| 1584 } | |
| 1585 for (n = dirn-1; n > 0; n--) { | |
| 1586 if (nextdir == 0) { | |
| 1587 TIFFErrorExt(tif->tif_clientdata, module, "Directory %d
does not exist", dirn); | |
| 1588 return (0); | |
| 1589 } | |
| 1590 if (!TIFFAdvanceDirectory(tif, &nextdir, &off)) | |
| 1591 return (0); | |
| 1592 } | |
| 1593 /* | |
| 1594 * Advance to the directory to be unlinked and fetch | |
| 1595 * the offset of the directory that follows. | |
| 1596 */ | |
| 1597 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) | |
| 1598 return (0); | |
| 1599 /* | |
| 1600 * Go back and patch the link field of the preceding | |
| 1601 * directory to point to the offset of the directory | |
| 1602 * that follows. | |
| 1603 */ | |
| 1604 (void) TIFFSeekFile(tif, off, SEEK_SET); | |
| 1605 if (!(tif->tif_flags&TIFF_BIGTIFF)) | |
| 1606 { | |
| 1607 uint32 nextdir32; | |
| 1608 nextdir32=(uint32)nextdir; | |
| 1609 assert((uint64)nextdir32==nextdir); | |
| 1610 if (tif->tif_flags & TIFF_SWAB) | |
| 1611 TIFFSwabLong(&nextdir32); | |
| 1612 if (!WriteOK(tif, &nextdir32, sizeof (uint32))) { | |
| 1613 TIFFErrorExt(tif->tif_clientdata, module, "Error writing
directory link"); | |
| 1614 return (0); | |
| 1615 } | |
| 1616 } | |
| 1617 else | |
| 1618 { | |
| 1619 if (tif->tif_flags & TIFF_SWAB) | |
| 1620 TIFFSwabLong8(&nextdir); | |
| 1621 if (!WriteOK(tif, &nextdir, sizeof (uint64))) { | |
| 1622 TIFFErrorExt(tif->tif_clientdata, module, "Error writing
directory link"); | |
| 1623 return (0); | |
| 1624 } | |
| 1625 } | |
| 1626 /* | |
| 1627 * Leave directory state setup safely. We don't have | |
| 1628 * facilities for doing inserting and removing directories, | |
| 1629 * so it's safest to just invalidate everything. This | |
| 1630 * means that the caller can only append to the directory | |
| 1631 * chain. | |
| 1632 */ | |
| 1633 (*tif->tif_cleanup)(tif); | |
| 1634 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { | |
| 1635 _TIFFfree(tif->tif_rawdata); | |
| 1636 tif->tif_rawdata = NULL; | |
| 1637 tif->tif_rawcc = 0; | |
| 1638 tif->tif_rawdataoff = 0; | |
| 1639 tif->tif_rawdataloaded = 0; | |
| 1640 } | |
| 1641 tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TI
FF_BUF4WRITE); | |
| 1642 TIFFFreeDirectory(tif); | |
| 1643 TIFFDefaultDirectory(tif); | |
| 1644 tif->tif_diroff = 0; /* force link on next write */ | |
| 1645 tif->tif_nextdiroff = 0; /* next write must be at end */ | |
| 1646 tif->tif_curoff = 0; | |
| 1647 tif->tif_row = (uint32) -1; | |
| 1648 tif->tif_curstrip = (uint32) -1; | |
| 1649 return (1); | |
| 1650 } | |
| 1651 | |
| 1652 /* vim: set ts=8 sts=8 sw=8 noet: */ | |
| 1653 /* | |
| 1654 * Local Variables: | |
| 1655 * mode: c | |
| 1656 * c-basic-offset: 8 | |
| 1657 * fill-column: 78 | |
| 1658 * End: | |
| 1659 */ | |
| 1660 | |
| OLD | NEW |