📄 bfc.c
字号:
/************************************************************************** Name: bfc.c* Author: Marcus Geelnard* Description: Basic Compression Library file compressor.** BFC stands for Basic File Compressor.** This is a simple test application for all the compression types* supported by the Basic Compression Library. It compresses or* decompresses an input file with a selected compression algorithm. In no* way is this program intended to be used for general purpose compression.* It is just a testbed for the the different algorithms supported by the* Basic Compression Library.**-------------------------------------------------------------------------* Copyright (c) 2003-2006 Marcus Geelnard** This software is provided 'as-is', without any express or implied* warranty. In no event will the authors be held liable for any damages* arising from the use of this software.** Permission is granted to anyone to use this software for any purpose,* including commercial applications, and to alter it and redistribute it* freely, subject to the following restrictions:** 1. The origin of this software must not be misrepresented; you must not* claim that you wrote the original software. If you use this software* in a product, an acknowledgment in the product documentation would* be appreciated but is not required.** 2. Altered source versions must be plainly marked as such, and must not* be misrepresented as being the original software.** 3. This notice may not be removed or altered from any source* distribution.** Marcus Geelnard* marcus.geelnard at home.se*************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "rle.h"#include "shannonfano.h"#include "huffman.h"#include "rice.h"#include "lz.h"/************************************************************************** ReadWord32()*************************************************************************/int ReadWord32( FILE *f ){ unsigned char buf[4]; fread( buf, 4, 1, f ); return (((unsigned int)buf[0])<<24) + (((unsigned int)buf[1])<<16) + (((unsigned int)buf[2])<<8) + (unsigned int)buf[3];}/************************************************************************** WriteWord32()*************************************************************************/void WriteWord32( int x, FILE *f ){ fputc( (x>>24)&255, f ); fputc( (x>>16)&255, f ); fputc( (x>>8)&255, f ); fputc( x&255, f );}/************************************************************************** GetFileSize()*************************************************************************/long GetFileSize( FILE *f ){ long pos, size; pos = ftell( f ); fseek( f, 0, SEEK_END ); size = ftell( f ); fseek( f, pos, SEEK_SET ); return size;}/************************************************************************** Help()*************************************************************************/void Help( char *prgname ){ printf( "Usage: %s command [algo] infile outfile\n\n", prgname ); printf( "Commands:\n" ); printf( " c Compress\n" ); printf( " d Deompress\n\n" ); printf( "Algo (only specify for compression):\n" ); printf( " rle RLE Compression\n" ); printf( " sf Shannon-Fano compression\n" ); printf( " huff Huffman compression\n" ); printf( " lz LZ77 Compression\n" ); printf( " rice8 Rice compresison of 8-bit data\n" ); printf( " rice16 Rice compresison of 16-bit data\n" ); printf( " rice32 Rice compresison of 32-bit data\n" ); printf( " rice8s Rice compresison of 8-bit signed data\n" ); printf( " rice16s Rice compresison of 16-bit signed data\n" ); printf( " rice32s Rice compresison of 32-bit signed data\n" );}/************************************************************************** main()*************************************************************************/int main( int argc, char **argv ){ FILE *f; unsigned char *in, *out, command, algo=0; unsigned int insize, outsize=0, *work; char *inname, *outname; /* Check arguments */ if( argc < 4 ) { Help( argv[ 0 ] ); return 0; } /* Get command */ command = argv[1][0]; if( (command != 'c') && (command != 'd') ) { Help( argv[ 0 ] ); return 0; } /* Get algo */ if( argc == 5 && command == 'c' ) { algo = 0; if( strcmp( argv[2], "rle" ) == 0 ) algo = 1; if( strcmp( argv[2], "huff" ) == 0 ) algo = 2; if( strcmp( argv[2], "rice8" ) == 0 ) algo = 3; if( strcmp( argv[2], "rice16" ) == 0 ) algo = 4; if( strcmp( argv[2], "rice32" ) == 0 ) algo = 5; if( strcmp( argv[2], "rice8s" ) == 0 ) algo = 6; if( strcmp( argv[2], "rice16s" ) == 0 ) algo = 7; if( strcmp( argv[2], "rice32s" ) == 0 ) algo = 8; if( strcmp( argv[2], "lz" ) == 0 ) algo = 9; if( strcmp( argv[2], "sf" ) == 0 ) algo = 10; if( !algo ) { Help( argv[ 0 ] ); return 0; } inname = argv[ 3 ]; outname = argv[ 4 ]; } else if( argc == 4 && command == 'd' ) { inname = argv[ 2 ]; outname = argv[ 3 ]; } else { Help( argv[ 0 ] ); return 0; } /* Open input file */ f = fopen( inname, "rb" ); if( !f ) { printf( "Unable to open input file \"%s\".\n", inname ); return 0; } /* Get input file size */ insize = GetFileSize( f ); /* Decompress? */ if( command == 'd' ) { /* Read header */ algo = ReadWord32( f ); /* Dummy */ algo = ReadWord32( f ); outsize = ReadWord32( f ); insize -= 12; } /* Print operation... */ switch( algo ) { case 1: printf( "RLE " ); break; case 2: printf( "Huffman " ); break; case 3: printf( "Rice 8-bit " ); break; case 4: printf( "Rice 16-bit " ); break; case 5: printf( "Rice 32-bit " ); break; case 6: printf( "Rice 8-bit signed " ); break; case 7: printf( "Rice 16-bit signed " ); break; case 8: printf( "Rice 32-bit signed " ); break; case 9: printf( "LZ77 " ); break; case 10: printf( "Shannon-Fano " ); break; } switch( command ) { case 'c': printf( "compress " ); break; case 'd': printf( "decompress " ); break; } printf( "%s to %s...\n", inname, outname ); /* Read input file */ printf( "Input file: %d bytes\n", insize ); in = (unsigned char *) malloc( insize ); if( !in ) { printf( "Not enough memory\n" ); fclose( f ); return 0; } fread( in, insize, 1, f ); fclose( f ); /* Show output file size for decompression */ if( command == 'd' ) { printf( "Output file: %d bytes\n", outsize ); } /* Open output file */ f = fopen( outname, "wb" ); if( !f ) { printf( "Unable to open output file \"%s\".\n", outname ); free( in ); return 0; } /* Compress? */ if( command == 'c' ) { /* Write header */ fwrite( "BCL1", 4, 1, f ); WriteWord32( algo, f ); WriteWord32( insize, f ); /* Worst case buffer size */ outsize = (insize*104+50)/100 + 384; } /* Allocate memory for output buffer */ out = malloc( outsize ); if( !out ) { printf( "Not enough memory\n" ); fclose( f ); free( in ); return 0; } /* Compress or decompress */ if( command == 'c' ) { switch( algo ) { case 1: outsize = RLE_Compress( in, out, insize ); break; case 2: outsize = Huffman_Compress( in, out, insize ); break; case 3: outsize = Rice_Compress( in, out, insize, RICE_FMT_UINT8 ); break; case 4: outsize = Rice_Compress( in, out, insize, RICE_FMT_UINT16 ); break; case 5: outsize = Rice_Compress( in, out, insize, RICE_FMT_UINT32 ); break; case 6: outsize = Rice_Compress( in, out, insize, RICE_FMT_INT8 ); break; case 7: outsize = Rice_Compress( in, out, insize, RICE_FMT_INT16 ); break; case 8: outsize = Rice_Compress( in, out, insize, RICE_FMT_INT32 ); break; case 9: work = malloc( sizeof(unsigned int) * (65536+insize) ); if( work ) { outsize = LZ_CompressFast( in, out, insize, work ); free( work ); } else { outsize = LZ_Compress( in, out, insize ); } break; case 10: outsize = SF_Compress( in, out, insize ); break; } printf( "Output file: %d bytes (%.1f%%)\n", outsize, 100*(float)outsize/(float)insize ); } else { switch( algo ) { case 1: RLE_Uncompress( in, out, insize ); break; case 2: Huffman_Uncompress( in, out, insize, outsize ); break; case 3: Rice_Uncompress( in, out, insize, outsize, RICE_FMT_UINT8 ); break; case 4: Rice_Uncompress( in, out, insize, outsize, RICE_FMT_UINT16 ); break; case 5: Rice_Uncompress( in, out, insize, outsize, RICE_FMT_UINT32 ); break; case 6: Rice_Uncompress( in, out, insize, outsize, RICE_FMT_INT8 ); break; case 7: Rice_Uncompress( in, out, insize, outsize, RICE_FMT_INT16 ); break; case 8: Rice_Uncompress( in, out, insize, outsize, RICE_FMT_INT32 ); break; case 9: LZ_Uncompress( in, out, insize ); break; case 10: SF_Uncompress( in, out, insize, outsize ); break; default: printf( "Unknown compression algorithm: %d\n", algo ); free( in ); free( out ); fclose( f ); return 0; } } /* Write output file */ fwrite( out, outsize, 1, f ); fclose( f ); /* Free memory */ free( in ); free( out ); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -