home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / grfx_snd / tifflib / source / tif_sgi.c < prev    next >
C/C++ Source or Header  |  1992-11-10  |  9KB  |  239 lines

  1. #pragma warn -use
  2. static char     *sccsid = "@(#)TIFF/tif_sgi.c 1.06, 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.  * SGI RLE Compression Algorithm Support
  14.  */
  15. #include "tiffio.h"
  16.  
  17. #define MAXRUN     126                /* max length of a run */
  18. #define LITBIT     0x80               /* bit indicating a literal string */
  19.  
  20. /****************************************************************************
  21.  * Encode a scanline of pixels (this is basically the PackBits encoding).
  22.  */
  23. static int
  24. SGIEncode(
  25.            TIFF        *tif,
  26.         u_char         *bp,
  27.         register int     cc
  28.         )
  29. {
  30.         register char    *op, *lastliteral;
  31.         register int     n, b;
  32.         enum { 
  33.             BASE, 
  34.             LITERAL, 
  35.             RUN, 
  36.             LITERAL_RUN
  37.         } state;
  38.         char     *ep;
  39.         int     slop;
  40.  
  41.         /*** XXX 16 bits/sample case ***/
  42.         op = (char *)tif->tif_rawcp;
  43.         ep = (char *)(tif->tif_rawdata + tif->tif_rawdatasize);
  44.         state = BASE;
  45.         lastliteral = 0;
  46.         while (cc > 0) {
  47.  
  48.     /*
  49.          * Find the longest string of identical bytes.
  50.          */
  51.                 b = *bp++;
  52.                 cc--;
  53.                 n = 1;
  54.                 for (; cc > 0 && b == *bp; cc--, bp++)
  55.                         n++;
  56. again:
  57.                 if (op + 2 >= ep) {                /* insure space for new data */
  58.  
  59.     /*
  60.          * Be careful about writing the last literal.  Must write up to that point
  61.          * and then copy the remainder to the front of the buffer.
  62.          */
  63.                         if (state == LITERAL || state == LITERAL_RUN) {
  64.                                 slop = (int)(op - lastliteral);
  65.                                 tif->tif_rawcc += ((u_char *)lastliteral - tif->tif_rawcp);
  66.                                 if (!TIFFFlushData(tif))
  67.                                         return(-1);
  68.                                 op = (char *)tif->tif_rawcp;
  69.                                 for (; slop-- > 0; *op++ = *lastliteral++)
  70.                                         ;
  71.                                 lastliteral = (char *)tif->tif_rawcp;
  72.                         } 
  73.                         else {
  74.                                 tif->tif_rawcc += ((u_char *)op - tif->tif_rawcp);
  75.                                 if (!TIFFFlushData(tif))
  76.                                         return(-1);
  77.                                 op = (char *)tif->tif_rawcp;
  78.                         }
  79.                 }
  80.                 switch (state) {
  81.                     case BASE:        /* initial state, set run/literal */
  82.                             if (n > 1) {
  83.                                     state = RUN;
  84.                                     if (n > MAXRUN) {
  85.                                             *op++ = MAXRUN;
  86.                                             *op++ = b;
  87.                                             n -= MAXRUN;
  88.                                             goto again;
  89.                                     }
  90.                                     *op++ = n;
  91.                                     *op++ = b;
  92.                             } 
  93.                             else {
  94.                                     lastliteral = op;
  95.                                     *op++ = 1;
  96.                                     *op++ = b;
  97.                                     state = LITERAL;
  98.                             }
  99.                             break;
  100.                     case LITERAL:              /* last object was literal string */
  101.                             if (n > 1) {
  102.                                     state = LITERAL_RUN;
  103.                                     if (n > MAXRUN) {
  104.                                             *op++ = MAXRUN;
  105.                                             *op++ = b;
  106.                                             n -= MAXRUN;
  107.                                             goto again;
  108.                                     }
  109.                                     *op++ = n;                /* encode run */
  110.                                     *op++ = b;
  111.                             } 
  112.                             else {                            /* extend literal */
  113.                                     if (++(*lastliteral) == MAXRUN) {
  114.                                             *lastliteral |= LITBIT;
  115.                                             state = BASE;
  116.                                     }
  117.                                     *op++ = b;
  118.                             }
  119.                             break;
  120.                     case RUN:                  /* last object was run */
  121.                             if (n > 1) {
  122.                                     if (n > MAXRUN) {
  123.                                             *op++ = MAXRUN;
  124.                                             *op++ = b;
  125.                                             n -= MAXRUN;
  126.                                             goto again;
  127.                                     }
  128.                                     *op++ = n;
  129.                                     *op++ = b;
  130.                             } 
  131.                             else {
  132.                                     lastliteral = op;
  133.                                     *op++ = 1;
  134.                                     *op++ = b;
  135.                                     state = LITERAL;
  136.                             }
  137.                             break;
  138.                     case LITERAL_RUN:          /* literal followed by a run */
  139.  
  140.     /*
  141.          * Check to see if previous run should be converted to a literal, in which
  142.          * case we convert literal-run-literal to a single literal.
  143.          */
  144.                             if (n == 1 && op[-2] == (char)-1 && *lastliteral < MAXRUN - 2) {
  145.                                     if ((*lastliteral += 2) == MAXRUN) {
  146.                                             *lastliteral |= LITBIT;
  147.                                             state = BASE;
  148.                                     } 
  149.                                     else
  150.                                             state = LITERAL;
  151.                                     op[-2] = op[-1];    /* replicate */
  152.                             } 
  153.                             else {
  154.                                     *lastliteral |= LITBIT;
  155.                                     state = RUN;
  156.                             }
  157.                             goto again;
  158.                 }
  159.         }
  160.         if (state == LITERAL || state == LITERAL_RUN)
  161.                 *lastliteral |= LITBIT;
  162.         tif->tif_rawcc += ((u_char *)op - tif->tif_rawcp);
  163.         tif->tif_rawcp = (u_char *)op;
  164.         return(1);
  165. }
  166.  
  167. #define    DECODE(cc, bp, occ, op, size)    while (cc > 0 && occ > 0) { \
  168.                                 pixel = *bp++; \
  169.                                 cc--; \
  170.                                 n = pixel &~ LITBIT; \
  171.                                 if (n == 0) \
  172.                                         continue; \
  173.                                 if (pixel & LITBIT) { \
  174.                                         bcopy(bp, op, size * n); \
  175.                                         op += size * n; \
  176.                                         occ -= size * n; \
  177.                                         bp += size * n; \
  178.                                         cc -= size * n; \
  179.                                 } \
  180.                                 else { \
  181.                                         pixel = *bp++; \
  182.                                         cc--; \
  183.                                         occ -= size * n; \
  184.                                         while (n-- > 0) \
  185.                                                 *op++ = pixel; \
  186.                                 } \
  187.                         }
  188.  
  189. /****************************************************************************
  190.  *
  191.  */
  192. static int
  193. SGIDecode(
  194.            TIFF         *tif,
  195.         u_char         *buf,
  196.         register int     occ
  197.         )
  198. {
  199.         register int     n, pixel;
  200.         register long    cc;
  201.  
  202.         cc = tif->tif_rawcc;
  203.         if (tif->tif_dir.td_bitspersample <= 8) {
  204.                 register u_char    *bp, *op;
  205.  
  206.                 bp = (u_char *)tif->tif_rawcp;
  207.                 op = buf;
  208.                 DECODE(cc, bp, occ, op, (int)sizeof(char));
  209.                 tif->tif_rawcp = bp;
  210.         } 
  211.         else {
  212.                 register u_short    *bp, *op;
  213.  
  214.                 bp = (u_short *)tif->tif_rawcp;
  215.                 op = (u_short *)buf;
  216.                 DECODE(cc, bp, occ, op, (int)sizeof(short));
  217.                 tif->tif_rawcp = (u_char *)bp;
  218.         }
  219.         tif->tif_rawcc = cc;
  220.         if (occ > 0) {
  221.                 TIFFError(tif->tif_name, "SGIDecode: Not enough data for scanline %d", tif->tif_row);
  222.                 return(0);
  223.         }
  224.         return(1);
  225. }
  226.  
  227. /****************************************************************************
  228.  *
  229.  */
  230. int
  231. TIFFInitSGI(
  232.            TIFF    *tif
  233.            )
  234. {
  235.         tif->tif_decoderow = SGIDecode;
  236.         tif->tif_encoderow = SGIEncode;
  237.         return(1);
  238. }
  239.