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