home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / tiff / tif_predict.c < prev    next >
C/C++ Source or Header  |  2002-11-10  |  13KB  |  467 lines

  1. /* $Header: /pack/cvsroots/wxwindows/wxWindows/src/tiff/tif_predict.c,v 1.3.4.1 2002/11/10 13:13:57 JS 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. /* Watcom C++ (or its make utility) doesn't like long filenames */
  34. #ifdef __WATCOMC__
  35. #include "tif_pred.h"
  36. #else
  37. #include "tif_predict.h"
  38. #endif
  39.  
  40. #include <assert.h>
  41.  
  42. #define    PredictorState(tif)    ((TIFFPredictorState*) (tif)->tif_data)
  43.  
  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);
  53.  
  54. static int
  55. PredictorSetup(TIFF* tif)
  56. {
  57.     TIFFPredictorState* sp = PredictorState(tif);
  58.     TIFFDirectory* td = &tif->tif_dir;
  59.  
  60.     if (sp->predictor == 1)        /* no differencing */
  61.         return (1);
  62.     if (sp->predictor != 2) {
  63.         TIFFError(tif->tif_name, "\"Predictor\" value %d not supported",
  64.             sp->predictor);
  65.         return (0);
  66.     }
  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);
  71.         return (0);
  72.     }
  73.     sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
  74.         td->td_samplesperpixel : 1);
  75.     /*
  76.      * Calculate the scanline/tile-width size in bytes.
  77.      */
  78.     if (isTiled(tif))
  79.         sp->rowsize = TIFFTileRowSize(tif);
  80.     else
  81.         sp->rowsize = TIFFScanlineSize(tif);
  82.     return (1);
  83. }
  84.  
  85. static int
  86. PredictorSetupDecode(TIFF* tif)
  87. {
  88.     TIFFPredictorState* sp = PredictorState(tif);
  89.     TIFFDirectory* td = &tif->tif_dir;
  90.  
  91.     if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
  92.         return (0);
  93.     if (sp->predictor == 2) {
  94.         switch (td->td_bitspersample) {
  95.         case 8:  sp->pfunc = horAcc8; break;
  96.         case 16: sp->pfunc = horAcc16; break;
  97.         }
  98.         /*
  99.          * Override default decoding method with
  100.          * one that does the predictor stuff.
  101.          */
  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;
  108.         /*
  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.
  116.          */
  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... */
  122.         }
  123.     }
  124.     return (1);
  125. }
  126.  
  127. static int
  128. PredictorSetupEncode(TIFF* tif)
  129. {
  130.     TIFFPredictorState* sp = PredictorState(tif);
  131.     TIFFDirectory* td = &tif->tif_dir;
  132.  
  133.     if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
  134.         return (0);
  135.     if (sp->predictor == 2) {
  136.         switch (td->td_bitspersample) {
  137.         case 8:  sp->pfunc = horDiff8; break;
  138.         case 16: sp->pfunc = horDiff16; break;
  139.         }
  140.         /*
  141.          * Override default encoding method with
  142.          * one that does the predictor stuff.
  143.          */
  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;
  150.     }
  151.     return (1);
  152. }
  153.  
  154. #define REPEAT4(n, op)        \
  155.     switch (n) {        \
  156.     default: { int i; for (i = n-4; i > 0; i--) { op; } } \
  157.     case 4:  op;        \
  158.     case 3:  op;        \
  159.     case 2:  op;        \
  160.     case 1:  op;        \
  161.     case 0:  ;            \
  162.     }
  163.  
  164. static void
  165. horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc)
  166. {
  167.     TIFFPredictorState* sp = PredictorState(tif);
  168.     u_int stride = sp->stride;
  169.  
  170.     char* cp = (char*) cp0;
  171.     if (cc > stride) {
  172.         cc -= stride;
  173.         /*
  174.          * Pipeline the most common cases.
  175.          */
  176.         if (stride == 3)  {
  177.             u_int cr = cp[0];
  178.             u_int cg = cp[1];
  179.             u_int cb = cp[2];
  180.             do {
  181.                 cc -= 3, cp += 3;
  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)  {
  187.             u_int cr = cp[0];
  188.             u_int cg = cp[1];
  189.             u_int cb = cp[2];
  190.             u_int ca = cp[3];
  191.             do {
  192.                 cc -= 4, cp += 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);
  198.         } else  {
  199.             do {
  200.                 REPEAT4(stride, cp[stride] += *cp; cp++)
  201.                 cc -= stride;
  202.             } while ((int32) cc > 0);
  203.         }
  204.     }
  205. }
  206.  
  207. static void
  208. swabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
  209. {
  210.     TIFFPredictorState* sp = PredictorState(tif);
  211.     u_int stride = sp->stride;
  212.     uint16* wp = (uint16*) cp0;
  213.     tsize_t wc = cc / 2;
  214.  
  215.     if (wc > stride) {
  216.         TIFFSwabArrayOfShort(wp, wc);
  217.         wc -= stride;
  218.         do {
  219.             REPEAT4(stride, wp[stride] += wp[0]; wp++)
  220.             wc -= stride;
  221.         } while ((int32) wc > 0);
  222.     }
  223. }
  224.  
  225. static void
  226. horAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
  227. {
  228.     u_int stride = PredictorState(tif)->stride;
  229.     uint16* wp = (uint16*) cp0;
  230.     tsize_t wc = cc / 2;
  231.  
  232.     if (wc > stride) {
  233.         wc -= stride;
  234.         do {
  235.             REPEAT4(stride, wp[stride] += wp[0]; wp++)
  236.             wc -= stride;
  237.         } while ((int32) wc > 0);
  238.     }
  239. }
  240.  
  241. /*
  242.  * Decode a scanline and apply the predictor routine.
  243.  */
  244. static int
  245. PredictorDecodeRow(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
  246. {
  247.     TIFFPredictorState *sp = PredictorState(tif);
  248.  
  249.     assert(sp != NULL);
  250.     assert(sp->coderow != NULL);
  251.     assert(sp->pfunc != NULL);
  252.     if ((*sp->coderow)(tif, op0, occ0, s)) {
  253.         (*sp->pfunc)(tif, op0, occ0);
  254.         return (1);
  255.     } else
  256.         return (0);
  257. }
  258.  
  259. /*
  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.
  265.  */
  266. static int
  267. PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
  268. {
  269.     TIFFPredictorState *sp = PredictorState(tif);
  270.  
  271.     assert(sp != NULL);
  272.     assert(sp->codetile != NULL);
  273.     if ((*sp->codetile)(tif, op0, occ0, s)) {
  274.         tsize_t rowsize = sp->rowsize;
  275.         assert(rowsize > 0);
  276.         assert(sp->pfunc != NULL);
  277.         while ((long)occ0 > 0) {
  278.             (*sp->pfunc)(tif, op0, (tsize_t) rowsize);
  279.             occ0 -= rowsize;
  280.             op0 += rowsize;
  281.         }
  282.         return (1);
  283.     } else
  284.         return (0);
  285. }
  286.  
  287. static void
  288. horDiff8(TIFF* tif, tidata_t cp0, tsize_t cc)
  289. {
  290.     TIFFPredictorState* sp = PredictorState(tif);
  291.     u_int stride = sp->stride;
  292.     char* cp = (char*) cp0;
  293.  
  294.     if (cc > stride) {
  295.         cc -= stride;
  296.         /*
  297.          * Pipeline the most common cases.
  298.          */
  299.         if (stride == 3) {
  300.             int r1, g1, b1;
  301.             int r2 = cp[0];
  302.             int g2 = cp[1];
  303.             int b2 = cp[2];
  304.             do {
  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;
  308.                 cp += 3;
  309.             } while ((int32)(cc -= 3) > 0);
  310.         } else if (stride == 4) {
  311.             int r1, g1, b1, a1;
  312.             int r2 = cp[0];
  313.             int g2 = cp[1];
  314.             int b2 = cp[2];
  315.             int a2 = cp[3];
  316.             do {
  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;
  321.                 cp += 4;
  322.             } while ((int32)(cc -= 4) > 0);
  323.         } else {
  324.             cp += cc - 1;
  325.             do {
  326.                 REPEAT4(stride, cp[stride] -= cp[0]; cp--)
  327.             } while ((int32)(cc -= stride) > 0);
  328.         }
  329.     }
  330. }
  331.  
  332. static void
  333. horDiff16(TIFF* tif, tidata_t cp0, tsize_t cc)
  334. {
  335.     TIFFPredictorState* sp = PredictorState(tif);
  336.     u_int stride = sp->stride;
  337.     int16 *wp = (int16*) cp0;
  338.     tsize_t wc = cc/2;
  339.  
  340.     if (wc > stride) {
  341.         wc -= stride;
  342.         wp += wc - 1;
  343.         do {
  344.             REPEAT4(stride, wp[stride] -= wp[0]; wp--)
  345.             wc -= stride;
  346.         } while ((int32) wc > 0);
  347.     }
  348. }
  349.  
  350. static int
  351. PredictorEncodeRow(TIFF* tif, tidata_t bp, tsize_t cc, tsample_t s)
  352. {
  353.     TIFFPredictorState *sp = PredictorState(tif);
  354.  
  355.     assert(sp != NULL);
  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));
  361. }
  362.  
  363. static int
  364. PredictorEncodeTile(TIFF* tif, tidata_t bp0, tsize_t cc0, tsample_t s)
  365. {
  366.     TIFFPredictorState *sp = PredictorState(tif);
  367.     tsize_t cc = cc0, rowsize;
  368.     u_char* bp = bp0;
  369.  
  370.     assert(sp != NULL);
  371.     assert(sp->pfunc != NULL);
  372.     assert(sp->codetile != NULL);
  373.     rowsize = sp->rowsize;
  374.     assert(rowsize > 0);
  375.     while ((long)cc > 0) {
  376.         (*sp->pfunc)(tif, bp, (tsize_t) rowsize);
  377.         cc -= rowsize;
  378.         bp += rowsize;
  379.     }
  380.     return ((*sp->codetile)(tif, bp0, cc0, s));
  381. }
  382.  
  383. #define    FIELD_PREDICTOR    (FIELD_CODEC+0)        /* XXX */
  384.  
  385. static const TIFFFieldInfo predictFieldInfo[] = {
  386.     { TIFFTAG_PREDICTOR,     1, 1, TIFF_SHORT,    FIELD_PREDICTOR,
  387.       FALSE,    FALSE,    "Predictor" },
  388. };
  389. #define    N(a)    (sizeof (a) / sizeof (a[0]))
  390.  
  391. static int
  392. PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap)
  393. {
  394.     TIFFPredictorState *sp = PredictorState(tif);
  395.  
  396.     switch (tag) {
  397.     case TIFFTAG_PREDICTOR:
  398.         sp->predictor = (uint16) va_arg(ap, int);
  399.         TIFFSetFieldBit(tif, FIELD_PREDICTOR);
  400.         break;
  401.     default:
  402.         return (*sp->vsetparent)(tif, tag, ap);
  403.     }
  404.     tif->tif_flags |= TIFF_DIRTYDIRECT;
  405.     return (1);
  406. }
  407.  
  408. static int
  409. PredictorVGetField(TIFF* tif, ttag_t tag, va_list ap)
  410. {
  411.     TIFFPredictorState *sp = PredictorState(tif);
  412.  
  413.     switch (tag) {
  414.     case TIFFTAG_PREDICTOR:
  415.         *va_arg(ap, uint16*) = sp->predictor;
  416.         break;
  417.     default:
  418.         return (*sp->vgetparent)(tif, tag, ap);
  419.     }
  420.     return (1);
  421. }
  422.  
  423. static void LINKAGEMODE
  424. PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
  425. {
  426.     TIFFPredictorState* sp = PredictorState(tif);
  427.  
  428.     (void) flags;
  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;
  434.         }
  435.         fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
  436.     }
  437.     if (sp->printdir)
  438.         (*sp->printdir)(tif, fd, flags);
  439. }
  440.  
  441. int
  442. TIFFPredictorInit(TIFF* tif)
  443. {
  444.     TIFFPredictorState* sp = PredictorState(tif);
  445.  
  446.     /*
  447.      * Merge codec-specific tag information and
  448.      * override parent get/set field methods.
  449.      */
  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 */
  457.  
  458.     sp->setupdecode = tif->tif_setupdecode;
  459.     tif->tif_setupdecode = PredictorSetupDecode;
  460.     sp->setupencode = tif->tif_setupencode;
  461.     tif->tif_setupencode = PredictorSetupEncode;
  462.  
  463.     sp->predictor = 1;            /* default value */
  464.     sp->pfunc = NULL;            /* no predictor routine */
  465.     return (1);
  466. }
  467.