diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2008-12-15 19:39:13 +0200 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2008-12-15 19:39:13 +0200 |
commit | 671a5adf1e844bfdd6fd327016c3c28694493158 (patch) | |
tree | 87f8e40cb30f2641b5b211e3bd3bec9ce084c95e /src/liblzma/api/lzma/block.h | |
parent | The LZMA2 decoder fix introduced a bug to LZ decoder, (diff) | |
download | xz-671a5adf1e844bfdd6fd327016c3c28694493158.tar.xz |
Bunch of liblzma API cleanups and fixes.
Diffstat (limited to 'src/liblzma/api/lzma/block.h')
-rw-r--r-- | src/liblzma/api/lzma/block.h | 211 |
1 files changed, 137 insertions, 74 deletions
diff --git a/src/liblzma/api/lzma/block.h b/src/liblzma/api/lzma/block.h index 06c1633c..2702cd51 100644 --- a/src/liblzma/api/lzma/block.h +++ b/src/liblzma/api/lzma/block.h @@ -22,10 +22,10 @@ /** - * \brief Options for the Block Header encoder and decoder + * \brief Options for the Block and Block Header encoders and decoders * - * Different things use different parts of this structure. Some read - * some members, other functions write, and some do both. Only the + * Different Block handling functions use different parts of this structure. + * Some read some members, other functions write, and some do both. Only the * members listed for reading need to be initialized when the specified * functions are called. The members marked for writing will be assigned * new values at some point either by calling the given function or by @@ -33,11 +33,16 @@ */ typedef struct { /** - * \brief Size of the Block Header + * \brief Size of the Block Header field + * + * This is always a multiple of four. * * Read by: * - lzma_block_header_encode() * - lzma_block_header_decode() + * - lzma_block_compressed_size() + * - lzma_block_unpadded_size() + * - lzma_block_total_size() * - lzma_block_decoder() * * Written by: @@ -50,12 +55,15 @@ typedef struct { /** * \brief Type of integrity Check * - * The type of the integrity Check is not stored into the Block - * Header, thus its value must be provided also when decoding. + * The Check ID is not stored into the Block Header, thus its value + * must be provided also when decoding. * * Read by: * - lzma_block_header_encode() * - lzma_block_header_decode() + * - lzma_block_compressed_size() + * - lzma_block_unpadded_size() + * - lzma_block_total_size() * - lzma_block_encoder() * - lzma_block_decoder() */ @@ -64,19 +72,50 @@ typedef struct { /** * \brief Size of the Compressed Data in bytes * - * Usually you don't know this value when encoding in streamed mode. - * In non-streamed mode you can reserve space for this field when - * encoding the Block Header the first time, and then re-encode the - * Block Header and copy it over the original one after the encoding - * of the Block has been finished. + * Encoding: If this is not LZMA_VLI_UNKNOWN, Block Header encoder + * will store this value to the Block Header. Block encoder doesn't + * care about this value, but will set it once the encoding has been + * finished. + * + * Decoding: If this is not LZMA_VLI_UNKNOWN, Block decoder will + * verify that the size of the Compressed Data field matches + * compressed_size. + * + * Usually you don't know this value when encoding in streamed mode, + * and thus cannot write this field into the Block Header. + * + * In non-streamed mode you can reserve space for this field before + * encoding the actual Block. After encoding the data, finish the + * Block by encoding the Block Header. Steps in detail: + * + * - Set compressed_size to some big enough value. If you don't know + * better, use LZMA_VLI_MAX, but remember that bigger values take + * more space in Block Header. + * + * - Call lzma_block_header_size() to see how much space you need to + * reserve for the Block Header. + * + * - Encode the Block using lzma_block_encoder() and lzma_code(). + * It sets compressed_size to the correct value. + * + * - Use lzma_block_header_encode() to encode the Block Header. + * Because space was reserved in the first step, you don't need + * to call lzma_block_header_size() anymore, because due to + * reserving, header_size has to be big enough. If it is "too big", + * lzma_block_header_encode() will add enough Header Padding to + * make Block Header to match the size specified by header_size. * * Read by: * - lzma_block_header_size() * - lzma_block_header_encode() + * - lzma_block_compressed_size() + * - lzma_block_unpadded_size() + * - lzma_block_total_size() * - lzma_block_decoder() * * Written by: * - lzma_block_header_decode() + * - lzma_block_compressed_size() * - lzma_block_encoder() * - lzma_block_decoder() */ @@ -85,18 +124,11 @@ typedef struct { /** * \brief Uncompressed Size in bytes * - * Encoder: If this value is not LZMA_VLI_UNKNOWN, it is stored - * to the Uncompressed Size field in the Block Header. The real - * uncompressed size of the data being compressed must match - * the Uncompressed Size or LZMA_OPTIONS_ERROR is returned. + * This is handled very similarly to compressed_size above. * - * If Uncompressed Size is unknown, End of Payload Marker must - * be used. If uncompressed_size == LZMA_VLI_UNKNOWN and - * has_eopm == 0, LZMA_OPTIONS_ERROR will be returned. - * - * Decoder: If this value is not LZMA_VLI_UNKNOWN, it is - * compared to the real Uncompressed Size. If they do not match, - * LZMA_OPTIONS_ERROR is returned. + * Unlike compressed_size, uncompressed_size is needed by fewer + * functions. This is because uncompressed_size isn't needed to + * validate that Block stays within proper limits. * * Read by: * - lzma_block_header_size() @@ -140,7 +172,7 @@ typedef struct { /** - * \brief Decodes the Block Header Size field + * \brief Decode 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_block.header_size. @@ -154,100 +186,130 @@ typedef struct { /** - * \brief Calculates the size of Block Header + * \brief Calculate Block Header Size + * + * Calculate the minimum size needed for the Block Header field using the + * settings specified in the lzma_block structure. Note that it is OK to + * increase the calculated header_size value as long as it is a multiple of + * four and doesn't exceed LZMA_BLOCK_HEADER_SIZE_MAX. Increasing header_size + * just means that lzma_block_header_encode() will add Header Padding. * * \return - LZMA_OK: Size calculated successfully and stored to - * options->header_size. + * block->header_size. * - LZMA_OPTIONS_ERROR: Unsupported filters or filter options. - * - LZMA_PROG_ERROR: Invalid options + * - LZMA_PROG_ERROR: Invalid values like compressed_size == 0. * * \note This doesn't check that all the options are valid i.e. this * may return LZMA_OK even if lzma_block_header_encode() or - * lzma_block_encoder() would fail. + * lzma_block_encoder() would fail. If you want to validate the + * filter chain, consider using lzma_memlimit_encoder() which as + * a side-effect validates the filter chain. */ -extern lzma_ret lzma_block_header_size(lzma_block *options) +extern lzma_ret lzma_block_header_size(lzma_block *block) lzma_attr_warn_unused_result; /** - * \brief Encodes Block Header + * \brief Encode Block Header * - * Encoding of the Block options is done with a single call instead of - * first initializing and then doing the actual work with lzma_code(). + * The caller must have calculated the size of the Block Header already with + * lzma_block_header_size(). If larger value than the one calculated by + * lzma_block_header_size() is used, the Block Header will be padded to the + * specified size. * * \param out Beginning of the output buffer. This must be - * at least options->header_size bytes. - * \param options Block options to be encoded. + * at least block->header_size bytes. + * \param block Block options to be encoded. * - * \return - LZMA_OK: Encoding was successful. options->header_size + * \return - LZMA_OK: Encoding was successful. block->header_size * bytes were written to output buffer. * - LZMA_OPTIONS_ERROR: Invalid or unsupported options. - * - LZMA_PROG_ERROR + * - LZMA_PROG_ERROR: Invalid arguments, for example + * block->header_size is invalid or block->filters is NULL. */ -extern lzma_ret lzma_block_header_encode( - const lzma_block *options, uint8_t *out) +extern lzma_ret lzma_block_header_encode(const lzma_block *block, uint8_t *out) lzma_attr_warn_unused_result; /** - * \brief Decodes Block Header + * \brief Decode Block Header * - * 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 size of the Block Header must have already been decoded with + * lzma_block_header_size_decode() macro and stored to block->header_size. + * block->filters must have been allocated, but not necessarily initialized. + * Possible existing filter options are _not_ freed. * - * \param options Destination for block options + * \param block Destination for block options with header_size + * properly initialized. * \param allocator lzma_allocator for custom allocator functions. - * Set to NULL to use malloc(). + * Set to NULL to use malloc() (and also free() + * if an error occurs). * \param in Beginning of the input buffer. This must be - * at least options->header_size bytes. + * at least block->header_size bytes. * - * \return - LZMA_OK: Decoding was successful. options->header_size - * bytes were written to output buffer. - * - LZMA_OPTIONS_ERROR: Invalid or unsupported options. - * - LZMA_PROG_ERROR + * \return - LZMA_OK: Decoding was successful. block->header_size + * bytes were read from the input buffer. + * - LZMA_OPTIONS_ERROR: The Block Header specifies some + * unsupported options such as unsupported filters. + * - LZMA_DATA_ERROR: Block Header is corrupt, for example, + * the CRC32 doesn't match. + * - LZMA_PROG_ERROR: Invalid arguments, for example + * block->header_size is invalid or block->filters is NULL. */ -extern lzma_ret lzma_block_header_decode(lzma_block *options, +extern lzma_ret lzma_block_header_decode(lzma_block *block, lzma_allocator *allocator, const uint8_t *in) lzma_attr_warn_unused_result; /** - * \brief Sets Compressed Size according to Unpadded Size + * \brief Validate and set Compressed Size according to Unpadded Size * * Block Header stores Compressed Size, but Index has Unpadded Size. If the * application has already parsed the Index and is now decoding Blocks, * it can calculate Compressed Size from Unpadded 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. + * exactly that with error checking: + * + * - Compressed Size calculated from Unpadded Size must be positive integer, + * that is, Unpadded Size must be big enough that after Block Header and + * Check fields there's still at least one byte for Compressed Size. * - * \return - LZMA_OK: options->compressed_size was set successfully. + * - If Compressed Size was present in Block Header, the new value + * calculated from Unpadded Size is compared against the value + * from Block Header. + * + * \note This function must be called _after_ decoding the Block Header + * field so that it can properly validate Compressed Size if it + * was present in Block Header. + * + * \return - LZMA_OK: block->compressed_size was set successfully. * - LZMA_DATA_ERROR: unpadded_size is too small compared to - * options->header_size and lzma_check_sizes[options->check]. + * block->header_size and lzma_check_size(block->check). * - LZMA_PROG_ERROR: Some values are invalid. For example, - * options->header_size must be a multiple of four, and - * options->header_size between 8 and 1024 inclusive. + * block->header_size must be a multiple of four and + * between 8 and 1024 inclusive. */ extern lzma_ret lzma_block_compressed_size( - lzma_block *options, lzma_vli unpadded_size) + lzma_block *block, lzma_vli unpadded_size) lzma_attr_warn_unused_result; /** - * \brief Calculates Unpadded Size + * \brief Calculate Unpadded Size * - * This function can be useful after decoding a Block to get Unpadded Size - * that is stored in Index. + * The Index field stores Unpadded Size and Uncompressed Size. The latter + * can be taken directly from the lzma_block structure after coding a Block, + * but Unpadded Size needs to be calculated from Block Header Size, + * Compressed Size, and size of the Check field. This is where this function + * is needed. * * \return Unpadded Size on success, or zero on error. */ -extern lzma_vli lzma_block_unpadded_size(const lzma_block *options) +extern lzma_vli lzma_block_unpadded_size(const lzma_block *block) lzma_attr_pure; /** - * \brief Calculates the total encoded size of a Block + * \brief Calculate the total encoded size of a Block * * This is equivalent to lzma_block_unpadded_size() except that the returned * value includes the size of the Block Padding field. @@ -255,39 +317,40 @@ extern lzma_vli lzma_block_unpadded_size(const lzma_block *options) * \return On success, total encoded size of the Block. On error, * zero is returned. */ -extern lzma_vli lzma_block_total_size(const lzma_block *options) +extern lzma_vli lzma_block_total_size(const lzma_block *block) lzma_attr_pure; /** - * \brief Initializes .lzma Block encoder + * \brief Initialize .xz Block encoder * - * This function is required for multi-thread encoding. It may also be - * useful when implementing custom file formats. + * Valid actions for lzma_code() are LZMA_RUN, LZMA_SYNC_FLUSH (only if the + * filter chain supports it), and LZMA_FINISH. * * \return - LZMA_OK: All good, continue with lzma_code(). * - LZMA_MEM_ERROR * - LZMA_OPTIONS_ERROR - * - LZMA_UNSUPPORTED_CHECK: options->check specfies a Check + * - LZMA_UNSUPPORTED_CHECK: block->check specfies a Check ID * that is not supported by this buid of liblzma. Initializing * the encoder failed. * - LZMA_PROG_ERROR - * - * lzma_code() can return FIXME */ -extern lzma_ret lzma_block_encoder(lzma_stream *strm, lzma_block *options) +extern lzma_ret lzma_block_encoder(lzma_stream *strm, lzma_block *block) lzma_attr_warn_unused_result; /** - * \brief Initializes decoder for .lzma Block + * \brief Initialize .xz Block decoder + * + * Valid actions for lzma_code() are LZMA_RUN and LZMA_FINISH. Using + * LZMA_FINISH is not required. It is supported only for convenience. * * \return - LZMA_OK: All good, continue with lzma_code(). * - LZMA_UNSUPPORTED_CHECK: Initialization was successful, but - * the given Check type is not supported, thus Check will be + * the given Check ID is not supported, thus Check will be * ignored. * - LZMA_PROG_ERROR * - LZMA_MEM_ERROR */ -extern lzma_ret lzma_block_decoder(lzma_stream *strm, lzma_block *options) +extern lzma_ret lzma_block_decoder(lzma_stream *strm, lzma_block *block) lzma_attr_warn_unused_result; |