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 /* Watcom C++ (or its make utility) doesn't like long filenames */
34 #ifdef wxUSE_SHORTNAMES
37 #include "tif_predict.h"
42 #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
44 static void LINKAGEMODE
horAcc8(TIFF
*, tidata_t
, tsize_t
);
45 static void LINKAGEMODE
horAcc16(TIFF
*, tidata_t
, tsize_t
);
46 static void LINKAGEMODE
swabHorAcc16(TIFF
*, tidata_t
, tsize_t
);
47 static void LINKAGEMODE
horDiff8(TIFF
*, tidata_t
, tsize_t
);
48 static void LINKAGEMODE
horDiff16(TIFF
*, tidata_t
, tsize_t
);
49 static int LINKAGEMODE
PredictorDecodeRow(TIFF
*, tidata_t
, tsize_t
, tsample_t
);
50 static int LINKAGEMODE
PredictorDecodeTile(TIFF
*, tidata_t
, tsize_t
, tsample_t
);
51 static int LINKAGEMODE
PredictorEncodeRow(TIFF
*, tidata_t
, tsize_t
, tsample_t
);
52 static int LINKAGEMODE
PredictorEncodeTile(TIFF
*, tidata_t
, tsize_t
, tsample_t
);
55 PredictorSetup(TIFF
* tif
)
57 TIFFPredictorState
* sp
= PredictorState(tif
);
58 TIFFDirectory
* td
= &tif
->tif_dir
;
60 if (sp
->predictor
== 1) /* no differencing */
62 if (sp
->predictor
!= 2) {
63 TIFFError(tif
->tif_name
, "\"Predictor\" value %d not supported",
67 if (td
->td_bitspersample
!= 8 && td
->td_bitspersample
!= 16) {
68 TIFFError(tif
->tif_name
,
69 "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
70 td
->td_bitspersample
);
73 sp
->stride
= (td
->td_planarconfig
== PLANARCONFIG_CONTIG
?
74 td
->td_samplesperpixel
: 1);
76 * Calculate the scanline/tile-width size in bytes.
79 sp
->rowsize
= TIFFTileRowSize(tif
);
81 sp
->rowsize
= TIFFScanlineSize(tif
);
86 PredictorSetupDecode(TIFF
* tif
)
88 TIFFPredictorState
* sp
= PredictorState(tif
);
89 TIFFDirectory
* td
= &tif
->tif_dir
;
91 if (!(*sp
->setupdecode
)(tif
) || !PredictorSetup(tif
))
93 if (sp
->predictor
== 2) {
94 switch (td
->td_bitspersample
) {
95 case 8: sp
->pfunc
= horAcc8
; break;
96 case 16: sp
->pfunc
= horAcc16
; break;
99 * Override default decoding method with
100 * one that does the predictor stuff.
102 sp
->coderow
= tif
->tif_decoderow
;
103 tif
->tif_decoderow
= PredictorDecodeRow
;
104 sp
->codestrip
= tif
->tif_decodestrip
;
105 tif
->tif_decodestrip
= PredictorDecodeTile
;
106 sp
->codetile
= tif
->tif_decodetile
;
107 tif
->tif_decodetile
= PredictorDecodeTile
;
109 * If the data is horizontally differenced
110 * 16-bit data that requires byte-swapping,
111 * then it must be byte swapped before the
112 * accumulation step. We do this with a
113 * special-purpose routine and override the
114 * normal post decoding logic that the library
115 * setup when the directory was read.
117 if (tif
->tif_flags
&TIFF_SWAB
) {
118 if (sp
->pfunc
== horAcc16
) {
119 sp
->pfunc
= swabHorAcc16
;
120 tif
->tif_postdecode
= _TIFFNoPostDecode
;
121 } /* else handle 32-bit case... */
128 PredictorSetupEncode(TIFF
* tif
)
130 TIFFPredictorState
* sp
= PredictorState(tif
);
131 TIFFDirectory
* td
= &tif
->tif_dir
;
133 if (!(*sp
->setupencode
)(tif
) || !PredictorSetup(tif
))
135 if (sp
->predictor
== 2) {
136 switch (td
->td_bitspersample
) {
137 case 8: sp
->pfunc
= horDiff8
; break;
138 case 16: sp
->pfunc
= horDiff16
; break;
141 * Override default encoding method with
142 * one that does the predictor stuff.
144 sp
->coderow
= tif
->tif_encoderow
;
145 tif
->tif_encoderow
= PredictorEncodeRow
;
146 sp
->codestrip
= tif
->tif_encodestrip
;
147 tif
->tif_encodestrip
= PredictorEncodeTile
;
148 sp
->codetile
= tif
->tif_encodetile
;
149 tif
->tif_encodetile
= PredictorEncodeTile
;
154 #define REPEAT4(n, op) \
156 default: { int i; for (i = n-4; i > 0; i--) { op; } } \
165 horAcc8(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
167 TIFFPredictorState
* sp
= PredictorState(tif
);
168 u_int stride
= sp
->stride
;
170 char* cp
= (char*) cp0
;
174 * Pipeline the most common cases.
182 cp
[0] = (cr
+= cp
[0]);
183 cp
[1] = (cg
+= cp
[1]);
184 cp
[2] = (cb
+= cp
[2]);
185 } while ((int32
) cc
> 0);
186 } else if (stride
== 4) {
193 cp
[0] = (cr
+= cp
[0]);
194 cp
[1] = (cg
+= cp
[1]);
195 cp
[2] = (cb
+= cp
[2]);
196 cp
[3] = (ca
+= cp
[3]);
197 } while ((int32
) cc
> 0);
200 REPEAT4(stride
, cp
[stride
] += *cp
; cp
++)
202 } while ((int32
) cc
> 0);
208 swabHorAcc16(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
210 TIFFPredictorState
* sp
= PredictorState(tif
);
211 u_int stride
= sp
->stride
;
212 uint16
* wp
= (uint16
*) cp0
;
216 TIFFSwabArrayOfShort(wp
, wc
);
219 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
221 } while ((int32
) wc
> 0);
226 horAcc16(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
228 u_int stride
= PredictorState(tif
)->stride
;
229 uint16
* wp
= (uint16
*) cp0
;
235 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
237 } while ((int32
) wc
> 0);
242 * Decode a scanline and apply the predictor routine.
245 PredictorDecodeRow(TIFF
* tif
, tidata_t op0
, tsize_t occ0
, tsample_t s
)
247 TIFFPredictorState
*sp
= PredictorState(tif
);
250 assert(sp
->coderow
!= NULL
);
251 assert(sp
->pfunc
!= NULL
);
252 if ((*sp
->coderow
)(tif
, op0
, occ0
, s
)) {
253 (*sp
->pfunc
)(tif
, op0
, occ0
);
260 * Decode a tile/strip and apply the predictor routine.
261 * Note that horizontal differencing must be done on a
262 * row-by-row basis. The width of a "row" has already
263 * been calculated at pre-decode time according to the
264 * strip/tile dimensions.
267 PredictorDecodeTile(TIFF
* tif
, tidata_t op0
, tsize_t occ0
, tsample_t s
)
269 TIFFPredictorState
*sp
= PredictorState(tif
);
272 assert(sp
->codetile
!= NULL
);
273 if ((*sp
->codetile
)(tif
, op0
, occ0
, s
)) {
274 tsize_t rowsize
= sp
->rowsize
;
276 assert(sp
->pfunc
!= NULL
);
277 while ((long)occ0
> 0) {
278 (*sp
->pfunc
)(tif
, op0
, (tsize_t
) rowsize
);
288 horDiff8(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
290 TIFFPredictorState
* sp
= PredictorState(tif
);
291 u_int stride
= sp
->stride
;
292 char* cp
= (char*) cp0
;
297 * Pipeline the most common cases.
305 r1
= cp
[3]; cp
[3] = r1
-r2
; r2
= r1
;
306 g1
= cp
[4]; cp
[4] = g1
-g2
; g2
= g1
;
307 b1
= cp
[5]; cp
[5] = b1
-b2
; b2
= b1
;
309 } while ((int32
)(cc
-= 3) > 0);
310 } else if (stride
== 4) {
317 r1
= cp
[4]; cp
[4] = r1
-r2
; r2
= r1
;
318 g1
= cp
[5]; cp
[5] = g1
-g2
; g2
= g1
;
319 b1
= cp
[6]; cp
[6] = b1
-b2
; b2
= b1
;
320 a1
= cp
[7]; cp
[7] = a1
-a2
; a2
= a1
;
322 } while ((int32
)(cc
-= 4) > 0);
326 REPEAT4(stride
, cp
[stride
] -= cp
[0]; cp
--)
327 } while ((int32
)(cc
-= stride
) > 0);
333 horDiff16(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
335 TIFFPredictorState
* sp
= PredictorState(tif
);
336 u_int stride
= sp
->stride
;
337 int16
*wp
= (int16
*) cp0
;
344 REPEAT4(stride
, wp
[stride
] -= wp
[0]; wp
--)
346 } while ((int32
) wc
> 0);
351 PredictorEncodeRow(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
)
353 TIFFPredictorState
*sp
= PredictorState(tif
);
356 assert(sp
->pfunc
!= NULL
);
357 assert(sp
->coderow
!= NULL
);
358 /* XXX horizontal differencing alters user's data XXX */
359 (*sp
->pfunc
)(tif
, bp
, cc
);
360 return ((*sp
->coderow
)(tif
, bp
, cc
, s
));
364 PredictorEncodeTile(TIFF
* tif
, tidata_t bp0
, tsize_t cc0
, tsample_t s
)
366 TIFFPredictorState
*sp
= PredictorState(tif
);
367 tsize_t cc
= cc0
, rowsize
;
371 assert(sp
->pfunc
!= NULL
);
372 assert(sp
->codetile
!= NULL
);
373 rowsize
= sp
->rowsize
;
375 while ((long)cc
> 0) {
376 (*sp
->pfunc
)(tif
, bp
, (tsize_t
) rowsize
);
380 return ((*sp
->codetile
)(tif
, bp0
, cc0
, s
));
383 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
385 static const TIFFFieldInfo predictFieldInfo
[] = {
386 { TIFFTAG_PREDICTOR
, 1, 1, TIFF_SHORT
, FIELD_PREDICTOR
,
387 FALSE
, FALSE
, "Predictor" },
389 #define N(a) (sizeof (a) / sizeof (a[0]))
392 PredictorVSetField(TIFF
* tif
, ttag_t tag
, va_list ap
)
394 TIFFPredictorState
*sp
= PredictorState(tif
);
397 case TIFFTAG_PREDICTOR
:
398 sp
->predictor
= (uint16
) va_arg(ap
, int);
399 TIFFSetFieldBit(tif
, FIELD_PREDICTOR
);
402 return (*sp
->vsetparent
)(tif
, tag
, ap
);
404 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
409 PredictorVGetField(TIFF
* tif
, ttag_t tag
, va_list ap
)
411 TIFFPredictorState
*sp
= PredictorState(tif
);
414 case TIFFTAG_PREDICTOR
:
415 *va_arg(ap
, uint16
*) = sp
->predictor
;
418 return (*sp
->vgetparent
)(tif
, tag
, ap
);
423 static void LINKAGEMODE
424 PredictorPrintDir(TIFF
* tif
, FILE* fd
, long flags
)
426 TIFFPredictorState
* sp
= PredictorState(tif
);
429 if (TIFFFieldSet(tif
,FIELD_PREDICTOR
)) {
430 fprintf(fd
, " Predictor: ");
431 switch (sp
->predictor
) {
432 case 1: fprintf(fd
, "none "); break;
433 case 2: fprintf(fd
, "horizontal differencing "); break;
435 fprintf(fd
, "%u (0x%x)\n", sp
->predictor
, sp
->predictor
);
438 (*sp
->printdir
)(tif
, fd
, flags
);
442 TIFFPredictorInit(TIFF
* tif
)
444 TIFFPredictorState
* sp
= PredictorState(tif
);
447 * Merge codec-specific tag information and
448 * override parent get/set field methods.
450 _TIFFMergeFieldInfo(tif
, predictFieldInfo
, N(predictFieldInfo
));
451 sp
->vgetparent
= tif
->tif_vgetfield
;
452 tif
->tif_vgetfield
= PredictorVGetField
;/* hook for predictor tag */
453 sp
->vsetparent
= tif
->tif_vsetfield
;
454 tif
->tif_vsetfield
= PredictorVSetField
;/* hook for predictor tag */
455 sp
->printdir
= tif
->tif_printdir
;
456 tif
->tif_printdir
= PredictorPrintDir
; /* hook for predictor tag */
458 sp
->setupdecode
= tif
->tif_setupdecode
;
459 tif
->tif_setupdecode
= PredictorSetupDecode
;
460 sp
->setupencode
= tif
->tif_setupencode
;
461 tif
->tif_setupencode
= PredictorSetupEncode
;
463 sp
->predictor
= 1; /* default value */
464 sp
->pfunc
= NULL
; /* no predictor routine */