]> git.saurik.com Git - wxWidgets.git/blame - src/tiff/tif_read.c
Added inline setters for wxTreeEvent so we don't need to add new
[wxWidgets.git] / src / tiff / tif_read.c
CommitLineData
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 * Scanline-oriented Read Support
30 */
31#include "tiffiop.h"
32#include <stdio.h>
33#include <assert.h>
34
35static int TIFFFillStrip(TIFF*, tstrip_t);
36static int TIFFFillTile(TIFF*, ttile_t);
37static int TIFFStartStrip(TIFF*, tstrip_t);
38static int TIFFStartTile(TIFF*, ttile_t);
39static int TIFFCheckRead(TIFF*, int);
40
41#define NOSTRIP ((tstrip_t) -1) /* undefined state */
42#define NOTILE ((ttile_t) -1) /* undefined state */
43
44/*
45 * Seek to a random row+sample in a file.
46 */
47static int
48TIFFSeek(TIFF* tif, uint32 row, tsample_t sample)
49{
50 register TIFFDirectory *td = &tif->tif_dir;
51 tstrip_t strip;
52
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);
56 return (0);
57 }
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);
63 return (0);
64 }
65 strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
66 } else
67 strip = row / td->td_rowsperstrip;
68 if (strip != tif->tif_curstrip) { /* different strip, refill */
69 if (!TIFFFillStrip(tif, strip))
70 return (0);
71 } else if (row < tif->tif_row) {
72 /*
73 * Moving backwards within the same strip: backup
74 * to the start and then decode forward (below).
75 *
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.
79 */
80 if (!TIFFStartStrip(tif, strip))
81 return (0);
82 }
83 if (row != tif->tif_row) {
84 /*
85 * Seek forward to the desired row.
86 */
87 if (!(*tif->tif_seek)(tif, row - tif->tif_row))
88 return (0);
89 tif->tif_row = row;
90 }
91 return (1);
92}
93
94int
95TIFFReadScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample)
96{
97 int e;
98
99 if (!TIFFCheckRead(tif, 0))
100 return (-1);
101 if( (e = TIFFSeek(tif, row, sample)) != 0) {
102 /*
103 * Decompress desired row into user buffer.
104 */
105 e = (*tif->tif_decoderow)
106 (tif, (tidata_t) buf, tif->tif_scanlinesize, sample);
107 tif->tif_row++;
108 if (e)
109 (*tif->tif_postdecode)(tif, (tidata_t) buf,
110 tif->tif_scanlinesize);
111 }
112 return (e > 0 ? 1 : -1);
113}
114
115/*
116 * Read a strip of data and decompress the specified
117 * amount into the user-supplied buffer.
118 */
119tsize_t
120TIFFReadEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size)
121{
122 TIFFDirectory *td = &tif->tif_dir;
123 uint32 nrows;
124 tsize_t stripsize;
125
126 if (!TIFFCheckRead(tif, 0))
127 return (-1);
128 if (strip >= td->td_nstrips) {
129 TIFFError(tif->tif_name, "%ld: Strip out of range, max %ld",
130 (long) strip, (long) td->td_nstrips);
131 return (-1);
132 }
133 /*
134 * Calculate the strip size according to the number of
135 * rows in the strip (check for truncated last strip).
136 */
137 if (strip != td->td_nstrips-1 ||
138 (nrows = td->td_imagelength % td->td_rowsperstrip) == 0)
139 nrows = td->td_rowsperstrip;
140 stripsize = TIFFVStripSize(tif, nrows);
141 if (size == (tsize_t) -1)
142 size = stripsize;
143 else if (size > stripsize)
144 size = stripsize;
145 if (TIFFFillStrip(tif, strip) && (*tif->tif_decodestrip)(tif,
146 (tidata_t) buf, size, (tsample_t)(strip / td->td_stripsperimage))) {
147 (*tif->tif_postdecode)(tif, (tidata_t) buf, size);
148 return (size);
149 } else
150 return ((tsize_t) -1);
151}
152
153static tsize_t
154TIFFReadRawStrip1(TIFF* tif,
155 tstrip_t strip, tdata_t buf, tsize_t size, const char* module)
156{
157 TIFFDirectory *td = &tif->tif_dir;
158
159 if (!isMapped(tif)) {
160 tsize_t cc;
161
162 if (!SeekOK(tif, td->td_stripoffset[strip])) {
163 TIFFError(module,
164 "%s: Seek error at scanline %lu, strip %lu",
165 tif->tif_name,
166 (u_long) tif->tif_row, (u_long) strip);
167 return (-1);
168 }
169 cc = TIFFReadFile(tif, buf, size);
170 if (cc != size) {
171 TIFFError(module,
172 "%s: Read error at scanline %lu; got %lu bytes, expected %lu",
173 tif->tif_name,
174 (u_long) tif->tif_row,
175 (u_long) cc,
176 (u_long) size);
177 return (-1);
178 }
179 } else {
180 if (td->td_stripoffset[strip] + size > tif->tif_size) {
181 TIFFError(module,
182 "%s: Read error at scanline %lu, strip %lu; got %lu bytes, expected %lu",
183 tif->tif_name,
184 (u_long) tif->tif_row,
185 (u_long) strip,
186 (u_long) tif->tif_size - td->td_stripoffset[strip],
187 (u_long) size);
188 return (-1);
189 }
190 _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[strip], size);
191 }
192 return (size);
193}
194
195/*
196 * Read a strip of data from the file.
197 */
198tsize_t
199TIFFReadRawStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size)
200{
201 static const char module[] = "TIFFReadRawStrip";
202 TIFFDirectory *td = &tif->tif_dir;
203 tsize_t bytecount;
204
205 if (!TIFFCheckRead(tif, 0))
206 return ((tsize_t) -1);
207 if (strip >= td->td_nstrips) {
208 TIFFError(tif->tif_name, "%lu: Strip out of range, max %lu",
209 (u_long) strip, (u_long) td->td_nstrips);
210 return ((tsize_t) -1);
211 }
212 bytecount = td->td_stripbytecount[strip];
213 if (bytecount <= 0) {
214 TIFFError(tif->tif_name,
215 "%lu: Invalid strip byte count, strip %lu",
216 (u_long) bytecount, (u_long) strip);
217 return ((tsize_t) -1);
218 }
219 if (size != (tsize_t)-1 && size < bytecount)
220 bytecount = size;
221 return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module));
222}
223
224/*
225 * Read the specified strip and setup for decoding.
226 * The data buffer is expanded, as necessary, to
227 * hold the strip's data.
228 */
229static int
230TIFFFillStrip(TIFF* tif, tstrip_t strip)
231{
232 static const char module[] = "TIFFFillStrip";
233 TIFFDirectory *td = &tif->tif_dir;
234 tsize_t bytecount;
235
236 bytecount = td->td_stripbytecount[strip];
237 if (bytecount <= 0) {
238 TIFFError(tif->tif_name,
239 "%lu: Invalid strip byte count, strip %lu",
240 (u_long) bytecount, (u_long) strip);
241 return (0);
242 }
243 if (isMapped(tif) &&
244 (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) {
245 /*
246 * The image is mapped into memory and we either don't
247 * need to flip bits or the compression routine is going
248 * to handle this operation itself. In this case, avoid
249 * copying the raw data and instead just reference the
250 * data from the memory mapped file image. This assumes
251 * that the decompression routines do not modify the
252 * contents of the raw data buffer (if they try to,
253 * the application will get a fault since the file is
254 * mapped read-only).
255 */
256 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
257 _TIFFfree(tif->tif_rawdata);
258 tif->tif_flags &= ~TIFF_MYBUFFER;
259 if (td->td_stripoffset[strip] + bytecount > tif->tif_size) {
260 /*
261 * This error message might seem strange, but it's
262 * what would happen if a read were done instead.
263 */
264 TIFFError(module,
265 "%s: Read error on strip %lu; got %lu bytes, expected %lu",
266 tif->tif_name,
267 (u_long) strip,
268 (u_long) tif->tif_size - td->td_stripoffset[strip],
269 (u_long) bytecount);
270 tif->tif_curstrip = NOSTRIP;
271 return (0);
272 }
273 tif->tif_rawdatasize = bytecount;
274 tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip];
275 } else {
276 /*
277 * Expand raw data buffer, if needed, to
278 * hold data strip coming from file
279 * (perhaps should set upper bound on
280 * the size of a buffer we'll use?).
281 */
282 if (bytecount > tif->tif_rawdatasize) {
283 tif->tif_curstrip = NOSTRIP;
284 if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
285 TIFFError(module,
286 "%s: Data buffer too small to hold strip %lu",
287 tif->tif_name, (u_long) strip);
288 return (0);
289 }
290 if (!TIFFReadBufferSetup(tif, 0,
291 TIFFroundup(bytecount, 1024)))
292 return (0);
293 }
294 if (TIFFReadRawStrip1(tif, strip, (u_char *)tif->tif_rawdata,
295 bytecount, module) != bytecount)
296 return (0);
297 if (!isFillOrder(tif, td->td_fillorder) &&
298 (tif->tif_flags & TIFF_NOBITREV) == 0)
299 TIFFReverseBits(tif->tif_rawdata, bytecount);
300 }
301 return (TIFFStartStrip(tif, strip));
302}
303
304/*
305 * Tile-oriented Read Support
306 * Contributed by Nancy Cam (Silicon Graphics).
307 */
308
309/*
310 * Read and decompress a tile of data. The
311 * tile is selected by the (x,y,z,s) coordinates.
312 */
313tsize_t
314TIFFReadTile(TIFF* tif,
315 tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s)
316{
317 if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
318 return (-1);
319 return (TIFFReadEncodedTile(tif,
320 TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1));
321}
322
323/*
324 * Read a tile of data and decompress the specified
325 * amount into the user-supplied buffer.
326 */
327tsize_t
328TIFFReadEncodedTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size)
329{
330 TIFFDirectory *td = &tif->tif_dir;
331 tsize_t tilesize = tif->tif_tilesize;
332
333 if (!TIFFCheckRead(tif, 1))
334 return (-1);
335 if (tile >= td->td_nstrips) {
336 TIFFError(tif->tif_name, "%ld: Tile out of range, max %ld",
337 (long) tile, (u_long) td->td_nstrips);
338 return (-1);
339 }
340 if (size == (tsize_t) -1)
341 size = tilesize;
342 else if (size > tilesize)
343 size = tilesize;
344 if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif,
345 (tidata_t) buf, size, (tsample_t)(tile/td->td_stripsperimage))) {
346 (*tif->tif_postdecode)(tif, (tidata_t) buf, size);
347 return (size);
348 } else
349 return (-1);
350}
351
352static tsize_t
353TIFFReadRawTile1(TIFF* tif,
354 ttile_t tile, tdata_t buf, tsize_t size, const char* module)
355{
356 TIFFDirectory *td = &tif->tif_dir;
357
358 if (!isMapped(tif)) {
359 tsize_t cc;
360
361 if (!SeekOK(tif, td->td_stripoffset[tile])) {
362 TIFFError(module,
363 "%s: Seek error at row %ld, col %ld, tile %ld",
364 tif->tif_name,
365 (long) tif->tif_row,
366 (long) tif->tif_col,
367 (long) tile);
368 return ((tsize_t) -1);
369 }
370 cc = TIFFReadFile(tif, buf, size);
371 if (cc != size) {
372 TIFFError(module,
373 "%s: Read error at row %ld, col %ld; got %lu bytes, expected %lu",
374 tif->tif_name,
375 (long) tif->tif_row,
376 (long) tif->tif_col,
377 (u_long) cc,
378 (u_long) size);
379 return ((tsize_t) -1);
380 }
381 } else {
382 if (td->td_stripoffset[tile] + size > tif->tif_size) {
383 TIFFError(module,
384 "%s: Read error at row %ld, col %ld, tile %ld; got %lu bytes, expected %lu",
385 tif->tif_name,
386 (long) tif->tif_row,
387 (long) tif->tif_col,
388 (long) tile,
389 (u_long) tif->tif_size - td->td_stripoffset[tile],
390 (u_long) size);
391 return ((tsize_t) -1);
392 }
393 _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[tile], size);
394 }
395 return (size);
396}
397
398/*
399 * Read a tile of data from the file.
400 */
401tsize_t
402TIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size)
403{
404 static const char module[] = "TIFFReadRawTile";
405 TIFFDirectory *td = &tif->tif_dir;
406 tsize_t bytecount;
407
408 if (!TIFFCheckRead(tif, 1))
409 return ((tsize_t) -1);
410 if (tile >= td->td_nstrips) {
411 TIFFError(tif->tif_name, "%lu: Tile out of range, max %lu",
412 (u_long) tile, (u_long) td->td_nstrips);
413 return ((tsize_t) -1);
414 }
415 bytecount = td->td_stripbytecount[tile];
416 if (size != (tsize_t) -1 && size < bytecount)
417 bytecount = size;
418 return (TIFFReadRawTile1(tif, tile, buf, bytecount, module));
419}
420
421/*
422 * Read the specified tile and setup for decoding.
423 * The data buffer is expanded, as necessary, to
424 * hold the tile's data.
425 */
426static int
427TIFFFillTile(TIFF* tif, ttile_t tile)
428{
429 static const char module[] = "TIFFFillTile";
430 TIFFDirectory *td = &tif->tif_dir;
431 tsize_t bytecount;
432
433 bytecount = td->td_stripbytecount[tile];
434 if (bytecount <= 0) {
435 TIFFError(tif->tif_name,
436 "%lu: Invalid tile byte count, tile %lu",
437 (u_long) bytecount, (u_long) tile);
438 return (0);
439 }
440 if (isMapped(tif) &&
441 (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) {
442 /*
443 * The image is mapped into memory and we either don't
444 * need to flip bits or the compression routine is going
445 * to handle this operation itself. In this case, avoid
446 * copying the raw data and instead just reference the
447 * data from the memory mapped file image. This assumes
448 * that the decompression routines do not modify the
449 * contents of the raw data buffer (if they try to,
450 * the application will get a fault since the file is
451 * mapped read-only).
452 */
453 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
454 _TIFFfree(tif->tif_rawdata);
455 tif->tif_flags &= ~TIFF_MYBUFFER;
456 if (td->td_stripoffset[tile] + bytecount > tif->tif_size) {
457 tif->tif_curtile = NOTILE;
458 return (0);
459 }
460 tif->tif_rawdatasize = bytecount;
461 tif->tif_rawdata = tif->tif_base + td->td_stripoffset[tile];
462 } else {
463 /*
464 * Expand raw data buffer, if needed, to
465 * hold data tile coming from file
466 * (perhaps should set upper bound on
467 * the size of a buffer we'll use?).
468 */
469 if (bytecount > tif->tif_rawdatasize) {
470 tif->tif_curtile = NOTILE;
471 if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
472 TIFFError(module,
473 "%s: Data buffer too small to hold tile %ld",
474 tif->tif_name, (long) tile);
475 return (0);
476 }
477 if (!TIFFReadBufferSetup(tif, 0,
478 TIFFroundup(bytecount, 1024)))
479 return (0);
480 }
481 if (TIFFReadRawTile1(tif, tile, (u_char *)tif->tif_rawdata,
482 bytecount, module) != bytecount)
483 return (0);
484 if (!isFillOrder(tif, td->td_fillorder) &&
485 (tif->tif_flags & TIFF_NOBITREV) == 0)
486 TIFFReverseBits(tif->tif_rawdata, bytecount);
487 }
488 return (TIFFStartTile(tif, tile));
489}
490
491/*
492 * Setup the raw data buffer in preparation for
493 * reading a strip of raw data. If the buffer
494 * is specified as zero, then a buffer of appropriate
495 * size is allocated by the library. Otherwise,
496 * the client must guarantee that the buffer is
497 * large enough to hold any individual strip of
498 * raw data.
499 */
500int
501TIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size)
502{
503 static const char module[] = "TIFFReadBufferSetup";
504
505 if (tif->tif_rawdata) {
506 if (tif->tif_flags & TIFF_MYBUFFER)
507 _TIFFfree(tif->tif_rawdata);
508 tif->tif_rawdata = NULL;
509 }
510 if (bp) {
511 tif->tif_rawdatasize = size;
512 tif->tif_rawdata = (tidata_t) bp;
513 tif->tif_flags &= ~TIFF_MYBUFFER;
514 } else {
515 tif->tif_rawdatasize = TIFFroundup(size, 1024);
516 tif->tif_rawdata = (tidata_t) _TIFFmalloc(tif->tif_rawdatasize);
517 tif->tif_flags |= TIFF_MYBUFFER;
518 }
519 if (tif->tif_rawdata == NULL) {
520 TIFFError(module,
521 "%s: No space for data buffer at scanline %ld",
522 tif->tif_name, (long) tif->tif_row);
523 tif->tif_rawdatasize = 0;
524 return (0);
525 }
526 return (1);
527}
528
529/*
530 * Set state to appear as if a
531 * strip has just been read in.
532 */
533static int
534TIFFStartStrip(TIFF* tif, tstrip_t strip)
535{
536 TIFFDirectory *td = &tif->tif_dir;
537
538 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
539 if (!(*tif->tif_setupdecode)(tif))
540 return (0);
541 tif->tif_flags |= TIFF_CODERSETUP;
542 }
543 tif->tif_curstrip = strip;
544 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
545 tif->tif_rawcp = tif->tif_rawdata;
546 tif->tif_rawcc = td->td_stripbytecount[strip];
547 return ((*tif->tif_predecode)(tif,
548 (tsample_t)(strip / td->td_stripsperimage)));
549}
550
551/*
552 * Set state to appear as if a
553 * tile has just been read in.
554 */
555static int
556TIFFStartTile(TIFF* tif, ttile_t tile)
557{
558 TIFFDirectory *td = &tif->tif_dir;
559
560 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
561 if (!(*tif->tif_setupdecode)(tif))
562 return (0);
563 tif->tif_flags |= TIFF_CODERSETUP;
564 }
565 tif->tif_curtile = tile;
566 tif->tif_row =
567 (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) *
568 td->td_tilelength;
569 tif->tif_col =
570 (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength)) *
571 td->td_tilewidth;
572 tif->tif_rawcp = tif->tif_rawdata;
573 tif->tif_rawcc = td->td_stripbytecount[tile];
574 return ((*tif->tif_predecode)(tif,
575 (tsample_t)(tile/td->td_stripsperimage)));
576}
577
578static int
579TIFFCheckRead(TIFF* tif, int tiles)
580{
581 if (tif->tif_mode == O_WRONLY) {
582 TIFFError(tif->tif_name, "File not open for reading");
583 return (0);
584 }
585 if (tiles ^ isTiled(tif)) {
586 TIFFError(tif->tif_name, tiles ?
587 "Can not read tiles from a stripped image" :
588 "Can not read scanlines from a tiled image");
589 return (0);
590 }
591 return (1);
592}
593
594void
595_TIFFNoPostDecode(TIFF* tif, tidata_t buf, tsize_t cc)
596{
597 (void) tif; (void) buf; (void) cc;
598}
599
600void
601_TIFFSwab16BitData(TIFF* tif, tidata_t buf, tsize_t cc)
602{
603 (void) tif;
604 assert((cc & 1) == 0);
605 TIFFSwabArrayOfShort((uint16*) buf, cc/2);
606}
607
608void
609_TIFFSwab32BitData(TIFF* tif, tidata_t buf, tsize_t cc)
610{
611 (void) tif;
612 assert((cc & 3) == 0);
613 TIFFSwabArrayOfLong((uint32*) buf, cc/4);
614}
615
616void
617_TIFFSwab64BitData(TIFF* tif, tidata_t buf, tsize_t cc)
618{
619 (void) tif;
620 assert((cc & 7) == 0);
621 TIFFSwabArrayOfDouble((double*) buf, cc/8);
622}