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;	 
}