home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / varie / xfd / developer / sources / c / lha3.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-22  |  9.5 KB  |  421 lines

  1. char version[] = "$VER: LHA3 2.0 (11.07.1999) by SDI";
  2.  
  3. /* Objectheader
  4.  
  5.     Name:        LHA3.c
  6.     Description:    xfd external decruncher for =SB= files
  7.     Author:     SDI (stoecker@amigaworld.com)
  8.     Distribution:    PD
  9.  
  10.  2.0   11.07.99 : first version
  11. */
  12.  
  13. #include <libraries/xfdmaster.h>
  14. #include <proto/exec.h>
  15. #include <exec/memory.h>
  16. #include <exec/execbase.h>
  17.  
  18. #define MAXMATCH    256
  19. #define THRESHOLD    3
  20. #define UCHAR_MAX    ((1<<(sizeof(UBYTE)*8))-1)
  21. #define NT        (USHRT_BIT + 3)
  22. #define TBIT         5
  23. #define NC         (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
  24. #define NPT        0x80
  25. #define CHAR_BIT      8
  26. #define CBIT        9
  27. #define USHRT_BIT    16
  28.  
  29. struct LhData {
  30.   STRPTR     inbuf;
  31.   STRPTR     outbuf;
  32.   LONG        origsize;
  33.   LONG        compsize;
  34.   LONG        XFDerr;
  35.   UWORD        blocksize;
  36.   UWORD        bitbuf;
  37.   UWORD        left[2 * NC - 1];
  38.   UWORD        right[2 * NC - 1];
  39.   UWORD        c_table[4096];
  40.   UWORD        pt_table[256];
  41.   UBYTE     subbitbuf;
  42.   UBYTE        bitcount;
  43.   UBYTE        c_len[NC];
  44.   UBYTE        pt_len[NPT];
  45.   UBYTE        text[1 << 15];
  46. };
  47.  
  48. /************** Here starts xfd stuff - the xfdSlave structure **********/
  49.  
  50. #define MASTER_VERS    39
  51.  
  52. typedef BOOL (*xfdFunc) ();
  53.  
  54. LONG __asm RecogLHA3(register __a0 ULONG * buf, register __a1 struct xfdRecogResult *rr,
  55. register __d0 ULONG length);
  56.  
  57. ULONG __asm DecrunchLHA3(register __a0 struct xfdBufferInfo * xbi,
  58. register __a6 struct xfdMasterBase *xfdMasterBase);
  59.  
  60. LONG __asm ScanLHA3(register __a0 ULONG *buf, register __d0 ULONG size);
  61.  
  62. ULONG __asm VerifyLHA3(register __a0 ULONG *buf, register __d0 ULONG size);
  63.  
  64. static void decode(struct LhData *lhd);
  65. static void read_pt_len(struct LhData *lhd, WORD nn, WORD nbit, WORD i_special);
  66. static void read_c_len(struct LhData *lhd);
  67. static UWORD decode_c_st1(struct LhData *lhd);
  68. static UWORD decode_p_st1(struct LhData *lhd);
  69. static void fillbuf(struct LhData *lhd, UBYTE n);            /* Shift bitbuf n bits left, read n bits */
  70. static UWORD getbits(struct LhData *lhd, UBYTE n);
  71. static void make_table(struct LhData *lhd, WORD nchar, UBYTE bitlen[], WORD tablebits, UWORD table[]);
  72.  
  73. struct xfdSlave FirstSlave = {
  74.   0, XFDS_VERSION, MASTER_VERS, "Stefan Boberg's LhA3 Converter", XFDPFF_DATA|XFDPFF_RECOGLEN|XFDPFF_USERTARGET,
  75.   0, (xfdFunc) RecogLHA3, (xfdFunc) DecrunchLHA3, (xfdFunc) ScanLHA3, (xfdFunc) VerifyLHA3, 0, 0, 12};
  76.  
  77. LONG __asm RecogLHA3(register __a0 ULONG * buf, register __a1 struct xfdRecogResult *rr,
  78. register __d0 ULONG length)
  79. {
  80.   if(*buf == 0x3D53423D)
  81.   {
  82.     rr->xfdrr_FinalTargetLen = rr->xfdrr_MinTargetLen = buf[1];
  83.     rr->xfdrr_MinSourceLen = 12 + buf[2];
  84.     return 1;
  85.   }
  86.   else
  87.     return 0;
  88. }
  89.  
  90. LONG __asm ScanLHA3(register __a0 ULONG *buf, register __d0 ULONG size)
  91. {
  92.   if(*buf == 0x3D53423D)
  93.     return 1;
  94.   else
  95.     return 0;
  96. }
  97.  
  98. ULONG __asm VerifyLHA3(register __a0 ULONG *buf, register __d0 ULONG size)
  99. {
  100.   if((buf[1] >= buf[2]) && (buf[2] + 12 <= size))
  101.     return buf[2] + 12;
  102.   return 0;
  103. }
  104.  
  105. ULONG __asm DecrunchLHA3(register __a0 struct xfdBufferInfo * xbi,
  106. register __a6 struct xfdMasterBase *xfdmasterBase)
  107. {
  108.   ULONG res = 0;
  109.   struct ExecBase *SysBase;
  110.   struct LhData *lhd;
  111.  
  112.   SysBase = xfdmasterBase->xfdm_ExecBase;
  113.  
  114.   if((lhd = (struct LhData *) AllocMem(sizeof(struct LhData), MEMF_CLEAR)))
  115.   {
  116.     lhd->outbuf = xbi->xfdbi_UserTargetBuf;
  117.     lhd->inbuf = ((STRPTR) xbi->xfdbi_SourceBuffer)+12;
  118.     lhd->origsize = xbi->xfdbi_TargetBufSaveLen;
  119.     lhd->compsize = xbi->xfdbi_SourceBufLen-12;
  120.     decode(lhd);
  121.     if(!(xbi->xfdbi_Error = lhd->XFDerr))
  122.       res = 1;
  123.  
  124.     FreeMem(lhd, sizeof(struct LhData));
  125.   }
  126.   else
  127.     xbi->xfdbi_Error = XFDERR_NOMEMORY;
  128.  
  129.   return res;
  130. }
  131.  
  132. static void decode(struct LhData *lhd)
  133. {
  134.   LONG i, j, k, c, dicsiz1, offset, count, loc, dicsiz;
  135.  
  136.   dicsiz = 1 << 15;
  137.   for(i = 0; i < dicsiz; ++i)
  138.     lhd->text[i] = ' ';
  139. //  lhd->bitbuf = 0;
  140. //  lhd->subbitbuf = 0;
  141. //  lhd->bitcount = 0;
  142.   fillbuf(lhd, 2 * CHAR_BIT);
  143. //  lhd->blocksize = 0;
  144.   dicsiz1 = dicsiz - 1;
  145.   offset = 0x100 - 3;
  146.   count = 0;
  147.   loc = 0;
  148.   while((count < lhd->origsize) && (!lhd->XFDerr))
  149.   {
  150.     c = decode_c_st1(lhd);
  151.     if (c <= UCHAR_MAX)
  152.     {
  153.       *(lhd->outbuf++) = lhd->text[loc++] = c;
  154.       if (loc == dicsiz)
  155.         loc = 0;
  156.       count++;
  157.     }
  158.     else
  159.     {
  160.       j = c - offset;
  161.       i = (loc - decode_p_st1(lhd) - 1) & dicsiz1;
  162.       count += j;
  163.       for (k = 0; k < j; k++)
  164.       {
  165.         *(lhd->outbuf++) = c = lhd->text[(i + k) & dicsiz1];
  166.         lhd->text[loc++] = c;
  167.         if (loc == dicsiz)
  168.           loc = 0;
  169.       }
  170.     }
  171.   }
  172. }
  173.  
  174. static void read_pt_len(struct LhData *lhd, WORD nn, WORD nbit, WORD i_special)
  175. {
  176.   WORD i, c, n;
  177.  
  178.   n = getbits(lhd, nbit);
  179.   if (n == 0) {
  180.     c = getbits(lhd, nbit);
  181.     for (i = 0; i < nn; i++)
  182.       lhd->pt_len[i] = 0;
  183.     for (i = 0; i < 256; i++)
  184.       lhd->pt_table[i] = c;
  185.   }
  186.   else {
  187.     i = 0;
  188.     while (i < n) {
  189.       c = lhd->bitbuf >> (16 - 3);
  190.       if (c == 7) {
  191.         UWORD  mask = 1 << (16 - 4);
  192.         while (mask & lhd->bitbuf) {
  193.           mask >>= 1;
  194.           c++;
  195.         }
  196.       }
  197.       fillbuf(lhd, (c < 7) ? 3 : c - 3);
  198.       lhd->pt_len[i++] = c;
  199.       if (i == i_special) {
  200.         c = getbits(lhd, 2);
  201.         while (--c >= 0)
  202.           lhd->pt_len[i++] = 0;
  203.       }
  204.     }
  205.     while (i < nn)
  206.       lhd->pt_len[i++] = 0;
  207.     make_table(lhd, nn, lhd->pt_len, 8, lhd->pt_table);
  208.   }
  209. }
  210.  
  211. static void read_c_len(struct LhData *lhd)
  212. {
  213.   WORD i, c, n;
  214.  
  215.   n = getbits(lhd, CBIT);
  216.   if (n == 0) {
  217.     c = getbits(lhd, CBIT);
  218.     for (i = 0; i < NC; i++)
  219.       lhd->c_len[i] = 0;
  220.     for (i = 0; i < 4096; i++)
  221.       lhd->c_table[i] = c;
  222.   } else {
  223.     i = 0;
  224.     while (i < n) {
  225.       c = lhd->pt_table[lhd->bitbuf >> (16 - 8)];
  226.       if (c >= NT) {
  227.         UWORD  mask = 1 << (16 - 9);
  228.         do {
  229.           if (lhd->bitbuf & mask)
  230.             c = lhd->right[c];
  231.           else
  232.             c = lhd->left[c];
  233.           mask >>= 1;
  234.         } while (c >= NT);
  235.       }
  236.       fillbuf(lhd, lhd->pt_len[c]);
  237.       if (c <= 2) {
  238.         if (c == 0)
  239.           c = 1;
  240.         else if (c == 1)
  241.           c = getbits(lhd, 4) + 3;
  242.         else
  243.           c = getbits(lhd, CBIT) + 20;
  244.         while (--c >= 0)
  245.           lhd->c_len[i++] = 0;
  246.       }
  247.       else
  248.         lhd->c_len[i++] = c - 2;
  249.     }
  250.     while (i < NC)
  251.       lhd->c_len[i++] = 0;
  252.     make_table(lhd, NC, lhd->c_len, 12, lhd->c_table);
  253.   }
  254. }
  255.  
  256. static UWORD decode_c_st1(struct LhData *lhd)
  257. {
  258.   UWORD  j, mask;
  259.  
  260.   if (lhd->blocksize == 0) {
  261.     lhd->blocksize = getbits(lhd, 16);
  262.     read_pt_len(lhd, NT, TBIT, 3);
  263.     read_c_len(lhd);
  264.     read_pt_len(lhd, 16, 5, -1);
  265.   }
  266.   lhd->blocksize--;
  267.   j = lhd->c_table[lhd->bitbuf >> 4];
  268.   if (j < NC)
  269.     fillbuf(lhd, lhd->c_len[j]);
  270.   else {
  271.     fillbuf(lhd, 12);
  272.     mask = 1 << (16 - 1);
  273.     do {
  274.       if (lhd->bitbuf & mask)
  275.         j = lhd->right[j];
  276.       else
  277.         j = lhd->left[j];
  278.       mask >>= 1;
  279.     } while (j >= NC);
  280.     fillbuf(lhd, lhd->c_len[j] - 12);
  281.   }
  282.   return j;
  283. }
  284.  
  285. static UWORD decode_p_st1(struct LhData *lhd)
  286. {
  287.   UWORD  j, mask;
  288.  
  289.   j = lhd->pt_table[lhd->bitbuf >> (16 - 8)];
  290.   if (j < 16)
  291.     fillbuf(lhd, lhd->pt_len[j]);
  292.   else {
  293.     fillbuf(lhd, 8);
  294.     mask = 1 << (16 - 1);
  295.     do {
  296.       if (lhd->bitbuf & mask)
  297.         j = lhd->right[j];
  298.       else
  299.         j = lhd->left[j];
  300.       mask >>= 1;
  301.     } while (j >= 16);
  302.     fillbuf(lhd, lhd->pt_len[j] - 8);
  303.   }
  304.   if (j != 0)
  305.     j = (1 << (j - 1)) + getbits(lhd, j - 1);
  306.   return j;
  307. }
  308.  
  309. static void fillbuf(struct LhData *lhd, UBYTE n)     /* Shift lhd->bitbuf n bits lhd->left, read n bits */
  310. {
  311.   while (n > lhd->bitcount) {
  312.     n -= lhd->bitcount;
  313.     lhd->bitbuf = (lhd->bitbuf << lhd->bitcount) + (lhd->subbitbuf >> (CHAR_BIT - lhd->bitcount));
  314.     if (lhd->compsize != 0) {
  315.       lhd->compsize--;
  316.       lhd->subbitbuf = (UBYTE) *(lhd->inbuf++);
  317.     }
  318.     else
  319.       lhd->subbitbuf = 0;
  320.     lhd->bitcount = CHAR_BIT;
  321.   }
  322.   lhd->bitcount -= n;
  323.   lhd->bitbuf = (lhd->bitbuf << n) + (lhd->subbitbuf >> (CHAR_BIT - n));
  324.   lhd->subbitbuf <<= n;
  325. }
  326.  
  327. static UWORD getbits(struct LhData *lhd, UBYTE n)
  328. {
  329.   UWORD  x;
  330.  
  331.   x = lhd->bitbuf >> (2 * CHAR_BIT - n);
  332.   fillbuf(lhd, n);
  333.   return x;
  334. }
  335.  
  336. static void make_table(struct LhData *lhd, WORD nchar, UBYTE bitlen[], WORD tablebits, UWORD table[])
  337. {
  338.   UWORD  count[17]; /* count of bitlen */
  339.   UWORD  weight[17];  /* 0x10000ul >> bitlen */
  340.   UWORD  start[17]; /* first code of bitlen */
  341.   UWORD  total;
  342.   ULONG    i;
  343.   LONG             j, k, l, m, n, avail;
  344.   UWORD *p;
  345.  
  346.   if(lhd->XFDerr)
  347.     return;
  348.  
  349.   avail = nchar;
  350.  
  351.   /* initialize */
  352.   for (i = 1; i <= 16; i++) {
  353.     count[i] = 0;
  354.     weight[i] = 1 << (16 - i);
  355.   }
  356.  
  357.   /* count */
  358.   for (i = 0; i < nchar; i++)
  359.     count[bitlen[i]]++;
  360.  
  361.   /* calculate first code */
  362.   total = 0;
  363.   for (i = 1; i <= 16; i++) {
  364.     start[i] = total;
  365.     total += weight[i] * count[i];
  366.   }
  367.   if ((total & 0xffff) != 0)
  368.   {
  369.     lhd->XFDerr = XFDERR_CORRUPTEDDATA;
  370.     return;
  371.   }
  372.  
  373.   /* shift data for make table. */
  374.   m = 16 - tablebits;
  375.   for (i = 1; i <= tablebits; i++) {
  376.     start[i] >>= m;
  377.     weight[i] >>= m;
  378.   }
  379.  
  380.   /* initialize */
  381.   j = start[tablebits + 1] >> m;
  382.   k = 1 << tablebits;
  383.   if (j != 0)
  384.     for (i = j; i < k; i++)
  385.       table[i] = 0;
  386.  
  387.   /* create table and tree */
  388.   for (j = 0; j < nchar; j++) {
  389.     k = bitlen[j];
  390.     if (k == 0)
  391.       continue;
  392.     l = start[k] + weight[k];
  393.     if (k <= tablebits) {
  394.       /* code in table */
  395.       for (i = start[k]; i < l; i++)
  396.         table[i] = j;
  397.     }
  398.     else {
  399.       /* code not in table */
  400.       p = &table[(i = start[k]) >> m];
  401.       i <<= tablebits;
  402.       n = k - tablebits;
  403.       /* make tree (n length) */
  404.       while (--n >= 0) {
  405.         if (*p == 0) {
  406.           lhd->right[avail] = lhd->left[avail] = 0;
  407.           *p = avail++;
  408.         }
  409.         if (i & 0x8000)
  410.           p = &lhd->right[*p];
  411.         else
  412.           p = &lhd->left[*p];
  413.         i <<= 1;
  414.       }
  415.       *p = j;
  416.     }
  417.     start[k] = l;
  418.   }
  419. }
  420.  
  421.