3 Part of the swftools installer.
5 Copyright (c) 1997-2004 Matthias Kramm <kramm@quiss.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
27 0x10, 0x20, 0x40, 0x80,
28 0x100, 0x200, 0x400, 0x800,
29 0x1000, 0x2000, 0x4000, 0x8000,
30 0x10000, 0x20000, 0x40000, 0x80000,
31 0x100000, 0x200000, 0x400000, 0x800000,
32 0x1000000, 0x2000000, 0x4000000, 0x8000000,
33 0x10000000,0x20000000,0x40000000,0x80000000
36 static void* malloc_z(int len)
38 void* buf = malloc(len);
40 fprintf(stderr, "\nout of memory\n");
47 typedef struct _dpackead {
52 typedef struct _tree {
58 typedef struct _depack_internal
75 writefunc_t writefunc;
84 void depack_destroy(depack_t*d)
86 depack_internal_t*i = (depack_internal_t*)d->internal;
87 free(i->mem);i->mem=0;
88 free(d->internal);d->internal=0;i=0;
91 static readbytes(depack_t*d, int num)
93 depack_internal_t*i = (depack_internal_t*)d->internal;
95 if(i->mempos+num<=i->DMEMSIZE) {
96 i->readfunc(i->reader, &i->mem[i->mempos],num);
97 i->writefunc(i->writer, &i->mem[i->mempos],num);
99 i->readfunc(i->reader, &i->mem[i->mempos],i->DMEMSIZE - i->mempos);
100 i->writefunc(i->writer, &i->mem[i->mempos],i->DMEMSIZE - i->mempos);
101 i->readfunc(i->reader, &i->mem[0],num-(i->DMEMSIZE - i->mempos));
102 i->writefunc(i->writer, &i->mem[0],num-(i->DMEMSIZE - i->mempos));
104 i->mempos=(i->mempos+num)&i->DMEMSIZEA;
108 int move(U8*dest, U8*src, int len)
117 static lookback(depack_t*d, int back,int len)
119 depack_internal_t*i = (depack_internal_t*)d->internal;
121 int x,z=(i->mempos-back)&i->DMEMSIZEA;
124 if(i->mempos+len <= i->DMEMSIZE &&
125 z+len <= i->DMEMSIZE)
127 move(&i->mem[i->mempos],&i->mem[z],len);
128 i->writefunc(i->writer, &i->mem[i->mempos],len);
129 i->mempos=(i->mempos+len)&i->DMEMSIZEA;
132 i->mem[i->mempos]=i->mem[z];
133 i->writefunc(i->writer, &i->mem[i->mempos],1);
134 i->mempos=(i->mempos+1)&i->DMEMSIZEA;
135 z=(z+1)&i->DMEMSIZEA;
141 static inline U8 readbit(depack_internal_t*i)
144 if(i->c==0) i->readfunc(i->reader, &i->b,4);
145 return (i->b>>(31-i->c++))&1;
148 static inline U32 readval(depack_internal_t*i,int b)
157 static tree_t gettree(depack_t*d)
159 depack_internal_t*i = (depack_internal_t*)d->internal;
164 memset(&tree, 0, sizeof(tree));
166 tree.depth = readval(i,4)+1;
168 for(x=0;x<tree.depth;x++)
171 r=0;while(!readbit(i)) r++;
177 tree.base[tree.depth]=z;
178 tree.bits[tree.depth]=0;
183 if(i->ttree[n].bits[z]>16)
186 printf("%c","0123456789abcdefg"[ttree[n].bits[z]]);
191 static void showtree(tree_t tree)
196 for(t=0;t<=tree.depth;t++)
199 printf("[%d] %d: %05x-%05x (%d=%d+%d+1)\n",t,lastbits, last,tree.base[t],lastbits+(t-1)+1, lastbits,t-1);
201 lastbits = tree.bits[t];
205 static int gettreeval(depack_t*d, tree_t*tree)
207 depack_internal_t*i = (depack_internal_t*)d->internal;
210 while(!readbit(i)) x++;
211 if(x<17) return tree->base[x]+readval(i, tree->bits[x]);
215 static int get_memsize(int b)
225 void depack_init(depack_t*d, void*reader, readfunc_t readfunc)
227 d->internal = malloc_z(sizeof(depack_internal_t));
228 depack_internal_t*i = (depack_internal_t*)d->internal;
230 fprintf(stderr, "depacker not initialized yet"); exit(1);
234 i->readfunc = readfunc;
240 i->readfunc(i->reader,&i->dpackead.back, 4);
241 i->readfunc(i->reader,&i->dpackead.len, 4);
243 i->DMEMSIZE = get_memsize(i->dpackead.len);
244 i->DMEMSIZEA = i->DMEMSIZE-1;
245 i->mem = malloc_z(i->DMEMSIZE);
247 i->T_REP = gettree(d);
248 i->T_STORE = gettree(d);
249 i->T_CNUM = gettree(d);
250 //showtree(i->T_CNUM);
251 i->T_BACK = gettree(d);
252 //showtree(i->T_BACK);
253 i->T_BACK2 = gettree(d);
254 //showtree(i->T_BACK);
255 i->T_BACK3 = gettree(d);
256 //showtree(i->T_BACK3);
258 d->size = i->dpackead.len;
261 void depack_process(depack_t*d, void*writer,writefunc_t writefunc)
263 depack_internal_t*i = (depack_internal_t*)d->internal;
265 i->writefunc = writefunc;
266 while(i->pos<i->dpackead.len)
270 store=gettreeval(d,&i->T_STORE)+1;
274 if(i->pos<i->dpackead.len)
276 rep = gettreeval(d,&i->T_REP)+1;
281 len = gettreeval(d,&i->T_CNUM)+1;
283 if(len == 1) back = readval(i,3)+1;
284 if(len == 2) back = gettreeval(d,&i->T_BACK2)+1;
285 if(len == 3) back = gettreeval(d,&i->T_BACK3)+1;
286 if(len >= 4) back = gettreeval(d,&i->T_BACK)+1;
288 lookback(d,back,len);
293 if(i->pos!=i->dpackead.len) {
294 fprintf(stderr, "Internal error");