Adding upstream version 1.2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
9c0f4fe9b6
commit
fa76077496
17 changed files with 302 additions and 339 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,11 @@
|
|||
2013-02-18 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 1.2 released.
|
||||
* Decompression time has been reduced by 12%.
|
||||
* Makefile.in: Added new target 'install-as-lzip'.
|
||||
* Makefile.in: Added new target 'install-bin'.
|
||||
* main.c: Use 'setmode' instead of '_setmode' on Windows and OS/2.
|
||||
|
||||
2012-02-26 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 1.1 released.
|
||||
|
@ -15,7 +23,7 @@
|
|||
* Created from the decompression code of clzip 1.1.
|
||||
|
||||
|
||||
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
|
||||
This file is a collection of facts, and thus it is not copyrightable,
|
||||
but just in case, you have unlimited permission to copy, distribute and
|
||||
|
|
11
INSTALL
11
INSTALL
|
@ -1,7 +1,7 @@
|
|||
Requirements
|
||||
------------
|
||||
You will need a C compiler.
|
||||
I use gcc 4.3.5 and 3.3.6, but the code should compile with any
|
||||
I use gcc 4.7.2 and 3.3.6, but the code should compile with any
|
||||
standards compliant compiler.
|
||||
Gcc is available at http://gcc.gnu.org.
|
||||
|
||||
|
@ -32,6 +32,13 @@ the main archive.
|
|||
5. Type 'make install' to install the program and any data files and
|
||||
documentation.
|
||||
|
||||
You can install only the program, the info manual or the man page
|
||||
typing 'make install-bin', 'make install-info' or 'make install-man'
|
||||
respectively.
|
||||
|
||||
5a. Type 'make install-as-lzip' to install the program and any data
|
||||
files and documentation, and link the program to the name 'lzip'.
|
||||
|
||||
|
||||
Another way
|
||||
-----------
|
||||
|
@ -50,7 +57,7 @@ After running 'configure', you can run 'make' and 'make install' as
|
|||
explained above.
|
||||
|
||||
|
||||
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute and modify it.
|
||||
|
|
21
Makefile.in
21
Makefile.in
|
@ -9,8 +9,8 @@ SHELL = /bin/sh
|
|||
objs = carg_parser.o decoder.o main.o
|
||||
|
||||
|
||||
.PHONY : all install install-info install-man install-strip \
|
||||
uninstall uninstall-info uninstall-man \
|
||||
.PHONY : all install install-bin install-info install-man install-strip \
|
||||
install-as-lzip uninstall uninstall-bin uninstall-info uninstall-man \
|
||||
doc info man check dist clean distclean
|
||||
|
||||
all : $(progname)
|
||||
|
@ -52,14 +52,16 @@ Makefile : $(VPATH)/configure $(VPATH)/Makefile.in
|
|||
check : all
|
||||
@$(VPATH)/testsuite/check.sh $(VPATH)/testsuite $(pkgversion)
|
||||
|
||||
install : all install-man
|
||||
install : install-bin install-man
|
||||
|
||||
install-bin : all
|
||||
if [ ! -d "$(DESTDIR)$(bindir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(bindir)" ; fi
|
||||
$(INSTALL_PROGRAM) ./$(progname) "$(DESTDIR)$(bindir)/$(progname)"
|
||||
|
||||
install-info :
|
||||
if [ ! -d "$(DESTDIR)$(infodir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(infodir)" ; fi
|
||||
$(INSTALL_DATA) $(VPATH)/doc/$(pkgname).info "$(DESTDIR)$(infodir)/$(pkgname).info"
|
||||
-install-info --info-dir="$(DESTDIR)$(infodir)" $(DESTDIR)$(infodir)/$(pkgname).info
|
||||
-install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$(pkgname).info"
|
||||
|
||||
install-man :
|
||||
if [ ! -d "$(DESTDIR)$(mandir)/man1" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1" ; fi
|
||||
|
@ -68,7 +70,13 @@ install-man :
|
|||
install-strip : all
|
||||
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
|
||||
|
||||
uninstall : uninstall-man
|
||||
install-as-lzip : install
|
||||
-rm -f "$(DESTDIR)$(bindir)/lzip"
|
||||
cd "$(DESTDIR)$(bindir)" && ln -s $(progname) lzip
|
||||
|
||||
uninstall : uninstall-bin uninstall-man
|
||||
|
||||
uninstall-bin :
|
||||
-rm -f "$(DESTDIR)$(bindir)/$(progname)"
|
||||
|
||||
uninstall-info :
|
||||
|
@ -92,8 +100,7 @@ dist : doc
|
|||
$(DISTNAME)/doc/$(progname).1 \
|
||||
$(DISTNAME)/testsuite/check.sh \
|
||||
$(DISTNAME)/testsuite/test.txt \
|
||||
$(DISTNAME)/testsuite/test_sync.lz \
|
||||
$(DISTNAME)/testsuite/test_v[01].lz \
|
||||
$(DISTNAME)/testsuite/test.txt.lz \
|
||||
$(DISTNAME)/*.h \
|
||||
$(DISTNAME)/*.c
|
||||
rm -f $(DISTNAME)
|
||||
|
|
14
NEWS
14
NEWS
|
@ -1,13 +1,7 @@
|
|||
Changes in version 1.1:
|
||||
Changes in version 1.2:
|
||||
|
||||
Print only one status line for each multimember file when only one "-v"
|
||||
is specified.
|
||||
Decompression time has been reduced by 12%.
|
||||
|
||||
Inability to change output file attributes has been downgraded from
|
||||
error to warning.
|
||||
The target "install-as-lzip" has been added to the Makefile.
|
||||
|
||||
Quote characters in messages have been changed as advised by GNU Coding
|
||||
Standards.
|
||||
|
||||
Configure option "--datadir" has been renamed to "--datarootdir" to
|
||||
follow GNU Standards.
|
||||
The target "install-bin" has been added to the Makefile.
|
||||
|
|
2
README
2
README
|
@ -35,7 +35,7 @@ few tens of KiB larger than the dictionary size used to compress that
|
|||
file.
|
||||
|
||||
|
||||
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute and modify it.
|
||||
|
|
|
@ -88,7 +88,7 @@ static char parse_long_option( struct Arg_parser * const ap,
|
|||
const struct ap_Option options[],
|
||||
int * const argindp )
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned len;
|
||||
int index = -1;
|
||||
int i;
|
||||
char exact = 0, ambig = 0;
|
||||
|
|
37
configure
vendored
37
configure
vendored
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# configure script for Lunzip - Decompressor for lzip files
|
||||
# Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
#
|
||||
# This configure script is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
|
@ -8,7 +8,7 @@
|
|||
args=
|
||||
no_create=
|
||||
pkgname=lunzip
|
||||
pkgversion=1.1
|
||||
pkgversion=1.2
|
||||
progname=lunzip
|
||||
srctrigger=lunzip.h
|
||||
|
||||
|
@ -22,11 +22,19 @@ bindir='$(exec_prefix)/bin'
|
|||
datarootdir='$(prefix)/share'
|
||||
infodir='$(datarootdir)/info'
|
||||
mandir='$(datarootdir)/man'
|
||||
CC=
|
||||
CC=gcc
|
||||
CPPFLAGS=
|
||||
CFLAGS='-Wall -W -O2'
|
||||
LDFLAGS=
|
||||
|
||||
# checking whether we are using GNU C.
|
||||
if [ ! -x /bin/gcc ] &&
|
||||
[ ! -x /usr/bin/gcc ] &&
|
||||
[ ! -x /usr/local/bin/gcc ] ; then
|
||||
CC=cc
|
||||
CFLAGS='-W -O2'
|
||||
fi
|
||||
|
||||
# Loop over all args
|
||||
while [ -n "$1" ] ; do
|
||||
|
||||
|
@ -91,14 +99,14 @@ done
|
|||
srcdirtext=
|
||||
if [ -z "${srcdir}" ] ; then
|
||||
srcdirtext="or . or .." ; srcdir=.
|
||||
if [ ! -r ${srcdir}/${srctrigger} ] ; then srcdir=.. ; fi
|
||||
if [ ! -r ${srcdir}/${srctrigger} ] ; then
|
||||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then srcdir=.. ; fi
|
||||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
|
||||
## the sed command below emulates the dirname command
|
||||
srcdir=`echo $0 | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -r ${srcdir}/${srctrigger} ] ; then
|
||||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
|
||||
exec 1>&2
|
||||
echo
|
||||
echo "configure: Can't find sources in ${srcdir} ${srcdirtext}"
|
||||
|
@ -107,18 +115,7 @@ if [ ! -r ${srcdir}/${srctrigger} ] ; then
|
|||
fi
|
||||
|
||||
# Set srcdir to . if that's what it is.
|
||||
if [ "`pwd`" = "`cd ${srcdir} ; pwd`" ] ; then srcdir=. ; fi
|
||||
|
||||
# checking whether we are using GNU C.
|
||||
if [ -z "${CC}" ] ; then # Let the user override the test.
|
||||
if [ -x /bin/gcc ] ||
|
||||
[ -x /usr/bin/gcc ] ||
|
||||
[ -x /usr/local/bin/gcc ] ; then
|
||||
CC="gcc"
|
||||
else
|
||||
CC="cc"
|
||||
fi
|
||||
fi
|
||||
if [ "`pwd`" = "`cd "${srcdir}" ; pwd`" ] ; then srcdir=. ; fi
|
||||
|
||||
echo
|
||||
if [ -z "${no_create}" ] ; then
|
||||
|
@ -152,7 +149,7 @@ echo "LDFLAGS = ${LDFLAGS}"
|
|||
rm -f Makefile
|
||||
cat > Makefile << EOF
|
||||
# Makefile for Lunzip - Decompressor for lzip files
|
||||
# Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
# This file was generated automatically by configure. Do not edit.
|
||||
#
|
||||
# This Makefile is free software: you have unlimited permission
|
||||
|
@ -173,6 +170,6 @@ CPPFLAGS = ${CPPFLAGS}
|
|||
CFLAGS = ${CFLAGS}
|
||||
LDFLAGS = ${LDFLAGS}
|
||||
EOF
|
||||
cat ${srcdir}/Makefile.in >> Makefile
|
||||
cat "${srcdir}/Makefile.in" >> Makefile
|
||||
|
||||
echo "OK. Now you can run make."
|
||||
|
|
103
decoder.c
103
decoder.c
|
@ -1,5 +1,5 @@
|
|||
/* Lunzip - Decompressor for lzip files
|
||||
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -32,23 +32,40 @@
|
|||
CRC32 crc32;
|
||||
|
||||
|
||||
void Pp_show_msg( struct Pretty_print * const pp, const char * const msg )
|
||||
{
|
||||
if( pp->verbosity >= 0 )
|
||||
{
|
||||
if( pp->first_post )
|
||||
{
|
||||
int i, len;
|
||||
pp->first_post = false;
|
||||
fprintf( stderr, " %s: ", pp->name );
|
||||
len = pp->longest_name - strlen( pp->name );
|
||||
for( i = 0; i < len; ++i ) fprintf( stderr, " " );
|
||||
if( !msg ) fflush( stderr );
|
||||
}
|
||||
if( msg ) fprintf( stderr, "%s.\n", msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Returns the number of bytes really read.
|
||||
If (returned value < size) and (errno == 0), means EOF was reached.
|
||||
*/
|
||||
static 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 );
|
||||
while( rest > 0 )
|
||||
{
|
||||
const int n = read( fd, buf + size - rest, rest );
|
||||
if( n > 0 ) rest -= n;
|
||||
else if( n == 0 ) break;
|
||||
else if( n == 0 ) break; /* EOF */
|
||||
else if( errno != EINTR && errno != EAGAIN ) break;
|
||||
errno = 0;
|
||||
}
|
||||
return ( rest > 0 ) ? size - rest : size;
|
||||
return size - rest;
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,16 +75,15 @@ static int readblock( const int fd, uint8_t * const buf, const int size )
|
|||
static 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 );
|
||||
while( rest > 0 )
|
||||
{
|
||||
const int n = write( fd, buf + size - rest, rest );
|
||||
if( n > 0 ) rest -= n;
|
||||
else if( n < 0 && errno != EINTR && errno != EAGAIN ) break;
|
||||
errno = 0;
|
||||
}
|
||||
return ( rest > 0 ) ? size - rest : size;
|
||||
return size - rest;
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,7 +123,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder,
|
|||
{
|
||||
File_trailer trailer;
|
||||
const int trailer_size = Ft_versioned_size( decoder->member_version );
|
||||
const long long member_size =
|
||||
const unsigned long long member_size =
|
||||
Rd_member_position( decoder->range_decoder ) + trailer_size;
|
||||
bool error = false;
|
||||
|
||||
|
@ -136,8 +152,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder,
|
|||
{
|
||||
Pp_show_msg( pp, 0 );
|
||||
fprintf( stderr, "CRC mismatch; trailer says %08X, data CRC is %08X.\n",
|
||||
(unsigned int)Ft_get_data_crc( trailer ),
|
||||
(unsigned int)LZd_crc( decoder ) );
|
||||
Ft_get_data_crc( trailer ), LZd_crc( decoder ) );
|
||||
}
|
||||
}
|
||||
if( Ft_get_data_size( trailer ) != LZd_data_position( decoder ) )
|
||||
|
@ -146,7 +161,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder,
|
|||
if( pp->verbosity >= 0 )
|
||||
{
|
||||
Pp_show_msg( pp, 0 );
|
||||
fprintf( stderr, "Data size mismatch; trailer says %lld, data size is %lld (0x%llX).\n",
|
||||
fprintf( stderr, "Data size mismatch; trailer says %llu, data size is %llu (0x%llX).\n",
|
||||
Ft_get_data_size( trailer ), LZd_data_position( decoder ), LZd_data_position( decoder ) );
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +171,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder,
|
|||
if( pp->verbosity >= 0 )
|
||||
{
|
||||
Pp_show_msg( pp, 0 );
|
||||
fprintf( stderr, "Member size mismatch; trailer says %lld, member size is %lld (0x%llX).\n",
|
||||
fprintf( stderr, "Member size mismatch; trailer says %llu, member size is %llu (0x%llX).\n",
|
||||
Ft_get_member_size( trailer ), member_size, member_size );
|
||||
}
|
||||
}
|
||||
|
@ -166,8 +181,8 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder,
|
|||
( 8.0 * member_size ) / LZd_data_position( decoder ),
|
||||
100.0 * ( 1.0 - ( (double)member_size / LZd_data_position( decoder ) ) ) );
|
||||
if( !error && pp->verbosity >= 4 )
|
||||
fprintf( stderr, "data CRC %08X, data size %9lld, member size %8lld. ",
|
||||
(unsigned int)Ft_get_data_crc( trailer ),
|
||||
fprintf( stderr, "data CRC %08X, data size %9llu, member size %8llu. ",
|
||||
Ft_get_data_crc( trailer ),
|
||||
Ft_get_data_size( trailer ), Ft_get_member_size( trailer ) );
|
||||
return !error;
|
||||
}
|
||||
|
@ -178,10 +193,11 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder,
|
|||
int LZd_decode_member( struct LZ_decoder * const decoder,
|
||||
struct Pretty_print * const pp )
|
||||
{
|
||||
unsigned int rep0 = 0; /* rep[0-3] latest four distances */
|
||||
unsigned int rep1 = 0; /* used for efficient coding of */
|
||||
unsigned int rep2 = 0; /* repeated distances */
|
||||
unsigned int rep3 = 0;
|
||||
unsigned rep0 = 0; /* rep[0-3] latest four distances */
|
||||
unsigned rep1 = 0; /* used for efficient coding of */
|
||||
unsigned rep2 = 0; /* repeated distances */
|
||||
unsigned rep3 = 0;
|
||||
|
||||
State state = 0;
|
||||
Rd_load( decoder->range_decoder );
|
||||
|
||||
|
@ -192,12 +208,17 @@ int LZd_decode_member( struct LZ_decoder * const decoder,
|
|||
{
|
||||
const uint8_t prev_byte = LZd_get_prev_byte( decoder );
|
||||
if( St_is_char( state ) )
|
||||
LZd_put_byte( decoder, Lid_decode( &decoder->literal_decoder,
|
||||
decoder->range_decoder, prev_byte ) );
|
||||
{
|
||||
state -= ( state < 4 ) ? state : 3;
|
||||
LZd_put_byte( decoder, Rd_decode_tree( decoder->range_decoder,
|
||||
decoder->bm_literal[get_lit_state(prev_byte)], 8 ) );
|
||||
}
|
||||
else
|
||||
LZd_put_byte( decoder, Lid_decode_matched( &decoder->literal_decoder,
|
||||
decoder->range_decoder, prev_byte, LZd_get_byte( decoder, rep0 ) ) );
|
||||
St_set_char( &state );
|
||||
{
|
||||
state -= ( state < 10 ) ? 3 : 6;
|
||||
LZd_put_byte( decoder, Rd_decode_matched( decoder->range_decoder,
|
||||
decoder->bm_literal[get_lit_state(prev_byte)], LZd_get_byte( decoder, rep0 ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -207,7 +228,7 @@ int LZd_decode_member( struct LZ_decoder * const decoder,
|
|||
len = 0;
|
||||
if( Rd_decode_bit( decoder->range_decoder, &decoder->bm_rep0[state] ) == 1 )
|
||||
{
|
||||
unsigned int distance;
|
||||
unsigned distance;
|
||||
if( Rd_decode_bit( decoder->range_decoder, &decoder->bm_rep1[state] ) == 0 )
|
||||
distance = rep1;
|
||||
else
|
||||
|
@ -223,31 +244,33 @@ int LZd_decode_member( struct LZ_decoder * const decoder,
|
|||
else
|
||||
{
|
||||
if( Rd_decode_bit( decoder->range_decoder, &decoder->bm_len[state][pos_state] ) == 0 )
|
||||
{ St_set_short_rep( &state ); len = 1; }
|
||||
{ state = St_set_short_rep( state ); len = 1; }
|
||||
}
|
||||
if( len == 0 )
|
||||
{
|
||||
St_set_rep( &state );
|
||||
state = St_set_rep( state );
|
||||
len = min_match_len + Led_decode( &decoder->rep_match_len_decoder, decoder->range_decoder, pos_state );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int dis_slot;
|
||||
const unsigned int rep0_saved = rep0;
|
||||
const unsigned rep0_saved = rep0;
|
||||
len = min_match_len + Led_decode( &decoder->len_decoder, decoder->range_decoder, pos_state );
|
||||
dis_slot = Rd_decode_tree( decoder->range_decoder, decoder->bm_dis_slot[get_dis_state(len)], dis_slot_bits );
|
||||
dis_slot = Rd_decode_tree6( decoder->range_decoder, decoder->bm_dis_slot[get_dis_state(len)] );
|
||||
if( dis_slot < start_dis_model ) rep0 = dis_slot;
|
||||
else
|
||||
{
|
||||
const int direct_bits = ( dis_slot >> 1 ) - 1;
|
||||
rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits;
|
||||
if( dis_slot < end_dis_model )
|
||||
rep0 += Rd_decode_tree_reversed( decoder->range_decoder, decoder->bm_dis + rep0 - dis_slot, direct_bits );
|
||||
rep0 += Rd_decode_tree_reversed( decoder->range_decoder,
|
||||
decoder->bm_dis + rep0 - dis_slot - 1,
|
||||
direct_bits );
|
||||
else
|
||||
{
|
||||
rep0 += Rd_decode( decoder->range_decoder, direct_bits - dis_align_bits ) << dis_align_bits;
|
||||
rep0 += Rd_decode_tree_reversed( decoder->range_decoder, decoder->bm_align, dis_align_bits );
|
||||
rep0 += Rd_decode_tree_reversed4( decoder->range_decoder, decoder->bm_align );
|
||||
if( rep0 == 0xFFFFFFFFU ) /* Marker found */
|
||||
{
|
||||
rep0 = rep0_saved;
|
||||
|
@ -271,9 +294,9 @@ int LZd_decode_member( struct LZ_decoder * const decoder,
|
|||
}
|
||||
}
|
||||
rep3 = rep2; rep2 = rep1; rep1 = rep0_saved;
|
||||
St_set_match( &state );
|
||||
if( rep0 >= (unsigned int)decoder->dictionary_size ||
|
||||
( rep0 >= (unsigned int)decoder->pos && !decoder->partial_data_pos ) )
|
||||
state = St_set_match( state );
|
||||
if( rep0 >= (unsigned)decoder->dictionary_size ||
|
||||
( rep0 >= (unsigned)decoder->pos && !decoder->partial_data_pos ) )
|
||||
{ LZd_flush_data( decoder ); return 1; }
|
||||
}
|
||||
LZd_copy_block( decoder, rep0, len );
|
||||
|
|
166
decoder.h
166
decoder.h
|
@ -1,5 +1,5 @@
|
|||
/* Lunzip - Decompressor for lzip files
|
||||
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,7 +19,7 @@ enum { rd_buffer_size = 16384 };
|
|||
|
||||
struct Range_decoder
|
||||
{
|
||||
long long partial_member_pos;
|
||||
unsigned long long partial_member_pos;
|
||||
uint8_t * buffer; /* input buffer */
|
||||
int pos; /* current pos in buffer */
|
||||
int stream_pos; /* when reached, a new block must be read */
|
||||
|
@ -51,7 +51,8 @@ static inline void Rd_free( struct Range_decoder * const rdec )
|
|||
static inline bool Rd_finished( struct Range_decoder * const rdec )
|
||||
{ return rdec->pos >= rdec->stream_pos && !Rd_read_block( rdec ); }
|
||||
|
||||
static inline long long Rd_member_position( const struct Range_decoder * const rdec )
|
||||
static inline unsigned long long
|
||||
Rd_member_position( const struct Range_decoder * const rdec )
|
||||
{ return rdec->partial_member_pos + rdec->pos; }
|
||||
|
||||
static inline void Rd_reset_member_position( struct Range_decoder * const rdec )
|
||||
|
@ -59,7 +60,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 )
|
||||
{
|
||||
if( Rd_finished( rdec ) ) return 0x55; /* make code != 0 */
|
||||
if( Rd_finished( rdec ) ) return 0xAA; /* make code != 0 */
|
||||
return rdec->buffer[rdec->pos++];
|
||||
}
|
||||
|
||||
|
@ -74,16 +75,16 @@ static inline int Rd_read_data( struct Range_decoder * const rdec,
|
|||
rdec->pos += rd;
|
||||
rest -= rd;
|
||||
}
|
||||
return ( rest > 0 ) ? size - rest : size;
|
||||
return size - rest;
|
||||
}
|
||||
|
||||
static inline void Rd_load( struct Range_decoder * const rdec )
|
||||
{
|
||||
int i;
|
||||
rdec->code = 0;
|
||||
rdec->range = 0xFFFFFFFFU;
|
||||
for( i = 0; i < 5; ++i )
|
||||
rdec->code = (rdec->code << 8) | Rd_get_byte( rdec );
|
||||
rdec->range = 0xFFFFFFFFU;
|
||||
}
|
||||
|
||||
static inline void Rd_normalize( struct Range_decoder * const rdec )
|
||||
|
@ -102,20 +103,15 @@ static inline int Rd_decode( struct Range_decoder * const rdec,
|
|||
int i;
|
||||
for( i = num_bits; i > 0; --i )
|
||||
{
|
||||
symbol <<= 1;
|
||||
if( rdec->range <= 0x00FFFFFFU )
|
||||
{
|
||||
rdec->range <<= 7;
|
||||
rdec->code = (rdec->code << 8) | Rd_get_byte( rdec );
|
||||
if( rdec->code >= rdec->range )
|
||||
{ rdec->code -= rdec->range; symbol |= 1; }
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t mask;
|
||||
Rd_normalize( rdec );
|
||||
rdec->range >>= 1;
|
||||
if( rdec->code >= rdec->range )
|
||||
{ rdec->code -= rdec->range; symbol |= 1; }
|
||||
}
|
||||
/* symbol <<= 1; */
|
||||
/* if( rdec->code >= rdec->range ) { rdec->code -= rdec->range; symbol |= 1; } */
|
||||
mask = 0U - (rdec->code < rdec->range);
|
||||
rdec->code -= rdec->range;
|
||||
rdec->code += rdec->range & mask;
|
||||
symbol = (symbol << 1) + (mask + 1);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
@ -151,6 +147,19 @@ static inline int Rd_decode_tree( struct Range_decoder * const rdec,
|
|||
return model - (1 << num_bits);
|
||||
}
|
||||
|
||||
static inline int Rd_decode_tree6( struct Range_decoder * const rdec,
|
||||
Bit_model bm[] )
|
||||
{
|
||||
int model = 1;
|
||||
model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] );
|
||||
model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] );
|
||||
model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] );
|
||||
model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] );
|
||||
model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] );
|
||||
model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] );
|
||||
return model - (1 << 6);
|
||||
}
|
||||
|
||||
static inline int Rd_decode_tree_reversed( struct Range_decoder * const rdec,
|
||||
Bit_model bm[], const int num_bits )
|
||||
{
|
||||
|
@ -159,32 +168,49 @@ static inline int Rd_decode_tree_reversed( struct Range_decoder * const rdec,
|
|||
int i;
|
||||
for( i = 0; i < num_bits; ++i )
|
||||
{
|
||||
const int bit = Rd_decode_bit( rdec, &bm[model] );
|
||||
const bool bit = Rd_decode_bit( rdec, &bm[model] );
|
||||
model <<= 1;
|
||||
if( bit ) { model |= 1; symbol |= (1 << i); }
|
||||
if( bit ) { ++model; symbol |= (1 << i); }
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
static inline int Rd_decode_tree_reversed4( struct Range_decoder * const rdec,
|
||||
Bit_model bm[] )
|
||||
{
|
||||
int model = 1;
|
||||
int symbol = 0;
|
||||
int bit = Rd_decode_bit( rdec, &bm[model] );
|
||||
model = (model << 1) + bit; symbol |= bit;
|
||||
bit = Rd_decode_bit( rdec, &bm[model] );
|
||||
model = (model << 1) + bit; symbol |= (bit << 1);
|
||||
bit = Rd_decode_bit( rdec, &bm[model] );
|
||||
model = (model << 1) + bit; symbol |= (bit << 2);
|
||||
if( Rd_decode_bit( rdec, &bm[model] ) ) symbol |= 8;
|
||||
return symbol;
|
||||
}
|
||||
|
||||
static inline int Rd_decode_matched( struct Range_decoder * const rdec,
|
||||
Bit_model bm[], const int match_byte )
|
||||
Bit_model bm[], int match_byte )
|
||||
{
|
||||
Bit_model * const bm1 = bm + 0x100;
|
||||
int symbol = 1;
|
||||
int i;
|
||||
for( i = 7; i >= 0; --i )
|
||||
{
|
||||
const int match_bit = ( match_byte >> i ) & 1;
|
||||
const int bit = Rd_decode_bit( rdec, &bm1[(match_bit<<8)+symbol] );
|
||||
int match_bit, bit;
|
||||
match_byte <<= 1;
|
||||
match_bit = match_byte & 0x100;
|
||||
bit = Rd_decode_bit( rdec, &bm1[match_bit+symbol] );
|
||||
symbol = ( symbol << 1 ) | bit;
|
||||
if( match_bit != bit )
|
||||
if( match_bit != bit << 8 )
|
||||
{
|
||||
while( --i >= 0 )
|
||||
while( symbol < 0x100 )
|
||||
symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return symbol & 0xFF;
|
||||
return symbol - 0x100;
|
||||
}
|
||||
|
||||
|
||||
|
@ -199,17 +225,11 @@ struct Len_decoder
|
|||
|
||||
static inline void Led_init( struct Len_decoder * const len_decoder )
|
||||
{
|
||||
int i, j;
|
||||
Bm_init( &len_decoder->choice1 );
|
||||
Bm_init( &len_decoder->choice2 );
|
||||
for( i = 0; i < pos_states; ++i )
|
||||
for( j = 0; j < len_low_symbols; ++j )
|
||||
Bm_init( &len_decoder->bm_low[i][j] );
|
||||
for( i = 0; i < pos_states; ++i )
|
||||
for( j = 0; j < len_mid_symbols; ++j )
|
||||
Bm_init( &len_decoder->bm_mid[i][j] );
|
||||
for( i = 0; i < len_high_symbols; ++i )
|
||||
Bm_init( &len_decoder->bm_high[i] );
|
||||
Bm_array_init( len_decoder->bm_low[0], pos_states * len_low_symbols );
|
||||
Bm_array_init( len_decoder->bm_mid[0], pos_states * len_mid_symbols );
|
||||
Bm_array_init( len_decoder->bm_high, len_high_symbols );
|
||||
}
|
||||
|
||||
static inline int Led_decode( struct Len_decoder * const len_decoder,
|
||||
|
@ -226,37 +246,9 @@ static inline int Led_decode( struct Len_decoder * const len_decoder,
|
|||
}
|
||||
|
||||
|
||||
struct Literal_decoder
|
||||
{
|
||||
Bit_model bm_literal[1<<literal_context_bits][0x300];
|
||||
};
|
||||
|
||||
static inline void Lid_init( struct Literal_decoder * const lidec )
|
||||
{
|
||||
int i, j;
|
||||
for( i = 0; i < 1<<literal_context_bits; ++i )
|
||||
for( j = 0; j < 0x300; ++j )
|
||||
Bm_init( &lidec->bm_literal[i][j] );
|
||||
}
|
||||
|
||||
static inline int Lid_state( const uint8_t prev_byte )
|
||||
{ return ( prev_byte >> ( 8 - literal_context_bits ) ); }
|
||||
|
||||
static inline uint8_t Lid_decode( struct Literal_decoder * const lidec,
|
||||
struct Range_decoder * const rdec,
|
||||
const uint8_t prev_byte )
|
||||
{ return Rd_decode_tree( rdec, lidec->bm_literal[Lid_state(prev_byte)], 8 ); }
|
||||
|
||||
static inline uint8_t Lid_decode_matched( struct Literal_decoder * const lidec,
|
||||
struct Range_decoder * const rdec,
|
||||
const uint8_t prev_byte,
|
||||
const uint8_t match_byte )
|
||||
{ return Rd_decode_matched( rdec, lidec->bm_literal[Lid_state(prev_byte)], match_byte ); }
|
||||
|
||||
|
||||
struct LZ_decoder
|
||||
{
|
||||
long long partial_data_pos;
|
||||
unsigned long long partial_data_pos;
|
||||
int dictionary_size;
|
||||
int buffer_size;
|
||||
uint8_t * buffer; /* output buffer */
|
||||
|
@ -266,6 +258,7 @@ struct LZ_decoder
|
|||
int outfd; /* output file descriptor */
|
||||
int member_version;
|
||||
|
||||
Bit_model bm_literal[1<<literal_context_bits][0x300];
|
||||
Bit_model bm_match[states][pos_states];
|
||||
Bit_model bm_rep[states];
|
||||
Bit_model bm_rep0[states];
|
||||
|
@ -273,13 +266,12 @@ struct LZ_decoder
|
|||
Bit_model bm_rep2[states];
|
||||
Bit_model bm_len[states][pos_states];
|
||||
Bit_model bm_dis_slot[max_dis_states][1<<dis_slot_bits];
|
||||
Bit_model bm_dis[modeled_distances-end_dis_model+1];
|
||||
Bit_model bm_dis[modeled_distances-end_dis_model];
|
||||
Bit_model bm_align[dis_align_size];
|
||||
|
||||
struct Range_decoder * range_decoder;
|
||||
struct Len_decoder len_decoder;
|
||||
struct Len_decoder rep_match_len_decoder;
|
||||
struct Literal_decoder literal_decoder;
|
||||
};
|
||||
|
||||
void LZd_flush_data( struct LZ_decoder * const decoder );
|
||||
|
@ -315,12 +307,12 @@ static inline void LZd_copy_block( struct LZ_decoder * const decoder,
|
|||
int i = decoder->pos - distance - 1;
|
||||
if( i < 0 ) i += decoder->buffer_size;
|
||||
if( len < decoder->buffer_size - max( decoder->pos, i ) &&
|
||||
len <= abs( decoder->pos - i ) )
|
||||
len <= abs( decoder->pos - i ) ) /* no wrap, no overlap */
|
||||
{
|
||||
memcpy( decoder->buffer + decoder->pos, decoder->buffer + i, len );
|
||||
decoder->pos += len;
|
||||
}
|
||||
else for( ; len > 0 ; --len )
|
||||
else for( ; len > 0; --len )
|
||||
{
|
||||
decoder->buffer[decoder->pos] = decoder->buffer[i];
|
||||
if( ++decoder->pos >= decoder->buffer_size ) LZd_flush_data( decoder );
|
||||
|
@ -332,7 +324,6 @@ static inline bool LZd_init( struct LZ_decoder * const decoder,
|
|||
const File_header header,
|
||||
struct Range_decoder * const rdec, const int ofd )
|
||||
{
|
||||
int i, j;
|
||||
decoder->partial_data_pos = 0;
|
||||
decoder->dictionary_size = Fh_get_dictionary_size( header );
|
||||
decoder->buffer_size = max( 65536, decoder->dictionary_size );
|
||||
|
@ -344,30 +335,20 @@ static inline bool LZd_init( struct LZ_decoder * const decoder,
|
|||
decoder->outfd = ofd;
|
||||
decoder->member_version = Fh_version( header );
|
||||
|
||||
for( i = 0; i < states; ++i )
|
||||
{
|
||||
for( j = 0; j < pos_states; ++j )
|
||||
{
|
||||
Bm_init( &decoder->bm_match[i][j] );
|
||||
Bm_init( &decoder->bm_len[i][j] );
|
||||
}
|
||||
Bm_init( &decoder->bm_rep[i] );
|
||||
Bm_init( &decoder->bm_rep0[i] );
|
||||
Bm_init( &decoder->bm_rep1[i] );
|
||||
Bm_init( &decoder->bm_rep2[i] );
|
||||
}
|
||||
for( i = 0; i < max_dis_states; ++i )
|
||||
for( j = 0; j < 1<<dis_slot_bits; ++j )
|
||||
Bm_init( &decoder->bm_dis_slot[i][j] );
|
||||
for( i = 0; i < modeled_distances-end_dis_model+1; ++i )
|
||||
Bm_init( &decoder->bm_dis[i] );
|
||||
for( i = 0; i < dis_align_size; ++i )
|
||||
Bm_init( &decoder->bm_align[i] );
|
||||
Bm_array_init( decoder->bm_literal[0], (1 << literal_context_bits) * 0x300 );
|
||||
Bm_array_init( decoder->bm_match[0], states * pos_states );
|
||||
Bm_array_init( decoder->bm_rep, states );
|
||||
Bm_array_init( decoder->bm_rep0, states );
|
||||
Bm_array_init( decoder->bm_rep1, states );
|
||||
Bm_array_init( decoder->bm_rep2, states );
|
||||
Bm_array_init( decoder->bm_len[0], states * pos_states );
|
||||
Bm_array_init( decoder->bm_dis_slot[0], max_dis_states * (1 << dis_slot_bits) );
|
||||
Bm_array_init( decoder->bm_dis, modeled_distances - end_dis_model );
|
||||
Bm_array_init( decoder->bm_align, dis_align_size );
|
||||
|
||||
decoder->range_decoder = rdec;
|
||||
Led_init( &decoder->len_decoder );
|
||||
Led_init( &decoder->rep_match_len_decoder );
|
||||
Lid_init( &decoder->literal_decoder );
|
||||
decoder->buffer[decoder->buffer_size-1] = 0; /* prev_byte of first_byte */
|
||||
return true;
|
||||
}
|
||||
|
@ -375,10 +356,11 @@ static inline bool LZd_init( struct LZ_decoder * const decoder,
|
|||
static inline void LZd_free( struct LZ_decoder * const decoder )
|
||||
{ free( decoder->buffer ); }
|
||||
|
||||
static inline uint32_t LZd_crc( const struct LZ_decoder * const decoder )
|
||||
static inline unsigned LZd_crc( const struct LZ_decoder * const decoder )
|
||||
{ return decoder->crc ^ 0xFFFFFFFFU; }
|
||||
|
||||
static inline long long LZd_data_position( const struct LZ_decoder * const decoder )
|
||||
static inline unsigned long long
|
||||
LZd_data_position( const struct LZ_decoder * const decoder )
|
||||
{ return decoder->partial_data_pos + decoder->pos; }
|
||||
|
||||
int LZd_decode_member( struct LZ_decoder * const decoder,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
|
||||
.TH LUNZIP "1" "February 2012" "Lunzip 1.1" "User Commands"
|
||||
.TH LUNZIP "1" "February 2013" "Lunzip 1.2" "User Commands"
|
||||
.SH NAME
|
||||
Lunzip \- small decompressor for lzip files
|
||||
.SH SYNOPSIS
|
||||
|
@ -46,7 +46,7 @@ Report bugs to lzip\-bug@nongnu.org
|
|||
.br
|
||||
Lunzip home page: http://www.nongnu.org/lzip/lunzip.html
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2012 Antonio Diaz Diaz.
|
||||
Copyright \(co 2013 Antonio Diaz Diaz.
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
.br
|
||||
This is free software: you are free to change and redistribute it.
|
||||
|
|
87
lunzip.h
87
lunzip.h
|
@ -1,5 +1,5 @@
|
|||
/* Lunzip - Decompressor for lzip files
|
||||
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,39 +22,26 @@
|
|||
#define min(x,y) ((x) <= (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
typedef unsigned char State;
|
||||
typedef int State;
|
||||
|
||||
enum { states = 12 };
|
||||
|
||||
static inline bool St_is_char( const State st ) { return st < 7; }
|
||||
|
||||
static inline void St_set_char( State * const st )
|
||||
static inline State St_set_char( const State st )
|
||||
{
|
||||
static const unsigned char next[states] =
|
||||
{ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
|
||||
*st = next[*st];
|
||||
static const State next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
|
||||
return next[st];
|
||||
}
|
||||
|
||||
static inline void St_set_match( State * const st )
|
||||
{
|
||||
static const unsigned char next[states] =
|
||||
{ 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 };
|
||||
*st = next[*st];
|
||||
}
|
||||
static inline State St_set_match( const State st )
|
||||
{ return ( ( st < 7 ) ? 7 : 10 ); }
|
||||
|
||||
static inline void St_set_rep( State * const st )
|
||||
{
|
||||
static const unsigned char next[states] =
|
||||
{ 8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11 };
|
||||
*st = next[*st];
|
||||
}
|
||||
static inline State St_set_rep( const State st )
|
||||
{ return ( ( st < 7 ) ? 8 : 11 ); }
|
||||
|
||||
static inline void St_set_short_rep( State * const st )
|
||||
{
|
||||
static const unsigned char next[states] =
|
||||
{ 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11 };
|
||||
*st = next[*st];
|
||||
}
|
||||
static inline State St_set_short_rep( const State st )
|
||||
{ return ( ( st < 7 ) ? 9 : 11 ); }
|
||||
|
||||
|
||||
enum {
|
||||
|
@ -88,23 +75,25 @@ enum {
|
|||
|
||||
max_dis_states = 4 };
|
||||
|
||||
static inline int get_dis_state( int len )
|
||||
{
|
||||
len -= min_match_len;
|
||||
if( len >= max_dis_states ) len = max_dis_states - 1;
|
||||
return len;
|
||||
}
|
||||
static inline int get_dis_state( const int len )
|
||||
{ return min( len - min_match_len, max_dis_states - 1 ); }
|
||||
|
||||
static inline int get_lit_state( const uint8_t prev_byte )
|
||||
{ return ( prev_byte >> ( 8 - literal_context_bits ) ); }
|
||||
|
||||
|
||||
enum { bit_model_move_bits = 5,
|
||||
bit_model_total_bits = 11,
|
||||
bit_model_total = 1 << bit_model_total_bits };
|
||||
|
||||
typedef unsigned int Bit_model;
|
||||
typedef int Bit_model;
|
||||
|
||||
static inline void Bm_init( Bit_model * const probability )
|
||||
{ *probability = bit_model_total / 2; }
|
||||
|
||||
static inline void Bm_array_init( Bit_model * const p, const int size )
|
||||
{ int i = 0; while( i < size ) p[i++] = bit_model_total / 2; }
|
||||
|
||||
|
||||
struct Pretty_print
|
||||
{
|
||||
|
@ -121,7 +110,7 @@ void Pp_init( struct Pretty_print * const pp, const char * const filenames[],
|
|||
static inline void Pp_set_name( struct Pretty_print * const pp,
|
||||
const char * const filename )
|
||||
{
|
||||
if( filename && filename[0] && strcmp( filename, "-" ) )
|
||||
if( filename && filename[0] && strcmp( filename, "-" ) != 0 )
|
||||
pp->name = filename;
|
||||
else pp->name = pp->stdin_name;
|
||||
pp->first_post = true;
|
||||
|
@ -136,12 +125,12 @@ typedef uint32_t CRC32[256]; /* Table of CRCs of all 8-bit messages. */
|
|||
|
||||
extern CRC32 crc32;
|
||||
|
||||
static inline void CRC32_init()
|
||||
static inline void CRC32_init( void )
|
||||
{
|
||||
unsigned int n;
|
||||
unsigned n;
|
||||
for( n = 0; n < 256; ++n )
|
||||
{
|
||||
unsigned int c = n;
|
||||
unsigned c = n;
|
||||
int k;
|
||||
for( k = 0; k < 8; ++k )
|
||||
{ if( c & 1 ) c = 0xEDB88320U ^ ( c >> 1 ); else c >>= 1; }
|
||||
|
@ -151,6 +140,7 @@ static inline void CRC32_init()
|
|||
|
||||
static inline void CRC32_update_byte( uint32_t * crc, const uint8_t byte )
|
||||
{ *crc = crc32[(*crc^byte)&0xFF] ^ ( *crc >> 8 ); }
|
||||
|
||||
static inline void CRC32_update_buf( uint32_t * crc, const uint8_t * const buffer,
|
||||
const int size )
|
||||
{
|
||||
|
@ -160,16 +150,15 @@ static inline void CRC32_update_buf( uint32_t * crc, const uint8_t * const buffe
|
|||
}
|
||||
|
||||
|
||||
static inline int real_bits( const unsigned int value )
|
||||
static inline int real_bits( unsigned value )
|
||||
{
|
||||
int bits = 0, i = 1;
|
||||
unsigned int mask = 1;
|
||||
for( ; mask > 0; ++i, mask <<= 1 ) if( value & mask ) bits = i;
|
||||
int bits = 0;
|
||||
while( value > 0 ) { value >>= 1; ++bits; }
|
||||
return bits;
|
||||
}
|
||||
|
||||
|
||||
static const uint8_t magic_string[4] = { 'L', 'Z', 'I', 'P' };
|
||||
static const uint8_t magic_string[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
|
||||
|
||||
typedef uint8_t File_header[6]; /* 0-3 magic bytes */
|
||||
/* 4 version */
|
||||
|
@ -226,43 +215,43 @@ enum { Ft_size = 20 };
|
|||
static inline int Ft_versioned_size( const int version )
|
||||
{ return ( ( version >= 1 ) ? 20 : 12 ); }
|
||||
|
||||
static inline uint32_t Ft_get_data_crc( const File_trailer data )
|
||||
static inline unsigned Ft_get_data_crc( const File_trailer data )
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
unsigned tmp = 0;
|
||||
int i;
|
||||
for( i = 3; i >= 0; --i ) { tmp <<= 8; tmp += data[i]; }
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static inline void Ft_set_data_crc( File_trailer data, uint32_t crc )
|
||||
static inline void Ft_set_data_crc( File_trailer data, unsigned crc )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i <= 3; ++i ) { data[i] = (uint8_t)crc; crc >>= 8; }
|
||||
}
|
||||
|
||||
static inline long long Ft_get_data_size( const File_trailer data )
|
||||
static inline unsigned long long Ft_get_data_size( const File_trailer data )
|
||||
{
|
||||
long long tmp = 0;
|
||||
unsigned long long tmp = 0;
|
||||
int i;
|
||||
for( i = 11; i >= 4; --i ) { tmp <<= 8; tmp += data[i]; }
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static inline void Ft_set_data_size( File_trailer data, long long sz )
|
||||
static inline void Ft_set_data_size( File_trailer data, unsigned long long sz )
|
||||
{
|
||||
int i;
|
||||
for( i = 4; i <= 11; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; }
|
||||
}
|
||||
|
||||
static inline long long Ft_get_member_size( const File_trailer data )
|
||||
static inline unsigned long long Ft_get_member_size( const File_trailer data )
|
||||
{
|
||||
long long tmp = 0;
|
||||
unsigned long long tmp = 0;
|
||||
int i;
|
||||
for( i = 19; i >= 12; --i ) { tmp <<= 8; tmp += data[i]; }
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static inline void Ft_set_member_size( File_trailer data, long long sz )
|
||||
static inline void Ft_set_member_size( File_trailer data, unsigned long long sz )
|
||||
{
|
||||
int i;
|
||||
for( i = 12; i <= 19; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; }
|
||||
|
|
157
main.c
157
main.c
|
@ -1,5 +1,5 @@
|
|||
/* Lunzip - Decompressor for lzip files
|
||||
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -58,12 +58,10 @@
|
|||
#error "Environments where CHAR_BIT != 8 are not supported."
|
||||
#endif
|
||||
|
||||
long long int llabs( long long int number );
|
||||
|
||||
|
||||
const char * const Program_name = "Lunzip";
|
||||
const char * const program_name = "lunzip";
|
||||
const char * const program_year = "2012";
|
||||
const char * const program_year = "2013";
|
||||
const char * invocation_name = 0;
|
||||
|
||||
#ifdef O_BINARY
|
||||
|
@ -86,21 +84,7 @@ mode_t outfd_mode = S_IRUSR | S_IWUSR;
|
|||
bool delete_output_on_interrupt = false;
|
||||
|
||||
|
||||
/* assure at least a minimum size for buffer 'buf' */
|
||||
static void * resize_buffer( void * buf, const int min_size )
|
||||
{
|
||||
if( buf ) buf = realloc( buf, min_size );
|
||||
else buf = malloc( min_size );
|
||||
if( !buf )
|
||||
{
|
||||
show_error( "Not enough memory.", 0, false );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static void show_help()
|
||||
static void show_help( void )
|
||||
{
|
||||
printf( "%s - Decompressor for lzip files.\n", Program_name );
|
||||
printf( "\nUsage: %s [options] [files]\n", invocation_name );
|
||||
|
@ -122,7 +106,7 @@ static void show_help()
|
|||
}
|
||||
|
||||
|
||||
static void show_version()
|
||||
static void show_version( void )
|
||||
{
|
||||
printf( "%s %s\n", Program_name, PROGVERSION );
|
||||
printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year );
|
||||
|
@ -132,21 +116,35 @@ static void show_version()
|
|||
}
|
||||
|
||||
|
||||
static const char * format_num( long long num )
|
||||
void show_header( const File_header header )
|
||||
{
|
||||
const char * const prefix[8] =
|
||||
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
|
||||
enum { buf_size = 16, factor = 1024 };
|
||||
static char buf[buf_size];
|
||||
const char *p = "";
|
||||
enum { factor = 1024 };
|
||||
const char * p = "";
|
||||
const char * np = " ";
|
||||
unsigned num = Fh_get_dictionary_size( header ), i;
|
||||
bool exact = ( num % factor == 0 );
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 8 && ( llabs( num ) > 9999 ||
|
||||
( exact && llabs( num ) >= factor ) ); ++i )
|
||||
{ num /= factor; if( num % factor != 0 ) exact = false; p = prefix[i]; }
|
||||
snprintf( buf, buf_size, "%lld %s", num, p );
|
||||
return buf;
|
||||
for( i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i )
|
||||
{ num /= factor; if( num % factor != 0 ) exact = false;
|
||||
p = prefix[i]; np = ""; }
|
||||
fprintf( stderr, "version %d, dictionary size %s%4u %sB. ",
|
||||
Fh_version( header ), np, num, p );
|
||||
}
|
||||
|
||||
|
||||
static int extension_index( const char * const name )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; known_extensions[i].from; ++i )
|
||||
{
|
||||
const char * const ext = known_extensions[i].from;
|
||||
if( strlen( name ) > strlen( ext ) &&
|
||||
strncmp( name + strlen( name ) - strlen( ext ), ext, strlen( ext ) ) == 0 )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,23 +181,22 @@ static int open_instream( const char * const name,
|
|||
}
|
||||
|
||||
|
||||
static int extension_index( const char * const name )
|
||||
/* assure at least a minimum size for buffer 'buf' */
|
||||
static void * resize_buffer( void * buf, const int min_size )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; known_extensions[i].from; ++i )
|
||||
if( buf ) buf = realloc( buf, min_size );
|
||||
else buf = malloc( min_size );
|
||||
if( !buf )
|
||||
{
|
||||
const char * const ext = known_extensions[i].from;
|
||||
if( strlen( name ) > strlen( ext ) &&
|
||||
strncmp( name + strlen( name ) - strlen( ext ), ext, strlen( ext ) ) == 0 )
|
||||
return i;
|
||||
show_error( "Not enough memory.", 0, false );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
return -1;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static void set_d_outname( const char * const name )
|
||||
static void set_d_outname( const char * const name, const int i )
|
||||
{
|
||||
const int i = extension_index( name );
|
||||
if( i >= 0 )
|
||||
{
|
||||
const char * const from = known_extensions[i].from;
|
||||
|
@ -286,9 +283,9 @@ static void close_and_set_permissions( const struct stat * const in_statsp )
|
|||
static int decompress( const int infd, struct Pretty_print * const pp,
|
||||
const bool testing )
|
||||
{
|
||||
long long partial_file_pos = 0;
|
||||
unsigned long long partial_file_pos = 0;
|
||||
struct Range_decoder rdec;
|
||||
int retval = 0, result;
|
||||
int retval = 0;
|
||||
bool first_member;
|
||||
if( !Rd_init( &rdec, infd ) )
|
||||
{
|
||||
|
@ -296,8 +293,9 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
cleanup_and_fail( 1 );
|
||||
}
|
||||
|
||||
for( first_member = true; ; first_member = false, Pp_reset( pp ) )
|
||||
for( first_member = true; ; first_member = false )
|
||||
{
|
||||
int result;
|
||||
File_header header;
|
||||
struct LZ_decoder decoder;
|
||||
Rd_reset_member_position( &rdec );
|
||||
|
@ -328,13 +326,7 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
retval = 2; break; }
|
||||
|
||||
if( verbosity >= 2 || ( verbosity == 1 && first_member ) )
|
||||
{
|
||||
Pp_show_msg( pp, 0 );
|
||||
if( verbosity >= 2 )
|
||||
fprintf( stderr, "version %d, dictionary size %7sB. ",
|
||||
Fh_version( header ),
|
||||
format_num( Fh_get_dictionary_size( header ) ) );
|
||||
}
|
||||
{ Pp_show_msg( pp, 0 ); if( verbosity >= 2 ) show_header( header ); }
|
||||
|
||||
if( !LZd_init( &decoder, header, &rdec, outfd ) )
|
||||
{
|
||||
|
@ -350,16 +342,16 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
{
|
||||
Pp_show_msg( pp, 0 );
|
||||
if( result == 2 )
|
||||
fprintf( stderr, "File ends unexpectedly at pos %lld\n",
|
||||
fprintf( stderr, "File ends unexpectedly at pos %llu\n",
|
||||
partial_file_pos );
|
||||
else
|
||||
fprintf( stderr, "Decoder error at pos %lld\n", partial_file_pos );
|
||||
fprintf( stderr, "Decoder error at pos %llu\n", partial_file_pos );
|
||||
}
|
||||
retval = 2; break;
|
||||
}
|
||||
if( verbosity >= 2 )
|
||||
{ if( testing ) fprintf( stderr, "ok\n" );
|
||||
else fprintf( stderr, "done\n" ); }
|
||||
else fprintf( stderr, "done\n" ); Pp_reset( pp ); }
|
||||
}
|
||||
Rd_free( &rdec );
|
||||
if( verbosity == 1 && retval == 0 )
|
||||
|
@ -371,13 +363,13 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
|
||||
void signal_handler( int sig )
|
||||
{
|
||||
sig = 0; /* keep compiler happy */
|
||||
if( sig ) {} /* keep compiler happy */
|
||||
show_error( "Control-C or similar caught, quitting.", 0, false );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
|
||||
|
||||
static void set_signals()
|
||||
static void set_signals( void )
|
||||
{
|
||||
signal( SIGHUP, signal_handler );
|
||||
signal( SIGINT, signal_handler );
|
||||
|
@ -388,7 +380,7 @@ static void set_signals()
|
|||
void Pp_init( struct Pretty_print * const pp, const char * const filenames[],
|
||||
const int num_filenames, const int v )
|
||||
{
|
||||
unsigned int stdin_name_len;
|
||||
unsigned stdin_name_len;
|
||||
int i;
|
||||
pp->name = 0;
|
||||
pp->stdin_name = "(stdin)";
|
||||
|
@ -400,31 +392,13 @@ void Pp_init( struct Pretty_print * const pp, const char * const filenames[],
|
|||
for( i = 0; i < num_filenames; ++i )
|
||||
{
|
||||
const char * const s = filenames[i];
|
||||
const int len = ( !strcmp( s, "-" ) ? stdin_name_len : strlen( s ) );
|
||||
const int len = ( (strcmp( s, "-" ) == 0) ? stdin_name_len : strlen( s ) );
|
||||
if( len > pp->longest_name ) pp->longest_name = len;
|
||||
}
|
||||
if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len;
|
||||
}
|
||||
|
||||
|
||||
void Pp_show_msg( struct Pretty_print * const pp, const char * const msg )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
{
|
||||
if( pp->first_post )
|
||||
{
|
||||
int i, len;
|
||||
pp->first_post = false;
|
||||
fprintf( stderr, " %s: ", pp->name );
|
||||
len = pp->longest_name - strlen( pp->name );
|
||||
for( i = 0; i < len; ++i ) fprintf( stderr, " " );
|
||||
if( !msg ) fflush( stderr );
|
||||
}
|
||||
if( msg ) fprintf( stderr, "%s.\n", msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void show_error( const char * const msg, const int errcode, const bool help )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
|
@ -435,7 +409,7 @@ void show_error( const char * const msg, const int errcode, const bool help )
|
|||
if( errcode > 0 ) fprintf( stderr, ": %s", strerror( errcode ) );
|
||||
fprintf( stderr, "\n" );
|
||||
}
|
||||
if( help && invocation_name && invocation_name[0] )
|
||||
if( help )
|
||||
fprintf( stderr, "Try '%s --help' for more information.\n",
|
||||
invocation_name );
|
||||
}
|
||||
|
@ -513,28 +487,23 @@ int main( const int argc, const char * const argv[] )
|
|||
} /* end process options */
|
||||
|
||||
#if defined(__MSVCRT__) || defined(__OS2__)
|
||||
_fsetmode( stdin, "b" );
|
||||
_fsetmode( stdout, "b" );
|
||||
setmode( STDIN_FILENO, O_BINARY );
|
||||
setmode( STDOUT_FILENO, O_BINARY );
|
||||
#endif
|
||||
|
||||
if( testing )
|
||||
outfd = -1;
|
||||
|
||||
for( ; argind < ap_arguments( &parser ); ++argind )
|
||||
num_filenames = max( 1, ap_arguments( &parser ) - argind );
|
||||
filenames = resize_buffer( filenames, num_filenames * sizeof filenames[0] );
|
||||
filenames[0] = "-";
|
||||
|
||||
for( i = 0; argind + i < ap_arguments( &parser ); ++i )
|
||||
{
|
||||
if( strcmp( ap_argument( &parser, argind ), "-" ) )
|
||||
filenames_given = true;
|
||||
++num_filenames;
|
||||
filenames = resize_buffer( filenames, num_filenames * sizeof (char *) );
|
||||
filenames[num_filenames-1] = ap_argument( &parser, argind );
|
||||
filenames[i] = ap_argument( &parser, argind + i );
|
||||
if( strcmp( filenames[i], "-" ) != 0 ) filenames_given = true;
|
||||
}
|
||||
|
||||
if( num_filenames == 0 )
|
||||
{
|
||||
++num_filenames;
|
||||
filenames = resize_buffer( filenames, sizeof (char *) );
|
||||
filenames[num_filenames-1] = "-";
|
||||
}
|
||||
if( !to_stdout && !testing &&
|
||||
( filenames_given || default_output_filename[0] ) )
|
||||
set_signals();
|
||||
|
@ -549,7 +518,7 @@ int main( const int argc, const char * const argv[] )
|
|||
const struct stat * in_statsp;
|
||||
output_filename[0] = 0;
|
||||
|
||||
if( !filenames[i][0] || !strcmp( filenames[i], "-" ) )
|
||||
if( !filenames[i][0] || strcmp( filenames[i], "-" ) == 0 )
|
||||
{
|
||||
input_filename = "";
|
||||
infd = STDIN_FILENO;
|
||||
|
@ -565,7 +534,7 @@ int main( const int argc, const char * const argv[] )
|
|||
outfd_mode = all_rw;
|
||||
if( !open_outstream( force ) )
|
||||
{
|
||||
if( outfd == -1 && retval < 1 ) retval = 1;
|
||||
if( retval < 1 ) retval = 1;
|
||||
close( infd ); infd = -1;
|
||||
continue;
|
||||
}
|
||||
|
@ -582,11 +551,11 @@ int main( const int argc, const char * const argv[] )
|
|||
if( to_stdout ) outfd = STDOUT_FILENO;
|
||||
else
|
||||
{
|
||||
set_d_outname( input_filename );
|
||||
set_d_outname( input_filename, extension_index( input_filename ) );
|
||||
outfd_mode = usr_rw;
|
||||
if( !open_outstream( force ) )
|
||||
{
|
||||
if( outfd == -1 && retval < 1 ) retval = 1;
|
||||
if( retval < 1 ) retval = 1;
|
||||
close( infd ); infd = -1;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# check script for Lunzip - Decompressor for lzip files
|
||||
# Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
|
||||
#
|
||||
# This script is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
|
@ -23,27 +23,14 @@ cd "${objdir}"/tmp
|
|||
|
||||
cat "${testdir}"/test.txt > in || framework_failure
|
||||
cat in in > in2 || framework_failure
|
||||
cat "${testdir}"/test_v1.lz > in.lz || framework_failure
|
||||
cat "${testdir}"/test.txt.lz > in.lz || framework_failure
|
||||
cat in.lz in.lz > in2.lz || framework_failure
|
||||
fail=0
|
||||
|
||||
printf "testing lunzip-%s..." "$2"
|
||||
|
||||
"${LZIP}" -t "${testdir}"/test_v0.lz || fail=1
|
||||
printf .
|
||||
"${LZIP}" -cd "${testdir}"/test_v0.lz > copy || fail=1
|
||||
cmp in copy || fail=1
|
||||
printf .
|
||||
|
||||
"${LZIP}" -t "${testdir}"/test_v1.lz || fail=1
|
||||
printf .
|
||||
"${LZIP}" -cd "${testdir}"/test_v1.lz > copy || fail=1
|
||||
cmp in copy || fail=1
|
||||
printf .
|
||||
|
||||
"${LZIP}" -t "${testdir}"/test_sync.lz || fail=1
|
||||
printf .
|
||||
"${LZIP}" -cd "${testdir}"/test_sync.lz > copy || fail=1
|
||||
"${LZIP}" -t "${testdir}"/test.txt.lz || fail=1
|
||||
"${LZIP}" -cd "${testdir}"/test.txt.lz > copy || fail=1
|
||||
cmp in copy || fail=1
|
||||
printf .
|
||||
|
||||
|
|
BIN
testsuite/test.txt.lz
Normal file
BIN
testsuite/test.txt.lz
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue