Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

756
LINES

< > BotCompany Repo | #1031420 // ZPAQ decompressor, C++

Document

1  
#include<stdio.h>
2  
#include<stdlib.h>
3  
#include<string.h>
4  
#include<math.h>
5  
#include<stdint.h>
6  
#include<string>
7  
using std::string;
8  
typedef uint8_t U8;
9  
typedef uint16_t U16;
10  
typedef uint32_t U32;
11  
typedef uint64_t U64;
12  
template<typename T>
13  
struct Array{
14  
T*data;
15  
size_t n;
16  
Array(size_t sz=0,int ex=0):data(0),n(0){
17  
resize(sz,ex);
18  
}
19  
void resize(size_t sz,int ex=0);
20  
~Array(){
21  
resize(0);
22  
}
23  
size_t size(){
24  
return n;
25  
}
26  
T&operator[](size_t i){
27  
return data[i];
28  
}
29  
T&operator()(size_t i){
30  
return data[i&(n-1)];
31  
}
32  
}
33  
;
34  
template<typename T>
35  
void Array<T>::resize(size_t sz,int ex){
36  
if(n>0)free((char*)data);
37  
n=0;
38  
if(sz==0)return;
39  
n=sz<<ex;
40  
const size_t nb=128+n*sizeof(T);
41  
data=(T*)calloc(nb,1);
42  
}
43  
typedef enum{
44  
NONE,CONS,CM,ICM,MATCH,AVG,MIX2,MIX,ISSE,SSE}
45  
CompType;
46  
const int compsize[256]={
47  
0,2,3,2,3,4,6,6,3,5}
48  
;
49  
struct ZP{
50  
ZP(){
51  
out=0;
52  
clear();
53  
}
54  
void clear();
55  
void run(U32 input){
56  
pc=hbegin;
57  
a=input;
58  
while(execute());
59  
}
60  
int read(FILE*in2);
61  
FILE*out;
62  
Array<U8>hd,m;
63  
Array<U32>h,r;
64  
int cend,hbegin,hend,f,pc;
65  
U32 a,b,c,d;
66  
void init(int hbits,int mbits);
67  
int execute();
68  
void div(U32 x){
69  
if(x)a/=x;
70  
else a=0;
71  
}
72  
void mod(U32 x){
73  
if(x)a%=x;
74  
else a=0;
75  
}
76  
void swap(U32&x){
77  
a^=x;
78  
x^=a;
79  
a^=x;
80  
}
81  
void swap(U8&x){
82  
a^=x;
83  
x^=a;
84  
a^=x;
85  
}
86  
}
87  
;
88  
int ZP::read(FILE*in2){
89  
int hsize=getc(in2);
90  
hsize+=getc(in2)*256;
91  
hd.resize(hsize+300);
92  
cend=hbegin=hend=0;
93  
hd[cend++]=hsize&255;
94  
hd[cend++]=hsize>>8;
95  
while(cend<7)hd[cend++]=getc(in2);
96  
int n=hd[cend-1];
97  
for(int i=0;i<n;++i){
98  
int type=getc(in2);
99  
hd[cend++]=type;
100  
int size=compsize[type];
101  
for(int j=1;j<size;++j)
102  
hd[cend++]=getc(in2);
103  
}
104  
hd[cend++]=getc(in2);
105  
hbegin=hend=cend+128;
106  
while(hend<hsize+129){
107  
int op=getc(in2);
108  
hd[hend++]=op;
109  
}
110  
hd[hend++]=getc(in2);
111  
return cend+hend-hbegin;
112  
}
113  
void ZP::clear(){
114  
cend=hbegin=hend=0;
115  
hd.resize(0);
116  
a=b=c=d=f=pc=0;
117  
h.resize(0);
118  
m.resize(0);
119  
r.resize(0);
120  
}
121  
void ZP::init(int hbits,int mbits){
122  
a=b=c=d=f=pc=0;
123  
h.resize(1,hbits);
124  
m.resize(1,mbits);
125  
r.resize(256);
126  
}
127  
#define C(i,L,R)\
128  
case i:L(a R);break;\
129  
case i+1:L(b R);break;\
130  
case i+2:L(c R);break;\
131  
case i+3:L(d R);break;\
132  
case i+4:L(U32(m(b))R);break;\
133  
case i+5:L(U32(m(c))R);break;\
134  
case i+6:L(h(d) R);break;\
135  
case i+7:L(U32(hd[pc++])R);break;
136  
#define C1(i,x)\
137  
case i:swap(x);break;\
138  
case i+1:++x;break;\
139  
case i+2:--x;break;\
140  
case i+3:x=~x;break;\
141  
case i+4:x=0;break;
142  
int ZP::execute(){
143  
switch(hd[pc++]){
144  
case 7:a=r[hd[pc++]];break;
145  
case 15:b=r[hd[pc++]];break;
146  
case 23:c=r[hd[pc++]];break;
147  
case 31:d=r[hd[pc++]];break;
148  
case 39:if(f)pc+=((hd[pc]+128)&255)-127;else ++pc;break;
149  
case 47:if(!f)pc+=((hd[pc]+128)&255)-127;else ++pc;break;
150  
case 55:r[hd[pc++]]=a;break;
151  
case 56:return 0;
152  
case 57:if(out)putc(a,out);break;
153  
case 59:a=(a+m(b)+512)*773;break;
154  
case 60:h(d)=(h(d)+a+512)*773;break;
155  
case 63:pc+=((hd[pc]+128)&255)-127;break;
156  
C1(0,a)
157  
C1(8,b)
158  
C1(16,c)
159  
C1(24,d)
160  
C1(32,m(b))
161  
C1(40,m(c))
162  
C1(48,h(d))
163  
C(64,a=,)
164  
C(72,b=,)
165  
C(80,c=,)
166  
C(88,d=,)
167  
C(96,m(b)=,)
168  
C(104,m(c)=,)
169  
C(112,h(d)=,)
170  
C(128,a+=,)
171  
C(136,a-=,)
172  
C(144,a*=,)
173  
C(152,div,)
174  
C(160,mod,)
175  
C(168,a&=,)
176  
C(176,a&= ~,)
177  
C(184,a|=,)
178  
C(192,a^=,)
179  
C(200,a<<=,&31)
180  
C(208,a>>=,&31)
181  
C(216,f=,==a)
182  
C(224,f=,>a)
183  
C(232,f=,<a)
184  
}
185  
return 1;
186  
}
187  
struct CP{
188  
U32 limit,cxt,a,b,c;
189  
Array<U32>cm;
190  
Array<U8>ht;
191  
Array<U16>a16;
192  
void init();
193  
CP(){
194  
init();
195  
}
196  
}
197  
;
198  
void CP::init(){
199  
limit=cxt=a=b=c=0;
200  
cm.resize(0);
201  
ht.resize(0);
202  
a16.resize(0);
203  
}
204  
struct ST{
205  
enum{
206  
N=64}
207  
;
208  
int nns(int n0,int n1);
209  
void ds(int&n0);
210  
void nx(int&n0,int&n1,int y);
211  
U8 ns[1024];
212  
int cminit(int state){
213  
return((ns[state*4+3]*2+1)<<22)/(ns[state*4+2]+ns[state*4+3]+1);
214  
}
215  
ST();
216  
}
217  
;
218  
int ST::nns(int n0,int n1){
219  
const int B=6,bound[B]={
220  
20,48,15,8,6,5}
221  
;
222  
if(n0<n1)return nns(n1,n0);
223  
if(n0<0||n1<0||n1>=B||n0>bound[n1])return 0;
224  
return 1+(n1>0&&n0+n1<=17);
225  
}
226  
void ST::ds(int&n0){
227  
n0=(n0>=1)+(n0>=2)+(n0>=3)+(n0>=4)+(n0>=5)+(n0>=7)+(n0>=8);
228  
}
229  
void ST::nx(int&n0,int&n1,int y){
230  
if(n0<n1)
231  
nx(n1,n0,1-y);
232  
else{
233  
if(y){
234  
++n1;
235  
ds(n0);
236  
}
237  
else{
238  
++n0;
239  
ds(n1);
240  
}
241  
while(!nns(n0,n1)){
242  
if(n1<2)--n0;
243  
else{
244  
n0=(n0*(n1-1)+(n1/2))/n1;
245  
--n1;
246  
}
247  
}
248  
}
249  
}
250  
ST::ST(){
251  
const int N=50;
252  
U8 t[N][N][2]={
253  
{
254  
{
255  
0}
256  
}
257  
}
258  
;
259  
int state=0;
260  
for(int i=0;i<N;++i){
261  
for(int n1=0;n1<=i;++n1){
262  
int n0=i-n1;
263  
int n=nns(n0,n1);
264  
if(n){
265  
t[n0][n1][0]=state;
266  
t[n0][n1][1]=state+n-1;
267  
state+=n;
268  
}
269  
}
270  
}
271  
memset(ns,0,sizeof(ns));
272  
for(int n0=0;n0<N;++n0){
273  
for(int n1=0;n1<N;++n1){
274  
for(int y=0;y<nns(n0,n1);++y){
275  
int s=t[n0][n1][y];
276  
int s0=n0,s1=n1;
277  
nx(s0,s1,0);
278  
ns[s*4+0]=t[s0][s1][0];
279  
s0=n0,s1=n1;
280  
nx(s0,s1,1);
281  
ns[s*4+1]=t[s0][s1][1];
282  
ns[s*4+2]=n0;
283  
ns[s*4+3]=n1;
284  
}
285  
}
286  
}
287  
}
288  
struct PR{
289  
PR(ZP&);
290  
void init();
291  
int predict();
292  
void update(int y);
293  
bool im(){
294  
return z.hd[6]!=0;
295  
}
296  
int c8,hmap4,p[256];
297  
U32 h[256];
298  
ZP&z;
299  
CP comp[256];
300  
int dt2k[256];
301  
int dt[1024];
302  
U16 squasht[4096];
303  
short stretcht[32768];
304  
ST st;
305  
void train(CP&cr,int y){
306  
U32&pn=cr.cm(cr.cxt);
307  
U32 count=pn&0x3ff;
308  
int error=y*32767-(cr.cm(cr.cxt)>>17);
309  
pn+=(error*dt[count]&-1024)+(count<cr.limit);
310  
}
311  
int squash(int x){
312  
return squasht[x+2048];
313  
}
314  
int stretch(int x){
315  
return stretcht[x];
316  
}
317  
int clamp2k(int x){
318  
if(x<-2048)return -2048;
319  
else if(x>2047)return 2047;
320  
else return x;
321  
}
322  
int clamp512k(int x){
323  
if(x<-(1<<19))return -(1<<19);
324  
else if(x>=(1<<19))return(1<<19)-1;
325  
else return x;
326  
}
327  
size_t find(Array<U8>&ht,int sizebits,U32 cxt);
328  
}
329  
;
330  
PR::PR(ZP&zr):
331  
c8(1),hmap4(1),z(zr){
332  
dt2k[0]=0;
333  
for(int i=1;i<256;++i)
334  
dt2k[i]=2048/i;
335  
for(int i=0;i<1024;++i)
336  
dt[i]=(1<<17)/(i*2+3)*2;
337  
for(int i=0;i<32768;++i)
338  
stretcht[i]=int(log((i+0.5)/(32767.5-i))*64+0.5+100000)-100000;
339  
for(int i=0;i<4096;++i)
340  
squasht[i]=int(32768.0/(1+exp((i-2048)*(-1.0/64))));
341  
}
342  
void PR::init(){
343  
z.init(z.hd[2],z.hd[3]);
344  
for(int i=0;i<256;++i)h[i]=p[i]=0;
345  
for(int i=0;i<256;++i)comp[i].init();
346  
int n=z.hd[6];
347  
const U8*cp=&z.hd[7];
348  
for(int i=0;i<n;++i){
349  
CP&cr=comp[i];
350  
switch(cp[0]){
351  
case CONS:
352  
p[i]=(cp[1]-128)*4;
353  
break;
354  
case CM:
355  
cr.cm.resize(1,cp[1]);
356  
cr.limit=cp[2]*4;
357  
for(size_t j=0;j<cr.cm.size();++j)
358  
cr.cm[j]=0x80000000;
359  
break;
360  
case ICM:
361  
cr.limit=1023;
362  
cr.cm.resize(256);
363  
cr.ht.resize(64,cp[1]);
364  
for(size_t j=0;j<cr.cm.size();++j)
365  
cr.cm[j]=st.cminit(j);
366  
break;
367  
case MATCH:
368  
cr.cm.resize(1,cp[1]);
369  
cr.ht.resize(1,cp[2]);
370  
cr.ht(0)=1;
371  
break;
372  
case MIX2:
373  
cr.c=(size_t(1)<<cp[1]);
374  
cr.a16.resize(1,cp[1]);
375  
for(size_t j=0;j<cr.a16.size();++j)
376  
cr.a16[j]=32768;
377  
break;
378  
case MIX:{
379  
int m=cp[3];
380  
cr.c=(size_t(1)<<cp[1]);
381  
cr.cm.resize(m,cp[1]);
382  
for(size_t j=0;j<cr.cm.size();++j)
383  
cr.cm[j]=65536/m;
384  
break;
385  
}
386  
case ISSE:
387  
cr.ht.resize(64,cp[1]);
388  
cr.cm.resize(512);
389  
for(int j=0;j<256;++j){
390  
cr.cm[j*2]=1<<15;
391  
cr.cm[j*2+1]=clamp512k(stretch(st.cminit(j)>>8)<<10);
392  
}
393  
break;
394  
case SSE:
395  
cr.cm.resize(32,cp[1]);
396  
cr.limit=cp[4]*4;
397  
for(size_t j=0;j<cr.cm.size();++j)
398  
cr.cm[j]=squash((j&31)*64-992)<<17|cp[3];
399  
break;
400  
}
401  
cp+=compsize[*cp];
402  
}
403  
}
404  
int PR::predict(){
405  
int n=z.hd[6];
406  
const U8*cp=&z.hd[7];
407  
for(int i=0;i<n;++i){
408  
CP&cr=comp[i];
409  
switch(cp[0]){
410  
case CM:
411  
cr.cxt=h[i]^hmap4;
412  
p[i]=stretch(cr.cm(cr.cxt)>>17);
413  
break;
414  
case ICM:
415  
if(c8==1||(c8&0xf0)==16)cr.c=find(cr.ht,cp[1]+2,h[i]+16*c8);
416  
cr.cxt=cr.ht[cr.c+(hmap4&15)];
417  
p[i]=stretch(cr.cm(cr.cxt)>>8);
418  
break;
419  
case MATCH:
420  
if(cr.a==0)p[i]=0;
421  
else{
422  
cr.c=(cr.ht(cr.limit-cr.b)>>(7-cr.cxt))&1;
423  
p[i]=stretch(dt2k[cr.a]*(cr.c*-2+1)&32767);
424  
}
425  
break;
426  
case AVG:
427  
p[i]=(p[cp[1]]*cp[3]+p[cp[2]]*(256-cp[3]))>>8;
428  
break;
429  
case MIX2:{
430  
cr.cxt=((h[i]+(c8&cp[5]))&(cr.c-1));
431  
int w=cr.a16[cr.cxt];
432  
p[i]=(w*p[cp[2]]+(65536-w)*p[cp[3]])>>16;
433  
}
434  
break;
435  
case MIX:{
436  
int m=cp[3];
437  
cr.cxt=h[i]+(c8&cp[5]);
438  
cr.cxt=(cr.cxt&(cr.c-1))*m;
439  
int*wt=(int*)&cr.cm[cr.cxt];
440  
p[i]=0;
441  
for(int j=0;j<m;++j)
442  
p[i]+=(wt[j]>>8)*p[cp[2]+j];
443  
p[i]=clamp2k(p[i]>>8);
444  
}
445  
break;
446  
case ISSE:{
447  
if(c8==1||(c8&0xf0)==16)
448  
cr.c=find(cr.ht,cp[1]+2,h[i]+16*c8);
449  
cr.cxt=cr.ht[cr.c+(hmap4&15)];
450  
int*wt=(int*)&cr.cm[cr.cxt*2];
451  
p[i]=clamp2k((wt[0]*p[cp[2]]+wt[1]*64)>>16);
452  
}
453  
break;
454  
case SSE:{
455  
cr.cxt=(h[i]+c8)*32;
456  
int pq=p[cp[2]]+992;
457  
if(pq<0)pq=0;
458  
if(pq>1983)pq=1983;
459  
int wt=pq&63;
460  
pq>>=6;
461  
cr.cxt+=pq;
462  
p[i]=stretch(((cr.cm(cr.cxt)>>10)*(64-wt)+(cr.cm(cr.cxt+1)>>10)*wt)
463  
>>13);
464  
cr.cxt+=wt>>5;
465  
}
466  
}
467  
cp+=compsize[cp[0]];
468  
}
469  
return squash(p[n-1]);
470  
}
471  
void PR::update(int y){
472  
const U8*cp=&z.hd[7];
473  
int n=z.hd[6];
474  
for(int i=0;i<n;++i){
475  
CP&cr=comp[i];
476  
switch(cp[0]){
477  
case CM:
478  
train(cr,y);
479  
break;
480  
case ICM:{
481  
cr.ht[cr.c+(hmap4&15)]=st.ns[cr.ht[cr.c+(hmap4&15)]*4+y];
482  
U32&pn=cr.cm(cr.cxt);
483  
pn+=int(y*32767-(pn>>8))>>2;
484  
}
485  
break;
486  
case MATCH:
487  
{
488  
if(int(cr.c)!=y)cr.a=0;
489  
cr.ht(cr.limit)+=cr.ht(cr.limit)+y;
490  
if(++cr.cxt==8){
491  
cr.cxt=0;
492  
++cr.limit;
493  
cr.limit&=(1<<cp[2])-1;
494  
if(cr.a==0){
495  
cr.b=cr.limit-cr.cm(h[i]);
496  
if(cr.b&(cr.ht.size()-1))
497  
while(cr.a<255&&cr.ht(cr.limit-cr.a-1)==cr.ht(cr.limit-cr.a-cr.b-1))
498  
++cr.a;
499  
}
500  
else cr.a+=cr.a<255;
501  
cr.cm(h[i])=cr.limit;
502  
}
503  
}
504  
break;
505  
case MIX2:{
506  
int err=(y*32767-squash(p[i]))*cp[4]>>5;
507  
int w=cr.a16[cr.cxt];
508  
w+=(err*(p[cp[2]]-p[cp[3]])+(1<<12))>>13;
509  
if(w<0)w=0;
510  
if(w>65535)w=65535;
511  
cr.a16[cr.cxt]=w;
512  
}
513  
break;
514  
case MIX:{
515  
int m=cp[3];
516  
int err=(y*32767-squash(p[i]))*cp[4]>>4;
517  
int*wt=(int*)&cr.cm[cr.cxt];
518  
for(int j=0;j<m;++j)
519  
wt[j]=clamp512k(wt[j]+((err*p[cp[2]+j]+(1<<12))>>13));
520  
}
521  
break;
522  
case ISSE:{
523  
int err=y*32767-squash(p[i]);
524  
int*wt=(int*)&cr.cm[cr.cxt*2];
525  
wt[0]=clamp512k(wt[0]+((err*p[cp[2]]+(1<<12))>>13));
526  
wt[1]=clamp512k(wt[1]+((err+16)>>5));
527  
cr.ht[cr.c+(hmap4&15)]=st.ns[cr.cxt*4+y];
528  
}
529  
break;
530  
case SSE:
531  
train(cr,y);
532  
}
533  
cp+=compsize[cp[0]];
534  
}
535  
c8+=c8+y;
536  
if(c8>=256){
537  
z.run(c8-256);
538  
hmap4=1;
539  
c8=1;
540  
for(int i=0;i<n;++i)h[i]=z.h(i);
541  
}
542  
else if(c8>=16&&c8<32)
543  
hmap4=(hmap4&0xf)<<5|y<<4|1;
544  
else
545  
hmap4=(hmap4&0x1f0)|(((hmap4&0xf)*2+y)&0xf);
546  
}
547  
size_t PR::find(Array<U8>&ht,int sizebits,U32 cxt){
548  
int chk=cxt>>sizebits&255;
549  
size_t h0=(cxt*16)&(ht.size()-16);
550  
if(ht[h0]==chk)return h0;
551  
size_t h1=h0^16;
552  
if(ht[h1]==chk)return h1;
553  
size_t h2=h0^32;
554  
if(ht[h2]==chk)return h2;
555  
if(ht[h0+1]<=ht[h1+1]&&ht[h0+1]<=ht[h2+1])
556  
return memset(&ht[h0],0,16),ht[h0]=chk,h0;
557  
else if(ht[h1+1]<ht[h2+1])
558  
return memset(&ht[h1],0,16),ht[h1]=chk,h1;
559  
else
560  
return memset(&ht[h2],0,16),ht[h2]=chk,h2;
561  
}
562  
struct DE{
563  
FILE*in;
564  
DE(ZP&z);
565  
int de();
566  
void init();
567  
U32 low,high;
568  
U32 curr;
569  
PR pr;
570  
int decode(int p);
571  
}
572  
;
573  
DE::DE(ZP&z):
574  
in(0),low(1),high(0xFFFFFFFF),curr(0),pr(z){
575  
}
576  
void DE::init(){
577  
pr.init();
578  
if(pr.im())low=1,high=0xFFFFFFFF,curr=0;
579  
else low=high=curr=0;
580  
}
581  
int DE::decode(int p){
582  
U32 mid=low+U32(((high-low)*U64(U32(p)))>>16);
583  
int y=curr<=mid;
584  
if(y)high=mid;
585  
else low=mid+1;
586  
while((high^low)<0x1000000){
587  
high=high<<8|255;
588  
low=low<<8;
589  
low+=(low==0);
590  
curr=curr<<8|getc(in);
591  
}
592  
return y;
593  
}
594  
int DE::de(){
595  
if(pr.im()){
596  
if(curr==0){
597  
for(int i=0;i<4;++i)
598  
curr=curr<<8|getc(in);
599  
}
600  
if(decode(0)){
601  
return -1;
602  
}
603  
else{
604  
int c=1;
605  
while(c<256){
606  
int p=pr.predict()*2+1;
607  
c+=c+decode(p);
608  
pr.update(c&1);
609  
}
610  
return c-256;
611  
}
612  
}
613  
else{
614  
if(curr==0){
615  
for(int i=0;i<4;++i)
616  
curr=curr<<8|getc(in);
617  
if(curr==0)return -1;
618  
}
619  
--curr;
620  
return getc(in);
621  
}
622  
}
623  
struct PP{
624  
int state;
625  
int hsize;
626  
int ph,pm;
627  
ZP z;
628  
PP():state(0),hsize(0),ph(0),pm(0){
629  
}
630  
void init(int h,int m);
631  
int write(int c);
632  
}
633  
;
634  
void PP::init(int h,int m){
635  
state=hsize=0;
636  
ph=h;
637  
pm=m;
638  
z.clear();
639  
}
640  
int PP::write(int c){
641  
switch(state){
642  
case 0:
643  
state=c+1;
644  
if(state==1)z.clear();
645  
break;
646  
case 1:
647  
if(c>=0&&z.out)putc(c,z.out);
648  
break;
649  
case 2:
650  
hsize=c;
651  
state=3;
652  
break;
653  
case 3:
654  
hsize+=c*256;
655  
z.hd.resize(hsize+300);
656  
z.cend=8;
657  
z.hbegin=z.hend=z.cend+128;
658  
z.hd[4]=ph;
659  
z.hd[5]=pm;
660  
state=4;
661  
break;
662  
case 4:
663  
z.hd[z.hend++]=c;
664  
if(z.hend-z.hbegin==hsize){
665  
hsize=z.cend-2+z.hend-z.hbegin;
666  
z.hd[0]=hsize&255;
667  
z.hd[1]=hsize>>8;
668  
z.init(z.hd[4],z.hd[5]);
669  
state=5;
670  
}
671  
break;
672  
case 5:
673  
z.run(c);
674  
break;
675  
}
676  
return state;
677  
}
678  
struct DC{
679  
DC():z(),dec(z),pp(),ds(0){
680  
}
681  
bool fb();
682  
bool ff(string&);
683  
void de();
684  
ZP z;
685  
DE dec;
686  
PP pp;
687  
int ds;
688  
}
689  
;
690  
bool DC::fb(){
691  
U32 h1=0x3D49B113,h2=0x29EB7F93,h3=0x2614BE13,h4=0x3828EB13;
692  
int c;
693  
while((c=getc(dec.in))!=EOF){
694  
h1=h1*12+c;
695  
h2=h2*20+c;
696  
h3=h3*28+c;
697  
h4=h4*44+c;
698  
if(h1==0xB16B88F1&&h2==0xFF5376F1&&h3==0x72AC5BF1&&h4==0x2F909AF1)
699  
break;
700  
}
701  
if(c<0)return false;
702  
getc(dec.in);
703  
getc(dec.in);
704  
z.read(dec.in);
705  
ds=0;
706  
return true;
707  
}
708  
bool DC::ff(string&filename){
709  
int c=getc(dec.in);
710  
if(c==1){
711  
while(true){
712  
c=getc(dec.in);
713  
if(c==0){
714  
return true;
715  
}
716  
filename+=char(c);
717  
}
718  
}
719  
return false;
720  
}
721  
void DC::de(){
722  
while(getc(dec.in));
723  
getc(dec.in);
724  
if(ds==0){
725  
dec.init();
726  
pp.init(z.hd[4],z.hd[5]);
727  
ds=1;
728  
}
729  
while((pp.state&3)!=1)
730  
pp.write(dec.de());
731  
while(true){
732  
int c=dec.de();
733  
pp.write(c);
734  
if(c==-1)break;
735  
}
736  
if(getc(dec.in)==253){
737  
for(int i=1;i<=20;++i)
738  
getc(dec.in);
739  
}
740  
}
741  
int main(int argc,char**argv){
742  
DC d;
743  
if(argc<2||!(d.dec.in=fopen(argv[1],"rb")))return 0;
744  
string sout;
745  
while(d.fb()){
746  
while(d.ff(sout)){
747  
if(sout!=""){
748  
if(d.pp.z.out)fclose(d.pp.z.out);
749  
d.pp.z.out=fopen(sout.c_str(),"wb");
750  
sout="";
751  
}
752  
d.de();
753  
}
754  
}
755  
return 0;
756  
}

download  show line numbers   

Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1031420
Snippet name: ZPAQ decompressor, C++
Eternal ID of this version: #1031420/1
Text MD5: e5d306ed04e90a89961178559ec6be72
Author: stefan
Category: zpaq
Type: Document
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-06-12 04:30:25
Source code size: 13106 bytes / 756 lines
Pitched / IR pitched: No / No
Views / Downloads: 125 / 51
Referenced in: [show references]