1 /* $Id: tif_dirwrite.c,v 1.37.2.7 2010-06-08 18:50:42 bfriesen Exp $ */
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
30 * Directory Write Support Routines.
35 # define TIFFCvtNativeToIEEEFloat(tif, n, fp)
36 # define TIFFCvtNativeToIEEEDouble(tif, n, dp)
38 extern void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
39 extern void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
42 static int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
43 static void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
44 static void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
45 static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
46 static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
47 static int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
48 static int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
49 static int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*);
50 static int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
51 static int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
52 static int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
53 static int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
54 static int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
55 static int TIFFWriteAnyArray(TIFF*,
56 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
57 static int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
58 static int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
59 static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
60 static int TIFFLinkDirectory(TIFF*);
62 #define WriteRationalPair(type, tag1, v1, tag2, v2) { \
63 TIFFWriteRational((tif), (type), (tag1), (dir), (v1)) \
64 TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2)) \
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))) \
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.
81 _TIFFWriteDirectory(TIFF* tif, int done)
91 unsigned long b, fields[FIELD_SETLONGS];
94 if (tif->tif_mode == O_RDONLY)
97 * Clear write state so that subsequent images with
98 * different characteristics get the right buffers
103 if (tif->tif_flags & TIFF_POSTENCODE) {
104 tif->tif_flags &= ~TIFF_POSTENCODE;
105 if (!(*tif->tif_postencode)(tif)) {
106 TIFFErrorExt(tif->tif_clientdata,
108 "Error post-encoding before directory write");
112 (*tif->tif_close)(tif); /* shutdown encoder */
114 * Flush any data that might have been written
115 * by the compression close+cleanup routines.
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");
124 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
125 _TIFFfree(tif->tif_rawdata);
126 tif->tif_rawdata = NULL;
128 tif->tif_rawdatasize = 0;
130 tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
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.
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);
147 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
148 "Cannot write directory, out of space");
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.
156 if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
158 tif->tif_dataoff = (toff_t)(
159 tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
160 if (tif->tif_dataoff & 1)
162 (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
164 dir = (TIFFDirEntry*) data;
166 * Setup external form of directory
167 * entries and write data items.
169 _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
171 * Write out ExtraSamples tag only if
172 * extra samples are present in the data.
174 if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
175 ResetFieldBit(fields, FIELD_EXTRASAMPLES);
177 dirsize -= sizeof (TIFFDirEntry);
179 for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
180 const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
183 * For custom fields, we test to see if the custom field
184 * is set or not. For normal fields, we just use the
187 if( fip->field_bit == FIELD_CUSTOM )
189 int ci, is_set = FALSE;
191 for( ci = 0; ci < td->td_customValueCount; ci++ )
192 is_set |= (td->td_customValues[ci].info == fip);
197 else if (!FieldSet(fields, fip->field_bit))
201 * Handle other fields.
203 switch (fip->field_bit)
205 case FIELD_STRIPOFFSETS:
207 * We use one field bit for both strip and tile
209 * offsets, and so must be careful in selecting
210 * the appropriate field descriptor (so that tags
211 * are written in sorted order).
214 TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
215 if (tag != fip->field_tag)
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))
224 case FIELD_STRIPBYTECOUNTS:
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).
232 TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
233 if (tag != fip->field_tag)
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))
242 case FIELD_ROWSPERSTRIP:
243 TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
244 dir, td->td_rowsperstrip);
247 if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
251 case FIELD_IMAGEDIMENSIONS:
252 TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
253 dir++, td->td_imagewidth);
254 TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
255 dir, td->td_imagelength);
257 case FIELD_TILEDIMENSIONS:
258 TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
259 dir++, td->td_tilewidth);
260 TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
261 dir, td->td_tilelength);
263 case FIELD_COMPRESSION:
264 TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
265 dir, td->td_compression);
267 case FIELD_PHOTOMETRIC:
268 TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
269 dir, td->td_photometric);
272 WriteRationalPair(TIFF_RATIONAL,
273 TIFFTAG_XPOSITION, td->td_xposition,
274 TIFFTAG_YPOSITION, td->td_yposition);
276 case FIELD_RESOLUTION:
277 WriteRationalPair(TIFF_RATIONAL,
278 TIFFTAG_XRESOLUTION, td->td_xresolution,
279 TIFFTAG_YRESOLUTION, td->td_yresolution);
281 case FIELD_BITSPERSAMPLE:
282 case FIELD_MINSAMPLEVALUE:
283 case FIELD_MAXSAMPLEVALUE:
284 case FIELD_SAMPLEFORMAT:
285 if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
288 case FIELD_SMINSAMPLEVALUE:
289 case FIELD_SMAXSAMPLEVALUE:
290 if (!TIFFWritePerSampleAnys(tif,
291 _TIFFSampleToTagType(tif), fip->field_tag, dir))
294 case FIELD_PAGENUMBER:
295 case FIELD_HALFTONEHINTS:
296 case FIELD_YCBCRSUBSAMPLING:
297 if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
301 if (!TIFFWriteInkNames(tif, dir))
304 case FIELD_TRANSFERFUNCTION:
305 if (!TIFFWriteTransferFunction(tif, dir))
310 * XXX: Always write this field using LONG type
311 * for backward compatibility.
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))
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.
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;
332 tif->tif_subifdoff = (uint32)(
335 + ((char*)&dir->tdir_offset-data));
339 /* XXX: Should be fixed and removed. */
340 if (fip->field_tag == TIFFTAG_DOTRANGE) {
341 if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
344 else if (!TIFFWriteNormalTag(tif, dir, fip))
350 if( fip->field_bit != FIELD_CUSTOM )
351 ResetFieldBit(fields, fip->field_bit);
357 dircount = (uint16) nfields;
358 diroff = (uint32) tif->tif_nextdiroff;
359 if (tif->tif_flags & TIFF_SWAB) {
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.
370 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
371 TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
372 TIFFSwabArrayOfLong(&dir->tdir_count, 2);
374 dircount = (uint16) nfields;
375 TIFFSwabShort(&dircount);
376 TIFFSwabLong(&diroff);
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");
384 if (!WriteOK(tif, data, dirsize)) {
385 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
386 "Error writing directory contents");
389 if (!WriteOK(tif, &diroff, sizeof (uint32))) {
390 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
391 "Error writing directory link");
395 TIFFFreeDirectory(tif);
396 tif->tif_flags &= ~TIFF_DIRTYDIRECT;
397 (*tif->tif_cleanup)(tif);
400 * Reset directory-related state for subsequent
403 TIFFCreateDirectory(tif);
411 #undef WriteRationalPair
414 TIFFWriteDirectory(TIFF* tif)
416 return _TIFFWriteDirectory(tif, TRUE);
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.
426 TIFFCheckpointDirectory(TIFF* tif)
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));
438 _TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
446 unsigned long b, fields[FIELD_SETLONGS];
449 if (tif->tif_mode == O_RDONLY)
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.
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);
466 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
467 "Cannot write directory, out of space");
471 * Put the directory at the end of the file.
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)
478 (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
479 dir = (TIFFDirEntry*) data;
481 * Setup external form of directory
482 * entries and write data items.
484 _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
486 for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
487 const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
490 * For custom fields, we test to see if the custom field
491 * is set or not. For normal fields, we just use the
494 if( fip->field_bit == FIELD_CUSTOM )
496 int ci, is_set = FALSE;
498 for( ci = 0; ci < td->td_customValueCount; ci++ )
499 is_set |= (td->td_customValues[ci].info == fip);
504 else if (!FieldSet(fields, fip->field_bit))
507 if( fip->field_bit != FIELD_CUSTOM )
508 ResetFieldBit(fields, fip->field_bit);
514 dircount = (uint16) nfields;
515 *pdiroff = (uint32) tif->tif_nextdiroff;
516 if (tif->tif_flags & TIFF_SWAB) {
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.
527 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
528 TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
529 TIFFSwabArrayOfLong(&dir->tdir_count, 2);
531 dircount = (uint16) nfields;
532 TIFFSwabShort(&dircount);
533 TIFFSwabLong(pdiroff);
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");
541 if (!WriteOK(tif, data, dirsize)) {
542 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
543 "Error writing directory contents");
546 if (!WriteOK(tif, pdiroff, sizeof (uint32))) {
547 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
548 "Error writing directory link");
559 TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
561 return _TIFFWriteCustomDirectory(tif, pdiroff);
565 * Process tags that are not special cased.
568 TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
570 uint16 wc = (uint16) fip->field_writecount;
573 dir->tdir_tag = (uint16) fip->field_tag;
574 dir->tdir_type = (uint16) fip->field_type;
575 dir->tdir_count = wc;
577 switch (fip->field_type) {
580 if (fip->field_passcount) {
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;
589 if (!TIFFWriteShortArray(tif, dir, wp))
594 TIFFGetField(tif, fip->field_tag, &sv);
596 TIFFInsertData(tif, dir->tdir_type, sv);
599 TIFFGetField(tif, fip->field_tag, &wp);
600 if (!TIFFWriteShortArray(tif, dir, wp))
608 if (fip->field_passcount) {
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;
617 if (!TIFFWriteLongArray(tif, dir, lp))
621 /* XXX handle LONG->SHORT conversion */
622 TIFFGetField(tif, fip->field_tag,
626 TIFFGetField(tif, fip->field_tag, &lp);
627 if (!TIFFWriteLongArray(tif, dir, lp))
634 if (fip->field_passcount) {
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;
643 if (!TIFFWriteRationalArray(tif, dir, fp))
648 TIFFGetField(tif, fip->field_tag, &fv);
649 if (!TIFFWriteRationalArray(tif, dir, &fv))
653 TIFFGetField(tif, fip->field_tag, &fp);
654 if (!TIFFWriteRationalArray(tif, dir, fp))
660 if (fip->field_passcount) {
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;
669 if (!TIFFWriteFloatArray(tif, dir, fp))
674 TIFFGetField(tif, fip->field_tag, &fv);
675 if (!TIFFWriteFloatArray(tif, dir, &fv))
679 TIFFGetField(tif, fip->field_tag, &fp);
680 if (!TIFFWriteFloatArray(tif, dir, fp))
686 if (fip->field_passcount) {
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;
695 if (!TIFFWriteDoubleArray(tif, dir, dp))
700 TIFFGetField(tif, fip->field_tag, &dv);
701 if (!TIFFWriteDoubleArray(tif, dir, &dv))
705 TIFFGetField(tif, fip->field_tag, &dp);
706 if (!TIFFWriteDoubleArray(tif, dir, dp))
714 if (fip->field_passcount)
716 if( wc == (uint16) TIFF_VARIABLE2 )
717 TIFFGetField(tif, fip->field_tag, &wc2, &cp);
719 TIFFGetField(tif, fip->field_tag, &wc, &cp);
722 TIFFGetField(tif, fip->field_tag, &cp);
724 dir->tdir_count = (uint32) (strlen(cp) + 1);
725 if (!TIFFWriteByteArray(tif, dir, cp))
732 if (fip->field_passcount) {
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;
741 if (!TIFFWriteByteArray(tif, dir, cp))
746 TIFFGetField(tif, fip->field_tag, &cv);
747 if (!TIFFWriteByteArray(tif, dir, &cv))
751 TIFFGetField(tif, fip->field_tag, &cp);
752 if (!TIFFWriteByteArray(tif, dir, 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;
767 TIFFGetField(tif, fip->field_tag, &cp);
768 if (!TIFFWriteByteArray(tif, dir, cp))
780 * Setup a directory entry with either a SHORT
781 * or LONG type according to the value.
784 TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
786 dir->tdir_tag = (uint16) tag;
789 dir->tdir_type = (short) TIFF_LONG;
790 dir->tdir_offset = v;
792 dir->tdir_type = (short) TIFF_SHORT;
793 dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
798 * Setup a SHORT directory entry
801 TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
803 dir->tdir_tag = (uint16) tag;
805 dir->tdir_type = (short) TIFF_SHORT;
806 dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
808 #undef MakeShortDirent
810 #define NITEMS(x) (sizeof (x) / sizeof (x[0]))
812 * Setup a directory entry that references a
813 * samples/pixel array of SHORT values and
814 * (potentially) write the associated indirect
818 TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
822 uint16 i, samples = tif->tif_dir.td_samplesperpixel;
825 if (samples > NITEMS(buf)) {
826 w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
828 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
829 "No space to write per-sample shorts");
833 TIFFGetField(tif, tag, &v);
834 for (i = 0; i < samples; i++)
837 dir->tdir_tag = (uint16) tag;
838 dir->tdir_type = (uint16) TIFF_SHORT;
839 dir->tdir_count = samples;
840 status = TIFFWriteShortArray(tif, dir, w);
842 _TIFFfree((char*) w);
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.
852 TIFFWritePerSampleAnys(TIFF* tif,
853 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
857 uint16 i, samples = tif->tif_dir.td_samplesperpixel;
860 if (samples > NITEMS(buf)) {
861 w = (double*) _TIFFmalloc(samples * sizeof (double));
863 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
864 "No space to write per-sample values");
868 TIFFGetField(tif, tag, &v);
869 for (i = 0; i < samples; i++)
871 status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
879 * Setup a pair of shorts that are returned by
880 * value, rather than as a reference to an array.
883 TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
887 TIFFGetField(tif, tag, &v[0], &v[1]);
889 dir->tdir_tag = (uint16) tag;
890 dir->tdir_type = (uint16) TIFF_SHORT;
892 return (TIFFWriteShortArray(tif, dir, v));
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.
901 TIFFWriteShortTable(TIFF* tif,
902 ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
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]))
914 dir->tdir_count *= n;
915 dir->tdir_offset = off;
920 * Write/copy data associated with an ASCII or opaque tag value.
923 TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
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];
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;
945 return TIFFWriteData(tif, dir, cp);
949 * Setup a directory entry of an array of SHORT
950 * or SSHORT and write the associated indirect values.
953 TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
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;
961 dir->tdir_offset = v[0] & 0xffff;
962 if (dir->tdir_count == 2)
963 dir->tdir_offset |= (uint32) v[1] << 16;
967 return (TIFFWriteData(tif, dir, (char*) v));
971 * Setup a directory entry of an array of LONG
972 * or SLONG and write the associated indirect values.
975 TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
977 if (dir->tdir_count == 1) {
978 dir->tdir_offset = v[0];
981 return (TIFFWriteData(tif, dir, (char*) v));
985 * Setup a directory entry of an array of RATIONAL
986 * or SRATIONAL and write the associated indirect values.
989 TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
995 t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
997 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
998 "No space to write RATIONAL array");
1001 for (i = 0; i < dir->tdir_count; i++) {
1007 if (dir->tdir_type == TIFF_RATIONAL) {
1008 TIFFWarningExt(tif->tif_clientdata,
1010 "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
1011 _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
1015 fv = -fv, sign = -1;
1019 while (fv < 1L<<(31-3) && den < 1L<<(31-3))
1020 fv *= 1<<3, den *= 1L<<3;
1022 t[2*i+0] = (uint32) (sign * (fv + 0.5));
1025 status = TIFFWriteData(tif, dir, (char *)t);
1026 _TIFFfree((char*) t);
1031 TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
1033 TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
1034 if (dir->tdir_count == 1) {
1035 dir->tdir_offset = *(uint32*) &v[0];
1038 return (TIFFWriteData(tif, dir, (char*) v));
1042 TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
1044 TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
1045 return (TIFFWriteData(tif, dir, (char*) v));
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
1058 TIFFWriteAnyArray(TIFF* tif,
1059 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
1061 char buf[10 * sizeof(double)];
1065 if (n * TIFFDataWidth(type) > sizeof buf) {
1066 w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
1068 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1069 "No space to write array");
1074 dir->tdir_tag = (uint16) tag;
1075 dir->tdir_type = (uint16) type;
1076 dir->tdir_count = n;
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))
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))
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))
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))
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))
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))
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))
1144 if( !TIFFWriteDoubleArray(tif, dir, v))
1151 /* TIFF_UNDEFINED */
1153 /* TIFF_SRATIONAL */
1164 TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
1166 TIFFDirectory* td = &tif->tif_dir;
1167 tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
1168 uint16** tf = td->td_transferfunction;
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.
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;
1182 return (TIFFWriteShortTable(tif,
1183 TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
1187 TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
1189 TIFFDirectory* td = &tif->tif_dir;
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));
1198 * Write a contiguous directory item.
1201 TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
1205 if (tif->tif_flags & TIFF_SWAB) {
1206 switch (dir->tdir_type) {
1209 TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
1214 TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
1217 case TIFF_SRATIONAL:
1218 TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
1221 TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
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;
1232 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1233 "Error writing data for field \"%s\"",
1234 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
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.
1246 TIFFRewriteDirectory( TIFF *tif )
1248 static const char module[] = "TIFFRewriteDirectory";
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 );
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.
1259 /* Is it the first directory in the file? */
1260 if (tif->tif_header.tiff_diroff == tif->tif_diroff)
1262 tif->tif_header.tiff_diroff = 0;
1263 tif->tif_diroff = 0;
1265 TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1267 if (!WriteOK(tif, &(tif->tif_header.tiff_diroff),
1268 sizeof (tif->tif_diroff)))
1270 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1271 "Error updating TIFF header");
1277 toff_t nextdir, off;
1279 nextdir = tif->tif_header.tiff_diroff;
1283 if (!SeekOK(tif, nextdir) ||
1284 !ReadOK(tif, &dircount, sizeof (dircount))) {
1285 TIFFErrorExt(tif->tif_clientdata, module,
1286 "Error fetching directory count");
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");
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");
1312 ** Now use TIFFWriteDirectory() normally.
1315 return TIFFWriteDirectory( tif );
1320 * Link the current directory into the directory chain for the file.
1323 TIFFLinkDirectory(TIFF* tif)
1325 static const char module[] = "TIFFLinkDirectory";
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);
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",
1346 * Advance to the next SubIFD or, if this is
1347 * the last one configured, revert back to the
1348 * normal directory linkage.
1350 if (--tif->tif_nsubifd)
1351 tif->tif_subifdoff += sizeof (diroff);
1353 tif->tif_flags &= ~TIFF_INSUBIFD;
1357 if (tif->tif_header.tiff_diroff == 0) {
1359 * First directory, overwrite offset in header.
1361 tif->tif_header.tiff_diroff = tif->tif_diroff;
1362 (void) TIFFSeekFile(tif,
1363 (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1365 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1366 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1367 "Error writing TIFF header");
1373 * Not the first directory, search to the last and append.
1375 nextdir = tif->tif_header.tiff_diroff;
1379 if (!SeekOK(tif, nextdir) ||
1380 !ReadOK(tif, &dircount, sizeof (dircount))) {
1381 TIFFErrorExt(tif->tif_clientdata, module,
1382 "Error fetching directory count");
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");
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");
1407 /* vim: set ts=8 sts=8 sw=8 noet: */