www.pudn.com > Compression.rar > main.cpp


#include "Codec/Huffman.h"
#include "Codec/LZ77.h"
#include "Codec/LZ78.h"
#include "Codec/LZW.h"
#include "Codec/Arithmetic.h"
#include "Codec/RLE.h"
#include "Generic.h"  

#include "Fatal/Fatal.h"  
#include 
#include 
#include 
#include      
#include  
#include 

#define	BLOCK_SIZE	0x10000
#define SIGNATURE	"CODR"

DWORD	block_size; 

void Encode(BYTE* pSource, long Length, char Code, BYTE* pData, long& CmpLength) 
{ 
	long slen, tlen, scount; 
	BYTE *source, *target; 
	 
	int i = 0; 
	for (scount = 0; scount < Length; scount += block_size) 
	{ 
		if ((Length - block_size * i) < block_size) 
		{ 
			slen = Length - block_size * i; 
		} 
		else 
		{ 
			slen = block_size; 
		} 
		i++; 
		 
		source = new BYTE[block_size]; 
		memmove(source, pSource, slen); 
		pSource=pSource+slen; 
		 
		switch(tolower(Code)) 
		{ 
		case 'a': 
			{ 
				printf("Encoding Arithmetic, source block[%d] size = %4ld\n", i,slen); 
				TGeneric *ar = new TGeneric; 
				tlen = ar->GetMaxEncoded(slen); 
				target = new BYTE[tlen+1]; 
				ar->Encode(target+1, tlen, source, slen); 
				if (tlen) 
				{ 
					target[0] = 'a'; 
					delete source; 
					source = target; 
					slen = tlen+1; 
					printf("Encoding Arithmetic, Compressed block size = %4ld\n", slen); 
				} else 
				{ 
					delete target; 
					target = new BYTE[slen+1]; 
					target[0] = 0; 
					memcpy(target+1, source, slen); 
					delete source; 
					source = target; 
					slen++; 
					printf("Encoding Arithmetic, Unpacked block size = %4ld\n", slen); 
				} 
				delete ar; 
			} 
			break; 
			 
		case 'h': 
			{ 
				printf("Encoding Huffman, source block[%d] size = %4ld\n", i,slen); 
				TGeneric < CHuffman > * huf = new TGeneric < CHuffman >; 
				tlen = huf->GetMaxEncoded(slen); 
				target = new BYTE[tlen + 1]; 
				huf->Encode(target + 1, tlen, source, slen); 
				if (tlen) 
				{ 
					target[0] = 'h'; 
					delete source; 
					source = target; 
					slen = tlen + 1; 
                    printf("Encoding Huffman, Compressed block size = %4ld\n", slen); 
				} 
				else 
				{ 
					delete target; 
					target = new BYTE[slen + 1]; 
					target[0] = 0; 
					memcpy(target + 1, source, slen); 
					delete source; 
					source = target; 
					slen++; 
					printf("Encoding Huffman, Unpacked block size = %4ld\n", slen); 
				} 
				delete huf; 
			} 
			break; 
		case '7': 
			{ 
				printf("Encoding LZ77, source block[%d] size = %4ld\n", i,slen); 
				TGeneric < CLZ77 > * lz = new TGeneric < CLZ77 > ; 
				tlen = lz->GetMaxEncoded(slen); 
				target = new BYTE[tlen + 1]; 
				lz->Encode(target + 1, tlen, source, slen); 
				if (tlen) 
				{ 
					target[0] = '7'; 
					delete source; 
					source = target; 
					slen = tlen + 1; 
					printf("Encoding LZ77, Compressed block size = %4ld\n", slen); 
				} 
				else 
				{ 
					delete target; 
					target = new BYTE[slen + 1]; 
					target[0] = 0; 
					memcpy(target + 1, source, slen); 
					delete source; 
					source = target; 
					slen++; 
                    printf("Encoding LZ77, Unpacked block size = %4ld\n", slen); 
				} 
				delete lz; 
			} 
			break; 
		case '8': 
			{ 
				printf("Encoding LZ78, source block[%d] size = %4ld\n", i,slen); 
				TGeneric < CLZ78 > * lz = new TGeneric < CLZ78 > ; 
				tlen = lz->GetMaxEncoded(slen); 
				target = new BYTE[tlen + 1]; 
				lz->Encode(target + 1, tlen, source, slen); 
				if (tlen) 
				{ 
					target[0] = '8'; 
					delete source; 
					source = target; 
					slen = tlen + 1; 
					printf("Encoding LZ78, Compressed block size = %4ld\n", slen); 
				} 
				else 
				{ 
					delete target; 
					target = new BYTE[slen + 1]; 
					target[0] = 0; 
					memcpy(target + 1, source, slen); 
					delete source; 
					source = target; 
					slen++; 
					printf("Encoding LZ78, Unpacked block size = %4ld\n", slen); 
				} 
				delete lz; 
			} 
			break; 
		case 'w': 
			{ 
				printf("Encoding LZW, source block[%d] size = %4ld\n", i,slen); 
				TGeneric < CLZW > * lz = new TGeneric < CLZW > ; 
				tlen = lz->GetMaxEncoded(slen); 
				target = new BYTE[tlen + 1]; 
				lz->Encode(target + 1, tlen, source, slen); 
				if (tlen) 
				{ 
					target[0] = 'w'; 
					delete source; 
					source = target; 
					slen = tlen + 1; 
					printf("Encoding LZW, Compressed block size = %4ld\n", slen); 
				} 
				else 
				{ 
					delete target; 
					target = new BYTE[slen + 1]; 
					target[0] = 0; 
					memcpy(target + 1, source, slen); 
					delete source; 
					source = target; 
					slen++; 
					printf("Encoding LZW, Unpacked block size = %4ld\n", slen); 
				} 
				delete lz; 
			} 
			break; 
		case 'r': 
			{ 
				printf("Encoding RLE, source block[%d] size = %4ld\n", i,slen); 
				TGeneric < CRLE > * rle = new TGeneric < CRLE > ; 
				tlen = rle->GetMaxEncoded(slen); 
				target = new BYTE[tlen + 1]; 
				rle->Encode(target + 1, tlen, source, slen); 
				if (tlen) 
				{ 
					target[0] = 'r'; 
					delete source; 
					source = target; 
					slen = tlen + 1; 
					printf("Encoding RLE, Compressed block size = %4ld\n", slen); 
				} 
				else 
				{ 
					delete target; 
					target = new BYTE[slen + 1]; 
					target[0] = 0; 
					memcpy(target + 1, source, slen); 
					delete source; 
					source = target; 
					slen++; 
					printf("Encoding RLE, Unpacked block size = %4ld\n", slen); 
				} 
				delete rle; 
			} 
			break; 
		case 'c': 
			delete source; 
			FatalError("DCT compression is not implemented yet!\n"); 
			break; 
		case 'f': 
			delete source; 
			FatalError("Furie Transform compression is not implemented yet!\n"); 
			break; 
		default: 
			delete source; 
			FatalError("Unrecognized method of compression!\n"); 
			break; 
            } 
			 
			memmove(pData, source, slen); 
			pData=pData+slen; 
			CmpLength += slen; 
			delete source; 
	} 
	 
	printf("Compression successfull. Compressed total size = %ld\n", CmpLength); 
} 
 
