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