]>
Commit | Line | Data |
---|---|---|
b47c832e RR |
1 | /* $Header$ */ |
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 | #include <assert.h> | |
34 | ||
00cb87b4 VZ |
35 | int TIFFFillStrip(TIFF*, tstrip_t); |
36 | int TIFFFillTile(TIFF*, ttile_t); | |
b47c832e RR |
37 | static int TIFFStartStrip(TIFF*, tstrip_t); |
38 | static int TIFFStartTile(TIFF*, ttile_t); | |
39 | static int TIFFCheckRead(TIFF*, int); | |
40 | ||
41 | #define NOSTRIP ((tstrip_t) -1) /* undefined state */ | |
42 | #define NOTILE ((ttile_t) -1) /* undefined state */ | |
43 | ||
44 | /* | |
45 | * Seek to a random row+sample in a file. | |
46 | */ | |
47 | static int | |
48 | TIFFSeek(TIFF* tif, uint32 row, tsample_t sample) | |
49 | { | |
50 | register TIFFDirectory *td = &tif->tif_dir; | |
51 | tstrip_t strip; | |
52 | ||
53 | if (row >= td->td_imagelength) { /* out of range */ | |
54 | TIFFError(tif->tif_name, "%lu: Row out of range, max %lu", | |
55 | (u_long) row, (u_long) td->td_imagelength); | |
56 | return (0); | |
57 | } | |
58 | if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { | |
59 | if (sample >= td->td_samplesperpixel) { | |
60 | TIFFError(tif->tif_name, | |
61 | "%lu: Sample out of range, max %lu", | |
62 | (u_long) sample, (u_long) td->td_samplesperpixel); | |
63 | return (0); | |
64 | } | |
65 | strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; | |
66 | } else | |
67 | strip = row / td->td_rowsperstrip; | |
68 | if (strip != tif->tif_curstrip) { /* different strip, refill */ | |
69 | if (!TIFFFillStrip(tif, strip)) | |
70 | return (0); | |
71 | } else if (row < tif->tif_row) { | |
72 | /* | |
73 | * Moving backwards within the same strip: backup | |
74 | * to the start and then decode forward (below). | |
75 | * | |
76 | * NB: If you're planning on lots of random access within a | |
77 | * strip, it's better to just read and decode the entire | |
78 | * strip, and then access the decoded data in a random fashion. | |
79 | */ | |
80 | if (!TIFFStartStrip(tif, strip)) | |
81 | return (0); | |
82 | } | |
83 | if (row != tif->tif_row) { | |
84 | /* | |
85 | * Seek forward to the desired row. | |
86 | */ | |
87 | if (!(*tif->tif_seek)(tif, row - tif->tif_row)) | |
88 | return (0); | |
89 | tif->tif_row = row; | |
90 | } | |
91 | return (1); | |
92 | } | |
93 | ||
94 | int | |
95 | TIFFReadScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) | |
96 | { | |
97 | int e; | |
98 | ||
99 | if (!TIFFCheckRead(tif, 0)) | |
100 | return (-1); | |
101 | if( (e = TIFFSeek(tif, row, sample)) != 0) { | |
102 | /* | |
103 | * Decompress desired row into user buffer. | |
104 | */ | |
105 | e = (*tif->tif_decoderow) | |
106 | (tif, (tidata_t) buf, tif->tif_scanlinesize, sample); | |
00cb87b4 VZ |
107 | |
108 | /* we are now poised at the beginning of the next row */ | |
109 | tif->tif_row = row + 1; | |
110 | ||
b47c832e RR |
111 | if (e) |
112 | (*tif->tif_postdecode)(tif, (tidata_t) buf, | |
113 | tif->tif_scanlinesize); | |
114 | } | |
115 | return (e > 0 ? 1 : -1); | |
116 | } | |
117 | ||
118 | /* | |
119 | * Read a strip of data and decompress the specified | |
120 | * amount into the user-supplied buffer. | |
121 | */ | |
122 | tsize_t | |
123 | TIFFReadEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size) | |
124 | { | |
125 | TIFFDirectory *td = &tif->tif_dir; | |
126 | uint32 nrows; | |
127 | tsize_t stripsize; | |
00cb87b4 | 128 | tstrip_t sep_strip, strips_per_sep; |
b47c832e RR |
129 | |
130 | if (!TIFFCheckRead(tif, 0)) | |
131 | return (-1); | |
132 | if (strip >= td->td_nstrips) { | |
133 | TIFFError(tif->tif_name, "%ld: Strip out of range, max %ld", | |
134 | (long) strip, (long) td->td_nstrips); | |
135 | return (-1); | |
136 | } | |
137 | /* | |
138 | * Calculate the strip size according to the number of | |
00cb87b4 VZ |
139 | * rows in the strip (check for truncated last strip on any |
140 | * of the separations). | |
b47c832e | 141 | */ |
00cb87b4 VZ |
142 | if( td->td_rowsperstrip >= td->td_imagelength ) |
143 | strips_per_sep = 1; | |
144 | else | |
145 | strips_per_sep = (td->td_imagelength+td->td_rowsperstrip-1) | |
146 | / td->td_rowsperstrip; | |
147 | ||
148 | sep_strip = strip % strips_per_sep; | |
149 | ||
150 | if (sep_strip != strips_per_sep-1 || | |
b47c832e RR |
151 | (nrows = td->td_imagelength % td->td_rowsperstrip) == 0) |
152 | nrows = td->td_rowsperstrip; | |
00cb87b4 | 153 | |
b47c832e RR |
154 | stripsize = TIFFVStripSize(tif, nrows); |
155 | if (size == (tsize_t) -1) | |
156 | size = stripsize; | |
157 | else if (size > stripsize) | |
158 | size = stripsize; | |
00cb87b4 VZ |
159 | if (TIFFFillStrip(tif, strip) |
160 | && (*tif->tif_decodestrip)(tif, (tidata_t) buf, size, | |
161 | (tsample_t)(strip / td->td_stripsperimage)) > 0 ) { | |
b47c832e RR |
162 | (*tif->tif_postdecode)(tif, (tidata_t) buf, size); |
163 | return (size); | |
164 | } else | |
165 | return ((tsize_t) -1); | |
166 | } | |
167 | ||
168 | static tsize_t | |
169 | TIFFReadRawStrip1(TIFF* tif, | |
170 | tstrip_t strip, tdata_t buf, tsize_t size, const char* module) | |
171 | { | |
172 | TIFFDirectory *td = &tif->tif_dir; | |
173 | ||
174 | if (!isMapped(tif)) { | |
175 | tsize_t cc; | |
176 | ||
177 | if (!SeekOK(tif, td->td_stripoffset[strip])) { | |
178 | TIFFError(module, | |
179 | "%s: Seek error at scanline %lu, strip %lu", | |
180 | tif->tif_name, | |
181 | (u_long) tif->tif_row, (u_long) strip); | |
182 | return (-1); | |
183 | } | |
184 | cc = TIFFReadFile(tif, buf, size); | |
185 | if (cc != size) { | |
186 | TIFFError(module, | |
187 | "%s: Read error at scanline %lu; got %lu bytes, expected %lu", | |
188 | tif->tif_name, | |
189 | (u_long) tif->tif_row, | |
190 | (u_long) cc, | |
191 | (u_long) size); | |
192 | return (-1); | |
193 | } | |
194 | } else { | |
195 | if (td->td_stripoffset[strip] + size > tif->tif_size) { | |
196 | TIFFError(module, | |
197 | "%s: Read error at scanline %lu, strip %lu; got %lu bytes, expected %lu", | |
198 | tif->tif_name, | |
199 | (u_long) tif->tif_row, | |
200 | (u_long) strip, | |
201 | (u_long) tif->tif_size - td->td_stripoffset[strip], | |
202 | (u_long) size); | |
203 | return (-1); | |
204 | } | |
205 | _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[strip], size); | |
206 | } | |
207 | return (size); | |
208 | } | |
209 | ||
210 | /* | |
211 | * Read a strip of data from the file. | |
212 | */ | |
213 | tsize_t | |
214 | TIFFReadRawStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size) | |
215 | { | |
216 | static const char module[] = "TIFFReadRawStrip"; | |
217 | TIFFDirectory *td = &tif->tif_dir; | |
218 | tsize_t bytecount; | |
219 | ||
220 | if (!TIFFCheckRead(tif, 0)) | |
221 | return ((tsize_t) -1); | |
222 | if (strip >= td->td_nstrips) { | |
223 | TIFFError(tif->tif_name, "%lu: Strip out of range, max %lu", | |
224 | (u_long) strip, (u_long) td->td_nstrips); | |
225 | return ((tsize_t) -1); | |
226 | } | |
227 | bytecount = td->td_stripbytecount[strip]; | |
228 | if (bytecount <= 0) { | |
229 | TIFFError(tif->tif_name, | |
230 | "%lu: Invalid strip byte count, strip %lu", | |
231 | (u_long) bytecount, (u_long) strip); | |
232 | return ((tsize_t) -1); | |
233 | } | |
234 | if (size != (tsize_t)-1 && size < bytecount) | |
235 | bytecount = size; | |
236 | return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module)); | |
237 | } | |
238 | ||
239 | /* | |
240 | * Read the specified strip and setup for decoding. | |
241 | * The data buffer is expanded, as necessary, to | |
242 | * hold the strip's data. | |
243 | */ | |
00cb87b4 | 244 | int |
b47c832e RR |
245 | TIFFFillStrip(TIFF* tif, tstrip_t strip) |
246 | { | |
247 | static const char module[] = "TIFFFillStrip"; | |
248 | TIFFDirectory *td = &tif->tif_dir; | |
249 | tsize_t bytecount; | |
250 | ||
251 | bytecount = td->td_stripbytecount[strip]; | |
252 | if (bytecount <= 0) { | |
253 | TIFFError(tif->tif_name, | |
254 | "%lu: Invalid strip byte count, strip %lu", | |
255 | (u_long) bytecount, (u_long) strip); | |
256 | return (0); | |
257 | } | |
258 | if (isMapped(tif) && | |
259 | (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) { | |
260 | /* | |
261 | * The image is mapped into memory and we either don't | |
262 | * need to flip bits or the compression routine is going | |
263 | * to handle this operation itself. In this case, avoid | |
264 | * copying the raw data and instead just reference the | |
265 | * data from the memory mapped file image. This assumes | |
266 | * that the decompression routines do not modify the | |
267 | * contents of the raw data buffer (if they try to, | |
268 | * the application will get a fault since the file is | |
269 | * mapped read-only). | |
270 | */ | |
271 | if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) | |
272 | _TIFFfree(tif->tif_rawdata); | |
273 | tif->tif_flags &= ~TIFF_MYBUFFER; | |
00cb87b4 | 274 | if ( td->td_stripoffset[strip] + bytecount > tif->tif_size) { |
b47c832e RR |
275 | /* |
276 | * This error message might seem strange, but it's | |
277 | * what would happen if a read were done instead. | |
278 | */ | |
279 | TIFFError(module, | |
280 | "%s: Read error on strip %lu; got %lu bytes, expected %lu", | |
281 | tif->tif_name, | |
282 | (u_long) strip, | |
283 | (u_long) tif->tif_size - td->td_stripoffset[strip], | |
284 | (u_long) bytecount); | |
285 | tif->tif_curstrip = NOSTRIP; | |
286 | return (0); | |
287 | } | |
288 | tif->tif_rawdatasize = bytecount; | |
289 | tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip]; | |
290 | } else { | |
291 | /* | |
292 | * Expand raw data buffer, if needed, to | |
293 | * hold data strip coming from file | |
294 | * (perhaps should set upper bound on | |
295 | * the size of a buffer we'll use?). | |
296 | */ | |
297 | if (bytecount > tif->tif_rawdatasize) { | |
298 | tif->tif_curstrip = NOSTRIP; | |
299 | if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { | |
300 | TIFFError(module, | |
301 | "%s: Data buffer too small to hold strip %lu", | |
302 | tif->tif_name, (u_long) strip); | |
303 | return (0); | |
304 | } | |
305 | if (!TIFFReadBufferSetup(tif, 0, | |
306 | TIFFroundup(bytecount, 1024))) | |
307 | return (0); | |
308 | } | |
309 | if (TIFFReadRawStrip1(tif, strip, (u_char *)tif->tif_rawdata, | |
310 | bytecount, module) != bytecount) | |
311 | return (0); | |
312 | if (!isFillOrder(tif, td->td_fillorder) && | |
313 | (tif->tif_flags & TIFF_NOBITREV) == 0) | |
314 | TIFFReverseBits(tif->tif_rawdata, bytecount); | |
315 | } | |
316 | return (TIFFStartStrip(tif, strip)); | |
317 | } | |
318 | ||
319 | /* | |
320 | * Tile-oriented Read Support | |
321 | * Contributed by Nancy Cam (Silicon Graphics). | |
322 | */ | |
323 | ||
324 | /* | |
325 | * Read and decompress a tile of data. The | |
326 | * tile is selected by the (x,y,z,s) coordinates. | |
327 | */ | |
328 | tsize_t | |
329 | TIFFReadTile(TIFF* tif, | |
330 | tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s) | |
331 | { | |
332 | if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) | |
333 | return (-1); | |
334 | return (TIFFReadEncodedTile(tif, | |
335 | TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1)); | |
336 | } | |
337 | ||
338 | /* | |
339 | * Read a tile of data and decompress the specified | |
340 | * amount into the user-supplied buffer. | |
341 | */ | |
342 | tsize_t | |
343 | TIFFReadEncodedTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size) | |
344 | { | |
345 | TIFFDirectory *td = &tif->tif_dir; | |
346 | tsize_t tilesize = tif->tif_tilesize; | |
347 | ||
348 | if (!TIFFCheckRead(tif, 1)) | |
349 | return (-1); | |
350 | if (tile >= td->td_nstrips) { | |
351 | TIFFError(tif->tif_name, "%ld: Tile out of range, max %ld", | |
352 | (long) tile, (u_long) td->td_nstrips); | |
353 | return (-1); | |
354 | } | |
355 | if (size == (tsize_t) -1) | |
356 | size = tilesize; | |
357 | else if (size > tilesize) | |
358 | size = tilesize; | |
359 | if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif, | |
360 | (tidata_t) buf, size, (tsample_t)(tile/td->td_stripsperimage))) { | |
361 | (*tif->tif_postdecode)(tif, (tidata_t) buf, size); | |
362 | return (size); | |
363 | } else | |
364 | return (-1); | |
365 | } | |
366 | ||
367 | static tsize_t | |
368 | TIFFReadRawTile1(TIFF* tif, | |
369 | ttile_t tile, tdata_t buf, tsize_t size, const char* module) | |
370 | { | |
371 | TIFFDirectory *td = &tif->tif_dir; | |
372 | ||
373 | if (!isMapped(tif)) { | |
374 | tsize_t cc; | |
375 | ||
376 | if (!SeekOK(tif, td->td_stripoffset[tile])) { | |
377 | TIFFError(module, | |
378 | "%s: Seek error at row %ld, col %ld, tile %ld", | |
379 | tif->tif_name, | |
380 | (long) tif->tif_row, | |
381 | (long) tif->tif_col, | |
382 | (long) tile); | |
383 | return ((tsize_t) -1); | |
384 | } | |
385 | cc = TIFFReadFile(tif, buf, size); | |
386 | if (cc != size) { | |
387 | TIFFError(module, | |
388 | "%s: Read error at row %ld, col %ld; got %lu bytes, expected %lu", | |
389 | tif->tif_name, | |
390 | (long) tif->tif_row, | |
391 | (long) tif->tif_col, | |
392 | (u_long) cc, | |
393 | (u_long) size); | |
394 | return ((tsize_t) -1); | |
395 | } | |
396 | } else { | |
397 | if (td->td_stripoffset[tile] + size > tif->tif_size) { | |
398 | TIFFError(module, | |
399 | "%s: Read error at row %ld, col %ld, tile %ld; got %lu bytes, expected %lu", | |
400 | tif->tif_name, | |
401 | (long) tif->tif_row, | |
402 | (long) tif->tif_col, | |
403 | (long) tile, | |
404 | (u_long) tif->tif_size - td->td_stripoffset[tile], | |
405 | (u_long) size); | |
406 | return ((tsize_t) -1); | |
407 | } | |
408 | _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[tile], size); | |
409 | } | |
410 | return (size); | |
411 | } | |
412 | ||
413 | /* | |
414 | * Read a tile of data from the file. | |
415 | */ | |
416 | tsize_t | |
417 | TIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size) | |
418 | { | |
419 | static const char module[] = "TIFFReadRawTile"; | |
420 | TIFFDirectory *td = &tif->tif_dir; | |
421 | tsize_t bytecount; | |
422 | ||
423 | if (!TIFFCheckRead(tif, 1)) | |
424 | return ((tsize_t) -1); | |
425 | if (tile >= td->td_nstrips) { | |
426 | TIFFError(tif->tif_name, "%lu: Tile out of range, max %lu", | |
427 | (u_long) tile, (u_long) td->td_nstrips); | |
428 | return ((tsize_t) -1); | |
429 | } | |
430 | bytecount = td->td_stripbytecount[tile]; | |
431 | if (size != (tsize_t) -1 && size < bytecount) | |
432 | bytecount = size; | |
433 | return (TIFFReadRawTile1(tif, tile, buf, bytecount, module)); | |
434 | } | |
435 | ||
436 | /* | |
437 | * Read the specified tile and setup for decoding. | |
438 | * The data buffer is expanded, as necessary, to | |
439 | * hold the tile's data. | |
440 | */ | |
00cb87b4 | 441 | int |
b47c832e RR |
442 | TIFFFillTile(TIFF* tif, ttile_t tile) |
443 | { | |
444 | static const char module[] = "TIFFFillTile"; | |
445 | TIFFDirectory *td = &tif->tif_dir; | |
446 | tsize_t bytecount; | |
447 | ||
448 | bytecount = td->td_stripbytecount[tile]; | |
449 | if (bytecount <= 0) { | |
450 | TIFFError(tif->tif_name, | |
451 | "%lu: Invalid tile byte count, tile %lu", | |
452 | (u_long) bytecount, (u_long) tile); | |
453 | return (0); | |
454 | } | |
455 | if (isMapped(tif) && | |
456 | (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) { | |
457 | /* | |
458 | * The image is mapped into memory and we either don't | |
459 | * need to flip bits or the compression routine is going | |
460 | * to handle this operation itself. In this case, avoid | |
461 | * copying the raw data and instead just reference the | |
462 | * data from the memory mapped file image. This assumes | |
463 | * that the decompression routines do not modify the | |
464 | * contents of the raw data buffer (if they try to, | |
465 | * the application will get a fault since the file is | |
466 | * mapped read-only). | |
467 | */ | |
468 | if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) | |
469 | _TIFFfree(tif->tif_rawdata); | |
470 | tif->tif_flags &= ~TIFF_MYBUFFER; | |
00cb87b4 | 471 | if ( td->td_stripoffset[tile] + bytecount > tif->tif_size) { |
b47c832e RR |
472 | tif->tif_curtile = NOTILE; |
473 | return (0); | |
474 | } | |
475 | tif->tif_rawdatasize = bytecount; | |
476 | tif->tif_rawdata = tif->tif_base + td->td_stripoffset[tile]; | |
477 | } else { | |
478 | /* | |
479 | * Expand raw data buffer, if needed, to | |
480 | * hold data tile coming from file | |
481 | * (perhaps should set upper bound on | |
482 | * the size of a buffer we'll use?). | |
483 | */ | |
484 | if (bytecount > tif->tif_rawdatasize) { | |
485 | tif->tif_curtile = NOTILE; | |
486 | if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { | |
487 | TIFFError(module, | |
488 | "%s: Data buffer too small to hold tile %ld", | |
489 | tif->tif_name, (long) tile); | |
490 | return (0); | |
491 | } | |
492 | if (!TIFFReadBufferSetup(tif, 0, | |
493 | TIFFroundup(bytecount, 1024))) | |
494 | return (0); | |
495 | } | |
496 | if (TIFFReadRawTile1(tif, tile, (u_char *)tif->tif_rawdata, | |
497 | bytecount, module) != bytecount) | |
498 | return (0); | |
499 | if (!isFillOrder(tif, td->td_fillorder) && | |
500 | (tif->tif_flags & TIFF_NOBITREV) == 0) | |
501 | TIFFReverseBits(tif->tif_rawdata, bytecount); | |
502 | } | |
503 | return (TIFFStartTile(tif, tile)); | |
504 | } | |
505 | ||
506 | /* | |
507 | * Setup the raw data buffer in preparation for | |
508 | * reading a strip of raw data. If the buffer | |
509 | * is specified as zero, then a buffer of appropriate | |
510 | * size is allocated by the library. Otherwise, | |
511 | * the client must guarantee that the buffer is | |
512 | * large enough to hold any individual strip of | |
513 | * raw data. | |
514 | */ | |
515 | int | |
516 | TIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) | |
517 | { | |
518 | static const char module[] = "TIFFReadBufferSetup"; | |
519 | ||
520 | if (tif->tif_rawdata) { | |
521 | if (tif->tif_flags & TIFF_MYBUFFER) | |
522 | _TIFFfree(tif->tif_rawdata); | |
523 | tif->tif_rawdata = NULL; | |
524 | } | |
525 | if (bp) { | |
526 | tif->tif_rawdatasize = size; | |
527 | tif->tif_rawdata = (tidata_t) bp; | |
528 | tif->tif_flags &= ~TIFF_MYBUFFER; | |
529 | } else { | |
530 | tif->tif_rawdatasize = TIFFroundup(size, 1024); | |
531 | tif->tif_rawdata = (tidata_t) _TIFFmalloc(tif->tif_rawdatasize); | |
532 | tif->tif_flags |= TIFF_MYBUFFER; | |
533 | } | |
534 | if (tif->tif_rawdata == NULL) { | |
535 | TIFFError(module, | |
536 | "%s: No space for data buffer at scanline %ld", | |
537 | tif->tif_name, (long) tif->tif_row); | |
538 | tif->tif_rawdatasize = 0; | |
539 | return (0); | |
540 | } | |
541 | return (1); | |
542 | } | |
543 | ||
544 | /* | |
545 | * Set state to appear as if a | |
546 | * strip has just been read in. | |
547 | */ | |
548 | static int | |
549 | TIFFStartStrip(TIFF* tif, tstrip_t strip) | |
550 | { | |
551 | TIFFDirectory *td = &tif->tif_dir; | |
552 | ||
553 | if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { | |
554 | if (!(*tif->tif_setupdecode)(tif)) | |
555 | return (0); | |
556 | tif->tif_flags |= TIFF_CODERSETUP; | |
557 | } | |
558 | tif->tif_curstrip = strip; | |
559 | tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; | |
560 | tif->tif_rawcp = tif->tif_rawdata; | |
561 | tif->tif_rawcc = td->td_stripbytecount[strip]; | |
562 | return ((*tif->tif_predecode)(tif, | |
563 | (tsample_t)(strip / td->td_stripsperimage))); | |
564 | } | |
565 | ||
566 | /* | |
567 | * Set state to appear as if a | |
568 | * tile has just been read in. | |
569 | */ | |
570 | static int | |
571 | TIFFStartTile(TIFF* tif, ttile_t tile) | |
572 | { | |
573 | TIFFDirectory *td = &tif->tif_dir; | |
574 | ||
575 | if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { | |
576 | if (!(*tif->tif_setupdecode)(tif)) | |
577 | return (0); | |
578 | tif->tif_flags |= TIFF_CODERSETUP; | |
579 | } | |
580 | tif->tif_curtile = tile; | |
581 | tif->tif_row = | |
582 | (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) * | |
583 | td->td_tilelength; | |
584 | tif->tif_col = | |
585 | (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength)) * | |
586 | td->td_tilewidth; | |
587 | tif->tif_rawcp = tif->tif_rawdata; | |
588 | tif->tif_rawcc = td->td_stripbytecount[tile]; | |
589 | return ((*tif->tif_predecode)(tif, | |
590 | (tsample_t)(tile/td->td_stripsperimage))); | |
591 | } | |
592 | ||
593 | static int | |
594 | TIFFCheckRead(TIFF* tif, int tiles) | |
595 | { | |
596 | if (tif->tif_mode == O_WRONLY) { | |
597 | TIFFError(tif->tif_name, "File not open for reading"); | |
598 | return (0); | |
599 | } | |
600 | if (tiles ^ isTiled(tif)) { | |
601 | TIFFError(tif->tif_name, tiles ? | |
602 | "Can not read tiles from a stripped image" : | |
603 | "Can not read scanlines from a tiled image"); | |
604 | return (0); | |
605 | } | |
606 | return (1); | |
607 | } | |
608 | ||
609 | void | |
610 | _TIFFNoPostDecode(TIFF* tif, tidata_t buf, tsize_t cc) | |
611 | { | |
612 | (void) tif; (void) buf; (void) cc; | |
613 | } | |
614 | ||
615 | void | |
616 | _TIFFSwab16BitData(TIFF* tif, tidata_t buf, tsize_t cc) | |
617 | { | |
618 | (void) tif; | |
619 | assert((cc & 1) == 0); | |
620 | TIFFSwabArrayOfShort((uint16*) buf, cc/2); | |
621 | } | |
622 | ||
623 | void | |
624 | _TIFFSwab32BitData(TIFF* tif, tidata_t buf, tsize_t cc) | |
625 | { | |
626 | (void) tif; | |
627 | assert((cc & 3) == 0); | |
628 | TIFFSwabArrayOfLong((uint32*) buf, cc/4); | |
629 | } | |
630 | ||
631 | void | |
632 | _TIFFSwab64BitData(TIFF* tif, tidata_t buf, tsize_t cc) | |
633 | { | |
634 | (void) tif; | |
635 | assert((cc & 7) == 0); | |
636 | TIFFSwabArrayOfDouble((double*) buf, cc/8); | |
637 | } |