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