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