1
0
Fork 0
mirror of https://git.tukaani.org/xz.git synced 2024-04-04 12:36:23 +02:00

Update the code to mostly match the new simpler file format

specification. Simplify things by removing most of the
support for known uncompressed size in most places.
There are some miscellaneous changes here and there too.

The API of liblzma has got many changes and still some
more will be done soon. While most of the code has been
updated, some things are not fixed (the command line tool
will choke with invalid filter chain, if nothing else).

Subblock filter is somewhat broken for now. It will be
updated once the encoded format of the Subblock filter
has been decided.
This commit is contained in:
Lasse Collin 2008-06-18 18:02:10 +03:00
parent bf6348d1a3
commit 7d17818cec
109 changed files with 4800 additions and 8110 deletions

View file

@ -26,7 +26,7 @@ AC_PREREQ(2.61)
# [LZMA] instead of [LZMA utils] since I prefer to have lzma-version.tar.gz
# instead of lzma-utils-version.tar.gz.
AC_INIT([LZMA], [4.999.3alpha], [lasse.collin@tukaani.org])
AC_INIT([LZMA], [4.999.5alpha], [lasse.collin@tukaani.org])
AC_CONFIG_SRCDIR([src/liblzma/common/common.h])
AC_CONFIG_HEADER([config.h])
@ -86,12 +86,12 @@ AM_CONDITIONAL(COND_MAIN_DECODER, test "x$enable_decoder" = xyes)
# Filters
AC_MSG_CHECKING([which filters to build])
AC_ARG_ENABLE(filters, AC_HELP_STRING([--enable-filters=],
AC_ARG_ENABLE(filters, AC_HELP_STRING([--enable-filters=LIST],
[Comma-separated list of filters to build. Default=all.
Filters used in encoding are needed also in decoding.
Available filters: copy subblock x86 powerpc ia64
arm armthumb sparc delta lzma]),
[], [enable_filters=copy,subblock,x86,powerpc,ia64,arm,armthumb,sparc,delta,lzma])
[], [enable_filters=copy,subblock,x86,powerpc,ia64,arm,armthumb,sparc,delta,lzma])
enable_filters=`echo "$enable_filters" | sed 's/,/ /g'`
enable_filters_copy=no
enable_filters_subblock=no
@ -203,7 +203,7 @@ AM_CONDITIONAL(COND_MAIN_SIMPLE, test "x$enable_simple_filters" = xyes)
# Which match finders should be enabled:
AC_MSG_CHECKING([which match finders to build])
AC_ARG_ENABLE(match-finders, AC_HELP_STRING([--enable-match-finders=],
AC_ARG_ENABLE(match-finders, AC_HELP_STRING([--enable-match-finders=LIST],
[Comma-separated list of match finders to build. Default=all.
At least one match finder is required for encoding with
the LZMA filter.
@ -242,10 +242,10 @@ AM_CONDITIONAL(COND_MF_BT4, test "x$enable_match_finders_bt4" = xyes)
# Which integrity checks to build
AC_MSG_CHECKING([which integrity checks to build])
AC_ARG_ENABLE(checks, AC_HELP_STRING([--enable-checks=],
AC_ARG_ENABLE(checks, AC_HELP_STRING([--enable-checks=LIST],
[Comma-separated list of integrity checks to build.
Default=all. Available integrity checks: crc32 crc64 sha256]),
[], [enable_checks=crc32,crc64,sha256])
[], [enable_checks=crc32,crc64,sha256])
enable_checks=`echo "$enable_checks" | sed 's/,/ /g'`
enable_checks_crc32=no
enable_checks_crc64=no
@ -294,7 +294,7 @@ AC_MSG_CHECKING([if assembler optimizations should be used])
AC_ARG_ENABLE(assembler, AC_HELP_STRING([--disable-assembler],
[Do not use assembler optimizations even if such exist
for the architecture.]),
[], [enable_assembler=yes])
[], [enable_assembler=yes])
if test "x$enable_assembler" = xyes; then
case $host_cpu in
i?86) enable_assembler=x86 ;;
@ -327,13 +327,38 @@ esac
AC_MSG_RESULT([$enable_assembler])
AM_CONDITIONAL(COND_ASM_X86, test "x$enable_assembler" = xx86)
# Fast unaligned memory access
AC_MSG_CHECKING([if unaligned memory access should be used])
AC_ARG_ENABLE(unaligned-access, AC_HELP_STRING([--enable-unaligned-access],
[Enable if the system supports *fast* unaligned memory access
with 16-bit and 32-bit integers. By default, this is enabled
only on x86, x86_64, and big endian PowerPC.]),
[], [enable_unaligned_access=auto])
if test "x$enable_unaligned_access" = xauto ; then
case $host_cpu in
i?86|x86_64|powerpc|powerpc64)
enable_unaligned_access=yes
;;
*)
enable_unaligned_access=no
;;
esac
fi
if test "x$enable_unaligned_access" = xyes ; then
AC_DEFINE([HAVE_FAST_UNALIGNED_ACCESS], [1], [Define to 1 if
the system supports fast unaligned memory access.])
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
# Size optimization
AC_MSG_CHECKING([if small size is preferred over speed])
AC_ARG_ENABLE(small, AC_HELP_STRING([--enable-small],
[Omit precomputed tables to make liblzma a few kilobytes
smaller. This will increase startup time of applications
slightly, because the tables need to be computed first.]),
[], [enable_small=no])
[], [enable_small=no])
if test "x$enable_small" = xyes; then
AC_DEFINE([HAVE_SMALL], 1, [Define to 1 if optimizing for size.])
elif test "x$enable_small" != xno; then

View file

@ -73,19 +73,13 @@ main(int argc, char **argv)
file_in = argc > 1 ? fopen(argv[1], "rb") : stdin;
// Config
lzma_options_stream opt_stream = {
.check = LZMA_CHECK_CRC32,
.has_crc32 = true,
.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
.alignment = 0,
};
opt_stream.filters[0].id = LZMA_VLI_VALUE_UNKNOWN;
opt_stream.metadata_filters[0].id = LZMA_VLI_VALUE_UNKNOWN;
opt_stream.header = NULL;
opt_stream.footer = NULL;
lzma_options_filter filters[LZMA_BLOCK_FILTERS_MAX + 1];
filters[0].id = LZMA_FILTER_SUBBLOCK;
filters[0].options = NULL;
filters[1].id = LZMA_VLI_VALUE_UNKNOWN;
// Init
if (lzma_stream_encoder_multi(&strm, &opt_stream) != LZMA_OK) {
if (lzma_stream_encoder(&strm, filters, LZMA_CHECK_CRC32) != LZMA_OK) {
fprintf(stderr, "init failed\n");
exit(1);
}

View file

@ -101,18 +101,13 @@ main(int argc, char **argv)
opt_subblock.subfilter_options.id = LZMA_FILTER_DELTA;
opt_subblock.subfilter_options.options = &opt_delta;
lzma_options_stream opt_stream = {
.check = LZMA_CHECK_NONE,
.has_crc32 = false,
.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
.alignment = 0,
};
opt_stream.filters[0].id = LZMA_FILTER_SUBBLOCK;
opt_stream.filters[0].options = &opt_subblock;
opt_stream.filters[1].id = LZMA_VLI_VALUE_UNKNOWN;
lzma_options_filter filters[LZMA_BLOCK_FILTERS_MAX + 1];
filters[0].id = LZMA_FILTER_LZMA;
filters[0].options = &opt_lzma;
filters[1].id = LZMA_VLI_VALUE_UNKNOWN;
// Init
if (lzma_stream_encoder_single(&strm, &opt_stream) != LZMA_OK) {
if (lzma_stream_encoder(&strm, filters, LZMA_CHECK_NONE) != LZMA_OK) {
fprintf(stderr, "init failed\n");
exit(1);
}

View file

@ -1,7 +1,7 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file check_byteswap.h
/// \brief Byteswapping needed by the checks
/// \file bswap.h
/// \brief Byte swapping
//
// This code has been put into the public domain.
//
@ -11,18 +11,19 @@
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_CHECK_BYTESWAP_H
#define LZMA_CHECK_BYTESWAP_H
#ifndef LZMA_BSWAP_H
#define LZMA_BSWAP_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
// NOTE: We assume that config.h is already #included.
// byteswap.h is a GNU extension. It contains inline assembly versions
// for byteswapping. When byteswap.h is not available, we use generic code.
#ifdef HAVE_BYTESWAP_H
# include <byteswap.h>
#else
# define bswap_16(num) \
(((num) << 8) | ((num) >> 8))
# define bswap_32(num) \
( (((num) << 24) ) \
| (((num) << 8) & UINT32_C(0x00FF0000)) \

167
src/common/integer.h Normal file
View file

@ -0,0 +1,167 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file integer.h
/// \brief Reading and writing integers from and to buffers
//
// This code has been put into the public domain.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_INTEGER_H
#define LZMA_INTEGER_H
// I'm aware of AC_CHECK_ALIGNED_ACCESS_REQUIRED from Autoconf archive, but
// it's not useful for us. We don't care if unaligned access is supported,
// we care if it is fast. Some systems can emulate unaligned access in
// software, which is horribly slow; we want to use byte-by-byte access on
// such systems but the Autoconf test would detect such a system as
// supporting unaligned access.
//
// NOTE: HAVE_FAST_UNALIGNED_ACCESS indicates only support for 16-bit and
// 32-bit integer loads and stores. 64-bit integers may or may not work.
// That's why 64-bit functions are commented out.
#ifdef HAVE_FAST_UNALIGNED_ACCESS
// On big endian, we need byte swapping.
//
// TODO: Big endian PowerPC supports byte swapping load and store instructions
// that also allow unaligned access. Inline assembler could be OK for that.
#ifdef WORDS_BIGENDIAN
# include "bswap.h"
# define integer_convert_16(n) bswap_16(n)
# define integer_convert_32(n) bswap_32(n)
# define integer_convert_64(n) bswap_64(n)
#else
# define integer_convert_16(n) (n)
# define integer_convert_32(n) (n)
# define integer_convert_64(n) (n)
#endif
static inline uint16_t
integer_read_16(const uint8_t buf[static 2])
{
uint16_t ret = *(const uint16_t *)(buf);
return integer_convert_16(ret);
}
static inline uint32_t
integer_read_32(const uint8_t buf[static 4])
{
uint32_t ret = *(const uint32_t *)(buf);
return integer_convert_32(ret);
}
/*
static inline uint64_t
integer_read_64(const uint8_t buf[static 8])
{
uint64_t ret = *(const uint64_t *)(buf);
return integer_convert_64(ret);
}
*/
static inline void
integer_write_16(uint8_t buf[static 2], uint16_t num)
{
*(uint16_t *)(buf) = integer_convert_16(num);
}
static inline void
integer_write_32(uint8_t buf[static 4], uint32_t num)
{
*(uint32_t *)(buf) = integer_convert_32(num);
}
/*
static inline void
integer_write_64(uint8_t buf[static 8], uint64_t num)
{
*(uint64_t *)(buf) = integer_convert_64(num);
}
*/
#else
static inline uint16_t
integer_read_16(const uint8_t buf[static 2])
{
uint16_t ret = buf[0] | (buf[1] << 8);
return ret;
}
static inline uint32_t
integer_read_32(const uint8_t buf[static 4])
{
uint32_t ret = buf[0];
ret |= (uint32_t)(buf[1]) << 8;
ret |= (uint32_t)(buf[2]) << 16;
ret |= (uint32_t)(buf[3]) << 24;
return ret;
}
/*
static inline uint64_t
integer_read_64(const uint8_t buf[static 8])
{
uint64_t ret = buf[0];
ret |= (uint64_t)(buf[1]) << 8;
ret |= (uint64_t)(buf[2]) << 16;
ret |= (uint64_t)(buf[3]) << 24;
ret |= (uint64_t)(buf[4]) << 32;
ret |= (uint64_t)(buf[5]) << 40;
ret |= (uint64_t)(buf[6]) << 48;
ret |= (uint64_t)(buf[7]) << 56;
return ret;
}
*/
static inline void
integer_write_16(uint8_t buf[static 2], uint16_t num)
{
buf[0] = (uint8_t)(num);
buf[1] = (uint8_t)(num >> 8);
}
static inline void
integer_write_32(uint8_t buf[static 4], uint32_t num)
{
buf[0] = (uint8_t)(num);
buf[1] = (uint8_t)(num >> 8);
buf[2] = (uint8_t)(num >> 16);
buf[3] = (uint8_t)(num >> 24);
}
/*
static inline void
integer_write_64(uint8_t buf[static 8], uint64_t num)
{
buf[0] = (uint8_t)(num);
buf[1] = (uint8_t)(num >> 8);
buf[2] = (uint8_t)(num >> 16);
buf[3] = (uint8_t)(num >> 24);
buf[4] = (uint8_t)(num >> 32);
buf[5] = (uint8_t)(num >> 40);
buf[6] = (uint8_t)(num >> 48);
buf[7] = (uint8_t)(num >> 56);
}
*/
#endif
#endif

View file

@ -20,17 +20,14 @@ nobase_include_HEADERS = \
lzma/base.h \
lzma/block.h \
lzma/check.h \
lzma/copy.h \
lzma/delta.h \
lzma/easy.h \
lzma/extra.h \
lzma/filter.h \
lzma/index.h \
lzma/info.h \
lzma/index_hash.h \
lzma/init.h \
lzma/lzma.h \
lzma/memlimit.h \
lzma/metadata.h \
lzma/raw.h \
lzma/simple.h \
lzma/stream.h \

View file

@ -96,17 +96,13 @@ extern "C" {
#include "lzma/check.h"
/* Filters */
#include "lzma/copy.h"
#include "lzma/subblock.h"
#include "lzma/simple.h"
#include "lzma/delta.h"
#include "lzma/lzma.h"
/* Container formats and Metadata */
/* Container formats */
#include "lzma/block.h"
#include "lzma/index.h"
#include "lzma/extra.h"
#include "lzma/metadata.h"
#include "lzma/stream.h"
#include "lzma/alone.h"
#include "lzma/raw.h"
@ -114,7 +110,8 @@ extern "C" {
#include "lzma/easy.h"
/* Advanced features */
#include "lzma/info.h"
#include "lzma/index.h"
#include "lzma/index_hash.h"
#include "lzma/alignment.h"
#include "lzma/stream_flags.h"
#include "lzma/memlimit.h"

View file

@ -21,36 +21,6 @@
#endif
/**
* \brief Options for files in the LZMA_Alone format
*/
typedef struct {
/**
* \brief Uncompressed Size and usage of End of Payload Marker
*
* In contrast to .lzma Blocks, LZMA_Alone format cannot have both
* uncompressed size field in the header and end of payload marker.
* If you don't know the uncompressed size beforehand, set it to
* LZMA_VLI_VALUE_UNKNOWN and liblzma will embed end of payload
* marker.
*/
lzma_vli uncompressed_size;
/**
* \brief LZMA options
*
* The LZMA_Alone format supports only one filter: the LZMA filter.
*
* \note There exists also an undocumented variant of the
* LZMA_Alone format, which uses the x86 filter in
* addition to LZMA. This format was never supported
* by LZMA Utils and is not supported by liblzma either.
*/
lzma_options_lzma lzma;
} lzma_options_alone;
/**
* \brief Initializes LZMA_Alone encoder
*
@ -68,7 +38,7 @@ typedef struct {
* - LZMA_PROG_ERROR
*/
extern lzma_ret lzma_alone_encoder(
lzma_stream *strm, const lzma_options_alone *options);
lzma_stream *strm, const lzma_options_lzma *options);
/**

View file

@ -29,13 +29,8 @@
* the type of the file has been detected.
*
* \param strm Pointer to propertily prepared lzma_stream
* \param header Pointer to hold a pointer to Extra Records read
* from the Header Metadata Block. Use NULL if
* you don't care about Extra Records.
* \param footer Same as header, but for Footer Metadata Block.
*
* \return - LZMA_OK: Initialization was successful.
* - LZMA_MEM_ERROR: Cannot allocate memory.
*/
extern lzma_ret lzma_auto_decoder(lzma_stream *strm,
lzma_extra **header, lzma_extra **footer);
extern lzma_ret lzma_auto_decoder(lzma_stream *strm);

View file

@ -128,6 +128,21 @@ typedef enum {
* In the decoder, this is only a warning and decoding can
* still proceed normally (but the Check is ignored).
*/
LZMA_FORMAT_ERROR = -8,
/**<
* \brief Unknown file format
*/
LZMA_MEMLIMIT_ERROR = -9
/**
* \brief Memory usage limit was reached
*
* Decoder would need more memory than allowed by the
* specified memory usage limit. To continue decoding,
* the memory usage limit has to be increased. See functions
* lzma_memlimit_get() and lzma_memlimit_set().
*/
} lzma_ret;

View file

@ -32,6 +32,21 @@
* later calls to lzma_code().
*/
typedef struct {
/**
* \brief Size of the Block Header
*
* Read by:
* - lzma_block_encoder()
* - lzma_block_decoder()
*
* Written by:
* - lzma_block_header_size()
* - lzma_block_header_decode()
*/
uint32_t header_size;
# define LZMA_BLOCK_HEADER_SIZE_MIN 8
# define LZMA_BLOCK_HEADER_SIZE_MAX 1024
/**
* \brief Type of integrity Check
*
@ -44,85 +59,6 @@ typedef struct {
*/
lzma_check_type check;
/**
* \brief Precense of CRC32 of the Block Header
*
* Set this to true if CRC32 of the Block Header should be
* calculated and stored in the Block Header.
*
* There is no way to autodetect if CRC32 is present in the Block
* Header, thus this information must be provided also when decoding.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encoder()
* - lzma_block_header_decoder()
*/
lzma_bool has_crc32;
/**
* \brief Usage of End of Payload Marker
*
* If this is true, End of Payload Marker is used even if
* Uncompressed Size is known.
*
* Read by:
* - lzma_block_header_encoder()
* - lzma_block_encoder()
* - lzma_block_decoder()
*
* Written by:
* - lzma_block_header_decoder()
*/
lzma_bool has_eopm;
/**
* \brief True if the Block is a Metadata Block
*
* If this is true, the Metadata bit will be set in the Block Header.
* It is up to the application to store correctly formatted data
* into Metadata Block.
*
* Read by:
* - lzma_block_header_encoder()
*
* Written by:
* - lzma_block_header_decoder()
*/
lzma_bool is_metadata;
/**
* \brief True if Uncompressed Size is in Block Footer
*
* Read by:
* - lzma_block_encoder()
* - lzma_block_decoder()
*/
lzma_bool has_uncompressed_size_in_footer;
/**
* \brief True if Backward Size is in Block Footer
*
* Read by:
* - lzma_block_encoder()
* - lzma_block_decoder()
*/
lzma_bool has_backward_size;
/**
* \brief True if Block coder should take care of Padding
*
* In liblzma, Stream decoder sets this to true when decoding
* Header Metadata Block or Data Blocks from Multi-Block Stream,
* and to false when decoding Single-Block Stream or Footer
* Metadata Block from a Multi-Block Stream.
*
* Read by:
* - lzma_block_encoder()
* - lzma_block_decoder()
*/
lzma_bool handle_padding;
/**
* \brief Size of the Compressed Data in bytes
*
@ -134,12 +70,12 @@ typedef struct {
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encoder()
* - lzma_block_header_encode()
* - lzma_block_encoder()
* - lzma_block_decoder()
*
* Written by:
* - lzma_block_header_decoder()
* - lzma_block_header_decode()
* - lzma_block_encoder()
* - lzma_block_decoder()
*/
@ -163,167 +99,61 @@ typedef struct {
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encoder()
* - lzma_block_header_encode()
* - lzma_block_encoder()
* - lzma_block_decoder()
*
* Written by:
* - lzma_block_header_decoder()
* - lzma_block_header_decode()
* - lzma_block_encoder()
* - lzma_block_decoder()
*/
lzma_vli uncompressed_size;
/**
* \brief Number of bytes to reserve for Compressed Size
*
* This is useful if you want to be able to store the Compressed Size
* to the Block Header, but you don't know it when starting to encode.
* Setting this to non-zero value at maximum of LZMA_VLI_BYTES_MAX,
* the Block Header encoder will force the Compressed Size field to
* occupy specified number of bytes. You can later rewrite the Block
* Header to contain correct information by using otherwise identical
* lzma_options_block structure except the correct compressed_size.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encoder()
*
* Written by:
* - lzma_block_header_decoder()
*/
uint32_t compressed_reserve;
/**
* \brief Number of bytes to reserve for Uncompressed Size
*
* See the description of compressed_size above.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encoder()
*
* Written by:
* - lzma_block_header_decoder()
*/
uint32_t uncompressed_reserve;
/**
* \brief Total Size of the Block in bytes
*
* This is useful in the decoder, which can verify the Total Size
* if it is known from Index.
*
* Read by:
* - lzma_block_encoder()
* - lzma_block_decoder()
*
* Written by:
* - lzma_block_encoder()
* - lzma_block_decoder()
*/
lzma_vli total_size;
/**
* \brief Upper limit of Total Size
*
* Read by:
* - lzma_block_encoder()
* - lzma_block_decoder()
*/
lzma_vli total_limit;
/**
* \brief Upper limit of Uncompressed Size
*
* Read by:
* - lzma_block_encoder()
* - lzma_block_decoder()
*/
lzma_vli uncompressed_limit;
/**
* \brief Array of filters
*
* There can be at maximum of seven filters. The end of the array
* is marked with .id = LZMA_VLI_VALUE_UNKNOWN. Minimum number of
* filters is zero; in that case, an implicit Copy filter is used.
* There can be 1-4 filters. The end of the array is marked with
* .id = LZMA_VLI_VALUE_UNKNOWN.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encoder()
* - lzma_block_header_encode()
* - lzma_block_encoder()
* - lzma_block_decoder()
*
* Written by:
* - lzma_block_header_decoder(): Note that this does NOT free()
* the old filter options structures. If decoding fails, the
* caller must take care of freeing the options structures
* that may have been allocated and decoded before the error
* occurred.
* - lzma_block_header_decode(): Note that this does NOT free()
* the old filter options structures. All unused filters[] will
* have .id == LZMA_VLI_VALUE_UNKNOWN and .options == NULL. If
* decoding fails, all filters[] are guaranteed to be
* LZMA_VLI_VALUE_UNKNOWN and NULL.
*
* \note Because of the array is terminated with
* .id = LZMA_VLI_VALUE_UNKNOWN, the actual array must
* have LZMA_BLOCK_FILTERS_MAX + 1 members or the Block
* Header decoder will overflow the buffer.
*/
lzma_options_filter filters[8];
/**
* \brief Size of the Padding field
*
* The Padding field exist to allow aligning the Compressed Data field
* optimally in the Block. See lzma_options_stream.alignment in
* stream.h for more information.
*
* If you want the Block Header encoder to automatically calculate
* optimal size for the Padding field by looking at the information
* in filters[], set this to LZMA_BLOCK_HEADER_PADDING_AUTO. In that
* case, you must also set the aligmnet variable to tell the the
* encoder the aligmnet of the beginning of the Block Header.
*
* The decoder never sets this to LZMA_BLOCK_HEADER_PADDING_AUTO.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encoder(): Note that this doesn't
* accept LZMA_BLOCK_HEADER_PADDING_AUTO.
*
* Written by (these never set padding to
* LZMA_BLOCK_HEADER_PADDING_AUTO):
* - lzma_block_header_size()
* - lzma_block_header_decoder()
*/
int32_t padding;
# define LZMA_BLOCK_HEADER_PADDING_AUTO (-1)
# define LZMA_BLOCK_HEADER_PADDING_MIN 0
# define LZMA_BLOCK_HEADER_PADDING_MAX 31
/**
* \brief Alignment of the beginning of the Block Header
*
* This variable is read only if padding has been set to
* LZMA_BLOCK_HEADER_PADDING_AUTO.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encoder()
*/
uint32_t alignment;
/**
* \brief Size of the Block Header
*
* Read by:
* - lzma_block_encoder()
* - lzma_block_decoder()
*
* Written by:
* - lzma_block_header_size()
* - lzma_block_header_decoder()
*/
uint32_t header_size;
lzma_options_filter *filters;
# define LZMA_BLOCK_FILTERS_MAX 4
} lzma_options_block;
/**
* \brief Calculates the size of Header Padding and Block Header
* \brief Decodes the Block Header Size field
*
* To decode Block Header using lzma_block_header_decode(), the size of the
* Block Header has to be known and stored into lzma_options_block.header_size.
* The size can be calculated from the first byte of a Block using this macro.
* Note that if the first byte is 0x00, it indicates beginning of Index; use
* this macro only when the byte is not 0x00.
*/
#define lzma_block_header_size_decode(b) (((uint32_t)(b) + 1) * 4)
/**
* \brief Calculates the size of Block Header
*
* \return - LZMA_OK: Size calculated successfully and stored to
* options->header_size.
@ -353,24 +183,62 @@ extern lzma_ret lzma_block_header_size(lzma_options_block *options);
* - LZMA_PROG_ERROR
*/
extern lzma_ret lzma_block_header_encode(
uint8_t *out, const lzma_options_block *options);
const lzma_options_block *options, uint8_t *out);
/**
* \brief Initializes Block Header decoder
* \brief Decodes Block Header
*
* Because the results of this decoder are placed into *options,
* strm->next_in, strm->avail_in, and strm->total_in are not used.
* Decoding of the Block options is done with a single call instead of
* first initializing and then doing the actual work with lzma_code().
*
* The only valid `action' with lzma_code() is LZMA_RUN.
* \param options Destination for block options
* \param allocator lzma_allocator for custom allocator functions.
* Set to NULL to use malloc().
* \param in Beginning of the input buffer. This must be
* at least options->header_size bytes.
*
* \return - LZMA_OK: Encoding was successful. options->header_size
* \return - LZMA_OK: Decoding was successful. options->header_size
* bytes were written to output buffer.
* - LZMA_HEADER_ERROR: Invalid or unsupported options.
* - LZMA_PROG_ERROR
*/
extern lzma_ret lzma_block_header_decoder(
lzma_stream *strm, lzma_options_block *options);
extern lzma_ret lzma_block_header_decode(lzma_options_block *options,
lzma_allocator *allocator, const uint8_t *in);
/**
* \brief Sets Compressed Size according to Total Size
*
* Block Header stores Compressed Size, but Index has Total Size. If the
* application has already parsed the Index and is now decoding Blocks,
* it can calculate Compressed Size from Total Size. This function does
* exactly that with error checking, so application doesn't need to check,
* for example, if the value in Index is too small to contain even the
* Block Header. Note that you need to call this function after decoding
* the Block Header field.
*
* \return - LZMA_OK: options->compressed_size was set successfully.
* - LZMA_DATA_ERROR: total_size is too small compared to
* options->header_size and lzma_check_sizes[options->check].
* - LZMA_PROG_ERROR: Some values are invalid. For example,
* total_size and options->header_size must be multiples
* of four, total_size must be at least 12, and
* options->header_size between 8 and 1024 inclusive.
*/
extern lzma_ret lzma_block_total_size_set(
lzma_options_block *options, lzma_vli total_size);
/**
* \brief Calculates Total Size
*
* This function can be useful after decoding a Block to get Total Size
* that is stored in Index.
*
* \return Total Size on success, or zero on error.
*/
extern lzma_vli lzma_block_total_size_get(const lzma_options_block *options);
/**

View file

@ -43,14 +43,14 @@ typedef enum {
* Size of the Check field: 4 bytes
*/
LZMA_CHECK_CRC64 = 3,
LZMA_CHECK_CRC64 = 4,
/**<
* CRC64 using the polynomial from the ECMA-182 standard
*
* Size of the Check field: 8 bytes
*/
LZMA_CHECK_SHA256 = 5
LZMA_CHECK_SHA256 = 10
/**<
* SHA-256
*
@ -62,7 +62,7 @@ typedef enum {
/**
* \brief Maximum valid Check ID
*
* The .lzma file format specification specifies eight Check IDs (0-7). Some
* The .lzma file format specification specifies eight Check IDs (0-15). Some
* of them are only reserved i.e. no actual Check algorithm has been assigned.
* Still liblzma accepts any of these eight IDs for future compatibility
* when decoding files. If a valid but unsupported Check ID is detected,
@ -70,7 +70,7 @@ typedef enum {
*
* FIXME bad desc
*/
#define LZMA_CHECK_ID_MAX 7
#define LZMA_CHECK_ID_MAX 15
/**
@ -89,12 +89,18 @@ extern const lzma_bool lzma_available_checks[LZMA_CHECK_ID_MAX + 1];
* Although not all Check IDs have a check algorithm associated, the size of
* every Check is already frozen. This array contains the size (in bytes) of
* the Check field with specified Check ID. The values are taken from the
* section 2.2.2 of the .lzma file format specification:
* { 0, 4, 4, 8, 16, 32, 32, 64 }
* section 2.1.1.2 of the .lzma file format specification:
* { 0, 4, 4, 4, 8, 8, 8, 16, 16, 16, 32, 32, 32, 64, 64, 64 }
*/
extern const uint32_t lzma_check_sizes[LZMA_CHECK_ID_MAX + 1];
/**
* \brief Maximum size of a Check field
*/
#define LZMA_CHECK_SIZE_MAX 64
/**
* \brief Calculate CRC32
*

View file

@ -1,29 +0,0 @@
/**
* \file lzma/copy.h
* \brief Copy filter
*
* \author Copyright (C) 1999-2006 Igor Pavlov
* \author Copyright (C) 2007 Lasse Collin
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Filter ID
*
* Filter ID of the Copy filter. This is used as lzma_options_filter.id.
*/
#define LZMA_FILTER_COPY LZMA_VLI_C(0x00)

View file

@ -69,7 +69,7 @@ typedef enum {
/**
* \brief Default compression level for Data Blocks
* \brief Default compression level
*
* Data Blocks contain the actual compressed data. It's not straightforward
* to recommend a default level, because in some cases keeping the resource
@ -79,16 +79,6 @@ typedef enum {
#define LZMA_EASY_DEFAULT LZMA_EASY_LZMA_7
/**
* \brief Default compression level for Metadata Blocks
*
* Metadata Blocks are present only in Multi-Block Streams. Metadata Blocks
* contain the Extra Records (if any) and some book-keeping data that is
* used by decoders.
*/
#define LZMA_EASY_METADATA_DEFAULT LZMA_EASY_LZMA_3
/**
* \brief Calculates rough memory requirements of a compression level
*
@ -104,11 +94,11 @@ extern uint32_t lzma_easy_memory_usage(lzma_easy_level level);
/**
* \brief Initializes Single-Block .lzma Stream encoder
* \brief Initializes .lzma Stream encoder
*
* This function is intended for those who just want to use the basic LZMA
* features (that is, most developers out there). Lots of assumptions are
* made, which are correct for most situations or at least good enough.
* made, which are correct or at least good enough for most situations.
*
* \param strm Pointer to lzma_stream that is at least initialized
* with LZMA_STREAM_INIT.
@ -125,50 +115,7 @@ extern uint32_t lzma_easy_memory_usage(lzma_easy_level level);
*
* If initialization succeeds, use lzma_code() to do the actual encoding.
* Valid values for `action' (the second argument of lzma_code()) are
* LZMA_RUN, LZMA_SYNC_FLUSH, and LZMA_FINISH. In future, there may be
* compression levels that don't support LZMA_SYNC_FLUSH.
*/
extern lzma_ret lzma_easy_encoder_single(
lzma_stream *strm, lzma_easy_level level);
/**
* \brief Initializes Multi-Block .lzma Stream encoder
*
* If you want to be able to store Extra Records or want to be able to use
* LZMA_FULL_FLUSH, you need to create a Multi-Block Stream.
*
* \param strm Pointer to lzma_stream that is at least initialized
* with LZMA_STREAM_INIT.
* \param level Compression level to use for the data being encoded.
* \param metadata_level
* Compression level to use for Metadata Blocks.
* Metadata Blocks contain the Extra Records (if any)
* and some book-keeping data that is used by decoders.
* \param header Pointer to a list of Extra Records to be stored to
* the Header Metadata Block. Set this to NULL to omit
* Header Metadata Block completely. The list must be
* kept available until the encoding has finished.
* \param footer Pointer to a list of Extra Records to be stored to
* the Footer Metadata Block. Set this to NULL if you
* don't want to store any Extra Records (the Footer
* Metadata Block will still be written for other
* reasons.) The list must be kept available until
* the encoding has finished.
*
* \return - LZMA_OK: Initialization succeeded. Use lzma_code() to
* encode your data.
* - LZMA_MEM_ERROR: Memory allocation failed. All memory
* previously allocated for *strm is now freed.
* - LZMA_HEADER_ERROR: The given compression level is not
* supported by this build of liblzma.
*
* If initialization succeeds, use lzma_code() to do the actual encoding.
* Valid values for `action' (the second argument of lzma_code()) are
* LZMA_RUN, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, and LZMA_FINISH. In future,
* there may be compression levels that don't support LZMA_SYNC_FLUSH.
* LZMA_FULL_FLUSH will always work with all compression levels.
*/
extern lzma_ret lzma_easy_encoder_multi(lzma_stream *strm,
lzma_easy_level level, lzma_easy_level metadata_level,
const lzma_extra *header, const lzma_extra *footer);
extern lzma_ret lzma_easy_encoder(lzma_stream *strm, lzma_easy_level level);

View file

@ -1,114 +0,0 @@
/**
* \file lzma/extra.h
* \brief Handling of Extra Records in Metadata
*
* \author Copyright (C) 1999-2006 Igor Pavlov
* \author Copyright (C) 2007 Lasse Collin
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/*
* Extra Record IDs
*
* See the .lzma file format specification for description what each
* Extra Record type exactly means.
*
* If you ever need to update .lzma files with Extra Records, note that
* the Record IDs are divided in two categories:
* - Safe-to-Copy Records may be preserved as is when the
* Stream is modified in ways that don't change the actual
* uncompressed data. Examples of such operatings include
* recompressing and adding, modifying, or deleting unrelated
* Extra Records.
* - Unsafe-to-Copy Records should be removed (and possibly
* recreated) when any kind of changes are made to the Stream.
*/
#define LZMA_EXTRA_PADDING 0x00
#define LZMA_EXTRA_OPENPGP 0x01
#define LZMA_EXTRA_FILTERS 0x02
#define LZMA_EXTRA_COMMENT 0x03
#define LZMA_EXTRA_CHECKS 0x04
#define LZMA_EXTRA_FILENAME 0x05
#define LZMA_EXTRA_MTIME 0x07
#define LZMA_EXTRA_MTIME_HR 0x09
#define LZMA_EXTRA_MIME_TYPE 0x0B
#define LZMA_EXTRA_HOMEPAGE 0x0D
/**
* \brief Extra Records
*
* The .lzma format provides a way to store custom information along
* the actual compressed content. Information about these Records
* are passed to and from liblzma via this linked list.
*/
typedef struct lzma_extra_s lzma_extra;
struct lzma_extra_s {
/**
* \brief Pointer to the next Extra Record
*
* This is NULL on the last Extra Record.
*/
lzma_extra *next;
/**
* \brief Record ID
*
* Extra Record IDs are divided in three categories:
* - Zero is a special case used for padding. It doesn't have
* Size of Data fields.
* - Odd IDs (1, 3, 5, ...) are Safe-to-Copy IDs.
* These can be preserved as is if the Stream is
* modified in a way that doesn't alter the actual
* uncompressed content.
* - Even IDs (2, 4, 6, ...) are Unsafe-to-Copy IDs.
* If the .lzma Stream is modified in any way,
* the Extra Records having a sensitive ID should
* be removed or updated accordingly.
*
* Refer to the .lzma file format specification for
* the up to date list of Extra Record IDs.
*/
lzma_vli id;
/**
* \brief Size of the Record data
*
* In case of strings, this should not include the
* trailing '\0'.
*/
size_t size;
/**
* \brief Record data
*
* Record data is often a string in UTF-8 encoding,
* but it can be arbitrary binary data. In case of
* strings, the trailing '\0' is usually not stored
* in the .lzma file.
*
* To ease working with Extra Records containing strings,
* liblzma always adds '\0' to the end of data even when
* it wasn't present in the .lzma file. This '\0' is not
* counted in the size of the data.
*/
uint8_t *data;
};
extern void lzma_extra_free(lzma_extra *extra, lzma_allocator *allocator);

View file

@ -162,5 +162,6 @@ extern lzma_ret lzma_filter_flags_encode(uint8_t *out, size_t *out_pos,
* - LZMA_MEM_ERROR
* - LZMA_PROG_ERROR
*/
extern lzma_ret lzma_filter_flags_decoder(
lzma_stream *strm, lzma_options_filter *options);
extern lzma_ret lzma_filter_flags_decode(
lzma_options_filter *options, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos, size_t in_size);

View file

@ -22,63 +22,211 @@
/**
* \brief
*
* FIXME desc
* \brief Opaque data type to hold the Index
*/
typedef struct lzma_index_s lzma_index;
struct lzma_index_s {
/**
* \brief Index Record and its location
*/
typedef struct {
/**
* \brief Total Size of the Block
*
* This includes Block Header, Compressed Data, and Block Footer.
* Total Size of a Block.
*/
lzma_vli total_size;
/**
* \brief Uncompressed Size of the Block
* Uncompressed Size of a Block
*/
lzma_vli uncompressed_size;
/**
* \brief Pointer to the next Index Record
*
* This is NULL on the last Index Record.
* Offset of the first byte of a Block relative to the beginning
* of the Stream, or if there are multiple Indexes combined,
* relative to the beginning of the first Stream.
*/
lzma_index *next;
};
lzma_vli stream_offset;
/**
* Uncompressed offset
*/
lzma_vli uncompressed_offset;
} lzma_index_record;
/**
* \brief Allocate and initialize a new lzma_index structure
*
* If i is NULL, a new lzma_index structure is allocated, initialized,
* and a pointer to it returned. If allocation fails, NULL is returned.
*
* If i is non-NULL, it is reinitialized and the same pointer returned.
* In this case, return value cannot be NULL or a different pointer than
* the i given as argument.
*/
extern lzma_index *lzma_index_init(lzma_index *i, lzma_allocator *allocator);
/**
* \brief Deallocate the Index
*/
extern void lzma_index_end(lzma_index *i, lzma_allocator *allocator);
/**
* \brief Add a new Record to an Index
*
* \param index Pointer to a lzma_index structure
* \param total_size Total Size of a Block
* \param uncompressed_size Uncompressed Size of a Block, or
* LZMA_VLI_VALUE_UNKNOWN to indicate padding.
*
* Appending a new Record does not affect the read position.
*
* \return - LZMA_OK
* - LZMA_DATA_ERROR: Compressed or uncompressed size of the
* Stream or size of the Index field would grow too big.
* - LZMA_PROG_ERROR
*/
extern lzma_ret lzma_index_append(lzma_index *i, lzma_allocator *allocator,
lzma_vli total_size, lzma_vli uncompressed_size);
/**
* \brief Get the number of Records
*/
extern lzma_vli lzma_index_count(const lzma_index *i);
/**
* \brief Get the size of the Index field as bytes
*
* This is needed to verify the Index Size field from the Stream Footer.
*/
extern lzma_vli lzma_index_size(const lzma_index *i);
/**
* \brief Get the total size of the Blocks
*
* This doesn't include the Stream Header, Stream Footer, Stream Padding,
* or Index fields.
*/
extern lzma_vli lzma_index_total_size(const lzma_index *i);
/**
* \brief Get the total size of the Stream
*
* If multiple Indexes have been combined, this works as if the Blocks
* were in a single Stream.
*/
extern lzma_vli lzma_index_stream_size(const lzma_index *i);
/**
* \brief Get the total size of the file
*
* When no Indexes have been combined with lzma_index_cat(), this function is
* identical to lzma_index_stream_size(). If multiple Indexes have been
* combined, this includes also the possible Stream Padding fields.
*/
extern lzma_vli lzma_index_file_size(const lzma_index *i);
/**
* \brief Get the uncompressed size of the Stream
*/
extern lzma_vli lzma_index_uncompressed_size(const lzma_index *i);
/**
* \brief Get the next Record from the Index
*/
extern lzma_bool lzma_index_read(lzma_index *i, lzma_index_record *record);
/**
* \brief Rewind the Index
*
* Rewind the Index so that next call to lzma_index_read() will return the
* first Record.
*/
extern void lzma_index_rewind(lzma_index *i);
/**
* \brief Locate a Record
*
* When the Index is available, it is possible to do random-access reading
* with granularity of Block size.
*
* \param i Pointer to lzma_index structure
* \param record Pointer to a structure to hold the search results
* \param target Uncompressed target offset
*
* If the target is smaller than the uncompressed size of the Stream (can be
* checked with lzma_index_uncompressed_size()):
* - Information about the Record containing the requested uncompressed
* offset is stored into *record.
* - Read offset will be adjusted so that calling lzma_index_read() can be
* used to read subsequent Records.
* - This function returns false.
*
* If target is greater than the uncompressed size of the Stream, *record
* and the read position are not modified, and this function returns true.
*/
extern lzma_bool lzma_index_locate(
lzma_index *i, lzma_index_record *record, lzma_vli target);
/**
* \brief Concatenate Indexes of two Streams
*
*
*
* \param dest Destination Index after which src is appended Source
* \param src Index. The memory allocated for this is either moved
* to be part of *dest or freed iff the function call