//////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// #include #include #include // Decode file (LUA & other compressed files) // Input : Data.file.input : input buffer // Data.filesize : input buffer size // Output: Data.file.output: output buffer (CMemFile) // New generation FSH/QFS decompressor/compressor // Version 1.22 - copyright (c) Denis Auroux 1998-2002 // auroux@math.polytechnique.fr typedef char BOOL; typedef unsigned int UINT ; void mmemcpy(unsigned char *dest,unsigned char *src,int len) /* LZ-compatible memcopy */ { while (len--) *(dest++)=*(src++); } unsigned char *uncompress_data( unsigned char *inbuf,int *buflen ) { unsigned char *outbuf; unsigned char packcode; int a,b,c,len,offset; int inlen,outlen,inpos,outpos; /* length of data */ inlen=*buflen; outlen=(inbuf[2]<<16)+(inbuf[3]<<8)+inbuf[4]; outbuf=(unsigned char*)malloc(outlen); if (outbuf==NULL) { //AfxMessageBox("Insufficient memory."); free(outbuf); return NULL; } /* position in file */ if (inbuf[0]&0x01) inpos=8; else inpos=5; outpos=0; /* main decoding loop */ while ((inpos>2)+3; offset=((packcode>>5)<<8)+a+1; mmemcpy(outbuf+outpos,outbuf+outpos-offset,len); outpos+=len; } else if (!(packcode&0x40)) { len=(a>>6)&3; mmemcpy(outbuf+outpos,inbuf+inpos+3,len); inpos+=len+3; outpos+=len; len=(packcode&0x3f)+4; offset=(a&0x3f)*256+b+1; mmemcpy(outbuf+outpos,outbuf+outpos-offset,len); outpos+=len; } else if (!(packcode&0x20)) { c=inbuf[inpos+3]; len=packcode&3; mmemcpy(outbuf+outpos,inbuf+inpos+4,len); inpos+=len+4; outpos+=len; len=((packcode>>2)&3)*256+c+5; offset=((packcode&0x10)<<12)+256*a+b+1; mmemcpy(outbuf+outpos,outbuf+outpos-offset,len); outpos+=len; } else { len=(packcode&0x1f)*4+4; mmemcpy(outbuf+outpos,inbuf+inpos+1,len); inpos+=len+1; outpos+=len; } } /* trailing bytes */ if ((inpos>16; outbuf[3]=(inlen>>8)&255; outbuf[4]=inlen&255; outpos=5; lastwrot=0; /* main encoding loop */ for (inpos=0,inrd=inbuf;inpos=0)&&(inpos-offsbestlen) { bestlen=len; bestoffs=inpos-offs; } offs=rev_similar[offs&WINDOW_MASK]; } /* check if redundancy is good enough */ if (bestlen>inlen-inpos) bestlen=inpos-inlen; if (bestlen<=2) bestlen=0; if ((bestlen==3)&&(bestoffs>1024)) bestlen=0; if ((bestlen==4)&&(bestoffs>16384)) bestlen=0; /* update compressed data */ if (bestlen) { while (inpos-lastwrot>=4) { len=(inpos-lastwrot)/4-1; if (len>0x1B) len=0x1B; outbuf[outpos++]=0xE0+len; len=4*len+4; memcpy(outbuf+outpos,inbuf+lastwrot,len); lastwrot+=len; outpos+=len; } len=inpos-lastwrot; if ((bestlen<=10)&&(bestoffs<=1024)) { outbuf[outpos++]=(((bestoffs-1)>>8)<<5)+((bestlen-3)<<2)+len; outbuf[outpos++]=(bestoffs-1)&0xff; while (len--) outbuf[outpos++]=inbuf[lastwrot++]; lastwrot+=bestlen; } else if ((bestlen<=67)&&(bestoffs<=16384)) { outbuf[outpos++]=0x80+(bestlen-4); outbuf[outpos++]=(len<<6)+((bestoffs-1)>>8); outbuf[outpos++]=(bestoffs-1)&0xff; while (len--) outbuf[outpos++]=inbuf[lastwrot++]; lastwrot+=bestlen; } else if ((bestlen<=1028)&&(bestoffs>16)<<4)+(((bestlen-5)>>8)<<2)+len; outbuf[outpos++]=(bestoffs>>8)&0xff; outbuf[outpos++]=bestoffs&0xff; outbuf[outpos++]=(bestlen-5)&0xff; while (len--) outbuf[outpos++]=inbuf[lastwrot++]; lastwrot+=bestlen; } } } /* end stuff */ inpos=inlen; while (inpos-lastwrot>=4) { len=(inpos-lastwrot)/4-1; if (len>0x1B) len=0x1B; outbuf[outpos++]=0xE0+len; len=4*len+4; memcpy(outbuf+outpos,inbuf+lastwrot,len); lastwrot+=len; outpos+=len; } len=inpos-lastwrot; outbuf[outpos++]=0xFC+len; while (len--) outbuf[outpos++]=inbuf[lastwrot++]; if (lastwrot!=inlen) { printf("Something strange happened at the end of compression!\n"); *buflen = 0; return; } if (rev_similar) free(rev_similar); if (rev_last) { free(rev_last[0]); free(rev_last); } *buflen=outpos; } static PyObject *QFSEncode( PyObject *self, PyObject *args ) { char* buffer; char* bufferIn; int len; unsigned char* out; PyObject *pRet ; if (!PyArg_ParseTuple(args, "s#", &buffer, &len)) return NULL; out = (unsigned char*)malloc( len*2 ); bufferIn = (unsigned char*)malloc( len + 2000 ); memcpy( bufferIn, buffer, len ); compress_data( (unsigned char*)bufferIn, &len, out); pRet = Py_BuildValue( "s#", out, len ); free( out ); free( bufferIn ); return pRet; } static PyObject *QFSDecode( PyObject *self, PyObject *args ) { char* buffer; int len; unsigned char* out; PyObject *pRet ; if (!PyArg_ParseTuple(args, "s#", &buffer, &len)) return NULL; out = uncompress_data( (unsigned char*)buffer, &len); pRet = Py_BuildValue( "s#", out, len ); free( out ); return pRet; } static PyMethodDef QFSMethods[] = { {"decode", QFSDecode, METH_VARARGS, "decode a buffer" }, {"encode", QFSEncode, METH_VARARGS, "encode a buffer" }, {NULL, NULL, 0, NULL} /* Sentinel */ }; PyMODINIT_FUNC initQFS(void) { (void) Py_InitModule("QFS", QFSMethods); }