Added : LZ4Demo : can handle appended compressed streams.

git-svn-id: https://lz4.googlecode.com/svn/trunk@65 650e7d94-2a16-8b24-b05c-7c0b3f6821cd
This commit is contained in:
yann.collet.73@gmail.com 2012-05-12 19:14:43 +00:00
parent d8184bf7ef
commit 3bc3a6afc3
2 changed files with 28 additions and 36 deletions

View File

@ -24,6 +24,8 @@
//************************************** //**************************************
// Compiler Options // Compiler Options
//************************************** //**************************************
// Visual warning messages
#define _CRT_SECURE_NO_WARNINGS
// Under Linux at least, pull in the *64 commands // Under Linux at least, pull in the *64 commands
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE

View File

@ -74,7 +74,6 @@ static inline unsigned int swap32(unsigned int x) {
#define COMPRESSOR_VERSION "" #define COMPRESSOR_VERSION ""
#define COMPILED __DATE__ #define COMPILED __DATE__
#define AUTHOR "Yann Collet" #define AUTHOR "Yann Collet"
#define BINARY_NAME "lz4demo.exe"
#define EXTENSION ".lz4" #define EXTENSION ".lz4"
#define WELCOME_MESSAGE "*** %s %s, by %s (%s) ***\n", COMPRESSOR_NAME, COMPRESSOR_VERSION, AUTHOR, COMPILED #define WELCOME_MESSAGE "*** %s %s, by %s (%s) ***\n", COMPRESSOR_NAME, COMPRESSOR_VERSION, AUTHOR, COMPILED
@ -102,10 +101,10 @@ static const int one = 1;
//**************************** //****************************
// Functions // Functions
//**************************** //****************************
int usage() int usage(char* exename)
{ {
DISPLAY( "Usage :\n"); DISPLAY( "Usage :\n");
DISPLAY( " %s [arg] input output\n", BINARY_NAME); DISPLAY( " %s [arg] input output\n", exename);
DISPLAY( "Arguments :\n"); DISPLAY( "Arguments :\n");
DISPLAY( " -c : compression (default)\n"); DISPLAY( " -c : compression (default)\n");
DISPLAY( " -d : decompression \n"); DISPLAY( " -d : decompression \n");
@ -118,10 +117,10 @@ int usage()
} }
int badusage() int badusage(char* exename)
{ {
DISPLAY("Wrong parameters\n"); DISPLAY("Wrong parameters\n");
usage(); usage(exename);
return 0; return 0;
} }
@ -235,7 +234,7 @@ int decode_file(char* input_filename, char* output_filename)
char* out_buff; char* out_buff;
size_t uselessRet; size_t uselessRet;
int sinkint; int sinkint;
unsigned int nextSize; unsigned int chunkSize;
FILE* finput; FILE* finput;
FILE* foutput; FILE* foutput;
clock_t start, end; clock_t start, end;
@ -253,43 +252,33 @@ int decode_file(char* input_filename, char* output_filename)
if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 7; } if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 7; }
// Check Archive Header // Check Archive Header
uselessRet = fread(out_buff, 1, ARCHIVE_MAGICNUMBER_SIZE, finput); chunkSize = 0;
nextSize = *(unsigned int*)out_buff; uselessRet = fread(&chunkSize, 1, ARCHIVE_MAGICNUMBER_SIZE, finput);
LITTLE_ENDIAN32(nextSize); LITTLE_ENDIAN32(chunkSize);
if (nextSize != ARCHIVE_MAGICNUMBER) { DISPLAY("Unrecognized header : file cannot be decoded\n"); return 6; } if (chunkSize != ARCHIVE_MAGICNUMBER) { DISPLAY("Unrecognized header : file cannot be decoded\n"); return 6; }
// First Block
*(unsigned int*)in_buff = 0;
uselessRet = fread(in_buff, 1, 4, finput);
nextSize = *(unsigned int*)in_buff;
LITTLE_ENDIAN32(nextSize);
// Main Loop // Main Loop
while (1) while (1)
{ {
// Block Size
uselessRet = fread(&chunkSize, 1, 4, finput);
if( uselessRet==0 ) break; // Nothing to read : file read is completed
LITTLE_ENDIAN32(chunkSize);
if (chunkSize == ARCHIVE_MAGICNUMBER)
continue; // appended compressed stream
// Read Block // Read Block
uselessRet = fread(in_buff, 1, nextSize, finput); uselessRet = fread(in_buff, 1, chunkSize, finput);
// Check Next Block
uselessRet = (size_t) fread(&nextSize, 1, 4, finput);
if( uselessRet==0 ) break; // Nothing read : file read is completed
LITTLE_ENDIAN32(nextSize);
// Decode Block // Decode Block
sinkint = LZ4_uncompress(in_buff, out_buff, CHUNKSIZE); sinkint = LZ4_uncompress_unknownOutputSize(in_buff, out_buff, chunkSize, CHUNKSIZE);
if (sinkint < 0) { DISPLAY("Decoding Failed ! Corrupted input !\n"); return 9; } if (sinkint < 0) { DISPLAY("Decoding Failed ! Corrupted input !\n"); return 9; }
filesize += CHUNKSIZE; filesize += sinkint;
// Write Block // Write Block
fwrite(out_buff, 1, CHUNKSIZE, foutput); fwrite(out_buff, 1, sinkint, foutput);
} }
// Last Block (which size is <= CHUNKSIZE, but let LZ4 figure that out)
uselessRet = fread(in_buff, 1, nextSize, finput);
sinkint = LZ4_uncompress_unknownOutputSize(in_buff, out_buff, nextSize, CHUNKSIZE);
filesize += sinkint;
fwrite(out_buff, 1, sinkint, foutput);
// Status // Status
end = clock(); end = clock();
DISPLAY( "Successfully decoded %llu bytes \n", (unsigned long long)filesize); DISPLAY( "Successfully decoded %llu bytes \n", (unsigned long long)filesize);
@ -315,6 +304,7 @@ int main(int argc, char** argv)
decode=0, decode=0,
bench=0, bench=0,
filenamesStart=2; filenamesStart=2;
char* exename=argv[0];
char* input_filename=0; char* input_filename=0;
char* output_filename=0; char* output_filename=0;
#ifdef _WIN32 #ifdef _WIN32
@ -327,7 +317,7 @@ int main(int argc, char** argv)
// Welcome message // Welcome message
DISPLAY( WELCOME_MESSAGE); DISPLAY( WELCOME_MESSAGE);
if (argc<2) { badusage(); return 1; } if (argc<2) { badusage(exename); return 1; }
for(i=1; i<argc; i++) for(i=1; i<argc; i++)
{ {
@ -341,7 +331,7 @@ int main(int argc, char** argv)
argument ++; argument ++;
// Display help on usage // Display help on usage
if ( argument[0] =='h' ) { usage(); return 0; } if ( argument[0] =='h' ) { usage(exename); return 0; }
// Compression (default) // Compression (default)
if ( argument[0] =='c' ) { compression=1; continue; } if ( argument[0] =='c' ) { compression=1; continue; }
@ -375,18 +365,18 @@ int main(int argc, char** argv)
} }
// No input filename ==> Error // No input filename ==> Error
if(!input_filename) { badusage(); return 1; } if(!input_filename) { badusage(exename); return 1; }
if (bench) return BMK_benchFile(argv+filenamesStart, argc-filenamesStart, 0); if (bench) return BMK_benchFile(argv+filenamesStart, argc-filenamesStart, 0);
// No output filename // No output filename
if (!output_filename) { badusage(); return 1; } if (!output_filename) { badusage(exename); return 1; }
if (decode) return decode_file(input_filename, output_filename); if (decode) return decode_file(input_filename, output_filename);
if (compression) return compress_file(input_filename, output_filename); if (compression) return compress_file(input_filename, output_filename);
badusage(); badusage(exename);
return 0; return 0;
} }