home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / pdflib / pdflib-4.0.1.sit / pdflib-4.0.1 / tiff / tif_predict.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-04  |  8.3 KB  |  326 lines  |  [TEXT/CWIE]

  1. /*
  2.  * Copyright (c) 1988-1997 Sam Leffler
  3.  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  4.  *
  5.  * Permission to use, copy, modify, distribute, and sell this software and 
  6.  * its documentation for any purpose is hereby granted without fee, provided
  7.  * that (i) the above copyright notices and this permission notice appear in
  8.  * all copies of the software and related documentation, and (ii) the names of
  9.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  10.  * publicity relating to the software without the specific, prior written
  11.  * permission of Sam Leffler and Silicon Graphics.
  12.  * 
  13.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  16.  * 
  17.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. /*
  26.  * TIFF Library.
  27.  *
  28.  * Predictor Tag Support (used by multiple codecs).
  29.  */
  30.  
  31. /* $Id: tif_predict.c,v 1.5 2001/03/21 10:41:18 rjs Exp $ */
  32.  
  33. #include "tiffiop.h"
  34. #include "tif_predict.h"
  35.  
  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    int PredictorDecodeRow(TIFF*, tidata_t, tsize_t, tsample_t);
  43. static    int PredictorDecodeTile(TIFF*, tidata_t, tsize_t, tsample_t);
  44.  
  45. static int
  46. PredictorSetup(TIFF* tif)
  47. {
  48.     TIFFPredictorState* sp = PredictorState(tif);
  49.     TIFFDirectory* td = &tif->tif_dir;
  50.  
  51.     if (sp->predictor == 1)        /* no differencing */
  52.         return (1);
  53.     if (sp->predictor != 2) {
  54.         TIFFError(tif->tif_name, "\"Predictor\" value %d not supported",
  55.             sp->predictor);
  56.         return (0);
  57.     }
  58.     if (td->td_bitspersample != 8 && td->td_bitspersample != 16) {
  59.         TIFFError(tif->tif_name,
  60.     "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
  61.             td->td_bitspersample);
  62.         return (0);
  63.     }
  64.     sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
  65.         td->td_samplesperpixel : 1);
  66.     /*
  67.      * Calculate the scanline/tile-width size in bytes.
  68.      */
  69.     if (isTiled(tif))
  70.         sp->rowsize = TIFFTileRowSize(tif);
  71.     else
  72.         sp->rowsize = TIFFScanlineSize(tif);
  73.     return (1);
  74. }
  75.  
  76. static int
  77. PredictorSetupDecode(TIFF* tif)
  78. {
  79.     TIFFPredictorState* sp = PredictorState(tif);
  80.     TIFFDirectory* td = &tif->tif_dir;
  81.  
  82.     if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
  83.         return (0);
  84.     if (sp->predictor == 2) {
  85.         switch (td->td_bitspersample) {
  86.         case 8:  sp->pfunc = horAcc8; break;
  87.         case 16: sp->pfunc = horAcc16; break;
  88.         }
  89.         /*
  90.          * Override default decoding method with
  91.          * one that does the predictor stuff.
  92.          */
  93.         sp->coderow = tif->tif_decoderow;
  94.         tif->tif_decoderow = PredictorDecodeRow;
  95.         sp->codestrip = tif->tif_decodestrip;
  96.         tif->tif_decodestrip = PredictorDecodeTile;
  97.         sp->codetile = tif->tif_decodetile;
  98.         tif->tif_decodetile = PredictorDecodeTile;
  99.         /*
  100.          * If the data is horizontally differenced
  101.          * 16-bit data that requires byte-swapping,
  102.          * then it must be byte swapped before the
  103.          * accumulation step.  We do this with a
  104.          * special-purpose routine and override the
  105.          * normal post decoding logic that the library
  106.          * setup when the directory was read.
  107.          */
  108.         if (tif->tif_flags&TIFF_SWAB) {
  109.             if (sp->pfunc == horAcc16) {
  110.                 sp->pfunc = swabHorAcc16;
  111.                 tif->tif_postdecode = _TIFFNoPostDecode;
  112.             } /* else handle 32-bit case... */
  113.         }
  114.     }
  115.     return (1);
  116. }
  117.  
  118. #define REPEAT4(n, op)        \
  119.     switch (n) {        \
  120.     default: { int i; for (i = n-4; i > 0; i--) { op; } } \
  121.     case 4:  op;        \
  122.     case 3:  op;        \
  123.     case 2:  op;        \
  124.     case 1:  op;        \
  125.     case 0:  ;            \
  126.     }
  127.  
  128. static void
  129. horAcc8(TIFF* tif, tidata_t cp0, tsize_t cc)
  130. {
  131.     TIFFPredictorState* sp = PredictorState(tif);
  132.     tsize_t stride = sp->stride;
  133.  
  134.     char* cp = (char*) cp0;
  135.     if (cc > stride) {
  136.         cc -= stride;
  137.         /*
  138.          * Pipeline the most common cases.
  139.          */
  140.         if (stride == 3)  {
  141.             u_int cr = cp[0];
  142.             u_int cg = cp[1];
  143.             u_int cb = cp[2];
  144.             do {
  145.                 cc -= 3, cp += 3;
  146.                 cp[0] = (cr += cp[0]);
  147.                 cp[1] = (cg += cp[1]);
  148.                 cp[2] = (cb += cp[2]);
  149.             } while ((int32) cc > 0);
  150.         } else if (stride == 4)  {
  151.             u_int cr = cp[0];
  152.             u_int cg = cp[1];
  153.             u_int cb = cp[2];
  154.             u_int ca = cp[3];
  155.             do {
  156.                 cc -= 4, cp += 4;
  157.                 cp[0] = (cr += cp[0]);
  158.                 cp[1] = (cg += cp[1]);
  159.                 cp[2] = (cb += cp[2]);
  160.                 cp[3] = (ca += cp[3]);
  161.             } while ((int32) cc > 0);
  162.         } else  {
  163.             do {
  164.                 REPEAT4(stride, cp[stride] += *cp; cp++)
  165.                 cc -= stride;
  166.             } while ((int32) cc > 0);
  167.         }
  168.     }
  169. }
  170.  
  171. static void
  172. swabHorAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
  173. {
  174.     TIFFPredictorState* sp = PredictorState(tif);
  175.     tsize_t stride = sp->stride;
  176.     uint16* wp = (uint16*) cp0;
  177.     tsize_t wc = cc / 2;
  178.  
  179.     if (wc > stride) {
  180.         TIFFSwabArrayOfShort(wp, wc);
  181.         wc -= stride;
  182.         do {
  183.             REPEAT4(stride, wp[stride] += wp[0]; wp++)
  184.             wc -= stride;
  185.         } while ((int32) wc > 0);
  186.     }
  187. }
  188.  
  189. static void
  190. horAcc16(TIFF* tif, tidata_t cp0, tsize_t cc)
  191. {
  192.     tsize_t stride = PredictorState(tif)->stride;
  193.     uint16* wp = (uint16*) cp0;
  194.     tsize_t wc = cc / 2;
  195.  
  196.     if (wc > stride) {
  197.         wc -= stride;
  198.         do {
  199.             REPEAT4(stride, wp[stride] += wp[0]; wp++)
  200.             wc -= stride;
  201.         } while ((int32) wc > 0);
  202.     }
  203. }
  204.  
  205. /*
  206.  * Decode a scanline and apply the predictor routine.
  207.  */
  208. static int
  209. PredictorDecodeRow(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
  210. {
  211.     TIFFPredictorState *sp = PredictorState(tif);
  212.  
  213.     if ((*sp->coderow)(tif, op0, occ0, s)) {
  214.         (*sp->pfunc)(tif, op0, occ0);
  215.         return (1);
  216.     } else
  217.         return (0);
  218. }
  219.  
  220. /*
  221.  * Decode a tile/strip and apply the predictor routine.
  222.  * Note that horizontal differencing must be done on a
  223.  * row-by-row basis.  The width of a "row" has already
  224.  * been calculated at pre-decode time according to the
  225.  * strip/tile dimensions.
  226.  */
  227. static int
  228. PredictorDecodeTile(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s)
  229. {
  230.     TIFFPredictorState *sp = PredictorState(tif);
  231.  
  232.     if ((*sp->codetile)(tif, op0, occ0, s)) {
  233.         tsize_t rowsize = sp->rowsize;
  234.         while ((long)occ0 > 0) {
  235.             (*sp->pfunc)(tif, op0, (tsize_t) rowsize);
  236.             occ0 -= rowsize;
  237.             op0 += rowsize;
  238.         }
  239.         return (1);
  240.     } else
  241.         return (0);
  242. }
  243.  
  244. #define    FIELD_PREDICTOR    (FIELD_CODEC+0)        /* XXX */
  245.  
  246. static const TIFFFieldInfo predictFieldInfo[] = {
  247.     { TIFFTAG_PREDICTOR,     1, 1, TIFF_SHORT,    FIELD_PREDICTOR,
  248.       FALSE,    FALSE,    "Predictor" },
  249. };
  250. #define    N(a)    (sizeof (a) / sizeof (a[0]))
  251.  
  252. static int
  253. PredictorVSetField(TIFF* tif, ttag_t tag, va_list ap)
  254. {
  255.     TIFFPredictorState *sp = PredictorState(tif);
  256.  
  257.     switch (tag) {
  258.     case TIFFTAG_PREDICTOR:
  259.         sp->predictor = (uint16) va_arg(ap, int);
  260.         TIFFSetFieldBit(tif, FIELD_PREDICTOR);
  261.         break;
  262.     default:
  263.         return (*sp->vsetparent)(tif, tag, ap);
  264.     }
  265.     tif->tif_flags |= TIFF_DIRTYDIRECT;
  266.     return (1);
  267. }
  268.  
  269. static int
  270. PredictorVGetField(TIFF* tif, ttag_t tag, va_list ap)
  271. {
  272.     TIFFPredictorState *sp = PredictorState(tif);
  273.  
  274.     switch (tag) {
  275.     case TIFFTAG_PREDICTOR:
  276.         *va_arg(ap, uint16*) = sp->predictor;
  277.         break;
  278.     default:
  279.         return (*sp->vgetparent)(tif, tag, ap);
  280.     }
  281.     return (1);
  282. }
  283.  
  284. static void
  285. PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
  286. {
  287.     TIFFPredictorState* sp = PredictorState(tif);
  288.  
  289.     (void) flags;
  290.     if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
  291.         fprintf(fd, "  Predictor: ");
  292.         switch (sp->predictor) {
  293.         case 1: fprintf(fd, "none "); break;
  294.         case 2: fprintf(fd, "horizontal differencing "); break;
  295.         }
  296.         fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
  297.     }
  298.     if (sp->printdir)
  299.         (*sp->printdir)(tif, fd, flags);
  300. }
  301.  
  302. int
  303. TIFFPredictorInit(TIFF* tif)
  304. {
  305.     TIFFPredictorState* sp = PredictorState(tif);
  306.  
  307.     /*
  308.      * Merge codec-specific tag information and
  309.      * override parent get/set field methods.
  310.      */
  311.     _TIFFMergeFieldInfo(tif, predictFieldInfo, N(predictFieldInfo));
  312.     sp->vgetparent = tif->tif_vgetfield;
  313.     tif->tif_vgetfield = PredictorVGetField;/* hook for predictor tag */
  314.     sp->vsetparent = tif->tif_vsetfield;
  315.     tif->tif_vsetfield = PredictorVSetField;/* hook for predictor tag */
  316.     sp->printdir = tif->tif_printdir;
  317.     tif->tif_printdir = PredictorPrintDir;    /* hook for predictor tag */
  318.  
  319.     sp->setupdecode = tif->tif_setupdecode;
  320.     tif->tif_setupdecode = PredictorSetupDecode;
  321.  
  322.     sp->predictor = 1;            /* default value */
  323.     sp->pfunc = NULL;            /* no predictor routine */
  324.     return (1);
  325. }
  326.