]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/contrib/pds/tif_pdsdirread.c
1 /* $Header: /cvs/maptools/cvsroot/libtiff/contrib/pds/tif_pdsdirread.c,v 1.3 2005/12/21 12:23:13 joris Exp $ */
4 * Copyright (c) 1988-1996 Sam Leffler
5 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
6 * Copyright (c( 1996 USAF Phillips Laboratory
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.
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.
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
31 * These routines written by Conrad J. Poelman on a single late-night of
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.
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.
48 * Oh, also note the bug fix in TIFFFetchFloat().
54 #define IGNORE 0 /* tag placeholder used below */
57 #define TIFFCvtIEEEFloatToNative(tif, n, fp)
58 #define TIFFCvtIEEEDoubleToNative(tif, n, dp)
60 extern void TIFFCvtIEEEFloatToNative(TIFF
*, uint32
, float*);
61 extern void TIFFCvtIEEEDoubleToNative(TIFF
*, uint32
, double*);
64 static void EstimateStripByteCounts(TIFF
*, TIFFDirEntry
*, uint16
);
65 static void MissingRequired(TIFF
*, const char*);
66 static int CheckDirCount(TIFF
*, TIFFDirEntry
*, uint32
);
67 static tsize_t
TIFFFetchData(TIFF
*, TIFFDirEntry
*, char*);
68 static tsize_t
TIFFFetchString(TIFF
*, TIFFDirEntry
*, char*);
69 static float TIFFFetchRational(TIFF
*, TIFFDirEntry
*);
70 static int TIFFFetchNormalSubTag(TIFF
*, TIFFDirEntry
*, const TIFFFieldInfo
*,
71 int (*getFieldFn
)(TIFF
*tif
,ttag_t tag
,...));
72 static int TIFFFetchPerSampleShorts(TIFF
*, TIFFDirEntry
*, int*);
73 static int TIFFFetchPerSampleAnys(TIFF
*, TIFFDirEntry
*, double*);
74 static int TIFFFetchShortArray(TIFF
*, TIFFDirEntry
*, uint16
*);
75 static int TIFFFetchStripThing(TIFF
*, TIFFDirEntry
*, long, uint32
**);
76 static int TIFFFetchExtraSamples(TIFF
*, TIFFDirEntry
*);
77 static int TIFFFetchRefBlackWhite(TIFF
*, TIFFDirEntry
*);
78 static float TIFFFetchFloat(TIFF
*, TIFFDirEntry
*);
79 static int TIFFFetchFloatArray(TIFF
*, TIFFDirEntry
*, float*);
80 static int TIFFFetchDoubleArray(TIFF
*, TIFFDirEntry
*, double*);
81 static int TIFFFetchAnyArray(TIFF
*, TIFFDirEntry
*, double*);
82 static int TIFFFetchShortPair(TIFF
*, TIFFDirEntry
*);
84 static void ChopUpSingleUncompressedStrip(TIFF
*);
88 CheckMalloc(TIFF
* tif
, tsize_t n
, const char* what
)
90 char *cp
= (char*)_TIFFmalloc(n
);
92 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, "No space %s", what
);
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.
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.
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.
112 It is also the caller's responsibility to verify the presence of
113 any required fields after reading the directory in.
118 TIFFReadPrivateDataSubDirectory(TIFF
* tif
, toff_t pdir_offset
,
119 TIFFFieldInfo
*field_info
,
120 int (*setFieldFn
)(TIFF
*tif
, ttag_t tag
, ...))
122 register TIFFDirEntry
* dp
;
124 register TIFFDirectory
* td
;
129 const TIFFFieldInfo
* fip
;
134 int diroutoforderwarning
= 0;
136 /* Skipped part about checking for directories or compression data. */
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");
144 if (!ReadOK(tif
, &dircount
, sizeof (uint16
))) {
145 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
,
146 "Can not read TIFF private subdirectory count");
149 if (tif
->tif_flags
& TIFF_SWAB
)
150 TIFFSwabShort(&dircount
);
151 dir
= (TIFFDirEntry
*)CheckMalloc(tif
,
152 dircount
* sizeof (TIFFDirEntry
), "to read TIFF private subdirectory");
155 if (!ReadOK(tif
, dir
, dircount
*sizeof (TIFFDirEntry
))) {
156 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, "Can not read TIFF private subdirectory");
160 * Read offset to next directory for sequential scans.
162 (void) ReadOK(tif
, &nextdiroff
, sizeof (uint32
));
164 toff_t off
= pdir_offset
;
166 if (off
+ sizeof (short) > tif
->tif_size
) {
167 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
,
168 "Can not read TIFF private subdirectory count");
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");
179 if (off
+ dircount
*sizeof (TIFFDirEntry
) > tif
->tif_size
) {
180 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
, "Can not read TIFF private subdirectory");
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
));
189 if (tif
->tif_flags
& TIFF_SWAB
)
190 TIFFSwabLong(&nextdiroff
);
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.
201 for (fip
= field_info
, dp
= dir
, n
= dircount
;
203 if (tif
->tif_flags
& TIFF_SWAB
) {
204 TIFFSwabArrayOfShort(&dp
->tdir_tag
, 2);
205 TIFFSwabArrayOfLong(&dp
->tdir_count
, 2);
208 * Find the field information entry for this tag.
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?).
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;
221 fip
= field_info
; /* O(n^2) */
224 while (fip
->field_tag
&& fip
->field_tag
< dp
->tdir_tag
)
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 */
235 * Null out old tags that we ignore.
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 */) {
242 dp
->tdir_tag
= IGNORE
;
250 while (dp
->tdir_type
!= (u_short
)fip
->field_type
) {
251 if (fip
->field_type
== TIFF_ANY
) /* wildcard */
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
);
262 * Check count if known in advance.
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
))
272 /* Now read in and process data from field. */
273 if (!TIFFFetchNormalSubTag(tif
, dp
, fip
, setFieldFn
))
288 EstimateStripByteCounts(TIFF
* tif
, TIFFDirEntry
* dir
, uint16 dircount
)
290 register TIFFDirEntry
*dp
;
291 register TIFFDirectory
*td
= &tif
->tif_dir
;
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
)
302 + (dircount
* sizeof (TIFFDirEntry
))
304 toff_t filesize
= TIFFGetFileSize(tif
);
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
))
313 space
= (filesize
- space
) / td
->td_samplesperpixel
;
314 for (i
= 0; i
< td
->td_nstrips
; i
++)
315 td
->td_stripbytecount
[i
] = space
;
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.
324 if (td
->td_stripoffset
[i
] + td
->td_stripbytecount
[i
] > filesize
)
325 td
->td_stripbytecount
[i
] =
326 filesize
- td
->td_stripoffset
[i
];
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
;
333 TIFFSetFieldBit(tif
, FIELD_STRIPBYTECOUNTS
);
334 if (!TIFFFieldSet(tif
, FIELD_ROWSPERSTRIP
))
335 td
->td_rowsperstrip
= td
->td_imagelength
;
339 MissingRequired(TIFF
* tif
, const char* tagname
)
341 TIFFErrorExt(tif
->tif_clientdata
, tif
->tif_name
,
342 "TIFF directory is missing required \"%s\" field", tagname
);
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.
352 CheckDirCount(TIFF
* tif
, TIFFDirEntry
* dir
, uint32 count
)
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
);
365 * Fetch a contiguous directory item.
368 TIFFFetchData(TIFF
* tif
, TIFFDirEntry
* dir
, char* cp
)
370 int w
= TIFFDataWidth(dir
->tdir_type
);
371 tsize_t cc
= dir
->tdir_count
* w
;
373 if (!isMapped(tif
)) {
374 if (!SeekOK(tif
, dir
->tdir_offset
))
376 if (!ReadOK(tif
, cp
, cc
))
379 if (dir
->tdir_offset
+ cc
> tif
->tif_size
)
381 _TIFFmemcpy(cp
, tif
->tif_base
+ dir
->tdir_offset
, cc
);
383 if (tif
->tif_flags
& TIFF_SWAB
) {
384 switch (dir
->tdir_type
) {
387 TIFFSwabArrayOfShort((uint16
*) cp
, dir
->tdir_count
);
392 TIFFSwabArrayOfLong((uint32
*) cp
, dir
->tdir_count
);
396 TIFFSwabArrayOfLong((uint32
*) cp
, 2*dir
->tdir_count
);
399 TIFFSwabArrayOfDouble((double*) cp
, dir
->tdir_count
);
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);
411 * Fetch an ASCII item from the file.
414 TIFFFetchString(TIFF
* tif
, TIFFDirEntry
* dir
, char* cp
)
416 if (dir
->tdir_count
<= 4) {
417 uint32 l
= dir
->tdir_offset
;
418 if (tif
->tif_flags
& TIFF_SWAB
)
420 _TIFFmemcpy(cp
, &l
, dir
->tdir_count
);
423 return (TIFFFetchData(tif
, dir
, cp
));
427 * Convert numerator+denominator to float.
430 cvtRational(TIFF
* tif
, TIFFDirEntry
* dir
, uint32 num
, uint32 denom
, float* rv
)
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
);
438 if (dir
->tdir_type
== TIFF_RATIONAL
)
439 *rv
= ((float)num
/ (float)denom
);
441 *rv
= ((float)(int32
)num
/ (float)(int32
)denom
);
447 * Fetch a rational item from the file
448 * at offset off and return the value
449 * as a floating point number.
452 TIFFFetchRational(TIFF
* tif
, TIFFDirEntry
* dir
)
457 return (!TIFFFetchData(tif
, dir
, (char *)l
) ||
458 !cvtRational(tif
, dir
, l
[0], l
[1], &v
) ? 1.0f
: v
);
462 * Fetch a single floating point value
463 * from the offset field and return it
467 TIFFFetchFloat(TIFF
* tif
, TIFFDirEntry
* dir
)
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. */
474 TIFFExtractData(tif
, dir
->tdir_type
, dir
->tdir_offset
);
475 TIFFCvtIEEEFloatToNative(tif
, 1, &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. */
484 TIFFExtractData(tif
, dir
->tdir_type
, dir
->tdir_offset
);
486 TIFFCvtIEEEFloatToNative(tif
, 1, &v
);
493 * Fetch an array of BYTE or SBYTE values.
496 TIFFFetchByteArray(TIFF
* tif
, TIFFDirEntry
* dir
, uint16
* v
)
498 if (dir
->tdir_count
<= 4) {
500 * Extract data from offset field.
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;
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;
519 return (TIFFFetchData(tif
, dir
, (char*) v
) != 0); /* XXX */
523 * Fetch an array of SHORT or SSHORT values.
526 TIFFFetchShortArray(TIFF
* tif
, TIFFDirEntry
* dir
, uint16
* v
)
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;
535 switch (dir
->tdir_count
) {
536 case 2: v
[1] = dir
->tdir_offset
>> 16;
537 case 1: v
[0] = dir
->tdir_offset
& 0xffff;
542 return (TIFFFetchData(tif
, dir
, (char *)v
) != 0);
546 * Fetch a pair of SHORT or BYTE values.
549 TIFFFetchShortPair(TIFF
* tif
, TIFFDirEntry
* dir
)
554 switch (dir
->tdir_type
) {
557 ok
= TIFFFetchShortArray(tif
, dir
, v
);
561 ok
= TIFFFetchByteArray(tif
, dir
, v
);
565 TIFFSetField(tif
, dir
->tdir_tag
, v
[0], v
[1]);
570 * Fetch an array of LONG or SLONG values.
573 TIFFFetchLongArray(TIFF
* tif
, TIFFDirEntry
* dir
, uint32
* v
)
575 if (dir
->tdir_count
== 1) {
576 v
[0] = dir
->tdir_offset
;
579 return (TIFFFetchData(tif
, dir
, (char*) v
) != 0);
583 * Fetch an array of RATIONAL or SRATIONAL values.
586 TIFFFetchRationalArray(TIFF
* tif
, TIFFDirEntry
* dir
, float* v
)
591 l
= (uint32
*)CheckMalloc(tif
,
592 dir
->tdir_count
*TIFFDataWidth(dir
->tdir_type
),
593 "to fetch array of rationals");
595 if (TIFFFetchData(tif
, dir
, (char *)l
)) {
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
]);
604 _TIFFfree((char *)l
);
610 * Fetch an array of FLOAT values.
613 TIFFFetchFloatArray(TIFF
* tif
, TIFFDirEntry
* dir
, float* v
)
616 if (dir
->tdir_count
== 1) {
617 v
[0] = *(float*) &dir
->tdir_offset
;
618 TIFFCvtIEEEFloatToNative(tif
, dir
->tdir_count
, v
);
620 } else if (TIFFFetchData(tif
, dir
, (char*) v
)) {
621 TIFFCvtIEEEFloatToNative(tif
, dir
->tdir_count
, v
);
628 * Fetch an array of DOUBLE values.
631 TIFFFetchDoubleArray(TIFF
* tif
, TIFFDirEntry
* dir
, double* v
)
633 if (TIFFFetchData(tif
, dir
, (char*) v
)) {
634 TIFFCvtIEEEDoubleToNative(tif
, dir
->tdir_count
, v
);
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).
652 TIFFFetchAnyArray(TIFF
* tif
, TIFFDirEntry
* dir
, double* v
)
656 switch (dir
->tdir_type
) {
659 if (!TIFFFetchByteArray(tif
, dir
, (uint16
*) v
))
661 if (dir
->tdir_type
== TIFF_BYTE
) {
662 uint16
* vp
= (uint16
*) v
;
663 for (i
= dir
->tdir_count
-1; i
>= 0; i
--)
666 int16
* vp
= (int16
*) v
;
667 for (i
= dir
->tdir_count
-1; i
>= 0; i
--)
673 if (!TIFFFetchShortArray(tif
, dir
, (uint16
*) v
))
675 if (dir
->tdir_type
== TIFF_SHORT
) {
676 uint16
* vp
= (uint16
*) v
;
677 for (i
= dir
->tdir_count
-1; i
>= 0; i
--)
680 int16
* vp
= (int16
*) v
;
681 for (i
= dir
->tdir_count
-1; i
>= 0; i
--)
687 if (!TIFFFetchLongArray(tif
, dir
, (uint32
*) v
))
689 if (dir
->tdir_type
== TIFF_LONG
) {
690 uint32
* vp
= (uint32
*) v
;
691 for (i
= dir
->tdir_count
-1; i
>= 0; i
--)
694 int32
* vp
= (int32
*) v
;
695 for (i
= dir
->tdir_count
-1; i
>= 0; i
--)
701 if (!TIFFFetchRationalArray(tif
, dir
, (float*) v
))
703 { float* vp
= (float*) v
;
704 for (i
= dir
->tdir_count
-1; i
>= 0; i
--)
709 if (!TIFFFetchFloatArray(tif
, dir
, (float*) v
))
711 { float* vp
= (float*) v
;
712 for (i
= dir
->tdir_count
-1; i
>= 0; i
--)
717 return (TIFFFetchDoubleArray(tif
, dir
, (double*) v
));
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
);
732 * Fetch a tag that is not handled by special case code.
734 /* The standard function TIFFFetchNormalTag() could definitely be replaced
735 with a simple call to this function, just adding TIFFSetField() as the
738 TIFFFetchNormalSubTag(TIFF
* tif
, TIFFDirEntry
* dp
, const TIFFFieldInfo
* fip
,
739 int (*setFieldFn
)(TIFF
*tif
, ttag_t tag
, ...))
741 static char mesg
[] = "to fetch tag value";
744 if (dp
->tdir_count
> 1) { /* array of values */
747 switch (dp
->tdir_type
) {
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
);
757 cp
= CheckMalloc(tif
,
758 dp
->tdir_count
* sizeof (uint16
), mesg
);
759 ok
= cp
&& TIFFFetchShortArray(tif
, dp
, (uint16
*) cp
);
763 cp
= CheckMalloc(tif
,
764 dp
->tdir_count
* sizeof (uint32
), mesg
);
765 ok
= cp
&& TIFFFetchLongArray(tif
, dp
, (uint32
*) cp
);
769 cp
= CheckMalloc(tif
,
770 dp
->tdir_count
* sizeof (float), mesg
);
771 ok
= cp
&& TIFFFetchRationalArray(tif
, dp
, (float*) cp
);
774 cp
= CheckMalloc(tif
,
775 dp
->tdir_count
* sizeof (float), mesg
);
776 ok
= cp
&& TIFFFetchFloatArray(tif
, dp
, (float*) cp
);
779 cp
= CheckMalloc(tif
,
780 dp
->tdir_count
* sizeof (double), mesg
);
781 ok
= cp
&& TIFFFetchDoubleArray(tif
, dp
, (double*) cp
);
784 case TIFF_UNDEFINED
: /* bit of a cheat... */
786 * Some vendors write strings w/o the trailing
787 * NULL byte, so always append one just in case.
789 cp
= CheckMalloc(tif
, dp
->tdir_count
+1, mesg
);
790 if (ok
= (cp
&& TIFFFetchString(tif
, dp
, cp
)))
791 cp
[dp
->tdir_count
] = '\0'; /* XXX */
795 ok
= (fip
->field_passcount
?
796 (*setFieldFn
)(tif
, dp
->tdir_tag
, dp
->tdir_count
, cp
)
797 : (*setFieldFn
)(tif
, dp
->tdir_tag
, cp
));
801 } else if (CheckDirCount(tif
, dp
, 1)) { /* singleton value */
802 switch (dp
->tdir_type
) {
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.
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.
820 { TIFFDataType type
= fip
->field_type
;
821 if (type
!= TIFF_LONG
&& type
!= TIFF_SLONG
) {
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
));
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
));
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
));
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
))
861 case TIFF_UNDEFINED
: /* bit of a cheat... */
863 if (ok
= (TIFFFetchString(tif
, dp
, c
) != 0)) {
864 c
[1] = '\0'; /* XXX paranoid */
865 ok
= (*setFieldFn
)(tif
, dp
->tdir_tag
, c
);
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
878 #define NITEMS(x) (sizeof (x) / sizeof (x[0]))
880 * Fetch samples/pixel short values for
881 * the specified tag and verify that
882 * all values are the same.
885 TIFFFetchPerSampleShorts(TIFF
* tif
, TIFFDirEntry
* dir
, int* pl
)
887 int samples
= tif
->tif_dir
.td_samplesperpixel
;
890 if (CheckDirCount(tif
, dir
, (uint32
) samples
)) {
894 if (samples
> NITEMS(buf
))
895 v
= (uint16
*) _TIFFmalloc(samples
* sizeof (uint16
));
896 if (TIFFFetchShortArray(tif
, dir
, v
)) {
898 for (i
= 1; i
< samples
; i
++)
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
);
910 _TIFFfree((char*) v
);
916 * Fetch samples/pixel ANY values for
917 * the specified tag and verify that
918 * all values are the same.
921 TIFFFetchPerSampleAnys(TIFF
* tif
, TIFFDirEntry
* dir
, double* pl
)
923 int samples
= (int) tif
->tif_dir
.td_samplesperpixel
;
926 if (CheckDirCount(tif
, dir
, (uint32
) samples
)) {
930 if (samples
> NITEMS(buf
))
931 v
= (double*) _TIFFmalloc(samples
* sizeof (double));
932 if (TIFFFetchAnyArray(tif
, dir
, v
)) {
934 for (i
= 1; i
< samples
; i
++)
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
);
953 * Fetch a set of offsets or lengths.
954 * While this routine says "strips",
955 * in fact it's also used for tiles.
958 TIFFFetchStripThing(TIFF
* tif
, TIFFDirEntry
* dir
, long nstrips
, uint32
** lpp
)
963 if (!CheckDirCount(tif
, dir
, (uint32
) nstrips
))
966 * Allocate space for strip information.
969 (*lpp
= (uint32
*)CheckMalloc(tif
,
970 nstrips
* sizeof (uint32
), "for strip array")) == NULL
)
973 if (dir
->tdir_type
== (int)TIFF_SHORT
) {
975 * Handle uint16->uint32 expansion.
977 uint16
* dp
= (uint16
*) CheckMalloc(tif
,
978 dir
->tdir_count
* sizeof (uint16
), "to fetch strip tag");
981 if (status
= TIFFFetchShortArray(tif
, dir
, dp
)) {
982 register uint16
* wp
= dp
;
983 while (nstrips
-- > 0)
986 _TIFFfree((char*) dp
);
988 status
= TIFFFetchLongArray(tif
, dir
, lp
);
992 #define NITEMS(x) (sizeof (x) / sizeof (x[0]))
994 * Fetch and set the ExtraSamples tag.
997 TIFFFetchExtraSamples(TIFF
* tif
, TIFFDirEntry
* dir
)
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
);
1008 status
= TIFFFetchShortArray(tif
, dir
, v
);
1010 status
= TIFFSetField(tif
, dir
->tdir_tag
, dir
->tdir_count
, v
);
1012 _TIFFfree((char*) v
);
1017 #ifdef COLORIMETRY_SUPPORT
1019 * Fetch and set the RefBlackWhite tag.
1022 TIFFFetchRefBlackWhite(TIFF
* tif
, TIFFDirEntry
* dir
)
1024 static char mesg
[] = "for \"ReferenceBlackWhite\" array";
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 */);
1031 * Handle LONG's for backward compatibility.
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
)) {
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
);
1051 #if STRIPCHOP_SUPPORT
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
1060 ChopUpSingleUncompressedStrip(TIFF
* tif
)
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
;
1071 * Make the rows hold at least one
1072 * scanline, but fill 8k if possible.
1074 if (rowbytes
> 8192) {
1075 stripbytes
= rowbytes
;
1078 rowsperstrip
= 8192 / rowbytes
;
1079 stripbytes
= rowbytes
* rowsperstrip
;
1081 /* never increase the number of strips in an image */
1082 if (rowsperstrip
>= td
->td_rowsperstrip
)
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
) {
1091 * Unable to allocate new strip information, give
1092 * up and use the original one strip information.
1094 if (newcounts
!= NULL
)
1095 _TIFFfree(newcounts
);
1096 if (newoffsets
!= NULL
)
1097 _TIFFfree(newoffsets
);
1101 * Fill the strip information arrays with
1102 * new bytecounts and offsets that reflect
1103 * the broken-up format.
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
;
1114 * Replace old single strip info with multi-strip info.
1116 td
->td_stripsperimage
= td
->td_nstrips
= nstrips
;
1117 TIFFSetField(tif
, TIFFTAG_ROWSPERSTRIP
, rowsperstrip
);
1119 _TIFFfree(td
->td_stripbytecount
);
1120 _TIFFfree(td
->td_stripoffset
);
1121 td
->td_stripbytecount
= newcounts
;
1122 td
->td_stripoffset
= newoffsets
;
1124 #endif /* STRIPCHOP_SUPPORT */