]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/tif_read.c
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
29 * Scanline-oriented Read Support
35 int TIFFFillStrip(TIFF
*, tstrip_t
);
36 int TIFFFillTile(TIFF
*, ttile_t
);
37 static int TIFFStartStrip(TIFF
*, tstrip_t
);
38 static int TIFFStartTile(TIFF
*, ttile_t
);
39 static int TIFFCheckRead(TIFF
*, int);
41 #define NOSTRIP ((tstrip_t) -1) /* undefined state */
42 #define NOTILE ((ttile_t) -1) /* undefined state */
45 * Seek to a random row+sample in a file.
48 TIFFSeek(TIFF
* tif
, uint32 row
, tsample_t sample
)
50 register TIFFDirectory
*td
= &tif
->tif_dir
;
53 if (row
>= td
->td_imagelength
) { /* out of range */
54 TIFFError(tif
->tif_name
, "%lu: Row out of range, max %lu",
55 (u_long
) row
, (u_long
) td
->td_imagelength
);
58 if (td
->td_planarconfig
== PLANARCONFIG_SEPARATE
) {
59 if (sample
>= td
->td_samplesperpixel
) {
60 TIFFError(tif
->tif_name
,
61 "%lu: Sample out of range, max %lu",
62 (u_long
) sample
, (u_long
) td
->td_samplesperpixel
);
65 strip
= sample
*td
->td_stripsperimage
+ row
/td
->td_rowsperstrip
;
67 strip
= row
/ td
->td_rowsperstrip
;
68 if (strip
!= tif
->tif_curstrip
) { /* different strip, refill */
69 if (!TIFFFillStrip(tif
, strip
))
71 } else if (row
< tif
->tif_row
) {
73 * Moving backwards within the same strip: backup
74 * to the start and then decode forward (below).
76 * NB: If you're planning on lots of random access within a
77 * strip, it's better to just read and decode the entire
78 * strip, and then access the decoded data in a random fashion.
80 if (!TIFFStartStrip(tif
, strip
))
83 if (row
!= tif
->tif_row
) {
85 * Seek forward to the desired row.
87 if (!(*tif
->tif_seek
)(tif
, row
- tif
->tif_row
))
95 TIFFReadScanline(TIFF
* tif
, tdata_t buf
, uint32 row
, tsample_t sample
)
99 if (!TIFFCheckRead(tif
, 0))
101 if( (e
= TIFFSeek(tif
, row
, sample
)) != 0) {
103 * Decompress desired row into user buffer.
105 e
= (*tif
->tif_decoderow
)
106 (tif
, (tidata_t
) buf
, tif
->tif_scanlinesize
, sample
);
108 /* we are now poised at the beginning of the next row */
109 tif
->tif_row
= row
+ 1;
112 (*tif
->tif_postdecode
)(tif
, (tidata_t
) buf
,
113 tif
->tif_scanlinesize
);
115 return (e
> 0 ? 1 : -1);
119 * Read a strip of data and decompress the specified
120 * amount into the user-supplied buffer.
123 TIFFReadEncodedStrip(TIFF
* tif
, tstrip_t strip
, tdata_t buf
, tsize_t size
)
125 TIFFDirectory
*td
= &tif
->tif_dir
;
128 tstrip_t sep_strip
, strips_per_sep
;
130 if (!TIFFCheckRead(tif
, 0))
132 if (strip
>= td
->td_nstrips
) {
133 TIFFError(tif
->tif_name
, "%ld: Strip out of range, max %ld",
134 (long) strip
, (long) td
->td_nstrips
);
138 * Calculate the strip size according to the number of
139 * rows in the strip (check for truncated last strip on any
140 * of the separations).
142 if( td
->td_rowsperstrip
>= td
->td_imagelength
)
145 strips_per_sep
= (td
->td_imagelength
+td
->td_rowsperstrip
-1)
146 / td
->td_rowsperstrip
;
148 sep_strip
= strip
% strips_per_sep
;
150 if (sep_strip
!= strips_per_sep
-1 ||
151 (nrows
= td
->td_imagelength
% td
->td_rowsperstrip
) == 0)
152 nrows
= td
->td_rowsperstrip
;
154 stripsize
= TIFFVStripSize(tif
, nrows
);
155 if (size
== (tsize_t
) -1)
157 else if (size
> stripsize
)
159 if (TIFFFillStrip(tif
, strip
)
160 && (*tif
->tif_decodestrip
)(tif
, (tidata_t
) buf
, size
,
161 (tsample_t
)(strip
/ td
->td_stripsperimage
)) > 0 ) {
162 (*tif
->tif_postdecode
)(tif
, (tidata_t
) buf
, size
);
165 return ((tsize_t
) -1);
169 TIFFReadRawStrip1(TIFF
* tif
,
170 tstrip_t strip
, tdata_t buf
, tsize_t size
, const char* module)
172 TIFFDirectory
*td
= &tif
->tif_dir
;
174 if (!isMapped(tif
)) {
177 if (!SeekOK(tif
, td
->td_stripoffset
[strip
])) {
179 "%s: Seek error at scanline %lu, strip %lu",
181 (u_long
) tif
->tif_row
, (u_long
) strip
);
184 cc
= TIFFReadFile(tif
, buf
, size
);
187 "%s: Read error at scanline %lu; got %lu bytes, expected %lu",
189 (u_long
) tif
->tif_row
,
195 if (td
->td_stripoffset
[strip
] + size
> tif
->tif_size
) {
197 "%s: Read error at scanline %lu, strip %lu; got %lu bytes, expected %lu",
199 (u_long
) tif
->tif_row
,
201 (u_long
) tif
->tif_size
- td
->td_stripoffset
[strip
],
205 _TIFFmemcpy(buf
, tif
->tif_base
+ td
->td_stripoffset
[strip
], size
);
211 * Read a strip of data from the file.
214 TIFFReadRawStrip(TIFF
* tif
, tstrip_t strip
, tdata_t buf
, tsize_t size
)
216 static const char module[] = "TIFFReadRawStrip";
217 TIFFDirectory
*td
= &tif
->tif_dir
;
220 if (!TIFFCheckRead(tif
, 0))
221 return ((tsize_t
) -1);
222 if (strip
>= td
->td_nstrips
) {
223 TIFFError(tif
->tif_name
, "%lu: Strip out of range, max %lu",
224 (u_long
) strip
, (u_long
) td
->td_nstrips
);
225 return ((tsize_t
) -1);
227 bytecount
= td
->td_stripbytecount
[strip
];
228 if (bytecount
<= 0) {
229 TIFFError(tif
->tif_name
,
230 "%lu: Invalid strip byte count, strip %lu",
231 (u_long
) bytecount
, (u_long
) strip
);
232 return ((tsize_t
) -1);
234 if (size
!= (tsize_t
)-1 && size
< bytecount
)
236 return (TIFFReadRawStrip1(tif
, strip
, buf
, bytecount
, module));
240 * Read the specified strip and setup for decoding.
241 * The data buffer is expanded, as necessary, to
242 * hold the strip's data.
245 TIFFFillStrip(TIFF
* tif
, tstrip_t strip
)
247 static const char module[] = "TIFFFillStrip";
248 TIFFDirectory
*td
= &tif
->tif_dir
;
251 bytecount
= td
->td_stripbytecount
[strip
];
252 if (bytecount
<= 0) {
253 TIFFError(tif
->tif_name
,
254 "%lu: Invalid strip byte count, strip %lu",
255 (u_long
) bytecount
, (u_long
) strip
);
259 (isFillOrder(tif
, td
->td_fillorder
) || (tif
->tif_flags
& TIFF_NOBITREV
))) {
261 * The image is mapped into memory and we either don't
262 * need to flip bits or the compression routine is going
263 * to handle this operation itself. In this case, avoid
264 * copying the raw data and instead just reference the
265 * data from the memory mapped file image. This assumes
266 * that the decompression routines do not modify the
267 * contents of the raw data buffer (if they try to,
268 * the application will get a fault since the file is
271 if ((tif
->tif_flags
& TIFF_MYBUFFER
) && tif
->tif_rawdata
)
272 _TIFFfree(tif
->tif_rawdata
);
273 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
274 if ( td
->td_stripoffset
[strip
] + bytecount
> tif
->tif_size
) {
276 * This error message might seem strange, but it's
277 * what would happen if a read were done instead.
280 "%s: Read error on strip %lu; got %lu bytes, expected %lu",
283 (u_long
) tif
->tif_size
- td
->td_stripoffset
[strip
],
285 tif
->tif_curstrip
= NOSTRIP
;
288 tif
->tif_rawdatasize
= bytecount
;
289 tif
->tif_rawdata
= tif
->tif_base
+ td
->td_stripoffset
[strip
];
292 * Expand raw data buffer, if needed, to
293 * hold data strip coming from file
294 * (perhaps should set upper bound on
295 * the size of a buffer we'll use?).
297 if (bytecount
> tif
->tif_rawdatasize
) {
298 tif
->tif_curstrip
= NOSTRIP
;
299 if ((tif
->tif_flags
& TIFF_MYBUFFER
) == 0) {
301 "%s: Data buffer too small to hold strip %lu",
302 tif
->tif_name
, (u_long
) strip
);
305 if (!TIFFReadBufferSetup(tif
, 0,
306 TIFFroundup(bytecount
, 1024)))
309 if (TIFFReadRawStrip1(tif
, strip
, (u_char
*)tif
->tif_rawdata
,
310 bytecount
, module) != bytecount
)
312 if (!isFillOrder(tif
, td
->td_fillorder
) &&
313 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
314 TIFFReverseBits(tif
->tif_rawdata
, bytecount
);
316 return (TIFFStartStrip(tif
, strip
));
320 * Tile-oriented Read Support
321 * Contributed by Nancy Cam (Silicon Graphics).
325 * Read and decompress a tile of data. The
326 * tile is selected by the (x,y,z,s) coordinates.
329 TIFFReadTile(TIFF
* tif
,
330 tdata_t buf
, uint32 x
, uint32 y
, uint32 z
, tsample_t s
)
332 if (!TIFFCheckRead(tif
, 1) || !TIFFCheckTile(tif
, x
, y
, z
, s
))
334 return (TIFFReadEncodedTile(tif
,
335 TIFFComputeTile(tif
, x
, y
, z
, s
), buf
, (tsize_t
) -1));
339 * Read a tile of data and decompress the specified
340 * amount into the user-supplied buffer.
343 TIFFReadEncodedTile(TIFF
* tif
, ttile_t tile
, tdata_t buf
, tsize_t size
)
345 TIFFDirectory
*td
= &tif
->tif_dir
;
346 tsize_t tilesize
= tif
->tif_tilesize
;
348 if (!TIFFCheckRead(tif
, 1))
350 if (tile
>= td
->td_nstrips
) {
351 TIFFError(tif
->tif_name
, "%ld: Tile out of range, max %ld",
352 (long) tile
, (u_long
) td
->td_nstrips
);
355 if (size
== (tsize_t
) -1)
357 else if (size
> tilesize
)
359 if (TIFFFillTile(tif
, tile
) && (*tif
->tif_decodetile
)(tif
,
360 (tidata_t
) buf
, size
, (tsample_t
)(tile
/td
->td_stripsperimage
))) {
361 (*tif
->tif_postdecode
)(tif
, (tidata_t
) buf
, size
);
368 TIFFReadRawTile1(TIFF
* tif
,
369 ttile_t tile
, tdata_t buf
, tsize_t size
, const char* module)
371 TIFFDirectory
*td
= &tif
->tif_dir
;
373 if (!isMapped(tif
)) {
376 if (!SeekOK(tif
, td
->td_stripoffset
[tile
])) {
378 "%s: Seek error at row %ld, col %ld, tile %ld",
383 return ((tsize_t
) -1);
385 cc
= TIFFReadFile(tif
, buf
, size
);
388 "%s: Read error at row %ld, col %ld; got %lu bytes, expected %lu",
394 return ((tsize_t
) -1);
397 if (td
->td_stripoffset
[tile
] + size
> tif
->tif_size
) {
399 "%s: Read error at row %ld, col %ld, tile %ld; got %lu bytes, expected %lu",
404 (u_long
) tif
->tif_size
- td
->td_stripoffset
[tile
],
406 return ((tsize_t
) -1);
408 _TIFFmemcpy(buf
, tif
->tif_base
+ td
->td_stripoffset
[tile
], size
);
414 * Read a tile of data from the file.
417 TIFFReadRawTile(TIFF
* tif
, ttile_t tile
, tdata_t buf
, tsize_t size
)
419 static const char module[] = "TIFFReadRawTile";
420 TIFFDirectory
*td
= &tif
->tif_dir
;
423 if (!TIFFCheckRead(tif
, 1))
424 return ((tsize_t
) -1);
425 if (tile
>= td
->td_nstrips
) {
426 TIFFError(tif
->tif_name
, "%lu: Tile out of range, max %lu",
427 (u_long
) tile
, (u_long
) td
->td_nstrips
);
428 return ((tsize_t
) -1);
430 bytecount
= td
->td_stripbytecount
[tile
];
431 if (size
!= (tsize_t
) -1 && size
< bytecount
)
433 return (TIFFReadRawTile1(tif
, tile
, buf
, bytecount
, module));
437 * Read the specified tile and setup for decoding.
438 * The data buffer is expanded, as necessary, to
439 * hold the tile's data.
442 TIFFFillTile(TIFF
* tif
, ttile_t tile
)
444 static const char module[] = "TIFFFillTile";
445 TIFFDirectory
*td
= &tif
->tif_dir
;
448 bytecount
= td
->td_stripbytecount
[tile
];
449 if (bytecount
<= 0) {
450 TIFFError(tif
->tif_name
,
451 "%lu: Invalid tile byte count, tile %lu",
452 (u_long
) bytecount
, (u_long
) tile
);
456 (isFillOrder(tif
, td
->td_fillorder
) || (tif
->tif_flags
& TIFF_NOBITREV
))) {
458 * The image is mapped into memory and we either don't
459 * need to flip bits or the compression routine is going
460 * to handle this operation itself. In this case, avoid
461 * copying the raw data and instead just reference the
462 * data from the memory mapped file image. This assumes
463 * that the decompression routines do not modify the
464 * contents of the raw data buffer (if they try to,
465 * the application will get a fault since the file is
468 if ((tif
->tif_flags
& TIFF_MYBUFFER
) && tif
->tif_rawdata
)
469 _TIFFfree(tif
->tif_rawdata
);
470 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
471 if ( td
->td_stripoffset
[tile
] + bytecount
> tif
->tif_size
) {
472 tif
->tif_curtile
= NOTILE
;
475 tif
->tif_rawdatasize
= bytecount
;
476 tif
->tif_rawdata
= tif
->tif_base
+ td
->td_stripoffset
[tile
];
479 * Expand raw data buffer, if needed, to
480 * hold data tile coming from file
481 * (perhaps should set upper bound on
482 * the size of a buffer we'll use?).
484 if (bytecount
> tif
->tif_rawdatasize
) {
485 tif
->tif_curtile
= NOTILE
;
486 if ((tif
->tif_flags
& TIFF_MYBUFFER
) == 0) {
488 "%s: Data buffer too small to hold tile %ld",
489 tif
->tif_name
, (long) tile
);
492 if (!TIFFReadBufferSetup(tif
, 0,
493 TIFFroundup(bytecount
, 1024)))
496 if (TIFFReadRawTile1(tif
, tile
, (u_char
*)tif
->tif_rawdata
,
497 bytecount
, module) != bytecount
)
499 if (!isFillOrder(tif
, td
->td_fillorder
) &&
500 (tif
->tif_flags
& TIFF_NOBITREV
) == 0)
501 TIFFReverseBits(tif
->tif_rawdata
, bytecount
);
503 return (TIFFStartTile(tif
, tile
));
507 * Setup the raw data buffer in preparation for
508 * reading a strip of raw data. If the buffer
509 * is specified as zero, then a buffer of appropriate
510 * size is allocated by the library. Otherwise,
511 * the client must guarantee that the buffer is
512 * large enough to hold any individual strip of
516 TIFFReadBufferSetup(TIFF
* tif
, tdata_t bp
, tsize_t size
)
518 static const char module[] = "TIFFReadBufferSetup";
520 if (tif
->tif_rawdata
) {
521 if (tif
->tif_flags
& TIFF_MYBUFFER
)
522 _TIFFfree(tif
->tif_rawdata
);
523 tif
->tif_rawdata
= NULL
;
526 tif
->tif_rawdatasize
= size
;
527 tif
->tif_rawdata
= (tidata_t
) bp
;
528 tif
->tif_flags
&= ~TIFF_MYBUFFER
;
530 tif
->tif_rawdatasize
= TIFFroundup(size
, 1024);
531 tif
->tif_rawdata
= (tidata_t
) _TIFFmalloc(tif
->tif_rawdatasize
);
532 tif
->tif_flags
|= TIFF_MYBUFFER
;
534 if (tif
->tif_rawdata
== NULL
) {
536 "%s: No space for data buffer at scanline %ld",
537 tif
->tif_name
, (long) tif
->tif_row
);
538 tif
->tif_rawdatasize
= 0;
545 * Set state to appear as if a
546 * strip has just been read in.
549 TIFFStartStrip(TIFF
* tif
, tstrip_t strip
)
551 TIFFDirectory
*td
= &tif
->tif_dir
;
553 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
554 if (!(*tif
->tif_setupdecode
)(tif
))
556 tif
->tif_flags
|= TIFF_CODERSETUP
;
558 tif
->tif_curstrip
= strip
;
559 tif
->tif_row
= (strip
% td
->td_stripsperimage
) * td
->td_rowsperstrip
;
560 tif
->tif_rawcp
= tif
->tif_rawdata
;
561 tif
->tif_rawcc
= td
->td_stripbytecount
[strip
];
562 return ((*tif
->tif_predecode
)(tif
,
563 (tsample_t
)(strip
/ td
->td_stripsperimage
)));
567 * Set state to appear as if a
568 * tile has just been read in.
571 TIFFStartTile(TIFF
* tif
, ttile_t tile
)
573 TIFFDirectory
*td
= &tif
->tif_dir
;
575 if ((tif
->tif_flags
& TIFF_CODERSETUP
) == 0) {
576 if (!(*tif
->tif_setupdecode
)(tif
))
578 tif
->tif_flags
|= TIFF_CODERSETUP
;
580 tif
->tif_curtile
= tile
;
582 (tile
% TIFFhowmany(td
->td_imagewidth
, td
->td_tilewidth
)) *
585 (tile
% TIFFhowmany(td
->td_imagelength
, td
->td_tilelength
)) *
587 tif
->tif_rawcp
= tif
->tif_rawdata
;
588 tif
->tif_rawcc
= td
->td_stripbytecount
[tile
];
589 return ((*tif
->tif_predecode
)(tif
,
590 (tsample_t
)(tile
/td
->td_stripsperimage
)));
594 TIFFCheckRead(TIFF
* tif
, int tiles
)
596 if (tif
->tif_mode
== O_WRONLY
) {
597 TIFFError(tif
->tif_name
, "File not open for reading");
600 if (tiles
^ isTiled(tif
)) {
601 TIFFError(tif
->tif_name
, tiles
?
602 "Can not read tiles from a stripped image" :
603 "Can not read scanlines from a tiled image");
610 _TIFFNoPostDecode(TIFF
* tif
, tidata_t buf
, tsize_t cc
)
612 (void) tif
; (void) buf
; (void) cc
;
616 _TIFFSwab16BitData(TIFF
* tif
, tidata_t buf
, tsize_t cc
)
619 assert((cc
& 1) == 0);
620 TIFFSwabArrayOfShort((uint16
*) buf
, cc
/2);
624 _TIFFSwab32BitData(TIFF
* tif
, tidata_t buf
, tsize_t cc
)
627 assert((cc
& 3) == 0);
628 TIFFSwabArrayOfLong((uint32
*) buf
, cc
/4);
632 _TIFFSwab64BitData(TIFF
* tif
, tidata_t buf
, tsize_t cc
)
635 assert((cc
& 7) == 0);
636 TIFFSwabArrayOfDouble((double*) buf
, cc
/8);