Files
envi-code/SourceCode/Code2026/Dimension/TGGiStreamFile.cpp
T
2026-09-28 15:28:50 +08:00

551 lines
9.3 KiB
C++

#include "StdAfx.h"
#include "globalFunc.h"
#include "TGGiStreamFile.h"
#include "AString.h"
#include <stdio.h>
#include <io.h>
#include <time.h>
#include "fcntl.h"
#include <fstream>
#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);
}
}