home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / l / lds_10.zip / LZRW1 / LZRW1.C next >
C/C++ Source or Header  |  1992-10-18  |  5KB  |  117 lines

  1. #ifndef __HUGE__
  2.    #error Use HUGE memory model.
  3. #endif
  4.  
  5. #define TRUE 1
  6.  
  7. #define UBYTE unsigned char /* Unsigned     byte (1 byte )        */
  8. #define UWORD unsigned int  /* Unsigned     word (2 bytes)        */
  9. #define ULONG unsigned long /* Unsigned longword (4 bytes)        */
  10. #define FLAG_BYTES    4     /* Number of bytes used by copy flag. */
  11. #define FLAG_COMPRESS 0     /* Signals that compression occurred. */
  12. #define FLAG_COPY     1     /* Signals that a copyover occurred.  */
  13. void fast_copy(p_src,p_dst,len) /* Fast copy routine.             */
  14. UBYTE *p_src,*p_dst; {while (len--) *p_dst++=*p_src++;}
  15.  
  16. /******************************************************************************/
  17.  
  18. void lzrw1_compress(p_src_first,src_len,p_dst_first,p_dst_len)
  19. /* Input  : Specify input block using p_src_first and src_len.          */
  20. /* Input  : Point p_dst_first to the start of the output zone (OZ).     */
  21. /* Input  : Point p_dst_len to a ULONG to receive the output length.    */
  22. /* Input  : Input block and output zone must not overlap.               */
  23. /* Output : Length of output block written to *p_dst_len.               */
  24. /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
  25. /* Output : May write in OZ=Mem[p_dst_first..p_dst_first+src_len+256-1].*/
  26. /* Output : Upon completion guaranteed *p_dst_len<=src_len+FLAG_BYTES.  */
  27. UBYTE *p_src_first,*p_dst_first; ULONG src_len,*p_dst_len;
  28. #define PS *p++!=*s++  /* Body of inner unrolled matching loop.         */
  29. #define ITEMMAX 16     /* Maximum number of bytes in an expanded item.  */
  30. {UBYTE *p_src=p_src_first,*p_dst=p_dst_first;
  31.  UBYTE *p_src_post=p_src_first+src_len,*p_dst_post=p_dst_first+src_len;
  32.  UBYTE *p_src_max1=p_src_post-ITEMMAX,*p_src_max16=p_src_post-16*ITEMMAX;
  33.  UBYTE *hash[4096],*p_control; UWORD control=0,control_bits=0;
  34.  *p_dst=FLAG_COMPRESS; p_dst+=FLAG_BYTES; p_control=p_dst; p_dst+=2;
  35.  while (TRUE)
  36.    {UBYTE *p,*s; UWORD unroll=16,len,index; ULONG offset;
  37.     if (p_dst>p_dst_post) goto overrun;
  38.     if (p_src>p_src_max16)
  39.       {unroll=1;
  40.        if (p_src>p_src_max1)
  41.          {if (p_src==p_src_post) break; goto literal;}}
  42.     begin_unrolled_loop:
  43.        index=((40543*((((p_src[0]<<4)^p_src[1])<<4)^p_src[2]))>>4) & 0xFFF;
  44.        p=hash[index]; hash[index]=s=p_src; offset=s-p;
  45.        if (offset>4095 || p<p_src_first || offset==0 || PS || PS || PS)
  46.          {literal: *p_dst++=*p_src++; control>>=1; control_bits++;}
  47.        else
  48.          {PS || PS || PS || PS || PS || PS || PS ||
  49.           PS || PS || PS || PS || PS || PS || s++; len=s-p_src-1;
  50.           *p_dst++=((offset&0xF00)>>4)+(len-1); *p_dst++=offset&0xFF;
  51.           p_src+=len; control=(control>>1)|0x8000; control_bits++;}
  52.     end_unrolled_loop: if (--unroll) goto begin_unrolled_loop;
  53.     if (control_bits==16)
  54.       {*p_control=control&0xFF; *(p_control+1)=control>>8;
  55.        p_control=p_dst; p_dst+=2; control=control_bits=0;}
  56.    }
  57.  control>>=16-control_bits;
  58.  *p_control++=control&0xFF; *p_control++=control>>8;
  59.  if (p_control==p_dst) p_dst-=2;
  60.  *p_dst_len=p_dst-p_dst_first;
  61.  return;
  62.  overrun: fast_copy(p_src_first,p_dst_first+FLAG_BYTES,src_len);
  63.           *p_dst_first=FLAG_COPY; *p_dst_len=src_len+FLAG_BYTES;
  64. }
  65.  
  66. /******************************************************************************/
  67.  
  68. void lzrw1_decompress(p_src_first,src_len,p_dst_first,p_dst_len)
  69. /* Input  : Specify input block using p_src_first and src_len.          */
  70. /* Input  : Point p_dst_first to the start of the output zone.          */
  71. /* Input  : Point p_dst_len to a ULONG to receive the output length.    */
  72. /* Input  : Input block and output zone must not overlap. User knows    */
  73. /* Input  : upperbound on output block length from earlier compression. */
  74. /* Input  : In any case, maximum expansion possible is eight times.     */
  75. /* Output : Length of output block written to *p_dst_len.               */
  76. /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
  77. /* Output : Writes only  in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
  78. UBYTE *p_src_first, *p_dst_first; ULONG src_len, *p_dst_len;
  79. {UWORD controlbits=0, control;
  80.  UBYTE *p_src=p_src_first+FLAG_BYTES, *p_dst=p_dst_first,
  81.        *p_src_post=p_src_first+src_len;
  82.  if (*p_src_first==FLAG_COPY)
  83.    {fast_copy(p_src_first+FLAG_BYTES,p_dst_first,src_len-FLAG_BYTES);
  84.     *p_dst_len=src_len-FLAG_BYTES; return;}
  85.  while (p_src!=p_src_post)
  86.    {if (controlbits==0)
  87.       {control=*p_src++; control|=(*p_src++)<<8; controlbits=16;}
  88.     if (control&1)
  89.       {UWORD offset,len; UBYTE *p;
  90.        offset=(*p_src&0xF0)<<4; len=1+(*p_src++&0xF);
  91.        offset+=*p_src++&0xFF; p=p_dst-offset;
  92.        while (len--) *p_dst++=*p++;}
  93.     else
  94.        *p_dst++=*p_src++;
  95.     control>>=1; controlbits--;
  96.    }
  97.  *p_dst_len=p_dst-p_dst_first;
  98. }
  99.  
  100. /******************************************************************************/
  101. /*                          End of LZRW1.C                                    */
  102. /******************************************************************************/
  103.  
  104. unsigned _stklen = 40000U;
  105.  
  106. void main (void){
  107.    char *str1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n\r";
  108.    char str2[100];
  109.    long len2;
  110.    char str3[100];
  111.    long len3;
  112.    lzrw1_compress (str1, (long)(strlen(str1)+1), str2, &len2);
  113.    lzrw1_decompress (str2, len2, str3, &len3);
  114.    printf (str1);
  115.    printf (str3);
  116. }
  117.