void Decode(BYTE* pData, long CmpLength, BYTE* pSource, long& Length) 
{ 
	long slen,tlen,temp,scount=0; 
	int delta,saved; 
	BYTE *source, *target; 
	slen = min((DWORD)CmpLength,block_size); 
	while(scount *ar = new TGeneric; 
			tlen = ar->GetMaxDecoded(source+1+delta); 
			target = new BYTE[tlen]; 
			temp = ar->Decode(target, tlen, source+1+delta, slen-1-delta); 
			delete source; 
			source = target; 
			slen = tlen; 
			delta = 0; 
			delete ar; 
		} 
		break; 
		case 'h': 
			{     
				printf("Decoding Huffman, compressed size = %ld\n", slen); 
				TGeneric *huf = new TGeneric; 
				tlen = huf->GetMaxDecoded(source+1+delta); 
				target = new BYTE[tlen]; 
				temp = huf->Decode(target, tlen, source+1+delta, slen-1-delta); 
				delete source; 
				source = target; 
				slen = tlen; 
				delta = 0; 
				delete huf; 
			} 
			break; 
		case '7': 
			{ 
				printf("Decoding LZ77, compressed size = %ld\n", slen); 
				TGeneric *lz = new TGeneric; 
				tlen = lz->GetMaxDecoded(source+1+delta); 
				target = new BYTE[tlen]; 
				temp = lz->Decode(target, tlen, source+1+delta, slen-1-delta); 
				delete source; 
				source = target; 
				slen = tlen; 
				delta = 0; 
				delete lz; 
			} 
			break; 
		case '8': 
			{ 
				printf("Decoding LZ78, compressed size = %ld\n", slen); 
				TGeneric *lz = new TGeneric; 
				tlen = lz->GetMaxDecoded(source+1+delta); 
				target = new BYTE[tlen]; 
				temp = lz->Decode(target, tlen, source+1+delta, slen-1-delta); 
				delete source; 
				source = target; 
				slen = tlen; 
				delta = 0; 
				delete lz; 
			} 
			break; 
		case 'w': 
			{ 
				printf("Decoding LZW, compressed size = %ld\n", slen); 
				TGeneric *lz = new TGeneric; 
				tlen = lz->GetMaxDecoded(source+1+delta); 
				target = new BYTE[tlen]; 
				temp = lz->Decode(target, tlen, source+1+delta, slen-1-delta); 
				delete source; 
				source = target; 
				slen = tlen; 
				delta = 0; 
				delete lz; 
			} 
			break; 
		case 'r': 
			{ 
				printf("Decoding RLE, compressed size = %ld\n", slen); 
				TGeneric *rle = new TGeneric; 
				tlen = rle->GetMaxDecoded(source+1+delta); 
				target = new BYTE[tlen]; 
				temp = rle->Decode(target, tlen, source+1+delta, slen-1-delta); 
				delete source; 
				source = target; 
				slen = tlen; 
				delta = 0; 
				delete rle; 
			} 
			break; 
		case 'c': 
			delete source; 
			FatalError("DCT decompression is not implemented yet!\n"); 
			break; 
		case 'f': 
			delete source; 
			FatalError("Furie Transform decompression is not implemented yet!\n"); 
			break; 
		case 0:	// not coded data 
			printf("Unpacked data block, size = %ld\n", slen); 
			delta++; 
			temp = 0; 
			break; 
		default: 
			delete source; 
			FatalError("Unrecognized method of decompression!\n"); 
			break; 
			} 
			if (!delta && !saved) 
			{ 
				scount += temp + 1; 
				pData=pData+temp + 1; 
				saved = 1; 
				printf("Decoding , compressed size = %ld\n", temp+1); 
			} 
			 
			if (!saved) 
			{ 
				delete source; 
				source = new BYTE[block_size+delta]; 
				memmove(source, pData, slen+delta);  
				 
				 
				scount += slen + delta; 
				pData=pData+slen+delta; 
				printf("Decoding , compressed size = %ld\n", slen+delta); 
				 
				 
			} 
			 
			memmove(pSource, source+ delta, slen);//-delta); 
			pSource=pSource+slen;//-delta; 
			Length += slen;//-delta; 
			 
			delete source; 
	} 
	printf("Decompression successfull. Decompressed size = %ld\n", Length); 
	 
} 
 

