www.pudn.com > SharedScreen.rar > LZWFILE.CPP
#include "stdafx.h"
#include "lzwtable.h"
#include "lzwcode.h"
#include "lzwfile.h"
// this .cpp is not consider try{}catch{} error case
const int iFileUsedBufferLength=1024*10;
CFile* pfileIn,*pfileOut;
BYTE bEncodeGet[iFileUsedBufferLength],bDecodePut[iFileUsedBufferLength];
DWORD dwEncodeGetTotal;
int iEncodeGetPos,iDecodeGetPos;
BOOL LZWCheckFile(LPCSTR pszCheck)// is the file a HGLZ
{
CFile fileCheck(pszCheck,CFile::modeRead|CFile::typeBinary);
BOOL fR=LZWCheckFile(&fileCheck);
fileCheck.Close();
return fR;
}
BOOL LZWCheckFile(CFile* pfileCheck)// is the file a HGLZ
{
WORD wRead;
DWORD dwRead;
BOOL fR=TRUE;
if(pfileCheck->GetLength()GetPosition();
pfileCheck->SeekToBegin();
pfileCheck->Read(&dwRead,4);
if(dwRead==LZW_FILE_TAG)
{
pfileCheck->Seek(sizeof(LZWFILEHEAD),CFile::begin);
pfileCheck->Read(&wRead,2);
if(wRead!=LZW_NODE_TAG)
fR=FALSE;
}
else
fR=FALSE;
pfileCheck->Seek(dwPos,CFile::begin);
return fR;
}
int FindFileName(LPCSTR pszName)
{
int iLen=strlen(pszName);
for(int i=iLen-1;i>=0;i--)
{
if(pszName[i]=='\\')
return i+1;
}
return 0;
}
BOOL EncodeGetNextByte(BYTE& bGet)
{
//pfileIn->Read(&bGet,1);
if(iEncodeGetPos==0)
{
int iRead=(dwEncodeGetTotal>=iFileUsedBufferLength)?
iFileUsedBufferLength:(int)dwEncodeGetTotal;
dwEncodeGetTotal-=(DWORD)iRead;
pfileIn->Read(bEncodeGet,iRead);
}
bGet=bEncodeGet[iEncodeGetPos++];
if(iEncodeGetPos>=iFileUsedBufferLength)
iEncodeGetPos=0;
return TRUE;
}
BOOL EncodePutNextBytes(BYTE* pbPut,int iPut)
{
pfileOut->Write(pbPut,iPut);
return TRUE;
}
BOOL DecodePutNextByte(BYTE bPut)
{
pfileOut->Write(&bPut,1);
return TRUE;
}
BOOL DecodeGetNextBytes(BYTE* pbGet,int iGet)
{
pfileIn->Read(pbGet,iGet);
return TRUE;
}
// for batch decompress files
BOOL LZWDecodeFileOnPosition(CFile* pInFile,
CFile* pOutFile,// file be decompressed
DWORD dwPos,// the decompressed file position
FUN_LZWDECODEDBYTES pfunDecodedBytes)
{
DWORD dwFileLength=pInFile->GetLength();
if(dwFileLength
<(sizeof(LZWFILEHEAD)+sizeof(LZWNODEHEAD)+sizeof(LZWSINGLEFILEHEAD)))
{
return FALSE;
}
LZWFILEHEAD LZWFileHead;
pInFile->Read(&LZWFileHead,sizeof(LZWFILEHEAD));
if(LZWFileHead.dwFileTag!=LZW_FILE_TAG)
{
return FALSE;
}
if(HIBYTE(LZWFileHead.wVersion)!=0 || LOBYTE(LZWFileHead.wVersion)>10)
{
return FALSE;
}
LZWNODEHEAD LZWNodeHead;
pInFile->Read(&LZWNodeHead,sizeof(LZWNODEHEAD));
if(LZWNodeHead.wNodeTag!=LZW_NODE_TAG)
{
return FALSE;
}
if(LZWNodeHead.wDirectoryType!=LZW_NODE_BEGIN_COMPRESS)
{
return FALSE;
}
LZWSINGLEFILEHEAD LZWSingleFileHead;
for(DWORD d=0;dRead(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
if(LZWSingleFileHead.wSingleFileTag!=LZW_SINGLE_FILE_TAG)
{
return FALSE;
}
//BYTE *pbFileNameRead=new BYTE[LZWSingleFileHead.wFileNameLength];
//pInFile->Read(pbFileName,LZWSingleFileHead.wFileNameLength);
pInFile->Seek(LZWSingleFileHead.dwFileCompressedLength+
LZWSingleFileHead.wFileNameLength,
CFile::current);
}
pInFile->Read(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
if(LZWSingleFileHead.wSingleFileTag!=LZW_SINGLE_FILE_TAG)
{
return FALSE;
}
BYTE *pbFileName=new BYTE[LZWSingleFileHead.wFileNameLength+1];
pInFile->Read(pbFileName,LZWSingleFileHead.wFileNameLength);
pbFileName[LZWSingleFileHead.wFileNameLength]='\0';
pfileIn=pInFile;
pfileOut=pOutFile;
if(LZWSingleFileHead.dwFileCompressedLength!=0)
{
CLZWDecode *pDecode=new CLZWDecode();
pDecode->BeginLZWDecode(LZWSingleFileHead.dwFileCompressedLength,
DecodeGetNextBytes,
DecodePutNextByte,
1024,
(LZWSingleFileHead.dwFileOldLength>1000)?pfunDecodedBytes:NULL,
LZWSingleFileHead.dwFileOldLength/100);
delete pDecode;
}
return TRUE;
}
// decompress a file
BOOL LZWDecodeFileToFile(CFile* pInFile,
CFile* pOutFile,
DWORD dwPos,
FUN_LZWDECODEDBYTES pfunDecodedBytes)
{
DWORD dwFileLength=pfileIn->GetLength();
if(dwFileLength
<(sizeof(LZWFILEHEAD)+sizeof(LZWNODEHEAD)+sizeof(LZWSINGLEFILEHEAD)))
{
return FALSE;
}
LZWFILEHEAD LZWFileHead;
pfileIn->Read(&LZWFileHead,sizeof(LZWFILEHEAD));
if(LZWFileHead.dwFileTag!=LZW_FILE_TAG)
{
return FALSE;
}
if(HIBYTE(LZWFileHead.wVersion)!=0 || LOBYTE(LZWFileHead.wVersion)>10)
{
return FALSE;
}
LZWNODEHEAD LZWNodeHead;
pfileIn->Read(&LZWNodeHead,sizeof(LZWNODEHEAD));
if(LZWNodeHead.wNodeTag!=LZW_NODE_TAG)
{
return FALSE;
}
if(LZWNodeHead.wDirectoryType!=LZW_NODE_BEGIN_COMPRESS)
{
return FALSE;
}
LZWSINGLEFILEHEAD LZWSingleFileHead;
for(DWORD d=0;dRead(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
if(LZWSingleFileHead.wSingleFileTag!=LZW_SINGLE_FILE_TAG)
{
return FALSE;
}
//BYTE *pbFileNameRead=new BYTE[LZWSingleFileHead.wFileNameLength];
//pfileIn->Read(pbFileName,LZWSingleFileHead.wFileNameLength);
pfileIn->Seek(LZWSingleFileHead.dwFileCompressedLength+
LZWSingleFileHead.wFileNameLength,
CFile::current);
}
pfileIn->Read(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
if(LZWSingleFileHead.wSingleFileTag!=LZW_SINGLE_FILE_TAG)
{
return FALSE;
}
pfileIn->Seek(LZWSingleFileHead.wFileNameLength,CFile::current);
//BYTE *pbFileName=new BYTE[LZWSingleFileHead.wFileNameLength];
//pfileIn->Read(pbFileName,LZWSingleFileHead.wFileNameLength);
//delete pbFileName;
// create the out file
pfileIn=pInFile;
pfileOut=pOutFile;
if(LZWSingleFileHead.dwFileCompressedLength!=0)
{
CLZWDecode *pDecode=new CLZWDecode();
pDecode->BeginLZWDecode(LZWSingleFileHead.dwFileCompressedLength,
DecodeGetNextBytes,
DecodePutNextByte,
1024,
(LZWSingleFileHead.dwFileCompressedLength>1000)?pfunDecodedBytes:NULL,
LZWSingleFileHead.dwFileCompressedLength/100);
delete pDecode;
}
return TRUE;
}
// add another file to the compressed file
BOOL LZWAddEncodeFile(LPCSTR pszInFile,// file to be added
LPCSTR pszOutFile,// compressed file
FUN_LZWENCODEDBYTES pfunEncodedBytes)
{
iEncodeGetPos=0;
if(!LZWCheckFile(pszOutFile))
return FALSE;
CFile fileIn(pszInFile,
CFile::modeRead|CFile::typeBinary);
CFile fileOut(pszOutFile,
CFile::modeReadWrite|CFile::typeBinary);
pfileOut=&fileOut;
pfileIn=&fileIn;
LZWFILEHEAD LZWFileHead;//(LZW_FILE_TAG,(9<<8)|0,1);
pfileOut->Read(&LZWFileHead,sizeof(LZWFILEHEAD));
LZWFileHead.dwFileCount++;
pfileOut->SeekToBegin();
pfileOut->Write(&LZWFileHead,sizeof(LZWFILEHEAD));
pfileOut->SeekToEnd();
LZWSINGLEFILEHEAD LZWSingleFileHead;/*(LZW_SINGLE_FILE_TAG,
0,
dwOldFileLength,
0,
strlen(pszInFile));*/
DWORD dwFileOldLength=pfileIn->GetLength();
LZWSingleFileHead.wSingleFileTag=LZW_SINGLE_FILE_TAG;
LZWSingleFileHead.dwAttribute=0;
LZWSingleFileHead.dwFileOldLength=dwFileOldLength;
dwEncodeGetTotal=dwFileOldLength;
int iFileNamePos=FindFileName(pszInFile);
LZWSingleFileHead.wFileNameLength=strlen(pszInFile+iFileNamePos);
pfileOut->Write(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
pfileOut->Write(pszInFile+iFileNamePos,strlen(pszInFile+iFileNamePos));
if(dwFileOldLength!=0)
{
CLZWEncode *pEncode=new CLZWEncode();
pEncode->BeginLZWEncode(dwFileOldLength,
EncodeGetNextByte,
EncodePutNextBytes,
1024,
(dwFileOldLength>1000)?pfunEncodedBytes:NULL,
dwFileOldLength/100);
pEncode->EndLZWEncode(EncodePutNextBytes);
LZWSingleFileHead.dwFileCompressedLength=
(DWORD)pEncode->GetCompressedLength();
DWORD dwCurrentPos=pfileOut->GetPosition();
DWORD dwLastSingleFileHeadPos=dwCurrentPos
-LZWSingleFileHead.dwFileCompressedLength
-LZWSingleFileHead.wFileNameLength
-sizeof(LZWSINGLEFILEHEAD);
//pfileOut->Flush();
/*pfileOut->Close();
pfileOut->Open(pszOutFile,
CFile::modeWrite|CFile::typeBinary);*/
pfileOut->Seek(dwLastSingleFileHeadPos,CFile::begin);
pfileOut->Write(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
pfileOut->Seek(dwCurrentPos,CFile::begin);
pfileOut->Flush();
//pfileOut->Seek(0,CFile::end);
delete pEncode;
}
pfileOut->Close();
pfileIn->Close();
return TRUE;
}
BOOL LZWEncodeFile(CFile* pInFile,CFile* pOutFile,
FUN_LZWENCODEDBYTES pfunEncodedBytes)
{
iEncodeGetPos=0;
pfileOut=pOutFile;
pfileIn=pInFile;
LZWFILEHEAD LZWFileHead;//(LZW_FILE_TAG,(9<<8)|0,1);
LZWFileHead.dwFileTag=LZW_FILE_TAG;
LZWFileHead.wVersion=(0<<8)|10;
LZWFileHead.dwFileCount=1;
pfileOut->Write(&LZWFileHead,sizeof(LZWFILEHEAD));
LZWNODEHEAD LZWNodeHead;//(LZW_NODE_TAG,LZW_BEGIN_COMPRESS,0);
LZWNodeHead.wNodeTag=LZW_NODE_TAG;
LZWNodeHead.wDirectoryType=LZW_NODE_BEGIN_COMPRESS;
LZWNodeHead.wDirectoryNameLength=0;
pfileOut->Write(&LZWNodeHead,sizeof(LZWNODEHEAD));
LZWSINGLEFILEHEAD LZWSingleFileHead;/*(LZW_SINGLE_FILE_TAG,
0,
dwOldFileLength,
0,
strlen(pszInFile));*/
DWORD dwFileOldLength=pfileIn->GetLength();
LZWSingleFileHead.wSingleFileTag=LZW_SINGLE_FILE_TAG;
LZWSingleFileHead.dwAttribute=0;
LZWSingleFileHead.dwFileOldLength=dwFileOldLength;
dwEncodeGetTotal=dwFileOldLength;
int iFileNamePos=0;
LZWSingleFileHead.wFileNameLength=strlen("LZW");//strlen(pszInFile+iFileNamePos);
pfileOut->Write(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
pfileOut->Write("LZW",strlen("LZW"));
if(dwFileOldLength!=0)
{
CLZWEncode *pEncode=new CLZWEncode();
pEncode->BeginLZWEncode(dwFileOldLength,
EncodeGetNextByte,
EncodePutNextBytes,
1024,
(dwFileOldLength>1000)?pfunEncodedBytes:NULL,
dwFileOldLength/100);
pEncode->EndLZWEncode(EncodePutNextBytes);
LZWSingleFileHead.dwFileCompressedLength=
(DWORD)pEncode->GetCompressedLength();
DWORD dwCurrentPos=pfileOut->GetPosition();
DWORD dwLastSingleFileHeadPos=dwCurrentPos
-LZWSingleFileHead.dwFileCompressedLength
-LZWSingleFileHead.wFileNameLength
-sizeof(LZWSINGLEFILEHEAD);
//pfileOut->Flush();
/*pfileOut->Close();
pfileOut->Open(pszOutFile,
CFile::modeWrite|CFile::typeBinary);*/
pfileOut->Seek(dwLastSingleFileHeadPos,CFile::begin);
pfileOut->Write(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
pfileOut->Seek(dwCurrentPos,CFile::begin);
//fileOut->Flush();
//pfileOut->Seek(0,CFile::end);
delete pEncode;
}
return TRUE;
}
/*BOOL LZWDecodeFile(LPCSTR pszInFile,LPCSTR pszOutFile)
{
return FALSE;
}*/
BOOL LZWParseFileHead(LPCSTR pszInFile,CString* pszOut)
{
DWORD dwCount=0;
CString szOut(pszInFile);
char szTemp[1000];
CFile fileIn(pszInFile,
CFile::modeRead|CFile::typeBinary);
DWORD dwFileLength=pfileIn->GetLength();
if(dwFileLength
<(sizeof(LZWFILEHEAD)+sizeof(LZWNODEHEAD)+sizeof(LZWSINGLEFILEHEAD)))
{
AfxMessageBox("error file format");
return FALSE;
}
LZWFILEHEAD LZWFileHead;
pfileIn->Read(&LZWFileHead,sizeof(LZWFILEHEAD));
if(LZWFileHead.dwFileTag!=LZW_FILE_TAG)
{
AfxMessageBox("not hglz file");
pfileIn->Close();
return FALSE;
}
szOut+="\n";
sprintf(szTemp,
"version %d.%d\nfile count %d\n",
HIBYTE(LZWFileHead.wVersion),
LOBYTE(LZWFileHead.wVersion),
LZWFileHead.dwFileCount);
szOut+=szTemp;
dwCount=LZWFileHead.dwFileCount;
LZWNODEHEAD LZWNodeHead;
pfileIn->Read(&LZWNodeHead,sizeof(LZWNODEHEAD));
if(LZWNodeHead.wNodeTag!=LZW_NODE_TAG)
{
AfxMessageBox("not hglz file node");
pfileIn->Close();
return FALSE;
}
if(LZWNodeHead.wDirectoryNameLength!=0)
{
ASSERT(0);
}
for(DWORD d=0;dRead(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
DWORD dwPos=pfileIn->GetPosition();
if(LZWSingleFileHead.wSingleFileTag!=LZW_SINGLE_FILE_TAG)
{
AfxMessageBox("not hglz single file head");
pfileIn->Close();
return FALSE;
}
szOut+="file:";
pfileIn->Read(szTemp,LZWSingleFileHead.wFileNameLength);
szTemp[LZWSingleFileHead.wFileNameLength]='\0';
szOut+=szTemp;
szOut+=" ";
sprintf(szTemp,"ratio %.2f%%\n",
(100*(float)LZWSingleFileHead.dwFileCompressedLength)
/(float)LZWSingleFileHead.dwFileOldLength);
szOut+=szTemp;
dwPos+=LZWSingleFileHead.dwFileCompressedLength;
dwPos+=LZWSingleFileHead.wFileNameLength;
pfileIn->Seek(dwPos,CFile::begin);
}
if(pszOut)
*pszOut=szOut;
else
AfxMessageBox(szOut);
pfileIn->Close();
return TRUE;
}
BOOL LZWParseFileHead(LPCSTR pszInFile,CStringArray &szNameArray)
{
DWORD dwCount=0;
CString szOut(pszInFile);
char szTemp[1000];
CFile fileIn(pszInFile,
CFile::modeRead|CFile::typeBinary);
DWORD dwFileLength=pfileIn->GetLength();
if(dwFileLength
<(sizeof(LZWFILEHEAD)+sizeof(LZWNODEHEAD)+sizeof(LZWSINGLEFILEHEAD)))
{
AfxMessageBox("error file format");
return FALSE;
}
LZWFILEHEAD LZWFileHead;
pfileIn->Read(&LZWFileHead,sizeof(LZWFILEHEAD));
if(LZWFileHead.dwFileTag!=LZW_FILE_TAG)
{
AfxMessageBox("not hglz file");
pfileIn->Close();
return FALSE;
}
szOut+="\n";
sprintf(szTemp,
"version %d.%d\nfile count %d\n",
HIBYTE(LZWFileHead.wVersion),
LOBYTE(LZWFileHead.wVersion),
LZWFileHead.dwFileCount);
szOut+=szTemp;
dwCount=LZWFileHead.dwFileCount;
LZWNODEHEAD LZWNodeHead;
pfileIn->Read(&LZWNodeHead,sizeof(LZWNODEHEAD));
if(LZWNodeHead.wNodeTag!=LZW_NODE_TAG)
{
AfxMessageBox("not hglz file node");
pfileIn->Close();
return FALSE;
}
if(LZWNodeHead.wDirectoryNameLength!=0)
{
ASSERT(0);
}
for(DWORD d=0;dRead(&LZWSingleFileHead,sizeof(LZWSINGLEFILEHEAD));
DWORD dwPos=pfileIn->GetPosition();
if(LZWSingleFileHead.wSingleFileTag!=LZW_SINGLE_FILE_TAG)
{
AfxMessageBox("not hglz single file head");
pfileIn->Close();
return FALSE;
}
szOut+="file:";
pfileIn->Read(szTemp,LZWSingleFileHead.wFileNameLength);
szTemp[LZWSingleFileHead.wFileNameLength]='\0';
szNameArray.Add(szTemp);
szOut+=szTemp;
szOut+=" ";
sprintf(szTemp,"ratio %.2f%%\n",
(100*(float)LZWSingleFileHead.dwFileCompressedLength)
/(float)LZWSingleFileHead.dwFileOldLength);
szOut+=szTemp;
dwPos+=LZWSingleFileHead.dwFileCompressedLength;
dwPos+=LZWSingleFileHead.wFileNameLength;
pfileIn->Seek(dwPos,CFile::begin);
}
pfileIn->Close();
return TRUE;
}