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