jpayne@69: /* SPDX-License-Identifier: 0BSD */ jpayne@69: jpayne@69: /** jpayne@69: * \file lzma/block.h jpayne@69: * \brief .xz Block handling jpayne@69: * \note Never include this file directly. Use instead. jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * Author: Lasse Collin jpayne@69: */ jpayne@69: jpayne@69: #ifndef LZMA_H_INTERNAL jpayne@69: # error Never include this file directly. Use instead. jpayne@69: #endif jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Options for the Block and Block Header encoders and decoders jpayne@69: * jpayne@69: * Different Block handling functions use different parts of this structure. jpayne@69: * Some read some members, other functions write, and some do both. Only the jpayne@69: * members listed for reading need to be initialized when the specified jpayne@69: * functions are called. The members marked for writing will be assigned jpayne@69: * new values at some point either by calling the given function or by jpayne@69: * later calls to lzma_code(). jpayne@69: */ jpayne@69: typedef struct { jpayne@69: /** jpayne@69: * \brief Block format version jpayne@69: * jpayne@69: * To prevent API and ABI breakages when new features are needed, jpayne@69: * a version number is used to indicate which members in this jpayne@69: * structure are in use: jpayne@69: * - liblzma >= 5.0.0: version = 0 is supported. jpayne@69: * - liblzma >= 5.1.4beta: Support for version = 1 was added, jpayne@69: * which adds the ignore_check member. jpayne@69: * jpayne@69: * If version is greater than one, most Block related functions jpayne@69: * will return LZMA_OPTIONS_ERROR (lzma_block_header_decode() works jpayne@69: * with any version value). jpayne@69: * jpayne@69: * Read by: jpayne@69: * - lzma_block_header_size() jpayne@69: * - lzma_block_header_encode() jpayne@69: * - lzma_block_header_decode() jpayne@69: * - lzma_block_compressed_size() jpayne@69: * - lzma_block_unpadded_size() jpayne@69: * - lzma_block_total_size() jpayne@69: * - lzma_block_encoder() jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_encode() jpayne@69: * - lzma_block_uncomp_encode() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: * jpayne@69: * Written by: jpayne@69: * - lzma_block_header_decode() jpayne@69: */ jpayne@69: uint32_t version; jpayne@69: jpayne@69: /** jpayne@69: * \brief Size of the Block Header field in bytes jpayne@69: * jpayne@69: * This is always a multiple of four. jpayne@69: * jpayne@69: * Read by: jpayne@69: * - lzma_block_header_encode() jpayne@69: * - lzma_block_header_decode() jpayne@69: * - lzma_block_compressed_size() jpayne@69: * - lzma_block_unpadded_size() jpayne@69: * - lzma_block_total_size() jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: * jpayne@69: * Written by: jpayne@69: * - lzma_block_header_size() jpayne@69: * - lzma_block_buffer_encode() jpayne@69: * - lzma_block_uncomp_encode() jpayne@69: */ jpayne@69: uint32_t header_size; jpayne@69: # define LZMA_BLOCK_HEADER_SIZE_MIN 8 jpayne@69: # define LZMA_BLOCK_HEADER_SIZE_MAX 1024 jpayne@69: jpayne@69: /** jpayne@69: * \brief Type of integrity Check jpayne@69: * jpayne@69: * The Check ID is not stored into the Block Header, thus its value jpayne@69: * must be provided also when decoding. jpayne@69: * jpayne@69: * Read by: jpayne@69: * - lzma_block_header_encode() jpayne@69: * - lzma_block_header_decode() jpayne@69: * - lzma_block_compressed_size() jpayne@69: * - lzma_block_unpadded_size() jpayne@69: * - lzma_block_total_size() jpayne@69: * - lzma_block_encoder() jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_encode() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: */ jpayne@69: lzma_check check; jpayne@69: jpayne@69: /** jpayne@69: * \brief Size of the Compressed Data in bytes jpayne@69: * jpayne@69: * Encoding: If this is not LZMA_VLI_UNKNOWN, Block Header encoder jpayne@69: * will store this value to the Block Header. Block encoder doesn't jpayne@69: * care about this value, but will set it once the encoding has been jpayne@69: * finished. jpayne@69: * jpayne@69: * Decoding: If this is not LZMA_VLI_UNKNOWN, Block decoder will jpayne@69: * verify that the size of the Compressed Data field matches jpayne@69: * compressed_size. jpayne@69: * jpayne@69: * Usually you don't know this value when encoding in streamed mode, jpayne@69: * and thus cannot write this field into the Block Header. jpayne@69: * jpayne@69: * In non-streamed mode you can reserve space for this field before jpayne@69: * encoding the actual Block. After encoding the data, finish the jpayne@69: * Block by encoding the Block Header. Steps in detail: jpayne@69: * jpayne@69: * - Set compressed_size to some big enough value. If you don't know jpayne@69: * better, use LZMA_VLI_MAX, but remember that bigger values take jpayne@69: * more space in Block Header. jpayne@69: * jpayne@69: * - Call lzma_block_header_size() to see how much space you need to jpayne@69: * reserve for the Block Header. jpayne@69: * jpayne@69: * - Encode the Block using lzma_block_encoder() and lzma_code(). jpayne@69: * It sets compressed_size to the correct value. jpayne@69: * jpayne@69: * - Use lzma_block_header_encode() to encode the Block Header. jpayne@69: * Because space was reserved in the first step, you don't need jpayne@69: * to call lzma_block_header_size() anymore, because due to jpayne@69: * reserving, header_size has to be big enough. If it is "too big", jpayne@69: * lzma_block_header_encode() will add enough Header Padding to jpayne@69: * make Block Header to match the size specified by header_size. jpayne@69: * jpayne@69: * Read by: jpayne@69: * - lzma_block_header_size() jpayne@69: * - lzma_block_header_encode() jpayne@69: * - lzma_block_compressed_size() jpayne@69: * - lzma_block_unpadded_size() jpayne@69: * - lzma_block_total_size() jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: * jpayne@69: * Written by: jpayne@69: * - lzma_block_header_decode() jpayne@69: * - lzma_block_compressed_size() jpayne@69: * - lzma_block_encoder() jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_encode() jpayne@69: * - lzma_block_uncomp_encode() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: */ jpayne@69: lzma_vli compressed_size; jpayne@69: jpayne@69: /** jpayne@69: * \brief Uncompressed Size in bytes jpayne@69: * jpayne@69: * This is handled very similarly to compressed_size above. jpayne@69: * jpayne@69: * uncompressed_size is needed by fewer functions than jpayne@69: * compressed_size. This is because uncompressed_size isn't jpayne@69: * needed to validate that Block stays within proper limits. jpayne@69: * jpayne@69: * Read by: jpayne@69: * - lzma_block_header_size() jpayne@69: * - lzma_block_header_encode() jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: * jpayne@69: * Written by: jpayne@69: * - lzma_block_header_decode() jpayne@69: * - lzma_block_encoder() jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_encode() jpayne@69: * - lzma_block_uncomp_encode() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: */ jpayne@69: lzma_vli uncompressed_size; jpayne@69: jpayne@69: /** jpayne@69: * \brief Array of filters jpayne@69: * jpayne@69: * There can be 1-4 filters. The end of the array is marked with jpayne@69: * .id = LZMA_VLI_UNKNOWN. jpayne@69: * jpayne@69: * Read by: jpayne@69: * - lzma_block_header_size() jpayne@69: * - lzma_block_header_encode() jpayne@69: * - lzma_block_encoder() jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_encode() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: * jpayne@69: * Written by: jpayne@69: * - lzma_block_header_decode(): Note that this does NOT free() jpayne@69: * the old filter options structures. All unused filters[] will jpayne@69: * have .id == LZMA_VLI_UNKNOWN and .options == NULL. If jpayne@69: * decoding fails, all filters[] are guaranteed to be jpayne@69: * LZMA_VLI_UNKNOWN and NULL. jpayne@69: * jpayne@69: * \note Because of the array is terminated with jpayne@69: * .id = LZMA_VLI_UNKNOWN, the actual array must jpayne@69: * have LZMA_FILTERS_MAX + 1 members or the Block jpayne@69: * Header decoder will overflow the buffer. jpayne@69: */ jpayne@69: lzma_filter *filters; jpayne@69: jpayne@69: /** jpayne@69: * \brief Raw value stored in the Check field jpayne@69: * jpayne@69: * After successful coding, the first lzma_check_size(check) bytes jpayne@69: * of this array contain the raw value stored in the Check field. jpayne@69: * jpayne@69: * Note that CRC32 and CRC64 are stored in little endian byte order. jpayne@69: * Take it into account if you display the Check values to the user. jpayne@69: * jpayne@69: * Written by: jpayne@69: * - lzma_block_encoder() jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_encode() jpayne@69: * - lzma_block_uncomp_encode() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: */ jpayne@69: uint8_t raw_check[LZMA_CHECK_SIZE_MAX]; jpayne@69: jpayne@69: /* jpayne@69: * Reserved space to allow possible future extensions without jpayne@69: * breaking the ABI. You should not touch these, because the names jpayne@69: * of these variables may change. These are and will never be used jpayne@69: * with the currently supported options, so it is safe to leave these jpayne@69: * uninitialized. jpayne@69: */ jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: void *reserved_ptr1; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: void *reserved_ptr2; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: void *reserved_ptr3; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: uint32_t reserved_int1; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: uint32_t reserved_int2; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_vli reserved_int3; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_vli reserved_int4; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_vli reserved_int5; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_vli reserved_int6; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_vli reserved_int7; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_vli reserved_int8; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_reserved_enum reserved_enum1; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_reserved_enum reserved_enum2; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_reserved_enum reserved_enum3; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_reserved_enum reserved_enum4; jpayne@69: jpayne@69: /** jpayne@69: * \brief A flag to Block decoder to not verify the Check field jpayne@69: * jpayne@69: * This member is supported by liblzma >= 5.1.4beta if .version >= 1. jpayne@69: * jpayne@69: * If this is set to true, the integrity check won't be calculated jpayne@69: * and verified. Unless you know what you are doing, you should jpayne@69: * leave this to false. (A reason to set this to true is when the jpayne@69: * file integrity is verified externally anyway and you want to jpayne@69: * speed up the decompression, which matters mostly when using jpayne@69: * SHA-256 as the integrity check.) jpayne@69: * jpayne@69: * If .version >= 1, read by: jpayne@69: * - lzma_block_decoder() jpayne@69: * - lzma_block_buffer_decode() jpayne@69: * jpayne@69: * Written by (.version is ignored): jpayne@69: * - lzma_block_header_decode() always sets this to false jpayne@69: */ jpayne@69: lzma_bool ignore_check; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_bool reserved_bool2; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_bool reserved_bool3; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_bool reserved_bool4; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_bool reserved_bool5; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_bool reserved_bool6; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_bool reserved_bool7; jpayne@69: jpayne@69: /** \private Reserved member. */ jpayne@69: lzma_bool reserved_bool8; jpayne@69: jpayne@69: } lzma_block; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Decode the Block Header Size field jpayne@69: * jpayne@69: * To decode Block Header using lzma_block_header_decode(), the size of the jpayne@69: * Block Header has to be known and stored into lzma_block.header_size. jpayne@69: * The size can be calculated from the first byte of a Block using this macro. jpayne@69: * Note that if the first byte is 0x00, it indicates beginning of Index; use jpayne@69: * this macro only when the byte is not 0x00. jpayne@69: * jpayne@69: * There is no encoding macro because lzma_block_header_size() and jpayne@69: * lzma_block_header_encode() should be used. jpayne@69: */ jpayne@69: #define lzma_block_header_size_decode(b) (((uint32_t)(b) + 1) * 4) jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Calculate Block Header Size jpayne@69: * jpayne@69: * Calculate the minimum size needed for the Block Header field using the jpayne@69: * settings specified in the lzma_block structure. Note that it is OK to jpayne@69: * increase the calculated header_size value as long as it is a multiple of jpayne@69: * four and doesn't exceed LZMA_BLOCK_HEADER_SIZE_MAX. Increasing header_size jpayne@69: * just means that lzma_block_header_encode() will add Header Padding. jpayne@69: * jpayne@69: * \note This doesn't check that all the options are valid i.e. this jpayne@69: * may return LZMA_OK even if lzma_block_header_encode() or jpayne@69: * lzma_block_encoder() would fail. If you want to validate the jpayne@69: * filter chain, consider using lzma_memlimit_encoder() which as jpayne@69: * a side-effect validates the filter chain. jpayne@69: * jpayne@69: * \param block Block options jpayne@69: * jpayne@69: * \return Possible lzma_ret values: jpayne@69: * - LZMA_OK: Size calculated successfully and stored to jpayne@69: * block->header_size. jpayne@69: * - LZMA_OPTIONS_ERROR: Unsupported version, filters or jpayne@69: * filter options. jpayne@69: * - LZMA_PROG_ERROR: Invalid values like compressed_size == 0. jpayne@69: */ jpayne@69: extern LZMA_API(lzma_ret) lzma_block_header_size(lzma_block *block) jpayne@69: lzma_nothrow lzma_attr_warn_unused_result; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Encode Block Header jpayne@69: * jpayne@69: * The caller must have calculated the size of the Block Header already with jpayne@69: * lzma_block_header_size(). If a value larger than the one calculated by jpayne@69: * lzma_block_header_size() is used, the Block Header will be padded to the jpayne@69: * specified size. jpayne@69: * jpayne@69: * \param block Block options to be encoded. jpayne@69: * \param[out] out Beginning of the output buffer. This must be jpayne@69: * at least block->header_size bytes. jpayne@69: * jpayne@69: * \return Possible lzma_ret values: jpayne@69: * - LZMA_OK: Encoding was successful. block->header_size jpayne@69: * bytes were written to output buffer. jpayne@69: * - LZMA_OPTIONS_ERROR: Invalid or unsupported options. jpayne@69: * - LZMA_PROG_ERROR: Invalid arguments, for example jpayne@69: * block->header_size is invalid or block->filters is NULL. jpayne@69: */ jpayne@69: extern LZMA_API(lzma_ret) lzma_block_header_encode( jpayne@69: const lzma_block *block, uint8_t *out) jpayne@69: lzma_nothrow lzma_attr_warn_unused_result; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Decode Block Header jpayne@69: * jpayne@69: * block->version should (usually) be set to the highest value supported jpayne@69: * by the application. If the application sets block->version to a value jpayne@69: * higher than supported by the current liblzma version, this function will jpayne@69: * downgrade block->version to the highest value supported by it. Thus one jpayne@69: * should check the value of block->version after calling this function if jpayne@69: * block->version was set to a non-zero value and the application doesn't jpayne@69: * otherwise know that the liblzma version being used is new enough to jpayne@69: * support the specified block->version. jpayne@69: * jpayne@69: * The size of the Block Header must have already been decoded with jpayne@69: * lzma_block_header_size_decode() macro and stored to block->header_size. jpayne@69: * jpayne@69: * The integrity check type from Stream Header must have been stored jpayne@69: * to block->check. jpayne@69: * jpayne@69: * block->filters must have been allocated, but they don't need to be jpayne@69: * initialized (possible existing filter options are not freed). jpayne@69: * jpayne@69: * \param[out] block Destination for Block options jpayne@69: * \param allocator lzma_allocator for custom allocator functions. jpayne@69: * Set to NULL to use malloc() (and also free() jpayne@69: * if an error occurs). jpayne@69: * \param in Beginning of the input buffer. This must be jpayne@69: * at least block->header_size bytes. jpayne@69: * jpayne@69: * \return Possible lzma_ret values: jpayne@69: * - LZMA_OK: Decoding was successful. block->header_size jpayne@69: * bytes were read from the input buffer. jpayne@69: * - LZMA_OPTIONS_ERROR: The Block Header specifies some jpayne@69: * unsupported options such as unsupported filters. This can jpayne@69: * happen also if block->version was set to a too low value jpayne@69: * compared to what would be required to properly represent jpayne@69: * the information stored in the Block Header. jpayne@69: * - LZMA_DATA_ERROR: Block Header is corrupt, for example, jpayne@69: * the CRC32 doesn't match. jpayne@69: * - LZMA_PROG_ERROR: Invalid arguments, for example jpayne@69: * block->header_size is invalid or block->filters is NULL. jpayne@69: */ jpayne@69: extern LZMA_API(lzma_ret) lzma_block_header_decode(lzma_block *block, jpayne@69: const lzma_allocator *allocator, const uint8_t *in) jpayne@69: lzma_nothrow lzma_attr_warn_unused_result; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Validate and set Compressed Size according to Unpadded Size jpayne@69: * jpayne@69: * Block Header stores Compressed Size, but Index has Unpadded Size. If the jpayne@69: * application has already parsed the Index and is now decoding Blocks, jpayne@69: * it can calculate Compressed Size from Unpadded Size. This function does jpayne@69: * exactly that with error checking: jpayne@69: * jpayne@69: * - Compressed Size calculated from Unpadded Size must be positive integer, jpayne@69: * that is, Unpadded Size must be big enough that after Block Header and jpayne@69: * Check fields there's still at least one byte for Compressed Size. jpayne@69: * jpayne@69: * - If Compressed Size was present in Block Header, the new value jpayne@69: * calculated from Unpadded Size is compared against the value jpayne@69: * from Block Header. jpayne@69: * jpayne@69: * \note This function must be called _after_ decoding the Block Header jpayne@69: * field so that it can properly validate Compressed Size if it jpayne@69: * was present in Block Header. jpayne@69: * jpayne@69: * \param block Block options: block->header_size must jpayne@69: * already be set with lzma_block_header_size(). jpayne@69: * \param unpadded_size Unpadded Size from the Index field in bytes jpayne@69: * jpayne@69: * \return Possible lzma_ret values: jpayne@69: * - LZMA_OK: block->compressed_size was set successfully. jpayne@69: * - LZMA_DATA_ERROR: unpadded_size is too small compared to jpayne@69: * block->header_size and lzma_check_size(block->check). jpayne@69: * - LZMA_PROG_ERROR: Some values are invalid. For example, jpayne@69: * block->header_size must be a multiple of four and jpayne@69: * between 8 and 1024 inclusive. jpayne@69: */ jpayne@69: extern LZMA_API(lzma_ret) lzma_block_compressed_size( jpayne@69: lzma_block *block, lzma_vli unpadded_size) jpayne@69: lzma_nothrow lzma_attr_warn_unused_result; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Calculate Unpadded Size jpayne@69: * jpayne@69: * The Index field stores Unpadded Size and Uncompressed Size. The latter jpayne@69: * can be taken directly from the lzma_block structure after coding a Block, jpayne@69: * but Unpadded Size needs to be calculated from Block Header Size, jpayne@69: * Compressed Size, and size of the Check field. This is where this function jpayne@69: * is needed. jpayne@69: * jpayne@69: * \param block Block options: block->header_size must already be jpayne@69: * set with lzma_block_header_size(). jpayne@69: * jpayne@69: * \return Unpadded Size on success, or zero on error. jpayne@69: */ jpayne@69: extern LZMA_API(lzma_vli) lzma_block_unpadded_size(const lzma_block *block) jpayne@69: lzma_nothrow lzma_attr_pure; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Calculate the total encoded size of a Block jpayne@69: * jpayne@69: * This is equivalent to lzma_block_unpadded_size() except that the returned jpayne@69: * value includes the size of the Block Padding field. jpayne@69: * jpayne@69: * \param block Block options: block->header_size must already be jpayne@69: * set with lzma_block_header_size(). jpayne@69: * jpayne@69: * \return On success, total encoded size of the Block. On error, jpayne@69: * zero is returned. jpayne@69: */ jpayne@69: extern LZMA_API(lzma_vli) lzma_block_total_size(const lzma_block *block) jpayne@69: lzma_nothrow lzma_attr_pure; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Initialize .xz Block encoder jpayne@69: * jpayne@69: * Valid actions for lzma_code() are LZMA_RUN, LZMA_SYNC_FLUSH (only if the jpayne@69: * filter chain supports it), and LZMA_FINISH. jpayne@69: * jpayne@69: * The Block encoder encodes the Block Data, Block Padding, and Check value. jpayne@69: * It does NOT encode the Block Header which can be encoded with jpayne@69: * lzma_block_header_encode(). jpayne@69: * jpayne@69: * \param strm Pointer to lzma_stream that is at least initialized jpayne@69: * with LZMA_STREAM_INIT. jpayne@69: * \param block Block options: block->version, block->check, jpayne@69: * and block->filters must have been initialized. jpayne@69: * jpayne@69: * \return Possible lzma_ret values: jpayne@69: * - LZMA_OK: All good, continue with lzma_code(). jpayne@69: * - LZMA_MEM_ERROR jpayne@69: * - LZMA_OPTIONS_ERROR jpayne@69: * - LZMA_UNSUPPORTED_CHECK: block->check specifies a Check ID jpayne@69: * that is not supported by this build of liblzma. Initializing jpayne@69: * the encoder failed. jpayne@69: * - LZMA_PROG_ERROR jpayne@69: */ jpayne@69: extern LZMA_API(lzma_ret) lzma_block_encoder( jpayne@69: lzma_stream *strm, lzma_block *block) jpayne@69: lzma_nothrow lzma_attr_warn_unused_result; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Initialize .xz Block decoder jpayne@69: * jpayne@69: * Valid actions for lzma_code() are LZMA_RUN and LZMA_FINISH. Using jpayne@69: * LZMA_FINISH is not required. It is supported only for convenience. jpayne@69: * jpayne@69: * The Block decoder decodes the Block Data, Block Padding, and Check value. jpayne@69: * It does NOT decode the Block Header which can be decoded with jpayne@69: * lzma_block_header_decode(). jpayne@69: * jpayne@69: * \param strm Pointer to lzma_stream that is at least initialized jpayne@69: * with LZMA_STREAM_INIT. jpayne@69: * \param block Block options jpayne@69: * jpayne@69: * \return Possible lzma_ret values: jpayne@69: * - LZMA_OK: All good, continue with lzma_code(). jpayne@69: * - LZMA_PROG_ERROR jpayne@69: * - LZMA_MEM_ERROR jpayne@69: */ jpayne@69: extern LZMA_API(lzma_ret) lzma_block_decoder( jpayne@69: lzma_stream *strm, lzma_block *block) jpayne@69: lzma_nothrow lzma_attr_warn_unused_result; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Calculate maximum output size for single-call Block encoding jpayne@69: * jpayne@69: * This is equivalent to lzma_stream_buffer_bound() but for .xz Blocks. jpayne@69: * See the documentation of lzma_stream_buffer_bound(). jpayne@69: * jpayne@69: * \param uncompressed_size Size of the data to be encoded with the jpayne@69: * single-call Block encoder. jpayne@69: * jpayne@69: * \return Maximum output size in bytes for single-call Block encoding. jpayne@69: */ jpayne@69: extern LZMA_API(size_t) lzma_block_buffer_bound(size_t uncompressed_size) jpayne@69: lzma_nothrow; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Single-call .xz Block encoder jpayne@69: * jpayne@69: * In contrast to the multi-call encoder initialized with jpayne@69: * lzma_block_encoder(), this function encodes also the Block Header. This jpayne@69: * is required to make it possible to write appropriate Block Header also jpayne@69: * in case the data isn't compressible, and different filter chain has to be jpayne@69: * used to encode the data in uncompressed form using uncompressed chunks jpayne@69: * of the LZMA2 filter. jpayne@69: * jpayne@69: * When the data isn't compressible, header_size, compressed_size, and jpayne@69: * uncompressed_size are set just like when the data was compressible, but jpayne@69: * it is possible that header_size is too small to hold the filter chain jpayne@69: * specified in block->filters, because that isn't necessarily the filter jpayne@69: * chain that was actually used to encode the data. lzma_block_unpadded_size() jpayne@69: * still works normally, because it doesn't read the filters array. jpayne@69: * jpayne@69: * \param block Block options: block->version, block->check, jpayne@69: * and block->filters must have been initialized. jpayne@69: * \param allocator lzma_allocator for custom allocator functions. jpayne@69: * Set to NULL to use malloc() and free(). jpayne@69: * \param in Beginning of the input buffer jpayne@69: * \param in_size Size of the input buffer jpayne@69: * \param[out] out Beginning of the output buffer jpayne@69: * \param[out] out_pos The next byte will be written to out[*out_pos]. jpayne@69: * *out_pos is updated only if encoding succeeds. jpayne@69: * \param out_size Size of the out buffer; the first byte into jpayne@69: * which no data is written to is out[out_size]. jpayne@69: * jpayne@69: * \return Possible lzma_ret values: jpayne@69: * - LZMA_OK: Encoding was successful. jpayne@69: * - LZMA_BUF_ERROR: Not enough output buffer space. jpayne@69: * - LZMA_UNSUPPORTED_CHECK jpayne@69: * - LZMA_OPTIONS_ERROR jpayne@69: * - LZMA_MEM_ERROR jpayne@69: * - LZMA_DATA_ERROR jpayne@69: * - LZMA_PROG_ERROR jpayne@69: */ jpayne@69: extern LZMA_API(lzma_ret) lzma_block_buffer_encode( jpayne@69: lzma_block *block, const lzma_allocator *allocator, jpayne@69: const uint8_t *in, size_t in_size, jpayne@69: uint8_t *out, size_t *out_pos, size_t out_size) jpayne@69: lzma_nothrow lzma_attr_warn_unused_result; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Single-call uncompressed .xz Block encoder jpayne@69: * jpayne@69: * This is like lzma_block_buffer_encode() except this doesn't try to jpayne@69: * compress the data and instead encodes the data using LZMA2 uncompressed jpayne@69: * chunks. The required output buffer size can be determined with jpayne@69: * lzma_block_buffer_bound(). jpayne@69: * jpayne@69: * Since the data won't be compressed, this function ignores block->filters. jpayne@69: * This function doesn't take lzma_allocator because this function doesn't jpayne@69: * allocate any memory from the heap. jpayne@69: * jpayne@69: * \param block Block options: block->version, block->check, jpayne@69: * and block->filters must have been initialized. jpayne@69: * \param in Beginning of the input buffer jpayne@69: * \param in_size Size of the input buffer jpayne@69: * \param[out] out Beginning of the output buffer jpayne@69: * \param[out] out_pos The next byte will be written to out[*out_pos]. jpayne@69: * *out_pos is updated only if encoding succeeds. jpayne@69: * \param out_size Size of the out buffer; the first byte into jpayne@69: * which no data is written to is out[out_size]. jpayne@69: * jpayne@69: * \return Possible lzma_ret values: jpayne@69: * - LZMA_OK: Encoding was successful. jpayne@69: * - LZMA_BUF_ERROR: Not enough output buffer space. jpayne@69: * - LZMA_UNSUPPORTED_CHECK jpayne@69: * - LZMA_OPTIONS_ERROR jpayne@69: * - LZMA_MEM_ERROR jpayne@69: * - LZMA_DATA_ERROR jpayne@69: * - LZMA_PROG_ERROR jpayne@69: */ jpayne@69: extern LZMA_API(lzma_ret) lzma_block_uncomp_encode(lzma_block *block, jpayne@69: const uint8_t *in, size_t in_size, jpayne@69: uint8_t *out, size_t *out_pos, size_t out_size) jpayne@69: lzma_nothrow lzma_attr_warn_unused_result; jpayne@69: jpayne@69: jpayne@69: /** jpayne@69: * \brief Single-call .xz Block decoder jpayne@69: * jpayne@69: * This is single-call equivalent of lzma_block_decoder(), and requires that jpayne@69: * the caller has already decoded Block Header and checked its memory usage. jpayne@69: * jpayne@69: * \param block Block options jpayne@69: * \param allocator lzma_allocator for custom allocator functions. jpayne@69: * Set to NULL to use malloc() and free(). jpayne@69: * \param in Beginning of the input buffer jpayne@69: * \param in_pos The next byte will be read from in[*in_pos]. jpayne@69: * *in_pos is updated only if decoding succeeds. jpayne@69: * \param in_size Size of the input buffer; the first byte that jpayne@69: * won't be read is in[in_size]. jpayne@69: * \param[out] out Beginning of the output buffer jpayne@69: * \param[out] out_pos The next byte will be written to out[*out_pos]. jpayne@69: * *out_pos is updated only if encoding succeeds. jpayne@69: * \param out_size Size of the out buffer; the first byte into jpayne@69: * which no data is written to is out[out_size]. jpayne@69: * jpayne@69: * \return Possible lzma_ret values: jpayne@69: * - LZMA_OK: Decoding was successful. jpayne@69: * - LZMA_OPTIONS_ERROR jpayne@69: * - LZMA_DATA_ERROR jpayne@69: * - LZMA_MEM_ERROR jpayne@69: * - LZMA_BUF_ERROR: Output buffer was too small. jpayne@69: * - LZMA_PROG_ERROR jpayne@69: */ jpayne@69: extern LZMA_API(lzma_ret) lzma_block_buffer_decode( jpayne@69: lzma_block *block, const lzma_allocator *allocator, jpayne@69: const uint8_t *in, size_t *in_pos, size_t in_size, jpayne@69: uint8_t *out, size_t *out_pos, size_t out_size) jpayne@69: lzma_nothrow;