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