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"
37 #define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
39 static void horAcc8(TIFF
*, tidata_t
, tsize_t
);
40 static void horAcc16(TIFF
*, tidata_t
, tsize_t
);
41 static void swabHorAcc16(TIFF
*, tidata_t
, tsize_t
);
42 static void horDiff8(TIFF
*, tidata_t
, tsize_t
);
43 static void horDiff16(TIFF
*, tidata_t
, tsize_t
);
44 static int PredictorDecodeRow(TIFF
*, tidata_t
, tsize_t
, tsample_t
);
45 static int PredictorDecodeTile(TIFF
*, tidata_t
, tsize_t
, tsample_t
);
46 static int PredictorEncodeRow(TIFF
*, tidata_t
, tsize_t
, tsample_t
);
47 static int PredictorEncodeTile(TIFF
*, tidata_t
, tsize_t
, tsample_t
);
50 PredictorSetup(TIFF
* tif
)
52 TIFFPredictorState
* sp
= PredictorState(tif
);
53 TIFFDirectory
* td
= &tif
->tif_dir
;
55 if (sp
->predictor
== 1) /* no differencing */
57 if (sp
->predictor
!= 2) {
58 TIFFError(tif
->tif_name
, "\"Predictor\" value %d not supported",
62 if (td
->td_bitspersample
!= 8 && td
->td_bitspersample
!= 16) {
63 TIFFError(tif
->tif_name
,
64 "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
65 td
->td_bitspersample
);
68 sp
->stride
= (td
->td_planarconfig
== PLANARCONFIG_CONTIG
?
69 td
->td_samplesperpixel
: 1);
71 * Calculate the scanline/tile-width size in bytes.
74 sp
->rowsize
= TIFFTileRowSize(tif
);
76 sp
->rowsize
= TIFFScanlineSize(tif
);
81 PredictorSetupDecode(TIFF
* tif
)
83 TIFFPredictorState
* sp
= PredictorState(tif
);
84 TIFFDirectory
* td
= &tif
->tif_dir
;
86 if (!(*sp
->setupdecode
)(tif
) || !PredictorSetup(tif
))
88 if (sp
->predictor
== 2) {
89 switch (td
->td_bitspersample
) {
90 case 8: sp
->pfunc
= horAcc8
; break;
91 case 16: sp
->pfunc
= horAcc16
; break;
94 * Override default decoding method with
95 * one that does the predictor stuff.
97 sp
->coderow
= tif
->tif_decoderow
;
98 tif
->tif_decoderow
= PredictorDecodeRow
;
99 sp
->codestrip
= tif
->tif_decodestrip
;
100 tif
->tif_decodestrip
= PredictorDecodeTile
;
101 sp
->codetile
= tif
->tif_decodetile
;
102 tif
->tif_decodetile
= PredictorDecodeTile
;
104 * If the data is horizontally differenced
105 * 16-bit data that requires byte-swapping,
106 * then it must be byte swapped before the
107 * accumulation step. We do this with a
108 * special-purpose routine and override the
109 * normal post decoding logic that the library
110 * setup when the directory was read.
112 if (tif
->tif_flags
&TIFF_SWAB
) {
113 if (sp
->pfunc
== horAcc16
) {
114 sp
->pfunc
= swabHorAcc16
;
115 tif
->tif_postdecode
= _TIFFNoPostDecode
;
116 } /* else handle 32-bit case... */
123 PredictorSetupEncode(TIFF
* tif
)
125 TIFFPredictorState
* sp
= PredictorState(tif
);
126 TIFFDirectory
* td
= &tif
->tif_dir
;
128 if (!(*sp
->setupencode
)(tif
) || !PredictorSetup(tif
))
130 if (sp
->predictor
== 2) {
131 switch (td
->td_bitspersample
) {
132 case 8: sp
->pfunc
= horDiff8
; break;
133 case 16: sp
->pfunc
= horDiff16
; break;
136 * Override default encoding method with
137 * one that does the predictor stuff.
139 sp
->coderow
= tif
->tif_encoderow
;
140 tif
->tif_encoderow
= PredictorEncodeRow
;
141 sp
->codestrip
= tif
->tif_encodestrip
;
142 tif
->tif_encodestrip
= PredictorEncodeTile
;
143 sp
->codetile
= tif
->tif_encodetile
;
144 tif
->tif_encodetile
= PredictorEncodeTile
;
149 #define REPEAT4(n, op) \
151 default: { int i; for (i = n-4; i > 0; i--) { op; } } \
160 horAcc8(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
162 TIFFPredictorState
* sp
= PredictorState(tif
);
163 tsize_t stride
= sp
->stride
;
165 char* cp
= (char*) cp0
;
169 * Pipeline the most common cases.
177 cp
[0] = (char) (cr
+= cp
[0]);
178 cp
[1] = (char) (cg
+= cp
[1]);
179 cp
[2] = (char) (cb
+= cp
[2]);
180 } while ((int32
) cc
> 0);
181 } else if (stride
== 4) {
188 cp
[0] = (char) (cr
+= cp
[0]);
189 cp
[1] = (char) (cg
+= cp
[1]);
190 cp
[2] = (char) (cb
+= cp
[2]);
191 cp
[3] = (char) (ca
+= cp
[3]);
192 } while ((int32
) cc
> 0);
195 REPEAT4(stride
, cp
[stride
] = (char) (cp
[stride
] + *cp
); cp
++)
197 } while ((int32
) cc
> 0);
203 swabHorAcc16(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
205 TIFFPredictorState
* sp
= PredictorState(tif
);
206 tsize_t stride
= sp
->stride
;
207 uint16
* wp
= (uint16
*) cp0
;
211 TIFFSwabArrayOfShort(wp
, wc
);
214 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
216 } while ((int32
) wc
> 0);
221 horAcc16(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
223 tsize_t stride
= PredictorState(tif
)->stride
;
224 uint16
* wp
= (uint16
*) cp0
;
230 REPEAT4(stride
, wp
[stride
] += wp
[0]; wp
++)
232 } while ((int32
) wc
> 0);
237 * Decode a scanline and apply the predictor routine.
240 PredictorDecodeRow(TIFF
* tif
, tidata_t op0
, tsize_t occ0
, tsample_t s
)
242 TIFFPredictorState
*sp
= PredictorState(tif
);
245 assert(sp
->coderow
!= NULL
);
246 assert(sp
->pfunc
!= NULL
);
247 if ((*sp
->coderow
)(tif
, op0
, occ0
, s
)) {
248 (*sp
->pfunc
)(tif
, op0
, occ0
);
255 * Decode a tile/strip and apply the predictor routine.
256 * Note that horizontal differencing must be done on a
257 * row-by-row basis. The width of a "row" has already
258 * been calculated at pre-decode time according to the
259 * strip/tile dimensions.
262 PredictorDecodeTile(TIFF
* tif
, tidata_t op0
, tsize_t occ0
, tsample_t s
)
264 TIFFPredictorState
*sp
= PredictorState(tif
);
267 assert(sp
->codetile
!= NULL
);
268 if ((*sp
->codetile
)(tif
, op0
, occ0
, s
)) {
269 tsize_t rowsize
= sp
->rowsize
;
271 assert(sp
->pfunc
!= NULL
);
272 while ((long)occ0
> 0) {
273 (*sp
->pfunc
)(tif
, op0
, (tsize_t
) rowsize
);
283 horDiff8(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
285 TIFFPredictorState
* sp
= PredictorState(tif
);
286 tsize_t stride
= sp
->stride
;
287 char* cp
= (char*) cp0
;
292 * Pipeline the most common cases.
300 r1
= cp
[3]; cp
[3] = r1
-r2
; r2
= r1
;
301 g1
= cp
[4]; cp
[4] = g1
-g2
; g2
= g1
;
302 b1
= cp
[5]; cp
[5] = b1
-b2
; b2
= b1
;
304 } while ((int32
)(cc
-= 3) > 0);
305 } else if (stride
== 4) {
312 r1
= cp
[4]; cp
[4] = r1
-r2
; r2
= r1
;
313 g1
= cp
[5]; cp
[5] = g1
-g2
; g2
= g1
;
314 b1
= cp
[6]; cp
[6] = b1
-b2
; b2
= b1
;
315 a1
= cp
[7]; cp
[7] = a1
-a2
; a2
= a1
;
317 } while ((int32
)(cc
-= 4) > 0);
321 REPEAT4(stride
, cp
[stride
] -= cp
[0]; cp
--)
322 } while ((int32
)(cc
-= stride
) > 0);
328 horDiff16(TIFF
* tif
, tidata_t cp0
, tsize_t cc
)
330 TIFFPredictorState
* sp
= PredictorState(tif
);
331 tsize_t stride
= sp
->stride
;
332 int16
*wp
= (int16
*) cp0
;
339 REPEAT4(stride
, wp
[stride
] -= wp
[0]; wp
--)
341 } while ((int32
) wc
> 0);
346 PredictorEncodeRow(TIFF
* tif
, tidata_t bp
, tsize_t cc
, tsample_t s
)
348 TIFFPredictorState
*sp
= PredictorState(tif
);
351 assert(sp
->pfunc
!= NULL
);
352 assert(sp
->coderow
!= NULL
);
353 /* XXX horizontal differencing alters user's data XXX */
354 (*sp
->pfunc
)(tif
, bp
, cc
);
355 return ((*sp
->coderow
)(tif
, bp
, cc
, s
));
359 PredictorEncodeTile(TIFF
* tif
, tidata_t bp0
, tsize_t cc0
, tsample_t s
)
361 TIFFPredictorState
*sp
= PredictorState(tif
);
362 tsize_t cc
= cc0
, rowsize
;
366 assert(sp
->pfunc
!= NULL
);
367 assert(sp
->codetile
!= NULL
);
368 rowsize
= sp
->rowsize
;
370 while ((long)cc
> 0) {
371 (*sp
->pfunc
)(tif
, bp
, (tsize_t
) rowsize
);
375 return ((*sp
->codetile
)(tif
, bp0
, cc0
, s
));
378 #define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
380 static const TIFFFieldInfo predictFieldInfo
[] = {
381 { TIFFTAG_PREDICTOR
, 1, 1, TIFF_SHORT
, FIELD_PREDICTOR
,
382 FALSE
, FALSE
, "Predictor" },
384 #define N(a) (sizeof (a) / sizeof (a[0]))
387 PredictorVSetField(TIFF
* tif
, ttag_t tag
, va_list ap
)
389 TIFFPredictorState
*sp
= PredictorState(tif
);
392 case TIFFTAG_PREDICTOR
:
393 sp
->predictor
= (uint16
) va_arg(ap
, int);
394 TIFFSetFieldBit(tif
, FIELD_PREDICTOR
);
397 return (*sp
->vsetparent
)(tif
, tag
, ap
);
399 tif
->tif_flags
|= TIFF_DIRTYDIRECT
;
404 PredictorVGetField(TIFF
* tif
, ttag_t tag
, va_list ap
)
406 TIFFPredictorState
*sp
= PredictorState(tif
);
409 case TIFFTAG_PREDICTOR
:
410 *va_arg(ap
, uint16
*) = sp
->predictor
;
413 return (*sp
->vgetparent
)(tif
, tag
, ap
);
419 PredictorPrintDir(TIFF
* tif
, FILE* fd
, long flags
)
421 TIFFPredictorState
* sp
= PredictorState(tif
);
424 if (TIFFFieldSet(tif
,FIELD_PREDICTOR
)) {
425 fprintf(fd
, " Predictor: ");
426 switch (sp
->predictor
) {
427 case 1: fprintf(fd
, "none "); break;
428 case 2: fprintf(fd
, "horizontal differencing "); break;
430 fprintf(fd
, "%u (0x%x)\n", sp
->predictor
, sp
->predictor
);
433 (*sp
->printdir
)(tif
, fd
, flags
);
437 TIFFPredictorInit(TIFF
* tif
)
439 TIFFPredictorState
* sp
= PredictorState(tif
);
442 * Merge codec-specific tag information and
443 * override parent get/set field methods.
445 _TIFFMergeFieldInfo(tif
, predictFieldInfo
, N(predictFieldInfo
));
446 sp
->vgetparent
= tif
->tif_tagmethods
.vgetfield
;
447 tif
->tif_tagmethods
.vgetfield
=
448 PredictorVGetField
;/* hook for predictor tag */
449 sp
->vsetparent
= tif
->tif_tagmethods
.vsetfield
;
450 tif
->tif_tagmethods
.vsetfield
=
451 PredictorVSetField
;/* hook for predictor tag */
452 sp
->printdir
= tif
->tif_tagmethods
.printdir
;
453 tif
->tif_tagmethods
.printdir
=
454 PredictorPrintDir
; /* hook for predictor tag */
456 sp
->setupdecode
= tif
->tif_setupdecode
;
457 tif
->tif_setupdecode
= PredictorSetupDecode
;
458 sp
->setupencode
= tif
->tif_setupencode
;
459 tif
->tif_setupencode
= PredictorSetupEncode
;
461 sp
->predictor
= 1; /* default value */
462 sp
->pfunc
= NULL
; /* no predictor routine */