]> git.saurik.com Git - wxWidgets.git/blame - src/tiff/contrib/pds/tif_pdsdirread.c
Fix --enable-webview_xxx options names in configure.
[wxWidgets.git] / src / tiff / contrib / pds / tif_pdsdirread.c
CommitLineData
8414a40c
VZ
1/* $Header: /cvs/maptools/cvsroot/libtiff/contrib/pds/tif_pdsdirread.c,v 1.3 2005/12/21 12:23:13 joris Exp $ */
2
3/*
4 * Copyright (c) 1988-1996 Sam Leffler
5 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
6 * Copyright (c( 1996 USAF Phillips Laboratory
7 *
8 * Permission to use, copy, modify, distribute, and sell this software and
9 * its documentation for any purpose is hereby granted without fee, provided
10 * that (i) the above copyright notices and this permission notice appear in
11 * all copies of the software and related documentation, and (ii) the names of
12 * Sam Leffler and Silicon Graphics may not be used in any advertising or
13 * publicity relating to the software without the specific, prior written
14 * permission of Sam Leffler and Silicon Graphics.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
21 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
22 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
24 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25 * OF THIS SOFTWARE.
26 */
27
28/*
29 * TIFF Library.
30 *
31 * These routines written by Conrad J. Poelman on a single late-night of
32 * March 20-21, 1996.
33 *
34 * The entire purpose of this file is to provide a single external function,
35 * TIFFReadPrivateDataSubDirectory(). This function is intended for use in reading a
36 * private subdirectory from a TIFF file into a private structure. The
37 * actual writing of data into the structure is handled by the setFieldFn(),
38 * which is passed to TIFFReadPrivateDataSubDirectory() as a parameter. The idea is to
39 * enable any application wishing to store private subdirectories to do so
40 * easily using this function, without modifying the TIFF library.
41 *
42 * The astute observer will notice that only two functions are at all different
43 * from the original tif_dirread.c file: TIFFReadPrivateDataSubDirectory() and
44 * TIFFFetchNormalSubTag(). All the other stuff that makes this file so huge
45 * is only necessary because all of those functions are declared static in
46 * tif_dirread.c, so we have to totally duplicate them in order to use them.
47 *
48 * Oh, also note the bug fix in TIFFFetchFloat().
49 *
50 */
51
52#include "tiffiop.h"
53
54#define IGNORE 0 /* tag placeholder used below */
55
56#if HAVE_IEEEFP
57#define TIFFCvtIEEEFloatToNative(tif, n, fp)
58#define TIFFCvtIEEEDoubleToNative(tif, n, dp)
59#else
60extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
61extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
62#endif
63
64static void EstimateStripByteCounts(TIFF*, TIFFDirEntry*, uint16);
65static void MissingRequired(TIFF*, const char*);
66static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
67static tsize_t TIFFFetchData(TIFF*, TIFFDirEntry*, char*);
68static tsize_t TIFFFetchString(TIFF*, TIFFDirEntry*, char*);
69static float TIFFFetchRational(TIFF*, TIFFDirEntry*);
70static int TIFFFetchNormalSubTag(TIFF*, TIFFDirEntry*, const TIFFFieldInfo*,
71 int (*getFieldFn)(TIFF *tif,ttag_t tag,...));
72static int TIFFFetchPerSampleShorts(TIFF*, TIFFDirEntry*, int*);
73static int TIFFFetchPerSampleAnys(TIFF*, TIFFDirEntry*, double*);
74static int TIFFFetchShortArray(TIFF*, TIFFDirEntry*, uint16*);
75static int TIFFFetchStripThing(TIFF*, TIFFDirEntry*, long, uint32**);
76static int TIFFFetchExtraSamples(TIFF*, TIFFDirEntry*);
77static int TIFFFetchRefBlackWhite(TIFF*, TIFFDirEntry*);
78static float TIFFFetchFloat(TIFF*, TIFFDirEntry*);
79static int TIFFFetchFloatArray(TIFF*, TIFFDirEntry*, float*);
80static int TIFFFetchDoubleArray(TIFF*, TIFFDirEntry*, double*);
81static int TIFFFetchAnyArray(TIFF*, TIFFDirEntry*, double*);
82static int TIFFFetchShortPair(TIFF*, TIFFDirEntry*);
83#if STRIPCHOP_SUPPORT
84static void ChopUpSingleUncompressedStrip(TIFF*);
85#endif
86
87static char *
88CheckMalloc(TIFF* tif, tsize_t n, const char* what)
89{
90 char *cp = (char*)_TIFFmalloc(n);
91 if (cp == NULL)
92 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space %s", what);
93 return (cp);
94}
95
96/* Just as was done with TIFFWritePrivateDataSubDirectory(), here we implement
97 TIFFReadPrivateDataSubDirectory() which takes an offset into the TIFF file,
98 a TIFFFieldInfo structure specifying the types of the various tags,
99 and a function to use to set individual tags when they are encountered.
100 The data is read from the file, translated using the TIFF library's
101 built-in machine-independent conversion functions, and filled into
102 private subdirectory structure.
103
104 This code was written by copying the original TIFFReadDirectory() function
105 from tif_dirread.c and paring it down to what is needed for this.
106
107 It is the caller's responsibility to allocate and initialize the internal
108 structure that setFieldFn() will be writing into. If this function is being
109 called more than once before closing the file, the caller also must be
110 careful to free data in the structure before re-initializing.
111
112 It is also the caller's responsibility to verify the presence of
113 any required fields after reading the directory in.
114*/
115
116
117int
118TIFFReadPrivateDataSubDirectory(TIFF* tif, toff_t pdir_offset,
119 TIFFFieldInfo *field_info,
120 int (*setFieldFn)(TIFF *tif, ttag_t tag, ...))
121{
122 register TIFFDirEntry* dp;
123 register int n;
124 register TIFFDirectory* td;
125 TIFFDirEntry* dir;
126 int iv;
127 long v;
128 double dv;
129 const TIFFFieldInfo* fip;
130 int fix;
131 uint16 dircount;
132 uint32 nextdiroff;
133 char* cp;
134 int diroutoforderwarning = 0;
135
136 /* Skipped part about checking for directories or compression data. */
137
138 if (!isMapped(tif)) {
139 if (!SeekOK(tif, pdir_offset)) {
140 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
141 "Seek error accessing TIFF private subdirectory");
142 return (0);
143 }
144 if (!ReadOK(tif, &dircount, sizeof (uint16))) {
145 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
146 "Can not read TIFF private subdirectory count");
147 return (0);
148 }
149 if (tif->tif_flags & TIFF_SWAB)
150 TIFFSwabShort(&dircount);
151 dir = (TIFFDirEntry *)CheckMalloc(tif,
152 dircount * sizeof (TIFFDirEntry), "to read TIFF private subdirectory");
153 if (dir == NULL)
154 return (0);
155 if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) {
156 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Can not read TIFF private subdirectory");
157 goto bad;
158 }
159 /*
160 * Read offset to next directory for sequential scans.
161 */
162 (void) ReadOK(tif, &nextdiroff, sizeof (uint32));
163 } else {
164 toff_t off = pdir_offset;
165
166 if (off + sizeof (short) > tif->tif_size) {
167 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
168 "Can not read TIFF private subdirectory count");
169 return (0);
170 } else
171 _TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16));
172 off += sizeof (uint16);
173 if (tif->tif_flags & TIFF_SWAB)
174 TIFFSwabShort(&dircount);
175 dir = (TIFFDirEntry *)CheckMalloc(tif,
176 dircount * sizeof (TIFFDirEntry), "to read TIFF private subdirectory");
177 if (dir == NULL)
178 return (0);
179 if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) {
180 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Can not read TIFF private subdirectory");
181 goto bad;
182 } else
183 _TIFFmemcpy(dir, tif->tif_base + off,
184 dircount*sizeof (TIFFDirEntry));
185 off += dircount* sizeof (TIFFDirEntry);
186 if (off + sizeof (uint32) < tif->tif_size)
187 _TIFFmemcpy(&nextdiroff, tif->tif_base+off, sizeof (uint32));
188 }
189 if (tif->tif_flags & TIFF_SWAB)
190 TIFFSwabLong(&nextdiroff);
191
192 /*
193 * Setup default value and then make a pass over
194 * the fields to check type and tag information,
195 * and to extract info required to size data
196 * structures. A second pass is made afterwards
197 * to read in everthing not taken in the first pass.
198 */
199 td = &tif->tif_dir;
200
201 for (fip = field_info, dp = dir, n = dircount;
202 n > 0; n--, dp++) {
203 if (tif->tif_flags & TIFF_SWAB) {
204 TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
205 TIFFSwabArrayOfLong(&dp->tdir_count, 2);
206 }
207 /*
208 * Find the field information entry for this tag.
209 */
210 /*
211 * Silicon Beach (at least) writes unordered
212 * directory tags (violating the spec). Handle
213 * it here, but be obnoxious (maybe they'll fix it?).
214 */
215 if (dp->tdir_tag < fip->field_tag) {
216 if (!diroutoforderwarning) {
217 TIFFWarning(tif->tif_name,
218 "invalid TIFF private subdirectory; tags are not sorted in ascending order");
219 diroutoforderwarning = 1;
220 }
221 fip = field_info; /* O(n^2) */
222 }
223
224 while (fip->field_tag && fip->field_tag < dp->tdir_tag)
225 fip++;
226 if (!fip->field_tag || fip->field_tag != dp->tdir_tag) {
227 TIFFWarning(tif->tif_name,
228 "unknown field with tag %d (0x%x) in private subdirectory ignored",
229 dp->tdir_tag, dp->tdir_tag);
230 dp->tdir_tag = IGNORE;
231 fip = field_info;/* restart search */
232 continue;
233 }
234 /*
235 * Null out old tags that we ignore.
236 */
237
238 /* Not implemented yet, since FIELD_IGNORE is specific to
239 the main directories. Could pass this in too... */
240 if (0 /* && fip->field_bit == FIELD_IGNORE */) {
241 ignore:
242 dp->tdir_tag = IGNORE;
243 continue;
244 }
245
246 /*
247 * Check data type.
248 */
249
250 while (dp->tdir_type != (u_short)fip->field_type) {
251 if (fip->field_type == TIFF_ANY) /* wildcard */
252 break;
253 fip++;
254 if (!fip->field_tag || fip->field_tag != dp->tdir_tag) {
255 TIFFWarning(tif->tif_name,
256 "wrong data type %d for \"%s\"; tag ignored",
257 dp->tdir_type, fip[-1].field_name);
258 goto ignore;
259 }
260 }
261 /*
262 * Check count if known in advance.
263 */
264 if (fip->field_readcount != TIFF_VARIABLE) {
265 uint32 expected = (fip->field_readcount == TIFF_SPP) ?
266 (uint32) td->td_samplesperpixel :
267 (uint32) fip->field_readcount;
268 if (!CheckDirCount(tif, dp, expected))
269 goto ignore;
270 }
271
272 /* Now read in and process data from field. */
273 if (!TIFFFetchNormalSubTag(tif, dp, fip, setFieldFn))
274 goto bad;
275
276 }
277
278 if (dir)
279 _TIFFfree(dir);
280 return (1);
281bad:
282 if (dir)
283 _TIFFfree(dir);
284 return (0);
285}
286
287static void
288EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
289{
290 register TIFFDirEntry *dp;
291 register TIFFDirectory *td = &tif->tif_dir;
292 uint16 i;
293
294 if (td->td_stripbytecount)
295 _TIFFfree(td->td_stripbytecount);
296 td->td_stripbytecount = (uint32*)
297 CheckMalloc(tif, td->td_nstrips * sizeof (uint32),
298 "for \"StripByteCounts\" array");
299 if (td->td_compression != COMPRESSION_NONE) {
300 uint32 space = (uint32)(sizeof (TIFFHeader)
301 + sizeof (uint16)
302 + (dircount * sizeof (TIFFDirEntry))
303 + sizeof (uint32));
304 toff_t filesize = TIFFGetFileSize(tif);
305 uint16 n;
306
307 /* calculate amount of space used by indirect values */
308 for (dp = dir, n = dircount; n > 0; n--, dp++) {
309 uint32 cc = dp->tdir_count*TIFFDataWidth(dp->tdir_type);
310 if (cc > sizeof (uint32))
311 space += cc;
312 }
313 space = (filesize - space) / td->td_samplesperpixel;
314 for (i = 0; i < td->td_nstrips; i++)
315 td->td_stripbytecount[i] = space;
316 /*
317 * This gross hack handles the case were the offset to
318 * the last strip is past the place where we think the strip
319 * should begin. Since a strip of data must be contiguous,
320 * it's safe to assume that we've overestimated the amount
321 * of data in the strip and trim this number back accordingly.
322 */
323 i--;
324 if (td->td_stripoffset[i] + td->td_stripbytecount[i] > filesize)
325 td->td_stripbytecount[i] =
326 filesize - td->td_stripoffset[i];
327 } else {
328 uint32 rowbytes = TIFFScanlineSize(tif);
329 uint32 rowsperstrip = td->td_imagelength / td->td_nstrips;
330 for (i = 0; i < td->td_nstrips; i++)
331 td->td_stripbytecount[i] = rowbytes*rowsperstrip;
332 }
333 TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
334 if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
335 td->td_rowsperstrip = td->td_imagelength;
336}
337
338static void
339MissingRequired(TIFF* tif, const char* tagname)
340{
341 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
342 "TIFF directory is missing required \"%s\" field", tagname);
343}
344
345/*
346 * Check the count field of a directory
347 * entry against a known value. The caller
348 * is expected to skip/ignore the tag if
349 * there is a mismatch.
350 */
351static int
352CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
353{
354 if (count != dir->tdir_count) {
355 TIFFWarning(tif->tif_name,
356 "incorrect count for field \"%s\" (%lu, expecting %lu); tag ignored",
357 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name,
358 dir->tdir_count, count);
359 return (0);
360 }
361 return (1);
362}
363
364/*
365 * Fetch a contiguous directory item.
366 */
367static tsize_t
368TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp)
369{
370 int w = TIFFDataWidth(dir->tdir_type);
371 tsize_t cc = dir->tdir_count * w;
372
373 if (!isMapped(tif)) {
374 if (!SeekOK(tif, dir->tdir_offset))
375 goto bad;
376 if (!ReadOK(tif, cp, cc))
377 goto bad;
378 } else {
379 if (dir->tdir_offset + cc > tif->tif_size)
380 goto bad;
381 _TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc);
382 }
383 if (tif->tif_flags & TIFF_SWAB) {
384 switch (dir->tdir_type) {
385 case TIFF_SHORT:
386 case TIFF_SSHORT:
387 TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count);
388 break;
389 case TIFF_LONG:
390 case TIFF_SLONG:
391 case TIFF_FLOAT:
392 TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count);
393 break;
394 case TIFF_RATIONAL:
395 case TIFF_SRATIONAL:
396 TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count);
397 break;
398 case TIFF_DOUBLE:
399 TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count);
400 break;
401 }
402 }
403 return (cc);
404bad:
405 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error fetching data for field \"%s\"",
406 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
407 return ((tsize_t) 0);
408}
409
410/*
411 * Fetch an ASCII item from the file.
412 */
413static tsize_t
414TIFFFetchString(TIFF* tif, TIFFDirEntry* dir, char* cp)
415{
416 if (dir->tdir_count <= 4) {
417 uint32 l = dir->tdir_offset;
418 if (tif->tif_flags & TIFF_SWAB)
419 TIFFSwabLong(&l);
420 _TIFFmemcpy(cp, &l, dir->tdir_count);
421 return (1);
422 }
423 return (TIFFFetchData(tif, dir, cp));
424}
425
426/*
427 * Convert numerator+denominator to float.
428 */
429static int
430cvtRational(TIFF* tif, TIFFDirEntry* dir, uint32 num, uint32 denom, float* rv)
431{
432 if (denom == 0) {
433 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
434 "%s: Rational with zero denominator (num = %lu)",
435 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name, num);
436 return (0);
437 } else {
438 if (dir->tdir_type == TIFF_RATIONAL)
439 *rv = ((float)num / (float)denom);
440 else
441 *rv = ((float)(int32)num / (float)(int32)denom);
442 return (1);
443 }
444}
445
446/*
447 * Fetch a rational item from the file
448 * at offset off and return the value
449 * as a floating point number.
450 */
451static float
452TIFFFetchRational(TIFF* tif, TIFFDirEntry* dir)
453{
454 uint32 l[2];
455 float v;
456
457 return (!TIFFFetchData(tif, dir, (char *)l) ||
458 !cvtRational(tif, dir, l[0], l[1], &v) ? 1.0f : v);
459}
460
461/*
462 * Fetch a single floating point value
463 * from the offset field and return it
464 * as a native float.
465 */
466static float
467TIFFFetchFloat(TIFF* tif, TIFFDirEntry* dir)
468{
469 /* This appears to be a flagrant bug in the TIFF library, yet I
470 actually don't understand how it could have ever worked the old
471 way. Look at the comments in my new code and you'll understand. */
472#if (0)
473 float v = (float)
474 TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset);
475 TIFFCvtIEEEFloatToNative(tif, 1, &v);
476#else
477 float v;
478 /* This is a little bit tricky - if we just cast the uint32 to a float,
479 C will perform a numerical conversion, which is not what we want.
480 We want to take the actual bit pattern in the uint32 and interpret
481 it as a float. Thus we cast a uint32 * into a float * and then
482 dereference to get v. */
483 uint32 l = (uint32)
484 TIFFExtractData(tif, dir->tdir_type, dir->tdir_offset);
485 v = * (float *) &l;
486 TIFFCvtIEEEFloatToNative(tif, 1, &v);
487#endif
488 return (v);
489
490}
491
492/*
493 * Fetch an array of BYTE or SBYTE values.
494 */
495static int
496TIFFFetchByteArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
497{
498 if (dir->tdir_count <= 4) {
499 /*
500 * Extract data from offset field.
501 */
502 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
503 switch (dir->tdir_count) {
504 case 4: v[3] = dir->tdir_offset & 0xff;
505 case 3: v[2] = (dir->tdir_offset >> 8) & 0xff;
506 case 2: v[1] = (dir->tdir_offset >> 16) & 0xff;
507 case 1: v[0] = dir->tdir_offset >> 24;
508 }
509 } else {
510 switch (dir->tdir_count) {
511 case 4: v[3] = dir->tdir_offset >> 24;
512 case 3: v[2] = (dir->tdir_offset >> 16) & 0xff;
513 case 2: v[1] = (dir->tdir_offset >> 8) & 0xff;
514 case 1: v[0] = dir->tdir_offset & 0xff;
515 }
516 }
517 return (1);
518 } else
519 return (TIFFFetchData(tif, dir, (char*) v) != 0); /* XXX */
520}
521
522/*
523 * Fetch an array of SHORT or SSHORT values.
524 */
525static int
526TIFFFetchShortArray(TIFF* tif, TIFFDirEntry* dir, uint16* v)
527{
528 if (dir->tdir_count <= 2) {
529 if (tif->tif_header.tiff_magic == TIFF_BIGENDIAN) {
530 switch (dir->tdir_count) {
531 case 2: v[1] = dir->tdir_offset & 0xffff;
532 case 1: v[0] = dir->tdir_offset >> 16;
533 }
534 } else {
535 switch (dir->tdir_count) {
536 case 2: v[1] = dir->tdir_offset >> 16;
537 case 1: v[0] = dir->tdir_offset & 0xffff;
538 }
539 }
540 return (1);
541 } else
542 return (TIFFFetchData(tif, dir, (char *)v) != 0);
543}
544
545/*
546 * Fetch a pair of SHORT or BYTE values.
547 */
548static int
549TIFFFetchShortPair(TIFF* tif, TIFFDirEntry* dir)
550{
551 uint16 v[2];
552 int ok = 0;
553
554 switch (dir->tdir_type) {
555 case TIFF_SHORT:
556 case TIFF_SSHORT:
557 ok = TIFFFetchShortArray(tif, dir, v);
558 break;
559 case TIFF_BYTE:
560 case TIFF_SBYTE:
561 ok = TIFFFetchByteArray(tif, dir, v);
562 break;
563 }
564 if (ok)
565 TIFFSetField(tif, dir->tdir_tag, v[0], v[1]);
566 return (ok);
567}
568
569/*
570 * Fetch an array of LONG or SLONG values.
571 */
572static int
573TIFFFetchLongArray(TIFF* tif, TIFFDirEntry* dir, uint32* v)
574{
575 if (dir->tdir_count == 1) {
576 v[0] = dir->tdir_offset;
577 return (1);
578 } else
579 return (TIFFFetchData(tif, dir, (char*) v) != 0);
580}
581
582/*
583 * Fetch an array of RATIONAL or SRATIONAL values.
584 */
585static int
586TIFFFetchRationalArray(TIFF* tif, TIFFDirEntry* dir, float* v)
587{
588 int ok = 0;
589 uint32* l;
590
591 l = (uint32*)CheckMalloc(tif,
592 dir->tdir_count*TIFFDataWidth(dir->tdir_type),
593 "to fetch array of rationals");
594 if (l) {
595 if (TIFFFetchData(tif, dir, (char *)l)) {
596 uint32 i;
597 for (i = 0; i < dir->tdir_count; i++) {
598 ok = cvtRational(tif, dir,
599 l[2*i+0], l[2*i+1], &v[i]);
600 if (!ok)
601 break;
602 }
603 }
604 _TIFFfree((char *)l);
605 }
606 return (ok);
607}
608
609/*
610 * Fetch an array of FLOAT values.
611 */
612static int
613TIFFFetchFloatArray(TIFF* tif, TIFFDirEntry* dir, float* v)
614{
615
616 if (dir->tdir_count == 1) {
617 v[0] = *(float*) &dir->tdir_offset;
618 TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
619 return (1);
620 } else if (TIFFFetchData(tif, dir, (char*) v)) {
621 TIFFCvtIEEEFloatToNative(tif, dir->tdir_count, v);
622 return (1);
623 } else
624 return (0);
625}
626
627/*
628 * Fetch an array of DOUBLE values.
629 */
630static int
631TIFFFetchDoubleArray(TIFF* tif, TIFFDirEntry* dir, double* v)
632{
633 if (TIFFFetchData(tif, dir, (char*) v)) {
634 TIFFCvtIEEEDoubleToNative(tif, dir->tdir_count, v);
635 return (1);
636 } else
637 return (0);
638}
639
640/*
641 * Fetch an array of ANY values. The actual values are
642 * returned as doubles which should be able hold all the
643 * types. Yes, there really should be an tany_t to avoid
644 * this potential non-portability ... Note in particular
645 * that we assume that the double return value vector is
646 * large enough to read in any fundamental type. We use
647 * that vector as a buffer to read in the base type vector
648 * and then convert it in place to double (from end
649 * to front of course).
650 */
651static int
652TIFFFetchAnyArray(TIFF* tif, TIFFDirEntry* dir, double* v)
653{
654 int i;
655
656 switch (dir->tdir_type) {
657 case TIFF_BYTE:
658 case TIFF_SBYTE:
659 if (!TIFFFetchByteArray(tif, dir, (uint16*) v))
660 return (0);
661 if (dir->tdir_type == TIFF_BYTE) {
662 uint16* vp = (uint16*) v;
663 for (i = dir->tdir_count-1; i >= 0; i--)
664 v[i] = vp[i];
665 } else {
666 int16* vp = (int16*) v;
667 for (i = dir->tdir_count-1; i >= 0; i--)
668 v[i] = vp[i];
669 }
670 break;
671 case TIFF_SHORT:
672 case TIFF_SSHORT:
673 if (!TIFFFetchShortArray(tif, dir, (uint16*) v))
674 return (0);
675 if (dir->tdir_type == TIFF_SHORT) {
676 uint16* vp = (uint16*) v;
677 for (i = dir->tdir_count-1; i >= 0; i--)
678 v[i] = vp[i];
679 } else {
680 int16* vp = (int16*) v;
681 for (i = dir->tdir_count-1; i >= 0; i--)
682 v[i] = vp[i];
683 }
684 break;
685 case TIFF_LONG:
686 case TIFF_SLONG:
687 if (!TIFFFetchLongArray(tif, dir, (uint32*) v))
688 return (0);
689 if (dir->tdir_type == TIFF_LONG) {
690 uint32* vp = (uint32*) v;
691 for (i = dir->tdir_count-1; i >= 0; i--)
692 v[i] = vp[i];
693 } else {
694 int32* vp = (int32*) v;
695 for (i = dir->tdir_count-1; i >= 0; i--)
696 v[i] = vp[i];
697 }
698 break;
699 case TIFF_RATIONAL:
700 case TIFF_SRATIONAL:
701 if (!TIFFFetchRationalArray(tif, dir, (float*) v))
702 return (0);
703 { float* vp = (float*) v;
704 for (i = dir->tdir_count-1; i >= 0; i--)
705 v[i] = vp[i];
706 }
707 break;
708 case TIFF_FLOAT:
709 if (!TIFFFetchFloatArray(tif, dir, (float*) v))
710 return (0);
711 { float* vp = (float*) v;
712 for (i = dir->tdir_count-1; i >= 0; i--)
713 v[i] = vp[i];
714 }
715 break;
716 case TIFF_DOUBLE:
717 return (TIFFFetchDoubleArray(tif, dir, (double*) v));
718 default:
719 /* TIFF_NOTYPE */
720 /* TIFF_ASCII */
721 /* TIFF_UNDEFINED */
722 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
723 "Cannot read TIFF_ANY type %d for field \"%s\"",
724 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
725 return (0);
726 }
727 return (1);
728}
729
730
731/*
732 * Fetch a tag that is not handled by special case code.
733 */
734/* The standard function TIFFFetchNormalTag() could definitely be replaced
735 with a simple call to this function, just adding TIFFSetField() as the
736 last argument. */
737static int
738TIFFFetchNormalSubTag(TIFF* tif, TIFFDirEntry* dp, const TIFFFieldInfo* fip,
739 int (*setFieldFn)(TIFF *tif, ttag_t tag, ...))
740{
741 static char mesg[] = "to fetch tag value";
742 int ok = 0;
743
744 if (dp->tdir_count > 1) { /* array of values */
745 char* cp = NULL;
746
747 switch (dp->tdir_type) {
748 case TIFF_BYTE:
749 case TIFF_SBYTE:
750 /* NB: always expand BYTE values to shorts */
751 cp = CheckMalloc(tif,
752 dp->tdir_count * sizeof (uint16), mesg);
753 ok = cp && TIFFFetchByteArray(tif, dp, (uint16*) cp);
754 break;
755 case TIFF_SHORT:
756 case TIFF_SSHORT:
757 cp = CheckMalloc(tif,
758 dp->tdir_count * sizeof (uint16), mesg);
759 ok = cp && TIFFFetchShortArray(tif, dp, (uint16*) cp);
760 break;
761 case TIFF_LONG:
762 case TIFF_SLONG:
763 cp = CheckMalloc(tif,
764 dp->tdir_count * sizeof (uint32), mesg);
765 ok = cp && TIFFFetchLongArray(tif, dp, (uint32*) cp);
766 break;
767 case TIFF_RATIONAL:
768 case TIFF_SRATIONAL:
769 cp = CheckMalloc(tif,
770 dp->tdir_count * sizeof (float), mesg);
771 ok = cp && TIFFFetchRationalArray(tif, dp, (float*) cp);
772 break;
773 case TIFF_FLOAT:
774 cp = CheckMalloc(tif,
775 dp->tdir_count * sizeof (float), mesg);
776 ok = cp && TIFFFetchFloatArray(tif, dp, (float*) cp);
777 break;
778 case TIFF_DOUBLE:
779 cp = CheckMalloc(tif,
780 dp->tdir_count * sizeof (double), mesg);
781 ok = cp && TIFFFetchDoubleArray(tif, dp, (double*) cp);
782 break;
783 case TIFF_ASCII:
784 case TIFF_UNDEFINED: /* bit of a cheat... */
785 /*
786 * Some vendors write strings w/o the trailing
787 * NULL byte, so always append one just in case.
788 */
789 cp = CheckMalloc(tif, dp->tdir_count+1, mesg);
790 if (ok = (cp && TIFFFetchString(tif, dp, cp)))
791 cp[dp->tdir_count] = '\0'; /* XXX */
792 break;
793 }
794 if (ok) {
795 ok = (fip->field_passcount ?
796 (*setFieldFn)(tif, dp->tdir_tag, dp->tdir_count, cp)
797 : (*setFieldFn)(tif, dp->tdir_tag, cp));
798 }
799 if (cp != NULL)
800 _TIFFfree(cp);
801 } else if (CheckDirCount(tif, dp, 1)) { /* singleton value */
802 switch (dp->tdir_type) {
803 case TIFF_BYTE:
804 case TIFF_SBYTE:
805 case TIFF_SHORT:
806 case TIFF_SSHORT:
807 /*
808 * If the tag is also acceptable as a LONG or SLONG
809 * then (*setFieldFn) will expect an uint32 parameter
810 * passed to it (through varargs). Thus, for machines
811 * where sizeof (int) != sizeof (uint32) we must do
812 * a careful check here. It's hard to say if this
813 * is worth optimizing.
814 *
815 * NB: We use TIFFFieldWithTag here knowing that
816 * it returns us the first entry in the table
817 * for the tag and that that entry is for the
818 * widest potential data type the tag may have.
819 */
820 { TIFFDataType type = fip->field_type;
821 if (type != TIFF_LONG && type != TIFF_SLONG) {
822 uint16 v = (uint16)
823 TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
824 ok = (fip->field_passcount ?
825 (*setFieldFn)(tif, dp->tdir_tag, 1, &v)
826 : (*setFieldFn)(tif, dp->tdir_tag, v));
827 break;
828 }
829 }
830 /* fall thru... */
831 case TIFF_LONG:
832 case TIFF_SLONG:
833 { uint32 v32 =
834 TIFFExtractData(tif, dp->tdir_type, dp->tdir_offset);
835 ok = (fip->field_passcount ?
836 (*setFieldFn)(tif, dp->tdir_tag, 1, &v32)
837 : (*setFieldFn)(tif, dp->tdir_tag, v32));
838 }
839 break;
840 case TIFF_RATIONAL:
841 case TIFF_SRATIONAL:
842 case TIFF_FLOAT:
843 { float v = (dp->tdir_type == TIFF_FLOAT ?
844 TIFFFetchFloat(tif, dp)
845 : TIFFFetchRational(tif, dp));
846 ok = (fip->field_passcount ?
847 (*setFieldFn)(tif, dp->tdir_tag, 1, &v)
848 : (*setFieldFn)(tif, dp->tdir_tag, v));
849 }
850 break;
851 case TIFF_DOUBLE:
852 { double v;
853 ok = (TIFFFetchDoubleArray(tif, dp, &v) &&
854 (fip->field_passcount ?
855 (*setFieldFn)(tif, dp->tdir_tag, 1, &v)
856 : (*setFieldFn)(tif, dp->tdir_tag, v))
857 );
858 }
859 break;
860 case TIFF_ASCII:
861 case TIFF_UNDEFINED: /* bit of a cheat... */
862 { char c[2];
863 if (ok = (TIFFFetchString(tif, dp, c) != 0)) {
864 c[1] = '\0'; /* XXX paranoid */
865 ok = (*setFieldFn)(tif, dp->tdir_tag, c);
866 }
867 }
868 break;
869 }
870 }
871 return (ok);
872}
873
874/* Everything after this is exactly duplicated from the standard tif_dirread.c
875 file, necessitated by the fact that they are declared static there so
876 we can't call them!
877*/
878#define NITEMS(x) (sizeof (x) / sizeof (x[0]))
879/*
880 * Fetch samples/pixel short values for
881 * the specified tag and verify that
882 * all values are the same.
883 */
884static int
885TIFFFetchPerSampleShorts(TIFF* tif, TIFFDirEntry* dir, int* pl)
886{
887 int samples = tif->tif_dir.td_samplesperpixel;
888 int status = 0;
889
890 if (CheckDirCount(tif, dir, (uint32) samples)) {
891 uint16 buf[10];
892 uint16* v = buf;
893
894 if (samples > NITEMS(buf))
895 v = (uint16*) _TIFFmalloc(samples * sizeof (uint16));
896 if (TIFFFetchShortArray(tif, dir, v)) {
897 int i;
898 for (i = 1; i < samples; i++)
899 if (v[i] != v[0]) {
900 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
901 "Cannot handle different per-sample values for field \"%s\"",
902 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
903 goto bad;
904 }
905 *pl = v[0];
906 status = 1;
907 }
908 bad:
909 if (v != buf)
910 _TIFFfree((char*) v);
911 }
912 return (status);
913}
914
915/*
916 * Fetch samples/pixel ANY values for
917 * the specified tag and verify that
918 * all values are the same.
919 */
920static int
921TIFFFetchPerSampleAnys(TIFF* tif, TIFFDirEntry* dir, double* pl)
922{
923 int samples = (int) tif->tif_dir.td_samplesperpixel;
924 int status = 0;
925
926 if (CheckDirCount(tif, dir, (uint32) samples)) {
927 double buf[10];
928 double* v = buf;
929
930 if (samples > NITEMS(buf))
931 v = (double*) _TIFFmalloc(samples * sizeof (double));
932 if (TIFFFetchAnyArray(tif, dir, v)) {
933 int i;
934 for (i = 1; i < samples; i++)
935 if (v[i] != v[0]) {
936 TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
937 "Cannot handle different per-sample values for field \"%s\"",
938 _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name);
939 goto bad;
940 }
941 *pl = v[0];
942 status = 1;
943 }
944 bad:
945 if (v != buf)
946 _TIFFfree(v);
947 }
948 return (status);
949}
950#undef NITEMS
951
952/*
953 * Fetch a set of offsets or lengths.
954 * While this routine says "strips",
955 * in fact it's also used for tiles.
956 */
957static int
958TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, long nstrips, uint32** lpp)
959{
960 register uint32* lp;
961 int status;
962
963 if (!CheckDirCount(tif, dir, (uint32) nstrips))
964 return (0);
965 /*
966 * Allocate space for strip information.
967 */
968 if (*lpp == NULL &&
969 (*lpp = (uint32 *)CheckMalloc(tif,
970 nstrips * sizeof (uint32), "for strip array")) == NULL)
971 return (0);
972 lp = *lpp;
973 if (dir->tdir_type == (int)TIFF_SHORT) {
974 /*
975 * Handle uint16->uint32 expansion.
976 */
977 uint16* dp = (uint16*) CheckMalloc(tif,
978 dir->tdir_count* sizeof (uint16), "to fetch strip tag");
979 if (dp == NULL)
980 return (0);
981 if (status = TIFFFetchShortArray(tif, dir, dp)) {
982 register uint16* wp = dp;
983 while (nstrips-- > 0)
984 *lp++ = *wp++;
985 }
986 _TIFFfree((char*) dp);
987 } else
988 status = TIFFFetchLongArray(tif, dir, lp);
989 return (status);
990}
991
992#define NITEMS(x) (sizeof (x) / sizeof (x[0]))
993/*
994 * Fetch and set the ExtraSamples tag.
995 */
996static int
997TIFFFetchExtraSamples(TIFF* tif, TIFFDirEntry* dir)
998{
999 uint16 buf[10];
1000 uint16* v = buf;
1001 int status;
1002
1003 if (dir->tdir_count > NITEMS(buf))
1004 v = (uint16*) _TIFFmalloc(dir->tdir_count * sizeof (uint16));
1005 if (dir->tdir_type == TIFF_BYTE)
1006 status = TIFFFetchByteArray(tif, dir, v);
1007 else
1008 status = TIFFFetchShortArray(tif, dir, v);
1009 if (status)
1010 status = TIFFSetField(tif, dir->tdir_tag, dir->tdir_count, v);
1011 if (v != buf)
1012 _TIFFfree((char*) v);
1013 return (status);
1014}
1015#undef NITEMS
1016
1017#ifdef COLORIMETRY_SUPPORT
1018/*
1019 * Fetch and set the RefBlackWhite tag.
1020 */
1021static int
1022TIFFFetchRefBlackWhite(TIFF* tif, TIFFDirEntry* dir)
1023{
1024 static char mesg[] = "for \"ReferenceBlackWhite\" array";
1025 char* cp;
1026 int ok;
1027
1028 if (dir->tdir_type == TIFF_RATIONAL)
1029 return (1/*TIFFFetchNormalTag(tif, dir) just so linker won't complain - this part of the code is never used anyway */);
1030 /*
1031 * Handle LONG's for backward compatibility.
1032 */
1033 cp = CheckMalloc(tif, dir->tdir_count * sizeof (uint32), mesg);
1034 if (ok = (cp && TIFFFetchLongArray(tif, dir, (uint32*) cp))) {
1035 float* fp = (float*)
1036 CheckMalloc(tif, dir->tdir_count * sizeof (float), mesg);
1037 if (ok = (fp != NULL)) {
1038 uint32 i;
1039 for (i = 0; i < dir->tdir_count; i++)
1040 fp[i] = (float)((uint32*) cp)[i];
1041 ok = TIFFSetField(tif, dir->tdir_tag, fp);
1042 _TIFFfree((char*) fp);
1043 }
1044 }
1045 if (cp)
1046 _TIFFfree(cp);
1047 return (ok);
1048}
1049#endif
1050
1051#if STRIPCHOP_SUPPORT
1052/*
1053 * Replace a single strip (tile) of uncompressed data by
1054 * multiple strips (tiles), each approximately 8Kbytes.
1055 * This is useful for dealing with large images or
1056 * for dealing with machines with a limited amount
1057 * memory.
1058 */
1059static void
1060ChopUpSingleUncompressedStrip(TIFF* tif)
1061{
1062 register TIFFDirectory *td = &tif->tif_dir;
1063 uint32 bytecount = td->td_stripbytecount[0];
1064 uint32 offset = td->td_stripoffset[0];
1065 tsize_t rowbytes = TIFFVTileSize(tif, 1), stripbytes;
1066 tstrip_t strip, nstrips, rowsperstrip;
1067 uint32* newcounts;
1068 uint32* newoffsets;
1069
1070 /*
1071 * Make the rows hold at least one
1072 * scanline, but fill 8k if possible.
1073 */
1074 if (rowbytes > 8192) {
1075 stripbytes = rowbytes;
1076 rowsperstrip = 1;
1077 } else {
1078 rowsperstrip = 8192 / rowbytes;
1079 stripbytes = rowbytes * rowsperstrip;
1080 }
1081 /* never increase the number of strips in an image */
1082 if (rowsperstrip >= td->td_rowsperstrip)
1083 return;
1084 nstrips = (tstrip_t) TIFFhowmany(bytecount, stripbytes);
1085 newcounts = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32),
1086 "for chopped \"StripByteCounts\" array");
1087 newoffsets = (uint32*) CheckMalloc(tif, nstrips * sizeof (uint32),
1088 "for chopped \"StripOffsets\" array");
1089 if (newcounts == NULL || newoffsets == NULL) {
1090 /*
1091 * Unable to allocate new strip information, give
1092 * up and use the original one strip information.
1093 */
1094 if (newcounts != NULL)
1095 _TIFFfree(newcounts);
1096 if (newoffsets != NULL)
1097 _TIFFfree(newoffsets);
1098 return;
1099 }
1100 /*
1101 * Fill the strip information arrays with
1102 * new bytecounts and offsets that reflect
1103 * the broken-up format.
1104 */
1105 for (strip = 0; strip < nstrips; strip++) {
1106 if (stripbytes > bytecount)
1107 stripbytes = bytecount;
1108 newcounts[strip] = stripbytes;
1109 newoffsets[strip] = offset;
1110 offset += stripbytes;
1111 bytecount -= stripbytes;
1112 }
1113 /*
1114 * Replace old single strip info with multi-strip info.
1115 */
1116 td->td_stripsperimage = td->td_nstrips = nstrips;
1117 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
1118
1119 _TIFFfree(td->td_stripbytecount);
1120 _TIFFfree(td->td_stripoffset);
1121 td->td_stripbytecount = newcounts;
1122 td->td_stripoffset = newoffsets;
1123}
1124#endif /* STRIPCHOP_SUPPORT */