Move the sources to trunk
[opencv] / otherlibs / _graphics / src / libtiff / tif_predict.c
1 /* $Id: tif_predict.c,v 1.1 2005/06/17 13:54:52 vp153 Exp $ */
2
3 /*
4  * Copyright (c) 1988-1997 Sam Leffler
5  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6  *
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.
14  * 
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.  
18  * 
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 
24  * OF THIS SOFTWARE.
25  */
26
27 /*
28  * TIFF Library.
29  *
30  * Predictor Tag Support (used by multiple codecs).
31  */
32 #include "tiffiop.h"
33 #include "tif_predict.h"
34
35 #define PredictorState(tif)     ((TIFFPredictorState*) (tif)->tif_data)
36
37 static  void horAcc8(TIFF*, tidata_t, tsize_t);
38 static  void horAcc16(TIFF*, tidata_t, tsize_t);
39 static  void swabHorAcc16(TIFF*, tidata_t, tsize_t);
40 static  void horDiff8(TIFF*, tidata_t, tsize_t);
41 static  void horDiff16(TIFF*, tidata_t, tsize_t);
42 static  int PredictorDecodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
43 static  int PredictorDecodeTile(TIFF*, tidata_t, tsize_t, tsample_t);
44 static  int PredictorEncodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
45 static  int PredictorEncodeTile(TIFF*, tidata_t, tsize_t, tsample_t);
46
47 static int
48 PredictorSetup(TIFF* tif)
49 {
50         TIFFPredictorState* sp = PredictorState(tif);
51         TIFFDirectory* td = &tif->tif_dir;
52
53         if (sp->predictor == 1)         /* no differencing */
54                 return (1);
55         if (sp->predictor != 2) {
56                 TIFFError(tif->tif_name, "\"Predictor\" value %d not supported",
57                     sp->predictor);
58                 return (0);
59         }
60         if (td->td_bitspersample != 8 && td->td_bitspersample != 16) {
61                 TIFFError(tif->tif_name,
62     "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
63                     td->td_bitspersample);
64                 return (0);
65         }
66         sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
67             td->td_samplesperpixel : 1);
68         /*
69          * Calculate the scanline/tile-width size in bytes.
70          */
71         if (isTiled(tif))
72                 sp->rowsize = TIFFTileRowSize(tif);
73         else
74                 sp->rowsize = TIFFScanlineSize(tif);
75         return (1);
76 }
77
78 static int
79 PredictorSetupDecode(TIFF* tif)
80 {
81         TIFFPredictorState* sp = PredictorState(tif);
82         TIFFDirectory* td = &tif->tif_dir;
83
84         if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
85                 return (0);
86         if (sp->predictor == 2) {
87                 switch (td->td_bitspersample) {
88                 case 8:  sp->pfunc = horAcc8; break;
89                 case 16: sp->pfunc = horAcc16; break;
90                 }
91                 /*
92                  * Override default decoding method with
93                  * one that does the predictor stuff.
94                  */
95                 sp->coderow = tif->tif_decoderow;
96                 tif->tif_decoderow = PredictorDecodeRow;
97                 sp->codestrip = tif->tif_decodestrip;
98                 tif->tif_decodestrip = PredictorDecodeTile;
99                 sp->codetile = tif->tif_decodetile;
100                 tif->tif_decodetile = PredictorDecodeTile;
101                 /*
102                  * If the data is horizontally differenced
103                  * 16-bit data that requires byte-swapping,
104                  * then it must be byte swapped before the
105                  * accumulation step.  We do this with a
106                  * special-purpose routine and override the
107                  * normal post decoding logic that the library
108                  * setup when the directory was read.
109                  */
110                 if (tif->tif_flags&TIFF_SWAB) {
111                         if (sp->pfunc == horAcc16) {
112                                 sp->pfunc = swabHorAcc16;
113                                 tif->tif_postdecode = _TIFFNoPostDecode;
114                         } /* else handle 32-bit case... */
115                 }
116         }
117         return (1);
118 }
119
120 static int
121 PredictorSetupEncode(TIFF* tif)
122 {
123         TIFFPredictorState* sp = PredictorState(tif);
124         TIFFDirectory* td = &tif->tif_dir;
125
126         if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
127                 return (0);
128         if (sp->predictor == 2) {
129                 switch (td->td_bitspersample) {
130                 case 8:  sp->pfunc = horDiff8; break;
131                 case 16: sp->pfunc = horDiff16; break;
132                 }
133                 /*
134                  * Override default encoding method with
135                  * one that does the predictor stuff.
136                  */
137                 sp->coderow = tif->tif_encoderow;
138                 tif->tif_encoderow = PredictorEncodeRow;
139                 sp->codestrip = tif->tif_encodestrip;
140                 tif->tif_encodestrip = PredictorEncodeTile;
141                 sp->codetile = tif->tif_encodetile;
142                 tif->tif_encodetile = PredictorEncodeTile;
143         }
144         return (1);
145 }
146
147 #define REPEAT4(n, op)          \
148     switch (n) {                \
149     default: { int i; for (i = n-4; i > 0; i--) { op; } } \
150     case 4:  op;                \
151     case 3:  op;                \
152     case 2:  op;                \
153     case 1:  op;                \
154     case 0:  ;                  \
155     }
156
157 static void
158 horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc)
159 {
160         TIFFPredictorState* sp = PredictorState(tif);
161         tsize_t stride = sp->stride;
162
163         char* cp = (char*) cp0;
164         if (cc > stride) {
165                 cc -= stride;
166                 /*
167                  * Pipeline the most common cases.
168                  */
169                 if (stride == 3)  {
170                         unsigned int cr = cp[0];
171                         unsigned int cg = cp[1];
172                         unsigned int cb = cp[2];
173                         do {
174                                 cc -= 3, cp += 3;
175                                 cp[0] = (char) (cr += cp[0]);
176                                 cp[1] = (char) (cg += cp[1]);
177                                 cp[2] = (char) (cb += cp[2]);
178                         } while ((int32) cc > 0);
179                 } else if (stride == 4)  {
180                         unsigned int cr = cp[0];
181                         unsigned int cg = cp[1];
182                         unsigned int cb = cp[2];
183                         unsigned int ca = cp[3];
184                         do {
185                                 cc -= 4, cp += 4;
186                                 cp[0] = (char) (cr += cp[0]);
187                                 cp[1] = (char) (cg += cp[1]);
188                                 cp[2] = (char) (cb += cp[2]);
189                                 cp[3] = (char) (ca += cp[3]);
190                         } while ((int32) cc > 0);
191                 } else  {
192                         do {
193                                 REPEAT4(stride, cp[stride] = (char) (cp[stride] + *cp); cp++)
194                                 cc -= stride;
195                         } while ((int32) cc > 0);
196                 }
197         }
198 }
199
200 static void
201 swabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
202 {
203         TIFFPredictorState* sp = PredictorState(tif);
204         tsize_t stride = sp->stride;
205         uint16* wp = (uint16*) cp0;
206         tsize_t wc = cc / 2;
207
208         if (wc > stride) {
209                 TIFFSwabArrayOfShort(wp, wc);
210                 wc -= stride;
211                 do {
212                         REPEAT4(stride, wp[stride] += wp[0]; wp++)
213                         wc -= stride;
214                 } while ((int32) wc > 0);
215         }
216 }
217
218 static void
219 horAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
220 {
221         tsize_t stride = PredictorState(tif)->stride;
222         uint16* wp = (uint16*) cp0;
223         tsize_t wc = cc / 2;
224
225         if (wc > stride) {
226                 wc -= stride;
227                 do {
228                         REPEAT4(stride, wp[stride] += wp[0]; wp++)
229                         wc -= stride;
230                 } while ((int32) wc > 0);
231         }
232 }
233
234 /*
235  * Decode a scanline and apply the predictor routine.
236  */
237 static int
238 PredictorDecodeRow(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
239 {
240         TIFFPredictorState *sp = PredictorState(tif);
241
242         assert(sp != NULL);
243         assert(sp->coderow != NULL);
244         assert(sp->pfunc != NULL);
245         if ((*sp->coderow)(tif, op0, occ0, s)) {
246                 (*sp->pfunc)(tif, op0, occ0);
247                 return (1);
248         } else
249                 return (0);
250 }
251
252 /*
253  * Decode a tile/strip and apply the predictor routine.
254  * Note that horizontal differencing must be done on a
255  * row-by-row basis.  The width of a "row" has already
256  * been calculated at pre-decode time according to the
257  * strip/tile dimensions.
258  */
259 static int
260 PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
261 {
262         TIFFPredictorState *sp = PredictorState(tif);
263
264         assert(sp != NULL);
265         assert(sp->codetile != NULL);
266         if ((*sp->codetile)(tif, op0, occ0, s)) {
267                 tsize_t rowsize = sp->rowsize;
268                 assert(rowsize > 0);
269                 assert(sp->pfunc != NULL);
270                 while ((long)occ0 > 0) {
271                         (*sp->pfunc)(tif, op0, (tsize_t) rowsize);
272                         occ0 -= rowsize;
273                         op0 += rowsize;
274                 }
275                 return (1);
276         } else
277                 return (0);
278 }
279
280 static void
281 horDiff8(TIFF* tif, tidata_t cp0, tsize_t cc)
282 {
283         TIFFPredictorState* sp = PredictorState(tif);
284         tsize_t stride = sp->stride;
285         char* cp = (char*) cp0;
286
287         if (cc > stride) {
288                 cc -= stride;
289                 /*
290                  * Pipeline the most common cases.
291                  */
292                 if (stride == 3) {
293                         int r1, g1, b1;
294                         int r2 = cp[0];
295                         int g2 = cp[1];
296                         int b2 = cp[2];
297                         do {
298                                 r1 = cp[3]; cp[3] = r1-r2; r2 = r1;
299                                 g1 = cp[4]; cp[4] = g1-g2; g2 = g1;
300                                 b1 = cp[5]; cp[5] = b1-b2; b2 = b1;
301                                 cp += 3;
302                         } while ((int32)(cc -= 3) > 0);
303                 } else if (stride == 4) {
304                         int r1, g1, b1, a1;
305                         int r2 = cp[0];
306                         int g2 = cp[1];
307                         int b2 = cp[2];
308                         int a2 = cp[3];
309                         do {
310                                 r1 = cp[4]; cp[4] = r1-r2; r2 = r1;
311                                 g1 = cp[5]; cp[5] = g1-g2; g2 = g1;
312                                 b1 = cp[6]; cp[6] = b1-b2; b2 = b1;
313                                 a1 = cp[7]; cp[7] = a1-a2; a2 = a1;
314                                 cp += 4;
315                         } while ((int32)(cc -= 4) > 0);
316                 } else {
317                         cp += cc - 1;
318                         do {
319                                 REPEAT4(stride, cp[stride] -= cp[0]; cp--)
320                         } while ((int32)(cc -= stride) > 0);
321                 }
322         }
323 }
324
325 static void
326 horDiff16(TIFF* tif, tidata_t cp0, tsize_t cc)
327 {
328         TIFFPredictorState* sp = PredictorState(tif);
329         tsize_t stride = sp->stride;
330         int16 *wp = (int16*) cp0;
331         tsize_t wc = cc/2;
332
333         if (wc > stride) {
334                 wc -= stride;
335                 wp += wc - 1;
336                 do {
337                         REPEAT4(stride, wp[stride] -= wp[0]; wp--)
338                         wc -= stride;
339                 } while ((int32) wc > 0);
340         }
341 }
342
343 static int
344 PredictorEncodeRow(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
345 {
346         TIFFPredictorState *sp = PredictorState(tif);
347
348         assert(sp != NULL);
349         assert(sp->pfunc != NULL);
350         assert(sp->coderow != NULL);
351 /* XXX horizontal differencing alters user's data XXX */
352         (*sp->pfunc)(tif, bp, cc);
353         return ((*sp->coderow)(tif, bp, cc, s));
354 }
355
356 static int
357 PredictorEncodeTile(TIFF* tif, tidata_t bp0, tsize_t cc0, tsample_t s)
358 {
359         TIFFPredictorState *sp = PredictorState(tif);
360         tsize_t cc = cc0, rowsize;
361         unsigned char* bp = bp0;
362
363         assert(sp != NULL);
364         assert(sp->pfunc != NULL);
365         assert(sp->codetile != NULL);
366         rowsize = sp->rowsize;
367         assert(rowsize > 0);
368         while ((long)cc > 0) {
369                 (*sp->pfunc)(tif, bp, (tsize_t) rowsize);
370                 cc -= rowsize;
371                 bp += rowsize;
372         }
373         return ((*sp->codetile)(tif, bp0, cc0, s));
374 }
375
376 #define FIELD_PREDICTOR (FIELD_CODEC+0)         /* XXX */
377
378 static const TIFFFieldInfo predictFieldInfo[] = {
379     { TIFFTAG_PREDICTOR,         1, 1, TIFF_SHORT,      FIELD_PREDICTOR,
380       FALSE,    FALSE,  "Predictor" },
381 };
382 #define N(a)    (sizeof (a) / sizeof (a[0]))
383
384 static int
385 PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap)
386 {
387         TIFFPredictorState *sp = PredictorState(tif);
388
389         switch (tag) {
390         case TIFFTAG_PREDICTOR:
391                 sp->predictor = (uint16) va_arg(ap, int);
392                 TIFFSetFieldBit(tif, FIELD_PREDICTOR);
393                 break;
394         default:
395                 return (*sp->vsetparent)(tif, tag, ap);
396         }
397         tif->tif_flags |= TIFF_DIRTYDIRECT;
398         return (1);
399 }
400
401 static int
402 PredictorVGetField(TIFF* tif, ttag_t tag, va_list ap)
403 {
404         TIFFPredictorState *sp = PredictorState(tif);
405
406         switch (tag) {
407         case TIFFTAG_PREDICTOR:
408                 *va_arg(ap, uint16*) = sp->predictor;
409                 break;
410         default:
411                 return (*sp->vgetparent)(tif, tag, ap);
412         }
413         return (1);
414 }
415
416 static void
417 PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
418 {
419         TIFFPredictorState* sp = PredictorState(tif);
420
421         (void) flags;
422         if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
423                 fprintf(fd, "  Predictor: ");
424                 switch (sp->predictor) {
425                 case 1: fprintf(fd, "none "); break;
426                 case 2: fprintf(fd, "horizontal differencing "); break;
427                 }
428                 fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
429         }
430         if (sp->printdir)
431                 (*sp->printdir)(tif, fd, flags);
432 }
433
434 int
435 TIFFPredictorInit(TIFF* tif)
436 {
437         TIFFPredictorState* sp = PredictorState(tif);
438
439         /*
440          * Merge codec-specific tag information and
441          * override parent get/set field methods.
442          */
443         _TIFFMergeFieldInfo(tif, predictFieldInfo, N(predictFieldInfo));
444         sp->vgetparent = tif->tif_tagmethods.vgetfield;
445         tif->tif_tagmethods.vgetfield =
446             PredictorVGetField;/* hook for predictor tag */
447         sp->vsetparent = tif->tif_tagmethods.vsetfield;
448         tif->tif_tagmethods.vsetfield =
449             PredictorVSetField;/* hook for predictor tag */
450         sp->printdir = tif->tif_tagmethods.printdir;
451         tif->tif_tagmethods.printdir =
452             PredictorPrintDir;  /* hook for predictor tag */
453
454         sp->setupdecode = tif->tif_setupdecode;
455         tif->tif_setupdecode = PredictorSetupDecode;
456         sp->setupencode = tif->tif_setupencode;
457         tif->tif_setupencode = PredictorSetupEncode;
458
459         sp->predictor = 1;                      /* default value */
460         sp->pfunc = NULL;                       /* no predictor routine */
461         return (1);
462 }
463
464 /* vim: set ts=8 sts=8 sw=8 noet: */