summaryrefslogtreecommitdiffstats
path: root/lzd.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lzd.cc')
-rw-r--r--lzd.cc114
1 files changed, 57 insertions, 57 deletions
diff --git a/lzd.cc b/lzd.cc
index 6fd536a..503bc36 100644
--- a/lzd.cc
+++ b/lzd.cc
@@ -1,5 +1,5 @@
/* Lzd - Educational decompressor for the lzip format
- Copyright (C) 2013-2017 Antonio Diaz Diaz.
+ Copyright (C) 2013-2019 Antonio Diaz Diaz.
This program is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided
@@ -29,7 +29,7 @@
#include <cstring>
#include <stdint.h>
#include <unistd.h>
-#if defined(__MSVCRT__) || defined(__OS2__) || defined(_MSC_VER)
+#if defined(__MSVCRT__) || defined(__OS2__) || defined(__DJGPP__)
#include <fcntl.h>
#include <io.h>
#endif
@@ -130,9 +130,9 @@ public:
const CRC32 crc32;
-typedef uint8_t File_header[6]; // 0-3 magic, 4 version, 5 coded_dict_size
+typedef uint8_t Lzip_header[6]; // 0-3 magic, 4 version, 5 coded_dict_size
-typedef uint8_t File_trailer[20];
+typedef uint8_t Lzip_trailer[20];
// 0-3 CRC32 of the uncompressed data
// 4-11 size of the uncompressed data
// 12-19 member size including header and trailer
@@ -326,6 +326,7 @@ bool LZ_decoder::decode_member() // Returns false if error
const int pos_state = data_position() & pos_state_mask;
if( rdec.decode_bit( bm_match[state()][pos_state] ) == 0 ) // 1st bit
{
+ // literal byte
const uint8_t prev_byte = peek( 0 );
const int literal_state = prev_byte >> ( 8 - literal_context_bits );
Bit_model * const bm = bm_literal[literal_state];
@@ -334,67 +335,66 @@ bool LZ_decoder::decode_member() // Returns false if error
else
put_byte( rdec.decode_matched( bm, peek( rep0 ) ) );
state.set_char();
+ continue;
}
- else // match or repeated match
+ // match or repeated match
+ int len;
+ if( rdec.decode_bit( bm_rep[state()] ) != 0 ) // 2nd bit
{
- int len;
- if( rdec.decode_bit( bm_rep[state()] ) != 0 ) // 2nd bit
+ if( rdec.decode_bit( bm_rep0[state()] ) == 0 ) // 3rd bit
{
- if( rdec.decode_bit( bm_rep0[state()] ) == 0 ) // 3rd bit
- {
- if( rdec.decode_bit( bm_len[state()][pos_state] ) == 0 ) // 4th bit
- { state.set_short_rep(); put_byte( peek( rep0 ) ); continue; }
- }
+ if( rdec.decode_bit( bm_len[state()][pos_state] ) == 0 ) // 4th bit
+ { state.set_short_rep(); put_byte( peek( rep0 ) ); continue; }
+ }
+ else
+ {
+ unsigned distance;
+ if( rdec.decode_bit( bm_rep1[state()] ) == 0 ) // 4th bit
+ distance = rep1;
else
{
- unsigned distance;
- if( rdec.decode_bit( bm_rep1[state()] ) == 0 ) // 4th bit
- distance = rep1;
+ if( rdec.decode_bit( bm_rep2[state()] ) == 0 ) // 5th bit
+ distance = rep2;
else
- {
- if( rdec.decode_bit( bm_rep2[state()] ) == 0 ) // 5th bit
- distance = rep2;
- else
- { distance = rep3; rep3 = rep2; }
- rep2 = rep1;
- }
- rep1 = rep0;
- rep0 = distance;
+ { distance = rep3; rep3 = rep2; }
+ rep2 = rep1;
}
- state.set_rep();
- len = min_match_len + rdec.decode_len( rep_len_model, pos_state );
+ rep1 = rep0;
+ rep0 = distance;
}
- else // match
+ state.set_rep();
+ len = min_match_len + rdec.decode_len( rep_len_model, pos_state );
+ }
+ else // match
+ {
+ rep3 = rep2; rep2 = rep1; rep1 = rep0;
+ len = min_match_len + rdec.decode_len( match_len_model, pos_state );
+ const int len_state = std::min( len - min_match_len, len_states - 1 );
+ rep0 = rdec.decode_tree( bm_dis_slot[len_state], dis_slot_bits );
+ if( rep0 >= start_dis_model )
{
- rep3 = rep2; rep2 = rep1; rep1 = rep0;
- len = min_match_len + rdec.decode_len( match_len_model, pos_state );
- const int len_state = std::min( len - min_match_len, len_states - 1 );
- rep0 = rdec.decode_tree( bm_dis_slot[len_state], dis_slot_bits );
- if( rep0 >= start_dis_model )
+ const unsigned dis_slot = rep0;
+ const int direct_bits = ( dis_slot >> 1 ) - 1;
+ rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits;
+ if( dis_slot < end_dis_model )
+ rep0 += rdec.decode_tree_reversed( bm_dis + ( rep0 - dis_slot ),
+ direct_bits );
+ else
{
- const unsigned dis_slot = rep0;
- const int direct_bits = ( dis_slot >> 1 ) - 1;
- rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits;
- if( dis_slot < end_dis_model )
- rep0 += rdec.decode_tree_reversed( bm_dis + ( rep0 - dis_slot ),
- direct_bits );
- else
+ rep0 += rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits;
+ rep0 += rdec.decode_tree_reversed( bm_align, dis_align_bits );
+ if( rep0 == 0xFFFFFFFFU ) // marker found
{
- rep0 += rdec.decode( direct_bits - dis_align_bits ) << dis_align_bits;
- rep0 += rdec.decode_tree_reversed( bm_align, dis_align_bits );
- if( rep0 == 0xFFFFFFFFU ) // marker found
- {
- flush_data();
- return ( len == min_match_len ); // End Of Stream marker
- }
+ flush_data();
+ return ( len == min_match_len ); // End Of Stream marker
}
}
- state.set_match();
- if( rep0 >= dictionary_size || ( rep0 >= pos && !pos_wrapped ) )
- { flush_data(); return false; }
}
- for( int i = 0; i < len; ++i ) put_byte( peek( rep0 ) );
+ state.set_match();
+ if( rep0 >= dictionary_size || ( rep0 >= pos && !pos_wrapped ) )
+ { flush_data(); return false; }
}
+ for( int i = 0; i < len; ++i ) put_byte( peek( rep0 ) );
}
flush_data();
return false;
@@ -412,7 +412,7 @@ int main( const int argc, const char * const argv[] )
"It is not safe to use lzd for any real work.\n"
"\nUsage: %s < file.lz > file\n", argv[0] );
std::printf( "Lzd decompresses from standard input to standard output.\n"
- "\nCopyright (C) 2017 Antonio Diaz Diaz.\n"
+ "\nCopyright (C) 2019 Antonio Diaz Diaz.\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n"
"Report bugs to lzip-bug@nongnu.org\n"
@@ -420,14 +420,14 @@ int main( const int argc, const char * const argv[] )
return 0;
}
-#if defined(__MSVCRT__) || defined(__OS2__) || defined(_MSC_VER)
- setmode( fileno( stdin ), O_BINARY );
- setmode( fileno( stdout ), O_BINARY );
+#if defined(__MSVCRT__) || defined(__OS2__) || defined(__DJGPP__)
+ setmode( STDIN_FILENO, O_BINARY );
+ setmode( STDOUT_FILENO, O_BINARY );
#endif
for( bool first_member = true; ; first_member = false )
{
- File_header header; // verify header
+ Lzip_header header; // verify header
for( int i = 0; i < 6; ++i ) header[i] = std::getc( stdin );
if( std::feof( stdin ) || std::memcmp( header, "LZIP\x01", 5 ) != 0 )
{
@@ -446,7 +446,7 @@ int main( const int argc, const char * const argv[] )
if( !decoder.decode_member() )
{ std::fputs( "Data error\n", stderr ); return 2; }
- File_trailer trailer; // verify trailer
+ Lzip_trailer trailer; // verify trailer
for( int i = 0; i < 20; ++i ) trailer[i] = std::getc( stdin );
unsigned crc = 0;
for( int i = 3; i >= 0; --i ) { crc <<= 8; crc += trailer[i]; }
@@ -457,7 +457,7 @@ int main( const int argc, const char * const argv[] )
}
if( std::fclose( stdout ) != 0 )
- { std::fprintf( stderr, "Can't close stdout: %s\n", std::strerror( errno ) );
+ { std::fprintf( stderr, "Error closing stdout: %s\n", std::strerror( errno ) );
return 1; }
return 0;
}