mirror of https://git.tukaani.org/xz.git
Use fastpos.h when encoding LZMA dictionary size in
Filter Flags encoder.
This commit is contained in:
parent
e5728142a2
commit
f10fc6a69d
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "lzma_encoder.h"
|
#include "lzma_encoder.h"
|
||||||
|
#include "fastpos.h"
|
||||||
|
|
||||||
|
|
||||||
/// \brief Calculates the size of the Filter Properties field
|
/// \brief Calculates the size of the Filter Properties field
|
||||||
|
@ -204,35 +205,32 @@ properties_lzma(uint8_t *out, size_t *out_pos, size_t out_size,
|
||||||
|
|
||||||
// Dictionary flags
|
// Dictionary flags
|
||||||
//
|
//
|
||||||
// Dictionary size is encoded using six bits of
|
// Dictionary size is encoded using similar encoding that is used
|
||||||
// which one is mantissa and five are exponent.
|
// internally by LZMA.
|
||||||
//
|
//
|
||||||
// There are some limits that must hold to keep
|
// This won't work if dictionary size can be zero:
|
||||||
// this coding working.
|
|
||||||
# if LZMA_DICTIONARY_SIZE_MAX > UINT32_MAX / 2
|
|
||||||
# error LZMA_DICTIONARY_SIZE_MAX is too big.
|
|
||||||
# endif
|
|
||||||
# if LZMA_DICTIONARY_SIZE_MIN < 1
|
# if LZMA_DICTIONARY_SIZE_MIN < 1
|
||||||
# error LZMA_DICTIONARY_SIZE_MIN cannot be zero.
|
# error LZMA_DICTIONARY_SIZE_MIN cannot be zero.
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
uint32_t d = options->dictionary_size;
|
||||||
|
|
||||||
// Validate it:
|
// Validate it:
|
||||||
if (options->dictionary_size < LZMA_DICTIONARY_SIZE_MIN
|
if (d < LZMA_DICTIONARY_SIZE_MIN || d > LZMA_DICTIONARY_SIZE_MAX)
|
||||||
|| options->dictionary_size > LZMA_DICTIONARY_SIZE_MAX)
|
|
||||||
return LZMA_HEADER_ERROR;
|
return LZMA_HEADER_ERROR;
|
||||||
|
|
||||||
if (options->dictionary_size == 1) {
|
// Round up to to the next 2^n or 2^n + 2^(n - 1) depending on which
|
||||||
// Special case
|
// one is the next:
|
||||||
out[*out_pos] = 0x00;
|
--d;
|
||||||
} else {
|
d |= d >> 2;
|
||||||
// TODO This could be more elegant.
|
d |= d >> 3;
|
||||||
uint32_t i = 1;
|
d |= d >> 4;
|
||||||
while (((2 | ((i + 1) & 1)) << ((i - 1) / 2))
|
d |= d >> 8;
|
||||||
< options->dictionary_size)
|
d |= d >> 16;
|
||||||
++i;
|
++d;
|
||||||
out[*out_pos] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Get the highest two bits using the proper encoding:
|
||||||
|
out[*out_pos] = get_pos_slot(d) - 1;
|
||||||
++*out_pos;
|
++*out_pos;
|
||||||
|
|
||||||
return LZMA_OK;
|
return LZMA_OK;
|
||||||
|
|
Loading…
Reference in New Issue