home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsf / libtiff / c / tif_predic < prev    next >
Encoding:
Text File  |  1995-10-12  |  11.8 KB  |  469 lines

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