#ifndef b_pack22_haha #define b_pack22_haha #include #include #include #include #include int P1Pack2(char*,char*,int); int P1UnPack2(char*,char*,int); struct QL1Element{ QL1Element* next; void* inhalt; }; struct QL1Liste{ QL1Element* first; QL1Element* last; char name[10]; int data; }; struct C1Buffer{ ULONG numbits; ULONG countbit; unsigned char* buffer; }; struct C1CharInfo{ ULONG count; C1CharInfo* left,* right,* prevtree; char ischar; unsigned char wert; char code[30]; char clength; }; void P1Sort(C1CharInfo**,int); //private void P1Eintragen(C1CharInfo*); //private void P1Hilf1(C1CharInfo*); //private void QL1AllesLoeschen(QL1Liste&,int dodelete=0); //private void QL1Init(QL1Liste&); //private QL1Element* QL1Einfuegen(QL1Liste&,QL1Element*); //private void P1Hilf1(C1CharInfo* c1){ if(c1->left){ strcpy(c1->left->code,c1->code); strcat(c1->left->code,"0"); P1Hilf1(c1->left); } if(c1->right){ strcpy(c1->right->code,c1->code); strcat(c1->right->code,"1"); P1Hilf1(c1->right); } } void P1Eintragen(C1CharInfo* baum){ if(!(baum->left)){if(!(baum->right)){baum->code[0]='0';return;}} if(baum->left){ baum->left->code[0]='0';P1Hilf1(baum->left); } if(baum->right){ baum->right->code[0]='1';P1Hilf1(baum->right); } } void P1Sort(C1CharInfo* a[],int N){ int i,j; C1CharInfo* v; for(i=1;i<=N;i++){ v = a[i];j=i; while(j>0 && a[j-1]->count > v->count) {a[j] = a[j-1];j--;} a[j]=v; } } int P1UnPack2(char* f1,char* f2,int doprev){ int err=0; BPTR file1=0; char kennung[6]; ULONG numbits; unsigned char flags1[32]; unsigned char flag2; C1CharInfo* c1,* c2,* c3; C1CharInfo* t1=0; int x,y; int charoffset,bitoffset; unsigned char uc1; unsigned short us1; ULONG ul1; C1CharInfo* baum1=0; C1CharInfo** t2=0,** t3=0; C1Buffer buf1; QL1Liste ql1; QL1Element elem; QL1Init(ql1); buf1.numbits=0;buf1.countbit=0; if(!(t1 = new C1CharInfo[256])){err=1;goto beenden;} if(!(file1 = Open(f1,MODE_OLDFILE))){err=2;goto beenden;} if(!(FRead(file1,kennung,5,1))){err=3;goto beenden;} kennung[5]=0; if(strcmp("P-0-2",kennung)){err=4;goto beenden;} if(!(FRead(file1,&numbits,sizeof(ULONG),1))){err=3;goto beenden;} if(!(FRead(file1,flags1,32,1))){err=3;goto beenden;} if(!(FRead(file1,&flag2,1,1))){err=3;goto beenden;} for(x=0,y=0;x<256;x++){ charoffset=x>>3; bitoffset=x-(charoffset<<3); if(flags1[charoffset] & (128>>bitoffset)){ y++; switch(flag2){ case 0: {if(!(FRead(file1,&uc1,1,1))){err=3;goto beenden;} t1[x].count=uc1;break;} case 1: {if(!(FRead(file1,&us1,sizeof(short),1))){err=3;goto beenden;} t1[x].count=us1;break;} case 2: {if(!(FRead(file1,&ul1,sizeof(ULONG),1))){err=3;goto beenden;} t1[x].count=ul1;break;} } } t1[x].ischar=1;t1[x].wert=x; } if(!y){err=5;goto beenden;} if(!(t2=new C1CharInfo*[y])){err=1;goto beenden;} for(x=0,y=0;x<256;x++){ if(t1[x].count){t2[y]=&t1[x];y++;} } t3=t2; baum1=t3[0]; while(y>1){ P1Sort(t3,y-1); c1=t3[0];c2=t3[1]; if(!(c3=new C1CharInfo)){err=1;goto beenden;} elem.inhalt=c3; if(!(QL1Einfuegen(ql1,&elem))){err=1;goto beenden;} c3->count = c1->count + c2->count; c3->left=c1;c3->right=c2; c1->prevtree=c3;c2->prevtree=c3; baum1=c3; t3[1]=c3; t3=&t3[1]; y--; } P1Eintragen(baum1); for(x=0;x<256;x++){ if(t1[x].count){ y=t1[x].clength=strlen(t1[x].code); buf1.numbits+=y*t1[x].count; } } if(buf1.numbits != numbits){err=5;goto beenden;} if(!(buf1.buffer = new unsigned char[(buf1.numbits+8)>>3])){err=1;goto beenden;} if(!(FRead(file1,buf1.buffer,(buf1.numbits+8)>>3,1))){err=3;goto beenden;} Close(file1);file1=0; if(!(file1 = Open(f2,MODE_NEWFILE))){err=2;goto beenden;} c2=baum1;x=-1; loop99: x++;if(x==buf1.numbits) goto beenden; charoffset=x>>3; bitoffset=x-(charoffset<<3); if(c2->ischar){if(-1==FPutC(file1,c2->wert)){err=3;goto beenden;}goto loop99;} if(buf1.buffer[charoffset] & (128>>bitoffset)){ c2=c2->right; if(c2->ischar){if(-1==FPutC(file1,c2->wert)){err=3;goto beenden;}c2=baum1;} goto loop99; } else{ c2=c2->left; if(c2->ischar){if(-1==FPutC(file1,c2->wert)){err=3;goto beenden;}c2=baum1;} goto loop99; } beenden: if(file1) Close(file1); if(t1) delete[] t1; if(t2) delete[] t2; QL1AllesLoeschen(ql1,1); return err; } int P1Pack2(char* f1,char* f2,int doprev){ int err=0; C1CharInfo* t1=0; C1CharInfo** t2=0,** t3; C1CharInfo* c1,* c2,* c3; C1CharInfo* baum1=0; C1Buffer buf1; unsigned char field1[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}; unsigned char flag1=0; unsigned char u1; unsigned short s1; ULONG l1; FileInfoBlock* exfh=0; unsigned char* buf2=0; QL1Liste ql1; QL1Element elem; BPTR file1=0; LONG x,y; LONG xx,yy; int charoffset,bitoffset; buf1.numbits=0;buf1.countbit=0; QL1Init(ql1); if(!(exfh = (FileInfoBlock*)AllocMem(sizeof(FileInfoBlock),MEMF_ANY))){err=1;goto beenden;} if(!(t1 = new C1CharInfo[256])){err=1;goto beenden;} if(!(file1 = Open(f1,MODE_OLDFILE))){err=2;goto beenden;} if(!(ExamineFH(file1,exfh))){err=3;goto beenden;} if(!(buf2 = new unsigned char[exfh->fib_Size])){err=1;goto beenden;} if(!(exfh->fib_Size==Read(file1,buf2,exfh->fib_Size))){err=4;goto beenden;} Close(file1);file1=0; for(x=0;x<(exfh->fib_Size);x++){ y=buf2[x]; t1[y].count++; } next1: for(x=0,y=0;x<256;x++){ if(t1[x].count) y++; t1[x].wert=x; t1[x].ischar=1; } if(y==0){err=4;goto beenden;} if(!(t2=new C1CharInfo*[y])){err=1;goto beenden;} for(x=0,y=0;x<256;x++){ if(t1[x].count){t2[y]=&t1[x];y++;} } t3=t2; baum1=t3[0]; while(y>1){ P1Sort(t3,y-1); c1=t3[0];c2=t3[1]; if(!(c3=new C1CharInfo)){err=1;goto beenden;} elem.inhalt=c3; if(!(QL1Einfuegen(ql1,&elem))){err=1;goto beenden;} c3->count = c1->count + c2->count; c3->left=c1;c3->right=c2; c1->prevtree=c3;c2->prevtree=c3; baum1=c3; t3[1]=c3; t3=&t3[1]; y--; } P1Eintragen(baum1); for(x=0;x<256;x++){ if(t1[x].count){ y=t1[x].clength=strlen(t1[x].code); buf1.numbits+=y*t1[x].count; } } if(!(buf1.buffer = new unsigned char[(buf1.numbits+8)/8])){err=1;goto beenden;} for(y=0;yfib_Size;y++){ x=buf2[y]; xx=t1[x].clength; yy=0; while(xx){ if(t1[x].code[yy]=='1'){ charoffset=buf1.countbit>>3; bitoffset=buf1.countbit-(charoffset<<3); buf1.buffer[charoffset] += ((unsigned char)128)>>bitoffset; } xx--;yy++;buf1.countbit++; } } Close(file1);file1=0; if(!(file1=Open(f2,MODE_NEWFILE))){err=2;goto beenden;} if(doprev){FPuts(file1,"P-0-2");} for(x=0;x<256;x++){ if(t1[x].count){ charoffset=x>>3; bitoffset=x-(charoffset<<3); field1[charoffset]+=((unsigned char)128)>>bitoffset; if(t1[x].count>255){if(t1[x].count>65535){flag1=2;}else{flag1=1;}} } } if(1 != FWrite(file1,&(buf1.numbits),sizeof(ULONG),1)){err=3;goto beenden;} if(1 != FWrite(file1,field1,32,1)){err=3;goto beenden;} if(1 != FWrite(file1,&flag1,1,1)){err=3;goto beenden;} for(x=0;x<256;x++){ if(t1[x].count){ switch(flag1){ case 0: {u1=t1[x].count;if(1 != FWrite(file1,&u1,1,1)){err=3;goto beenden;}break;} case 1: {s1=t1[x].count;if(1 != FWrite(file1,&s1,sizeof(short),1)){err=3;goto beenden;}break;} case 2: {l1=t1[x].count;if(1 != FWrite(file1,&l1,sizeof(ULONG),1)){err=3;goto beenden;}break;} } } } if(((buf1.numbits+8)>>3) != FWrite(file1,buf1.buffer,1,(buf1.numbits+8)>>3)){err=3;goto beenden;} beenden: if(t2) delete[] t2; if(t1) delete[] t1; if(file1) Close(file1); QL1AllesLoeschen(ql1,1); if(exfh) FreeMem(exfh,sizeof(FileInfoBlock)); if(buf2) delete[] buf2; return err; } void QL1Init(QL1Liste& ql1){ ql1.first=0; ql1.last=0; ql1.name[0]=0; ql1.data=0; }; void QL1AllesLoeschen(QL1Liste& ql1,int dodelete){ QL1Element* ez=ql1.first; QL1Element* hilf; while(ez){ if(dodelete){ delete ez->inhalt; } hilf=ez; ez=ez->next; delete hilf; } QL1Init(ql1); } QL1Element* QL1Einfuegen(QL1Liste& ql1,QL1Element* ez1){ QL1Element* ez2; if(!(ez2 = new QL1Element)) return 0; ez2->inhalt = ez1->inhalt; ez2->next=0; if(!ql1.first){ ql1.first = ez2; ql1.last = ez2; } else{ ql1.last->next=ez2; ql1.last=ez2; } return ez2; } #endif