home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK5 / WIN_12 / IDEPIX2.ZIP / TIFFACS.ZIP / PACKBITS.C < prev    next >
C/C++ Source or Header  |  1993-06-23  |  5KB  |  243 lines

  1. /*-------------------------------------------------------
  2.  
  3.     T I F F A C S : Unterstⁿtzungsroutinen fⁿr TIFF-Dateien
  4.             Ursprⁿnglich von Aldus, von mir auf dem
  5.             Walnut-Creek - Source-Code-ROM gefunden.
  6.  
  7.             Der ursprⁿngliche Source ist TIFF 4.0 und
  8.             auch ansonsten ein ziemlicher Mⁿll.
  9.  
  10.             Diese Version hat Funktionsprototypen und
  11.             ein paar Fehler weniger, aber im Grunde ist
  12.             sie auch ein ziemlicher Mⁿll.
  13.  
  14.             Im Mircosoft System Journal 4/93 ist eine ganz
  15.             brauchbare TIF-Routine dabei, aber eben nicht PD
  16.  
  17.             Bernd Herd
  18.             Rudolf Virchow Str. 8
  19.             6842 Bⁿrstadt
  20.             06206/79222
  21.  
  22.        P A C K B I T S : Kompression im PackBits-Format
  23.  
  24.   -------------------------------------------------------------*/
  25.  
  26. #include <windows.h>
  27. #pragma hdrstop
  28. #include <string.h>
  29. #include "tiff.h"
  30. #include "tiffi.h"
  31.  
  32. #define    MAXINBYTES    127
  33. #define    INITIAL        0
  34. #define    LITERAL        1
  35. #define    UNDECIDED    2
  36.  
  37. char CalcRaw (WORD n, LPSTR lpIn, char *rawrunbuf)
  38. {
  39.     char ncounts = 0;
  40.     char thisbyte;
  41.     char cnt = 1;
  42.     char runbyte = *lpIn++;
  43.  
  44.     while (--n) {
  45.         thisbyte = *lpIn++;
  46.         if (thisbyte == runbyte) {
  47.             cnt++;
  48.         } else { /* write prev raw run, & start a new one */
  49.             *rawrunbuf++ = cnt;
  50.             ncounts++;
  51.             cnt = 1;
  52.             runbyte = thisbyte;
  53.         }
  54.     }
  55.     *rawrunbuf = cnt;
  56.     return (++ncounts);
  57. }
  58.  
  59. /* this should be a Mac ToolBox lookalike
  60.  * n must be <= 127
  61.  */
  62. void near _pascal static PackBits (LPSTR *plpIn, LPSTR *plpOut, WORD n)
  63. {
  64.     LPSTR    lpIn  = *plpIn;
  65.     LPSTR    lpOut = *plpOut;
  66.     char    runcount;
  67.     char    rawrunbuf[MAXINBYTES];
  68.     char    *pRaw;
  69.     char    nraw;
  70.     char    state;
  71.     char    rawcount;
  72.     char    twins;
  73. //    BOOL    success = FALSE;
  74. #ifdef n
  75.     if (n <= 0 || n > 127) {
  76.         DBMSG(("PackBits: n=%u\n", n));
  77.         err = IE_BUG;
  78.         goto cu0;
  79.     }
  80.  
  81. #endif
  82.     /* calculate raw run counts
  83.      */
  84.     nraw = CalcRaw (n, lpIn, rawrunbuf);
  85. #ifdef n
  86.     if (nraw <= 0 || nraw > 127) {
  87.         DBMSG(("PackBits: nraw=%u\n",nraw));
  88.         err = IE_BUG;
  89.         goto cu0;
  90.     }
  91. #endif
  92.     /* initialize a few things
  93.      */
  94.     pRaw = rawrunbuf;
  95.     state = INITIAL;
  96.  
  97.     /* go through the raw run count array
  98.      */
  99.     while (nraw--) {
  100.  
  101.         rawcount = *pRaw++;
  102. #ifdef nein
  103.         if (rawcount < 1 || rawcount > 127) {
  104.             DBMSG(("PackBits: rawcount=%d\n",rawcount));
  105.             err = IE_BUG;
  106.             goto cu0;
  107.         }
  108. #endif
  109.         if (state == INITIAL) {
  110.             if (rawcount == 1) {
  111.                 state = LITERAL;
  112.                 runcount = 1;
  113.             } else if (rawcount == 2) {
  114.                 state = UNDECIDED;
  115.                 runcount = 2;
  116.             } else {    /* rawcount >= 3 */
  117.                 /* state = INITIAL; */
  118.                 /* write replicate run and update ptrs
  119.                  */
  120.                 *lpOut++ = -(rawcount - 1);
  121.                 *lpOut++ = *lpIn;
  122.                 lpIn += rawcount;
  123.             }
  124.  
  125.         } else if (state == LITERAL) {
  126.             if (rawcount < 3) {
  127.                 runcount += rawcount;
  128.             } else {
  129.                 state = INITIAL;
  130.                 /* write literal run and update ptrs
  131.                  */
  132.                 *lpOut++ = runcount - 1;
  133.  
  134. #ifdef NEIN
  135.                 if (runcount < 1 || runcount > 127) {
  136.                     DBMSG(("PackBits: runcount=%d\n",runcount));
  137.                     goto cu0;
  138.                 }
  139. #endif
  140.  
  141.                 memcpy (lpOut, lpIn, runcount);
  142.                 lpOut += runcount;
  143.                 lpIn += runcount;
  144.                 /* write replicate run and update ptrs
  145.                  */
  146.                 *lpOut++ = -(rawcount - 1);
  147.                 *lpOut++ = *lpIn;
  148.                 lpIn += rawcount;
  149.             }
  150.  
  151.         } else {    /* state = UNDECIDED */
  152.             if (rawcount == 1) {
  153.                 state = LITERAL;
  154.                 runcount++;
  155.             } else if (rawcount == 2) {
  156.                 /* state = UNDECIDED */
  157.                 runcount += 2;
  158.             } else {    /* rawcount >= 3 */
  159.                 state = INITIAL;
  160.  
  161. #ifdef NEIN
  162.                 if (runcount < 1 || runcount > 127) {
  163.                     DBMSG(("PackBits: runcount=%d\n",runcount));
  164.                     goto cu0;
  165.                 }
  166. #endif
  167.  
  168.                 /* write out runcount/2 twin replicate runs */
  169.                 for (twins = (runcount>>1); twins--; ) {
  170.                     *lpOut++ = -1;
  171.                     *lpOut++ = *lpIn;
  172.                     lpIn += 2;
  173.                 }
  174.                 /* write out this replicate run
  175.                  */
  176.                 *lpOut++ = -(rawcount - 1);
  177.                 *lpOut++ = *lpIn;
  178.                 lpIn += rawcount;
  179.             }
  180.         } /* end of UNDECIDED case */
  181.  
  182.     } /* end of main for loop */
  183.  
  184.     /* clean up hanging states
  185.      */
  186.     if (state == LITERAL) {
  187.  
  188. #ifdef NEIN
  189.         if (runcount < 1 || runcount > 127) {
  190.             DBMSG(("PackBits: runcount=%d\n",runcount));
  191.             goto cu0;
  192.         }
  193. #endif
  194.         /* write out literal run
  195.          */
  196.         *lpOut++ = runcount - 1;
  197.         memcpy (lpOut, lpIn, runcount);
  198.         lpOut += runcount;
  199.         lpIn += runcount;
  200.     }
  201.     else if (state == UNDECIDED) {
  202. #ifdef NEIN
  203.         if (runcount < 1 || runcount > 127) {
  204.             DBMSG(("PackBits: runcount=%d\n",runcount));
  205.             goto cu0;
  206.         }
  207. #endif
  208.         /* write out runcount/2 twin replicate runs
  209.          */
  210.         for (twins = (runcount>>1); twins--; ) {
  211.             *lpOut++ = -1;
  212.             *lpOut++ = *lpIn;
  213.             lpIn += 2;
  214.         }
  215.     }
  216.  
  217.     /* set up return values
  218.      */
  219.     *plpIn = lpIn;
  220.     *plpOut = lpOut;
  221.  
  222. cu0: return;
  223.  
  224. } /* that's all, folks */
  225.  
  226.  
  227.  
  228.  
  229.  
  230. /* if you might have more than 127 input bytes, call this routine instead
  231.  * of the basic PackBits
  232.  */
  233. void BigPackBits (LPSTR *plpIn, LPSTR *plpOut, unsigned n)
  234. {
  235.         WORD    topack;
  236.  
  237.         while (n) {
  238.             topack = (n < MAXINBYTES) ? n : MAXINBYTES;
  239.             PackBits (plpIn, plpOut, topack);
  240.             n -= topack;
  241.         }
  242. }
  243.