1/* $Header: /cvs/maptools/cvsroot/libtiff/contrib/pds/tif_pdsdirwrite.c,v 1.3.2.1 2010-06-08 18:50:41 bfriesen Exp $ */ 2 3/* When writing data to TIFF files, it is often useful to store application- 4 specific data in a private TIFF directory so that the tags don't need to 5 be registered and won't conflict with other people's user-defined tags. 6 One needs to have a registered public tag which contains some amount of 7 raw data. That raw data, however, is interpreted at an independent, 8 separate, private tiff directory. This file provides some routines which 9 will be useful for converting that data from its raw binary form into 10 the proper form for your application. 11*/ 12 13/* 14 * Copyright (c) 1988-1996 Sam Leffler 15 * Copyright (c) 1991-1996 Silicon Graphics, Inc. 16 * Copyright (c( 1996 USAF Phillips Laboratory 17 * 18 * Permission to use, copy, modify, distribute, and sell this software and 19 * its documentation for any purpose is hereby granted without fee, provided 20 * that (i) the above copyright notices and this permission notice appear in 21 * all copies of the software and related documentation, and (ii) the names of 22 * Sam Leffler and Silicon Graphics may not be used in any advertising or 23 * publicity relating to the software without the specific, prior written 24 * permission of Sam Leffler and Silicon Graphics. 25 * 26 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 28 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 29 * 30 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 31 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 32 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 33 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 34 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 35 * OF THIS SOFTWARE. 36 */ 37 38/* 39 * TIFF Library. 40 * 41 * These routines written by Conrad J. Poelman on a single late-night of 42 * March 20-21, 1996. 43 * 44 * The entire purpose of this file is to provide a single external function, 45 * TIFFWritePrivateDataSubDirectory(). This function is intended for use 46 * in writing a private subdirectory structure into a TIFF file. The 47 * actual reading of data from the structure is handled by the getFieldFn(), 48 * which is passed to TIFFWritePrivateDataSubDirectory() as a parameter. The 49 * idea is to enable any application wishing to read private subdirectories to 50 * do so easily using this function, without modifying the TIFF library. 51 * 52 * The astute observer will notice that only two functions are at all different 53 * from the original tif_dirwrite.c file: TIFFWritePrivateDataSubDirectory()and 54 * TIFFWriteNormalSubTag(). All the other stuff that makes this file so huge 55 * is only necessary because all of those functions are declared static in 56 * tif_dirwrite.c, so we have to totally duplicate them in order to use them. 57 * 58 * Oh, also please note the bug-fix in the routine TIFFWriteNormalSubTag(), 59 * which equally should be applied to TIFFWriteNormalTag(). 60 * 61 */ 62#include "tiffiop.h" 63 64#if HAVE_IEEEFP 65#define TIFFCvtNativeToIEEEFloat(tif, n, fp) 66#define TIFFCvtNativeToIEEEDouble(tif, n, dp) 67#else 68extern void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*); 69extern void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*); 70#endif 71 72static int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*); 73static int TIFFWriteNormalSubTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*, 74 int (*getFieldFn)(TIFF *tif,ttag_t tag,...)); 75static void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32); 76static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*); 77static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*); 78static int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*); 79static int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**); 80static int TIFFWriteShortArray(TIFF*, 81 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint16*); 82static int TIFFWriteLongArray(TIFF *, 83 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint32*); 84static int TIFFWriteRationalArray(TIFF *, 85 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*); 86static int TIFFWriteFloatArray(TIFF *, 87 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*); 88static int TIFFWriteDoubleArray(TIFF *, 89 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); 90static int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*); 91static int TIFFWriteAnyArray(TIFF*, 92 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*); 93#ifdef COLORIMETRY_SUPPORT 94static int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*); 95#endif 96static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*); 97static int TIFFLinkDirectory(TIFF*); 98 99#define WriteRationalPair(type, tag1, v1, tag2, v2) { \ 100 if (!TIFFWriteRational(tif, type, tag1, dir, v1)) \ 101 goto bad; \ 102 if (!TIFFWriteRational(tif, type, tag2, dir+1, v2)) \ 103 goto bad; \ 104 dir++; \ 105} 106#define TIFFWriteRational(tif, type, tag, dir, v) \ 107 TIFFWriteRationalArray((tif), (type), (tag), (dir), 1, &(v)) 108#ifndef TIFFWriteRational 109static int TIFFWriteRational(TIFF*, 110 TIFFDataType, ttag_t, TIFFDirEntry*, float); 111#endif 112 113/* This function will write an entire directory to the disk, and return the 114 offset value indicating where in the file it wrote the beginning of the 115 directory structure. This is NOT the same as the offset value before 116 calling this function, because some of the fields may have caused various 117 data items to be written out BEFORE writing the directory structure. 118 119 This code was basically written by ripping of the TIFFWriteDirectory() 120 code and generalizing it, using RPS's TIFFWritePliIfd() code for 121 inspiration. My original goal was to make this code general enough that 122 the original TIFFWriteDirectory() could be rewritten to just call this 123 function with the appropriate field and field-accessing arguments. 124 125 However, now I realize that there's a lot of code that gets executed for 126 the main, standard TIFF directories that does not apply to special 127 private subdirectories, so such a reimplementation for the sake of 128 eliminating redundant or duplicate code is probably not possible, 129 unless we also pass in a Main flag to indiciate which type of handling 130 to do, which would be kind of a hack. I've marked those places where I 131 changed or ripped out code which would have to be re-inserted to 132 generalize this function. If it can be done in a clean and graceful way, 133 it would be a great way to generalize the TIFF library. Otherwise, I'll 134 just leave this code here where it duplicates but remains on top of and 135 hopefully mostly independent of the main TIFF library. 136 137 The caller will probably want to free the sub directory structure after 138 returning from this call, since otherwise once written out, the user 139 is likely to forget about it and leave data lying around. 140*/ 141toff_t 142TIFFWritePrivateDataSubDirectory(TIFF* tif, 143 uint32 pdir_fieldsset[], int pdir_fields_last, 144 TIFFFieldInfo *field_info, 145 int (*getFieldFn)(TIFF *tif, ttag_t tag, ...)) 146{ 147 uint16 dircount; 148 uint32 diroff, nextdiroff; 149 ttag_t tag; 150 uint32 nfields; 151 tsize_t dirsize; 152 char* data; 153 TIFFDirEntry* dir; 154 u_long b, *fields, fields_size; 155 toff_t directory_offset; 156 TIFFFieldInfo* fip; 157 158 /* 159 * Deleted out all of the encoder flushing and such code from here - 160 * not necessary for subdirectories. 161 */ 162 163 /* Finish writing out any image data. */ 164 TIFFFlushData(tif); 165 166 /* 167 * Size the directory so that we can calculate 168 * offsets for the data items that aren't kept 169 * in-place in each field. 170 */ 171 nfields = 0; 172 for (b = 0; b <= pdir_fields_last; b++) 173 if (FieldSet(pdir_fieldsset, b)) 174 /* Deleted code to make size of first 4 tags 2 175 instead of 1. */ 176 nfields += 1; 177 dirsize = nfields * sizeof (TIFFDirEntry); 178 data = (char*) _TIFFmalloc(dirsize); 179 if (data == NULL) { 180 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 181 "Cannot write private subdirectory, out of space"); 182 return (0); 183 } 184 /* 185 * Place directory in data section of the file. If there isn't one 186 * yet, place it at the end of the file. The directory is treated as 187 * data, so we don't link it into the directory structure at all. 188 */ 189 if (tif->tif_dataoff == 0) 190 tif->tif_dataoff =(TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; 191 diroff = tif->tif_dataoff; 192 tif->tif_dataoff = (toff_t)( 193 diroff + sizeof (uint16) + dirsize + sizeof (toff_t)); 194 if (tif->tif_dataoff & 1) 195 tif->tif_dataoff++; 196 (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET); 197 /*tif->tif_curdir++;*/ 198 dir = (TIFFDirEntry*) data; 199 /* 200 * Setup external form of directory 201 * entries and write data items. 202 */ 203 /* 204 * We make a local copy of the fieldsset here so that we don't mess 205 * up the original one when we call ResetFieldBit(). But I'm not sure 206 * why the original code calls ResetFieldBit(), since we're already 207 * going through the fields in order... 208 * 209 * fields_size is the number of uint32's we will need to hold the 210 * bit-mask for all of the fields. If our highest field number is 211 * 100, then we'll need 100 / (8*4)+1 == 4 uint32's to hold the 212 * fieldset. 213 * 214 * Unlike the original code, we allocate fields dynamically based 215 * on the requested pdir_fields_last value, allowing private 216 * data subdirectories to contain more than the built-in code's limit 217 * of 95 tags in a directory. 218 */ 219 fields_size = pdir_fields_last / (8*sizeof(uint32)) + 1; 220 fields = _TIFFmalloc(fields_size*sizeof(uint32)); 221 _TIFFmemcpy(fields, pdir_fieldsset, fields_size * sizeof(uint32)); 222 223 /* Deleted "write out extra samples tag" code here. */ 224 225 /* Deleted code for checking a billion little special cases for the 226 * standard TIFF tags. Should add a general mechanism for overloading 227 * write function for each field, just like Brian kept telling me!!! 228 */ 229 for (fip = field_info; fip->field_tag; fip++) { 230 /* Deleted code to check for FIELD_IGNORE!! */ 231 if (/* fip->field_bit == FIELD_IGNORE || */ 232 !FieldSet(fields, fip->field_bit)) 233 continue; 234 if (!TIFFWriteNormalSubTag(tif, dir, fip, getFieldFn)) 235 goto bad; 236 dir++; 237 ResetFieldBit(fields, fip->field_bit); 238 } 239 240 /* Now we've written all of the referenced data, and are about to 241 write the main directory structure, so grab the tif_dataoff value 242 now so we can remember where we wrote the directory. */ 243 directory_offset = tif->tif_dataoff; 244 245 /* 246 * Write directory. 247 */ 248 dircount = (uint16) nfields; 249 /* Deleted code to link to the next directory - we set it to zero! */ 250 nextdiroff = 0; 251 if (tif->tif_flags & TIFF_SWAB) { 252 /* 253 * The file's byte order is opposite to the 254 * native machine architecture. We overwrite 255 * the directory information with impunity 256 * because it'll be released below after we 257 * write it to the file. Note that all the 258 * other tag construction routines assume that 259 * we do this byte-swapping; i.e. they only 260 * byte-swap indirect data. 261 */ 262 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) { 263 TIFFSwabArrayOfShort(&dir->tdir_tag, 2); 264 TIFFSwabArrayOfLong(&dir->tdir_count, 2); 265 } 266 dircount = (uint16) nfields; 267 TIFFSwabShort(&dircount); 268 TIFFSwabLong(&nextdiroff); 269 } 270 271 (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET); 272 if (!WriteOK(tif, &dircount, sizeof (dircount))) { 273 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing private subdirectory count"); 274 goto bad; 275 } 276 if (!WriteOK(tif, data, dirsize)) { 277 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing private subdirectory contents"); 278 goto bad; 279 } 280 if (!WriteOK(tif, &nextdiroff, sizeof (nextdiroff))) { 281 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing private subdirectory link"); 282 goto bad; 283 } 284 tif->tif_dataoff += sizeof(dircount) + dirsize + sizeof(nextdiroff); 285 286 _TIFFfree(data); 287 _TIFFfree(fields); 288 tif->tif_flags &= ~TIFF_DIRTYDIRECT; 289 290#if (0) 291 /* This stuff commented out because I don't think we want it for 292 subdirectories, but I could be wrong. */ 293 (*tif->tif_cleanup)(tif); 294 295 /* 296 * Reset directory-related state for subsequent 297 * directories. 298 */ 299 TIFFDefaultDirectory(tif); 300 tif->tif_curoff = 0; 301 tif->tif_row = (uint32) -1; 302 tif->tif_curstrip = (tstrip_t) -1; 303#endif 304 305 return (directory_offset); 306bad: 307 _TIFFfree(data); 308 _TIFFfree(fields); 309 return (0); 310} 311#undef WriteRationalPair 312 313/* 314 * Process tags that are not special cased. 315 */ 316/* The standard function TIFFWriteNormalTag() could definitely be replaced 317 with a simple call to this function, just adding TIFFGetField() as the 318 last argument. */ 319static int 320TIFFWriteNormalSubTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip, 321 int (*getFieldFn)(TIFF *tif, ttag_t tag, ...)) 322{ 323 u_short wc = (u_short) fip->field_writecount; 324 325 dir->tdir_tag = fip->field_tag; 326 dir->tdir_type = (u_short) fip->field_type; 327 dir->tdir_count = wc; 328#define WRITEF(x,y) x(tif, fip->field_type, fip->field_tag, dir, wc, y) 329 switch (fip->field_type) { 330 case TIFF_SHORT: 331 case TIFF_SSHORT: 332 if (wc > 1) { 333 uint16* wp; 334 if (wc == (u_short) TIFF_VARIABLE) { 335 (*getFieldFn)(tif, fip->field_tag, &wc, &wp); 336 dir->tdir_count = wc; 337 } else 338 (*getFieldFn)(tif, fip->field_tag, &wp); 339 if (!WRITEF(TIFFWriteShortArray, wp)) 340 return (0); 341 } else { 342 uint16 sv; 343 (*getFieldFn)(tif, fip->field_tag, &sv); 344 dir->tdir_offset = 345 TIFFInsertData(tif, dir->tdir_type, sv); 346 } 347 break; 348 case TIFF_LONG: 349 case TIFF_SLONG: 350 if (wc > 1) { 351 uint32* lp; 352 if (wc == (u_short) TIFF_VARIABLE) { 353 (*getFieldFn)(tif, fip->field_tag, &wc, &lp); 354 dir->tdir_count = wc; 355 } else 356 (*getFieldFn)(tif, fip->field_tag, &lp); 357 if (!WRITEF(TIFFWriteLongArray, lp)) 358 return (0); 359 } else { 360 /* XXX handle LONG->SHORT conversion */ 361 (*getFieldFn)(tif, fip->field_tag, &dir->tdir_offset); 362 } 363 break; 364 case TIFF_RATIONAL: 365 case TIFF_SRATIONAL: 366 if (wc > 1) { 367 float* fp; 368 if (wc == (u_short) TIFF_VARIABLE) { 369 (*getFieldFn)(tif, fip->field_tag, &wc, &fp); 370 dir->tdir_count = wc; 371 } else 372 (*getFieldFn)(tif, fip->field_tag, &fp); 373 if (!WRITEF(TIFFWriteRationalArray, fp)) 374 return (0); 375 } else { 376 float fv; 377 (*getFieldFn)(tif, fip->field_tag, &fv); 378 if (!WRITEF(TIFFWriteRationalArray, &fv)) 379 return (0); 380 } 381 break; 382 case TIFF_FLOAT: 383 if (wc > 1) { 384 float* fp; 385 if (wc == (u_short) TIFF_VARIABLE) { 386 (*getFieldFn)(tif, fip->field_tag, &wc, &fp); 387 dir->tdir_count = wc; 388 } else 389 (*getFieldFn)(tif, fip->field_tag, &fp); 390 if (!WRITEF(TIFFWriteFloatArray, fp)) 391 return (0); 392 } else { 393 float fv; 394 (*getFieldFn)(tif, fip->field_tag, &fv); 395 if (!WRITEF(TIFFWriteFloatArray, &fv)) 396 return (0); 397 } 398 break; 399 case TIFF_DOUBLE: 400 /* Hey - I think this is a bug, or at least a "gross 401 inconsistency", in the TIFF library. Look at the original 402 TIFF library code below within the "#if (0) ... #else". 403 Just from the type of *dp, you can see that this code 404 expects TIFFGetField() to be handed a double ** for 405 any TIFF_DOUBLE tag, even for the constant wc==1 case. 406 This is totally inconsistent with other fields (like 407 TIFF_FLOAT, above) and is also inconsistent with the 408 TIFFSetField() function for TIFF_DOUBLEs, which expects 409 to be passed a single double by value for the wc==1 case. 410 (See the handling of TIFFFetchNormalTag() in tif_dirread.c 411 for an example.) Maybe this function was written before 412 TIFFWriteDoubleArray() was written, not that that's an 413 excuse. Anyway, the new code below is a trivial modification 414 of the TIFF_FLOAT code above. The fact that even single 415 doubles get written out in the data segment and get an 416 offset value stored is irrelevant here - that is all 417 handled by TIFFWriteDoubleArray(). */ 418#if (0) 419 { double* dp; 420 if (wc == (u_short) TIFF_VARIABLE) { 421 (*getFieldFn)(tif, fip->field_tag, &wc, &dp); 422 dir->tdir_count = wc; 423 } else 424 (*getFieldFn)(tif, fip->field_tag, &dp); 425 TIFFCvtNativeToIEEEDouble(tif, wc, dp); 426 if (!TIFFWriteData(tif, dir, (char*) dp)) 427 return (0); 428 } 429#else 430 if (wc > 1) { 431 double* dp; 432 if (wc == (u_short) TIFF_VARIABLE) { 433 (*getFieldFn)(tif, fip->field_tag, &wc, &dp); 434 dir->tdir_count = wc; 435 } else 436 (*getFieldFn)(tif, fip->field_tag, &dp); 437 if (!WRITEF(TIFFWriteDoubleArray, dp)) 438 return (0); 439 } else { 440 double dv; 441 (*getFieldFn)(tif, fip->field_tag, &dv); 442 if (!WRITEF(TIFFWriteDoubleArray, &dv)) 443 return (0); 444 } 445#endif 446 break; 447 case TIFF_ASCII: 448 { char* cp; 449 (*getFieldFn)(tif, fip->field_tag, &cp); 450 dir->tdir_count = (uint32) (strlen(cp) + 1); 451 if (!TIFFWriteByteArray(tif, dir, cp)) 452 return (0); 453 } 454 break; 455 case TIFF_UNDEFINED: 456 { char* cp; 457 if (wc == (u_short) TIFF_VARIABLE) { 458 (*getFieldFn)(tif, fip->field_tag, &wc, &cp); 459 dir->tdir_count = wc; 460 } else 461 (*getFieldFn)(tif, fip->field_tag, &cp); 462 if (!TIFFWriteByteArray(tif, dir, cp)) 463 return (0); 464 } 465 break; 466 } 467 return (1); 468} 469#undef WRITEF 470 471/* Everything after this is exactly duplicated from the standard tif_dirwrite.c 472 file, necessitated by the fact that they are declared static there so 473 we can't call them! 474*/ 475/* 476 * Setup a directory entry with either a SHORT 477 * or LONG type according to the value. 478 */ 479static void 480TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v) 481{ 482 dir->tdir_tag = tag; 483 dir->tdir_count = 1; 484 if (v > 0xffffL) { 485 dir->tdir_type = (short) TIFF_LONG; 486 dir->tdir_offset = v; 487 } else { 488 dir->tdir_type = (short) TIFF_SHORT; 489 dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v); 490 } 491} 492#undef MakeShortDirent 493 494#ifndef TIFFWriteRational 495/* 496 * Setup a RATIONAL directory entry and 497 * write the associated indirect value. 498 */ 499static int 500TIFFWriteRational(TIFF* tif, 501 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, float v) 502{ 503 return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v)); 504} 505#endif 506 507#define NITEMS(x) (sizeof (x) / sizeof (x[0])) 508/* 509 * Setup a directory entry that references a 510 * samples/pixel array of SHORT values and 511 * (potentially) write the associated indirect 512 * values. 513 */ 514static int 515TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) 516{ 517 uint16 buf[10], v; 518 uint16* w = buf; 519 int i, status, samples = tif->tif_dir.td_samplesperpixel; 520 521 if (samples > NITEMS(buf)) 522 w = (uint16*) _TIFFmalloc(samples * sizeof (uint16)); 523 TIFFGetField(tif, tag, &v); 524 for (i = 0; i < samples; i++) 525 w[i] = v; 526 status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w); 527 if (w != buf) 528 _TIFFfree((char*) w); 529 return (status); 530} 531 532/* 533 * Setup a directory entry that references a samples/pixel array of ``type'' 534 * values and (potentially) write the associated indirect values. The source 535 * data from TIFFGetField() for the specified tag must be returned as double. 536 */ 537static int 538TIFFWritePerSampleAnys(TIFF* tif, 539 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir) 540{ 541 double buf[10], v; 542 double* w = buf; 543 int i, status; 544 int samples = (int) tif->tif_dir.td_samplesperpixel; 545 546 if (samples > NITEMS(buf)) 547 w = (double*) _TIFFmalloc(samples * sizeof (double)); 548 TIFFGetField(tif, tag, &v); 549 for (i = 0; i < samples; i++) 550 w[i] = v; 551 status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w); 552 if (w != buf) 553 _TIFFfree(w); 554 return (status); 555} 556#undef NITEMS 557 558/* 559 * Setup a pair of shorts that are returned by 560 * value, rather than as a reference to an array. 561 */ 562static int 563TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir) 564{ 565 uint16 v[2]; 566 567 TIFFGetField(tif, tag, &v[0], &v[1]); 568 return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v)); 569} 570 571/* 572 * Setup a directory entry for an NxM table of shorts, 573 * where M is known to be 2**bitspersample, and write 574 * the associated indirect data. 575 */ 576static int 577TIFFWriteShortTable(TIFF* tif, 578 ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table) 579{ 580 uint32 i, off; 581 582 dir->tdir_tag = tag; 583 dir->tdir_type = (short) TIFF_SHORT; 584 /* XXX -- yech, fool TIFFWriteData */ 585 dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample); 586 off = tif->tif_dataoff; 587 for (i = 0; i < n; i++) 588 if (!TIFFWriteData(tif, dir, (char *)table[i])) 589 return (0); 590 dir->tdir_count *= n; 591 dir->tdir_offset = off; 592 return (1); 593} 594 595/* 596 * Write/copy data associated with an ASCII or opaque tag value. 597 */ 598static int 599TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp) 600{ 601 if (dir->tdir_count > 4) { 602 if (!TIFFWriteData(tif, dir, cp)) 603 return (0); 604 } else 605 _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count); 606 return (1); 607} 608 609/* 610 * Setup a directory entry of an array of SHORT 611 * or SSHORT and write the associated indirect values. 612 */ 613static int 614TIFFWriteShortArray(TIFF* tif, 615 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v) 616{ 617 dir->tdir_tag = tag; 618 dir->tdir_type = (short) type; 619 dir->tdir_count = n; 620 if (n <= 2) { 621 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) { 622 dir->tdir_offset = (uint32) ((long) v[0] << 16); 623 if (n == 2) 624 dir->tdir_offset |= v[1] & 0xffff; 625 } else { 626 dir->tdir_offset = v[0] & 0xffff; 627 if (n == 2) 628 dir->tdir_offset |= (long) v[1] << 16; 629 } 630 return (1); 631 } else 632 return (TIFFWriteData(tif, dir, (char*) v)); 633} 634 635/* 636 * Setup a directory entry of an array of LONG 637 * or SLONG and write the associated indirect values. 638 */ 639static int 640TIFFWriteLongArray(TIFF* tif, 641 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v) 642{ 643 dir->tdir_tag = tag; 644 dir->tdir_type = (short) type; 645 dir->tdir_count = n; 646 if (n == 1) { 647 dir->tdir_offset = v[0]; 648 return (1); 649 } else 650 return (TIFFWriteData(tif, dir, (char*) v)); 651} 652 653/* 654 * Setup a directory entry of an array of RATIONAL 655 * or SRATIONAL and write the associated indirect values. 656 */ 657static int 658TIFFWriteRationalArray(TIFF* tif, 659 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) 660{ 661 uint32 i; 662 uint32* t; 663 int status; 664 665 dir->tdir_tag = tag; 666 dir->tdir_type = (short) type; 667 dir->tdir_count = n; 668 t = (uint32*) _TIFFmalloc(2*n * sizeof (uint32)); 669 for (i = 0; i < n; i++) { 670 float fv = v[i]; 671 int sign = 1; 672 uint32 den; 673 674 if (fv < 0) { 675 if (type == TIFF_RATIONAL) { 676 TIFFWarning(tif->tif_name, 677 "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL", 678 _TIFFFieldWithTag(tif,tag)->field_name, v); 679 fv = 0; 680 } else 681 fv = -fv, sign = -1; 682 } 683 den = 1L; 684 if (fv > 0) { 685 while (fv < 1L<<(31-3) && den < 1L<<(31-3)) 686 fv *= 1<<3, den *= 1L<<3; 687 } 688 t[2*i+0] = sign * (fv + 0.5); 689 t[2*i+1] = den; 690 } 691 status = TIFFWriteData(tif, dir, (char *)t); 692 _TIFFfree((char*) t); 693 return (status); 694} 695 696static int 697TIFFWriteFloatArray(TIFF* tif, 698 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v) 699{ 700 dir->tdir_tag = tag; 701 dir->tdir_type = (short) type; 702 dir->tdir_count = n; 703 TIFFCvtNativeToIEEEFloat(tif, n, v); 704 if (n == 1) { 705 dir->tdir_offset = *(uint32*) &v[0]; 706 return (1); 707 } else 708 return (TIFFWriteData(tif, dir, (char*) v)); 709} 710 711static int 712TIFFWriteDoubleArray(TIFF* tif, 713 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v) 714{ 715 dir->tdir_tag = tag; 716 dir->tdir_type = (short) type; 717 dir->tdir_count = n; 718 TIFFCvtNativeToIEEEDouble(tif, n, v); 719 return (TIFFWriteData(tif, dir, (char*) v)); 720} 721 722/* 723 * Write an array of ``type'' values for a specified tag (i.e. this is a tag 724 * which is allowed to have different types, e.g. SMaxSampleType). 725 * Internally the data values are represented as double since a double can 726 * hold any of the TIFF tag types (yes, this should really be an abstract 727 * type tany_t for portability). The data is converted into the specified 728 * type in a temporary buffer and then handed off to the appropriate array 729 * writer. 730 */ 731static int 732TIFFWriteAnyArray(TIFF* tif, 733 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v) 734{ 735 char buf[10 * sizeof(double)]; 736 char* w = buf; 737 int i, status = 0; 738 739 if (n * TIFFDataWidth(type) > sizeof buf) 740 w = (char*) _TIFFmalloc(n * TIFFDataWidth(type)); 741 switch (type) { 742 case TIFF_BYTE: 743 { unsigned char* bp = (unsigned char*) w; 744 for (i = 0; i < n; i++) 745 bp[i] = (unsigned char) v[i]; 746 dir->tdir_tag = tag; 747 dir->tdir_type = (short) type; 748 dir->tdir_count = n; 749 if (!TIFFWriteByteArray(tif, dir, (char*) bp)) 750 goto out; 751 } 752 break; 753 case TIFF_SBYTE: 754 { signed char* bp = (signed char*) w; 755 for (i = 0; i < n; i++) 756 bp[i] = (signed char) v[i]; 757 dir->tdir_tag = tag; 758 dir->tdir_type = (short) type; 759 dir->tdir_count = n; 760 if (!TIFFWriteByteArray(tif, dir, (char*) bp)) 761 goto out; 762 } 763 break; 764 case TIFF_SHORT: 765 { uint16* bp = (uint16*) w; 766 for (i = 0; i < n; i++) 767 bp[i] = (uint16) v[i]; 768 if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp)) 769 goto out; 770 } 771 break; 772 case TIFF_SSHORT: 773 { int16* bp = (int16*) w; 774 for (i = 0; i < n; i++) 775 bp[i] = (int16) v[i]; 776 if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp)) 777 goto out; 778 } 779 break; 780 case TIFF_LONG: 781 { uint32* bp = (uint32*) w; 782 for (i = 0; i < n; i++) 783 bp[i] = (uint32) v[i]; 784 if (!TIFFWriteLongArray(tif, type, tag, dir, n, bp)) 785 goto out; 786 } 787 break; 788 case TIFF_SLONG: 789 { int32* bp = (int32*) w; 790 for (i = 0; i < n; i++) 791 bp[i] = (int32) v[i]; 792 if (!TIFFWriteLongArray(tif, type, tag, dir, n, (uint32*) bp)) 793 goto out; 794 } 795 break; 796 case TIFF_FLOAT: 797 { float* bp = (float*) w; 798 for (i = 0; i < n; i++) 799 bp[i] = (float) v[i]; 800 if (!TIFFWriteFloatArray(tif, type, tag, dir, n, bp)) 801 goto out; 802 } 803 break; 804 case TIFF_DOUBLE: 805 return (TIFFWriteDoubleArray(tif, type, tag, dir, n, v)); 806 default: 807 /* TIFF_NOTYPE */ 808 /* TIFF_ASCII */ 809 /* TIFF_UNDEFINED */ 810 /* TIFF_RATIONAL */ 811 /* TIFF_SRATIONAL */ 812 goto out; 813 } 814 status = 1; 815 out: 816 if (w != buf) 817 _TIFFfree(w); 818 return (status); 819} 820 821#ifdef COLORIMETRY_SUPPORT 822static int 823TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir) 824{ 825 TIFFDirectory* td = &tif->tif_dir; 826 tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16); 827 uint16** tf = td->td_transferfunction; 828 int ncols; 829 830 /* 831 * Check if the table can be written as a single column, 832 * or if it must be written as 3 columns. Note that we 833 * write a 3-column tag if there are 2 samples/pixel and 834 * a single column of data won't suffice--hmm. 835 */ 836 switch (td->td_samplesperpixel - td->td_extrasamples) { 837 default: if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; } 838 case 2: if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; } 839 case 1: case 0: ncols = 1; 840 } 841 return (TIFFWriteShortTable(tif, 842 TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf)); 843} 844#endif 845 846/* 847 * Write a contiguous directory item. 848 */ 849static int 850TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp) 851{ 852 tsize_t cc; 853 854 if (tif->tif_flags & TIFF_SWAB) { 855 switch (dir->tdir_type) { 856 case TIFF_SHORT: 857 case TIFF_SSHORT: 858 TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); 859 break; 860 case TIFF_LONG: 861 case TIFF_SLONG: 862 case TIFF_FLOAT: 863 TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); 864 break; 865 case TIFF_RATIONAL: 866 case TIFF_SRATIONAL: 867 TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); 868 break; 869 case TIFF_DOUBLE: 870 TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); 871 break; 872 } 873 } 874 dir->tdir_offset = tif->tif_dataoff; 875 cc = dir->tdir_count * TIFFDataWidth(dir->tdir_type); 876 if (SeekOK(tif, dir->tdir_offset) && 877 WriteOK(tif, cp, cc)) { 878 tif->tif_dataoff += (cc + 1) & ~1; 879 return (1); 880 } 881 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing data for field \"%s\"", 882 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); 883 return (0); 884} 885 886/* 887 * Link the current directory into the 888 * directory chain for the file. 889 */ 890static int 891TIFFLinkDirectory(TIFF* tif) 892{ 893 static const char module[] = "TIFFLinkDirectory"; 894 uint32 nextdir; 895 uint32 diroff; 896 897 tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; 898 diroff = (uint32) tif->tif_diroff; 899 if (tif->tif_flags & TIFF_SWAB) 900 TIFFSwabLong(&diroff); 901#if SUBIFD_SUPPORT 902 if (tif->tif_flags & TIFF_INSUBIFD) { 903 (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); 904 if (!WriteOK(tif, &diroff, sizeof (diroff))) { 905 TIFFErrorExt(tif->tif_clientdata, module, 906 "%s: Error writing SubIFD directory link", 907 tif->tif_name); 908 return (0); 909 } 910 /* 911 * Advance to the next SubIFD or, if this is 912 * the last one configured, revert back to the 913 * normal directory linkage. 914 */ 915 if (--tif->tif_nsubifd) 916 tif->tif_subifdoff += sizeof (diroff); 917 else 918 tif->tif_flags &= ~TIFF_INSUBIFD; 919 return (1); 920 } 921#endif 922 if (tif->tif_header.tiff_diroff == 0) { 923 /* 924 * First directory, overwrite offset in header. 925 */ 926 tif->tif_header.tiff_diroff = (uint32) tif->tif_diroff; 927#define HDROFF(f) ((toff_t) &(((TIFFHeader*) 0)->f)) 928 (void) TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET); 929 if (!WriteOK(tif, &diroff, sizeof (diroff))) { 930 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing TIFF header"); 931 return (0); 932 } 933 return (1); 934 } 935 /* 936 * Not the first directory, search to the last and append. 937 */ 938 nextdir = tif->tif_header.tiff_diroff; 939 do { 940 uint16 dircount; 941 942 if (!SeekOK(tif, nextdir) || 943 !ReadOK(tif, &dircount, sizeof (dircount))) { 944 TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count"); 945 return (0); 946 } 947 if (tif->tif_flags & TIFF_SWAB) 948 TIFFSwabShort(&dircount); 949 (void) TIFFSeekFile(tif, 950 dircount * sizeof (TIFFDirEntry), SEEK_CUR); 951 if (!ReadOK(tif, &nextdir, sizeof (nextdir))) { 952 TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory link"); 953 return (0); 954 } 955 if (tif->tif_flags & TIFF_SWAB) 956 TIFFSwabLong(&nextdir); 957 } while (nextdir != 0); 958 (void) TIFFSeekFile(tif, -(toff_t) sizeof (nextdir), SEEK_CUR); 959 if (!WriteOK(tif, &diroff, sizeof (diroff))) { 960 TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link"); 961 return (0); 962 } 963 return (1); 964} 965/* 966 * Local Variables: 967 * mode: c 968 * c-basic-offset: 8 969 * fill-column: 78 970 * End: 971 */ 972