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