Line data Source code
1 : /*
2 : * Copyright (c) 1988-1997 Sam Leffler
3 : * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4 : *
5 : * Permission to use, copy, modify, distribute, and sell this software and
6 : * its documentation for any purpose is hereby granted without fee, provided
7 : * that (i) the above copyright notices and this permission notice appear in
8 : * all copies of the software and related documentation, and (ii) the names of
9 : * Sam Leffler and Silicon Graphics may not be used in any advertising or
10 : * publicity relating to the software without the specific, prior written
11 : * permission of Sam Leffler and Silicon Graphics.
12 : *
13 : * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14 : * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 : * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16 : *
17 : * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18 : * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 : * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 : * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 : * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22 : * OF THIS SOFTWARE.
23 : */
24 :
25 : /*
26 : * TIFF Library.
27 : * Scanline-oriented Read Support
28 : */
29 : #include "tiffiop.h"
30 : #include <stdio.h>
31 :
32 : int TIFFFillStrip(TIFF *tif, uint32_t strip);
33 : int TIFFFillTile(TIFF *tif, uint32_t tile);
34 : static int TIFFStartStrip(TIFF *tif, uint32_t strip);
35 : static int TIFFStartTile(TIFF *tif, uint32_t tile);
36 : static int TIFFCheckRead(TIFF *, int);
37 : static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
38 : tmsize_t size, const char *module);
39 : static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
40 : tmsize_t size, const char *module);
41 :
42 : #define NOSTRIP ((uint32_t)(-1)) /* undefined state */
43 : #define NOTILE ((uint32_t)(-1)) /* undefined state */
44 :
45 : #define INITIAL_THRESHOLD (1024 * 1024)
46 : #define THRESHOLD_MULTIPLIER 10
47 : #define MAX_THRESHOLD \
48 : (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * \
49 : INITIAL_THRESHOLD)
50 :
51 : #define TIFF_INT64_MAX ((((int64_t)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
52 :
53 : /* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
54 : * Returns 1 in case of success, 0 otherwise. */
55 15648 : static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
56 : int is_strip, uint32_t strip_or_tile,
57 : const char *module)
58 : {
59 : #if SIZEOF_SIZE_T == 8
60 15648 : tmsize_t threshold = INITIAL_THRESHOLD;
61 : #endif
62 15648 : tmsize_t already_read = 0;
63 :
64 : #if SIZEOF_SIZE_T != 8
65 : /* On 32 bit processes, if the request is large enough, check against */
66 : /* file size */
67 : if (size > 1000 * 1000 * 1000)
68 : {
69 : uint64_t filesize = TIFFGetFileSize(tif);
70 : if ((uint64_t)size >= filesize)
71 : {
72 : TIFFErrorExtR(tif, module,
73 : "Chunk size requested is larger than file size.");
74 : return 0;
75 : }
76 : }
77 : #endif
78 :
79 : /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
80 : /* so as to avoid allocating too much memory in case the file is too */
81 : /* short. We could ask for the file size, but this might be */
82 : /* expensive with some I/O layers (think of reading a gzipped file) */
83 : /* Restrict to 64 bit processes, so as to avoid reallocs() */
84 : /* on 32 bit processes where virtual memory is scarce. */
85 31269 : while (already_read < size)
86 : {
87 : tmsize_t bytes_read;
88 15651 : tmsize_t to_read = size - already_read;
89 : #if SIZEOF_SIZE_T == 8
90 15651 : if (to_read >= threshold && threshold < MAX_THRESHOLD &&
91 3 : already_read + to_read + rawdata_offset > tif->tif_rawdatasize)
92 : {
93 3 : to_read = threshold;
94 3 : threshold *= THRESHOLD_MULTIPLIER;
95 : }
96 : #endif
97 15651 : if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize)
98 : {
99 : uint8_t *new_rawdata;
100 1569 : assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
101 1569 : tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
102 : (uint64_t)already_read + to_read + rawdata_offset, 1024);
103 1569 : if (tif->tif_rawdatasize == 0)
104 : {
105 0 : TIFFErrorExtR(tif, module, "Invalid buffer size");
106 0 : return 0;
107 : }
108 1569 : new_rawdata = (uint8_t *)_TIFFreallocExt(tif, tif->tif_rawdata,
109 : tif->tif_rawdatasize);
110 1568 : if (new_rawdata == 0)
111 : {
112 0 : TIFFErrorExtR(tif, module,
113 : "No space for data buffer at scanline %" PRIu32,
114 : tif->tif_row);
115 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
116 0 : tif->tif_rawdata = 0;
117 0 : tif->tif_rawdatasize = 0;
118 0 : return 0;
119 : }
120 1568 : tif->tif_rawdata = new_rawdata;
121 : }
122 15650 : if (tif->tif_rawdata == NULL)
123 : {
124 : /* should not happen in practice but helps CoverityScan */
125 0 : return 0;
126 : }
127 :
128 15650 : bytes_read = TIFFReadFile(
129 : tif, tif->tif_rawdata + rawdata_offset + already_read, to_read);
130 15650 : already_read += bytes_read;
131 15650 : if (bytes_read != to_read)
132 : {
133 29 : memset(tif->tif_rawdata + rawdata_offset + already_read, 0,
134 29 : tif->tif_rawdatasize - rawdata_offset - already_read);
135 29 : if (is_strip)
136 : {
137 2 : TIFFErrorExtR(tif, module,
138 : "Read error at scanline %" PRIu32
139 : "; got %" TIFF_SSIZE_FORMAT " bytes, "
140 : "expected %" TIFF_SSIZE_FORMAT,
141 : tif->tif_row, already_read, size);
142 : }
143 : else
144 : {
145 27 : TIFFErrorExtR(tif, module,
146 : "Read error at row %" PRIu32 ", col %" PRIu32
147 : ", tile %" PRIu32 "; "
148 : "got %" TIFF_SSIZE_FORMAT
149 : " bytes, expected %" TIFF_SSIZE_FORMAT "",
150 : tif->tif_row, tif->tif_col, strip_or_tile,
151 : already_read, size);
152 : }
153 29 : return 0;
154 : }
155 : }
156 15618 : return 1;
157 : }
158 :
159 59 : static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
160 : int restart)
161 : {
162 : static const char module[] = "TIFFFillStripPartial";
163 59 : register TIFFDirectory *td = &tif->tif_dir;
164 : tmsize_t unused_data;
165 : uint64_t read_offset;
166 : tmsize_t to_read;
167 : tmsize_t read_ahead_mod;
168 : /* tmsize_t bytecountm; */
169 :
170 : /*
171 : * Expand raw data buffer, if needed, to hold data
172 : * strip coming from file (perhaps should set upper
173 : * bound on the size of a buffer we'll use?).
174 : */
175 :
176 : /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */
177 :
178 : /* Not completely sure where the * 2 comes from, but probably for */
179 : /* an exponentional growth strategy of tif_rawdatasize */
180 59 : if (read_ahead < TIFF_TMSIZE_T_MAX / 2)
181 59 : read_ahead_mod = read_ahead * 2;
182 : else
183 0 : read_ahead_mod = read_ahead;
184 59 : if (read_ahead_mod > tif->tif_rawdatasize)
185 : {
186 34 : assert(restart);
187 :
188 34 : tif->tif_curstrip = NOSTRIP;
189 34 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
190 : {
191 0 : TIFFErrorExtR(tif, module,
192 : "Data buffer too small to hold part of strip %d",
193 : strip);
194 0 : return (0);
195 : }
196 : }
197 :
198 59 : if (restart)
199 : {
200 34 : tif->tif_rawdataloaded = 0;
201 34 : tif->tif_rawdataoff = 0;
202 : }
203 :
204 : /*
205 : ** If we are reading more data, move any unused data to the
206 : ** start of the buffer.
207 : */
208 59 : if (tif->tif_rawdataloaded > 0)
209 23 : unused_data =
210 23 : tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata);
211 : else
212 36 : unused_data = 0;
213 :
214 59 : if (unused_data > 0)
215 : {
216 23 : assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
217 23 : memmove(tif->tif_rawdata, tif->tif_rawcp, unused_data);
218 : }
219 :
220 : /*
221 : ** Seek to the point in the file where more data should be read.
222 : */
223 59 : read_offset = TIFFGetStrileOffset(tif, strip) + tif->tif_rawdataoff +
224 59 : tif->tif_rawdataloaded;
225 :
226 59 : if (!SeekOK(tif, read_offset))
227 : {
228 0 : TIFFErrorExtR(tif, module,
229 : "Seek error at scanline %" PRIu32 ", strip %d",
230 : tif->tif_row, strip);
231 0 : return 0;
232 : }
233 :
234 : /*
235 : ** How much do we want to read?
236 : */
237 59 : if (read_ahead_mod > tif->tif_rawdatasize)
238 34 : to_read = read_ahead_mod - unused_data;
239 : else
240 25 : to_read = tif->tif_rawdatasize - unused_data;
241 59 : if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, strip) -
242 59 : tif->tif_rawdataoff - tif->tif_rawdataloaded)
243 : {
244 33 : to_read = (tmsize_t)TIFFGetStrileByteCount(tif, strip) -
245 33 : tif->tif_rawdataoff - tif->tif_rawdataloaded;
246 : }
247 :
248 59 : assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
249 59 : if (!TIFFReadAndRealloc(tif, to_read, unused_data, 1, /* is_strip */
250 : 0, /* strip_or_tile */
251 : module))
252 : {
253 0 : return 0;
254 : }
255 :
256 59 : tif->tif_rawdataoff =
257 59 : tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data;
258 59 : tif->tif_rawdataloaded = unused_data + to_read;
259 :
260 59 : tif->tif_rawcc = tif->tif_rawdataloaded;
261 59 : tif->tif_rawcp = tif->tif_rawdata;
262 :
263 59 : if (!isFillOrder(tif, td->td_fillorder) &&
264 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
265 : {
266 0 : assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
267 0 : TIFFReverseBits(tif->tif_rawdata + unused_data, to_read);
268 : }
269 :
270 : /*
271 : ** When starting a strip from the beginning we need to
272 : ** restart the decoder.
273 : */
274 59 : if (restart)
275 : {
276 :
277 : #ifdef JPEG_SUPPORT
278 : /* A bit messy since breaks the codec abstraction. Ultimately */
279 : /* there should be a function pointer for that, but it seems */
280 : /* only JPEG is affected. */
281 : /* For JPEG, if there are multiple scans (can generally be known */
282 : /* with the read_ahead used), we need to read the whole strip */
283 36 : if (tif->tif_dir.td_compression == COMPRESSION_JPEG &&
284 2 : (uint64_t)tif->tif_rawcc < TIFFGetStrileByteCount(tif, strip))
285 : {
286 2 : if (TIFFJPEGIsFullStripRequired(tif))
287 : {
288 2 : return TIFFFillStrip(tif, strip);
289 : }
290 : }
291 : #endif
292 :
293 32 : return TIFFStartStrip(tif, strip);
294 : }
295 : else
296 : {
297 25 : return 1;
298 : }
299 : }
300 :
301 : /*
302 : * Seek to a random row+sample in a file.
303 : *
304 : * Only used by TIFFReadScanline, and is only used on
305 : * strip organized files. We do some tricky stuff to try
306 : * and avoid reading the whole compressed raw data for big
307 : * strips.
308 : */
309 153234 : static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
310 : {
311 153234 : register TIFFDirectory *td = &tif->tif_dir;
312 : uint32_t strip;
313 : int whole_strip;
314 153234 : tmsize_t read_ahead = 0;
315 :
316 : /*
317 : ** Establish what strip we are working from.
318 : */
319 153234 : if (row >= td->td_imagelength)
320 : { /* out of range */
321 0 : TIFFErrorExtR(tif, tif->tif_name,
322 : "%" PRIu32 ": Row out of range, max %" PRIu32 "", row,
323 : td->td_imagelength);
324 0 : return (0);
325 : }
326 153234 : if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
327 : {
328 64244 : if (sample >= td->td_samplesperpixel)
329 : {
330 0 : TIFFErrorExtR(tif, tif->tif_name,
331 : "%" PRIu16 ": Sample out of range, max %" PRIu16 "",
332 0 : sample, td->td_samplesperpixel);
333 0 : return (0);
334 : }
335 64244 : strip = (uint32_t)sample * td->td_stripsperimage +
336 64244 : row / td->td_rowsperstrip;
337 : }
338 : else
339 88990 : strip = row / td->td_rowsperstrip;
340 :
341 : /*
342 : * Do we want to treat this strip as one whole chunk or
343 : * read it a few lines at a time?
344 : */
345 : #if defined(CHUNKY_STRIP_READ_SUPPORT)
346 153234 : whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif);
347 153234 : if (td->td_compression == COMPRESSION_LERC ||
348 153234 : td->td_compression == COMPRESSION_JBIG)
349 : {
350 : /* Ideally plugins should have a way to declare they don't support
351 : * chunk strip */
352 0 : whole_strip = 1;
353 : }
354 : #else
355 : whole_strip = 1;
356 : #endif
357 :
358 153234 : if (!whole_strip)
359 : {
360 : /* 16 is for YCbCr mode where we may need to read 16 */
361 : /* lines at a time to get a decompressed line, and 5000 */
362 : /* is some constant value, for example for JPEG tables */
363 153233 : if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
364 153233 : tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000)
365 : {
366 153233 : read_ahead = tif->tif_scanlinesize * 16 + 5000;
367 : }
368 : else
369 : {
370 0 : read_ahead = tif->tif_scanlinesize;
371 : }
372 : }
373 :
374 : /*
375 : * If we haven't loaded this strip, do so now, possibly
376 : * only reading the first part.
377 : */
378 153234 : if (strip != tif->tif_curstrip)
379 : { /* different strip, refill */
380 :
381 35 : if (whole_strip)
382 : {
383 1 : if (!TIFFFillStrip(tif, strip))
384 1 : return (0);
385 : }
386 : else
387 : {
388 34 : if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
389 2 : return 0;
390 : }
391 : }
392 :
393 : /*
394 : ** If we already have some data loaded, do we need to read some more?
395 : */
396 153199 : else if (!whole_strip)
397 : {
398 153199 : if (((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) <
399 148298 : read_ahead &&
400 148298 : (uint64_t)tif->tif_rawdataoff + tif->tif_rawdataloaded <
401 148298 : TIFFGetStrileByteCount(tif, strip))
402 : {
403 25 : if (!TIFFFillStripPartial(tif, strip, read_ahead, 0))
404 0 : return 0;
405 : }
406 : }
407 :
408 153231 : if (row < tif->tif_row)
409 : {
410 : /*
411 : * Moving backwards within the same strip: backup
412 : * to the start and then decode forward (below).
413 : *
414 : * NB: If you're planning on lots of random access within a
415 : * strip, it's better to just read and decode the entire
416 : * strip, and then access the decoded data in a random fashion.
417 : */
418 :
419 25 : if (tif->tif_rawdataoff != 0)
420 : {
421 0 : if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
422 0 : return 0;
423 : }
424 : else
425 : {
426 25 : if (!TIFFStartStrip(tif, strip))
427 0 : return (0);
428 : }
429 : }
430 :
431 153231 : if (row != tif->tif_row)
432 : {
433 : /*
434 : * Seek forward to the desired row.
435 : */
436 :
437 : /* TODO: Will this really work with partial buffers? */
438 :
439 0 : if (!(*tif->tif_seek)(tif, row - tif->tif_row))
440 0 : return (0);
441 0 : tif->tif_row = row;
442 : }
443 :
444 153231 : return (1);
445 : }
446 :
447 153234 : int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
448 : {
449 : int e;
450 :
451 153234 : if (!TIFFCheckRead(tif, 0))
452 0 : return (-1);
453 153234 : if ((e = TIFFSeek(tif, row, sample)) != 0)
454 : {
455 : /*
456 : * Decompress desired row into user buffer.
457 : */
458 153231 : e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
459 : sample);
460 :
461 : /* we are now poised at the beginning of the next row */
462 153231 : tif->tif_row = row + 1;
463 :
464 153231 : if (e)
465 153229 : (*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize);
466 : }
467 : else
468 : {
469 : /* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
470 3 : if (buf)
471 3 : memset(buf, 0, (size_t)tif->tif_scanlinesize);
472 : }
473 153234 : return (e > 0 ? 1 : -1);
474 : }
475 :
476 : /*
477 : * Calculate the strip size according to the number of
478 : * rows in the strip (check for truncated last strip on any
479 : * of the separations).
480 : */
481 2084700 : static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip,
482 : uint16_t *pplane)
483 : {
484 : static const char module[] = "TIFFReadEncodedStrip";
485 2084700 : TIFFDirectory *td = &tif->tif_dir;
486 : uint32_t rowsperstrip;
487 : uint32_t stripsperplane;
488 : uint32_t stripinplane;
489 : uint32_t rows;
490 : tmsize_t stripsize;
491 2084700 : if (!TIFFCheckRead(tif, 0))
492 0 : return ((tmsize_t)(-1));
493 2084670 : if (strip >= td->td_nstrips)
494 : {
495 0 : TIFFErrorExtR(tif, module,
496 : "%" PRIu32 ": Strip out of range, max %" PRIu32, strip,
497 : td->td_nstrips);
498 0 : return ((tmsize_t)(-1));
499 : }
500 :
501 2084670 : rowsperstrip = td->td_rowsperstrip;
502 2084670 : if (rowsperstrip > td->td_imagelength)
503 16 : rowsperstrip = td->td_imagelength;
504 2084670 : if (rowsperstrip == 0)
505 : {
506 0 : TIFFErrorExtR(tif, module, "rowsperstrip is zero");
507 0 : return ((tmsize_t)(-1));
508 : }
509 2084670 : stripsperplane =
510 2084670 : TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
511 2084670 : stripinplane = (strip % stripsperplane);
512 2084670 : if (pplane)
513 2084660 : *pplane = (uint16_t)(strip / stripsperplane);
514 2084670 : rows = td->td_imagelength - stripinplane * rowsperstrip;
515 2084670 : if (rows > rowsperstrip)
516 2071920 : rows = rowsperstrip;
517 2084670 : stripsize = TIFFVStripSize(tif, rows);
518 2084670 : if (stripsize == 0)
519 0 : return ((tmsize_t)(-1));
520 2084670 : return stripsize;
521 : }
522 :
523 : /*
524 : * Read a strip of data and decompress the specified
525 : * amount into the user-supplied buffer.
526 : */
527 2084660 : tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
528 : tmsize_t size)
529 : {
530 : static const char module[] = "TIFFReadEncodedStrip";
531 2084660 : TIFFDirectory *td = &tif->tif_dir;
532 : tmsize_t stripsize;
533 : uint16_t plane;
534 :
535 2084660 : stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
536 2084620 : if (stripsize == ((tmsize_t)(-1)))
537 0 : return ((tmsize_t)(-1));
538 :
539 : /* shortcut to avoid an extra memcpy() */
540 2084620 : if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
541 2074530 : size >= stripsize && !isMapped(tif) &&
542 2074530 : ((tif->tif_flags & TIFF_NOREADRAW) == 0))
543 : {
544 2074530 : if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize)
545 61 : return ((tmsize_t)(-1));
546 :
547 2074540 : if (!isFillOrder(tif, td->td_fillorder) &&
548 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
549 0 : TIFFReverseBits(buf, stripsize);
550 :
551 2074540 : (*tif->tif_postdecode)(tif, buf, stripsize);
552 2074540 : return (stripsize);
553 : }
554 :
555 10094 : if ((size != (tmsize_t)(-1)) && (size < stripsize))
556 0 : stripsize = size;
557 10094 : if (!TIFFFillStrip(tif, strip))
558 : {
559 : /* The output buf may be NULL, in particular if TIFFTAG_FAXFILLFUNC
560 : is being used. Thus, memset must be conditional on buf not NULL. */
561 5 : if (buf)
562 5 : memset(buf, 0, (size_t)stripsize);
563 5 : return ((tmsize_t)(-1));
564 : }
565 10059 : if ((*tif->tif_decodestrip)(tif, buf, stripsize, plane) <= 0)
566 4 : return ((tmsize_t)(-1));
567 10055 : (*tif->tif_postdecode)(tif, buf, stripsize);
568 10055 : return (stripsize);
569 : }
570 :
571 : /* Variant of TIFFReadEncodedStrip() that does
572 : * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
573 : * TIFFFillStrip() has succeeded. This avoid excessive memory allocation in case
574 : * of truncated file.
575 : * * calls regular TIFFReadEncodedStrip() if *buf != NULL
576 : */
577 53 : tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip,
578 : void **buf,
579 : tmsize_t bufsizetoalloc,
580 : tmsize_t size_to_read)
581 : {
582 : tmsize_t this_stripsize;
583 : uint16_t plane;
584 :
585 53 : if (*buf != NULL)
586 : {
587 0 : return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read);
588 : }
589 :
590 53 : this_stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
591 53 : if (this_stripsize == ((tmsize_t)(-1)))
592 0 : return ((tmsize_t)(-1));
593 :
594 53 : if ((size_to_read != (tmsize_t)(-1)) && (size_to_read < this_stripsize))
595 0 : this_stripsize = size_to_read;
596 53 : if (!TIFFFillStrip(tif, strip))
597 0 : return ((tmsize_t)(-1));
598 :
599 53 : *buf = _TIFFmallocExt(tif, bufsizetoalloc);
600 53 : if (*buf == NULL)
601 : {
602 0 : TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
603 0 : return ((tmsize_t)(-1));
604 : }
605 53 : _TIFFmemset(*buf, 0, bufsizetoalloc);
606 :
607 53 : if ((*tif->tif_decodestrip)(tif, *buf, this_stripsize, plane) <= 0)
608 0 : return ((tmsize_t)(-1));
609 53 : (*tif->tif_postdecode)(tif, *buf, this_stripsize);
610 53 : return (this_stripsize);
611 : }
612 :
613 2074580 : static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
614 : tmsize_t size, const char *module)
615 : {
616 2074580 : assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
617 2074580 : if (!isMapped(tif))
618 : {
619 : tmsize_t cc;
620 :
621 2074570 : if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip)))
622 : {
623 0 : TIFFErrorExtR(tif, module,
624 : "Seek error at scanline %" PRIu32 ", strip %" PRIu32,
625 : tif->tif_row, strip);
626 0 : return ((tmsize_t)(-1));
627 : }
628 2074540 : cc = TIFFReadFile(tif, buf, size);
629 2074600 : if (cc != size)
630 : {
631 61 : TIFFErrorExtR(tif, module,
632 : "Read error at scanline %" PRIu32
633 : "; got %" TIFF_SSIZE_FORMAT
634 : " bytes, expected %" TIFF_SSIZE_FORMAT,
635 : tif->tif_row, cc, size);
636 61 : return ((tmsize_t)(-1));
637 : }
638 : }
639 : else
640 : {
641 13 : tmsize_t ma = 0;
642 : tmsize_t n;
643 13 : if ((TIFFGetStrileOffset(tif, strip) > (uint64_t)TIFF_TMSIZE_T_MAX) ||
644 0 : ((ma = (tmsize_t)TIFFGetStrileOffset(tif, strip)) > tif->tif_size))
645 : {
646 0 : n = 0;
647 : }
648 0 : else if (ma > TIFF_TMSIZE_T_MAX - size)
649 : {
650 0 : n = 0;
651 : }
652 : else
653 : {
654 0 : tmsize_t mb = ma + size;
655 0 : if (mb > tif->tif_size)
656 0 : n = tif->tif_size - ma;
657 : else
658 0 : n = size;
659 : }
660 0 : if (n != size)
661 : {
662 0 : TIFFErrorExtR(tif, module,
663 : "Read error at scanline %" PRIu32 ", strip %" PRIu32
664 : "; got %" TIFF_SSIZE_FORMAT
665 : " bytes, expected %" TIFF_SSIZE_FORMAT,
666 : tif->tif_row, strip, n, size);
667 0 : return ((tmsize_t)(-1));
668 : }
669 0 : _TIFFmemcpy(buf, tif->tif_base + ma, size);
670 : }
671 2074540 : return (size);
672 : }
673 :
674 15588 : static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile,
675 : int is_strip, tmsize_t size,
676 : const char *module)
677 : {
678 15588 : assert(!isMapped(tif));
679 15588 : assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
680 :
681 15588 : if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile)))
682 : {
683 0 : if (is_strip)
684 : {
685 0 : TIFFErrorExtR(tif, module,
686 : "Seek error at scanline %" PRIu32 ", strip %" PRIu32,
687 : tif->tif_row, strip_or_tile);
688 : }
689 : else
690 : {
691 0 : TIFFErrorExtR(tif, module,
692 : "Seek error at row %" PRIu32 ", col %" PRIu32
693 : ", tile %" PRIu32,
694 : tif->tif_row, tif->tif_col, strip_or_tile);
695 : }
696 0 : return ((tmsize_t)(-1));
697 : }
698 :
699 15588 : if (!TIFFReadAndRealloc(tif, size, 0, is_strip, strip_or_tile, module))
700 : {
701 29 : return ((tmsize_t)(-1));
702 : }
703 :
704 15560 : return (size);
705 : }
706 :
707 : /*
708 : * Read a strip of data from the file.
709 : */
710 4 : tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, tmsize_t size)
711 : {
712 : static const char module[] = "TIFFReadRawStrip";
713 4 : TIFFDirectory *td = &tif->tif_dir;
714 : uint64_t bytecount64;
715 : tmsize_t bytecountm;
716 :
717 4 : if (!TIFFCheckRead(tif, 0))
718 0 : return ((tmsize_t)(-1));
719 4 : if (strip >= td->td_nstrips)
720 : {
721 0 : TIFFErrorExtR(tif, module,
722 : "%" PRIu32 ": Strip out of range, max %" PRIu32, strip,
723 : td->td_nstrips);
724 0 : return ((tmsize_t)(-1));
725 : }
726 4 : if (tif->tif_flags & TIFF_NOREADRAW)
727 : {
728 0 : TIFFErrorExtR(tif, module,
729 : "Compression scheme does not support access to raw "
730 : "uncompressed data");
731 0 : return ((tmsize_t)(-1));
732 : }
733 4 : bytecount64 = TIFFGetStrileByteCount(tif, strip);
734 4 : if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64)
735 4 : bytecountm = size;
736 : else
737 0 : bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
738 4 : if (bytecountm == 0)
739 : {
740 0 : return ((tmsize_t)(-1));
741 : }
742 4 : return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
743 : }
744 :
745 : TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
746 2 : static uint64_t NoSanitizeSubUInt64(uint64_t a, uint64_t b) { return a - b; }
747 :
748 : /*
749 : * Read the specified strip and setup for decoding. The data buffer is
750 : * expanded, as necessary, to hold the strip's data.
751 : */
752 10120 : int TIFFFillStrip(TIFF *tif, uint32_t strip)
753 : {
754 : static const char module[] = "TIFFFillStrip";
755 10120 : TIFFDirectory *td = &tif->tif_dir;
756 :
757 10120 : if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
758 : {
759 10120 : uint64_t bytecount = TIFFGetStrileByteCount(tif, strip);
760 10120 : if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
761 : {
762 1 : TIFFErrorExtR(tif, module,
763 : "Invalid strip byte count %" PRIu64
764 : ", strip %" PRIu32,
765 : bytecount, strip);
766 1 : return (0);
767 : }
768 :
769 : /* To avoid excessive memory allocations: */
770 : /* Byte count should normally not be larger than a number of */
771 : /* times the uncompressed size plus some margin */
772 10119 : if (bytecount > 1024 * 1024)
773 : {
774 : /* 10 and 4096 are just values that could be adjusted. */
775 : /* Hopefully they are safe enough for all codecs */
776 3 : tmsize_t stripsize = TIFFStripSize(tif);
777 3 : if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
778 : {
779 1 : uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
780 1 : TIFFErrorExtR(tif, module,
781 : "Too large strip byte count %" PRIu64
782 : ", strip %" PRIu32 ". Limiting to %" PRIu64,
783 : bytecount, strip, newbytecount);
784 1 : bytecount = newbytecount;
785 : }
786 : }
787 :
788 10119 : if (isMapped(tif))
789 : {
790 : /*
791 : * We must check for overflow, potentially causing
792 : * an OOB read. Instead of simple
793 : *
794 : * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size
795 : *
796 : * comparison (which can overflow) we do the following
797 : * two comparisons:
798 : */
799 4 : if (bytecount > (uint64_t)tif->tif_size ||
800 4 : TIFFGetStrileOffset(tif, strip) >
801 4 : (uint64_t)tif->tif_size - bytecount)
802 : {
803 : /*
804 : * This error message might seem strange, but
805 : * it's what would happen if a read were done
806 : * instead.
807 : */
808 4 : TIFFErrorExtR(
809 : tif, module,
810 :
811 : "Read error on strip %" PRIu32 "; "
812 : "got %" PRIu64 " bytes, expected %" PRIu64,
813 : strip,
814 2 : NoSanitizeSubUInt64(tif->tif_size,
815 : TIFFGetStrileOffset(tif, strip)),
816 : bytecount);
817 2 : tif->tif_curstrip = NOSTRIP;
818 2 : return (0);
819 : }
820 : }
821 :
822 10117 : if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
823 0 : (tif->tif_flags & TIFF_NOBITREV)))
824 : {
825 : /*
826 : * The image is mapped into memory and we either don't
827 : * need to flip bits or the compression routine is
828 : * going to handle this operation itself. In this
829 : * case, avoid copying the raw data and instead just
830 : * reference the data from the memory mapped file
831 : * image. This assumes that the decompression
832 : * routines do not modify the contents of the raw data
833 : * buffer (if they try to, the application will get a
834 : * fault since the file is mapped read-only).
835 : */
836 2 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
837 : {
838 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
839 0 : tif->tif_rawdata = NULL;
840 0 : tif->tif_rawdatasize = 0;
841 : }
842 2 : tif->tif_flags &= ~TIFF_MYBUFFER;
843 2 : tif->tif_rawdatasize = (tmsize_t)bytecount;
844 2 : tif->tif_rawdata =
845 2 : tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip);
846 2 : tif->tif_rawdataoff = 0;
847 2 : tif->tif_rawdataloaded = (tmsize_t)bytecount;
848 :
849 : /*
850 : * When we have tif_rawdata reference directly into the memory
851 : * mapped file we need to be pretty careful about how we use the
852 : * rawdata. It is not a general purpose working buffer as it
853 : * normally otherwise is. So we keep track of this fact to avoid
854 : * using it improperly.
855 : */
856 2 : tif->tif_flags |= TIFF_BUFFERMMAP;
857 : }
858 : else
859 : {
860 : /*
861 : * Expand raw data buffer, if needed, to hold data
862 : * strip coming from file (perhaps should set upper
863 : * bound on the size of a buffer we'll use?).
864 : */
865 : tmsize_t bytecountm;
866 10115 : bytecountm = (tmsize_t)bytecount;
867 10115 : if ((uint64_t)bytecountm != bytecount)
868 : {
869 0 : TIFFErrorExtR(tif, module, "Integer overflow");
870 0 : return (0);
871 : }
872 10115 : if (bytecountm > tif->tif_rawdatasize)
873 : {
874 771 : tif->tif_curstrip = NOSTRIP;
875 771 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
876 : {
877 0 : TIFFErrorExtR(
878 : tif, module,
879 : "Data buffer too small to hold strip %" PRIu32, strip);
880 0 : return (0);
881 : }
882 : }
883 10115 : if (tif->tif_flags & TIFF_BUFFERMMAP)
884 : {
885 0 : tif->tif_curstrip = NOSTRIP;
886 0 : tif->tif_rawdata = NULL;
887 0 : tif->tif_rawdatasize = 0;
888 0 : tif->tif_flags &= ~TIFF_BUFFERMMAP;
889 : }
890 :
891 10115 : if (isMapped(tif))
892 : {
893 0 : if (bytecountm > tif->tif_rawdatasize &&
894 0 : !TIFFReadBufferSetup(tif, 0, bytecountm))
895 : {
896 0 : return (0);
897 : }
898 0 : if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecountm,
899 : module) != bytecountm)
900 : {
901 0 : return (0);
902 : }
903 : }
904 : else
905 : {
906 10115 : if (TIFFReadRawStripOrTile2(tif, strip, 1, bytecountm,
907 : module) != bytecountm)
908 : {
909 2 : return (0);
910 : }
911 : }
912 :
913 10113 : tif->tif_rawdataoff = 0;
914 10113 : tif->tif_rawdataloaded = bytecountm;
915 :
916 10113 : if (!isFillOrder(tif, td->td_fillorder) &&
917 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
918 0 : TIFFReverseBits(tif->tif_rawdata, bytecountm);
919 : }
920 : }
921 10115 : return (TIFFStartStrip(tif, strip));
922 : }
923 :
924 : /*
925 : * Tile-oriented Read Support
926 : * Contributed by Nancy Cam (Silicon Graphics).
927 : */
928 :
929 : /*
930 : * Read and decompress a tile of data. The
931 : * tile is selected by the (x,y,z,s) coordinates.
932 : */
933 2 : tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
934 : uint16_t s)
935 : {
936 2 : if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
937 0 : return ((tmsize_t)(-1));
938 2 : return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
939 : (tmsize_t)(-1)));
940 : }
941 :
942 : /*
943 : * Read a tile of data and decompress the specified
944 : * amount into the user-supplied buffer.
945 : */
946 27105 : tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
947 : {
948 : static const char module[] = "TIFFReadEncodedTile";
949 27105 : TIFFDirectory *td = &tif->tif_dir;
950 27105 : tmsize_t tilesize = tif->tif_tilesize;
951 :
952 27105 : if (!TIFFCheckRead(tif, 1))
953 0 : return ((tmsize_t)(-1));
954 27106 : if (tile >= td->td_nstrips)
955 : {
956 0 : TIFFErrorExtR(tif, module,
957 : "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
958 : td->td_nstrips);
959 0 : return ((tmsize_t)(-1));
960 : }
961 :
962 : /* shortcut to avoid an extra memcpy() */
963 27106 : if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
964 21630 : size >= tilesize && !isMapped(tif) &&
965 21630 : ((tif->tif_flags & TIFF_NOREADRAW) == 0))
966 : {
967 21630 : if (TIFFReadRawTile1(tif, tile, buf, tilesize, module) != tilesize)
968 1 : return ((tmsize_t)(-1));
969 :
970 21627 : if (!isFillOrder(tif, td->td_fillorder) &&
971 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
972 0 : TIFFReverseBits(buf, tilesize);
973 :
974 21627 : (*tif->tif_postdecode)(tif, buf, tilesize);
975 21627 : return (tilesize);
976 : }
977 :
978 5476 : if (size == (tmsize_t)(-1))
979 2 : size = tilesize;
980 5474 : else if (size > tilesize)
981 0 : size = tilesize;
982 5476 : if (!TIFFFillTile(tif, tile))
983 : {
984 : /* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
985 30 : if (buf)
986 30 : memset(buf, 0, (size_t)size);
987 30 : return ((tmsize_t)(-1));
988 : }
989 5446 : else if ((*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
990 5445 : (uint16_t)(tile / td->td_stripsperimage)))
991 : {
992 5446 : (*tif->tif_postdecode)(tif, (uint8_t *)buf, size);
993 5446 : return (size);
994 : }
995 : else
996 0 : return ((tmsize_t)(-1));
997 : }
998 :
999 : /* Variant of TIFFReadTile() that does
1000 : * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
1001 : * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
1002 : * of truncated file.
1003 : * * calls regular TIFFReadEncodedTile() if *buf != NULL
1004 : */
1005 4 : tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf,
1006 : tmsize_t bufsizetoalloc, uint32_t x,
1007 : uint32_t y, uint32_t z, uint16_t s)
1008 : {
1009 4 : if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
1010 0 : return ((tmsize_t)(-1));
1011 4 : return (_TIFFReadEncodedTileAndAllocBuffer(
1012 : tif, TIFFComputeTile(tif, x, y, z, s), buf, bufsizetoalloc,
1013 : (tmsize_t)(-1)));
1014 : }
1015 :
1016 : /* Variant of TIFFReadEncodedTile() that does
1017 : * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
1018 : * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
1019 : * of truncated file.
1020 : * * calls regular TIFFReadEncodedTile() if *buf != NULL
1021 : */
1022 4 : tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
1023 : void **buf, tmsize_t bufsizetoalloc,
1024 : tmsize_t size_to_read)
1025 : {
1026 : static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer";
1027 4 : TIFFDirectory *td = &tif->tif_dir;
1028 4 : tmsize_t tilesize = tif->tif_tilesize;
1029 :
1030 4 : if (*buf != NULL)
1031 : {
1032 0 : return TIFFReadEncodedTile(tif, tile, *buf, size_to_read);
1033 : }
1034 :
1035 4 : if (!TIFFCheckRead(tif, 1))
1036 0 : return ((tmsize_t)(-1));
1037 4 : if (tile >= td->td_nstrips)
1038 : {
1039 0 : TIFFErrorExtR(tif, module,
1040 : "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
1041 : td->td_nstrips);
1042 0 : return ((tmsize_t)(-1));
1043 : }
1044 :
1045 4 : if (!TIFFFillTile(tif, tile))
1046 1 : return ((tmsize_t)(-1));
1047 :
1048 : /* Sanity checks to avoid excessive memory allocation */
1049 : /* Cf https://gitlab.com/libtiff/libtiff/-/issues/479 */
1050 3 : if (td->td_compression == COMPRESSION_NONE)
1051 : {
1052 2 : if (tif->tif_rawdatasize != tilesize)
1053 : {
1054 0 : TIFFErrorExtR(tif, TIFFFileName(tif),
1055 : "Invalid tile byte count for tile %u. "
1056 : "Expected %" PRIu64 ", got %" PRIu64,
1057 : tile, (uint64_t)tilesize,
1058 0 : (uint64_t)tif->tif_rawdatasize);
1059 0 : return ((tmsize_t)(-1));
1060 : }
1061 : }
1062 : else
1063 : {
1064 : /* Max compression ratio experimentally determined. Might be fragile...
1065 : * Only apply this heuristics to situations where the memory allocation
1066 : * would be big, to avoid breaking nominal use cases.
1067 : */
1068 1 : const int maxCompressionRatio =
1069 1 : td->td_compression == COMPRESSION_ZSTD ? 33000
1070 2 : : td->td_compression == COMPRESSION_JXL
1071 : ?
1072 : /* Evaluated on a 8000x8000 tile */
1073 0 : 25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG
1074 0 : ? td->td_samplesperpixel
1075 0 : : 1)
1076 1 : : td->td_compression == COMPRESSION_LZMA ? 7000 : 1000;
1077 1 : if (bufsizetoalloc > 100 * 1000 * 1000 &&
1078 0 : tif->tif_rawdatasize < tilesize / maxCompressionRatio)
1079 : {
1080 0 : TIFFErrorExtR(tif, TIFFFileName(tif),
1081 : "Likely invalid tile byte count for tile %u. "
1082 : "Uncompressed tile size is %" PRIu64 ", "
1083 : "compressed one is %" PRIu64,
1084 : tile, (uint64_t)tilesize,
1085 0 : (uint64_t)tif->tif_rawdatasize);
1086 0 : return ((tmsize_t)(-1));
1087 : }
1088 : }
1089 :
1090 3 : *buf = _TIFFmallocExt(tif, bufsizetoalloc);
1091 3 : if (*buf == NULL)
1092 : {
1093 0 : TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
1094 0 : return ((tmsize_t)(-1));
1095 : }
1096 3 : _TIFFmemset(*buf, 0, bufsizetoalloc);
1097 :
1098 3 : if (size_to_read == (tmsize_t)(-1))
1099 3 : size_to_read = tilesize;
1100 0 : else if (size_to_read > tilesize)
1101 0 : size_to_read = tilesize;
1102 3 : if ((*tif->tif_decodetile)(tif, (uint8_t *)*buf, size_to_read,
1103 3 : (uint16_t)(tile / td->td_stripsperimage)))
1104 : {
1105 3 : (*tif->tif_postdecode)(tif, (uint8_t *)*buf, size_to_read);
1106 3 : return (size_to_read);
1107 : }
1108 : else
1109 0 : return ((tmsize_t)(-1));
1110 : }
1111 :
1112 21633 : static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
1113 : tmsize_t size, const char *module)
1114 : {
1115 21633 : assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
1116 21633 : if (!isMapped(tif))
1117 : {
1118 : tmsize_t cc;
1119 :
1120 21633 : if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile)))
1121 : {
1122 0 : TIFFErrorExtR(tif, module,
1123 : "Seek error at row %" PRIu32 ", col %" PRIu32
1124 : ", tile %" PRIu32,
1125 : tif->tif_row, tif->tif_col, tile);
1126 0 : return ((tmsize_t)(-1));
1127 : }
1128 21633 : cc = TIFFReadFile(tif, buf, size);
1129 21632 : if (cc != size)
1130 : {
1131 1 : TIFFErrorExtR(tif, module,
1132 : "Read error at row %" PRIu32 ", col %" PRIu32
1133 : "; got %" TIFF_SSIZE_FORMAT
1134 : " bytes, expected %" TIFF_SSIZE_FORMAT,
1135 : tif->tif_row, tif->tif_col, cc, size);
1136 1 : return ((tmsize_t)(-1));
1137 : }
1138 : }
1139 : else
1140 : {
1141 : tmsize_t ma, mb;
1142 : tmsize_t n;
1143 0 : ma = (tmsize_t)TIFFGetStrileOffset(tif, tile);
1144 0 : mb = ma + size;
1145 0 : if ((TIFFGetStrileOffset(tif, tile) > (uint64_t)TIFF_TMSIZE_T_MAX) ||
1146 0 : (ma > tif->tif_size))
1147 0 : n = 0;
1148 0 : else if ((mb < ma) || (mb < size) || (mb > tif->tif_size))
1149 0 : n = tif->tif_size - ma;
1150 : else
1151 0 : n = size;
1152 0 : if (n != size)
1153 : {
1154 0 : TIFFErrorExtR(tif, module,
1155 : "Read error at row %" PRIu32 ", col %" PRIu32
1156 : ", tile %" PRIu32 "; got %" TIFF_SSIZE_FORMAT
1157 : " bytes, expected %" TIFF_SSIZE_FORMAT,
1158 : tif->tif_row, tif->tif_col, tile, n, size);
1159 0 : return ((tmsize_t)(-1));
1160 : }
1161 0 : _TIFFmemcpy(buf, tif->tif_base + ma, size);
1162 : }
1163 21631 : return (size);
1164 : }
1165 :
1166 : /*
1167 : * Read a tile of data from the file.
1168 : */
1169 3 : tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
1170 : {
1171 : static const char module[] = "TIFFReadRawTile";
1172 3 : TIFFDirectory *td = &tif->tif_dir;
1173 : uint64_t bytecount64;
1174 : tmsize_t bytecountm;
1175 :
1176 3 : if (!TIFFCheckRead(tif, 1))
1177 0 : return ((tmsize_t)(-1));
1178 3 : if (tile >= td->td_nstrips)
1179 : {
1180 0 : TIFFErrorExtR(tif, module,
1181 : "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
1182 : td->td_nstrips);
1183 0 : return ((tmsize_t)(-1));
1184 : }
1185 3 : if (tif->tif_flags & TIFF_NOREADRAW)
1186 : {
1187 0 : TIFFErrorExtR(tif, module,
1188 : "Compression scheme does not support access to raw "
1189 : "uncompressed data");
1190 0 : return ((tmsize_t)(-1));
1191 : }
1192 3 : bytecount64 = TIFFGetStrileByteCount(tif, tile);
1193 3 : if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64)
1194 3 : bytecountm = size;
1195 : else
1196 0 : bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
1197 3 : if (bytecountm == 0)
1198 : {
1199 0 : return ((tmsize_t)(-1));
1200 : }
1201 3 : return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
1202 : }
1203 :
1204 : /*
1205 : * Read the specified tile and setup for decoding. The data buffer is
1206 : * expanded, as necessary, to hold the tile's data.
1207 : */
1208 5479 : int TIFFFillTile(TIFF *tif, uint32_t tile)
1209 : {
1210 : static const char module[] = "TIFFFillTile";
1211 5479 : TIFFDirectory *td = &tif->tif_dir;
1212 :
1213 5479 : if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
1214 : {
1215 5477 : uint64_t bytecount = TIFFGetStrileByteCount(tif, tile);
1216 5477 : if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
1217 : {
1218 0 : TIFFErrorExtR(tif, module,
1219 : "%" PRIu64 ": Invalid tile byte count, tile %" PRIu32,
1220 : bytecount, tile);
1221 0 : return (0);
1222 : }
1223 :
1224 : /* To avoid excessive memory allocations: */
1225 : /* Byte count should normally not be larger than a number of */
1226 : /* times the uncompressed size plus some margin */
1227 5477 : if (bytecount > 1024 * 1024)
1228 : {
1229 : /* 10 and 4096 are just values that could be adjusted. */
1230 : /* Hopefully they are safe enough for all codecs */
1231 2 : tmsize_t stripsize = TIFFTileSize(tif);
1232 2 : if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
1233 : {
1234 1 : uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
1235 1 : TIFFErrorExtR(tif, module,
1236 : "Too large tile byte count %" PRIu64
1237 : ", tile %" PRIu32 ". Limiting to %" PRIu64,
1238 : bytecount, tile, newbytecount);
1239 1 : bytecount = newbytecount;
1240 : }
1241 : }
1242 :
1243 5477 : if (isMapped(tif))
1244 : {
1245 : /*
1246 : * We must check for overflow, potentially causing
1247 : * an OOB read. Instead of simple
1248 : *
1249 : * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size
1250 : *
1251 : * comparison (which can overflow) we do the following
1252 : * two comparisons:
1253 : */
1254 4 : if (bytecount > (uint64_t)tif->tif_size ||
1255 4 : TIFFGetStrileOffset(tif, tile) >
1256 4 : (uint64_t)tif->tif_size - bytecount)
1257 : {
1258 2 : tif->tif_curtile = NOTILE;
1259 2 : return (0);
1260 : }
1261 : }
1262 :
1263 5475 : if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
1264 0 : (tif->tif_flags & TIFF_NOBITREV)))
1265 : {
1266 : /*
1267 : * The image is mapped into memory and we either don't
1268 : * need to flip bits or the compression routine is
1269 : * going to handle this operation itself. In this
1270 : * case, avoid copying the raw data and instead just
1271 : * reference the data from the memory mapped file
1272 : * image. This assumes that the decompression
1273 : * routines do not modify the contents of the raw data
1274 : * buffer (if they try to, the application will get a
1275 : * fault since the file is mapped read-only).
1276 : */
1277 1 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
1278 : {
1279 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
1280 0 : tif->tif_rawdata = NULL;
1281 0 : tif->tif_rawdatasize = 0;
1282 : }
1283 1 : tif->tif_flags &= ~TIFF_MYBUFFER;
1284 :
1285 1 : tif->tif_rawdatasize = (tmsize_t)bytecount;
1286 2 : tif->tif_rawdata =
1287 1 : tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile);
1288 2 : tif->tif_rawdataoff = 0;
1289 2 : tif->tif_rawdataloaded = (tmsize_t)bytecount;
1290 2 : tif->tif_flags |= TIFF_BUFFERMMAP;
1291 : }
1292 : else
1293 : {
1294 : /*
1295 : * Expand raw data buffer, if needed, to hold data
1296 : * tile coming from file (perhaps should set upper
1297 : * bound on the size of a buffer we'll use?).
1298 : */
1299 : tmsize_t bytecountm;
1300 5474 : bytecountm = (tmsize_t)bytecount;
1301 5474 : if ((uint64_t)bytecountm != bytecount)
1302 : {
1303 0 : TIFFErrorExtR(tif, module, "Integer overflow");
1304 0 : return (0);
1305 : }
1306 5474 : if (bytecountm > tif->tif_rawdatasize)
1307 : {
1308 781 : tif->tif_curtile = NOTILE;
1309 781 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
1310 : {
1311 0 : TIFFErrorExtR(tif, module,
1312 : "Data buffer too small to hold tile %" PRIu32,
1313 : tile);
1314 0 : return (0);
1315 : }
1316 : }
1317 5474 : if (tif->tif_flags & TIFF_BUFFERMMAP)
1318 : {
1319 0 : tif->tif_curtile = NOTILE;
1320 0 : tif->tif_rawdata = NULL;
1321 0 : tif->tif_rawdatasize = 0;
1322 0 : tif->tif_flags &= ~TIFF_BUFFERMMAP;
1323 : }
1324 :
1325 5474 : if (isMapped(tif))
1326 : {
1327 0 : if (bytecountm > tif->tif_rawdatasize &&
1328 0 : !TIFFReadBufferSetup(tif, 0, bytecountm))
1329 : {
1330 0 : return (0);
1331 : }
1332 0 : if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, bytecountm,
1333 : module) != bytecountm)
1334 : {
1335 0 : return (0);
1336 : }
1337 : }
1338 : else
1339 : {
1340 5474 : if (TIFFReadRawStripOrTile2(tif, tile, 0, bytecountm, module) !=
1341 : bytecountm)
1342 : {
1343 27 : return (0);
1344 : }
1345 : }
1346 :
1347 5447 : tif->tif_rawdataoff = 0;
1348 5447 : tif->tif_rawdataloaded = bytecountm;
1349 :
1350 5447 : if (tif->tif_rawdata != NULL &&
1351 5447 : !isFillOrder(tif, td->td_fillorder) &&
1352 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
1353 0 : TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdataloaded);
1354 : }
1355 : }
1356 5451 : return (TIFFStartTile(tif, tile));
1357 : }
1358 :
1359 : /*
1360 : * Setup the raw data buffer in preparation for
1361 : * reading a strip of raw data. If the buffer
1362 : * is specified as zero, then a buffer of appropriate
1363 : * size is allocated by the library. Otherwise,
1364 : * the client must guarantee that the buffer is
1365 : * large enough to hold any individual strip of
1366 : * raw data.
1367 : */
1368 0 : int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size)
1369 : {
1370 : static const char module[] = "TIFFReadBufferSetup";
1371 :
1372 0 : assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
1373 0 : tif->tif_flags &= ~TIFF_BUFFERMMAP;
1374 :
1375 0 : if (tif->tif_rawdata)
1376 : {
1377 0 : if (tif->tif_flags & TIFF_MYBUFFER)
1378 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
1379 0 : tif->tif_rawdata = NULL;
1380 0 : tif->tif_rawdatasize = 0;
1381 : }
1382 0 : if (bp)
1383 : {
1384 0 : tif->tif_rawdatasize = size;
1385 0 : tif->tif_rawdata = (uint8_t *)bp;
1386 0 : tif->tif_flags &= ~TIFF_MYBUFFER;
1387 : }
1388 : else
1389 : {
1390 0 : tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64_t)size, 1024);
1391 0 : if (tif->tif_rawdatasize == 0)
1392 : {
1393 0 : TIFFErrorExtR(tif, module, "Invalid buffer size");
1394 0 : return (0);
1395 : }
1396 : /* Initialize to zero to avoid uninitialized buffers in case of */
1397 : /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */
1398 0 : tif->tif_rawdata =
1399 0 : (uint8_t *)_TIFFcallocExt(tif, 1, tif->tif_rawdatasize);
1400 0 : tif->tif_flags |= TIFF_MYBUFFER;
1401 : }
1402 0 : if (tif->tif_rawdata == NULL)
1403 : {
1404 0 : TIFFErrorExtR(tif, module,
1405 : "No space for data buffer at scanline %" PRIu32,
1406 : tif->tif_row);
1407 0 : tif->tif_rawdatasize = 0;
1408 0 : return (0);
1409 : }
1410 0 : return (1);
1411 : }
1412 :
1413 : /*
1414 : * Set state to appear as if a
1415 : * strip has just been read in.
1416 : */
1417 12532 : static int TIFFStartStrip(TIFF *tif, uint32_t strip)
1418 : {
1419 12532 : TIFFDirectory *td = &tif->tif_dir;
1420 :
1421 12532 : if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
1422 : {
1423 3057 : if (!(*tif->tif_setupdecode)(tif))
1424 1 : return (0);
1425 3057 : tif->tif_flags |= TIFF_CODERSETUP;
1426 : }
1427 12532 : tif->tif_curstrip = strip;
1428 12532 : tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
1429 12532 : tif->tif_flags &= ~TIFF_BUF4WRITE;
1430 :
1431 12532 : if (tif->tif_flags & TIFF_NOREADRAW)
1432 : {
1433 0 : tif->tif_rawcp = NULL;
1434 0 : tif->tif_rawcc = 0;
1435 : }
1436 : else
1437 : {
1438 12532 : tif->tif_rawcp = tif->tif_rawdata;
1439 12532 : if (tif->tif_rawdataloaded > 0)
1440 12529 : tif->tif_rawcc = tif->tif_rawdataloaded;
1441 : else
1442 3 : tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
1443 : }
1444 12529 : if ((*tif->tif_predecode)(tif, (uint16_t)(strip / td->td_stripsperimage)) ==
1445 : 0)
1446 : {
1447 : /* Needed for example for scanline access, if tif_predecode */
1448 : /* fails, and we try to read the same strip again. Without invalidating
1449 : */
1450 : /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */
1451 : /* codec state. */
1452 2 : tif->tif_curstrip = NOSTRIP;
1453 2 : return 0;
1454 : }
1455 12527 : return 1;
1456 : }
1457 :
1458 : /*
1459 : * Set state to appear as if a
1460 : * tile has just been read in.
1461 : */
1462 5664 : static int TIFFStartTile(TIFF *tif, uint32_t tile)
1463 : {
1464 : static const char module[] = "TIFFStartTile";
1465 5664 : TIFFDirectory *td = &tif->tif_dir;
1466 : uint32_t howmany32;
1467 :
1468 5664 : if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
1469 : {
1470 806 : if (!(*tif->tif_setupdecode)(tif))
1471 0 : return (0);
1472 806 : tif->tif_flags |= TIFF_CODERSETUP;
1473 : }
1474 5664 : tif->tif_curtile = tile;
1475 5664 : if (td->td_tilewidth == 0)
1476 : {
1477 0 : TIFFErrorExtR(tif, module, "Zero tilewidth");
1478 0 : return 0;
1479 : }
1480 5664 : howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
1481 5664 : if (howmany32 == 0)
1482 : {
1483 0 : TIFFErrorExtR(tif, module, "Zero tiles");
1484 0 : return 0;
1485 : }
1486 5664 : tif->tif_row = (tile % howmany32) * td->td_tilelength;
1487 5664 : howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
1488 5664 : if (howmany32 == 0)
1489 : {
1490 0 : TIFFErrorExtR(tif, module, "Zero tiles");
1491 0 : return 0;
1492 : }
1493 5664 : tif->tif_col = (tile % howmany32) * td->td_tilewidth;
1494 5664 : tif->tif_flags &= ~TIFF_BUF4WRITE;
1495 5664 : if (tif->tif_flags & TIFF_NOREADRAW)
1496 : {
1497 2 : tif->tif_rawcp = NULL;
1498 2 : tif->tif_rawcc = 0;
1499 : }
1500 : else
1501 : {
1502 5662 : tif->tif_rawcp = tif->tif_rawdata;
1503 5662 : if (tif->tif_rawdataloaded > 0)
1504 5662 : tif->tif_rawcc = tif->tif_rawdataloaded;
1505 : else
1506 0 : tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile);
1507 : }
1508 : return (
1509 5664 : (*tif->tif_predecode)(tif, (uint16_t)(tile / td->td_stripsperimage)));
1510 : }
1511 :
1512 2265060 : static int TIFFCheckRead(TIFF *tif, int tiles)
1513 : {
1514 2265060 : if (tif->tif_mode == O_WRONLY)
1515 : {
1516 0 : TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
1517 0 : return (0);
1518 : }
1519 2265060 : if (tiles ^ isTiled(tif))
1520 : {
1521 0 : TIFFErrorExtR(tif, tif->tif_name,
1522 : tiles ? "Can not read tiles from a striped image"
1523 : : "Can not read scanlines from a tiled image");
1524 0 : return (0);
1525 : }
1526 2265060 : return (1);
1527 : }
1528 :
1529 : /* Use the provided input buffer (inbuf, insize) and decompress it into
1530 : * (outbuf, outsize).
1531 : * This function replaces the use of
1532 : * TIFFReadEncodedStrip()/TIFFReadEncodedTile() when the user can provide the
1533 : * buffer for the input data, for example when he wants to avoid libtiff to read
1534 : * the strile offset/count values from the [Strip|Tile][Offsets/ByteCounts]
1535 : * array. inbuf content must be writable (if bit reversal is needed) Returns 1
1536 : * in case of success, 0 otherwise.
1537 : */
1538 2572 : int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
1539 : tmsize_t insize, void *outbuf, tmsize_t outsize)
1540 : {
1541 : static const char module[] = "TIFFReadFromUserBuffer";
1542 2572 : TIFFDirectory *td = &tif->tif_dir;
1543 2572 : int ret = 1;
1544 2572 : uint32_t old_tif_flags = tif->tif_flags;
1545 2572 : tmsize_t old_rawdatasize = tif->tif_rawdatasize;
1546 2572 : void *old_rawdata = tif->tif_rawdata;
1547 :
1548 2572 : if (tif->tif_mode == O_WRONLY)
1549 : {
1550 0 : TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
1551 0 : return 0;
1552 : }
1553 2572 : if (tif->tif_flags & TIFF_NOREADRAW)
1554 : {
1555 0 : TIFFErrorExtR(tif, module,
1556 : "Compression scheme does not support access to raw "
1557 : "uncompressed data");
1558 0 : return 0;
1559 : }
1560 :
1561 2572 : tif->tif_flags &= ~TIFF_MYBUFFER;
1562 2572 : tif->tif_flags |= TIFF_BUFFERMMAP;
1563 2572 : tif->tif_rawdatasize = insize;
1564 2572 : tif->tif_rawdata = inbuf;
1565 2572 : tif->tif_rawdataoff = 0;
1566 2572 : tif->tif_rawdataloaded = insize;
1567 :
1568 2572 : if (!isFillOrder(tif, td->td_fillorder) &&
1569 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
1570 : {
1571 0 : TIFFReverseBits(inbuf, insize);
1572 : }
1573 :
1574 2572 : if (TIFFIsTiled(tif))
1575 : {
1576 212 : if (!TIFFStartTile(tif, strile))
1577 : {
1578 0 : ret = 0;
1579 : /* See related TIFFReadEncodedStrip comment. */
1580 0 : if (outbuf)
1581 0 : memset(outbuf, 0, (size_t)outsize);
1582 : }
1583 214 : else if (!(*tif->tif_decodetile)(
1584 : tif, (uint8_t *)outbuf, outsize,
1585 214 : (uint16_t)(strile / td->td_stripsperimage)))
1586 : {
1587 0 : ret = 0;
1588 : }
1589 : }
1590 : else
1591 : {
1592 2358 : uint32_t rowsperstrip = td->td_rowsperstrip;
1593 : uint32_t stripsperplane;
1594 2358 : if (rowsperstrip > td->td_imagelength)
1595 0 : rowsperstrip = td->td_imagelength;
1596 2358 : if (rowsperstrip == 0)
1597 : {
1598 0 : TIFFErrorExtR(tif, module, "rowsperstrip is zero");
1599 0 : ret = 0;
1600 : }
1601 : else
1602 : {
1603 2358 : stripsperplane =
1604 2358 : TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
1605 2358 : if (!TIFFStartStrip(tif, strile))
1606 : {
1607 0 : ret = 0;
1608 : /* See related TIFFReadEncodedStrip comment. */
1609 0 : if (outbuf)
1610 0 : memset(outbuf, 0, (size_t)outsize);
1611 : }
1612 2360 : else if (!(*tif->tif_decodestrip)(
1613 : tif, (uint8_t *)outbuf, outsize,
1614 2357 : (uint16_t)(strile / stripsperplane)))
1615 : {
1616 0 : ret = 0;
1617 : }
1618 : }
1619 : }
1620 2574 : if (ret)
1621 : {
1622 2574 : (*tif->tif_postdecode)(tif, (uint8_t *)outbuf, outsize);
1623 : }
1624 :
1625 2573 : if (!isFillOrder(tif, td->td_fillorder) &&
1626 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
1627 : {
1628 0 : TIFFReverseBits(inbuf, insize);
1629 : }
1630 :
1631 2571 : tif->tif_flags = (old_tif_flags & (TIFF_MYBUFFER | TIFF_BUFFERMMAP)) |
1632 2571 : (tif->tif_flags & ~(TIFF_MYBUFFER | TIFF_BUFFERMMAP));
1633 2571 : tif->tif_rawdatasize = old_rawdatasize;
1634 2571 : tif->tif_rawdata = old_rawdata;
1635 2571 : tif->tif_rawdataoff = 0;
1636 2571 : tif->tif_rawdataloaded = 0;
1637 :
1638 2571 : return ret;
1639 : }
1640 :
1641 2463520 : void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc)
1642 : {
1643 : (void)tif;
1644 : (void)buf;
1645 : (void)cc;
1646 2463520 : }
1647 :
1648 1943 : void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1649 : {
1650 : (void)tif;
1651 1943 : assert((cc & 1) == 0);
1652 1943 : TIFFSwabArrayOfShort((uint16_t *)buf, cc / 2);
1653 1943 : }
1654 :
1655 0 : void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1656 : {
1657 : (void)tif;
1658 0 : assert((cc % 3) == 0);
1659 0 : TIFFSwabArrayOfTriples((uint8_t *)buf, cc / 3);
1660 0 : }
1661 :
1662 188 : void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1663 : {
1664 : (void)tif;
1665 188 : assert((cc & 3) == 0);
1666 188 : TIFFSwabArrayOfLong((uint32_t *)buf, cc / 4);
1667 188 : }
1668 :
1669 4 : void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1670 : {
1671 : (void)tif;
1672 4 : assert((cc & 7) == 0);
1673 4 : TIFFSwabArrayOfDouble((double *)buf, cc / 8);
1674 4 : }
|