]>
git.saurik.com Git - wxWidgets.git/blob - src/tiff/libtiff/tif_predict.c
3 * Copyright (c) 1988-1997 Sam Leffler
4 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
29 * Predictor Tag Support (used by multiple codecs).
32 #include "tif_predict.h"
34 #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
36 static void horAcc8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
37 static void horAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
38 static void horAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
39 static void swabHorAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
40 static void swabHorAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
41 static void horDiff8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
42 static void horDiff16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
43 static void horDiff32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
44 static void fpAcc(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
45 static void fpDiff(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
);
46 static int PredictorDecodeRow(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
);
47 static int PredictorDecodeTile(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
);
48 static int PredictorEncodeRow(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
);
49 static int PredictorEncodeTile(TIFF
* tif
, uint8
* bp0
, tmsize_t cc0
, uint16 s
);
52 PredictorSetup(TIFF
* tif
)
54 static const char module[] = "PredictorSetup";
56 TIFFPredictorState
* sp
= PredictorState(tif
);
57 TIFFDirectory
* td
= &tif
->tif_dir
;
59 switch (sp
->predictor
) /* no differencing */
63 case PREDICTOR_HORIZONTAL
:
64 if (td
->td_bitspersample
!= 8
65 && td
->td_bitspersample
!= 16
66 && td
->td_bitspersample
!= 32) {
67 TIFFErrorExt(tif
->tif_clientdata
, module,
68 "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
69 td
->td_bitspersample
);
73 case PREDICTOR_FLOATINGPOINT
:
74 if (td
->td_sampleformat
!= SAMPLEFORMAT_IEEEFP
) {
75 TIFFErrorExt(tif
->tif_clientdata
, module,
76 "Floating point \"Predictor\" not supported with %d data format",
82 TIFFErrorExt(tif
->tif_clientdata
, module,
83 "\"Predictor\" value %d not supported",
87 sp
->stride
= (td
->td_planarconfig
== PLANARCONFIG_CONTIG
?
88 td
->td_samplesperpixel
: 1);
90 * Calculate the scanline/tile-width size in bytes.
93 sp
->rowsize
= TIFFTileRowSize(tif
);
95 sp
->rowsize
= TIFFScanlineSize(tif
);
103 PredictorSetupDecode(TIFF
* tif
)
105 TIFFPredictorState
* sp
= PredictorState(tif
);
106 TIFFDirectory
* td
= &tif
->tif_dir
;
108 if (!(*sp
->setupdecode
)(tif
) || !PredictorSetup(tif
))
111 if (sp
->predictor
== 2) {
112 switch (td
->td_bitspersample
) {
113 case 8: sp
->decodepfunc
= horAcc8
; break;
114 case 16: sp
->decodepfunc
= horAcc16
; break;
115 case 32: sp
->decodepfunc
= horAcc32
; break;
118 * Override default decoding method with one that does the
121 if( tif
->tif_decoderow
!= PredictorDecodeRow
)
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
;
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.
138 if (tif
->tif_flags
& TIFF_SWAB
) {
139 if (sp
->decodepfunc
== horAcc16
) {
140 sp
->decodepfunc
= swabHorAcc16
;
141 tif
->tif_postdecode
= _TIFFNoPostDecode
;
142 } else if (sp
->decodepfunc
== horAcc32
) {
143 sp
->decodepfunc
= swabHorAcc32
;
144 tif
->tif_postdecode
= _TIFFNoPostDecode
;
149 else if (sp
->predictor
== 3) {
150 sp
->decodepfunc
= fpAcc
;
152 * Override default decoding method with one that does the
155 if( tif
->tif_decoderow
!= PredictorDecodeRow
)
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
;
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.
169 if (tif
->tif_flags
& TIFF_SWAB
) {
170 tif
->tif_postdecode
= _TIFFNoPostDecode
;
173 * Allocate buffer to keep the decoded bytes before
174 * rearranging in the ight order
182 PredictorSetupEncode(TIFF
* tif
)
184 TIFFPredictorState
* sp
= PredictorState(tif
);
185 TIFFDirectory
* td
= &tif
->tif_dir
;
187 if (!(*sp
->setupencode
)(tif
) || !PredictorSetup(tif
))
190 if (sp
->predictor
== 2) {
191 switch (td
->td_bitspersample
) {
192 case 8: sp
->encodepfunc
= horDiff8
; break;
193 case 16: sp
->encodepfunc
= horDiff16
; break;
194 case 32: sp
->encodepfunc
= horDiff32
; break;
197 * Override default encoding method with one that does the
200 if( tif
->tif_encoderow
!= PredictorEncodeRow
)
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
;
211 else if (sp
->predictor
== 3) {
212 sp
->encodepfunc
= fpDiff
;
214 * Override default encoding method with one that does the
217 if( tif
->tif_encoderow
!= PredictorEncodeRow
)
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
;
231 #define REPEAT4(n, op) \
233 default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
242 horAcc8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
244 tmsize_t stride
= PredictorState(tif
)->stride
;
246 char* cp
= (char*) cp0
;
247 assert((cc%stride
)==0);
250 * Pipeline the most common cases.
253 unsigned int cr
= cp
[0];
254 unsigned int cg
= cp
[1];
255 unsigned int cb
= cp
[2];
259 cp
[0] = (char) (cr
+= cp
[0]);
260 cp
[1] = (char) (cg
+= cp
[1]);
261 cp
[2] = (char) (cb
+= cp
[2]);
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];
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]);
283 REPEAT4(stride
, cp
[stride
] =
284 (char) (cp
[stride
] + *cp
); cp
++)
292 swabHorAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
294 tmsize_t stride
= PredictorState(tif
)->stride
;
295 uint16
* wp
= (uint16
*) cp0
;
296 tmsize_t wc
= cc
/ 2;
298 assert((cc
%(2*stride
))==0);
301 TIFFSwabArrayOfShort(wp
, wc
);
304 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
311 horAcc16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
313 tmsize_t stride
= PredictorState(tif
)->stride
;
314 uint16
* wp
= (uint16
*) cp0
;
315 tmsize_t wc
= cc
/ 2;
317 assert((cc
%(2*stride
))==0);
322 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
329 swabHorAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
331 tmsize_t stride
= PredictorState(tif
)->stride
;
332 uint32
* wp
= (uint32
*) cp0
;
333 tmsize_t wc
= cc
/ 4;
335 assert((cc
%(4*stride
))==0);
338 TIFFSwabArrayOfLong(wp
, wc
);
341 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
348 horAcc32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
350 tmsize_t stride
= PredictorState(tif
)->stride
;
351 uint32
* wp
= (uint32
*) cp0
;
352 tmsize_t wc
= cc
/ 4;
354 assert((cc
%(4*stride
))==0);
359 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
366 * Floating point predictor accumulation routine.
369 fpAcc(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
371 tmsize_t stride
= PredictorState(tif
)->stride
;
372 uint32 bps
= tif
->tif_dir
.td_bitspersample
/ 8;
373 tmsize_t wc
= cc
/ bps
;
375 uint8
*cp
= (uint8
*) cp0
;
376 uint8
*tmp
= (uint8
*)_TIFFmalloc(cc
);
378 assert((cc
%(bps
*stride
))==0);
383 while (count
> stride
) {
384 REPEAT4(stride
, cp
[stride
] += cp
[0]; cp
++)
388 _TIFFmemcpy(tmp
, cp0
, cc
);
390 for (count
= 0; count
< wc
; count
++) {
392 for (byte
= 0; byte
< bps
; byte
++) {
393 #ifdef WORDS_BIGENDIAN
394 cp
[bps
* count
+ byte
] = tmp
[byte
* wc
+ count
];
396 cp
[bps
* count
+ byte
] =
397 tmp
[(bps
- byte
- 1) * wc
+ count
];
405 * Decode a scanline and apply the predictor routine.
408 PredictorDecodeRow(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
)
410 TIFFPredictorState
*sp
= PredictorState(tif
);
413 assert(sp
->decoderow
!= NULL
);
414 assert(sp
->decodepfunc
!= NULL
);
416 if ((*sp
->decoderow
)(tif
, op0
, occ0
, s
)) {
417 (*sp
->decodepfunc
)(tif
, op0
, occ0
);
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.
431 PredictorDecodeTile(TIFF
* tif
, uint8
* op0
, tmsize_t occ0
, uint16 s
)
433 TIFFPredictorState
*sp
= PredictorState(tif
);
436 assert(sp
->decodetile
!= NULL
);
438 if ((*sp
->decodetile
)(tif
, op0
, occ0
, s
)) {
439 tmsize_t rowsize
= sp
->rowsize
;
441 assert((occ0%rowsize
)==0);
442 assert(sp
->decodepfunc
!= NULL
);
444 (*sp
->decodepfunc
)(tif
, op0
, rowsize
);
454 horDiff8(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
456 TIFFPredictorState
* sp
= PredictorState(tif
);
457 tmsize_t stride
= sp
->stride
;
458 char* cp
= (char*) cp0
;
460 assert((cc%stride
)==0);
465 * Pipeline the most common cases.
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
;
477 } while ((cc
-= 3) > 0);
478 } else if (stride
== 4) {
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
;
490 } while ((cc
-= 4) > 0);
494 REPEAT4(stride
, cp
[stride
] -= cp
[0]; cp
--)
495 } while ((cc
-= stride
) > 0);
501 horDiff16(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
503 TIFFPredictorState
* sp
= PredictorState(tif
);
504 tmsize_t stride
= sp
->stride
;
505 int16
*wp
= (int16
*) cp0
;
508 assert((cc
%(2*stride
))==0);
514 REPEAT4(stride
, wp
[stride
] -= wp
[0]; wp
--)
521 horDiff32(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
523 TIFFPredictorState
* sp
= PredictorState(tif
);
524 tmsize_t stride
= sp
->stride
;
525 int32
*wp
= (int32
*) cp0
;
528 assert((cc
%(4*stride
))==0);
534 REPEAT4(stride
, wp
[stride
] -= wp
[0]; wp
--)
541 * Floating point predictor differencing routine.
544 fpDiff(TIFF
* tif
, uint8
* cp0
, tmsize_t cc
)
546 tmsize_t stride
= PredictorState(tif
)->stride
;
547 uint32 bps
= tif
->tif_dir
.td_bitspersample
/ 8;
548 tmsize_t wc
= cc
/ bps
;
550 uint8
*cp
= (uint8
*) cp0
;
551 uint8
*tmp
= (uint8
*)_TIFFmalloc(cc
);
553 assert((cc
%(bps
*stride
))==0);
558 _TIFFmemcpy(tmp
, cp0
, cc
);
559 for (count
= 0; count
< wc
; count
++) {
561 for (byte
= 0; byte
< bps
; byte
++) {
562 #ifdef WORDS_BIGENDIAN
563 cp
[byte
* wc
+ count
] = tmp
[bps
* count
+ byte
];
565 cp
[(bps
- byte
- 1) * wc
+ count
] =
566 tmp
[bps
* count
+ byte
];
573 cp
+= cc
- stride
- 1;
574 for (count
= cc
; count
> stride
; count
-= stride
)
575 REPEAT4(stride
, cp
[stride
] -= cp
[0]; cp
--)
579 PredictorEncodeRow(TIFF
* tif
, uint8
* bp
, tmsize_t cc
, uint16 s
)
581 TIFFPredictorState
*sp
= PredictorState(tif
);
584 assert(sp
->encodepfunc
!= NULL
);
585 assert(sp
->encoderow
!= NULL
);
587 /* XXX horizontal differencing alters user's data XXX */
588 (*sp
->encodepfunc
)(tif
, bp
, cc
);
589 return (*sp
->encoderow
)(tif
, bp
, cc
, s
);
593 PredictorEncodeTile(TIFF
* tif
, uint8
* bp0
, tmsize_t cc0
, uint16 s
)
595 static const char module[] = "PredictorEncodeTile";
596 TIFFPredictorState
*sp
= PredictorState(tif
);
598 tmsize_t cc
= cc0
, rowsize
;
603 assert(sp
->encodepfunc
!= NULL
);
604 assert(sp
->encodetile
!= NULL
);
607 * Do predictor manipulation in a working buffer to avoid altering
608 * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
610 working_copy
= (uint8
*) _TIFFmalloc(cc0
);
611 if( working_copy
== NULL
)
613 TIFFErrorExt(tif
->tif_clientdata
, module,
614 "Out of memory allocating " TIFF_SSIZE_FORMAT
" byte temp buffer.",
618 memcpy( working_copy
, bp0
, cc0
);
621 rowsize
= sp
->rowsize
;
623 assert((cc0%rowsize
)==0);
625 (*sp
->encodepfunc
)(tif
, bp
, rowsize
);
629 result_code
= (*sp
->encodetile
)(tif
, working_copy
, cc0
, s
);
631 _TIFFfree( working_copy
);
636 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
638 static const TIFFField predictFields
[] = {
639 { TIFFTAG_PREDICTOR
, 1, 1, TIFF_SHORT
, 0, TIFF_SETGET_UINT16
, TIFF_SETGET_UINT16
, FIELD_PREDICTOR
, FALSE
, FALSE
, "Predictor", NULL
},
643 PredictorVSetField(TIFF
* tif
, uint32 tag
, va_list ap
)
645 TIFFPredictorState
*sp
= PredictorState(tif
);
648 assert(sp
->vsetparent
!= NULL
);
651 case TIFFTAG_PREDICTOR
:
652 sp
->predictor
= (uint16
) va_arg(ap
, uint16_vap
);
653 TIFFSetFieldBit(tif
, FIELD_PREDICTOR
);
656 return (*sp
->vsetparent
)(tif
, tag
, ap
);
658 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
663 PredictorVGetField(TIFF
* tif
, uint32 tag
, va_list ap
)
665 TIFFPredictorState
*sp
= PredictorState(tif
);
668 assert(sp
->vgetparent
!= NULL
);
671 case TIFFTAG_PREDICTOR
:
672 *va_arg(ap
, uint16
*) = sp
->predictor
;
675 return (*sp
->vgetparent
)(tif
, tag
, ap
);
681 PredictorPrintDir(TIFF
* tif
, FILE* fd
, long flags
)
683 TIFFPredictorState
* sp
= PredictorState(tif
);
686 if (TIFFFieldSet(tif
,FIELD_PREDICTOR
)) {
687 fprintf(fd
, " Predictor: ");
688 switch (sp
->predictor
) {
689 case 1: fprintf(fd
, "none "); break;
690 case 2: fprintf(fd
, "horizontal differencing "); break;
691 case 3: fprintf(fd
, "floating point predictor "); break;
693 fprintf(fd
, "%u (0x%x)\n", sp
->predictor
, sp
->predictor
);
696 (*sp
->printdir
)(tif
, fd
, flags
);
700 TIFFPredictorInit(TIFF
* tif
)
702 TIFFPredictorState
* sp
= PredictorState(tif
);
707 * Merge codec-specific tag information.
709 if (!_TIFFMergeFields(tif
, predictFields
,
710 TIFFArrayCount(predictFields
))) {
711 TIFFErrorExt(tif
->tif_clientdata
, "TIFFPredictorInit",
712 "Merging Predictor codec-specific tags failed");
717 * Override parent get/set field methods.
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
=
724 PredictorVSetField
;/* hook for predictor tag */
725 sp
->printdir
= tif
->tif_tagmethods
.printdir
;
726 tif
->tif_tagmethods
.printdir
=
727 PredictorPrintDir
; /* hook for predictor tag */
729 sp
->setupdecode
= tif
->tif_setupdecode
;
730 tif
->tif_setupdecode
= PredictorSetupDecode
;
731 sp
->setupencode
= tif
->tif_setupencode
;
732 tif
->tif_setupencode
= PredictorSetupEncode
;
734 sp
->predictor
= 1; /* default value */
735 sp
->encodepfunc
= NULL
; /* no predictor routine */
736 sp
->decodepfunc
= NULL
; /* no predictor routine */
741 TIFFPredictorCleanup(TIFF
* tif
)
743 TIFFPredictorState
* sp
= PredictorState(tif
);
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
;
756 /* vim: set ts=8 sts=8 sw=8 noet: */