#include #include #include #include #include #include using std::string; typedef uint8_t U8; typedef uint16_t U16; typedef uint32_t U32; typedef uint64_t U64; template struct Array{ T*data; size_t n; Array(size_t sz=0,int ex=0):data(0),n(0){ resize(sz,ex); } void resize(size_t sz,int ex=0); ~Array(){ resize(0); } size_t size(){ return n; } T&operator[](size_t i){ return data[i]; } T&operator()(size_t i){ return data[i&(n-1)]; } } ; template void Array::resize(size_t sz,int ex){ if(n>0)free((char*)data); n=0; if(sz==0)return; n=sz<hd,m; Arrayh,r; int cend,hbegin,hend,f,pc; U32 a,b,c,d; void init(int hbits,int mbits); int execute(); void div(U32 x){ if(x)a/=x; else a=0; } void mod(U32 x){ if(x)a%=x; else a=0; } void swap(U32&x){ a^=x; x^=a; a^=x; } void swap(U8&x){ a^=x; x^=a; a^=x; } } ; int ZP::read(FILE*in2){ int hsize=getc(in2); hsize+=getc(in2)*256; hd.resize(hsize+300); cend=hbegin=hend=0; hd[cend++]=hsize&255; hd[cend++]=hsize>>8; while(cend<7)hd[cend++]=getc(in2); int n=hd[cend-1]; for(int i=0;i>=,&31) C(216,f=,==a) C(224,f=,>a) C(232,f=,cm; Arrayht; Arraya16; void init(); CP(){ init(); } } ; void CP::init(){ limit=cxt=a=b=c=0; cm.resize(0); ht.resize(0); a16.resize(0); } struct ST{ enum{ N=64} ; int nns(int n0,int n1); void ds(int&n0); void nx(int&n0,int&n1,int y); U8 ns[1024]; int cminit(int state){ return((ns[state*4+3]*2+1)<<22)/(ns[state*4+2]+ns[state*4+3]+1); } ST(); } ; int ST::nns(int n0,int n1){ const int B=6,bound[B]={ 20,48,15,8,6,5} ; if(n0=B||n0>bound[n1])return 0; return 1+(n1>0&&n0+n1<=17); } void ST::ds(int&n0){ n0=(n0>=1)+(n0>=2)+(n0>=3)+(n0>=4)+(n0>=5)+(n0>=7)+(n0>=8); } void ST::nx(int&n0,int&n1,int y){ if(n0>17); pn+=(error*dt[count]&-1024)+(count2047)return 2047; else return x; } int clamp512k(int x){ if(x<-(1<<19))return -(1<<19); else if(x>=(1<<19))return(1<<19)-1; else return x; } size_t find(Array&ht,int sizebits,U32 cxt); } ; PR::PR(ZP&zr): c8(1),hmap4(1),z(zr){ dt2k[0]=0; for(int i=1;i<256;++i) dt2k[i]=2048/i; for(int i=0;i<1024;++i) dt[i]=(1<<17)/(i*2+3)*2; for(int i=0;i<32768;++i) stretcht[i]=int(log((i+0.5)/(32767.5-i))*64+0.5+100000)-100000; for(int i=0;i<4096;++i) squasht[i]=int(32768.0/(1+exp((i-2048)*(-1.0/64)))); } void PR::init(){ z.init(z.hd[2],z.hd[3]); for(int i=0;i<256;++i)h[i]=p[i]=0; for(int i=0;i<256;++i)comp[i].init(); int n=z.hd[6]; const U8*cp=&z.hd[7]; for(int i=0;i>8)<<10); } break; case SSE: cr.cm.resize(32,cp[1]); cr.limit=cp[4]*4; for(size_t j=0;j>17); break; case ICM: if(c8==1||(c8&0xf0)==16)cr.c=find(cr.ht,cp[1]+2,h[i]+16*c8); cr.cxt=cr.ht[cr.c+(hmap4&15)]; p[i]=stretch(cr.cm(cr.cxt)>>8); break; case MATCH: if(cr.a==0)p[i]=0; else{ cr.c=(cr.ht(cr.limit-cr.b)>>(7-cr.cxt))&1; p[i]=stretch(dt2k[cr.a]*(cr.c*-2+1)&32767); } break; case AVG: p[i]=(p[cp[1]]*cp[3]+p[cp[2]]*(256-cp[3]))>>8; break; case MIX2:{ cr.cxt=((h[i]+(c8&cp[5]))&(cr.c-1)); int w=cr.a16[cr.cxt]; p[i]=(w*p[cp[2]]+(65536-w)*p[cp[3]])>>16; } break; case MIX:{ int m=cp[3]; cr.cxt=h[i]+(c8&cp[5]); cr.cxt=(cr.cxt&(cr.c-1))*m; int*wt=(int*)&cr.cm[cr.cxt]; p[i]=0; for(int j=0;j>8)*p[cp[2]+j]; p[i]=clamp2k(p[i]>>8); } break; case ISSE:{ if(c8==1||(c8&0xf0)==16) cr.c=find(cr.ht,cp[1]+2,h[i]+16*c8); cr.cxt=cr.ht[cr.c+(hmap4&15)]; int*wt=(int*)&cr.cm[cr.cxt*2]; p[i]=clamp2k((wt[0]*p[cp[2]]+wt[1]*64)>>16); } break; case SSE:{ cr.cxt=(h[i]+c8)*32; int pq=p[cp[2]]+992; if(pq<0)pq=0; if(pq>1983)pq=1983; int wt=pq&63; pq>>=6; cr.cxt+=pq; p[i]=stretch(((cr.cm(cr.cxt)>>10)*(64-wt)+(cr.cm(cr.cxt+1)>>10)*wt) >>13); cr.cxt+=wt>>5; } } cp+=compsize[cp[0]]; } return squash(p[n-1]); } void PR::update(int y){ const U8*cp=&z.hd[7]; int n=z.hd[6]; for(int i=0;i>8))>>2; } break; case MATCH: { if(int(cr.c)!=y)cr.a=0; cr.ht(cr.limit)+=cr.ht(cr.limit)+y; if(++cr.cxt==8){ cr.cxt=0; ++cr.limit; cr.limit&=(1<>5; int w=cr.a16[cr.cxt]; w+=(err*(p[cp[2]]-p[cp[3]])+(1<<12))>>13; if(w<0)w=0; if(w>65535)w=65535; cr.a16[cr.cxt]=w; } break; case MIX:{ int m=cp[3]; int err=(y*32767-squash(p[i]))*cp[4]>>4; int*wt=(int*)&cr.cm[cr.cxt]; for(int j=0;j>13)); } break; case ISSE:{ int err=y*32767-squash(p[i]); int*wt=(int*)&cr.cm[cr.cxt*2]; wt[0]=clamp512k(wt[0]+((err*p[cp[2]]+(1<<12))>>13)); wt[1]=clamp512k(wt[1]+((err+16)>>5)); cr.ht[cr.c+(hmap4&15)]=st.ns[cr.cxt*4+y]; } break; case SSE: train(cr,y); } cp+=compsize[cp[0]]; } c8+=c8+y; if(c8>=256){ z.run(c8-256); hmap4=1; c8=1; for(int i=0;i=16&&c8<32) hmap4=(hmap4&0xf)<<5|y<<4|1; else hmap4=(hmap4&0x1f0)|(((hmap4&0xf)*2+y)&0xf); } size_t PR::find(Array&ht,int sizebits,U32 cxt){ int chk=cxt>>sizebits&255; size_t h0=(cxt*16)&(ht.size()-16); if(ht[h0]==chk)return h0; size_t h1=h0^16; if(ht[h1]==chk)return h1; size_t h2=h0^32; if(ht[h2]==chk)return h2; if(ht[h0+1]<=ht[h1+1]&&ht[h0+1]<=ht[h2+1]) return memset(&ht[h0],0,16),ht[h0]=chk,h0; else if(ht[h1+1]>16); int y=curr<=mid; if(y)high=mid; else low=mid+1; while((high^low)<0x1000000){ high=high<<8|255; low=low<<8; low+=(low==0); curr=curr<<8|getc(in); } return y; } int DE::de(){ if(pr.im()){ if(curr==0){ for(int i=0;i<4;++i) curr=curr<<8|getc(in); } if(decode(0)){ return -1; } else{ int c=1; while(c<256){ int p=pr.predict()*2+1; c+=c+decode(p); pr.update(c&1); } return c-256; } } else{ if(curr==0){ for(int i=0;i<4;++i) curr=curr<<8|getc(in); if(curr==0)return -1; } --curr; return getc(in); } } struct PP{ int state; int hsize; int ph,pm; ZP z; PP():state(0),hsize(0),ph(0),pm(0){ } void init(int h,int m); int write(int c); } ; void PP::init(int h,int m){ state=hsize=0; ph=h; pm=m; z.clear(); } int PP::write(int c){ switch(state){ case 0: state=c+1; if(state==1)z.clear(); break; case 1: if(c>=0&&z.out)putc(c,z.out); break; case 2: hsize=c; state=3; break; case 3: hsize+=c*256; z.hd.resize(hsize+300); z.cend=8; z.hbegin=z.hend=z.cend+128; z.hd[4]=ph; z.hd[5]=pm; state=4; break; case 4: z.hd[z.hend++]=c; if(z.hend-z.hbegin==hsize){ hsize=z.cend-2+z.hend-z.hbegin; z.hd[0]=hsize&255; z.hd[1]=hsize>>8; z.init(z.hd[4],z.hd[5]); state=5; } break; case 5: z.run(c); break; } return state; } struct DC{ DC():z(),dec(z),pp(),ds(0){ } bool fb(); bool ff(string&); void de(); ZP z; DE dec; PP pp; int ds; } ; bool DC::fb(){ U32 h1=0x3D49B113,h2=0x29EB7F93,h3=0x2614BE13,h4=0x3828EB13; int c; while((c=getc(dec.in))!=EOF){ h1=h1*12+c; h2=h2*20+c; h3=h3*28+c; h4=h4*44+c; if(h1==0xB16B88F1&&h2==0xFF5376F1&&h3==0x72AC5BF1&&h4==0x2F909AF1) break; } if(c<0)return false; getc(dec.in); getc(dec.in); z.read(dec.in); ds=0; return true; } bool DC::ff(string&filename){ int c=getc(dec.in); if(c==1){ while(true){ c=getc(dec.in); if(c==0){ return true; } filename+=char(c); } } return false; } void DC::de(){ while(getc(dec.in)); getc(dec.in); if(ds==0){ dec.init(); pp.init(z.hd[4],z.hd[5]); ds=1; } while((pp.state&3)!=1) pp.write(dec.de()); while(true){ int c=dec.de(); pp.write(c); if(c==-1)break; } if(getc(dec.in)==253){ for(int i=1;i<=20;++i) getc(dec.in); } } int main(int argc,char**argv){ DC d; if(argc<2||!(d.dec.in=fopen(argv[1],"rb")))return 0; string sout; while(d.fb()){ while(d.ff(sout)){ if(sout!=""){ if(d.pp.z.out)fclose(d.pp.z.out); d.pp.z.out=fopen(sout.c_str(),"wb"); sout=""; } d.de(); } } return 0; }