summaryrefslogtreecommitdiffstats
path: root/lzlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'lzlib.c')
-rw-r--r--lzlib.c152
1 files changed, 74 insertions, 78 deletions
diff --git a/lzlib.c b/lzlib.c
index bc3b32c..26764d0 100644
--- a/lzlib.c
+++ b/lzlib.c
@@ -1,5 +1,5 @@
/* Lzlib - Compression library for the lzip format
- Copyright (C) 2009-2014 Antonio Diaz Diaz.
+ Copyright (C) 2009-2015 Antonio Diaz Diaz.
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,33 +35,33 @@
#include "cbuffer.c"
#include "decoder.h"
#include "decoder.c"
+#include "encoder_base.h"
+#include "encoder_base.c"
#include "encoder.h"
#include "encoder.c"
+#include "fast_encoder.h"
+#include "fast_encoder.c"
struct LZ_Encoder
{
unsigned long long partial_in_size;
unsigned long long partial_out_size;
- struct Matchfinder * matchfinder;
- struct LZ_encoder * lz_encoder;
+ struct LZ_encoder_base * lz_encoder_base; /* these 3 pointers make a */
+ struct LZ_encoder * lz_encoder; /* polymorphic encoder */
+ struct FLZ_encoder * flz_encoder;
enum LZ_Errno lz_errno;
- int flush_pending;
- File_header member_header;
bool fatal;
};
-static void LZ_Encoder_init( struct LZ_Encoder * const e,
- const File_header header )
+static void LZ_Encoder_init( struct LZ_Encoder * const e )
{
- int i;
e->partial_in_size = 0;
e->partial_out_size = 0;
- e->matchfinder = 0;
+ e->lz_encoder_base = 0;
e->lz_encoder = 0;
+ e->flz_encoder = 0;
e->lz_errno = LZ_ok;
- e->flush_pending = 0;
- for( i = 0; i < Fh_size; ++i ) e->member_header[i] = header[i];
e->fatal = false;
}
@@ -95,7 +95,8 @@ static void LZ_Decoder_init( struct LZ_Decoder * const d )
static bool verify_encoder( struct LZ_Encoder * const e )
{
if( !e ) return false;
- if( !e->matchfinder || !e->lz_encoder )
+ if( !e->lz_encoder_base || ( !e->lz_encoder && !e->flz_encoder ) ||
+ ( e->lz_encoder && e->flz_encoder ) )
{ e->lz_errno = LZ_bad_argument; return false; }
return true;
}
@@ -147,35 +148,31 @@ struct LZ_Encoder * LZ_compress_open( const int dictionary_size,
const unsigned long long member_size )
{
File_header header;
- const bool error = ( !Fh_set_dictionary_size( header, dictionary_size ) ||
- match_len_limit < min_match_len_limit ||
- match_len_limit > max_match_len ||
- member_size < min_dictionary_size );
-
struct LZ_Encoder * const e =
(struct LZ_Encoder *)malloc( sizeof (struct LZ_Encoder) );
if( !e ) return 0;
- Fh_set_magic( header );
- LZ_Encoder_init( e, header );
- if( error ) e->lz_errno = LZ_bad_argument;
+ LZ_Encoder_init( e );
+ if( !Fh_set_dictionary_size( header, dictionary_size ) ||
+ match_len_limit < min_match_len_limit ||
+ match_len_limit > max_match_len ||
+ member_size < min_dictionary_size )
+ e->lz_errno = LZ_bad_argument;
else
{
- e->matchfinder = (struct Matchfinder *)malloc( sizeof (struct Matchfinder) );
- if( e->matchfinder )
+ if( dictionary_size == 65535 && match_len_limit == 16 )
+ {
+ e->flz_encoder = (struct FLZ_encoder *)malloc( sizeof (struct FLZ_encoder) );
+ if( e->flz_encoder && FLZe_init( e->flz_encoder, member_size ) )
+ { e->lz_encoder_base = &e->flz_encoder->eb; return e; }
+ free( e->flz_encoder ); e->flz_encoder = 0;
+ }
+ else
{
e->lz_encoder = (struct LZ_encoder *)malloc( sizeof (struct LZ_encoder) );
- if( e->lz_encoder )
- {
- if( Mf_init( e->matchfinder,
- Fh_get_dictionary_size( header ), match_len_limit ) )
- {
- if( LZe_init( e->lz_encoder, e->matchfinder, header, member_size ) )
- return e;
- Mf_free( e->matchfinder );
- }
- free( e->lz_encoder ); e->lz_encoder = 0;
- }
- free( e->matchfinder ); e->matchfinder = 0;
+ if( e->lz_encoder && LZe_init( e->lz_encoder, Fh_get_dictionary_size( header ),
+ match_len_limit, member_size ) )
+ { e->lz_encoder_base = &e->lz_encoder->eb; return e; }
+ free( e->lz_encoder ); e->lz_encoder = 0;
}
e->lz_errno = LZ_mem_error;
}
@@ -187,10 +184,9 @@ struct LZ_Encoder * LZ_compress_open( const int dictionary_size,
int LZ_compress_close( struct LZ_Encoder * const e )
{
if( !e ) return -1;
- if( e->lz_encoder )
- { LZe_free( e->lz_encoder ); free( e->lz_encoder ); }
- if( e->matchfinder )
- { Mf_free( e->matchfinder ); free( e->matchfinder ); }
+ if( e->lz_encoder_base )
+ { LZeb_free( e->lz_encoder_base );
+ free( e->lz_encoder ); free( e->flz_encoder ); }
free( e );
return 0;
}
@@ -199,13 +195,17 @@ int LZ_compress_close( struct LZ_Encoder * const e )
int LZ_compress_finish( struct LZ_Encoder * const e )
{
if( !verify_encoder( e ) || e->fatal ) return -1;
- Mf_finish( e->matchfinder );
- e->flush_pending = 0;
+ Mb_finish( &e->lz_encoder_base->mb );
/* if (open --> write --> finish) use same dictionary size as lzip. */
/* this does not save any memory. */
- if( Mf_data_position( e->matchfinder ) == 0 &&
+ if( Mb_data_position( &e->lz_encoder_base->mb ) == 0 &&
LZ_compress_total_out_size( e ) == Fh_size )
- Mf_adjust_distionary_size( e->matchfinder );
+ {
+ Mb_adjust_distionary_size( &e->lz_encoder_base->mb );
+ Fh_set_dictionary_size( e->lz_encoder_base->renc.header,
+ e->lz_encoder_base->mb.dictionary_size );
+ e->lz_encoder_base->renc.cb.buffer[5] = e->lz_encoder_base->renc.header[5];
+ }
return 0;
}
@@ -214,22 +214,16 @@ int LZ_compress_restart_member( struct LZ_Encoder * const e,
const unsigned long long member_size )
{
if( !verify_encoder( e ) || e->fatal ) return -1;
- if( !LZe_member_finished( e->lz_encoder ) )
+ if( !LZeb_member_finished( e->lz_encoder_base ) )
{ e->lz_errno = LZ_sequence_error; return -1; }
if( member_size < min_dictionary_size )
{ e->lz_errno = LZ_bad_argument; return -1; }
- e->partial_in_size += Mf_data_position( e->matchfinder );
- e->partial_out_size += Re_member_position( &e->lz_encoder->renc );
- Mf_reset( e->matchfinder );
+ e->partial_in_size += Mb_data_position( &e->lz_encoder_base->mb );
+ e->partial_out_size += Re_member_position( &e->lz_encoder_base->renc );
- LZe_free( e->lz_encoder );
- if( !LZe_init( e->lz_encoder, e->matchfinder, e->member_header, member_size ) )
- {
- LZe_free( e->lz_encoder ); free( e->lz_encoder ); e->lz_encoder = 0;
- e->lz_errno = LZ_mem_error; e->fatal = true;
- return -1;
- }
+ if( e->lz_encoder ) LZe_reset( e->lz_encoder, member_size );
+ else FLZe_reset( e->flz_encoder, member_size );
e->lz_errno = LZ_ok;
return 0;
}
@@ -238,15 +232,8 @@ int LZ_compress_restart_member( struct LZ_Encoder * const e,
int LZ_compress_sync_flush( struct LZ_Encoder * const e )
{
if( !verify_encoder( e ) || e->fatal ) return -1;
- if( e->flush_pending <= 0 && !Mf_flushing_or_end( e->matchfinder ) )
- {
- e->flush_pending = 2; /* 2 consecutive markers guarantee decoding */
- e->matchfinder->flushing = true;
- if( !LZe_encode_member( e->lz_encoder ) )
- { e->lz_errno = LZ_library_error; e->fatal = true; return -1; }
- while( e->flush_pending > 0 && LZe_sync_flush( e->lz_encoder ) )
- { if( --e->flush_pending <= 0 ) e->matchfinder->flushing = false; }
- }
+ if( !Mb_flushing_or_end( &e->lz_encoder_base->mb ) )
+ e->lz_encoder_base->mb.flushing = true;
return 0;
}
@@ -254,12 +241,23 @@ int LZ_compress_sync_flush( struct LZ_Encoder * const e )
int LZ_compress_read( struct LZ_Encoder * const e,
uint8_t * const buffer, const int size )
{
+ int out_size = 0;
if( !verify_encoder( e ) || e->fatal ) return -1;
- if( !LZe_encode_member( e->lz_encoder ) )
- { e->lz_errno = LZ_library_error; e->fatal = true; return -1; }
- while( e->flush_pending > 0 && LZe_sync_flush( e->lz_encoder ) )
- { if( --e->flush_pending <= 0 ) e->matchfinder->flushing = false; }
- return Re_read_data( &e->lz_encoder->renc, buffer, size );
+ do {
+ if( ( e->flz_encoder && !FLZe_encode_member( e->flz_encoder ) ) ||
+ ( e->lz_encoder && !LZe_encode_member( e->lz_encoder ) ) )
+ { e->lz_errno = LZ_library_error; e->fatal = true; return -1; }
+ if( e->lz_encoder_base->mb.flushing &&
+ Mb_available_bytes( &e->lz_encoder_base->mb ) <= 0 &&
+ LZeb_sync_flush( e->lz_encoder_base ) )
+ e->lz_encoder_base->mb.flushing = false;
+ out_size += Re_read_data( &e->lz_encoder_base->renc,
+ buffer + out_size, size - out_size );
+ }
+ while( e->lz_encoder_base->mb.flushing && out_size < size &&
+ Mb_enough_available_bytes( &e->lz_encoder_base->mb ) &&
+ Re_enough_free_bytes( &e->lz_encoder_base->renc ) );
+ return out_size;
}
@@ -267,16 +265,14 @@ int LZ_compress_write( struct LZ_Encoder * const e,
const uint8_t * const buffer, const int size )
{
if( !verify_encoder( e ) || e->fatal ) return -1;
- if( e->flush_pending > 0 || size < 0 ) return 0;
- return Mf_write_data( e->matchfinder, buffer, size );
+ return Mb_write_data( &e->lz_encoder_base->mb, buffer, size );
}
int LZ_compress_write_size( struct LZ_Encoder * const e )
{
if( !verify_encoder( e ) || e->fatal ) return -1;
- if( e->flush_pending > 0 ) return 0;
- return Mf_free_bytes( e->matchfinder );
+ return Mb_free_bytes( &e->lz_encoder_base->mb );
}
@@ -290,43 +286,43 @@ enum LZ_Errno LZ_compress_errno( struct LZ_Encoder * const e )
int LZ_compress_finished( struct LZ_Encoder * const e )
{
if( !verify_encoder( e ) ) return -1;
- return ( e->flush_pending <= 0 && Mf_finished( e->matchfinder ) &&
- LZe_member_finished( e->lz_encoder ) );
+ return ( Mb_data_finished( &e->lz_encoder_base->mb ) &&
+ LZeb_member_finished( e->lz_encoder_base ) );
}
int LZ_compress_member_finished( struct LZ_Encoder * const e )
{
if( !verify_encoder( e ) ) return -1;
- return LZe_member_finished( e->lz_encoder );
+ return LZeb_member_finished( e->lz_encoder_base );
}
unsigned long long LZ_compress_data_position( struct LZ_Encoder * const e )
{
if( !verify_encoder( e ) ) return 0;
- return Mf_data_position( e->matchfinder );
+ return Mb_data_position( &e->lz_encoder_base->mb );
}
unsigned long long LZ_compress_member_position( struct LZ_Encoder * const e )
{
if( !verify_encoder( e ) ) return 0;
- return Re_member_position( &e->lz_encoder->renc );
+ return Re_member_position( &e->lz_encoder_base->renc );
}
unsigned long long LZ_compress_total_in_size( struct LZ_Encoder * const e )
{
if( !verify_encoder( e ) ) return 0;
- return e->partial_in_size + Mf_data_position( e->matchfinder );
+ return e->partial_in_size + Mb_data_position( &e->lz_encoder_base->mb );
}
unsigned long long LZ_compress_total_out_size( struct LZ_Encoder * const e )
{
if( !verify_encoder( e ) ) return 0;
- return e->partial_out_size + Re_member_position( &e->lz_encoder->renc );
+ return e->partial_out_size + Re_member_position( &e->lz_encoder_base->renc );
}