]> granicus.if.org Git - xz/commitdiff
Filter handling cleanups
authorLasse Collin <lasse.collin@tukaani.org>
Wed, 10 Sep 2008 13:44:32 +0000 (16:44 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Wed, 10 Sep 2008 13:44:32 +0000 (16:44 +0300)
src/liblzma/api/lzma/filter.h
src/liblzma/common/filter_common.h
src/liblzma/common/filter_decoder.c
src/liblzma/common/filter_decoder.h
src/liblzma/common/filter_encoder.c
src/liblzma/common/filter_encoder.h

index d5903f898862d5ac9b65b39e31d22eb33bf24fef..f9c30d5e6665e69a8b833da5af2a420c90a77efd 100644 (file)
@@ -55,59 +55,55 @@ typedef struct {
 
 
 /**
- * \brief       Filters available for encoding
+ * \brief       Test if the given Filter ID is supported for encoding
  *
- * Pointer to an array containing the list of available Filter IDs that
- * can be used for encoding. The last element is LZMA_VLI_VALUE_UNKNOWN.
+ * Returns true if the give Filter ID  is supported for encoding by this
+ * liblzma build. Otherwise false is returned.
  *
- * If lzma_available_filter_encoders[0] == LZMA_VLI_VALUE_UNKNOWN, the
- * encoder components haven't been built at all. This means that the
- * encoding-specific functions are probably missing from the library
- * API/ABI completely.
+ * There is no way to list which filters are available in this particular
+ * liblzma version and build. It would be useless, because the application
+ * couldn't know what kind of options the filter would need.
  */
-extern const lzma_vli *const lzma_filter_encoders;
+extern lzma_bool lzma_filter_encoder_is_supported(lzma_vli id);
 
 
 /**
- * \brief       Filters available for decoding
+ * \brief       Test if the given Filter ID is supported for decoding
  *
- * Pointer to an array containing the list of available Filter IDs that
- * can be used for decoding. The last element is LZMA_VLI_VALUE_UNKNOWN.
- *
- * If lzma_available_filter_decoders[0] == LZMA_VLI_VALUE_UNKNOWN, the
- * decoder components haven't been built at all. This means that the
- * decoding-specific functions are probably missing from the library
- * API/ABI completely.
+ * Returns true if the give Filter ID  is supported for decoding by this
+ * liblzma build. Otherwise false is returned.
  */
-extern const lzma_vli *const lzma_filter_decoders;
+extern lzma_bool lzma_filter_decoder_is_supported(lzma_vli id);
 
 
 /**
- * \brief       Calculate rough memory requirements for given filter chain
+ * \brief       Calculate rough memory requirements for raw encoder
  *
  * \param       filters     Array of filters terminated with
  *                          .id == LZMA_VLI_VALUE_UNKNOWN.
  *
- * \return      Number of mebibytes (MiB i.e. 2^20) required for the given
- *              encoder or decoder filter chain.
- *
- * \note        If calculating memory requirements of encoder, lzma_init() or
- *              lzma_init_encoder() must have been called earlier. Similarly,
- *              if calculating memory requirements of decoder, lzma_init() or
- *              lzma_init_decoder() must have been called earlier.
+ * \return      Rough number of bytes required for the given filter chain
+ *              when encoding.
  */
-// extern uint32_t lzma_memory_usage(
-//             const lzma_filter *filters, lzma_bool is_encoder);
-
 extern uint64_t lzma_memusage_encoder(const lzma_filter *filters)
                lzma_attr_pure;
 
+
+/**
+ * \brief       Calculate rough memory requirements for raw decoder
+ *
+ * \param       filters     Array of filters terminated with
+ *                          .id == LZMA_VLI_VALUE_UNKNOWN.
+ *
+ * \return      Rough number of bytes required for the given filter chain
+ *              when decoding.
+ */
 extern uint64_t lzma_memusage_decoder(const lzma_filter *filters)
                lzma_attr_pure;
 
 
 /**
- * \brief       Initializes raw encoder
+ * \brief       Initialize raw encoder
  *
  * This function may be useful when implementing custom file formats.
  *
@@ -131,11 +127,12 @@ extern lzma_ret lzma_raw_encoder(
 
 
 /**
- * \brief       Initializes raw decoder
+ * \brief       Initialize raw decoder
  *
  * The initialization of raw decoder goes similarly to raw encoder.
  *
- * The `action' with lzma_code() can be LZMA_RUN or LZMA_SYNC_FLUSH.
+ * The `action' with lzma_code() can be LZMA_RUN or LZMA_FINISH. Using
+ * LZMA_FINISH is not required, it is supported just for convenience.
  *
  * \return      - LZMA_OK
  *              - LZMA_MEM_ERROR
@@ -147,6 +144,80 @@ extern lzma_ret lzma_raw_decoder(
                lzma_attr_warn_unused_result;
 
 
+/**
+ * \brief       Get the size of the Filter Properties field
+ *
+ * This function may be useful when implementing custom file formats
+ * using the raw encoder and decoder.
+ *
+ * \param       size    Pointer to uint32_t to hold the size of the properties
+ * \param       filter  Filter ID and options (the size of the propeties may
+ *                      vary depending on the options)
+ *
+ * \return      - LZMA_OK
+ *              - LZMA_HEADER_ERROR
+ *              - LZMA_PROG_ERROR
+ *
+ * \note        This function validates the Filter ID, but does not
+ *              necessarily validate the options. Thus, it is possible
+ *              that this returns LZMA_OK while the following call to
+ *              lzma_properties_encode() returns LZMA_HEADER_ERROR.
+ */
+extern lzma_ret lzma_properties_size(
+               uint32_t *size, const lzma_filter *filter);
+
+
+/**
+ * \brief       Encode the Filter Properties field
+ *
+ * \param       filter  Filter ID and options
+ * \param       props   Buffer to hold the encoded options. The size of
+ *                      buffer must have been already determined with
+ *                      lzma_properties_size().
+ *
+ * \return      - LZMA_OK
+ *              - LZMA_HEADER_ERROR
+ *              - LZMA_PROG_ERROR
+ *
+ * \note        Even this function won't validate more options than actually
+ *              necessary. Thus, it is possible that encoding the properties
+ *              succeeds but using the same options to initialize the encoder
+ *              will fail.
+ *
+ * \note        It is OK to skip calling this function if
+ *              lzma_properties_size() indicated that the size
+ *              of the Filter Properties field is zero.
+ */
+extern lzma_ret lzma_properties_encode(
+               const lzma_filter *filter, uint8_t *props);
+
+
+/**
+ * \brief       Decode the Filter Properties field
+ *
+ * \param       filter      filter->id must have been set to the correct
+ *                          Filter ID. filter->options doesn't need to be
+ *                          initialized (it's not freed by this function). The
+ *                          decoded options will be stored to filter->options.
+ *                          filter->options is set to NULL if there are no
+ *                          properties or if an error occurs.
+ * \param       allocator   Custom memory allocator used to allocate the
+ *                          options. Set to NULL to use the default malloc(),
+ *                          and in case of an error, also free().
+ * \param       props       Input buffer containing the properties.
+ * \param       props_size  Size of the properties. This must be the exact
+ *                          size; giving too much or too little input will
+ *                          return LZMA_HEADER_ERROR.
+ *
+ * \return      - LZMA_OK
+ *              - LZMA_HEADER_ERROR
+ *              - LZMA_MEM_ERROR
+ */
+extern lzma_ret lzma_properties_decode(
+               lzma_filter *filter, lzma_allocator *allocator,
+               const uint8_t *props, size_t props_size);
+
+
 /**
  * \brief       Calculates encoded size of a Filter Flags field
  *
index 9def50b9fa6eefe7a6689c11da60a1a6144728eb..5241e5dfb304dce662b32a79b3370571ea364783 100644 (file)
@@ -25,6 +25,9 @@
 
 /// Both lzma_filter_encoder and lzma_filter_decoder begin with these members.
 typedef struct {
+       /// Filter ID
+       lzma_vli id;
+
        /// Initializes the filter encoder and calls lzma_next_filter_init()
        /// for filters + 1.
        lzma_init_function init;
index 5eb6d770356dbd5f48e3a1357dbcb24d107526af..fb5632e86e30dc2365f71347782e306a3c243a8b 100644 (file)
@@ -28,6 +28,9 @@
 
 
 typedef struct {
+       /// Filter ID
+       lzma_vli id;
+
        /// Initializes the filter encoder and calls lzma_next_filter_init()
        /// for filters + 1.
        lzma_init_function init;
@@ -47,60 +50,10 @@ typedef struct {
 } lzma_filter_decoder;
 
 
-static const lzma_vli ids[] = {
-#ifdef HAVE_DECODER_LZMA
-       LZMA_FILTER_LZMA,
-#endif
-
-#ifdef HAVE_DECODER_LZMA2
-       LZMA_FILTER_LZMA2,
-#endif
-
-#ifdef HAVE_DECODER_SUBBLOCK
-       LZMA_FILTER_SUBBLOCK,
-       LZMA_FILTER_SUBBLOCK_HELPER,
-#endif
-
-#ifdef HAVE_DECODER_X86
-       LZMA_FILTER_X86,
-#endif
-
-#ifdef HAVE_DECODER_POWERPC
-       LZMA_FILTER_POWERPC,
-#endif
-
-#ifdef HAVE_DECODER_IA64
-       LZMA_FILTER_IA64,
-#endif
-
-#ifdef HAVE_DECODER_ARM
-       LZMA_FILTER_ARM,
-#endif
-
-#ifdef HAVE_DECODER_ARMTHUMB
-       LZMA_FILTER_ARMTHUMB,
-#endif
-
-#ifdef HAVE_DECODER_SPARC
-       LZMA_FILTER_SPARC,
-#endif
-
-#ifdef HAVE_DECODER_DELTA
-       LZMA_FILTER_DELTA,
-#endif
-
-       LZMA_VLI_VALUE_UNKNOWN
-};
-
-
-// Using a pointer to avoid putting the size of the array to API/ABI.
-LZMA_API const lzma_vli *const lzma_filter_decoders = ids;
-
-
-// These must be in the same order as ids[].
-static const lzma_filter_decoder funcs[] = {
+static const lzma_filter_decoder decoders[] = {
 #ifdef HAVE_DECODER_LZMA
        {
+               .id = LZMA_FILTER_LZMA,
                .init = &lzma_lzma_decoder_init,
                .memusage = &lzma_lzma_decoder_memusage,
                .props_decode = &lzma_lzma_props_decode,
@@ -108,6 +61,7 @@ static const lzma_filter_decoder funcs[] = {
 #endif
 #ifdef HAVE_DECODER_LZMA2
        {
+               .id = LZMA_FILTER_LZMA2,
                .init = &lzma_lzma2_decoder_init,
                .memusage = &lzma_lzma2_decoder_memusage,
                .props_decode = &lzma_lzma2_props_decode,
@@ -115,11 +69,13 @@ static const lzma_filter_decoder funcs[] = {
 #endif
 #ifdef HAVE_DECODER_SUBBLOCK
        {
+               .id = LZMA_FILTER_SUBBLOCK,
                .init = &lzma_subblock_decoder_init,
 //             .memusage = &lzma_subblock_decoder_memusage,
                .props_decode = NULL,
        },
        {
+               .id = LZMA_FILTER_SUBBLOCK_HELPER,
                .init = &lzma_subblock_decoder_helper_init,
                .memusage = NULL,
                .props_decode = NULL,
@@ -127,6 +83,7 @@ static const lzma_filter_decoder funcs[] = {
 #endif
 #ifdef HAVE_DECODER_X86
        {
+               .id = LZMA_FILTER_X86,
                .init = &lzma_simple_x86_decoder_init,
                .memusage = NULL,
                .props_decode = &lzma_simple_props_decode,
@@ -134,6 +91,7 @@ static const lzma_filter_decoder funcs[] = {
 #endif
 #ifdef HAVE_DECODER_POWERPC
        {
+               .id = LZMA_FILTER_POWERPC,
                .init = &lzma_simple_powerpc_decoder_init,
                .memusage = NULL,
                .props_decode = &lzma_simple_props_decode,
@@ -141,6 +99,7 @@ static const lzma_filter_decoder funcs[] = {
 #endif
 #ifdef HAVE_DECODER_IA64
        {
+               .id = LZMA_FILTER_IA64,
                .init = &lzma_simple_ia64_decoder_init,
                .memusage = NULL,
                .props_decode = &lzma_simple_props_decode,
@@ -148,6 +107,7 @@ static const lzma_filter_decoder funcs[] = {
 #endif
 #ifdef HAVE_DECODER_ARM
        {
+               .id = LZMA_FILTER_ARM,
                .init = &lzma_simple_arm_decoder_init,
                .memusage = NULL,
                .props_decode = &lzma_simple_props_decode,
@@ -155,6 +115,7 @@ static const lzma_filter_decoder funcs[] = {
 #endif
 #ifdef HAVE_DECODER_ARMTHUMB
        {
+               .id = LZMA_FILTER_ARMTHUMB,
                .init = &lzma_simple_armthumb_decoder_init,
                .memusage = NULL,
                .props_decode = &lzma_simple_props_decode,
@@ -162,6 +123,7 @@ static const lzma_filter_decoder funcs[] = {
 #endif
 #ifdef HAVE_DECODER_SPARC
        {
+               .id = LZMA_FILTER_SPARC,
                .init = &lzma_simple_sparc_decoder_init,
                .memusage = NULL,
                .props_decode = &lzma_simple_props_decode,
@@ -169,6 +131,7 @@ static const lzma_filter_decoder funcs[] = {
 #endif
 #ifdef HAVE_DECODER_DELTA
        {
+               .id = LZMA_FILTER_DELTA,
                .init = &lzma_delta_decoder_init,
                .memusage = NULL,
                .props_decode = &lzma_delta_props_decode,
@@ -180,14 +143,21 @@ static const lzma_filter_decoder funcs[] = {
 static const lzma_filter_decoder *
 decoder_find(lzma_vli id)
 {
-       for (size_t i = 0; ids[i] != LZMA_VLI_VALUE_UNKNOWN; ++i)
-               if (ids[i] == id)
-                       return funcs + i;
+       for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i)
+               if (decoders[i].id == id)
+                       return decoders + i;
 
        return NULL;
 }
 
 
+extern LZMA_API lzma_bool
+lzma_filter_decoder_is_supported(lzma_vli id)
+{
+       return decoder_find(id) != NULL;
+}
+
+
 extern lzma_ret
 lzma_raw_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
                const lzma_filter *options)
index 33e491d194c077b18d71d25e542ae16abff027f2..6d651e69bd9652d019e55f6fbd8dd93f9e59f7e7 100644 (file)
 
 #include "common.h"
 
-// FIXME !!! Public API
-extern lzma_ret lzma_properties_decode(
-               lzma_filter *filter, lzma_allocator *allocator,
-               const uint8_t *props, size_t props_size);
-
 
 extern lzma_ret lzma_raw_decoder_init(
                lzma_next_coder *next, lzma_allocator *allocator,
index 55862e1822febff6f518a3d26ddced46d7a1cc11..8f2c517fc265f5805611f6d40817b98d72b86029 100644 (file)
@@ -27,6 +27,9 @@
 
 
 typedef struct {
+       /// Filter ID
+       lzma_vli id;
+
        /// Initializes the filter encoder and calls lzma_next_filter_init()
        /// for filters + 1.
        lzma_init_function init;
@@ -58,59 +61,10 @@ typedef struct {
 } lzma_filter_encoder;
 
 
-static const lzma_vli ids[] = {
-#ifdef HAVE_ENCODER_LZMA
-       LZMA_FILTER_LZMA,
-#endif
-
-#ifdef HAVE_ENCODER_LZMA2
-       LZMA_FILTER_LZMA2,
-#endif
-
-#ifdef HAVE_ENCODER_SUBBLOCK
-       LZMA_FILTER_SUBBLOCK,
-#endif
-
-#ifdef HAVE_ENCODER_X86
-       LZMA_FILTER_X86,
-#endif
-
-#ifdef HAVE_ENCODER_POWERPC
-       LZMA_FILTER_POWERPC,
-#endif
-
-#ifdef HAVE_ENCODER_IA64
-       LZMA_FILTER_IA64,
-#endif
-
-#ifdef HAVE_ENCODER_ARM
-       LZMA_FILTER_ARM,
-#endif
-
-#ifdef HAVE_ENCODER_ARMTHUMB
-       LZMA_FILTER_ARMTHUMB,
-#endif
-
-#ifdef HAVE_ENCODER_SPARC
-       LZMA_FILTER_SPARC,
-#endif
-
-#ifdef HAVE_ENCODER_DELTA
-       LZMA_FILTER_DELTA,
-#endif
-
-       LZMA_VLI_VALUE_UNKNOWN
-};
-
-
-// Using a pointer to avoid putting the size of the array to API/ABI.
-LZMA_API const lzma_vli *const lzma_filter_encoders = ids;
-
-
-// These must be in the same order as ids[].
-static const lzma_filter_encoder funcs[] = {
+static const lzma_filter_encoder encoders[] = {
 #ifdef HAVE_ENCODER_LZMA
        {
+               .id = LZMA_FILTER_LZMA,
                .init = &lzma_lzma_encoder_init,
                .memusage = &lzma_lzma_encoder_memusage,
                .chunk_size = NULL, // FIXME
@@ -121,6 +75,7 @@ static const lzma_filter_encoder funcs[] = {
 #endif
 #ifdef HAVE_ENCODER_LZMA2
        {
+               .id = LZMA_FILTER_LZMA2,
                .init = &lzma_lzma2_encoder_init,
                .memusage = &lzma_lzma2_encoder_memusage,
                .chunk_size = NULL, // FIXME
@@ -131,6 +86,7 @@ static const lzma_filter_encoder funcs[] = {
 #endif
 #ifdef HAVE_ENCODER_SUBBLOCK
        {
+               .id = LZMA_FILTER_SUBBLOCK,
                .init = &lzma_subblock_encoder_init,
 //             .memusage = &lzma_subblock_encoder_memusage,
                .chunk_size = NULL,
@@ -141,6 +97,7 @@ static const lzma_filter_encoder funcs[] = {
 #endif
 #ifdef HAVE_ENCODER_X86
        {
+               .id = LZMA_FILTER_X86,
                .init = &lzma_simple_x86_encoder_init,
                .memusage = NULL,
                .chunk_size = NULL,
@@ -150,6 +107,7 @@ static const lzma_filter_encoder funcs[] = {
 #endif
 #ifdef HAVE_ENCODER_POWERPC
        {
+               .id = LZMA_FILTER_POWERPC,
                .init = &lzma_simple_powerpc_encoder_init,
                .memusage = NULL,
                .chunk_size = NULL,
@@ -159,6 +117,7 @@ static const lzma_filter_encoder funcs[] = {
 #endif
 #ifdef HAVE_ENCODER_IA64
        {
+               .id = LZMA_FILTER_IA64,
                .init = &lzma_simple_ia64_encoder_init,
                .memusage = NULL,
                .chunk_size = NULL,
@@ -168,6 +127,7 @@ static const lzma_filter_encoder funcs[] = {
 #endif
 #ifdef HAVE_ENCODER_ARM
        {
+               .id = LZMA_FILTER_ARM,
                .init = &lzma_simple_arm_encoder_init,
                .memusage = NULL,
                .chunk_size = NULL,
@@ -177,6 +137,7 @@ static const lzma_filter_encoder funcs[] = {
 #endif
 #ifdef HAVE_ENCODER_ARMTHUMB
        {
+               .id = LZMA_FILTER_ARMTHUMB,
                .init = &lzma_simple_armthumb_encoder_init,
                .memusage = NULL,
                .chunk_size = NULL,
@@ -186,6 +147,7 @@ static const lzma_filter_encoder funcs[] = {
 #endif
 #ifdef HAVE_ENCODER_SPARC
        {
+               .id = LZMA_FILTER_SPARC,
                .init = &lzma_simple_sparc_encoder_init,
                .memusage = NULL,
                .chunk_size = NULL,
@@ -195,6 +157,7 @@ static const lzma_filter_encoder funcs[] = {
 #endif
 #ifdef HAVE_ENCODER_DELTA
        {
+               .id = LZMA_FILTER_DELTA,
                .init = &lzma_delta_encoder_init,
                .memusage = NULL,
                .chunk_size = NULL,
@@ -209,14 +172,21 @@ static const lzma_filter_encoder funcs[] = {
 static const lzma_filter_encoder *
 encoder_find(lzma_vli id)
 {
-       for (size_t i = 0; ids[i] != LZMA_VLI_VALUE_UNKNOWN; ++i)
-               if (ids[i] == id)
-                       return funcs + i;
+       for (size_t i = 0; i < ARRAY_SIZE(encoders); ++i)
+               if (encoders[i].id == id)
+                       return encoders + i;
 
        return NULL;
 }
 
 
+extern LZMA_API lzma_bool
+lzma_filter_encoder_is_supported(lzma_vli id)
+{
+       return encoder_find(id) != NULL;
+}
+
+
 extern lzma_ret
 lzma_raw_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
                const lzma_filter *options)
@@ -251,7 +221,7 @@ lzma_memusage_encoder(const lzma_filter *filters)
 extern LZMA_API lzma_vli
 lzma_chunk_size(const lzma_filter *filters)
 {
-       uint64_t max = 0;
+       lzma_vli max = 0;
 
        for (size_t i = 0; filters[i].id != LZMA_VLI_VALUE_UNKNOWN; ++i) {
                const lzma_filter_encoder *const fe
@@ -285,7 +255,7 @@ lzma_properties_size(uint32_t *size, const lzma_filter *filter)
        }
 
        if (fe->props_size_get == NULL) {
-               // No props_size() function, use props_size_fixed.
+               // No props_size_get() function, use props_size_fixed.
                *size = fe->props_size_fixed;
                return LZMA_OK;
        }
index b2bf851d3f03b6c2c6f02349c064190e02b53ace..552012584ad8bc04f2303e5ef7d9bbd84ee5d937 100644 (file)
 
 // FIXME !!! Public API
 extern lzma_vli lzma_chunk_size(const lzma_filter *filters);
-extern lzma_ret lzma_properties_size(
-               uint32_t *size, const lzma_filter *filter);
-extern lzma_ret lzma_properties_encode(
-               const lzma_filter *filter, uint8_t *props);
 
 
 extern lzma_ret lzma_raw_encoder_init(