]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/tiff/tif_dirread.c
rtti api mods added
[wxWidgets.git] / src / tiff / tif_dirread.c
... / ...
CommitLineData
1/* $Header$ */
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#if HAVE_IEEEFP
37#define TIFFCvtIEEEFloatToNative(tif, n, fp)
38#define TIFFCvtIEEEDoubleToNative(tif, n, dp)
39#else
40extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
41extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
42#endif
43
44static void EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16);
45static void MissingRequired(TIFF*, const char*);
46static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
47static tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
48static tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
49static float TIFFFetchRational(TIFF*, TIFFDirEntry*);
50static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*);
51static int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, int*);
52static int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*);
53static int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*);
54static int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**);
55static int TIFFFetchExtraSamples(TIFF*, TIFFDirEntry*);
56static int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*);
57static float TIFFFetchFloat(TIFF*, TIFFDirEntry*);
58static int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*);
59static int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*);
60static int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*);
61static int TIFFFetchShortPair(TIFF*, TIFFDirEntry*);
62static void ChopUpSingleUncompressedStrip(TIFF*);
63
64static char *
65CheckMalloc(TIFF* tif, tsize_t n, const char* what)
66{
67 char *cp = (char*)_TIFFmalloc(n);
68 if (cp == NULL)
69 TIFFError(tif->tif_name, "No space %s", what);
70 return (cp);
71}
72
73/*
74 * Read the next TIFF directory from a file
75 * and convert it to the internal format.
76 * We read directories sequentially.
77 */
78int
79TIFFReadDirectory(TIFF* tif)
80{
81 register TIFFDirEntry* dp;
82 register int n;
83 register TIFFDirectory* td;
84 TIFFDirEntry* dir;
85 int iv;
86 long v;
87 double dv;
88 const TIFFFieldInfo* fip;
89 int fix;
90 uint16 dircount;
91 uint32 nextdiroff;
92 char* cp;
93 int diroutoforderwarning = 0;
94
95 tif->tif_diroff = tif->tif_nextdiroff;
96 if (tif->tif_diroff == 0) /* no more directories */
97 return (0);
98 /*
99 * Cleanup any previous compression state.
100 */
101 (*tif->tif_cleanup)(tif);
102 tif->tif_curdir++;
103 nextdiroff = 0;
104 if (!isMapped(tif)) {
105 if (!SeekOK(tif, tif->tif_diroff)) {
106 TIFFError(tif->tif_name,
107 "Seek error accessing TIFF directory");
108 return (0);
109 }
110 if (!ReadOK(tif, &dircount, sizeof (uint16))) {
111 TIFFError(tif->tif_name,
112 "Can not read TIFF directory count");
113 return (0);
114 }
115 if (tif->tif_flags & TIFF_SWAB)
116 TIFFSwabShort(&dircount);
117 dir = (TIFFDirEntry *)CheckMalloc(tif,
118 dircount * sizeof (TIFFDirEntry), "to read TIFF directory");
119 if (dir == NULL)
120 return (0);
121 if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) {
122 TIFFError(tif->tif_name, "Can not read TIFF directory");
123 goto bad;
124 }
125 /*
126 * Read offset to next directory for sequential scans.
127 */
128 (void) ReadOK(tif, &nextdiroff, sizeof (uint32));
129 } else {
130 toff_t off = tif->tif_diroff;
131
132 if (off + sizeof (uint16) > tif->tif_size) {
133 TIFFError(tif->tif_name,
134 "Can not read TIFF directory count");
135 return (0);
136 } else
137 _TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16));
138 off += sizeof (uint16);
139 if (tif->tif_flags & TIFF_SWAB)
140 TIFFSwabShort(&dircount);
141 dir = (TIFFDirEntry *)CheckMalloc(tif,
142 dircount * sizeof (TIFFDirEntry), "to read TIFF directory");
143 if (dir == NULL)
144 return (0);
145 if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) {
146 TIFFError(tif->tif_name, "Can not read TIFF directory");
147 goto bad;
148 } else
149 _TIFFmemcpy(dir, tif->tif_base + off,
150 dircount*sizeof (TIFFDirEntry));
151 off += dircount* sizeof (TIFFDirEntry);
152 if (off + sizeof (uint32) <= tif->tif_size)
153 _TIFFmemcpy(&nextdiroff, tif->tif_base+off, sizeof (uint32));
154 }
155 if (tif->tif_flags & TIFF_SWAB)
156 TIFFSwabLong(&nextdiroff);
157 tif->tif_nextdiroff = nextdiroff;
158
159 tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */
160 /*
161 * Setup default value and then make a pass over
162 * the fields to check type and tag information,
163 * and to extract info required to size data
164 * structures. A second pass is made afterwards
165 * to read in everthing not taken in the first pass.
166 */
167 td = &tif->tif_dir;
168 /* free any old stuff and reinit */
169 TIFFFreeDirectory(tif);
170 TIFFDefaultDirectory(tif);
171 /*
172 * Electronic Arts writes gray-scale TIFF files
173 * without a PlanarConfiguration directory entry.
174 * Thus we setup a default value here, even though
175 * the TIFF spec says there is no default value.
176 */
177 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
178
179 /*
180 * Sigh, we must make a separate pass through the
181 * directory for the following reason:
182 *
183 * We must process the Compression tag in the first pass
184 * in order to merge in codec-private tag definitions (otherwise
185 * we may get complaints about unknown tags). However, the
186 * Compression tag may be dependent on the SamplesPerPixel
187 * tag value because older TIFF specs permited Compression
188 * to be written as a SamplesPerPixel-count tag entry.
189 * Thus if we don't first figure out the correct SamplesPerPixel
190 * tag value then we may end up ignoring the Compression tag
191 * value because it has an incorrect count value (if the
192 * true value of SamplesPerPixel is not 1).
193 *
194 * It sure would have been nice if Aldus had really thought
195 * this stuff through carefully.
196 */
197 for (dp = dir, n = dircount; n > 0; n--, dp++) {
198 if (tif->tif_flags & TIFF_SWAB) {
199 TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
200 TIFFSwabArrayOfLong(&dp->tdir_count, 2);
201 }
202 if (dp->tdir_tag == TIFFTAG_SAMPLESPERPIXEL) {
203 if (!TIFFFetchNormalTag(tif, dp))
204 goto bad;
205 dp->tdir_tag = IGNORE;
206 }
207 }
208 /*
209 * First real pass over the directory.
210 */
211 fix = 0;
212 for (dp = dir, n = dircount; n > 0; n--, dp++) {
213
214 /*
215 * Find the field information entry for this tag.
216 * Added check for tags to ignore ... [BFC]
217 */
218 if( TIFFReassignTagToIgnore(TIS_EXTRACT, dp->tdir_tag) )
219 dp->tdir_tag = IGNORE;
220
221 if (dp->tdir_tag == IGNORE)
222 continue;
223
224 /*
225 * Silicon Beach (at least) writes unordered
226 * directory tags (violating the spec). Handle
227 * it here, but be obnoxious (maybe they'll fix it?).
228 */
229 if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) {
230 if (!diroutoforderwarning) {
231 TIFFWarning(tif->tif_name,
232 "invalid TIFF directory; tags are not sorted in ascending order");
233 diroutoforderwarning = 1;
234 }
235 fix = 0; /* O(n^2) */
236 }
237 while (fix < tif->tif_nfields &&
238 tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
239 fix++;
240 if (fix == tif->tif_nfields ||
241 tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
242 TIFFWarning(tif->tif_name,
243 "unknown field with tag %d (0x%x) ignored",
244 dp->tdir_tag, dp->tdir_tag);
245 dp->tdir_tag = IGNORE;
246 fix = 0; /* restart search */
247 continue;
248 }
249 /*
250 * Null out old tags that we ignore.
251 */
252 if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {
253 ignore:
254 dp->tdir_tag = IGNORE;
255 continue;
256 }
257 /*
258 * Check data type.
259 */
260 fip = tif->tif_fieldinfo[fix];
261 while (dp->tdir_type != (u_short) fip->field_type) {
262 if (fip->field_type == TIFF_ANY) /* wildcard */
263 break;
264 fip++, fix++;
265 if (fix == tif->tif_nfields ||
266 fip->field_tag != dp->tdir_tag) {
267 TIFFWarning(tif->tif_name,
268 "wrong data type %d for \"%s\"; tag ignored",
269 dp->tdir_type, fip[-1].field_name);
270 goto ignore;
271 }
272 }
273 /*
274 * Check count if known in advance.
275 */
276 if (fip->field_readcount != TIFF_VARIABLE) {
277 uint32 expected = (fip->field_readcount == TIFF_SPP) ?
278 (uint32) td->td_samplesperpixel :
279 (uint32) fip->field_readcount;
280 if (!CheckDirCount(tif, dp, expected))
281 goto ignore;
282 }
283
284 switch (dp->tdir_tag) {
285 case TIFFTAG_COMPRESSION:
286 /*
287 * The 5.0 spec says the Compression tag has
288 * one value, while earlier specs say it has
289 * one value per sample. Because of this, we
290 * accept the tag if one value is supplied.
291 */
292 if (dp->tdir_count == 1) {
293 v = TIFFExtractData(tif,
294 dp->tdir_type, dp->tdir_offset);
295 if (!TIFFSetField(tif, dp->tdir_tag, (int)v))
296 goto bad;
297 break;
298 }
299 if (!TIFFFetchPerSampleShorts(tif, dp, &iv) ||
300 !TIFFSetField(tif, dp->tdir_tag, iv))
301 goto bad;
302 dp->tdir_tag = IGNORE;
303 break;
304 case TIFFTAG_STRIPOFFSETS:
305 case TIFFTAG_STRIPBYTECOUNTS:
306 case TIFFTAG_TILEOFFSETS:
307 case TIFFTAG_TILEBYTECOUNTS:
308 TIFFSetFieldBit(tif, fip->field_bit);
309 break;
310 case TIFFTAG_IMAGEWIDTH:
311 case TIFFTAG_IMAGELENGTH:
312 case TIFFTAG_IMAGEDEPTH:
313 case TIFFTAG_TILELENGTH:
314 case TIFFTAG_TILEWIDTH:
315 case TIFFTAG_TILEDEPTH:
316 case TIFFTAG_PLANARCONFIG:
317 case TIFFTAG_ROWSPERSTRIP:
318 if (!TIFFFetchNormalTag(tif, dp))
319 goto bad;
320 dp->tdir_tag = IGNORE;
321 break;
322 case TIFFTAG_EXTRASAMPLES:
323 (void) TIFFFetchExtraSamples(tif, dp);
324 dp->tdir_tag = IGNORE;
325 break;
326 }
327 }
328
329 /*
330 * Allocate directory structure and setup defaults.
331 */
332 if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
333 MissingRequired(tif, "ImageLength");
334 goto bad;
335 }
336 if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
337 MissingRequired(tif, "PlanarConfiguration");
338 goto bad;
339 }
340 /*
341 * Setup appropriate structures (by strip or by tile)
342 */
343 if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
344 td->td_nstrips = TIFFNumberOfStrips(tif);
345 td->td_tilewidth = td->td_imagewidth;
346 td->td_tilelength = td->td_rowsperstrip;
347 td->td_tiledepth = td->td_imagedepth;
348 tif->tif_flags &= ~TIFF_ISTILED;
349 } else {
350 td->td_nstrips = TIFFNumberOfTiles(tif);
351 tif->tif_flags |= TIFF_ISTILED;
352 }
353 td->td_stripsperimage = td->td_nstrips;
354 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
355 td->td_stripsperimage /= td->td_samplesperpixel;
356 if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
357 MissingRequired(tif,
358 isTiled(tif) ? "TileOffsets" : "StripOffsets");
359 goto bad;
360 }
361
362 /*
363 * Second pass: extract other information.
364 */
365 for (dp = dir, n = dircount; n > 0; n--, dp++) {
366 if (dp->tdir_tag == IGNORE)
367 continue;
368 switch (dp->tdir_tag) {
369 case TIFFTAG_MINSAMPLEVALUE:
370 case TIFFTAG_MAXSAMPLEVALUE:
371 case TIFFTAG_BITSPERSAMPLE:
372 /*
373 * The 5.0 spec says the Compression tag has
374 * one value, while earlier specs say it has
375 * one value per sample. Because of this, we
376 * accept the tag if one value is supplied.
377 *
378 * The MinSampleValue, MaxSampleValue and
379 * BitsPerSample tags are supposed to be written
380 * as one value/sample, but some vendors incorrectly
381 * write one value only -- so we accept that
382 * as well (yech).
383 */
384 if (dp->tdir_count == 1) {
385 v = TIFFExtractData(tif,
386 dp->tdir_type, dp->tdir_offset);
387 if (!TIFFSetField(tif, dp->tdir_tag, (int)v))
388 goto bad;
389 break;
390 }
391 /* fall thru... */
392 case TIFFTAG_DATATYPE:
393 case TIFFTAG_SAMPLEFORMAT:
394 if (!TIFFFetchPerSampleShorts(tif, dp, &iv) ||
395 !TIFFSetField(tif, dp->tdir_tag, iv))
396 goto bad;
397 break;
398 case TIFFTAG_SMINSAMPLEVALUE:
399 case TIFFTAG_SMAXSAMPLEVALUE:
400 if (!TIFFFetchPerSampleAnys(tif, dp, &dv) ||
401 !TIFFSetField(tif, dp->tdir_tag, dv))
402 goto bad;
403 break;
404 case TIFFTAG_STRIPOFFSETS:
405 case TIFFTAG_TILEOFFSETS:
406 if (!TIFFFetchStripThing(tif, dp,
407 td->td_nstrips, &td->td_stripoffset))
408 goto bad;
409 break;
410 case TIFFTAG_STRIPBYTECOUNTS:
411 case TIFFTAG_TILEBYTECOUNTS:
412 if (!TIFFFetchStripThing(tif, dp,
413 td->td_nstrips, &td->td_stripbytecount))
414 goto bad;
415 break;
416 case TIFFTAG_COLORMAP:
417 case TIFFTAG_TRANSFERFUNCTION:
418 /*
419 * TransferFunction can have either 1x or 3x data
420 * values; Colormap can have only 3x items.
421 */
422 v = 1L<<td->td_bitspersample;
423 if (dp->tdir_tag == TIFFTAG_COLORMAP ||
424 dp->tdir_count != (uint32) v) {
425 if (!CheckDirCount(tif, dp, (uint32)(3*v)))
426 break;
427 }
428 v *= sizeof (uint16);
429 cp = CheckMalloc(tif, dp->tdir_count * sizeof (uint16),
430 "to read \"TransferFunction\" tag");
431 if (cp != NULL) {
432 if (TIFFFetchData(tif, dp, cp)) {
433 /*
434 * This deals with there being only
435 * one array to apply to all samples.
436 */
437 uint32 c =
438 (uint32)1 << td->td_bitspersample;
439 if (dp->tdir_count == c)
440 v = 0;
441 TIFFSetField(tif, dp->tdir_tag,
442 cp, cp+v, cp+2*v);
443 }
444 _TIFFfree(cp);
445 }
446 break;
447 case TIFFTAG_PAGENUMBER:
448 case TIFFTAG_HALFTONEHINTS:
449 case TIFFTAG_YCBCRSUBSAMPLING:
450 case TIFFTAG_DOTRANGE:
451 (void) TIFFFetchShortPair(tif, dp);
452 break;
453#ifdef COLORIMETRY_SUPPORT
454 case TIFFTAG_REFERENCEBLACKWHITE:
455 (void) TIFFFetchRefBlackWhite(tif, dp);
456 break;
457#endif
458/* BEGIN REV 4.0 COMPATIBILITY */
459 case TIFFTAG_OSUBFILETYPE:
460 v = 0;
461 switch (TIFFExtractData(tif, dp->tdir_type,
462 dp->tdir_offset)) {
463 case OFILETYPE_REDUCEDIMAGE:
464 v = FILETYPE_REDUCEDIMAGE;
465 break;
466 case OFILETYPE_PAGE:
467 v = FILETYPE_PAGE;
468 break;
469 }
470 if (v)
471 (void) TIFFSetField(tif,
472 TIFFTAG_SUBFILETYPE, (int)v);
473 break;
474/* END REV 4.0 COMPATIBILITY */
475 default:
476 (void) TIFFFetchNormalTag(tif, dp);
477 break;
478 }
479 }
480 /*
481 * Verify Palette image has a Colormap.
482 */
483 if (td->td_photometric == PHOTOMETRIC_PALETTE &&
484 !TIFFFieldSet(tif, FIELD_COLORMAP)) {
485 MissingRequired(tif, "Colormap");
486 goto bad;
487 }
488 /*
489 * Attempt to deal with a missing StripByteCounts tag.
490 */
491 if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
492 /*
493 * Some manufacturers violate the spec by not giving
494 * the size of the strips. In this case, assume there
495 * is one uncompressed strip of data.
496 */
497 if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
498 td->td_nstrips > 1) ||
499 (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
500 td->td_nstrips != td->td_samplesperpixel)) {
501 MissingRequired(tif, "StripByteCounts");
502 goto bad;
503 }
504 TIFFWarning(tif->tif_name,
505"TIFF directory is missing required \"%s\" field, calculating from imagelength",
506 _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
507 EstimateStripByteCounts(tif, dir, dircount);
508#define BYTECOUNTLOOKSBAD \
509 (td->td_stripbytecount[0] == 0 || \
510 (td->td_compression == COMPRESSION_NONE && \
511 td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0]))
512 } else if (td->td_nstrips == 1 && BYTECOUNTLOOKSBAD) {
513 /*
514 * Plexus (and others) sometimes give a value
515 * of zero for a tag when they don't know what
516 * the correct value is! Try and handle the
517 * simple case of estimating the size of a one
518 * strip image.
519 */
520 TIFFWarning(tif->tif_name,
521 "Bogus \"%s\" field, ignoring and calculating from imagelength",
522 _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
523 EstimateStripByteCounts(tif, dir, dircount);
524 }
525 if (dir)
526 _TIFFfree((char *)dir);
527 if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
528 td->td_maxsamplevalue = (uint16)((1L<<td->td_bitspersample)-1);
529 /*
530 * Setup default compression scheme.
531 */
532 if (!TIFFFieldSet(tif, FIELD_COMPRESSION))
533 TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
534 /*
535 * Some manufacturers make life difficult by writing
536 * large amounts of uncompressed data as a single strip.
537 * This is contrary to the recommendations of the spec.
538 * The following makes an attempt at breaking such images
539 * into strips closer to the recommended 8k bytes. A
540 * side effect, however, is that the RowsPerStrip tag
541 * value may be changed.
542 */
543 if (td->td_nstrips == 1 && td->td_compression == COMPRESSION_NONE &&
544 (tif->tif_flags & (TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP)
545 ChopUpSingleUncompressedStrip(tif);
546 /*
547 * Reinitialize i/o since we are starting on a new directory.
548 */
549 tif->tif_row = (uint32) -1;
550 tif->tif_curstrip = (tstrip_t) -1;
551 tif->tif_col = (uint32) -1;
552 tif->tif_curtile = (ttile_t) -1;
553 tif->tif_tilesize = TIFFTileSize(tif);
554 tif->tif_scanlinesize = TIFFScanlineSize(tif);
555 return (1);
556bad:
557 if (dir)
558 _TIFFfree(dir);
559 return (0);
560}
561
562static void
563EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
564{
565 register TIFFDirEntry *dp;
566 register TIFFDirectory *td = &tif->tif_dir;
567 uint16 i;
568
569 if (td->td_stripbytecount)
570 _TIFFfree(td->td_stripbytecount);
571 td->td_stripbytecount = (uint32*)
572 CheckMalloc(tif, td->td_nstrips * sizeof (uint32),
573 "for \"StripByteCounts\" array");
574 if (td->td_compression != COMPRESSION_NONE) {
575 uint32 space = (uint32)(sizeof (TIFFHeader)
576 + sizeof (uint16)
577 + (dircount * sizeof (TIFFDirEntry))
578 + sizeof (uint32));
579 toff_t filesize = TIFFGetFileSize(tif);
580 uint16 n;
581
582 /* calculate amount of space used by indirect values */
583 for (dp = dir, n = dircount; n > 0; n--, dp++) {
584 uint32 cc = dp->tdir_count*tiffDataWidth[dp->tdir_type];
585 if (cc > sizeof (uint32))
586 space += cc;
587 }
588 space = filesize - space;
589 if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
590 space /= td->td_samplesperpixel;
591 for (i = 0; i < td->td_nstrips; i++)
592 td->td_stripbytecount[i] = space;
593 /*
594 * This gross hack handles the case were the offset to
595 * the last strip is past the place where we think the strip
596 * should begin. Since a strip of data must be contiguous,
597 * it's safe to assume that we've overestimated the amount
598 * of data in the strip and trim this number back accordingly.
599 */
600 i--;
601 if (td->td_stripoffset[i] + td->td_stripbytecount[i] > filesize)
602 td->td_stripbytecount[i] =
603 filesize - td->td_stripoffset[i];
604 } else {
605 uint32 rowbytes = TIFFScanlineSize(tif);
606 uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
607 for (i = 0; i < td->td_nstrips; i++)
608 td->td_stripbytecount[i] = rowbytes*rowsperstrip;
609 }
610 TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
611 if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
612 td->td_rowsperstrip = td->td_imagelength;
613}
614
615static void
616MissingRequired(TIFF* tif, const char* tagname)
617{
618 TIFFError(tif->tif_name,
619 "TIFF directory is missing required \"%s\" field", tagname);
620}
621
622/*
623 * Check the count field of a directory
624 * entry against a known value. The caller
625 * is expected to skip/ignore the tag if
626 * there is a mismatch.
627 */
628static int
629CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
630{
631 if (count != dir->tdir_count) {
632 TIFFWarning(tif->tif_name,
633 "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",
634 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
635 dir->tdir_count, count);
636 return (0);
637 }
638 return (1);
639}
640
641/*
642 * Fetch a contiguous directory item.
643 */
644static tsize_t
645TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp)
646{
647 int w = tiffDataWidth[dir->tdir_type];
648 tsize_t cc = dir->tdir_count * w;
649
650 if (!isMapped(tif)) {
651 if (!SeekOK(tif, dir->tdir_offset))
652 goto bad;
653 if (!ReadOK(tif, cp, cc))
654 goto bad;
655 } else {
656 if (dir->tdir_offset + cc > tif->tif_size)
657 goto bad;
658 _TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc);
659 }
660 if (tif->tif_flags & TIFF_SWAB) {
661 switch (dir->tdir_type) {
662 case TIFF_SHORT:
663 case TIFF_SSHORT:
664 TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
665 break;
666 case TIFF_LONG:
667 case TIFF_SLONG:
668 case TIFF_FLOAT:
669 TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
670 break;
671 case TIFF_RATIONAL:
672 case TIFF_SRATIONAL:
673 TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
674 break;
675 case TIFF_DOUBLE:
676 TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
677 break;
678 }
679 }
680 return (cc);
681bad:
682 TIFFError(tif->tif_name, "Error fetching data for field \"%s\"",
683 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
684 return ((tsize_t) 0);
685}
686
687/*
688 * Fetch an ASCII item from the file.
689 */
690static tsize_t
691TIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp)
692{
693 if (dir->tdir_count <= 4) {
694 uint32 l = dir->tdir_offset;
695 if (tif->tif_flags & TIFF_SWAB)
696 TIFFSwabLong(&l);
697 _TIFFmemcpy(cp, &l, dir->tdir_count);
698 return (1);
699 }
700 return (TIFFFetchData(tif, dir, cp));
701}
702
703/*
704 * Convert numerator+denominator to float.
705 */
706static int
707cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv)
708{
709 if (denom == 0) {
710 TIFFError(tif->tif_name,
711 "%s: Rational with zero denominator (num = %lu)",
712 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num);
713 return (0);
714 } else {
715 if (dir->tdir_type == TIFF_RATIONAL)
716 *rv = ((float)num / (float)denom);
717 else
718 *rv = ((float)(int32)num / (float)(int32)denom);
719 return (1);
720 }
721}
722
723/*
724 * Fetch a rational item from the file
725 * at offset off and return the value
726 * as a floating point number.
727 */
728static float
729TIFFFetchRational(TIFF* tif, TIFFDirEntry* dir)
730{
731 uint32 l[2];
732 float v;
733
734 return (!TIFFFetchData(tif, dir, (char *)l) ||
735 !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v);
736}
737
738/*
739 * Fetch a single floating point value
740 * from the offset field and return it
741 * as a native float.
742 */
743static float
744TIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir)
745{
746 long l = TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset);
747 float v = *(float*) &l;
748 TIFFCvtIEEEFloatToNative(tif, 1, &v);
749 return (v);
750}
751
752/*
753 * Fetch an array of BYTE or SBYTE values.
754 */
755static int
756TIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
757{
758 if (dir->tdir_count <= 4) {
759 /*
760 * Extract data from offset field.
761 */
762 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
763 switch (dir->tdir_count) {
764 case 4: v[3] = dir->tdir_offset & 0xff;
765 case 3: v[2] = (dir->tdir_offset >> 8) & 0xff;
766 case 2: v[1] = (dir->tdir_offset >> 16) & 0xff;
767 case 1: v[0] = dir->tdir_offset >> 24;
768 }
769 } else {
770 switch (dir->tdir_count) {
771 case 4: v[3] = dir->tdir_offset >> 24;
772 case 3: v[2] = (dir->tdir_offset >> 16) & 0xff;
773 case 2: v[1] = (dir->tdir_offset >> 8) & 0xff;
774 case 1: v[0] = dir->tdir_offset & 0xff;
775 }
776 }
777 return (1);
778 } else
779 return (TIFFFetchData(tif, dir, (char*) v) != 0); /* XXX */
780}
781
782/*
783 * Fetch an array of SHORT or SSHORT values.
784 */
785static int
786TIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
787{
788 if (dir->tdir_count <= 2) {
789 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
790 switch (dir->tdir_count) {
791 case 2: v[1] = dir->tdir_offset & 0xffff;
792 case 1: v[0] = dir->tdir_offset >> 16;
793 }
794 } else {
795 switch (dir->tdir_count) {
796 case 2: v[1] = dir->tdir_offset >> 16;
797 case 1: v[0] = dir->tdir_offset & 0xffff;
798 }
799 }
800 return (1);
801 } else
802 return (TIFFFetchData(tif, dir, (char *)v) != 0);
803}
804
805/*
806 * Fetch a pair of SHORT or BYTE values.
807 */
808static int
809TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir)
810{
811 uint16 v[2];
812 int ok = 0;
813
814 switch (dir->tdir_type) {
815 case TIFF_SHORT:
816 case TIFF_SSHORT:
817 ok = TIFFFetchShortArray(tif, dir, v);
818 break;
819 case TIFF_BYTE:
820 case TIFF_SBYTE:
821 ok = TIFFFetchByteArray(tif, dir, v);
822 break;
823 }
824 if (ok)
825 TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
826 return (ok);
827}
828
829/*
830 * Fetch an array of LONG or SLONG values.
831 */
832static int
833TIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
834{
835 if (dir->tdir_count == 1) {
836 v[0] = dir->tdir_offset;
837 return (1);
838 } else
839 return (TIFFFetchData(tif, dir, (char*) v) != 0);
840}
841
842/*
843 * Fetch an array of RATIONAL or SRATIONAL values.
844 */
845static int
846TIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
847{
848 int ok = 0;
849 uint32* l;
850
851 l = (uint32*)CheckMalloc(tif,
852 dir->tdir_count*tiffDataWidth[dir->tdir_type],
853 "to fetch array of rationals");
854 if (l) {
855 if (TIFFFetchData(tif, dir, (char *)l)) {
856 uint32 i;
857 for (i = 0; i < dir->tdir_count; i++) {
858 ok = cvtRational(tif, dir,
859 l[2*i+0], l[2*i+1], &v[i]);
860 if (!ok)
861 break;
862 }
863 }
864 _TIFFfree((char *)l);
865 }
866 return (ok);
867}
868
869/*
870 * Fetch an array of FLOAT values.
871 */
872static int
873TIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
874{
875
876 if (dir->tdir_count == 1) {
877 v[0] = *(float*) &dir->tdir_offset;
878 TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
879 return (1);
880 } else if (TIFFFetchData(tif, dir, (char*) v)) {
881 TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
882 return (1);
883 } else
884 return (0);
885}
886
887/*
888 * Fetch an array of DOUBLE values.
889 */
890static int
891TIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
892{
893 if (TIFFFetchData(tif, dir, (char*) v)) {
894 TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v);
895 return (1);
896 } else
897 return (0);
898}
899
900/*
901 * Fetch an array of ANY values. The actual values are
902 * returned as doubles which should be able hold all the
903 * types. Yes, there really should be an tany_t to avoid
904 * this potential non-portability ... Note in particular
905 * that we assume that the double return value vector is
906 * large enough to read in any fundamental type. We use
907 * that vector as a buffer to read in the base type vector
908 * and then convert it in place to double (from end
909 * to front of course).
910 */
911static int
912TIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v)
913{
914 int i;
915
916 switch (dir->tdir_type) {
917 case TIFF_BYTE:
918 case TIFF_SBYTE:
919 if (!TIFFFetchByteArray(tif, dir, (uint16*) v))
920 return (0);
921 if (dir->tdir_type == TIFF_BYTE) {
922 uint16* vp = (uint16*) v;
923 for (i = dir->tdir_count-1; i >= 0; i--)
924 v[i] = vp[i];
925 } else {
926 int16* vp = (int16*) v;
927 for (i = dir->tdir_count-1; i >= 0; i--)
928 v[i] = vp[i];
929 }
930 break;
931 case TIFF_SHORT:
932 case TIFF_SSHORT:
933 if (!TIFFFetchShortArray(tif, dir, (uint16*) v))
934 return (0);
935 if (dir->tdir_type == TIFF_SHORT) {
936 uint16* vp = (uint16*) v;
937 for (i = dir->tdir_count-1; i >= 0; i--)
938 v[i] = vp[i];
939 } else {
940 int16* vp = (int16*) v;
941 for (i = dir->tdir_count-1; i >= 0; i--)
942 v[i] = vp[i];
943 }
944 break;
945 case TIFF_LONG:
946 case TIFF_SLONG:
947 if (!TIFFFetchLongArray(tif, dir, (uint32*) v))
948 return (0);
949 if (dir->tdir_type == TIFF_LONG) {
950 uint32* vp = (uint32*) v;
951 for (i = dir->tdir_count-1; i >= 0; i--)
952 v[i] = vp[i];
953 } else {
954 int32* vp = (int32*) v;
955 for (i = dir->tdir_count-1; i >= 0; i--)
956 v[i] = vp[i];
957 }
958 break;
959 case TIFF_RATIONAL:
960 case TIFF_SRATIONAL:
961 if (!TIFFFetchRationalArray(tif, dir, (float*) v))
962 return (0);
963 { float* vp = (float*) v;
964 for (i = dir->tdir_count-1; i >= 0; i--)
965 v[i] = vp[i];
966 }
967 break;
968 case TIFF_FLOAT:
969 if (!TIFFFetchFloatArray(tif, dir, (float*) v))
970 return (0);
971 { float* vp = (float*) v;
972 for (i = dir->tdir_count-1; i >= 0; i--)
973 v[i] = vp[i];
974 }
975 break;
976 case TIFF_DOUBLE:
977 return (TIFFFetchDoubleArray(tif, dir, (double*) v));
978 default:
979 /* TIFF_NOTYPE */
980 /* TIFF_ASCII */
981 /* TIFF_UNDEFINED */
982 TIFFError(tif->tif_name,
983 "Cannot read TIFF_ANY type %d for field \"%s\"",
984 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
985 return (0);
986 }
987 return (1);
988}
989
990/*
991 * Fetch a tag that is not handled by special case code.
992 */
993static int
994TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp)
995{
996 static const char mesg[] = "to fetch tag value";
997 int ok = 0;
998 const TIFFFieldInfo* fip = _TIFFFieldWithTag(tif, dp->tdir_tag);
999
1000 if (dp->tdir_count > 1) { /* array of values */
1001 char* cp = NULL;
1002
1003 switch (dp->tdir_type) {
1004 case TIFF_BYTE:
1005 case TIFF_SBYTE:
1006 /* NB: always expand BYTE values to shorts */
1007 cp = CheckMalloc(tif,
1008 dp->tdir_count * sizeof (uint16), mesg);
1009 ok = cp && TIFFFetchByteArray(tif, dp, (uint16*) cp);
1010 break;
1011 case TIFF_SHORT:
1012 case TIFF_SSHORT:
1013 cp = CheckMalloc(tif,
1014 dp->tdir_count * sizeof (uint16), mesg);
1015 ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp);
1016 break;
1017 case TIFF_LONG:
1018 case TIFF_SLONG:
1019 cp = CheckMalloc(tif,
1020 dp->tdir_count * sizeof (uint32), mesg);
1021 ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp);
1022 break;
1023 case TIFF_RATIONAL:
1024 case TIFF_SRATIONAL:
1025 cp = CheckMalloc(tif,
1026 dp->tdir_count * sizeof (float), mesg);
1027 ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp);
1028 break;
1029 case TIFF_FLOAT:
1030 cp = CheckMalloc(tif,
1031 dp->tdir_count * sizeof (float), mesg);
1032 ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp);
1033 break;
1034 case TIFF_DOUBLE:
1035 cp = CheckMalloc(tif,
1036 dp->tdir_count * sizeof (double), mesg);
1037 ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp);
1038 break;
1039 case TIFF_ASCII:
1040 case TIFF_UNDEFINED: /* bit of a cheat... */
1041 /*
1042 * Some vendors write strings w/o the trailing
1043 * NULL byte, so always append one just in case.
1044 */
1045 cp = CheckMalloc(tif, dp->tdir_count+1, mesg);
1046 if( (ok = (cp && TIFFFetchString(tif, dp, cp))) != 0 )
1047 cp[dp->tdir_count] = '\0'; /* XXX */
1048 break;
1049 }
1050 if (ok) {
1051 ok = (fip->field_passcount ?
1052 TIFFSetField(tif, dp->tdir_tag, dp->tdir_count, cp)
1053 : TIFFSetField(tif, dp->tdir_tag, cp));
1054 }
1055 if (cp != NULL)
1056 _TIFFfree(cp);
1057 } else if (CheckDirCount(tif, dp, 1)) { /* singleton value */
1058 switch (dp->tdir_type) {
1059 case TIFF_BYTE:
1060 case TIFF_SBYTE:
1061 case TIFF_SHORT:
1062 case TIFF_SSHORT:
1063 /*
1064 * If the tag is also acceptable as a LONG or SLONG
1065 * then TIFFSetField will expect an uint32 parameter
1066 * passed to it (through varargs). Thus, for machines
1067 * where sizeof (int) != sizeof (uint32) we must do
1068 * a careful check here. It's hard to say if this
1069 * is worth optimizing.
1070 *
1071 * NB: We use TIFFFieldWithTag here knowing that
1072 * it returns us the first entry in the table
1073 * for the tag and that that entry is for the
1074 * widest potential data type the tag may have.
1075 */
1076 { TIFFDataType type = fip->field_type;
1077 if (type != TIFF_LONG && type != TIFF_SLONG) {
1078 uint16 v = (uint16)
1079 TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
1080 ok = (fip->field_passcount ?
1081 TIFFSetField(tif, dp->tdir_tag, 1, &v)
1082 : TIFFSetField(tif, dp->tdir_tag, v));
1083 break;
1084 }
1085 }
1086 /* fall thru... */
1087 case TIFF_LONG:
1088 case TIFF_SLONG:
1089 { uint32 v32 =
1090 TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
1091 ok = (fip->field_passcount ?
1092 TIFFSetField(tif, dp->tdir_tag, 1, &v32)
1093 : TIFFSetField(tif, dp->tdir_tag, v32));
1094 }
1095 break;
1096 case TIFF_RATIONAL:
1097 case TIFF_SRATIONAL:
1098 case TIFF_FLOAT:
1099 { float v = (dp->tdir_type == TIFF_FLOAT ?
1100 TIFFFetchFloat(tif, dp)
1101 : TIFFFetchRational(tif, dp));
1102 ok = (fip->field_passcount ?
1103 TIFFSetField(tif, dp->tdir_tag, 1, &v)
1104 : TIFFSetField(tif, dp->tdir_tag, v));
1105 }
1106 break;
1107 case TIFF_DOUBLE:
1108 { double v;
1109 ok = (TIFFFetchDoubleArray(tif, dp, &v) &&
1110 (fip->field_passcount ?
1111 TIFFSetField(tif, dp->tdir_tag, 1, &v)
1112 : TIFFSetField(tif, dp->tdir_tag, v))
1113 );
1114 }
1115 break;
1116 case TIFF_ASCII:
1117 case TIFF_UNDEFINED: /* bit of a cheat... */
1118 { char c[2];
1119 if( (ok = (TIFFFetchString(tif, dp, c) != 0)) != 0 ){
1120 c[1] = '\0'; /* XXX paranoid */
1121 ok = TIFFSetField(tif, dp->tdir_tag, c);
1122 }
1123 }
1124 break;
1125 }
1126 }
1127 return (ok);
1128}
1129
1130#define NITEMS(x) (sizeof (x) / sizeof (x[0]))
1131/*
1132 * Fetch samples/pixel short values for
1133 * the specified tag and verify that
1134 * all values are the same.
1135 */
1136static int
1137TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, int* pl)
1138{
1139 int samples = tif->tif_dir.td_samplesperpixel;
1140 int status = 0;
1141
1142 if (CheckDirCount(tif, dir, (uint32) samples)) {
1143 uint16 buf[10];
1144 uint16* v = buf;
1145
1146 if (samples > NITEMS(buf))
1147 v = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
1148 if (TIFFFetchShortArray(tif, dir, v)) {
1149 int i;
1150 for (i = 1; i < samples; i++)
1151 if (v[i] != v[0]) {
1152 TIFFError(tif->tif_name,
1153 "Cannot handle different per-sample values for field \"%s\"",
1154 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1155 goto bad;
1156 }
1157 *pl = v[0];
1158 status = 1;
1159 }
1160 bad:
1161 if (v != buf)
1162 _TIFFfree((char*) v);
1163 }
1164 return (status);
1165}
1166
1167/*
1168 * Fetch samples/pixel ANY values for
1169 * the specified tag and verify that
1170 * all values are the same.
1171 */
1172static int
1173TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl)
1174{
1175 int samples = (int) tif->tif_dir.td_samplesperpixel;
1176 int status = 0;
1177
1178 if (CheckDirCount(tif, dir, (uint32) samples)) {
1179 double buf[10];
1180 double* v = buf;
1181
1182 if (samples > NITEMS(buf))
1183 v = (double*) _TIFFmalloc(samples * sizeof (double));
1184 if (TIFFFetchAnyArray(tif, dir, v)) {
1185 int i;
1186 for (i = 1; i < samples; i++)
1187 if (v[i] != v[0]) {
1188 TIFFError(tif->tif_name,
1189 "Cannot handle different per-sample values for field \"%s\"",
1190 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
1191 goto bad;
1192 }
1193 *pl = v[0];
1194 status = 1;
1195 }
1196 bad:
1197 if (v != buf)
1198 _TIFFfree(v);
1199 }
1200 return (status);
1201}
1202#undef NITEMS
1203
1204/*
1205 * Fetch a set of offsets or lengths.
1206 * While this routine says "strips",
1207 * in fact it's also used for tiles.
1208 */
1209static int
1210TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, long nstrips, uint32** lpp)
1211{
1212 register uint32* lp;
1213 int status;
1214
1215 if (!CheckDirCount(tif, dir, (uint32) nstrips))
1216 return (0);
1217 /*
1218 * Allocate space for strip information.
1219 */
1220 if (*lpp == NULL &&
1221 (*lpp = (uint32 *)CheckMalloc(tif,
1222 nstrips * sizeof (uint32), "for strip array")) == NULL)
1223 return (0);
1224 lp = *lpp;
1225 if (dir->tdir_type == (int)TIFF_SHORT) {
1226 /*
1227 * Handle uint16->uint32 expansion.
1228 */
1229 uint16* dp = (uint16*) CheckMalloc(tif,
1230 dir->tdir_count* sizeof (uint16), "to fetch strip tag");
1231 if (dp == NULL)
1232 return (0);
1233 if( (status = TIFFFetchShortArray(tif, dir, dp)) != 0 ) {
1234 register uint16* wp = dp;
1235 while (nstrips-- > 0)
1236 *lp++ = *wp++;
1237 }
1238 _TIFFfree((char*) dp);
1239 } else
1240 status = TIFFFetchLongArray(tif, dir, lp);
1241 return (status);
1242}
1243
1244#define NITEMS(x) (sizeof (x) / sizeof (x[0]))
1245/*
1246 * Fetch and set the ExtraSamples tag.
1247 */
1248static int
1249TIFFFetchExtraSamples(TIFF* tif, TIFFDirEntry* dir)
1250{
1251 uint16 buf[10];
1252 uint16* v = buf;
1253 int status;
1254
1255 if (dir->tdir_count > NITEMS(buf))
1256 v = (uint16*) _TIFFmalloc(dir->tdir_count * sizeof (uint16));
1257 if (dir->tdir_type == TIFF_BYTE)
1258 status = TIFFFetchByteArray(tif, dir, v);
1259 else
1260 status = TIFFFetchShortArray(tif, dir, v);
1261 if (status)
1262 status = TIFFSetField(tif, dir->tdir_tag, dir->tdir_count, v);
1263 if (v != buf)
1264 _TIFFfree((char*) v);
1265 return (status);
1266}
1267#undef NITEMS
1268
1269#ifdef COLORIMETRY_SUPPORT
1270/*
1271 * Fetch and set the RefBlackWhite tag.
1272 */
1273static int
1274TIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir)
1275{
1276 static const char mesg[] = "for \"ReferenceBlackWhite\" array";
1277 char* cp;
1278 int ok;
1279
1280 if (dir->tdir_type == TIFF_RATIONAL)
1281 return (TIFFFetchNormalTag(tif, dir));
1282 /*
1283 * Handle LONG's for backward compatibility.
1284 */
1285 cp = CheckMalloc(tif, dir->tdir_count * sizeof (uint32), mesg);
1286 if( (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) != 0) {
1287 float* fp = (float*)
1288 CheckMalloc(tif, dir->tdir_count * sizeof (float), mesg);
1289 if( (ok = (fp != NULL)) != 0 ) {
1290 uint32 i;
1291 for (i = 0; i < dir->tdir_count; i++)
1292 fp[i] = (float)((uint32*) cp)[i];
1293 ok = TIFFSetField(tif, dir->tdir_tag, fp);
1294 _TIFFfree((char*) fp);
1295 }
1296 }
1297 if (cp)
1298 _TIFFfree(cp);
1299 return (ok);
1300}
1301#endif
1302
1303/*
1304 * Replace a single strip (tile) of uncompressed data by
1305 * multiple strips (tiles), each approximately 8Kbytes.
1306 * This is useful for dealing with large images or
1307 * for dealing with machines with a limited amount
1308 * memory.
1309 */
1310static void
1311ChopUpSingleUncompressedStrip(TIFF* tif)
1312{
1313 register TIFFDirectory *td = &tif->tif_dir;
1314 uint32 bytecount = td->td_stripbytecount[0];
1315 uint32 offset = td->td_stripoffset[0];
1316 tsize_t rowbytes = TIFFVTileSize(tif, 1), stripbytes;
1317 tstrip_t strip, nstrips, rowsperstrip;
1318 uint32* newcounts;
1319 uint32* newoffsets;
1320
1321 /*
1322 * Make the rows hold at least one
1323 * scanline, but fill 8k if possible.
1324 */
1325 if (rowbytes > 8192) {
1326 stripbytes = rowbytes;
1327 rowsperstrip = 1;
1328 } else {
1329 rowsperstrip = 8192 / rowbytes;
1330 stripbytes = rowbytes * rowsperstrip;
1331 }
1332 /* never increase the number of strips in an image */
1333 if (rowsperstrip >= td->td_rowsperstrip)
1334 return;
1335 nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes);
1336 newcounts = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32),
1337 "for chopped \"StripByteCounts\" array");
1338 newoffsets = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32),
1339 "for chopped \"StripOffsets\" array");
1340 if (newcounts == NULL || newoffsets == NULL) {
1341 /*
1342 * Unable to allocate new strip information, give
1343 * up and use the original one strip information.
1344 */
1345 if (newcounts != NULL)
1346 _TIFFfree(newcounts);
1347 if (newoffsets != NULL)
1348 _TIFFfree(newoffsets);
1349 return;
1350 }
1351 /*
1352 * Fill the strip information arrays with
1353 * new bytecounts and offsets that reflect
1354 * the broken-up format.
1355 */
1356 for (strip = 0; strip < nstrips; strip++) {
1357 if (stripbytes > bytecount)
1358 stripbytes = bytecount;
1359 newcounts[strip] = stripbytes;
1360 newoffsets[strip] = offset;
1361 offset += stripbytes;
1362 bytecount -= stripbytes;
1363 }
1364 /*
1365 * Replace old single strip info with multi-strip info.
1366 */
1367 td->td_stripsperimage = td->td_nstrips = nstrips;
1368 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
1369
1370 _TIFFfree(td->td_stripbytecount);
1371 _TIFFfree(td->td_stripoffset);
1372 td->td_stripbytecount = newcounts;
1373 td->td_stripoffset = newoffsets;
1374}