]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/libtiff/tif_predict.c
52411c6d14e6d0abf0c1e594ac5a540c36d84c93
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).
33 #include "tif_predict.h"
35 #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
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
);
53 PredictorSetup(TIFF
* tif
)
55 static const char module[] = "PredictorSetup";
57 TIFFPredictorState
* sp
= PredictorState(tif
);
58 TIFFDirectory
* td
= &tif
->tif_dir
;
60 switch (sp
->predictor
) /* no differencing */
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 supported with %d-bit samples",
70 td
->td_bitspersample
);
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",
83 TIFFErrorExt(tif
->tif_clientdata
, module,
84 "\"Predictor\" value %d not supported",
88 sp
->stride
= (td
->td_planarconfig
== PLANARCONFIG_CONTIG
?
89 td
->td_samplesperpixel
: 1);
91 * Calculate the scanline/tile-width size in bytes.
94 sp
->rowsize
= TIFFTileRowSize(tif
);
96 sp
->rowsize
= TIFFScanlineSize(tif
);
104 PredictorSetupDecode(TIFF
* tif
)
106 TIFFPredictorState
* sp
= PredictorState(tif
);
107 TIFFDirectory
* td
= &tif
->tif_dir
;
109 if (!(*sp
->setupdecode
)(tif
) || !PredictorSetup(tif
))
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;
119 * Override default decoding method with one that does the
122 if( tif
->tif_decoderow
!= PredictorDecodeRow
)
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
;
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.
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
;
150 else if (sp
->predictor
== 3) {
151 sp
->decodepfunc
= fpAcc
;
153 * Override default decoding method with one that does the
156 if( tif
->tif_decoderow
!= PredictorDecodeRow
)
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
;
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.
170 if (tif
->tif_flags
& TIFF_SWAB
) {
171 tif
->tif_postdecode
= _TIFFNoPostDecode
;
174 * Allocate buffer to keep the decoded bytes before
175 * rearranging in the ight order
183 PredictorSetupEncode(TIFF
* tif
)
185 TIFFPredictorState
* sp
= PredictorState(tif
);
186 TIFFDirectory
* td
= &tif
->tif_dir
;
188 if (!(*sp
->setupencode
)(tif
) || !PredictorSetup(tif
))
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;
198 * Override default encoding method with one that does the
201 if( tif
->tif_encoderow
!= PredictorEncodeRow
)
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
;
212 else if (sp
->predictor
== 3) {
213 sp
->encodepfunc
= fpDiff
;
215 * Override default encoding method with one that does the
218 if( tif
->tif_encoderow
!= PredictorEncodeRow
)
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
;
232 #define REPEAT4(n, op) \
234 default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
243 horAcc8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
245 tmsize_t stride
= PredictorState(tif
)->stride
;
247 char* cp
= (char*) cp0
;
248 assert((cc%stride
)==0);
251 * Pipeline the most common cases.
254 unsigned int cr
= cp
[0];
255 unsigned int cg
= cp
[1];
256 unsigned int cb
= cp
[2];
260 cp
[0] = (char) (cr
+= cp
[0]);
261 cp
[1] = (char) (cg
+= cp
[1]);
262 cp
[2] = (char) (cb
+= cp
[2]);
266 } else if (stride
== 4) {
267 unsigned int cr
= cp
[0];
268 unsigned int cg
= cp
[1];
269 unsigned int cb
= cp
[2];
270 unsigned int ca
= cp
[3];
274 cp
[0] = (char) (cr
+= cp
[0]);
275 cp
[1] = (char) (cg
+= cp
[1]);
276 cp
[2] = (char) (cb
+= cp
[2]);
277 cp
[3] = (char) (ca
+= cp
[3]);
284 REPEAT4(stride
, cp
[stride
] =
285 (char) (cp
[stride
] + *cp
); cp
++)
293 swabHorAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
295 tmsize_t stride
= PredictorState(tif
)->stride
;
296 uint16
* wp
= (uint16
*) cp0
;
297 tmsize_t wc
= cc
/ 2;
299 assert((cc
%(2*stride
))==0);
302 TIFFSwabArrayOfShort(wp
, wc
);
305 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
312 horAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
314 tmsize_t stride
= PredictorState(tif
)->stride
;
315 uint16
* wp
= (uint16
*) cp0
;
316 tmsize_t wc
= cc
/ 2;
318 assert((cc
%(2*stride
))==0);
323 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
330 swabHorAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
332 tmsize_t stride
= PredictorState(tif
)->stride
;
333 uint32
* wp
= (uint32
*) cp0
;
334 tmsize_t wc
= cc
/ 4;
336 assert((cc
%(4*stride
))==0);
339 TIFFSwabArrayOfLong(wp
, wc
);
342 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
349 horAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
351 tmsize_t stride
= PredictorState(tif
)->stride
;
352 uint32
* wp
= (uint32
*) cp0
;
353 tmsize_t wc
= cc
/ 4;
355 assert((cc
%(4*stride
))==0);
360 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
367 * Floating point predictor accumulation routine.
370 fpAcc(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
372 tmsize_t stride
= PredictorState(tif
)->stride
;
373 uint32 bps
= tif
->tif_dir
.td_bitspersample
/ 8;
374 tmsize_t wc
= cc
/ bps
;
376 uint8
*cp
= (uint8
*) cp0
;
377 uint8
*tmp
= (uint8
*)_TIFFmalloc(cc
);
379 assert((cc
%(bps
*stride
))==0);
384 while (count
> stride
) {
385 REPEAT4(stride
, cp
[stride
] += cp
[0]; cp
++)
389 _TIFFmemcpy(tmp
, cp0
, cc
);
391 for (count
= 0; count
< wc
; count
++) {
393 for (byte
= 0; byte
< bps
; byte
++) {
394 #ifdef WORDS_BIGENDIAN
395 cp
[bps
* count
+ byte
] = tmp
[byte
* wc
+ count
];
397 cp
[bps
* count
+ byte
] =
398 tmp
[(bps
- byte
- 1) * wc
+ count
];
406 * Decode a scanline and apply the predictor routine.
409 PredictorDecodeRow(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
)
411 TIFFPredictorState
*sp
= PredictorState(tif
);
414 assert(sp
->decoderow
!= NULL
);
415 assert(sp
->decodepfunc
!= NULL
);
417 if ((*sp
->decoderow
)(tif
, op0
, occ0
, s
)) {
418 (*sp
->decodepfunc
)(tif
, op0
, occ0
);
425 * Decode a tile/strip and apply the predictor routine.
426 * Note that horizontal differencing must be done on a
427 * row-by-row basis. The width of a "row" has already
428 * been calculated at pre-decode time according to the
429 * strip/tile dimensions.
432 PredictorDecodeTile(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
)
434 TIFFPredictorState
*sp
= PredictorState(tif
);
437 assert(sp
->decodetile
!= NULL
);
439 if ((*sp
->decodetile
)(tif
, op0
, occ0
, s
)) {
440 tmsize_t rowsize
= sp
->rowsize
;
442 assert((occ0%rowsize
)==0);
443 assert(sp
->decodepfunc
!= NULL
);
445 (*sp
->decodepfunc
)(tif
, op0
, rowsize
);
455 horDiff8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
457 TIFFPredictorState
* sp
= PredictorState(tif
);
458 tmsize_t stride
= sp
->stride
;
459 char* cp
= (char*) cp0
;
461 assert((cc%stride
)==0);
466 * Pipeline the most common cases.
474 r1
= cp
[3]; cp
[3] = r1
-r2
; r2
= r1
;
475 g1
= cp
[4]; cp
[4] = g1
-g2
; g2
= g1
;
476 b1
= cp
[5]; cp
[5] = b1
-b2
; b2
= b1
;
478 } while ((cc
-= 3) > 0);
479 } else if (stride
== 4) {
486 r1
= cp
[4]; cp
[4] = r1
-r2
; r2
= r1
;
487 g1
= cp
[5]; cp
[5] = g1
-g2
; g2
= g1
;
488 b1
= cp
[6]; cp
[6] = b1
-b2
; b2
= b1
;
489 a1
= cp
[7]; cp
[7] = a1
-a2
; a2
= a1
;
491 } while ((cc
-= 4) > 0);
495 REPEAT4(stride
, cp
[stride
] -= cp
[0]; cp
--)
496 } while ((cc
-= stride
) > 0);
502 horDiff16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
504 TIFFPredictorState
* sp
= PredictorState(tif
);
505 tmsize_t stride
= sp
->stride
;
506 int16
*wp
= (int16
*) cp0
;
509 assert((cc
%(2*stride
))==0);
515 REPEAT4(stride
, wp
[stride
] -= wp
[0]; wp
--)
522 horDiff32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
524 TIFFPredictorState
* sp
= PredictorState(tif
);
525 tmsize_t stride
= sp
->stride
;
526 int32
*wp
= (int32
*) cp0
;
529 assert((cc
%(4*stride
))==0);
535 REPEAT4(stride
, wp
[stride
] -= wp
[0]; wp
--)
542 * Floating point predictor differencing routine.
545 fpDiff(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
547 tmsize_t stride
= PredictorState(tif
)->stride
;
548 uint32 bps
= tif
->tif_dir
.td_bitspersample
/ 8;
549 tmsize_t wc
= cc
/ bps
;
551 uint8
*cp
= (uint8
*) cp0
;
552 uint8
*tmp
= (uint8
*)_TIFFmalloc(cc
);
554 assert((cc
%(bps
*stride
))==0);
559 _TIFFmemcpy(tmp
, cp0
, cc
);
560 for (count
= 0; count
< wc
; count
++) {
562 for (byte
= 0; byte
< bps
; byte
++) {
563 #ifdef WORDS_BIGENDIAN
564 cp
[byte
* wc
+ count
] = tmp
[bps
* count
+ byte
];
566 cp
[(bps
- byte
- 1) * wc
+ count
] =
567 tmp
[bps
* count
+ byte
];
574 cp
+= cc
- stride
- 1;
575 for (count
= cc
; count
> stride
; count
-= stride
)
576 REPEAT4(stride
, cp
[stride
] -= cp
[0]; cp
--)
580 PredictorEncodeRow(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
)
582 TIFFPredictorState
*sp
= PredictorState(tif
);
585 assert(sp
->encodepfunc
!= NULL
);
586 assert(sp
->encoderow
!= NULL
);
588 /* XXX horizontal differencing alters user's data XXX */
589 (*sp
->encodepfunc
)(tif
, bp
, cc
);
590 return (*sp
->encoderow
)(tif
, bp
, cc
, s
);
594 PredictorEncodeTile(TIFF
* tif
, uint8
* bp0
, tmsize_t cc0
, uint16 s
)
596 static const char module[] = "PredictorEncodeTile";
597 TIFFPredictorState
*sp
= PredictorState(tif
);
599 tmsize_t cc
= cc0
, rowsize
;
604 assert(sp
->encodepfunc
!= NULL
);
605 assert(sp
->encodetile
!= NULL
);
608 * Do predictor manipulation in a working buffer to avoid altering
609 * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
611 working_copy
= (uint8
*) _TIFFmalloc(cc0
);
612 if( working_copy
== NULL
)
614 TIFFErrorExt(tif
->tif_clientdata
, module,
615 "Out of memory allocating " TIFF_SSIZE_FORMAT
" byte temp buffer.",
619 memcpy( working_copy
, bp0
, cc0
);
622 rowsize
= sp
->rowsize
;
624 assert((cc0%rowsize
)==0);
626 (*sp
->encodepfunc
)(tif
, bp
, rowsize
);
630 result_code
= (*sp
->encodetile
)(tif
, working_copy
, cc0
, s
);
632 _TIFFfree( working_copy
);
637 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
639 static const TIFFField predictFields
[] = {
640 { TIFFTAG_PREDICTOR
, 1, 1, TIFF_SHORT
, 0, TIFF_SETGET_UINT16
, TIFF_SETGET_UINT16
, FIELD_PREDICTOR
, FALSE
, FALSE
, "Predictor", NULL
},
644 PredictorVSetField(TIFF
* tif
, uint32 tag
, va_list ap
)
646 TIFFPredictorState
*sp
= PredictorState(tif
);
649 assert(sp
->vsetparent
!= NULL
);
652 case TIFFTAG_PREDICTOR
:
653 sp
->predictor
= (uint16
) va_arg(ap
, uint16_vap
);
654 TIFFSetFieldBit(tif
, FIELD_PREDICTOR
);
657 return (*sp
->vsetparent
)(tif
, tag
, ap
);
659 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
664 PredictorVGetField(TIFF
* tif
, uint32 tag
, va_list ap
)
666 TIFFPredictorState
*sp
= PredictorState(tif
);
669 assert(sp
->vgetparent
!= NULL
);
672 case TIFFTAG_PREDICTOR
:
673 *va_arg(ap
, uint16
*) = sp
->predictor
;
676 return (*sp
->vgetparent
)(tif
, tag
, ap
);
682 PredictorPrintDir(TIFF
* tif
, FILE* fd
, long flags
)
684 TIFFPredictorState
* sp
= PredictorState(tif
);
687 if (TIFFFieldSet(tif
,FIELD_PREDICTOR
)) {
688 fprintf(fd
, " Predictor: ");
689 switch (sp
->predictor
) {
690 case 1: fprintf(fd
, "none "); break;
691 case 2: fprintf(fd
, "horizontal differencing "); break;
692 case 3: fprintf(fd
, "floating point predictor "); break;
694 fprintf(fd
, "%u (0x%x)\n", sp
->predictor
, sp
->predictor
);
697 (*sp
->printdir
)(tif
, fd
, flags
);
701 TIFFPredictorInit(TIFF
* tif
)
703 TIFFPredictorState
* sp
= PredictorState(tif
);
708 * Merge codec-specific tag information.
710 if (!_TIFFMergeFields(tif
, predictFields
,
711 TIFFArrayCount(predictFields
))) {
712 TIFFErrorExt(tif
->tif_clientdata
, "TIFFPredictorInit",
713 "Merging Predictor codec-specific tags failed");
718 * Override parent get/set field methods.
720 sp
->vgetparent
= tif
->tif_tagmethods
.vgetfield
;
721 tif
->tif_tagmethods
.vgetfield
=
722 PredictorVGetField
;/* hook for predictor tag */
723 sp
->vsetparent
= tif
->tif_tagmethods
.vsetfield
;
724 tif
->tif_tagmethods
.vsetfield
=
725 PredictorVSetField
;/* hook for predictor tag */
726 sp
->printdir
= tif
->tif_tagmethods
.printdir
;
727 tif
->tif_tagmethods
.printdir
=
728 PredictorPrintDir
; /* hook for predictor tag */
730 sp
->setupdecode
= tif
->tif_setupdecode
;
731 tif
->tif_setupdecode
= PredictorSetupDecode
;
732 sp
->setupencode
= tif
->tif_setupencode
;
733 tif
->tif_setupencode
= PredictorSetupEncode
;
735 sp
->predictor
= 1; /* default value */
736 sp
->encodepfunc
= NULL
; /* no predictor routine */
737 sp
->decodepfunc
= NULL
; /* no predictor routine */
742 TIFFPredictorCleanup(TIFF
* tif
)
744 TIFFPredictorState
* sp
= PredictorState(tif
);
748 tif
->tif_tagmethods
.vgetfield
= sp
->vgetparent
;
749 tif
->tif_tagmethods
.vsetfield
= sp
->vsetparent
;
750 tif
->tif_tagmethods
.printdir
= sp
->printdir
;
751 tif
->tif_setupdecode
= sp
->setupdecode
;
752 tif
->tif_setupencode
= sp
->setupencode
;
757 /* vim: set ts=8 sts=8 sw=8 noet: */