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