#include "StdAfx.h" #include "globalFunc.h" #include "TGGiStreamFile.h" #include "AString.h" #include #include #include #include "fcntl.h" #include #include "sys\stat.h" static short bitpos; static short charpos; static unsigned short mask[16]; static unsigned short intmask[16]; static unsigned char writemaskl[8]; static unsigned char writemaskr[8]; static unsigned char setmask[8]; TGGiStreamFile::TGGiStreamFile() { } TGGiStreamFile::~TGGiStreamFile() { } void TGGiStreamFile::InitValue(void) { int i; writemaskr[7] = 127; for (i = 6; i >= 0; i--) { writemaskr[i] = (writemaskr[i + 1] >> 1); } writemaskl[0] = 255; for (i = 1; i <= 7; i++) { writemaskl[i] = (writemaskl[i - 1] << 1); } intmask[15] = 65535; for (i = 15; i >= 1; i--) { intmask[i - 1] = (intmask[i] >> 1); } for (i = 1; i <= 16; i++) { mask[i - 1] = (1 << (i - 1)); } for (i = 1; i <= 8; i++) { setmask[i - 1] = (1 << (i - 1)); } } void TGGiStreamFile::WriteBit(short mode,short lentowrite,short whatchar,unsigned char *where,int h2) { short i; short howlong; short oldpos; short oldcharpos; unsigned char first; unsigned long tempvalue = 0; if (mode == 1) { bitpos = 1; charpos = 1; } oldpos = bitpos; oldcharpos = charpos; i = bitpos + lentowrite - 1; howlong = ((i + 7) >> 3); charpos += (i >> 3); bitpos = (i & 7) + 1; tempvalue = (unsigned long )whatchar; tempvalue = (tempvalue << (oldpos - 1)); first = where[oldcharpos - 1]; for (i = 0; i <= howlong - 1; i++) { where[oldcharpos + i - 1] = *((unsigned char *)(&tempvalue) + i); } if (oldpos > 1) { first &= writemaskr[oldpos - 1]; where[oldcharpos - 1] |= first; } if (charpos > PACKSIZE) { Write(h2,where,PACKSIZE,true); memset(where,'\0',PACKSIZE); charpos -= PACKSIZE; for (i = 1; i <= charpos; i++) { where[i - 1] = where[i - 1 + PACKSIZE]; } where[PACKSIZE] = where[PACKSIZE + 1] = '\0'; } } int TGGiStreamFile::ReadBit(short mode1,short lentowrite, unsigned char *where,int h1) { unsigned long tempvalue = 0; unsigned long t; unsigned short t1; short howlong; short oldpos; short oldcharpos; if (mode1 == 1) { bitpos = 1; charpos = 1; return 0; } else { oldpos = bitpos; oldcharpos = charpos; t1 = bitpos + lentowrite - 1; howlong = (t1 >> 3) + 1; charpos += (howlong - 1); bitpos = (t1 & 7) + 1; tempvalue = *((unsigned long *)(where + oldcharpos - 1)); if (charpos > PACKSIZE) { Read(h1,where,PACKSIZE,true); charpos -= PACKSIZE; *((unsigned char *)(&tempvalue) + howlong - 1) = where[charpos - 1]; if (charpos == 2) { *((unsigned char *)(&tempvalue) + howlong - 2) = where[0]; } } t = (tempvalue >> (oldpos - 1)); t1 = *((unsigned short *)(&t)); return (t1 & intmask[lentowrite - 1]); } } int TGGiStreamFile::PackFile(short size,int h1,int h2) { int WorkFlag; char head[HEADLENGTH]; long lint; unsigned char *in; unsigned char *inptr; unsigned char *out; short length; STPACKTREE *tree; short i,route,now,code,clear,eoi,len,next,max,prefix; tree = (STPACKTREE *)malloc(4097 * sizeof(STPACKTREE)); inptr = in = (unsigned char *)malloc(PACKSIZE + 2); out = (unsigned char *)malloc(PACKSIZE + 2); if (!in || !out || !tree) { WorkFlag = NOMEMORY; goto OUT1; } Write(h2,head,HEADLENGTH,true); lseek(h2,0L,SEEK_SET); { char temp[256] = COMPRESSFLAG; Write(h2,temp,strlen(COMPRESSFLAG),true); } // modify by gjm 2010/08/06 lint = lseek(h1,0L, SEEK_END); lseek(h1, 0L, SEEK_SET); // end Write(h2,&lint,sizeof(long ),true); lseek(h2,(long )HEADLENGTH,SEEK_SET); for (i = 1; i <= PACKSIZE; i++) { out[i - 1] = '\0'; } length = Read(h1,in,PACKSIZE); if (!length) { WorkFlag = NOCONTENT; goto OUT1; } clear = 1 << size; eoi = clear + 1; next = clear + 2; len = size + 1; max = 1 << len; for (i = 0; i <= clear; i++) { tree[i].l = -1; } TGGiStreamFile::WriteBit(1,len,clear,out,h2); now = prefix = code = *in; in++; length--; while (length > 0) { code = *in; in++; route = 0; if (tree[now].l != -1) { now = tree[now].l; for (;;) { if (code == tree[now].k) { code = prefix = now; break; } else if (tree[now].r == -1) { route = 2; break; } else { now = tree[now].r; } } } else { route = 1; } if (route) { tree[next].k = (unsigned char)code; tree[next].l = tree[next].r = -1; if (route == 1) { tree[now].l = next; } else { tree[now].r = next; } TGGiStreamFile::WriteBit(0,len,prefix,out,h2); next++; if (next == max + 1) { max <<= 1; len++; if (len > 12) { TGGiStreamFile::WriteBit(0,12,clear,out,h2); next = clear + 2; len = size + 1; max = mask[len]; for (i = 0; i < clear; i++) { tree[i].l = -1; } } } } now = prefix = code; length--; if (in-inptr == PACKSIZE) { in = inptr; length = Read(h1,in,PACKSIZE); } } TGGiStreamFile::WriteBit(0,len,prefix,out,h2); TGGiStreamFile::WriteBit(2,len,eoi,out,h2); Write(h2,out,charpos + 5,true); WorkFlag = SUCCEED; OUT1: free(inptr); free(out); free(tree); return WorkFlag; } int TGGiStreamFile::UnPackFile(short size,int h1,int h2) { short code,incode,oldcode,clear,eoi,len,next; register short i; int WorkFlag; long lint; long ByteNumber; char head[HEADLENGTH]; unsigned char *in; unsigned char *out; unsigned char *buff; unsigned char *storeptr; STUNPACKTREE *tree; short finchar = 0; short max; buff = (unsigned char *)malloc(4000); tree = (STUNPACKTREE *)malloc(4097 * sizeof(STUNPACKTREE)); ByteNumber = 0; for (i = 1; i <= HEADLENGTH; i++) { head[i - 1] = '\0'; } in = (unsigned char *)malloc(PACKSIZE + 2); out = (unsigned char *)malloc(PACKSIZE + 2); storeptr = out; if (!in || !out || !tree || !buff) { WorkFlag = NOMEMORY; goto OUT2; } Read(h1,head,strlen(COMPRESSFLAG),true); if (strcmp(head,COMPRESSFLAG)) { WorkFlag = ILLFORMAT; goto OUT2; } Read(h1,&lint,sizeof(long ),true); lseek(h1,(long )HEADLENGTH,SEEK_SET); memset(out,'\0',PACKSIZE); Read(h1,in,PACKSIZE,true); clear = 1 << size; eoi = clear + 1; oldcode = -1; next = clear + 1; len = size + 1; TGGiStreamFile::ReadBit(1,0,in,h1); while((code = incode = TGGiStreamFile::ReadBit(0,len,in,h1)) != eoi && code >= 0) { if (code == clear) { oldcode = -1; next = clear + 1; len = size + 1; max = mask[len]; } else { i = 0; if (code >= next) { code = oldcode; buff[i] = (unsigned char)finchar; i++; } finchar = code; while(finchar > eoi) { buff[i] = tree[finchar].k; finchar = tree[finchar].p; i++; } buff[i++] = (unsigned char)finchar; while(i--) { *out = buff[i]; out++; ByteNumber++; if (out-storeptr == PACKSIZE) { Write(h2,storeptr,PACKSIZE); out = storeptr; } if (ByteNumber > lint) { WorkFlag = WRONGDATA; goto OUT2; } } tree[next].p = oldcode; tree[next].k = (unsigned char)finchar; next++; if (next == max) { max <<= 1; len++; if (len > 12) { len = 12; } } oldcode = incode; } } Write(h2,storeptr,(out - storeptr)); if (ByteNumber == lint) { WorkFlag = SUCCEED; } else { WorkFlag = WRONGDATA; } OUT2: free(in); free(storeptr); free(tree); free(buff); return WorkFlag; } int TGGiStreamFile::UnPack(const TCHAR *lzwFile, const TCHAR *dwgFile) { int h1 = open(_AS(lzwFile),O_RDONLY | O_BINARY); if (h1 == -1) { return RTERROR; } int h2 = open(_AS(dwgFile),O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,S_IREAD | S_IWRITE); if (h2 == -1) { close(h1); return RTERROR; } TGGiStreamFile::InitValue(); int nRet = TGGiStreamFile::UnPackFile(8,h1,h2) ? RTERROR : RTNORM; close(h1); close(h2); return nRet; } int TGGiStreamFile::Pack(const TCHAR *dwgFile, const TCHAR *lzwFile) { int h1 = open(_AS(dwgFile),O_RDONLY | O_BINARY); if (h1 == -1) { return RTERROR; } int h2 = open(_AS(lzwFile),O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,S_IREAD | S_IWRITE); if (h2 == -1) { close(h1); return RTERROR; } TGGiStreamFile::InitValue(); int nRet = TGGiStreamFile::PackFile(8,h1,h2) ? RTERROR : RTNORM; close(h1); close(h2); return nRet; } int TGGiStreamFile::Read(int h,void *buf,int num,bool bProtect) { long res = read(h,buf,num); if (bProtect && g_Option::instance().g_iPackMode == 1) { unsigned char *c = (unsigned char*)buf; for (long i = 0; i < num; i++) { c[i] = 255 - c[i]; c[i] = 100 ^ c[i]; } } return res; } int TGGiStreamFile::Write(int h,void *buf,int num,bool bProtect) { if (bProtect && g_Option::instance().g_iPackMode == 1) { unsigned char *c = (unsigned char*)buf; for (long i = 0; i < num; i++) { c[i] = 100 ^ c[i]; c[i] = 255 - c[i]; } } return write(h,buf,num); } void TGGiStreamFile::StreamCopy(std::istream & _libfile, std::ostream &sld_out, long sld_fsize) { char bufp[MAXBUFSIZE]; long blockNum = sld_fsize / MAXBUFSIZE, blockLeft = sld_fsize % MAXBUFSIZE; for (long j = 0; j < blockNum; j++) { _libfile.read(bufp, MAXBUFSIZE); sld_out.write(bufp, MAXBUFSIZE); } if (blockLeft) { _libfile.read(bufp, blockLeft); sld_out.write(bufp, blockLeft); } }