-/* depack.c\r
-\r
- Part of the swftools installer.\r
- \r
- Copyright (c) 1997-2004 Matthias Kramm <kramm@quiss.org> \r
- \r
- This program is free software; you can redistribute it and/or modify\r
- it under the terms of the GNU General Public License as published by\r
- the Free Software Foundation; either version 2 of the License, or\r
- (at your option) any later version.\r
-\r
- This program is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- GNU General Public License for more details.\r
-\r
- You should have received a copy of the GNU General Public License\r
- along with this program; if not, write to the Free Software\r
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */\r
-\r
-#include "stdlib.h"\r
-#include "stdio.h"\r
-#include "depack.h"\r
-\r
-U32 dbittab[] = {\r
- 0x1, 0x2, 0x4, 0x8,\r
- 0x10, 0x20, 0x40, 0x80,\r
- 0x100, 0x200, 0x400, 0x800,\r
- 0x1000, 0x2000, 0x4000, 0x8000,\r
- 0x10000, 0x20000, 0x40000, 0x80000, \r
- 0x100000, 0x200000, 0x400000, 0x800000,\r
- 0x1000000, 0x2000000, 0x4000000, 0x8000000,\r
- 0x10000000,0x20000000,0x40000000,0x80000000\r
-};\r
-\r
-static void* malloc_z(int len)\r
-{\r
- void* buf = malloc(len);\r
- if(buf == 0) {\r
- fprintf(stderr, "\nout of memory\n");\r
- exit(1);\r
- }\r
- memset(buf, 0, len);\r
- return buf;\r
-}\r
-\r
-typedef struct _dpackead {\r
- int back;\r
- int len;\r
-} dpackead_t;\r
-\r
-typedef struct _tree { \r
- int depth;\r
- U8 bits[17];\r
- U32 base[17];\r
-} tree_t;\r
-\r
-typedef struct _depack_internal\r
-{\r
- int DMEMSIZE;\r
- int DMEMSIZEA;\r
-\r
- tree_t T_REP;\r
- tree_t T_STORE;\r
- tree_t T_CNUM;\r
- tree_t T_BACK;\r
- tree_t T_BACK2;\r
- tree_t T_BACK3;\r
-\r
- dpackead_t dpackead;\r
-\r
- void*reader;\r
- readfunc_t readfunc;\r
- void*writer;\r
- writefunc_t writefunc;\r
-\r
- U8* mem;\r
- int mempos;\r
- int pos;\r
- U8 c;\r
- U32 b;\r
-} depack_internal_t;\r
-\r
-void depack_destroy(depack_t*d)\r
-{\r
- depack_internal_t*i = (depack_internal_t*)d->internal;\r
- free(i->mem);i->mem=0;\r
- free(d->internal);d->internal=0;i=0;\r
-}\r
-\r
-static readbytes(depack_t*d, int num)\r
-{\r
- depack_internal_t*i = (depack_internal_t*)d->internal;\r
-\r
- if(i->mempos+num<=i->DMEMSIZE) {\r
- i->readfunc(i->reader, &i->mem[i->mempos],num);\r
- i->writefunc(i->writer, &i->mem[i->mempos],num);\r
- } else {\r
- i->readfunc(i->reader, &i->mem[i->mempos],i->DMEMSIZE - i->mempos);\r
- i->writefunc(i->writer, &i->mem[i->mempos],i->DMEMSIZE - i->mempos);\r
- i->readfunc(i->reader, &i->mem[0],num-(i->DMEMSIZE - i->mempos));\r
- i->writefunc(i->writer, &i->mem[0],num-(i->DMEMSIZE - i->mempos));\r
- }\r
- i->mempos=(i->mempos+num)&i->DMEMSIZEA;\r
- i->pos+=num;\r
-}\r
-\r
-int move(U8*dest, U8*src, int len)\r
-{\r
- if(len) do {\r
- *dest=*src;\r
- src++;\r
- dest++;\r
- } while(--len);\r
-}\r
-\r
-static lookback(depack_t*d, int back,int len)\r
-{\r
- depack_internal_t*i = (depack_internal_t*)d->internal;\r
-\r
- int x,z=(i->mempos-back)&i->DMEMSIZEA;\r
- char fail=0;\r
-\r
- if(i->mempos+len <= i->DMEMSIZE && \r
- z+len <= i->DMEMSIZE) \r
- {\r
- move(&i->mem[i->mempos],&i->mem[z],len);\r
- i->writefunc(i->writer, &i->mem[i->mempos],len);\r
- i->mempos=(i->mempos+len)&i->DMEMSIZEA;\r
- } else {\r
- for(x=0;x<len;x++) {\r
- i->mem[i->mempos]=i->mem[z];\r
- i->writefunc(i->writer, &i->mem[i->mempos],1);\r
- i->mempos=(i->mempos+1)&i->DMEMSIZEA;\r
- z=(z+1)&i->DMEMSIZEA;\r
- }\r
- }\r
- i->pos += len;\r
-}\r
-\r
-static inline U8 readbit(depack_internal_t*i)\r
-{\r
- i->c&=31;\r
- if(i->c==0) i->readfunc(i->reader, &i->b,4);\r
- return (i->b>>(31-i->c++))&1;\r
-}\r
-\r
-static inline U32 readval(depack_internal_t*i,int b)\r
-{\r
- unsigned v=0;\r
- signed char l;\r
- for(l=b-1;l>=0;l--)\r
- v|=readbit(i)<<l;\r
- return v;\r
-}\r
-\r
-static tree_t gettree(depack_t*d)\r
-{\r
- depack_internal_t*i = (depack_internal_t*)d->internal;\r
-\r
- int l;\r
- int x,y,z=0,b=0,r;\r
- tree_t tree;\r
- memset(&tree, 0, sizeof(tree));\r
- \r
- tree.depth = readval(i,4)+1;\r
-\r
- for(x=0;x<tree.depth;x++)\r
- {\r
- tree.base[x]=z;\r
- r=0;while(!readbit(i)) r++;\r
- if(readbit(i)) r=-r;\r
- b+=r;\r
- tree.bits[x]=b;\r
- z+=dbittab[b];\r
- }\r
- tree.base[tree.depth]=z;\r
- tree.bits[tree.depth]=0;\r
- return tree;\r
-\r
-/* for(z=0;z<=l;z++)\r
- {\r
- if(i->ttree[n].bits[z]>16) \r
- printf(".");\r
- else \r
- printf("%c","0123456789abcdefg"[ttree[n].bits[z]]);\r
- }\r
- printf("\n");*/\r
-}\r
-\r
-static void showtree(tree_t tree)\r
-{\r
- int t;\r
- int last=0;\r
- int lastbits = 0;\r
- for(t=0;t<=tree.depth;t++)\r
- {\r
- if(t>0)\r
- printf("[%d] %d: %05x-%05x (%d=%d+%d+1)\n",t,lastbits, last,tree.base[t],lastbits+(t-1)+1, lastbits,t-1);\r
- last=tree.base[t];\r
- lastbits = tree.bits[t];\r
- }\r
-}\r
-\r
-static int gettreeval(depack_t*d, tree_t*tree)\r
-{\r
- depack_internal_t*i = (depack_internal_t*)d->internal;\r
-\r
- U8 x=0;\r
- while(!readbit(i)) x++;\r
- if(x<17) return tree->base[x]+readval(i, tree->bits[x]);\r
- else return -1;\r
-}\r
-\r
-static int get_memsize(int b)\r
-{\r
- int t,c=1;\r
- for(t=0;;t++) {\r
- if(c>=b) return c;\r
- c<<=1;\r
- }\r
- return 0;\r
-}\r
-\r
-void depack_init(depack_t*d, void*reader, readfunc_t readfunc)\r
-{\r
- d->internal = malloc_z(sizeof(depack_internal_t));\r
- depack_internal_t*i = (depack_internal_t*)d->internal;\r
- if(i==0) {\r
- fprintf(stderr, "depacker not initialized yet"); exit(1);\r
- }\r
-\r
- i->reader = reader;\r
- i->readfunc = readfunc;\r
-\r
- i->mempos=0;\r
- i->pos=0;\r
- i->b=i->c=0;\r
-\r
- i->readfunc(i->reader,&i->dpackead.back, 4);\r
- i->readfunc(i->reader,&i->dpackead.len, 4);\r
-\r
- i->DMEMSIZE = get_memsize(i->dpackead.len);\r
- i->DMEMSIZEA = i->DMEMSIZE-1;\r
- i->mem = malloc_z(i->DMEMSIZE);\r
-\r
- i->T_REP = gettree(d);\r
- i->T_STORE = gettree(d);\r
- i->T_CNUM = gettree(d);\r
- //showtree(i->T_CNUM);\r
- i->T_BACK = gettree(d);\r
- //showtree(i->T_BACK);\r
- i->T_BACK2 = gettree(d);\r
- //showtree(i->T_BACK);\r
- i->T_BACK3 = gettree(d);\r
- //showtree(i->T_BACK3);\r
-\r
- d->size = i->dpackead.len;\r
-}\r
-\r
-void depack_process(depack_t*d, void*writer,writefunc_t writefunc)\r
-{\r
- depack_internal_t*i = (depack_internal_t*)d->internal;\r
- i->writer = writer;\r
- i->writefunc = writefunc;\r
- while(i->pos<i->dpackead.len)\r
- {\r
- int store,rep,x;\r
-\r
- store=gettreeval(d,&i->T_STORE)+1;\r
-\r
- readbytes(d,store);\r
-\r
- if(i->pos<i->dpackead.len)\r
- {\r
- rep = gettreeval(d,&i->T_REP)+1;\r
-\r
- for(x=0;x<rep;x++)\r
- {\r
- int back,len;\r
- len = gettreeval(d,&i->T_CNUM)+1;\r
-\r
- if(len == 1) back = readval(i,3)+1;\r
- if(len == 2) back = gettreeval(d,&i->T_BACK2)+1;\r
- if(len == 3) back = gettreeval(d,&i->T_BACK3)+1;\r
- if(len >= 4) back = gettreeval(d,&i->T_BACK)+1;\r
-\r
- lookback(d,back,len);\r
- }\r
- }\r
- }\r
-\r
- if(i->pos!=i->dpackead.len) {\r
- fprintf(stderr, "Internal error");\r
- exit(1);\r
- }\r
-}\r
-\r
-/*\r
-\r
- mov eax,[b1]\r
- mov ebx,[b2]\r
- shld eax,ebx,cl\r
- mov [b1],eax\r
- shr ebx,cl\r
- mov [b2],ebx\r
- sub cnt,cl\r
- cmp cnt,32-8\r
- ja jj\r
-mm: xor eax,eax\r
- call read\r
- shl eax,[cnt]\r
- or [b2],eax\r
- add cnt,8\r
- cmp cnt,32-8\r
- jb mm\r
-jj:\r
-\r
-*/\r
-\r
+/* depack.c
+
+ Part of the swftools installer.
+
+ Copyright (c) 1997-2004 Matthias Kramm <kramm@quiss.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "stdlib.h"
+#include "stdio.h"
+#include "depack.h"
+
+U32 dbittab[] = {
+ 0x1, 0x2, 0x4, 0x8,
+ 0x10, 0x20, 0x40, 0x80,
+ 0x100, 0x200, 0x400, 0x800,
+ 0x1000, 0x2000, 0x4000, 0x8000,
+ 0x10000, 0x20000, 0x40000, 0x80000,
+ 0x100000, 0x200000, 0x400000, 0x800000,
+ 0x1000000, 0x2000000, 0x4000000, 0x8000000,
+ 0x10000000,0x20000000,0x40000000,0x80000000
+};
+
+static void* malloc_z(int len)
+{
+ void* buf = malloc(len);
+ if(buf == 0) {
+ fprintf(stderr, "\nout of memory\n");
+ exit(1);
+ }
+ memset(buf, 0, len);
+ return buf;
+}
+
+typedef struct _dpackead {
+ int back;
+ int len;
+} dpackead_t;
+
+typedef struct _tree {
+ int depth;
+ U8 bits[17];
+ U32 base[17];
+} tree_t;
+
+typedef struct _depack_internal
+{
+ int DMEMSIZE;
+ int DMEMSIZEA;
+
+ tree_t T_REP;
+ tree_t T_STORE;
+ tree_t T_CNUM;
+ tree_t T_BACK;
+ tree_t T_BACK2;
+ tree_t T_BACK3;
+
+ dpackead_t dpackead;
+
+ void*reader;
+ readfunc_t readfunc;
+ void*writer;
+ writefunc_t writefunc;
+
+ U8* mem;
+ int mempos;
+ int pos;
+ U8 c;
+ U32 b;
+} depack_internal_t;
+
+void depack_destroy(depack_t*d)
+{
+ depack_internal_t*i = (depack_internal_t*)d->internal;
+ free(i->mem);i->mem=0;
+ free(d->internal);d->internal=0;i=0;
+}
+
+static readbytes(depack_t*d, int num)
+{
+ depack_internal_t*i = (depack_internal_t*)d->internal;
+
+ if(i->mempos+num<=i->DMEMSIZE) {
+ i->readfunc(i->reader, &i->mem[i->mempos],num);
+ i->writefunc(i->writer, &i->mem[i->mempos],num);
+ } else {
+ i->readfunc(i->reader, &i->mem[i->mempos],i->DMEMSIZE - i->mempos);
+ i->writefunc(i->writer, &i->mem[i->mempos],i->DMEMSIZE - i->mempos);
+ i->readfunc(i->reader, &i->mem[0],num-(i->DMEMSIZE - i->mempos));
+ i->writefunc(i->writer, &i->mem[0],num-(i->DMEMSIZE - i->mempos));
+ }
+ i->mempos=(i->mempos+num)&i->DMEMSIZEA;
+ i->pos+=num;
+}
+
+int move(U8*dest, U8*src, int len)
+{
+ if(len) do {
+ *dest=*src;
+ src++;
+ dest++;
+ } while(--len);
+}
+
+static lookback(depack_t*d, int back,int len)
+{
+ depack_internal_t*i = (depack_internal_t*)d->internal;
+
+ int x,z=(i->mempos-back)&i->DMEMSIZEA;
+ char fail=0;
+
+ if(i->mempos+len <= i->DMEMSIZE &&
+ z+len <= i->DMEMSIZE)
+ {
+ move(&i->mem[i->mempos],&i->mem[z],len);
+ i->writefunc(i->writer, &i->mem[i->mempos],len);
+ i->mempos=(i->mempos+len)&i->DMEMSIZEA;
+ } else {
+ for(x=0;x<len;x++) {
+ i->mem[i->mempos]=i->mem[z];
+ i->writefunc(i->writer, &i->mem[i->mempos],1);
+ i->mempos=(i->mempos+1)&i->DMEMSIZEA;
+ z=(z+1)&i->DMEMSIZEA;
+ }
+ }
+ i->pos += len;
+}
+
+static inline U8 readbit(depack_internal_t*i)
+{
+ i->c&=31;
+ if(i->c==0) i->readfunc(i->reader, &i->b,4);
+ return (i->b>>(31-i->c++))&1;
+}
+
+static inline U32 readval(depack_internal_t*i,int b)
+{
+ unsigned v=0;
+ signed char l;
+ for(l=b-1;l>=0;l--)
+ v|=readbit(i)<<l;
+ return v;
+}
+
+static tree_t gettree(depack_t*d)
+{
+ depack_internal_t*i = (depack_internal_t*)d->internal;
+
+ int l;
+ int x,y,z=0,b=0,r;
+ tree_t tree;
+ memset(&tree, 0, sizeof(tree));
+
+ tree.depth = readval(i,4)+1;
+
+ for(x=0;x<tree.depth;x++)
+ {
+ tree.base[x]=z;
+ r=0;while(!readbit(i)) r++;
+ if(readbit(i)) r=-r;
+ b+=r;
+ tree.bits[x]=b;
+ z+=dbittab[b];
+ }
+ tree.base[tree.depth]=z;
+ tree.bits[tree.depth]=0;
+ return tree;
+
+/* for(z=0;z<=l;z++)
+ {
+ if(i->ttree[n].bits[z]>16)
+ printf(".");
+ else
+ printf("%c","0123456789abcdefg"[ttree[n].bits[z]]);
+ }
+ printf("\n");*/
+}
+
+static void showtree(tree_t tree)
+{
+ int t;
+ int last=0;
+ int lastbits = 0;
+ for(t=0;t<=tree.depth;t++)
+ {
+ if(t>0)
+ printf("[%d] %d: %05x-%05x (%d=%d+%d+1)\n",t,lastbits, last,tree.base[t],lastbits+(t-1)+1, lastbits,t-1);
+ last=tree.base[t];
+ lastbits = tree.bits[t];
+ }
+}
+
+static int gettreeval(depack_t*d, tree_t*tree)
+{
+ depack_internal_t*i = (depack_internal_t*)d->internal;
+
+ U8 x=0;
+ while(!readbit(i)) x++;
+ if(x<17) return tree->base[x]+readval(i, tree->bits[x]);
+ else return -1;
+}
+
+static int get_memsize(int b)
+{
+ int t,c=1;
+ for(t=0;;t++) {
+ if(c>=b) return c;
+ c<<=1;
+ }
+ return 0;
+}
+
+void depack_init(depack_t*d, void*reader, readfunc_t readfunc)
+{
+ d->internal = malloc_z(sizeof(depack_internal_t));
+ depack_internal_t*i = (depack_internal_t*)d->internal;
+ if(i==0) {
+ fprintf(stderr, "depacker not initialized yet"); exit(1);
+ }
+
+ i->reader = reader;
+ i->readfunc = readfunc;
+
+ i->mempos=0;
+ i->pos=0;
+ i->b=i->c=0;
+
+ i->readfunc(i->reader,&i->dpackead.back, 4);
+ i->readfunc(i->reader,&i->dpackead.len, 4);
+
+ i->DMEMSIZE = get_memsize(i->dpackead.len);
+ i->DMEMSIZEA = i->DMEMSIZE-1;
+ i->mem = malloc_z(i->DMEMSIZE);
+
+ i->T_REP = gettree(d);
+ i->T_STORE = gettree(d);
+ i->T_CNUM = gettree(d);
+ //showtree(i->T_CNUM);
+ i->T_BACK = gettree(d);
+ //showtree(i->T_BACK);
+ i->T_BACK2 = gettree(d);
+ //showtree(i->T_BACK);
+ i->T_BACK3 = gettree(d);
+ //showtree(i->T_BACK3);
+
+ d->size = i->dpackead.len;
+}
+
+void depack_process(depack_t*d, void*writer,writefunc_t writefunc)
+{
+ depack_internal_t*i = (depack_internal_t*)d->internal;
+ i->writer = writer;
+ i->writefunc = writefunc;
+ while(i->pos<i->dpackead.len)
+ {
+ int store,rep,x;
+
+ store=gettreeval(d,&i->T_STORE)+1;
+
+ readbytes(d,store);
+
+ if(i->pos<i->dpackead.len)
+ {
+ rep = gettreeval(d,&i->T_REP)+1;
+
+ for(x=0;x<rep;x++)
+ {
+ int back,len;
+ len = gettreeval(d,&i->T_CNUM)+1;
+
+ if(len == 1) back = readval(i,3)+1;
+ if(len == 2) back = gettreeval(d,&i->T_BACK2)+1;
+ if(len == 3) back = gettreeval(d,&i->T_BACK3)+1;
+ if(len >= 4) back = gettreeval(d,&i->T_BACK)+1;
+
+ lookback(d,back,len);
+ }
+ }
+ }
+
+ if(i->pos!=i->dpackead.len) {
+ fprintf(stderr, "Internal error");
+ exit(1);
+ }
+}
+
+/*
+
+ mov eax,[b1]
+ mov ebx,[b2]
+ shld eax,ebx,cl
+ mov [b1],eax
+ shr ebx,cl
+ mov [b2],ebx
+ sub cnt,cl
+ cmp cnt,32-8
+ ja jj
+mm: xor eax,eax
+ call read
+ shl eax,[cnt]
+ or [b2],eax
+ add cnt,8
+ cmp cnt,32-8
+ jb mm
+jj:
+
+*/
+