home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / grfx_snd / tifflib / source / tif_thun.c < prev    next >
C/C++ Source or Header  |  1993-01-10  |  5KB  |  147 lines

  1. #pragma warn -use
  2. static char     *sccsid = "@(#)TIFF/tif_thunder.c 1.11, Copyright (c) Sam Leffler, Dieter Linde, "__DATE__;
  3. #pragma warn .use
  4. /*
  5.  * Copyright (c) 1988, 1990 by Sam Leffler, Oct 8 1990
  6.  * All rights reserved.
  7.  *
  8.  * This file is provided for unrestricted use provided that this legend is included on all tape media and as a part of the
  9.  * software program in whole or part.  Users may copy, modify or distribute this file at will.
  10.  *
  11.  * TIFF Library.
  12.  *
  13.  * ThunderScan 4-bit Compression Algorithm Support
  14.  */
  15. #include "tiffio.h"
  16.  
  17. /*
  18.  * ThunderScan uses an encoding scheme designed for 4-bit pixel values.  Data is encoded in bytes, with
  19.  * each byte split into a 2-bit code word and a 6-bit data value.  The encoding gives raw data, runs of
  20.  * pixels, or pixel values encoded as a delta from the previous pixel value.  For the latter, either 2-bit
  21.  * or 3-bit delta values are used, with the deltas packed into a single byte.
  22.  */
  23. #define THUNDER_DATA        0x3    /* mask for 6-bit data */
  24. #define THUNDER_CODE            0xc0    /* mask for 2-bit code word */
  25. /*** code values ***/
  26. #define THUNDER_RUN             0x00    /* run of pixels w/ encoded count */
  27. #define THUNDER_2BITDELTAS      0x40    /* 3 pixels w/ encoded 2-bit deltas */
  28. #define     DELTA2_SKIP         2       /* skip code for 2-bit deltas */
  29. #define THUNDER_3BITDELTAS      0x80    /* 2 pixels w/ encoded 3-bit deltas */
  30. #define     DELTA3_SKIP         4       /* skip code for 3-bit deltas */
  31. #define THUNDER_RAW             0xc0    /* raw data encoded */
  32.  
  33. #define SETPIXEL(op, v)    { \
  34.                     lastpixel = (v) & 0xf; \
  35.                     if (npixels++ & 1) \
  36.                             *op++ |= lastpixel; \
  37.                     else \
  38.                             op[0] = lastpixel << 4; \
  39.             }
  40.  
  41. static int    twobitdeltas[4] = { 0, 1, 0, -1 };
  42. static int     threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 };
  43.  
  44. #pragma warn -par
  45. /****************************************************************************
  46.  *
  47.  */
  48. static int
  49. ThunderScanEncode(
  50.         TIFF     *tif,
  51.         u_char     *pp,
  52.         int     cc
  53.         )
  54. {
  55.         TIFFError(tif->tif_name, "ThunderScan encoding is not implemented");
  56.         return(-1);
  57. }
  58. #pragma warn .par
  59.  
  60. #pragma warn -par
  61. /****************************************************************************
  62.  *
  63.  */
  64. static int
  65. ThunderScanDecode(
  66.         TIFF         *tif,
  67.         register u_char    *op,
  68.         int         occ
  69.         )
  70. {
  71.         register u_char    *bp;
  72.         register int     n, lastpixel, npixels, delta;
  73.         register long    cc;
  74.         int         imagewidth;
  75.  
  76.         bp = (u_char *)tif->tif_rawcp;
  77.         cc = tif->tif_rawcc;
  78.         imagewidth = tif->tif_dir.td_imagewidth;
  79.         lastpixel = npixels = 0;
  80.         while (cc > 0 && npixels < imagewidth) {
  81.                 n = *bp++, cc--;
  82.                 switch (n & THUNDER_CODE) {
  83.                     case THUNDER_RUN:    /* pixel run */
  84.  
  85.         /*
  86.          * Replicate the last pixel n times, where n is the lower-order 6 bits.
  87.          */
  88.                             if (npixels & 1) {
  89.                                     op[0] |= lastpixel;
  90.                                     lastpixel = *op++; 
  91.                                     npixels++; 
  92.                                     n--;
  93.                             } 
  94.                             else
  95.                                     lastpixel |= lastpixel << 4;
  96.                                 npixels += n;
  97.                                 for (; n > 0; n -= 2)
  98.                                         *op++ = lastpixel;
  99.                                 if (n == -1)
  100.                                         *--op &= 0xf0;
  101.                                 lastpixel &= 0xf;
  102.                                 break;
  103.  
  104.                     case THUNDER_2BITDELTAS:    /* 2-bit deltas */
  105.                             if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
  106.                                     SETPIXEL(op, lastpixel + twobitdeltas[delta]);
  107.                             if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
  108.                                     SETPIXEL(op, lastpixel + twobitdeltas[delta]);
  109.                             if ((delta = (n & 3)) != DELTA2_SKIP)
  110.                                     SETPIXEL(op, lastpixel + twobitdeltas[delta]);
  111.                             break;
  112.  
  113.                     case THUNDER_3BITDELTAS:    /* 3-bit deltas */
  114.                             if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
  115.                                     SETPIXEL(op, lastpixel + threebitdeltas[delta]);
  116.                             if ((delta = (n & 7)) != DELTA3_SKIP)
  117.                                     SETPIXEL(op, lastpixel + threebitdeltas[delta]);
  118.                             break;
  119.  
  120.                     case THUNDER_RAW:    /* raw data */
  121.                             SETPIXEL(op, n);
  122.                             break;
  123.                    }
  124.           }
  125.         tif->tif_rawcp = (u_char *)bp;
  126.         tif->tif_rawcc = cc;
  127.         if (npixels != imagewidth) {
  128.                 TIFFError(tif->tif_name, "ThunderScanDecode: %s data for scanline %d (npixels = %d)", npixels < imagewidth ? "Not enough" : "Too much", tif->tif_row, npixels);
  129.                 return(0);
  130.         }
  131.         return(1);
  132. }
  133. #pragma warn .par
  134.  
  135. /****************************************************************************
  136.  *
  137.  */
  138. int
  139. TIFFInitThunderScan(
  140.            TIFF     *tif
  141.            )
  142. {
  143.         tif->tif_decoderow = ThunderScanDecode;
  144.         tif->tif_encoderow = ThunderScanEncode;
  145.         return(1);
  146. }
  147.