/** * \file lzma/block.h * \brief .lzma Block handling * * \author Copyright (C) 1999-2006 Igor Pavlov * \author Copyright (C) 2007 Lasse Collin * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ #ifndef LZMA_H_INTERNAL # error Never include this file directly. Use instead. #endif /** * \brief Options for the Block Header encoder and decoder * * Different things 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 * later calls to lzma_code(). */ 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. * * Read by: * - lzma_block_encoder() * - lzma_block_decoder() */ lzma_check_type check; /** * \brief Precense of CRC32 of the Block Header * * Set this to true if CRC32 of the Block Header should be * calculated and stored in the Block Header. * * There is no way to autodetect if CRC32 is present in the Block * Header, thus this information must be provided also when decoding. * * Read by: * - lzma_block_header_size() * - lzma_block_header_encoder() * - lzma_block_header_decoder() */ lzma_bool has_crc32; /** * \brief Usage of End of Payload Marker * * If this is true, End of Payload Marker is used even if * Uncompressed Size is known. * * Read by: * - lzma_block_header_encoder() * - lzma_block_encoder() * - lzma_block_decoder() * * Written by: * - lzma_block_header_decoder() */ lzma_bool has_eopm; /** * \brief True if the Block is a Metadata Block * * If this is true, the Metadata bit will be set in the Block Header. * It is up to the application to store correctly formatted data * into Metadata Block. * * Read by: * - lzma_block_header_encoder() * * Written by: * - lzma_block_header_decoder() */ lzma_bool is_metadata; /** * \brief True if Uncompressed Size is in Block Footer * * Read by: * - lzma_block_encoder() * - lzma_block_decoder() */ lzma_bool has_uncompressed_size_in_footer; /** * \brief True if Backward Size is in Block Footer * * Read by: * - lzma_block_encoder() * - lzma_block_decoder() */ lzma_bool has_backward_size; /** * \brief True if Block coder should take care of Padding * * In liblzma, Stream decoder sets this to true when decoding * Header Metadata Block or Data Blocks from Multi-Block Stream, * and to false when decoding Single-Block Stream or Footer * Metadata Block from a Multi-Block Stream. * * Read by: * - lzma_block_encoder() * - lzma_block_decoder() */ lzma_bool handle_padding; /** * \brief Size of the Compressed Data in bytes * * 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. * * Read by: * - lzma_block_header_size() * - lzma_block_header_encoder() * - lzma_block_encoder() * - lzma_block_decoder() * * Written by: * - lzma_block_header_decoder() * - lzma_block_encoder() * - lzma_block_decoder() */ lzma_vli compressed_size; /** * \brief Uncompressed Size in bytes * * Encoder: If this value is not LZMA_VLI_VALUE_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_HEADER_ERROR is returned. * * If Uncompressed Size is unknown, End of Payload Marker must * be used. If uncompressed_size == LZMA_VLI_VALUE_UNKNOWN and * has_eopm == 0, LZMA_HEADER_ERROR will be returned. * * Decoder: If this value is not LZMA_VLI_VALUE_UNKNOWN, it is * compared to the real Uncompressed Size. If they do not match, * LZMA_HEADER_ERROR is returned. * * Read by: * - lzma_block_header_size() * - lzma_block_header_encoder() * - lzma_block_encoder() * - lzma_block_decoder() * * Written by: * - lzma_block_header_decoder() * - lzma_block_encoder() * - lzma_block_decoder() */ lzma_vli uncompressed_size; /** * \brief Number of bytes to reserve for Compressed Size * * This is useful if you want to be able to store the Compressed Size * to the Block Header, but you don't know it when starting to encode. * Setting this to non-zero value at maximum of LZMA_VLI_BYTES_MAX, * the Block Header encoder will force the Compressed Size field to * occupy specified number of bytes. You can later rewrite the Block * Header to contain correct information by using otherwise identical * lzma_options_block structure except the correct compressed_size. * * Read by: * - lzma_block_header_size() * - lzma_block_header_encoder() * * Written by: * - lzma_block_header_decoder() */ uint32_t compressed_reserve; /** * \brief Number of bytes to reserve for Uncompressed Size * * See the description of compressed_size above. * * Read by: * - lzma_block_header_size() * - lzma_block_header_encoder() * * Written by: * - lzma_block_header_decoder() */ uint32_t uncompressed_reserve; /** * \brief Total Size of the Block in bytes * * This is useful in the decoder, which can verify the Total Size * if it is known from Index. * * Read by: * - lzma_block_encoder() * - lzma_block_decoder() * * Written by: * - lzma_block_encoder() * - lzma_block_decoder() */ lzma_vli total_size; /** * \brief Upper limit of Total Size * * Read by: * - lzma_block_encoder() * - lzma_block_decoder() */ lzma_vli total_limit; /** * \brief Upper limit of Uncompressed Size * * Read by: * - lzma_block_encoder() * - lzma_block_decoder() */ lzma_vli uncompressed_limit; /** * \brief Array of filters * * There can be at maximum of seven filters. The end of the array * is marked with .id = LZMA_VLI_VALUE_UNKNOWN. Minimum number of * filters is zero; in that case, an implicit Copy filter is used. * * Read by: * - lzma_block_header_size() * - lzma_block_header_encoder() * - lzma_block_encoder() * - lzma_block_decoder() * * Written by: * - lzma_block_header_decoder(): Note that this does NOT free() * the old filter options structures. If decoding fails, the * caller must take care of freeing the options structures * that may have been allocated and decoded before the error * occurred. */ lzma_options_filter filters[8]; /** * \brief Size of the Padding field * * The Padding field exist to allow aligning the Compressed Data field * optimally in the Block. See lzma_options_stream.alignment in * stream.h for more information. * * If you want the Block Header encoder to automatically calculate * optimal size for the Padding field by looking at the information * in filters[], set this to LZMA_BLOCK_HEADER_PADDING_AUTO. In that * case, you must also set the aligmnet variable to tell the the * encoder the aligmnet of the beginning of the Block Header. * * The decoder never sets this to LZMA_BLOCK_HEADER_PADDING_AUTO. * * Read by: * - lzma_block_header_size() * - lzma_block_header_encoder(): Note that this doesn't * accept LZMA_BLOCK_HEADER_PADDING_AUTO. * * Written by (these never set padding to * LZMA_BLOCK_HEADER_PADDING_AUTO): * - lzma_block_header_size() * - lzma_block_header_decoder() */ int32_t padding; # define LZMA_BLOCK_HEADER_PADDING_AUTO (-1) # define LZMA_BLOCK_HEADER_PADDING_MIN 0 # define LZMA_BLOCK_HEADER_PADDING_MAX 31 /** * \brief Alignment of the beginning of the Block Header * * This variable is read only if padding has been set to * LZMA_BLOCK_HEADER_PADDING_AUTO. * * Read by: * - lzma_block_header_size() * - lzma_block_header_encoder() */ uint32_t alignment; /** * \brief Size of the Block Header * * Read by: * - lzma_block_encoder() * - lzma_block_decoder() * * Written by: * - lzma_block_header_size() * - lzma_block_header_decoder() */ uint32_t header_size; } lzma_options_block; /** * \brief Calculates the size of Header Padding and Block Header * * \return - LZMA_OK: Size calculated successfully and stored to * options->header_size. * - LZMA_HEADER_ERROR: Unsupported filters or filter options. * - LZMA_PROG_ERROR: Invalid options * * \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. */ extern lzma_ret lzma_block_header_size(lzma_options_block *options); /** * \brief Encodes 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(). * * \param out Beginning of the output buffer. This must be * at least options->header_size bytes. * \param options Block options to be encoded. * * \return - LZMA_OK: Encoding was successful. options->header_size * bytes were written to output buffer. * - LZMA_HEADER_ERROR: Invalid or unsupported options. * - LZMA_PROG_ERROR */ extern lzma_ret lzma_block_header_encode( uint8_t *out, const lzma_options_block *options); /** * \brief Initializes Block Header decoder * * Because the results of this decoder are placed into *options, * strm->next_in, strm->avail_in, and strm->total_in are not used. * * The only valid `action' with lzma_code() is LZMA_RUN. * * \return - LZMA_OK: Encoding was successful. options->header_size * bytes were written to output buffer. * - LZMA_HEADER_ERROR: Invalid or unsupported options. * - LZMA_PROG_ERROR */ extern lzma_ret lzma_block_header_decoder( lzma_stream *strm, lzma_options_block *options); /** * \brief Initializes .lzma Block encoder * * This function is required for multi-thread encoding. It may also be * useful when implementing custom file formats. * * \return - LZMA_OK: All good, continue with lzma_code(). * - LZMA_MEM_ERROR * - LZMA_HEADER_ERROR * - LZMA_DATA_ERROR: Limits (total_limit and uncompressed_limit) * have been reached already. * - LZMA_UNSUPPORTED_CHECK: options->check specfies a Check * 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_options_block *options); /** * \brief Initializes decoder for .lzma Block * * \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 * ignored. * - LZMA_PROG_ERROR * - LZMA_MEM_ERROR */ extern lzma_ret lzma_block_decoder( lzma_stream *strm, lzma_options_block *options);