void Encode(FILE* s, FILE* t, char* sequence) 
{ 
    int i; 
    long slen, tlen, scount, length, compressed = 0; 
    BYTE* source, * target; 
    BYTE* signature = (BYTE*)SIGNATURE; 
    compressed += fwrite(signature, 1, strlen((char*)signature), t); 
    compressed += fwrite(&block_size, 1, sizeof(DWORD), t); 
    fseek(s, 0, SEEK_END); 
    length = ftell(s); 
    fseek(s, 0, SEEK_SET); 
    for (scount = 0; scount < length; scount += block_size) 
    {    
		int n=(scount+block_size)/block_size; 
        source = new BYTE[block_size]; 
        slen = fread(source, 1, block_size, s); 
        if (!slen) 
            break; 
        for (i = 0; sequence[i]; i++) 
        { 
            switch (tolower(sequence[i])) 
            { 
			case 'a': 
				{ 
					printf("Encoding Arithmetic, source block[%d] size = %4ld\n", n,slen); 
					TGeneric < CArithmetic > * ar = new TGeneric  ; 
					tlen = ar->GetMaxEncoded(slen); 
					target = new BYTE[tlen + 1]; 
					ar->Encode(target + 1, tlen, source, slen); 
					if (tlen) 
					{ 
						target[0] = 'a'; 
						delete source; 
						source = target; 
						slen = tlen + 1; 
                        printf("Encoding Arithmetic, Compressed block size = %4ld\n", slen); 
					} 
					else 
					{ 
						delete target; 
						target = new BYTE[slen + 1]; 
						target[0] = 0; 
						memcpy(target + 1, source, slen); 
						delete source; 
						source = target; 
						slen++; 
                        printf("Encoding Arithmetic, Unpacked block size = %4ld\n", slen); 
					} 
					delete ar; 
				} 
				break; 
			case 'h': 
				{ 
					printf("Encoding Huffman, source block[%d] size = %4ld\n", n,slen); 
					TGeneric < CHuffman > * huf = new TGeneric < CHuffman > 
						; 
					tlen = huf->GetMaxEncoded(slen); 
					target = new BYTE[tlen + 1]; 
					huf->Encode(target + 1, tlen, source, slen); 
					if (tlen) 
					{ 
						target[0] = 'h'; 
						delete source; 
						source = target; 
						slen = tlen + 1; 
						printf("Encoding Huffman, Compressed block size = %4ld\n", slen); 
					} 
					else 
					{ 
						delete target; 
						target = new BYTE[slen + 1]; 
						target[0] = 0; 
						memcpy(target + 1, source, slen); 
						delete source; 
						source = target; 
						slen++; 
						printf("Encoding Huffman, Unpacked block size = %4ld\n", slen); 
					} 
					delete huf; 
				} 
				break; 
			case '7': 
				{ 
					printf("Encoding LZ77, source block[%d] size = %4ld\n", n,slen); 
					TGeneric < CLZ77 > * lz = new TGeneric < CLZ77 > ; 
					tlen = lz->GetMaxEncoded(slen); 
					target = new BYTE[tlen + 1]; 
					lz->Encode(target + 1, tlen, source, slen); 
					if (tlen) 
					{ 
						target[0] = '7'; 
						delete source; 
						source = target; 
						slen = tlen + 1; 
						printf("Encoding LZ77, Compressed block size = %4ld\n", slen); 
					} 
					else 
					{ 
						delete target; 
						target = new BYTE[slen + 1]; 
						target[0] = 0; 
						memcpy(target + 1, source, slen); 
						delete source; 
						source = target; 
						slen++; 
						printf("Encoding LZ77, Unpacked block size = %4ld\n", slen); 
					} 
					delete lz; 
				} 
				break; 
			case '8': 
				{ 
					printf("Encoding LZ78, source block[%d] size = %4ld\n", n,slen); 
					TGeneric < CLZ78 > * lz = new TGeneric < CLZ78 > ; 
					tlen = lz->GetMaxEncoded(slen); 
					target = new BYTE[tlen + 1]; 
					lz->Encode(target + 1, tlen, source, slen); 
					if (tlen) 
					{ 
						target[0] = '8'; 
						delete source; 
						source = target; 
						slen = tlen + 1; 
						printf("Encoding LZ78, Compressed block size = %4ld\n", slen); 
					} 
					else 
					{ 
						delete target; 
						target = new BYTE[slen + 1]; 
						target[0] = 0; 
						memcpy(target + 1, source, slen); 
						delete source; 
						source = target; 
						slen++; 
						printf("Encoding LZ78, Unpacked block size = %4ld\n", slen); 
					} 
					delete lz; 
				} 
				break;
			case 'w': 
				{ 
					printf("Encoding LZW, source block[%d] size = %4ld\n", n,slen); 
					TGeneric < CLZW > * lz = new TGeneric < CLZW > ; 
					tlen = lz->GetMaxEncoded(slen); 
					target = new BYTE[tlen + 1]; 
					lz->Encode(target + 1, tlen, source, slen); 
					if (tlen) 
					{ 
						target[0] = 'w'; 
						delete source; 
						source = target; 
						slen = tlen + 1; 
						printf("Encoding LZW, Compressed block size = %4ld\n", slen); 
					} 
					else 
					{ 
						delete target; 
						target = new BYTE[slen + 1]; 
						target[0] = 0; 
						memcpy(target + 1, source, slen); 
						delete source; 
						source = target; 
						slen++; 
						printf("Encoding LZW, Unpacked block size = %4ld\n", slen); 
					} 
					delete lz; 
				} 
				break; 
			case 'r': 
				{ 
					printf("Encoding RLE, source block[%d] size = %4ld\n", n,slen); 
					TGeneric < CRLE > * rle = new TGeneric < CRLE > ; 
					tlen = rle->GetMaxEncoded(slen); 
					target = new BYTE[tlen + 1]; 
					rle->Encode(target + 1, tlen, source, slen); 
					if (tlen) 
					{ 
						target[0] = 'r'; 
						delete source; 
						source = target; 
						slen = tlen + 1; 
						printf("Encoding RLE, Compressed block size = %4ld\n", slen); 
					} 
					else 
					{ 
						delete target; 
						target = new BYTE[slen + 1]; 
						target[0] = 0; 
						memcpy(target + 1, source, slen); 
						delete source; 
						source = target; 
						slen++; 
						printf("Encoding RLE, Unpacked block size = %4ld\n", slen); 
					} 
					delete rle; 
				} 
				break; 
			case 'c': 
				delete source; 
				fclose(s); 
				fclose(t); 
				FatalError("DCT compression is not implemented yet!\n"); 
				break; 
			case 'f': 
				delete source; 
				fclose(s); 
				fclose(t); 
				FatalError("Furie Transform compression is not implemented yet!\n"); 
				break; 
			default: 
				delete source; 
				fclose(s); 
				fclose(t); 
				FatalError("Unrecognized method of compression!\n"); 
				break; 
            } 
        } 
        if (!i) 
        { 
            delete source; 
            fclose(s); 
            fclose(t); 
            FatalError("Compression method is not specified!\n"); 
        } 
        if (!scount) 
            compressed += fwrite(&i, 1, 1, t); 
        compressed += fwrite(source, 1, slen, t); 
        delete source; 
    } 
    printf("Compression successfull. Compressed total size = %ld\n", compressed); 
} 

