1 : /* $Id: tif_read.c,v 1.29 2007/11/23 20:49:43 fwarmerdam Exp $ */
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 :
34 : int TIFFFillStrip(TIFF* tif, uint32 strip);
35 : int TIFFFillTile(TIFF* tif, uint32 tile);
36 : static int TIFFStartStrip(TIFF* tif, uint32 strip);
37 : static int TIFFStartTile(TIFF* tif, uint32 tile);
38 : static int TIFFCheckRead(TIFF*, int);
39 :
40 : #define NOSTRIP ((uint32)(-1)) /* undefined state */
41 : #define NOTILE ((uint32)(-1)) /* undefined state */
42 :
43 : /*
44 : * Seek to a random row+sample in a file.
45 : */
46 : static int
47 137048 : TIFFSeek(TIFF* tif, uint32 row, uint16 sample)
48 : {
49 137048 : register TIFFDirectory *td = &tif->tif_dir;
50 : uint32 strip;
51 :
52 137048 : if (row >= td->td_imagelength) { /* out of range */
53 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
54 : "%lu: Row out of range, max %lu",
55 : (unsigned long) row,
56 : (unsigned long) td->td_imagelength);
57 0 : return (0);
58 : }
59 137048 : if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
60 64244 : if (sample >= td->td_samplesperpixel) {
61 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
62 : "%lu: Sample out of range, max %lu",
63 : (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
64 0 : return (0);
65 : }
66 64244 : strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowsperstrip;
67 : } else
68 72804 : strip = row / td->td_rowsperstrip;
69 137048 : if (strip != tif->tif_curstrip) { /* different strip, refill */
70 25 : if (!TIFFFillStrip(tif, strip))
71 0 : return (0);
72 137023 : } else if (row < tif->tif_row) {
73 : /*
74 : * Moving backwards within the same strip: backup
75 : * to the start and then decode forward (below).
76 : *
77 : * NB: If you're planning on lots of random access within a
78 : * strip, it's better to just read and decode the entire
79 : * strip, and then access the decoded data in a random fashion.
80 : */
81 22 : if (!TIFFStartStrip(tif, strip))
82 0 : return (0);
83 : }
84 137048 : if (row != tif->tif_row) {
85 : /*
86 : * Seek forward to the desired row.
87 : */
88 0 : if (!(*tif->tif_seek)(tif, row - tif->tif_row))
89 0 : return (0);
90 0 : tif->tif_row = row;
91 : }
92 137048 : return (1);
93 : }
94 :
95 : int
96 137048 : TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
97 : {
98 : int e;
99 :
100 137048 : if (!TIFFCheckRead(tif, 0))
101 0 : return (-1);
102 137048 : if( (e = TIFFSeek(tif, row, sample)) != 0) {
103 : /*
104 : * Decompress desired row into user buffer.
105 : */
106 137048 : e = (*tif->tif_decoderow)
107 : (tif, (uint8*) buf, tif->tif_scanlinesize, sample);
108 :
109 : /* we are now poised at the beginning of the next row */
110 137048 : tif->tif_row = row + 1;
111 :
112 137048 : if (e)
113 137048 : (*tif->tif_postdecode)(tif, (uint8*) buf,
114 : tif->tif_scanlinesize);
115 : }
116 137048 : return (e > 0 ? 1 : -1);
117 : }
118 :
119 : /*
120 : * Read a strip of data and decompress the specified
121 : * amount into the user-supplied buffer.
122 : */
123 : tmsize_t
124 3118 : TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
125 : {
126 : static const char module[] = "TIFFReadEncodedStrip";
127 3118 : TIFFDirectory *td = &tif->tif_dir;
128 : uint32 rowsperstrip;
129 : uint32 stripsperplane;
130 : uint32 stripinplane;
131 : uint16 plane;
132 : uint32 rows;
133 : tmsize_t stripsize;
134 3118 : if (!TIFFCheckRead(tif,0))
135 0 : return((tmsize_t)(-1));
136 3118 : if (strip>=td->td_nstrips)
137 : {
138 0 : TIFFErrorExt(tif->tif_clientdata,module,
139 : "%lu: Strip out of range, max %lu",(unsigned long)strip,
140 : (unsigned long)td->td_nstrips);
141 0 : return((tmsize_t)(-1));
142 : }
143 : /*
144 : * Calculate the strip size according to the number of
145 : * rows in the strip (check for truncated last strip on any
146 : * of the separations).
147 : */
148 3118 : rowsperstrip=td->td_rowsperstrip;
149 3118 : if (rowsperstrip>td->td_imagelength)
150 6 : rowsperstrip=td->td_imagelength;
151 3118 : stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
152 3118 : stripinplane=(strip%stripsperplane);
153 3118 : plane=(strip/stripsperplane);
154 3118 : rows=td->td_imagelength-stripinplane*rowsperstrip;
155 3118 : if (rows>rowsperstrip)
156 1736 : rows=rowsperstrip;
157 3118 : stripsize=TIFFVStripSize(tif,rows);
158 3118 : if (stripsize==0)
159 0 : return((tmsize_t)(-1));
160 3118 : if ((size!=(tmsize_t)(-1))&&(size<stripsize))
161 0 : stripsize=size;
162 3118 : if (!TIFFFillStrip(tif,strip))
163 0 : return((tmsize_t)(-1));
164 3118 : if ((*tif->tif_decodestrip)(tif,buf,stripsize,plane)<=0)
165 0 : return((tmsize_t)(-1));
166 3118 : (*tif->tif_postdecode)(tif,buf,stripsize);
167 3118 : return(stripsize);
168 : }
169 :
170 : static tmsize_t
171 3143 : TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
172 : const char* module)
173 : {
174 3143 : TIFFDirectory *td = &tif->tif_dir;
175 :
176 3143 : assert((tif->tif_flags&TIFF_NOREADRAW)==0);
177 3143 : if (!isMapped(tif)) {
178 : tmsize_t cc;
179 :
180 3143 : if (!SeekOK(tif, td->td_stripoffset[strip])) {
181 0 : TIFFErrorExt(tif->tif_clientdata, module,
182 : "Seek error at scanline %lu, strip %lu",
183 : (unsigned long) tif->tif_row, (unsigned long) strip);
184 0 : return ((tmsize_t)(-1));
185 : }
186 3143 : cc = TIFFReadFile(tif, buf, size);
187 3143 : if (cc != size) {
188 : #if defined(__WIN32__) && defined(_MSC_VER)
189 : TIFFErrorExt(tif->tif_clientdata, module,
190 : "Read error at scanline %lu; got %I64u bytes, expected %I64u",
191 : (unsigned long) tif->tif_row,
192 : (unsigned __int64) cc,
193 : (unsigned __int64) size);
194 : #else
195 0 : TIFFErrorExt(tif->tif_clientdata, module,
196 : "Read error at scanline %lu; got %llu bytes, expected %llu",
197 : (unsigned long) tif->tif_row,
198 : (unsigned long long) cc,
199 : (unsigned long long) size);
200 : #endif
201 0 : return ((tmsize_t)(-1));
202 : }
203 : } else {
204 : tmsize_t ma,mb;
205 : tmsize_t n;
206 0 : ma=(tmsize_t)td->td_stripoffset[strip];
207 0 : mb=ma+size;
208 0 : if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size))
209 0 : n=0;
210 0 : else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
211 0 : n=tif->tif_size-ma;
212 : else
213 0 : n=size;
214 0 : if (n!=size) {
215 : #if defined(__WIN32__) && defined(_MSC_VER)
216 : TIFFErrorExt(tif->tif_clientdata, module,
217 : "Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u",
218 : (unsigned long) tif->tif_row,
219 : (unsigned long) strip,
220 : (unsigned __int64) n,
221 : (unsigned __int64) size);
222 : #else
223 0 : TIFFErrorExt(tif->tif_clientdata, module,
224 : "Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu",
225 : (unsigned long) tif->tif_row,
226 : (unsigned long) strip,
227 : (unsigned long long) n,
228 : (unsigned long long) size);
229 : #endif
230 0 : return ((tmsize_t)(-1));
231 : }
232 0 : _TIFFmemcpy(buf, tif->tif_base + ma,
233 : size);
234 : }
235 3143 : return (size);
236 : }
237 :
238 : /*
239 : * Read a strip of data from the file.
240 : */
241 : tmsize_t
242 0 : TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
243 : {
244 : static const char module[] = "TIFFReadRawStrip";
245 0 : TIFFDirectory *td = &tif->tif_dir;
246 : uint64 bytecount;
247 : tmsize_t bytecountm;
248 :
249 0 : if (!TIFFCheckRead(tif, 0))
250 0 : return ((tmsize_t)(-1));
251 0 : if (strip >= td->td_nstrips) {
252 0 : TIFFErrorExt(tif->tif_clientdata, module,
253 : "%lu: Strip out of range, max %lu",
254 : (unsigned long) strip,
255 : (unsigned long) td->td_nstrips);
256 0 : return ((tmsize_t)(-1));
257 : }
258 0 : if (tif->tif_flags&TIFF_NOREADRAW)
259 : {
260 0 : TIFFErrorExt(tif->tif_clientdata, module,
261 : "Compression scheme does not support access to raw uncompressed data");
262 0 : return ((tmsize_t)(-1));
263 : }
264 0 : bytecount = td->td_stripbytecount[strip];
265 0 : if (bytecount <= 0) {
266 : #if defined(__WIN32__) && defined(_MSC_VER)
267 : TIFFErrorExt(tif->tif_clientdata, module,
268 : "%I64u: Invalid strip byte count, strip %lu",
269 : (unsigned __int64) bytecount,
270 : (unsigned long) strip);
271 : #else
272 0 : TIFFErrorExt(tif->tif_clientdata, module,
273 : "%llu: Invalid strip byte count, strip %lu",
274 : (unsigned long long) bytecount,
275 : (unsigned long) strip);
276 : #endif
277 0 : return ((tmsize_t)(-1));
278 : }
279 0 : bytecountm = (tmsize_t)bytecount;
280 0 : if ((uint64)bytecountm!=bytecount) {
281 0 : TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
282 0 : return ((tmsize_t)(-1));
283 : }
284 0 : if (size != (tmsize_t)(-1) && size < bytecountm)
285 0 : bytecountm = size;
286 0 : return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
287 : }
288 :
289 : /*
290 : * Read the specified strip and setup for decoding. The data buffer is
291 : * expanded, as necessary, to hold the strip's data.
292 : */
293 : int
294 3143 : TIFFFillStrip(TIFF* tif, uint32 strip)
295 : {
296 : static const char module[] = "TIFFFillStrip";
297 3143 : TIFFDirectory *td = &tif->tif_dir;
298 :
299 3143 : if ((tif->tif_flags&TIFF_NOREADRAW)==0)
300 : {
301 3143 : uint64 bytecount = td->td_stripbytecount[strip];
302 3143 : if (bytecount <= 0) {
303 : #if defined(__WIN32__) && defined(_MSC_VER)
304 : TIFFErrorExt(tif->tif_clientdata, module,
305 : "Invalid strip byte count %I64u, strip %lu",
306 : (unsigned __int64) bytecount,
307 : (unsigned long) strip);
308 : #else
309 0 : TIFFErrorExt(tif->tif_clientdata, module,
310 : "Invalid strip byte count %llu, strip %lu",
311 : (unsigned long long) bytecount,
312 : (unsigned long) strip);
313 : #endif
314 0 : return (0);
315 : }
316 3143 : if (isMapped(tif) &&
317 0 : (isFillOrder(tif, td->td_fillorder)
318 0 : || (tif->tif_flags & TIFF_NOBITREV))) {
319 : /*
320 : * The image is mapped into memory and we either don't
321 : * need to flip bits or the compression routine is
322 : * going to handle this operation itself. In this
323 : * case, avoid copying the raw data and instead just
324 : * reference the data from the memory mapped file
325 : * image. This assumes that the decompression
326 : * routines do not modify the contents of the raw data
327 : * buffer (if they try to, the application will get a
328 : * fault since the file is mapped read-only).
329 : */
330 0 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
331 0 : _TIFFfree(tif->tif_rawdata);
332 0 : tif->tif_flags &= ~TIFF_MYBUFFER;
333 : /*
334 : * We must check for overflow, potentially causing
335 : * an OOB read. Instead of simple
336 : *
337 : * td->td_stripoffset[strip]+bytecount > tif->tif_size
338 : *
339 : * comparison (which can overflow) we do the following
340 : * two comparisons:
341 : */
342 0 : if (bytecount > (uint64)tif->tif_size ||
343 0 : td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
344 : /*
345 : * This error message might seem strange, but
346 : * it's what would happen if a read were done
347 : * instead.
348 : */
349 : #if defined(__WIN32__) && defined(_MSC_VER)
350 : TIFFErrorExt(tif->tif_clientdata, module,
351 :
352 : "Read error on strip %lu; "
353 : "got %I64u bytes, expected %I64u",
354 : (unsigned long) strip,
355 : (unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
356 : (unsigned __int64) bytecount);
357 : #else
358 0 : TIFFErrorExt(tif->tif_clientdata, module,
359 :
360 : "Read error on strip %lu; "
361 : "got %llu bytes, expected %llu",
362 : (unsigned long) strip,
363 0 : (unsigned long long) tif->tif_size - td->td_stripoffset[strip],
364 : (unsigned long long) bytecount);
365 : #endif
366 0 : tif->tif_curstrip = NOSTRIP;
367 0 : return (0);
368 : }
369 0 : tif->tif_rawdatasize = (tmsize_t)bytecount;
370 0 : tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
371 : } else {
372 : /*
373 : * Expand raw data buffer, if needed, to hold data
374 : * strip coming from file (perhaps should set upper
375 : * bound on the size of a buffer we'll use?).
376 : */
377 : tmsize_t bytecountm;
378 3143 : bytecountm=(tmsize_t)bytecount;
379 3143 : if ((uint64)bytecountm!=bytecount)
380 : {
381 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
382 0 : return(0);
383 : }
384 3143 : if (bytecountm > tif->tif_rawdatasize) {
385 1337 : tif->tif_curstrip = NOSTRIP;
386 1337 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
387 0 : TIFFErrorExt(tif->tif_clientdata, module,
388 : "Data buffer too small to hold strip %lu",
389 : (unsigned long) strip);
390 0 : return (0);
391 : }
392 1337 : if (!TIFFReadBufferSetup(tif, 0, bytecountm))
393 0 : return (0);
394 : }
395 3143 : if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
396 : bytecountm, module) != bytecountm)
397 0 : return (0);
398 3143 : if (!isFillOrder(tif, td->td_fillorder) &&
399 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
400 0 : TIFFReverseBits(tif->tif_rawdata, bytecountm);
401 : }
402 : }
403 3143 : return (TIFFStartStrip(tif, strip));
404 : }
405 :
406 : /*
407 : * Tile-oriented Read Support
408 : * Contributed by Nancy Cam (Silicon Graphics).
409 : */
410 :
411 : /*
412 : * Read and decompress a tile of data. The
413 : * tile is selected by the (x,y,z,s) coordinates.
414 : */
415 : tmsize_t
416 0 : TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
417 : {
418 0 : if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
419 0 : return ((tmsize_t)(-1));
420 0 : return (TIFFReadEncodedTile(tif,
421 : TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
422 : }
423 :
424 : /*
425 : * Read a tile of data and decompress the specified
426 : * amount into the user-supplied buffer.
427 : */
428 : tmsize_t
429 552 : TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
430 : {
431 : static const char module[] = "TIFFReadEncodedTile";
432 552 : TIFFDirectory *td = &tif->tif_dir;
433 552 : tmsize_t tilesize = tif->tif_tilesize;
434 :
435 552 : if (!TIFFCheckRead(tif, 1))
436 0 : return ((tmsize_t)(-1));
437 552 : if (tile >= td->td_nstrips) {
438 0 : TIFFErrorExt(tif->tif_clientdata, module,
439 : "%lu: Tile out of range, max %lu",
440 : (unsigned long) tile, (unsigned long) td->td_nstrips);
441 0 : return ((tmsize_t)(-1));
442 : }
443 552 : if (size == (tmsize_t)(-1))
444 0 : size = tilesize;
445 552 : else if (size > tilesize)
446 0 : size = tilesize;
447 1104 : if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif,
448 552 : (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) {
449 552 : (*tif->tif_postdecode)(tif, (uint8*) buf, size);
450 552 : return (size);
451 : } else
452 0 : return ((tmsize_t)(-1));
453 : }
454 :
455 : static tmsize_t
456 552 : TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
457 : {
458 552 : TIFFDirectory *td = &tif->tif_dir;
459 :
460 552 : assert((tif->tif_flags&TIFF_NOREADRAW)==0);
461 552 : if (!isMapped(tif)) {
462 : tmsize_t cc;
463 :
464 552 : if (!SeekOK(tif, td->td_stripoffset[tile])) {
465 0 : TIFFErrorExt(tif->tif_clientdata, module,
466 : "Seek error at row %lu, col %lu, tile %lu",
467 : (unsigned long) tif->tif_row,
468 : (unsigned long) tif->tif_col,
469 : (unsigned long) tile);
470 0 : return ((tmsize_t)(-1));
471 : }
472 552 : cc = TIFFReadFile(tif, buf, size);
473 552 : if (cc != size) {
474 : #if defined(__WIN32__) && defined(_MSC_VER)
475 : TIFFErrorExt(tif->tif_clientdata, module,
476 : "Read error at row %lu, col %lu; got %I64u bytes, expected %I64u",
477 : (unsigned long) tif->tif_row,
478 : (unsigned long) tif->tif_col,
479 : (unsigned __int64) cc,
480 : (unsigned __int64) size);
481 : #else
482 0 : TIFFErrorExt(tif->tif_clientdata, module,
483 : "Read error at row %lu, col %lu; got %llu bytes, expected %llu",
484 : (unsigned long) tif->tif_row,
485 : (unsigned long) tif->tif_col,
486 : (unsigned long long) cc,
487 : (unsigned long long) size);
488 : #endif
489 0 : return ((tmsize_t)(-1));
490 : }
491 : } else {
492 : tmsize_t ma,mb;
493 : tmsize_t n;
494 0 : ma=(tmsize_t)td->td_stripoffset[tile];
495 0 : mb=ma+size;
496 0 : if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size))
497 0 : n=0;
498 0 : else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
499 0 : n=tif->tif_size-ma;
500 : else
501 0 : n=size;
502 0 : if (n!=size) {
503 : #if defined(__WIN32__) && defined(_MSC_VER)
504 : TIFFErrorExt(tif->tif_clientdata, module,
505 : "Read error at row %lu, col %lu, tile %lu; got %I64u bytes, expected %I64u",
506 : (unsigned long) tif->tif_row,
507 : (unsigned long) tif->tif_col,
508 : (unsigned long) tile,
509 : (unsigned __int64) n,
510 : (unsigned __int64) size);
511 : #else
512 0 : TIFFErrorExt(tif->tif_clientdata, module,
513 : "Read error at row %lu, col %lu, tile %lu; got %llu bytes, expected %llu",
514 : (unsigned long) tif->tif_row,
515 : (unsigned long) tif->tif_col,
516 : (unsigned long) tile,
517 : (unsigned long long) n,
518 : (unsigned long long) size);
519 : #endif
520 0 : return ((tmsize_t)(-1));
521 : }
522 0 : _TIFFmemcpy(buf, tif->tif_base + ma, size);
523 : }
524 552 : return (size);
525 : }
526 :
527 : /*
528 : * Read a tile of data from the file.
529 : */
530 : tmsize_t
531 0 : TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
532 : {
533 : static const char module[] = "TIFFReadRawTile";
534 0 : TIFFDirectory *td = &tif->tif_dir;
535 : uint64 bytecount64;
536 : tmsize_t bytecountm;
537 :
538 0 : if (!TIFFCheckRead(tif, 1))
539 0 : return ((tmsize_t)(-1));
540 0 : if (tile >= td->td_nstrips) {
541 0 : TIFFErrorExt(tif->tif_clientdata, module,
542 : "%lu: Tile out of range, max %lu",
543 : (unsigned long) tile, (unsigned long) td->td_nstrips);
544 0 : return ((tmsize_t)(-1));
545 : }
546 0 : if (tif->tif_flags&TIFF_NOREADRAW)
547 : {
548 0 : TIFFErrorExt(tif->tif_clientdata, module,
549 : "Compression scheme does not support access to raw uncompressed data");
550 0 : return ((tmsize_t)(-1));
551 : }
552 0 : bytecount64 = td->td_stripbytecount[tile];
553 0 : if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
554 0 : bytecount64 = (uint64)size;
555 0 : bytecountm = (tmsize_t)bytecount64;
556 0 : if ((uint64)bytecountm!=bytecount64)
557 : {
558 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
559 0 : return ((tmsize_t)(-1));
560 : }
561 0 : return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
562 : }
563 :
564 : /*
565 : * Read the specified tile and setup for decoding. The data buffer is
566 : * expanded, as necessary, to hold the tile's data.
567 : */
568 : int
569 552 : TIFFFillTile(TIFF* tif, uint32 tile)
570 : {
571 : static const char module[] = "TIFFFillTile";
572 552 : TIFFDirectory *td = &tif->tif_dir;
573 :
574 552 : if ((tif->tif_flags&TIFF_NOREADRAW)==0)
575 : {
576 552 : uint64 bytecount = td->td_stripbytecount[tile];
577 552 : if (bytecount <= 0) {
578 : #if defined(__WIN32__) && defined(_MSC_VER)
579 : TIFFErrorExt(tif->tif_clientdata, module,
580 : "%I64u: Invalid tile byte count, tile %lu",
581 : (unsigned __int64) bytecount,
582 : (unsigned long) tile);
583 : #else
584 0 : TIFFErrorExt(tif->tif_clientdata, module,
585 : "%llu: Invalid tile byte count, tile %lu",
586 : (unsigned long long) bytecount,
587 : (unsigned long) tile);
588 : #endif
589 0 : return (0);
590 : }
591 552 : if (isMapped(tif) &&
592 0 : (isFillOrder(tif, td->td_fillorder)
593 0 : || (tif->tif_flags & TIFF_NOBITREV))) {
594 : /*
595 : * The image is mapped into memory and we either don't
596 : * need to flip bits or the compression routine is
597 : * going to handle this operation itself. In this
598 : * case, avoid copying the raw data and instead just
599 : * reference the data from the memory mapped file
600 : * image. This assumes that the decompression
601 : * routines do not modify the contents of the raw data
602 : * buffer (if they try to, the application will get a
603 : * fault since the file is mapped read-only).
604 : */
605 0 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
606 0 : _TIFFfree(tif->tif_rawdata);
607 0 : tif->tif_flags &= ~TIFF_MYBUFFER;
608 : /*
609 : * We must check for overflow, potentially causing
610 : * an OOB read. Instead of simple
611 : *
612 : * td->td_stripoffset[tile]+bytecount > tif->tif_size
613 : *
614 : * comparison (which can overflow) we do the following
615 : * two comparisons:
616 : */
617 0 : if (bytecount > (uint64)tif->tif_size ||
618 0 : td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
619 0 : tif->tif_curtile = NOTILE;
620 0 : return (0);
621 : }
622 0 : tif->tif_rawdatasize = (tmsize_t)bytecount;
623 0 : tif->tif_rawdata =
624 0 : tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
625 : } else {
626 : /*
627 : * Expand raw data buffer, if needed, to hold data
628 : * tile coming from file (perhaps should set upper
629 : * bound on the size of a buffer we'll use?).
630 : */
631 : tmsize_t bytecountm;
632 552 : bytecountm=(tmsize_t)bytecount;
633 552 : if ((uint64)bytecountm!=bytecount)
634 : {
635 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
636 0 : return(0);
637 : }
638 552 : if (bytecountm > tif->tif_rawdatasize) {
639 62 : tif->tif_curtile = NOTILE;
640 62 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
641 0 : TIFFErrorExt(tif->tif_clientdata, module,
642 : "Data buffer too small to hold tile %lu",
643 : (unsigned long) tile);
644 0 : return (0);
645 : }
646 62 : if (!TIFFReadBufferSetup(tif, 0, bytecountm))
647 0 : return (0);
648 : }
649 552 : if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
650 : bytecountm, module) != bytecountm)
651 0 : return (0);
652 552 : if (!isFillOrder(tif, td->td_fillorder) &&
653 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
654 0 : TIFFReverseBits(tif->tif_rawdata, bytecountm);
655 : }
656 : }
657 552 : return (TIFFStartTile(tif, tile));
658 : }
659 :
660 : /*
661 : * Setup the raw data buffer in preparation for
662 : * reading a strip of raw data. If the buffer
663 : * is specified as zero, then a buffer of appropriate
664 : * size is allocated by the library. Otherwise,
665 : * the client must guarantee that the buffer is
666 : * large enough to hold any individual strip of
667 : * raw data.
668 : */
669 : int
670 1399 : TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
671 : {
672 : static const char module[] = "TIFFReadBufferSetup";
673 :
674 1399 : assert((tif->tif_flags&TIFF_NOREADRAW)==0);
675 1399 : if (tif->tif_rawdata) {
676 17 : if (tif->tif_flags & TIFF_MYBUFFER)
677 17 : _TIFFfree(tif->tif_rawdata);
678 17 : tif->tif_rawdata = NULL;
679 : }
680 1399 : if (bp) {
681 0 : tif->tif_rawdatasize = size;
682 0 : tif->tif_rawdata = (uint8*) bp;
683 0 : tif->tif_flags &= ~TIFF_MYBUFFER;
684 : } else {
685 1399 : tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024);
686 1399 : if (tif->tif_rawdatasize==0)
687 0 : tif->tif_rawdatasize=(tmsize_t)(-1);
688 1399 : tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
689 1399 : tif->tif_flags |= TIFF_MYBUFFER;
690 : }
691 1399 : if (tif->tif_rawdata == NULL) {
692 0 : TIFFErrorExt(tif->tif_clientdata, module,
693 : "No space for data buffer at scanline %lu",
694 : (unsigned long) tif->tif_row);
695 0 : tif->tif_rawdatasize = 0;
696 0 : return (0);
697 : }
698 1399 : return (1);
699 : }
700 :
701 : /*
702 : * Set state to appear as if a
703 : * strip has just been read in.
704 : */
705 : static int
706 3165 : TIFFStartStrip(TIFF* tif, uint32 strip)
707 : {
708 3165 : TIFFDirectory *td = &tif->tif_dir;
709 :
710 3165 : if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
711 1324 : if (!(*tif->tif_setupdecode)(tif))
712 0 : return (0);
713 1324 : tif->tif_flags |= TIFF_CODERSETUP;
714 : }
715 3165 : tif->tif_curstrip = strip;
716 3165 : tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
717 3165 : tif->tif_flags &= ~TIFF_BUF4WRITE;
718 :
719 3165 : if (tif->tif_flags&TIFF_NOREADRAW)
720 : {
721 0 : tif->tif_rawcp = NULL;
722 0 : tif->tif_rawcc = 0;
723 : }
724 : else
725 : {
726 3165 : tif->tif_rawcp = tif->tif_rawdata;
727 3165 : tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
728 : }
729 6330 : return ((*tif->tif_predecode)(tif,
730 3165 : (uint16)(strip / td->td_stripsperimage)));
731 : }
732 :
733 : /*
734 : * Set state to appear as if a
735 : * tile has just been read in.
736 : */
737 : static int
738 552 : TIFFStartTile(TIFF* tif, uint32 tile)
739 : {
740 552 : TIFFDirectory *td = &tif->tif_dir;
741 :
742 552 : if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
743 50 : if (!(*tif->tif_setupdecode)(tif))
744 0 : return (0);
745 50 : tif->tif_flags |= TIFF_CODERSETUP;
746 : }
747 552 : tif->tif_curtile = tile;
748 552 : tif->tif_row =
749 552 : (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) *
750 : td->td_tilelength;
751 552 : tif->tif_col =
752 552 : (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) *
753 : td->td_tilewidth;
754 552 : tif->tif_flags &= ~TIFF_BUF4WRITE;
755 552 : if (tif->tif_flags&TIFF_NOREADRAW)
756 : {
757 0 : tif->tif_rawcp = NULL;
758 0 : tif->tif_rawcc = 0;
759 : }
760 : else
761 : {
762 552 : tif->tif_rawcp = tif->tif_rawdata;
763 552 : tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
764 : }
765 1104 : return ((*tif->tif_predecode)(tif,
766 552 : (uint16)(tile/td->td_stripsperimage)));
767 : }
768 :
769 : static int
770 140718 : TIFFCheckRead(TIFF* tif, int tiles)
771 : {
772 140718 : if (tif->tif_mode == O_WRONLY) {
773 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");
774 0 : return (0);
775 : }
776 140718 : if (tiles ^ isTiled(tif)) {
777 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
778 : "Can not read tiles from a stripped image" :
779 : "Can not read scanlines from a tiled image");
780 0 : return (0);
781 : }
782 140718 : return (1);
783 : }
784 :
785 : void
786 237245 : _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
787 : {
788 : (void) tif; (void) buf; (void) cc;
789 237245 : }
790 :
791 : void
792 0 : _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc)
793 : {
794 : (void) tif;
795 0 : assert((cc & 1) == 0);
796 0 : TIFFSwabArrayOfShort((uint16*) buf, cc/2);
797 0 : }
798 :
799 : void
800 0 : _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc)
801 : {
802 : (void) tif;
803 0 : assert((cc % 3) == 0);
804 0 : TIFFSwabArrayOfTriples((uint8*) buf, cc/3);
805 0 : }
806 :
807 : void
808 15 : _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc)
809 : {
810 : (void) tif;
811 15 : assert((cc & 3) == 0);
812 15 : TIFFSwabArrayOfLong((uint32*) buf, cc/4);
813 15 : }
814 :
815 : void
816 0 : _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc)
817 : {
818 : (void) tif;
819 0 : assert((cc & 7) == 0);
820 0 : TIFFSwabArrayOfDouble((double*) buf, cc/8);
821 0 : }
822 :
823 : /* vim: set ts=8 sts=8 sw=8 noet: */
|