1 /* Id */
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 Read Support Routines.
31  */
32 #include "tiffiop.h"
33 
34 #define IGNORE  0               /* tag placeholder used below */
35 
36 #ifdef HAVE_IEEEFP
37 # define        TIFFCvtIEEEFloatToNative(tif, n, fp)
38 # define        TIFFCvtIEEEDoubleToNative(tif, n, dp)
39 #else
40 extern  void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
41 extern  void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
42 #endif
43 
44 static  int EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16);
45 static  void MissingRequired(TIFF*, const char*);
46 static  int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
47 static  tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
48 static  tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
49 static  float TIFFFetchRational(TIFF*, TIFFDirEntry*);
50 static  int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*);
51 static  int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, uint16*);
52 static  int TIFFFetchPerSampleLongs(TIFF*, TIFFDirEntry*, uint32*);
53 static  int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*);
54 static  int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*);
55 static  int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**);
56 static  int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*);
57 static  float TIFFFetchFloat(TIFF*, TIFFDirEntry*);
58 static  int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*);
59 static  int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*);
60 static  int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*);
61 static  int TIFFFetchShortPair(TIFF*, TIFFDirEntry*);
62 static  void ChopUpSingleUncompressedStrip(TIFF*);
63 
64 /*
65  * Read the next TIFF directory from a file
66  * and convert it to the internal format.
67  * We read directories sequentially.
68  */
69 int
70 TEXPORT
TIFFReadDirectory(TIFF * tif)71 TIFFReadDirectory(TIFF* tif)
72 {
73         static const char module[] = "TIFFReadDirectory";
74 
75         int n;
76         TIFFDirectory* td;
77         TIFFDirEntry *dp, *dir = NULL;
78         uint16 iv;
79         uint32 v;
80         const TIFFFieldInfo* fip;
81         size_t fix;
82         uint16 dircount;
83         toff_t nextdiroff;
84         int diroutoforderwarning = 0;
85         toff_t* new_dirlist;
86 
87         tif->tif_diroff = tif->tif_nextdiroff;
88         if (tif->tif_diroff == 0)               /* no more directories */
89                 return (0);
90 
91         /*
92          * XXX: Trick to prevent IFD looping. The one can create TIFF file
93          * with looped directory pointers. We will maintain a list of already
94          * seen directories and check every IFD offset against this list.
95          */
96         for (n = 0; n < tif->tif_dirnumber; n++) {
97                 if (tif->tif_dirlist[n] == tif->tif_diroff)
98                         return (0);
99         }
100         tif->tif_dirnumber++;
101         new_dirlist = (toff_t *)_TIFFrealloc(tif->tif_dirlist,
102                                         tif->tif_dirnumber * sizeof(toff_t));
103         if (!new_dirlist) {
104                 TIFFErrorExt(tif->tif_clientdata, module,
105                           "%s: Failed to allocate space for IFD list",
106                           tif->tif_name);
107                 return (0);
108         }
109         tif->tif_dirlist = new_dirlist;
110         tif->tif_dirlist[tif->tif_dirnumber - 1] = tif->tif_diroff;
111 
112         /*
113          * Cleanup any previous compression state.
114          */
115         (*tif->tif_cleanup)(tif);
116         tif->tif_curdir++;
117         nextdiroff = 0;
118         if (!isMapped(tif)) {
119                 if (!SeekOK(tif, tif->tif_diroff)) {
120                         TIFFErrorExt(tif->tif_clientdata, module,
121                             "%s: Seek error accessing TIFF directory",
122                             tif->tif_name);
123                         return (0);
124                 }
125                 if (!ReadOK(tif, &dircount, sizeof (uint16))) {
126                         TIFFErrorExt(tif->tif_clientdata, module,
127                             "%s: Can not read TIFF directory count",
128                             tif->tif_name);
129                         return (0);
130                 }
131                 if (tif->tif_flags & TIFF_SWAB)
132                         TIFFSwabShort(&dircount);
133                 dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
134                                                        sizeof (TIFFDirEntry),
135                                                 "to read TIFF directory");
136                 if (dir == NULL)
137                         return (0);
138                 if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) {
139                         TIFFErrorExt(tif->tif_clientdata, module,
140                                   "%.100s: Can not read TIFF directory",
141                                   tif->tif_name);
142                         goto bad;
143                 }
144                 /*
145                  * Read offset to next directory for sequential scans.
146                  */
147                 (void) ReadOK(tif, &nextdiroff, sizeof (uint32));
148         } else {
149                 toff_t off = tif->tif_diroff;
150 
151                 if (off + sizeof (uint16) > tif->tif_size) {
152                         TIFFErrorExt(tif->tif_clientdata, module,
153                             "%s: Can not read TIFF directory count",
154                             tif->tif_name);
155                         return (0);
156                 } else
157                         _TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16));
158                 off += sizeof (uint16);
159                 if (tif->tif_flags & TIFF_SWAB)
160                         TIFFSwabShort(&dircount);
161                 dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
162                                                        sizeof (TIFFDirEntry),
163                                                 "to read TIFF directory");
164                 if (dir == NULL)
165                         return (0);
166                 if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) {
167                         TIFFErrorExt(tif->tif_clientdata, module,
168                                   "%s: Can not read TIFF directory",
169                                   tif->tif_name);
170                         goto bad;
171                 } else {
172                         _TIFFmemcpy(dir, tif->tif_base + off,
173                                     dircount*sizeof (TIFFDirEntry));
174                 }
175                 off += dircount* sizeof (TIFFDirEntry);
176                 if (off + sizeof (uint32) <= tif->tif_size)
177                         _TIFFmemcpy(&nextdiroff, tif->tif_base+off, sizeof (uint32));
178         }
179         if (tif->tif_flags & TIFF_SWAB)
180                 TIFFSwabLong(&nextdiroff);
181         tif->tif_nextdiroff = nextdiroff;
182 
183         tif->tif_flags &= ~TIFF_BEENWRITING;    /* reset before new dir */
184         /*
185          * Setup default value and then make a pass over
186          * the fields to check type and tag information,
187          * and to extract info required to size data
188          * structures.  A second pass is made afterwards
189          * to read in everthing not taken in the first pass.
190          */
191         td = &tif->tif_dir;
192         /* free any old stuff and reinit */
193         TIFFFreeDirectory(tif);
194         TIFFDefaultDirectory(tif);
195         /*
196          * Electronic Arts writes gray-scale TIFF files
197          * without a PlanarConfiguration directory entry.
198          * Thus we setup a default value here, even though
199          * the TIFF spec says there is no default value.
200          */
201         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
202 
203         /*
204          * Sigh, we must make a separate pass through the
205          * directory for the following reason:
206          *
207          * We must process the Compression tag in the first pass
208          * in order to merge in codec-private tag definitions (otherwise
209          * we may get complaints about unknown tags).  However, the
210          * Compression tag may be dependent on the SamplesPerPixel
211          * tag value because older TIFF specs permited Compression
212          * to be written as a SamplesPerPixel-count tag entry.
213          * Thus if we don't first figure out the correct SamplesPerPixel
214          * tag value then we may end up ignoring the Compression tag
215          * value because it has an incorrect count value (if the
216          * true value of SamplesPerPixel is not 1).
217          *
218          * It sure would have been nice if Aldus had really thought
219          * this stuff through carefully.
220          */
221         for (dp = dir, n = dircount; n > 0; n--, dp++) {
222                 if (tif->tif_flags & TIFF_SWAB) {
223                         TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
224                         TIFFSwabArrayOfLong(&dp->tdir_count, 2);
225                 }
226                 if (dp->tdir_tag == TIFFTAG_SAMPLESPERPIXEL) {
227                         if (!TIFFFetchNormalTag(tif, dp))
228                                 goto bad;
229                         dp->tdir_tag = IGNORE;
230                 }
231         }
232         /*
233          * First real pass over the directory.
234          */
235         fix = 0;
236         for (dp = dir, n = dircount; n > 0; n--, dp++) {
237 
238                 if (fix >= tif->tif_nfields || dp->tdir_tag == IGNORE)
239                         continue;
240 
241                 /*
242                  * Silicon Beach (at least) writes unordered
243                  * directory tags (violating the spec).  Handle
244                  * it here, but be obnoxious (maybe they'll fix it?).
245                  */
246                 if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) {
247                         if (!diroutoforderwarning) {
248                                 TIFFWarningExt(tif->tif_clientdata, module,
249         "%s: invalid TIFF directory; tags are not sorted in ascending order",
250                                                tif->tif_name);
251                                 diroutoforderwarning = 1;
252                         }
253                         fix = 0;                        /* O(n^2) */
254                 }
255                 while (fix < tif->tif_nfields &&
256                        tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
257                         fix++;
258                 if (fix >= tif->tif_nfields ||
259                     tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
260 
261                                         TIFFWarningExt(tif->tif_clientdata,
262                                                        module,
263                         "%s: unknown field with tag %d (0x%x) encountered",
264                                                        tif->tif_name,
265                                                        dp->tdir_tag,
266                                                        dp->tdir_tag,
267                                                        dp->tdir_type);
268 
269                     TIFFMergeFieldInfo(tif,
270                                        _TIFFCreateAnonFieldInfo(tif,
271                                                 dp->tdir_tag,
272                                                 (TIFFDataType) dp->tdir_type),
273                                        1 );
274                     fix = 0;
275                     while (fix < tif->tif_nfields &&
276                            tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
277                         fix++;
278                 }
279                 /*
280                  * Null out old tags that we ignore.
281                  */
282                 if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {
283         ignore:
284                         dp->tdir_tag = IGNORE;
285                         continue;
286                 }
287                 /*
288                  * Check data type.
289                  */
290                 fip = tif->tif_fieldinfo[fix];
291                 while (dp->tdir_type != (unsigned short) fip->field_type
292                        && fix < tif->tif_nfields) {
293                         if (fip->field_type == TIFF_ANY)        /* wildcard */
294                                 break;
295                         fip = tif->tif_fieldinfo[++fix];
296                         if (fix >= tif->tif_nfields ||
297                             fip->field_tag != dp->tdir_tag) {
298                                 TIFFWarningExt(tif->tif_clientdata, module,
299                         "%s: wrong data type %d for \"%s\"; tag ignored",
300                                             tif->tif_name, dp->tdir_type,
301                                             tif->tif_fieldinfo[fix-1]->field_name);
302                                 goto ignore;
303                         }
304                 }
305                 /*
306                  * Check count if known in advance.
307                  */
308                 if (fip->field_readcount != TIFF_VARIABLE
309                     && fip->field_readcount != TIFF_VARIABLE2) {
310                         uint32 expected = (fip->field_readcount == TIFF_SPP) ?
311                             (uint32) td->td_samplesperpixel :
312                             (uint32) fip->field_readcount;
313                         if (!CheckDirCount(tif, dp, expected))
314                                 goto ignore;
315                 }
316 
317                 switch (dp->tdir_tag) {
318                 case TIFFTAG_COMPRESSION:
319                         /*
320                          * The 5.0 spec says the Compression tag has
321                          * one value, while earlier specs say it has
322                          * one value per sample.  Because of this, we
323                          * accept the tag if one value is supplied.
324                          */
325                         if (dp->tdir_count == 1) {
326                                 v = TIFFExtractData(tif,
327                                     dp->tdir_type, dp->tdir_offset);
328                                 if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v))
329                                         goto bad;
330                                 break;
331                         /* XXX: workaround for broken TIFFs */
332                         } else if (dp->tdir_type == TIFF_LONG) {
333                                 if (!TIFFFetchPerSampleLongs(tif, dp, &v) ||
334                                     !TIFFSetField(tif, dp->tdir_tag, (uint16)v))
335                                         goto bad;
336                         } else {
337                                 if (!TIFFFetchPerSampleShorts(tif, dp, &iv)
338                                     || !TIFFSetField(tif, dp->tdir_tag, iv))
339                                         goto bad;
340                         }
341                         dp->tdir_tag = IGNORE;
342                         break;
343                 case TIFFTAG_STRIPOFFSETS:
344                 case TIFFTAG_STRIPBYTECOUNTS:
345                 case TIFFTAG_TILEOFFSETS:
346                 case TIFFTAG_TILEBYTECOUNTS:
347                         TIFFSetFieldBit(tif, fip->field_bit);
348                         break;
349                 case TIFFTAG_IMAGEWIDTH:
350                 case TIFFTAG_IMAGELENGTH:
351                 case TIFFTAG_IMAGEDEPTH:
352                 case TIFFTAG_TILELENGTH:
353                 case TIFFTAG_TILEWIDTH:
354                 case TIFFTAG_TILEDEPTH:
355                 case TIFFTAG_PLANARCONFIG:
356                 case TIFFTAG_ROWSPERSTRIP:
357                 case TIFFTAG_EXTRASAMPLES:
358                         if (!TIFFFetchNormalTag(tif, dp))
359                                 goto bad;
360                         dp->tdir_tag = IGNORE;
361                         break;
362                 }
363         }
364 
365         /*
366          * Allocate directory structure and setup defaults.
367          */
368         if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
369                 MissingRequired(tif, "ImageLength");
370                 goto bad;
371         }
372         /*
373          * Setup appropriate structures (by strip or by tile)
374          */
375         if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
376                 td->td_nstrips = TIFFNumberOfStrips(tif);
377                 td->td_tilewidth = td->td_imagewidth;
378                 td->td_tilelength = td->td_rowsperstrip;
379                 td->td_tiledepth = td->td_imagedepth;
380                 tif->tif_flags &= ~TIFF_ISTILED;
381         } else {
382                 td->td_nstrips = TIFFNumberOfTiles(tif);
383                 tif->tif_flags |= TIFF_ISTILED;
384         }
385         if (!td->td_nstrips) {
386                 TIFFErrorExt(tif->tif_clientdata, module,
387                              "%s: cannot handle zero number of %s",
388                              tif->tif_name, isTiled(tif) ? "tiles" : "strips");
389                 goto bad;
390         }
391         td->td_stripsperimage = td->td_nstrips;
392         if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
393                 td->td_stripsperimage /= td->td_samplesperpixel;
394         if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
395                 MissingRequired(tif,
396                                 isTiled(tif) ? "TileOffsets" : "StripOffsets");
397                 goto bad;
398         }
399 
400         /*
401          * Second pass: extract other information.
402          */
403         for (dp = dir, n = dircount; n > 0; n--, dp++) {
404                 if (dp->tdir_tag == IGNORE)
405                         continue;
406                 switch (dp->tdir_tag) {
407                 case TIFFTAG_MINSAMPLEVALUE:
408                 case TIFFTAG_MAXSAMPLEVALUE:
409                 case TIFFTAG_BITSPERSAMPLE:
410                 case TIFFTAG_DATATYPE:
411                 case TIFFTAG_SAMPLEFORMAT:
412                         /*
413                          * The 5.0 spec says the Compression tag has
414                          * one value, while earlier specs say it has
415                          * one value per sample.  Because of this, we
416                          * accept the tag if one value is supplied.
417                          *
418                          * The MinSampleValue, MaxSampleValue, BitsPerSample
419                          * DataType and SampleFormat tags are supposed to be
420                          * written as one value/sample, but some vendors
421                          * incorrectly write one value only -- so we accept
422                          * that as well (yech). Other vendors write correct
423                          * value for NumberOfSamples, but incorrect one for
424                          * BitsPerSample and friends, and we will read this
425                          * too.
426                          */
427                         if (dp->tdir_count == 1) {
428                                 v = TIFFExtractData(tif,
429                                     dp->tdir_type, dp->tdir_offset);
430                                 if (!TIFFSetField(tif, dp->tdir_tag, (uint16)v))
431                                         goto bad;
432                         /* XXX: workaround for broken TIFFs */
433                         } else if (dp->tdir_tag == TIFFTAG_BITSPERSAMPLE
434                                    && dp->tdir_type == TIFF_LONG) {
435                                 if (!TIFFFetchPerSampleLongs(tif, dp, &v) ||
436                                     !TIFFSetField(tif, dp->tdir_tag, (uint16)v))
437                                         goto bad;
438                         } else {
439                                 if (!TIFFFetchPerSampleShorts(tif, dp, &iv) ||
440                                     !TIFFSetField(tif, dp->tdir_tag, iv))
441                                         goto bad;
442                         }
443                         break;
444                 case TIFFTAG_SMINSAMPLEVALUE:
445                 case TIFFTAG_SMAXSAMPLEVALUE:
446                         {
447                                 double dv = 0.0;
448                                 if (!TIFFFetchPerSampleAnys(tif, dp, &dv) ||
449                                     !TIFFSetField(tif, dp->tdir_tag, dv))
450                                         goto bad;
451                         }
452                         break;
453                 case TIFFTAG_STRIPOFFSETS:
454                 case TIFFTAG_TILEOFFSETS:
455                         if (!TIFFFetchStripThing(tif, dp,
456                             td->td_nstrips, &td->td_stripoffset))
457                                 goto bad;
458                         break;
459                 case TIFFTAG_STRIPBYTECOUNTS:
460                 case TIFFTAG_TILEBYTECOUNTS:
461                         if (!TIFFFetchStripThing(tif, dp,
462                             td->td_nstrips, &td->td_stripbytecount))
463                                 goto bad;
464                         break;
465                 case TIFFTAG_COLORMAP:
466                 case TIFFTAG_TRANSFERFUNCTION:
467                         {
468                                 char* cp;
469                                 /*
470                                  * TransferFunction can have either 1x or 3x
471                                  * data values; Colormap can have only 3x
472                                  * items.
473                                  */
474                                 v = 1L<<td->td_bitspersample;
475                                 if (dp->tdir_tag == TIFFTAG_COLORMAP ||
476                                     dp->tdir_count != v) {
477                                         if (!CheckDirCount(tif, dp, 3 * v))
478                                                 break;
479                                 }
480                                 v *= sizeof(uint16);
481                                 cp = (char *)_TIFFCheckMalloc(tif,
482                                                               dp->tdir_count,
483                                                               sizeof (uint16),
484                                         "to read \"TransferFunction\" tag");
485                                 if (cp != NULL) {
486                                         if (TIFFFetchData(tif, dp, cp)) {
487                                                 /*
488                                                  * This deals with there being
489                                                  * only one array to apply to
490                                                  * all samples.
491                                                  */
492                                                 uint32 c = 1L << td->td_bitspersample;
493                                                 if (dp->tdir_count == c)
494                                                         v = 0L;
495                                                 TIFFSetField(tif, dp->tdir_tag,
496                                                     cp, cp+v, cp+2*v);
497                                         }
498                                         _TIFFfree(cp);
499                                 }
500                                 break;
501                         }
502                 case TIFFTAG_PAGENUMBER:
503                 case TIFFTAG_HALFTONEHINTS:
504                 case TIFFTAG_YCBCRSUBSAMPLING:
505                 case TIFFTAG_DOTRANGE:
506                         (void) TIFFFetchShortPair(tif, dp);
507                         break;
508                 case TIFFTAG_REFERENCEBLACKWHITE:
509                         (void) TIFFFetchRefBlackWhite(tif, dp);
510                         break;
511 /* BEGIN REV 4.0 COMPATIBILITY */
512                 case TIFFTAG_OSUBFILETYPE:
513                         v = 0L;
514                         switch (TIFFExtractData(tif, dp->tdir_type,
515                             dp->tdir_offset)) {
516                         case OFILETYPE_REDUCEDIMAGE:
517                                 v = FILETYPE_REDUCEDIMAGE;
518                                 break;
519                         case OFILETYPE_PAGE:
520                                 v = FILETYPE_PAGE;
521                                 break;
522                         }
523                         if (v)
524                                 TIFFSetField(tif, TIFFTAG_SUBFILETYPE, v);
525                         break;
526 /* END REV 4.0 COMPATIBILITY */
527                 default:
528                         (void) TIFFFetchNormalTag(tif, dp);
529                         break;
530                 }
531         }
532         /*
533          * Verify Palette image has a Colormap.
534          */
535         if (td->td_photometric == PHOTOMETRIC_PALETTE &&
536             !TIFFFieldSet(tif, FIELD_COLORMAP)) {
537                 MissingRequired(tif, "Colormap");
538                 goto bad;
539         }
540         /*
541          * Attempt to deal with a missing StripByteCounts tag.
542          */
543         if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
544                 /*
545                  * Some manufacturers violate the spec by not giving
546                  * the size of the strips.  In this case, assume there
547                  * is one uncompressed strip of data.
548                  */
549                 if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
550                     td->td_nstrips > 1) ||
551                     (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
552                      td->td_nstrips != td->td_samplesperpixel)) {
553                     MissingRequired(tif, "StripByteCounts");
554                     goto bad;
555                 }
556                 TIFFWarningExt(tif->tif_clientdata, module,
557                         "%s: TIFF directory is missing required "
558                         "\"%s\" field, calculating from imagelength",
559                         tif->tif_name,
560                         _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
561                 if (EstimateStripByteCounts(tif, dir, dircount) < 0)
562                     goto bad;
563 /*
564  * Assume we have wrong StripByteCount value (in case of single strip) in
565  * following cases:
566  *   - it is equal to zero along with StripOffset;
567  *   - it is larger than file itself (in case of uncompressed image);
568  *   - it is smaller than the size of the bytes per row multiplied on the
569  *     number of rows.  The last case should not be checked in the case of
570  *     writing new image, because we may do not know the exact strip size
571  *     until the whole image will be written and directory dumped out.
572  */
573 #define BYTECOUNTLOOKSBAD \
574     ( (td->td_stripbytecount[0] == 0 && td->td_stripoffset[0] != 0) || \
575       (td->td_compression == COMPRESSION_NONE && \
576        td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0]) || \
577       (tif->tif_mode == O_RDONLY && \
578        td->td_compression == COMPRESSION_NONE && \
579        td->td_stripbytecount[0] < TIFFScanlineSize(tif) * td->td_imagelength) )
580 
581         } else if (td->td_nstrips == 1
582                    && td->td_stripoffset[0] != 0
583                    && BYTECOUNTLOOKSBAD) {
584                 /*
585                  * XXX: Plexus (and others) sometimes give a value of zero for
586                  * a tag when they don't know what the correct value is!  Try
587                  * and handle the simple case of estimating the size of a one
588                  * strip image.
589                  */
590                 TIFFWarningExt(tif->tif_clientdata, module,
591         "%s: Bogus \"%s\" field, ignoring and calculating from imagelength",
592                             tif->tif_name,
593                             _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
594                 if(EstimateStripByteCounts(tif, dir, dircount) < 0)
595                     goto bad;
596         } else if (td->td_planarconfig == PLANARCONFIG_CONTIG
597                    && td->td_nstrips > 2
598                    && td->td_compression == COMPRESSION_NONE
599                    && td->td_stripbytecount[0] != td->td_stripbytecount[1]) {
600                 /*
601                  * XXX: Some vendors fill StripByteCount array with absolutely
602                  * wrong values (it can be equal to StripOffset array, for
603                  * example). Catch this case here.
604                  */
605                 TIFFWarningExt(tif->tif_clientdata, module,
606         "%s: Wrong \"%s\" field, ignoring and calculating from imagelength",
607                             tif->tif_name,
608                             _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
609                 if (EstimateStripByteCounts(tif, dir, dircount) < 0)
610                     goto bad;
611         }
612         if (dir) {
613                 _TIFFfree((char *)dir);
614                 dir = NULL;
615         }
616         if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
617                 td->td_maxsamplevalue = (uint16)((1L<<td->td_bitspersample)-1);
618         /*
619          * Setup default compression scheme.
620          */
621 
622         /*
623          * XXX: We can optimize checking for the strip bounds using the sorted
624          * bytecounts array. See also comments for TIFFAppendToStrip()
625          * function in tif_write.c.
626          */
627         if (td->td_nstrips > 1) {
628                 tstrip_t strip;
629 
630                 td->td_stripbytecountsorted = 1;
631                 for (strip = 1; strip < td->td_nstrips; strip++) {
632                         if (td->td_stripoffset[strip - 1] >
633                             td->td_stripoffset[strip]) {
634                                 td->td_stripbytecountsorted = 0;
635                                 break;
636                         }
637                 }
638         }
639 
640         if (!TIFFFieldSet(tif, FIELD_COMPRESSION))
641                 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
642         /*
643          * Some manufacturers make life difficult by writing
644          * large amounts of uncompressed data as a single strip.
645          * This is contrary to the recommendations of the spec.
646          * The following makes an attempt at breaking such images
647          * into strips closer to the recommended 8k bytes.  A
648          * side effect, however, is that the RowsPerStrip tag
649          * value may be changed.
650          */
651         if (td->td_nstrips == 1 && td->td_compression == COMPRESSION_NONE &&
652             (tif->tif_flags & (TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP)
653                 ChopUpSingleUncompressedStrip(tif);
654 
655         /*
656          * Reinitialize i/o since we are starting on a new directory.
657          */
658         tif->tif_row = (uint32) -1;
659         tif->tif_curstrip = (tstrip_t) -1;
660         tif->tif_col = (uint32) -1;
661         tif->tif_curtile = (ttile_t) -1;
662         tif->tif_tilesize = (tsize_t) -1;
663 
664         tif->tif_scanlinesize = TIFFScanlineSize(tif);
665         if (!tif->tif_scanlinesize) {
666                 TIFFErrorExt(tif->tif_clientdata, module, "%s: cannot handle zero scanline size",
667                           tif->tif_name);
668                 return (0);
669         }
670 
671         if (isTiled(tif)) {
672                 tif->tif_tilesize = TIFFTileSize(tif);
673                 if (!tif->tif_tilesize) {
674                         TIFFErrorExt(tif->tif_clientdata, module, "%s: cannot handle zero tile size",
675                                   tif->tif_name);
676                         return (0);
677                 }
678         } else {
679                 if (!TIFFStripSize(tif)) {
680                         TIFFErrorExt(tif->tif_clientdata, module, "%s: cannot handle zero strip size",
681                                   tif->tif_name);
682                         return (0);
683                 }
684         }
685         return (1);
686 bad:
687         if (dir)
688                 _TIFFfree(dir);
689         return (0);
690 }
691 
692 /*
693  * Read custom directory from the arbitarry offset.
694  * The code is very similar to TIFFReadDirectory().
695  */
696 int
TIFFReadCustomDirectory(TIFF * tif,toff_t diroff,const TIFFFieldInfo info[],size_t n)697 TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
698                         const TIFFFieldInfo info[], size_t n)
699 {
700         static const char module[] = "TIFFReadCustomDirectory";
701 
702         TIFFDirectory* td = &tif->tif_dir;
703         TIFFDirEntry *dp, *dir = NULL;
704         const TIFFFieldInfo* fip;
705         size_t fix;
706         uint16 i, dircount;
707 
708         _TIFFSetupFieldInfo(tif, info, n);
709 
710         tif->tif_diroff = diroff;
711 
712         if (!isMapped(tif)) {
713                 if (!SeekOK(tif, diroff)) {
714                         TIFFErrorExt(tif->tif_clientdata, module,
715                             "%s: Seek error accessing TIFF directory",
716                             tif->tif_name);
717                         return (0);
718                 }
719                 if (!ReadOK(tif, &dircount, sizeof (uint16))) {
720                         TIFFErrorExt(tif->tif_clientdata, module,
721                             "%s: Can not read TIFF directory count",
722                             tif->tif_name);
723                         return (0);
724                 }
725                 if (tif->tif_flags & TIFF_SWAB)
726                         TIFFSwabShort(&dircount);
727                 dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
728                                                        sizeof (TIFFDirEntry),
729                                         "to read TIFF custom directory");
730                 if (dir == NULL)
731                         return (0);
732                 if (!ReadOK(tif, dir, dircount * sizeof (TIFFDirEntry))) {
733                         TIFFErrorExt(tif->tif_clientdata, module,
734                                   "%.100s: Can not read TIFF directory",
735                                   tif->tif_name);
736                         goto bad;
737                 }
738         } else {
739                 toff_t off = diroff;
740 
741                 if (off + sizeof (uint16) > tif->tif_size) {
742                         TIFFErrorExt(tif->tif_clientdata, module,
743                             "%s: Can not read TIFF directory count",
744                             tif->tif_name);
745                         return (0);
746                 } else
747                         _TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16));
748                 off += sizeof (uint16);
749                 if (tif->tif_flags & TIFF_SWAB)
750                         TIFFSwabShort(&dircount);
751                 dir = (TIFFDirEntry *)_TIFFCheckMalloc(tif, dircount,
752                                                        sizeof (TIFFDirEntry),
753                                         "to read TIFF custom directory");
754                 if (dir == NULL)
755                         return (0);
756                 if (off + dircount * sizeof (TIFFDirEntry) > tif->tif_size) {
757                         TIFFErrorExt(tif->tif_clientdata, module,
758                                   "%s: Can not read TIFF directory",
759                                   tif->tif_name);
760                         goto bad;
761                 } else {
762                         _TIFFmemcpy(dir, tif->tif_base + off,
763                                     dircount * sizeof (TIFFDirEntry));
764                 }
765         }
766 
767         TIFFFreeDirectory(tif);
768 
769         fix = 0;
770         for (dp = dir, i = dircount; i > 0; i--, dp++) {
771                 if (tif->tif_flags & TIFF_SWAB) {
772                         TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
773                         TIFFSwabArrayOfLong(&dp->tdir_count, 2);
774                 }
775 
776                 if (fix >= tif->tif_nfields || dp->tdir_tag == IGNORE)
777                         continue;
778 
779                 while (fix < tif->tif_nfields &&
780                        tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
781                         fix++;
782 
783                 if (fix >= tif->tif_nfields ||
784                     tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
785 
786                         TIFFWarningExt(tif->tif_clientdata, module,
787                         "%s: unknown field with tag %d (0x%x) encountered",
788                                     tif->tif_name, dp->tdir_tag, dp->tdir_tag,
789                                     dp->tdir_type);
790 
791                         TIFFMergeFieldInfo(tif,
792                                            _TIFFCreateAnonFieldInfo(tif,
793                                                 dp->tdir_tag,
794                                                 (TIFFDataType)dp->tdir_type),
795                                            1);
796 
797                         fix = 0;
798                         while (fix < tif->tif_nfields &&
799                                tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
800                                 fix++;
801                 }
802                 /*
803                  * Null out old tags that we ignore.
804                  */
805                 if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {
806         ignore:
807                         dp->tdir_tag = IGNORE;
808                         continue;
809                 }
810                 /*
811                  * Check data type.
812                  */
813                 fip = tif->tif_fieldinfo[fix];
814                 while (dp->tdir_type != (unsigned short) fip->field_type
815                        && fix < tif->tif_nfields) {
816                         if (fip->field_type == TIFF_ANY)        /* wildcard */
817                                 break;
818                         fip = tif->tif_fieldinfo[++fix];
819                         if (fix >= tif->tif_nfields ||
820                             fip->field_tag != dp->tdir_tag) {
821                                 TIFFWarningExt(tif->tif_clientdata, module,
822                         "%s: wrong data type %d for \"%s\"; tag ignored",
823                                             tif->tif_name, dp->tdir_type,
824                                             tif->tif_fieldinfo[fix-1]->field_name);
825                                 goto ignore;
826                         }
827                 }
828                 /*
829                  * Check count if known in advance.
830                  */
831                 if (fip->field_readcount != TIFF_VARIABLE
832                     && fip->field_readcount != TIFF_VARIABLE2) {
833                         uint32 expected = (fip->field_readcount == TIFF_SPP) ?
834                             (uint32) td->td_samplesperpixel :
835                             (uint32) fip->field_readcount;
836                         if (!CheckDirCount(tif, dp, expected))
837                                 goto ignore;
838                 }
839 
840                 (void) TIFFFetchNormalTag(tif, dp);
841         }
842 
843         if (dir)
844                 _TIFFfree(dir);
845         return 1;
846 
847 bad:
848         if (dir)
849                 _TIFFfree(dir);
850         return 0;
851 }
852 
853 /*
854  * EXIF is important special case of custom IFD, so we have a special
855  * function to read it.
856  */
857 int
TIFFReadEXIFDirectory(TIFF * tif,toff_t diroff)858 TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
859 {
860         size_t exifFieldInfoCount;
861         const TIFFFieldInfo *exifFieldInfo =
862                 _TIFFGetExifFieldInfo(&exifFieldInfoCount);
863         return TIFFReadCustomDirectory(tif, diroff, exifFieldInfo,
864                                        exifFieldInfoCount);
865 }
866 
867 static int
EstimateStripByteCounts(TIFF * tif,TIFFDirEntry * dir,uint16 dircount)868 EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
869 {
870         static const char module[] = "EstimateStripByteCounts";
871 
872         register TIFFDirEntry *dp;
873         register TIFFDirectory *td = &tif->tif_dir;
874         uint16 i;
875 
876         if (td->td_stripbytecount)
877                 _TIFFfree(td->td_stripbytecount);
878         td->td_stripbytecount = (uint32*)
879             _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint32),
880                 "for \"StripByteCounts\" array");
881         if (td->td_compression != COMPRESSION_NONE) {
882                 uint32 space = (uint32)(sizeof (TIFFHeader)
883                     + sizeof (uint16)
884                     + (dircount * sizeof (TIFFDirEntry))
885                     + sizeof (uint32));
886                 toff_t filesize = TIFFGetFileSize(tif);
887                 uint16 n;
888 
889                 /* calculate amount of space used by indirect values */
890                 for (dp = dir, n = dircount; n > 0; n--, dp++)
891                 {
892                         uint32 cc = TIFFDataWidth((TIFFDataType) dp->tdir_type);
893                         if (cc == 0) {
894                                 TIFFErrorExt(tif->tif_clientdata, module,
895                         "%s: Cannot determine size of unknown tag type %d",
896                                           tif->tif_name, dp->tdir_type);
897                                 return -1;
898                         }
899                         cc = cc * dp->tdir_count;
900                         if (cc > sizeof (uint32))
901                                 space += cc;
902                 }
903                 space = filesize - space;
904                 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
905                         space /= td->td_samplesperpixel;
906                 for (i = 0; i < td->td_nstrips; i++)
907                         td->td_stripbytecount[i] = space;
908                 /*
909                  * This gross hack handles the case were the offset to
910                  * the last strip is past the place where we think the strip
911                  * should begin.  Since a strip of data must be contiguous,
912                  * it's safe to assume that we've overestimated the amount
913                  * of data in the strip and trim this number back accordingly.
914                  */
915                 i--;
916                 if (((toff_t)(td->td_stripoffset[i]+td->td_stripbytecount[i]))
917                                                                > filesize)
918                         td->td_stripbytecount[i] =
919                             filesize - td->td_stripoffset[i];
920         } else {
921                 uint32 rowbytes = TIFFScanlineSize(tif);
922                 uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
923                 for (i = 0; i < td->td_nstrips; i++)
924                         td->td_stripbytecount[i] = rowbytes*rowsperstrip;
925         }
926         TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
927         if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
928                 td->td_rowsperstrip = td->td_imagelength;
929         return 1;
930 }
931 
932 static void
MissingRequired(TIFF * tif,const char * tagname)933 MissingRequired(TIFF* tif, const char* tagname)
934 {
935         static const char module[] = "MissingRequired";
936 
937         TIFFErrorExt(tif->tif_clientdata, module,
938                   "%s: TIFF directory is missing required \"%s\" field",
939                   tif->tif_name, tagname);
940 }
941 
942 /*
943  * Check the count field of a directory
944  * entry against a known value.  The caller
945  * is expected to skip/ignore the tag if
946  * there is a mismatch.
947  */
948 static int
CheckDirCount(TIFF * tif,TIFFDirEntry * dir,uint32 count)949 CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
950 {
951         if (count > dir->tdir_count) {
952                 TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
953         "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",
954                     _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
955                     dir->tdir_count, count);
956                 return (0);
957         } else if (count < dir->tdir_count) {
958                 TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
959         "incorrect count for field \"%s\" (%lu, expecting %lu); tag trimmed",
960                     _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
961                     dir->tdir_count, count);
962                 return (1);
963         }
964         return (1);
965 }
966 
967 /*
968  * Fetch a contiguous directory item.
969  */
970 static tsize_t
TIFFFetchData(TIFF * tif,TIFFDirEntry * dir,char * cp)971 TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp)
972 {
973         int w = TIFFDataWidth((TIFFDataType) dir->tdir_type);
974         tsize_t cc = dir->tdir_count * w;
975 
976         /* Check for overflow. */
977         if (!dir->tdir_count || !w || cc / w != (tsize_t)dir->tdir_count)
978                 goto bad;
979 
980         if (!isMapped(tif)) {
981                 if (!SeekOK(tif, dir->tdir_offset))
982                         goto bad;
983                 if (!ReadOK(tif, cp, cc))
984                         goto bad;
985         } else {
986                 /* Check for overflow. */
987                 if ((tsize_t)dir->tdir_offset + cc < (tsize_t)dir->tdir_offset
988                     || (tsize_t)dir->tdir_offset + cc < cc
989                     || (tsize_t)dir->tdir_offset + cc > (tsize_t)tif->tif_size)
990                         goto bad;
991                 _TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc);
992         }
993         if (tif->tif_flags & TIFF_SWAB) {
994                 switch (dir->tdir_type) {
995                 case TIFF_SHORT:
996                 case TIFF_SSHORT:
997                         TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
998                         break;
999                 case TIFF_LONG:
1000                 case TIFF_SLONG:
1001                 case TIFF_FLOAT:
1002                         TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
1003                         break;
1004                 case TIFF_RATIONAL:
1005                 case TIFF_SRATIONAL:
1006                         TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
1007                         break;
1008                 case TIFF_DOUBLE:
1009                         TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
1010                         break;
1011                 }
1012         }
1013         return (cc);
1014 bad:
1015         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1016                      "Error fetching data for field \"%s\"",
1017                      _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1018         return (tsize_t) 0;
1019 }
1020 
1021 /*
1022  * Fetch an ASCII item from the file.
1023  */
1024 static tsize_t
TIFFFetchString(TIFF * tif,TIFFDirEntry * dir,char * cp)1025 TIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp)
1026 {
1027         if (dir->tdir_count <= 4) {
1028                 uint32 l = dir->tdir_offset;
1029                 if (tif->tif_flags & TIFF_SWAB)
1030                         TIFFSwabLong(&l);
1031                 _TIFFmemcpy(cp, &l, dir->tdir_count);
1032                 return (1);
1033         }
1034         return (TIFFFetchData(tif, dir, cp));
1035 }
1036 
1037 /*
1038  * Convert numerator+denominator to float.
1039  */
1040 static int
cvtRational(TIFF * tif,TIFFDirEntry * dir,uint32 num,uint32 denom,float * rv)1041 cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv)
1042 {
1043         if (denom == 0) {
1044                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1045                     "%s: Rational with zero denominator (num = %lu)",
1046                     _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num);
1047                 return (0);
1048         } else {
1049                 if (dir->tdir_type == TIFF_RATIONAL)
1050                         *rv = ((float)num / (float)denom);
1051                 else
1052                         *rv = ((float)(int32)num / (float)(int32)denom);
1053                 return (1);
1054         }
1055 }
1056 
1057 /*
1058  * Fetch a rational item from the file
1059  * at offset off and return the value
1060  * as a floating point number.
1061  */
1062 static float
TIFFFetchRational(TIFF * tif,TIFFDirEntry * dir)1063 TIFFFetchRational(TIFF* tif, TIFFDirEntry* dir)
1064 {
1065         uint32 l[2];
1066         float v;
1067 
1068         return (!TIFFFetchData(tif, dir, (char *)l) ||
1069             !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v);
1070 }
1071 
1072 /*
1073  * Fetch a single floating point value
1074  * from the offset field and return it
1075  * as a native float.
1076  */
1077 static float
TIFFFetchFloat(TIFF * tif,TIFFDirEntry * dir)1078 TIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir)
1079 {
1080         float v;
1081         int32 l = TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset);
1082         _TIFFmemcpy(&v, &l, sizeof(float));
1083         TIFFCvtIEEEFloatToNative(tif, 1, &v);
1084         return (v);
1085 }
1086 
1087 /*
1088  * Fetch an array of BYTE or SBYTE values.
1089  */
1090 static int
TIFFFetchByteArray(TIFF * tif,TIFFDirEntry * dir,uint16 * v)1091 TIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
1092 {
1093     if (dir->tdir_count <= 4) {
1094         /*
1095          * Extract data from offset field.
1096          */
1097         if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
1098             if (dir->tdir_type == TIFF_SBYTE)
1099                 switch (dir->tdir_count) {
1100                     case 4: v[3] = (signed char)(dir->tdir_offset & 0xff);
1101                     case 3: v[2] = (signed char)((dir->tdir_offset >> 8) & 0xff);
1102                     case 2: v[1] = (signed char)((dir->tdir_offset >> 16) & 0xff);
1103                     case 1: v[0] = (signed char)(dir->tdir_offset >> 24);
1104                 }
1105             else
1106                 switch (dir->tdir_count) {
1107                     case 4: v[3] = (uint16)(dir->tdir_offset & 0xff);
1108                     case 3: v[2] = (uint16)((dir->tdir_offset >> 8) & 0xff);
1109                     case 2: v[1] = (uint16)((dir->tdir_offset >> 16) & 0xff);
1110                     case 1: v[0] = (uint16)(dir->tdir_offset >> 24);
1111                 }
1112         } else {
1113             if (dir->tdir_type == TIFF_SBYTE)
1114                 switch (dir->tdir_count) {
1115                     case 4: v[3] = (signed char)(dir->tdir_offset >> 24);
1116                     case 3: v[2] = (signed char)((dir->tdir_offset >> 16) & 0xff);
1117                     case 2: v[1] = (signed char)((dir->tdir_offset >> 8) & 0xff);
1118                     case 1: v[0] = (signed char)(dir->tdir_offset & 0xff);
1119                 }
1120             else
1121                 switch (dir->tdir_count) {
1122                     case 4: v[3] = (uint16)(dir->tdir_offset >> 24);
1123                     case 3: v[2] = (uint16)((dir->tdir_offset >> 16) & 0xff);
1124                     case 2: v[1] = (uint16)((dir->tdir_offset >> 8) & 0xff);
1125                     case 1: v[0] = (uint16)(dir->tdir_offset & 0xff);
1126                 }
1127         }
1128         return (1);
1129     } else
1130         return (TIFFFetchData(tif, dir, (char*) v) != 0);       /* XXX */
1131 }
1132 
1133 /*
1134  * Fetch an array of SHORT or SSHORT values.
1135  */
1136 static int
TIFFFetchShortArray(TIFF * tif,TIFFDirEntry * dir,uint16 * v)1137 TIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
1138 {
1139         if (dir->tdir_count <= 2) {
1140                 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
1141                         switch (dir->tdir_count) {
1142                         case 2: v[1] = (uint16) (dir->tdir_offset & 0xffff);
1143                         case 1: v[0] = (uint16) (dir->tdir_offset >> 16);
1144                         }
1145                 } else {
1146                         switch (dir->tdir_count) {
1147                         case 2: v[1] = (uint16) (dir->tdir_offset >> 16);
1148                         case 1: v[0] = (uint16) (dir->tdir_offset & 0xffff);
1149                         }
1150                 }
1151                 return (1);
1152         } else
1153                 return (TIFFFetchData(tif, dir, (char *)v) != 0);
1154 }
1155 
1156 /*
1157  * Fetch a pair of SHORT or BYTE values. Some tags may have either BYTE
1158  * or SHORT type and this function works with both ones.
1159  */
1160 static int
TIFFFetchShortPair(TIFF * tif,TIFFDirEntry * dir)1161 TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir)
1162 {
1163         switch (dir->tdir_type) {
1164                 case TIFF_BYTE:
1165                 case TIFF_SBYTE:
1166                         {
1167                         uint16 v[4];
1168                         return TIFFFetchByteArray(tif, dir, v)
1169                                 && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
1170                         }
1171                 case TIFF_SHORT:
1172                 case TIFF_SSHORT:
1173                         {
1174                         uint16 v[2];
1175                         return TIFFFetchShortArray(tif, dir, v)
1176                                 && TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
1177                         }
1178                 default:
1179                         return 0;
1180         }
1181 }
1182 
1183 /*
1184  * Fetch an array of LONG or SLONG values.
1185  */
1186 static int
TIFFFetchLongArray(TIFF * tif,TIFFDirEntry * dir,uint32 * v)1187 TIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
1188 {
1189         if (dir->tdir_count == 1) {
1190                 v[0] = dir->tdir_offset;
1191                 return (1);
1192         } else
1193                 return (TIFFFetchData(tif, dir, (char*) v) != 0);
1194 }
1195 
1196 /*
1197  * Fetch an array of RATIONAL or SRATIONAL values.
1198  */
1199 static int
TIFFFetchRationalArray(TIFF * tif,TIFFDirEntry * dir,float * v)1200 TIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
1201 {
1202         int ok = 0;
1203         uint32* l;
1204 
1205         l = (uint32*)_TIFFCheckMalloc(tif,
1206             dir->tdir_count, TIFFDataWidth((TIFFDataType) dir->tdir_type),
1207             "to fetch array of rationals");
1208         if (l) {
1209                 if (TIFFFetchData(tif, dir, (char *)l)) {
1210                         uint32 i;
1211                         for (i = 0; i < dir->tdir_count; i++) {
1212                                 ok = cvtRational(tif, dir,
1213                                     l[2*i+0], l[2*i+1], &v[i]);
1214                                 if (!ok)
1215                                         break;
1216                         }
1217                 }
1218                 _TIFFfree((char *)l);
1219         }
1220         return (ok);
1221 }
1222 
1223 /*
1224  * Fetch an array of FLOAT values.
1225  */
1226 static int
TIFFFetchFloatArray(TIFF * tif,TIFFDirEntry * dir,float * v)1227 TIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
1228 {
1229 
1230         if (dir->tdir_count == 1) {
1231                 v[0] = *(float*) &dir->tdir_offset;
1232                 TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
1233                 return (1);
1234         } else  if (TIFFFetchData(tif, dir, (char*) v)) {
1235                 TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
1236                 return (1);
1237         } else
1238                 return (0);
1239 }
1240 
1241 /*
1242  * Fetch an array of DOUBLE values.
1243  */
1244 static int
TIFFFetchDoubleArray(TIFF * tif,TIFFDirEntry * dir,double * v)1245 TIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
1246 {
1247         if (TIFFFetchData(tif, dir, (char*) v)) {
1248                 TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v);
1249                 return (1);
1250         } else
1251                 return (0);
1252 }
1253 
1254 /*
1255  * Fetch an array of ANY values.  The actual values are
1256  * returned as doubles which should be able hold all the
1257  * types.  Yes, there really should be an tany_t to avoid
1258  * this potential non-portability ...  Note in particular
1259  * that we assume that the double return value vector is
1260  * large enough to read in any fundamental type.  We use
1261  * that vector as a buffer to read in the base type vector
1262  * and then convert it in place to double (from end
1263  * to front of course).
1264  */
1265 static int
TIFFFetchAnyArray(TIFF * tif,TIFFDirEntry * dir,double * v)1266 TIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v)
1267 {
1268         int i;
1269 
1270         switch (dir->tdir_type) {
1271         case TIFF_BYTE:
1272         case TIFF_SBYTE:
1273                 if (!TIFFFetchByteArray(tif, dir, (uint16*) v))
1274                         return (0);
1275                 if (dir->tdir_type == TIFF_BYTE) {
1276                         uint8* vp = (uint8*) v;
1277                         for (i = dir->tdir_count-1; i >= 0; i--)
1278                                 v[i] = vp[i];
1279                 } else {
1280                         int8* vp = (int8*) v;
1281                         for (i = dir->tdir_count-1; i >= 0; i--)
1282                                 v[i] = vp[i];
1283                 }
1284                 break;
1285         case TIFF_SHORT:
1286         case TIFF_SSHORT:
1287                 if (!TIFFFetchShortArray(tif, dir, (uint16*) v))
1288                         return (0);
1289                 if (dir->tdir_type == TIFF_SHORT) {
1290                         uint16* vp = (uint16*) v;
1291                         for (i = dir->tdir_count-1; i >= 0; i--)
1292                                 v[i] = vp[i];
1293                 } else {
1294                         int16* vp = (int16*) v;
1295                         for (i = dir->tdir_count-1; i >= 0; i--)
1296                                 v[i] = vp[i];
1297                 }
1298                 break;
1299         case TIFF_LONG:
1300         case TIFF_SLONG:
1301                 if (!TIFFFetchLongArray(tif, dir, (uint32*) v))
1302                         return (0);
1303                 if (dir->tdir_type == TIFF_LONG) {
1304                         uint32* vp = (uint32*) v;
1305                         for (i = dir->tdir_count-1; i >= 0; i--)
1306                                 v[i] = vp[i];
1307                 } else {
1308                         int32* vp = (int32*) v;
1309                         for (i = dir->tdir_count-1; i >= 0; i--)
1310                                 v[i] = vp[i];
1311                 }
1312                 break;
1313         case TIFF_RATIONAL:
1314         case TIFF_SRATIONAL:
1315                 if (!TIFFFetchRationalArray(tif, dir, (float*) v))
1316                         return (0);
1317                 { float* vp = (float*) v;
1318                   for (i = dir->tdir_count-1; i >= 0; i--)
1319                         v[i] = vp[i];
1320                 }
1321                 break;
1322         case TIFF_FLOAT:
1323                 if (!TIFFFetchFloatArray(tif, dir, (float*) v))
1324                         return (0);
1325                 { float* vp = (float*) v;
1326                   for (i = dir->tdir_count-1; i >= 0; i--)
1327                         v[i] = vp[i];
1328                 }
1329                 break;
1330         case TIFF_DOUBLE:
1331                 return (TIFFFetchDoubleArray(tif, dir, (double*) v));
1332         default:
1333                 /* TIFF_NOTYPE */
1334                 /* TIFF_ASCII */
1335                 /* TIFF_UNDEFINED */
1336                 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1337                              "cannot read TIFF_ANY type %d for field \"%s\"",
1338                              dir->tdir_type,
1339                              _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1340                 return (0);
1341         }
1342         return (1);
1343 }
1344 
1345 /*
1346  * Fetch a tag that is not handled by special case code.
1347  */
1348 static int
TIFFFetchNormalTag(TIFF * tif,TIFFDirEntry * dp)1349 TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp)
1350 {
1351         static const char mesg[] = "to fetch tag value";
1352         int ok = 0;
1353         const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag);
1354 
1355         if (dp->tdir_count > 1) {               /* array of values */
1356                 char* cp = NULL;
1357 
1358                 switch (dp->tdir_type) {
1359                 case TIFF_BYTE:
1360                 case TIFF_SBYTE:
1361                 /* NB: always expand BYTE values to shorts */
1362                 cp = (char *)_TIFFCheckMalloc(tif,
1363                       dp->tdir_count, sizeof (uint16), mesg);
1364                 ok = cp && TIFFFetchByteArray(tif, dp, (uint16*) cp);
1365                         break;
1366                 case TIFF_SHORT:
1367                 case TIFF_SSHORT:
1368                         cp = (char *)_TIFFCheckMalloc(tif,
1369                             dp->tdir_count, sizeof (uint16), mesg);
1370                         ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp);
1371                         break;
1372                 case TIFF_LONG:
1373                 case TIFF_SLONG:
1374                         cp = (char *)_TIFFCheckMalloc(tif,
1375                             dp->tdir_count, sizeof (uint32), mesg);
1376                         ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp);
1377                         break;
1378                 case TIFF_RATIONAL:
1379                 case TIFF_SRATIONAL:
1380                         cp = (char *)_TIFFCheckMalloc(tif,
1381                             dp->tdir_count, sizeof (float), mesg);
1382                         ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp);
1383                         break;
1384                 case TIFF_FLOAT:
1385                         cp = (char *)_TIFFCheckMalloc(tif,
1386                             dp->tdir_count, sizeof (float), mesg);
1387                         ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp);
1388                         break;
1389                 case TIFF_DOUBLE:
1390                         cp = (char *)_TIFFCheckMalloc(tif,
1391                             dp->tdir_count, sizeof (double), mesg);
1392                         ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp);
1393                         break;
1394                 case TIFF_ASCII:
1395                 case TIFF_UNDEFINED:            /* bit of a cheat... */
1396                         /*
1397                          * Some vendors write strings w/o the trailing
1398                          * NULL byte, so always append one just in case.
1399                          */
1400                         cp = (char *)_TIFFCheckMalloc(tif, dp->tdir_count + 1,
1401                                                       1, mesg);
1402                         if( (ok = (cp && TIFFFetchString(tif, dp, cp))) != 0 )
1403                                 cp[dp->tdir_count] = '\0';      /* XXX */
1404                         break;
1405                 }
1406                 if (ok) {
1407                         ok = (fip->field_passcount ?
1408                             TIFFSetField(tif, dp->tdir_tag, dp->tdir_count, cp)
1409                           : TIFFSetField(tif, dp->tdir_tag, cp));
1410                 }
1411                 if (cp != NULL)
1412                         _TIFFfree(cp);
1413         } else if (CheckDirCount(tif, dp, 1)) { /* singleton value */
1414                 switch (dp->tdir_type) {
1415                 case TIFF_BYTE:
1416                 case TIFF_SBYTE:
1417                 case TIFF_SHORT:
1418                 case TIFF_SSHORT:
1419                         /*
1420                          * If the tag is also acceptable as a LONG or SLONG
1421                          * then TIFFSetField will expect an uint32 parameter
1422                          * passed to it (through varargs).  Thus, for machines
1423                          * where sizeof (int) != sizeof (uint32) we must do
1424                          * a careful check here.  It's hard to say if this
1425                          * is worth optimizing.
1426                          *
1427                          * NB: We use TIFFFieldWithTag here knowing that
1428                          *     it returns us the first entry in the table
1429                          *     for the tag and that that entry is for the
1430                          *     widest potential data type the tag may have.
1431                          */
1432                         { TIFFDataType type = fip->field_type;
1433                           if (type != TIFF_LONG && type != TIFF_SLONG) {
1434                                 uint16 v = (uint16)
1435                            TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
1436                                 ok = (fip->field_passcount ?
1437                                     TIFFSetField(tif, dp->tdir_tag, 1, &v)
1438                                   : TIFFSetField(tif, dp->tdir_tag, v));
1439                                 break;
1440                           }
1441                         }
1442                         /* fall thru... */
1443                 case TIFF_LONG:
1444                 case TIFF_SLONG:
1445                         { uint32 v32 =
1446                     TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
1447                           ok = (fip->field_passcount ?
1448                               TIFFSetField(tif, dp->tdir_tag, 1, &v32)
1449                             : TIFFSetField(tif, dp->tdir_tag, v32));
1450                         }
1451                         break;
1452                 case TIFF_RATIONAL:
1453                 case TIFF_SRATIONAL:
1454                 case TIFF_FLOAT:
1455                         { float v = (dp->tdir_type == TIFF_FLOAT ?
1456                               TIFFFetchFloat(tif, dp)
1457                             : TIFFFetchRational(tif, dp));
1458                           ok = (fip->field_passcount ?
1459                               TIFFSetField(tif, dp->tdir_tag, 1, &v)
1460                             : TIFFSetField(tif, dp->tdir_tag, v));
1461                         }
1462                         break;
1463                 case TIFF_DOUBLE:
1464                         { double v;
1465                           ok = (TIFFFetchDoubleArray(tif, dp, &v) &&
1466                             (fip->field_passcount ?
1467                               TIFFSetField(tif, dp->tdir_tag, 1, &v)
1468                             : TIFFSetField(tif, dp->tdir_tag, v))
1469                           );
1470                         }
1471                         break;
1472                 case TIFF_ASCII:
1473                 case TIFF_UNDEFINED:            /* bit of a cheat... */
1474                         { char c[2];
1475                           if( (ok = (TIFFFetchString(tif, dp, c) != 0)) != 0 ) {
1476                                 c[1] = '\0';            /* XXX paranoid */
1477                                 ok = (fip->field_passcount ?
1478                                         TIFFSetField(tif, dp->tdir_tag, 1, c)
1479                                       : TIFFSetField(tif, dp->tdir_tag, c));
1480                           }
1481                         }
1482                         break;
1483                 }
1484         }
1485         return (ok);
1486 }
1487 
1488 #define NITEMS(x)       (sizeof (x) / sizeof (x[0]))
1489 /*
1490  * Fetch samples/pixel short values for
1491  * the specified tag and verify that
1492  * all values are the same.
1493  */
1494 static int
TIFFFetchPerSampleShorts(TIFF * tif,TIFFDirEntry * dir,uint16 * pl)1495 TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, uint16* pl)
1496 {
1497     uint16 samples = tif->tif_dir.td_samplesperpixel;
1498     int status = 0;
1499 
1500     if (CheckDirCount(tif, dir, (uint32) samples)) {
1501         uint16 buf[10];
1502         uint16* v = buf;
1503 
1504         if (dir->tdir_count > NITEMS(buf))
1505             v = (uint16*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof(uint16),
1506                                       "to fetch per-sample values");
1507         if (v && TIFFFetchShortArray(tif, dir, v)) {
1508             uint16 i;
1509             int check_count = dir->tdir_count;
1510             if( samples < check_count )
1511                 check_count = samples;
1512 
1513             for (i = 1; i < check_count; i++)
1514                 if (v[i] != v[0]) {
1515                                         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1516                               "Cannot handle different per-sample values for field \"%s\"",
1517                               _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1518                     goto bad;
1519                 }
1520             *pl = v[0];
1521             status = 1;
1522         }
1523       bad:
1524         if (v && v != buf)
1525             _TIFFfree(v);
1526     }
1527     return (status);
1528 }
1529 
1530 /*
1531  * Fetch samples/pixel long values for
1532  * the specified tag and verify that
1533  * all values are the same.
1534  */
1535 static int
TIFFFetchPerSampleLongs(TIFF * tif,TIFFDirEntry * dir,uint32 * pl)1536 TIFFFetchPerSampleLongs(TIFF* tif, TIFFDirEntry* dir, uint32* pl)
1537 {
1538     uint16 samples = tif->tif_dir.td_samplesperpixel;
1539     int status = 0;
1540 
1541     if (CheckDirCount(tif, dir, (uint32) samples)) {
1542         uint32 buf[10];
1543         uint32* v = buf;
1544 
1545         if (dir->tdir_count > NITEMS(buf))
1546             v = (uint32*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof(uint32),
1547                                       "to fetch per-sample values");
1548         if (v && TIFFFetchLongArray(tif, dir, v)) {
1549             uint16 i;
1550             int check_count = dir->tdir_count;
1551 
1552             if( samples < check_count )
1553                 check_count = samples;
1554             for (i = 1; i < check_count; i++)
1555                 if (v[i] != v[0]) {
1556                                         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1557                               "Cannot handle different per-sample values for field \"%s\"",
1558                               _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1559                     goto bad;
1560                 }
1561             *pl = v[0];
1562             status = 1;
1563         }
1564       bad:
1565         if (v && v != buf)
1566             _TIFFfree(v);
1567     }
1568     return (status);
1569 }
1570 
1571 /*
1572  * Fetch samples/pixel ANY values for the specified tag and verify that all
1573  * values are the same.
1574  */
1575 static int
TIFFFetchPerSampleAnys(TIFF * tif,TIFFDirEntry * dir,double * pl)1576 TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl)
1577 {
1578     uint16 samples = tif->tif_dir.td_samplesperpixel;
1579     int status = 0;
1580 
1581     if (CheckDirCount(tif, dir, (uint32) samples)) {
1582         double buf[10];
1583         double* v = buf;
1584 
1585         if (dir->tdir_count > NITEMS(buf))
1586             v = (double*) _TIFFCheckMalloc(tif, dir->tdir_count, sizeof (double),
1587                                       "to fetch per-sample values");
1588         if (v && TIFFFetchAnyArray(tif, dir, v)) {
1589             uint16 i;
1590             int check_count = dir->tdir_count;
1591             if( samples < check_count )
1592                 check_count = samples;
1593 
1594             for (i = 1; i < check_count; i++)
1595                 if (v[i] != v[0]) {
1596                     TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
1597                               "Cannot handle different per-sample values for field \"%s\"",
1598                               _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1599                     goto bad;
1600                 }
1601             *pl = v[0];
1602             status = 1;
1603         }
1604       bad:
1605         if (v && v != buf)
1606             _TIFFfree(v);
1607     }
1608     return (status);
1609 }
1610 #undef NITEMS
1611 
1612 /*
1613  * Fetch a set of offsets or lengths.
1614  * While this routine says "strips", in fact it's also used for tiles.
1615  */
1616 static int
TIFFFetchStripThing(TIFF * tif,TIFFDirEntry * dir,long nstrips,uint32 ** lpp)1617 TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, long nstrips, uint32** lpp)
1618 {
1619         register uint32* lp;
1620         int status;
1621 
1622         CheckDirCount(tif, dir, (uint32) nstrips);
1623 
1624         /*
1625          * Allocate space for strip information.
1626          */
1627         if (*lpp == NULL &&
1628             (*lpp = (uint32 *)_TIFFCheckMalloc(tif,
1629               nstrips, sizeof (uint32), "for strip array")) == NULL)
1630                 return (0);
1631         lp = *lpp;
1632         _TIFFmemset( lp, 0, sizeof(uint32) * nstrips );
1633 
1634         if (dir->tdir_type == (int)TIFF_SHORT) {
1635                 /*
1636                  * Handle uint16->uint32 expansion.
1637                  */
1638                 uint16* dp = (uint16*) _TIFFCheckMalloc(tif,
1639                     dir->tdir_count, sizeof (uint16), "to fetch strip tag");
1640                 if (dp == NULL)
1641                         return (0);
1642                 if( (status = TIFFFetchShortArray(tif, dir, dp)) != 0 ) {
1643                     int i;
1644 
1645                     for( i = 0; i < nstrips && i < (int) dir->tdir_count; i++ )
1646                     {
1647                         lp[i] = dp[i];
1648                     }
1649                 }
1650                 _TIFFfree((char*) dp);
1651 
1652         } else if( nstrips != (int) dir->tdir_count ) {
1653             /* Special case to correct length */
1654 
1655             uint32* dp = (uint32*) _TIFFCheckMalloc(tif,
1656                     dir->tdir_count, sizeof (uint32), "to fetch strip tag");
1657             if (dp == NULL)
1658                 return (0);
1659 
1660             status = TIFFFetchLongArray(tif, dir, dp);
1661             if( status != 0 ) {
1662                 int i;
1663 
1664                 for( i = 0; i < nstrips && i < (int) dir->tdir_count; i++ )
1665                 {
1666                     lp[i] = dp[i];
1667                 }
1668             }
1669 
1670             _TIFFfree( (char *) dp );
1671         } else
1672             status = TIFFFetchLongArray(tif, dir, lp);
1673 
1674         return (status);
1675 }
1676 
1677 /*
1678  * Fetch and set the RefBlackWhite tag.
1679  */
1680 static int
TIFFFetchRefBlackWhite(TIFF * tif,TIFFDirEntry * dir)1681 TIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir)
1682 {
1683         static const char mesg[] = "for \"ReferenceBlackWhite\" array";
1684         char* cp;
1685         int ok;
1686 
1687         if (dir->tdir_type == TIFF_RATIONAL)
1688                 return (TIFFFetchNormalTag(tif, dir));
1689         /*
1690          * Handle LONG's for backward compatibility.
1691          */
1692         cp = (char *)_TIFFCheckMalloc(tif, dir->tdir_count,
1693                                       sizeof (uint32), mesg);
1694         if( (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) != 0) {
1695                 float* fp = (float*)
1696                     _TIFFCheckMalloc(tif, dir->tdir_count, sizeof (float), mesg);
1697                 if( (ok = (fp != NULL)) != 0 ) {
1698                         uint32 i;
1699                         for (i = 0; i < dir->tdir_count; i++)
1700                                 fp[i] = (float)((uint32*) cp)[i];
1701                         ok = TIFFSetField(tif, dir->tdir_tag, fp);
1702                         _TIFFfree((char*) fp);
1703                 }
1704         }
1705         if (cp)
1706                 _TIFFfree(cp);
1707         return (ok);
1708 }
1709 
1710 /*
1711  * Replace a single strip (tile) of uncompressed data by
1712  * multiple strips (tiles), each approximately 8Kbytes.
1713  * This is useful for dealing with large images or
1714  * for dealing with machines with a limited amount
1715  * memory.
1716  */
1717 static void
ChopUpSingleUncompressedStrip(TIFF * tif)1718 ChopUpSingleUncompressedStrip(TIFF* tif)
1719 {
1720         register TIFFDirectory *td = &tif->tif_dir;
1721         uint32 bytecount = td->td_stripbytecount[0];
1722         uint32 offset = td->td_stripoffset[0];
1723         tsize_t rowbytes = TIFFVTileSize(tif, 1), stripbytes;
1724         tstrip_t strip, nstrips, rowsperstrip;
1725         uint32* newcounts;
1726         uint32* newoffsets;
1727 
1728         /*
1729          * Make the rows hold at least one scanline, but fill specified amount
1730          * of data if possible.
1731          */
1732         if (rowbytes > STRIP_SIZE_DEFAULT) {
1733                 stripbytes = rowbytes;
1734                 rowsperstrip = 1;
1735         } else if (rowbytes > 0 ) {
1736                 rowsperstrip = STRIP_SIZE_DEFAULT / rowbytes;
1737                 stripbytes = rowbytes * rowsperstrip;
1738         }
1739         else
1740             return;
1741 
1742         /*
1743          * never increase the number of strips in an image
1744          */
1745         if (rowsperstrip >= td->td_rowsperstrip)
1746                 return;
1747         nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes);
1748         if( nstrips == 0 ) /* something is wonky, do nothing. */
1749             return;
1750 
1751         newcounts = (uint32*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint32),
1752                                 "for chopped \"StripByteCounts\" array");
1753         newoffsets = (uint32*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint32),
1754                                 "for chopped \"StripOffsets\" array");
1755         if (newcounts == NULL || newoffsets == NULL) {
1756                 /*
1757                  * Unable to allocate new strip information, give
1758                  * up and use the original one strip information.
1759                  */
1760                 if (newcounts != NULL)
1761                         _TIFFfree(newcounts);
1762                 if (newoffsets != NULL)
1763                         _TIFFfree(newoffsets);
1764                 return;
1765         }
1766         /*
1767          * Fill the strip information arrays with new bytecounts and offsets
1768          * that reflect the broken-up format.
1769          */
1770         for (strip = 0; strip < nstrips; strip++) {
1771                 if (stripbytes > (tsize_t) bytecount)
1772                         stripbytes = bytecount;
1773                 newcounts[strip] = stripbytes;
1774                 newoffsets[strip] = offset;
1775                 offset += stripbytes;
1776                 bytecount -= stripbytes;
1777         }
1778         /*
1779          * Replace old single strip info with multi-strip info.
1780          */
1781         td->td_stripsperimage = td->td_nstrips = nstrips;
1782         TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
1783 
1784         _TIFFfree(td->td_stripbytecount);
1785         _TIFFfree(td->td_stripoffset);
1786         td->td_stripbytecount = newcounts;
1787         td->td_stripoffset = newoffsets;
1788         td->td_stripbytecountsorted = 1;
1789 }
1790 
1791 /* vim: set ts=8 sts=8 sw=8 noet: */
1792