home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xloadimg.zip / xloadimage.4.1 / tiff / tif_packbits.c < prev    next >
C/C++ Source or Header  |  1993-10-21  |  7KB  |  273 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_packbits.c,v 1.23 92/03/30 18:29:40 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * TIFF Library.
  31.  *
  32.  * PackBits Compression Algorithm Support
  33.  */
  34. #include "tiffioP.h"
  35. #include <stdio.h>
  36. #include <assert.h>
  37.  
  38. #if USE_PROTOTYPES
  39. static    int PackBitsPreEncode(TIFF *);
  40. static    int PackBitsEncode(TIFF *, u_char *, int, u_int);
  41. static    int PackBitsEncodeChunk(TIFF *, u_char *, int, u_int);
  42. static    int PackBitsDecode(TIFF *, u_char *, int, u_int);
  43. #else
  44. static    int PackBitsPreEncode();
  45. static    int PackBitsEncode(), PackBitsEncodeChunk();
  46. static    int PackBitsDecode();
  47. #endif
  48.  
  49. TIFFInitPackBits(tif)
  50.     TIFF *tif;
  51. {
  52.     tif->tif_decoderow = PackBitsDecode;
  53.     tif->tif_decodestrip = PackBitsDecode;
  54.     tif->tif_decodetile = PackBitsDecode;
  55.     tif->tif_preencode = PackBitsPreEncode;
  56.     tif->tif_encoderow = PackBitsEncode;
  57.     tif->tif_encodestrip = PackBitsEncodeChunk;
  58.     tif->tif_encodetile = PackBitsEncodeChunk;
  59.     return (1);
  60. }
  61.  
  62. static int
  63. PackBitsPreEncode(tif)
  64.     TIFF *tif;
  65. {
  66.     /*
  67.      * Calculate the scanline/tile-width size in bytes.
  68.      */
  69.     if (isTiled(tif))
  70.         tif->tif_data = (char *) TIFFTileRowSize(tif);
  71.     else
  72.         tif->tif_data = (char *) TIFFScanlineSize(tif);
  73.     return (1);
  74. }
  75.  
  76. /*
  77.  * Encode a rectangular chunk of pixels.  We break it up
  78.  * into row-sized pieces to insure that encoded runs do
  79.  * not span rows.  Otherwise, there can be problems with
  80.  * the decoder if data is read, for example, by scanlines
  81.  * when it was encoded by strips.
  82.  */
  83. static int
  84. PackBitsEncodeChunk(tif, bp, cc, s)
  85.     TIFF *tif;
  86.     u_char *bp;
  87.     int cc;
  88.     u_int s;
  89. {
  90.     int rowsize = (int) tif->tif_data;
  91.  
  92.     assert(rowsize > 0);
  93.     while (cc > 0) {
  94.         if (PackBitsEncode(tif, bp, rowsize, s) < 0)
  95.             return (-1);
  96.         bp += rowsize;
  97.         cc -= rowsize;
  98.     }
  99.     return (1);
  100. }
  101.  
  102. /*
  103.  * Encode a run of pixels.
  104.  */
  105. static int
  106. PackBitsEncode(tif, bp, cc, s)
  107.     TIFF *tif;
  108.     u_char *bp;
  109.     register int cc;
  110.     u_int s;
  111. {
  112.     register char *op, *lastliteral;
  113.     register int n, b;
  114.     enum { BASE, LITERAL, RUN, LITERAL_RUN } state;
  115.     char *ep;
  116.     int slop;
  117.  
  118.     op = tif->tif_rawcp;
  119.     ep = tif->tif_rawdata + tif->tif_rawdatasize;
  120.     state = BASE;
  121.     lastliteral = 0;
  122.     while (cc > 0) {
  123.         /*
  124.          * Find the longest string of identical bytes.
  125.          */
  126.         b = *bp++, cc--, n = 1;
  127.         for (; cc > 0 && b == *bp; cc--, bp++)
  128.             n++;
  129.     again:
  130.         if (op + 2 >= ep) {        /* insure space for new data */
  131.             /*
  132.              * Be careful about writing the last
  133.              * literal.  Must write up to that point
  134.              * and then copy the remainder to the
  135.              * front of the buffer.
  136.              */
  137.             if (state == LITERAL || state == LITERAL_RUN) {
  138.                 slop = op - lastliteral;
  139.                 tif->tif_rawcc += lastliteral - tif->tif_rawcp;
  140.                 if (!TIFFFlushData1(tif))
  141.                     return (-1);
  142.                 op = tif->tif_rawcp;
  143.                 for (; slop-- > 0; *op++ = *lastliteral++)
  144.                     ;
  145.                 lastliteral = tif->tif_rawcp;
  146.             } else {
  147.                 tif->tif_rawcc += op - tif->tif_rawcp;
  148.                 if (!TIFFFlushData1(tif))
  149.                     return (-1);
  150.                 op = tif->tif_rawcp;
  151.             }
  152.         }
  153.         switch (state) {
  154.         case BASE:        /* initial state, set run/literal */
  155.             if (n > 1) {
  156.                 state = RUN;
  157.                 if (n > 128) {
  158.                     *op++ = -127;
  159.                     *op++ = b;
  160.                     n -= 128;
  161.                     goto again;
  162.                 }
  163.                 *op++ = -(n-1);
  164.                 *op++ = b;
  165.             } else {
  166.                 lastliteral = op;
  167.                 *op++ = 0;
  168.                 *op++ = b;
  169.                 state = LITERAL;
  170.             }
  171.             break;
  172.         case LITERAL:        /* last object was literal string */
  173.             if (n > 1) {
  174.                 state = LITERAL_RUN;
  175.                 if (n > 128) {
  176.                     *op++ = -127;
  177.                     *op++ = b;
  178.                     n -= 128;
  179.                     goto again;
  180.                 }
  181.                 *op++ = -(n-1);        /* encode run */
  182.                 *op++ = b;
  183.             } else {            /* extend literal */
  184.                 if (++(*lastliteral) == 127)
  185.                     state = BASE;
  186.                 *op++ = b;
  187.             }
  188.             break;
  189.         case RUN:        /* last object was run */
  190.             if (n > 1) {
  191.                 if (n > 128) {
  192.                     *op++ = -127;
  193.                     *op++ = b;
  194.                     n -= 128;
  195.                     goto again;
  196.                 }
  197.                 *op++ = -(n-1);
  198.                 *op++ = b;
  199.             } else {
  200.                 lastliteral = op;
  201.                 *op++ = 0;
  202.                 *op++ = b;
  203.                 state = LITERAL;
  204.             }
  205.             break;
  206.         case LITERAL_RUN:    /* literal followed by a run */
  207.             /*
  208.              * Check to see if previous run should
  209.              * be converted to a literal, in which
  210.              * case we convert literal-run-literal
  211.              * to a single literal.
  212.              */
  213.             if (n == 1 && op[-2] == (char)-1 &&
  214.                 *lastliteral < 126) {
  215.                 state = (((*lastliteral) += 2) == 127 ?
  216.                     BASE : LITERAL);
  217.                 op[-2] = op[-1];    /* replicate */
  218.             } else
  219.                 state = RUN;
  220.             goto again;
  221.         }
  222.     }
  223.     tif->tif_rawcc += op - tif->tif_rawcp;
  224.     tif->tif_rawcp = op;
  225.     return (1);
  226. }
  227.  
  228. static int
  229. PackBitsDecode(tif, op, occ, s)
  230.     TIFF *tif;
  231.     register u_char *op;
  232.     register int occ;
  233.     u_int s;
  234. {
  235.     register char *bp;
  236.     register int n, b;
  237.     register int cc;
  238.  
  239.     bp = tif->tif_rawcp; cc = tif->tif_rawcc;
  240.     while (cc > 0 && occ > 0) {
  241.         n = (int) *bp++;
  242.         /*
  243.          * Watch out for compilers that
  244.          * don't sign extend chars...
  245.          */
  246.         if (n >= 128)
  247.             n -= 256;
  248.         if (n < 0) {        /* replicate next byte -n+1 times */
  249.             cc--;
  250.             if (n == -128)    /* nop */
  251.                 continue;
  252.             n = -n + 1;
  253.             occ -= n;
  254.             for (b = *bp++; n-- > 0;)
  255.                 *op++ = b;
  256.         } else {        /* copy next n+1 bytes literally */
  257.             bcopy(bp, op, ++n);
  258.             op += n; occ -= n;
  259.             bp += n; cc -= n;
  260.         }
  261.     }
  262.     tif->tif_rawcp = bp;
  263.     tif->tif_rawcc = cc;
  264.     if (occ > 0) {
  265.         TIFFError(tif->tif_name,
  266.             "PackBitsDecode: Not enough data for scanline %d",
  267.             tif->tif_row);
  268.         return (0);
  269.     }
  270.     /* check for buffer overruns? */
  271.     return (1);
  272. }
  273.