]> granicus.if.org Git - xz/commitdiff
Add limit of lc + lp <= 4. Now we can allocate the
authorLasse Collin <lasse.collin@tukaani.org>
Thu, 19 Jun 2008 13:35:08 +0000 (16:35 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Thu, 19 Jun 2008 13:35:08 +0000 (16:35 +0300)
literal coder as part of the main LZMA encoder or
decoder structure.

Make the LZMA decoder to rely on the current internal API
to free the allocated memory in case an error occurs.

src/liblzma/api/lzma/lzma.h
src/liblzma/lzma/lzma_decoder.c
src/liblzma/lzma/lzma_encoder_init.c
src/liblzma/lzma/lzma_encoder_private.h
src/liblzma/lzma/lzma_literal.c
src/liblzma/lzma/lzma_literal.h

index da0bb52da7b2dfdc8d03c2dee92abb43285be948..9473f448b6f826f1bb8311116ea0c1b3173d2d1f 100644 (file)
@@ -167,7 +167,7 @@ typedef struct {
         */
        uint32_t literal_context_bits;
 #      define LZMA_LITERAL_CONTEXT_BITS_MIN       0
-#      define LZMA_LITERAL_CONTEXT_BITS_MAX       8
+#      define LZMA_LITERAL_CONTEXT_BITS_MAX       4
 #      define LZMA_LITERAL_CONTEXT_BITS_DEFAULT   3
 
        /**
@@ -278,6 +278,14 @@ typedef struct {
 } lzma_options_lzma;
 
 
+/**
+ * \brief       Maximum sum of literal_context_bits and literal_pos_bits
+ *
+ * literal_context_bits + literal_pos_bits <= LZMA_LITERAL_BITS_MAX
+ */
+#define LZMA_LITERAL_BITS_MAX 4
+
+
 /**
  * \brief       Available LZMA encoding modes
  *
index d4cefe0b72c145946deb43f2c2823ac73be0e39a..68941021ffa672bb43a1b878e9ee2d0d665e898b 100644 (file)
@@ -115,7 +115,7 @@ struct lzma_coder_s {
        uint32_t pos_mask;
        uint32_t now_pos; // Lowest 32-bits are enough here.
 
-       lzma_literal_coder *literal_coder;
+       lzma_literal_coder literal_coder;
 
        /// If 1, it's a match. Otherwise it's a single 8-bit literal.
        probability is_match[STATES][POS_STATES_MAX];
@@ -651,7 +651,6 @@ lzma_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
 {
        lzma_next_coder_end(&coder->next, allocator);
        lzma_lz_decoder_end(&coder->lz, allocator);
-       lzma_literal_end(&coder->literal_coder, allocator);
        lzma_free(coder, allocator);
        return;
 }
@@ -661,6 +660,9 @@ extern lzma_ret
 lzma_lzma_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
                const lzma_filter_info *filters)
 {
+       // LZMA can only be the last filter in the chain.
+       assert(filters[1].init == NULL);
+
        // Validate pos_bits. Other options are validated by the
        // respective initialization functions.
        const lzma_options_lzma *options = filters[0].options;
@@ -673,43 +675,25 @@ lzma_lzma_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
                if (next->coder == NULL)
                        return LZMA_MEM_ERROR;
 
-               // Initialize variables so that we know later that we don't
-               // have an existing decoder initialized.
+               next->code = &lzma_lz_decode;
+               next->end = &lzma_decoder_end;
                next->coder->next = LZMA_NEXT_CODER_INIT;
                next->coder->lz = LZMA_LZ_DECODER_INIT;
-               next->coder->literal_coder = NULL;
        }
 
        // Store the pos_bits and calculate pos_mask.
        next->coder->pos_bits = options->pos_bits;
        next->coder->pos_mask = (1U << next->coder->pos_bits) - 1;
 
-       // Allocate (if needed) and initialize the literal decoder.
-       {
-               const lzma_ret ret = lzma_literal_init(
-                               &next->coder->literal_coder, allocator,
+       // Initialize the literal decoder.
+       return_if_error(lzma_literal_init(&next->coder->literal_coder,
                                options->literal_context_bits,
-                               options->literal_pos_bits);
-               if (ret != LZMA_OK) {
-                       lzma_free(next->coder, allocator);
-                       next->coder = NULL;
-                       return ret;
-               }
-       }
+                               options->literal_pos_bits));
 
        // Allocate and initialize the LZ decoder.
-       {
-               const lzma_ret ret = lzma_lz_decoder_reset(
-                               &next->coder->lz, allocator, &decode_real,
-                               options->dictionary_size, MATCH_MAX_LEN);
-               if (ret != LZMA_OK) {
-                       lzma_literal_end(&next->coder->literal_coder,
-                                       allocator);
-                       lzma_free(next->coder, allocator);
-                       next->coder = NULL;
-                       return ret;
-               }
-       }
+       return_if_error(lzma_lz_decoder_reset(&next->coder->lz, allocator,
+                       &decode_real, options->dictionary_size,
+                       MATCH_MAX_LEN));
 
        // State
        next->coder->state = 0;
@@ -769,20 +753,6 @@ lzma_lzma_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
 
        next->coder->has_produced_output = false;
 
-       // Initialize the next decoder in the chain, if any.
-       {
-               const lzma_ret ret = lzma_next_filter_init(&next->coder->next,
-                               allocator, filters + 1);
-               if (ret != LZMA_OK) {
-                       lzma_decoder_end(next->coder, allocator);
-                       return ret;
-               }
-       }
-
-       // Initialization successful. Set the function pointers.
-       next->code = &lzma_lz_decode;
-       next->end = &lzma_decoder_end;
-
        return LZMA_OK;
 }
 
@@ -808,5 +778,6 @@ lzma_lzma_decode_properties(lzma_options_lzma *options, uint8_t byte)
        options->literal_pos_bits = byte / 9;
        options->literal_context_bits = byte - options->literal_pos_bits * 9;
 
-       return false;
+       return options->literal_context_bits + options->literal_pos_bits
+                       > LZMA_LITERAL_BITS_MAX;
 }
index c925f811a700a367a10d5edc2e2bf279c20748ae..21335f95e16fffd8ecf0ee793e50e74b4370e139 100644 (file)
@@ -52,7 +52,6 @@ static void
 lzma_lzma_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
 {
        lzma_lz_encoder_end(&coder->lz, allocator);
-       lzma_literal_end(&coder->literal_coder, allocator);
        lzma_free(coder, allocator);
        return;
 }
@@ -69,7 +68,6 @@ lzma_lzma_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
 
                next->coder->next = LZMA_NEXT_CODER_INIT;
                next->coder->lz = LZMA_LZ_ENCODER_INIT;
-               next->coder->literal_coder = NULL;
        }
 
        // Validate options that aren't validated elsewhere.
@@ -99,13 +97,11 @@ lzma_lzma_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
        // Initialize literal coder.
        {
                const lzma_ret ret = lzma_literal_init(
-                               &next->coder->literal_coder, allocator,
+                               &next->coder->literal_coder,
                                options->literal_context_bits,
                                options->literal_pos_bits);
-               if (ret != LZMA_OK) {
-                       lzma_lzma_encoder_end(next->coder, allocator);
+               if (ret != LZMA_OK)
                        return ret;
-               }
        }
 
        // Initialize LZ encoder.
@@ -218,7 +214,10 @@ lzma_lzma_encode_properties(const lzma_options_lzma *options, uint8_t *byte)
        if (options->literal_context_bits > LZMA_LITERAL_CONTEXT_BITS_MAX
                        || options->literal_pos_bits
                                > LZMA_LITERAL_POS_BITS_MAX
-                       || options->pos_bits > LZMA_POS_BITS_MAX)
+                       || options->pos_bits > LZMA_POS_BITS_MAX
+                       || options->literal_context_bits
+                                       + options->literal_pos_bits
+                               > LZMA_LITERAL_BITS_MAX)
                return true;
 
        *byte = (options->pos_bits * 5 + options->literal_pos_bits) * 9
index 4159b468eb75b5767e9c6959c2d5a57a1ae10f12..a16051f8bbc28ee49763eb1265403a4132d6733b 100644 (file)
@@ -95,7 +95,7 @@ struct lzma_coder_s {
        bool write_eopm;
 
        // Literal encoder
-       lzma_literal_coder *literal_coder;
+       lzma_literal_coder literal_coder;
 
        // Bit encoders
        probability is_match[STATES][POS_STATES_MAX];
index 8f650fbfaedb4ae95f1ec5499ab35558fe4be4ba..3611a1f7c4d4ec0dd01caeb57a0345ff46b66db7 100644 (file)
@@ -22,7 +22,7 @@
 
 
 extern lzma_ret
-lzma_literal_init(lzma_literal_coder **coder, lzma_allocator *allocator,
+lzma_literal_init(lzma_literal_coder *coder,
                uint32_t literal_context_bits, uint32_t literal_pos_bits)
 {
        // Verify that arguments are sane.
@@ -34,41 +34,18 @@ lzma_literal_init(lzma_literal_coder **coder, lzma_allocator *allocator,
        const uint32_t states = literal_states(
                        literal_pos_bits, literal_context_bits);
 
-       // Allocate a new literal coder, if needed.
-       if (*coder == NULL || (**coder).literal_context_bits
-                               != literal_context_bits
-                       || (**coder).literal_pos_bits != literal_pos_bits) {
-               // Free the old coder, if any.
-               lzma_free(*coder, allocator);
+       // Store the new settings.
+       coder->literal_context_bits = literal_context_bits;
+       coder->literal_pos_bits = literal_pos_bits;
 
-               // Allocate a new one.
-               *coder = lzma_alloc(sizeof(lzma_literal_coder)
-                               + states * LIT_SIZE * sizeof(probability),
-                               allocator);
-               if (*coder == NULL)
-                       return LZMA_MEM_ERROR;
-
-               // Store the new settings.
-               (**coder).literal_context_bits = literal_context_bits;
-               (**coder).literal_pos_bits = literal_pos_bits;
-
-               // Calculate also the literal_pos_mask. It's not changed
-               // anywhere else than here.
-               (**coder).literal_pos_mask = (1 << literal_pos_bits) - 1;
-       }
+       // Calculate also the literal_pos_mask. It's not changed
+       // anywhere else than here.
+       coder->literal_pos_mask = (1 << literal_pos_bits) - 1;
 
        // Reset the literal coder.
        for (uint32_t i = 0; i < states; ++i)
                for (uint32_t j = 0; j < LIT_SIZE; ++j)
-                       bit_reset((**coder).coders[i][j]);
+                       bit_reset(coder->coders[i][j]);
 
        return LZMA_OK;
 }
-
-
-extern void
-lzma_literal_end(lzma_literal_coder **coder, lzma_allocator *allocator)
-{
-       lzma_free(*coder, allocator);
-       *coder = NULL;
-}
index 174f5ed462b130950f96f8d0d1ec3e727fea1a44..208abd99df4cc0a0b089b03b6fd53eff0289b658 100644 (file)
@@ -45,9 +45,9 @@
 ///     byte; and
 ///   - the highest literal_context_bits bits of the previous byte.
 #define literal_get_subcoder(literal_coder, pos, prev_byte) \
-       (literal_coder)->coders[(((pos) & (literal_coder)->literal_pos_mask) \
-                       << (literal_coder)->literal_context_bits) \
-               + ((prev_byte) >> (8 - (literal_coder)->literal_context_bits))]
+       (literal_coder).coders[(((pos) & (literal_coder).literal_pos_mask) \
+                       << (literal_coder).literal_context_bits) \
+               + ((prev_byte) >> (8 - (literal_coder).literal_context_bits))]
 
 
 typedef struct {
@@ -59,16 +59,13 @@ typedef struct {
 
        /// There are (1 << (literal_pos_bits + literal_context_bits))
        /// literal coders.
-       probability coders[][LIT_SIZE];
+       probability coders[1 << LZMA_LITERAL_BITS_MAX][LIT_SIZE];
 
 } lzma_literal_coder;
 
 
 extern lzma_ret lzma_literal_init(
-               lzma_literal_coder **coder, lzma_allocator *allocator,
+               lzma_literal_coder *coder,
                uint32_t literal_context_bits, uint32_t literal_pos_bits);
 
-extern void lzma_literal_end(
-               lzma_literal_coder **coder, lzma_allocator *allocator);
-
 #endif