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