source: liacs/MIR2010/SourceCode/cximage/tiff/tif_dirwrite.c@ 354

Last change on this file since 354 was 95, checked in by Rick van der Zwet, 15 years ago

Bad boy, improper move of directory

File size: 33.7 KB
RevLine 
[95]1/* $Id: tif_dirwrite.c,v 1.34 2006/02/23 16:07:45 dron Exp $ */
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#ifdef 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);
44static void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
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*, TIFFDirEntry*, uint16*);
50static int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
51static int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
52static int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
53static int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
54static int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
55static int TIFFWriteAnyArray(TIFF*,
56 TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
57static int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
58static int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
59static int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
60static int TIFFLinkDirectory(TIFF*);
61
62#define WriteRationalPair(type, tag1, v1, tag2, v2) { \
63 TIFFWriteRational((tif), (type), (tag1), (dir), (v1)) \
64 TIFFWriteRational((tif), (type), (tag2), (dir)+1, (v2)) \
65 (dir)++; \
66}
67#define TIFFWriteRational(tif, type, tag, dir, v) \
68 (dir)->tdir_tag = (tag); \
69 (dir)->tdir_type = (type); \
70 (dir)->tdir_count = 1; \
71 if (!TIFFWriteRationalArray((tif), (dir), &(v))) \
72 goto bad;
73
74/*
75 * Write the contents of the current directory
76 * to the specified file. This routine doesn't
77 * handle overwriting a directory with auxiliary
78 * storage that's been changed.
79 */
80static int
81_TIFFWriteDirectory(TIFF* tif, int done)
82{
83 uint16 dircount;
84 toff_t diroff;
85 ttag_t tag;
86 uint32 nfields;
87 tsize_t dirsize;
88 char* data;
89 TIFFDirEntry* dir;
90 TIFFDirectory* td;
91 unsigned long b, fields[FIELD_SETLONGS];
92 int fi, nfi;
93
94 if (tif->tif_mode == O_RDONLY)
95 return (1);
96 /*
97 * Clear write state so that subsequent images with
98 * different characteristics get the right buffers
99 * setup for them.
100 */
101 if (done)
102 {
103 if (tif->tif_flags & TIFF_POSTENCODE) {
104 tif->tif_flags &= ~TIFF_POSTENCODE;
105 if (!(*tif->tif_postencode)(tif)) {
106 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
107 "Error post-encoding before directory write");
108 return (0);
109 }
110 }
111 (*tif->tif_close)(tif); /* shutdown encoder */
112 /*
113 * Flush any data that might have been written
114 * by the compression close+cleanup routines.
115 */
116 if (tif->tif_rawcc > 0 && !TIFFFlushData1(tif)) {
117 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
118 "Error flushing data before directory write");
119 return (0);
120 }
121 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
122 _TIFFfree(tif->tif_rawdata);
123 tif->tif_rawdata = NULL;
124 tif->tif_rawcc = 0;
125 tif->tif_rawdatasize = 0;
126 }
127 tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
128 }
129
130 td = &tif->tif_dir;
131 /*
132 * Size the directory so that we can calculate
133 * offsets for the data items that aren't kept
134 * in-place in each field.
135 */
136 nfields = 0;
137 for (b = 0; b <= FIELD_LAST; b++)
138 if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
139 nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
140 nfields += td->td_customValueCount;
141 dirsize = nfields * sizeof (TIFFDirEntry);
142 data = (char*) _TIFFmalloc(dirsize);
143 if (data == NULL) {
144 TIFFErrorExt(tif->tif_clientdata, 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, SEEK_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 (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
177 const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
178
179 /*
180 ** For custom fields, we test to see if the custom field
181 ** is set or not. For normal fields, we just use the
182 ** FieldSet test.
183 */
184 if( fip->field_bit == FIELD_CUSTOM )
185 {
186 int ci, is_set = FALSE;
187
188 for( ci = 0; ci < td->td_customValueCount; ci++ )
189 is_set |= (td->td_customValues[ci].info == fip);
190
191 if( !is_set )
192 continue;
193 }
194 else if (!FieldSet(fields, fip->field_bit))
195 continue;
196
197
198 /*
199 ** Handle other fields.
200 */
201 switch (fip->field_bit)
202 {
203 case FIELD_STRIPOFFSETS:
204 /*
205 * We use one field bit for both strip and tile
206
207 * offsets, and so must be careful in selecting
208 * the appropriate field descriptor (so that tags
209 * are written in sorted order).
210 */
211 tag = isTiled(tif) ?
212 TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
213 if (tag != fip->field_tag)
214 continue;
215
216 dir->tdir_tag = (uint16) tag;
217 dir->tdir_type = (uint16) TIFF_LONG;
218 dir->tdir_count = (uint32) td->td_nstrips;
219 if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset))
220 goto bad;
221 break;
222 case FIELD_STRIPBYTECOUNTS:
223 /*
224 * We use one field bit for both strip and tile
225 * byte counts, and so must be careful in selecting
226 * the appropriate field descriptor (so that tags
227 * are written in sorted order).
228 */
229 tag = isTiled(tif) ?
230 TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
231 if (tag != fip->field_tag)
232 continue;
233
234 dir->tdir_tag = (uint16) tag;
235 dir->tdir_type = (uint16) TIFF_LONG;
236 dir->tdir_count = (uint32) td->td_nstrips;
237 if (!TIFFWriteLongArray(tif, dir,
238 td->td_stripbytecount))
239 goto bad;
240 break;
241 case FIELD_ROWSPERSTRIP:
242 TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
243 dir, td->td_rowsperstrip);
244 break;
245 case FIELD_COLORMAP:
246 if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
247 3, td->td_colormap))
248 goto bad;
249 break;
250 case FIELD_IMAGEDIMENSIONS:
251 TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
252 dir++, td->td_imagewidth);
253 TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
254 dir, td->td_imagelength);
255 break;
256 case FIELD_TILEDIMENSIONS:
257 TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
258 dir++, td->td_tilewidth);
259 TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
260 dir, td->td_tilelength);
261 break;
262 case FIELD_COMPRESSION:
263 TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
264 dir, td->td_compression);
265 break;
266 case FIELD_PHOTOMETRIC:
267 TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
268 dir, td->td_photometric);
269 break;
270 case FIELD_POSITION:
271 WriteRationalPair(TIFF_RATIONAL,
272 TIFFTAG_XPOSITION, td->td_xposition,
273 TIFFTAG_YPOSITION, td->td_yposition);
274 break;
275 case FIELD_RESOLUTION:
276 WriteRationalPair(TIFF_RATIONAL,
277 TIFFTAG_XRESOLUTION, td->td_xresolution,
278 TIFFTAG_YRESOLUTION, td->td_yresolution);
279 break;
280 case FIELD_BITSPERSAMPLE:
281 case FIELD_MINSAMPLEVALUE:
282 case FIELD_MAXSAMPLEVALUE:
283 case FIELD_SAMPLEFORMAT:
284 if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
285 goto bad;
286 break;
287 case FIELD_SMINSAMPLEVALUE:
288 case FIELD_SMAXSAMPLEVALUE:
289 if (!TIFFWritePerSampleAnys(tif,
290 _TIFFSampleToTagType(tif), fip->field_tag, dir))
291 goto bad;
292 break;
293 case FIELD_PAGENUMBER:
294 case FIELD_HALFTONEHINTS:
295 case FIELD_YCBCRSUBSAMPLING:
296 if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
297 goto bad;
298 break;
299 case FIELD_INKNAMES:
300 if (!TIFFWriteInkNames(tif, dir))
301 goto bad;
302 break;
303 case FIELD_TRANSFERFUNCTION:
304 if (!TIFFWriteTransferFunction(tif, dir))
305 goto bad;
306 break;
307 case FIELD_SUBIFD:
308 /*
309 * XXX: Always write this field using LONG type
310 * for backward compatibility.
311 */
312 dir->tdir_tag = (uint16) fip->field_tag;
313 dir->tdir_type = (uint16) TIFF_LONG;
314 dir->tdir_count = (uint32) td->td_nsubifd;
315 if (!TIFFWriteLongArray(tif, dir, td->td_subifd))
316 goto bad;
317 /*
318 * Total hack: if this directory includes a SubIFD
319 * tag then force the next <n> directories to be
320 * written as ``sub directories'' of this one. This
321 * is used to write things like thumbnails and
322 * image masks that one wants to keep out of the
323 * normal directory linkage access mechanism.
324 */
325 if (dir->tdir_count > 0) {
326 tif->tif_flags |= TIFF_INSUBIFD;
327 tif->tif_nsubifd = (uint16) dir->tdir_count;
328 if (dir->tdir_count > 1)
329 tif->tif_subifdoff = dir->tdir_offset;
330 else
331 tif->tif_subifdoff = (uint32)(
332 tif->tif_diroff
333 + sizeof (uint16)
334 + ((char*)&dir->tdir_offset-data));
335 }
336 break;
337 default:
338 /* XXX: Should be fixed and removed. */
339 if (fip->field_tag == TIFFTAG_DOTRANGE) {
340 if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
341 goto bad;
342 }
343 else if (!TIFFWriteNormalTag(tif, dir, fip))
344 goto bad;
345 break;
346 }
347 dir++;
348
349 if( fip->field_bit != FIELD_CUSTOM )
350 ResetFieldBit(fields, fip->field_bit);
351 }
352
353 /*
354 * Write directory.
355 */
356 dircount = (uint16) nfields;
357 diroff = (uint32) tif->tif_nextdiroff;
358 if (tif->tif_flags & TIFF_SWAB) {
359 /*
360 * The file's byte order is opposite to the
361 * native machine architecture. We overwrite
362 * the directory information with impunity
363 * because it'll be released below after we
364 * write it to the file. Note that all the
365 * other tag construction routines assume that
366 * we do this byte-swapping; i.e. they only
367 * byte-swap indirect data.
368 */
369 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
370 TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
371 TIFFSwabArrayOfLong(&dir->tdir_count, 2);
372 }
373 dircount = (uint16) nfields;
374 TIFFSwabShort(&dircount);
375 TIFFSwabLong(&diroff);
376 }
377 (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
378 if (!WriteOK(tif, &dircount, sizeof (dircount))) {
379 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing directory count");
380 goto bad;
381 }
382 if (!WriteOK(tif, data, dirsize)) {
383 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing directory contents");
384 goto bad;
385 }
386 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
387 TIFFErrorExt(tif->tif_clientdata, 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);
403bad:
404 _TIFFfree(data);
405 return (0);
406}
407#undef WriteRationalPair
408
409int
410TIFFWriteDirectory(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 */
421int
422TIFFCheckpointDirectory(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 */
436static int
437TIFFWriteNormalTag(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 */
647static void
648TIFFSetupShortLong(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 */
664static void
665TIFFSetupShort(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 */
681static int
682TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
683{
684 uint16 buf[10], v;
685 uint16* w = buf;
686 uint16 i, samples = tif->tif_dir.td_samplesperpixel;
687 int status;
688
689 if (samples > NITEMS(buf)) {
690 w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
691 if (w == NULL) {
692 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
693 "No space to write per-sample shorts");
694 return (0);
695 }
696 }
697 TIFFGetField(tif, tag, &v);
698 for (i = 0; i < samples; i++)
699 w[i] = v;
700
701 dir->tdir_tag = (uint16) tag;
702 dir->tdir_type = (uint16) TIFF_SHORT;
703 dir->tdir_count = samples;
704 status = TIFFWriteShortArray(tif, dir, w);
705 if (w != buf)
706 _TIFFfree((char*) w);
707 return (status);
708}
709
710/*
711 * Setup a directory entry that references a samples/pixel array of ``type''
712 * values and (potentially) write the associated indirect values. The source
713 * data from TIFFGetField() for the specified tag must be returned as double.
714 */
715static int
716TIFFWritePerSampleAnys(TIFF* tif,
717 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
718{
719 double buf[10], v;
720 double* w = buf;
721 uint16 i, samples = tif->tif_dir.td_samplesperpixel;
722 int status;
723
724 if (samples > NITEMS(buf)) {
725 w = (double*) _TIFFmalloc(samples * sizeof (double));
726 if (w == NULL) {
727 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
728 "No space to write per-sample values");
729 return (0);
730 }
731 }
732 TIFFGetField(tif, tag, &v);
733 for (i = 0; i < samples; i++)
734 w[i] = v;
735 status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
736 if (w != buf)
737 _TIFFfree(w);
738 return (status);
739}
740#undef NITEMS
741
742/*
743 * Setup a pair of shorts that are returned by
744 * value, rather than as a reference to an array.
745 */
746static int
747TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
748{
749 uint16 v[2];
750
751 TIFFGetField(tif, tag, &v[0], &v[1]);
752
753 dir->tdir_tag = (uint16) tag;
754 dir->tdir_type = (uint16) TIFF_SHORT;
755 dir->tdir_count = 2;
756 return (TIFFWriteShortArray(tif, dir, v));
757}
758
759/*
760 * Setup a directory entry for an NxM table of shorts,
761 * where M is known to be 2**bitspersample, and write
762 * the associated indirect data.
763 */
764static int
765TIFFWriteShortTable(TIFF* tif,
766 ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
767{
768 uint32 i, off;
769
770 dir->tdir_tag = (uint16) tag;
771 dir->tdir_type = (short) TIFF_SHORT;
772 /* XXX -- yech, fool TIFFWriteData */
773 dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
774 off = tif->tif_dataoff;
775 for (i = 0; i < n; i++)
776 if (!TIFFWriteData(tif, dir, (char *)table[i]))
777 return (0);
778 dir->tdir_count *= n;
779 dir->tdir_offset = off;
780 return (1);
781}
782
783/*
784 * Write/copy data associated with an ASCII or opaque tag value.
785 */
786static int
787TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
788{
789 if (dir->tdir_count > 4) {
790 if (!TIFFWriteData(tif, dir, cp))
791 return (0);
792 } else
793 _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
794 return (1);
795}
796
797/*
798 * Setup a directory entry of an array of SHORT
799 * or SSHORT and write the associated indirect values.
800 */
801static int
802TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
803{
804 if (dir->tdir_count <= 2) {
805 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
806 dir->tdir_offset = (uint32) ((long) v[0] << 16);
807 if (dir->tdir_count == 2)
808 dir->tdir_offset |= v[1] & 0xffff;
809 } else {
810 dir->tdir_offset = v[0] & 0xffff;
811 if (dir->tdir_count == 2)
812 dir->tdir_offset |= (long) v[1] << 16;
813 }
814 return (1);
815 } else
816 return (TIFFWriteData(tif, dir, (char*) v));
817}
818
819/*
820 * Setup a directory entry of an array of LONG
821 * or SLONG and write the associated indirect values.
822 */
823static int
824TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
825{
826 if (dir->tdir_count == 1) {
827 dir->tdir_offset = v[0];
828 return (1);
829 } else
830 return (TIFFWriteData(tif, dir, (char*) v));
831}
832
833/*
834 * Setup a directory entry of an array of RATIONAL
835 * or SRATIONAL and write the associated indirect values.
836 */
837static int
838TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
839{
840 uint32 i;
841 uint32* t;
842 int status;
843
844 t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
845 if (t == NULL) {
846 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
847 "No space to write RATIONAL array");
848 return (0);
849 }
850 for (i = 0; i < dir->tdir_count; i++) {
851 float fv = v[i];
852 int sign = 1;
853 uint32 den;
854
855 if (fv < 0) {
856 if (dir->tdir_type == TIFF_RATIONAL) {
857 TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
858 "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
859 _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
860 fv);
861 fv = 0;
862 } else
863 fv = -fv, sign = -1;
864 }
865 den = 1L;
866 if (fv > 0) {
867 while (fv < 1L<<(31-3) && den < 1L<<(31-3))
868 fv *= 1<<3, den *= 1L<<3;
869 }
870 t[2*i+0] = (uint32) (sign * (fv + 0.5));
871 t[2*i+1] = den;
872 }
873 status = TIFFWriteData(tif, dir, (char *)t);
874 _TIFFfree((char*) t);
875 return (status);
876}
877
878static int
879TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
880{
881 TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
882 if (dir->tdir_count == 1) {
883 dir->tdir_offset = *(uint32*) &v[0];
884 return (1);
885 } else
886 return (TIFFWriteData(tif, dir, (char*) v));
887}
888
889static int
890TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
891{
892 TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
893 return (TIFFWriteData(tif, dir, (char*) v));
894}
895
896/*
897 * Write an array of ``type'' values for a specified tag (i.e. this is a tag
898 * which is allowed to have different types, e.g. SMaxSampleType).
899 * Internally the data values are represented as double since a double can
900 * hold any of the TIFF tag types (yes, this should really be an abstract
901 * type tany_t for portability). The data is converted into the specified
902 * type in a temporary buffer and then handed off to the appropriate array
903 * writer.
904 */
905static int
906TIFFWriteAnyArray(TIFF* tif,
907 TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
908{
909 char buf[10 * sizeof(double)];
910 char* w = buf;
911 int i, status = 0;
912
913 if (n * TIFFDataWidth(type) > sizeof buf) {
914 w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
915 if (w == NULL) {
916 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
917 "No space to write array");
918 return (0);
919 }
920 }
921
922 dir->tdir_tag = (uint16) tag;
923 dir->tdir_type = (uint16) type;
924 dir->tdir_count = n;
925
926 switch (type) {
927 case TIFF_BYTE:
928 {
929 uint8* bp = (uint8*) w;
930 for (i = 0; i < (int) n; i++)
931 bp[i] = (uint8) v[i];
932 if (!TIFFWriteByteArray(tif, dir, (char*) bp))
933 goto out;
934 }
935 break;
936 case TIFF_SBYTE:
937 {
938 int8* bp = (int8*) w;
939 for (i = 0; i < (int) n; i++)
940 bp[i] = (int8) v[i];
941 if (!TIFFWriteByteArray(tif, dir, (char*) bp))
942 goto out;
943 }
944 break;
945 case TIFF_SHORT:
946 {
947 uint16* bp = (uint16*) w;
948 for (i = 0; i < (int) n; i++)
949 bp[i] = (uint16) v[i];
950 if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
951 goto out;
952 }
953 break;
954 case TIFF_SSHORT:
955 {
956 int16* bp = (int16*) w;
957 for (i = 0; i < (int) n; i++)
958 bp[i] = (int16) v[i];
959 if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
960 goto out;
961 }
962 break;
963 case TIFF_LONG:
964 {
965 uint32* bp = (uint32*) w;
966 for (i = 0; i < (int) n; i++)
967 bp[i] = (uint32) v[i];
968 if (!TIFFWriteLongArray(tif, dir, bp))
969 goto out;
970 }
971 break;
972 case TIFF_SLONG:
973 {
974 int32* bp = (int32*) w;
975 for (i = 0; i < (int) n; i++)
976 bp[i] = (int32) v[i];
977 if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
978 goto out;
979 }
980 break;
981 case TIFF_FLOAT:
982 {
983 float* bp = (float*) w;
984 for (i = 0; i < (int) n; i++)
985 bp[i] = (float) v[i];
986 if (!TIFFWriteFloatArray(tif, dir, bp))
987 goto out;
988 }
989 break;
990 case TIFF_DOUBLE:
991 return (TIFFWriteDoubleArray(tif, dir, v));
992 default:
993 /* TIFF_NOTYPE */
994 /* TIFF_ASCII */
995 /* TIFF_UNDEFINED */
996 /* TIFF_RATIONAL */
997 /* TIFF_SRATIONAL */
998 goto out;
999 }
1000 status = 1;
1001 out:
1002 if (w != buf)
1003 _TIFFfree(w);
1004 return (status);
1005}
1006
1007static int
1008TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
1009{
1010 TIFFDirectory* td = &tif->tif_dir;
1011 tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
1012 uint16** tf = td->td_transferfunction;
1013 int ncols;
1014
1015 /*
1016 * Check if the table can be written as a single column,
1017 * or if it must be written as 3 columns. Note that we
1018 * write a 3-column tag if there are 2 samples/pixel and
1019 * a single column of data won't suffice--hmm.
1020 */
1021 switch (td->td_samplesperpixel - td->td_extrasamples) {
1022 default: if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
1023 case 2: if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
1024 case 1: case 0: ncols = 1;
1025 }
1026 return (TIFFWriteShortTable(tif,
1027 TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
1028}
1029
1030static int
1031TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
1032{
1033 TIFFDirectory* td = &tif->tif_dir;
1034
1035 dir->tdir_tag = TIFFTAG_INKNAMES;
1036 dir->tdir_type = (short) TIFF_ASCII;
1037 dir->tdir_count = td->td_inknameslen;
1038 return (TIFFWriteByteArray(tif, dir, td->td_inknames));
1039}
1040
1041/*
1042 * Write a contiguous directory item.
1043 */
1044static int
1045TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
1046{
1047 tsize_t cc;
1048
1049 if (tif->tif_flags & TIFF_SWAB) {
1050 switch (dir->tdir_type) {
1051 case TIFF_SHORT:
1052 case TIFF_SSHORT:
1053 TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
1054 break;
1055 case TIFF_LONG:
1056 case TIFF_SLONG:
1057 case TIFF_FLOAT:
1058 TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
1059 break;
1060 case TIFF_RATIONAL:
1061 case TIFF_SRATIONAL:
1062 TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
1063 break;
1064 case TIFF_DOUBLE:
1065 TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
1066 break;
1067 }
1068 }
1069 dir->tdir_offset = tif->tif_dataoff;
1070 cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
1071 if (SeekOK(tif, dir->tdir_offset) &&
1072 WriteOK(tif, cp, cc)) {
1073 tif->tif_dataoff += (cc + 1) & ~1;
1074 return (1);
1075 }
1076 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing data for field \"%s\"",
1077 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1078 return (0);
1079}
1080
1081/*
1082 * Similar to TIFFWriteDirectory(), but if the directory has already
1083 * been written once, it is relocated to the end of the file, in case it
1084 * has changed in size. Note that this will result in the loss of the
1085 * previously used directory space.
1086 */
1087
1088int
1089TIFFRewriteDirectory( TIFF *tif )
1090{
1091 static const char module[] = "TIFFRewriteDirectory";
1092
1093 /* We don't need to do anything special if it hasn't been written. */
1094 if( tif->tif_diroff == 0 )
1095 return TIFFWriteDirectory( tif );
1096
1097 /*
1098 ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
1099 ** will cause it to be added after this directories current pre-link.
1100 */
1101
1102 /* Is it the first directory in the file? */
1103 if (tif->tif_header.tiff_diroff == tif->tif_diroff)
1104 {
1105 tif->tif_header.tiff_diroff = 0;
1106 tif->tif_diroff = 0;
1107
1108 TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1109 SEEK_SET);
1110 if (!WriteOK(tif, &(tif->tif_header.tiff_diroff),
1111 sizeof (tif->tif_diroff)))
1112 {
1113 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error updating TIFF header");
1114 return (0);
1115 }
1116 }
1117 else
1118 {
1119 toff_t nextdir, off;
1120
1121 nextdir = tif->tif_header.tiff_diroff;
1122 do {
1123 uint16 dircount;
1124
1125 if (!SeekOK(tif, nextdir) ||
1126 !ReadOK(tif, &dircount, sizeof (dircount))) {
1127 TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
1128 return (0);
1129 }
1130 if (tif->tif_flags & TIFF_SWAB)
1131 TIFFSwabShort(&dircount);
1132 (void) TIFFSeekFile(tif,
1133 dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1134 if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1135 TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory link");
1136 return (0);
1137 }
1138 if (tif->tif_flags & TIFF_SWAB)
1139 TIFFSwabLong(&nextdir);
1140 } while (nextdir != tif->tif_diroff && nextdir != 0);
1141 off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1142 (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1143 tif->tif_diroff = 0;
1144 if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
1145 TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1146 return (0);
1147 }
1148 }
1149
1150 /*
1151 ** Now use TIFFWriteDirectory() normally.
1152 */
1153
1154 return TIFFWriteDirectory( tif );
1155}
1156
1157
1158/*
1159 * Link the current directory into the
1160 * directory chain for the file.
1161 */
1162static int
1163TIFFLinkDirectory(TIFF* tif)
1164{
1165 static const char module[] = "TIFFLinkDirectory";
1166 toff_t nextdir;
1167 toff_t diroff, off;
1168
1169 tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
1170 diroff = tif->tif_diroff;
1171 if (tif->tif_flags & TIFF_SWAB)
1172 TIFFSwabLong(&diroff);
1173
1174 /*
1175 * Handle SubIFDs
1176 */
1177 if (tif->tif_flags & TIFF_INSUBIFD) {
1178 (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
1179 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1180 TIFFErrorExt(tif->tif_clientdata, module,
1181 "%s: Error writing SubIFD directory link",
1182 tif->tif_name);
1183 return (0);
1184 }
1185 /*
1186 * Advance to the next SubIFD or, if this is
1187 * the last one configured, revert back to the
1188 * normal directory linkage.
1189 */
1190 if (--tif->tif_nsubifd)
1191 tif->tif_subifdoff += sizeof (diroff);
1192 else
1193 tif->tif_flags &= ~TIFF_INSUBIFD;
1194 return (1);
1195 }
1196
1197 if (tif->tif_header.tiff_diroff == 0) {
1198 /*
1199 * First directory, overwrite offset in header.
1200 */
1201 tif->tif_header.tiff_diroff = tif->tif_diroff;
1202 (void) TIFFSeekFile(tif,
1203 (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1204 SEEK_SET);
1205 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1206 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "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 TIFFErrorExt(tif->tif_clientdata, 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 TIFFErrorExt(tif->tif_clientdata, 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 TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
1238 return (0);
1239 }
1240 return (1);
1241}
1242
1243/* vim: set ts=8 sts=8 sw=8 noet: */
Note: See TracBrowser for help on using the repository browser.