OLD | NEW |
| (Empty) |
1 /* $Id: tif_read.c,v 1.41 2012-07-06 19:22:58 bfriesen Exp $ */ | |
2 | |
3 /* | |
4 * Copyright (c) 1988-1997 Sam Leffler | |
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc. | |
6 * | |
7 * Permission to use, copy, modify, distribute, and sell this software and | |
8 * its documentation for any purpose is hereby granted without fee, provided | |
9 * that (i) the above copyright notices and this permission notice appear in | |
10 * all copies of the software and related documentation, and (ii) the names of | |
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or | |
12 * publicity relating to the software without the specific, prior written | |
13 * permission of Sam Leffler and Silicon Graphics. | |
14 * | |
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | |
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | |
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |
18 * | |
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR | |
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | |
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | |
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
24 * OF THIS SOFTWARE. | |
25 */ | |
26 | |
27 /* | |
28 * TIFF Library. | |
29 * Scanline-oriented Read Support | |
30 */ | |
31 #include "tiffiop.h" | |
32 #include <stdio.h> | |
33 | |
34 int TIFFFillStrip(TIFF* tif, uint32 strip); | |
35 int TIFFFillTile(TIFF* tif, uint32 tile); | |
36 static int TIFFStartStrip(TIFF* tif, uint32 strip); | |
37 static int TIFFStartTile(TIFF* tif, uint32 tile); | |
38 static int TIFFCheckRead(TIFF*, int); | |
39 static tmsize_t | |
40 TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,const char*
module); | |
41 | |
42 #define NOSTRIP ((uint32)(-1)) /* undefined state */ | |
43 #define NOTILE ((uint32)(-1)) /* undefined state */ | |
44 | |
45 static int | |
46 TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart ) | |
47 { | |
48 static const char module[] = "TIFFFillStripPartial"; | |
49 register TIFFDirectory *td = &tif->tif_dir; | |
50 uint64 unused_data; | |
51 uint64 read_offset; | |
52 tmsize_t cc, to_read; | |
53 /* tmsize_t bytecountm; */ | |
54 | |
55 if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) | |
56 return 0; | |
57 | |
58 /* | |
59 * Expand raw data buffer, if needed, to hold data | |
60 * strip coming from file (perhaps should set upper | |
61 * bound on the size of a buffer we'll use?). | |
62 */ | |
63 | |
64 /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */ | |
65 if (read_ahead*2 > tif->tif_rawdatasize) { | |
66 assert( restart ); | |
67 | |
68 tif->tif_curstrip = NOSTRIP; | |
69 if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { | |
70 TIFFErrorExt(tif->tif_clientdata, module, | |
71 "Data buffer too small to hold part of stri
p %lu", | |
72 (unsigned long) strip); | |
73 return (0); | |
74 } | |
75 if (!TIFFReadBufferSetup(tif, 0, read_ahead*2)) | |
76 return (0); | |
77 } | |
78 | |
79 if( restart ) | |
80 { | |
81 tif->tif_rawdataloaded = 0; | |
82 tif->tif_rawdataoff = 0; | |
83 } | |
84 | |
85 /* | |
86 ** If we are reading more data, move any unused data to the | |
87 ** start of the buffer. | |
88 */ | |
89 if( tif->tif_rawdataloaded > 0 ) | |
90 unused_data = tif->tif_rawdataloaded - (tif->tif_rawcp - tif->ti
f_rawdata); | |
91 else | |
92 unused_data = 0; | |
93 | |
94 if( unused_data > 0 ) | |
95 { | |
96 assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); | |
97 memmove( tif->tif_rawdata, tif->tif_rawcp, (size_t)unused_data )
; | |
98 } | |
99 | |
100 /* | |
101 ** Seek to the point in the file where more data should be read. | |
102 */ | |
103 read_offset = td->td_stripoffset[strip] | |
104 + tif->tif_rawdataoff + tif->tif_rawdataloaded; | |
105 | |
106 if (!SeekOK(tif, read_offset)) { | |
107 TIFFErrorExt(tif->tif_clientdata, module, | |
108 "Seek error at scanline %lu, strip %lu", | |
109 (unsigned long) tif->tif_row, (unsigned long) strip
); | |
110 return 0; | |
111 } | |
112 | |
113 /* | |
114 ** How much do we want to read? | |
115 */ | |
116 to_read = (tmsize_t)(tif->tif_rawdatasize - unused_data); | |
117 if( (uint64) to_read > td->td_stripbytecount[strip] | |
118 - tif->tif_rawdataoff - tif->tif_rawdataloaded ) | |
119 { | |
120 to_read = (tmsize_t)(td->td_stripbytecount[strip] | |
121 - tif->tif_rawdataoff - tif->tif_rawdataloaded); | |
122 } | |
123 | |
124 assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); | |
125 cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read); | |
126 | |
127 if (cc != to_read) { | |
128 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
129 TIFFErrorExt(tif->tif_clientdata, module, | |
130 "Read error at scanline %lu; got %I64u bytes, expec
ted %I64u", | |
131 (unsigned long) tif->tif_row, | |
132 (unsigned __int64) cc, | |
133 (unsigned __int64) to_read); | |
134 #else | |
135 TIFFErrorExt(tif->tif_clientdata, module, | |
136 "Read error at scanline %lu; got %llu bytes, expect
ed %llu", | |
137 (unsigned long) tif->tif_row, | |
138 (unsigned long long) cc, | |
139 (unsigned long long) to_read); | |
140 #endif | |
141 return 0; | |
142 } | |
143 | |
144 tif->tif_rawdataoff = (tmsize_t)(tif->tif_rawdataoff + tif->tif_rawdatal
oaded - unused_data) ; | |
145 tif->tif_rawdataloaded = (tmsize_t)unused_data + to_read; | |
146 | |
147 tif->tif_rawcp = tif->tif_rawdata; | |
148 | |
149 if (!isFillOrder(tif, td->td_fillorder) && | |
150 (tif->tif_flags & TIFF_NOBITREV) == 0) { | |
151 assert((tif->tif_flags&TIFF_BUFFERMMAP)==0); | |
152 TIFFReverseBits(tif->tif_rawdata + unused_data, to_read ); | |
153 } | |
154 | |
155 /* | |
156 ** When starting a strip from the beginning we need to | |
157 ** restart the decoder. | |
158 */ | |
159 if( restart ) | |
160 return TIFFStartStrip(tif, strip); | |
161 else | |
162 return 1; | |
163 } | |
164 | |
165 /* | |
166 * Seek to a random row+sample in a file. | |
167 * | |
168 * Only used by TIFFReadScanline, and is only used on | |
169 * strip organized files. We do some tricky stuff to try | |
170 * and avoid reading the whole compressed raw data for big | |
171 * strips. | |
172 */ | |
173 static int | |
174 TIFFSeek(TIFF* tif, uint32 row, uint16 sample ) | |
175 { | |
176 register TIFFDirectory *td = &tif->tif_dir; | |
177 uint32 strip; | |
178 int whole_strip; | |
179 tmsize_t read_ahead = 0; | |
180 | |
181 /* | |
182 ** Establish what strip we are working from. | |
183 */ | |
184 if (row >= td->td_imagelength) { /* out of range */ | |
185 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, | |
186 "%lu: Row out of range, max %lu", | |
187 (unsigned long) row, | |
188 (unsigned long) td->td_imagelength); | |
189 return (0); | |
190 } | |
191 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { | |
192 if (sample >= td->td_samplesperpixel) { | |
193 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, | |
194 "%lu: Sample out of range, max %lu", | |
195 (unsigned long) sample, (unsigned long) td->td_sampl
esperpixel); | |
196 return (0); | |
197 } | |
198 strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowspe
rstrip; | |
199 } else | |
200 strip = row / td->td_rowsperstrip; | |
201 | |
202 /* | |
203 * Do we want to treat this strip as one whole chunk or | |
204 * read it a few lines at a time? | |
205 */ | |
206 #if defined(CHUNKY_STRIP_READ_SUPPORT) | |
207 if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) | |
208 return 0; | |
209 whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10 | |
210 || isMapped(tif); | |
211 #else | |
212 whole_strip = 1; | |
213 #endif | |
214 | |
215 if( !whole_strip ) | |
216 { | |
217 read_ahead = tif->tif_scanlinesize * 16 + 5000; | |
218 } | |
219 | |
220 /* | |
221 * If we haven't loaded this strip, do so now, possibly | |
222 * only reading the first part. | |
223 */ | |
224 if (strip != tif->tif_curstrip) { /* different strip, refill */ | |
225 | |
226 if( whole_strip ) | |
227 { | |
228 if (!TIFFFillStrip(tif, strip)) | |
229 return (0); | |
230 } | |
231 else | |
232 { | |
233 if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) | |
234 return 0; | |
235 } | |
236 } | |
237 | |
238 /* | |
239 ** If we already have some data loaded, do we need to read some more? | |
240 */ | |
241 else if( !whole_strip ) | |
242 { | |
243 if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawc
p) < read_ahead | |
244 && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td-
>td_stripbytecount[strip] ) | |
245 { | |
246 if( !TIFFFillStripPartial(tif,strip,read_ahead,0) ) | |
247 return 0; | |
248 } | |
249 } | |
250 | |
251 if (row < tif->tif_row) { | |
252 /* | |
253 * Moving backwards within the same strip: backup | |
254 * to the start and then decode forward (below). | |
255 * | |
256 * NB: If you're planning on lots of random access within a | |
257 * strip, it's better to just read and decode the entire | |
258 * strip, and then access the decoded data in a random fashion. | |
259 */ | |
260 | |
261 if( tif->tif_rawdataoff != 0 ) | |
262 { | |
263 if( !TIFFFillStripPartial(tif,strip,read_ahead,1) ) | |
264 return 0; | |
265 } | |
266 else | |
267 { | |
268 if (!TIFFStartStrip(tif, strip)) | |
269 return (0); | |
270 } | |
271 } | |
272 | |
273 if (row != tif->tif_row) { | |
274 /* | |
275 * Seek forward to the desired row. | |
276 */ | |
277 | |
278 /* TODO: Will this really work with partial buffers? */ | |
279 | |
280 if (!(*tif->tif_seek)(tif, row - tif->tif_row)) | |
281 return (0); | |
282 tif->tif_row = row; | |
283 } | |
284 | |
285 return (1); | |
286 } | |
287 | |
288 int | |
289 TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample) | |
290 { | |
291 int e; | |
292 | |
293 if (!TIFFCheckRead(tif, 0)) | |
294 return (-1); | |
295 if( (e = TIFFSeek(tif, row, sample)) != 0) { | |
296 /* | |
297 * Decompress desired row into user buffer. | |
298 */ | |
299 e = (*tif->tif_decoderow) | |
300 (tif, (uint8*) buf, tif->tif_scanlinesize, sample); | |
301 | |
302 /* we are now poised at the beginning of the next row */ | |
303 tif->tif_row = row + 1; | |
304 | |
305 if (e) | |
306 (*tif->tif_postdecode)(tif, (uint8*) buf, | |
307 tif->tif_scanlinesize); | |
308 } | |
309 return (e > 0 ? 1 : -1); | |
310 } | |
311 | |
312 /* | |
313 * Read a strip of data and decompress the specified | |
314 * amount into the user-supplied buffer. | |
315 */ | |
316 tmsize_t | |
317 TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) | |
318 { | |
319 static const char module[] = "TIFFReadEncodedStrip"; | |
320 TIFFDirectory *td = &tif->tif_dir; | |
321 uint32 rowsperstrip; | |
322 uint32 stripsperplane; | |
323 uint32 stripinplane; | |
324 uint16 plane, comp; | |
325 uint32 rows; | |
326 tmsize_t stripsize; | |
327 if (!TIFFCheckRead(tif,0)) | |
328 return((tmsize_t)(-1)); | |
329 if (strip>=td->td_nstrips) | |
330 { | |
331 TIFFErrorExt(tif->tif_clientdata,module, | |
332 "%lu: Strip out of range, max %lu",(unsigned long)strip, | |
333 (unsigned long)td->td_nstrips); | |
334 return((tmsize_t)(-1)); | |
335 } | |
336 /* | |
337 * Calculate the strip size according to the number of | |
338 * rows in the strip (check for truncated last strip on any | |
339 * of the separations). | |
340 */ | |
341 rowsperstrip=td->td_rowsperstrip; | |
342 if (rowsperstrip>td->td_imagelength) | |
343 rowsperstrip=td->td_imagelength; | |
344 stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip); | |
345 stripinplane=(strip%stripsperplane); | |
346 plane=(strip/stripsperplane); | |
347 rows=td->td_imagelength-stripinplane*rowsperstrip; | |
348 if (rows>rowsperstrip) | |
349 rows=rowsperstrip; | |
350 stripsize=TIFFVStripSize(tif,rows); | |
351 if (stripsize==0) | |
352 return((tmsize_t)(-1)); | |
353 if ((size!=(tmsize_t)(-1))&&(size<stripsize)) | |
354 stripsize=size; | |
355 | |
356 /* | |
357 * discard those. | |
358 * keep code modified by Changjin Gao. | |
359 * Xiaochuan Liu 20100828. | |
360 */ | |
361 /*if (!TIFFFillStrip(tif,strip)) | |
362 return((tmsize_t)(-1)); | |
363 if ((*tif->tif_decodestrip)(tif,buf,stripsize,plane)<=0) | |
364 return((tmsize_t)(-1)); | |
365 (*tif->tif_postdecode)(tif,buf,stripsize); | |
366 return(stripsize);*/ | |
367 | |
368 /* | |
369 * Changjin Gao 20110726 fixed decode error issue. | |
370 * Test file: mantis #27308 020511-1158450.tiff. | |
371 */ | |
372 comp = COMPRESSION_NONE; | |
373 StripDecode: | |
374 if (TIFFFillStrip(tif, strip) && (*tif->tif_decodestrip)(tif, buf, strip
size, plane) > 0) | |
375 { | |
376 (*tif->tif_postdecode)(tif, buf, stripsize); | |
377 return (stripsize); | |
378 } | |
379 else | |
380 { | |
381 if (comp < 9) | |
382 { | |
383 TIFFSetField(tif, TIFFTAG_COMPRESSION, comp); | |
384 TIFFSetField(tif, TIFFTAG_FAXMODE,FAXMODE_CLASSIC); | |
385 comp++; | |
386 goto StripDecode; | |
387 } | |
388 | |
389 return ((tsize_t) -1); | |
390 } | |
391 } | |
392 | |
393 static tmsize_t | |
394 TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size, | |
395 const char* module) | |
396 { | |
397 TIFFDirectory *td = &tif->tif_dir; | |
398 | |
399 if (!_TIFFFillStriles( tif )) | |
400 return ((tmsize_t)(-1)); | |
401 | |
402 assert((tif->tif_flags&TIFF_NOREADRAW)==0); | |
403 if (!isMapped(tif)) { | |
404 tmsize_t cc; | |
405 | |
406 if (!SeekOK(tif, td->td_stripoffset[strip])) { | |
407 TIFFErrorExt(tif->tif_clientdata, module, | |
408 "Seek error at scanline %lu, strip %lu", | |
409 (unsigned long) tif->tif_row, (unsigned long) strip)
; | |
410 return ((tmsize_t)(-1)); | |
411 } | |
412 cc = TIFFReadFile(tif, buf, size); | |
413 if (cc != size) { | |
414 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
415 TIFFErrorExt(tif->tif_clientdata, module, | |
416 "Read error at scanline %lu; got %I64u bytes, expected %I64u", | |
417 (unsigned long) tif->tif_row, | |
418 (unsigned __int64) cc, | |
419 (unsigned __int64) size); | |
420 #else | |
421 TIFFErrorExt(tif->tif_clientdata, module, | |
422 "Read error at scanline %lu; got %llu bytes, expected %llu", | |
423 (unsigned long) tif->tif_row, | |
424 (unsigned long long) cc, | |
425 (unsigned long long) size); | |
426 #endif | |
427 return ((tmsize_t)(-1)); | |
428 } | |
429 } else { | |
430 tmsize_t ma,mb; | |
431 tmsize_t n; | |
432 ma=(tmsize_t)td->td_stripoffset[strip]; | |
433 mb=ma+size; | |
434 if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size)) | |
435 n=0; | |
436 else if ((mb<ma)||(mb<size)||(mb>tif->tif_size)) | |
437 n=tif->tif_size-ma; | |
438 else | |
439 n=size; | |
440 if (n!=size) { | |
441 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
442 TIFFErrorExt(tif->tif_clientdata, module, | |
443 "Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u"
, | |
444 (unsigned long) tif->tif_row, | |
445 (unsigned long) strip, | |
446 (unsigned __int64) n, | |
447 (unsigned __int64) size); | |
448 #else | |
449 TIFFErrorExt(tif->tif_clientdata, module, | |
450 "Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu", | |
451 (unsigned long) tif->tif_row, | |
452 (unsigned long) strip, | |
453 (unsigned long long) n, | |
454 (unsigned long long) size); | |
455 #endif | |
456 return ((tmsize_t)(-1)); | |
457 } | |
458 _TIFFmemcpy(buf, tif->tif_base + ma, | |
459 size); | |
460 } | |
461 return (size); | |
462 } | |
463 | |
464 /* | |
465 * Read a strip of data from the file. | |
466 */ | |
467 tmsize_t | |
468 TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size) | |
469 { | |
470 static const char module[] = "TIFFReadRawStrip"; | |
471 TIFFDirectory *td = &tif->tif_dir; | |
472 uint64 bytecount; | |
473 tmsize_t bytecountm; | |
474 | |
475 if (!TIFFCheckRead(tif, 0)) | |
476 return ((tmsize_t)(-1)); | |
477 if (strip >= td->td_nstrips) { | |
478 TIFFErrorExt(tif->tif_clientdata, module, | |
479 "%lu: Strip out of range, max %lu", | |
480 (unsigned long) strip, | |
481 (unsigned long) td->td_nstrips); | |
482 return ((tmsize_t)(-1)); | |
483 } | |
484 if (tif->tif_flags&TIFF_NOREADRAW) | |
485 { | |
486 TIFFErrorExt(tif->tif_clientdata, module, | |
487 "Compression scheme does not support access to raw uncompres
sed data"); | |
488 return ((tmsize_t)(-1)); | |
489 } | |
490 bytecount = td->td_stripbytecount[strip]; | |
491 if (bytecount <= 0) { | |
492 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
493 TIFFErrorExt(tif->tif_clientdata, module, | |
494 "%I64u: Invalid strip byte count, strip %lu", | |
495 (unsigned __int64) bytecount, | |
496 (unsigned long) strip); | |
497 #else | |
498 TIFFErrorExt(tif->tif_clientdata, module, | |
499 "%llu: Invalid strip byte count, strip %lu", | |
500 (unsigned long long) bytecount, | |
501 (unsigned long) strip); | |
502 #endif | |
503 return ((tmsize_t)(-1)); | |
504 } | |
505 bytecountm = (tmsize_t)bytecount; | |
506 if ((uint64)bytecountm!=bytecount) { | |
507 TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow"); | |
508 return ((tmsize_t)(-1)); | |
509 } | |
510 if (size != (tmsize_t)(-1) && size < bytecountm) | |
511 bytecountm = size; | |
512 return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module)); | |
513 } | |
514 | |
515 /* | |
516 * Read the specified strip and setup for decoding. The data buffer is | |
517 * expanded, as necessary, to hold the strip's data. | |
518 */ | |
519 int | |
520 TIFFFillStrip(TIFF* tif, uint32 strip) | |
521 { | |
522 static const char module[] = "TIFFFillStrip"; | |
523 TIFFDirectory *td = &tif->tif_dir; | |
524 | |
525 if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) | |
526 return 0; | |
527 | |
528 if ((tif->tif_flags&TIFF_NOREADRAW)==0) | |
529 { | |
530 uint64 bytecount = td->td_stripbytecount[strip]; | |
531 if (bytecount <= 0) { | |
532 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
533 TIFFErrorExt(tif->tif_clientdata, module, | |
534 "Invalid strip byte count %I64u, strip %lu", | |
535 (unsigned __int64) bytecount, | |
536 (unsigned long) strip); | |
537 #else | |
538 TIFFErrorExt(tif->tif_clientdata, module, | |
539 "Invalid strip byte count %llu, strip %lu", | |
540 (unsigned long long) bytecount, | |
541 (unsigned long) strip); | |
542 #endif | |
543 return (0); | |
544 } | |
545 if (isMapped(tif) && | |
546 (isFillOrder(tif, td->td_fillorder) | |
547 || (tif->tif_flags & TIFF_NOBITREV))) { | |
548 /* | |
549 * The image is mapped into memory and we either don't | |
550 * need to flip bits or the compression routine is | |
551 * going to handle this operation itself. In this | |
552 * case, avoid copying the raw data and instead just | |
553 * reference the data from the memory mapped file | |
554 * image. This assumes that the decompression | |
555 * routines do not modify the contents of the raw data | |
556 * buffer (if they try to, the application will get a | |
557 * fault since the file is mapped read-only). | |
558 */ | |
559 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata
) { | |
560 _TIFFfree(tif->tif_rawdata); | |
561 tif->tif_rawdata = NULL; | |
562 tif->tif_rawdatasize = 0; | |
563 } | |
564 tif->tif_flags &= ~TIFF_MYBUFFER; | |
565 /* | |
566 * We must check for overflow, potentially causing | |
567 * an OOB read. Instead of simple | |
568 * | |
569 * td->td_stripoffset[strip]+bytecount > tif->tif_size | |
570 * | |
571 * comparison (which can overflow) we do the following | |
572 * two comparisons: | |
573 */ | |
574 if (bytecount > (uint64)tif->tif_size || | |
575 td->td_stripoffset[strip] > (uint64)tif->tif_size -
bytecount) { | |
576 /* | |
577 * This error message might seem strange, but | |
578 * it's what would happen if a read were done | |
579 * instead. | |
580 */ | |
581 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
582 TIFFErrorExt(tif->tif_clientdata, module, | |
583 | |
584 "Read error on strip %lu; " | |
585 "got %I64u bytes, expected %I64u", | |
586 (unsigned long) strip, | |
587 (unsigned __int64) tif->tif_size - td->t
d_stripoffset[strip], | |
588 (unsigned __int64) bytecount); | |
589 #else | |
590 TIFFErrorExt(tif->tif_clientdata, module, | |
591 | |
592 "Read error on strip %lu; " | |
593 "got %llu bytes, expected %llu", | |
594 (unsigned long) strip, | |
595 (unsigned long long) tif->tif_size - td-
>td_stripoffset[strip], | |
596 (unsigned long long) bytecount); | |
597 #endif | |
598 tif->tif_curstrip = NOSTRIP; | |
599 return (0); | |
600 } | |
601 tif->tif_rawdatasize = (tmsize_t)bytecount; | |
602 tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stri
poffset[strip]; | |
603 tif->tif_rawdataoff = 0; | |
604 tif->tif_rawdataloaded = (tmsize_t) bytecount; | |
605 | |
606 /* | |
607 * When we have tif_rawdata reference directly into the
memory mapped file | |
608 * we need to be pretty careful about how we use the raw
data. It is not | |
609 * a general purpose working buffer as it normally other
wise is. So we | |
610 * keep track of this fact to avoid using it improperly. | |
611 */ | |
612 tif->tif_flags |= TIFF_BUFFERMMAP; | |
613 } else { | |
614 /* | |
615 * Expand raw data buffer, if needed, to hold data | |
616 * strip coming from file (perhaps should set upper | |
617 * bound on the size of a buffer we'll use?). | |
618 */ | |
619 tmsize_t bytecountm; | |
620 bytecountm=(tmsize_t)bytecount; | |
621 if ((uint64)bytecountm!=bytecount) | |
622 { | |
623 TIFFErrorExt(tif->tif_clientdata,module,"Integer
overflow"); | |
624 return(0); | |
625 } | |
626 if (bytecountm > tif->tif_rawdatasize) { | |
627 tif->tif_curstrip = NOSTRIP; | |
628 if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { | |
629 TIFFErrorExt(tif->tif_clientdata, module
, | |
630 "Data buffer too small to hold strip
%lu", | |
631 (unsigned long) strip); | |
632 return (0); | |
633 } | |
634 if (!TIFFReadBufferSetup(tif, 0, bytecountm)) | |
635 return (0); | |
636 } | |
637 if (tif->tif_flags&TIFF_BUFFERMMAP) { | |
638 tif->tif_curstrip = NOSTRIP; | |
639 if (!TIFFReadBufferSetup(tif, 0, bytecountm)) | |
640 return (0); | |
641 } | |
642 if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, | |
643 bytecountm, module) != bytecountm) | |
644 return (0); | |
645 | |
646 tif->tif_rawdataoff = 0; | |
647 tif->tif_rawdataloaded = bytecountm; | |
648 | |
649 if (!isFillOrder(tif, td->td_fillorder) && | |
650 (tif->tif_flags & TIFF_NOBITREV) == 0) | |
651 TIFFReverseBits(tif->tif_rawdata, bytecountm); | |
652 } | |
653 } | |
654 return (TIFFStartStrip(tif, strip)); | |
655 } | |
656 | |
657 /* | |
658 * Tile-oriented Read Support | |
659 * Contributed by Nancy Cam (Silicon Graphics). | |
660 */ | |
661 | |
662 /* | |
663 * Read and decompress a tile of data. The | |
664 * tile is selected by the (x,y,z,s) coordinates. | |
665 */ | |
666 tmsize_t | |
667 TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s) | |
668 { | |
669 if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) | |
670 return ((tmsize_t)(-1)); | |
671 return (TIFFReadEncodedTile(tif, | |
672 TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1))); | |
673 } | |
674 | |
675 /* | |
676 * Read a tile of data and decompress the specified | |
677 * amount into the user-supplied buffer. | |
678 */ | |
679 tmsize_t | |
680 TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) | |
681 { | |
682 static const char module[] = "TIFFReadEncodedTile"; | |
683 TIFFDirectory *td = &tif->tif_dir; | |
684 tmsize_t tilesize = tif->tif_tilesize; | |
685 | |
686 if (!TIFFCheckRead(tif, 1)) | |
687 return ((tmsize_t)(-1)); | |
688 if (tile >= td->td_nstrips) { | |
689 TIFFErrorExt(tif->tif_clientdata, module, | |
690 "%lu: Tile out of range, max %lu", | |
691 (unsigned long) tile, (unsigned long) td->td_nstrips); | |
692 return ((tmsize_t)(-1)); | |
693 } | |
694 if (size == (tmsize_t)(-1)) | |
695 size = tilesize; | |
696 else if (size > tilesize) | |
697 size = tilesize; | |
698 if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif, | |
699 (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) { | |
700 (*tif->tif_postdecode)(tif, (uint8*) buf, size); | |
701 return (size); | |
702 } else | |
703 return ((tmsize_t)(-1)); | |
704 } | |
705 | |
706 static tmsize_t | |
707 TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* m
odule) | |
708 { | |
709 TIFFDirectory *td = &tif->tif_dir; | |
710 | |
711 if (!_TIFFFillStriles( tif )) | |
712 return ((tmsize_t)(-1)); | |
713 | |
714 assert((tif->tif_flags&TIFF_NOREADRAW)==0); | |
715 if (!isMapped(tif)) { | |
716 tmsize_t cc; | |
717 | |
718 if (!SeekOK(tif, td->td_stripoffset[tile])) { | |
719 TIFFErrorExt(tif->tif_clientdata, module, | |
720 "Seek error at row %lu, col %lu, tile %lu", | |
721 (unsigned long) tif->tif_row, | |
722 (unsigned long) tif->tif_col, | |
723 (unsigned long) tile); | |
724 return ((tmsize_t)(-1)); | |
725 } | |
726 cc = TIFFReadFile(tif, buf, size); | |
727 if (cc != size) { | |
728 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
729 TIFFErrorExt(tif->tif_clientdata, module, | |
730 "Read error at row %lu, col %lu; got %I64u bytes, expected %I64u", | |
731 (unsigned long) tif->tif_row, | |
732 (unsigned long) tif->tif_col, | |
733 (unsigned __int64) cc, | |
734 (unsigned __int64) size); | |
735 #else | |
736 TIFFErrorExt(tif->tif_clientdata, module, | |
737 "Read error at row %lu, col %lu; got %llu bytes, expected %llu", | |
738 (unsigned long) tif->tif_row, | |
739 (unsigned long) tif->tif_col, | |
740 (unsigned long long) cc, | |
741 (unsigned long long) size); | |
742 #endif | |
743 return ((tmsize_t)(-1)); | |
744 } | |
745 } else { | |
746 tmsize_t ma,mb; | |
747 tmsize_t n; | |
748 ma=(tmsize_t)td->td_stripoffset[tile]; | |
749 mb=ma+size; | |
750 if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size)) | |
751 n=0; | |
752 else if ((mb<ma)||(mb<size)||(mb>tif->tif_size)) | |
753 n=tif->tif_size-ma; | |
754 else | |
755 n=size; | |
756 if (n!=size) { | |
757 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
758 TIFFErrorExt(tif->tif_clientdata, module, | |
759 "Read error at row %lu, col %lu, tile %lu; got %I64u bytes, expected %I64u", | |
760 (unsigned long) tif->tif_row, | |
761 (unsigned long) tif->tif_col, | |
762 (unsigned long) tile, | |
763 (unsigned __int64) n, | |
764 (unsigned __int64) size); | |
765 #else | |
766 TIFFErrorExt(tif->tif_clientdata, module, | |
767 "Read error at row %lu, col %lu, tile %lu; got %llu bytes, expected %llu", | |
768 (unsigned long) tif->tif_row, | |
769 (unsigned long) tif->tif_col, | |
770 (unsigned long) tile, | |
771 (unsigned long long) n, | |
772 (unsigned long long) size); | |
773 #endif | |
774 return ((tmsize_t)(-1)); | |
775 } | |
776 _TIFFmemcpy(buf, tif->tif_base + ma, size); | |
777 } | |
778 return (size); | |
779 } | |
780 | |
781 /* | |
782 * Read a tile of data from the file. | |
783 */ | |
784 tmsize_t | |
785 TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size) | |
786 { | |
787 static const char module[] = "TIFFReadRawTile"; | |
788 TIFFDirectory *td = &tif->tif_dir; | |
789 uint64 bytecount64; | |
790 tmsize_t bytecountm; | |
791 | |
792 if (!TIFFCheckRead(tif, 1)) | |
793 return ((tmsize_t)(-1)); | |
794 if (tile >= td->td_nstrips) { | |
795 TIFFErrorExt(tif->tif_clientdata, module, | |
796 "%lu: Tile out of range, max %lu", | |
797 (unsigned long) tile, (unsigned long) td->td_nstrips); | |
798 return ((tmsize_t)(-1)); | |
799 } | |
800 if (tif->tif_flags&TIFF_NOREADRAW) | |
801 { | |
802 TIFFErrorExt(tif->tif_clientdata, module, | |
803 "Compression scheme does not support access to raw uncompressed
data"); | |
804 return ((tmsize_t)(-1)); | |
805 } | |
806 bytecount64 = td->td_stripbytecount[tile]; | |
807 if (size != (tmsize_t)(-1) && (uint64)size < bytecount64) | |
808 bytecount64 = (uint64)size; | |
809 bytecountm = (tmsize_t)bytecount64; | |
810 if ((uint64)bytecountm!=bytecount64) | |
811 { | |
812 TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow"); | |
813 return ((tmsize_t)(-1)); | |
814 } | |
815 return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module)); | |
816 } | |
817 | |
818 /* | |
819 * Read the specified tile and setup for decoding. The data buffer is | |
820 * expanded, as necessary, to hold the tile's data. | |
821 */ | |
822 int | |
823 TIFFFillTile(TIFF* tif, uint32 tile) | |
824 { | |
825 static const char module[] = "TIFFFillTile"; | |
826 TIFFDirectory *td = &tif->tif_dir; | |
827 | |
828 if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) | |
829 return 0; | |
830 | |
831 if ((tif->tif_flags&TIFF_NOREADRAW)==0) | |
832 { | |
833 uint64 bytecount = td->td_stripbytecount[tile]; | |
834 if (bytecount <= 0) { | |
835 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
836 TIFFErrorExt(tif->tif_clientdata, module, | |
837 "%I64u: Invalid tile byte count, tile %lu", | |
838 (unsigned __int64) bytecount, | |
839 (unsigned long) tile); | |
840 #else | |
841 TIFFErrorExt(tif->tif_clientdata, module, | |
842 "%llu: Invalid tile byte count, tile %lu", | |
843 (unsigned long long) bytecount, | |
844 (unsigned long) tile); | |
845 #endif | |
846 return (0); | |
847 } | |
848 if (isMapped(tif) && | |
849 (isFillOrder(tif, td->td_fillorder) | |
850 || (tif->tif_flags & TIFF_NOBITREV))) { | |
851 /* | |
852 * The image is mapped into memory and we either don't | |
853 * need to flip bits or the compression routine is | |
854 * going to handle this operation itself. In this | |
855 * case, avoid copying the raw data and instead just | |
856 * reference the data from the memory mapped file | |
857 * image. This assumes that the decompression | |
858 * routines do not modify the contents of the raw data | |
859 * buffer (if they try to, the application will get a | |
860 * fault since the file is mapped read-only). | |
861 */ | |
862 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata
) { | |
863 _TIFFfree(tif->tif_rawdata); | |
864 tif->tif_rawdata = NULL; | |
865 tif->tif_rawdatasize = 0; | |
866 } | |
867 tif->tif_flags &= ~TIFF_MYBUFFER; | |
868 /* | |
869 * We must check for overflow, potentially causing | |
870 * an OOB read. Instead of simple | |
871 * | |
872 * td->td_stripoffset[tile]+bytecount > tif->tif_size | |
873 * | |
874 * comparison (which can overflow) we do the following | |
875 * two comparisons: | |
876 */ | |
877 if (bytecount > (uint64)tif->tif_size || | |
878 td->td_stripoffset[tile] > (uint64)tif->tif_size - b
ytecount) { | |
879 tif->tif_curtile = NOTILE; | |
880 return (0); | |
881 } | |
882 tif->tif_rawdatasize = (tmsize_t)bytecount; | |
883 tif->tif_rawdata = | |
884 tif->tif_base + (tmsize_t)td->td_stripoffset[til
e]; | |
885 tif->tif_rawdataoff = 0; | |
886 tif->tif_rawdataloaded = (tmsize_t) bytecount; | |
887 tif->tif_flags |= TIFF_BUFFERMMAP; | |
888 } else { | |
889 /* | |
890 * Expand raw data buffer, if needed, to hold data | |
891 * tile coming from file (perhaps should set upper | |
892 * bound on the size of a buffer we'll use?). | |
893 */ | |
894 tmsize_t bytecountm; | |
895 bytecountm=(tmsize_t)bytecount; | |
896 if ((uint64)bytecountm!=bytecount) | |
897 { | |
898 TIFFErrorExt(tif->tif_clientdata,module,"Integer
overflow"); | |
899 return(0); | |
900 } | |
901 if (bytecountm > tif->tif_rawdatasize) { | |
902 tif->tif_curtile = NOTILE; | |
903 if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { | |
904 TIFFErrorExt(tif->tif_clientdata, module
, | |
905 "Data buffer too small to hold tile
%lu", | |
906 (unsigned long) tile); | |
907 return (0); | |
908 } | |
909 if (!TIFFReadBufferSetup(tif, 0, bytecountm)) | |
910 return (0); | |
911 } | |
912 if (tif->tif_flags&TIFF_BUFFERMMAP) { | |
913 tif->tif_curtile = NOTILE; | |
914 if (!TIFFReadBufferSetup(tif, 0, bytecountm)) | |
915 return (0); | |
916 } | |
917 | |
918 if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, | |
919 bytecountm, module) != bytecountm) | |
920 return (0); | |
921 | |
922 tif->tif_rawdataoff = 0; | |
923 tif->tif_rawdataloaded = bytecountm; | |
924 | |
925 if (!isFillOrder(tif, td->td_fillorder) && | |
926 (tif->tif_flags & TIFF_NOBITREV) == 0) | |
927 TIFFReverseBits(tif->tif_rawdata, | |
928 tif->tif_rawdataloaded); | |
929 } | |
930 } | |
931 return (TIFFStartTile(tif, tile)); | |
932 } | |
933 | |
934 /* | |
935 * Setup the raw data buffer in preparation for | |
936 * reading a strip of raw data. If the buffer | |
937 * is specified as zero, then a buffer of appropriate | |
938 * size is allocated by the library. Otherwise, | |
939 * the client must guarantee that the buffer is | |
940 * large enough to hold any individual strip of | |
941 * raw data. | |
942 */ | |
943 int | |
944 TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size) | |
945 { | |
946 static const char module[] = "TIFFReadBufferSetup"; | |
947 | |
948 assert((tif->tif_flags&TIFF_NOREADRAW)==0); | |
949 tif->tif_flags &= ~TIFF_BUFFERMMAP; | |
950 | |
951 if (tif->tif_rawdata) { | |
952 if (tif->tif_flags & TIFF_MYBUFFER) | |
953 _TIFFfree(tif->tif_rawdata); | |
954 tif->tif_rawdata = NULL; | |
955 tif->tif_rawdatasize = 0; | |
956 } | |
957 if (bp) { | |
958 tif->tif_rawdatasize = size; | |
959 tif->tif_rawdata = (uint8*) bp; | |
960 tif->tif_flags &= ~TIFF_MYBUFFER; | |
961 } else { | |
962 tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 10
24); | |
963 if (tif->tif_rawdatasize==0) | |
964 tif->tif_rawdatasize=(tmsize_t)(-1); | |
965 tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize); | |
966 tif->tif_flags |= TIFF_MYBUFFER; | |
967 } | |
968 if (tif->tif_rawdata == NULL) { | |
969 TIFFErrorExt(tif->tif_clientdata, module, | |
970 "No space for data buffer at scanline %lu", | |
971 (unsigned long) tif->tif_row); | |
972 tif->tif_rawdatasize = 0; | |
973 return (0); | |
974 } | |
975 return (1); | |
976 } | |
977 | |
978 /* | |
979 * Set state to appear as if a | |
980 * strip has just been read in. | |
981 */ | |
982 static int | |
983 TIFFStartStrip(TIFF* tif, uint32 strip) | |
984 { | |
985 TIFFDirectory *td = &tif->tif_dir; | |
986 | |
987 if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) | |
988 return 0; | |
989 | |
990 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { | |
991 if (!(*tif->tif_setupdecode)(tif)) | |
992 return (0); | |
993 tif->tif_flags |= TIFF_CODERSETUP; | |
994 } | |
995 tif->tif_curstrip = strip; | |
996 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; | |
997 tif->tif_flags &= ~TIFF_BUF4WRITE; | |
998 | |
999 if (tif->tif_flags&TIFF_NOREADRAW) | |
1000 { | |
1001 tif->tif_rawcp = NULL; | |
1002 tif->tif_rawcc = 0; | |
1003 } | |
1004 else | |
1005 { | |
1006 tif->tif_rawcp = tif->tif_rawdata; | |
1007 tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip]; | |
1008 } | |
1009 return ((*tif->tif_predecode)(tif, | |
1010 (uint16)(strip / td->td_stripsperimage))); | |
1011 } | |
1012 | |
1013 /* | |
1014 * Set state to appear as if a | |
1015 * tile has just been read in. | |
1016 */ | |
1017 static int | |
1018 TIFFStartTile(TIFF* tif, uint32 tile) | |
1019 { | |
1020 TIFFDirectory *td = &tif->tif_dir; | |
1021 | |
1022 if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount) | |
1023 return 0; | |
1024 | |
1025 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { | |
1026 if (!(*tif->tif_setupdecode)(tif)) | |
1027 return (0); | |
1028 tif->tif_flags |= TIFF_CODERSETUP; | |
1029 } | |
1030 tif->tif_curtile = tile; | |
1031 tif->tif_row = | |
1032 (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) * | |
1033 td->td_tilelength; | |
1034 tif->tif_col = | |
1035 (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) * | |
1036 td->td_tilewidth; | |
1037 tif->tif_flags &= ~TIFF_BUF4WRITE; | |
1038 if (tif->tif_flags&TIFF_NOREADRAW) | |
1039 { | |
1040 tif->tif_rawcp = NULL; | |
1041 tif->tif_rawcc = 0; | |
1042 } | |
1043 else | |
1044 { | |
1045 tif->tif_rawcp = tif->tif_rawdata; | |
1046 tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile]; | |
1047 } | |
1048 return ((*tif->tif_predecode)(tif, | |
1049 (uint16)(tile/td->td_stripsperimage))); | |
1050 } | |
1051 | |
1052 static int | |
1053 TIFFCheckRead(TIFF* tif, int tiles) | |
1054 { | |
1055 if (tif->tif_mode == O_WRONLY) { | |
1056 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open
for reading"); | |
1057 return (0); | |
1058 } | |
1059 if (tiles ^ isTiled(tif)) { | |
1060 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ? | |
1061 "Can not read tiles from a stripped image" : | |
1062 "Can not read scanlines from a tiled image"); | |
1063 return (0); | |
1064 } | |
1065 return (1); | |
1066 } | |
1067 | |
1068 void | |
1069 _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc) | |
1070 { | |
1071 (void) tif; (void) buf; (void) cc; | |
1072 } | |
1073 | |
1074 void | |
1075 _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc) | |
1076 { | |
1077 (void) tif; | |
1078 assert((cc & 1) == 0); | |
1079 TIFFSwabArrayOfShort((uint16*) buf, cc/2); | |
1080 } | |
1081 | |
1082 void | |
1083 _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc) | |
1084 { | |
1085 (void) tif; | |
1086 assert((cc % 3) == 0); | |
1087 TIFFSwabArrayOfTriples((uint8*) buf, cc/3); | |
1088 } | |
1089 | |
1090 void | |
1091 _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc) | |
1092 { | |
1093 (void) tif; | |
1094 assert((cc & 3) == 0); | |
1095 TIFFSwabArrayOfLong((uint32*) buf, cc/4); | |
1096 } | |
1097 | |
1098 void | |
1099 _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc) | |
1100 { | |
1101 (void) tif; | |
1102 assert((cc & 7) == 0); | |
1103 TIFFSwabArrayOfDouble((double*) buf, cc/8); | |
1104 } | |
1105 | |
1106 /* vim: set ts=8 sts=8 sw=8 noet: */ | |
1107 /* | |
1108 * Local Variables: | |
1109 * mode: c | |
1110 * c-basic-offset: 8 | |
1111 * fill-column: 78 | |
1112 * End: | |
1113 */ | |
1114 | |
OLD | NEW |