/src/FreeImage/Source/LibTIFF/tif_dirwrite.c
C | 1436 lines | 1083 code | 86 blank | 267 comment | 278 complexity | 98c8b22e58be25f2f87d871018ed9488 MD5 | raw file
1/* $Id: tif_dirwrite.c,v 1.37 2011/04/10 17:14:09 drolon 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 Write Support Routines. 31 */ 32#include "tiffiop.h" 33 34#ifdef HAVE_IEEEFP 35# define TIFFCvtNativeToIEEEFloat(tif, n, fp) 36# define TIFFCvtNativeToIEEEDouble(tif, n, dp) 37#else 38extern void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*); 39extern void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*); 40#endif 41 42static int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*); 43static void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32); 44static void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16); 45static int TIFFSetupBytePair(TIFF*, ttag_t, TIFFDirEntry*); 46static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*); 47static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*); 48static int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*); 49static int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**); 50static int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*); 51static int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*); 52static int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*); 53static int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*); 54static int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*); 55static int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*); 56static int TIFFWriteAnyArray(TIFF*, 57 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); 58static int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*); 59static int TIFFWriteInkNames(TIFF*, TIFFDirEntry*); 60static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*); 61static int TIFFLinkDirectory(TIFF*); 62 63#define WriteRationalPair(type, tag1, v1, tag2, v2) { \ 64 TIFFWriteRational((tif), (type), (tag1), (dir), (v1)) \ 65 TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2)) \ 66 (dir)++; \ 67} 68#define TIFFWriteRational(tif, type, tag, dir, v) \ 69 (dir)->tdir_tag = (tag); \ 70 (dir)->tdir_type = (type); \ 71 (dir)->tdir_count = 1; \ 72 if (!TIFFWriteRationalArray((tif), (dir), &(v))) \ 73 goto bad; 74 75/* 76 * Write the contents of the current directory 77 * to the specified file. This routine doesn't 78 * handle overwriting a directory with auxiliary 79 * storage that's been changed. 80 */ 81static int 82_TIFFWriteDirectory(TIFF* tif, int done) 83{ 84 uint16 dircount; 85 toff_t diroff; 86 ttag_t tag; 87 uint32 nfields; 88 tsize_t dirsize; 89 char* data; 90 TIFFDirEntry* dir; 91 TIFFDirectory* td; 92 unsigned long b, fields[FIELD_SETLONGS]; 93 int fi, nfi; 94 95 if (tif->tif_mode == O_RDONLY) 96 return (1); 97 /* 98 * Clear write state so that subsequent images with 99 * different characteristics get the right buffers 100 * setup for them. 101 */ 102 if (done) 103 { 104 if (tif->tif_flags & TIFF_POSTENCODE) { 105 tif->tif_flags &= ~TIFF_POSTENCODE; 106 if (!(*tif->tif_postencode)(tif)) { 107 TIFFErrorExt(tif->tif_clientdata, 108 tif->tif_name, 109 "Error post-encoding before directory write"); 110 return (0); 111 } 112 } 113 (*tif->tif_close)(tif); /* shutdown encoder */ 114 /* 115 * Flush any data that might have been written 116 * by the compression close+cleanup routines. 117 */ 118 if (tif->tif_rawcc > 0 119 && (tif->tif_flags & TIFF_BEENWRITING) != 0 120 && !TIFFFlushData1(tif)) { 121 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 122 "Error flushing data before directory write"); 123 return (0); 124 } 125 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) { 126 _TIFFfree(tif->tif_rawdata); 127 tif->tif_rawdata = NULL; 128 tif->tif_rawcc = 0; 129 tif->tif_rawdatasize = 0; 130 } 131 tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP); 132 } 133 134 td = &tif->tif_dir; 135 /* 136 * Size the directory so that we can calculate 137 * offsets for the data items that aren't kept 138 * in-place in each field. 139 */ 140 nfields = 0; 141 for (b = 0; b <= FIELD_LAST; b++) 142 if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM) 143 nfields += (b < FIELD_SUBFILETYPE ? 2 : 1); 144 nfields += td->td_customValueCount; 145 dirsize = nfields * sizeof (TIFFDirEntry); 146 data = (char*) _TIFFmalloc(dirsize); 147 if (data == NULL) { 148 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 149 "Cannot write directory, out of space"); 150 return (0); 151 } 152 /* 153 * Directory hasn't been placed yet, put 154 * it at the end of the file and link it 155 * into the existing directory structure. 156 */ 157 if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif)) 158 goto bad; 159 tif->tif_dataoff = (toff_t)( 160 tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t)); 161 if (tif->tif_dataoff & 1) 162 tif->tif_dataoff++; 163 (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET); 164 tif->tif_curdir++; 165 dir = (TIFFDirEntry*) data; 166 /* 167 * Setup external form of directory 168 * entries and write data items. 169 */ 170 _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields)); 171 /* 172 * Write out ExtraSamples tag only if 173 * extra samples are present in the data. 174 */ 175 if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) { 176 ResetFieldBit(fields, FIELD_EXTRASAMPLES); 177 nfields--; 178 dirsize -= sizeof (TIFFDirEntry); 179 } /*XXX*/ 180 for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) { 181 const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi]; 182 183 /* 184 * For custom fields, we test to see if the custom field 185 * is set or not. For normal fields, we just use the 186 * FieldSet test. 187 */ 188 if( fip->field_bit == FIELD_CUSTOM ) 189 { 190 int ci, is_set = FALSE; 191 192 for( ci = 0; ci < td->td_customValueCount; ci++ ) 193 is_set |= (td->td_customValues[ci].info == fip); 194 195 if( !is_set ) 196 continue; 197 } 198 else if (!FieldSet(fields, fip->field_bit)) 199 continue; 200 201 /* 202 * Handle other fields. 203 */ 204 switch (fip->field_bit) 205 { 206 case FIELD_STRIPOFFSETS: 207 /* 208 * We use one field bit for both strip and tile 209 210 * offsets, and so must be careful in selecting 211 * the appropriate field descriptor (so that tags 212 * are written in sorted order). 213 */ 214 tag = isTiled(tif) ? 215 TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS; 216 if (tag != fip->field_tag) 217 continue; 218 219 dir->tdir_tag = (uint16) tag; 220 dir->tdir_type = (uint16) TIFF_LONG; 221 dir->tdir_count = (uint32) td->td_nstrips; 222 if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset)) 223 goto bad; 224 break; 225 case FIELD_STRIPBYTECOUNTS: 226 /* 227 * We use one field bit for both strip and tile 228 * byte counts, and so must be careful in selecting 229 * the appropriate field descriptor (so that tags 230 * are written in sorted order). 231 */ 232 tag = isTiled(tif) ? 233 TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS; 234 if (tag != fip->field_tag) 235 continue; 236 237 dir->tdir_tag = (uint16) tag; 238 dir->tdir_type = (uint16) TIFF_LONG; 239 dir->tdir_count = (uint32) td->td_nstrips; 240 if (!TIFFWriteLongArray(tif, dir, td->td_stripbytecount)) 241 goto bad; 242 break; 243 case FIELD_ROWSPERSTRIP: 244 TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP, 245 dir, td->td_rowsperstrip); 246 break; 247 case FIELD_COLORMAP: 248 if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir, 249 3, td->td_colormap)) 250 goto bad; 251 break; 252 case FIELD_IMAGEDIMENSIONS: 253 TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH, 254 dir++, td->td_imagewidth); 255 TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH, 256 dir, td->td_imagelength); 257 break; 258 case FIELD_TILEDIMENSIONS: 259 TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH, 260 dir++, td->td_tilewidth); 261 TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH, 262 dir, td->td_tilelength); 263 break; 264 case FIELD_COMPRESSION: 265 TIFFSetupShort(tif, TIFFTAG_COMPRESSION, 266 dir, td->td_compression); 267 break; 268 case FIELD_PHOTOMETRIC: 269 TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC, 270 dir, td->td_photometric); 271 break; 272 case FIELD_POSITION: 273 WriteRationalPair(TIFF_RATIONAL, 274 TIFFTAG_XPOSITION, td->td_xposition, 275 TIFFTAG_YPOSITION, td->td_yposition); 276 break; 277 case FIELD_RESOLUTION: 278 WriteRationalPair(TIFF_RATIONAL, 279 TIFFTAG_XRESOLUTION, td->td_xresolution, 280 TIFFTAG_YRESOLUTION, td->td_yresolution); 281 break; 282 case FIELD_BITSPERSAMPLE: 283 case FIELD_MINSAMPLEVALUE: 284 case FIELD_MAXSAMPLEVALUE: 285 case FIELD_SAMPLEFORMAT: 286 if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir)) 287 goto bad; 288 break; 289 case FIELD_SMINSAMPLEVALUE: 290 case FIELD_SMAXSAMPLEVALUE: 291 if (!TIFFWritePerSampleAnys(tif, 292 _TIFFSampleToTagType(tif), fip->field_tag, dir)) 293 goto bad; 294 break; 295 case FIELD_INKNAMES: 296 if (!TIFFWriteInkNames(tif, dir)) 297 goto bad; 298 break; 299 case FIELD_TRANSFERFUNCTION: 300 if (!TIFFWriteTransferFunction(tif, dir)) 301 goto bad; 302 break; 303 case FIELD_SUBIFD: 304 /* 305 * XXX: Always write this field using LONG type 306 * for backward compatibility. 307 */ 308 dir->tdir_tag = (uint16) fip->field_tag; 309 dir->tdir_type = (uint16) TIFF_LONG; 310 dir->tdir_count = (uint32) td->td_nsubifd; 311 if (!TIFFWriteLongArray(tif, dir, td->td_subifd)) 312 goto bad; 313 /* 314 * Total hack: if this directory includes a SubIFD 315 * tag then force the next <n> directories to be 316 * written as ``sub directories'' of this one. This 317 * is used to write things like thumbnails and 318 * image masks that one wants to keep out of the 319 * normal directory linkage access mechanism. 320 */ 321 if (dir->tdir_count > 0) { 322 tif->tif_flags |= TIFF_INSUBIFD; 323 tif->tif_nsubifd = (uint16) dir->tdir_count; 324 if (dir->tdir_count > 1) 325 tif->tif_subifdoff = dir->tdir_offset; 326 else 327 tif->tif_subifdoff = (uint32)( 328 tif->tif_diroff 329 + sizeof (uint16) 330 + ((char*)&dir->tdir_offset-data)); 331 } 332 break; 333 default: 334 /* 335 * XXX: Should be fixed and removed. See comments 336 * related to these tags in tif_dir.c. 337 */ 338 if (fip->field_tag == TIFFTAG_PAGENUMBER 339 || fip->field_tag == TIFFTAG_HALFTONEHINTS 340 || fip->field_tag == TIFFTAG_YCBCRSUBSAMPLING 341 || fip->field_tag == TIFFTAG_DOTRANGE) { 342 if (fip->field_type == TIFF_BYTE) { 343 if (!TIFFSetupBytePair(tif, fip->field_tag, dir)) 344 goto bad; 345 } else if (fip->field_type == TIFF_SHORT) { 346 if (!TIFFSetupShortPair(tif, fip->field_tag, dir)) 347 goto bad; 348 } 349 } else if (!TIFFWriteNormalTag(tif, dir, fip)) 350 goto bad; 351 break; 352 } 353 dir++; 354 355 if( fip->field_bit != FIELD_CUSTOM ) 356 ResetFieldBit(fields, fip->field_bit); 357 } 358 359 /* 360 * Write directory. 361 */ 362 dircount = (uint16) nfields; 363 diroff = (uint32) tif->tif_nextdiroff; 364 if (tif->tif_flags & TIFF_SWAB) { 365 /* 366 * The file's byte order is opposite to the 367 * native machine architecture. We overwrite 368 * the directory information with impunity 369 * because it'll be released below after we 370 * write it to the file. Note that all the 371 * other tag construction routines assume that 372 * we do this byte-swapping; i.e. they only 373 * byte-swap indirect data. 374 */ 375 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) { 376 TIFFSwabArrayOfShort(&dir->tdir_tag, 2); 377 TIFFSwabArrayOfLong(&dir->tdir_count, 2); 378 } 379 dircount = (uint16) nfields; 380 TIFFSwabShort(&dircount); 381 TIFFSwabLong(&diroff); 382 } 383 (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET); 384 if (!WriteOK(tif, &dircount, sizeof (dircount))) { 385 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 386 "Error writing directory count"); 387 goto bad; 388 } 389 if (!WriteOK(tif, data, dirsize)) { 390 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 391 "Error writing directory contents"); 392 goto bad; 393 } 394 if (!WriteOK(tif, &diroff, sizeof (uint32))) { 395 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 396 "Error writing directory link"); 397 goto bad; 398 } 399 if (done) { 400 TIFFFreeDirectory(tif); 401 tif->tif_flags &= ~TIFF_DIRTYDIRECT; 402 (*tif->tif_cleanup)(tif); 403 404 /* 405 * Reset directory-related state for subsequent 406 * directories. 407 */ 408 TIFFCreateDirectory(tif); 409 } 410 _TIFFfree(data); 411 return (1); 412bad: 413 _TIFFfree(data); 414 return (0); 415} 416#undef WriteRationalPair 417 418int 419TIFFWriteDirectory(TIFF* tif) 420{ 421 return _TIFFWriteDirectory(tif, TRUE); 422} 423 424/* 425 * Similar to TIFFWriteDirectory(), writes the directory out 426 * but leaves all data structures in memory so that it can be 427 * written again. This will make a partially written TIFF file 428 * readable before it is successfully completed/closed. 429 */ 430int 431TIFFCheckpointDirectory(TIFF* tif) 432{ 433 int rc; 434 /* Setup the strips arrays, if they haven't already been. */ 435 if (tif->tif_dir.td_stripoffset == NULL) 436 (void) TIFFSetupStrips(tif); 437 rc = _TIFFWriteDirectory(tif, FALSE); 438 (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END)); 439 return rc; 440} 441 442static int 443_TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff) 444{ 445 uint16 dircount; 446 uint32 nfields; 447 tsize_t dirsize; 448 char* data; 449 TIFFDirEntry* dir; 450 TIFFDirectory* td; 451 unsigned long b, fields[FIELD_SETLONGS]; 452 int fi, nfi; 453 454 if (tif->tif_mode == O_RDONLY) 455 return (1); 456 457 td = &tif->tif_dir; 458 /* 459 * Size the directory so that we can calculate 460 * offsets for the data items that aren't kept 461 * in-place in each field. 462 */ 463 nfields = 0; 464 for (b = 0; b <= FIELD_LAST; b++) 465 if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM) 466 nfields += (b < FIELD_SUBFILETYPE ? 2 : 1); 467 nfields += td->td_customValueCount; 468 dirsize = nfields * sizeof (TIFFDirEntry); 469 data = (char*) _TIFFmalloc(dirsize); 470 if (data == NULL) { 471 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 472 "Cannot write directory, out of space"); 473 return (0); 474 } 475 /* 476 * Put the directory at the end of the file. 477 */ 478 tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; 479 tif->tif_dataoff = (toff_t)( 480 tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t)); 481 if (tif->tif_dataoff & 1) 482 tif->tif_dataoff++; 483 (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET); 484 dir = (TIFFDirEntry*) data; 485 /* 486 * Setup external form of directory 487 * entries and write data items. 488 */ 489 _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields)); 490 491 for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) { 492 const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi]; 493 494 /* 495 * For custom fields, we test to see if the custom field 496 * is set or not. For normal fields, we just use the 497 * FieldSet test. 498 */ 499 if( fip->field_bit == FIELD_CUSTOM ) 500 { 501 int ci, is_set = FALSE; 502 503 for( ci = 0; ci < td->td_customValueCount; ci++ ) 504 is_set |= (td->td_customValues[ci].info == fip); 505 506 if( !is_set ) 507 continue; 508 } 509 else if (!FieldSet(fields, fip->field_bit)) 510 continue; 511 512 if( fip->field_bit != FIELD_CUSTOM ) 513 ResetFieldBit(fields, fip->field_bit); 514 } 515 516 /* 517 * Write directory. 518 */ 519 dircount = (uint16) nfields; 520 *pdiroff = (uint32) tif->tif_nextdiroff; 521 if (tif->tif_flags & TIFF_SWAB) { 522 /* 523 * The file's byte order is opposite to the 524 * native machine architecture. We overwrite 525 * the directory information with impunity 526 * because it'll be released below after we 527 * write it to the file. Note that all the 528 * other tag construction routines assume that 529 * we do this byte-swapping; i.e. they only 530 * byte-swap indirect data. 531 */ 532 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) { 533 TIFFSwabArrayOfShort(&dir->tdir_tag, 2); 534 TIFFSwabArrayOfLong(&dir->tdir_count, 2); 535 } 536 dircount = (uint16) nfields; 537 TIFFSwabShort(&dircount); 538 TIFFSwabLong(pdiroff); 539 } 540 (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET); 541 if (!WriteOK(tif, &dircount, sizeof (dircount))) { 542 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 543 "Error writing directory count"); 544 goto bad; 545 } 546 if (!WriteOK(tif, data, dirsize)) { 547 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 548 "Error writing directory contents"); 549 goto bad; 550 } 551 if (!WriteOK(tif, pdiroff, sizeof (uint32))) { 552 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 553 "Error writing directory link"); 554 goto bad; 555 } 556 _TIFFfree(data); 557 return (1); 558bad: 559 _TIFFfree(data); 560 return (0); 561} 562 563int 564TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff) 565{ 566 return _TIFFWriteCustomDirectory(tif, pdiroff); 567} 568 569/* 570 * Process tags that are not special cased. 571 */ 572static int 573TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip) 574{ 575 uint16 wc = (uint16) fip->field_writecount; 576 uint32 wc2; 577 578 dir->tdir_tag = (uint16) fip->field_tag; 579 dir->tdir_type = (uint16) fip->field_type; 580 dir->tdir_count = wc; 581 582 switch (fip->field_type) { 583 case TIFF_SHORT: 584 case TIFF_SSHORT: 585 if (fip->field_passcount) { 586 uint16* wp; 587 if (wc == (uint16) TIFF_VARIABLE2) { 588 TIFFGetField(tif, fip->field_tag, &wc2, &wp); 589 dir->tdir_count = wc2; 590 } else { /* Assume TIFF_VARIABLE */ 591 TIFFGetField(tif, fip->field_tag, &wc, &wp); 592 dir->tdir_count = wc; 593 } 594 if (!TIFFWriteShortArray(tif, dir, wp)) 595 return 0; 596 } else { 597 if (wc == 1) { 598 uint16 sv; 599 TIFFGetField(tif, fip->field_tag, &sv); 600 dir->tdir_offset = 601 TIFFInsertData(tif, dir->tdir_type, sv); 602 } else { 603 uint16* wp; 604 TIFFGetField(tif, fip->field_tag, &wp); 605 if (!TIFFWriteShortArray(tif, dir, wp)) 606 return 0; 607 } 608 } 609 break; 610 case TIFF_LONG: 611 case TIFF_SLONG: 612 case TIFF_IFD: 613 if (fip->field_passcount) { 614 uint32* lp; 615 if (wc == (uint16) TIFF_VARIABLE2) { 616 TIFFGetField(tif, fip->field_tag, &wc2, &lp); 617 dir->tdir_count = wc2; 618 } else { /* Assume TIFF_VARIABLE */ 619 TIFFGetField(tif, fip->field_tag, &wc, &lp); 620 dir->tdir_count = wc; 621 } 622 if (!TIFFWriteLongArray(tif, dir, lp)) 623 return 0; 624 } else { 625 if (wc == 1) { 626 /* XXX handle LONG->SHORT conversion */ 627 TIFFGetField(tif, fip->field_tag, 628 &dir->tdir_offset); 629 } else { 630 uint32* lp; 631 TIFFGetField(tif, fip->field_tag, &lp); 632 if (!TIFFWriteLongArray(tif, dir, lp)) 633 return 0; 634 } 635 } 636 break; 637 case TIFF_RATIONAL: 638 case TIFF_SRATIONAL: 639 if (fip->field_passcount) { 640 float* fp; 641 if (wc == (uint16) TIFF_VARIABLE2) { 642 TIFFGetField(tif, fip->field_tag, &wc2, &fp); 643 dir->tdir_count = wc2; 644 } else { /* Assume TIFF_VARIABLE */ 645 TIFFGetField(tif, fip->field_tag, &wc, &fp); 646 dir->tdir_count = wc; 647 } 648 if (!TIFFWriteRationalArray(tif, dir, fp)) 649 return 0; 650 } else { 651 if (wc == 1) { 652 float fv; 653 TIFFGetField(tif, fip->field_tag, &fv); 654 if (!TIFFWriteRationalArray(tif, dir, &fv)) 655 return 0; 656 } else { 657 float* fp; 658 TIFFGetField(tif, fip->field_tag, &fp); 659 if (!TIFFWriteRationalArray(tif, dir, fp)) 660 return 0; 661 } 662 } 663 break; 664 case TIFF_FLOAT: 665 if (fip->field_passcount) { 666 float* fp; 667 if (wc == (uint16) TIFF_VARIABLE2) { 668 TIFFGetField(tif, fip->field_tag, &wc2, &fp); 669 dir->tdir_count = wc2; 670 } else { /* Assume TIFF_VARIABLE */ 671 TIFFGetField(tif, fip->field_tag, &wc, &fp); 672 dir->tdir_count = wc; 673 } 674 if (!TIFFWriteFloatArray(tif, dir, fp)) 675 return 0; 676 } else { 677 if (wc == 1) { 678 float fv; 679 TIFFGetField(tif, fip->field_tag, &fv); 680 if (!TIFFWriteFloatArray(tif, dir, &fv)) 681 return 0; 682 } else { 683 float* fp; 684 TIFFGetField(tif, fip->field_tag, &fp); 685 if (!TIFFWriteFloatArray(tif, dir, fp)) 686 return 0; 687 } 688 } 689 break; 690 case TIFF_DOUBLE: 691 if (fip->field_passcount) { 692 double* dp; 693 if (wc == (uint16) TIFF_VARIABLE2) { 694 TIFFGetField(tif, fip->field_tag, &wc2, &dp); 695 dir->tdir_count = wc2; 696 } else { /* Assume TIFF_VARIABLE */ 697 TIFFGetField(tif, fip->field_tag, &wc, &dp); 698 dir->tdir_count = wc; 699 } 700 if (!TIFFWriteDoubleArray(tif, dir, dp)) 701 return 0; 702 } else { 703 if (wc == 1) { 704 double dv; 705 TIFFGetField(tif, fip->field_tag, &dv); 706 if (!TIFFWriteDoubleArray(tif, dir, &dv)) 707 return 0; 708 } else { 709 double* dp; 710 TIFFGetField(tif, fip->field_tag, &dp); 711 if (!TIFFWriteDoubleArray(tif, dir, dp)) 712 return 0; 713 } 714 } 715 break; 716 case TIFF_ASCII: 717 { 718 char* cp; 719 if (fip->field_passcount) 720 { 721 if( wc == (uint16) TIFF_VARIABLE2 ) 722 TIFFGetField(tif, fip->field_tag, &wc2, &cp); 723 else 724 TIFFGetField(tif, fip->field_tag, &wc, &cp); 725 } 726 else 727 TIFFGetField(tif, fip->field_tag, &cp); 728 729 dir->tdir_count = (uint32) (strlen(cp) + 1); 730 if (!TIFFWriteByteArray(tif, dir, cp)) 731 return (0); 732 } 733 break; 734 735 case TIFF_BYTE: 736 case TIFF_SBYTE: 737 if (fip->field_passcount) { 738 char* cp; 739 if (wc == (uint16) TIFF_VARIABLE2) { 740 TIFFGetField(tif, fip->field_tag, &wc2, &cp); 741 dir->tdir_count = wc2; 742 } else { /* Assume TIFF_VARIABLE */ 743 TIFFGetField(tif, fip->field_tag, &wc, &cp); 744 dir->tdir_count = wc; 745 } 746 if (!TIFFWriteByteArray(tif, dir, cp)) 747 return 0; 748 } else { 749 if (wc == 1) { 750 char cv; 751 TIFFGetField(tif, fip->field_tag, &cv); 752 if (!TIFFWriteByteArray(tif, dir, &cv)) 753 return 0; 754 } else { 755 char* cp; 756 TIFFGetField(tif, fip->field_tag, &cp); 757 if (!TIFFWriteByteArray(tif, dir, cp)) 758 return 0; 759 } 760 } 761 break; 762 763 case TIFF_UNDEFINED: 764 { char* cp; 765 if (wc == (unsigned short) TIFF_VARIABLE) { 766 TIFFGetField(tif, fip->field_tag, &wc, &cp); 767 dir->tdir_count = wc; 768 } else if (wc == (unsigned short) TIFF_VARIABLE2) { 769 TIFFGetField(tif, fip->field_tag, &wc2, &cp); 770 dir->tdir_count = wc2; 771 } else 772 TIFFGetField(tif, fip->field_tag, &cp); 773 if (!TIFFWriteByteArray(tif, dir, cp)) 774 return (0); 775 } 776 break; 777 778 case TIFF_NOTYPE: 779 break; 780 } 781 return (1); 782} 783 784/* 785 * Setup a directory entry with either a SHORT 786 * or LONG type according to the value. 787 */ 788static void 789TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v) 790{ 791 dir->tdir_tag = (uint16) tag; 792 dir->tdir_count = 1; 793 if (v > 0xffffL) { 794 dir->tdir_type = (short) TIFF_LONG; 795 dir->tdir_offset = v; 796 } else { 797 dir->tdir_type = (short) TIFF_SHORT; 798 dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v); 799 } 800} 801 802/* 803 * Setup a SHORT directory entry 804 */ 805static void 806TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v) 807{ 808 dir->tdir_tag = (uint16) tag; 809 dir->tdir_count = 1; 810 dir->tdir_type = (short) TIFF_SHORT; 811 dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v); 812} 813#undef MakeShortDirent 814 815#define NITEMS(x) (sizeof (x) / sizeof (x[0])) 816/* 817 * Setup a directory entry that references a 818 * samples/pixel array of SHORT values and 819 * (potentially) write the associated indirect 820 * values. 821 */ 822static int 823TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) 824{ 825 uint16 buf[10], v; 826 uint16* w = buf; 827 uint16 i, samples = tif->tif_dir.td_samplesperpixel; 828 int status; 829 830 if (samples > NITEMS(buf)) { 831 w = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); 832 if (w == NULL) { 833 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 834 "No space to write per-sample shorts"); 835 return (0); 836 } 837 } 838 TIFFGetField(tif, tag, &v); 839 for (i = 0; i < samples; i++) 840 w[i] = v; 841 842 dir->tdir_tag = (uint16) tag; 843 dir->tdir_type = (uint16) TIFF_SHORT; 844 dir->tdir_count = samples; 845 status = TIFFWriteShortArray(tif, dir, w); 846 if (w != buf) 847 _TIFFfree((char*) w); 848 return (status); 849} 850 851/* 852 * Setup a directory entry that references a samples/pixel array of ``type'' 853 * values and (potentially) write the associated indirect values. The source 854 * data from TIFFGetField() for the specified tag must be returned as double. 855 */ 856static int 857TIFFWritePerSampleAnys(TIFF* tif, 858 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir) 859{ 860 double buf[10], v; 861 double* w = buf; 862 uint16 i, samples = tif->tif_dir.td_samplesperpixel; 863 int status; 864 865 if (samples > NITEMS(buf)) { 866 w = (double*) _TIFFmalloc(samples * sizeof (double)); 867 if (w == NULL) { 868 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 869 "No space to write per-sample values"); 870 return (0); 871 } 872 } 873 TIFFGetField(tif, tag, &v); 874 for (i = 0; i < samples; i++) 875 w[i] = v; 876 status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w); 877 if (w != buf) 878 _TIFFfree(w); 879 return (status); 880} 881#undef NITEMS 882 883/* 884 * Setup a pair of bytes that are returned by 885 * value, rather than as a reference to an array. 886 */ 887static int 888TIFFSetupBytePair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) 889{ 890 char v[2]; 891 892 TIFFGetField(tif, tag, &v[0], &v[1]); 893 894 dir->tdir_tag = (uint16) tag; 895 dir->tdir_type = (uint16) TIFF_BYTE; 896 dir->tdir_count = 2; 897 return (TIFFWriteByteArray(tif, dir, v)); 898} 899 900/* 901 * Setup a pair of shorts that are returned by 902 * value, rather than as a reference to an array. 903 */ 904static int 905TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) 906{ 907 uint16 v[2]; 908 909 TIFFGetField(tif, tag, &v[0], &v[1]); 910 911 dir->tdir_tag = (uint16) tag; 912 dir->tdir_type = (uint16) TIFF_SHORT; 913 dir->tdir_count = 2; 914 return (TIFFWriteShortArray(tif, dir, v)); 915} 916 917/* 918 * Setup a directory entry for an NxM table of shorts, 919 * where M is known to be 2**bitspersample, and write 920 * the associated indirect data. 921 */ 922static int 923TIFFWriteShortTable(TIFF* tif, 924 ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table) 925{ 926 uint32 i, off; 927 928 dir->tdir_tag = (uint16) tag; 929 dir->tdir_type = (short) TIFF_SHORT; 930 /* XXX -- yech, fool TIFFWriteData */ 931 dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample); 932 off = tif->tif_dataoff; 933 for (i = 0; i < n; i++) 934 if (!TIFFWriteData(tif, dir, (char *)table[i])) 935 return (0); 936 dir->tdir_count *= n; 937 dir->tdir_offset = off; 938 return (1); 939} 940 941/* 942 * Write/copy data associated with an ASCII or opaque tag value. 943 */ 944static int 945TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp) 946{ 947 if (dir->tdir_count <= 4) { 948 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { 949 dir->tdir_offset = (uint32)cp[0] << 24; 950 if (dir->tdir_count >= 2) 951 dir->tdir_offset |= (uint32)cp[1] << 16; 952 if (dir->tdir_count >= 3) 953 dir->tdir_offset |= (uint32)cp[2] << 8; 954 if (dir->tdir_count == 4) 955 dir->tdir_offset |= cp[3]; 956 } else { 957 dir->tdir_offset = cp[0]; 958 if (dir->tdir_count >= 2) 959 dir->tdir_offset |= (uint32) cp[1] << 8; 960 if (dir->tdir_count >= 3) 961 dir->tdir_offset |= (uint32) cp[2] << 16; 962 if (dir->tdir_count == 4) 963 dir->tdir_offset |= (uint32) cp[3] << 24; 964 } 965 return 1; 966 } else 967 return TIFFWriteData(tif, dir, cp); 968} 969 970/* 971 * Setup a directory entry of an array of SHORT 972 * or SSHORT and write the associated indirect values. 973 */ 974static int 975TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v) 976{ 977 if (dir->tdir_count <= 2) { 978 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { 979 dir->tdir_offset = (uint32) v[0] << 16; 980 if (dir->tdir_count == 2) 981 dir->tdir_offset |= v[1] & 0xffff; 982 } else { 983 dir->tdir_offset = v[0] & 0xffff; 984 if (dir->tdir_count == 2) 985 dir->tdir_offset |= (uint32) v[1] << 16; 986 } 987 return (1); 988 } else 989 return (TIFFWriteData(tif, dir, (char*) v)); 990} 991 992/* 993 * Setup a directory entry of an array of LONG 994 * or SLONG and write the associated indirect values. 995 */ 996static int 997TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v) 998{ 999 if (dir->tdir_count == 1) { 1000 dir->tdir_offset = v[0]; 1001 return (1); 1002 } else 1003 return (TIFFWriteData(tif, dir, (char*) v)); 1004} 1005 1006/* 1007 * Setup a directory entry of an array of RATIONAL 1008 * or SRATIONAL and write the associated indirect values. 1009 */ 1010static int 1011TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v) 1012{ 1013 uint32 i; 1014 uint32* t; 1015 int status; 1016 1017 t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32)); 1018 if (t == NULL) { 1019 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 1020 "No space to write RATIONAL array"); 1021 return (0); 1022 } 1023 for (i = 0; i < dir->tdir_count; i++) { 1024 float fv = v[i]; 1025 int sign = 1; 1026 uint32 den; 1027 1028 if (fv < 0) { 1029 if (dir->tdir_type == TIFF_RATIONAL) { 1030 TIFFWarningExt(tif->tif_clientdata, 1031 tif->tif_name, 1032 "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL", 1033 _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name, 1034 fv); 1035 fv = 0; 1036 } else 1037 fv = -fv, sign = -1; 1038 } 1039 den = 1L; 1040 if (fv > 0) { 1041 while (fv < 1L<<(31-3) && den < 1L<<(31-3)) 1042 fv *= 1<<3, den *= 1L<<3; 1043 } 1044 t[2*i+0] = (uint32) (sign * (int32)(fv + 0.5)); 1045 t[2*i+1] = den; 1046 } 1047 status = TIFFWriteData(tif, dir, (char *)t); 1048 _TIFFfree((char*) t); 1049 return (status); 1050} 1051 1052static int 1053TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v) 1054{ 1055 TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v); 1056 if (dir->tdir_count == 1) { 1057 dir->tdir_offset = *(uint32*) &v[0]; 1058 return (1); 1059 } else 1060 return (TIFFWriteData(tif, dir, (char*) v)); 1061} 1062 1063static int 1064TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v) 1065{ 1066 TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v); 1067 return (TIFFWriteData(tif, dir, (char*) v)); 1068} 1069 1070/* 1071 * Write an array of ``type'' values for a specified tag (i.e. this is a tag 1072 * which is allowed to have different types, e.g. SMaxSampleType). 1073 * Internally the data values are represented as double since a double can 1074 * hold any of the TIFF tag types (yes, this should really be an abstract 1075 * type tany_t for portability). The data is converted into the specified 1076 * type in a temporary buffer and then handed off to the appropriate array 1077 * writer. 1078 */ 1079static int 1080TIFFWriteAnyArray(TIFF* tif, 1081 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v) 1082{ 1083 char buf[10 * sizeof(double)]; 1084 char* w = buf; 1085 int i, status = 0; 1086 1087 if (n * TIFFDataWidth(type) > sizeof buf) { 1088 w = (char*) _TIFFmalloc(n * TIFFDataWidth(type)); 1089 if (w == NULL) { 1090 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 1091 "No space to write array"); 1092 return (0); 1093 } 1094 } 1095 1096 dir->tdir_tag = (uint16) tag; 1097 dir->tdir_type = (uint16) type; 1098 dir->tdir_count = n; 1099 1100 switch (type) { 1101 case TIFF_BYTE: 1102 { 1103 uint8* bp = (uint8*) w; 1104 for (i = 0; i < (int) n; i++) 1105 bp[i] = (uint8) v[i]; 1106 if (!TIFFWriteByteArray(tif, dir, (char*) bp)) 1107 goto out; 1108 } 1109 break; 1110 case TIFF_SBYTE: 1111 { 1112 int8* bp = (int8*) w; 1113 for (i = 0; i < (int) n; i++) 1114 bp[i] = (int8) v[i]; 1115 if (!TIFFWriteByteArray(tif, dir, (char*) bp)) 1116 goto out; 1117 } 1118 break; 1119 case TIFF_SHORT: 1120 { 1121 uint16* bp = (uint16*) w; 1122 for (i = 0; i < (int) n; i++) 1123 bp[i] = (uint16) v[i]; 1124 if (!TIFFWriteShortArray(tif, dir, (uint16*)bp)) 1125 goto out; 1126 } 1127 break; 1128 case TIFF_SSHORT: 1129 { 1130 int16* bp = (int16*) w; 1131 for (i = 0; i < (int) n; i++) 1132 bp[i] = (int16) v[i]; 1133 if (!TIFFWriteShortArray(tif, dir, (uint16*)bp)) 1134 goto out; 1135 } 1136 break; 1137 case TIFF_LONG: 1138 { 1139 uint32* bp = (uint32*) w; 1140 for (i = 0; i < (int) n; i++) 1141 bp[i] = (uint32) v[i]; 1142 if (!TIFFWriteLongArray(tif, dir, bp)) 1143 goto out; 1144 } 1145 break; 1146 case TIFF_SLONG: 1147 { 1148 int32* bp = (int32*) w; 1149 for (i = 0; i < (int) n; i++) 1150 bp[i] = (int32) v[i]; 1151 if (!TIFFWriteLongArray(tif, dir, (uint32*) bp)) 1152 goto out; 1153 } 1154 break; 1155 case TIFF_FLOAT: 1156 { 1157 float* bp = (float*) w; 1158 for (i = 0; i < (int) n; i++) 1159 bp[i] = (float) v[i]; 1160 if (!TIFFWriteFloatArray(tif, dir, bp)) 1161 goto out; 1162 } 1163 break; 1164 case TIFF_DOUBLE: 1165 { 1166 if( !TIFFWriteDoubleArray(tif, dir, v)) 1167 goto out; 1168 } 1169 break; 1170 default: 1171 /* TIFF_NOTYPE */ 1172 /* TIFF_ASCII */ 1173 /* TIFF_UNDEFINED */ 1174 /* TIFF_RATIONAL */ 1175 /* TIFF_SRATIONAL */ 1176 goto out; 1177 } 1178 status = 1; 1179 out: 1180 if (w != buf) 1181 _TIFFfree(w); 1182 return (status); 1183} 1184 1185static int 1186TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir) 1187{ 1188 TIFFDirectory* td = &tif->tif_dir; 1189 tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16); 1190 uint16** tf = td->td_transferfunction; 1191 int ncols; 1192 1193 /* 1194 * Check if the table can be written as a single column, 1195 * or if it must be written as 3 columns. Note that we 1196 * write a 3-column tag if there are 2 samples/pixel and 1197 * a single column of data won't suffice--hmm. 1198 */ 1199 switch (td->td_samplesperpixel - td->td_extrasamples) { 1200 default: if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; } 1201 case 2: if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; } 1202 case 1: case 0: ncols = 1; 1203 } 1204 return (TIFFWriteShortTable(tif, 1205 TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf)); 1206} 1207 1208static int 1209TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir) 1210{ 1211 TIFFDirectory* td = &tif->tif_dir; 1212 1213 dir->tdir_tag = TIFFTAG_INKNAMES; 1214 dir->tdir_type = (short) TIFF_ASCII; 1215 dir->tdir_count = td->td_inknameslen; 1216 return (TIFFWriteByteArray(tif, dir, td->td_inknames)); 1217} 1218 1219/* 1220 * Write a contiguous directory item. 1221 */ 1222static int 1223TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp) 1224{ 1225 tsize_t cc; 1226 1227 if (tif->tif_flags & TIFF_SWAB) { 1228 switch (dir->tdir_type) { 1229 case TIFF_SHORT: 1230 case TIFF_SSHORT: 1231 TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); 1232 break; 1233 case TIFF_LONG: 1234 case TIFF_SLONG: 1235 case TIFF_FLOAT: 1236 TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); 1237 break; 1238 case TIFF_RATIONAL: 1239 case TIFF_SRATIONAL: 1240 TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); 1241 break; 1242 case TIFF_DOUBLE: 1243 TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); 1244 break; 1245 } 1246 } 1247 dir->tdir_offset = tif->tif_dataoff; 1248 cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type); 1249 if (SeekOK(tif, dir->tdir_offset) && 1250 WriteOK(tif, cp, cc)) { 1251 tif->tif_dataoff += (cc + 1) & ~1; 1252 return (1); 1253 } 1254 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 1255 "Error writing data for field \"%s\"", 1256 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); 1257 return (0); 1258} 1259 1260/* 1261 * Similar to TIFFWriteDirectory(), but if the directory has already 1262 * been written once, it is relocated to the end of the file, in case it 1263 * has changed in size. Note that this will result in the loss of the 1264 * previously used directory space. 1265 */ 1266 1267int 1268TIFFRewriteDirectory( TIFF *tif ) 1269{ 1270 static const char module[] = "TIFFRewriteDirectory"; 1271 1272 /* We don't need to do anything special if it hasn't been written. */ 1273 if( tif->tif_diroff == 0 ) 1274 return TIFFWriteDirectory( tif ); 1275 1276 /* 1277 ** Find and zero the pointer to this directory, so that TIFFLinkDirectory 1278 ** will cause it to be added after this directories current pre-link. 1279 */ 1280 1281 /* Is it the first directory in the file? */ 1282 if (tif->tif_header.tiff_diroff == tif->tif_diroff) 1283 { 1284 tif->tif_header.tiff_diroff = 0; 1285 tif->tif_diroff = 0; 1286 1287 TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE), 1288 SEEK_SET); 1289 if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 1290 sizeof (tif->tif_diroff))) 1291 { 1292 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 1293 "Error updating TIFF header"); 1294 return (0); 1295 } 1296 } 1297 else 1298 { 1299 toff_t nextdir, off; 1300 1301 nextdir = tif->tif_header.tiff_diroff; 1302 do { 1303 uint16 dircount; 1304 1305 if (!SeekOK(tif, nextdir) || 1306 !ReadOK(tif, &dircount, sizeof (dircount))) { 1307 TIFFErrorExt(tif->tif_clientdata, module, 1308 "Error fetching directory count"); 1309 return (0); 1310 } 1311 if (tif->tif_flags & TIFF_SWAB) 1312 TIFFSwabShort(&dircount); 1313 (void) TIFFSeekFile(tif, 1314 dircount * sizeof (TIFFDirEntry), SEEK_CUR); 1315 if (!ReadOK(tif, &nextdir, sizeof (nextdir))) { 1316 TIFFErrorExt(tif->tif_clientdata, module, 1317 "Error fetching directory link"); 1318 return (0); 1319 } 1320 if (tif->tif_flags & TIFF_SWAB) 1321 TIFFSwabLong(&nextdir); 1322 } while (nextdir != tif->tif_diroff && nextdir != 0); 1323 off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */ 1324 (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET); 1325 tif->tif_diroff = 0; 1326 if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) { 1327 TIFFErrorExt(tif->tif_clientdata, module, 1328 "Error writing directory link"); 1329 return (0); 1330 } 1331 } 1332 1333 /* 1334 ** Now use TIFFWriteDirectory() normally. 1335 */ 1336 1337 return TIFFWriteDirectory( tif ); 1338} 1339 1340 1341/* 1342 * Link the current directory into the directory chain for the file. 1343 */ 1344static int 1345TIFFLinkDirectory(TIFF* tif) 1346{ 1347 static const char module[] = "TIFFLinkDirectory"; 1348 toff_t nextdir; 1349 toff_t diroff, off; 1350 1351 tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; 1352 diroff = tif->tif_diroff; 1353 if (tif->tif_flags & TIFF_SWAB) 1354 TIFFSwabLong(&diroff); 1355 1356 /* 1357 * Handle SubIFDs 1358 */ 1359 if (tif->tif_flags & TIFF_INSUBIFD) { 1360 (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); 1361 if (!WriteOK(tif, &diroff, sizeof (diroff))) { 1362 TIFFErrorExt(tif->tif_clientdata, module, 1363 "%s: Error writing SubIFD directory link", 1364 tif->tif_name); 1365 return (0); 1366 } 1367 /* 1368 * Advance to the next SubIFD or, if this is 1369 * the last one configured, revert back to the 1370 * normal directory linkage. 1371 */ 1372 if (--tif->tif_nsubifd) 1373 tif->tif_subifdoff += sizeof (diroff); 1374 else 1375 tif->tif_flags &= ~TIFF_INSUBIFD; 1376 return (1); 1377 } 1378 1379 if (tif->tif_header.tiff_diroff == 0) { 1380 /* 1381 * First directory, overwrite offset in header. 1382 */ 1383 tif->tif_header.tiff_diroff = tif->tif_diroff; 1384 (void) TIFFSeekFile(tif, 1385 (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE), 1386 SEEK_SET); 1387 if (!WriteOK(tif, &diroff, sizeof (diroff))) { 1388 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 1389 "Error writing TIFF header"); 1390 return (0); 1391 } 1392 return (1); 1393 } 1394 /* 1395 * Not the first directory, search to the last and append. 1396 */ 1397 nextdir = tif->tif_header.tiff_diroff; 1398 do { 1399 uint16 dircount; 1400 1401 if (!SeekOK(tif, nextdir) || 1402 !ReadOK(tif, &dircount, sizeof (dircount))) { 1403 TIFFErrorExt(tif->tif_clientdata, module, 1404 "Error fetching directory count"); 1405 return (0); 1406 } 1407 if (tif->tif_flags & TIFF_SWAB) 1408 TIFFSwabShort(&dircount); 1409 (void) TIFFSeekFile(tif, 1410 dircount * sizeof (TIFFDirEntry), SEEK_CUR); 1411 if (!ReadOK(tif, &nextdir, sizeof (nextdir))) { 1412 TIFFErrorExt(tif->tif_clientdata, module, 1413 "Error fetching directory link"); 1414 return (0); 1415 } 1416 if (tif->tif_flags & TIFF_SWAB) 1417 TIFFSwabLong(&nextdir); 1418 } while (nextdir != 0); 1419 off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */ 1420 (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET); 1421 if (!WriteOK(tif, &diroff, sizeof (diroff))) { 1422 TIFFErrorExt(tif->tif_clientdata, module, 1423 "Error writing directory link"); 1424 return (0); 1425 } 1426 return (1); 1427} 1428 1429/* vim: set ts=8 sts=8 sw=8 noet: */ 1430/* 1431 * Local Variables: 1432 * mode: c 1433 * c-basic-offset: 8 1434 * fill-column: 78 1435 * End: 1436 */