Mail Archives: djgpp/1995/10/24/13:14:52
In DJGPP\SRC\GZIP-124\ I have the source (but not the compiled form) of an
unzipper. It seems to claim to be able to be able to unzip any zipped file
that has only one file in. The file DJGPP\SRC\GZIP-124\UNLZW.C "decompress
files in LZW format" is the file to unzip files that have been shrunk. Here
follows a program that I just wrote that successfully unzips a PKZIP file that
contains one file, which must have been packed by shrinking. But its algorithm
varies in various places from DJGPP\SRC\GZIP-124\UNLZW.C, which may be able to
handle ordinary LZW'ing, but therefore won't be able to PKZIP's version:-
#include <stdio.h>
#include <string.h>
#define pk __attribute__((packed))
typedef unsigned long ul;
typedef unsigned short us;
typedef unsigned char byte;
/*-----*/
class fileheader{public: ul signature pk; byte version pk; byte opsystem pk;
us gp pk; us compmethod pk; us time pk; us date pk; ul crc32 pk;
ul compsize pk; ul uncompsize pk; us fnleng pk; us extraleng pk;};
class centralfileheader : public fileheader {public: us fcommleng pk;
us filediskno pk; us intattr pk; ul extattr pk; ul localoffset pk;};
/*-----*/
class bits{public: int addr,mask;
inline bits(void*i){addr=(int)i;};
inline void operator=(void*i){addr=(int)i;};
inline int operator[](int i){return (*(long*)(addr+(i>>3))>>(i&7))&mask;};};
/*-----*/
main(){int i,j,k,l,fs,fhs=sizeof(fileheader),ptr; fileheader*fh;
char file[0x100000],*p,sw[256],inname[256],outname[256];
printf("pkzip file to unshrink from?"); gets(inname);
printf("text file to unshrink into?"); gets(outname);
FILE*Z=fopen(inname,"rb"); fs=fread(file,1,0x100000,Z);
FILE*Y=fopen(outname,"wb");
fh=(fileheader*)file;
ptr=sizeof(fileheader)+fh->fnleng+fh->extraleng;
{ /* unshrink */ bits F(file+ptr); F.mask=0x1ff;
int N=9,c,q,inbit=0,n=0,i=0,j,k,l,m,p=-1,pc=0;
us a[0x10000],b[0x10000]; char w[256],pn[0x10000];
for(i=0;i<0x10000;i++) a[i]=b[i]=pn[i]=0; q=256;
for(c=-1,i=0;(inbit>>3)<fh->compsize;i++) {
p=c; X: k=inbit; c=F[inbit]; inbit+=N;
if(c==256) {c=F[inbit]; inbit+=N;
if(c==1) {N++; F.mask=(F.mask<<1)|1;}
/* Here UNLZW.C rounds `inbit' up to the next code boundary which is also */
/* a byte boundary, but this program (and therefore PKZIP) do not. */
else if(c==2) {pc++;
for(m=256;m<0x10000;m++) b[a[m]]|=0x8000;
for(m=0;m<0x10000;m++)
if(b[m]&0x8000) b[m]&=0x7fff; else a[m]=b[m]=0;
for(q=257;b[q];q++) if(q>=0x10000) break /* MOAN */;}
/* Here UNLZW.C zeros all the arrays a and b, and returns N to 9 */
/* I and PKZIP merely remove all code entries that no other code entry is */
/* pointing to. */
goto X;}
for(l=0,j=c;j>255;j=j==q?p:a[j]) w[l++]=b[j]; w[l++]=j;
a[q]=p; b[q]=j; if(c==q) w[0]=j; pn[q]=pc;
for(q++;b[q];q++) if(q>=0x10000) break /* MOAN */;
for(j=l-1;j>=0;j--) putc(w[j],Y);}}
fclose(Y); fclose(Z);}
- Raw text -