Bunch of liblzma tweaks, including some API changes.

The API and ABI should now be very close to stable,
although the code behind it isn't yet.
This commit is contained in:
Lasse Collin 2008-12-27 19:27:49 +02:00
parent 4d00652e75
commit e33194e79d
23 changed files with 294 additions and 262 deletions

View File

@ -127,12 +127,12 @@
#endif /* ifdef LZMA_MANUAL_HEADERS */ #endif /* ifdef LZMA_MANUAL_HEADERS */
/****************** /********************
* GCC extensions * * GNU C extensions *
******************/ ********************/
/* /*
* GCC extensions are used conditionally in the public API. It doesn't * GNU C extensions are used conditionally in the public API. It doesn't
* break anything if these are sometimes enabled and sometimes not, only * break anything if these are sometimes enabled and sometimes not, only
* affects warnings and optimizations. * affects warnings and optimizations.
*/ */

View File

@ -32,6 +32,35 @@
* later calls to lzma_code(). * later calls to lzma_code().
*/ */
typedef struct { typedef struct {
/**
* \brief Block format version
*
* To prevent API and ABI breakages if new features are needed in
* Block, a version number is used to indicate which fields in this
* structure are in use. For now, version must always be zero.
* With non-zero version, most Block related functions will return
* LZMA_OPTIONS_ERROR.
*
* The decoding functions will always set this to the lowest value
* that supports all the features indicated by the Block Header field.
* The application must check that the version number set by the
* decoding functions is supported by the application. Otherwise it
* is possible that the application will decode the Block incorrectly.
*
* Read by:
* - lzma_block_header_size()
* - lzma_block_header_encode()
* - lzma_block_compressed_size()
* - lzma_block_unpadded_size()
* - lzma_block_total_size()
* - lzma_block_encoder()
* - lzma_block_decoder()
*
* Written by:
* - lzma_block_header_decode()
*/
uint32_t version;
/** /**
* \brief Size of the Block Header field * \brief Size of the Block Header field
* *
@ -168,6 +197,37 @@ typedef struct {
*/ */
lzma_filter *filters; lzma_filter *filters;
/*
* Reserved space to allow possible future extensions without
* breaking the ABI. You should not touch these, because the names
* of these variables may change. These are and will never be used
* with the currently supported options, so it is safe to leave these
* uninitialized.
*/
void *reserved_ptr1;
void *reserved_ptr2;
void *reserved_ptr3;
uint32_t reserved_int1;
uint32_t reserved_int2;
lzma_vli reserved_int3;
lzma_vli reserved_int4;
lzma_vli reserved_int5;
lzma_vli reserved_int6;
lzma_vli reserved_int7;
lzma_vli reserved_int8;
lzma_reserved_enum reserved_enum1;
lzma_reserved_enum reserved_enum2;
lzma_reserved_enum reserved_enum3;
lzma_reserved_enum reserved_enum4;
lzma_bool reserved_bool1;
lzma_bool reserved_bool2;
lzma_bool reserved_bool3;
lzma_bool reserved_bool4;
lzma_bool reserved_bool5;
lzma_bool reserved_bool6;
lzma_bool reserved_bool7;
lzma_bool reserved_bool8;
} lzma_block; } lzma_block;
@ -196,7 +256,8 @@ typedef struct {
* *
* \return - LZMA_OK: Size calculated successfully and stored to * \return - LZMA_OK: Size calculated successfully and stored to
* block->header_size. * block->header_size.
* - LZMA_OPTIONS_ERROR: Unsupported filters or filter options. * - LZMA_OPTIONS_ERROR: Unsupported version, filters or
* filter options.
* - LZMA_PROG_ERROR: Invalid values like compressed_size == 0. * - LZMA_PROG_ERROR: Invalid values like compressed_size == 0.
* *
* \note This doesn't check that all the options are valid i.e. this * \note This doesn't check that all the options are valid i.e. this

View File

@ -26,30 +26,42 @@
************/ ************/
/** /**
* \brief Default compression level for easy encoder * \brief Default compression preset
* *
* It's not straightforward to recommend a default level, because in some * It's not straightforward to recommend a default preset, because in some
* cases keeping the resource usage relatively low is more important that * cases keeping the resource usage relatively low is more important that
* getting the maximum compression ratio. * getting the maximum compression ratio.
*/ */
#define LZMA_EASY_LEVEL_DEFAULT 6 #define LZMA_PRESET_DEFAULT UINT32_C(6)
/**
* \brief Mask for preset level
*
* This is useful only if you need to extract the level from the preset
* variable. That should be rare.
*/
#define LZMA_PRESET_LEVEL_MASK UINT32_C(0x1F)
/* /*
* Flags for easy encoder * Preset flags
* *
* Currently only one flag is defined. * Currently only one flag is defined.
*/ */
/** /**
* Use significantly slower compression to get marginally better compression * \brief Extreme compression preset
* ratio. This doesn't affect the memory requirements of the encoder or
* decoder. This flag is useful when you don't mind wasting time to get as
* small result as possible.
* *
* FIXME: Not implemented yet. * This flag modifies the preset to make the encoding significantly slower
* while improving the compression ratio only marginally. This is useful
* when you don't mind wasting time to get as small result as possible.
*
* This flag doesn't affect the memory usage requirements of the decoder (at
* least not significantly). The memory usage of the encoder may be increased
* a little but only at the lowest preset levels (0-4 or so).
*/ */
#define LZMA_EASY_EXTREME UINT32_C(0x01) #define LZMA_PRESET_EXTREME (UINT32_C(1) << 31)
/** /**
@ -57,12 +69,9 @@
* *
* This function is a wrapper for lzma_raw_encoder_memusage(). * This function is a wrapper for lzma_raw_encoder_memusage().
* *
* \param level Compression level * \param preset Compression preset (level and possible flags)
* \param flags Easy encoder flags (usually zero). This parameter is
* needed, because in future some flags may affect the
* memory requirements.
*/ */
extern uint64_t lzma_easy_encoder_memusage(uint32_t level, uint32_t flags) extern uint64_t lzma_easy_encoder_memusage(uint32_t preset)
lzma_attr_pure; lzma_attr_pure;
@ -71,12 +80,9 @@ extern uint64_t lzma_easy_encoder_memusage(uint32_t level, uint32_t flags)
* *
* This function is a wrapper for lzma_raw_decoder_memusage(). * This function is a wrapper for lzma_raw_decoder_memusage().
* *
* \param level Compression level * \param preset Compression preset (level and possible flags)
* \param flags Easy encoder flags (usually zero). This parameter is
* needed, because in future some flags may affect the
* memory requirements.
*/ */
extern uint64_t lzma_easy_decoder_memusage(uint32_t level, uint32_t flags) extern uint64_t lzma_easy_decoder_memusage(uint32_t preset)
lzma_attr_pure; lzma_attr_pure;
@ -88,14 +94,12 @@ extern uint64_t lzma_easy_decoder_memusage(uint32_t level, uint32_t flags)
* *
* \param strm Pointer to lzma_stream that is at least initialized * \param strm Pointer to lzma_stream that is at least initialized
* with LZMA_STREAM_INIT. * with LZMA_STREAM_INIT.
* \param level Compression level to use. This selects a set of * \param preset Compression preset to use. A preset consist of level
* compression settings from a list of compression * number and zero or more flags. Usually flags aren't
* presets. Currently levels from 1 to 9 are defined, * used, so preset is simply a number [0, 9] which match
* which match the options -1 .. -9 of the xz command * the options -0 .. -9 of the xz command line tool.
* line tool. * Additional flags can be be set using bitwise-or with
* \param flags Flags that can finetune the compression preset. * the preset level number, e.g. 6 | LZMA_PRESET_EXTREME.
* In most cases, no flags are wanted, and this
* parameter is zero.
* \param check Integrity check type to use. See check.h for available * \param check Integrity check type to use. See check.h for available
* checks. If you are unsure, use LZMA_CHECK_CRC32. * checks. If you are unsure, use LZMA_CHECK_CRC32.
* *
@ -115,8 +119,8 @@ extern uint64_t lzma_easy_decoder_memusage(uint32_t level, uint32_t flags)
* LZMA_RUN, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, and LZMA_FINISH. In future, * LZMA_RUN, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, and LZMA_FINISH. In future,
* there may be compression levels or flags that don't support LZMA_SYNC_FLUSH. * there may be compression levels or flags that don't support LZMA_SYNC_FLUSH.
*/ */
extern lzma_ret lzma_easy_encoder(lzma_stream *strm, extern lzma_ret lzma_easy_encoder(
uint32_t level, uint32_t flags, lzma_check check) lzma_stream *strm, uint32_t preset, lzma_check check)
lzma_attr_warn_unused_result; lzma_attr_warn_unused_result;
@ -125,10 +129,8 @@ extern lzma_ret lzma_easy_encoder(lzma_stream *strm,
* *
* \param strm Pointer to properly prepared lzma_stream * \param strm Pointer to properly prepared lzma_stream
* \param filters Array of filters. This must be terminated with * \param filters Array of filters. This must be terminated with
* filters[n].id = LZMA_VLI_UNKNOWN. There must * filters[n].id = LZMA_VLI_UNKNOWN. See filter.h for
* be 1-4 filters, but there are restrictions on how * more information.
* multiple filters can be combined. FIXME Tell where
* to find more information.
* \param check Type of the integrity check to calculate from * \param check Type of the integrity check to calculate from
* uncompressed data. * uncompressed data.
* *
@ -153,15 +155,13 @@ extern lzma_ret lzma_stream_encoder(lzma_stream *strm,
* legacy LZMA tools such as LZMA Utils 4.32.x. Moving to the .xz format * legacy LZMA tools such as LZMA Utils 4.32.x. Moving to the .xz format
* is strongly recommended. * is strongly recommended.
* *
* FIXME: Dictionary size limit?
*
* The valid action values for lzma_code() are LZMA_RUN and LZMA_FINISH. * The valid action values for lzma_code() are LZMA_RUN and LZMA_FINISH.
* No kind of flushing is supported, because the file format doesn't make * No kind of flushing is supported, because the file format doesn't make
* it possible. * it possible.
* *
* \return - LZMA_OK * \return - LZMA_OK
* - LZMA_MEM_ERROR * - LZMA_MEM_ERROR
* - LZMA_OPTIONS_ERROR // FIXME * - LZMA_OPTIONS_ERROR
* - LZMA_PROG_ERROR * - LZMA_PROG_ERROR
*/ */
extern lzma_ret lzma_alone_encoder( extern lzma_ret lzma_alone_encoder(
@ -252,7 +252,7 @@ extern lzma_ret lzma_auto_decoder(
/** /**
* \brief Initializes decoder for .lzma file * \brief Initialize .lzma decoder (legacy file format)
* *
* Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH. * Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.
* There is no need to use LZMA_FINISH, but allowing it may simplify * There is no need to use LZMA_FINISH, but allowing it may simplify

View File

@ -160,19 +160,20 @@ typedef enum {
* mode, which the application developer wasn't aware, could require giving * mode, which the application developer wasn't aware, could require giving
* additional options to the encoder that the older modes don't need. * additional options to the encoder that the older modes don't need.
*/ */
extern lzma_bool lzma_mode_is_available(lzma_mode mode) lzma_attr_const; extern lzma_bool lzma_mode_is_supported(lzma_mode mode) lzma_attr_const;
/** /**
* \brief Options specific to the LZMA1 and LZMA2 filters * \brief Options specific to the LZMA1 and LZMA2 filters
*
* Since LZMA1 and LZMA2 share most of the code, it's simplest to share
* the options structure too. For encoding, all but the reserved variables
* need to be initialized unless specifically mentioned otherwise.
*
* For raw decoding, both LZMA1 and LZMA2 need dict_size, preset_dict, and
* preset_dict_size (if preset_dict != NULL). LZMA1 needs also lc, lp, and pb.
*/ */
typedef struct { typedef struct {
/**********************************
* LZMA encoding/decoding options *
**********************************/
/* These options are required in encoder and also with raw decoding. */
/** /**
* \brief Dictionary size in bytes * \brief Dictionary size in bytes
* *
@ -298,10 +299,6 @@ typedef struct {
# define LZMA_PB_MAX 4 # define LZMA_PB_MAX 4
# define LZMA_PB_DEFAULT 2 # define LZMA_PB_DEFAULT 2
/******************************************
* LZMA options needed only when encoding *
******************************************/
/** /**
* \brief Indicate if the options structure is persistent * \brief Indicate if the options structure is persistent
* *
@ -377,6 +374,8 @@ typedef struct {
* with the currently supported options, so it is safe to leave these * with the currently supported options, so it is safe to leave these
* uninitialized. * uninitialized.
*/ */
void *reserved_ptr1;
void *reserved_ptr2;
uint32_t reserved_int1; uint32_t reserved_int1;
uint32_t reserved_int2; uint32_t reserved_int2;
uint32_t reserved_int3; uint32_t reserved_int3;
@ -385,20 +384,26 @@ typedef struct {
uint32_t reserved_int6; uint32_t reserved_int6;
uint32_t reserved_int7; uint32_t reserved_int7;
uint32_t reserved_int8; uint32_t reserved_int8;
void *reserved_ptr1; lzma_reserved_enum reserved_enum1;
void *reserved_ptr2; lzma_reserved_enum reserved_enum2;
lzma_reserved_enum reserved_enum3;
lzma_reserved_enum reserved_enum4;
} lzma_options_lzma; } lzma_options_lzma;
/** /**
* \brief Set a compression level preset to lzma_options_lzma structure * \brief Set a compression preset to lzma_options_lzma structure
* *
* level = 1 is the fastest and level = 9 is the slowest. These presets match * 0 is the fastest and 9 is the slowest. These match the switches -0 .. -9
* the switches -1 .. -9 of the command line tool. * of the xz command line tool. In addition, it is possible to bitwise-or
* flags to the preset. Currently only LZMA_PRESET_EXTREME is supported.
* The flags are defined in container.h, because the flags are used also
* with lzma_easy_encoder().
* *
* The preset values are subject to changes between liblzma versions. * The preset values are subject to changes between liblzma versions.
* *
* This function is available only if LZMA encoder has been enabled. * This function is available only if LZMA1 or LZMA2 encoder has been enabled
* when building liblzma.
*/ */
extern lzma_bool lzma_lzma_preset(lzma_options_lzma *options, uint32_t level); extern lzma_bool lzma_lzma_preset(lzma_options_lzma *options, uint32_t preset);

View File

@ -75,24 +75,24 @@ alone_decode(lzma_coder *coder,
|= (size_t)(in[*in_pos]) << (coder->pos * 8); |= (size_t)(in[*in_pos]) << (coder->pos * 8);
if (++coder->pos == 4) { if (++coder->pos == 4) {
if (coder->options.dict_size > (UINT32_C(1) << 30)) if (coder->options.dict_size != UINT32_MAX) {
return LZMA_FORMAT_ERROR; // A hack to ditch tons of false positives:
// We allow only dictionary sizes that are
// 2^n or 2^n + 2^(n-1). LZMA_Alone created
// only files with 2^n, but accepts any
// dictionary size. If someone complains, this
// will be reconsidered.
uint32_t d = coder->options.dict_size - 1;
d |= d >> 2;
d |= d >> 3;
d |= d >> 4;
d |= d >> 8;
d |= d >> 16;
++d;
// A hack to ditch tons of false positives: We allow if (d != coder->options.dict_size)
// only dictionary sizes that are 2^n or 2^n + 2^(n-1). return LZMA_FORMAT_ERROR;
// LZMA_Alone created only files with 2^n, but accepts }
// any dictionary size. If someone complains, this
// will be reconsidered.
uint32_t d = coder->options.dict_size - 1;
d |= d >> 2;
d |= d >> 3;
d |= d >> 4;
d |= d >> 8;
d |= d >> 16;
++d;
if (d != coder->options.dict_size)
return LZMA_FORMAT_ERROR;
coder->pos = 0; coder->pos = 0;
coder->sequence = SEQ_UNCOMPRESSED_SIZE; coder->sequence = SEQ_UNCOMPRESSED_SIZE;

View File

@ -104,28 +104,24 @@ alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
// Encode the header: // Encode the header:
// - Properties (1 byte) // - Properties (1 byte)
if (lzma_lzma_lclppb_encode(options, next->coder->header)) if (lzma_lzma_lclppb_encode(options, next->coder->header))
return LZMA_PROG_ERROR; return LZMA_OPTIONS_ERROR;
// - Dictionary size (4 bytes); limit to 1 GiB since that's what // - Dictionary size (4 bytes)
// LZMA SDK currently does for encoding. if (options->dict_size < LZMA_DICT_SIZE_MIN)
if (options->dict_size < LZMA_DICT_SIZE_MIN return LZMA_OPTIONS_ERROR;
|| options->dict_size > (UINT32_C(1) << 30))
return LZMA_PROG_ERROR;
// Round up to to the next 2^n or 2^n + 2^(n - 1) depending on which // Round up to to the next 2^n or 2^n + 2^(n - 1) depending on which
// one is the next. While the header would allow any 32-bit integer, // one is the next unless it is UINT32_MAX. While the header would
// we do this to keep the decoder of liblzma accepting the resulting // allow any 32-bit integer, we do this to keep the decoder of liblzma
// files. // accepting the resulting files.
//
// FIXME Maybe LZMA_Alone needs some lower limit for maximum
// dictionary size? Must check decoders from old LZMA SDK version.
uint32_t d = options->dict_size - 1; uint32_t d = options->dict_size - 1;
d |= d >> 2; d |= d >> 2;
d |= d >> 3; d |= d >> 3;
d |= d >> 4; d |= d >> 4;
d |= d >> 8; d |= d >> 8;
d |= d >> 16; d |= d >> 16;
++d; if (d != UINT32_MAX)
++d;
integer_write_32(next->coder->header + 1, d); integer_write_32(next->coder->header + 1, d);

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file auto_decoder.c /// \file auto_decoder.c
/// \brief Autodetect between .lzma Stream and LZMA_Alone formats /// \brief Autodetect between .xz Stream and .lzma (LZMA_Alone) formats
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file block_decoder.c /// \file block_decoder.c
/// \brief Decodes .lzma Blocks /// \brief Decodes .xz Blocks
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //
@ -34,7 +34,7 @@ struct lzma_coder_s {
/// Decoding options; we also write Compressed Size and Uncompressed /// Decoding options; we also write Compressed Size and Uncompressed
/// Size back to this structure when the decoding has been finished. /// Size back to this structure when the decoding has been finished.
lzma_block *options; lzma_block *block;
/// Compressed Size calculated while decoding /// Compressed Size calculated while decoding
lzma_vli compressed_size; lzma_vli compressed_size;
@ -101,10 +101,10 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
coder->compressed_limit) coder->compressed_limit)
|| update_size(&coder->uncompressed_size, || update_size(&coder->uncompressed_size,
out_used, out_used,
coder->options->uncompressed_size)) coder->block->uncompressed_size))
return LZMA_DATA_ERROR; return LZMA_DATA_ERROR;
lzma_check_update(&coder->check, coder->options->check, lzma_check_update(&coder->check, coder->block->check,
out + out_start, out_used); out + out_start, out_used);
if (ret != LZMA_STREAM_END) if (ret != LZMA_STREAM_END)
@ -113,15 +113,15 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
// Compressed and Uncompressed Sizes are now at their final // Compressed and Uncompressed Sizes are now at their final
// values. Verify that they match the values given to us. // values. Verify that they match the values given to us.
if (!is_size_valid(coder->compressed_size, if (!is_size_valid(coder->compressed_size,
coder->options->compressed_size) coder->block->compressed_size)
|| !is_size_valid(coder->uncompressed_size, || !is_size_valid(coder->uncompressed_size,
coder->options->uncompressed_size)) coder->block->uncompressed_size))
return LZMA_DATA_ERROR; return LZMA_DATA_ERROR;
// Copy the values into coder->options. The caller // Copy the values into coder->block. The caller
// may use this information to construct Index. // may use this information to construct Index.
coder->options->compressed_size = coder->compressed_size; coder->block->compressed_size = coder->compressed_size;
coder->options->uncompressed_size = coder->uncompressed_size; coder->block->uncompressed_size = coder->uncompressed_size;
coder->sequence = SEQ_PADDING; coder->sequence = SEQ_PADDING;
} }
@ -133,7 +133,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
while (coder->compressed_size & 3) { while (coder->compressed_size & 3) {
// We use compressed_size here just get the Padding // We use compressed_size here just get the Padding
// right. The actual Compressed Size was stored to // right. The actual Compressed Size was stored to
// coder->options already, and won't be modified by // coder->block already, and won't be modified by
// us anymore. // us anymore.
++coder->compressed_size; ++coder->compressed_size;
@ -144,17 +144,17 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
return LZMA_DATA_ERROR; return LZMA_DATA_ERROR;
} }
if (coder->options->check == LZMA_CHECK_NONE) if (coder->block->check == LZMA_CHECK_NONE)
return LZMA_STREAM_END; return LZMA_STREAM_END;
lzma_check_finish(&coder->check, coder->options->check); lzma_check_finish(&coder->check, coder->block->check);
coder->sequence = SEQ_CHECK; coder->sequence = SEQ_CHECK;
// Fall through // Fall through
case SEQ_CHECK: { case SEQ_CHECK: {
const bool chksup = lzma_check_is_supported( const bool chksup = lzma_check_is_supported(
coder->options->check); coder->block->check);
while (*in_pos < in_size) { while (*in_pos < in_size) {
// coder->check.buffer[] may be uninitialized when // coder->check.buffer[] may be uninitialized when
@ -168,7 +168,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
++*in_pos; ++*in_pos;
if (++coder->check_pos == lzma_check_size( if (++coder->check_pos == lzma_check_size(
coder->options->check)) coder->block->check))
return LZMA_STREAM_END; return LZMA_STREAM_END;
} }
@ -191,15 +191,15 @@ block_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
extern lzma_ret extern lzma_ret
lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator, lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
lzma_block *options) lzma_block *block)
{ {
lzma_next_coder_init(lzma_block_decoder_init, next, allocator); lzma_next_coder_init(lzma_block_decoder_init, next, allocator);
// Validate the options. lzma_block_unpadded_size() does that for us // Validate the options. lzma_block_unpadded_size() does that for us
// except for Uncompressed Size and filters. Filters are validated // except for Uncompressed Size and filters. Filters are validated
// by the raw decoder. // by the raw decoder.
if (lzma_block_unpadded_size(options) == 0 if (lzma_block_unpadded_size(block) == 0
|| !lzma_vli_is_valid(options->uncompressed_size)) || !lzma_vli_is_valid(block->uncompressed_size))
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
// Allocate and initialize *next->coder if needed. // Allocate and initialize *next->coder if needed.
@ -215,7 +215,7 @@ lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
// Basic initializations // Basic initializations
next->coder->sequence = SEQ_CODE; next->coder->sequence = SEQ_CODE;
next->coder->options = options; next->coder->block = block;
next->coder->compressed_size = 0; next->coder->compressed_size = 0;
next->coder->uncompressed_size = 0; next->coder->uncompressed_size = 0;
@ -223,28 +223,28 @@ lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
// value so that encoded size of the Block (including Block Padding) // value so that encoded size of the Block (including Block Padding)
// is still a valid VLI and a multiple of four. // is still a valid VLI and a multiple of four.
next->coder->compressed_limit next->coder->compressed_limit
= options->compressed_size == LZMA_VLI_UNKNOWN = block->compressed_size == LZMA_VLI_UNKNOWN
? (LZMA_VLI_MAX & ~LZMA_VLI_C(3)) ? (LZMA_VLI_MAX & ~LZMA_VLI_C(3))
- options->header_size - block->header_size
- lzma_check_size(options->check) - lzma_check_size(block->check)
: options->compressed_size; : block->compressed_size;
// Initialize the check. It's caller's problem if the Check ID is not // Initialize the check. It's caller's problem if the Check ID is not
// supported, and the Block decoder cannot verify the Check field. // supported, and the Block decoder cannot verify the Check field.
// Caller can test lzma_checks[options->check]. // Caller can test lzma_check_is_supported(block->check).
next->coder->check_pos = 0; next->coder->check_pos = 0;
lzma_check_init(&next->coder->check, options->check); lzma_check_init(&next->coder->check, block->check);
// Initialize the filter chain. // Initialize the filter chain.
return lzma_raw_decoder_init(&next->coder->next, allocator, return lzma_raw_decoder_init(&next->coder->next, allocator,
options->filters); block->filters);
} }
extern LZMA_API lzma_ret extern LZMA_API lzma_ret
lzma_block_decoder(lzma_stream *strm, lzma_block *options) lzma_block_decoder(lzma_stream *strm, lzma_block *block)
{ {
lzma_next_strm_init(lzma_block_decoder_init, strm, options); lzma_next_strm_init(lzma_block_decoder_init, strm, block);
strm->internal->supported_actions[LZMA_RUN] = true; strm->internal->supported_actions[LZMA_RUN] = true;
strm->internal->supported_actions[LZMA_FINISH] = true; strm->internal->supported_actions[LZMA_FINISH] = true;

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file block_decoder.h /// \file block_decoder.h
/// \brief Decodes .lzma Blocks /// \brief Decodes .xz Blocks
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //
@ -24,6 +24,6 @@
extern lzma_ret lzma_block_decoder_init(lzma_next_coder *next, extern lzma_ret lzma_block_decoder_init(lzma_next_coder *next,
lzma_allocator *allocator, lzma_block *options); lzma_allocator *allocator, lzma_block *block);
#endif #endif

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file block_encoder.c /// \file block_encoder.c
/// \brief Encodes .lzma Blocks /// \brief Encodes .xz Blocks
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //
@ -44,7 +44,7 @@ struct lzma_coder_s {
/// Encoding options; we also write Unpadded Size, Compressed Size, /// Encoding options; we also write Unpadded Size, Compressed Size,
/// and Uncompressed Size back to this structure when the encoding /// and Uncompressed Size back to this structure when the encoding
/// has been finished. /// has been finished.
lzma_block *options; lzma_block *block;
enum { enum {
SEQ_CODE, SEQ_CODE,
@ -97,7 +97,7 @@ block_encode(lzma_coder *coder, lzma_allocator *allocator,
// checked it at the beginning of this function. // checked it at the beginning of this function.
coder->uncompressed_size += in_used; coder->uncompressed_size += in_used;
lzma_check_update(&coder->check, coder->options->check, lzma_check_update(&coder->check, coder->block->check,
in + in_start, in_used); in + in_start, in_used);
if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH) if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH)
@ -106,10 +106,10 @@ block_encode(lzma_coder *coder, lzma_allocator *allocator,
assert(*in_pos == in_size); assert(*in_pos == in_size);
assert(action == LZMA_FINISH); assert(action == LZMA_FINISH);
// Copy the values into coder->options. The caller // Copy the values into coder->block. The caller
// may use this information to construct Index. // may use this information to construct Index.
coder->options->compressed_size = coder->compressed_size; coder->block->compressed_size = coder->compressed_size;
coder->options->uncompressed_size = coder->uncompressed_size; coder->block->uncompressed_size = coder->uncompressed_size;
coder->sequence = SEQ_PADDING; coder->sequence = SEQ_PADDING;
} }
@ -127,10 +127,10 @@ block_encode(lzma_coder *coder, lzma_allocator *allocator,
++coder->pos; ++coder->pos;
} }
if (coder->options->check == LZMA_CHECK_NONE) if (coder->block->check == LZMA_CHECK_NONE)
return LZMA_STREAM_END; return LZMA_STREAM_END;
lzma_check_finish(&coder->check, coder->options->check); lzma_check_finish(&coder->check, coder->block->check);
coder->pos = 0; coder->pos = 0;
coder->sequence = SEQ_CHECK; coder->sequence = SEQ_CHECK;
@ -139,7 +139,7 @@ block_encode(lzma_coder *coder, lzma_allocator *allocator,
case SEQ_CHECK: { case SEQ_CHECK: {
const uint32_t check_size const uint32_t check_size
= lzma_check_size(coder->options->check); = lzma_check_size(coder->block->check);
while (*out_pos < out_size) { while (*out_pos < out_size) {
out[*out_pos] = coder->check.buffer.u8[coder->pos]; out[*out_pos] = coder->check.buffer.u8[coder->pos];
@ -168,16 +168,19 @@ block_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
extern lzma_ret extern lzma_ret
lzma_block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator, lzma_block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
lzma_block *options) lzma_block *block)
{ {
lzma_next_coder_init(lzma_block_encoder_init, next, allocator); lzma_next_coder_init(lzma_block_encoder_init, next, allocator);
if (block->version != 0)
return LZMA_OPTIONS_ERROR;
// If the Check ID is not supported, we cannot calculate the check and // If the Check ID is not supported, we cannot calculate the check and
// thus not create a proper Block. // thus not create a proper Block.
if ((unsigned)(options->check) > LZMA_CHECK_ID_MAX) if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
if (!lzma_check_is_supported(options->check)) if (!lzma_check_is_supported(block->check))
return LZMA_UNSUPPORTED_CHECK; return LZMA_UNSUPPORTED_CHECK;
// Allocate and initialize *next->coder if needed. // Allocate and initialize *next->coder if needed.
@ -193,24 +196,24 @@ lzma_block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
// Basic initializations // Basic initializations
next->coder->sequence = SEQ_CODE; next->coder->sequence = SEQ_CODE;
next->coder->options = options; next->coder->block = block;
next->coder->compressed_size = 0; next->coder->compressed_size = 0;
next->coder->uncompressed_size = 0; next->coder->uncompressed_size = 0;
next->coder->pos = 0; next->coder->pos = 0;
// Initialize the check // Initialize the check
lzma_check_init(&next->coder->check, options->check); lzma_check_init(&next->coder->check, block->check);
// Initialize the requested filters. // Initialize the requested filters.
return lzma_raw_encoder_init(&next->coder->next, allocator, return lzma_raw_encoder_init(&next->coder->next, allocator,
options->filters); block->filters);
} }
extern LZMA_API lzma_ret extern LZMA_API lzma_ret
lzma_block_encoder(lzma_stream *strm, lzma_block *options) lzma_block_encoder(lzma_stream *strm, lzma_block *block)
{ {
lzma_next_strm_init(lzma_block_encoder_init, strm, options); lzma_next_strm_init(lzma_block_encoder_init, strm, block);
strm->internal->supported_actions[LZMA_RUN] = true; strm->internal->supported_actions[LZMA_RUN] = true;
strm->internal->supported_actions[LZMA_FINISH] = true; strm->internal->supported_actions[LZMA_FINISH] = true;

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file block_encoder.h /// \file block_encoder.h
/// \brief Encodes .lzma Blocks /// \brief Encodes .xz Blocks
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //
@ -24,6 +24,6 @@
extern lzma_ret lzma_block_encoder_init(lzma_next_coder *next, extern lzma_ret lzma_block_encoder_init(lzma_next_coder *next,
lzma_allocator *allocator, lzma_block *options); lzma_allocator *allocator, lzma_block *block);
#endif #endif

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file block_header_decoder.c /// \file block_header_decoder.c
/// \brief Decodes Block Header from .lzma files /// \brief Decodes Block Header from .xz files
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //
@ -22,15 +22,15 @@
static void static void
free_properties(lzma_block *options, lzma_allocator *allocator) free_properties(lzma_block *block, lzma_allocator *allocator)
{ {
// Free allocated filter options. The last array member is not // Free allocated filter options. The last array member is not
// touched after the initialization in the beginning of // touched after the initialization in the beginning of
// lzma_block_header_decode(), so we don't need to touch that here. // lzma_block_header_decode(), so we don't need to touch that here.
for (size_t i = 0; i < LZMA_FILTERS_MAX; ++i) { for (size_t i = 0; i < LZMA_FILTERS_MAX; ++i) {
lzma_free(options->filters[i].options, allocator); lzma_free(block->filters[i].options, allocator);
options->filters[i].id = LZMA_VLI_UNKNOWN; block->filters[i].id = LZMA_VLI_UNKNOWN;
options->filters[i].options = NULL; block->filters[i].options = NULL;
} }
return; return;
@ -38,7 +38,7 @@ free_properties(lzma_block *options, lzma_allocator *allocator)
extern LZMA_API lzma_ret extern LZMA_API lzma_ret
lzma_block_header_decode(lzma_block *options, lzma_block_header_decode(lzma_block *block,
lzma_allocator *allocator, const uint8_t *in) lzma_allocator *allocator, const uint8_t *in)
{ {
// NOTE: We consider the header to be corrupt not only when the // NOTE: We consider the header to be corrupt not only when the
@ -49,18 +49,21 @@ lzma_block_header_decode(lzma_block *options,
// Initialize the filter options array. This way the caller can // Initialize the filter options array. This way the caller can
// safely free() the options even if an error occurs in this function. // safely free() the options even if an error occurs in this function.
for (size_t i = 0; i <= LZMA_FILTERS_MAX; ++i) { for (size_t i = 0; i <= LZMA_FILTERS_MAX; ++i) {
options->filters[i].id = LZMA_VLI_UNKNOWN; block->filters[i].id = LZMA_VLI_UNKNOWN;
options->filters[i].options = NULL; block->filters[i].options = NULL;
} }
// Always zero for now.
block->version = 0;
// Validate Block Header Size and Check type. The caller must have // Validate Block Header Size and Check type. The caller must have
// already set these, so it is a programming error if this test fails. // already set these, so it is a programming error if this test fails.
if (lzma_block_header_size_decode(in[0]) != options->header_size if (lzma_block_header_size_decode(in[0]) != block->header_size
|| (unsigned int)(options->check) > LZMA_CHECK_ID_MAX) || (unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
// Exclude the CRC32 field. // Exclude the CRC32 field.
const size_t in_size = options->header_size - 4; const size_t in_size = block->header_size - 4;
// Verify CRC32 // Verify CRC32
if (lzma_crc32(in, in_size, 0) != integer_read_32(in + in_size)) if (lzma_crc32(in, in_size, 0) != integer_read_32(in + in_size))
@ -75,32 +78,32 @@ lzma_block_header_decode(lzma_block *options,
// Compressed Size // Compressed Size
if (in[1] & 0x40) { if (in[1] & 0x40) {
return_if_error(lzma_vli_decode(&options->compressed_size, return_if_error(lzma_vli_decode(&block->compressed_size,
NULL, in, &in_pos, in_size)); NULL, in, &in_pos, in_size));
// Validate Compressed Size. This checks that it isn't zero // Validate Compressed Size. This checks that it isn't zero
// and that the total size of the Block is a valid VLI. // and that the total size of the Block is a valid VLI.
if (lzma_block_unpadded_size(options) == 0) if (lzma_block_unpadded_size(block) == 0)
return LZMA_DATA_ERROR; return LZMA_DATA_ERROR;
} else { } else {
options->compressed_size = LZMA_VLI_UNKNOWN; block->compressed_size = LZMA_VLI_UNKNOWN;
} }
// Uncompressed Size // Uncompressed Size
if (in[1] & 0x80) if (in[1] & 0x80)
return_if_error(lzma_vli_decode(&options->uncompressed_size, return_if_error(lzma_vli_decode(&block->uncompressed_size,
NULL, in, &in_pos, in_size)); NULL, in, &in_pos, in_size));
else else
options->uncompressed_size = LZMA_VLI_UNKNOWN; block->uncompressed_size = LZMA_VLI_UNKNOWN;
// Filter Flags // Filter Flags
const size_t filter_count = (in[1] & 3) + 1; const size_t filter_count = (in[1] & 3) + 1;
for (size_t i = 0; i < filter_count; ++i) { for (size_t i = 0; i < filter_count; ++i) {
const lzma_ret ret = lzma_filter_flags_decode( const lzma_ret ret = lzma_filter_flags_decode(
&options->filters[i], allocator, &block->filters[i], allocator,
in, &in_pos, in_size); in, &in_pos, in_size);
if (ret != LZMA_OK) { if (ret != LZMA_OK) {
free_properties(options, allocator); free_properties(block, allocator);
return ret; return ret;
} }
} }
@ -108,7 +111,7 @@ lzma_block_header_decode(lzma_block *options,
// Padding // Padding
while (in_pos < in_size) { while (in_pos < in_size) {
if (in[in_pos++] != 0x00) { if (in[in_pos++] != 0x00) {
free_properties(options, allocator); free_properties(block, allocator);
// Possibly some new field present so use // Possibly some new field present so use
// LZMA_OPTIONS_ERROR instead of LZMA_DATA_ERROR. // LZMA_OPTIONS_ERROR instead of LZMA_DATA_ERROR.

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file block_header_encoder.c /// \file block_header_encoder.c
/// \brief Encodes Block Header for .lzma files /// \brief Encodes Block Header for .xz files
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //
@ -22,23 +22,26 @@
extern LZMA_API lzma_ret extern LZMA_API lzma_ret
lzma_block_header_size(lzma_block *options) lzma_block_header_size(lzma_block *block)
{ {
if (block->version != 0)
return LZMA_OPTIONS_ERROR;
// Block Header Size + Block Flags + CRC32. // Block Header Size + Block Flags + CRC32.
uint32_t size = 1 + 1 + 4; uint32_t size = 1 + 1 + 4;
// Compressed Size // Compressed Size
if (options->compressed_size != LZMA_VLI_UNKNOWN) { if (block->compressed_size != LZMA_VLI_UNKNOWN) {
const uint32_t add = lzma_vli_size(options->compressed_size); const uint32_t add = lzma_vli_size(block->compressed_size);
if (add == 0 || options->compressed_size == 0) if (add == 0 || block->compressed_size == 0)
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
size += add; size += add;
} }
// Uncompressed Size // Uncompressed Size
if (options->uncompressed_size != LZMA_VLI_UNKNOWN) { if (block->uncompressed_size != LZMA_VLI_UNKNOWN) {
const uint32_t add = lzma_vli_size(options->uncompressed_size); const uint32_t add = lzma_vli_size(block->uncompressed_size);
if (add == 0) if (add == 0)
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
@ -46,24 +49,23 @@ lzma_block_header_size(lzma_block *options)
} }
// List of Filter Flags // List of Filter Flags
if (options->filters == NULL if (block->filters == NULL || block->filters[0].id == LZMA_VLI_UNKNOWN)
|| options->filters[0].id == LZMA_VLI_UNKNOWN)
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
for (size_t i = 0; options->filters[i].id != LZMA_VLI_UNKNOWN; ++i) { for (size_t i = 0; block->filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
// Don't allow too many filters. // Don't allow too many filters.
if (i == LZMA_FILTERS_MAX) if (i == LZMA_FILTERS_MAX)
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
uint32_t add; uint32_t add;
return_if_error(lzma_filter_flags_size(&add, return_if_error(lzma_filter_flags_size(&add,
options->filters + i)); block->filters + i));
size += add; size += add;
} }
// Pad to a multiple of four bytes. // Pad to a multiple of four bytes.
options->header_size = (size + 3) & ~UINT32_C(3); block->header_size = (size + 3) & ~UINT32_C(3);
// NOTE: We don't verify that the encoded size of the Block stays // NOTE: We don't verify that the encoded size of the Block stays
// within limits. This is because it is possible that we are called // within limits. This is because it is possible that we are called
@ -76,15 +78,15 @@ lzma_block_header_size(lzma_block *options)
extern LZMA_API lzma_ret extern LZMA_API lzma_ret
lzma_block_header_encode(const lzma_block *options, uint8_t *out) lzma_block_header_encode(const lzma_block *block, uint8_t *out)
{ {
// Valdidate everything but filters. // Valdidate everything but filters.
if (lzma_block_unpadded_size(options) == 0 if (lzma_block_unpadded_size(block) == 0
|| !lzma_vli_is_valid(options->uncompressed_size)) || !lzma_vli_is_valid(block->uncompressed_size))
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
// Indicate the size of the buffer _excluding_ the CRC32 field. // Indicate the size of the buffer _excluding_ the CRC32 field.
const size_t out_size = options->header_size - 4; const size_t out_size = block->header_size - 4;
// Store the Block Header Size. // Store the Block Header Size.
out[0] = out_size / 4; out[0] = out_size / 4;
@ -94,26 +96,23 @@ lzma_block_header_encode(const lzma_block *options, uint8_t *out)
size_t out_pos = 2; size_t out_pos = 2;
// Compressed Size // Compressed Size
if (options->compressed_size != LZMA_VLI_UNKNOWN) { if (block->compressed_size != LZMA_VLI_UNKNOWN) {
return_if_error(lzma_vli_encode( return_if_error(lzma_vli_encode(block->compressed_size, NULL,
options->compressed_size, NULL,
out, &out_pos, out_size)); out, &out_pos, out_size));
out[1] |= 0x40; out[1] |= 0x40;
} }
// Uncompressed Size // Uncompressed Size
if (options->uncompressed_size != LZMA_VLI_UNKNOWN) { if (block->uncompressed_size != LZMA_VLI_UNKNOWN) {
return_if_error(lzma_vli_encode( return_if_error(lzma_vli_encode(block->uncompressed_size, NULL,
options->uncompressed_size, NULL,
out, &out_pos, out_size)); out, &out_pos, out_size));
out[1] |= 0x80; out[1] |= 0x80;
} }
// Filter Flags // Filter Flags
if (options->filters == NULL if (block->filters == NULL || block->filters[0].id == LZMA_VLI_UNKNOWN)
|| options->filters[0].id == LZMA_VLI_UNKNOWN)
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
size_t filter_count = 0; size_t filter_count = 0;
@ -123,10 +122,10 @@ lzma_block_header_encode(const lzma_block *options, uint8_t *out)
return LZMA_PROG_ERROR; return LZMA_PROG_ERROR;
return_if_error(lzma_filter_flags_encode( return_if_error(lzma_filter_flags_encode(
options->filters + filter_count, block->filters + filter_count,
out, &out_pos, out_size)); out, &out_pos, out_size));
} while (options->filters[++filter_count].id != LZMA_VLI_UNKNOWN); } while (block->filters[++filter_count].id != LZMA_VLI_UNKNOWN);
out[1] |= filter_count - 1; out[1] |= filter_count - 1;

View File

@ -58,7 +58,8 @@ lzma_block_unpadded_size(const lzma_block *block)
// NOTE: This function is used for validation too, so it is // NOTE: This function is used for validation too, so it is
// essential that these checks are always done even if // essential that these checks are always done even if
// Compressed Size is unknown. // Compressed Size is unknown.
if (block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN if (block->version != 0
|| block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN
|| block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX || block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX
|| (block->header_size & 3) || (block->header_size & 3)
|| !lzma_vli_is_valid(block->compressed_size) || !lzma_vli_is_valid(block->compressed_size)

View File

@ -33,30 +33,16 @@ struct lzma_coder_s {
static bool static bool
easy_set_filters(lzma_coder *coder, uint32_t level, uint32_t flags) easy_set_filters(lzma_coder *coder, uint32_t preset)
{ {
// FIXME if (lzma_lzma_preset(&coder->opt_lzma, preset))
(void)flags; return true;
bool error = false; coder->filters[0].id = LZMA_FILTER_LZMA2;
coder->filters[0].options = &coder->opt_lzma;
coder->filters[1].id = LZMA_VLI_UNKNOWN;
if (level == 0) { return false;
// TODO FIXME Use Subblock or LZMA2 with no compression.
error = true;
#ifdef HAVE_ENCODER_LZMA2
} else if (level <= 9) {
error = lzma_lzma_preset(&coder->opt_lzma, level);
coder->filters[0].id = LZMA_FILTER_LZMA2;
coder->filters[0].options = &coder->opt_lzma;
coder->filters[1].id = LZMA_VLI_UNKNOWN;
#endif
} else {
error = true;
}
return error;
} }
@ -83,7 +69,7 @@ easy_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
static lzma_ret static lzma_ret
easy_encoder_init(lzma_next_coder *next, lzma_allocator *allocator, easy_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
uint32_t level, uint32_t flags, lzma_check check) uint32_t preset, lzma_check check)
{ {
lzma_next_coder_init(easy_encoder_init, next, allocator); lzma_next_coder_init(easy_encoder_init, next, allocator);
@ -98,7 +84,7 @@ easy_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
next->coder->stream_encoder = LZMA_NEXT_CODER_INIT; next->coder->stream_encoder = LZMA_NEXT_CODER_INIT;
} }
if (easy_set_filters(next->coder, level, flags)) if (easy_set_filters(next->coder, preset))
return LZMA_OPTIONS_ERROR; return LZMA_OPTIONS_ERROR;
return lzma_stream_encoder_init(&next->coder->stream_encoder, return lzma_stream_encoder_init(&next->coder->stream_encoder,
@ -107,10 +93,9 @@ easy_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
extern LZMA_API lzma_ret extern LZMA_API lzma_ret
lzma_easy_encoder(lzma_stream *strm, lzma_easy_encoder(lzma_stream *strm, uint32_t preset, lzma_check check)
uint32_t level, uint32_t flags, lzma_check check)
{ {
lzma_next_strm_init(easy_encoder_init, strm, level, flags, check); lzma_next_strm_init(easy_encoder_init, strm, preset, check);
strm->internal->supported_actions[LZMA_RUN] = true; strm->internal->supported_actions[LZMA_RUN] = true;
strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true; strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
@ -122,10 +107,10 @@ lzma_easy_encoder(lzma_stream *strm,
extern LZMA_API uint64_t extern LZMA_API uint64_t
lzma_easy_encoder_memusage(uint32_t level, uint32_t flags) lzma_easy_encoder_memusage(uint32_t preset)
{ {
lzma_coder coder; lzma_coder coder;
if (easy_set_filters(&coder, level, flags)) if (easy_set_filters(&coder, preset))
return UINT32_MAX; return UINT32_MAX;
return lzma_memusage_encoder(coder.filters); return lzma_memusage_encoder(coder.filters);
@ -133,10 +118,10 @@ lzma_easy_encoder_memusage(uint32_t level, uint32_t flags)
extern LZMA_API uint64_t extern LZMA_API uint64_t
lzma_easy_decoder_memusage(uint32_t level, uint32_t flags) lzma_easy_decoder_memusage(uint32_t preset)
{ {
lzma_coder coder; lzma_coder coder;
if (easy_set_filters(&coder, level, flags)) if (easy_set_filters(&coder, preset))
return UINT32_MAX; return UINT32_MAX;
return lzma_memusage_decoder(coder.filters); return lzma_memusage_decoder(coder.filters);

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file stream_decoder.c /// \file stream_decoder.c
/// \brief Decodes .lzma Streams /// \brief Decodes .xz Streams
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //
@ -96,7 +96,6 @@ stream_decoder_reset(lzma_coder *coder, lzma_allocator *allocator)
// Reset the rest of the variables. // Reset the rest of the variables.
coder->sequence = SEQ_STREAM_HEADER; coder->sequence = SEQ_STREAM_HEADER;
coder->block_options.filters = NULL;
coder->pos = 0; coder->pos = 0;
return LZMA_OK; return LZMA_OK;

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file stream_decoder.h /// \file stream_decoder.h
/// \brief Decodes .lzma Streams /// \brief Decodes .xz Streams
// //
// Copyright (C) 2008 Lasse Collin // Copyright (C) 2008 Lasse Collin
// //

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file stream_encoder.c /// \file stream_encoder.c
/// \brief Encodes .lzma Streams /// \brief Encodes .xz Streams
// //
// Copyright (C) 2007-2008 Lasse Collin // Copyright (C) 2007-2008 Lasse Collin
// //
@ -238,6 +238,7 @@ lzma_stream_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
// Basic initializations // Basic initializations
next->coder->sequence = SEQ_STREAM_HEADER; next->coder->sequence = SEQ_STREAM_HEADER;
next->coder->block_options.version = 0;
next->coder->block_options.check = check; next->coder->block_options.check = check;
next->coder->block_options.filters = (lzma_filter *)(filters); next->coder->block_options.filters = (lzma_filter *)(filters);

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file stream_encoder.h /// \file stream_encoder.h
/// \brief Encodes .lzma Streams /// \brief Encodes .xz Streams
// //
// Copyright (C) 2008 Lasse Collin // Copyright (C) 2008 Lasse Collin
// //

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file stream_flags_decoder.c /// \file stream_flags_decoder.c
/// \brief Decodes Stream Header and Stream Footer from .lzma files /// \brief Decodes Stream Header and Stream Footer from .xz files
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //

View File

@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
/// \file stream_flags_encoder.c /// \file stream_flags_encoder.c
/// \brief Encodes Stream Header and Stream Footer for .lzma files /// \brief Encodes Stream Header and Stream Footer for .xz files
// //
// Copyright (C) 2007 Lasse Collin // Copyright (C) 2007 Lasse Collin
// //

View File

@ -668,7 +668,7 @@ lzma_lzma_props_encode(const void *options, uint8_t *out)
extern LZMA_API lzma_bool extern LZMA_API lzma_bool
lzma_mode_is_available(lzma_mode mode) lzma_mode_is_supported(lzma_mode mode)
{ {
return mode == LZMA_MODE_FAST || mode == LZMA_MODE_NORMAL; return mode == LZMA_MODE_FAST || mode == LZMA_MODE_NORMAL;
} }

View File

@ -20,47 +20,18 @@
#include "common.h" #include "common.h"
/*
#define pow2(e) (UINT32_C(1) << (e))
static const lzma_options_lzma presets[9] = {
// dict lc lp pb mode fb mf mfc
{ pow2(16), NULL, 0, 3, 0, 2, false, LZMA_MODE_FAST, 64, LZMA_MF_HC3, 0, 0, 0, 0, 0, NULL, NULL },
{ pow2(20), NULL, 0, 3, 0, 0, false, LZMA_MODE_FAST, 64, LZMA_MF_HC4, 0, 0, 0, 0, 0, NULL, NULL },
{ pow2(19), NULL, 0, 3, 0, 0, false, LZMA_MODE_NORMAL, 64, LZMA_MF_BT4, 0, 0, 0, 0, 0, NULL, NULL },
{ pow2(20), NULL, 0, 3, 0, 0, false, LZMA_MODE_NORMAL, 64, LZMA_MF_BT4, 0, 0, 0, 0, 0, NULL, NULL },
{ pow2(21), NULL, 0, 3, 0, 0, false, LZMA_MODE_NORMAL, 128, LZMA_MF_BT4, 0, 0, 0, 0, 0, NULL, NULL },
{ pow2(22), NULL, 0, 3, 0, 0, false, LZMA_MODE_NORMAL, 128, LZMA_MF_BT4, 0, 0, 0, 0, 0, NULL, NULL },
{ pow2(23), NULL, 0, 3, 0, 0, false, LZMA_MODE_NORMAL, 128, LZMA_MF_BT4, 0, 0, 0, 0, 0, NULL, NULL },
{ pow2(24), NULL, 0, 3, 0, 0, false, LZMA_MODE_NORMAL, 273, LZMA_MF_BT4, 0, 0, 0, 0, 0, NULL, NULL },
{ pow2(25), NULL, 0, 3, 0, 0, false, LZMA_MODE_NORMAL, 273, LZMA_MF_BT4, 0, 0, 0, 0, 0, NULL, NULL },
};
extern LZMA_API lzma_bool extern LZMA_API lzma_bool
lzma_lzma_preset(lzma_options_lzma *options, uint32_t level) lzma_lzma_preset(lzma_options_lzma *options, uint32_t preset)
{ {
if (level >= ARRAY_SIZE(presetes)) const uint32_t level = preset & LZMA_PRESET_LEVEL_MASK;
const uint32_t flags = preset & ~LZMA_PRESET_LEVEL_MASK;
const uint32_t supported_flags = LZMA_PRESET_EXTREME;
if (level > 9 || (flags & ~supported_flags))
return true; return true;
*options = presets[level]; const uint32_t dict_shift = level <= 1 ? 16 : level + 17;
return false; options->dict_size = UINT32_C(1) << dict_shift;
}
*/
extern LZMA_API lzma_bool
lzma_lzma_preset(lzma_options_lzma *options, uint32_t level)
{
if (level == 0 || level > 9)
return true;
--level;
memzero(options, sizeof(*options));
static const uint8_t shift[9] = { 16, 20, 19, 20, 21, 22, 23, 24, 25 };
options->dict_size = UINT32_C(1) << shift[level];
options->preset_dict = NULL; options->preset_dict = NULL;
options->preset_dict_size = 0; options->preset_dict_size = 0;
@ -72,10 +43,18 @@ lzma_lzma_preset(lzma_options_lzma *options, uint32_t level)
options->persistent = false; options->persistent = false;
options->mode = level <= 2 ? LZMA_MODE_FAST : LZMA_MODE_NORMAL; options->mode = level <= 2 ? LZMA_MODE_FAST : LZMA_MODE_NORMAL;
options->nice_len = level <= 5 ? 32 : 64; options->nice_len = level == 0 ? 8 : level <= 5 ? 32 : 64;
options->mf = level <= 1 ? LZMA_MF_HC3 : level <= 2 ? LZMA_MF_HC4 options->mf = level <= 1 ? LZMA_MF_HC3 : level <= 2 ? LZMA_MF_HC4
: LZMA_MF_BT4; : LZMA_MF_BT4;
options->depth = 0; options->depth = 0;
if (flags & LZMA_PRESET_EXTREME) {
options->lc = 4; // FIXME?
options->mode = LZMA_MODE_NORMAL;
options->mf = LZMA_MF_BT4;
options->nice_len = 273;
options->depth = 512;
}
return false; return false;
} }