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 23355 : 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 23355 : tmsize_t threshold = INITIAL_THRESHOLD;
59 : #endif
60 23355 : 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 46685 : while (already_read < size)
84 : {
85 : tmsize_t bytes_read;
86 23361 : tmsize_t to_read = size - already_read;
87 : #if SIZEOF_SIZE_T == 8
88 23361 : 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 23361 : if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize)
96 : {
97 : uint8_t *new_rawdata;
98 1964 : assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
99 1964 : tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
100 : (uint64_t)already_read + (uint64_t)to_read +
101 : (uint64_t)rawdata_offset,
102 : 1024);
103 1964 : if (tif->tif_rawdatasize == 0)
104 : {
105 0 : TIFFErrorExtR(tif, module, "Invalid buffer size");
106 0 : return 0;
107 : }
108 1964 : new_rawdata = (uint8_t *)_TIFFreallocExt(tif, tif->tif_rawdata,
109 : tif->tif_rawdatasize);
110 1964 : 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 1964 : tif->tif_rawdata = new_rawdata;
121 : }
122 23361 : if (tif->tif_rawdata == NULL)
123 : {
124 : /* should not happen in practice but helps CoverityScan */
125 0 : return 0;
126 : }
127 :
128 23361 : bytes_read = TIFFReadFile(
129 : tif, tif->tif_rawdata + rawdata_offset + already_read, to_read);
130 23361 : already_read += bytes_read;
131 23361 : 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 23324 : 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 2101840 : static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip,
504 : uint16_t *pplane)
505 : {
506 : static const char module[] = "TIFFReadEncodedStrip";
507 2101840 : 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 2101840 : if (!TIFFCheckRead(tif, 0))
514 0 : return ((tmsize_t)(-1));
515 2101810 : 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 2101810 : rowsperstrip = td->td_rowsperstrip;
524 2101810 : if (rowsperstrip > td->td_imagelength)
525 16 : rowsperstrip = td->td_imagelength;
526 2101810 : if (rowsperstrip == 0)
527 : {
528 0 : TIFFErrorExtR(tif, module, "rowsperstrip is zero");
529 0 : return ((tmsize_t)(-1));
530 : }
531 2101810 : stripsperplane =
532 2101810 : TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
533 2101810 : stripinplane = (strip % stripsperplane);
534 2101810 : if (pplane)
535 2101820 : *pplane = (uint16_t)(strip / stripsperplane);
536 2101810 : rows = td->td_imagelength - stripinplane * rowsperstrip;
537 2101810 : if (rows > rowsperstrip)
538 2084870 : rows = rowsperstrip;
539 2101810 : stripsize = TIFFVStripSize(tif, rows);
540 2101840 : if (stripsize == 0)
541 0 : return ((tmsize_t)(-1));
542 2101840 : return stripsize;
543 : }
544 :
545 : /*
546 : * Read a strip of data and decompress the specified
547 : * amount into the user-supplied buffer.
548 : */
549 2101790 : tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
550 : tmsize_t size)
551 : {
552 : static const char module[] = "TIFFReadEncodedStrip";
553 2101790 : TIFFDirectory *td = &tif->tif_dir;
554 : tmsize_t stripsize;
555 : uint16_t plane;
556 :
557 2101790 : stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
558 2101780 : if (stripsize == ((tmsize_t)(-1)))
559 0 : return ((tmsize_t)(-1));
560 :
561 : /* shortcut to avoid an extra memcpy() */
562 2101780 : if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
563 2085280 : size >= stripsize && !isMapped(tif) &&
564 2085290 : ((tif->tif_flags & TIFF_NOREADRAW) == 0))
565 : {
566 2085290 : if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize)
567 64 : return ((tmsize_t)(-1));
568 :
569 2085260 : if (!isFillOrder(tif, td->td_fillorder) &&
570 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
571 0 : TIFFReverseBits((uint8_t *)buf, stripsize);
572 :
573 2085260 : (*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize);
574 2085240 : return (stripsize);
575 : }
576 :
577 16494 : if ((size != (tmsize_t)(-1)) && (size < stripsize))
578 0 : stripsize = size;
579 16494 : 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 16466 : (*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize);
590 16465 : 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 2085320 : static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
658 : tmsize_t size, const char *module)
659 : {
660 2085320 : assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
661 2085320 : if (!isMapped(tif))
662 : {
663 : tmsize_t cc;
664 :
665 2085310 : 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 2085300 : cc = TIFFReadFile(tif, buf, size);
673 2085320 : 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 9 : tmsize_t ma = 0;
686 : tmsize_t n;
687 9 : 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 2085270 : return (size);
716 : }
717 :
718 23292 : static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile,
719 : int is_strip, tmsize_t size,
720 : const char *module)
721 : {
722 23292 : assert(!isMapped(tif));
723 23292 : assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
724 :
725 23292 : 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 23297 : if (!TIFFReadAndRealloc(tif, size, 0, is_strip, strip_or_tile, module))
744 : {
745 31 : return ((tmsize_t)(-1));
746 : }
747 :
748 23266 : 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 16533 : int TIFFFillStrip(TIFF *tif, uint32_t strip)
797 : {
798 : static const char module[] = "TIFFFillStrip";
799 16533 : TIFFDirectory *td = &tif->tif_dir;
800 :
801 16533 : if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
802 : {
803 16534 : uint64_t bytecount = TIFFGetStrileByteCount(tif, strip);
804 16533 : if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
805 : {
806 0 : 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 : /* Byte count should normally not be larger than a number of */
815 : /* times the uncompressed size plus some margin */
816 16533 : if (bytecount > 1024 * 1024)
817 : {
818 : /* 10 and 4096 are just values that could be adjusted. */
819 : /* Hopefully they are safe enough for all codecs */
820 3 : tmsize_t stripsize = TIFFStripSize(tif);
821 3 : if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
822 : {
823 1 : uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
824 1 : TIFFErrorExtR(tif, module,
825 : "Too large strip byte count %" PRIu64
826 : ", strip %" PRIu32 ". Limiting to %" PRIu64,
827 : bytecount, strip, newbytecount);
828 1 : bytecount = newbytecount;
829 : }
830 : }
831 :
832 16533 : if (isMapped(tif))
833 : {
834 : /*
835 : * We must check for overflow, potentially causing
836 : * an OOB read. Instead of simple
837 : *
838 : * TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size
839 : *
840 : * comparison (which can overflow) we do the following
841 : * two comparisons:
842 : */
843 4 : if (bytecount > (uint64_t)tif->tif_size ||
844 4 : TIFFGetStrileOffset(tif, strip) >
845 4 : (uint64_t)tif->tif_size - bytecount)
846 : {
847 : /*
848 : * This error message might seem strange, but
849 : * it's what would happen if a read were done
850 : * instead.
851 : */
852 6 : TIFFErrorExtR(
853 : tif, module,
854 :
855 : "Read error on strip %" PRIu32 "; "
856 : "got %" PRIu64 " bytes, expected %" PRIu64,
857 : strip,
858 2 : NoSanitizeSubUInt64((uint64_t)tif->tif_size,
859 : TIFFGetStrileOffset(tif, strip)),
860 : bytecount);
861 2 : tif->tif_dir.td_curstrip = NOSTRIP;
862 2 : return (0);
863 : }
864 : }
865 :
866 16529 : if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
867 0 : (tif->tif_flags & TIFF_NOBITREV)))
868 : {
869 : /*
870 : * The image is mapped into memory and we either don't
871 : * need to flip bits or the compression routine is
872 : * going to handle this operation itself. In this
873 : * case, avoid copying the raw data and instead just
874 : * reference the data from the memory mapped file
875 : * image. This assumes that the decompression
876 : * routines do not modify the contents of the raw data
877 : * buffer (if they try to, the application will get a
878 : * fault since the file is mapped read-only).
879 : */
880 1 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
881 : {
882 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
883 0 : tif->tif_rawdata = NULL;
884 0 : tif->tif_rawdatasize = 0;
885 : }
886 1 : tif->tif_flags &= ~TIFF_MYBUFFER;
887 1 : tif->tif_rawdatasize = (tmsize_t)bytecount;
888 2 : tif->tif_rawdata =
889 1 : tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip);
890 2 : tif->tif_rawdataoff = 0;
891 2 : tif->tif_rawdataloaded = (tmsize_t)bytecount;
892 :
893 : /*
894 : * When we have tif_rawdata reference directly into the memory
895 : * mapped file we need to be pretty careful about how we use the
896 : * rawdata. It is not a general purpose working buffer as it
897 : * normally otherwise is. So we keep track of this fact to avoid
898 : * using it improperly.
899 : */
900 2 : tif->tif_flags |= TIFF_BUFFERMMAP;
901 : }
902 : else
903 : {
904 : /*
905 : * Expand raw data buffer, if needed, to hold data
906 : * strip coming from file (perhaps should set upper
907 : * bound on the size of a buffer we'll use?).
908 : */
909 : tmsize_t bytecountm;
910 16528 : bytecountm = (tmsize_t)bytecount;
911 16528 : if ((uint64_t)bytecountm != bytecount)
912 : {
913 0 : TIFFErrorExtR(tif, module, "Integer overflow");
914 0 : return (0);
915 : }
916 16528 : if (bytecountm > tif->tif_rawdatasize)
917 : {
918 1036 : tif->tif_dir.td_curstrip = NOSTRIP;
919 1036 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
920 : {
921 0 : TIFFErrorExtR(
922 : tif, module,
923 : "Data buffer too small to hold strip %" PRIu32, strip);
924 0 : return (0);
925 : }
926 : }
927 16528 : if (tif->tif_flags & TIFF_BUFFERMMAP)
928 : {
929 0 : tif->tif_dir.td_curstrip = NOSTRIP;
930 0 : tif->tif_rawdata = NULL;
931 0 : tif->tif_rawdatasize = 0;
932 0 : tif->tif_flags &= ~TIFF_BUFFERMMAP;
933 : }
934 :
935 16528 : if (isMapped(tif))
936 : {
937 0 : if (bytecountm > tif->tif_rawdatasize &&
938 0 : !TIFFReadBufferSetup(tif, 0, bytecountm))
939 : {
940 0 : return (0);
941 : }
942 0 : if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecountm,
943 : module) != bytecountm)
944 : {
945 0 : return (0);
946 : }
947 : }
948 : else
949 : {
950 16528 : if (TIFFReadRawStripOrTile2(tif, strip, 1, bytecountm,
951 : module) != bytecountm)
952 : {
953 4 : return (0);
954 : }
955 : }
956 :
957 16526 : tif->tif_rawdataoff = 0;
958 16526 : tif->tif_rawdataloaded = bytecountm;
959 :
960 16526 : if (!isFillOrder(tif, td->td_fillorder) &&
961 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
962 0 : TIFFReverseBits(tif->tif_rawdata, bytecountm);
963 : }
964 : }
965 16527 : return (TIFFStartStrip(tif, strip));
966 : }
967 :
968 : /*
969 : * Tile-oriented Read Support
970 : * Contributed by Nancy Cam (Silicon Graphics).
971 : */
972 :
973 : /*
974 : * Read and decompress a tile of data. The
975 : * tile is selected by the (x,y,z,s) coordinates.
976 : */
977 2 : tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
978 : uint16_t s)
979 : {
980 2 : if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
981 0 : return ((tmsize_t)(-1));
982 2 : return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
983 : (tmsize_t)(-1)));
984 : }
985 :
986 : /*
987 : * Read a tile of data and decompress the specified
988 : * amount into the user-supplied buffer.
989 : */
990 30350 : tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
991 : {
992 : static const char module[] = "TIFFReadEncodedTile";
993 30350 : TIFFDirectory *td = &tif->tif_dir;
994 30350 : tmsize_t tilesize = tif->tif_dir.td_tilesize;
995 :
996 30350 : if (!TIFFCheckRead(tif, 1))
997 0 : return ((tmsize_t)(-1));
998 30350 : if (tile >= td->td_nstrips)
999 : {
1000 0 : TIFFErrorExtR(tif, module,
1001 : "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
1002 : td->td_nstrips);
1003 0 : return ((tmsize_t)(-1));
1004 : }
1005 :
1006 : /* shortcut to avoid an extra memcpy() */
1007 30350 : if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
1008 23581 : size >= tilesize && !isMapped(tif) &&
1009 23581 : ((tif->tif_flags & TIFF_NOREADRAW) == 0))
1010 : {
1011 23581 : if (TIFFReadRawTile1(tif, tile, buf, tilesize, module) != tilesize)
1012 4 : return ((tmsize_t)(-1));
1013 :
1014 23577 : if (!isFillOrder(tif, td->td_fillorder) &&
1015 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
1016 0 : TIFFReverseBits((uint8_t *)buf, tilesize);
1017 :
1018 23577 : (*tif->tif_postdecode)(tif, (uint8_t *)buf, tilesize);
1019 23577 : return (tilesize);
1020 : }
1021 :
1022 6769 : if (size == (tmsize_t)(-1))
1023 2 : size = tilesize;
1024 6767 : else if (size > tilesize)
1025 0 : size = tilesize;
1026 6769 : if (!TIFFFillTile(tif, tile))
1027 : {
1028 : /* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
1029 30 : if (buf)
1030 30 : memset(buf, 0, (size_t)size);
1031 30 : return ((tmsize_t)(-1));
1032 : }
1033 6739 : else if ((*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
1034 6739 : (uint16_t)(tile / td->td_stripsperimage)))
1035 : {
1036 6739 : (*tif->tif_postdecode)(tif, (uint8_t *)buf, size);
1037 6739 : return (size);
1038 : }
1039 : else
1040 0 : return ((tmsize_t)(-1));
1041 : }
1042 :
1043 : /* Variant of TIFFReadTile() that does
1044 : * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
1045 : * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
1046 : * of truncated file.
1047 : * * calls regular TIFFReadEncodedTile() if *buf != NULL
1048 : */
1049 4 : tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf,
1050 : tmsize_t bufsizetoalloc, uint32_t x,
1051 : uint32_t y, uint32_t z, uint16_t s)
1052 : {
1053 4 : if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
1054 0 : return ((tmsize_t)(-1));
1055 4 : return (_TIFFReadEncodedTileAndAllocBuffer(
1056 : tif, TIFFComputeTile(tif, x, y, z, s), buf, bufsizetoalloc,
1057 : (tmsize_t)(-1)));
1058 : }
1059 :
1060 : /* Variant of TIFFReadEncodedTile() that does
1061 : * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
1062 : * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
1063 : * of truncated file.
1064 : * * calls regular TIFFReadEncodedTile() if *buf != NULL
1065 : */
1066 4 : tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
1067 : void **buf, tmsize_t bufsizetoalloc,
1068 : tmsize_t size_to_read)
1069 : {
1070 : static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer";
1071 4 : TIFFDirectory *td = &tif->tif_dir;
1072 4 : tmsize_t tilesize = tif->tif_dir.td_tilesize;
1073 :
1074 4 : if (*buf != NULL)
1075 : {
1076 0 : return TIFFReadEncodedTile(tif, tile, *buf, size_to_read);
1077 : }
1078 :
1079 4 : if (!TIFFCheckRead(tif, 1))
1080 0 : return ((tmsize_t)(-1));
1081 4 : if (tile >= td->td_nstrips)
1082 : {
1083 0 : TIFFErrorExtR(tif, module,
1084 : "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
1085 : td->td_nstrips);
1086 0 : return ((tmsize_t)(-1));
1087 : }
1088 :
1089 4 : if (!TIFFFillTile(tif, tile))
1090 1 : return ((tmsize_t)(-1));
1091 :
1092 : /* Sanity checks to avoid excessive memory allocation */
1093 : /* Cf https://gitlab.com/libtiff/libtiff/-/issues/479 */
1094 3 : if (td->td_compression == COMPRESSION_NONE)
1095 : {
1096 2 : if (tif->tif_rawdatasize != tilesize)
1097 : {
1098 0 : TIFFErrorExtR(tif, TIFFFileName(tif),
1099 : "Invalid tile byte count for tile %u. "
1100 : "Expected %" PRIu64 ", got %" PRIu64,
1101 : tile, (uint64_t)tilesize,
1102 0 : (uint64_t)tif->tif_rawdatasize);
1103 0 : return ((tmsize_t)(-1));
1104 : }
1105 : }
1106 : else
1107 : {
1108 : /* Max compression ratio experimentally determined. Might be fragile...
1109 : * Only apply this heuristics to situations where the memory allocation
1110 : * would be big, to avoid breaking nominal use cases.
1111 : */
1112 1 : if (bufsizetoalloc > 100 * 1024 * 1024)
1113 : {
1114 : const uint64_t maxCompressionRatio =
1115 0 : TIFFGetMaxCompressionRatio(tif);
1116 0 : if (maxCompressionRatio > 0 &&
1117 0 : (uint64_t)tif->tif_rawdatasize <
1118 0 : (uint64_t)tilesize / maxCompressionRatio)
1119 : {
1120 0 : TIFFErrorExtR(tif, TIFFFileName(tif),
1121 : "Likely invalid tile byte count for tile %u. "
1122 : "Uncompressed tile size is %" PRIu64 ", "
1123 : "compressed one is %" PRIu64,
1124 : tile, (uint64_t)tilesize,
1125 0 : (uint64_t)tif->tif_rawdatasize);
1126 0 : return ((tmsize_t)(-1));
1127 : }
1128 : }
1129 : }
1130 :
1131 3 : *buf = _TIFFmallocExt(tif, bufsizetoalloc);
1132 3 : if (*buf == NULL)
1133 : {
1134 0 : TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
1135 0 : return ((tmsize_t)(-1));
1136 : }
1137 3 : _TIFFmemset(*buf, 0, bufsizetoalloc);
1138 :
1139 3 : if (size_to_read == (tmsize_t)(-1))
1140 3 : size_to_read = tilesize;
1141 0 : else if (size_to_read > tilesize)
1142 0 : size_to_read = tilesize;
1143 3 : if ((*tif->tif_decodetile)(tif, (uint8_t *)*buf, size_to_read,
1144 3 : (uint16_t)(tile / td->td_stripsperimage)))
1145 : {
1146 3 : (*tif->tif_postdecode)(tif, (uint8_t *)*buf, size_to_read);
1147 3 : return (size_to_read);
1148 : }
1149 : else
1150 0 : return ((tmsize_t)(-1));
1151 : }
1152 :
1153 23584 : static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
1154 : tmsize_t size, const char *module)
1155 : {
1156 23584 : assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
1157 23584 : if (!isMapped(tif))
1158 : {
1159 : tmsize_t cc;
1160 :
1161 23584 : if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile)))
1162 : {
1163 0 : TIFFErrorExtR(tif, module,
1164 : "Seek error at row %" PRIu32 ", col %" PRIu32
1165 : ", tile %" PRIu32,
1166 : tif->tif_dir.td_row, tif->tif_dir.td_col, tile);
1167 0 : return ((tmsize_t)(-1));
1168 : }
1169 23584 : cc = TIFFReadFile(tif, buf, size);
1170 23584 : if (cc != size)
1171 : {
1172 4 : TIFFErrorExtR(tif, module,
1173 : "Read error at row %" PRIu32 ", col %" PRIu32
1174 : "; got %" TIFF_SSIZE_FORMAT
1175 : " bytes, expected %" TIFF_SSIZE_FORMAT,
1176 : tif->tif_dir.td_row, tif->tif_dir.td_col, cc, size);
1177 4 : return ((tmsize_t)(-1));
1178 : }
1179 : }
1180 : else
1181 : {
1182 : tmsize_t ma, mb;
1183 : tmsize_t n;
1184 0 : ma = (tmsize_t)TIFFGetStrileOffset(tif, tile);
1185 0 : mb = ma + size;
1186 0 : if ((TIFFGetStrileOffset(tif, tile) > (uint64_t)TIFF_TMSIZE_T_MAX) ||
1187 0 : (ma > tif->tif_size))
1188 0 : n = 0;
1189 0 : else if ((mb < ma) || (mb < size) || (mb > tif->tif_size))
1190 0 : n = tif->tif_size - ma;
1191 : else
1192 0 : n = size;
1193 0 : if (n != size)
1194 : {
1195 0 : TIFFErrorExtR(tif, module,
1196 : "Read error at row %" PRIu32 ", col %" PRIu32
1197 : ", tile %" PRIu32 "; got %" TIFF_SSIZE_FORMAT
1198 : " bytes, expected %" TIFF_SSIZE_FORMAT,
1199 : tif->tif_dir.td_row, tif->tif_dir.td_col, tile, n,
1200 : size);
1201 0 : return ((tmsize_t)(-1));
1202 : }
1203 0 : _TIFFmemcpy(buf, tif->tif_base + ma, size);
1204 : }
1205 23580 : return (size);
1206 : }
1207 :
1208 : /*
1209 : * Read a tile of data from the file.
1210 : */
1211 3 : tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
1212 : {
1213 : static const char module[] = "TIFFReadRawTile";
1214 3 : TIFFDirectory *td = &tif->tif_dir;
1215 : uint64_t bytecount64;
1216 : tmsize_t bytecountm;
1217 :
1218 3 : if (!TIFFCheckRead(tif, 1))
1219 0 : return ((tmsize_t)(-1));
1220 3 : if (tile >= td->td_nstrips)
1221 : {
1222 0 : TIFFErrorExtR(tif, module,
1223 : "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
1224 : td->td_nstrips);
1225 0 : return ((tmsize_t)(-1));
1226 : }
1227 3 : if (tif->tif_flags & TIFF_NOREADRAW)
1228 : {
1229 0 : TIFFErrorExtR(tif, module,
1230 : "Compression scheme does not support access to raw "
1231 : "uncompressed data");
1232 0 : return ((tmsize_t)(-1));
1233 : }
1234 3 : bytecount64 = TIFFGetStrileByteCount(tif, tile);
1235 3 : if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64)
1236 3 : bytecountm = size;
1237 : else
1238 0 : bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
1239 3 : if (bytecountm == 0)
1240 : {
1241 0 : return ((tmsize_t)(-1));
1242 : }
1243 3 : return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
1244 : }
1245 :
1246 : /*
1247 : * Read the specified tile and setup for decoding. The data buffer is
1248 : * expanded, as necessary, to hold the tile's data.
1249 : */
1250 6773 : int TIFFFillTile(TIFF *tif, uint32_t tile)
1251 : {
1252 : static const char module[] = "TIFFFillTile";
1253 6773 : TIFFDirectory *td = &tif->tif_dir;
1254 :
1255 6773 : if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
1256 : {
1257 6771 : uint64_t bytecount = TIFFGetStrileByteCount(tif, tile);
1258 6771 : if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
1259 : {
1260 0 : TIFFErrorExtR(tif, module,
1261 : "%" PRIu64 ": Invalid tile byte count, tile %" PRIu32,
1262 : bytecount, tile);
1263 0 : return (0);
1264 : }
1265 :
1266 : /* To avoid excessive memory allocations: */
1267 : /* Byte count should normally not be larger than a number of */
1268 : /* times the uncompressed size plus some margin */
1269 6771 : if (bytecount > 1024 * 1024)
1270 : {
1271 : /* 10 and 4096 are just values that could be adjusted. */
1272 : /* Hopefully they are safe enough for all codecs */
1273 3 : tmsize_t stripsize = TIFFTileSize(tif);
1274 3 : if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
1275 : {
1276 1 : uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
1277 1 : TIFFErrorExtR(tif, module,
1278 : "Too large tile byte count %" PRIu64
1279 : ", tile %" PRIu32 ". Limiting to %" PRIu64,
1280 : bytecount, tile, newbytecount);
1281 1 : bytecount = newbytecount;
1282 : }
1283 : }
1284 :
1285 6771 : if (isMapped(tif))
1286 : {
1287 : /*
1288 : * We must check for overflow, potentially causing
1289 : * an OOB read. Instead of simple
1290 : *
1291 : * TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size
1292 : *
1293 : * comparison (which can overflow) we do the following
1294 : * two comparisons:
1295 : */
1296 4 : if (bytecount > (uint64_t)tif->tif_size ||
1297 4 : TIFFGetStrileOffset(tif, tile) >
1298 4 : (uint64_t)tif->tif_size - bytecount)
1299 : {
1300 2 : tif->tif_dir.td_curtile = NOTILE;
1301 2 : return (0);
1302 : }
1303 : }
1304 :
1305 6769 : if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
1306 0 : (tif->tif_flags & TIFF_NOBITREV)))
1307 : {
1308 : /*
1309 : * The image is mapped into memory and we either don't
1310 : * need to flip bits or the compression routine is
1311 : * going to handle this operation itself. In this
1312 : * case, avoid copying the raw data and instead just
1313 : * reference the data from the memory mapped file
1314 : * image. This assumes that the decompression
1315 : * routines do not modify the contents of the raw data
1316 : * buffer (if they try to, the application will get a
1317 : * fault since the file is mapped read-only).
1318 : */
1319 2 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
1320 : {
1321 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
1322 0 : tif->tif_rawdata = NULL;
1323 0 : tif->tif_rawdatasize = 0;
1324 : }
1325 2 : tif->tif_flags &= ~TIFF_MYBUFFER;
1326 :
1327 2 : tif->tif_rawdatasize = (tmsize_t)bytecount;
1328 2 : tif->tif_rawdata =
1329 2 : tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile);
1330 2 : tif->tif_rawdataoff = 0;
1331 2 : tif->tif_rawdataloaded = (tmsize_t)bytecount;
1332 2 : tif->tif_flags |= TIFF_BUFFERMMAP;
1333 : }
1334 : else
1335 : {
1336 : /*
1337 : * Expand raw data buffer, if needed, to hold data
1338 : * tile coming from file (perhaps should set upper
1339 : * bound on the size of a buffer we'll use?).
1340 : */
1341 : tmsize_t bytecountm;
1342 6767 : bytecountm = (tmsize_t)bytecount;
1343 6767 : if ((uint64_t)bytecountm != bytecount)
1344 : {
1345 0 : TIFFErrorExtR(tif, module, "Integer overflow");
1346 0 : return (0);
1347 : }
1348 6767 : if (bytecountm > tif->tif_rawdatasize)
1349 : {
1350 908 : tif->tif_dir.td_curtile = NOTILE;
1351 908 : if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
1352 : {
1353 0 : TIFFErrorExtR(tif, module,
1354 : "Data buffer too small to hold tile %" PRIu32,
1355 : tile);
1356 0 : return (0);
1357 : }
1358 : }
1359 6767 : if (tif->tif_flags & TIFF_BUFFERMMAP)
1360 : {
1361 0 : tif->tif_dir.td_curtile = NOTILE;
1362 0 : tif->tif_rawdata = NULL;
1363 0 : tif->tif_rawdatasize = 0;
1364 0 : tif->tif_flags &= ~TIFF_BUFFERMMAP;
1365 : }
1366 :
1367 6767 : if (isMapped(tif))
1368 : {
1369 0 : if (bytecountm > tif->tif_rawdatasize &&
1370 0 : !TIFFReadBufferSetup(tif, 0, bytecountm))
1371 : {
1372 0 : return (0);
1373 : }
1374 0 : if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, bytecountm,
1375 : module) != bytecountm)
1376 : {
1377 0 : return (0);
1378 : }
1379 : }
1380 : else
1381 : {
1382 6767 : if (TIFFReadRawStripOrTile2(tif, tile, 0, bytecountm, module) !=
1383 : bytecountm)
1384 : {
1385 27 : return (0);
1386 : }
1387 : }
1388 :
1389 6740 : tif->tif_rawdataoff = 0;
1390 6740 : tif->tif_rawdataloaded = bytecountm;
1391 :
1392 6740 : if (tif->tif_rawdata != NULL &&
1393 6740 : !isFillOrder(tif, td->td_fillorder) &&
1394 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
1395 0 : TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdataloaded);
1396 : }
1397 : }
1398 6744 : return (TIFFStartTile(tif, tile));
1399 : }
1400 :
1401 : /*
1402 : * Setup the raw data buffer in preparation for
1403 : * reading a strip of raw data. If the buffer
1404 : * is specified as zero, then a buffer of appropriate
1405 : * size is allocated by the library. Otherwise,
1406 : * the client must guarantee that the buffer is
1407 : * large enough to hold any individual strip of
1408 : * raw data.
1409 : */
1410 0 : int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size)
1411 : {
1412 : static const char module[] = "TIFFReadBufferSetup";
1413 :
1414 0 : assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
1415 0 : tif->tif_flags &= ~TIFF_BUFFERMMAP;
1416 :
1417 0 : if (tif->tif_rawdata)
1418 : {
1419 0 : if (tif->tif_flags & TIFF_MYBUFFER)
1420 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
1421 0 : tif->tif_rawdata = NULL;
1422 0 : tif->tif_rawdatasize = 0;
1423 : }
1424 0 : if (bp)
1425 : {
1426 0 : tif->tif_rawdatasize = size;
1427 0 : tif->tif_rawdata = (uint8_t *)bp;
1428 0 : tif->tif_flags &= ~TIFF_MYBUFFER;
1429 : }
1430 : else
1431 : {
1432 0 : tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64_t)size, 1024);
1433 0 : if (tif->tif_rawdatasize == 0)
1434 : {
1435 0 : TIFFErrorExtR(tif, module, "Invalid buffer size");
1436 0 : return (0);
1437 : }
1438 : /* Initialize to zero to avoid uninitialized buffers in case of */
1439 : /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */
1440 0 : tif->tif_rawdata =
1441 0 : (uint8_t *)_TIFFcallocExt(tif, 1, tif->tif_rawdatasize);
1442 0 : tif->tif_flags |= TIFF_MYBUFFER;
1443 : }
1444 0 : if (tif->tif_rawdata == NULL)
1445 : {
1446 0 : TIFFErrorExtR(tif, module,
1447 : "No space for data buffer at scanline %" PRIu32,
1448 : tif->tif_dir.td_row);
1449 0 : tif->tif_rawdatasize = 0;
1450 0 : return (0);
1451 : }
1452 0 : return (1);
1453 : }
1454 :
1455 : /*
1456 : * Set state to appear as if a
1457 : * strip has just been read in.
1458 : */
1459 18965 : static int TIFFStartStrip(TIFF *tif, uint32_t strip)
1460 : {
1461 18965 : TIFFDirectory *td = &tif->tif_dir;
1462 :
1463 18965 : if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
1464 : {
1465 3339 : if (!(*tif->tif_setupdecode)(tif))
1466 1 : return (0);
1467 3343 : tif->tif_flags |= TIFF_CODERSETUP;
1468 : }
1469 18969 : if (td->td_stripsperimage == 0)
1470 : {
1471 0 : TIFFErrorExtR(tif, "TIFFStartStrip", "Zero strips per image");
1472 0 : return 0;
1473 : }
1474 18969 : tif->tif_dir.td_curstrip = strip;
1475 18969 : tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
1476 18969 : tif->tif_flags &= ~TIFF_BUF4WRITE;
1477 :
1478 18969 : if (tif->tif_flags & TIFF_NOREADRAW)
1479 : {
1480 0 : tif->tif_rawcp = NULL;
1481 0 : tif->tif_rawcc = 0;
1482 : }
1483 : else
1484 : {
1485 18969 : tif->tif_rawcp = tif->tif_rawdata;
1486 18969 : if (tif->tif_rawdataloaded > 0)
1487 18960 : tif->tif_rawcc = tif->tif_rawdataloaded;
1488 : else
1489 9 : tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
1490 : }
1491 18960 : if ((*tif->tif_predecode)(tif, (uint16_t)(strip / td->td_stripsperimage)) ==
1492 : 0)
1493 : {
1494 : /* Needed for example for scanline access, if tif_predecode */
1495 : /* fails, and we try to read the same strip again. Without invalidating
1496 : */
1497 : /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */
1498 : /* codec state. */
1499 2 : tif->tif_dir.td_curstrip = NOSTRIP;
1500 2 : return 0;
1501 : }
1502 18960 : return 1;
1503 : }
1504 :
1505 : /*
1506 : * Set state to appear as if a
1507 : * tile has just been read in.
1508 : */
1509 6984 : static int TIFFStartTile(TIFF *tif, uint32_t tile)
1510 : {
1511 : static const char module[] = "TIFFStartTile";
1512 6984 : TIFFDirectory *td = &tif->tif_dir;
1513 : uint32_t howmany32;
1514 :
1515 6984 : if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
1516 : {
1517 934 : if (!(*tif->tif_setupdecode)(tif))
1518 0 : return (0);
1519 934 : tif->tif_flags |= TIFF_CODERSETUP;
1520 : }
1521 6984 : tif->tif_dir.td_curtile = tile;
1522 6984 : if (td->td_tilewidth == 0)
1523 : {
1524 0 : TIFFErrorExtR(tif, module, "Zero tilewidth");
1525 0 : return 0;
1526 : }
1527 6984 : howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
1528 6984 : if (howmany32 == 0)
1529 : {
1530 0 : TIFFErrorExtR(tif, module, "Zero tiles");
1531 0 : return 0;
1532 : }
1533 6984 : tif->tif_dir.td_row = (tile % howmany32) * td->td_tilelength;
1534 6984 : howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
1535 6984 : if (howmany32 == 0)
1536 : {
1537 0 : TIFFErrorExtR(tif, module, "Zero tiles");
1538 0 : return 0;
1539 : }
1540 6984 : tif->tif_dir.td_col = (tile % howmany32) * td->td_tilewidth;
1541 6984 : tif->tif_flags &= ~TIFF_BUF4WRITE;
1542 6984 : if (tif->tif_flags & TIFF_NOREADRAW)
1543 : {
1544 2 : tif->tif_rawcp = NULL;
1545 2 : tif->tif_rawcc = 0;
1546 : }
1547 : else
1548 : {
1549 6982 : tif->tif_rawcp = tif->tif_rawdata;
1550 6982 : if (tif->tif_rawdataloaded > 0)
1551 6982 : tif->tif_rawcc = tif->tif_rawdataloaded;
1552 : else
1553 0 : tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile);
1554 : }
1555 : return (
1556 6984 : (*tif->tif_predecode)(tif, (uint16_t)(tile / td->td_stripsperimage)));
1557 : }
1558 :
1559 2285450 : static int TIFFCheckRead(TIFF *tif, int tiles)
1560 : {
1561 2285450 : if (tif->tif_mode == O_WRONLY)
1562 : {
1563 0 : TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
1564 0 : return (0);
1565 : }
1566 2285450 : if (tiles ^ isTiled(tif))
1567 : {
1568 0 : TIFFErrorExtR(tif, tif->tif_name,
1569 : tiles ? "Can not read tiles from a striped image"
1570 : : "Can not read scanlines from a tiled image");
1571 0 : return (0);
1572 : }
1573 2285450 : return (1);
1574 : }
1575 :
1576 : /* Use the provided input buffer (inbuf, insize) and decompress it into
1577 : * (outbuf, outsize).
1578 : * This function replaces the use of
1579 : * TIFFReadEncodedStrip()/TIFFReadEncodedTile() when the user can provide the
1580 : * buffer for the input data, for example when he wants to avoid libtiff to read
1581 : * the strile offset/count values from the [Strip|Tile][Offsets/ByteCounts]
1582 : * array. inbuf content must be writable (if bit reversal is needed) Returns 1
1583 : * in case of success, 0 otherwise.
1584 : */
1585 2620 : int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
1586 : tmsize_t insize, void *outbuf, tmsize_t outsize)
1587 : {
1588 : static const char module[] = "TIFFReadFromUserBuffer";
1589 2620 : TIFFDirectory *td = &tif->tif_dir;
1590 2620 : int ret = 1;
1591 2620 : uint32_t old_tif_flags = tif->tif_flags;
1592 2620 : tmsize_t old_rawdatasize = tif->tif_rawdatasize;
1593 2620 : void *old_rawdata = tif->tif_rawdata;
1594 :
1595 2620 : if (tif->tif_mode == O_WRONLY)
1596 : {
1597 0 : TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
1598 0 : return 0;
1599 : }
1600 2620 : if (tif->tif_flags & TIFF_NOREADRAW)
1601 : {
1602 0 : TIFFErrorExtR(tif, module,
1603 : "Compression scheme does not support access to raw "
1604 : "uncompressed data");
1605 0 : return 0;
1606 : }
1607 :
1608 2620 : tif->tif_flags &= ~TIFF_MYBUFFER;
1609 2620 : tif->tif_flags |= TIFF_BUFFERMMAP;
1610 2620 : tif->tif_rawdatasize = insize;
1611 2620 : tif->tif_rawdata = (uint8_t *)inbuf;
1612 2620 : tif->tif_rawdataoff = 0;
1613 2620 : tif->tif_rawdataloaded = insize;
1614 :
1615 2620 : if (!isFillOrder(tif, td->td_fillorder) &&
1616 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
1617 : {
1618 0 : TIFFReverseBits((uint8_t *)inbuf, insize);
1619 : }
1620 :
1621 2620 : if (TIFFIsTiled(tif))
1622 : {
1623 245 : if (!TIFFStartTile(tif, strile))
1624 : {
1625 0 : ret = 0;
1626 : /* See related TIFFReadEncodedStrip comment. */
1627 0 : if (outbuf)
1628 0 : memset(outbuf, 0, (size_t)outsize);
1629 : }
1630 240 : else if (!(*tif->tif_decodetile)(
1631 : tif, (uint8_t *)outbuf, outsize,
1632 240 : (uint16_t)(strile / td->td_stripsperimage)))
1633 : {
1634 0 : ret = 0;
1635 : }
1636 : }
1637 : else
1638 : {
1639 2373 : uint32_t rowsperstrip = td->td_rowsperstrip;
1640 : uint32_t stripsperplane;
1641 2373 : if (rowsperstrip > td->td_imagelength)
1642 0 : rowsperstrip = td->td_imagelength;
1643 2373 : if (rowsperstrip == 0)
1644 : {
1645 0 : TIFFErrorExtR(tif, module, "rowsperstrip is zero");
1646 0 : ret = 0;
1647 : }
1648 : else
1649 : {
1650 2373 : stripsperplane =
1651 2373 : TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
1652 2373 : if (!TIFFStartStrip(tif, strile))
1653 : {
1654 0 : ret = 0;
1655 : /* See related TIFFReadEncodedStrip comment. */
1656 0 : if (outbuf)
1657 0 : memset(outbuf, 0, (size_t)outsize);
1658 : }
1659 2382 : else if (!(*tif->tif_decodestrip)(
1660 : tif, (uint8_t *)outbuf, outsize,
1661 2379 : (uint16_t)(strile / stripsperplane)))
1662 : {
1663 0 : ret = 0;
1664 : }
1665 : }
1666 : }
1667 2622 : if (ret)
1668 : {
1669 2619 : (*tif->tif_postdecode)(tif, (uint8_t *)outbuf, outsize);
1670 : }
1671 :
1672 2624 : if (!isFillOrder(tif, td->td_fillorder) &&
1673 0 : (tif->tif_flags & TIFF_NOBITREV) == 0)
1674 : {
1675 0 : TIFFReverseBits((uint8_t *)inbuf, insize);
1676 : }
1677 :
1678 2620 : tif->tif_flags = (old_tif_flags & (TIFF_MYBUFFER | TIFF_BUFFERMMAP)) |
1679 2620 : (tif->tif_flags & ~(TIFF_MYBUFFER | TIFF_BUFFERMMAP));
1680 2620 : tif->tif_rawdatasize = old_rawdatasize;
1681 2620 : tif->tif_rawdata = (uint8_t *)old_rawdata;
1682 2620 : tif->tif_rawdataoff = 0;
1683 2620 : tif->tif_rawdataloaded = 0;
1684 :
1685 2620 : return ret;
1686 : }
1687 :
1688 2539730 : void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc)
1689 : {
1690 : (void)tif;
1691 : (void)buf;
1692 : (void)cc;
1693 2539730 : }
1694 :
1695 5073 : void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1696 : {
1697 : (void)tif;
1698 5073 : assert((cc & 1) == 0);
1699 5073 : TIFFSwabArrayOfShort((uint16_t *)buf, cc / 2);
1700 5073 : }
1701 :
1702 0 : void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1703 : {
1704 : (void)tif;
1705 0 : assert((cc % 3) == 0);
1706 0 : TIFFSwabArrayOfTriples((uint8_t *)buf, cc / 3);
1707 0 : }
1708 :
1709 188 : void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1710 : {
1711 : (void)tif;
1712 188 : assert((cc & 3) == 0);
1713 188 : TIFFSwabArrayOfLong((uint32_t *)buf, cc / 4);
1714 188 : }
1715 :
1716 4 : void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1717 : {
1718 : (void)tif;
1719 4 : assert((cc & 7) == 0);
1720 4 : TIFFSwabArrayOfDouble((double *)buf, cc / 8);
1721 4 : }
|