1/* $Id: tif_dir.c 276 2010-06-30 12:18:30Z nijtmans $ */ 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 43static void 44setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size) 45{ 46 if (*vpp) 47 _TIFFfree(*vpp), *vpp = 0; 48 if (vp) { 49 tsize_t bytes = 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} 56void _TIFFsetByteArray(void** vpp, void* vp, uint32 n) 57 { setByteArray(vpp, vp, n, 1); } 58void _TIFFsetString(char** cpp, char* cp) 59 { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); } 60void _TIFFsetNString(char** cpp, char* cp, uint32 n) 61 { setByteArray((void**) cpp, (void*) cp, n, 1); } 62void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n) 63 { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); } 64void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n) 65 { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); } 66void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n) 67 { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); } 68void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n) 69 { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); } 70 71/* 72 * Install extra samples information. 73 */ 74static int 75setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v) 76{ 77/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */ 78#define EXTRASAMPLE_COREL_UNASSALPHA 999 79 80 uint16* va; 81 uint32 i; 82 83 *v = va_arg(ap, uint32); 84 if ((uint16) *v > td->td_samplesperpixel) 85 return 0; 86 va = va_arg(ap, uint16*); 87 if (*v > 0 && va == NULL) /* typically missing param */ 88 return 0; 89 for (i = 0; i < *v; i++) { 90 if (va[i] > EXTRASAMPLE_UNASSALPHA) { 91 /* 92 * XXX: Corel Draw is known to produce incorrect 93 * ExtraSamples tags which must be patched here if we 94 * want to be able to open some of the damaged TIFF 95 * files: 96 */ 97 if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA) 98 va[i] = EXTRASAMPLE_UNASSALPHA; 99 else 100 return 0; 101 } 102 } 103 td->td_extrasamples = (uint16) *v; 104 _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples); 105 return 1; 106 107#undef EXTRASAMPLE_COREL_UNASSALPHA 108} 109 110static uint32 111checkInkNamesString(TIFF* tif, uint32 slen, const char* s) 112{ 113 TIFFDirectory* td = &tif->tif_dir; 114 uint16 i = td->td_samplesperpixel; 115 116 if (slen > 0) { 117 const char* ep = s+slen; 118 const char* cp = s; 119 for (; i > 0; i--) { 120 for (; *cp != '\0'; cp++) 121 if (cp >= ep) 122 goto bad; 123 cp++; /* skip \0 */ 124 } 125 return (cp-s); 126 } 127bad: 128 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", 129 "%s: Invalid InkNames value; expecting %d names, found %d", 130 tif->tif_name, 131 td->td_samplesperpixel, 132 td->td_samplesperpixel-i); 133 return (0); 134} 135 136static int 137_TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) 138{ 139 static const char module[] = "_TIFFVSetField"; 140 141 TIFFDirectory* td = &tif->tif_dir; 142 int status = 1; 143 uint32 v32, i, v; 144 char* s; 145 146 switch (tag) { 147 case TIFFTAG_SUBFILETYPE: 148 td->td_subfiletype = va_arg(ap, uint32); 149 break; 150 case TIFFTAG_IMAGEWIDTH: 151 td->td_imagewidth = va_arg(ap, uint32); 152 break; 153 case TIFFTAG_IMAGELENGTH: 154 td->td_imagelength = va_arg(ap, uint32); 155 break; 156 case TIFFTAG_BITSPERSAMPLE: 157 td->td_bitspersample = (uint16) va_arg(ap, int); 158 /* 159 * If the data require post-decoding processing to byte-swap 160 * samples, set it up here. Note that since tags are required 161 * to be ordered, compression code can override this behaviour 162 * in the setup method if it wants to roll the post decoding 163 * work in with its normal work. 164 */ 165 if (tif->tif_flags & TIFF_SWAB) { 166 if (td->td_bitspersample == 16) 167 tif->tif_postdecode = _TIFFSwab16BitData; 168 else if (td->td_bitspersample == 24) 169 tif->tif_postdecode = _TIFFSwab24BitData; 170 else if (td->td_bitspersample == 32) 171 tif->tif_postdecode = _TIFFSwab32BitData; 172 else if (td->td_bitspersample == 64) 173 tif->tif_postdecode = _TIFFSwab64BitData; 174 else if (td->td_bitspersample == 128) /* two 64's */ 175 tif->tif_postdecode = _TIFFSwab64BitData; 176 } 177 break; 178 case TIFFTAG_COMPRESSION: 179 v = va_arg(ap, uint32) & 0xffff; 180 /* 181 * If we're changing the compression scheme, the notify the 182 * previous module so that it can cleanup any state it's 183 * setup. 184 */ 185 if (TIFFFieldSet(tif, FIELD_COMPRESSION)) { 186 if (td->td_compression == v) 187 break; 188 (*tif->tif_cleanup)(tif); 189 tif->tif_flags &= ~TIFF_CODERSETUP; 190 } 191 /* 192 * Setup new compression routine state. 193 */ 194 if( (status = TIFFSetCompressionScheme(tif, v)) != 0 ) 195 td->td_compression = (uint16) v; 196 else 197 status = 0; 198 break; 199 case TIFFTAG_PHOTOMETRIC: 200 td->td_photometric = (uint16) va_arg(ap, int); 201 break; 202 case TIFFTAG_THRESHHOLDING: 203 td->td_threshholding = (uint16) va_arg(ap, int); 204 break; 205 case TIFFTAG_FILLORDER: 206 v = va_arg(ap, uint32); 207 if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB) 208 goto badvalue; 209 td->td_fillorder = (uint16) v; 210 break; 211 case TIFFTAG_ORIENTATION: 212 v = va_arg(ap, uint32); 213 if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v) 214 goto badvalue; 215 else 216 td->td_orientation = (uint16) v; 217 break; 218 case TIFFTAG_SAMPLESPERPIXEL: 219 /* XXX should cross check -- e.g. if pallette, then 1 */ 220 v = va_arg(ap, uint32); 221 if (v == 0) 222 goto badvalue; 223 td->td_samplesperpixel = (uint16) v; 224 break; 225 case TIFFTAG_ROWSPERSTRIP: 226 v32 = va_arg(ap, uint32); 227 if (v32 == 0) 228 goto badvalue32; 229 td->td_rowsperstrip = v32; 230 if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) { 231 td->td_tilelength = v32; 232 td->td_tilewidth = td->td_imagewidth; 233 } 234 break; 235 case TIFFTAG_MINSAMPLEVALUE: 236 td->td_minsamplevalue = (uint16) va_arg(ap, int); 237 break; 238 case TIFFTAG_MAXSAMPLEVALUE: 239 td->td_maxsamplevalue = (uint16) va_arg(ap, int); 240 break; 241 case TIFFTAG_SMINSAMPLEVALUE: 242 td->td_sminsamplevalue = va_arg(ap, double); 243 break; 244 case TIFFTAG_SMAXSAMPLEVALUE: 245 td->td_smaxsamplevalue = va_arg(ap, double); 246 break; 247 case TIFFTAG_XRESOLUTION: 248 td->td_xresolution = (float) va_arg(ap, double); 249 break; 250 case TIFFTAG_YRESOLUTION: 251 td->td_yresolution = (float) va_arg(ap, double); 252 break; 253 case TIFFTAG_PLANARCONFIG: 254 v = va_arg(ap, uint32); 255 if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE) 256 goto badvalue; 257 td->td_planarconfig = (uint16) v; 258 break; 259 case TIFFTAG_XPOSITION: 260 td->td_xposition = (float) va_arg(ap, double); 261 break; 262 case TIFFTAG_YPOSITION: 263 td->td_yposition = (float) va_arg(ap, double); 264 break; 265 case TIFFTAG_RESOLUTIONUNIT: 266 v = va_arg(ap, uint32); 267 if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v) 268 goto badvalue; 269 td->td_resolutionunit = (uint16) v; 270 break; 271 case TIFFTAG_PAGENUMBER: 272 td->td_pagenumber[0] = (uint16) va_arg(ap, int); 273 td->td_pagenumber[1] = (uint16) va_arg(ap, int); 274 break; 275 case TIFFTAG_HALFTONEHINTS: 276 td->td_halftonehints[0] = (uint16) va_arg(ap, int); 277 td->td_halftonehints[1] = (uint16) va_arg(ap, int); 278 break; 279 case TIFFTAG_COLORMAP: 280 v32 = (uint32)(1L<<td->td_bitspersample); 281 _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32); 282 _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32); 283 _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32); 284 break; 285 case TIFFTAG_EXTRASAMPLES: 286 if (!setExtraSamples(td, ap, &v)) 287 goto badvalue; 288 break; 289 case TIFFTAG_MATTEING: 290 td->td_extrasamples = (uint16) (va_arg(ap, int) != 0); 291 if (td->td_extrasamples) { 292 uint16 sv = EXTRASAMPLE_ASSOCALPHA; 293 _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1); 294 } 295 break; 296 case TIFFTAG_TILEWIDTH: 297 v32 = va_arg(ap, uint32); 298 if (v32 % 16) { 299 if (tif->tif_mode != O_RDONLY) 300 goto badvalue32; 301 TIFFWarningExt(tif->tif_clientdata, tif->tif_name, 302 "Nonstandard tile width %d, convert file", v32); 303 } 304 td->td_tilewidth = v32; 305 tif->tif_flags |= TIFF_ISTILED; 306 break; 307 case TIFFTAG_TILELENGTH: 308 v32 = va_arg(ap, uint32); 309 if (v32 % 16) { 310 if (tif->tif_mode != O_RDONLY) 311 goto badvalue32; 312 TIFFWarningExt(tif->tif_clientdata, tif->tif_name, 313 "Nonstandard tile length %d, convert file", v32); 314 } 315 td->td_tilelength = v32; 316 tif->tif_flags |= TIFF_ISTILED; 317 break; 318 case TIFFTAG_TILEDEPTH: 319 v32 = va_arg(ap, uint32); 320 if (v32 == 0) 321 goto badvalue32; 322 td->td_tiledepth = v32; 323 break; 324 case TIFFTAG_DATATYPE: 325 v = va_arg(ap, uint32); 326 switch (v) { 327 case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break; 328 case DATATYPE_INT: v = SAMPLEFORMAT_INT; break; 329 case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break; 330 case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break; 331 default: goto badvalue; 332 } 333 td->td_sampleformat = (uint16) v; 334 break; 335 case TIFFTAG_SAMPLEFORMAT: 336 v = va_arg(ap, uint32); 337 if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v) 338 goto badvalue; 339 td->td_sampleformat = (uint16) v; 340 341 /* Try to fix up the SWAB function for complex data. */ 342 if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 343 && td->td_bitspersample == 32 344 && tif->tif_postdecode == _TIFFSwab32BitData ) 345 tif->tif_postdecode = _TIFFSwab16BitData; 346 else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT 347 || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) 348 && td->td_bitspersample == 64 349 && tif->tif_postdecode == _TIFFSwab64BitData ) 350 tif->tif_postdecode = _TIFFSwab32BitData; 351 break; 352 case TIFFTAG_IMAGEDEPTH: 353 td->td_imagedepth = va_arg(ap, uint32); 354 break; 355 case TIFFTAG_SUBIFD: 356 if ((tif->tif_flags & TIFF_INSUBIFD) == 0) { 357 td->td_nsubifd = (uint16) va_arg(ap, int); 358 _TIFFsetLongArray(&td->td_subifd, va_arg(ap, uint32*), 359 (long) td->td_nsubifd); 360 } else { 361 TIFFErrorExt(tif->tif_clientdata, module, 362 "%s: Sorry, cannot nest SubIFDs", 363 tif->tif_name); 364 status = 0; 365 } 366 break; 367 case TIFFTAG_YCBCRPOSITIONING: 368 td->td_ycbcrpositioning = (uint16) va_arg(ap, int); 369 break; 370 case TIFFTAG_YCBCRSUBSAMPLING: 371 td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, int); 372 td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, int); 373 break; 374 case TIFFTAG_TRANSFERFUNCTION: 375 v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1; 376 for (i = 0; i < v; i++) 377 _TIFFsetShortArray(&td->td_transferfunction[i], 378 va_arg(ap, uint16*), 1L<<td->td_bitspersample); 379 break; 380 case TIFFTAG_REFERENCEBLACKWHITE: 381 /* XXX should check for null range */ 382 _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6); 383 break; 384 case TIFFTAG_INKNAMES: 385 v = va_arg(ap, uint32); 386 s = va_arg(ap, char*); 387 v = checkInkNamesString(tif, v, s); 388 status = v > 0; 389 if( v > 0 ) { 390 _TIFFsetNString(&td->td_inknames, s, v); 391 td->td_inknameslen = v; 392 } 393 break; 394 default: { 395 TIFFTagValue *tv; 396 int tv_size, iCustom; 397 const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); 398 399 /* 400 * This can happen if multiple images are open with different 401 * codecs which have private tags. The global tag information 402 * table may then have tags that are valid for one file but not 403 * the other. If the client tries to set a tag that is not valid 404 * for the image's codec then we'll arrive here. This 405 * happens, for example, when tiffcp is used to convert between 406 * compression schemes and codec-specific tags are blindly copied. 407 */ 408 if(fip == NULL || fip->field_bit != FIELD_CUSTOM) { 409 TIFFErrorExt(tif->tif_clientdata, module, 410 "%s: Invalid %stag \"%s\" (not supported by codec)", 411 tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", 412 fip ? fip->field_name : "Unknown"); 413 status = 0; 414 break; 415 } 416 417 /* 418 * Find the existing entry for this custom value. 419 */ 420 tv = NULL; 421 for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) { 422 if (td->td_customValues[iCustom].info->field_tag == tag) { 423 tv = td->td_customValues + iCustom; 424 if (tv->value != NULL) { 425 _TIFFfree(tv->value); 426 tv->value = NULL; 427 } 428 break; 429 } 430 } 431 432 /* 433 * Grow the custom list if the entry was not found. 434 */ 435 if(tv == NULL) { 436 TIFFTagValue *new_customValues; 437 438 td->td_customValueCount++; 439 new_customValues = (TIFFTagValue *) 440 _TIFFrealloc(td->td_customValues, 441 sizeof(TIFFTagValue) * td->td_customValueCount); 442 if (!new_customValues) { 443 TIFFErrorExt(tif->tif_clientdata, module, 444 "%s: Failed to allocate space for list of custom values", 445 tif->tif_name); 446 status = 0; 447 goto end; 448 } 449 450 td->td_customValues = new_customValues; 451 452 tv = td->td_customValues + (td->td_customValueCount - 1); 453 tv->info = fip; 454 tv->value = NULL; 455 tv->count = 0; 456 } 457 458 /* 459 * Set custom value ... save a copy of the custom tag value. 460 */ 461 tv_size = _TIFFDataSize(fip->field_type); 462 if (tv_size == 0) { 463 status = 0; 464 TIFFErrorExt(tif->tif_clientdata, module, 465 "%s: Bad field type %d for \"%s\"", 466 tif->tif_name, fip->field_type, 467 fip->field_name); 468 goto end; 469 } 470 471 if(fip->field_passcount) { 472 if (fip->field_writecount == TIFF_VARIABLE2) 473 tv->count = (uint32) va_arg(ap, uint32); 474 else 475 tv->count = (int) va_arg(ap, int); 476 } else if (fip->field_writecount == TIFF_VARIABLE 477 || fip->field_writecount == TIFF_VARIABLE2) 478 tv->count = 1; 479 else if (fip->field_writecount == TIFF_SPP) 480 tv->count = td->td_samplesperpixel; 481 else 482 tv->count = fip->field_writecount; 483 484 485 if (fip->field_type == TIFF_ASCII) 486 _TIFFsetString((char **)&tv->value, va_arg(ap, char *)); 487 else { 488 tv->value = _TIFFCheckMalloc(tif, tv_size, tv->count, 489 "Tag Value"); 490 if (!tv->value) { 491 status = 0; 492 goto end; 493 } 494 495 if ((fip->field_passcount 496 || fip->field_writecount == TIFF_VARIABLE 497 || fip->field_writecount == TIFF_VARIABLE2 498 || fip->field_writecount == TIFF_SPP 499 || tv->count > 1) 500 && fip->field_tag != TIFFTAG_PAGENUMBER 501 && fip->field_tag != TIFFTAG_HALFTONEHINTS 502 && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING 503 && fip->field_tag != TIFFTAG_DOTRANGE) { 504 _TIFFmemcpy(tv->value, va_arg(ap, void *), 505 tv->count * tv_size); 506 } else { 507 /* 508 * XXX: The following loop required to handle 509 * TIFFTAG_PAGENUMBER, TIFFTAG_HALFTONEHINTS, 510 * TIFFTAG_YCBCRSUBSAMPLING and TIFFTAG_DOTRANGE tags. 511 * These tags are actually arrays and should be passed as 512 * array pointers to TIFFSetField() function, but actually 513 * passed as a list of separate values. This behaviour 514 * must be changed in the future! 515 */ 516 int i; 517 char *val = (char *)tv->value; 518 519 for (i = 0; i < tv->count; i++, val += tv_size) { 520 switch (fip->field_type) { 521 case TIFF_BYTE: 522 case TIFF_UNDEFINED: 523 { 524 uint8 v = (uint8)va_arg(ap, int); 525 _TIFFmemcpy(val, &v, tv_size); 526 } 527 break; 528 case TIFF_SBYTE: 529 { 530 int8 v = (int8)va_arg(ap, int); 531 _TIFFmemcpy(val, &v, tv_size); 532 } 533 break; 534 case TIFF_SHORT: 535 { 536 uint16 v = (uint16)va_arg(ap, int); 537 _TIFFmemcpy(val, &v, tv_size); 538 } 539 break; 540 case TIFF_SSHORT: 541 { 542 int16 v = (int16)va_arg(ap, int); 543 _TIFFmemcpy(val, &v, tv_size); 544 } 545 break; 546 case TIFF_LONG: 547 case TIFF_IFD: 548 { 549 uint32 v = va_arg(ap, uint32); 550 _TIFFmemcpy(val, &v, tv_size); 551 } 552 break; 553 case TIFF_SLONG: 554 { 555 int32 v = va_arg(ap, int32); 556 _TIFFmemcpy(val, &v, tv_size); 557 } 558 break; 559 case TIFF_RATIONAL: 560 case TIFF_SRATIONAL: 561 case TIFF_FLOAT: 562 { 563 float v = (float)va_arg(ap, double); 564 _TIFFmemcpy(val, &v, tv_size); 565 } 566 break; 567 case TIFF_DOUBLE: 568 { 569 double v = va_arg(ap, double); 570 _TIFFmemcpy(val, &v, tv_size); 571 } 572 break; 573 default: 574 _TIFFmemset(val, 0, tv_size); 575 status = 0; 576 break; 577 } 578 } 579 } 580 } 581 } 582 } 583 if (status) { 584 TIFFSetFieldBit(tif, _TIFFFieldWithTag(tif, tag)->field_bit); 585 tif->tif_flags |= TIFF_DIRTYDIRECT; 586 } 587 588end: 589 va_end(ap); 590 return (status); 591badvalue: 592 TIFFErrorExt(tif->tif_clientdata, module, 593 "%s: Bad value %d for \"%s\" tag", 594 tif->tif_name, v, 595 _TIFFFieldWithTag(tif, tag)->field_name); 596 va_end(ap); 597 return (0); 598badvalue32: 599 TIFFErrorExt(tif->tif_clientdata, module, 600 "%s: Bad value %u for \"%s\" tag", 601 tif->tif_name, v32, 602 _TIFFFieldWithTag(tif, tag)->field_name); 603 va_end(ap); 604 return (0); 605} 606 607/* 608 * Return 1/0 according to whether or not 609 * it is permissible to set the tag's value. 610 * Note that we allow ImageLength to be changed 611 * so that we can append and extend to images. 612 * Any other tag may not be altered once writing 613 * has commenced, unless its value has no effect 614 * on the format of the data that is written. 615 */ 616static int 617OkToChangeTag(TIFF* tif, ttag_t tag) 618{ 619 const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); 620 if (!fip) { /* unknown tag */ 621 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u", 622 tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag); 623 return (0); 624 } 625 if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) && 626 !fip->field_oktochange) { 627 /* 628 * Consult info table to see if tag can be changed 629 * after we've started writing. We only allow changes 630 * to those tags that don't/shouldn't affect the 631 * compression and/or format of the data. 632 */ 633 TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", 634 "%s: Cannot modify tag \"%s\" while writing", 635 tif->tif_name, fip->field_name); 636 return (0); 637 } 638 return (1); 639} 640 641/* 642 * Record the value of a field in the 643 * internal directory structure. The 644 * field will be written to the file 645 * when/if the directory structure is 646 * updated. 647 */ 648int 649TIFFSetField(TIFF* tif, ttag_t tag, ...) 650{ 651 va_list ap; 652 int status; 653 654 va_start(ap, tag); 655 status = TIFFVSetField(tif, tag, ap); 656 va_end(ap); 657 return (status); 658} 659 660/* 661 * Like TIFFSetField, but taking a varargs 662 * parameter list. This routine is useful 663 * for building higher-level interfaces on 664 * top of the library. 665 */ 666int 667TIFFVSetField(TIFF* tif, ttag_t tag, va_list ap) 668{ 669 return OkToChangeTag(tif, tag) ? 670 (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0; 671} 672 673static int 674_TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) 675{ 676 TIFFDirectory* td = &tif->tif_dir; 677 int ret_val = 1; 678 679 switch (tag) { 680 case TIFFTAG_SUBFILETYPE: 681 *va_arg(ap, uint32*) = td->td_subfiletype; 682 break; 683 case TIFFTAG_IMAGEWIDTH: 684 *va_arg(ap, uint32*) = td->td_imagewidth; 685 break; 686 case TIFFTAG_IMAGELENGTH: 687 *va_arg(ap, uint32*) = td->td_imagelength; 688 break; 689 case TIFFTAG_BITSPERSAMPLE: 690 *va_arg(ap, uint16*) = td->td_bitspersample; 691 break; 692 case TIFFTAG_COMPRESSION: 693 *va_arg(ap, uint16*) = td->td_compression; 694 break; 695 case TIFFTAG_PHOTOMETRIC: 696 *va_arg(ap, uint16*) = td->td_photometric; 697 break; 698 case TIFFTAG_THRESHHOLDING: 699 *va_arg(ap, uint16*) = td->td_threshholding; 700 break; 701 case TIFFTAG_FILLORDER: 702 *va_arg(ap, uint16*) = td->td_fillorder; 703 break; 704 case TIFFTAG_ORIENTATION: 705 *va_arg(ap, uint16*) = td->td_orientation; 706 break; 707 case TIFFTAG_SAMPLESPERPIXEL: 708 *va_arg(ap, uint16*) = td->td_samplesperpixel; 709 break; 710 case TIFFTAG_ROWSPERSTRIP: 711 *va_arg(ap, uint32*) = td->td_rowsperstrip; 712 break; 713 case TIFFTAG_MINSAMPLEVALUE: 714 *va_arg(ap, uint16*) = td->td_minsamplevalue; 715 break; 716 case TIFFTAG_MAXSAMPLEVALUE: 717 *va_arg(ap, uint16*) = td->td_maxsamplevalue; 718 break; 719 case TIFFTAG_SMINSAMPLEVALUE: 720 *va_arg(ap, double*) = td->td_sminsamplevalue; 721 break; 722 case TIFFTAG_SMAXSAMPLEVALUE: 723 *va_arg(ap, double*) = td->td_smaxsamplevalue; 724 break; 725 case TIFFTAG_XRESOLUTION: 726 *va_arg(ap, float*) = td->td_xresolution; 727 break; 728 case TIFFTAG_YRESOLUTION: 729 *va_arg(ap, float*) = td->td_yresolution; 730 break; 731 case TIFFTAG_PLANARCONFIG: 732 *va_arg(ap, uint16*) = td->td_planarconfig; 733 break; 734 case TIFFTAG_XPOSITION: 735 *va_arg(ap, float*) = td->td_xposition; 736 break; 737 case TIFFTAG_YPOSITION: 738 *va_arg(ap, float*) = td->td_yposition; 739 break; 740 case TIFFTAG_RESOLUTIONUNIT: 741 *va_arg(ap, uint16*) = td->td_resolutionunit; 742 break; 743 case TIFFTAG_PAGENUMBER: 744 *va_arg(ap, uint16*) = td->td_pagenumber[0]; 745 *va_arg(ap, uint16*) = td->td_pagenumber[1]; 746 break; 747 case TIFFTAG_HALFTONEHINTS: 748 *va_arg(ap, uint16*) = td->td_halftonehints[0]; 749 *va_arg(ap, uint16*) = td->td_halftonehints[1]; 750 break; 751 case TIFFTAG_COLORMAP: 752 *va_arg(ap, uint16**) = td->td_colormap[0]; 753 *va_arg(ap, uint16**) = td->td_colormap[1]; 754 *va_arg(ap, uint16**) = td->td_colormap[2]; 755 break; 756 case TIFFTAG_STRIPOFFSETS: 757 case TIFFTAG_TILEOFFSETS: 758 *va_arg(ap, uint32**) = td->td_stripoffset; 759 break; 760 case TIFFTAG_STRIPBYTECOUNTS: 761 case TIFFTAG_TILEBYTECOUNTS: 762 *va_arg(ap, uint32**) = td->td_stripbytecount; 763 break; 764 case TIFFTAG_MATTEING: 765 *va_arg(ap, uint16*) = 766 (td->td_extrasamples == 1 && 767 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA); 768 break; 769 case TIFFTAG_EXTRASAMPLES: 770 *va_arg(ap, uint16*) = td->td_extrasamples; 771 *va_arg(ap, uint16**) = td->td_sampleinfo; 772 break; 773 case TIFFTAG_TILEWIDTH: 774 *va_arg(ap, uint32*) = td->td_tilewidth; 775 break; 776 case TIFFTAG_TILELENGTH: 777 *va_arg(ap, uint32*) = td->td_tilelength; 778 break; 779 case TIFFTAG_TILEDEPTH: 780 *va_arg(ap, uint32*) = td->td_tiledepth; 781 break; 782 case TIFFTAG_DATATYPE: 783 switch (td->td_sampleformat) { 784 case SAMPLEFORMAT_UINT: 785 *va_arg(ap, uint16*) = DATATYPE_UINT; 786 break; 787 case SAMPLEFORMAT_INT: 788 *va_arg(ap, uint16*) = DATATYPE_INT; 789 break; 790 case SAMPLEFORMAT_IEEEFP: 791 *va_arg(ap, uint16*) = DATATYPE_IEEEFP; 792 break; 793 case SAMPLEFORMAT_VOID: 794 *va_arg(ap, uint16*) = DATATYPE_VOID; 795 break; 796 } 797 break; 798 case TIFFTAG_SAMPLEFORMAT: 799 *va_arg(ap, uint16*) = td->td_sampleformat; 800 break; 801 case TIFFTAG_IMAGEDEPTH: 802 *va_arg(ap, uint32*) = td->td_imagedepth; 803 break; 804 case TIFFTAG_SUBIFD: 805 *va_arg(ap, uint16*) = td->td_nsubifd; 806 *va_arg(ap, uint32**) = td->td_subifd; 807 break; 808 case TIFFTAG_YCBCRPOSITIONING: 809 *va_arg(ap, uint16*) = td->td_ycbcrpositioning; 810 break; 811 case TIFFTAG_YCBCRSUBSAMPLING: 812 *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0]; 813 *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1]; 814 break; 815 case TIFFTAG_TRANSFERFUNCTION: 816 *va_arg(ap, uint16**) = td->td_transferfunction[0]; 817 if (td->td_samplesperpixel - td->td_extrasamples > 1) { 818 *va_arg(ap, uint16**) = td->td_transferfunction[1]; 819 *va_arg(ap, uint16**) = td->td_transferfunction[2]; 820 } 821 break; 822 case TIFFTAG_REFERENCEBLACKWHITE: 823 *va_arg(ap, float**) = td->td_refblackwhite; 824 break; 825 case TIFFTAG_INKNAMES: 826 *va_arg(ap, char**) = td->td_inknames; 827 break; 828 default: 829 { 830 const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); 831 int i; 832 833 /* 834 * This can happen if multiple images are open with different 835 * codecs which have private tags. The global tag information 836 * table may then have tags that are valid for one file but not 837 * the other. If the client tries to get a tag that is not valid 838 * for the image's codec then we'll arrive here. 839 */ 840 if( fip == NULL || fip->field_bit != FIELD_CUSTOM ) 841 { 842 TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField", 843 "%s: Invalid %stag \"%s\" " 844 "(not supported by codec)", 845 tif->tif_name, 846 isPseudoTag(tag) ? "pseudo-" : "", 847 fip ? fip->field_name : "Unknown"); 848 ret_val = 0; 849 break; 850 } 851 852 /* 853 * Do we have a custom value? 854 */ 855 ret_val = 0; 856 for (i = 0; i < td->td_customValueCount; i++) { 857 TIFFTagValue *tv = td->td_customValues + i; 858 859 if (tv->info->field_tag != tag) 860 continue; 861 862 if (fip->field_passcount) { 863 if (fip->field_readcount == TIFF_VARIABLE2) 864 *va_arg(ap, uint32*) = (uint32)tv->count; 865 else /* Assume TIFF_VARIABLE */ 866 *va_arg(ap, uint16*) = (uint16)tv->count; 867 *va_arg(ap, void **) = tv->value; 868 ret_val = 1; 869 } else { 870 if ((fip->field_type == TIFF_ASCII 871 || fip->field_readcount == TIFF_VARIABLE 872 || fip->field_readcount == TIFF_VARIABLE2 873 || fip->field_readcount == TIFF_SPP 874 || tv->count > 1) 875 && fip->field_tag != TIFFTAG_PAGENUMBER 876 && fip->field_tag != TIFFTAG_HALFTONEHINTS 877 && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING 878 && fip->field_tag != TIFFTAG_DOTRANGE) { 879 *va_arg(ap, void **) = tv->value; 880 ret_val = 1; 881 } else { 882 int j; 883 char *val = (char *)tv->value; 884 885 for (j = 0; j < tv->count; 886 j++, val += _TIFFDataSize(tv->info->field_type)) { 887 switch (fip->field_type) { 888 case TIFF_BYTE: 889 case TIFF_UNDEFINED: 890 *va_arg(ap, uint8*) = 891 *(uint8 *)val; 892 ret_val = 1; 893 break; 894 case TIFF_SBYTE: 895 *va_arg(ap, int8*) = 896 *(int8 *)val; 897 ret_val = 1; 898 break; 899 case TIFF_SHORT: 900 *va_arg(ap, uint16*) = 901 *(uint16 *)val; 902 ret_val = 1; 903 break; 904 case TIFF_SSHORT: 905 *va_arg(ap, int16*) = 906 *(int16 *)val; 907 ret_val = 1; 908 break; 909 case TIFF_LONG: 910 case TIFF_IFD: 911 *va_arg(ap, uint32*) = 912 *(uint32 *)val; 913 ret_val = 1; 914 break; 915 case TIFF_SLONG: 916 *va_arg(ap, int32*) = 917 *(int32 *)val; 918 ret_val = 1; 919 break; 920 case TIFF_RATIONAL: 921 case TIFF_SRATIONAL: 922 case TIFF_FLOAT: 923 *va_arg(ap, float*) = 924 *(float *)val; 925 ret_val = 1; 926 break; 927 case TIFF_DOUBLE: 928 *va_arg(ap, double*) = 929 *(double *)val; 930 ret_val = 1; 931 break; 932 default: 933 ret_val = 0; 934 break; 935 } 936 } 937 } 938 } 939 break; 940 } 941 } 942 } 943 return(ret_val); 944} 945 946/* 947 * Return the value of a field in the 948 * internal directory structure. 949 */ 950int 951TIFFGetField(TIFF* tif, ttag_t tag, ...) 952{ 953 int status; 954 va_list ap; 955 956 va_start(ap, tag); 957 status = TIFFVGetField(tif, tag, ap); 958 va_end(ap); 959 return (status); 960} 961 962/* 963 * Like TIFFGetField, but taking a varargs 964 * parameter list. This routine is useful 965 * for building higher-level interfaces on 966 * top of the library. 967 */ 968int 969TIFFVGetField(TIFF* tif, ttag_t tag, va_list ap) 970{ 971 const TIFFFieldInfo* fip = _TIFFFindFieldInfo(tif, tag, TIFF_ANY); 972 return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ? 973 (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0); 974} 975 976#define CleanupField(member) { \ 977 if (td->member) { \ 978 _TIFFfree(td->member); \ 979 td->member = 0; \ 980 } \ 981} 982 983/* 984 * Release storage associated with a directory. 985 */ 986void 987TIFFFreeDirectory(TIFF* tif) 988{ 989 TIFFDirectory *td = &tif->tif_dir; 990 int i; 991 992 _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS); 993 CleanupField(td_colormap[0]); 994 CleanupField(td_colormap[1]); 995 CleanupField(td_colormap[2]); 996 CleanupField(td_sampleinfo); 997 CleanupField(td_subifd); 998 CleanupField(td_inknames); 999 CleanupField(td_refblackwhite); 1000 CleanupField(td_transferfunction[0]); 1001 CleanupField(td_transferfunction[1]); 1002 CleanupField(td_transferfunction[2]); 1003 CleanupField(td_stripoffset); 1004 CleanupField(td_stripbytecount); 1005 TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING); 1006 TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING); 1007 1008 /* Cleanup custom tag values */ 1009 for( i = 0; i < td->td_customValueCount; i++ ) { 1010 if (td->td_customValues[i].value) 1011 _TIFFfree(td->td_customValues[i].value); 1012 } 1013 1014 td->td_customValueCount = 0; 1015 CleanupField(td_customValues); 1016} 1017#undef CleanupField 1018 1019/* 1020 * Client Tag extension support (from Niles Ritter). 1021 */ 1022static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL; 1023 1024TIFFExtendProc 1025TIFFSetTagExtender(TIFFExtendProc extender) 1026{ 1027 TIFFExtendProc prev = _TIFFextender; 1028 _TIFFextender = extender; 1029 return (prev); 1030} 1031 1032/* 1033 * Setup for a new directory. Should we automatically call 1034 * TIFFWriteDirectory() if the current one is dirty? 1035 * 1036 * The newly created directory will not exist on the file till 1037 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called. 1038 */ 1039int 1040TIFFCreateDirectory(TIFF* tif) 1041{ 1042 TIFFDefaultDirectory(tif); 1043 tif->tif_diroff = 0; 1044 tif->tif_nextdiroff = 0; 1045 tif->tif_curoff = 0; 1046 tif->tif_row = (uint32) -1; 1047 tif->tif_curstrip = (tstrip_t) -1; 1048 1049 return 0; 1050} 1051 1052/* 1053 * Setup a default directory structure. 1054 */ 1055int 1056TIFFDefaultDirectory(TIFF* tif) 1057{ 1058 register TIFFDirectory* td = &tif->tif_dir; 1059 1060 size_t tiffFieldInfoCount; 1061 const TIFFFieldInfo *tiffFieldInfo = 1062 _TIFFGetFieldInfo(&tiffFieldInfoCount); 1063 _TIFFSetupFieldInfo(tif, tiffFieldInfo, tiffFieldInfoCount); 1064 1065 _TIFFmemset(td, 0, sizeof (*td)); 1066 td->td_fillorder = FILLORDER_MSB2LSB; 1067 td->td_bitspersample = 1; 1068 td->td_threshholding = THRESHHOLD_BILEVEL; 1069 td->td_orientation = ORIENTATION_TOPLEFT; 1070 td->td_samplesperpixel = 1; 1071 td->td_rowsperstrip = (uint32) -1; 1072 td->td_tilewidth = 0; 1073 td->td_tilelength = 0; 1074 td->td_tiledepth = 1; 1075 td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */ 1076 td->td_resolutionunit = RESUNIT_INCH; 1077 td->td_sampleformat = SAMPLEFORMAT_UINT; 1078 td->td_imagedepth = 1; 1079 td->td_ycbcrsubsampling[0] = 2; 1080 td->td_ycbcrsubsampling[1] = 2; 1081 td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED; 1082 tif->tif_postdecode = _TIFFNoPostDecode; 1083 tif->tif_foundfield = NULL; 1084 tif->tif_tagmethods.vsetfield = _TIFFVSetField; 1085 tif->tif_tagmethods.vgetfield = _TIFFVGetField; 1086 tif->tif_tagmethods.printdir = NULL; 1087 /* 1088 * Give client code a chance to install their own 1089 * tag extensions & methods, prior to compression overloads. 1090 */ 1091 if (_TIFFextender) 1092 (*_TIFFextender)(tif); 1093 (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE); 1094 /* 1095 * NB: The directory is marked dirty as a result of setting 1096 * up the default compression scheme. However, this really 1097 * isn't correct -- we want TIFF_DIRTYDIRECT to be set only 1098 * if the user does something. We could just do the setup 1099 * by hand, but it seems better to use the normal mechanism 1100 * (i.e. TIFFSetField). 1101 */ 1102 tif->tif_flags &= ~TIFF_DIRTYDIRECT; 1103 1104 /* 1105 * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19 1106 * we clear the ISTILED flag when setting up a new directory. 1107 * Should we also be clearing stuff like INSUBIFD? 1108 */ 1109 tif->tif_flags &= ~TIFF_ISTILED; 1110 /* 1111 * Clear other directory-specific fields. 1112 */ 1113 tif->tif_tilesize = -1; 1114 tif->tif_scanlinesize = -1; 1115 1116 return (1); 1117} 1118 1119static int 1120TIFFAdvanceDirectory(TIFF* tif, uint32* nextdir, toff_t* off) 1121{ 1122 static const char module[] = "TIFFAdvanceDirectory"; 1123 uint16 dircount; 1124 if (isMapped(tif)) 1125 { 1126 toff_t poff=*nextdir; 1127 if (poff+sizeof(uint16) > tif->tif_size) 1128 { 1129 TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", 1130 tif->tif_name); 1131 return (0); 1132 } 1133 _TIFFmemcpy(&dircount, tif->tif_base+poff, sizeof (uint16)); 1134 if (tif->tif_flags & TIFF_SWAB) 1135 TIFFSwabShort(&dircount); 1136 poff+=sizeof (uint16)+dircount*sizeof (TIFFDirEntry); 1137 if (off != NULL) 1138 *off = poff; 1139 if (((toff_t) (poff+sizeof (uint32))) > tif->tif_size) 1140 { 1141 TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link", 1142 tif->tif_name); 1143 return (0); 1144 } 1145 _TIFFmemcpy(nextdir, tif->tif_base+poff, sizeof (uint32)); 1146 if (tif->tif_flags & TIFF_SWAB) 1147 TIFFSwabLong(nextdir); 1148 return (1); 1149 } 1150 else 1151 { 1152 if (!SeekOK(tif, *nextdir) || 1153 !ReadOK(tif, &dircount, sizeof (uint16))) { 1154 TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count", 1155 tif->tif_name); 1156 return (0); 1157 } 1158 if (tif->tif_flags & TIFF_SWAB) 1159 TIFFSwabShort(&dircount); 1160 if (off != NULL) 1161 *off = TIFFSeekFile(tif, 1162 dircount*sizeof (TIFFDirEntry), SEEK_CUR); 1163 else 1164 (void) TIFFSeekFile(tif, 1165 dircount*sizeof (TIFFDirEntry), SEEK_CUR); 1166 if (!ReadOK(tif, nextdir, sizeof (uint32))) { 1167 TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link", 1168 tif->tif_name); 1169 return (0); 1170 } 1171 if (tif->tif_flags & TIFF_SWAB) 1172 TIFFSwabLong(nextdir); 1173 return (1); 1174 } 1175} 1176 1177/* 1178 * Count the number of directories in a file. 1179 */ 1180tdir_t 1181TIFFNumberOfDirectories(TIFF* tif) 1182{ 1183 toff_t nextdir = tif->tif_header.tiff_diroff; 1184 tdir_t n = 0; 1185 1186 while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL)) 1187 n++; 1188 return (n); 1189} 1190 1191/* 1192 * Set the n-th directory as the current directory. 1193 * NB: Directories are numbered starting at 0. 1194 */ 1195int 1196TIFFSetDirectory(TIFF* tif, tdir_t dirn) 1197{ 1198 toff_t nextdir; 1199 tdir_t n; 1200 1201 nextdir = tif->tif_header.tiff_diroff; 1202 for (n = dirn; n > 0 && nextdir != 0; n--) 1203 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) 1204 return (0); 1205 tif->tif_nextdiroff = nextdir; 1206 /* 1207 * Set curdir to the actual directory index. The 1208 * -1 is because TIFFReadDirectory will increment 1209 * tif_curdir after successfully reading the directory. 1210 */ 1211 tif->tif_curdir = (dirn - n) - 1; 1212 /* 1213 * Reset tif_dirnumber counter and start new list of seen directories. 1214 * We need this to prevent IFD loops. 1215 */ 1216 tif->tif_dirnumber = 0; 1217 return (TIFFReadDirectory(tif)); 1218} 1219 1220/* 1221 * Set the current directory to be the directory 1222 * located at the specified file offset. This interface 1223 * is used mainly to access directories linked with 1224 * the SubIFD tag (e.g. thumbnail images). 1225 */ 1226int 1227TIFFSetSubDirectory(TIFF* tif, uint32 diroff) 1228{ 1229 tif->tif_nextdiroff = diroff; 1230 /* 1231 * Reset tif_dirnumber counter and start new list of seen directories. 1232 * We need this to prevent IFD loops. 1233 */ 1234 tif->tif_dirnumber = 0; 1235 return (TIFFReadDirectory(tif)); 1236} 1237 1238/* 1239 * Return file offset of the current directory. 1240 */ 1241uint32 1242TIFFCurrentDirOffset(TIFF* tif) 1243{ 1244 return (tif->tif_diroff); 1245} 1246 1247/* 1248 * Return an indication of whether or not we are 1249 * at the last directory in the file. 1250 */ 1251int 1252TIFFLastDirectory(TIFF* tif) 1253{ 1254 return (tif->tif_nextdiroff == 0); 1255} 1256 1257/* 1258 * Unlink the specified directory from the directory chain. 1259 */ 1260int 1261TIFFUnlinkDirectory(TIFF* tif, tdir_t dirn) 1262{ 1263 static const char module[] = "TIFFUnlinkDirectory"; 1264 toff_t nextdir; 1265 toff_t off; 1266 tdir_t n; 1267 1268 if (tif->tif_mode == O_RDONLY) { 1269 TIFFErrorExt(tif->tif_clientdata, module, 1270 "Can not unlink directory in read-only file"); 1271 return (0); 1272 } 1273 /* 1274 * Go to the directory before the one we want 1275 * to unlink and nab the offset of the link 1276 * field we'll need to patch. 1277 */ 1278 nextdir = tif->tif_header.tiff_diroff; 1279 off = sizeof (uint16) + sizeof (uint16); 1280 for (n = dirn-1; n > 0; n--) { 1281 if (nextdir == 0) { 1282 TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn); 1283 return (0); 1284 } 1285 if (!TIFFAdvanceDirectory(tif, &nextdir, &off)) 1286 return (0); 1287 } 1288 /* 1289 * Advance to the directory to be unlinked and fetch 1290 * the offset of the directory that follows. 1291 */ 1292 if (!TIFFAdvanceDirectory(tif, &nextdir, NULL)) 1293 return (0); 1294 /* 1295 * Go back and patch the link field of the preceding 1296 * directory to point to the offset of the directory 1297 * that follows. 1298 */ 1299 (void) TIFFSeekFile(tif, off, SEEK_SET); 1300 if (tif->tif_flags & TIFF_SWAB) 1301 TIFFSwabLong(&nextdir); 1302 if (!WriteOK(tif, &nextdir, sizeof (uint32))) { 1303 TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link"); 1304 return (0); 1305 } 1306 /* 1307 * Leave directory state setup safely. We don't have 1308 * facilities for doing inserting and removing directories, 1309 * so it's safest to just invalidate everything. This 1310 * means that the caller can only append to the directory 1311 * chain. 1312 */ 1313 (*tif->tif_cleanup)(tif); 1314 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { 1315 _TIFFfree(tif->tif_rawdata); 1316 tif->tif_rawdata = NULL; 1317 tif->tif_rawcc = 0; 1318 } 1319 tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE); 1320 TIFFFreeDirectory(tif); 1321 TIFFDefaultDirectory(tif); 1322 tif->tif_diroff = 0; /* force link on next write */ 1323 tif->tif_nextdiroff = 0; /* next write must be at end */ 1324 tif->tif_curoff = 0; 1325 tif->tif_row = (uint32) -1; 1326 tif->tif_curstrip = (tstrip_t) -1; 1327 return (1); 1328} 1329 1330/* [BFC] 1331 * 1332 * Author: Bruce Cameron <cameron@petris.com> 1333 * 1334 * Set a table of tags that are to be replaced during directory process by the 1335 * 'IGNORE' state - or return TRUE/FALSE for the requested tag such that 1336 * 'ReadDirectory' can use the stored information. 1337 * 1338 * FIXME: this is never used properly. Should be removed in the future. 1339 */ 1340int 1341TIFFReassignTagToIgnore (enum TIFFIgnoreSense task, int TIFFtagID) 1342{ 1343 static int TIFFignoretags [FIELD_LAST]; 1344 static int tagcount = 0 ; 1345 int i; /* Loop index */ 1346 int j; /* Loop index */ 1347 1348 switch (task) 1349 { 1350 case TIS_STORE: 1351 if ( tagcount < (FIELD_LAST - 1) ) 1352 { 1353 for ( j = 0 ; j < tagcount ; ++j ) 1354 { /* Do not add duplicate tag */ 1355 if ( TIFFignoretags [j] == TIFFtagID ) 1356 return (TRUE) ; 1357 } 1358 TIFFignoretags [tagcount++] = TIFFtagID ; 1359 return (TRUE) ; 1360 } 1361 break ; 1362 1363 case TIS_EXTRACT: 1364 for ( i = 0 ; i < tagcount ; ++i ) 1365 { 1366 if ( TIFFignoretags [i] == TIFFtagID ) 1367 return (TRUE) ; 1368 } 1369 break; 1370 1371 case TIS_EMPTY: 1372 tagcount = 0 ; /* Clear the list */ 1373 return (TRUE) ; 1374 1375 default: 1376 break; 1377 } 1378 1379 return (FALSE); 1380} 1381 1382/* vim: set ts=8 sts=8 sw=8 noet: */ 1383/* 1384 * Local Variables: 1385 * mode: c 1386 * c-basic-offset: 8 1387 * fill-column: 78 1388 * End: 1389 */ 1390