Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / libtiff / tif_dirwrite.c
1 /* $Id: tif_dirwrite.c,v 1.1 2005-06-17 13:54:52 vp153 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 #if 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                             TIFFError(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                     TIFFError(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                 TIFFError(tif->tif_name,
145                     "Cannot write directory, out of space");
146                 return (0);
147         }
148         /*
149          * Directory hasn't been placed yet, put
150          * it at the end of the file and link it
151          * into the existing directory structure.
152          */
153         if (tif->tif_diroff == 0 && !TIFFLinkDirectory(tif))
154                 goto bad;
155         tif->tif_dataoff = (toff_t)(
156             tif->tif_diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
157         if (tif->tif_dataoff & 1)
158                 tif->tif_dataoff++;
159         (void) TIFFSeekFile(tif, tif->tif_dataoff, 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                 case FIELD_DOTRANGE:
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                         if (!TIFFWriteNormalTag(tif, dir, fip))
340                                 goto bad;
341                         break;
342                 }
343                 dir++;
344                 
345                 if( fip->field_bit != FIELD_CUSTOM )
346                     ResetFieldBit(fields, fip->field_bit);
347         }
348
349         /*
350          * Write directory.
351          */
352         dircount = (uint16) nfields;
353         diroff = (uint32) tif->tif_nextdiroff;
354         if (tif->tif_flags & TIFF_SWAB) {
355                 /*
356                  * The file's byte order is opposite to the
357                  * native machine architecture.  We overwrite
358                  * the directory information with impunity
359                  * because it'll be released below after we
360                  * write it to the file.  Note that all the
361                  * other tag construction routines assume that
362                  * we do this byte-swapping; i.e. they only
363                  * byte-swap indirect data.
364                  */
365                 for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
366                         TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
367                         TIFFSwabArrayOfLong(&dir->tdir_count, 2);
368                 }
369                 dircount = (uint16) nfields;
370                 TIFFSwabShort(&dircount);
371                 TIFFSwabLong(&diroff);
372         }
373         (void) TIFFSeekFile(tif, tif->tif_diroff, SEEK_SET);
374         if (!WriteOK(tif, &dircount, sizeof (dircount))) {
375                 TIFFError(tif->tif_name, "Error writing directory count");
376                 goto bad;
377         }
378         if (!WriteOK(tif, data, dirsize)) {
379                 TIFFError(tif->tif_name, "Error writing directory contents");
380                 goto bad;
381         }
382         if (!WriteOK(tif, &diroff, sizeof (diroff))) {
383                 TIFFError(tif->tif_name, "Error writing directory link");
384                 goto bad;
385         }
386         if (done) {
387                 TIFFFreeDirectory(tif);
388                 tif->tif_flags &= ~TIFF_DIRTYDIRECT;
389                 (*tif->tif_cleanup)(tif);
390
391                 /*
392                 * Reset directory-related state for subsequent
393                 * directories.
394                 */
395                 TIFFCreateDirectory(tif);
396         }
397         _TIFFfree(data);
398         return (1);
399 bad:
400         _TIFFfree(data);
401         return (0);
402 }
403 #undef WriteRationalPair
404
405 int
406 TIFFWriteDirectory(TIFF* tif)
407 {
408         return _TIFFWriteDirectory(tif, TRUE);
409 }
410
411 /*
412  * Similar to TIFFWriteDirectory(), writes the directory out
413  * but leaves all data structures in memory so that it can be
414  * written again.  This will make a partially written TIFF file
415  * readable before it is successfully completed/closed.
416  */ 
417 int
418 TIFFCheckpointDirectory(TIFF* tif)
419 {
420         int rc;
421         /* Setup the strips arrays, if they haven't already been. */
422         if (tif->tif_dir.td_stripoffset == NULL)
423             (void) TIFFSetupStrips(tif);
424         rc = _TIFFWriteDirectory(tif, FALSE);
425         (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
426         return rc;
427 }
428
429 /*
430  * Process tags that are not special cased.
431  */
432 static int
433 TIFFWriteNormalTag(TIFF* tif, TIFFDirEntry* dir, const TIFFFieldInfo* fip)
434 {
435         uint16 wc = (uint16) fip->field_writecount;
436         uint32 wc2;
437
438         dir->tdir_tag = (uint16) fip->field_tag;
439         dir->tdir_type = (uint16) fip->field_type;
440         dir->tdir_count = wc;
441         
442         switch (fip->field_type) {
443         case TIFF_SHORT:
444         case TIFF_SSHORT:
445                 if (fip->field_passcount) {
446                         uint16* wp;
447                         if (wc == (uint16) TIFF_VARIABLE2) {
448                                 TIFFGetField(tif, fip->field_tag, &wc2, &wp);
449                                 dir->tdir_count = wc2;
450                         } else {        /* Assume TIFF_VARIABLE */
451                                 TIFFGetField(tif, fip->field_tag, &wc, &wp);
452                                 dir->tdir_count = wc;
453                         }
454                         if (!TIFFWriteShortArray(tif, dir, wp))
455                                 return 0;
456                 } else {
457                         if (wc == 1) {
458                                 uint16 sv;
459                                 TIFFGetField(tif, fip->field_tag, &sv);
460                                 dir->tdir_offset =
461                                         TIFFInsertData(tif, dir->tdir_type, sv);
462                         } else {
463                                 uint16* wp;
464                                 TIFFGetField(tif, fip->field_tag, &wp);
465                                 if (!TIFFWriteShortArray(tif, dir, wp))
466                                         return 0;
467                         }
468                 }
469                 break;
470         case TIFF_LONG:
471         case TIFF_SLONG:
472         case TIFF_IFD:
473                 if (fip->field_passcount) {
474                         uint32* lp;
475                         if (wc == (uint16) TIFF_VARIABLE2) {
476                                 TIFFGetField(tif, fip->field_tag, &wc2, &lp);
477                                 dir->tdir_count = wc2;
478                         } else {        /* Assume TIFF_VARIABLE */
479                                 TIFFGetField(tif, fip->field_tag, &wc, &lp);
480                                 dir->tdir_count = wc;
481                         }
482                         if (!TIFFWriteLongArray(tif, dir, lp))
483                                 return 0;
484                 } else {
485                         if (wc == 1) {
486                                 /* XXX handle LONG->SHORT conversion */
487                                 TIFFGetField(tif, fip->field_tag,
488                                              &dir->tdir_offset);
489                         } else {
490                                 uint32* lp;
491                                 TIFFGetField(tif, fip->field_tag, &lp);
492                                 if (!TIFFWriteLongArray(tif, dir, lp))
493                                         return 0;
494                         }
495                 }
496                 break;
497         case TIFF_RATIONAL:
498         case TIFF_SRATIONAL:
499                 if (fip->field_passcount) {
500                         float* fp;
501                         if (wc == (uint16) TIFF_VARIABLE2) {
502                                 TIFFGetField(tif, fip->field_tag, &wc2, &fp);
503                                 dir->tdir_count = wc2;
504                         } else {        /* Assume TIFF_VARIABLE */
505                                 TIFFGetField(tif, fip->field_tag, &wc, &fp);
506                                 dir->tdir_count = wc;
507                         }
508                         if (!TIFFWriteRationalArray(tif, dir, fp))
509                                 return 0;
510                 } else {
511                         if (wc == 1) {
512                                 float fv;
513                                 TIFFGetField(tif, fip->field_tag, &fv);
514                                 if (!TIFFWriteRationalArray(tif, dir, &fv))
515                                         return 0;
516                         } else {
517                                 float* fp;
518                                 TIFFGetField(tif, fip->field_tag, &fp);
519                                 if (!TIFFWriteRationalArray(tif, dir, fp))
520                                         return 0;
521                         }
522                 }
523                 break;
524         case TIFF_FLOAT:
525                 if (fip->field_passcount) {
526                         float* fp;
527                         if (wc == (uint16) TIFF_VARIABLE2) {
528                                 TIFFGetField(tif, fip->field_tag, &wc2, &fp);
529                                 dir->tdir_count = wc2;
530                         } else {        /* Assume TIFF_VARIABLE */
531                                 TIFFGetField(tif, fip->field_tag, &wc, &fp);
532                                 dir->tdir_count = wc;
533                         }
534                         if (!TIFFWriteFloatArray(tif, dir, fp))
535                                 return 0;
536                 } else {
537                         if (wc == 1) {
538                                 float fv;
539                                 TIFFGetField(tif, fip->field_tag, &fv);
540                                 if (!TIFFWriteFloatArray(tif, dir, &fv))
541                                         return 0;
542                         } else {
543                                 float* fp;
544                                 TIFFGetField(tif, fip->field_tag, &fp);
545                                 if (!TIFFWriteFloatArray(tif, dir, fp))
546                                         return 0;
547                         }
548                 }
549                 break;
550         case TIFF_DOUBLE:
551                 if (fip->field_passcount) {
552                         double* dp;
553                         if (wc == (uint16) TIFF_VARIABLE2) {
554                                 TIFFGetField(tif, fip->field_tag, &wc2, &dp);
555                                 dir->tdir_count = wc2;
556                         } else {        /* Assume TIFF_VARIABLE */
557                                 TIFFGetField(tif, fip->field_tag, &wc, &dp);
558                                 dir->tdir_count = wc;
559                         }
560                         if (!TIFFWriteDoubleArray(tif, dir, dp))
561                                 return 0;
562                 } else {
563                         if (wc == 1) {
564                                 double dv;
565                                 TIFFGetField(tif, fip->field_tag, &dv);
566                                 if (!TIFFWriteDoubleArray(tif, dir, &dv))
567                                         return 0;
568                         } else {
569                                 double* dp;
570                                 TIFFGetField(tif, fip->field_tag, &dp);
571                                 if (!TIFFWriteDoubleArray(tif, dir, dp))
572                                         return 0;
573                         }
574                 }
575                 break;
576         case TIFF_ASCII:
577                 { 
578                     char* cp;
579                     if (fip->field_passcount)
580                         TIFFGetField(tif, fip->field_tag, &wc, &cp);
581                     else
582                         TIFFGetField(tif, fip->field_tag, &cp);
583
584                     dir->tdir_count = (uint32) (strlen(cp) + 1);
585                     if (!TIFFWriteByteArray(tif, dir, cp))
586                         return (0);
587                 }
588                 break;
589
590         case TIFF_BYTE:
591         case TIFF_SBYTE:          
592                 if (fip->field_passcount) {
593                         char* cp;
594                         if (wc == (uint16) TIFF_VARIABLE2) {
595                                 TIFFGetField(tif, fip->field_tag, &wc2, &cp);
596                                 dir->tdir_count = wc2;
597                         } else {        /* Assume TIFF_VARIABLE */
598                                 TIFFGetField(tif, fip->field_tag, &wc, &cp);
599                                 dir->tdir_count = wc;
600                         }
601                         if (!TIFFWriteByteArray(tif, dir, cp))
602                                 return 0;
603                 } else {
604                         if (wc == 1) {
605                                 char cv;
606                                 TIFFGetField(tif, fip->field_tag, &cv);
607                                 if (!TIFFWriteByteArray(tif, dir, &cv))
608                                         return 0;
609                         } else {
610                                 char* cp;
611                                 TIFFGetField(tif, fip->field_tag, &cp);
612                                 if (!TIFFWriteByteArray(tif, dir, cp))
613                                         return 0;
614                         }
615                 }
616                 break;
617
618         case TIFF_UNDEFINED:
619                 { char* cp;
620                   if (wc == (unsigned short) TIFF_VARIABLE) {
621                         TIFFGetField(tif, fip->field_tag, &wc, &cp);
622                         dir->tdir_count = wc;
623                   } else if (wc == (unsigned short) TIFF_VARIABLE2) {
624                         TIFFGetField(tif, fip->field_tag, &wc2, &cp);
625                         dir->tdir_count = wc2;
626                   } else 
627                         TIFFGetField(tif, fip->field_tag, &cp);
628                   if (!TIFFWriteByteArray(tif, dir, cp))
629                         return (0);
630                 }
631                 break;
632
633         case TIFF_NOTYPE:
634                 break;
635         }
636         return (1);
637 }
638
639 /*
640  * Setup a directory entry with either a SHORT
641  * or LONG type according to the value.
642  */
643 static void
644 TIFFSetupShortLong(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint32 v)
645 {
646         dir->tdir_tag = (uint16) tag;
647         dir->tdir_count = 1;
648         if (v > 0xffffL) {
649                 dir->tdir_type = (short) TIFF_LONG;
650                 dir->tdir_offset = v;
651         } else {
652                 dir->tdir_type = (short) TIFF_SHORT;
653                 dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
654         }
655 }
656
657 /*
658  * Setup a SHORT directory entry
659  */
660 static void
661 TIFFSetupShort(TIFF* tif, ttag_t tag, TIFFDirEntry* dir, uint16 v)
662 {
663         dir->tdir_tag = (uint16) tag;
664         dir->tdir_count = 1;
665         dir->tdir_type = (short) TIFF_SHORT;
666         dir->tdir_offset = TIFFInsertData(tif, (int) TIFF_SHORT, v);
667 }
668 #undef MakeShortDirent
669
670 #define NITEMS(x)       (sizeof (x) / sizeof (x[0]))
671 /*
672  * Setup a directory entry that references a
673  * samples/pixel array of SHORT values and
674  * (potentially) write the associated indirect
675  * values.
676  */
677 static int
678 TIFFWritePerSampleShorts(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
679 {
680         uint16 buf[10], v;
681         uint16* w = buf;
682         int i, status, samples = tif->tif_dir.td_samplesperpixel;
683
684         if (samples > NITEMS(buf)) {
685                 w = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
686                 if (w == NULL) {
687                         TIFFError(tif->tif_name,
688                             "No space to write per-sample shorts");
689                         return (0);
690                 }
691         }
692         TIFFGetField(tif, tag, &v);
693         for (i = 0; i < samples; i++)
694                 w[i] = v;
695         
696         dir->tdir_tag = (uint16) tag;
697         dir->tdir_type = (uint16) TIFF_SHORT;
698         dir->tdir_count = samples;
699         status = TIFFWriteShortArray(tif, dir, w);
700         if (w != buf)
701                 _TIFFfree((char*) w);
702         return (status);
703 }
704
705 /*
706  * Setup a directory entry that references a samples/pixel array of ``type''
707  * values and (potentially) write the associated indirect values.  The source
708  * data from TIFFGetField() for the specified tag must be returned as double.
709  */
710 static int
711 TIFFWritePerSampleAnys(TIFF* tif,
712     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir)
713 {
714         double buf[10], v;
715         double* w = buf;
716         int i, status;
717         int samples = (int) tif->tif_dir.td_samplesperpixel;
718
719         if (samples > NITEMS(buf)) {
720                 w = (double*) _TIFFmalloc(samples * sizeof (double));
721                 if (w == NULL) {
722                         TIFFError(tif->tif_name,
723                             "No space to write per-sample values");
724                         return (0);
725                 }
726         }
727         TIFFGetField(tif, tag, &v);
728         for (i = 0; i < samples; i++)
729                 w[i] = v;
730         status = TIFFWriteAnyArray(tif, type, tag, dir, samples, w);
731         if (w != buf)
732                 _TIFFfree(w);
733         return (status);
734 }
735 #undef NITEMS
736
737 /*
738  * Setup a pair of shorts that are returned by
739  * value, rather than as a reference to an array.
740  */
741 static int
742 TIFFSetupShortPair(TIFF* tif, ttag_t tag, TIFFDirEntry* dir)
743 {
744         uint16 v[2];
745
746         TIFFGetField(tif, tag, &v[0], &v[1]);
747
748         dir->tdir_tag = (uint16) tag;
749         dir->tdir_type = (uint16) TIFF_SHORT;
750         dir->tdir_count = 2;
751         return (TIFFWriteShortArray(tif, dir, v));
752 }
753
754 /*
755  * Setup a directory entry for an NxM table of shorts,
756  * where M is known to be 2**bitspersample, and write
757  * the associated indirect data.
758  */
759 static int
760 TIFFWriteShortTable(TIFF* tif,
761     ttag_t tag, TIFFDirEntry* dir, uint32 n, uint16** table)
762 {
763         uint32 i, off;
764
765         dir->tdir_tag = (uint16) tag;
766         dir->tdir_type = (short) TIFF_SHORT;
767         /* XXX -- yech, fool TIFFWriteData */
768         dir->tdir_count = (uint32) (1L<<tif->tif_dir.td_bitspersample);
769         off = tif->tif_dataoff;
770         for (i = 0; i < n; i++)
771                 if (!TIFFWriteData(tif, dir, (char *)table[i]))
772                         return (0);
773         dir->tdir_count *= n;
774         dir->tdir_offset = off;
775         return (1);
776 }
777
778 /*
779  * Write/copy data associated with an ASCII or opaque tag value.
780  */
781 static int
782 TIFFWriteByteArray(TIFF* tif, TIFFDirEntry* dir, char* cp)
783 {
784         if (dir->tdir_count > 4) {
785                 if (!TIFFWriteData(tif, dir, cp))
786                         return (0);
787         } else
788                 _TIFFmemcpy(&dir->tdir_offset, cp, dir->tdir_count);
789         return (1);
790 }
791
792 /*
793  * Setup a directory entry of an array of SHORT
794  * or SSHORT and write the associated indirect values.
795  */
796 static int
797 TIFFWriteShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
798 {
799         if (dir->tdir_count <= 2) {
800                 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
801                         dir->tdir_offset = (uint32) ((long) v[0] << 16);
802                         if (dir->tdir_count == 2)
803                                 dir->tdir_offset |= v[1] & 0xffff;
804                 } else {
805                         dir->tdir_offset = v[0] & 0xffff;
806                         if (dir->tdir_count == 2)
807                                 dir->tdir_offset |= (long) v[1] << 16;
808                 }
809                 return (1);
810         } else
811                 return (TIFFWriteData(tif, dir, (char*) v));
812 }
813
814 /*
815  * Setup a directory entry of an array of LONG
816  * or SLONG and write the associated indirect values.
817  */
818 static int
819 TIFFWriteLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
820 {
821         if (dir->tdir_count == 1) {
822                 dir->tdir_offset = v[0];
823                 return (1);
824         } else
825                 return (TIFFWriteData(tif, dir, (char*) v));
826 }
827
828 /*
829  * Setup a directory entry of an array of RATIONAL
830  * or SRATIONAL and write the associated indirect values.
831  */
832 static int
833 TIFFWriteRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
834 {
835         uint32 i;
836         uint32* t;
837         int status;
838
839         t = (uint32*) _TIFFmalloc(2 * dir->tdir_count * sizeof (uint32));
840         if (t == NULL) {
841                 TIFFError(tif->tif_name,
842                     "No space to write RATIONAL array");
843                 return (0);
844         }
845         for (i = 0; i < dir->tdir_count; i++) {
846                 float fv = v[i];
847                 int sign = 1;
848                 uint32 den;
849
850                 if (fv < 0) {
851                         if (dir->tdir_type == TIFF_RATIONAL) {
852                                 TIFFWarning(tif->tif_name,
853         "\"%s\": Information lost writing value (%g) as (unsigned) RATIONAL",
854                                 _TIFFFieldWithTag(tif,dir->tdir_tag)->field_name,
855                                 fv);
856                                 fv = 0;
857                         } else
858                                 fv = -fv, sign = -1;
859                 }
860                 den = 1L;
861                 if (fv > 0) {
862                         while (fv < 1L<<(31-3) && den < 1L<<(31-3))
863                                 fv *= 1<<3, den *= 1L<<3;
864                 }
865                 t[2*i+0] = (uint32) (sign * (fv + 0.5));
866                 t[2*i+1] = den;
867         }
868         status = TIFFWriteData(tif, dir, (char *)t);
869         _TIFFfree((char*) t);
870         return (status);
871 }
872
873 static int
874 TIFFWriteFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
875 {
876         TIFFCvtNativeToIEEEFloat(tif, dir->tdir_count, v);
877         if (dir->tdir_count == 1) {
878                 dir->tdir_offset = *(uint32*) &v[0];
879                 return (1);
880         } else
881                 return (TIFFWriteData(tif, dir, (char*) v));
882 }
883
884 static int
885 TIFFWriteDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
886 {
887         TIFFCvtNativeToIEEEDouble(tif, n, v);
888         return (TIFFWriteData(tif, dir, (char*) v));
889 }
890
891 /*
892  * Write an array of ``type'' values for a specified tag (i.e. this is a tag
893  * which is allowed to have different types, e.g. SMaxSampleType).
894  * Internally the data values are represented as double since a double can
895  * hold any of the TIFF tag types (yes, this should really be an abstract
896  * type tany_t for portability).  The data is converted into the specified
897  * type in a temporary buffer and then handed off to the appropriate array
898  * writer.
899  */
900 static int
901 TIFFWriteAnyArray(TIFF* tif,
902     TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
903 {
904         char buf[10 * sizeof(double)];
905         char* w = buf;
906         int i, status = 0;
907
908         if (n * TIFFDataWidth(type) > sizeof buf) {
909                 w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
910                 if (w == NULL) {
911                         TIFFError(tif->tif_name,
912                             "No space to write array");
913                         return (0);
914                 }
915         }
916
917         dir->tdir_tag = (uint16) tag;
918         dir->tdir_type = (uint16) type;
919         dir->tdir_count = n;
920
921         switch (type) {
922         case TIFF_BYTE:
923                 { 
924                         uint8* bp = (uint8*) w;
925                         for (i = 0; i < (int) n; i++)
926                                 bp[i] = (uint8) v[i];
927                         if (!TIFFWriteByteArray(tif, dir, (char*) bp))
928                                 goto out;
929                 }
930                 break;
931         case TIFF_SBYTE:
932                 { 
933                         int8* bp = (int8*) w;
934                         for (i = 0; i < (int) n; i++)
935                                 bp[i] = (int8) v[i];
936                         if (!TIFFWriteByteArray(tif, dir, (char*) bp))
937                                 goto out;
938                 }
939                 break;
940         case TIFF_SHORT:
941                 {
942                         uint16* bp = (uint16*) w;
943                         for (i = 0; i < (int) n; i++)
944                                 bp[i] = (uint16) v[i];
945                         if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
946                                 goto out;
947                 }
948                 break;
949         case TIFF_SSHORT:
950                 { 
951                         int16* bp = (int16*) w;
952                         for (i = 0; i < (int) n; i++)
953                                 bp[i] = (int16) v[i];
954                         if (!TIFFWriteShortArray(tif, dir, (uint16*)bp))
955                                 goto out;
956                 }
957                 break;
958         case TIFF_LONG:
959                 {
960                         uint32* bp = (uint32*) w;
961                         for (i = 0; i < (int) n; i++)
962                                 bp[i] = (uint32) v[i];
963                         if (!TIFFWriteLongArray(tif, dir, bp))
964                                 goto out;
965                 }
966                 break;
967         case TIFF_SLONG:
968                 {
969                         int32* bp = (int32*) w;
970                         for (i = 0; i < (int) n; i++)
971                                 bp[i] = (int32) v[i];
972                         if (!TIFFWriteLongArray(tif, dir, (uint32*) bp))
973                                 goto out;
974                 }
975                 break;
976         case TIFF_FLOAT:
977                 { 
978                         float* bp = (float*) w;
979                         for (i = 0; i < (int) n; i++)
980                                 bp[i] = (float) v[i];
981                         if (!TIFFWriteFloatArray(tif, dir, bp))
982                                 goto out;
983                 }
984                 break;
985         case TIFF_DOUBLE:
986                 return (TIFFWriteDoubleArray(tif, dir, v));
987         default:
988                 /* TIFF_NOTYPE */
989                 /* TIFF_ASCII */
990                 /* TIFF_UNDEFINED */
991                 /* TIFF_RATIONAL */
992                 /* TIFF_SRATIONAL */
993                 goto out;
994         }
995         status = 1;
996  out:
997         if (w != buf)
998                 _TIFFfree(w);
999         return (status);
1000 }
1001
1002 static int
1003 TIFFWriteTransferFunction(TIFF* tif, TIFFDirEntry* dir)
1004 {
1005         TIFFDirectory* td = &tif->tif_dir;
1006         tsize_t n = (1L<<td->td_bitspersample) * sizeof (uint16);
1007         uint16** tf = td->td_transferfunction;
1008         int ncols;
1009
1010         /*
1011          * Check if the table can be written as a single column,
1012          * or if it must be written as 3 columns.  Note that we
1013          * write a 3-column tag if there are 2 samples/pixel and
1014          * a single column of data won't suffice--hmm.
1015          */
1016         switch (td->td_samplesperpixel - td->td_extrasamples) {
1017         default:        if (_TIFFmemcmp(tf[0], tf[2], n)) { ncols = 3; break; }
1018         case 2:         if (_TIFFmemcmp(tf[0], tf[1], n)) { ncols = 3; break; }
1019         case 1: case 0: ncols = 1;
1020         }
1021         return (TIFFWriteShortTable(tif,
1022             TIFFTAG_TRANSFERFUNCTION, dir, ncols, tf));
1023 }
1024
1025 static int
1026 TIFFWriteInkNames(TIFF* tif, TIFFDirEntry* dir)
1027 {
1028         TIFFDirectory* td = &tif->tif_dir;
1029
1030         dir->tdir_tag = TIFFTAG_INKNAMES;
1031         dir->tdir_type = (short) TIFF_ASCII;
1032         dir->tdir_count = td->td_inknameslen;
1033         return (TIFFWriteByteArray(tif, dir, td->td_inknames));
1034 }
1035
1036 /*
1037  * Write a contiguous directory item.
1038  */
1039 static int
1040 TIFFWriteData(TIFF* tif, TIFFDirEntry* dir, char* cp)
1041 {
1042         tsize_t cc;
1043
1044         if (tif->tif_flags & TIFF_SWAB) {
1045                 switch (dir->tdir_type) {
1046                 case TIFF_SHORT:
1047                 case TIFF_SSHORT:
1048                         TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
1049                         break;
1050                 case TIFF_LONG:
1051                 case TIFF_SLONG:
1052                 case TIFF_FLOAT:
1053                         TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
1054                         break;
1055                 case TIFF_RATIONAL:
1056                 case TIFF_SRATIONAL:
1057                         TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
1058                         break;
1059                 case TIFF_DOUBLE:
1060                         TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
1061                         break;
1062                 }
1063         }
1064         dir->tdir_offset = tif->tif_dataoff;
1065         cc = dir->tdir_count * TIFFDataWidth((TIFFDataType) dir->tdir_type);
1066         if (SeekOK(tif, dir->tdir_offset) &&
1067             WriteOK(tif, cp, cc)) {
1068                 tif->tif_dataoff += (cc + 1) & ~1;
1069                 return (1);
1070         }
1071         TIFFError(tif->tif_name, "Error writing data for field \"%s\"",
1072             _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1073         return (0);
1074 }
1075
1076 /*
1077  * Similar to TIFFWriteDirectory(), but if the directory has already
1078  * been written once, it is relocated to the end of the file, in case it
1079  * has changed in size.  Note that this will result in the loss of the 
1080  * previously used directory space. 
1081  */ 
1082
1083 int 
1084 TIFFRewriteDirectory( TIFF *tif )
1085 {
1086     static const char module[] = "TIFFRewriteDirectory";
1087
1088     /* We don't need to do anything special if it hasn't been written. */
1089     if( tif->tif_diroff == 0 )
1090         return TIFFWriteDirectory( tif );
1091
1092     /*
1093     ** Find and zero the pointer to this directory, so that TIFFLinkDirectory
1094     ** will cause it to be added after this directories current pre-link.
1095     */
1096     
1097     /* Is it the first directory in the file? */
1098     if (tif->tif_header.tiff_diroff == tif->tif_diroff) 
1099     {
1100         tif->tif_header.tiff_diroff = 0;
1101         tif->tif_diroff = 0;
1102
1103         TIFFSeekFile(tif, (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1104                      SEEK_SET);
1105         if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), 
1106                      sizeof (tif->tif_diroff))) 
1107         {
1108             TIFFError(tif->tif_name, "Error updating TIFF header");
1109             return (0);
1110         }
1111     }
1112     else
1113     {
1114         toff_t  nextdir, off;
1115
1116         nextdir = tif->tif_header.tiff_diroff;
1117         do {
1118                 uint16 dircount;
1119
1120                 if (!SeekOK(tif, nextdir) ||
1121                     !ReadOK(tif, &dircount, sizeof (dircount))) {
1122                         TIFFError(module, "Error fetching directory count");
1123                         return (0);
1124                 }
1125                 if (tif->tif_flags & TIFF_SWAB)
1126                         TIFFSwabShort(&dircount);
1127                 (void) TIFFSeekFile(tif,
1128                     dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1129                 if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1130                         TIFFError(module, "Error fetching directory link");
1131                         return (0);
1132                 }
1133                 if (tif->tif_flags & TIFF_SWAB)
1134                         TIFFSwabLong(&nextdir);
1135         } while (nextdir != tif->tif_diroff && nextdir != 0);
1136         off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1137         (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1138         tif->tif_diroff = 0;
1139         if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) {
1140                 TIFFError(module, "Error writing directory link");
1141                 return (0);
1142         }
1143     }
1144
1145     /*
1146     ** Now use TIFFWriteDirectory() normally.
1147     */
1148
1149     return TIFFWriteDirectory( tif );
1150 }
1151
1152
1153 /*
1154  * Link the current directory into the
1155  * directory chain for the file.
1156  */
1157 static int
1158 TIFFLinkDirectory(TIFF* tif)
1159 {
1160         static const char module[] = "TIFFLinkDirectory";
1161         toff_t nextdir;
1162         toff_t diroff, off;
1163
1164         tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
1165         diroff = tif->tif_diroff;
1166         if (tif->tif_flags & TIFF_SWAB)
1167                 TIFFSwabLong(&diroff);
1168
1169         /*
1170          * Handle SubIFDs
1171          */
1172         if (tif->tif_flags & TIFF_INSUBIFD) {
1173                 (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
1174                 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1175                         TIFFError(module,
1176                             "%s: Error writing SubIFD directory link",
1177                             tif->tif_name);
1178                         return (0);
1179                 }
1180                 /*
1181                  * Advance to the next SubIFD or, if this is
1182                  * the last one configured, revert back to the
1183                  * normal directory linkage.
1184                  */
1185                 if (--tif->tif_nsubifd)
1186                         tif->tif_subifdoff += sizeof (diroff);
1187                 else
1188                         tif->tif_flags &= ~TIFF_INSUBIFD;
1189                 return (1);
1190         }
1191
1192         if (tif->tif_header.tiff_diroff == 0) {
1193                 /*
1194                  * First directory, overwrite offset in header.
1195                  */
1196                 tif->tif_header.tiff_diroff = tif->tif_diroff;
1197                 (void) TIFFSeekFile(tif,
1198                                     (toff_t)(TIFF_MAGIC_SIZE+TIFF_VERSION_SIZE),
1199                                     SEEK_SET);
1200                 if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1201                         TIFFError(tif->tif_name, "Error writing TIFF header");
1202                         return (0);
1203                 }
1204                 return (1);
1205         }
1206         /*
1207          * Not the first directory, search to the last and append.
1208          */
1209         nextdir = tif->tif_header.tiff_diroff;
1210         do {
1211                 uint16 dircount;
1212
1213                 if (!SeekOK(tif, nextdir) ||
1214                     !ReadOK(tif, &dircount, sizeof (dircount))) {
1215                         TIFFError(module, "Error fetching directory count");
1216                         return (0);
1217                 }
1218                 if (tif->tif_flags & TIFF_SWAB)
1219                         TIFFSwabShort(&dircount);
1220                 (void) TIFFSeekFile(tif,
1221                     dircount * sizeof (TIFFDirEntry), SEEK_CUR);
1222                 if (!ReadOK(tif, &nextdir, sizeof (nextdir))) {
1223                         TIFFError(module, "Error fetching directory link");
1224                         return (0);
1225                 }
1226                 if (tif->tif_flags & TIFF_SWAB)
1227                         TIFFSwabLong(&nextdir);
1228         } while (nextdir != 0);
1229         off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */
1230         (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET);
1231         if (!WriteOK(tif, &diroff, sizeof (diroff))) {
1232                 TIFFError(module, "Error writing directory link");
1233                 return (0);
1234         }
1235         return (1);
1236 }
1237
1238 /* vim: set ts=8 sts=8 sw=8 noet: */