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