1 /* $Id: tif_predict.c,v 1.32 2010-03-10 18:56:49 bfriesen Exp $ */
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
30 * Predictor Tag Support (used by multiple codecs).
34 #include "tif_predict.h"
36 #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
38 static void horAcc8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
39 static void horAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
40 static void horAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
41 static void swabHorAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
42 static void swabHorAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
43 static void horDiff8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
44 static void horDiff16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
45 static void horDiff32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
46 static void fpAcc(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
47 static void fpDiff(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
48 static int PredictorDecodeRow(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
);
49 static int PredictorDecodeTile(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
);
50 static int PredictorEncodeRow(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
);
51 static int PredictorEncodeTile(TIFF
* tif
, uint8
* bp0
, tmsize_t cc0
, uint16 s
);
54 PredictorSetup(TIFF
* tif
)
56 static const char module
[] = "PredictorSetup";
58 TIFFPredictorState
* sp
= PredictorState(tif
);
59 TIFFDirectory
* td
= &tif
->tif_dir
;
61 switch (sp
->predictor
) /* no differencing */
65 case PREDICTOR_HORIZONTAL
:
66 if (td
->td_bitspersample
!= 8
67 && td
->td_bitspersample
!= 16
68 && td
->td_bitspersample
!= 32) {
69 TIFFErrorExt(tif
->tif_clientdata
, module
,
70 "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
71 td
->td_bitspersample
);
75 case PREDICTOR_FLOATINGPOINT
:
76 if (td
->td_sampleformat
!= SAMPLEFORMAT_IEEEFP
) {
77 TIFFErrorExt(tif
->tif_clientdata
, module
,
78 "Floating point \"Predictor\" not supported with %d data format",
84 TIFFErrorExt(tif
->tif_clientdata
, module
,
85 "\"Predictor\" value %d not supported",
89 sp
->stride
= (td
->td_planarconfig
== PLANARCONFIG_CONTIG
?
90 td
->td_samplesperpixel
: 1);
92 * Calculate the scanline/tile-width size in bytes.
95 sp
->rowsize
= TIFFTileRowSize(tif
);
97 sp
->rowsize
= TIFFScanlineSize(tif
);
105 PredictorSetupDecode(TIFF
* tif
)
107 TIFFPredictorState
* sp
= PredictorState(tif
);
108 TIFFDirectory
* td
= &tif
->tif_dir
;
110 if (!(*sp
->setupdecode
)(tif
) || !PredictorSetup(tif
))
113 if (sp
->predictor
== 2) {
114 switch (td
->td_bitspersample
) {
115 case 8: sp
->decodepfunc
= horAcc8
; break;
116 case 16: sp
->decodepfunc
= horAcc16
; break;
117 case 32: sp
->decodepfunc
= horAcc32
; break;
120 * Override default decoding method with one that does the
123 if( tif
->tif_decoderow
!= PredictorDecodeRow
)
125 sp
->decoderow
= tif
->tif_decoderow
;
126 tif
->tif_decoderow
= PredictorDecodeRow
;
127 sp
->decodestrip
= tif
->tif_decodestrip
;
128 tif
->tif_decodestrip
= PredictorDecodeTile
;
129 sp
->decodetile
= tif
->tif_decodetile
;
130 tif
->tif_decodetile
= PredictorDecodeTile
;
134 * If the data is horizontally differenced 16-bit data that
135 * requires byte-swapping, then it must be byte swapped before
136 * the accumulation step. We do this with a special-purpose
137 * routine and override the normal post decoding logic that
138 * the library setup when the directory was read.
140 if (tif
->tif_flags
& TIFF_SWAB
) {
141 if (sp
->decodepfunc
== horAcc16
) {
142 sp
->decodepfunc
= swabHorAcc16
;
143 tif
->tif_postdecode
= _TIFFNoPostDecode
;
144 } else if (sp
->decodepfunc
== horAcc32
) {
145 sp
->decodepfunc
= swabHorAcc32
;
146 tif
->tif_postdecode
= _TIFFNoPostDecode
;
151 else if (sp
->predictor
== 3) {
152 sp
->decodepfunc
= fpAcc
;
154 * Override default decoding method with one that does the
157 if( tif
->tif_decoderow
!= PredictorDecodeRow
)
159 sp
->decoderow
= tif
->tif_decoderow
;
160 tif
->tif_decoderow
= PredictorDecodeRow
;
161 sp
->decodestrip
= tif
->tif_decodestrip
;
162 tif
->tif_decodestrip
= PredictorDecodeTile
;
163 sp
->decodetile
= tif
->tif_decodetile
;
164 tif
->tif_decodetile
= PredictorDecodeTile
;
167 * The data should not be swapped outside of the floating
168 * point predictor, the accumulation routine should return
169 * byres in the native order.
171 if (tif
->tif_flags
& TIFF_SWAB
) {
172 tif
->tif_postdecode
= _TIFFNoPostDecode
;
175 * Allocate buffer to keep the decoded bytes before
176 * rearranging in the ight order
184 PredictorSetupEncode(TIFF
* tif
)
186 TIFFPredictorState
* sp
= PredictorState(tif
);
187 TIFFDirectory
* td
= &tif
->tif_dir
;
189 if (!(*sp
->setupencode
)(tif
) || !PredictorSetup(tif
))
192 if (sp
->predictor
== 2) {
193 switch (td
->td_bitspersample
) {
194 case 8: sp
->encodepfunc
= horDiff8
; break;
195 case 16: sp
->encodepfunc
= horDiff16
; break;
196 case 32: sp
->encodepfunc
= horDiff32
; break;
199 * Override default encoding method with one that does the
202 if( tif
->tif_encoderow
!= PredictorEncodeRow
)
204 sp
->encoderow
= tif
->tif_encoderow
;
205 tif
->tif_encoderow
= PredictorEncodeRow
;
206 sp
->encodestrip
= tif
->tif_encodestrip
;
207 tif
->tif_encodestrip
= PredictorEncodeTile
;
208 sp
->encodetile
= tif
->tif_encodetile
;
209 tif
->tif_encodetile
= PredictorEncodeTile
;
213 else if (sp
->predictor
== 3) {
214 sp
->encodepfunc
= fpDiff
;
216 * Override default encoding method with one that does the
219 if( tif
->tif_encoderow
!= PredictorEncodeRow
)
221 sp
->encoderow
= tif
->tif_encoderow
;
222 tif
->tif_encoderow
= PredictorEncodeRow
;
223 sp
->encodestrip
= tif
->tif_encodestrip
;
224 tif
->tif_encodestrip
= PredictorEncodeTile
;
225 sp
->encodetile
= tif
->tif_encodetile
;
226 tif
->tif_encodetile
= PredictorEncodeTile
;
233 #define REPEAT4(n, op) \
235 default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
244 horAcc8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
246 tmsize_t stride
= PredictorState(tif
)->stride
;
248 char* cp
= (char*) cp0
;
249 assert((cc
%stride
)==0);
252 * Pipeline the most common cases.
255 unsigned int cr
= cp
[0];
256 unsigned int cg
= cp
[1];
257 unsigned int cb
= cp
[2];
261 cp
[0] = (char) (cr
+= cp
[0]);
262 cp
[1] = (char) (cg
+= cp
[1]);
263 cp
[2] = (char) (cb
+= cp
[2]);
267 } else if (stride
== 4) {
268 unsigned int cr
= cp
[0];
269 unsigned int cg
= cp
[1];
270 unsigned int cb
= cp
[2];
271 unsigned int ca
= cp
[3];
275 cp
[0] = (char) (cr
+= cp
[0]);
276 cp
[1] = (char) (cg
+= cp
[1]);
277 cp
[2] = (char) (cb
+= cp
[2]);
278 cp
[3] = (char) (ca
+= cp
[3]);
285 REPEAT4(stride
, cp
[stride
] =
286 (char) (cp
[stride
] + *cp
); cp
++)
294 swabHorAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
296 tmsize_t stride
= PredictorState(tif
)->stride
;
297 uint16
* wp
= (uint16
*) cp0
;
298 tmsize_t wc
= cc
/ 2;
300 assert((cc
%(2*stride
))==0);
303 TIFFSwabArrayOfShort(wp
, wc
);
306 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
313 horAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
315 tmsize_t stride
= PredictorState(tif
)->stride
;
316 uint16
* wp
= (uint16
*) cp0
;
317 tmsize_t wc
= cc
/ 2;
319 assert((cc
%(2*stride
))==0);
324 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
331 swabHorAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
333 tmsize_t stride
= PredictorState(tif
)->stride
;
334 uint32
* wp
= (uint32
*) cp0
;
335 tmsize_t wc
= cc
/ 4;
337 assert((cc
%(4*stride
))==0);
340 TIFFSwabArrayOfLong(wp
, wc
);
343 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
350 horAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
352 tmsize_t stride
= PredictorState(tif
)->stride
;
353 uint32
* wp
= (uint32
*) cp0
;
354 tmsize_t wc
= cc
/ 4;
356 assert((cc
%(4*stride
))==0);
361 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
368 * Floating point predictor accumulation routine.
371 fpAcc(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
373 tmsize_t stride
= PredictorState(tif
)->stride
;
374 uint32 bps
= tif
->tif_dir
.td_bitspersample
/ 8;
375 tmsize_t wc
= cc
/ bps
;
377 uint8
*cp
= (uint8
*) cp0
;
378 uint8
*tmp
= (uint8
*)_TIFFmalloc(cc
);
380 assert((cc
%(bps
*stride
))==0);
385 while (count
> stride
) {
386 REPEAT4(stride
, cp
[stride
] += cp
[0]; cp
++)
390 _TIFFmemcpy(tmp
, cp0
, cc
);
392 for (count
= 0; count
< wc
; count
++) {
394 for (byte
= 0; byte
< bps
; byte
++) {
396 cp
[bps
* count
+ byte
] = tmp
[byte
* wc
+ count
];
398 cp
[bps
* count
+ byte
] =
399 tmp
[(bps
- byte
- 1) * wc
+ count
];
407 * Decode a scanline and apply the predictor routine.
410 PredictorDecodeRow(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
)
412 TIFFPredictorState
*sp
= PredictorState(tif
);
415 assert(sp
->decoderow
!= NULL
);
416 assert(sp
->decodepfunc
!= NULL
);
418 if ((*sp
->decoderow
)(tif
, op0
, occ0
, s
)) {
419 (*sp
->decodepfunc
)(tif
, op0
, occ0
);
426 * Decode a tile/strip and apply the predictor routine.
427 * Note that horizontal differencing must be done on a
428 * row-by-row basis. The width of a "row" has already
429 * been calculated at pre-decode time according to the
430 * strip/tile dimensions.
433 PredictorDecodeTile(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
)
435 TIFFPredictorState
*sp
= PredictorState(tif
);
438 assert(sp
->decodetile
!= NULL
);
440 if ((*sp
->decodetile
)(tif
, op0
, occ0
, s
)) {
441 tmsize_t rowsize
= sp
->rowsize
;
443 assert((occ0
%rowsize
)==0);
444 assert(sp
->decodepfunc
!= NULL
);
446 (*sp
->decodepfunc
)(tif
, op0
, rowsize
);
456 horDiff8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
458 TIFFPredictorState
* sp
= PredictorState(tif
);
459 tmsize_t stride
= sp
->stride
;
460 char* cp
= (char*) cp0
;
462 assert((cc
%stride
)==0);
467 * Pipeline the most common cases.
475 r1
= cp
[3]; cp
[3] = r1
-r2
; r2
= r1
;
476 g1
= cp
[4]; cp
[4] = g1
-g2
; g2
= g1
;
477 b1
= cp
[5]; cp
[5] = b1
-b2
; b2
= b1
;
479 } while ((cc
-= 3) > 0);
480 } else if (stride
== 4) {
487 r1
= cp
[4]; cp
[4] = r1
-r2
; r2
= r1
;
488 g1
= cp
[5]; cp
[5] = g1
-g2
; g2
= g1
;
489 b1
= cp
[6]; cp
[6] = b1
-b2
; b2
= b1
;
490 a1
= cp
[7]; cp
[7] = a1
-a2
; a2
= a1
;
492 } while ((cc
-= 4) > 0);
496 REPEAT4(stride
, cp
[stride
] -= cp
[0]; cp
--)
497 } while ((cc
-= stride
) > 0);
503 horDiff16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
505 TIFFPredictorState
* sp
= PredictorState(tif
);
506 tmsize_t stride
= sp
->stride
;
507 int16
*wp
= (int16
*) cp0
;
510 assert((cc
%(2*stride
))==0);
516 REPEAT4(stride
, wp
[stride
] -= wp
[0]; wp
--)
523 horDiff32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
525 TIFFPredictorState
* sp
= PredictorState(tif
);
526 tmsize_t stride
= sp
->stride
;
527 int32
*wp
= (int32
*) cp0
;
530 assert((cc
%(4*stride
))==0);
536 REPEAT4(stride
, wp
[stride
] -= wp
[0]; wp
--)
543 * Floating point predictor differencing routine.
546 fpDiff(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
548 tmsize_t stride
= PredictorState(tif
)->stride
;
549 uint32 bps
= tif
->tif_dir
.td_bitspersample
/ 8;
550 tmsize_t wc
= cc
/ bps
;
552 uint8
*cp
= (uint8
*) cp0
;
553 uint8
*tmp
= (uint8
*)_TIFFmalloc(cc
);
555 assert((cc
%(bps
*stride
))==0);
560 _TIFFmemcpy(tmp
, cp0
, cc
);
561 for (count
= 0; count
< wc
; count
++) {
563 for (byte
= 0; byte
< bps
; byte
++) {
565 cp
[byte
* wc
+ count
] = tmp
[bps
* count
+ byte
];
567 cp
[(bps
- byte
- 1) * wc
+ count
] =
568 tmp
[bps
* count
+ byte
];
575 cp
+= cc
- stride
- 1;
576 for (count
= cc
; count
> stride
; count
-= stride
)
577 REPEAT4(stride
, cp
[stride
] -= cp
[0]; cp
--)
581 PredictorEncodeRow(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
)
583 TIFFPredictorState
*sp
= PredictorState(tif
);
586 assert(sp
->encodepfunc
!= NULL
);
587 assert(sp
->encoderow
!= NULL
);
589 /* XXX horizontal differencing alters user's data XXX */
590 (*sp
->encodepfunc
)(tif
, bp
, cc
);
591 return (*sp
->encoderow
)(tif
, bp
, cc
, s
);
595 PredictorEncodeTile(TIFF
* tif
, uint8
* bp0
, tmsize_t cc0
, uint16 s
)
597 static const char module
[] = "PredictorEncodeTile";
598 TIFFPredictorState
*sp
= PredictorState(tif
);
600 tmsize_t cc
= cc0
, rowsize
;
605 assert(sp
->encodepfunc
!= NULL
);
606 assert(sp
->encodetile
!= NULL
);
609 * Do predictor manipulation in a working buffer to avoid altering
610 * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
612 working_copy
= (uint8
*) _TIFFmalloc(cc0
);
613 if( working_copy
== NULL
)
615 TIFFErrorExt(tif
->tif_clientdata
, module
,
616 "Out of memory allocating " TIFF_SSIZE_FORMAT
" byte temp buffer.",
620 memcpy( working_copy
, bp0
, cc0
);
623 rowsize
= sp
->rowsize
;
625 assert((cc0
%rowsize
)==0);
627 (*sp
->encodepfunc
)(tif
, bp
, rowsize
);
631 result_code
= (*sp
->encodetile
)(tif
, working_copy
, cc0
, s
);
633 _TIFFfree( working_copy
);
638 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
640 static const TIFFField predictFields
[] = {
641 { TIFFTAG_PREDICTOR
, 1, 1, TIFF_SHORT
, 0, TIFF_SETGET_UINT16
, TIFF_SETGET_UINT16
, FIELD_PREDICTOR
, FALSE
, FALSE
, "Predictor", NULL
},
645 PredictorVSetField(TIFF
* tif
, uint32 tag
, va_list ap
)
647 TIFFPredictorState
*sp
= PredictorState(tif
);
650 assert(sp
->vsetparent
!= NULL
);
653 case TIFFTAG_PREDICTOR
:
654 sp
->predictor
= (uint16
) va_arg(ap
, uint16_vap
);
655 TIFFSetFieldBit(tif
, FIELD_PREDICTOR
);
658 return (*sp
->vsetparent
)(tif
, tag
, ap
);
660 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
665 PredictorVGetField(TIFF
* tif
, uint32 tag
, va_list ap
)
667 TIFFPredictorState
*sp
= PredictorState(tif
);
670 assert(sp
->vgetparent
!= NULL
);
673 case TIFFTAG_PREDICTOR
:
674 *va_arg(ap
, uint16
*) = sp
->predictor
;
677 return (*sp
->vgetparent
)(tif
, tag
, ap
);
683 PredictorPrintDir(TIFF
* tif
, FILE* fd
, long flags
)
685 TIFFPredictorState
* sp
= PredictorState(tif
);
688 if (TIFFFieldSet(tif
,FIELD_PREDICTOR
)) {
689 fprintf(fd
, " Predictor: ");
690 switch (sp
->predictor
) {
691 case 1: fprintf(fd
, "none "); break;
692 case 2: fprintf(fd
, "horizontal differencing "); break;
693 case 3: fprintf(fd
, "floating point predictor "); break;
695 fprintf(fd
, "%u (0x%x)\n", sp
->predictor
, sp
->predictor
);
698 (*sp
->printdir
)(tif
, fd
, flags
);
702 TIFFPredictorInit(TIFF
* tif
)
704 TIFFPredictorState
* sp
= PredictorState(tif
);
709 * Merge codec-specific tag information.
711 if (!_TIFFMergeFields(tif
, predictFields
,
712 TIFFArrayCount(predictFields
))) {
713 TIFFErrorExt(tif
->tif_clientdata
, "TIFFPredictorInit",
714 "Merging Predictor codec-specific tags failed");
719 * Override parent get/set field methods.
721 sp
->vgetparent
= tif
->tif_tagmethods
.vgetfield
;
722 tif
->tif_tagmethods
.vgetfield
=
723 PredictorVGetField
;/* hook for predictor tag */
724 sp
->vsetparent
= tif
->tif_tagmethods
.vsetfield
;
725 tif
->tif_tagmethods
.vsetfield
=
726 PredictorVSetField
;/* hook for predictor tag */
727 sp
->printdir
= tif
->tif_tagmethods
.printdir
;
728 tif
->tif_tagmethods
.printdir
=
729 PredictorPrintDir
; /* hook for predictor tag */
731 sp
->setupdecode
= tif
->tif_setupdecode
;
732 tif
->tif_setupdecode
= PredictorSetupDecode
;
733 sp
->setupencode
= tif
->tif_setupencode
;
734 tif
->tif_setupencode
= PredictorSetupEncode
;
736 sp
->predictor
= 1; /* default value */
737 sp
->encodepfunc
= NULL
; /* no predictor routine */
738 sp
->decodepfunc
= NULL
; /* no predictor routine */
743 TIFFPredictorCleanup(TIFF
* tif
)
745 TIFFPredictorState
* sp
= PredictorState(tif
);
749 tif
->tif_tagmethods
.vgetfield
= sp
->vgetparent
;
750 tif
->tif_tagmethods
.vsetfield
= sp
->vsetparent
;
751 tif
->tif_tagmethods
.printdir
= sp
->printdir
;
752 tif
->tif_setupdecode
= sp
->setupdecode
;
753 tif
->tif_setupencode
= sp
->setupencode
;
758 /* vim: set ts=8 sts=8 sw=8 noet: */