void Decode(FILE *s, FILE *t)
{
	int i, delta, saved, count = 0;
	long slen, tlen, length, decompressed = 0;
	long last_point, temp;
	BYTE *source, *target;
	BYTE signature[20];
	fseek(s, 0, SEEK_END);
	length = ftell(s);
	fseek(s, 0, SEEK_SET);
	fread(signature, 1, strlen(SIGNATURE), s);
	if (memcmp(signature, SIGNATURE, strlen((char*)SIGNATURE)))
		FatalError("The source file is not encoded by this tool.\nDecoding impossible.\n");
	fread(&block_size, 1, sizeof(DWORD), s);
	fread(&count, 1, 1, s);
	length--;
	last_point = ftell(s);
	slen = min((DWORD)length, block_size);
	while (last_point < length)
	{
		delta = 0;
		saved = 0;
		fseek(s, last_point, SEEK_SET);
		source = new BYTE[block_size];
		slen = fread(source, 1, block_size, s);
		for (i = 0; i < count; i++)
		{
			temp = 0;
			switch(tolower(source[delta]))
			{
			case 'a':
				{
					printf("Decoding Arithmetic, compressed size = %ld\n", slen);
					TGeneric *ar = new TGeneric;
					tlen = ar->GetMaxDecoded(source+1+delta);
					target = new BYTE[tlen];
					temp = ar->Decode(target, tlen, source+1+delta, slen-1-delta);
					delete source;
					source = target;
					slen = tlen;
					delta = 0;
					delete ar;
				}
				break;
			case 'h':
				{
					printf("Decoding Huffman, compressed size = %ld\n", slen);
					TGeneric *huf = new TGeneric;
					tlen = huf->GetMaxDecoded(source+1+delta);
					target = new BYTE[tlen];
					temp = huf->Decode(target, tlen, source+1+delta, slen-1-delta);
					delete source;
					source = target;
					slen = tlen;
					delta = 0;
					delete huf;
				}
				break;
			case '7':
				{
					printf("Decoding LZ77, compressed size = %ld\n", slen);
					TGeneric *lz = new TGeneric;
					tlen = lz->GetMaxDecoded(source+1+delta);
					target = new BYTE[tlen];
					temp = lz->Decode(target, tlen, source+1+delta, slen-1-delta);
					delete source;
					source = target;
					slen = tlen;
					delta = 0;
					delete lz;
				}
				break;
			case '8':
				{
					printf("Decoding LZ78, compressed size = %ld\n", slen);
					TGeneric *lz = new TGeneric;
					tlen = lz->GetMaxDecoded(source+1+delta);
					target = new BYTE[tlen];
					temp = lz->Decode(target, tlen, source+1+delta, slen-1-delta);
					delete source;
					source = target;
					slen = tlen;
					delta = 0;
					delete lz;
				}
				break;
			case 'w':
				{
					printf("Decoding LZW, compressed size = %ld\n", slen);
					TGeneric *lz = new TGeneric;
					tlen = lz->GetMaxDecoded(source+1+delta);
					target = new BYTE[tlen];
					temp = lz->Decode(target, tlen, source+1+delta, slen-1-delta);
					delete source;
					source = target;
					slen = tlen;
					delta = 0;
					delete lz;
				}
				break;
			case 'r':
				{
					printf("Decoding RLE, compressed size = %ld\n", slen);
					TGeneric *rle = new TGeneric;
					tlen = rle->GetMaxDecoded(source+1+delta);
					target = new BYTE[tlen];
					temp = rle->Decode(target, tlen, source+1+delta, slen-1-delta);
					delete source;
					source = target;
					slen = tlen;
					delta = 0;
					delete rle;
				}
				break;
			case 'c':
				fclose(s);
				fclose(t);
				FatalError("DCT compression is not implemented yet");
				break;
			case 'f':
				fclose(s);
				fclose(t);
				FatalError("Furie Transform compression is not implemented yet");
				break;
			case 0:	// not coded data
				printf("Unpacked data block, size = %ld\n", slen);
				delta++;
				temp = 0;
				break;
			default:
				fclose(s);
				fclose(t);
				FatalError("Unrecognized method of compression");
				break;
			};
			if (!delta && !saved)
			{
				last_point += temp + i + 1;
				saved = 1; 
				printf("Decoding , compressed size = %ld\n", temp+i+1);
			}
		}
		if (!saved)
		{ 
			last_point += slen + delta; 
            printf("Decoding , compressed size = %ld\n", slen+delta);  
		}
		if (!i)
		{
			fclose(s);
			fclose(t);
			FatalError("Compression method is not specified");
		}
		decompressed += fwrite(source + delta, 1, slen - delta, t);
		delete source;
	}
	printf("Decompression successfull. Decompressed size = %ld\n", decompressed);
} 

