1 /* $Header: /usr/people/sam/tiff/libtiff/RCS/tif_dirwrite.c,v 1.41 1994/09/28 00:54:41 sam Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 Sam Leffler
5 * Copyright (c) 1991, 1992, 1993, 1994 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 #endif
37
38 static int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
39 static void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
40 static int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
41 static int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
42 static int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
43 static int TIFFWriteShortArray(TIFF*,
44 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint16*);
45 static int TIFFWriteLongArray(TIFF *,
46 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, uint32*);
47 static int TIFFWriteRationalArray(TIFF *,
48 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*);
49 static int TIFFWriteFloatArray(TIFF *,
50 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, float*);
51 static int TIFFWriteString(TIFF*, ttag_t, TIFFDirEntry*, char*);
52 #ifdef JPEG_SUPPORT
53 static int TIFFWriteJPEGQTables(TIFF*, TIFFDirEntry*);
54 static int TIFFWriteJPEGCTables(TIFF*, ttag_t, TIFFDirEntry*, u_char**);
55 #endif
56 #ifdef COLORIMETRY_SUPPORT
57 static int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
58 #endif
59 static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
60 static int TIFFLinkDirectory(TIFF*);
61
62 #define WriteRationalPair(type, tag1, v1, tag2, v2) { \
63 if (!TIFFWriteRational(tif, type, tag1, dir, v1)) \
64 goto bad; \
65 if (!TIFFWriteRational(tif, type, tag2, dir+1, v2)) \
66 goto bad; \
67 dir++; \
68 }
69 #define TIFFWriteRational(tif, type, tag, dir, v) \
70 TIFFWriteRationalArray((tif), (type), (tag), (dir), 1, &(v))
71 #ifndef TIFFWriteRational
72 static int TIFFWriteRational(TIFF*,
73 TIFFDataType, ttag_t, TIFFDirEntry*, float);
74 #endif
75
76 /*
77 * Write the contents of the current directory
78 * to the specified file. This routine doesn't
79 * handle overwriting a directory with auxiliary
80 * storage that's been changed.
81 */
82 int
TIFFWriteDirectory(TIFF * tif)83 TIFFWriteDirectory(TIFF* tif)
84 {
85 uint16 dircount;
86 uint32 diroff;
87 ttag_t tag;
88 uint32 nfields;
89 size_t dirsize;
90 char *data;
91 const TIFFFieldInfo *fip;
92 TIFFDirEntry *dir;
93 TIFFDirectory *td;
94 u_long b, fields[FIELD_SETLONGS];
95
96 if (tif->tif_mode == O_RDONLY)
97 return (1);
98 /*
99 * Clear write state so that subsequent images with
100 * different characteristics get the right buffers
101 * setup for them.
102 */
103 if (tif->tif_flags & TIFF_POSTENCODE) {
104 tif->tif_flags &= ~TIFF_POSTENCODE;
105 if (tif->tif_postencode && !(*tif->tif_postencode)(tif)) {
106 TIFFError(tif->tif_name,
107 "Error post-encoding before directory write");
108 return (0);
109 }
110 }
111 if (tif->tif_close)
112 (*tif->tif_close)(tif);
113 if (tif->tif_cleanup)
114 (*tif->tif_cleanup)(tif);
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_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 }
129 tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
130
131 td = &tif->tif_dir;
132 /*
133 * Size the directory so that we can calculate
134 * offsets for the data items that aren't kept
135 * in-place in each field.
136 */
137 nfields = 0;
138 for (b = 0; b <= FIELD_LAST; b++)
139 if (TIFFFieldSet(tif, b))
140 nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
141 dirsize = nfields * sizeof (TIFFDirEntry);
142 data = (char*)_TIFFmalloc(dirsize);
143 if (data == NULL) {
144 TIFFError(tif->tif_name,
145 "Cannot write directory, out of space");
146 return (0);
147 }
148 /*
149 * Directory hasn't been placed yet, put
150 * it at the end of the file and link it
151 * into the existing directory structure.
152 */
153 if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
154 goto bad;
155 tif->tif_dataoff = (toff_t)(
156 tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
157 if (tif->tif_dataoff & 1)
158 tif->tif_dataoff++;
159 (void) TIFFSeekFile(tif, tif->tif_dataoff, L_SET);
160 tif->tif_curdir++;
161 dir = (TIFFDirEntry *)data;
162 /*
163 * Setup external form of directory
164 * entries and write data items.
165 */
166 _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
167 /*
168 * Write out ExtraSamples tag only if
169 * extra samples are present in the data.
170 */
171 if (FieldSet(fields, FIELD_EXTRASAMPLES) && !td->td_extrasamples) {
172 ResetFieldBit(fields, FIELD_EXTRASAMPLES);
173 nfields--;
174 dirsize -= sizeof (TIFFDirEntry);
175 } /*XXX*/
176 for (fip = tiffFieldInfo; fip->field_tag; fip++) {
177 if (fip->field_bit == FIELD_IGNORE ||
178 !FieldSet(fields, fip->field_bit))
179 continue;
180 switch (fip->field_bit) {
181 case FIELD_STRIPOFFSETS:
182 /*
183 * We use one field bit for both strip and tile
184 * offsets, and so must be careful in selecting
185 * the appropriate field descriptor (so that tags
186 * are written in sorted order).
187 */
188 tag = isTiled(tif) ?
189 TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
190 if (tag != fip->field_tag)
191 continue;
192 if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir,
193 (uint32) td->td_nstrips, td->td_stripoffset))
194 goto bad;
195 break;
196 case FIELD_STRIPBYTECOUNTS:
197 /*
198 * We use one field bit for both strip and tile
199 * byte counts, and so must be careful in selecting
200 * the appropriate field descriptor (so that tags
201 * are written in sorted order).
202 */
203 tag = isTiled(tif) ?
204 TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
205 if (tag != fip->field_tag)
206 continue;
207 if (!TIFFWriteLongArray(tif, TIFF_LONG, tag, dir,
208 (uint32) td->td_nstrips, td->td_stripbytecount))
209 goto bad;
210 break;
211 case FIELD_ROWSPERSTRIP:
212 TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
213 dir, td->td_rowsperstrip);
214 break;
215 case FIELD_COLORMAP:
216 if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
217 3, td->td_colormap))
218 goto bad;
219 break;
220 case FIELD_IMAGEDIMENSIONS:
221 TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
222 dir++, td->td_imagewidth);
223 TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
224 dir, td->td_imagelength);
225 break;
226 case FIELD_TILEDIMENSIONS:
227 TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
228 dir++, td->td_tilewidth);
229 TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
230 dir, td->td_tilelength);
231 break;
232 case FIELD_POSITION:
233 WriteRationalPair(TIFF_RATIONAL,
234 TIFFTAG_XPOSITION, td->td_xposition,
235 TIFFTAG_YPOSITION, td->td_yposition);
236 break;
237 case FIELD_RESOLUTION:
238 WriteRationalPair(TIFF_RATIONAL,
239 TIFFTAG_XRESOLUTION, td->td_xresolution,
240 TIFFTAG_YRESOLUTION, td->td_yresolution);
241 break;
242 case FIELD_BITSPERSAMPLE:
243 case FIELD_MINSAMPLEVALUE:
244 case FIELD_MAXSAMPLEVALUE:
245 case FIELD_SAMPLEFORMAT:
246 if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
247 goto bad;
248 break;
249 case FIELD_PAGENUMBER:
250 case FIELD_HALFTONEHINTS:
251 #ifdef YCBCR_SUPPORT
252 case FIELD_YCBCRSUBSAMPLING:
253 #endif
254 #ifdef CMYK_SUPPORT
255 case FIELD_DOTRANGE:
256 #endif
257 if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
258 goto bad;
259 break;
260 #ifdef JPEG_SUPPORT
261 case FIELD_JPEGQTABLES:
262 if (!TIFFWriteJPEGQTables(tif, dir))
263 goto bad;
264 break;
265 case FIELD_JPEGDCTABLES:
266 if (!TIFFWriteJPEGCTables(tif,
267 TIFFTAG_JPEGDCTABLES, dir, td->td_dctab))
268 goto bad;
269 break;
270 case FIELD_JPEGACTABLES:
271 if (!TIFFWriteJPEGCTables(tif,
272 TIFFTAG_JPEGACTABLES, dir, td->td_actab))
273 goto bad;
274 break;
275 #endif
276 #ifdef COLORIMETRY_SUPPORT
277 case FIELD_TRANSFERFUNCTION:
278 if (!TIFFWriteTransferFunction(tif, dir))
279 goto bad;
280 break;
281 #endif
282 #if SUBIFD_SUPPORT
283 case FIELD_SUBIFD:
284 if (!TIFFWriteNormalTag(tif, dir, fip))
285 goto bad;
286 /*
287 * Total hack: if this directory includes a SubIFD
288 * tag then force the next <n> directories to be
289 * written as ``sub directories'' of this one. This
290 * is used to write things like thumbnails and
291 * image masks that one wants to keep out of the
292 * normal directory linkage access mechanism.
293 */
294 if (dir->tdir_count > 0) {
295 tif->tif_flags |= TIFF_INSUBIFD;
296 tif->tif_nsubifd = dir->tdir_count;
297 if (dir->tdir_count > 1)
298 tif->tif_subifdoff = dir->tdir_offset;
299 else
300 tif->tif_subifdoff = (uint32)(
301 tif->tif_diroff
302 + sizeof (uint16)
303 + ((char*)&dir->tdir_offset-data));
304 }
305 break;
306 #endif
307 default:
308 if (!TIFFWriteNormalTag(tif, dir, fip))
309 goto bad;
310 break;
311 }
312 dir++;
313 ResetFieldBit(fields, fip->field_bit);
314 }
315 /*
316 * Write directory.
317 */
318 dircount = (uint16) nfields;
319 diroff = (uint32) tif->tif_nextdiroff;
320 if (tif->tif_flags & TIFF_SWAB) {
321 TIFFSwabShort(&dircount);
322 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
323 TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
324 TIFFSwabArrayOfLong(&dir->tdir_count, 2);
325 }
326 TIFFSwabLong(&diroff);
327 }
328 (void) TIFFSeekFile(tif, tif->tif_diroff, L_SET);
329 if (!WriteOK(tif, &dircount, sizeof (dircount))) {
330 TIFFError(tif->tif_name, "Error writing directory count");
331 goto bad;
332 }
333 if (!WriteOK(tif, data, dirsize)) {
334 TIFFError(tif->tif_name, "Error writing directory contents");
335 goto bad;
336 }
337 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
338 TIFFError(tif->tif_name, "Error writing directory link");
339 goto bad;
340 }
341 TIFFFreeDirectory(tif);
342 _TIFFfree(data);
343 tif->tif_flags &= ~TIFF_DIRTYDIRECT;
344
345 /*
346 * Reset directory-related state for subsequent
347 * directories.
348 */
349 TIFFDefaultDirectory(tif);
350 tif->tif_diroff = 0;
351 tif->tif_curoff = 0;
352 tif->tif_row = (uint32) -1;
353 tif->tif_curstrip = (tstrip_t) -1;
354 return (1);
355 bad:
356 _TIFFfree(data);
357 return (0);
358 }
359 #undef WriteRationalPair
360
361 /*
362 * Process tags that are not special cased.
363 */
364 static int
TIFFWriteNormalTag(TIFF * tif,TIFFDirEntry * dir,const TIFFFieldInfo * fip)365 TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
366 {
367 TIFFDirectory* td = &tif->tif_dir;
368 u_short wc = (u_short) fip->field_writecount;
369
370 dir->tdir_tag = fip->field_tag;
371 dir->tdir_type = (u_short)fip->field_type;
372 dir->tdir_count = wc;
373 #define WRITE(x,y) x(tif, fip->field_type, fip->field_tag, dir, wc, y)
374 switch (fip->field_type) {
375 case TIFF_SHORT:
376 case TIFF_SSHORT:
377 if (wc > 1) {
378 uint16 *wp;
379 if (wc == (u_short) TIFF_VARIABLE) {
380 _TIFFgetfield(td, fip->field_tag, &wc, &wp);
381 dir->tdir_count = wc;
382 } else
383 _TIFFgetfield(td, fip->field_tag, &wp);
384 if (!WRITE(TIFFWriteShortArray, wp))
385 return (0);
386 } else {
387 uint16 sv;
388 _TIFFgetfield(td, fip->field_tag, &sv);
389 dir->tdir_offset =
390 TIFFInsertData(tif, dir->tdir_type, sv);
391 }
392 break;
393 case TIFF_LONG:
394 case TIFF_SLONG:
395 if (wc > 1) {
396 uint32 *lp;
397 if (wc == (u_short) TIFF_VARIABLE) {
398 _TIFFgetfield(td, fip->field_tag, &wc, &lp);
399 dir->tdir_count = wc;
400 } else
401 _TIFFgetfield(td, fip->field_tag, &lp);
402 if (!WRITE(TIFFWriteLongArray, lp))
403 return (0);
404 } else {
405 /* XXX handle LONG->SHORT conversion */
406 _TIFFgetfield(td, fip->field_tag, &dir->tdir_offset);
407 }
408 break;
409 case TIFF_RATIONAL:
410 case TIFF_SRATIONAL:
411 if (wc > 1) {
412 float *fp;
413 if (wc == (u_short) TIFF_VARIABLE) {
414 _TIFFgetfield(td, fip->field_tag, &wc, &fp);
415 dir->tdir_count = wc;
416 } else
417 _TIFFgetfield(td, fip->field_tag, &fp);
418 if (!WRITE(TIFFWriteRationalArray, fp))
419 return (0);
420 } else {
421 float fv;
422 _TIFFgetfield(td, fip->field_tag, &fv);
423 if (!TIFFWriteRational(tif, fip->field_type, fip->field_tag, dir, fv))
424 return (0);
425 }
426 break;
427 case TIFF_FLOAT:
428 if (wc > 1) {
429 float *fp;
430 if (wc == (u_short) TIFF_VARIABLE) {
431 _TIFFgetfield(td, fip->field_tag, &wc, &fp);
432 dir->tdir_count = wc;
433 } else
434 _TIFFgetfield(td, fip->field_tag, &fp);
435 if (!WRITE(TIFFWriteFloatArray, fp))
436 return (0);
437 } else {
438 float fv;
439 _TIFFgetfield(td, fip->field_tag, &fv);
440 TIFFCvtNativeToIEEEFloat(tif, 1, &fv);
441 /* XXX assumes sizeof (long) == sizeof (float) */
442 dir->tdir_offset = *(uint32*) &fv; /* XXX */
443 }
444 break;
445 case TIFF_ASCII: {
446 char *cp;
447 _TIFFgetfield(td, fip->field_tag, &cp);
448 if (!TIFFWriteString(tif, fip->field_tag, dir, cp))
449 return (0);
450 break;
451 }
452 }
453 return (1);
454 }
455 #undef WRITE
456
457 /*
458 * Setup a directory entry with either a SHORT
459 * or LONG type according to the value.
460 */
461 static void
TIFFSetupShortLong(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,uint32 v)462 TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
463 {
464 dir->tdir_tag = tag;
465 dir->tdir_count = 1;
466 if (v > 0xffffL) {
467 dir->tdir_type = (short)TIFF_LONG;
468 dir->tdir_offset = v;
469 } else {
470 dir->tdir_type = (short)TIFF_SHORT;
471 dir->tdir_offset = TIFFInsertData(tif, (int)TIFF_SHORT, v);
472 }
473 }
474 #undef MakeShortDirent
475
476 #ifndef TIFFWriteRational
477 /*
478 * Setup a RATIONAL directory entry and
479 * write the associated indirect value.
480 */
481 static int
TIFFWriteRational(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,float v)482 TIFFWriteRational(TIFF* tif,
483 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, float v)
484 {
485 return (TIFFWriteRationalArray(tif, type, tag, dir, 1, &v));
486 }
487 #endif
488
489 #define NITEMS(x) (sizeof (x) / sizeof (x[0]))
490 /*
491 * Setup a directory entry that references a
492 * samples/pixel array of SHORT values and
493 * (potentially) write the associated indirect
494 * values.
495 */
496 static int
TIFFWritePerSampleShorts(TIFF * tif,ttag_t tag,TIFFDirEntry * dir)497 TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
498 {
499 uint16 buf[10], v;
500 uint16* w = buf;
501 int i, status, samples = tif->tif_dir.td_samplesperpixel;
502
503 if (samples > NITEMS(buf))
504 w = (uint16*)_TIFFmalloc(samples * sizeof (uint16));
505 _TIFFgetfield(&tif->tif_dir, tag, &v);
506 for (i = 0; i < samples; i++)
507 w[i] = v;
508 status = TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, samples, w);
509 if (w != buf)
510 _TIFFfree((char*)w);
511 return (status);
512 }
513 #undef NITEMS
514
515 /*
516 * Setup a pair of shorts that are returned by
517 * value, rather than as a reference to an array.
518 */
519 static int
TIFFSetupShortPair(TIFF * tif,ttag_t tag,TIFFDirEntry * dir)520 TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
521 {
522 uint16 v[2];
523
524 _TIFFgetfield(&tif->tif_dir, tag, &v[0], &v[1]);
525 return (TIFFWriteShortArray(tif, TIFF_SHORT, tag, dir, 2, v));
526 }
527
528 /*
529 * Setup a directory entry for an NxM table of shorts,
530 * where M is known to be 2**bitspersample, and write
531 * the associated indirect data.
532 */
533 static int
TIFFWriteShortTable(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,uint32 n,uint16 ** table)534 TIFFWriteShortTable(TIFF* tif,
535 ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
536 {
537 uint32 i, off;
538
539 dir->tdir_tag = tag;
540 dir->tdir_type = (short)TIFF_SHORT;
541 /* XXX -- yech, fool TIFFWriteData */
542 dir->tdir_count = (uint32)(1L<<tif->tif_dir.td_bitspersample);
543 off = tif->tif_dataoff;
544 for (i = 0; i < n; i++)
545 if (!TIFFWriteData(tif, dir, (char *)table[i]))
546 return (0);
547 dir->tdir_count *= n;
548 dir->tdir_offset = off;
549 return (1);
550 }
551
552 /*
553 * Setup a directory entry of an ASCII string
554 * and write any associated indirect value.
555 */
556 static int
TIFFWriteString(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,char * cp)557 TIFFWriteString(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, char* cp)
558 {
559 dir->tdir_tag = tag;
560 dir->tdir_type = (short)TIFF_ASCII;
561 dir->tdir_count = (uint32)(strlen(cp) + 1); /* includes \0 byte */
562 if (dir->tdir_count > 4) {
563 if (!TIFFWriteData(tif, dir, cp))
564 return (0);
565 } else
566 _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
567 return (1);
568 }
569
570 /*
571 * Setup a directory entry of an array of SHORT
572 * or SSHORT and write the associated indirect values.
573 */
574 static int
TIFFWriteShortArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,uint16 * v)575 TIFFWriteShortArray(TIFF* tif,
576 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16* v)
577 {
578 dir->tdir_tag = tag;
579 dir->tdir_type = (short)type;
580 dir->tdir_count = n;
581 if (n <= 2) {
582 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
583 dir->tdir_offset = (uint32)((long)v[0] << 16);
584 if (n == 2)
585 dir->tdir_offset |= v[1] & 0xffff;
586 } else {
587 dir->tdir_offset = v[0] & 0xffff;
588 if (n == 2)
589 dir->tdir_offset |= (long)v[1] << 16;
590 }
591 return (1);
592 } else
593 return (TIFFWriteData(tif, dir, (char *)v));
594 }
595
596 /*
597 * Setup a directory entry of an array of LONG
598 * or SLONG and write the associated indirect values.
599 */
600 static int
TIFFWriteLongArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,uint32 * v)601 TIFFWriteLongArray(TIFF* tif,
602 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, uint32* v)
603 {
604 dir->tdir_tag = tag;
605 dir->tdir_type = (short)type;
606 dir->tdir_count = n;
607 if (n == 1) {
608 dir->tdir_offset = v[0];
609 return (1);
610 } else
611 return (TIFFWriteData(tif, dir, (char *)v));
612 }
613
614 /*
615 * Setup a directory entry of an array of RATIONAL
616 * or SRATIONAL and write the associated indirect values.
617 */
618 static int
TIFFWriteRationalArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,float * v)619 TIFFWriteRationalArray(TIFF* tif,
620 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v)
621 {
622 uint32 i;
623 uint32* t;
624 int status;
625
626 dir->tdir_tag = tag;
627 dir->tdir_type = (short)type;
628 dir->tdir_count = n;
629 t = (uint32*)_TIFFmalloc(2*n * sizeof (uint32));
630 for (i = 0; i < n; i++) {
631 float fv = v[i];
632 int sign = 1;
633 uint32 den;
634
635 if (fv < 0) {
636 if (type == TIFF_RATIONAL) {
637 TIFFWarning(tif->tif_name,
638 "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
639 TIFFFieldWithTag(tag)->field_name, v);
640 fv = 0;
641 } else
642 fv = -fv, sign = -1;
643 }
644 den = 1L;
645 if (fv > 0) {
646 while (fv < 1L<<(31-3) && den < 1L<<(31-3))
647 fv *= 1<<3, den *= 1L<<3;
648 }
649 t[2*i+0] = sign * (fv + 0.5);
650 t[2*i+1] = den;
651 }
652 status = TIFFWriteData(tif, dir, (char *)t);
653 _TIFFfree((char *)t);
654 return (status);
655 }
656
657 static int
TIFFWriteFloatArray(TIFF * tif,TIFFDataType type,ttag_t tag,TIFFDirEntry * dir,uint32 n,float * v)658 TIFFWriteFloatArray(TIFF* tif,
659 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, float* v)
660 {
661 dir->tdir_tag = tag;
662 dir->tdir_type = (short)type;
663 dir->tdir_count = n;
664 TIFFCvtNativeToIEEEFloat(tif, n, v);
665 if (n == 1) {
666 dir->tdir_offset = *(uint32*)&v[0];
667 return (1);
668 } else
669 return (TIFFWriteData(tif, dir, (char *)v));
670 }
671
672 #ifdef JPEG_SUPPORT
673 #define NITEMS(x) (sizeof (x) / sizeof (x[0]))
674 /*
675 * Setup a directory entry for JPEG Quantization
676 * tables and write the associated indirect values.
677 */
678 static int
TIFFWriteJPEGQTables(TIFF * tif,TIFFDirEntry * dir)679 TIFFWriteJPEGQTables(TIFF* tif, TIFFDirEntry* dir)
680 {
681 int i, status = 0, samples = tif->tif_dir.td_samplesperpixel;
682 uint32 buf[10], *off = buf;
683 TIFFDirEntry tdir;
684
685 tdir.tdir_tag = TIFFTAG_JPEGQTABLES; /* for diagnostics */
686 tdir.tdir_type = (short)TIFF_BYTE;
687 tdir.tdir_count = 64;
688 if (samples > NITEMS(buf))
689 off = (uint32*)_TIFFmalloc(samples * sizeof (uint32));
690 for (i = 0; i < samples; i++) {
691 if (!TIFFWriteData(tif, &tdir, (char *)tif->tif_dir.td_qtab[i]))
692 goto bad;
693 off[i] = tdir.tdir_offset;
694 }
695 status = TIFFWriteLongArray(tif, TIFF_LONG,
696 TIFFTAG_JPEGQTABLES, dir, samples, off);
697 bad:
698 if (off != buf)
699 _TIFFfree((char*)off);
700 return (status);
701 }
702
703 /*
704 * Setup a directory entry for JPEG Coefficient
705 * tables and write the associated indirect values.
706 */
707 static int
TIFFWriteJPEGCTables(TIFF * tif,ttag_t tag,TIFFDirEntry * dir,u_char ** tab)708 TIFFWriteJPEGCTables(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, u_char** tab)
709 {
710 int status = 0, samples = tif->tif_dir.td_samplesperpixel;
711 uint32 buf[10], *off = buf;
712 TIFFDirEntry tdir;
713 int i, j, ncodes;
714
715 tdir.tdir_tag = tag; /* for diagnostics */
716 tdir.tdir_type = (short)TIFF_BYTE;
717 if (samples > NITEMS(buf))
718 off = (uint32*)_TIFFmalloc(samples * sizeof (uint32));
719 for (i = 0; i < samples; i++) {
720 for (ncodes = 0, j = 0; j < 16; j++)
721 ncodes += tab[i][j];
722 tdir.tdir_count = 16+ncodes;
723 if (!TIFFWriteData(tif, &tdir, (char *)tab[i]))
724 goto bad;
725 off[i] = tdir.tdir_offset;
726 }
727 status = TIFFWriteLongArray(tif, TIFF_LONG, tag, dir, samples, off);
728 bad:
729 if (off != buf)
730 _TIFFfree((char*)off);
731 return (status);
732 }
733 #undef NITEMS
734 #endif
735
736 #ifdef COLORIMETRY_SUPPORT
737 static int
TIFFWriteTransferFunction(TIFF * tif,TIFFDirEntry * dir)738 TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
739 {
740 TIFFDirectory* td = &tif->tif_dir;
741 size_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
742 uint16** tf = td->td_transferfunction;
743 int ncols;
744
745 /*
746 * Check if the table can be written as a single column,
747 * or if it must be written as 3 columns. Note that we
748 * write a 3-column tag if there are 2 samples/pixel and
749 * a single column of data won't suffice--hmm.
750 */
751 switch (td->td_samplesperpixel - td->td_extrasamples) {
752 default: if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
753 case 2: if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
754 case 1: case 0: ncols = 1;
755 }
756 return (TIFFWriteShortTable(tif,
757 TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
758 }
759 #endif
760
761 /*
762 * Write a contiguous directory item.
763 */
764 static int
TIFFWriteData(TIFF * tif,TIFFDirEntry * dir,char * cp)765 TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
766 {
767 tsize_t cc;
768
769 if (tif->tif_flags & TIFF_SWAB) {
770 switch (dir->tdir_type) {
771 case TIFF_SHORT:
772 case TIFF_SSHORT:
773 TIFFSwabArrayOfShort((uint16*)cp, dir->tdir_count);
774 break;
775 case TIFF_LONG:
776 case TIFF_SLONG:
777 case TIFF_FLOAT:
778 TIFFSwabArrayOfLong((uint32*)cp, dir->tdir_count);
779 break;
780 case TIFF_RATIONAL:
781 case TIFF_SRATIONAL:
782 TIFFSwabArrayOfLong((uint32*)cp, 2*dir->tdir_count);
783 break;
784 }
785 }
786 dir->tdir_offset = tif->tif_dataoff;
787 cc = dir->tdir_count * tiffDataWidth[dir->tdir_type];
788 if (SeekOK(tif, dir->tdir_offset) &&
789 WriteOK(tif, cp, cc)) {
790 tif->tif_dataoff += (cc + 1) & ~1;
791 return (1);
792 }
793 TIFFError(tif->tif_name, "Error writing data for field \"%s\"",
794 TIFFFieldWithTag(dir->tdir_tag)->field_name);
795 return (0);
796 }
797
798 /*
799 * Link the current directory into the
800 * directory chain for the file.
801 */
802 static int
TIFFLinkDirectory(TIFF * tif)803 TIFFLinkDirectory(TIFF* tif)
804 {
805 static const char module[] = "TIFFLinkDirectory";
806 uint32 nextdir;
807 uint32 diroff;
808
809 tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, L_XTND)+1) &~ 1;
810 diroff = (uint32) tif->tif_diroff;
811 if (tif->tif_flags & TIFF_SWAB)
812 TIFFSwabLong(&diroff);
813 #if SUBIFD_SUPPORT
814 if (tif->tif_flags & TIFF_INSUBIFD) {
815 (void) TIFFSeekFile(tif, tif->tif_subifdoff, L_SET);
816 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
817 TIFFError(module,
818 "%s: Error writing SubIFD directory link",
819 tif->tif_name);
820 return (0);
821 }
822 /*
823 * Advance to the next SubIFD or, if this is
824 * the last one configured, revert back to the
825 * normal directory linkage.
826 */
827 if (--tif->tif_nsubifd)
828 tif->tif_subifdoff += sizeof (diroff);
829 else
830 tif->tif_flags &= ~TIFF_INSUBIFD;
831 return (1);
832 }
833 #endif
834 if (tif->tif_header.tiff_diroff == 0) {
835 /*
836 * First directory, overwrite header.
837 */
838 tif->tif_header.tiff_diroff = diroff;
839 (void) TIFFSeekFile(tif, (toff_t) 0, L_SET);
840 if (!WriteOK(tif, &tif->tif_header, sizeof (tif->tif_header))) {
841 TIFFError(tif->tif_name, "Error writing TIFF header");
842 return (0);
843 }
844 return (1);
845 }
846 /*
847 * Not the first directory, search to the last and append.
848 */
849 nextdir = tif->tif_header.tiff_diroff;
850 do {
851 uint16 dircount;
852
853 if (!SeekOK(tif, nextdir) ||
854 !ReadOK(tif, &dircount, sizeof (dircount))) {
855 TIFFError(module, "Error fetching directory count");
856 return (0);
857 }
858 if (tif->tif_flags & TIFF_SWAB)
859 TIFFSwabShort(&dircount);
860 (void) TIFFSeekFile(tif,
861 dircount * sizeof (TIFFDirEntry), L_INCR);
862 if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
863 TIFFError(module, "Error fetching directory link");
864 return (0);
865 }
866 if (tif->tif_flags & TIFF_SWAB)
867 TIFFSwabLong(&nextdir);
868 } while (nextdir != 0);
869 (void) TIFFSeekFile(tif, (toff_t) -sizeof (nextdir), L_INCR);
870 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
871 TIFFError(module, "Error writing directory link");
872 return (0);
873 }
874 return (1);
875 }
876