Merging upstream version 1.2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
9147dd9be8
commit
27d31fb65e
17 changed files with 197 additions and 125 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2011-05-18 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||||
|
|
||||||
|
* Version 1.2 released.
|
||||||
|
* main.c: Added new option `-F, --recompress'.
|
||||||
|
* main.c (decompress): Print only one status line for each
|
||||||
|
multimember file when only one `-v' is specified.
|
||||||
|
* encoder.h (Lee_update_prices): Update high length symbol prices
|
||||||
|
independently of the value of `pos_state'. This gives better
|
||||||
|
compression for large values of `--match-length' without being
|
||||||
|
slower.
|
||||||
|
* encoder.h encoder.c: Optimize pair price calculations. This
|
||||||
|
reduces compression time for large values of `--match-length'
|
||||||
|
by up to 6%.
|
||||||
|
|
||||||
2011-01-11 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
2011-01-11 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||||
|
|
||||||
* Version 1.1 released.
|
* Version 1.1 released.
|
||||||
|
|
|
@ -95,6 +95,7 @@ dist : doc
|
||||||
$(DISTNAME)/doc/$(pkgname).texinfo \
|
$(DISTNAME)/doc/$(pkgname).texinfo \
|
||||||
$(DISTNAME)/testsuite/check.sh \
|
$(DISTNAME)/testsuite/check.sh \
|
||||||
$(DISTNAME)/testsuite/test.txt \
|
$(DISTNAME)/testsuite/test.txt \
|
||||||
|
$(DISTNAME)/testsuite/test_sync.lz \
|
||||||
$(DISTNAME)/testsuite/test_v[01].lz \
|
$(DISTNAME)/testsuite/test_v[01].lz \
|
||||||
$(DISTNAME)/*.h \
|
$(DISTNAME)/*.h \
|
||||||
$(DISTNAME)/*.c
|
$(DISTNAME)/*.c
|
||||||
|
|
28
NEWS
28
NEWS
|
@ -1,24 +1,10 @@
|
||||||
Changes in version 1.1:
|
Changes in version 1.2:
|
||||||
|
|
||||||
Code has been converted to "C89 + long long". A C99 compiler is no more
|
The option "-F, --recompress", which forces recompression of files whose
|
||||||
needed.
|
name already has the ".lz" or ".tlz" suffix, has been added.
|
||||||
|
|
||||||
A warning about fchown's return value being ignored has been fixed.
|
Print only one status line for each multimember file when only one "-v"
|
||||||
|
is specified.
|
||||||
|
|
||||||
"clzip -tvvvv" now shows file compression ratio.
|
For large values of "--match-length", compression ratio has been
|
||||||
|
slightly increased and compression time has been reduced by up to 6%.
|
||||||
Match length limit set by options -1 to -8 has been reduced to extend
|
|
||||||
range of use towards gzip. Lower numbers now compress less but faster.
|
|
||||||
(-1 now takes 43% less time for only 20% larger compressed size).
|
|
||||||
|
|
||||||
(Note that the bidimensional parameter space of LZMA can't be mapped to
|
|
||||||
a linear scale optimal for all files. If your files are large, very
|
|
||||||
repetitive, etc, you may need to use the --match-length and
|
|
||||||
--dictionary-size options directly to achieve optimal performance).
|
|
||||||
|
|
||||||
Compression of option -9 has been slightly increased.
|
|
||||||
|
|
||||||
Do not show the message "and `--stdout' was not specified" for file
|
|
||||||
types that can't be read (directories, etc).
|
|
||||||
|
|
||||||
Some new examples have been added to the manual.
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Arg_parser - A POSIX/GNU command line argument parser. (C version)
|
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
|
||||||
Copyright (C) 2006, 2007, 2008, 2009, 2010 Antonio Diaz Diaz.
|
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Antonio Diaz Diaz.
|
||||||
|
|
||||||
This library is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -45,7 +45,8 @@ static char push_back_record( struct Arg_parser * const ap,
|
||||||
{
|
{
|
||||||
const int len = strlen( argument );
|
const int len = strlen( argument );
|
||||||
struct ap_Record *p;
|
struct ap_Record *p;
|
||||||
void * tmp = ap_resize_buffer( ap->data, ( ap->data_size + 1 ) * sizeof (struct ap_Record) );
|
void * tmp = ap_resize_buffer( ap->data,
|
||||||
|
( ap->data_size + 1 ) * sizeof (struct ap_Record) );
|
||||||
if( !tmp ) return 0;
|
if( !tmp ) return 0;
|
||||||
ap->data = (struct ap_Record *)tmp;
|
ap->data = (struct ap_Record *)tmp;
|
||||||
p = &(ap->data[ap->data_size]);
|
p = &(ap->data[ap->data_size]);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Arg_parser - A POSIX/GNU command line argument parser. (C version)
|
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
|
||||||
Copyright (C) 2006, 2007, 2008, 2009, 2010 Antonio Diaz Diaz.
|
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Antonio Diaz Diaz.
|
||||||
|
|
||||||
This library is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
3
clzip.h
3
clzip.h
|
@ -56,6 +56,7 @@ static inline void St_set_short_rep( State * const st )
|
||||||
*st = next[*st];
|
*st = next[*st];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
min_dictionary_bits = 12,
|
min_dictionary_bits = 12,
|
||||||
min_dictionary_size = 1 << min_dictionary_bits,
|
min_dictionary_size = 1 << min_dictionary_bits,
|
||||||
|
@ -277,5 +278,7 @@ static inline void Ft_set_member_size( File_trailer data, long long sz )
|
||||||
void cleanup_and_fail( const int retval );
|
void cleanup_and_fail( const int retval );
|
||||||
void show_error( const char * const msg, const int errcode, const bool help );
|
void show_error( const char * const msg, const int errcode, const bool help );
|
||||||
void internal_error( const char * const msg );
|
void internal_error( const char * const msg );
|
||||||
|
|
||||||
|
/* defined in decoder.c */
|
||||||
int readblock( const int fd, uint8_t * const buf, const int size );
|
int readblock( const int fd, uint8_t * const buf, const int size );
|
||||||
int writeblock( const int fd, const uint8_t * const buf, const int size );
|
int writeblock( const int fd, const uint8_t * const buf, const int size );
|
||||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -8,7 +8,7 @@
|
||||||
args=
|
args=
|
||||||
no_create=
|
no_create=
|
||||||
pkgname=clzip
|
pkgname=clzip
|
||||||
pkgversion=1.1
|
pkgversion=1.2
|
||||||
progname=clzip
|
progname=clzip
|
||||||
srctrigger=clzip.h
|
srctrigger=clzip.h
|
||||||
|
|
||||||
|
|
47
decoder.c
47
decoder.c
|
@ -23,6 +23,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "clzip.h"
|
#include "clzip.h"
|
||||||
#include "decoder.h"
|
#include "decoder.h"
|
||||||
|
@ -30,6 +31,46 @@
|
||||||
|
|
||||||
CRC32 crc32;
|
CRC32 crc32;
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns the number of bytes really read.
|
||||||
|
If (returned value < size) and (errno == 0), means EOF was reached.
|
||||||
|
*/
|
||||||
|
int readblock( const int fd, uint8_t * const buf, const int size )
|
||||||
|
{
|
||||||
|
int rest = size;
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
errno = 0;
|
||||||
|
if( rest <= 0 ) break;
|
||||||
|
n = read( fd, buf + size - rest, rest );
|
||||||
|
if( n > 0 ) rest -= n;
|
||||||
|
else if( n == 0 ) break;
|
||||||
|
else if( errno != EINTR && errno != EAGAIN ) break;
|
||||||
|
}
|
||||||
|
return ( rest > 0 ) ? size - rest : size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns the number of bytes really written.
|
||||||
|
If (returned value < size), it is always an error.
|
||||||
|
*/
|
||||||
|
int writeblock( const int fd, const uint8_t * const buf, const int size )
|
||||||
|
{
|
||||||
|
int rest = size;
|
||||||
|
while( true )
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
errno = 0;
|
||||||
|
if( rest <= 0 ) break;
|
||||||
|
n = write( fd, buf + size - rest, rest );
|
||||||
|
if( n > 0 ) rest -= n;
|
||||||
|
else if( errno && errno != EINTR && errno != EAGAIN ) break;
|
||||||
|
}
|
||||||
|
return ( rest > 0 ) ? size - rest : size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Rd_read_block( struct Range_decoder * const rdec )
|
bool Rd_read_block( struct Range_decoder * const rdec )
|
||||||
{
|
{
|
||||||
if( !rdec->at_stream_end )
|
if( !rdec->at_stream_end )
|
||||||
|
@ -53,7 +94,7 @@ void LZd_flush_data( struct LZ_decoder * const decoder )
|
||||||
CRC32_update_buf( &decoder->crc_, decoder->buffer + decoder->stream_pos, size );
|
CRC32_update_buf( &decoder->crc_, decoder->buffer + decoder->stream_pos, size );
|
||||||
if( decoder->outfd >= 0 &&
|
if( decoder->outfd >= 0 &&
|
||||||
writeblock( decoder->outfd, decoder->buffer + decoder->stream_pos, size ) != size )
|
writeblock( decoder->outfd, decoder->buffer + decoder->stream_pos, size ) != size )
|
||||||
{ show_error( "write error", errno, false ); cleanup_and_fail( 1 ); }
|
{ show_error( "Write error", errno, false ); cleanup_and_fail( 1 ); }
|
||||||
if( decoder->pos >= decoder->buffer_size )
|
if( decoder->pos >= decoder->buffer_size )
|
||||||
{ decoder->partial_data_pos += decoder->pos; decoder->pos = 0; }
|
{ decoder->partial_data_pos += decoder->pos; decoder->pos = 0; }
|
||||||
decoder->stream_pos = decoder->pos;
|
decoder->stream_pos = decoder->pos;
|
||||||
|
@ -124,12 +165,12 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder,
|
||||||
Ft_get_member_size( trailer ), member_size, member_size );
|
Ft_get_member_size( trailer ), member_size, member_size );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( !error && pp->verbosity >= 4 && LZd_data_position( decoder ) > 0 && member_size > 0 )
|
if( !error && pp->verbosity >= 3 && LZd_data_position( decoder ) > 0 && member_size > 0 )
|
||||||
fprintf( stderr, "%6.3f:1, %6.3f bits/byte, %5.2f%% saved. ",
|
fprintf( stderr, "%6.3f:1, %6.3f bits/byte, %5.2f%% saved. ",
|
||||||
(double)LZd_data_position( decoder ) / member_size,
|
(double)LZd_data_position( decoder ) / member_size,
|
||||||
( 8.0 * member_size ) / LZd_data_position( decoder ),
|
( 8.0 * member_size ) / LZd_data_position( decoder ),
|
||||||
100.0 * ( 1.0 - ( (double)member_size / LZd_data_position( decoder ) ) ) );
|
100.0 * ( 1.0 - ( (double)member_size / LZd_data_position( decoder ) ) ) );
|
||||||
if( !error && pp->verbosity >= 3 )
|
if( !error && pp->verbosity >= 4 )
|
||||||
fprintf( stderr, "data CRC %08X, data size %9lld, member size %8lld. ",
|
fprintf( stderr, "data CRC %08X, data size %9lld, member size %8lld. ",
|
||||||
(unsigned int)Ft_get_data_crc( trailer ),
|
(unsigned int)Ft_get_data_crc( trailer ),
|
||||||
Ft_get_data_size( trailer ), Ft_get_member_size( trailer ) );
|
Ft_get_data_size( trailer ), Ft_get_member_size( trailer ) );
|
||||||
|
|
|
@ -65,7 +65,7 @@ static inline void Rd_reset_member_position( struct Range_decoder * const rdec )
|
||||||
|
|
||||||
static inline uint8_t Rd_get_byte( struct Range_decoder * const rdec )
|
static inline uint8_t Rd_get_byte( struct Range_decoder * const rdec )
|
||||||
{
|
{
|
||||||
if( Rd_finished( rdec ) ) return 0;
|
if( Rd_finished( rdec ) ) return 0x55; /* make code != 0 */
|
||||||
return rdec->buffer[rdec->pos++];
|
return rdec->buffer[rdec->pos++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
||||||
.TH CLZIP "1" "January 2011" "Clzip 1.1" "User Commands"
|
.TH CLZIP "1" "May 2011" "Clzip 1.2" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
Clzip \- reduces the size of files
|
Clzip \- reduces the size of files
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -27,6 +27,9 @@ decompress
|
||||||
\fB\-f\fR, \fB\-\-force\fR
|
\fB\-f\fR, \fB\-\-force\fR
|
||||||
overwrite existing output files
|
overwrite existing output files
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-F\fR, \fB\-\-recompress\fR
|
||||||
|
force recompression of compressed files
|
||||||
|
.TP
|
||||||
\fB\-k\fR, \fB\-\-keep\fR
|
\fB\-k\fR, \fB\-\-keep\fR
|
||||||
keep (don't delete) input files
|
keep (don't delete) input files
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -12,7 +12,7 @@ File: clzip.info, Node: Top, Next: Introduction, Up: (dir)
|
||||||
Clzip Manual
|
Clzip Manual
|
||||||
************
|
************
|
||||||
|
|
||||||
This manual is for Clzip (version 1.1, 11 January 2011).
|
This manual is for Clzip (version 1.2, 18 May 2011).
|
||||||
|
|
||||||
* Menu:
|
* Menu:
|
||||||
|
|
||||||
|
@ -207,6 +207,11 @@ The format for running clzip is:
|
||||||
`--force'
|
`--force'
|
||||||
Force overwrite of output file.
|
Force overwrite of output file.
|
||||||
|
|
||||||
|
`-F'
|
||||||
|
`--recompress'
|
||||||
|
Force recompression of files whose name already has the `.lz' or
|
||||||
|
`.tlz' suffix.
|
||||||
|
|
||||||
`-k'
|
`-k'
|
||||||
`--keep'
|
`--keep'
|
||||||
Keep (don't delete) input files during compression or
|
Keep (don't delete) input files during compression or
|
||||||
|
@ -238,7 +243,8 @@ The format for running clzip is:
|
||||||
4KiB to 512MiB. Clzip will use the smallest possible dictionary
|
4KiB to 512MiB. Clzip will use the smallest possible dictionary
|
||||||
size for each member without exceeding this limit. Note that
|
size for each member without exceeding this limit. Note that
|
||||||
dictionary sizes are quantized. If the specified size does not
|
dictionary sizes are quantized. If the specified size does not
|
||||||
match one of the valid sizes, it will be rounded upwards.
|
match one of the valid sizes, it will be rounded upwards by adding
|
||||||
|
up to (SIZE / 16) to it.
|
||||||
|
|
||||||
For maximum compression you should use a dictionary size limit as
|
For maximum compression you should use a dictionary size limit as
|
||||||
large as possible, but keep in mind that the decompression memory
|
large as possible, but keep in mind that the decompression memory
|
||||||
|
@ -263,8 +269,11 @@ The format for running clzip is:
|
||||||
|
|
||||||
`-v'
|
`-v'
|
||||||
`--verbose'
|
`--verbose'
|
||||||
Verbose mode. Show the compression ratio for each file processed.
|
Verbose mode. When compressing, show the compression ratio for
|
||||||
Further -v's increase the verbosity level.
|
each file processed. When decompressing or testing, further -v's
|
||||||
|
(up to 4) increase the verbosity level, showing status, dictionary
|
||||||
|
size, compression ratio, and trailer contents (CRC, data size,
|
||||||
|
member size).
|
||||||
|
|
||||||
`-1 .. -9'
|
`-1 .. -9'
|
||||||
Set the compression parameters (dictionary size and match length
|
Set the compression parameters (dictionary size and match length
|
||||||
|
@ -345,8 +354,8 @@ additional information before, between, or after them.
|
||||||
|
|
||||||
`VN (version number, 1 byte)'
|
`VN (version number, 1 byte)'
|
||||||
Just in case something needs to be modified in the future. Valid
|
Just in case something needs to be modified in the future. Valid
|
||||||
values are 0 and 1. Version 0 files have only one member and lack
|
values are 0 and 1. Version 0 files are deprecated. They can
|
||||||
`Member size'.
|
contain only one member and lack the `Member size' field.
|
||||||
|
|
||||||
`DS (coded dictionary size, 1 byte)'
|
`DS (coded dictionary size, 1 byte)'
|
||||||
Bits 4-0 contain the base 2 logarithm of the base dictionary size.
|
Bits 4-0 contain the base 2 logarithm of the base dictionary size.
|
||||||
|
@ -477,12 +486,12 @@ Concept Index
|
||||||
|
|
||||||
Tag Table:
|
Tag Table:
|
||||||
Node: Top226
|
Node: Top226
|
||||||
Node: Introduction907
|
Node: Introduction903
|
||||||
Node: Algorithm4484
|
Node: Algorithm4480
|
||||||
Node: Invoking Clzip7008
|
Node: Invoking Clzip7004
|
||||||
Node: File Format11949
|
Node: File Format12275
|
||||||
Node: Examples13905
|
Node: Examples14269
|
||||||
Node: Problems15674
|
Node: Problems16038
|
||||||
Node: Concept Index16200
|
Node: Concept Index16564
|
||||||
|
|
||||||
End Tag Table
|
End Tag Table
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
@finalout
|
@finalout
|
||||||
@c %**end of header
|
@c %**end of header
|
||||||
|
|
||||||
@set UPDATED 11 January 2011
|
@set UPDATED 18 May 2011
|
||||||
@set VERSION 1.1
|
@set VERSION 1.2
|
||||||
|
|
||||||
@dircategory Data Compression
|
@dircategory Data Compression
|
||||||
@direntry
|
@direntry
|
||||||
|
@ -231,6 +231,11 @@ Decompress.
|
||||||
@itemx --force
|
@itemx --force
|
||||||
Force overwrite of output file.
|
Force overwrite of output file.
|
||||||
|
|
||||||
|
@item -F
|
||||||
|
@itemx --recompress
|
||||||
|
Force recompression of files whose name already has the @samp{.lz} or
|
||||||
|
@samp{.tlz} suffix.
|
||||||
|
|
||||||
@item -k
|
@item -k
|
||||||
@itemx --keep
|
@itemx --keep
|
||||||
Keep (don't delete) input files during compression or decompression.
|
Keep (don't delete) input files during compression or decompression.
|
||||||
|
@ -260,7 +265,7 @@ Set the dictionary size limit in bytes. Valid values range from 4KiB to
|
||||||
512MiB. Clzip will use the smallest possible dictionary size for each
|
512MiB. Clzip will use the smallest possible dictionary size for each
|
||||||
member without exceeding this limit. Note that dictionary sizes are
|
member without exceeding this limit. Note that dictionary sizes are
|
||||||
quantized. If the specified size does not match one of the valid sizes,
|
quantized. If the specified size does not match one of the valid sizes,
|
||||||
it will be rounded upwards.
|
it will be rounded upwards by adding up to (@var{size} / 16) to it.
|
||||||
|
|
||||||
For maximum compression you should use a dictionary size limit as large
|
For maximum compression you should use a dictionary size limit as large
|
||||||
as possible, but keep in mind that the decompression memory requirement
|
as possible, but keep in mind that the decompression memory requirement
|
||||||
|
@ -282,8 +287,11 @@ Use it together with @samp{-v} to see information about the file.
|
||||||
|
|
||||||
@item -v
|
@item -v
|
||||||
@itemx --verbose
|
@itemx --verbose
|
||||||
Verbose mode. Show the compression ratio for each file processed.
|
Verbose mode.
|
||||||
Further -v's increase the verbosity level.
|
When compressing, show the compression ratio for each file processed.
|
||||||
|
When decompressing or testing, further -v's (up to 4) increase the
|
||||||
|
verbosity level, showing status, dictionary size, compression ratio,
|
||||||
|
and trailer contents (CRC, data size, member size).
|
||||||
|
|
||||||
@item -1 .. -9
|
@item -1 .. -9
|
||||||
Set the compression parameters (dictionary size and match length limit)
|
Set the compression parameters (dictionary size and match length limit)
|
||||||
|
@ -374,8 +382,8 @@ A four byte string, identifying the lzip format, with the value "LZIP".
|
||||||
|
|
||||||
@item VN (version number, 1 byte)
|
@item VN (version number, 1 byte)
|
||||||
Just in case something needs to be modified in the future. Valid values
|
Just in case something needs to be modified in the future. Valid values
|
||||||
are 0 and 1. Version 0 files have only one member and lack @samp{Member
|
are 0 and 1. Version 0 files are deprecated. They can contain only one
|
||||||
size}.
|
member and lack the @samp{Member size} field.
|
||||||
|
|
||||||
@item DS (coded dictionary size, 1 byte)
|
@item DS (coded dictionary size, 1 byte)
|
||||||
Bits 4-0 contain the base 2 logarithm of the base dictionary size.@*
|
Bits 4-0 contain the base 2 logarithm of the base dictionary size.@*
|
||||||
|
|
48
encoder.c
48
encoder.c
|
@ -388,23 +388,25 @@ int LZe_sequence_optimizer( struct LZ_encoder * const encoder,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
const int normal_match_price = match_price + price0( encoder->bm_rep[state] );
|
|
||||||
int len = min_match_len;
|
|
||||||
if( main_len <= replens[rep_index] )
|
if( main_len <= replens[rep_index] )
|
||||||
{
|
{
|
||||||
|
int len;
|
||||||
main_len = replens[rep_index];
|
main_len = replens[rep_index];
|
||||||
for( ; len <= main_len; ++len )
|
for( len = min_match_len; len <= main_len; ++len )
|
||||||
encoder->trials[len].price = infinite_price;
|
encoder->trials[len].price = infinite_price;
|
||||||
}
|
}
|
||||||
else for( ; len <= main_len; ++len )
|
else
|
||||||
{
|
{
|
||||||
encoder->trials[len].dis = encoder->match_distances[len] + num_rep_distances;
|
int len;
|
||||||
encoder->trials[len].prev_index = 0;
|
const int normal_match_price = match_price + price0( encoder->bm_rep[state] );
|
||||||
encoder->trials[len].price = normal_match_price +
|
for( len = min_match_len; len <= main_len; ++len )
|
||||||
LZe_price_pair( encoder, encoder->match_distances[len], len, pos_state );
|
{
|
||||||
|
encoder->trials[len].dis = encoder->match_distances[len] + num_rep_distances;
|
||||||
|
encoder->trials[len].prev_index = 0;
|
||||||
|
encoder->trials[len].price = normal_match_price +
|
||||||
|
LZe_price_pair( encoder, encoder->match_distances[len], len, pos_state );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for( rep = 0; rep < num_rep_distances; ++rep )
|
for( rep = 0; rep < num_rep_distances; ++rep )
|
||||||
{
|
{
|
||||||
|
@ -513,13 +515,31 @@ int LZe_sequence_optimizer( struct LZ_encoder * const encoder,
|
||||||
const int normal_match_price = match_price +
|
const int normal_match_price = match_price +
|
||||||
price0( encoder->bm_rep[cur_trial->state] );
|
price0( encoder->bm_rep[cur_trial->state] );
|
||||||
int len;
|
int len;
|
||||||
|
int dis = encoder->match_distances[min_match_len];
|
||||||
|
int dis_state = get_dis_state( min_match_len );
|
||||||
|
int dis_price = infinite_price;
|
||||||
|
|
||||||
while( num_trials < cur + newlen )
|
while( num_trials < cur + newlen )
|
||||||
encoder->trials[++num_trials].price = infinite_price;
|
encoder->trials[++num_trials].price = infinite_price;
|
||||||
|
|
||||||
for( len = min_match_len; len <= newlen; ++len )
|
if( dis < modeled_distances )
|
||||||
Tr_update( &encoder->trials[cur+len], encoder->match_distances[len] + num_rep_distances,
|
Tr_update( &encoder->trials[cur+min_match_len], dis + num_rep_distances,
|
||||||
cur, normal_match_price +
|
cur, normal_match_price + encoder->dis_prices[dis_state][dis] +
|
||||||
LZe_price_pair( encoder, encoder->match_distances[len], len, pos_state ) );
|
Lee_price( &encoder->len_encoder, min_match_len, pos_state ) );
|
||||||
|
|
||||||
|
for( len = min_match_len + 1; len <= newlen; ++len )
|
||||||
|
{
|
||||||
|
if( dis != encoder->match_distances[len] ||
|
||||||
|
dis_state < max_dis_states - 1 )
|
||||||
|
{
|
||||||
|
dis = encoder->match_distances[len];
|
||||||
|
dis_state = get_dis_state( len );
|
||||||
|
dis_price = LZe_price_dis( encoder, dis, dis_state );
|
||||||
|
}
|
||||||
|
Tr_update( &encoder->trials[cur+len], dis + num_rep_distances, cur,
|
||||||
|
normal_match_price + dis_price +
|
||||||
|
Lee_price( &encoder->len_encoder, len, pos_state ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
29
encoder.h
29
encoder.h
|
@ -393,7 +393,10 @@ static inline void Lee_update_prices( struct Len_encoder * const len_encoder,
|
||||||
pps[len] = tmp + price0( len_encoder->choice2 ) +
|
pps[len] = tmp + price0( len_encoder->choice2 ) +
|
||||||
price_symbol( len_encoder->bm_mid[pos_state], len - len_low_symbols, len_mid_bits );
|
price_symbol( len_encoder->bm_mid[pos_state], len - len_low_symbols, len_mid_bits );
|
||||||
for( ; len < len_encoder->len_symbols; ++len )
|
for( ; len < len_encoder->len_symbols; ++len )
|
||||||
pps[len] = tmp + price1( len_encoder->choice2 ) +
|
/* using 4 slots per value makes "Lee_price" faster */
|
||||||
|
len_encoder->prices[3][len] = len_encoder->prices[2][len] =
|
||||||
|
len_encoder->prices[1][len] = len_encoder->prices[0][len] =
|
||||||
|
tmp + price1( len_encoder->choice2 ) +
|
||||||
price_symbol( len_encoder->bm_high, len - len_low_symbols - len_mid_symbols, len_high_bits );
|
price_symbol( len_encoder->bm_high, len - len_low_symbols - len_mid_symbols, len_high_bits );
|
||||||
len_encoder->counters[pos_state] = len_encoder->len_symbols;
|
len_encoder->counters[pos_state] = len_encoder->len_symbols;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +433,7 @@ struct Literal_encoder
|
||||||
Bit_model bm_literal[1<<literal_context_bits][0x300];
|
Bit_model bm_literal[1<<literal_context_bits][0x300];
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int Lie_state( const int prev_byte )
|
static inline int Lie_state( const uint8_t prev_byte )
|
||||||
{ return ( prev_byte >> ( 8 - literal_context_bits ) ); }
|
{ return ( prev_byte >> ( 8 - literal_context_bits ) ); }
|
||||||
|
|
||||||
static inline void Lie_init( struct Literal_encoder * const literal_encoder )
|
static inline void Lie_init( struct Literal_encoder * const literal_encoder )
|
||||||
|
@ -558,22 +561,24 @@ static inline int LZe_price_rep( struct LZ_encoder * const encoder, const int re
|
||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int LZe_price_dis( struct LZ_encoder * const encoder,
|
||||||
|
const int dis, const int dis_state )
|
||||||
|
{
|
||||||
|
if( dis < modeled_distances )
|
||||||
|
return encoder->dis_prices[dis_state][dis];
|
||||||
|
else
|
||||||
|
return encoder->dis_slot_prices[dis_state][get_slot( dis )] +
|
||||||
|
encoder->align_prices[dis & (dis_align_size - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
static inline int LZe_price_pair( struct LZ_encoder * const encoder,
|
static inline int LZe_price_pair( struct LZ_encoder * const encoder,
|
||||||
const int dis, const int len,
|
const int dis, const int len,
|
||||||
const int pos_state )
|
const int pos_state )
|
||||||
{
|
{
|
||||||
const int dis_state = get_dis_state( len );
|
|
||||||
int price;
|
|
||||||
|
|
||||||
if( len <= min_match_len && dis >= modeled_distances )
|
if( len <= min_match_len && dis >= modeled_distances )
|
||||||
return infinite_price;
|
return infinite_price;
|
||||||
price = Lee_price( &encoder->len_encoder, len, pos_state );
|
return Lee_price( &encoder->len_encoder, len, pos_state ) +
|
||||||
if( dis < modeled_distances )
|
LZe_price_dis( encoder, dis, get_dis_state( len ) );
|
||||||
price += encoder->dis_prices[dis_state][dis];
|
|
||||||
else
|
|
||||||
price += encoder->dis_slot_prices[dis_state][get_slot( dis )] +
|
|
||||||
encoder->align_prices[dis & (dis_align_size - 1)];
|
|
||||||
return price;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void LZe_encode_pair( struct LZ_encoder * const encoder,
|
static inline void LZe_encode_pair( struct LZ_encoder * const encoder,
|
||||||
|
|
60
main.c
60
main.c
|
@ -128,6 +128,7 @@ static void show_help()
|
||||||
printf( " -c, --stdout send output to standard output\n" );
|
printf( " -c, --stdout send output to standard output\n" );
|
||||||
printf( " -d, --decompress decompress\n" );
|
printf( " -d, --decompress decompress\n" );
|
||||||
printf( " -f, --force overwrite existing output files\n" );
|
printf( " -f, --force overwrite existing output files\n" );
|
||||||
|
printf( " -F, --recompress force recompression of compressed files\n" );
|
||||||
printf( " -k, --keep keep (don't delete) input files\n" );
|
printf( " -k, --keep keep (don't delete) input files\n" );
|
||||||
printf( " -m, --match-length=<n> set match length limit in bytes [36]\n" );
|
printf( " -m, --match-length=<n> set match length limit in bytes [36]\n" );
|
||||||
printf( " -o, --output=<file> if reading stdin, place the output into <file>\n" );
|
printf( " -o, --output=<file> if reading stdin, place the output into <file>\n" );
|
||||||
|
@ -244,10 +245,10 @@ static int get_dict_size( const char * const arg )
|
||||||
|
|
||||||
static int open_instream( const char * const name, struct stat * const in_statsp,
|
static int open_instream( const char * const name, struct stat * const in_statsp,
|
||||||
const enum Mode program_mode, const int eindex,
|
const enum Mode program_mode, const int eindex,
|
||||||
const bool force, const bool to_stdout )
|
const bool recompress, const bool to_stdout )
|
||||||
{
|
{
|
||||||
int infd = -1;
|
int infd = -1;
|
||||||
if( program_mode == m_compress && !force && eindex >= 0 )
|
if( program_mode == m_compress && !recompress && eindex >= 0 )
|
||||||
{
|
{
|
||||||
if( verbosity >= 0 )
|
if( verbosity >= 0 )
|
||||||
fprintf( stderr, "%s: Input file `%s' already has `%s' suffix.\n",
|
fprintf( stderr, "%s: Input file `%s' already has `%s' suffix.\n",
|
||||||
|
@ -327,7 +328,7 @@ static void set_d_outname( const char * const name, const int i )
|
||||||
output_filename = resize_buffer( output_filename, strlen( name ) + 4 + 1 );
|
output_filename = resize_buffer( output_filename, strlen( name ) + 4 + 1 );
|
||||||
strcpy( output_filename, name );
|
strcpy( output_filename, name );
|
||||||
strcat( output_filename, ".out" );
|
strcat( output_filename, ".out" );
|
||||||
if( verbosity >= 0 )
|
if( verbosity >= 1 )
|
||||||
fprintf( stderr, "%s: Can't guess original name for `%s' -- using `%s'.\n",
|
fprintf( stderr, "%s: Can't guess original name for `%s' -- using `%s'.\n",
|
||||||
program_name, name, output_filename );
|
program_name, name, output_filename );
|
||||||
}
|
}
|
||||||
|
@ -378,7 +379,7 @@ void cleanup_and_fail( const int retval )
|
||||||
fprintf( stderr, "%s: Deleting output file `%s', if it exists.\n",
|
fprintf( stderr, "%s: Deleting output file `%s', if it exists.\n",
|
||||||
program_name, output_filename );
|
program_name, output_filename );
|
||||||
if( outfd >= 0 ) { close( outfd ); outfd = -1; }
|
if( outfd >= 0 ) { close( outfd ); outfd = -1; }
|
||||||
if( remove( output_filename ) != 0 )
|
if( remove( output_filename ) != 0 && errno != ENOENT )
|
||||||
show_error( "WARNING: deletion of output file (apparently) failed.", 0, false );
|
show_error( "WARNING: deletion of output file (apparently) failed.", 0, false );
|
||||||
}
|
}
|
||||||
exit( retval );
|
exit( retval );
|
||||||
|
@ -538,7 +539,7 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
||||||
{ Pp_show_msg( pp, "Invalid dictionary size in member header" );
|
{ Pp_show_msg( pp, "Invalid dictionary size in member header" );
|
||||||
retval = 2; break; }
|
retval = 2; break; }
|
||||||
|
|
||||||
if( verbosity >= 1 )
|
if( verbosity >= 2 || ( verbosity == 1 && first_member ) )
|
||||||
{
|
{
|
||||||
Pp_show_msg( pp, 0 );
|
Pp_show_msg( pp, 0 );
|
||||||
if( verbosity >= 2 )
|
if( verbosity >= 2 )
|
||||||
|
@ -564,11 +565,14 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
||||||
}
|
}
|
||||||
retval = 2; break;
|
retval = 2; break;
|
||||||
}
|
}
|
||||||
if( verbosity >= 1 )
|
if( verbosity >= 2 )
|
||||||
{ if( testing ) fprintf( stderr, "ok\n" );
|
{ if( testing ) fprintf( stderr, "ok\n" );
|
||||||
else fprintf( stderr, "done\n" ); }
|
else fprintf( stderr, "done\n" ); }
|
||||||
}
|
}
|
||||||
Rd_free( &rdec );
|
Rd_free( &rdec );
|
||||||
|
if( verbosity == 1 && retval == 0 )
|
||||||
|
{ if( testing ) fprintf( stderr, "ok\n" );
|
||||||
|
else fprintf( stderr, "done\n" ); }
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,45 +658,6 @@ void internal_error( const char * const msg )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Returns the number of bytes really read.
|
|
||||||
If (returned value < size) and (errno == 0), means EOF was reached.
|
|
||||||
*/
|
|
||||||
int readblock( const int fd, uint8_t * const buf, const int size )
|
|
||||||
{
|
|
||||||
int rest = size;
|
|
||||||
while( true )
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
errno = 0;
|
|
||||||
if( rest <= 0 ) break;
|
|
||||||
n = read( fd, buf + size - rest, rest );
|
|
||||||
if( n > 0 ) rest -= n;
|
|
||||||
else if( n == 0 ) break;
|
|
||||||
else if( errno != EINTR && errno != EAGAIN ) break;
|
|
||||||
}
|
|
||||||
return ( rest > 0 ) ? size - rest : size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns the number of bytes really written.
|
|
||||||
If (returned value < size), it is always an error.
|
|
||||||
*/
|
|
||||||
int writeblock( const int fd, const uint8_t * const buf, const int size )
|
|
||||||
{
|
|
||||||
int rest = size;
|
|
||||||
while( true )
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
errno = 0;
|
|
||||||
if( rest <= 0 ) break;
|
|
||||||
n = write( fd, buf + size - rest, rest );
|
|
||||||
if( n > 0 ) rest -= n;
|
|
||||||
else if( errno && errno != EINTR && errno != EAGAIN ) break;
|
|
||||||
}
|
|
||||||
return ( rest > 0 ) ? size - rest : size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main( const int argc, const char * const argv[] )
|
int main( const int argc, const char * const argv[] )
|
||||||
{
|
{
|
||||||
/* Mapping from gzip/bzip2 style 1..9 compression modes
|
/* Mapping from gzip/bzip2 style 1..9 compression modes
|
||||||
|
@ -724,6 +689,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
bool filenames_given = false;
|
bool filenames_given = false;
|
||||||
bool force = false;
|
bool force = false;
|
||||||
bool keep_input_files = false;
|
bool keep_input_files = false;
|
||||||
|
bool recompress = false;
|
||||||
bool to_stdout = false;
|
bool to_stdout = false;
|
||||||
struct Pretty_print pp;
|
struct Pretty_print pp;
|
||||||
|
|
||||||
|
@ -744,6 +710,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
{ 'd', "decompress", ap_no },
|
{ 'd', "decompress", ap_no },
|
||||||
{ 'e', "extreme", ap_no },
|
{ 'e', "extreme", ap_no },
|
||||||
{ 'f', "force", ap_no },
|
{ 'f', "force", ap_no },
|
||||||
|
{ 'F', "recompress", ap_no },
|
||||||
{ 'h', "help", ap_no },
|
{ 'h', "help", ap_no },
|
||||||
{ 'k', "keep", ap_no },
|
{ 'k', "keep", ap_no },
|
||||||
{ 'm', "match-length", ap_yes },
|
{ 'm', "match-length", ap_yes },
|
||||||
|
@ -781,6 +748,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
case 'd': program_mode = m_decompress; break;
|
case 'd': program_mode = m_decompress; break;
|
||||||
case 'e': break; /* ignored by now */
|
case 'e': break; /* ignored by now */
|
||||||
case 'f': force = true; break;
|
case 'f': force = true; break;
|
||||||
|
case 'F': recompress = true; break;
|
||||||
case 'h': show_help(); return 0;
|
case 'h': show_help(); return 0;
|
||||||
case 'k': keep_input_files = true; break;
|
case 'k': keep_input_files = true; break;
|
||||||
case 'm': encoder_options.match_len_limit =
|
case 'm': encoder_options.match_len_limit =
|
||||||
|
@ -871,7 +839,7 @@ int main( const int argc, const char * const argv[] )
|
||||||
const int eindex = extension_index( filenames[i] );
|
const int eindex = extension_index( filenames[i] );
|
||||||
input_filename = filenames[i];
|
input_filename = filenames[i];
|
||||||
infd = open_instream( input_filename, &in_stats, program_mode,
|
infd = open_instream( input_filename, &in_stats, program_mode,
|
||||||
eindex, force, to_stdout );
|
eindex, recompress, to_stdout );
|
||||||
if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; }
|
if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; }
|
||||||
if( program_mode != m_test )
|
if( program_mode != m_test )
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,19 @@ printf .
|
||||||
cmp in copy || fail=1
|
cmp in copy || fail=1
|
||||||
printf .
|
printf .
|
||||||
|
|
||||||
|
"${LZIP}" -t "${testdir}"/test_sync.lz || fail=1
|
||||||
|
printf .
|
||||||
|
"${LZIP}" -cd "${testdir}"/test_sync.lz > copy || fail=1
|
||||||
|
cmp in copy || fail=1
|
||||||
|
printf .
|
||||||
|
|
||||||
|
"${LZIP}" -cf "${testdir}"/test_v1.lz > out 2>/dev/null
|
||||||
|
if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi
|
||||||
|
"${LZIP}" -cF "${testdir}"/test_v1.lz > out || fail=1
|
||||||
|
"${LZIP}" -cd out | "${LZIP}" -d > copy || fail=1
|
||||||
|
cmp in copy || fail=1
|
||||||
|
printf .
|
||||||
|
|
||||||
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
|
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
|
||||||
"${LZIP}" -k -$i in || fail=1
|
"${LZIP}" -k -$i in || fail=1
|
||||||
mv -f in.lz copy.lz || fail=1
|
mv -f in.lz copy.lz || fail=1
|
||||||
|
@ -69,7 +82,7 @@ for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
|
||||||
done
|
done
|
||||||
|
|
||||||
"${LZIP}" -$i < in > anyothername || fail=1
|
"${LZIP}" -$i < in > anyothername || fail=1
|
||||||
"${LZIP}" -dq anyothername || fail=1
|
"${LZIP}" -d anyothername || fail=1
|
||||||
cmp in anyothername.out || fail=1
|
cmp in anyothername.out || fail=1
|
||||||
printf .
|
printf .
|
||||||
|
|
||||||
|
|
BIN
testsuite/test_sync.lz
Normal file
BIN
testsuite/test_sync.lz
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue