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