home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / xfd_developer / sources / c / szdd.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-27  |  3.7 KB  |  111 lines

  1. /* SZDD decruncher by Kyzer/CSG <kyzer@4u.net>
  2.  * $VER: SZDD.c 1.1 (19.06.2000)
  3.  * v1.1: better xfd name, eliminated 4k buffer
  4.  *
  5.  * based on "ms-expand" by Daniel Risacher <magnus@mit.edu> and someone else
  6.  * http://www.im.lcs.mit.edu/~magnus/ms-expand.c
  7.  *
  8.  * Header:
  9.  * 4 bytes : "SZDD"
  10.  * 4 bytes : $88,$F0,$27,$33
  11.  * 2 bytes : random value? (seen $41,$00 and $41,$39)
  12.  * 4 bytes : A,B,C,D. unpacked size of file is (D<<24)|(C<<16)|(B<<8)|(A)
  13.  * 
  14.  * Compressed data format:
  15.  * - one header byte, whose bits from LSB (0) to MSB (7) dictate the format
  16.  *   of the next 8 elements
  17.  * - if a bit is set, the next element is a single byte literal
  18.  * - otherwise, the next element is a repeat: two bytes, %AAAAAAAA, %BBBBCCCC
  19.  *   where offset = %BBBBAAAAAAAA and length is %CCCC + 3
  20.  *
  21.  * A virtual 4096 byte wraparound window must be kept by the decruncher.
  22.  * A wraparound pointer starts at 4096-16 and each outputted byte must be
  23.  * written at that position and the pointer advanced by one. The buffer
  24.  * starts off filled with zeroes. The offsets of the compressed data refer
  25.  * to an absolute position in this buffer, which may be before the pointer,
  26.  * or after it.
  27.  *
  28.  * It seems that there can often be superfluous data at the end of a file -
  29.  * I can only go by the uncompressed size, so I can only really test running
  30.  * out of source data. Some files end in the middle of a run, so I can't
  31.  * test if they exactly reach the endpoint and no more.
  32.  */
  33.  
  34. #include <libraries/xfdmaster.h>
  35. #include <proto/exec.h>
  36. #include <exec/memory.h>
  37. #include "SDI_compiler.h"
  38.  
  39. #define SZDD_OVERRUN  (144)    /* 8 matches, at maximum length */
  40. #define SZDD_MINLEN   (14)     /* 4+4+2+4 = 14 byte header (and 0 data) */
  41. #define SZDD_WNDSIZE  (4096)   /* LZ sliding window size (4k) */
  42.  
  43. static char version[]="$VER: SZDD 1.1 (19.06.2000) by <kyzer@4u.net>";
  44.  
  45.  
  46. ASM(BOOL) SZDD_recog(REG(a0, STRPTR buf), REG(d0, ULONG length)
  47.   REG(a1, struct xfdRecogResult *rr)) {
  48.   if (buf[0]=='S' && buf[1]=='Z' && buf[2] =='D' && buf[3]=='D') {
  49.     rr->xfdrr_MinTargetLen = SZDD_OVERRUN + (
  50.       rr->xfdrr_FinalTargetLen =
  51.       buf[10] | (buf[11]<<8) | (buf[12]<<16) | (buf[13]<<24)
  52.     );
  53.     return (BOOL) 1;
  54.   }
  55.   return (BOOL) 0;
  56. }
  57.  
  58. ASM(BOOL) SZDD_decrunch(REG(a0, struct xfdBufferInfo * xbi),
  59.   REG(a6, struct xfdMasterBase *xfdMasterBase)) {
  60.  
  61.   struct ExecBase *SysBase = xfdMasterBase->xfdm_ExecBase;
  62.  
  63.   UBYTE *rep, mask, bits;
  64.   int offset, length, clrlen;
  65.  
  66.   UBYTE *src  = (UBYTE *) xbi->xfdbi_SourceBuffer + 14;
  67.   UBYTE *dest = (UBYTE *) xbi->xfdbi_UserTargetBuf;
  68.   UBYTE *ends = src  + xbi->xfdbi_SourceBufLen;
  69.   UBYTE *endd = dest + xbi->xfdbi_TargetBufSaveLen;
  70.   UBYTE *base = dest;
  71.   int posn = SZDD_WNDSIZE-16;
  72.  
  73.   while (src < ends) {
  74.     bits = *src++;
  75.     for (mask = 0x01; mask & 0xFF; mask <<= 1) {
  76.       if (bits & mask) posn++, *dest++ = *src++;
  77.       else {
  78.         offset  = *src++; length = *src++;
  79.         offset |= (length << 4) & 0xF00;
  80.         length  = (length & 0x0F) + 3;
  81.  
  82.         /* translate absolute 4k buffer offset into real window offset */
  83.         posn &= SZDD_WNDSIZE-1; if (offset > posn) posn += SZDD_WNDSIZE;
  84.         rep = dest - posn + offset;
  85.         posn += length;
  86.  
  87.         /* if repeat starts before actual data, write zeroes */
  88.         while (rep < base && length-- > 0) rep++, *dest++ = 0;
  89.  
  90.         /* copy out repeat */
  91.         while (length-- > 0) *dest++ = *rep++;
  92.       }
  93.  
  94.     }
  95.  
  96.     /* at worst, we could overrun dest by (15+3)*8 = 144 bytes */
  97.     if (dest >= endd) return 1;
  98.   }
  99.  
  100.   /* bad exit - run out of src */
  101.   xbi->xfdbi_Error = XFDERR_CORRUPTEDDATA;
  102.   return 0;
  103. }
  104.  
  105. struct xfdSlave FirstSlave = {
  106.   NULL, XFDS_VERSION, 39, "(SZDD) Microsoft Data Cruncher",
  107.   XFDPFF_DATA|XFDPFF_RECOGLEN|XFDPFF_USERTARGET,
  108.   0, (BOOL (*)()) SZDD_recog, (BOOL (*)()) SZDD_decrunch,
  109.   NULL, NULL, 0, 0, SZDD_MINLEN
  110. };
  111.