OLD | NEW |
| (Empty) |
1 /* $Id: tif_predict.c,v 1.32 2010-03-10 18:56:49 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 * | |
30 * Predictor Tag Support (used by multiple codecs). | |
31 */ | |
32 #include "tiffiop.h" | |
33 #include "tif_predict.h" | |
34 | |
35 #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data) | |
36 | |
37 static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc); | |
38 static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); | |
39 static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); | |
40 static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc); | |
41 static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc); | |
42 static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc); | |
43 static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc); | |
44 static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc); | |
45 static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc); | |
46 static void fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc); | |
47 static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); | |
48 static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s); | |
49 static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s); | |
50 static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s); | |
51 | |
52 static int | |
53 PredictorSetup(TIFF* tif) | |
54 { | |
55 static const char module[] = "PredictorSetup"; | |
56 | |
57 TIFFPredictorState* sp = PredictorState(tif); | |
58 TIFFDirectory* td = &tif->tif_dir; | |
59 | |
60 switch (sp->predictor) /* no differencing */ | |
61 { | |
62 case PREDICTOR_NONE: | |
63 return 1; | |
64 case PREDICTOR_HORIZONTAL: | |
65 if (td->td_bitspersample != 8 | |
66 && td->td_bitspersample != 16 | |
67 && td->td_bitspersample != 32) { | |
68 TIFFErrorExt(tif->tif_clientdata, module, | |
69 "Horizontal differencing \"Predictor\" not s
upported with %d-bit samples", | |
70 td->td_bitspersample); | |
71 return 0; | |
72 } | |
73 break; | |
74 case PREDICTOR_FLOATINGPOINT: | |
75 if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) { | |
76 TIFFErrorExt(tif->tif_clientdata, module, | |
77 "Floating point \"Predictor\" not supported
with %d data format", | |
78 td->td_sampleformat); | |
79 return 0; | |
80 } | |
81 break; | |
82 default: | |
83 TIFFErrorExt(tif->tif_clientdata, module, | |
84 "\"Predictor\" value %d not supported", | |
85 sp->predictor); | |
86 return 0; | |
87 } | |
88 sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? | |
89 td->td_samplesperpixel : 1); | |
90 /* | |
91 * Calculate the scanline/tile-width size in bytes. | |
92 */ | |
93 if (isTiled(tif)) | |
94 sp->rowsize = TIFFTileRowSize(tif); | |
95 else | |
96 sp->rowsize = TIFFScanlineSize(tif); | |
97 if (sp->rowsize == 0) | |
98 return 0; | |
99 | |
100 return 1; | |
101 } | |
102 | |
103 static int | |
104 PredictorSetupDecode(TIFF* tif) | |
105 { | |
106 TIFFPredictorState* sp = PredictorState(tif); | |
107 TIFFDirectory* td = &tif->tif_dir; | |
108 | |
109 if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) | |
110 return 0; | |
111 | |
112 if (sp->predictor == 2) { | |
113 switch (td->td_bitspersample) { | |
114 case 8: sp->decodepfunc = horAcc8; break; | |
115 case 16: sp->decodepfunc = horAcc16; break; | |
116 case 32: sp->decodepfunc = horAcc32; break; | |
117 } | |
118 /* | |
119 * Override default decoding method with one that does the | |
120 * predictor stuff. | |
121 */ | |
122 if( tif->tif_decoderow != PredictorDecodeRow ) | |
123 { | |
124 sp->decoderow = tif->tif_decoderow; | |
125 tif->tif_decoderow = PredictorDecodeRow; | |
126 sp->decodestrip = tif->tif_decodestrip; | |
127 tif->tif_decodestrip = PredictorDecodeTile; | |
128 sp->decodetile = tif->tif_decodetile; | |
129 tif->tif_decodetile = PredictorDecodeTile; | |
130 } | |
131 | |
132 /* | |
133 * If the data is horizontally differenced 16-bit data that | |
134 * requires byte-swapping, then it must be byte swapped before | |
135 * the accumulation step. We do this with a special-purpose | |
136 * routine and override the normal post decoding logic that | |
137 * the library setup when the directory was read. | |
138 */ | |
139 if (tif->tif_flags & TIFF_SWAB) { | |
140 if (sp->decodepfunc == horAcc16) { | |
141 sp->decodepfunc = swabHorAcc16; | |
142 tif->tif_postdecode = _TIFFNoPostDecode; | |
143 } else if (sp->decodepfunc == horAcc32) { | |
144 sp->decodepfunc = swabHorAcc32; | |
145 tif->tif_postdecode = _TIFFNoPostDecode; | |
146 } | |
147 } | |
148 } | |
149 | |
150 else if (sp->predictor == 3) { | |
151 sp->decodepfunc = fpAcc; | |
152 /* | |
153 * Override default decoding method with one that does the | |
154 * predictor stuff. | |
155 */ | |
156 if( tif->tif_decoderow != PredictorDecodeRow ) | |
157 { | |
158 sp->decoderow = tif->tif_decoderow; | |
159 tif->tif_decoderow = PredictorDecodeRow; | |
160 sp->decodestrip = tif->tif_decodestrip; | |
161 tif->tif_decodestrip = PredictorDecodeTile; | |
162 sp->decodetile = tif->tif_decodetile; | |
163 tif->tif_decodetile = PredictorDecodeTile; | |
164 } | |
165 /* | |
166 * The data should not be swapped outside of the floating | |
167 * point predictor, the accumulation routine should return | |
168 * byres in the native order. | |
169 */ | |
170 if (tif->tif_flags & TIFF_SWAB) { | |
171 tif->tif_postdecode = _TIFFNoPostDecode; | |
172 } | |
173 /* | |
174 * Allocate buffer to keep the decoded bytes before | |
175 * rearranging in the ight order | |
176 */ | |
177 } | |
178 | |
179 return 1; | |
180 } | |
181 | |
182 static int | |
183 PredictorSetupEncode(TIFF* tif) | |
184 { | |
185 TIFFPredictorState* sp = PredictorState(tif); | |
186 TIFFDirectory* td = &tif->tif_dir; | |
187 | |
188 if (!(*sp->setupencode)(tif) || !PredictorSetup(tif)) | |
189 return 0; | |
190 | |
191 if (sp->predictor == 2) { | |
192 switch (td->td_bitspersample) { | |
193 case 8: sp->encodepfunc = horDiff8; break; | |
194 case 16: sp->encodepfunc = horDiff16; break; | |
195 case 32: sp->encodepfunc = horDiff32; break; | |
196 } | |
197 /* | |
198 * Override default encoding method with one that does the | |
199 * predictor stuff. | |
200 */ | |
201 if( tif->tif_encoderow != PredictorEncodeRow ) | |
202 { | |
203 sp->encoderow = tif->tif_encoderow; | |
204 tif->tif_encoderow = PredictorEncodeRow; | |
205 sp->encodestrip = tif->tif_encodestrip; | |
206 tif->tif_encodestrip = PredictorEncodeTile; | |
207 sp->encodetile = tif->tif_encodetile; | |
208 tif->tif_encodetile = PredictorEncodeTile; | |
209 } | |
210 } | |
211 | |
212 else if (sp->predictor == 3) { | |
213 sp->encodepfunc = fpDiff; | |
214 /* | |
215 * Override default encoding method with one that does the | |
216 * predictor stuff. | |
217 */ | |
218 if( tif->tif_encoderow != PredictorEncodeRow ) | |
219 { | |
220 sp->encoderow = tif->tif_encoderow; | |
221 tif->tif_encoderow = PredictorEncodeRow; | |
222 sp->encodestrip = tif->tif_encodestrip; | |
223 tif->tif_encodestrip = PredictorEncodeTile; | |
224 sp->encodetile = tif->tif_encodetile; | |
225 tif->tif_encodetile = PredictorEncodeTile; | |
226 } | |
227 } | |
228 | |
229 return 1; | |
230 } | |
231 | |
232 #define REPEAT4(n, op) \ | |
233 switch (n) { \ | |
234 default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \ | |
235 case 4: op; \ | |
236 case 3: op; \ | |
237 case 2: op; \ | |
238 case 1: op; \ | |
239 case 0: ; \ | |
240 } | |
241 | |
242 static void | |
243 horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc) | |
244 { | |
245 /* | |
246 * compare v4.0.3 with v3.9.5, | |
247 * we find that horAcc8 uses while loop in the v4.0.3 and uses do while
loop in the v3.9.5. | |
248 * times of do while loop are less than while loop, so we use v3.9.5 ins
tead of v4.0.3. | |
249 */ | |
250 #if 0 | |
251 tmsize_t stride = PredictorState(tif)->stride; | |
252 | |
253 char* cp = (char*) cp0; | |
254 assert((cc%stride)==0); | |
255 if (cc > stride) { | |
256 /* | |
257 * Pipeline the most common cases. | |
258 */ | |
259 if (stride == 3) { | |
260 unsigned int cr = cp[0]; | |
261 unsigned int cg = cp[1]; | |
262 unsigned int cb = cp[2]; | |
263 cc -= 3; | |
264 cp += 3; | |
265 while (cc>0) { | |
266 cp[0] = (char) (cr += cp[0]); | |
267 cp[1] = (char) (cg += cp[1]); | |
268 cp[2] = (char) (cb += cp[2]); | |
269 cc -= 3; | |
270 cp += 3; | |
271 } | |
272 } else if (stride == 4) { | |
273 unsigned int cr = cp[0]; | |
274 unsigned int cg = cp[1]; | |
275 unsigned int cb = cp[2]; | |
276 unsigned int ca = cp[3]; | |
277 cc -= 4; | |
278 cp += 4; | |
279 while (cc>0) { | |
280 cp[0] = (char) (cr += cp[0]); | |
281 cp[1] = (char) (cg += cp[1]); | |
282 cp[2] = (char) (cb += cp[2]); | |
283 cp[3] = (char) (ca += cp[3]); | |
284 cc -= 4; | |
285 cp += 4; | |
286 } | |
287 } else { | |
288 cc -= stride; | |
289 do { | |
290 REPEAT4(stride, cp[stride] = | |
291 (char) (cp[stride] + *cp); cp++) | |
292 cc -= stride; | |
293 } while (cc>0); | |
294 } | |
295 } | |
296 #else | |
297 tsize_t stride = PredictorState(tif)->stride; | |
298 | |
299 char* cp = (char*) cp0; | |
300 if (cc > stride) { | |
301 cc -= stride; | |
302 /* | |
303 * Pipeline the most common cases. | |
304 */ | |
305 if (stride == 3) { | |
306 unsigned int cr = cp[0]; | |
307 unsigned int cg = cp[1]; | |
308 unsigned int cb = cp[2]; | |
309 do { | |
310 cc -= 3, cp += 3; | |
311 cp[0] = (char) (cr += cp[0]); | |
312 cp[1] = (char) (cg += cp[1]); | |
313 cp[2] = (char) (cb += cp[2]); | |
314 } while ((int32) cc > 0); | |
315 } else if (stride == 4) { | |
316 unsigned int cr = cp[0]; | |
317 unsigned int cg = cp[1]; | |
318 unsigned int cb = cp[2]; | |
319 unsigned int ca = cp[3]; | |
320 do { | |
321 cc -= 4, cp += 4; | |
322 cp[0] = (char) (cr += cp[0]); | |
323 cp[1] = (char) (cg += cp[1]); | |
324 cp[2] = (char) (cb += cp[2]); | |
325 cp[3] = (char) (ca += cp[3]); | |
326 } while ((int32) cc > 0); | |
327 } else { | |
328 do { | |
329 REPEAT4(stride, cp[stride] = | |
330 (char) (cp[stride] + *cp); cp++) | |
331 cc -= stride; | |
332 } while ((int32) cc > 0); | |
333 } | |
334 } | |
335 #endif | |
336 } | |
337 | |
338 static void | |
339 swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) | |
340 { | |
341 tmsize_t stride = PredictorState(tif)->stride; | |
342 uint16* wp = (uint16*) cp0; | |
343 tmsize_t wc = cc / 2; | |
344 | |
345 assert((cc%(2*stride))==0); | |
346 | |
347 if (wc > stride) { | |
348 TIFFSwabArrayOfShort(wp, wc); | |
349 wc -= stride; | |
350 do { | |
351 REPEAT4(stride, wp[stride] += wp[0]; wp++) | |
352 wc -= stride; | |
353 } while (wc > 0); | |
354 } | |
355 } | |
356 | |
357 static void | |
358 horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc) | |
359 { | |
360 tmsize_t stride = PredictorState(tif)->stride; | |
361 uint16* wp = (uint16*) cp0; | |
362 tmsize_t wc = cc / 2; | |
363 | |
364 assert((cc%(2*stride))==0); | |
365 | |
366 if (wc > stride) { | |
367 wc -= stride; | |
368 do { | |
369 REPEAT4(stride, wp[stride] += wp[0]; wp++) | |
370 wc -= stride; | |
371 } while (wc > 0); | |
372 } | |
373 } | |
374 | |
375 static void | |
376 swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) | |
377 { | |
378 tmsize_t stride = PredictorState(tif)->stride; | |
379 uint32* wp = (uint32*) cp0; | |
380 tmsize_t wc = cc / 4; | |
381 | |
382 assert((cc%(4*stride))==0); | |
383 | |
384 if (wc > stride) { | |
385 TIFFSwabArrayOfLong(wp, wc); | |
386 wc -= stride; | |
387 do { | |
388 REPEAT4(stride, wp[stride] += wp[0]; wp++) | |
389 wc -= stride; | |
390 } while (wc > 0); | |
391 } | |
392 } | |
393 | |
394 static void | |
395 horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc) | |
396 { | |
397 tmsize_t stride = PredictorState(tif)->stride; | |
398 uint32* wp = (uint32*) cp0; | |
399 tmsize_t wc = cc / 4; | |
400 | |
401 assert((cc%(4*stride))==0); | |
402 | |
403 if (wc > stride) { | |
404 wc -= stride; | |
405 do { | |
406 REPEAT4(stride, wp[stride] += wp[0]; wp++) | |
407 wc -= stride; | |
408 } while (wc > 0); | |
409 } | |
410 } | |
411 | |
412 /* | |
413 * Floating point predictor accumulation routine. | |
414 */ | |
415 static void | |
416 fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc) | |
417 { | |
418 tmsize_t stride = PredictorState(tif)->stride; | |
419 uint32 bps = tif->tif_dir.td_bitspersample / 8; | |
420 tmsize_t wc = cc / bps; | |
421 tmsize_t count = cc; | |
422 uint8 *cp = (uint8 *) cp0; | |
423 uint8 *tmp = (uint8 *)_TIFFmalloc(cc); | |
424 | |
425 assert((cc%(bps*stride))==0); | |
426 | |
427 if (!tmp) | |
428 return; | |
429 | |
430 while (count > stride) { | |
431 REPEAT4(stride, cp[stride] += cp[0]; cp++) | |
432 count -= stride; | |
433 } | |
434 | |
435 _TIFFmemcpy(tmp, cp0, cc); | |
436 cp = (uint8 *) cp0; | |
437 for (count = 0; count < wc; count++) { | |
438 uint32 byte; | |
439 for (byte = 0; byte < bps; byte++) { | |
440 #if WORDS_BIGENDIAN | |
441 cp[bps * count + byte] = tmp[byte * wc + count]; | |
442 #else | |
443 cp[bps * count + byte] = | |
444 tmp[(bps - byte - 1) * wc + count]; | |
445 #endif | |
446 } | |
447 } | |
448 _TIFFfree(tmp); | |
449 } | |
450 | |
451 /* | |
452 * Decode a scanline and apply the predictor routine. | |
453 */ | |
454 static int | |
455 PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) | |
456 { | |
457 TIFFPredictorState *sp = PredictorState(tif); | |
458 | |
459 assert(sp != NULL); | |
460 assert(sp->decoderow != NULL); | |
461 assert(sp->decodepfunc != NULL); | |
462 | |
463 if ((*sp->decoderow)(tif, op0, occ0, s)) { | |
464 (*sp->decodepfunc)(tif, op0, occ0); | |
465 return 1; | |
466 } else | |
467 return 0; | |
468 } | |
469 | |
470 /* | |
471 * Decode a tile/strip and apply the predictor routine. | |
472 * Note that horizontal differencing must be done on a | |
473 * row-by-row basis. The width of a "row" has already | |
474 * been calculated at pre-decode time according to the | |
475 * strip/tile dimensions. | |
476 */ | |
477 static int | |
478 PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s) | |
479 { | |
480 TIFFPredictorState *sp = PredictorState(tif); | |
481 | |
482 assert(sp != NULL); | |
483 assert(sp->decodetile != NULL); | |
484 | |
485 if ((*sp->decodetile)(tif, op0, occ0, s)) { | |
486 tmsize_t rowsize = sp->rowsize; | |
487 assert(rowsize > 0); | |
488 assert((occ0%rowsize)==0); | |
489 assert(sp->decodepfunc != NULL); | |
490 while (occ0 > 0) { | |
491 (*sp->decodepfunc)(tif, op0, rowsize); | |
492 occ0 -= rowsize; | |
493 op0 += rowsize; | |
494 } | |
495 return 1; | |
496 } else | |
497 return 0; | |
498 } | |
499 | |
500 static void | |
501 horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc) | |
502 { | |
503 TIFFPredictorState* sp = PredictorState(tif); | |
504 tmsize_t stride = sp->stride; | |
505 char* cp = (char*) cp0; | |
506 | |
507 assert((cc%stride)==0); | |
508 | |
509 if (cc > stride) { | |
510 cc -= stride; | |
511 /* | |
512 * Pipeline the most common cases. | |
513 */ | |
514 if (stride == 3) { | |
515 int r1, g1, b1; | |
516 int r2 = cp[0]; | |
517 int g2 = cp[1]; | |
518 int b2 = cp[2]; | |
519 do { | |
520 r1 = cp[3]; cp[3] = r1-r2; r2 = r1; | |
521 g1 = cp[4]; cp[4] = g1-g2; g2 = g1; | |
522 b1 = cp[5]; cp[5] = b1-b2; b2 = b1; | |
523 cp += 3; | |
524 } while ((cc -= 3) > 0); | |
525 } else if (stride == 4) { | |
526 int r1, g1, b1, a1; | |
527 int r2 = cp[0]; | |
528 int g2 = cp[1]; | |
529 int b2 = cp[2]; | |
530 int a2 = cp[3]; | |
531 do { | |
532 r1 = cp[4]; cp[4] = r1-r2; r2 = r1; | |
533 g1 = cp[5]; cp[5] = g1-g2; g2 = g1; | |
534 b1 = cp[6]; cp[6] = b1-b2; b2 = b1; | |
535 a1 = cp[7]; cp[7] = a1-a2; a2 = a1; | |
536 cp += 4; | |
537 } while ((cc -= 4) > 0); | |
538 } else { | |
539 cp += cc - 1; | |
540 do { | |
541 REPEAT4(stride, cp[stride] -= cp[0]; cp--) | |
542 } while ((cc -= stride) > 0); | |
543 } | |
544 } | |
545 } | |
546 | |
547 static void | |
548 horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc) | |
549 { | |
550 TIFFPredictorState* sp = PredictorState(tif); | |
551 tmsize_t stride = sp->stride; | |
552 int16 *wp = (int16*) cp0; | |
553 tmsize_t wc = cc/2; | |
554 | |
555 assert((cc%(2*stride))==0); | |
556 | |
557 if (wc > stride) { | |
558 wc -= stride; | |
559 wp += wc - 1; | |
560 do { | |
561 REPEAT4(stride, wp[stride] -= wp[0]; wp--) | |
562 wc -= stride; | |
563 } while (wc > 0); | |
564 } | |
565 } | |
566 | |
567 static void | |
568 horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc) | |
569 { | |
570 TIFFPredictorState* sp = PredictorState(tif); | |
571 tmsize_t stride = sp->stride; | |
572 int32 *wp = (int32*) cp0; | |
573 tmsize_t wc = cc/4; | |
574 | |
575 assert((cc%(4*stride))==0); | |
576 | |
577 if (wc > stride) { | |
578 wc -= stride; | |
579 wp += wc - 1; | |
580 do { | |
581 REPEAT4(stride, wp[stride] -= wp[0]; wp--) | |
582 wc -= stride; | |
583 } while (wc > 0); | |
584 } | |
585 } | |
586 | |
587 /* | |
588 * Floating point predictor differencing routine. | |
589 */ | |
590 static void | |
591 fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc) | |
592 { | |
593 tmsize_t stride = PredictorState(tif)->stride; | |
594 uint32 bps = tif->tif_dir.td_bitspersample / 8; | |
595 tmsize_t wc = cc / bps; | |
596 tmsize_t count; | |
597 uint8 *cp = (uint8 *) cp0; | |
598 uint8 *tmp = (uint8 *)_TIFFmalloc(cc); | |
599 | |
600 assert((cc%(bps*stride))==0); | |
601 | |
602 if (!tmp) | |
603 return; | |
604 | |
605 _TIFFmemcpy(tmp, cp0, cc); | |
606 for (count = 0; count < wc; count++) { | |
607 uint32 byte; | |
608 for (byte = 0; byte < bps; byte++) { | |
609 #if WORDS_BIGENDIAN | |
610 cp[byte * wc + count] = tmp[bps * count + byte]; | |
611 #else | |
612 cp[(bps - byte - 1) * wc + count] = | |
613 tmp[bps * count + byte]; | |
614 #endif | |
615 } | |
616 } | |
617 _TIFFfree(tmp); | |
618 | |
619 cp = (uint8 *) cp0; | |
620 cp += cc - stride - 1; | |
621 for (count = cc; count > stride; count -= stride) | |
622 REPEAT4(stride, cp[stride] -= cp[0]; cp--) | |
623 } | |
624 | |
625 static int | |
626 PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s) | |
627 { | |
628 TIFFPredictorState *sp = PredictorState(tif); | |
629 | |
630 assert(sp != NULL); | |
631 assert(sp->encodepfunc != NULL); | |
632 assert(sp->encoderow != NULL); | |
633 | |
634 /* XXX horizontal differencing alters user's data XXX */ | |
635 (*sp->encodepfunc)(tif, bp, cc); | |
636 return (*sp->encoderow)(tif, bp, cc, s); | |
637 } | |
638 | |
639 static int | |
640 PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s) | |
641 { | |
642 static const char module[] = "PredictorEncodeTile"; | |
643 TIFFPredictorState *sp = PredictorState(tif); | |
644 uint8 *working_copy; | |
645 tmsize_t cc = cc0, rowsize; | |
646 unsigned char* bp; | |
647 int result_code; | |
648 | |
649 assert(sp != NULL); | |
650 assert(sp->encodepfunc != NULL); | |
651 assert(sp->encodetile != NULL); | |
652 | |
653 /* | |
654 * Do predictor manipulation in a working buffer to avoid altering | |
655 * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965 | |
656 */ | |
657 working_copy = (uint8*) _TIFFmalloc(cc0); | |
658 if( working_copy == NULL ) | |
659 { | |
660 TIFFErrorExt(tif->tif_clientdata, module, | |
661 "Out of memory allocating " TIFF_SSIZE_FORMAT " byte te
mp buffer.", | |
662 cc0 ); | |
663 return 0; | |
664 } | |
665 memcpy( working_copy, bp0, cc0 ); | |
666 bp = working_copy; | |
667 | |
668 rowsize = sp->rowsize; | |
669 assert(rowsize > 0); | |
670 assert((cc0%rowsize)==0); | |
671 while (cc > 0) { | |
672 (*sp->encodepfunc)(tif, bp, rowsize); | |
673 cc -= rowsize; | |
674 bp += rowsize; | |
675 } | |
676 result_code = (*sp->encodetile)(tif, working_copy, cc0, s); | |
677 | |
678 _TIFFfree( working_copy ); | |
679 | |
680 return result_code; | |
681 } | |
682 | |
683 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */ | |
684 | |
685 static const TIFFField predictFields[] = { | |
686 { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UI
NT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL }, | |
687 }; | |
688 | |
689 static int | |
690 PredictorVSetField(TIFF* tif, uint32 tag, va_list ap) | |
691 { | |
692 TIFFPredictorState *sp = PredictorState(tif); | |
693 | |
694 assert(sp != NULL); | |
695 assert(sp->vsetparent != NULL); | |
696 | |
697 switch (tag) { | |
698 case TIFFTAG_PREDICTOR: | |
699 sp->predictor = (uint16) va_arg(ap, uint16_vap); | |
700 TIFFSetFieldBit(tif, FIELD_PREDICTOR); | |
701 break; | |
702 default: | |
703 return (*sp->vsetparent)(tif, tag, ap); | |
704 } | |
705 tif->tif_flags |= TIFF_DIRTYDIRECT; | |
706 return 1; | |
707 } | |
708 | |
709 static int | |
710 PredictorVGetField(TIFF* tif, uint32 tag, va_list ap) | |
711 { | |
712 TIFFPredictorState *sp = PredictorState(tif); | |
713 | |
714 assert(sp != NULL); | |
715 assert(sp->vgetparent != NULL); | |
716 | |
717 switch (tag) { | |
718 case TIFFTAG_PREDICTOR: | |
719 *va_arg(ap, uint16*) = sp->predictor; | |
720 break; | |
721 default: | |
722 return (*sp->vgetparent)(tif, tag, ap); | |
723 } | |
724 return 1; | |
725 } | |
726 | |
727 static void | |
728 PredictorPrintDir(TIFF* tif, FILE* fd, long flags) | |
729 { | |
730 TIFFPredictorState* sp = PredictorState(tif); | |
731 | |
732 (void) flags; | |
733 if (TIFFFieldSet(tif,FIELD_PREDICTOR)) { | |
734 fprintf(fd, " Predictor: "); | |
735 switch (sp->predictor) { | |
736 case 1: fprintf(fd, "none "); break; | |
737 case 2: fprintf(fd, "horizontal differencing "); break; | |
738 case 3: fprintf(fd, "floating point predictor "); break; | |
739 } | |
740 fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor); | |
741 } | |
742 if (sp->printdir) | |
743 (*sp->printdir)(tif, fd, flags); | |
744 } | |
745 | |
746 int | |
747 TIFFPredictorInit(TIFF* tif) | |
748 { | |
749 TIFFPredictorState* sp = PredictorState(tif); | |
750 | |
751 assert(sp != 0); | |
752 | |
753 /* | |
754 * Merge codec-specific tag information. | |
755 */ | |
756 if (!_TIFFMergeFields(tif, predictFields, | |
757 TIFFArrayCount(predictFields))) { | |
758 TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit", | |
759 "Merging Predictor codec-specific tags failed"); | |
760 return 0; | |
761 } | |
762 | |
763 /* | |
764 * Override parent get/set field methods. | |
765 */ | |
766 sp->vgetparent = tif->tif_tagmethods.vgetfield; | |
767 tif->tif_tagmethods.vgetfield = | |
768 PredictorVGetField;/* hook for predictor tag */ | |
769 sp->vsetparent = tif->tif_tagmethods.vsetfield; | |
770 tif->tif_tagmethods.vsetfield = | |
771 PredictorVSetField;/* hook for predictor tag */ | |
772 sp->printdir = tif->tif_tagmethods.printdir; | |
773 tif->tif_tagmethods.printdir = | |
774 PredictorPrintDir; /* hook for predictor tag */ | |
775 | |
776 sp->setupdecode = tif->tif_setupdecode; | |
777 tif->tif_setupdecode = PredictorSetupDecode; | |
778 sp->setupencode = tif->tif_setupencode; | |
779 tif->tif_setupencode = PredictorSetupEncode; | |
780 | |
781 sp->predictor = 1; /* default value */ | |
782 sp->encodepfunc = NULL; /* no predictor routine */ | |
783 sp->decodepfunc = NULL; /* no predictor routine */ | |
784 return 1; | |
785 } | |
786 | |
787 int | |
788 TIFFPredictorCleanup(TIFF* tif) | |
789 { | |
790 TIFFPredictorState* sp = PredictorState(tif); | |
791 | |
792 assert(sp != 0); | |
793 | |
794 tif->tif_tagmethods.vgetfield = sp->vgetparent; | |
795 tif->tif_tagmethods.vsetfield = sp->vsetparent; | |
796 tif->tif_tagmethods.printdir = sp->printdir; | |
797 tif->tif_setupdecode = sp->setupdecode; | |
798 tif->tif_setupencode = sp->setupencode; | |
799 | |
800 return 1; | |
801 } | |
802 | |
803 /* vim: set ts=8 sts=8 sw=8 noet: */ | |
804 /* | |
805 * Local Variables: | |
806 * mode: c | |
807 * c-basic-offset: 8 | |
808 * fill-column: 78 | |
809 * End: | |
810 */ | |
811 | |
OLD | NEW |