Removed the libs directory containing win32 compiled versions of libpng, libtiff...
[openjpeg.git] / thirdparty / libtiff / tif_dirwrite.c
1 /* $Id: tif_dirwrite.c,v 1.37.2.7 2010-06-08 18:50:42 bfriesen 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
38 extern  void TIFFCvtNativeToIEEEFloat(TIFF*, uint32, float*);
39 extern  void TIFFCvtNativeToIEEEDouble(TIFF*, uint32, double*);
40 #endif
41
42 static  int TIFFWriteNormalTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*);
43 static  void TIFFSetupShortLong(TIFF*, ttag_t, TIFFDirEntry*, uint32);
44 static  void TIFFSetupShort(TIFF*, ttag_t, TIFFDirEntry*, uint16);
45 static  int TIFFSetupShortPair(TIFF*, ttag_t, TIFFDirEntry*);
46 static  int TIFFWritePerSampleShorts(TIFF*, ttag_t, TIFFDirEntry*);
47 static  int TIFFWritePerSampleAnys(TIFF*, TIFFDataType, ttag_t, TIFFDirEntry*);
48 static  int TIFFWriteShortTable(TIFF*, ttag_t, TIFFDirEntry*, uint32, uint16**);
49 static  int TIFFWriteShortArray(TIFF*, TIFFDirEntry*, uint16*);
50 static  int TIFFWriteLongArray(TIFF *, TIFFDirEntry*, uint32*);
51 static  int TIFFWriteRationalArray(TIFF *, TIFFDirEntry*, float*);
52 static  int TIFFWriteFloatArray(TIFF *, TIFFDirEntry*, float*);
53 static  int TIFFWriteDoubleArray(TIFF *, TIFFDirEntry*, double*);
54 static  int TIFFWriteByteArray(TIFF*, TIFFDirEntry*, char*);
55 static  int TIFFWriteAnyArray(TIFF*,
56             TIFFDataType, ttag_t, TIFFDirEntry*, uint32, double*);
57 static  int TIFFWriteTransferFunction(TIFF*, TIFFDirEntry*);
58 static  int TIFFWriteInkNames(TIFF*, TIFFDirEntry*);
59 static  int TIFFWriteData(TIFF*, TIFFDirEntry*, char*);
60 static  int TIFFLinkDirectory(TIFF*);
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  */
80 static 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,
107                                              tif->tif_name,
108                                 "Error post-encoding before directory write");
109                                 return (0);
110                         }
111                 }
112                 (*tif->tif_close)(tif);         /* shutdown encoder */
113                 /*
114                  * Flush any data that might have been written
115                  * by the compression close+cleanup routines.
116                  */
117                 if (tif->tif_rawcc > 0
118                     && (tif->tif_flags & TIFF_BEENWRITING) != 0
119                     && !TIFFFlushData1(tif)) {
120                         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
121                             "Error flushing data before directory write");
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                 TIFFErrorExt(tif->tif_clientdata, 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                  * Handle other fields.
202                  */
203                 switch (fip->field_bit)
204                 {
205                 case FIELD_STRIPOFFSETS:
206                         /*
207                          * We use one field bit for both strip and tile
208
209                          * offsets, and so must be careful in selecting
210                          * the appropriate field descriptor (so that tags
211                          * are written in sorted order).
212                          */
213                         tag = isTiled(tif) ?
214                             TIFFTAG_TILEOFFSETS : TIFFTAG_STRIPOFFSETS;
215                         if (tag != fip->field_tag)
216                                 continue;
217                         
218                         dir->tdir_tag = (uint16) tag;
219                         dir->tdir_type = (uint16) TIFF_LONG;
220                         dir->tdir_count = (uint32) td->td_nstrips;
221                         if (!TIFFWriteLongArray(tif, dir, td->td_stripoffset))
222                                 goto bad;
223                         break;
224                 case FIELD_STRIPBYTECOUNTS:
225                         /*
226                          * We use one field bit for both strip and tile
227                          * byte counts, and so must be careful in selecting
228                          * the appropriate field descriptor (so that tags
229                          * are written in sorted order).
230                          */
231                         tag = isTiled(tif) ?
232                             TIFFTAG_TILEBYTECOUNTS : TIFFTAG_STRIPBYTECOUNTS;
233                         if (tag != fip->field_tag)
234                                 continue;
235                         
236                         dir->tdir_tag = (uint16) tag;
237                         dir->tdir_type = (uint16) TIFF_LONG;
238                         dir->tdir_count = (uint32) td->td_nstrips;
239                         if (!TIFFWriteLongArray(tif, dir, td->td_stripbytecount))
240                                 goto bad;
241                         break;
242                 case FIELD_ROWSPERSTRIP:
243                         TIFFSetupShortLong(tif, TIFFTAG_ROWSPERSTRIP,
244                             dir, td->td_rowsperstrip);
245                         break;
246                 case FIELD_COLORMAP:
247                         if (!TIFFWriteShortTable(tif, TIFFTAG_COLORMAP, dir,
248                             3, td->td_colormap))
249                                 goto bad;
250                         break;
251                 case FIELD_IMAGEDIMENSIONS:
252                         TIFFSetupShortLong(tif, TIFFTAG_IMAGEWIDTH,
253                             dir++, td->td_imagewidth);
254                         TIFFSetupShortLong(tif, TIFFTAG_IMAGELENGTH,
255                             dir, td->td_imagelength);
256                         break;
257                 case FIELD_TILEDIMENSIONS:
258                         TIFFSetupShortLong(tif, TIFFTAG_TILEWIDTH,
259                             dir++, td->td_tilewidth);
260                         TIFFSetupShortLong(tif, TIFFTAG_TILELENGTH,
261                             dir, td->td_tilelength);
262                         break;
263                 case FIELD_COMPRESSION:
264                         TIFFSetupShort(tif, TIFFTAG_COMPRESSION,
265                             dir, td->td_compression);
266                         break;
267                 case FIELD_PHOTOMETRIC:
268                         TIFFSetupShort(tif, TIFFTAG_PHOTOMETRIC,
269                             dir, td->td_photometric);
270                         break;
271                 case FIELD_POSITION:
272                         WriteRationalPair(TIFF_RATIONAL,
273                             TIFFTAG_XPOSITION, td->td_xposition,
274                             TIFFTAG_YPOSITION, td->td_yposition);
275                         break;
276                 case FIELD_RESOLUTION:
277                         WriteRationalPair(TIFF_RATIONAL,
278                             TIFFTAG_XRESOLUTION, td->td_xresolution,
279                             TIFFTAG_YRESOLUTION, td->td_yresolution);
280                         break;
281                 case FIELD_BITSPERSAMPLE:
282                 case FIELD_MINSAMPLEVALUE:
283                 case FIELD_MAXSAMPLEVALUE:
284                 case FIELD_SAMPLEFORMAT:
285                         if (!TIFFWritePerSampleShorts(tif, fip->field_tag, dir))
286                                 goto bad;
287                         break;
288                 case FIELD_SMINSAMPLEVALUE:
289                 case FIELD_SMAXSAMPLEVALUE:
290                         if (!TIFFWritePerSampleAnys(tif,
291                             _TIFFSampleToTagType(tif), fip->field_tag, dir))
292                                 goto bad;
293                         break;
294                 case FIELD_PAGENUMBER:
295                 case FIELD_HALFTONEHINTS:
296                 case FIELD_YCBCRSUBSAMPLING:
297                         if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
298                                 goto bad;
299                         break;
300                 case FIELD_INKNAMES:
301                         if (!TIFFWriteInkNames(tif, dir))
302                                 goto bad;
303                         break;
304                 case FIELD_TRANSFERFUNCTION:
305                         if (!TIFFWriteTransferFunction(tif, dir))
306                                 goto bad;
307                         break;
308                 case FIELD_SUBIFD:
309                         /*
310                          * XXX: Always write this field using LONG type
311                          * for backward compatibility.
312                          */
313                         dir->tdir_tag = (uint16) fip->field_tag;
314                         dir->tdir_type = (uint16) TIFF_LONG;
315                         dir->tdir_count = (uint32) td->td_nsubifd;
316                         if (!TIFFWriteLongArray(tif, dir, td->td_subifd))
317                                 goto bad;
318                         /*
319                          * Total hack: if this directory includes a SubIFD
320                          * tag then force the next <n> directories to be
321                          * written as ``sub directories'' of this one.  This
322                          * is used to write things like thumbnails and
323                          * image masks that one wants to keep out of the
324                          * normal directory linkage access mechanism.
325                          */
326                         if (dir->tdir_count > 0) {
327                                 tif->tif_flags |= TIFF_INSUBIFD;
328                                 tif->tif_nsubifd = (uint16) dir->tdir_count;
329                                 if (dir->tdir_count > 1)
330                                         tif->tif_subifdoff = dir->tdir_offset;
331                                 else
332                                         tif->tif_subifdoff = (uint32)(
333                                               tif->tif_diroff
334                                             + sizeof (uint16)
335                                             + ((char*)&dir->tdir_offset-data));
336                         }
337                         break;
338                 default:
339                         /* XXX: Should be fixed and removed. */
340                         if (fip->field_tag == TIFFTAG_DOTRANGE) {
341                                 if (!TIFFSetupShortPair(tif, fip->field_tag, dir))
342                                         goto bad;
343                         }
344                         else if (!TIFFWriteNormalTag(tif, dir, fip))
345                                 goto bad;
346                         break;
347                 }
348                 dir++;
349                 
350                 if( fip->field_bit != FIELD_CUSTOM )
351                         ResetFieldBit(fields, fip->field_bit);
352         }
353
354         /*
355          * Write directory.
356          */
357         dircount = (uint16) nfields;
358         diroff = (uint32) tif->tif_nextdiroff;
359         if (tif->tif_flags & TIFF_SWAB) {
360                 /*
361                  * The file's byte order is opposite to the
362                  * native machine architecture.  We overwrite
363                  * the directory information with impunity
364                  * because it'll be released below after we
365                  * write it to the file.  Note that all the
366                  * other tag construction routines assume that
367                  * we do this byte-swapping; i.e. they only
368                  * byte-swap indirect data.
369                  */
370                 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
371                         TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
372                         TIFFSwabArrayOfLong(&dir->tdir_count, 2);
373                 }
374                 dircount = (uint16) nfields;
375                 TIFFSwabShort(&dircount);
376                 TIFFSwabLong(&diroff);
377         }
378         (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
379         if (!WriteOK(tif, &dircount, sizeof (dircount))) {
380                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
381                              "Error writing directory count");
382                 goto bad;
383         }
384         if (!WriteOK(tif, data, dirsize)) {
385                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
386                              "Error writing directory contents");
387                 goto bad;
388         }
389         if (!WriteOK(tif, &diroff, sizeof (uint32))) {
390                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
391                              "Error writing directory link");
392                 goto bad;
393         }
394         if (done) {
395                 TIFFFreeDirectory(tif);
396                 tif->tif_flags &= ~TIFF_DIRTYDIRECT;
397                 (*tif->tif_cleanup)(tif);
398
399                 /*
400                 * Reset directory-related state for subsequent
401                 * directories.
402                 */
403                 TIFFCreateDirectory(tif);
404         }
405         _TIFFfree(data);
406         return (1);
407 bad:
408         _TIFFfree(data);
409         return (0);
410 }
411 #undef WriteRationalPair
412
413 int
414 TIFFWriteDirectory(TIFF* tif)
415 {
416         return _TIFFWriteDirectory(tif, TRUE);
417 }
418
419 /*
420  * Similar to TIFFWriteDirectory(), writes the directory out
421  * but leaves all data structures in memory so that it can be
422  * written again.  This will make a partially written TIFF file
423  * readable before it is successfully completed/closed.
424  */ 
425 int
426 TIFFCheckpointDirectory(TIFF* tif)
427 {
428         int rc;
429         /* Setup the strips arrays, if they haven't already been. */
430         if (tif->tif_dir.td_stripoffset == NULL)
431             (void) TIFFSetupStrips(tif);
432         rc = _TIFFWriteDirectory(tif, FALSE);
433         (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
434         return rc;
435 }
436
437 static int
438 _TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
439 {
440         uint16 dircount;
441         uint32 nfields;
442         tsize_t dirsize;
443         char* data;
444         TIFFDirEntry* dir;
445         TIFFDirectory* td;
446         unsigned long b, fields[FIELD_SETLONGS];
447         int fi, nfi;
448
449         if (tif->tif_mode == O_RDONLY)
450                 return (1);
451
452         td = &tif->tif_dir;
453         /*
454          * Size the directory so that we can calculate
455          * offsets for the data items that aren't kept
456          * in-place in each field.
457          */
458         nfields = 0;
459         for (b = 0; b <= FIELD_LAST; b++)
460                 if (TIFFFieldSet(tif, b) && b != FIELD_CUSTOM)
461                         nfields += (b < FIELD_SUBFILETYPE ? 2 : 1);
462         nfields += td->td_customValueCount;
463         dirsize = nfields * sizeof (TIFFDirEntry);
464         data = (char*) _TIFFmalloc(dirsize);
465         if (data == NULL) {
466                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
467                              "Cannot write directory, out of space");
468                 return (0);
469         }
470         /*
471          * Put the directory  at the end of the file.
472          */
473         tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
474         tif->tif_dataoff = (toff_t)(
475             tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
476         if (tif->tif_dataoff & 1)
477                 tif->tif_dataoff++;
478         (void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
479         dir = (TIFFDirEntry*) data;
480         /*
481          * Setup external form of directory
482          * entries and write data items.
483          */
484         _TIFFmemcpy(fields, td->td_fieldsset, sizeof (fields));
485
486         for (fi = 0, nfi = tif->tif_nfields; nfi > 0; nfi--, fi++) {
487                 const TIFFFieldInfo* fip = tif->tif_fieldinfo[fi];
488
489                 /*
490                  * For custom fields, we test to see if the custom field
491                  * is set or not.  For normal fields, we just use the
492                  * FieldSet test.
493                 */
494                 if( fip->field_bit == FIELD_CUSTOM )
495                 {
496                         int ci, is_set = FALSE;
497
498                         for( ci = 0; ci < td->td_customValueCount; ci++ )
499                                 is_set |= (td->td_customValues[ci].info == fip);
500
501                         if( !is_set )
502                                 continue;
503                 }
504                 else if (!FieldSet(fields, fip->field_bit))
505                         continue;
506                 
507                 if( fip->field_bit != FIELD_CUSTOM )
508                         ResetFieldBit(fields, fip->field_bit);
509         }
510
511         /*
512          * Write directory.
513          */
514         dircount = (uint16) nfields;
515         *pdiroff = (uint32) tif->tif_nextdiroff;
516         if (tif->tif_flags & TIFF_SWAB) {
517                 /*
518                  * The file's byte order is opposite to the
519                  * native machine architecture.  We overwrite
520                  * the directory information with impunity
521                  * because it'll be released below after we
522                  * write it to the file.  Note that all the
523                  * other tag construction routines assume that
524                  * we do this byte-swapping; i.e. they only
525                  * byte-swap indirect data.
526                  */
527                 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
528                         TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
529                         TIFFSwabArrayOfLong(&dir->tdir_count, 2);
530                 }
531                 dircount = (uint16) nfields;
532                 TIFFSwabShort(&dircount);
533                 TIFFSwabLong(pdiroff);
534         }
535         (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
536         if (!WriteOK(tif, &dircount, sizeof (dircount))) {
537                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
538                              "Error writing directory count");
539                 goto bad;
540         }
541         if (!WriteOK(tif, data, dirsize)) {
542                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
543                              "Error writing directory contents");
544                 goto bad;
545         }
546         if (!WriteOK(tif, pdiroff, sizeof (uint32))) {
547                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
548                              "Error writing directory link");
549                 goto bad;
550         }
551         _TIFFfree(data);
552         return (1);
553 bad:
554         _TIFFfree(data);
555         return (0);
556 }
557
558 int
559 TIFFWriteCustomDirectory(TIFF* tif, toff_t *pdiroff)
560 {
561         return _TIFFWriteCustomDirectory(tif, pdiroff);
562 }
563
564 /*
565  * Process tags that are not special cased.
566  */
567 static int
568 TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
569 {
570         uint16 wc = (uint16) fip->field_writecount;
571         uint32 wc2;
572
573         dir->tdir_tag = (uint16) fip->field_tag;
574         dir->tdir_type = (uint16) fip->field_type;
575         dir->tdir_count = wc;
576         
577         switch (fip->field_type) {
578         case TIFF_SHORT:
579         case TIFF_SSHORT:
580                 if (fip->field_passcount) {
581                         uint16* wp;
582                         if (wc == (uint16) TIFF_VARIABLE2) {
583                                 TIFFGetField(tif, fip->field_tag, &wc2, &wp);
584                                 dir->tdir_count = wc2;
585                         } else {        /* Assume TIFF_VARIABLE */
586                                 TIFFGetField(tif, fip->field_tag, &wc, &wp);
587                                 dir->tdir_count = wc;
588                         }
589                         if (!TIFFWriteShortArray(tif, dir, wp))
590                                 return 0;
591                 } else {
592                         if (wc == 1) {
593                                 uint16 sv;
594                                 TIFFGetField(tif, fip->field_tag, &sv);
595                                 dir->tdir_offset =
596                                         TIFFInsertData(tif, dir->tdir_type, sv);
597                         } else {
598                                 uint16* wp;
599                                 TIFFGetField(tif, fip->field_tag, &wp);
600                                 if (!TIFFWriteShortArray(tif, dir, wp))
601                                         return 0;
602                         }
603                 }
604                 break;
605         case TIFF_LONG:
606         case TIFF_SLONG:
607         case TIFF_IFD:
608                 if (fip->field_passcount) {
609                         uint32* lp;
610                         if (wc == (uint16) TIFF_VARIABLE2) {
611                                 TIFFGetField(tif, fip->field_tag, &wc2, &lp);
612                                 dir->tdir_count = wc2;
613                         } else {        /* Assume TIFF_VARIABLE */
614                                 TIFFGetField(tif, fip->field_tag, &wc, &lp);
615                                 dir->tdir_count = wc;
616                         }
617                         if (!TIFFWriteLongArray(tif, dir, lp))
618                                 return 0;
619                 } else {
620                         if (wc == 1) {
621                                 /* XXX handle LONG->SHORT conversion */
622                                 TIFFGetField(tif, fip->field_tag,
623                                              &dir->tdir_offset);
624                         } else {
625                                 uint32* lp;
626                                 TIFFGetField(tif, fip->field_tag, &lp);
627                                 if (!TIFFWriteLongArray(tif, dir, lp))
628                                         return 0;
629                         }
630                 }
631                 break;
632         case TIFF_RATIONAL:
633         case TIFF_SRATIONAL:
634                 if (fip->field_passcount) {
635                         float* fp;
636                         if (wc == (uint16) TIFF_VARIABLE2) {
637                                 TIFFGetField(tif, fip->field_tag, &wc2, &fp);
638                                 dir->tdir_count = wc2;
639                         } else {        /* Assume TIFF_VARIABLE */
640                                 TIFFGetField(tif, fip->field_tag, &wc, &fp);
641                                 dir->tdir_count = wc;
642                         }
643                         if (!TIFFWriteRationalArray(tif, dir, fp))
644                                 return 0;
645                 } else {
646                         if (wc == 1) {
647                                 float fv;
648                                 TIFFGetField(tif, fip->field_tag, &fv);
649                                 if (!TIFFWriteRationalArray(tif, dir, &fv))
650                                         return 0;
651                         } else {
652                                 float* fp;
653                                 TIFFGetField(tif, fip->field_tag, &fp);
654                                 if (!TIFFWriteRationalArray(tif, dir, fp))
655                                         return 0;
656                         }
657                 }
658                 break;
659         case TIFF_FLOAT:
660                 if (fip->field_passcount) {
661                         float* fp;
662                         if (wc == (uint16) TIFF_VARIABLE2) {
663                                 TIFFGetField(tif, fip->field_tag, &wc2, &fp);
664                                 dir->tdir_count = wc2;
665                         } else {        /* Assume TIFF_VARIABLE */
666                                 TIFFGetField(tif, fip->field_tag, &wc, &fp);
667                                 dir->tdir_count = wc;
668                         }
669                         if (!TIFFWriteFloatArray(tif, dir, fp))
670                                 return 0;
671                 } else {
672                         if (wc == 1) {
673                                 float fv;
674                                 TIFFGetField(tif, fip->field_tag, &fv);
675                                 if (!TIFFWriteFloatArray(tif, dir, &fv))
676                                         return 0;
677                         } else {
678                                 float* fp;
679                                 TIFFGetField(tif, fip->field_tag, &fp);
680                                 if (!TIFFWriteFloatArray(tif, dir, fp))
681                                         return 0;
682                         }
683                 }
684                 break;
685         case TIFF_DOUBLE:
686                 if (fip->field_passcount) {
687                         double* dp;
688                         if (wc == (uint16) TIFF_VARIABLE2) {
689                                 TIFFGetField(tif, fip->field_tag, &wc2, &dp);
690                                 dir->tdir_count = wc2;
691                         } else {        /* Assume TIFF_VARIABLE */
692                                 TIFFGetField(tif, fip->field_tag, &wc, &dp);
693                                 dir->tdir_count = wc;
694                         }
695                         if (!TIFFWriteDoubleArray(tif, dir, dp))
696                                 return 0;
697                 } else {
698                         if (wc == 1) {
699                                 double dv;
700                                 TIFFGetField(tif, fip->field_tag, &dv);
701                                 if (!TIFFWriteDoubleArray(tif, dir, &dv))
702                                         return 0;
703                         } else {
704                                 double* dp;
705                                 TIFFGetField(tif, fip->field_tag, &dp);
706                                 if (!TIFFWriteDoubleArray(tif, dir, dp))
707                                         return 0;
708                         }
709                 }
710                 break;
711         case TIFF_ASCII:
712                 { 
713                     char* cp;
714                     if (fip->field_passcount)
715                     {
716                         if( wc == (uint16) TIFF_VARIABLE2 )
717                             TIFFGetField(tif, fip->field_tag, &wc2, &cp);
718                         else
719                             TIFFGetField(tif, fip->field_tag, &wc, &cp);
720                     }
721                     else
722                         TIFFGetField(tif, fip->field_tag, &cp);
723
724                     dir->tdir_count = (uint32) (strlen(cp) + 1);
725                     if (!TIFFWriteByteArray(tif, dir, cp))
726                         return (0);
727                 }
728                 break;
729
730         case TIFF_BYTE:
731         case TIFF_SBYTE:          
732                 if (fip->field_passcount) {
733                         char* cp;
734                         if (wc == (uint16) TIFF_VARIABLE2) {
735                                 TIFFGetField(tif, fip->field_tag, &wc2, &cp);
736                                 dir->tdir_count = wc2;
737                         } else {        /* Assume TIFF_VARIABLE */
738                                 TIFFGetField(tif, fip->field_tag, &wc, &cp);
739                                 dir->tdir_count = wc;
740                         }
741                         if (!TIFFWriteByteArray(tif, dir, cp))
742                                 return 0;
743                 } else {
744                         if (wc == 1) {
745                                 char cv;
746                                 TIFFGetField(tif, fip->field_tag, &cv);
747                                 if (!TIFFWriteByteArray(tif, dir, &cv))
748                                         return 0;
749                         } else {
750                                 char* cp;
751                                 TIFFGetField(tif, fip->field_tag, &cp);
752                                 if (!TIFFWriteByteArray(tif, dir, cp))
753                                         return 0;
754                         }
755                 }
756                 break;
757
758         case TIFF_UNDEFINED:
759                 { char* cp;
760                   if (wc == (unsigned short) TIFF_VARIABLE) {
761                         TIFFGetField(tif, fip->field_tag, &wc, &cp);
762                         dir->tdir_count = wc;
763                   } else if (wc == (unsigned short) TIFF_VARIABLE2) {
764                         TIFFGetField(tif, fip->field_tag, &wc2, &cp);
765                         dir->tdir_count = wc2;
766                   } else 
767                         TIFFGetField(tif, fip->field_tag, &cp);
768                   if (!TIFFWriteByteArray(tif, dir, cp))
769                         return (0);
770                 }
771                 break;
772
773         case TIFF_NOTYPE:
774                 break;
775         }
776         return (1);
777 }
778
779 /*
780  * Setup a directory entry with either a SHORT
781  * or LONG type according to the value.
782  */
783 static void
784 TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
785 {
786         dir->tdir_tag = (uint16) tag;
787         dir->tdir_count = 1;
788         if (v > 0xffffL) {
789                 dir->tdir_type = (short) TIFF_LONG;
790                 dir->tdir_offset = v;
791         } else {
792                 dir->tdir_type = (short) TIFF_SHORT;
793                 dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
794         }
795 }
796
797 /*
798  * Setup a SHORT directory entry
799  */
800 static void
801 TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
802 {
803         dir->tdir_tag = (uint16) tag;
804         dir->tdir_count = 1;
805         dir->tdir_type = (short) TIFF_SHORT;
806         dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
807 }
808 #undef MakeShortDirent
809
810 #define NITEMS(x)       (sizeof (x) / sizeof (x[0]))
811 /*
812  * Setup a directory entry that references a
813  * samples/pixel array of SHORT values and
814  * (potentially) write the associated indirect
815  * values.
816  */
817 static int
818 TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
819 {
820         uint16 buf[10], v;
821         uint16* w = buf;
822         uint16 i, samples = tif->tif_dir.td_samplesperpixel;
823         int status;
824
825         if (samples > NITEMS(buf)) {
826                 w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
827                 if (w == NULL) {
828                         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
829                             "No space to write per-sample shorts");
830                         return (0);
831                 }
832         }
833         TIFFGetField(tif, tag, &v);
834         for (i = 0; i < samples; i++)
835                 w[i] = v;
836         
837         dir->tdir_tag = (uint16) tag;
838         dir->tdir_type = (uint16) TIFF_SHORT;
839         dir->tdir_count = samples;
840         status = TIFFWriteShortArray(tif, dir, w);
841         if (w != buf)
842                 _TIFFfree((char*) w);
843         return (status);
844 }
845
846 /*
847  * Setup a directory entry that references a samples/pixel array of ``type''
848  * values and (potentially) write the associated indirect values.  The source
849  * data from TIFFGetField() for the specified tag must be returned as double.
850  */
851 static int
852 TIFFWritePerSampleAnys(TIFF* tif,
853     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
854 {
855         double buf[10], v;
856         double* w = buf;
857         uint16 i, samples = tif->tif_dir.td_samplesperpixel;
858         int status;
859
860         if (samples > NITEMS(buf)) {
861                 w = (double*) _TIFFmalloc(samples * sizeof (double));
862                 if (w == NULL) {
863                         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
864                             "No space to write per-sample values");
865                         return (0);
866                 }
867         }
868         TIFFGetField(tif, tag, &v);
869         for (i = 0; i < samples; i++)
870                 w[i] = v;
871         status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
872         if (w != buf)
873                 _TIFFfree(w);
874         return (status);
875 }
876 #undef NITEMS
877
878 /*
879  * Setup a pair of shorts that are returned by
880  * value, rather than as a reference to an array.
881  */
882 static int
883 TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
884 {
885         uint16 v[2];
886
887         TIFFGetField(tif, tag, &v[0], &v[1]);
888
889         dir->tdir_tag = (uint16) tag;
890         dir->tdir_type = (uint16) TIFF_SHORT;
891         dir->tdir_count = 2;
892         return (TIFFWriteShortArray(tif, dir, v));
893 }
894
895 /*
896  * Setup a directory entry for an NxM table of shorts,
897  * where M is known to be 2**bitspersample, and write
898  * the associated indirect data.
899  */
900 static int
901 TIFFWriteShortTable(TIFF* tif,
902     ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
903 {
904         uint32 i, off;
905
906         dir->tdir_tag = (uint16) tag;
907         dir->tdir_type = (short) TIFF_SHORT;
908         /* XXX -- yech, fool TIFFWriteData */
909         dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
910         off = tif->tif_dataoff;
911         for (i = 0; i < n; i++)
912                 if (!TIFFWriteData(tif, dir, (char *)table[i]))
913                         return (0);
914         dir->tdir_count *= n;
915         dir->tdir_offset = off;
916         return (1);
917 }
918
919 /*
920  * Write/copy data associated with an ASCII or opaque tag value.
921  */
922 static int
923 TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
924 {
925         if (dir->tdir_count <= 4) {
926                 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
927                         dir->tdir_offset = (uint32)cp[0] << 24;
928                         if (dir->tdir_count >= 2)
929                                 dir->tdir_offset |= (uint32)cp[1] << 16;
930                         if (dir->tdir_count >= 3)
931                                 dir->tdir_offset |= (uint32)cp[2] << 8;
932                         if (dir->tdir_count == 4)
933                                 dir->tdir_offset |= cp[3];
934                 } else {
935                         dir->tdir_offset = cp[0];
936                         if (dir->tdir_count >= 2)
937                                 dir->tdir_offset |= (uint32) cp[1] << 8;
938                         if (dir->tdir_count >= 3)
939                                 dir->tdir_offset |= (uint32) cp[2] << 16;
940                         if (dir->tdir_count == 4)
941                                 dir->tdir_offset |= (uint32) cp[3] << 24;
942                 }
943                 return 1;
944         } else
945                 return TIFFWriteData(tif, dir, cp);
946 }
947
948 /*
949  * Setup a directory entry of an array of SHORT
950  * or SSHORT and write the associated indirect values.
951  */
952 static int
953 TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
954 {
955         if (dir->tdir_count <= 2) {
956                 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
957                         dir->tdir_offset = (uint32) v[0] << 16;
958                         if (dir->tdir_count == 2)
959                                 dir->tdir_offset |= v[1] & 0xffff;
960                 } else {
961                         dir->tdir_offset = v[0] & 0xffff;
962                         if (dir->tdir_count == 2)
963                                 dir->tdir_offset |= (uint32) v[1] << 16;
964                 }
965                 return (1);
966         } else
967                 return (TIFFWriteData(tif, dir, (char*) v));
968 }
969
970 /*
971  * Setup a directory entry of an array of LONG
972  * or SLONG and write the associated indirect values.
973  */
974 static int
975 TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
976 {
977         if (dir->tdir_count == 1) {
978                 dir->tdir_offset = v[0];
979                 return (1);
980         } else
981                 return (TIFFWriteData(tif, dir, (char*) v));
982 }
983
984 /*
985  * Setup a directory entry of an array of RATIONAL
986  * or SRATIONAL and write the associated indirect values.
987  */
988 static int
989 TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
990 {
991         uint32 i;
992         uint32* t;
993         int status;
994
995         t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
996         if (t == NULL) {
997                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
998                     "No space to write RATIONAL array");
999                 return (0);
1000         }
1001         for (i = 0; i < dir->tdir_count; i++) {
1002                 float fv = v[i];
1003                 int sign = 1;
1004                 uint32 den;
1005
1006                 if (fv < 0) {
1007                         if (dir->tdir_type == TIFF_RATIONAL) {
1008                                 TIFFWarningExt(tif->tif_clientdata,
1009                                                tif->tif_name,
1010         "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
1011                                 _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
1012                                                 fv);
1013                                 fv = 0;
1014                         } else
1015                                 fv = -fv, sign = -1;
1016                 }
1017                 den = 1L;
1018                 if (fv > 0) {
1019                         while (fv < 1L<<(31-3) && den < 1L<<(31-3))
1020                                 fv *= 1<<3, den *= 1L<<3;
1021                 }
1022                 t[2*i+0] = (uint32) (sign * (fv + 0.5));
1023                 t[2*i+1] = den;
1024         }
1025         status = TIFFWriteData(tif, dir, (char *)t);
1026         _TIFFfree((char*) t);
1027         return (status);
1028 }
1029
1030 static int
1031 TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
1032 {
1033         TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
1034         if (dir->tdir_count == 1) {
1035                 dir->tdir_offset = *(uint32*) &v[0];
1036                 return (1);
1037         } else
1038                 return (TIFFWriteData(tif, dir, (char*) v));
1039 }
1040
1041 static int
1042 TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
1043 {
1044         TIFFCvtNativeToIEEEDouble(tif, dir->tdir_count, v);
1045         return (TIFFWriteData(tif, dir, (char*) v));
1046 }
1047
1048 /*
1049  * Write an array of ``type'' values for a specified tag (i.e. this is a tag
1050  * which is allowed to have different types, e.g. SMaxSampleType).
1051  * Internally the data values are represented as double since a double can
1052  * hold any of the TIFF tag types (yes, this should really be an abstract
1053  * type tany_t for portability).  The data is converted into the specified
1054  * type in a temporary buffer and then handed off to the appropriate array
1055  * writer.
1056  */
1057 static int
1058 TIFFWriteAnyArray(TIFF* tif,
1059     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
1060 {
1061         char buf[10 * sizeof(double)];
1062         char* w = buf;
1063         int i, status = 0;
1064
1065         if (n * TIFFDataWidth(type) > sizeof buf) {
1066                 w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
1067                 if (w == NULL) {
1068                         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1069                                      "No space to write array");
1070                         return (0);
1071                 }
1072         }
1073
1074         dir->tdir_tag = (uint16) tag;
1075         dir->tdir_type = (uint16) type;
1076         dir->tdir_count = n;
1077
1078         switch (type) {
1079         case TIFF_BYTE:
1080                 { 
1081                         uint8* bp = (uint8*) w;
1082                         for (i = 0; i < (int) n; i++)
1083                                 bp[i] = (uint8) v[i];
1084                         if (!TIFFWriteByteArray(tif, dir, (char*) bp))
1085                                 goto out;
1086                 }
1087                 break;
1088         case TIFF_SBYTE:
1089                 { 
1090                         int8* bp = (int8*) w;
1091                         for (i = 0; i < (int) n; i++)
1092                                 bp[i] = (int8) v[i];
1093                         if (!TIFFWriteByteArray(tif, dir, (char*) bp))
1094                                 goto out;
1095                 }
1096                 break;
1097         case TIFF_SHORT:
1098                 {
1099                         uint16* bp = (uint16*) w;
1100                         for (i = 0; i < (int) n; i++)
1101                                 bp[i] = (uint16) v[i];
1102                         if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
1103                                 goto out;
1104                 }
1105                 break;
1106         case TIFF_SSHORT:
1107                 { 
1108                         int16* bp = (int16*) w;
1109                         for (i = 0; i < (int) n; i++)
1110                                 bp[i] = (int16) v[i];
1111                         if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
1112                                 goto out;
1113                 }
1114                 break;
1115         case TIFF_LONG:
1116                 {
1117                         uint32* bp = (uint32*) w;
1118                         for (i = 0; i < (int) n; i++)
1119                                 bp[i] = (uint32) v[i];
1120                         if (!TIFFWriteLongArray(tif, dir, bp))
1121                                 goto out;
1122                 }
1123                 break;
1124         case TIFF_SLONG:
1125                 {
1126                         int32* bp = (int32*) w;
1127                         for (i = 0; i < (int) n; i++)
1128                                 bp[i] = (int32) v[i];
1129                         if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
1130                                 goto out;
1131                 }
1132                 break;
1133         case TIFF_FLOAT:
1134                 { 
1135                         float* bp = (float*) w;
1136                         for (i = 0; i < (int) n; i++)
1137                                 bp[i] = (float) v[i];
1138                         if (!TIFFWriteFloatArray(tif, dir, bp))
1139                                 goto out;
1140                 }
1141                 break;
1142         case TIFF_DOUBLE:
1143                 {
1144                     if( !TIFFWriteDoubleArray(tif, dir, v))
1145                         goto out;
1146                 }
1147                 break;
1148         default:
1149                 /* TIFF_NOTYPE */
1150                 /* TIFF_ASCII */
1151                 /* TIFF_UNDEFINED */
1152                 /* TIFF_RATIONAL */
1153                 /* TIFF_SRATIONAL */
1154                 goto out;
1155         }
1156         status = 1;
1157  out:
1158         if (w != buf)
1159                 _TIFFfree(w);
1160         return (status);
1161 }
1162
1163 static int
1164 TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
1165 {
1166         TIFFDirectory* td = &tif->tif_dir;
1167         tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
1168         uint16** tf = td->td_transferfunction;
1169         int ncols;
1170
1171         /*
1172          * Check if the table can be written as a single column,
1173          * or if it must be written as 3 columns.  Note that we
1174          * write a 3-column tag if there are 2 samples/pixel and
1175          * a single column of data won't suffice--hmm.
1176          */
1177         switch (td->td_samplesperpixel - td->td_extrasamples) {
1178         default:        if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
1179         case 2:         if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
1180         case 1: case 0: ncols = 1;
1181         }
1182         return (TIFFWriteShortTable(tif,
1183             TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
1184 }
1185
1186 static int
1187 TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
1188 {
1189         TIFFDirectory* td = &tif->tif_dir;
1190
1191         dir->tdir_tag = TIFFTAG_INKNAMES;
1192         dir->tdir_type = (short) TIFF_ASCII;
1193         dir->tdir_count = td->td_inknameslen;
1194         return (TIFFWriteByteArray(tif, dir, td->td_inknames));
1195 }
1196
1197 /*
1198  * Write a contiguous directory item.
1199  */
1200 static int
1201 TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
1202 {
1203         tsize_t cc;
1204
1205         if (tif->tif_flags & TIFF_SWAB) {
1206                 switch (dir->tdir_type) {
1207                 case TIFF_SHORT:
1208                 case TIFF_SSHORT:
1209                         TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
1210                         break;
1211                 case TIFF_LONG:
1212                 case TIFF_SLONG:
1213                 case TIFF_FLOAT:
1214                         TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
1215                         break;
1216                 case TIFF_RATIONAL:
1217                 case TIFF_SRATIONAL:
1218                         TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
1219                         break;
1220                 case TIFF_DOUBLE:
1221                         TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
1222                         break;
1223                 }
1224         }
1225         dir->tdir_offset = tif->tif_dataoff;
1226         cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
1227         if (SeekOK(tif, dir->tdir_offset) &&
1228             WriteOK(tif, cp, cc)) {
1229                 tif->tif_dataoff += (cc + 1) & ~1;
1230                 return (1);
1231         }
1232         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1233                      "Error writing data for field \"%s\"",
1234         _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1235         return (0);
1236 }
1237
1238 /*
1239  * Similar to TIFFWriteDirectory(), but if the directory has already
1240  * been written once, it is relocated to the end of the file, in case it
1241  * has changed in size.  Note that this will result in the loss of the 
1242  * previously used directory space. 
1243  */ 
1244
1245 int 
1246 TIFFRewriteDirectory( TIFF *tif )
1247 {
1248     static const char module[] = "TIFFRewriteDirectory";
1249
1250     /* We don't need to do anything special if it hasn't been written. */
1251     if( tif->tif_diroff == 0 )
1252         return TIFFWriteDirectory( tif );
1253
1254     /*
1255     ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
1256     ** will cause it to be added after this directories current pre-link.
1257     */
1258     
1259     /* Is it the first directory in the file? */
1260     if (tif->tif_header.tiff_diroff == tif->tif_diroff) 
1261     {
1262         tif->tif_header.tiff_diroff = 0;
1263         tif->tif_diroff = 0;
1264
1265         TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1266                      SEEK_SET);
1267         if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 
1268                      sizeof (tif->tif_diroff))) 
1269         {
1270                         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1271                                      "Error updating TIFF header");
1272             return (0);
1273         }
1274     }
1275     else
1276     {
1277         toff_t  nextdir, off;
1278
1279         nextdir = tif->tif_header.tiff_diroff;
1280         do {
1281                 uint16 dircount;
1282
1283                 if (!SeekOK(tif, nextdir) ||
1284                     !ReadOK(tif, &dircount, sizeof (dircount))) {
1285                         TIFFErrorExt(tif->tif_clientdata, module,
1286                                      "Error fetching directory count");
1287                         return (0);
1288                 }
1289                 if (tif->tif_flags & TIFF_SWAB)
1290                         TIFFSwabShort(&dircount);
1291                 (void) TIFFSeekFile(tif,
1292                     dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1293                 if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1294                         TIFFErrorExt(tif->tif_clientdata, module,
1295                                      "Error fetching directory link");
1296                         return (0);
1297                 }
1298                 if (tif->tif_flags & TIFF_SWAB)
1299                         TIFFSwabLong(&nextdir);
1300         } while (nextdir != tif->tif_diroff && nextdir != 0);
1301         off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1302         (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1303         tif->tif_diroff = 0;
1304         if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
1305                 TIFFErrorExt(tif->tif_clientdata, module,
1306                              "Error writing directory link");
1307                 return (0);
1308         }
1309     }
1310
1311     /*
1312     ** Now use TIFFWriteDirectory() normally.
1313     */
1314
1315     return TIFFWriteDirectory( tif );
1316 }
1317
1318
1319 /*
1320  * Link the current directory into the directory chain for the file.
1321  */
1322 static int
1323 TIFFLinkDirectory(TIFF* tif)
1324 {
1325         static const char module[] = "TIFFLinkDirectory";
1326         toff_t nextdir;
1327         toff_t diroff, off;
1328
1329         tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
1330         diroff = tif->tif_diroff;
1331         if (tif->tif_flags & TIFF_SWAB)
1332                 TIFFSwabLong(&diroff);
1333
1334         /*
1335          * Handle SubIFDs
1336          */
1337         if (tif->tif_flags & TIFF_INSUBIFD) {
1338                 (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
1339                 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1340                         TIFFErrorExt(tif->tif_clientdata, module,
1341                                      "%s: Error writing SubIFD directory link",
1342                                      tif->tif_name);
1343                         return (0);
1344                 }
1345                 /*
1346                  * Advance to the next SubIFD or, if this is
1347                  * the last one configured, revert back to the
1348                  * normal directory linkage.
1349                  */
1350                 if (--tif->tif_nsubifd)
1351                         tif->tif_subifdoff += sizeof (diroff);
1352                 else
1353                         tif->tif_flags &= ~TIFF_INSUBIFD;
1354                 return (1);
1355         }
1356
1357         if (tif->tif_header.tiff_diroff == 0) {
1358                 /*
1359                  * First directory, overwrite offset in header.
1360                  */
1361                 tif->tif_header.tiff_diroff = tif->tif_diroff;
1362                 (void) TIFFSeekFile(tif,
1363                                     (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1364                                     SEEK_SET);
1365                 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1366                         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1367                                      "Error writing TIFF header");
1368                         return (0);
1369                 }
1370                 return (1);
1371         }
1372         /*
1373          * Not the first directory, search to the last and append.
1374          */
1375         nextdir = tif->tif_header.tiff_diroff;
1376         do {
1377                 uint16 dircount;
1378
1379                 if (!SeekOK(tif, nextdir) ||
1380                     !ReadOK(tif, &dircount, sizeof (dircount))) {
1381                         TIFFErrorExt(tif->tif_clientdata, module,
1382                                      "Error fetching directory count");
1383                         return (0);
1384                 }
1385                 if (tif->tif_flags & TIFF_SWAB)
1386                         TIFFSwabShort(&dircount);
1387                 (void) TIFFSeekFile(tif,
1388                     dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1389                 if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1390                         TIFFErrorExt(tif->tif_clientdata, module,
1391                                      "Error fetching directory link");
1392                         return (0);
1393                 }
1394                 if (tif->tif_flags & TIFF_SWAB)
1395                         TIFFSwabLong(&nextdir);
1396         } while (nextdir != 0);
1397         off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1398         (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1399         if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1400                 TIFFErrorExt(tif->tif_clientdata, module,
1401                              "Error writing directory link");
1402                 return (0);
1403         }
1404         return (1);
1405 }
1406
1407 /* vim: set ts=8 sts=8 sw=8 noet: */
1408 /*
1409  * Local Variables:
1410  * mode: c
1411  * c-basic-offset: 8
1412  * fill-column: 78
1413  * End:
1414  */