void Help(char *name)
{
	printf("Use this program like this:\n");
	printf("%s [block_size] -{d|{e{a|h|7|8|w|c|f}}}  \n", name);
	printf("Where:\n");
	printf("\tblock_size\t- Size of sub block of data to encode\n");
	printf("\t\t- Source file name\n");
	printf("\t\t- Target file name\n");
	printf("Options requered:\n");
	printf("\te\t- Encode file\n");
	printf("\td\t- Decode file\n");
	printf("Encoding methods:\n");
	printf("\ta\t- Arithmetic coding\n");
	printf("\th\t- Huffman coding\n");
	printf("\t7\t- LZ77 coding\n");
	printf("\t8\t- LZ78 coding\n");
	printf("\tw\t- LZW coding\n");
	printf("\tr\t- RLE coding\n");
	printf("\tc\t- DCT encoding for graphic\n");
	printf("\tf\t- Furie transform\n");
} 

int main(int argc,char **argv )  
{
	 
	FILE *s, *t;
	char *sname, *tname, *options;
	printf("Compression utility\n");
	printf("Revised Author: CYY\n");
	if ((argc != 4) && (argc != 5))   
	{
		Help(argv[0]);  
		return 1;       
	}
	
	block_size = atol(argv[1]);  
	if (!block_size)
		block_size = BLOCK_SIZE;
	
	options = argv[1 + (argc == 5)]; 
	sname = argv[2 + (argc == 5)];
	tname = argv[3 + (argc == 5)];
	
	s = fopen(sname, "rb");
	if (s == NULL)
		FatalError("Can`t open source file!\n");
	t = fopen(tname, "wb+");
	if (t == NULL)
	{
		fclose(s);
		FatalError("Can`t create target file!\n");
	}
	 
	 
	 
	 
	int No; 
	 
	fseek(s, 0, SEEK_END); 
	long length = ftell(s); 
	fseek(s, 0, SEEK_SET); 
	
	switch(tolower(options[1]))
	{
	case 'e':  
		 
		printf("Encoding , source total size = %4ld\n", length); 
		 
		cout<<"No. :"; 
		cin>>No; 
		if (No == 1) 
		{ 
			Encode(s, t, options + 2); 
		} 
		else 
		{ 
            BYTE* pSource = new BYTE[length]; 
			fread(pSource, length, 1, s); 
			BYTE* pData = new BYTE[length]; 
			long CmpLength = 0; 
			char* sequence = options + 2; 
			 
			for (int i = 0; sequence[i]; i++) 
			{ 
				Encode(pSource, length, sequence[i], pData, CmpLength); 
				// 将pData(数据块)写入结果文件中,如果要对第一次压缩结果进行二次压缩,编译下面两行代码 
				//pSource = pData;    
				//length = CmpLength; 
                fwrite(pData, CmpLength, 1, t); 
			} 
			 
			if (!i) 
			{ 
				fclose(s); 
				fclose(t); 
				FatalError("Compression method is not specified!\n"); 
			} 
		}
		break;
	case 'd':  
		 
		printf("Decoding , source total size = %4ld\n", length); 
		 
		cout<<"No.:"; 
		cin>>No; 
		if(No == 1) 
		{ 
			Decode(s, t); 
		} 
		else 
		{  
            BYTE* pData = new BYTE[length]; 
			fread(pData, length, 1, s); 
			BYTE* pSource = new BYTE[2*length];  //? 
			long CmpLength = length; 
            long Length = 0; 
             
			Decode(pData, CmpLength, pSource, Length); 
            fwrite(pSource, Length, 1, t); 
		}
		break;
	default:
		fclose(s);
		fclose(t);
		FatalError("Not specified action to perform (Encode or Decode)\n");
	};
	
	fclose(s);
	fclose(t);
	return 0; 
	
}