1
0
Fork 0

Merging upstream version 1.1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-20 15:04:13 +01:00
parent 67fe5d1941
commit de80b4cbe6
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
7 changed files with 104 additions and 91 deletions

View file

@ -1,8 +1,15 @@
2019-01-11 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.1 released.
* File_* renamed to Lzip_*.
* lzd.cc: Compile on DOS with DJGPP.
* configure: Accept appending to CXXFLAGS, 'CXXFLAGS+=OPTIONS'.
2017-05-02 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.0 released.
* lzd.cc: Minor code improvements.
* testsuite/check.sh: A POSIX shell is required to run the tests.
* check.sh: A POSIX shell is required to run the tests.
2016-05-10 Antonio Diaz Diaz <antonio@gnu.org>
@ -32,7 +39,7 @@
2013-08-01 Antonio Diaz Diaz <antonio@gnu.org>
* Version 0.4 released.
* testsuite/check.sh: Removed '/dev/full' from tests.
* check.sh: Removed '/dev/full' from tests.
2013-07-24 Antonio Diaz Diaz <antonio@gnu.org>
@ -49,7 +56,7 @@
* Version 0.1 released.
Copyright (C) 2013-2017 Antonio Diaz Diaz.
Copyright (C) 2013-2019 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

View file

@ -1,8 +1,8 @@
Requirements
------------
You will need a C++ compiler.
I use gcc 5.3.0 and 4.1.2, but the code should compile with any
standards compliant compiler.
I use gcc 5.3.0 and 4.1.2, but the code should compile with any standards
compliant compiler.
Gcc is available at http://gcc.gnu.org.
@ -50,7 +50,7 @@ After running 'configure', you can run 'make' and 'make install' as
explained above.
Copyright (C) 2013-2017 Antonio Diaz Diaz.
Copyright (C) 2013-2019 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy,
distribute and modify it.

9
NEWS
View file

@ -1,5 +1,8 @@
Changes in version 1.0:
Changes in version 1.1:
Minor code improvements have been made.
All 'File_*' identifiers have been renamed to 'Lzip_*'.
The tests have been improved.
Lzd now should compile on DOS with DJGPP.
The configure script now accepts appending options to CXXFLAGS using the
syntax 'CXXFLAGS+=OPTIONS'.

19
README
View file

@ -13,22 +13,21 @@ correctly decompress the concatenation of two or more compressed files.
The result is the concatenation of the corresponding decompressed data.
Integrity of such concatenated compressed input is also verified.
The lzip file format is designed for data sharing and long-term
archiving, taking into account both data integrity and decoder
availability:
The lzip file format is designed for data sharing and long-term archiving,
taking into account both data integrity and decoder availability:
* The lzip format provides very safe integrity checking and some data
recovery means. The lziprecover program can repair bit-flip errors
recovery means. The lziprecover program can repair bit flip errors
(one of the most common forms of data corruption) in lzip files,
and provides data recovery capabilities, including error-checked
merging of damaged copies of a file.
* The lzip format is as simple as possible (but not simpler). The
lzip manual provides the source code of a simple decompressor along
with a detailed explanation of how it works, so that with the only
help of the lzip manual it would be possible for a digital
archaeologist to extract the data from a lzip file long after
quantum computers eventually render LZMA obsolete.
lzip manual provides the source code of a simple decompressor
along with a detailed explanation of how it works, so that with
the only help of the lzip manual it would be possible for a
digital archaeologist to extract the data from a lzip file long
after quantum computers eventually render LZMA obsolete.
* Additionally the lzip reference implementation is copylefted, which
guarantees that it will remain free forever.
@ -45,7 +44,7 @@ range encoding), and Igor Pavlov (for putting all the above together in
LZMA).
Copyright (C) 2013-2017 Antonio Diaz Diaz.
Copyright (C) 2013-2019 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy,
distribute and modify it.

16
configure vendored
View file

@ -1,12 +1,12 @@
#! /bin/sh
# configure script for Lzd - Educational decompressor for the lzip format
# Copyright (C) 2013-2017 Antonio Diaz Diaz.
# Copyright (C) 2013-2019 Antonio Diaz Diaz.
#
# This configure script is free software: you have unlimited permission
# to copy, distribute and modify it.
pkgname=lzd
pkgversion=1.0
pkgversion=1.1
progname=lzd
srctrigger=lzd.cc
@ -70,6 +70,7 @@ while [ $# != 0 ] ; do
echo " CXX=COMPILER C++ compiler to use [${CXX}]"
echo " CPPFLAGS=OPTIONS command line options for the preprocessor [${CPPFLAGS}]"
echo " CXXFLAGS=OPTIONS command line options for the C++ compiler [${CXXFLAGS}]"
echo " CXXFLAGS+=OPTIONS append options to the current value of CXXFLAGS"
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]"
echo
exit 0 ;;
@ -93,10 +94,11 @@ while [ $# != 0 ] ; do
--mandir=*) mandir=${optarg} ;;
--no-create) no_create=yes ;;
CXX=*) CXX=${optarg} ;;
CPPFLAGS=*) CPPFLAGS=${optarg} ;;
CXXFLAGS=*) CXXFLAGS=${optarg} ;;
LDFLAGS=*) LDFLAGS=${optarg} ;;
CXX=*) CXX=${optarg} ;;
CPPFLAGS=*) CPPFLAGS=${optarg} ;;
CXXFLAGS=*) CXXFLAGS=${optarg} ;;
CXXFLAGS+=*) CXXFLAGS="${CXXFLAGS} ${optarg}" ;;
LDFLAGS=*) LDFLAGS=${optarg} ;;
--*)
echo "configure: WARNING: unrecognized option: '${option}'" 1>&2 ;;
@ -168,7 +170,7 @@ echo "LDFLAGS = ${LDFLAGS}"
rm -f Makefile
cat > Makefile << EOF
# Makefile for Lzd - Educational decompressor for the lzip format
# Copyright (C) 2013-2017 Antonio Diaz Diaz.
# Copyright (C) 2013-2019 Antonio Diaz Diaz.
# This file was generated automatically by configure. Don't edit.
#
# This Makefile is free software: you have unlimited permission

126
lzd.cc
View file

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

View file

@ -1,6 +1,6 @@
#! /bin/sh
# check script for Lzd - Educational decompressor for lzip files
# Copyright (C) 2013-2017 Antonio Diaz Diaz.
# check script for Lzd - Educational decompressor for the lzip format
# Copyright (C) 2013-2019 Antonio Diaz Diaz.
#
# This script is free software: you have unlimited permission
# to copy, distribute and modify it.
@ -60,12 +60,14 @@ if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null &&
else
printf "\nwarning: skipping truncation test: 'dd' does not work on your system."
fi
rm -f in2.lz in3.lz trunc.lz out || framework_failure
cat "${in_lz}" > ingin.lz || framework_failure
printf "g" >> ingin.lz || framework_failure
cat "${in_lz}" >> ingin.lz || framework_failure
"${LZIP}" < ingin.lz > copy || test_failed $LINENO
cmp "${in}" copy || test_failed $LINENO
rm -f copy ingin.lz || framework_failure
echo
if [ ${fail} = 0 ] ; then