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