1 : /* $Id: tif_read.c,v 1.38 2011-12-09 03:29:10 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 : static tmsize_t
40 : TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,const char* module);
41 :
42 : #define NOSTRIP ((uint32)(-1)) /* undefined state */
43 : #define NOTILE ((uint32)(-1)) /* undefined state */
44 :
45 : static int
46 30 : TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
47 : {
48 : static const char module[] = "TIFFFillStripPartial";
49 30 : register TIFFDirectory *td = &tif->tif_dir;
50 : uint64 unused_data;
51 : uint64 read_offset;
52 : tmsize_t cc, to_read;
53 : tmsize_t bytecountm;
54 :
55 30 : if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
56 0 : return 0;
57 :
58 : /*
59 : * Expand raw data buffer, if needed, to hold data
60 : * strip coming from file (perhaps should set upper
61 : * bound on the size of a buffer we'll use?).
62 : */
63 :
64 30 : bytecountm=(tmsize_t) td->td_stripbytecount[strip];
65 30 : if (read_ahead*2 > tif->tif_rawdatasize) {
66 8 : assert( restart );
67 :
68 8 : tif->tif_curstrip = NOSTRIP;
69 8 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
70 0 : TIFFErrorExt(tif->tif_clientdata, module,
71 : "Data buffer too small to hold part of strip %lu",
72 : (unsigned long) strip);
73 0 : return (0);
74 : }
75 8 : if (!TIFFReadBufferSetup(tif, 0, read_ahead*2))
76 0 : return (0);
77 : }
78 :
79 30 : if( restart )
80 : {
81 26 : tif->tif_rawdataloaded = 0;
82 26 : tif->tif_rawdataoff = 0;
83 : }
84 :
85 : /*
86 : ** If we are reading more data, move any unused data to the
87 : ** start of the buffer.
88 : */
89 30 : if( tif->tif_rawdataloaded > 0 )
90 3 : unused_data = tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata);
91 : else
92 27 : unused_data = 0;
93 :
94 30 : if( unused_data > 0 )
95 : {
96 3 : memmove( tif->tif_rawdata, tif->tif_rawcp, unused_data );
97 : }
98 :
99 : /*
100 : ** Seek to the point in the file where more data should be read.
101 : */
102 60 : read_offset = td->td_stripoffset[strip]
103 30 : + tif->tif_rawdataoff + tif->tif_rawdataloaded;
104 :
105 30 : if (!SeekOK(tif, read_offset)) {
106 0 : TIFFErrorExt(tif->tif_clientdata, module,
107 : "Seek error at scanline %lu, strip %lu",
108 : (unsigned long) tif->tif_row, (unsigned long) strip);
109 0 : return 0;
110 : }
111 :
112 : /*
113 : ** How much do we want to read?
114 : */
115 30 : to_read = tif->tif_rawdatasize - unused_data;
116 60 : if( (uint64) to_read > td->td_stripbytecount[strip]
117 30 : - tif->tif_rawdataoff - tif->tif_rawdataloaded )
118 : {
119 54 : to_read = td->td_stripbytecount[strip]
120 27 : - tif->tif_rawdataoff - tif->tif_rawdataloaded;
121 : }
122 :
123 30 : cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read);
124 :
125 30 : if (cc != to_read) {
126 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
127 : TIFFErrorExt(tif->tif_clientdata, module,
128 : "Read error at scanline %lu; got %I64u bytes, expected %I64u",
129 : (unsigned long) tif->tif_row,
130 : (unsigned __int64) cc,
131 : (unsigned __int64) to_read);
132 : #else
133 0 : TIFFErrorExt(tif->tif_clientdata, module,
134 : "Read error at scanline %lu; got %llu bytes, expected %llu",
135 : (unsigned long) tif->tif_row,
136 : (unsigned long long) cc,
137 : (unsigned long long) to_read);
138 : #endif
139 0 : return 0;
140 : }
141 :
142 30 : tif->tif_rawdataoff = tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data ;
143 30 : tif->tif_rawdataloaded = unused_data + to_read;
144 :
145 30 : tif->tif_rawcp = tif->tif_rawdata;
146 :
147 30 : if (!isFillOrder(tif, td->td_fillorder) &&
148 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
149 0 : TIFFReverseBits(tif->tif_rawdata + unused_data, to_read );
150 :
151 : /*
152 : ** When starting a strip from the beginning we need to
153 : ** restart the decoder.
154 : */
155 30 : if( restart )
156 26 : return TIFFStartStrip(tif, strip);
157 : else
158 4 : return 1;
159 : }
160 :
161 : /*
162 : * Seek to a random row+sample in a file.
163 : *
164 : * Only used by TIFFReadScanline, and is only used on
165 : * strip organized files. We do some tricky stuff to try
166 : * and avoid reading the whole compressed raw data for big
167 : * strips.
168 : */
169 : static int
170 140760 : TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
171 : {
172 140760 : register TIFFDirectory *td = &tif->tif_dir;
173 : uint32 strip;
174 : int whole_strip;
175 140760 : tmsize_t read_ahead = 0;
176 :
177 : /*
178 : ** Establish what strip we are working from.
179 : */
180 140760 : if (row >= td->td_imagelength) { /* out of range */
181 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
182 : "%lu: Row out of range, max %lu",
183 : (unsigned long) row,
184 : (unsigned long) td->td_imagelength);
185 0 : return (0);
186 : }
187 140760 : if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
188 64244 : if (sample >= td->td_samplesperpixel) {
189 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
190 : "%lu: Sample out of range, max %lu",
191 : (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
192 0 : return (0);
193 : }
194 64244 : strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowsperstrip;
195 : } else
196 76516 : strip = row / td->td_rowsperstrip;
197 :
198 : /*
199 : * Do we want to treat this strip as one whole chunk or
200 : * read it a few lines at a time?
201 : */
202 : #if defined(CHUNKY_STRIP_READ_SUPPORT)
203 140760 : if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
204 0 : return 0;
205 281520 : whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10
206 140760 : || isMapped(tif);
207 : #else
208 : whole_strip = 1;
209 : #endif
210 :
211 140760 : if( !whole_strip )
212 : {
213 140760 : read_ahead = tif->tif_scanlinesize * 16 + 5000;
214 : }
215 :
216 : /*
217 : * If we haven't loaded this strip, do so now, possibly
218 : * only reading the first part.
219 : */
220 140760 : if (strip != tif->tif_curstrip) { /* different strip, refill */
221 :
222 26 : if( whole_strip )
223 : {
224 0 : if (!TIFFFillStrip(tif, strip))
225 0 : return (0);
226 : }
227 : else
228 : {
229 26 : if( !TIFFFillStripPartial(tif,strip,read_ahead,1) )
230 0 : return 0;
231 : }
232 : }
233 :
234 : /*
235 : ** If we already have some data loaded, do we need to read some more?
236 : */
237 140734 : else if( !whole_strip )
238 : {
239 275818 : if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead
240 135084 : && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] )
241 : {
242 4 : if( !TIFFFillStripPartial(tif,strip,read_ahead,0) )
243 0 : return 0;
244 : }
245 : }
246 :
247 140760 : if (row < tif->tif_row) {
248 : /*
249 : * Moving backwards within the same strip: backup
250 : * to the start and then decode forward (below).
251 : *
252 : * NB: If you're planning on lots of random access within a
253 : * strip, it's better to just read and decode the entire
254 : * strip, and then access the decoded data in a random fashion.
255 : */
256 :
257 22 : if( tif->tif_rawdataoff != 0 )
258 : {
259 0 : if( !TIFFFillStripPartial(tif,strip,read_ahead,1) )
260 0 : return 0;
261 : }
262 : else
263 : {
264 22 : if (!TIFFStartStrip(tif, strip))
265 0 : return (0);
266 : }
267 : }
268 :
269 140760 : if (row != tif->tif_row) {
270 : /*
271 : * Seek forward to the desired row.
272 : */
273 :
274 : /* TODO: Will this really work with partial buffers? */
275 :
276 0 : if (!(*tif->tif_seek)(tif, row - tif->tif_row))
277 0 : return (0);
278 0 : tif->tif_row = row;
279 : }
280 :
281 140760 : return (1);
282 : }
283 :
284 : int
285 140760 : TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
286 : {
287 : int e;
288 :
289 140760 : if (!TIFFCheckRead(tif, 0))
290 0 : return (-1);
291 140760 : if( (e = TIFFSeek(tif, row, sample)) != 0) {
292 : /*
293 : * Decompress desired row into user buffer.
294 : */
295 140760 : e = (*tif->tif_decoderow)
296 : (tif, (uint8*) buf, tif->tif_scanlinesize, sample);
297 :
298 : /* we are now poised at the beginning of the next row */
299 140760 : tif->tif_row = row + 1;
300 :
301 140760 : if (e)
302 140760 : (*tif->tif_postdecode)(tif, (uint8*) buf,
303 : tif->tif_scanlinesize);
304 : }
305 140760 : return (e > 0 ? 1 : -1);
306 : }
307 :
308 : /*
309 : * Read a strip of data and decompress the specified
310 : * amount into the user-supplied buffer.
311 : */
312 : tmsize_t
313 5959 : TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
314 : {
315 : static const char module[] = "TIFFReadEncodedStrip";
316 5959 : TIFFDirectory *td = &tif->tif_dir;
317 : uint32 rowsperstrip;
318 : uint32 stripsperplane;
319 : uint32 stripinplane;
320 : uint16 plane;
321 : uint32 rows;
322 : tmsize_t stripsize;
323 5959 : if (!TIFFCheckRead(tif,0))
324 0 : return((tmsize_t)(-1));
325 5959 : if (strip>=td->td_nstrips)
326 : {
327 0 : TIFFErrorExt(tif->tif_clientdata,module,
328 : "%lu: Strip out of range, max %lu",(unsigned long)strip,
329 : (unsigned long)td->td_nstrips);
330 0 : return((tmsize_t)(-1));
331 : }
332 : /*
333 : * Calculate the strip size according to the number of
334 : * rows in the strip (check for truncated last strip on any
335 : * of the separations).
336 : */
337 5959 : rowsperstrip=td->td_rowsperstrip;
338 5959 : if (rowsperstrip>td->td_imagelength)
339 8 : rowsperstrip=td->td_imagelength;
340 5959 : stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
341 5959 : stripinplane=(strip%stripsperplane);
342 5959 : plane=(strip/stripsperplane);
343 5959 : rows=td->td_imagelength-stripinplane*rowsperstrip;
344 5959 : if (rows>rowsperstrip)
345 4160 : rows=rowsperstrip;
346 5959 : stripsize=TIFFVStripSize(tif,rows);
347 5959 : if (stripsize==0)
348 0 : return((tmsize_t)(-1));
349 5959 : if ((size!=(tmsize_t)(-1))&&(size<stripsize))
350 0 : stripsize=size;
351 5959 : if (!TIFFFillStrip(tif,strip))
352 0 : return((tmsize_t)(-1));
353 5959 : if ((*tif->tif_decodestrip)(tif,buf,stripsize,plane)<=0)
354 2 : return((tmsize_t)(-1));
355 5957 : (*tif->tif_postdecode)(tif,buf,stripsize);
356 5957 : return(stripsize);
357 : }
358 :
359 : static tmsize_t
360 5959 : TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
361 : const char* module)
362 : {
363 5959 : TIFFDirectory *td = &tif->tif_dir;
364 :
365 5959 : if (!_TIFFFillStriles( tif ))
366 0 : return ((tmsize_t)(-1));
367 :
368 5959 : assert((tif->tif_flags&TIFF_NOREADRAW)==0);
369 5959 : if (!isMapped(tif)) {
370 : tmsize_t cc;
371 :
372 5959 : if (!SeekOK(tif, td->td_stripoffset[strip])) {
373 0 : TIFFErrorExt(tif->tif_clientdata, module,
374 : "Seek error at scanline %lu, strip %lu",
375 : (unsigned long) tif->tif_row, (unsigned long) strip);
376 0 : return ((tmsize_t)(-1));
377 : }
378 5959 : cc = TIFFReadFile(tif, buf, size);
379 5959 : if (cc != size) {
380 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
381 : TIFFErrorExt(tif->tif_clientdata, module,
382 : "Read error at scanline %lu; got %I64u bytes, expected %I64u",
383 : (unsigned long) tif->tif_row,
384 : (unsigned __int64) cc,
385 : (unsigned __int64) size);
386 : #else
387 0 : TIFFErrorExt(tif->tif_clientdata, module,
388 : "Read error at scanline %lu; got %llu bytes, expected %llu",
389 : (unsigned long) tif->tif_row,
390 : (unsigned long long) cc,
391 : (unsigned long long) size);
392 : #endif
393 0 : return ((tmsize_t)(-1));
394 : }
395 : } else {
396 : tmsize_t ma,mb;
397 : tmsize_t n;
398 0 : ma=(tmsize_t)td->td_stripoffset[strip];
399 0 : mb=ma+size;
400 0 : if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size))
401 0 : n=0;
402 0 : else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
403 0 : n=tif->tif_size-ma;
404 : else
405 0 : n=size;
406 0 : if (n!=size) {
407 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
408 : TIFFErrorExt(tif->tif_clientdata, module,
409 : "Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u",
410 : (unsigned long) tif->tif_row,
411 : (unsigned long) strip,
412 : (unsigned __int64) n,
413 : (unsigned __int64) size);
414 : #else
415 0 : TIFFErrorExt(tif->tif_clientdata, module,
416 : "Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu",
417 : (unsigned long) tif->tif_row,
418 : (unsigned long) strip,
419 : (unsigned long long) n,
420 : (unsigned long long) size);
421 : #endif
422 0 : return ((tmsize_t)(-1));
423 : }
424 0 : _TIFFmemcpy(buf, tif->tif_base + ma,
425 : size);
426 : }
427 5959 : return (size);
428 : }
429 :
430 : /*
431 : * Read a strip of data from the file.
432 : */
433 : tmsize_t
434 0 : TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
435 : {
436 : static const char module[] = "TIFFReadRawStrip";
437 0 : TIFFDirectory *td = &tif->tif_dir;
438 : uint64 bytecount;
439 : tmsize_t bytecountm;
440 :
441 0 : if (!TIFFCheckRead(tif, 0))
442 0 : return ((tmsize_t)(-1));
443 0 : if (strip >= td->td_nstrips) {
444 0 : TIFFErrorExt(tif->tif_clientdata, module,
445 : "%lu: Strip out of range, max %lu",
446 : (unsigned long) strip,
447 : (unsigned long) td->td_nstrips);
448 0 : return ((tmsize_t)(-1));
449 : }
450 0 : if (tif->tif_flags&TIFF_NOREADRAW)
451 : {
452 0 : TIFFErrorExt(tif->tif_clientdata, module,
453 : "Compression scheme does not support access to raw uncompressed data");
454 0 : return ((tmsize_t)(-1));
455 : }
456 0 : bytecount = td->td_stripbytecount[strip];
457 0 : if (bytecount <= 0) {
458 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
459 : TIFFErrorExt(tif->tif_clientdata, module,
460 : "%I64u: Invalid strip byte count, strip %lu",
461 : (unsigned __int64) bytecount,
462 : (unsigned long) strip);
463 : #else
464 0 : TIFFErrorExt(tif->tif_clientdata, module,
465 : "%llu: Invalid strip byte count, strip %lu",
466 : (unsigned long long) bytecount,
467 : (unsigned long) strip);
468 : #endif
469 0 : return ((tmsize_t)(-1));
470 : }
471 0 : bytecountm = (tmsize_t)bytecount;
472 0 : if ((uint64)bytecountm!=bytecount) {
473 0 : TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
474 0 : return ((tmsize_t)(-1));
475 : }
476 0 : if (size != (tmsize_t)(-1) && size < bytecountm)
477 0 : bytecountm = size;
478 0 : return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
479 : }
480 :
481 : /*
482 : * Read the specified strip and setup for decoding. The data buffer is
483 : * expanded, as necessary, to hold the strip's data.
484 : */
485 : int
486 5959 : TIFFFillStrip(TIFF* tif, uint32 strip)
487 : {
488 : static const char module[] = "TIFFFillStrip";
489 5959 : TIFFDirectory *td = &tif->tif_dir;
490 :
491 5959 : if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
492 0 : return 0;
493 :
494 5959 : if ((tif->tif_flags&TIFF_NOREADRAW)==0)
495 : {
496 5959 : uint64 bytecount = td->td_stripbytecount[strip];
497 5959 : if (bytecount <= 0) {
498 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
499 : TIFFErrorExt(tif->tif_clientdata, module,
500 : "Invalid strip byte count %I64u, strip %lu",
501 : (unsigned __int64) bytecount,
502 : (unsigned long) strip);
503 : #else
504 0 : TIFFErrorExt(tif->tif_clientdata, module,
505 : "Invalid strip byte count %llu, strip %lu",
506 : (unsigned long long) bytecount,
507 : (unsigned long) strip);
508 : #endif
509 0 : return (0);
510 : }
511 5959 : if (isMapped(tif) &&
512 0 : (isFillOrder(tif, td->td_fillorder)
513 0 : || (tif->tif_flags & TIFF_NOBITREV))) {
514 : /*
515 : * The image is mapped into memory and we either don't
516 : * need to flip bits or the compression routine is
517 : * going to handle this operation itself. In this
518 : * case, avoid copying the raw data and instead just
519 : * reference the data from the memory mapped file
520 : * image. This assumes that the decompression
521 : * routines do not modify the contents of the raw data
522 : * buffer (if they try to, the application will get a
523 : * fault since the file is mapped read-only).
524 : */
525 0 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
526 0 : _TIFFfree(tif->tif_rawdata);
527 0 : tif->tif_flags &= ~TIFF_MYBUFFER;
528 : /*
529 : * We must check for overflow, potentially causing
530 : * an OOB read. Instead of simple
531 : *
532 : * td->td_stripoffset[strip]+bytecount > tif->tif_size
533 : *
534 : * comparison (which can overflow) we do the following
535 : * two comparisons:
536 : */
537 0 : if (bytecount > (uint64)tif->tif_size ||
538 0 : td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
539 : /*
540 : * This error message might seem strange, but
541 : * it's what would happen if a read were done
542 : * instead.
543 : */
544 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
545 : TIFFErrorExt(tif->tif_clientdata, module,
546 :
547 : "Read error on strip %lu; "
548 : "got %I64u bytes, expected %I64u",
549 : (unsigned long) strip,
550 : (unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
551 : (unsigned __int64) bytecount);
552 : #else
553 0 : TIFFErrorExt(tif->tif_clientdata, module,
554 :
555 : "Read error on strip %lu; "
556 : "got %llu bytes, expected %llu",
557 : (unsigned long) strip,
558 0 : (unsigned long long) tif->tif_size - td->td_stripoffset[strip],
559 : (unsigned long long) bytecount);
560 : #endif
561 0 : tif->tif_curstrip = NOSTRIP;
562 0 : return (0);
563 : }
564 0 : tif->tif_rawdatasize = (tmsize_t)bytecount;
565 0 : tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
566 0 : tif->tif_rawdataoff = 0;
567 0 : tif->tif_rawdataloaded = (tmsize_t) bytecount;
568 : } else {
569 : /*
570 : * Expand raw data buffer, if needed, to hold data
571 : * strip coming from file (perhaps should set upper
572 : * bound on the size of a buffer we'll use?).
573 : */
574 : tmsize_t bytecountm;
575 5959 : bytecountm=(tmsize_t)bytecount;
576 5959 : if ((uint64)bytecountm!=bytecount)
577 : {
578 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
579 0 : return(0);
580 : }
581 5959 : if (bytecountm > tif->tif_rawdatasize) {
582 1715 : tif->tif_curstrip = NOSTRIP;
583 1715 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
584 0 : TIFFErrorExt(tif->tif_clientdata, module,
585 : "Data buffer too small to hold strip %lu",
586 : (unsigned long) strip);
587 0 : return (0);
588 : }
589 1715 : if (!TIFFReadBufferSetup(tif, 0, bytecountm))
590 0 : return (0);
591 : }
592 5959 : if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
593 : bytecountm, module) != bytecountm)
594 0 : return (0);
595 :
596 5959 : tif->tif_rawdataoff = 0;
597 5959 : tif->tif_rawdataloaded = bytecountm;
598 :
599 5959 : if (!isFillOrder(tif, td->td_fillorder) &&
600 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
601 0 : TIFFReverseBits(tif->tif_rawdata, bytecountm);
602 : }
603 : }
604 5959 : return (TIFFStartStrip(tif, strip));
605 : }
606 :
607 : /*
608 : * Tile-oriented Read Support
609 : * Contributed by Nancy Cam (Silicon Graphics).
610 : */
611 :
612 : /*
613 : * Read and decompress a tile of data. The
614 : * tile is selected by the (x,y,z,s) coordinates.
615 : */
616 : tmsize_t
617 1 : TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
618 : {
619 1 : if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
620 0 : return ((tmsize_t)(-1));
621 1 : return (TIFFReadEncodedTile(tif,
622 : TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
623 : }
624 :
625 : /*
626 : * Read a tile of data and decompress the specified
627 : * amount into the user-supplied buffer.
628 : */
629 : tmsize_t
630 8911 : TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
631 : {
632 : static const char module[] = "TIFFReadEncodedTile";
633 8911 : TIFFDirectory *td = &tif->tif_dir;
634 8911 : tmsize_t tilesize = tif->tif_tilesize;
635 :
636 8911 : if (!TIFFCheckRead(tif, 1))
637 0 : return ((tmsize_t)(-1));
638 8911 : if (tile >= td->td_nstrips) {
639 0 : TIFFErrorExt(tif->tif_clientdata, module,
640 : "%lu: Tile out of range, max %lu",
641 : (unsigned long) tile, (unsigned long) td->td_nstrips);
642 0 : return ((tmsize_t)(-1));
643 : }
644 8911 : if (size == (tmsize_t)(-1))
645 1 : size = tilesize;
646 8910 : else if (size > tilesize)
647 0 : size = tilesize;
648 17821 : if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif,
649 8910 : (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) {
650 8910 : (*tif->tif_postdecode)(tif, (uint8*) buf, size);
651 8910 : return (size);
652 : } else
653 1 : return ((tmsize_t)(-1));
654 : }
655 :
656 : static tmsize_t
657 8910 : TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
658 : {
659 8910 : TIFFDirectory *td = &tif->tif_dir;
660 :
661 8910 : if (!_TIFFFillStriles( tif ))
662 0 : return ((tmsize_t)(-1));
663 :
664 8910 : assert((tif->tif_flags&TIFF_NOREADRAW)==0);
665 8910 : if (!isMapped(tif)) {
666 : tmsize_t cc;
667 :
668 8910 : if (!SeekOK(tif, td->td_stripoffset[tile])) {
669 0 : TIFFErrorExt(tif->tif_clientdata, module,
670 : "Seek error at row %lu, col %lu, tile %lu",
671 : (unsigned long) tif->tif_row,
672 : (unsigned long) tif->tif_col,
673 : (unsigned long) tile);
674 0 : return ((tmsize_t)(-1));
675 : }
676 8910 : cc = TIFFReadFile(tif, buf, size);
677 8910 : if (cc != size) {
678 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
679 : TIFFErrorExt(tif->tif_clientdata, module,
680 : "Read error at row %lu, col %lu; got %I64u bytes, expected %I64u",
681 : (unsigned long) tif->tif_row,
682 : (unsigned long) tif->tif_col,
683 : (unsigned __int64) cc,
684 : (unsigned __int64) size);
685 : #else
686 1 : TIFFErrorExt(tif->tif_clientdata, module,
687 : "Read error at row %lu, col %lu; got %llu bytes, expected %llu",
688 : (unsigned long) tif->tif_row,
689 : (unsigned long) tif->tif_col,
690 : (unsigned long long) cc,
691 : (unsigned long long) size);
692 : #endif
693 1 : return ((tmsize_t)(-1));
694 : }
695 : } else {
696 : tmsize_t ma,mb;
697 : tmsize_t n;
698 0 : ma=(tmsize_t)td->td_stripoffset[tile];
699 0 : mb=ma+size;
700 0 : if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size))
701 0 : n=0;
702 0 : else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
703 0 : n=tif->tif_size-ma;
704 : else
705 0 : n=size;
706 0 : if (n!=size) {
707 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
708 : TIFFErrorExt(tif->tif_clientdata, module,
709 : "Read error at row %lu, col %lu, tile %lu; got %I64u bytes, expected %I64u",
710 : (unsigned long) tif->tif_row,
711 : (unsigned long) tif->tif_col,
712 : (unsigned long) tile,
713 : (unsigned __int64) n,
714 : (unsigned __int64) size);
715 : #else
716 0 : TIFFErrorExt(tif->tif_clientdata, module,
717 : "Read error at row %lu, col %lu, tile %lu; got %llu bytes, expected %llu",
718 : (unsigned long) tif->tif_row,
719 : (unsigned long) tif->tif_col,
720 : (unsigned long) tile,
721 : (unsigned long long) n,
722 : (unsigned long long) size);
723 : #endif
724 0 : return ((tmsize_t)(-1));
725 : }
726 0 : _TIFFmemcpy(buf, tif->tif_base + ma, size);
727 : }
728 8909 : return (size);
729 : }
730 :
731 : /*
732 : * Read a tile of data from the file.
733 : */
734 : tmsize_t
735 0 : TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
736 : {
737 : static const char module[] = "TIFFReadRawTile";
738 0 : TIFFDirectory *td = &tif->tif_dir;
739 : uint64 bytecount64;
740 : tmsize_t bytecountm;
741 :
742 0 : if (!TIFFCheckRead(tif, 1))
743 0 : return ((tmsize_t)(-1));
744 0 : if (tile >= td->td_nstrips) {
745 0 : TIFFErrorExt(tif->tif_clientdata, module,
746 : "%lu: Tile out of range, max %lu",
747 : (unsigned long) tile, (unsigned long) td->td_nstrips);
748 0 : return ((tmsize_t)(-1));
749 : }
750 0 : if (tif->tif_flags&TIFF_NOREADRAW)
751 : {
752 0 : TIFFErrorExt(tif->tif_clientdata, module,
753 : "Compression scheme does not support access to raw uncompressed data");
754 0 : return ((tmsize_t)(-1));
755 : }
756 0 : bytecount64 = td->td_stripbytecount[tile];
757 0 : if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
758 0 : bytecount64 = (uint64)size;
759 0 : bytecountm = (tmsize_t)bytecount64;
760 0 : if ((uint64)bytecountm!=bytecount64)
761 : {
762 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
763 0 : return ((tmsize_t)(-1));
764 : }
765 0 : return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
766 : }
767 :
768 : /*
769 : * Read the specified tile and setup for decoding. The data buffer is
770 : * expanded, as necessary, to hold the tile's data.
771 : */
772 : int
773 8911 : TIFFFillTile(TIFF* tif, uint32 tile)
774 : {
775 : static const char module[] = "TIFFFillTile";
776 8911 : TIFFDirectory *td = &tif->tif_dir;
777 :
778 8911 : if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
779 0 : return 0;
780 :
781 8911 : if ((tif->tif_flags&TIFF_NOREADRAW)==0)
782 : {
783 8910 : uint64 bytecount = td->td_stripbytecount[tile];
784 8910 : if (bytecount <= 0) {
785 : #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
786 : TIFFErrorExt(tif->tif_clientdata, module,
787 : "%I64u: Invalid tile byte count, tile %lu",
788 : (unsigned __int64) bytecount,
789 : (unsigned long) tile);
790 : #else
791 0 : TIFFErrorExt(tif->tif_clientdata, module,
792 : "%llu: Invalid tile byte count, tile %lu",
793 : (unsigned long long) bytecount,
794 : (unsigned long) tile);
795 : #endif
796 0 : return (0);
797 : }
798 8910 : if (isMapped(tif) &&
799 0 : (isFillOrder(tif, td->td_fillorder)
800 0 : || (tif->tif_flags & TIFF_NOBITREV))) {
801 : /*
802 : * The image is mapped into memory and we either don't
803 : * need to flip bits or the compression routine is
804 : * going to handle this operation itself. In this
805 : * case, avoid copying the raw data and instead just
806 : * reference the data from the memory mapped file
807 : * image. This assumes that the decompression
808 : * routines do not modify the contents of the raw data
809 : * buffer (if they try to, the application will get a
810 : * fault since the file is mapped read-only).
811 : */
812 0 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
813 0 : _TIFFfree(tif->tif_rawdata);
814 0 : tif->tif_flags &= ~TIFF_MYBUFFER;
815 : /*
816 : * We must check for overflow, potentially causing
817 : * an OOB read. Instead of simple
818 : *
819 : * td->td_stripoffset[tile]+bytecount > tif->tif_size
820 : *
821 : * comparison (which can overflow) we do the following
822 : * two comparisons:
823 : */
824 0 : if (bytecount > (uint64)tif->tif_size ||
825 0 : td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
826 0 : tif->tif_curtile = NOTILE;
827 0 : return (0);
828 : }
829 0 : tif->tif_rawdatasize = (tmsize_t)bytecount;
830 0 : tif->tif_rawdata =
831 0 : tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
832 0 : tif->tif_rawdataoff = 0;
833 0 : tif->tif_rawdataloaded = (tmsize_t) bytecount;
834 : } else {
835 : /*
836 : * Expand raw data buffer, if needed, to hold data
837 : * tile coming from file (perhaps should set upper
838 : * bound on the size of a buffer we'll use?).
839 : */
840 : tmsize_t bytecountm;
841 8910 : bytecountm=(tmsize_t)bytecount;
842 8910 : if ((uint64)bytecountm!=bytecount)
843 : {
844 0 : TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
845 0 : return(0);
846 : }
847 8910 : if (bytecountm > tif->tif_rawdatasize) {
848 152 : tif->tif_curtile = NOTILE;
849 152 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
850 0 : TIFFErrorExt(tif->tif_clientdata, module,
851 : "Data buffer too small to hold tile %lu",
852 : (unsigned long) tile);
853 0 : return (0);
854 : }
855 152 : if (!TIFFReadBufferSetup(tif, 0, bytecountm))
856 0 : return (0);
857 : }
858 8910 : if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
859 : bytecountm, module) != bytecountm)
860 1 : return (0);
861 :
862 8909 : tif->tif_rawdataoff = 0;
863 8909 : tif->tif_rawdataloaded = bytecountm;
864 :
865 8909 : if (!isFillOrder(tif, td->td_fillorder) &&
866 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
867 0 : TIFFReverseBits(tif->tif_rawdata,
868 : tif->tif_rawdataloaded);
869 : }
870 : }
871 8910 : return (TIFFStartTile(tif, tile));
872 : }
873 :
874 : /*
875 : * Setup the raw data buffer in preparation for
876 : * reading a strip of raw data. If the buffer
877 : * is specified as zero, then a buffer of appropriate
878 : * size is allocated by the library. Otherwise,
879 : * the client must guarantee that the buffer is
880 : * large enough to hold any individual strip of
881 : * raw data.
882 : */
883 : int
884 1875 : TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
885 : {
886 : static const char module[] = "TIFFReadBufferSetup";
887 :
888 1875 : assert((tif->tif_flags&TIFF_NOREADRAW)==0);
889 1875 : if (tif->tif_rawdata) {
890 33 : if (tif->tif_flags & TIFF_MYBUFFER)
891 33 : _TIFFfree(tif->tif_rawdata);
892 33 : tif->tif_rawdata = NULL;
893 : }
894 1875 : if (bp) {
895 0 : tif->tif_rawdatasize = size;
896 0 : tif->tif_rawdata = (uint8*) bp;
897 0 : tif->tif_flags &= ~TIFF_MYBUFFER;
898 : } else {
899 1875 : tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024);
900 1875 : if (tif->tif_rawdatasize==0)
901 0 : tif->tif_rawdatasize=(tmsize_t)(-1);
902 1875 : tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
903 1875 : tif->tif_flags |= TIFF_MYBUFFER;
904 : }
905 1875 : if (tif->tif_rawdata == NULL) {
906 0 : TIFFErrorExt(tif->tif_clientdata, module,
907 : "No space for data buffer at scanline %lu",
908 : (unsigned long) tif->tif_row);
909 0 : tif->tif_rawdatasize = 0;
910 0 : return (0);
911 : }
912 1875 : return (1);
913 : }
914 :
915 : /*
916 : * Set state to appear as if a
917 : * strip has just been read in.
918 : */
919 : static int
920 6007 : TIFFStartStrip(TIFF* tif, uint32 strip)
921 : {
922 6007 : TIFFDirectory *td = &tif->tif_dir;
923 :
924 6007 : if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
925 0 : return 0;
926 :
927 6007 : if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
928 1725 : if (!(*tif->tif_setupdecode)(tif))
929 0 : return (0);
930 1725 : tif->tif_flags |= TIFF_CODERSETUP;
931 : }
932 6007 : tif->tif_curstrip = strip;
933 6007 : tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
934 6007 : tif->tif_flags &= ~TIFF_BUF4WRITE;
935 :
936 6007 : if (tif->tif_flags&TIFF_NOREADRAW)
937 : {
938 0 : tif->tif_rawcp = NULL;
939 0 : tif->tif_rawcc = 0;
940 : }
941 : else
942 : {
943 6007 : tif->tif_rawcp = tif->tif_rawdata;
944 6007 : tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
945 : }
946 12014 : return ((*tif->tif_predecode)(tif,
947 6007 : (uint16)(strip / td->td_stripsperimage)));
948 : }
949 :
950 : /*
951 : * Set state to appear as if a
952 : * tile has just been read in.
953 : */
954 : static int
955 8910 : TIFFStartTile(TIFF* tif, uint32 tile)
956 : {
957 8910 : TIFFDirectory *td = &tif->tif_dir;
958 :
959 8910 : if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
960 0 : return 0;
961 :
962 8910 : if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
963 176 : if (!(*tif->tif_setupdecode)(tif))
964 0 : return (0);
965 176 : tif->tif_flags |= TIFF_CODERSETUP;
966 : }
967 8910 : tif->tif_curtile = tile;
968 8910 : tif->tif_row =
969 8910 : (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) *
970 : td->td_tilelength;
971 8910 : tif->tif_col =
972 8910 : (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) *
973 : td->td_tilewidth;
974 8910 : tif->tif_flags &= ~TIFF_BUF4WRITE;
975 8910 : if (tif->tif_flags&TIFF_NOREADRAW)
976 : {
977 1 : tif->tif_rawcp = NULL;
978 1 : tif->tif_rawcc = 0;
979 : }
980 : else
981 : {
982 8909 : tif->tif_rawcp = tif->tif_rawdata;
983 8909 : tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
984 : }
985 17820 : return ((*tif->tif_predecode)(tif,
986 8910 : (uint16)(tile/td->td_stripsperimage)));
987 : }
988 :
989 : static int
990 155631 : TIFFCheckRead(TIFF* tif, int tiles)
991 : {
992 155631 : if (tif->tif_mode == O_WRONLY) {
993 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");
994 0 : return (0);
995 : }
996 155631 : if (tiles ^ isTiled(tif)) {
997 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
998 : "Can not read tiles from a stripped image" :
999 : "Can not read scanlines from a tiled image");
1000 0 : return (0);
1001 : }
1002 155631 : return (1);
1003 : }
1004 :
1005 : void
1006 282113 : _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
1007 : {
1008 : (void) tif; (void) buf; (void) cc;
1009 282113 : }
1010 :
1011 : void
1012 8 : _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc)
1013 : {
1014 : (void) tif;
1015 8 : assert((cc & 1) == 0);
1016 8 : TIFFSwabArrayOfShort((uint16*) buf, cc/2);
1017 8 : }
1018 :
1019 : void
1020 0 : _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc)
1021 : {
1022 : (void) tif;
1023 0 : assert((cc % 3) == 0);
1024 0 : TIFFSwabArrayOfTriples((uint8*) buf, cc/3);
1025 0 : }
1026 :
1027 : void
1028 15 : _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc)
1029 : {
1030 : (void) tif;
1031 15 : assert((cc & 3) == 0);
1032 15 : TIFFSwabArrayOfLong((uint32*) buf, cc/4);
1033 15 : }
1034 :
1035 : void
1036 0 : _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc)
1037 : {
1038 : (void) tif;
1039 0 : assert((cc & 7) == 0);
1040 0 : TIFFSwabArrayOfDouble((double*) buf, cc/8);
1041 0 : }
1042 :
1043 : /* vim: set ts=8 sts=8 sw=8 noet: */
1044 : /*
1045 : * Local Variables:
1046 : * mode: c
1047 : * c-basic-offset: 8
1048 : * fill-column: 78
1049 : * End:
1050 : */
|