aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/api/lzma/block.h
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2008-12-15 19:39:13 +0200
committerLasse Collin <lasse.collin@tukaani.org>2008-12-15 19:39:13 +0200
commit671a5adf1e844bfdd6fd327016c3c28694493158 (patch)
tree87f8e40cb30f2641b5b211e3bd3bec9ce084c95e /src/liblzma/api/lzma/block.h
parentThe LZMA2 decoder fix introduced a bug to LZ decoder, (diff)
downloadxz-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.h211
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;