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