diff --git a/c/common/dictionary.h b/c/common/dictionary.h index 3fa3391..b1c6f7f 100644 --- a/c/common/dictionary.h +++ b/c/common/dictionary.h @@ -41,7 +41,7 @@ typedef struct BrotliDictionary { const uint8_t* data; } BrotliDictionary; -BROTLI_COMMON_API extern const BrotliDictionary* BrotliGetDictionary(void); +BROTLI_COMMON_API const BrotliDictionary* BrotliGetDictionary(void); /** * Sets dictionary data. diff --git a/c/common/platform.h b/c/common/platform.h new file mode 100755 index 0000000..804fd25 --- /dev/null +++ b/c/common/platform.h @@ -0,0 +1,418 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Macros for compiler / platform specific features and build options. */ + +#ifndef BROTLI_COMMON_PLATFORM_H_ +#define BROTLI_COMMON_PLATFORM_H_ + +#include /* memcpy */ + +#include +#include + +#if defined OS_LINUX || defined OS_CYGWIN +#include +#elif defined OS_FREEBSD +#include +#elif defined OS_MACOSX +#include +/* Let's try and follow the Linux convention */ +#define BROTLI_X_BYTE_ORDER BYTE_ORDER +#define BROTLI_X_LITTLE_ENDIAN LITTLE_ENDIAN +#define BROTLI_X_BIG_ENDIAN BIG_ENDIAN +#endif + +#if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG) +#include +#include +#endif + +/* Macros for compiler / platform specific features and build options. + + Build options are: + * BROTLI_BUILD_32_BIT disables 64-bit optimizations + * BROTLI_BUILD_64_BIT forces to use 64-bit optimizations + * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations + * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations + * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations + * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned + read and overlapping memcpy; this reduces decompression speed by 5% + * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs + * BROTLI_DEBUG dumps file name and line number when decoder detects stream + or memory error + * BROTLI_ENABLE_LOG enables asserts and dumps various state information +*/ + +#if BROTLI_MODERN_COMPILER || __has_attribute(always_inline) +#define BROTLI_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) +#else +#define BROTLI_ATTRIBUTE_ALWAYS_INLINE +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +#define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN +#elif BROTLI_MODERN_COMPILER || __has_attribute(visibility) +#define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN \ + __attribute__ ((visibility ("hidden"))) +#else +#define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN +#endif + +#ifndef BROTLI_INTERNAL +#define BROTLI_INTERNAL BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN +#endif + +#ifndef _MSC_VER +#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) +#define BROTLI_INLINE inline BROTLI_ATTRIBUTE_ALWAYS_INLINE +#else +#define BROTLI_INLINE +#endif +#else /* _MSC_VER */ +#define BROTLI_INLINE __forceinline +#endif /* _MSC_VER */ + +#if BROTLI_MODERN_COMPILER || __has_attribute(unused) +#define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE __attribute__ ((unused)) +#else +#define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE +#endif + +#if !defined(__cplusplus) && !defined(c_plusplus) && \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) +#define BROTLI_RESTRICT restrict +#elif BROTLI_GCC_VERSION > 295 || defined(__llvm__) +#define BROTLI_RESTRICT __restrict +#else +#define BROTLI_RESTRICT +#endif + +#if BROTLI_MODERN_COMPILER || __has_attribute(noinline) +#define BROTLI_NOINLINE __attribute__((noinline)) +#else +#define BROTLI_NOINLINE +#endif + +#if defined(__arm__) || defined(__thumb__) || \ + defined(_M_ARM) || defined(_M_ARMT) || defined(__ARM64_ARCH_8__) +#define BROTLI_TARGET_ARM +#if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \ + (defined(M_ARM) && (M_ARM == 7)) +#define BROTLI_TARGET_ARMV7 +#endif /* ARMv7 */ +#if defined(__aarch64__) || defined(__ARM64_ARCH_8__) +#define BROTLI_TARGET_ARMV8 +#endif /* ARMv8 */ +#endif /* ARM */ + +#if defined(__i386) || defined(_M_IX86) +#define BROTLI_TARGET_X86 +#endif + +#if defined(__x86_64__) || defined(_M_X64) +#define BROTLI_TARGET_X64 +#endif + +#if defined(__PPC64__) +#define BROTLI_TARGET_POWERPC64 +#endif + +#if defined(BROTLI_BUILD_64_BIT) +#define BROTLI_64_BITS 1 +#elif defined(BROTLI_BUILD_32_BIT) +#define BROTLI_64_BITS 0 +#elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \ + defined(BROTLI_TARGET_POWERPC64) +#define BROTLI_64_BITS 1 +#else +#define BROTLI_64_BITS 0 +#endif + +#if (BROTLI_64_BITS) +#define brotli_reg_t uint64_t +#else +#define brotli_reg_t uint32_t +#endif + +#if defined(BROTLI_BUILD_BIG_ENDIAN) +#define BROTLI_BIG_ENDIAN 1 +#elif defined(BROTLI_BUILD_LITTLE_ENDIAN) +#define BROTLI_LITTLE_ENDIAN 1 +#elif defined(BROTLI_BUILD_ENDIAN_NEUTRAL) +/* Just break elif chain. */ +#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define BROTLI_LITTLE_ENDIAN 1 +#elif defined(_WIN32) || defined(BROTLI_TARGET_X64) +/* Win32 & x64 can currently always be assumed to be little endian */ +#define BROTLI_LITTLE_ENDIAN 1 +#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define BROTLI_BIG_ENDIAN 1 +#elif defined(BROTLI_X_BYTE_ORDER) +#if BROTLI_X_BYTE_ORDER == BROTLI_X_LITTLE_ENDIAN +#define BROTLI_LITTLE_ENDIAN 1 +#elif BROTLI_X_BYTE_ORDER == BROTLI_X_BIG_ENDIAN +#define BROTLI_BIG_ENDIAN 1 +#endif +#endif /* BROTLI_X_BYTE_ORDER */ + +#if !defined(BROTLI_LITTLE_ENDIAN) +#define BROTLI_LITTLE_ENDIAN 0 +#endif + +#if !defined(BROTLI_BIG_ENDIAN) +#define BROTLI_BIG_ENDIAN 0 +#endif + +#ifdef BROTLI_X_BYTE_ORDER +#undef BROTLI_X_BYTE_ORDER +#undef BROTLI_X_LITTLE_ENDIAN +#undef BROTLI_X_BIG_ENDIAN +#endif + +#ifdef BROTLI_BUILD_PORTABLE +#define BROTLI_ALIGNED_READ (!!1) +#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \ + defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) +/* Allow unaligned read only for white-listed CPUs. */ +#define BROTLI_ALIGNED_READ (!!0) +#else +#define BROTLI_ALIGNED_READ (!!1) +#endif + +#if BROTLI_ALIGNED_READ +/* Portable unaligned memory access: read / write values via memcpy. */ +static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) { + uint16_t t; + memcpy(&t, p, sizeof t); + return t; +} +static BROTLI_INLINE uint32_t BrotliUnalignedRead32(const void* p) { + uint32_t t; + memcpy(&t, p, sizeof t); + return t; +} +static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} +static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { + memcpy(p, &v, sizeof v); +} +#else /* BROTLI_ALIGNED_READ */ +/* Unaligned memory access is allowed: just cast pointer to requested type. */ +static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) { + return *(const uint16_t*)p; +} +static BROTLI_INLINE uint32_t BrotliUnalignedRead32(const void* p) { + return *(const uint32_t*)p; +} +static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) { + return *(const uint64_t*)p; +} +static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { + *(uint64_t*)p = v; +} +#endif /* BROTLI_ALIGNED_READ */ + +#if BROTLI_LITTLE_ENDIAN +/* Straight endianness. Just read / write values. */ +#define BROTLI_UNALIGNED_LOAD16LE BrotliUnalignedRead16 +#define BROTLI_UNALIGNED_LOAD32LE BrotliUnalignedRead32 +#define BROTLI_UNALIGNED_LOAD64LE BrotliUnalignedRead64 +#define BROTLI_UNALIGNED_STORE64LE BrotliUnalignedWrite64 +#elif BROTLI_BIG_ENDIAN /* BROTLI_LITTLE_ENDIAN */ +/* Explain compiler to byte-swap values. */ +#define BROTLI_BSWAP16_(V) ((uint16_t)( \ + (((V) & 0xFFU) << 8) | \ + (((V) >> 8) & 0xFFU))) +static BROTLI_INLINE uint16_t BROTLI_UNALIGNED_LOAD16LE(const void* p) { + uint16_t value = BrotliUnalignedRead16(p); + return BROTLI_BSWAP16_(value); +} +#define BROTLI_BSWAP32_(V) ( \ + (((V) & 0xFFU) << 24) | (((V) & 0xFF00U) << 8) | \ + (((V) >> 8) & 0xFF00U) | (((V) >> 24) & 0xFFU)) +static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32LE(const void* p) { + uint32_t value = BrotliUnalignedRead32(p); + return BROTLI_BSWAP32_(value); +} +#define BROTLI_BSWAP64_(V) ( \ + (((V) & 0xFFU) << 56) | (((V) & 0xFF00U) << 40) | \ + (((V) & 0xFF0000U) << 24) | (((V) & 0xFF000000U) << 8) | \ + (((V) >> 8) & 0xFF000000U) | (((V) >> 24) & 0xFF0000U) | \ + (((V) >> 40) & 0xFF00U) | (((V) >> 56) & 0xFFU)) +static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void* p) { + uint64_t value = BrotliUnalignedRead64(p); + return BROTLI_BSWAP64_(value); +} +static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) { + uint64_t value = BROTLI_BSWAP64_(v); + BrotliUnalignedWrite64(p, value); +} +#else /* BROTLI_LITTLE_ENDIAN */ +/* Read / store values byte-wise; hopefully compiler will understand. */ +static BROTLI_INLINE uint16_t BROTLI_UNALIGNED_LOAD16LE(const void* p) { + const uint8_t* in = (const uint8_t*)p; + return (uint16_t)(in[0] | (in[1] << 8)); +} +static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32LE(const void* p) { + const uint8_t* in = (const uint8_t*)p; + uint32_t value = (uint32_t)(in[0]); + value |= (uint32_t)(in[1]) << 8; + value |= (uint32_t)(in[2]) << 16; + value |= (uint32_t)(in[3]) << 24; + return value; +} +static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void* p) { + const uint8_t* in = (const uint8_t*)p; + uint64_t value = (uint64_t)(in[0]); + value |= (uint64_t)(in[1]) << 8; + value |= (uint64_t)(in[2]) << 16; + value |= (uint64_t)(in[3]) << 24; + value |= (uint64_t)(in[4]) << 32; + value |= (uint64_t)(in[5]) << 40; + value |= (uint64_t)(in[6]) << 48; + value |= (uint64_t)(in[7]) << 56; + return value; +} +static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) { + uint8_t* out = (uint8_t*)p; + out[0] = (uint8_t)v; + out[1] = (uint8_t)(v >> 8); + out[2] = (uint8_t)(v >> 16); + out[3] = (uint8_t)(v >> 24); + out[4] = (uint8_t)(v >> 32); + out[5] = (uint8_t)(v >> 40); + out[6] = (uint8_t)(v >> 48); + out[7] = (uint8_t)(v >> 56); +} +#endif /* BROTLI_LITTLE_ENDIAN */ + +/* Define "BROTLI_PREDICT_TRUE" and "BROTLI_PREDICT_FALSE" macros for capable + compilers. + +To apply compiler hint, enclose the branching condition into macros, like this: + + if (BROTLI_PREDICT_TRUE(zero == 0)) { + // main execution path + } else { + // compiler should place this code outside of main execution path + } + +OR: + + if (BROTLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) { + // compiler should place this code outside of main execution path + } + +*/ +#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_expect) +#define BROTLI_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#define BROTLI_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#else +#define BROTLI_PREDICT_FALSE(x) (x) +#define BROTLI_PREDICT_TRUE(x) (x) +#endif + +/* BROTLI_IS_CONSTANT macros returns true for compile-time constants. */ +#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_constant_p) +#define BROTLI_IS_CONSTANT(x) (!!__builtin_constant_p(x)) +#else +#define BROTLI_IS_CONSTANT(x) (!!0) +#endif + +#if defined(BROTLI_TARGET_ARM) +#define BROTLI_HAS_UBFX (!!1) +#else +#define BROTLI_HAS_UBFX (!!0) +#endif + +#ifdef BROTLI_ENABLE_LOG +#define BROTLI_DCHECK(x) assert(x) +#define BROTLI_LOG(x) printf x +#else +#define BROTLI_DCHECK(x) +#define BROTLI_LOG(x) +#endif + +#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG) +static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) { + fprintf(stderr, "%s:%d (%s)\n", f, l, fn); + fflush(stderr); +} +#define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__) +#else +#define BROTLI_DUMP() (void)(0) +#endif + +#if (BROTLI_MODERN_COMPILER || defined(__llvm__)) && \ + !defined(BROTLI_BUILD_NO_RBIT) +#if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) +/* TODO: detect ARMv6T2 and enable this code for it. */ +static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) { + brotli_reg_t output; + __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input)); + return output; +} +#define BROTLI_RBIT(x) BrotliRBit(x) +#endif /* armv7 */ +#endif /* gcc || clang */ +#if !defined(BROTLI_RBIT) +static BROTLI_INLINE void BrotliRBit(void) { /* Should break build if used. */ } +#endif /* BROTLI_RBIT */ + +#define BROTLI_REPEAT(N, X) { \ + if ((N & 1) != 0) {X;} \ + if ((N & 2) != 0) {X; X;} \ + if ((N & 4) != 0) {X; X; X; X;} \ +} + +#define BROTLI_UNUSED(X) (void)(X) + +#define BROTLI_MIN_MAX(T) \ + static BROTLI_INLINE T brotli_min_ ## T (T a, T b) { return a < b ? a : b; } \ + static BROTLI_INLINE T brotli_max_ ## T (T a, T b) { return a > b ? a : b; } +BROTLI_MIN_MAX(double) BROTLI_MIN_MAX(float) BROTLI_MIN_MAX(int) +BROTLI_MIN_MAX(size_t) BROTLI_MIN_MAX(uint32_t) BROTLI_MIN_MAX(uint8_t) +#undef BROTLI_MIN_MAX +#define BROTLI_MIN(T, A, B) (brotli_min_ ## T((A), (B))) +#define BROTLI_MAX(T, A, B) (brotli_max_ ## T((A), (B))) + +#define BROTLI_SWAP(T, A, I, J) { \ + T __brotli_swap_tmp = (A)[(I)]; \ + (A)[(I)] = (A)[(J)]; \ + (A)[(J)] = __brotli_swap_tmp; \ +} + +BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) { + BROTLI_UNUSED(BrotliSuppressUnusedFunctions); + BROTLI_UNUSED(BrotliUnalignedRead16); + BROTLI_UNUSED(BrotliUnalignedRead32); + BROTLI_UNUSED(BrotliUnalignedRead64); + BROTLI_UNUSED(BrotliUnalignedWrite64); + BROTLI_UNUSED(BROTLI_UNALIGNED_LOAD16LE); + BROTLI_UNUSED(BROTLI_UNALIGNED_LOAD32LE); + BROTLI_UNUSED(BROTLI_UNALIGNED_LOAD64LE); + BROTLI_UNUSED(BROTLI_UNALIGNED_STORE64LE); + BROTLI_UNUSED(BrotliRBit); + BROTLI_UNUSED(brotli_min_double); + BROTLI_UNUSED(brotli_max_double); + BROTLI_UNUSED(brotli_min_float); + BROTLI_UNUSED(brotli_max_float); + BROTLI_UNUSED(brotli_min_int); + BROTLI_UNUSED(brotli_max_int); + BROTLI_UNUSED(brotli_min_size_t); + BROTLI_UNUSED(brotli_max_size_t); + BROTLI_UNUSED(brotli_min_uint32_t); + BROTLI_UNUSED(brotli_max_uint32_t); + BROTLI_UNUSED(brotli_min_uint8_t); + BROTLI_UNUSED(brotli_max_uint8_t); +} + +#endif /* BROTLI_COMMON_PLATFORM_H_ */ diff --git a/c/dec/bit_reader.c b/c/dec/bit_reader.c index 9925ba4..722fd90 100644 --- a/c/dec/bit_reader.c +++ b/c/dec/bit_reader.c @@ -8,8 +8,8 @@ #include "./bit_reader.h" +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/dec/bit_reader.h b/c/dec/bit_reader.h index 30e6761..21c59d7 100644 --- a/c/dec/bit_reader.h +++ b/c/dec/bit_reader.h @@ -11,14 +11,14 @@ #include /* memcpy */ +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(reg_t) >> 1) +#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1) static const uint32_t kBitMask[33] = { 0x0000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, @@ -32,7 +32,7 @@ static const uint32_t kBitMask[33] = { 0x0000, }; static BROTLI_INLINE uint32_t BitMask(uint32_t n) { - if (IS_CONSTANT(n) || BROTLI_HAS_UBFX) { + if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) { /* Masking with this expression turns to a single "Unsigned Bit Field Extract" UBFX instruction on ARM. */ return ~((0xffffffffU) << n); @@ -42,14 +42,14 @@ static BROTLI_INLINE uint32_t BitMask(uint32_t n) { } typedef struct { - reg_t val_; /* pre-fetched bits */ + brotli_reg_t val_; /* pre-fetched bits */ uint32_t bit_pos_; /* current bit-reading position in val_ */ const uint8_t* next_in; /* the byte we're reading from */ size_t avail_in; } BrotliBitReader; typedef struct { - reg_t val_; + brotli_reg_t val_; uint32_t bit_pos_; const uint8_t* next_in; size_t avail_in; @@ -98,62 +98,6 @@ static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount( return TO_BROTLI_BOOL(br->avail_in >= num); } -static BROTLI_INLINE uint16_t BrotliLoad16LE(const uint8_t* in) { - if (BROTLI_LITTLE_ENDIAN) { - return *((const uint16_t*)in); - } else if (BROTLI_BIG_ENDIAN) { - uint16_t value = *((const uint16_t*)in); - return (uint16_t)(((value & 0xFFU) << 8) | ((value & 0xFF00U) >> 8)); - } else { - return (uint16_t)(in[0] | (in[1] << 8)); - } -} - -static BROTLI_INLINE uint32_t BrotliLoad32LE(const uint8_t* in) { - if (BROTLI_LITTLE_ENDIAN) { - return *((const uint32_t*)in); - } else if (BROTLI_BIG_ENDIAN) { - uint32_t value = *((const uint32_t*)in); - return ((value & 0xFFU) << 24) | ((value & 0xFF00U) << 8) | - ((value & 0xFF0000U) >> 8) | ((value & 0xFF000000U) >> 24); - } else { - uint32_t value = (uint32_t)(*(in++)); - value |= (uint32_t)(*(in++)) << 8; - value |= (uint32_t)(*(in++)) << 16; - value |= (uint32_t)(*(in++)) << 24; - return value; - } -} - -#if (BROTLI_64_BITS) -static BROTLI_INLINE uint64_t BrotliLoad64LE(const uint8_t* in) { - if (BROTLI_LITTLE_ENDIAN) { - return *((const uint64_t*)in); - } else if (BROTLI_BIG_ENDIAN) { - uint64_t value = *((const uint64_t*)in); - return - ((value & 0xFFU) << 56) | - ((value & 0xFF00U) << 40) | - ((value & 0xFF0000U) << 24) | - ((value & 0xFF000000U) << 8) | - ((value & 0xFF00000000U) >> 8) | - ((value & 0xFF0000000000U) >> 24) | - ((value & 0xFF000000000000U) >> 40) | - ((value & 0xFF00000000000000U) >> 56); - } else { - uint64_t value = (uint64_t)(*(in++)); - value |= (uint64_t)(*(in++)) << 8; - value |= (uint64_t)(*(in++)) << 16; - value |= (uint64_t)(*(in++)) << 24; - value |= (uint64_t)(*(in++)) << 32; - value |= (uint64_t)(*(in++)) << 40; - value |= (uint64_t)(*(in++)) << 48; - value |= (uint64_t)(*(in++)) << 56; - return value; - } -} -#endif - /* Guarantees that there are at least n_bits + 1 bits in accumulator. Precondition: accumulator contains at least 1 bit. n_bits should be in the range [1..24] for regular build. For portable @@ -161,19 +105,20 @@ static BROTLI_INLINE uint64_t BrotliLoad64LE(const uint8_t* in) { static BROTLI_INLINE void BrotliFillBitWindow( BrotliBitReader* const br, uint32_t n_bits) { #if (BROTLI_64_BITS) - if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) { + if (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) { if (br->bit_pos_ >= 56) { br->val_ >>= 56; br->bit_pos_ ^= 56; /* here same as -= 56 because of the if condition */ - br->val_ |= BrotliLoad64LE(br->next_in) << 8; + br->val_ |= BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 8; br->avail_in -= 7; br->next_in += 7; } - } else if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 16)) { + } else if ( + !BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 16)) { if (br->bit_pos_ >= 48) { br->val_ >>= 48; br->bit_pos_ ^= 48; /* here same as -= 48 because of the if condition */ - br->val_ |= BrotliLoad64LE(br->next_in) << 16; + br->val_ |= BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 16; br->avail_in -= 6; br->next_in += 6; } @@ -181,17 +126,17 @@ static BROTLI_INLINE void BrotliFillBitWindow( if (br->bit_pos_ >= 32) { br->val_ >>= 32; br->bit_pos_ ^= 32; /* here same as -= 32 because of the if condition */ - br->val_ |= ((uint64_t)BrotliLoad32LE(br->next_in)) << 32; + br->val_ |= ((uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in)) << 32; br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ; br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ; } } #else - if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) { + if (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) { if (br->bit_pos_ >= 24) { br->val_ >>= 24; br->bit_pos_ ^= 24; /* here same as -= 24 because of the if condition */ - br->val_ |= BrotliLoad32LE(br->next_in) << 8; + br->val_ |= BROTLI_UNALIGNED_LOAD32LE(br->next_in) << 8; br->avail_in -= 3; br->next_in += 3; } @@ -199,7 +144,7 @@ static BROTLI_INLINE void BrotliFillBitWindow( if (br->bit_pos_ >= 16) { br->val_ >>= 16; br->bit_pos_ ^= 16; /* here same as -= 16 because of the if condition */ - br->val_ |= ((uint32_t)BrotliLoad16LE(br->next_in)) << 16; + br->val_ |= ((uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in)) << 16; br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ; br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ; } @@ -232,7 +177,8 @@ static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) { /* Returns currently available bits. The number of valid bits could be calculated by BrotliGetAvailableBits. */ -static BROTLI_INLINE reg_t BrotliGetBitsUnmasked(BrotliBitReader* const br) { +static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked( + BrotliBitReader* const br) { return br->val_ >> br->bit_pos_; } diff --git a/c/dec/decode.c b/c/dec/decode.c index 24da35b..846557a 100644 --- a/c/dec/decode.c +++ b/c/dec/decode.c @@ -15,11 +15,11 @@ #include "../common/constants.h" #include "../common/dictionary.h" +#include "../common/platform.h" #include "../common/version.h" #include "./bit_reader.h" #include "./context.h" #include "./huffman.h" -#include "./port.h" #include "./prefix.h" #include "./state.h" #include "./transform.h" @@ -953,7 +953,8 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size, s->context_index = 0; BROTLI_LOG_UINT(context_map_size); BROTLI_LOG_UINT(*num_htrees); - *context_map_arg = (uint8_t*)BROTLI_ALLOC(s, (size_t)context_map_size); + *context_map_arg = + (uint8_t*)BROTLI_DECODER_ALLOC(s, (size_t)context_map_size); if (*context_map_arg == 0) { return BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP); } @@ -1268,8 +1269,8 @@ static BROTLI_BOOL BROTLI_NOINLINE BrotliEnsureRingBuffer( return BROTLI_TRUE; } - s->ringbuffer = (uint8_t*)BROTLI_ALLOC(s, (size_t)(s->new_ringbuffer_size) + - kRingBufferWriteAheadSlack); + s->ringbuffer = (uint8_t*)BROTLI_DECODER_ALLOC(s, + (size_t)(s->new_ringbuffer_size) + kRingBufferWriteAheadSlack); if (s->ringbuffer == 0) { /* Restore previous value. */ s->ringbuffer = old_ringbuffer; @@ -1280,7 +1281,7 @@ static BROTLI_BOOL BROTLI_NOINLINE BrotliEnsureRingBuffer( if (!!old_ringbuffer) { memcpy(s->ringbuffer, old_ringbuffer, (size_t)s->pos); - BROTLI_FREE(s, old_ringbuffer); + BROTLI_DECODER_FREE(s, old_ringbuffer); } s->ringbuffer_size = s->new_ringbuffer_size; @@ -1748,6 +1749,7 @@ CommandPostDecodeLiterals: int address = s->distance_code - s->max_distance - 1; if (i >= BROTLI_MIN_DICTIONARY_WORD_LENGTH && i <= BROTLI_MAX_DICTIONARY_WORD_LENGTH) { + const BrotliDictionary* words = s->dictionary; int offset = (int)s->dictionary->offsets_by_length[i]; uint32_t shift = s->dictionary->size_bits_by_length[i]; int mask = (int)BitMask(shift); @@ -1756,19 +1758,19 @@ CommandPostDecodeLiterals: /* Compensate double distance-ring-buffer roll. */ s->dist_rb_idx += s->distance_context; offset += word_idx * i; - if (BROTLI_PREDICT_FALSE(!s->dictionary->data)) { + if (BROTLI_PREDICT_FALSE(!words->data)) { return BROTLI_FAILURE(BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET); } if (transform_idx < kNumTransforms) { - const uint8_t* word = &s->dictionary->data[offset]; + const uint8_t* word = &words->data[offset]; int len = i; if (transform_idx == 0) { memcpy(&s->ringbuffer[pos], word, (size_t)len); BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s]\n", len, word)); } else { - len = TransformDictionaryWord( - &s->ringbuffer[pos], word, len, transform_idx); + len = BrotliTransformDictionaryWord(&s->ringbuffer[pos], word, len, + transform_idx); BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s]," " transform_idx = %d, transformed: [%.*s]\n", i, word, transform_idx, len, &s->ringbuffer[pos])); @@ -2021,7 +2023,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream( s->max_backward_distance = (1 << s->window_bits) - BROTLI_WINDOW_GAP; /* Allocate memory for both block_type_trees and block_len_trees. */ - s->block_type_trees = (HuffmanCode*)BROTLI_ALLOC(s, + s->block_type_trees = (HuffmanCode*)BROTLI_DECODER_ALLOC(s, sizeof(HuffmanCode) * 3 * (BROTLI_HUFFMAN_MAX_SIZE_258 + BROTLI_HUFFMAN_MAX_SIZE_26)); if (s->block_type_trees == 0) { @@ -2151,7 +2153,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream( BROTLI_LOG_UINT(s->distance_postfix_bits); s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits); s->context_modes = - (uint8_t*)BROTLI_ALLOC(s, (size_t)s->num_block_types[0]); + (uint8_t*)BROTLI_DECODER_ALLOC(s, (size_t)s->num_block_types[0]); if (s->context_modes == 0) { result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES); break; diff --git a/c/dec/huffman.c b/c/dec/huffman.c index 37da2a5..4fe7bfa 100644 --- a/c/dec/huffman.c +++ b/c/dec/huffman.c @@ -11,8 +11,8 @@ #include /* memcpy, memset */ #include "../common/constants.h" +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -22,7 +22,7 @@ extern "C" { #ifdef BROTLI_RBIT #define BROTLI_REVERSE_BITS_BASE \ - ((sizeof(reg_t) << 3) - BROTLI_REVERSE_BITS_MAX) + ((sizeof(brotli_reg_t) << 3) - BROTLI_REVERSE_BITS_MAX) #else #define BROTLI_REVERSE_BITS_BASE 0 static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = { @@ -62,12 +62,12 @@ static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = { #endif /* BROTLI_RBIT */ #define BROTLI_REVERSE_BITS_LOWEST \ - ((reg_t)1 << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE)) + ((brotli_reg_t)1 << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE)) /* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX), where reverse(value, len) is the bit-wise reversal of the len least significant bits of value. */ -static BROTLI_INLINE reg_t BrotliReverseBits(reg_t num) { +static BROTLI_INLINE brotli_reg_t BrotliReverseBits(brotli_reg_t num) { #ifdef BROTLI_RBIT return BROTLI_RBIT(num); #else @@ -104,12 +104,12 @@ static BROTLI_INLINE int NextTableBitSize(const uint16_t* const count, void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table, const uint8_t* const code_lengths, uint16_t* count) { - HuffmanCode code; /* current table entry */ - int symbol; /* symbol index in original or sorted table */ - reg_t key; /* prefix code */ - reg_t key_step; /* prefix code addend */ - int step; /* step size to replicate values in current table */ - int table_size; /* size of current table */ + HuffmanCode code; /* current table entry */ + int symbol; /* symbol index in original or sorted table */ + brotli_reg_t key; /* prefix code */ + brotli_reg_t key_step; /* prefix code addend */ + int step; /* step size to replicate values in current table */ + int table_size; /* size of current table */ int sorted[BROTLI_CODE_LENGTH_CODES]; /* symbols sorted by code length */ /* offsets in sorted table for each length */ int offset[BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1]; @@ -144,7 +144,7 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table, if (offset[0] == 0) { code.bits = 0; code.value = (uint16_t)sorted[0]; - for (key = 0; key < (reg_t)table_size; ++key) { + for (key = 0; key < (brotli_reg_t)table_size; ++key) { table[key] = code; } return; @@ -172,18 +172,18 @@ uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table, int root_bits, const uint16_t* const symbol_lists, uint16_t* count) { - HuffmanCode code; /* current table entry */ - HuffmanCode* table; /* next available space in table */ - int len; /* current code length */ - int symbol; /* symbol index in original or sorted table */ - reg_t key; /* prefix code */ - reg_t key_step; /* prefix code addend */ - reg_t sub_key; /* 2nd level table prefix code */ - reg_t sub_key_step; /* 2nd level table prefix code addend */ - int step; /* step size to replicate values in current table */ - int table_bits; /* key length of current table */ - int table_size; /* size of current table */ - int total_size; /* sum of root table size and 2nd level table sizes */ + HuffmanCode code; /* current table entry */ + HuffmanCode* table; /* next available space in table */ + int len; /* current code length */ + int symbol; /* symbol index in original or sorted table */ + brotli_reg_t key; /* prefix code */ + brotli_reg_t key_step; /* prefix code addend */ + brotli_reg_t sub_key; /* 2nd level table prefix code */ + brotli_reg_t sub_key_step; /* 2nd level table prefix code addend */ + int step; /* step size to replicate values in current table */ + int table_bits; /* key length of current table */ + int table_size; /* size of current table */ + int total_size; /* sum of root table size and 2nd level table sizes */ int max_length = -1; int bits; int bits_count; diff --git a/c/dec/huffman.h b/c/dec/huffman.h index d3b4d53..730af88 100644 --- a/c/dec/huffman.h +++ b/c/dec/huffman.h @@ -9,8 +9,8 @@ #ifndef BROTLI_DEC_HUFFMAN_H_ #define BROTLI_DEC_HUFFMAN_H_ +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/dec/port.h b/c/dec/port.h deleted file mode 100644 index 6b3d735..0000000 --- a/c/dec/port.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright 2015 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Macros for compiler / platform specific features and build options. - - Build options are: - * BROTLI_BUILD_32_BIT disables 64-bit optimizations - * BROTLI_BUILD_64_BIT forces to use 64-bit optimizations - * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations - * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations - * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations - * BROTLI_BUILD_MODERN_COMPILER forces to use modern compilers built-ins, - features and attributes - * BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned - read and overlapping memcpy; this reduces decompression speed by 5% - * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs - * BROTLI_DEBUG dumps file name and line number when decoder detects stream - or memory error - * BROTLI_ENABLE_LOG enables asserts and dumps various state information - */ - -#ifndef BROTLI_DEC_PORT_H_ -#define BROTLI_DEC_PORT_H_ - -#if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG) -#include -#include -#endif - -#include - -#if defined(__arm__) || defined(__thumb__) || \ - defined(_M_ARM) || defined(_M_ARMT) || defined(__ARM64_ARCH_8__) -#define BROTLI_TARGET_ARM -#if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \ - (defined(M_ARM) && (M_ARM == 7)) -#define BROTLI_TARGET_ARMV7 -#endif /* ARMv7 */ -#if defined(__aarch64__) || defined(__ARM64_ARCH_8__) -#define BROTLI_TARGET_ARMV8 -#endif /* ARMv8 */ -#endif /* ARM */ - -#if defined(__i386) || defined(_M_IX86) -#define BROTLI_TARGET_X86 -#endif - -#if defined(__x86_64__) || defined(_M_X64) -#define BROTLI_TARGET_X64 -#endif - -#if defined(__PPC64__) -#define BROTLI_TARGET_POWERPC64 -#endif - -#ifdef BROTLI_BUILD_PORTABLE -#define BROTLI_ALIGNED_READ (!!1) -#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \ - defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) -/* Allow unaligned read only for white-listed CPUs. */ -#define BROTLI_ALIGNED_READ (!!0) -#else -#define BROTLI_ALIGNED_READ (!!1) -#endif - -/* IS_CONSTANT macros returns true for compile-time constant expressions. */ -#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_constant_p) -#define IS_CONSTANT(x) (!!__builtin_constant_p(x)) -#else -#define IS_CONSTANT(x) (!!0) -#endif - -#ifdef BROTLI_ENABLE_LOG -#define BROTLI_DCHECK(x) assert(x) -#define BROTLI_LOG(x) printf x -#else -#define BROTLI_DCHECK(x) -#define BROTLI_LOG(x) -#endif - -#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG) -static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) { - fprintf(stderr, "%s:%d (%s)\n", f, l, fn); - fflush(stderr); -} -#define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__) -#else -#define BROTLI_DUMP() (void)(0) -#endif - -#if defined(BROTLI_BUILD_64_BIT) -#define BROTLI_64_BITS 1 -#elif defined(BROTLI_BUILD_32_BIT) -#define BROTLI_64_BITS 0 -#elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \ - defined(BROTLI_TARGET_POWERPC64) -#define BROTLI_64_BITS 1 -#else -#define BROTLI_64_BITS 0 -#endif - -#if (BROTLI_64_BITS) -#define reg_t uint64_t -#else -#define reg_t uint32_t -#endif - -#if defined(BROTLI_BUILD_BIG_ENDIAN) -#define BROTLI_LITTLE_ENDIAN 0 -#define BROTLI_BIG_ENDIAN 1 -#elif defined(BROTLI_BUILD_LITTLE_ENDIAN) -#define BROTLI_LITTLE_ENDIAN 1 -#define BROTLI_BIG_ENDIAN 0 -#elif defined(BROTLI_BUILD_ENDIAN_NEUTRAL) -#define BROTLI_LITTLE_ENDIAN 0 -#define BROTLI_BIG_ENDIAN 0 -#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define BROTLI_LITTLE_ENDIAN 1 -#define BROTLI_BIG_ENDIAN 0 -#elif defined(_WIN32) -/* Win32 can currently always be assumed to be little endian */ -#define BROTLI_LITTLE_ENDIAN 1 -#define BROTLI_BIG_ENDIAN 0 -#else -#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) -#define BROTLI_BIG_ENDIAN 1 -#else -#define BROTLI_BIG_ENDIAN 0 -#endif -#define BROTLI_LITTLE_ENDIAN 0 -#endif - -#define BROTLI_REPEAT(N, X) { \ - if ((N & 1) != 0) {X;} \ - if ((N & 2) != 0) {X; X;} \ - if ((N & 4) != 0) {X; X; X; X;} \ -} - -#if (BROTLI_MODERN_COMPILER || defined(__llvm__)) && \ - !defined(BROTLI_BUILD_NO_RBIT) -#if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8) -/* TODO: detect ARMv6T2 and enable this code for it. */ -static BROTLI_INLINE reg_t BrotliRBit(reg_t input) { - reg_t output; - __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input)); - return output; -} -#define BROTLI_RBIT(x) BrotliRBit(x) -#endif /* armv7 */ -#endif /* gcc || clang */ - -#if defined(BROTLI_TARGET_ARM) -#define BROTLI_HAS_UBFX (!!1) -#else -#define BROTLI_HAS_UBFX (!!0) -#endif - -#define BROTLI_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L) - -#define BROTLI_FREE(S, X) { \ - S->free_func(S->memory_manager_opaque, X); \ - X = NULL; \ -} - -#endif /* BROTLI_DEC_PORT_H_ */ diff --git a/c/dec/state.c b/c/dec/state.c index 554313d..eaec823 100644 --- a/c/dec/state.c +++ b/c/dec/state.c @@ -53,8 +53,6 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s, s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE; s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE; - s->dictionary = BrotliGetDictionary(); - s->buffer_length = 0; s->loop_counter = 0; s->pos = 0; @@ -103,6 +101,8 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s, s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1]; s->mtf_upper_bound = 63; + + s->dictionary = BrotliGetDictionary(); } void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) { @@ -137,19 +137,19 @@ void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) { } void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState* s) { - BROTLI_FREE(s, s->context_modes); - BROTLI_FREE(s, s->context_map); - BROTLI_FREE(s, s->dist_context_map); - BROTLI_FREE(s, s->literal_hgroup.htrees); - BROTLI_FREE(s, s->insert_copy_hgroup.htrees); - BROTLI_FREE(s, s->distance_hgroup.htrees); + BROTLI_DECODER_FREE(s, s->context_modes); + BROTLI_DECODER_FREE(s, s->context_map); + BROTLI_DECODER_FREE(s, s->dist_context_map); + BROTLI_DECODER_FREE(s, s->literal_hgroup.htrees); + BROTLI_DECODER_FREE(s, s->insert_copy_hgroup.htrees); + BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees); } void BrotliDecoderStateCleanup(BrotliDecoderState* s) { BrotliDecoderStateCleanupAfterMetablock(s); - BROTLI_FREE(s, s->ringbuffer); - BROTLI_FREE(s, s->block_type_trees); + BROTLI_DECODER_FREE(s, s->ringbuffer); + BROTLI_DECODER_FREE(s, s->block_type_trees); } BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s, @@ -159,7 +159,8 @@ BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s, const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size; const size_t htree_size = sizeof(HuffmanCode*) * ntrees; /* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */ - HuffmanCode** p = (HuffmanCode**)BROTLI_ALLOC(s, code_size + htree_size); + HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s, + code_size + htree_size); group->alphabet_size = (uint16_t)alphabet_size; group->num_htrees = (uint16_t)ntrees; group->htrees = p; diff --git a/c/dec/state.h b/c/dec/state.h index 1d2773b..069beca 100644 --- a/c/dec/state.h +++ b/c/dec/state.h @@ -11,10 +11,10 @@ #include "../common/constants.h" #include "../common/dictionary.h" +#include "../common/platform.h" #include #include "./bit_reader.h" #include "./huffman.h" -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -220,6 +220,7 @@ struct BrotliDecoderStateStruct { uint32_t num_literal_htrees; uint8_t* context_map; uint8_t* context_modes; + const BrotliDictionary* dictionary; uint32_t trivial_literal_contexts[8]; /* 256 bits */ @@ -240,6 +241,13 @@ BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit( BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t ntrees); +#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L) + +#define BROTLI_DECODER_FREE(S, X) { \ + S->free_func(S->memory_manager_opaque, X); \ + X = NULL; \ +} + #if defined(__cplusplus) || defined(c_plusplus) } /* extern "C" */ #endif diff --git a/c/dec/transform.h b/c/dec/transform.h index fde3cdf..e1d96ff 100644 --- a/c/dec/transform.h +++ b/c/dec/transform.h @@ -9,8 +9,8 @@ #ifndef BROTLI_DEC_TRANSFORM_H_ #define BROTLI_DEC_TRANSFORM_H_ +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -257,7 +257,7 @@ static int ToUpperCase(uint8_t* p) { return 3; } -static BROTLI_NOINLINE int TransformDictionaryWord( +static BROTLI_NOINLINE int BrotliTransformDictionaryWord( uint8_t* dst, const uint8_t* word, int len, int transform) { int idx = 0; { diff --git a/c/enc/backward_references.c b/c/enc/backward_references.c index 3ac7f2f..cce0cd4 100644 --- a/c/enc/backward_references.c +++ b/c/enc/backward_references.c @@ -10,11 +10,11 @@ #include "../common/constants.h" #include "../common/dictionary.h" +#include "../common/platform.h" #include #include "./command.h" #include "./dictionary_hash.h" #include "./memory.h" -#include "./port.h" #include "./quality.h" #if defined(__cplusplus) || defined(c_plusplus) diff --git a/c/enc/backward_references.h b/c/enc/backward_references.h index 7ad9881..631c2f6 100644 --- a/c/enc/backward_references.h +++ b/c/enc/backward_references.h @@ -11,10 +11,10 @@ #include "../common/constants.h" #include "../common/dictionary.h" +#include "../common/platform.h" #include #include "./command.h" #include "./hash.h" -#include "./port.h" #include "./quality.h" #if defined(__cplusplus) || defined(c_plusplus) @@ -26,11 +26,11 @@ extern "C" { CreateBackwardReferences calls, and must be incremented by the amount written by this call. */ BROTLI_INTERNAL void BrotliCreateBackwardReferences( - const BrotliDictionary* dictionary, size_t num_bytes, size_t position, - const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache, - size_t* last_insert_len, Command* commands, size_t* num_commands, - size_t* num_literals); + const BrotliDictionary* dictionary, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask, const BrotliEncoderParams* params, + HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals); #if defined(__cplusplus) || defined(c_plusplus) } /* extern "C" */ diff --git a/c/enc/backward_references_hq.c b/c/enc/backward_references_hq.c index 92ce8fb..b05cb4f 100644 --- a/c/enc/backward_references_hq.c +++ b/c/enc/backward_references_hq.c @@ -11,13 +11,13 @@ #include /* memcpy, memset */ #include "../common/constants.h" +#include "../common/platform.h" #include #include "./command.h" #include "./fast_log.h" #include "./find_match_length.h" #include "./literal_cost.h" #include "./memory.h" -#include "./port.h" #include "./prefix.h" #include "./quality.h" @@ -624,16 +624,11 @@ static size_t ZopfliIterate(size_t num_bytes, /* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, - const BrotliDictionary* dictionary, - size_t num_bytes, - size_t position, - const uint8_t* ringbuffer, - size_t ringbuffer_mask, - const BrotliEncoderParams* params, - const size_t max_backward_limit, - const int* dist_cache, - HasherHandle hasher, - ZopfliNode* nodes) { + const BrotliDictionary* dictionary, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask, const BrotliEncoderParams* params, + const size_t max_backward_limit, const int* dist_cache, HasherHandle hasher, + ZopfliNode* nodes) { const size_t max_zopfli_len = MaxZopfliLen(params); ZopfliCostModel model; StartPosQueue queue; @@ -653,10 +648,10 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; i++) { const size_t pos = position + i; const size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit); + size_t skip; size_t num_matches = FindAllMatchesH10(hasher, dictionary, ringbuffer, ringbuffer_mask, pos, num_bytes - i, max_distance, gap, params, &matches[lz_matches_offset]); - size_t skip; if (num_matches > 0 && BackwardMatchLength(&matches[num_matches - 1]) > max_zopfli_len) { matches[0] = matches[num_matches - 1]; @@ -687,32 +682,32 @@ size_t BrotliZopfliComputeShortestPath(MemoryManager* m, return ComputeShortestPathFromNodes(num_bytes, nodes); } -void BrotliCreateZopfliBackwardReferences( - MemoryManager* m, const BrotliDictionary* dictionary, size_t num_bytes, - size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache, - size_t* last_insert_len, Command* commands, size_t* num_commands, - size_t* num_literals) { +void BrotliCreateZopfliBackwardReferences(MemoryManager* m, + const BrotliDictionary* dictionary, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask, const BrotliEncoderParams* params, + HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals) { const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); ZopfliNode* nodes; nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1); if (BROTLI_IS_OOM(m)) return; BrotliInitZopfliNodes(nodes, num_bytes + 1); - *num_commands += BrotliZopfliComputeShortestPath(m, dictionary, num_bytes, - position, ringbuffer, ringbuffer_mask, params, max_backward_limit, - dist_cache, hasher, nodes); + *num_commands += BrotliZopfliComputeShortestPath(m, dictionary, + num_bytes, position, ringbuffer, ringbuffer_mask, + params, max_backward_limit, dist_cache, hasher, nodes); if (BROTLI_IS_OOM(m)) return; BrotliZopfliCreateCommands(num_bytes, position, max_backward_limit, nodes, dist_cache, last_insert_len, params, commands, num_literals); BROTLI_FREE(m, nodes); } -void BrotliCreateHqZopfliBackwardReferences( - MemoryManager* m, const BrotliDictionary* dictionary, size_t num_bytes, - size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache, - size_t* last_insert_len, Command* commands, size_t* num_commands, - size_t* num_literals) { +void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, + const BrotliDictionary* dictionary, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask, const BrotliEncoderParams* params, + HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals) { const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); uint32_t* num_matches = BROTLI_ALLOC(m, uint32_t, num_bytes); size_t matches_size = 4 * num_bytes; @@ -741,12 +736,12 @@ void BrotliCreateHqZopfliBackwardReferences( BROTLI_ENSURE_CAPACITY(m, BackwardMatch, matches, matches_size, cur_match_pos + MAX_NUM_MATCHES_H10 + shadow_matches); if (BROTLI_IS_OOM(m)) return; - num_found_matches = FindAllMatchesH10(hasher, dictionary, ringbuffer, - ringbuffer_mask, pos, max_length, max_distance, gap, params, - &matches[cur_match_pos + shadow_matches]); + num_found_matches = FindAllMatchesH10(hasher, dictionary, + ringbuffer, ringbuffer_mask, pos, max_length, + max_distance, gap, params, &matches[cur_match_pos + shadow_matches]); cur_match_end = cur_match_pos + num_found_matches; for (j = cur_match_pos; j + 1 < cur_match_end; ++j) { - assert(BackwardMatchLength(&matches[j]) <= + BROTLI_DCHECK(BackwardMatchLength(&matches[j]) <= BackwardMatchLength(&matches[j + 1])); } num_matches[i] = (uint32_t)num_found_matches; diff --git a/c/enc/backward_references_hq.h b/c/enc/backward_references_hq.h index 02bb278..cc19544 100644 --- a/c/enc/backward_references_hq.h +++ b/c/enc/backward_references_hq.h @@ -11,30 +11,30 @@ #include "../common/constants.h" #include "../common/dictionary.h" +#include "../common/platform.h" #include #include "./command.h" #include "./hash.h" #include "./memory.h" -#include "./port.h" #include "./quality.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -BROTLI_INTERNAL void BrotliCreateZopfliBackwardReferences( - MemoryManager* m, const BrotliDictionary* dictionary, size_t num_bytes, - size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache, - size_t* last_insert_len, Command* commands, size_t* num_commands, - size_t* num_literals); +BROTLI_INTERNAL void BrotliCreateZopfliBackwardReferences(MemoryManager* m, + const BrotliDictionary* dictionary, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask, const BrotliEncoderParams* params, + HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals); -BROTLI_INTERNAL void BrotliCreateHqZopfliBackwardReferences( - MemoryManager* m, const BrotliDictionary* dictionary, size_t num_bytes, - size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache, - size_t* last_insert_len, Command* commands, size_t* num_commands, - size_t* num_literals); +BROTLI_INTERNAL void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, + const BrotliDictionary* dictionary, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask, const BrotliEncoderParams* params, + HasherHandle hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals); typedef struct ZopfliNode { /* best length to get up to this byte (not including this byte itself) @@ -77,11 +77,12 @@ BROTLI_INTERNAL void BrotliInitZopfliNodes(ZopfliNode* array, size_t length); (1) nodes[i].copy_length() >= 2 (2) nodes[i].command_length() <= i and (3) nodes[i - nodes[i].command_length()].cost < kInfinity */ -BROTLI_INTERNAL size_t BrotliZopfliComputeShortestPath( - MemoryManager* m, const BrotliDictionary* dictionary, size_t num_bytes, - size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, - const BrotliEncoderParams* params, const size_t max_backward_limit, - const int* dist_cache, HasherHandle hasher, ZopfliNode* nodes); +BROTLI_INTERNAL size_t BrotliZopfliComputeShortestPath(MemoryManager* m, + const BrotliDictionary* dictionary, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask, const BrotliEncoderParams* params, + const size_t max_backward_limit, const int* dist_cache, HasherHandle hasher, + ZopfliNode* nodes); BROTLI_INTERNAL void BrotliZopfliCreateCommands( const size_t num_bytes, const size_t block_start, diff --git a/c/enc/backward_references_inc.h b/c/enc/backward_references_inc.h index 81c783c..0a715b2 100644 --- a/c/enc/backward_references_inc.h +++ b/c/enc/backward_references_inc.h @@ -9,7 +9,8 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( const BrotliDictionary* dictionary, - const uint16_t* dictionary_hash, size_t num_bytes, size_t position, + const uint16_t* dictionary_hash, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, const BrotliEncoderParams* params, HasherHandle hasher, int* dist_cache, size_t* last_insert_len, Command* commands, size_t* num_commands, @@ -58,9 +59,9 @@ static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( sr2.distance = 0; sr2.score = kMinScore; max_distance = BROTLI_MIN(size_t, position + 1, max_backward_limit); - FN(FindLongestMatch)(hasher, dictionary, dictionary_hash, ringbuffer, - ringbuffer_mask, dist_cache, position + 1, - max_length, max_distance, gap, &sr2); + FN(FindLongestMatch)(hasher, dictionary, dictionary_hash, + ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length, + max_distance, gap, &sr2); if (sr2.score >= sr.score + cost_diff_lazy) { /* Ok, let's just write one byte for now and start a match from the next byte. */ diff --git a/c/enc/bit_cost.c b/c/enc/bit_cost.c index 01e30f6..1f3f7ad 100644 --- a/c/enc/bit_cost.c +++ b/c/enc/bit_cost.c @@ -9,10 +9,10 @@ #include "./bit_cost.h" #include "../common/constants.h" +#include "../common/platform.h" #include #include "./fast_log.h" #include "./histogram.h" -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/bit_cost.h b/c/enc/bit_cost.h index e69ee04..e8b7013 100644 --- a/c/enc/bit_cost.h +++ b/c/enc/bit_cost.h @@ -9,10 +9,10 @@ #ifndef BROTLI_ENC_BIT_COST_H_ #define BROTLI_ENC_BIT_COST_H_ +#include "../common/platform.h" #include #include "./fast_log.h" #include "./histogram.h" -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/block_splitter.c b/c/enc/block_splitter.c index 0331146..6362211 100644 --- a/c/enc/block_splitter.c +++ b/c/enc/block_splitter.c @@ -8,16 +8,15 @@ #include "./block_splitter.h" -#include #include /* memcpy, memset */ +#include "../common/platform.h" #include "./bit_cost.h" #include "./cluster.h" #include "./command.h" #include "./fast_log.h" #include "./histogram.h" #include "./memory.h" -#include "./port.h" #include "./quality.h" #if defined(__cplusplus) || defined(c_plusplus) diff --git a/c/enc/block_splitter.h b/c/enc/block_splitter.h index 6abac08..a5e006c 100644 --- a/c/enc/block_splitter.h +++ b/c/enc/block_splitter.h @@ -9,10 +9,10 @@ #ifndef BROTLI_ENC_BLOCK_SPLITTER_H_ #define BROTLI_ENC_BLOCK_SPLITTER_H_ +#include "../common/platform.h" #include #include "./command.h" #include "./memory.h" -#include "./port.h" #include "./quality.h" #if defined(__cplusplus) || defined(c_plusplus) diff --git a/c/enc/block_splitter_inc.h b/c/enc/block_splitter_inc.h index 4884478..5712572 100644 --- a/c/enc/block_splitter_inc.h +++ b/c/enc/block_splitter_inc.h @@ -76,7 +76,7 @@ static size_t FN(FindBlocks)(const DataType* data, const size_t length, size_t num_blocks = 1; size_t i; size_t j; - assert(num_histograms <= 256); + BROTLI_DCHECK(num_histograms <= 256); if (num_histograms <= 1) { for (i = 0; i < length; ++i) { block_id[i] = 0; @@ -126,7 +126,7 @@ static size_t FN(FindBlocks)(const DataType* data, const size_t length, if (cost[k] >= block_switch_cost) { const uint8_t mask = (uint8_t)(1u << (k & 7)); cost[k] = block_switch_cost; - assert((k >> 3) < bitmaplen); + BROTLI_DCHECK((k >> 3) < bitmaplen); switch_signal[ix + (k >> 3)] |= mask; } } @@ -137,7 +137,7 @@ static size_t FN(FindBlocks)(const DataType* data, const size_t length, uint8_t cur_id = block_id[byte_ix]; while (byte_ix > 0) { const uint8_t mask = (uint8_t)(1u << (cur_id & 7)); - assert(((size_t)cur_id >> 3) < bitmaplen); + BROTLI_DCHECK(((size_t)cur_id >> 3) < bitmaplen); --byte_ix; ix -= bitmaplen; if (switch_signal[ix + (cur_id >> 3)] & mask) { @@ -161,16 +161,16 @@ static size_t FN(RemapBlockIds)(uint8_t* block_ids, const size_t length, new_id[i] = kInvalidId; } for (i = 0; i < length; ++i) { - assert(block_ids[i] < num_histograms); + BROTLI_DCHECK(block_ids[i] < num_histograms); if (new_id[block_ids[i]] == kInvalidId) { new_id[block_ids[i]] = next_id++; } } for (i = 0; i < length; ++i) { block_ids[i] = (uint8_t)new_id[block_ids[i]]; - assert(block_ids[i] < num_histograms); + BROTLI_DCHECK(block_ids[i] < num_histograms); } - assert(next_id <= num_histograms); + BROTLI_DCHECK(next_id <= num_histograms); return next_id; } @@ -226,13 +226,13 @@ static void FN(ClusterBlocks)(MemoryManager* m, { size_t block_idx = 0; for (i = 0; i < length; ++i) { - assert(block_idx < num_blocks); + BROTLI_DCHECK(block_idx < num_blocks); ++block_lengths[block_idx]; if (i + 1 == length || block_ids[i] != block_ids[i + 1]) { ++block_idx; } } - assert(block_idx == num_blocks); + BROTLI_DCHECK(block_idx == num_blocks); } for (i = 0; i < num_blocks; i += HISTOGRAMS_PER_BATCH) { @@ -268,8 +268,8 @@ static void FN(ClusterBlocks)(MemoryManager* m, histogram_symbols[i + j] = (uint32_t)num_clusters + remap[symbols[j]]; } num_clusters += num_new_clusters; - assert(num_clusters == cluster_size_size); - assert(num_clusters == all_histograms_size); + BROTLI_DCHECK(num_clusters == cluster_size_size); + BROTLI_DCHECK(num_clusters == all_histograms_size); } BROTLI_FREE(m, histograms); diff --git a/c/enc/brotli_bit_stream.c b/c/enc/brotli_bit_stream.c index 2907510..cd9c594 100644 --- a/c/enc/brotli_bit_stream.c +++ b/c/enc/brotli_bit_stream.c @@ -13,13 +13,13 @@ #include /* memcpy, memset */ #include "../common/constants.h" +#include "../common/platform.h" #include #include "./context.h" #include "./entropy_encode.h" #include "./entropy_encode_static.h" #include "./fast_log.h" #include "./memory.h" -#include "./port.h" #include "./write_bits.h" #if defined(__cplusplus) || defined(c_plusplus) @@ -89,9 +89,9 @@ static void BrotliEncodeMlen(size_t length, uint64_t* bits, size_t* numbits, uint64_t* nibblesbits) { size_t lg = (length == 1) ? 1 : Log2FloorNonZero((uint32_t)(length - 1)) + 1; size_t mnibbles = (lg < 16 ? 16 : (lg + 3)) / 4; - assert(length > 0); - assert(length <= (1 << 24)); - assert(lg <= 24); + BROTLI_DCHECK(length > 0); + BROTLI_DCHECK(length <= (1 << 24)); + BROTLI_DCHECK(lg <= 24); *nibblesbits = mnibbles - 4; *numbits = mnibbles * 4; *bits = length - 1; @@ -311,7 +311,7 @@ void BrotliStoreHuffmanTree(const uint8_t* depths, size_t num, int num_codes = 0; size_t code = 0; - assert(num <= BROTLI_NUM_COMMAND_SYMBOLS); + BROTLI_DCHECK(num <= BROTLI_NUM_COMMAND_SYMBOLS); BrotliWriteHuffmanTree(depths, num, &huffman_tree_size, huffman_tree, huffman_tree_extra_bits); @@ -619,7 +619,7 @@ static void MoveToFrontTransform(const uint32_t* BROTLI_RESTRICT v_in, for (i = 1; i < v_size; ++i) { if (v_in[i] > max_value) max_value = v_in[i]; } - assert(max_value < 256u); + BROTLI_DCHECK(max_value < 256u); for (i = 0; i <= max_value; ++i) { mtf[i] = (uint8_t)i; } @@ -627,7 +627,7 @@ static void MoveToFrontTransform(const uint32_t* BROTLI_RESTRICT v_in, size_t mtf_size = max_value + 1; for (i = 0; i < v_size; ++i) { size_t index = IndexOf(mtf, mtf_size, (uint8_t)v_in[i]); - assert(index < mtf_size); + BROTLI_DCHECK(index < mtf_size); v_out[i] = (uint32_t)index; MoveToFront(mtf, index); } @@ -659,7 +659,7 @@ static void RunLengthCodeZeros(const size_t in_size, *max_run_length_prefix = max_prefix; *out_size = 0; for (i = 0; i < in_size;) { - assert(*out_size <= i); + BROTLI_DCHECK(*out_size <= i); if (v[i] != 0) { v[*out_size] = v[i] + *max_run_length_prefix; ++i; diff --git a/c/enc/brotli_bit_stream.h b/c/enc/brotli_bit_stream.h index 2c8bfed..1324b18 100644 --- a/c/enc/brotli_bit_stream.h +++ b/c/enc/brotli_bit_stream.h @@ -16,13 +16,13 @@ #ifndef BROTLI_ENC_BROTLI_BIT_STREAM_H_ #define BROTLI_ENC_BROTLI_BIT_STREAM_H_ +#include "../common/platform.h" #include #include "./command.h" #include "./context.h" #include "./entropy_encode.h" #include "./memory.h" #include "./metablock.h" -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/cluster.c b/c/enc/cluster.c index bb66327..a20dfd3 100644 --- a/c/enc/cluster.c +++ b/c/enc/cluster.c @@ -8,12 +8,12 @@ #include "./cluster.h" +#include "../common/platform.h" #include #include "./bit_cost.h" /* BrotliPopulationCost */ #include "./fast_log.h" #include "./histogram.h" #include "./memory.h" -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/cluster.h b/c/enc/cluster.h index be58614..bb26124 100644 --- a/c/enc/cluster.h +++ b/c/enc/cluster.h @@ -9,10 +9,10 @@ #ifndef BROTLI_ENC_CLUSTER_H_ #define BROTLI_ENC_CLUSTER_H_ +#include "../common/platform.h" #include #include "./histogram.h" #include "./memory.h" -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/command.h b/c/enc/command.h index 632318e..3bf0cf7 100644 --- a/c/enc/command.h +++ b/c/enc/command.h @@ -10,7 +10,7 @@ #define BROTLI_ENC_COMMAND_H_ #include "../common/constants.h" -#include +#include "../common/platform.h" #include #include "./fast_log.h" #include "./prefix.h" diff --git a/c/enc/compress_fragment.c b/c/enc/compress_fragment.c index b4ca810..40dce3e 100644 --- a/c/enc/compress_fragment.c +++ b/c/enc/compress_fragment.c @@ -17,16 +17,15 @@ #include /* memcmp, memcpy, memset */ #include "../common/constants.h" +#include "../common/platform.h" #include #include "./brotli_bit_stream.h" #include "./entropy_encode.h" #include "./fast_log.h" #include "./find_match_length.h" #include "./memory.h" -#include "./port.h" #include "./write_bits.h" - #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -48,8 +47,8 @@ static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) { static BROTLI_INLINE uint32_t HashBytesAtOffset( uint64_t v, int offset, size_t shift) { - assert(offset >= 0); - assert(offset <= 3); + BROTLI_DCHECK(offset >= 0); + BROTLI_DCHECK(offset <= 3); { const uint64_t h = ((v >> (8 * offset)) << 24) * kHashMul32; return (uint32_t)(h >> shift); @@ -58,7 +57,7 @@ static BROTLI_INLINE uint32_t HashBytesAtOffset( static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2) { return TO_BROTLI_BOOL( - BROTLI_UNALIGNED_LOAD32(p1) == BROTLI_UNALIGNED_LOAD32(p2) && + BrotliUnalignedRead32(p1) == BrotliUnalignedRead32(p2) && p1[4] == p2[4]); } @@ -522,12 +521,12 @@ static BROTLI_INLINE void BrotliCompressFragmentFastImpl( const uint8_t* next_ip = ip; const uint8_t* candidate; - assert(next_emit < ip); + BROTLI_DCHECK(next_emit < ip); trawl: do { uint32_t hash = next_hash; uint32_t bytes_between_hash_lookups = skip++ >> 5; - assert(hash == Hash(next_ip, shift)); + BROTLI_DCHECK(hash == Hash(next_ip, shift)); ip = next_ip; next_ip = ip + bytes_between_hash_lookups; if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) { @@ -542,8 +541,8 @@ trawl: } } candidate = base_ip + table[hash]; - assert(candidate >= base_ip); - assert(candidate < ip); + BROTLI_DCHECK(candidate >= base_ip); + BROTLI_DCHECK(candidate < ip); table[hash] = (int)(ip - base_ip); } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate))); @@ -566,7 +565,7 @@ trawl: int distance = (int)(base - candidate); /* > 0 */ size_t insert = (size_t)(base - next_emit); ip += matched; - assert(0 == memcmp(base, candidate, matched)); + BROTLI_DCHECK(0 == memcmp(base, candidate, matched)); if (BROTLI_PREDICT_TRUE(insert < 6210)) { EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, storage_ix, storage); @@ -626,7 +625,7 @@ trawl: if (ip - candidate > MAX_DISTANCE) break; ip += matched; last_distance = (int)(base - candidate); /* > 0 */ - assert(0 == memcmp(base, candidate, matched)); + BROTLI_DCHECK(0 == memcmp(base, candidate, matched)); EmitCopyLen(matched, cmd_depth, cmd_bits, cmd_histo, storage_ix, storage); EmitDistance((size_t)last_distance, cmd_depth, cmd_bits, @@ -659,7 +658,7 @@ trawl: } emit_remainder: - assert(next_emit <= ip_end); + BROTLI_DCHECK(next_emit <= ip_end); input += block_size; input_size -= block_size; block_size = BROTLI_MIN(size_t, input_size, kMergeBlockSize); @@ -669,7 +668,7 @@ trawl: if (input_size > 0 && total_block_size + block_size <= (1 << 20) && ShouldMergeBlock(input, block_size, lit_depth)) { - assert(total_block_size > (1 << 16)); + BROTLI_DCHECK(total_block_size > (1 << 16)); /* Update the size of the current meta-block and continue emitting commands. We can do this because the current size and the new size both have 5 nibbles. */ @@ -752,7 +751,7 @@ void BrotliCompressFragmentFast( const size_t table_bits = Log2FloorNonZero(table_size); if (input_size == 0) { - assert(is_last); + BROTLI_DCHECK(is_last); BrotliWriteBits(1, 1, storage_ix, storage); /* islast */ BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */ *storage_ix = (*storage_ix + 7u) & ~7u; @@ -768,7 +767,7 @@ void BrotliCompressFragmentFast( break; FOR_TABLE_BITS_(CASE_) #undef CASE_ - default: assert(0); break; + default: BROTLI_DCHECK(0); break; } /* If output is larger than single uncompressed block, rewrite it. */ diff --git a/c/enc/compress_fragment.h b/c/enc/compress_fragment.h index d221266..80007f5 100644 --- a/c/enc/compress_fragment.h +++ b/c/enc/compress_fragment.h @@ -12,9 +12,9 @@ #ifndef BROTLI_ENC_COMPRESS_FRAGMENT_H_ #define BROTLI_ENC_COMPRESS_FRAGMENT_H_ +#include "../common/platform.h" #include #include "./memory.h" -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/compress_fragment_two_pass.c b/c/enc/compress_fragment_two_pass.c index e6611a0..8259817 100644 --- a/c/enc/compress_fragment_two_pass.c +++ b/c/enc/compress_fragment_two_pass.c @@ -15,6 +15,7 @@ #include /* memcmp, memcpy, memset */ #include "../common/constants.h" +#include "../common/platform.h" #include #include "./bit_cost.h" #include "./brotli_bit_stream.h" @@ -22,10 +23,8 @@ #include "./fast_log.h" #include "./find_match_length.h" #include "./memory.h" -#include "./port.h" #include "./write_bits.h" - #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif @@ -47,8 +46,8 @@ static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) { static BROTLI_INLINE uint32_t HashBytesAtOffset( uint64_t v, int offset, size_t shift) { - assert(offset >= 0); - assert(offset <= 2); + BROTLI_DCHECK(offset >= 0); + BROTLI_DCHECK(offset <= 2); { const uint64_t h = ((v >> (8 * offset)) << 16) * kHashMul32; return (uint32_t)(h >> shift); @@ -57,7 +56,7 @@ static BROTLI_INLINE uint32_t HashBytesAtOffset( static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2) { return TO_BROTLI_BOOL( - BROTLI_UNALIGNED_LOAD32(p1) == BROTLI_UNALIGNED_LOAD32(p2) && + BrotliUnalignedRead32(p1) == BrotliUnalignedRead32(p2) && p1[4] == p2[4] && p1[5] == p2[5]); } @@ -281,13 +280,13 @@ static BROTLI_INLINE void CreateCommands(const uint8_t* input, const uint8_t* next_ip = ip; const uint8_t* candidate; - assert(next_emit < ip); + BROTLI_DCHECK(next_emit < ip); trawl: do { uint32_t hash = next_hash; uint32_t bytes_between_hash_lookups = skip++ >> 5; ip = next_ip; - assert(hash == Hash(ip, shift)); + BROTLI_DCHECK(hash == Hash(ip, shift)); next_ip = ip + bytes_between_hash_lookups; if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) { goto emit_remainder; @@ -301,8 +300,8 @@ trawl: } } candidate = base_ip + table[hash]; - assert(candidate >= base_ip); - assert(candidate < ip); + BROTLI_DCHECK(candidate >= base_ip); + BROTLI_DCHECK(candidate < ip); table[hash] = (int)(ip - base_ip); } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate))); @@ -325,7 +324,7 @@ trawl: int distance = (int)(base - candidate); /* > 0 */ int insert = (int)(base - next_emit); ip += matched; - assert(0 == memcmp(base, candidate, matched)); + BROTLI_DCHECK(0 == memcmp(base, candidate, matched)); EmitInsertLen((uint32_t)insert, commands); memcpy(*literals, next_emit, (size_t)insert); *literals += insert; @@ -374,7 +373,7 @@ trawl: candidate + 6, ip + 6, (size_t)(ip_end - ip) - 6); ip += matched; last_distance = (int)(base - candidate); /* > 0 */ - assert(0 == memcmp(base, candidate, matched)); + BROTLI_DCHECK(0 == memcmp(base, candidate, matched)); EmitCopyLen(matched, commands); EmitDistance((uint32_t)last_distance, commands); @@ -411,7 +410,7 @@ trawl: } emit_remainder: - assert(next_emit <= ip_end); + BROTLI_DCHECK(next_emit <= ip_end); /* Emit the remaining bytes as literals. */ if (next_emit < ip_end) { const uint32_t insert = (uint32_t)(ip_end - next_emit); @@ -457,7 +456,7 @@ static void StoreCommands(MemoryManager* m, for (i = 0; i < num_commands; ++i) { const uint32_t code = commands[i] & 0xFF; - assert(code < 128); + BROTLI_DCHECK(code < 128); ++cmd_histo[code]; } cmd_histo[1] += 1; @@ -471,7 +470,7 @@ static void StoreCommands(MemoryManager* m, const uint32_t cmd = commands[i]; const uint32_t code = cmd & 0xFF; const uint32_t extra = cmd >> 8; - assert(code < 128); + BROTLI_DCHECK(code < 128); BrotliWriteBits(cmd_depths[code], cmd_bits[code], storage_ix, storage); BrotliWriteBits(kNumExtraBits[code], extra, storage_ix, storage); if (code < 24) { @@ -589,7 +588,7 @@ void BrotliCompressFragmentTwoPass( break; FOR_TABLE_BITS_(CASE_) #undef CASE_ - default: assert(0); break; + default: BROTLI_DCHECK(0); break; } /* If output is larger than single uncompressed block, rewrite it. */ diff --git a/c/enc/compress_fragment_two_pass.h b/c/enc/compress_fragment_two_pass.h index ed91942..928677d 100644 --- a/c/enc/compress_fragment_two_pass.h +++ b/c/enc/compress_fragment_two_pass.h @@ -13,9 +13,9 @@ #ifndef BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ #define BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ +#include "../common/platform.h" #include #include "./memory.h" -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/context.h b/c/enc/context.h index 0e2e453..caa4230 100644 --- a/c/enc/context.h +++ b/c/enc/context.h @@ -9,7 +9,7 @@ #ifndef BROTLI_ENC_CONTEXT_H_ #define BROTLI_ENC_CONTEXT_H_ -#include +#include "../common/platform.h" #include #if defined(__cplusplus) || defined(c_plusplus) diff --git a/c/enc/dictionary_hash.c b/c/enc/dictionary_hash.c index 4018784..3677d7d 100644 --- a/c/enc/dictionary_hash.c +++ b/c/enc/dictionary_hash.c @@ -6,7 +6,7 @@ /* Hash table on the 4-byte prefixes of static dictionary words. */ -#include +#include "../common/platform.h" #include "./dictionary_hash.h" #if defined(__cplusplus) || defined(c_plusplus) diff --git a/c/enc/encode.c b/c/enc/encode.c index 0695210..794a409 100644 --- a/c/enc/encode.c +++ b/c/enc/encode.c @@ -11,6 +11,7 @@ #include /* free, malloc */ #include /* memcpy, memset */ +#include "../common/platform.h" #include "../common/version.h" #include "./backward_references.h" #include "./backward_references_hq.h" @@ -25,7 +26,6 @@ #include "./histogram.h" #include "./memory.h" #include "./metablock.h" -#include "./port.h" #include "./prefix.h" #include "./quality.h" #include "./ringbuffer.h" @@ -226,7 +226,7 @@ static int* GetHashTable(BrotliEncoderState* s, int quality, const size_t max_table_size = MaxHashTableSize(quality); size_t htsize = HashTableSize(max_table_size, input_size); int* table; - assert(max_table_size >= 256); + BROTLI_DCHECK(max_table_size >= 256); if (quality == FAST_ONE_PASS_COMPRESSION_QUALITY) { /* Only odd shifts are supported by fast-one-pass. */ if ((htsize & 0xAAAAA) == 0) { @@ -357,7 +357,7 @@ static void ChooseContextMap(int quality, } total = monogram_histo[0] + monogram_histo[1] + monogram_histo[2]; - assert(total != 0); + BROTLI_DCHECK(total != 0); entropy[0] = 1.0 / (double)total; entropy[1] *= entropy[0]; entropy[2] *= entropy[0]; @@ -949,24 +949,27 @@ static BROTLI_BOOL EncodeData( if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; if (s->params.quality == ZOPFLIFICATION_QUALITY) { - assert(s->params.hasher.type == 10); + BROTLI_DCHECK(s->params.hasher.type == 10); BrotliCreateZopfliBackwardReferences( - m, dictionary, bytes, wrapped_last_processed_pos, data, mask, - &s->params, s->hasher_, s->dist_cache_, &s->last_insert_len_, - &s->commands_[s->num_commands_], &s->num_commands_, &s->num_literals_); + m, dictionary, bytes, wrapped_last_processed_pos, + data, mask, &s->params, s->hasher_, s->dist_cache_, + &s->last_insert_len_, &s->commands_[s->num_commands_], + &s->num_commands_, &s->num_literals_); if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; } else if (s->params.quality == HQ_ZOPFLIFICATION_QUALITY) { - assert(s->params.hasher.type == 10); + BROTLI_DCHECK(s->params.hasher.type == 10); BrotliCreateHqZopfliBackwardReferences( - m, dictionary, bytes, wrapped_last_processed_pos, data, mask, - &s->params, s->hasher_, s->dist_cache_, &s->last_insert_len_, - &s->commands_[s->num_commands_], &s->num_commands_, &s->num_literals_); + m, dictionary, bytes, wrapped_last_processed_pos, + data, mask, &s->params, s->hasher_, s->dist_cache_, + &s->last_insert_len_, &s->commands_[s->num_commands_], + &s->num_commands_, &s->num_literals_); if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; } else { BrotliCreateBackwardReferences( - dictionary, bytes, wrapped_last_processed_pos, data, mask, - &s->params, s->hasher_, s->dist_cache_, &s->last_insert_len_, - &s->commands_[s->num_commands_], &s->num_commands_, &s->num_literals_); + dictionary, bytes, wrapped_last_processed_pos, + data, mask, &s->params, s->hasher_, s->dist_cache_, + &s->last_insert_len_, &s->commands_[s->num_commands_], + &s->num_commands_, &s->num_literals_); } { @@ -1009,9 +1012,9 @@ static BROTLI_BOOL EncodeData( *out_size = 0; return BROTLI_TRUE; } - assert(s->input_pos_ >= s->last_flush_pos_); - assert(s->input_pos_ > s->last_flush_pos_ || is_last); - assert(s->input_pos_ - s->last_flush_pos_ <= 1u << 24); + BROTLI_DCHECK(s->input_pos_ >= s->last_flush_pos_); + BROTLI_DCHECK(s->input_pos_ > s->last_flush_pos_ || is_last); + BROTLI_DCHECK(s->input_pos_ - s->last_flush_pos_ <= 1u << 24); { const uint32_t metablock_size = (uint32_t)(s->input_pos_ - s->last_flush_pos_); @@ -1116,7 +1119,7 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( BrotliInitMemoryManager(m, 0, 0, 0); - assert(input_size <= mask + 1); + BROTLI_DCHECK(input_size <= mask + 1); EncodeWindowBits(lgwin, &last_byte, &last_byte_bits); InitOrStitchToPreviousBlock(m, &hasher, input_buffer, mask, ¶ms, 0, hasher_eff_size, BROTLI_TRUE); @@ -1149,8 +1152,9 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( StitchToPreviousBlockH10(hasher, block_size, block_start, input_buffer, mask); path_size = BrotliZopfliComputeShortestPath( - m, dictionary, block_size, block_start, input_buffer, mask, ¶ms, - max_backward_limit, dist_cache, hasher, nodes); + m, dictionary, block_size, block_start, + input_buffer, mask, ¶ms, max_backward_limit, dist_cache, hasher, + nodes); if (BROTLI_IS_OOM(m)) goto oom; /* We allocate a command buffer in the first iteration of this loop that will be likely big enough for the whole metablock, so that for most @@ -1259,8 +1263,10 @@ static BROTLI_BOOL BrotliCompressBufferQuality10( last_byte = storage[storage_ix >> 3]; last_byte_bits = storage_ix & 7u; metablock_start += metablock_size; - prev_byte = input_buffer[metablock_start - 1]; - prev_byte2 = input_buffer[metablock_start - 2]; + if (metablock_start < input_size) { + prev_byte = input_buffer[metablock_start - 1]; + prev_byte2 = input_buffer[metablock_start - 2]; + } /* Save the state of the distance cache in case we need to restore it for emitting an uncompressed block. */ memcpy(saved_dist_cache, dist_cache, 4 * sizeof(dist_cache[0])); @@ -1290,12 +1296,10 @@ oom: size_t BrotliEncoderMaxCompressedSize(size_t input_size) { /* [window bits / empty metadata] + N * [uncompressed] + [last empty] */ - size_t num_large_blocks = input_size >> 24; - size_t tail = input_size - (num_large_blocks << 24); - size_t tail_overhead = (tail > (1 << 20)) ? 4 : 3; - size_t overhead = 2 + (4 * num_large_blocks) + tail_overhead + 1; + size_t num_small_blocks = input_size >> 14; + size_t overhead = 2 + (4 * num_small_blocks) + 3 + 1; size_t result = input_size + overhead; - if (input_size == 0) return 1; + if (input_size == 0) return 2; return (result < input_size) ? 0 : result; } @@ -1546,8 +1550,8 @@ static BROTLI_BOOL BrotliEncoderCompressStreamFast( *available_in -= block_size; if (inplace) { size_t out_bytes = storage_ix >> 3; - assert(out_bytes <= *available_out); - assert((storage_ix & 7) == 0 || out_bytes < *available_out); + BROTLI_DCHECK(out_bytes <= *available_out); + BROTLI_DCHECK((storage_ix & 7) == 0 || out_bytes < *available_out); *next_out += out_bytes; *available_out -= out_bytes; s->total_out_ += out_bytes; diff --git a/c/enc/entropy_encode.c b/c/enc/entropy_encode.c index 41ea948..9e0ea11 100644 --- a/c/enc/entropy_encode.c +++ b/c/enc/entropy_encode.c @@ -11,8 +11,8 @@ #include /* memset */ #include "../common/constants.h" +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -23,7 +23,7 @@ BROTLI_BOOL BrotliSetDepth( int stack[16]; int level = 0; int p = p0; - assert(max_depth <= 15); + BROTLI_DCHECK(max_depth <= 15); stack[0] = -1; while (BROTLI_TRUE) { if (pool[p].index_left_ >= 0) { @@ -165,7 +165,7 @@ static void BrotliWriteHuffmanTreeRepetitions( size_t* tree_size, uint8_t* tree, uint8_t* extra_bits_data) { - assert(repetitions > 0); + BROTLI_DCHECK(repetitions > 0); if (previous_value != value) { tree[*tree_size] = value; extra_bits_data[*tree_size] = 0; diff --git a/c/enc/entropy_encode.h b/c/enc/entropy_encode.h index 812d009..ef7c216 100644 --- a/c/enc/entropy_encode.h +++ b/c/enc/entropy_encode.h @@ -9,8 +9,8 @@ #ifndef BROTLI_ENC_ENTROPY_ENCODE_H_ #define BROTLI_ENC_ENTROPY_ENCODE_H_ +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/entropy_encode_static.h b/c/enc/entropy_encode_static.h index bc0ee53..b2c1fbb 100644 --- a/c/enc/entropy_encode_static.h +++ b/c/enc/entropy_encode_static.h @@ -10,7 +10,7 @@ #define BROTLI_ENC_ENTROPY_ENCODE_STATIC_H_ #include "../common/constants.h" -#include +#include "../common/platform.h" #include #include "./write_bits.h" diff --git a/c/enc/fast_log.h b/c/enc/fast_log.h index 49c1af3..d45a528 100644 --- a/c/enc/fast_log.h +++ b/c/enc/fast_log.h @@ -11,8 +11,8 @@ #include +#include "../common/platform.h" #include -#include #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/find_match_length.h b/c/enc/find_match_length.h index 4184531..bc428cf 100644 --- a/c/enc/find_match_length.h +++ b/c/enc/find_match_length.h @@ -9,8 +9,8 @@ #ifndef BROTLI_ENC_FIND_MATCH_LENGTH_H_ #define BROTLI_ENC_FIND_MATCH_LENGTH_H_ +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -60,8 +60,8 @@ static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, the first non-matching bit and use that to calculate the total length of the match. */ while (s2_ptr <= s2_limit - 4 && - BROTLI_UNALIGNED_LOAD32(s2_ptr) == - BROTLI_UNALIGNED_LOAD32(s1 + matched)) { + BrotliUnalignedRead32(s2_ptr) == + BrotliUnalignedRead32(s1 + matched)) { s2_ptr += 4; matched += 4; } diff --git a/c/enc/hash.h b/c/enc/hash.h index c94edd3..2a1634d 100644 --- a/c/enc/hash.h +++ b/c/enc/hash.h @@ -14,11 +14,11 @@ #include "../common/constants.h" #include "../common/dictionary.h" +#include "../common/platform.h" #include #include "./fast_log.h" #include "./find_match_length.h" #include "./memory.h" -#include "./port.h" #include "./quality.h" #include "./static_dict.h" @@ -79,7 +79,7 @@ static const uint64_t kHashMul64Long = BROTLI_MAKE_UINT64_T(0x1fe35a7bU, 0xd3579bd3U); static BROTLI_INLINE uint32_t Hash14(const uint8_t* data) { - uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kHashMul32; + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; /* The higher bits contain more mixture from the multiplication, so we take our results from there. */ return h >> (32 - 14); diff --git a/c/enc/hash_forgetful_chain_inc.h b/c/enc/hash_forgetful_chain_inc.h index 8f9ee73..46d363c 100644 --- a/c/enc/hash_forgetful_chain_inc.h +++ b/c/enc/hash_forgetful_chain_inc.h @@ -29,7 +29,7 @@ static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; } /* HashBytes is the function that chooses the bucket to place the address in.*/ static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t *data) { - const uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kHashMul32; + const uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; /* The higher bits contain more mixture from the multiplication, so we take our results from there. */ return h >> (32 - BUCKET_BITS); diff --git a/c/enc/hash_longest_match_inc.h b/c/enc/hash_longest_match_inc.h index dc5335f..d24576d 100644 --- a/c/enc/hash_longest_match_inc.h +++ b/c/enc/hash_longest_match_inc.h @@ -21,7 +21,7 @@ static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; } /* HashBytes is the function that chooses the bucket to place the address in. */ static uint32_t FN(HashBytes)(const uint8_t *data, const int shift) { - uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kHashMul32; + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; /* The higher bits contain more mixture from the multiplication, so we take our results from there. */ return (uint32_t)(h >> shift); diff --git a/c/enc/hash_to_binary_tree_inc.h b/c/enc/hash_to_binary_tree_inc.h index 30c71b5..73774b2 100644 --- a/c/enc/hash_to_binary_tree_inc.h +++ b/c/enc/hash_to_binary_tree_inc.h @@ -25,7 +25,7 @@ static BROTLI_INLINE size_t FN(StoreLookahead)(void) { } static uint32_t FN(HashBytes)(const uint8_t *data) { - uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kHashMul32; + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; /* The higher bits contain more mixture from the multiplication, so we take our results from there. */ return h >> (32 - BUCKET_BITS); @@ -154,12 +154,13 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)( { const size_t cur_len = BROTLI_MIN(size_t, best_len_left, best_len_right); size_t len; - assert(cur_len <= MAX_TREE_COMP_LENGTH); + BROTLI_DCHECK(cur_len <= MAX_TREE_COMP_LENGTH); len = cur_len + FindMatchLengthWithLimit(&data[cur_ix_masked + cur_len], &data[prev_ix_masked + cur_len], max_length - cur_len); - assert(0 == memcmp(&data[cur_ix_masked], &data[prev_ix_masked], len)); + BROTLI_DCHECK( + 0 == memcmp(&data[cur_ix_masked], &data[prev_ix_masked], len)); if (matches && len > *best_len) { *best_len = len; InitBackwardMatch(matches++, backward, len); diff --git a/c/enc/histogram.h b/c/enc/histogram.h index 2161574..b1b8d11 100644 --- a/c/enc/histogram.h +++ b/c/enc/histogram.h @@ -12,11 +12,11 @@ #include /* memset */ #include "../common/constants.h" +#include "../common/platform.h" #include #include "./block_splitter.h" #include "./command.h" #include "./context.h" -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/literal_cost.c b/c/enc/literal_cost.c index 91c691c..9bcb680 100644 --- a/c/enc/literal_cost.c +++ b/c/enc/literal_cost.c @@ -9,9 +9,9 @@ #include "./literal_cost.h" +#include "../common/platform.h" #include #include "./fast_log.h" -#include "./port.h" #include "./utf8_util.h" #if defined(__cplusplus) || defined(c_plusplus) diff --git a/c/enc/literal_cost.h b/c/enc/literal_cost.h index 7b3d030..d2f430c 100644 --- a/c/enc/literal_cost.h +++ b/c/enc/literal_cost.h @@ -10,8 +10,8 @@ #ifndef BROTLI_ENC_LITERAL_COST_H_ #define BROTLI_ENC_LITERAL_COST_H_ +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/memory.c b/c/enc/memory.c index 5aa5a22..3716b98 100644 --- a/c/enc/memory.c +++ b/c/enc/memory.c @@ -9,12 +9,11 @@ #include "./memory.h" -#include #include /* exit, free, malloc */ #include /* memcpy */ +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -132,11 +131,11 @@ static void CollectGarbagePointers(MemoryManager* m) { m->pointers + NEW_FREED_OFFSET, m->new_freed); m->perm_allocated -= annihilated; m->new_freed -= annihilated; - assert(m->new_freed == 0); + BROTLI_DCHECK(m->new_freed == 0); } if (m->new_allocated != 0) { - assert(m->perm_allocated + m->new_allocated <= MAX_PERM_ALLOCATED); + BROTLI_DCHECK(m->perm_allocated + m->new_allocated <= MAX_PERM_ALLOCATED); memcpy(m->pointers + PERM_ALLOCATED_OFFSET + m->perm_allocated, m->pointers + NEW_ALLOCATED_OFFSET, sizeof(void*) * m->new_allocated); diff --git a/c/enc/memory.h b/c/enc/memory.h index babf1f8..2d56e97 100644 --- a/c/enc/memory.h +++ b/c/enc/memory.h @@ -9,8 +9,10 @@ #ifndef BROTLI_ENC_MEMORY_H_ #define BROTLI_ENC_MEMORY_H_ +#include /* memcpy */ + +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -56,6 +58,28 @@ BROTLI_INTERNAL void BrotliFree(MemoryManager* m, void* p); BROTLI_INTERNAL void BrotliWipeOutMemoryManager(MemoryManager* m); +/* +Dynamically grows array capacity to at least the requested size +M: MemoryManager +T: data type +A: array +C: capacity +R: requested size +*/ +#define BROTLI_ENSURE_CAPACITY(M, T, A, C, R) { \ + if (C < (R)) { \ + size_t _new_size = (C == 0) ? (R) : C; \ + T* new_array; \ + while (_new_size < (R)) _new_size *= 2; \ + new_array = BROTLI_ALLOC((M), T, _new_size); \ + if (!BROTLI_IS_OOM(M) && C != 0) \ + memcpy(new_array, A, C * sizeof(T)); \ + BROTLI_FREE((M), A); \ + A = new_array; \ + C = _new_size; \ + } \ +} + #if defined(__cplusplus) || defined(c_plusplus) } /* extern "C" */ #endif diff --git a/c/enc/metablock.c b/c/enc/metablock.c index 1db76da..50f2ea2 100644 --- a/c/enc/metablock.c +++ b/c/enc/metablock.c @@ -10,6 +10,7 @@ #include "./metablock.h" #include "../common/constants.h" +#include "../common/platform.h" #include #include "./bit_cost.h" #include "./block_splitter.h" @@ -18,7 +19,6 @@ #include "./entropy_encode.h" #include "./histogram.h" #include "./memory.h" -#include "./port.h" #include "./quality.h" #if defined(__cplusplus) || defined(c_plusplus) @@ -77,7 +77,7 @@ void BrotliBuildMetaBlock(MemoryManager* m, if (BROTLI_IS_OOM(m)) return; ClearHistogramsDistance(distance_histograms, distance_histograms_size); - assert(mb->command_histograms == 0); + BROTLI_DCHECK(mb->command_histograms == 0); mb->command_histograms_size = mb->command_split.num_types; mb->command_histograms = BROTLI_ALLOC(m, HistogramCommand, mb->command_histograms_size); @@ -90,14 +90,14 @@ void BrotliBuildMetaBlock(MemoryManager* m, literal_histograms, mb->command_histograms, distance_histograms); BROTLI_FREE(m, literal_context_modes); - assert(mb->literal_context_map == 0); + BROTLI_DCHECK(mb->literal_context_map == 0); mb->literal_context_map_size = mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS; mb->literal_context_map = BROTLI_ALLOC(m, uint32_t, mb->literal_context_map_size); if (BROTLI_IS_OOM(m)) return; - assert(mb->literal_histograms == 0); + BROTLI_DCHECK(mb->literal_histograms == 0); mb->literal_histograms_size = mb->literal_context_map_size; mb->literal_histograms = BROTLI_ALLOC(m, HistogramLiteral, mb->literal_histograms_size); @@ -121,14 +121,14 @@ void BrotliBuildMetaBlock(MemoryManager* m, } } - assert(mb->distance_context_map == 0); + BROTLI_DCHECK(mb->distance_context_map == 0); mb->distance_context_map_size = mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS; mb->distance_context_map = BROTLI_ALLOC(m, uint32_t, mb->distance_context_map_size); if (BROTLI_IS_OOM(m)) return; - assert(mb->distance_histograms == 0); + BROTLI_DCHECK(mb->distance_histograms == 0); mb->distance_histograms_size = mb->distance_context_map_size; mb->distance_histograms = BROTLI_ALLOC(m, HistogramDistance, mb->distance_histograms_size); @@ -200,7 +200,7 @@ static void InitContextBlockSplitter( size_t* histograms_size) { size_t max_num_blocks = num_symbols / min_block_size + 1; size_t max_num_types; - assert(num_contexts <= BROTLI_MAX_STATIC_CONTEXTS); + BROTLI_DCHECK(num_contexts <= BROTLI_MAX_STATIC_CONTEXTS); self->alphabet_size_ = alphabet_size; self->num_contexts_ = num_contexts; @@ -226,7 +226,7 @@ static void InitContextBlockSplitter( if (BROTLI_IS_OOM(m)) return; split->num_blocks = max_num_blocks; if (BROTLI_IS_OOM(m)) return; - assert(*histograms == 0); + BROTLI_DCHECK(*histograms == 0); *histograms_size = max_num_types * num_contexts; *histograms = BROTLI_ALLOC(m, HistogramLiteral, *histograms_size); self->histograms_ = *histograms; @@ -379,7 +379,7 @@ static void MapStaticContexts(MemoryManager* m, const uint32_t* static_context_map, MetaBlockSplit* mb) { size_t i; - assert(mb->literal_context_map == 0); + BROTLI_DCHECK(mb->literal_context_map == 0); mb->literal_context_map_size = mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS; mb->literal_context_map = diff --git a/c/enc/metablock.h b/c/enc/metablock.h index cc52399..3fa6d65 100644 --- a/c/enc/metablock.h +++ b/c/enc/metablock.h @@ -10,13 +10,13 @@ #ifndef BROTLI_ENC_METABLOCK_H_ #define BROTLI_ENC_METABLOCK_H_ +#include "../common/platform.h" #include #include "./block_splitter.h" #include "./command.h" #include "./context.h" #include "./histogram.h" #include "./memory.h" -#include "./port.h" #include "./quality.h" #if defined(__cplusplus) || defined(c_plusplus) diff --git a/c/enc/metablock_inc.h b/c/enc/metablock_inc.h index c8bfb81..dcc9d3c 100644 --- a/c/enc/metablock_inc.h +++ b/c/enc/metablock_inc.h @@ -67,7 +67,7 @@ static void FN(InitBlockSplitter)( split->lengths, split->lengths_alloc_size, max_num_blocks); if (BROTLI_IS_OOM(m)) return; self->split_->num_blocks = max_num_blocks; - assert(*histograms == 0); + BROTLI_DCHECK(*histograms == 0); *histograms_size = max_num_types; *histograms = BROTLI_ALLOC(m, HistogramType, *histograms_size); self->histograms_ = *histograms; diff --git a/c/enc/params.h b/c/enc/params.h new file mode 100755 index 0000000..acb3668 --- /dev/null +++ b/c/enc/params.h @@ -0,0 +1,33 @@ +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Parameters for the Brotli encoder with chosen quality levels. */ + +#ifndef BROTLI_ENC_PARAMS_H_ +#define BROTLI_ENC_PARAMS_H_ + +#include + +typedef struct BrotliHasherParams { + int type; + int bucket_bits; + int block_bits; + int hash_len; + int num_last_distances_to_check; +} BrotliHasherParams; + +/* Encoding parameters */ +typedef struct BrotliEncoderParams { + BrotliEncoderMode mode; + int quality; + int lgwin; + int lgblock; + size_t size_hint; + BROTLI_BOOL disable_literal_context_modeling; + BrotliHasherParams hasher; +} BrotliEncoderParams; + +#endif /* BROTLI_ENC_PARAMS_H_ */ diff --git a/c/enc/port.h b/c/enc/port.h deleted file mode 100644 index c3befdf..0000000 --- a/c/enc/port.h +++ /dev/null @@ -1,192 +0,0 @@ -/* Copyright 2013 Google Inc. All Rights Reserved. - - Distributed under MIT license. - See file LICENSE for detail or copy at https://opensource.org/licenses/MIT -*/ - -/* Macros for endianness, branch prediction and unaligned loads and stores. */ - -#ifndef BROTLI_ENC_PORT_H_ -#define BROTLI_ENC_PORT_H_ - -#include -#include /* memcpy */ - -#include -#include - -#if defined OS_LINUX || defined OS_CYGWIN -#include -#elif defined OS_FREEBSD -#include -#elif defined OS_MACOSX -#include -/* Let's try and follow the Linux convention */ -#define __BYTE_ORDER BYTE_ORDER -#define __LITTLE_ENDIAN LITTLE_ENDIAN -#endif - -/* define the macro BROTLI_LITTLE_ENDIAN - using the above endian definitions from endian.h if - endian.h was included */ -#ifdef __BYTE_ORDER -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define BROTLI_LITTLE_ENDIAN -#endif - -#else - -#if defined(__LITTLE_ENDIAN__) -#define BROTLI_LITTLE_ENDIAN -#endif -#endif /* __BYTE_ORDER */ - -#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define BROTLI_LITTLE_ENDIAN -#endif - -/* Enable little-endian optimization for x64 architecture on Windows. */ -#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_X64) -#define BROTLI_LITTLE_ENDIAN -#endif - -/* Portable handling of unaligned loads, stores, and copies. - On some platforms, like ARM, the copy functions can be more efficient - then a load and a store. */ - -#if defined(BROTLI_LITTLE_ENDIAN) && (\ - defined(ARCH_PIII) || defined(ARCH_ATHLON) || \ - defined(ARCH_K8) || defined(_ARCH_PPC)) - -/* x86 and x86-64 can perform unaligned loads/stores directly; - modern PowerPC hardware can also do unaligned integer loads and stores; - but note: the FPU still sends unaligned loads and stores to a trap handler! -*/ - -#define BROTLI_UNALIGNED_LOAD32(_p) (*(const uint32_t *)(_p)) -#define BROTLI_UNALIGNED_LOAD64LE(_p) (*(const uint64_t *)(_p)) - -#define BROTLI_UNALIGNED_STORE64LE(_p, _val) \ - (*(uint64_t *)(_p) = (_val)) - -#elif defined(BROTLI_LITTLE_ENDIAN) && defined(__arm__) && \ - !defined(__ARM_ARCH_5__) && \ - !defined(__ARM_ARCH_5T__) && \ - !defined(__ARM_ARCH_5TE__) && \ - !defined(__ARM_ARCH_5TEJ__) && \ - !defined(__ARM_ARCH_6__) && \ - !defined(__ARM_ARCH_6J__) && \ - !defined(__ARM_ARCH_6K__) && \ - !defined(__ARM_ARCH_6Z__) && \ - !defined(__ARM_ARCH_6ZK__) && \ - !defined(__ARM_ARCH_6T2__) - -/* ARMv7 and newer support native unaligned accesses, but only of 16-bit - and 32-bit values (not 64-bit); older versions either raise a fatal signal, - do an unaligned read and rotate the words around a bit, or do the reads very - slowly (trip through kernel mode). */ - -#define BROTLI_UNALIGNED_LOAD32(_p) (*(const uint32_t *)(_p)) - -static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void *p) { - uint64_t t; - memcpy(&t, p, sizeof t); - return t; -} - -static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void *p, uint64_t v) { - memcpy(p, &v, sizeof v); -} - -#else - -/* These functions are provided for architectures that don't support */ -/* unaligned loads and stores. */ - -static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32(const void *p) { - uint32_t t; - memcpy(&t, p, sizeof t); - return t; -} - -#if defined(BROTLI_LITTLE_ENDIAN) - -static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void *p) { - uint64_t t; - memcpy(&t, p, sizeof t); - return t; -} - -static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void *p, uint64_t v) { - memcpy(p, &v, sizeof v); -} - -#else /* BROTLI_LITTLE_ENDIAN */ - -static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void *p) { - const uint8_t* in = (const uint8_t*)p; - uint64_t value = (uint64_t)(in[0]); - value |= (uint64_t)(in[1]) << 8; - value |= (uint64_t)(in[2]) << 16; - value |= (uint64_t)(in[3]) << 24; - value |= (uint64_t)(in[4]) << 32; - value |= (uint64_t)(in[5]) << 40; - value |= (uint64_t)(in[6]) << 48; - value |= (uint64_t)(in[7]) << 56; - return value; -} - -static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void *p, uint64_t v) { - uint8_t* out = (uint8_t*)p; - out[0] = (uint8_t)v; - out[1] = (uint8_t)(v >> 8); - out[2] = (uint8_t)(v >> 16); - out[3] = (uint8_t)(v >> 24); - out[4] = (uint8_t)(v >> 32); - out[5] = (uint8_t)(v >> 40); - out[6] = (uint8_t)(v >> 48); - out[7] = (uint8_t)(v >> 56); -} - -#endif /* BROTLI_LITTLE_ENDIAN */ - -#endif - -#define TEMPLATE_(T) \ - static BROTLI_INLINE T brotli_min_ ## T (T a, T b) { return a < b ? a : b; } \ - static BROTLI_INLINE T brotli_max_ ## T (T a, T b) { return a > b ? a : b; } -TEMPLATE_(double) TEMPLATE_(float) TEMPLATE_(int) -TEMPLATE_(size_t) TEMPLATE_(uint32_t) TEMPLATE_(uint8_t) -#undef TEMPLATE_ -#define BROTLI_MIN(T, A, B) (brotli_min_ ## T((A), (B))) -#define BROTLI_MAX(T, A, B) (brotli_max_ ## T((A), (B))) - -#define BROTLI_SWAP(T, A, I, J) { \ - T __brotli_swap_tmp = (A)[(I)]; \ - (A)[(I)] = (A)[(J)]; \ - (A)[(J)] = __brotli_swap_tmp; \ -} - -/* -Dynamically grows array capacity to at least the requested size -M: MemoryManager -T: data type -A: array -C: capacity -R: requested size -*/ -#define BROTLI_ENSURE_CAPACITY(M, T, A, C, R) { \ - if (C < (R)) { \ - size_t _new_size = (C == 0) ? (R) : C; \ - T* new_array; \ - while (_new_size < (R)) _new_size *= 2; \ - new_array = BROTLI_ALLOC((M), T, _new_size); \ - if (!BROTLI_IS_OOM(M) && C != 0) \ - memcpy(new_array, A, C * sizeof(T)); \ - BROTLI_FREE((M), A); \ - A = new_array; \ - C = _new_size; \ - } \ -} - -#endif /* BROTLI_ENC_PORT_H_ */ diff --git a/c/enc/prefix.h b/c/enc/prefix.h index e279ffe..0168d4e 100644 --- a/c/enc/prefix.h +++ b/c/enc/prefix.h @@ -11,7 +11,7 @@ #define BROTLI_ENC_PREFIX_H_ #include "../common/constants.h" -#include +#include "../common/platform.h" #include #include "./fast_log.h" diff --git a/c/enc/quality.h b/c/enc/quality.h index 5791470..80b7051 100644 --- a/c/enc/quality.h +++ b/c/enc/quality.h @@ -10,8 +10,9 @@ #ifndef BROTLI_ENC_QUALITY_H_ #define BROTLI_ENC_QUALITY_H_ +#include "../common/platform.h" #include -#include "./port.h" +#include "./params.h" #define FAST_ONE_PASS_COMPRESSION_QUALITY 0 #define FAST_TWO_PASS_COMPRESSION_QUALITY 1 @@ -32,25 +33,6 @@ so we buffer at most this much literals and commands. */ #define MAX_NUM_DELAYED_SYMBOLS 0x2fff -typedef struct BrotliHasherParams { - int type; - int bucket_bits; - int block_bits; - int hash_len; - int num_last_distances_to_check; -} BrotliHasherParams; - -/* Encoding parameters */ -typedef struct BrotliEncoderParams { - BrotliEncoderMode mode; - int quality; - int lgwin; - int lgblock; - size_t size_hint; - BROTLI_BOOL disable_literal_context_modeling; - BrotliHasherParams hasher; -} BrotliEncoderParams; - /* Returns hash-table size for quality levels 0 and 1. */ static BROTLI_INLINE size_t MaxHashTableSize(int quality) { return quality == FAST_ONE_PASS_COMPRESSION_QUALITY ? 1 << 15 : 1 << 17; diff --git a/c/enc/ringbuffer.h b/c/enc/ringbuffer.h index 0e7ef97..4e58749 100644 --- a/c/enc/ringbuffer.h +++ b/c/enc/ringbuffer.h @@ -11,9 +11,9 @@ #include /* memcpy */ +#include "../common/platform.h" #include #include "./memory.h" -#include "./port.h" #include "./quality.h" #if defined(__cplusplus) || defined(c_plusplus) diff --git a/c/enc/static_dict.c b/c/enc/static_dict.c index b98ee8b..36caa61 100644 --- a/c/enc/static_dict.c +++ b/c/enc/static_dict.c @@ -7,8 +7,8 @@ #include "./static_dict.h" #include "../common/dictionary.h" +#include "../common/platform.h" #include "./find_match_length.h" -#include "./port.h" #include "./static_dict_lut.h" #if defined(__cplusplus) || defined(c_plusplus) @@ -21,7 +21,7 @@ static const uint8_t kOmitLastNTransforms[10] = { }; static BROTLI_INLINE uint32_t Hash(const uint8_t *data) { - uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kDictHashMul32; + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kDictHashMul32; /* The higher bits contain more mixture from the multiplication, so we take our results from there. */ return h >> (32 - kDictNumBits); @@ -79,8 +79,8 @@ static BROTLI_INLINE BROTLI_BOOL IsMatch(const BrotliDictionary* dictionary, } BROTLI_BOOL BrotliFindAllStaticDictionaryMatches( - const BrotliDictionary* dictionary, const uint8_t* data, size_t min_length, - size_t max_length, uint32_t* matches) { + const BrotliDictionary* dictionary, const uint8_t* data, + size_t min_length, size_t max_length, uint32_t* matches) { BROTLI_BOOL has_found_match = BROTLI_FALSE; { size_t offset = kStaticDictionaryBuckets[Hash(data)]; diff --git a/c/enc/static_dict.h b/c/enc/static_dict.h index fb74b13..0b3f6b3 100644 --- a/c/enc/static_dict.h +++ b/c/enc/static_dict.h @@ -10,8 +10,8 @@ #define BROTLI_ENC_STATIC_DICT_H_ #include "../common/dictionary.h" +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/utf8_util.h b/c/enc/utf8_util.h index 2ede131..8fda80c 100644 --- a/c/enc/utf8_util.h +++ b/c/enc/utf8_util.h @@ -9,8 +9,8 @@ #ifndef BROTLI_ENC_UTF8_UTIL_H_ #define BROTLI_ENC_UTF8_UTIL_H_ +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/c/enc/write_bits.h b/c/enc/write_bits.h index 83fdddc..efa66f8 100644 --- a/c/enc/write_bits.h +++ b/c/enc/write_bits.h @@ -9,11 +9,8 @@ #ifndef BROTLI_ENC_WRITE_BITS_H_ #define BROTLI_ENC_WRITE_BITS_H_ -#include -#include /* printf */ - +#include "../common/platform.h" #include -#include "./port.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -48,11 +45,9 @@ static BROTLI_INLINE void BrotliWriteBits(size_t n_bits, access a byte that was never initialized). */ uint8_t *p = &array[*pos >> 3]; uint64_t v = *p; -#ifdef BIT_WRITER_DEBUG - printf("WriteBits %2d 0x%016llx %10d\n", n_bits, bits, *pos); -#endif - assert((bits >> n_bits) == 0); - assert(n_bits <= 56); + BROTLI_LOG(("WriteBits %2d 0x%016llx %10d\n", n_bits, bits, *pos)); + BROTLI_DCHECK((bits >> n_bits) == 0); + BROTLI_DCHECK(n_bits <= 56); v |= bits << (*pos & 7); BROTLI_UNALIGNED_STORE64LE(p, v); /* Set some bits. */ *pos += n_bits; @@ -76,10 +71,8 @@ static BROTLI_INLINE void BrotliWriteBits(size_t n_bits, static BROTLI_INLINE void BrotliWriteBitsPrepareStorage( size_t pos, uint8_t *array) { -#ifdef BIT_WRITER_DEBUG - printf("WriteBitsPrepareStorage %10d\n", pos); -#endif - assert((pos & 7) == 0); + BROTLI_LOG(("WriteBitsPrepareStorage %10d\n", pos)); + BROTLI_DCHECK((pos & 7) == 0); array[pos >> 3] = 0; } diff --git a/c/include/brotli/decode.h b/c/include/brotli/decode.h index ac4fe90..1acf605 100644 --- a/c/include/brotli/decode.h +++ b/c/include/brotli/decode.h @@ -160,7 +160,7 @@ BROTLI_DEC_API BROTLI_BOOL BrotliDecoderSetParameter( * @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the * case they are both zero, default memory allocators are used. @p opaque is * passed to @p alloc_func and @p free_func when they are called. @p free_func - * should return without doing anything when asked to free a NULL pointer. + * has to return without doing anything when asked to free a NULL pointer. * * @param alloc_func custom memory allocation function * @param free_func custom memory free function diff --git a/c/include/brotli/encode.h b/c/include/brotli/encode.h index 8849de2..1fa85cc 100644 --- a/c/include/brotli/encode.h +++ b/c/include/brotli/encode.h @@ -210,7 +210,7 @@ BROTLI_ENC_API BROTLI_BOOL BrotliEncoderSetParameter( * @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the * case they are both zero, default memory allocators are used. @p opaque is * passed to @p alloc_func and @p free_func when they are called. @p free_func - * should return without doing anything when asked to free a NULL pointer. + * has to return without doing anything when asked to free a NULL pointer. * * @param alloc_func custom memory allocation function * @param free_func custom memory free function @@ -231,10 +231,9 @@ BROTLI_ENC_API void BrotliEncoderDestroyInstance(BrotliEncoderState* state); /** * Calculates the output size bound for the given @p input_size. * - * @warning Result is not applicable to ::BrotliEncoderCompressStream output, - * because every "flush" adds extra overhead bytes, and some encoder - * settings (e.g. quality @c 0 and @c 1) might imply a "soft flush" - * after every chunk of input. + * @warning Result is only valid if quality is at least @c 2 and, in + * case ::BrotliEncoderCompressStream was used, no flushes + * (::BROTLI_OPERATION_FLUSH) were performed. * * @param input_size size of projected input * @returns @c 0 if result does not fit @c size_t diff --git a/c/include/brotli/port.h b/c/include/brotli/port.h index 16c31d4..88cdbf4 100644 --- a/c/include/brotli/port.h +++ b/c/include/brotli/port.h @@ -4,7 +4,12 @@ See file LICENSE for detail or copy at https://opensource.org/licenses/MIT */ -/* Macros for compiler / platform specific features and build options. */ +/* Macros for compiler / platform specific features and build options. + + Build options are: + * BROTLI_BUILD_MODERN_COMPILER forces to use modern compilers built-ins, + features and attributes + */ #ifndef BROTLI_COMMON_PORT_H_ #define BROTLI_COMMON_PORT_H_ @@ -42,51 +47,6 @@ #define BROTLI_MODERN_COMPILER 0 #endif -/* Define "BROTLI_PREDICT_TRUE" and "BROTLI_PREDICT_FALSE" macros for capable - compilers. - -To apply compiler hint, enclose the branching condition into macros, like this: - - if (BROTLI_PREDICT_TRUE(zero == 0)) { - // main execution path - } else { - // compiler should place this code outside of main execution path - } - -OR: - - if (BROTLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) { - // compiler should place this code outside of main execution path - } - -*/ -#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_expect) -#define BROTLI_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) -#define BROTLI_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#else -#define BROTLI_PREDICT_FALSE(x) (x) -#define BROTLI_PREDICT_TRUE(x) (x) -#endif - -#if BROTLI_MODERN_COMPILER || __has_attribute(always_inline) -#define BROTLI_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline)) -#else -#define BROTLI_ATTRIBUTE_ALWAYS_INLINE -#endif - -#if defined(_WIN32) || defined(__CYGWIN__) -#define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN -#elif BROTLI_MODERN_COMPILER || __has_attribute(visibility) -#define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN \ - __attribute__ ((visibility ("hidden"))) -#else -#define BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN -#endif - -#ifndef BROTLI_INTERNAL -#define BROTLI_INTERNAL BROTLI_ATTRIBUTE_VISIBILITY_HIDDEN -#endif - #if defined(BROTLI_SHARED_COMPILATION) && defined(_WIN32) #if defined(BROTLICOMMON_SHARED_COMPILATION) #define BROTLI_COMMON_API __declspec(dllexport) @@ -109,38 +69,10 @@ OR: #define BROTLI_ENC_API #endif -#ifndef _MSC_VER -#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \ - (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) -#define BROTLI_INLINE inline BROTLI_ATTRIBUTE_ALWAYS_INLINE -#else -#define BROTLI_INLINE -#endif -#else /* _MSC_VER */ -#define BROTLI_INLINE __forceinline -#endif /* _MSC_VER */ - -#if !defined(__cplusplus) && !defined(c_plusplus) && \ - (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) -#define BROTLI_RESTRICT restrict -#elif BROTLI_GCC_VERSION > 295 || defined(__llvm__) -#define BROTLI_RESTRICT __restrict -#else -#define BROTLI_RESTRICT -#endif - -#if BROTLI_MODERN_COMPILER || __has_attribute(noinline) -#define BROTLI_NOINLINE __attribute__((noinline)) -#else -#define BROTLI_NOINLINE -#endif - #if BROTLI_MODERN_COMPILER || __has_attribute(deprecated) #define BROTLI_DEPRECATED __attribute__((deprecated)) #else #define BROTLI_DEPRECATED #endif -#define BROTLI_UNUSED(X) (void)(X) - #endif /* BROTLI_COMMON_PORT_H_ */ diff --git a/docs/decode.h.3 b/docs/decode.h.3 index 965d07f..0948bf7 100644 --- a/docs/decode.h.3 +++ b/docs/decode.h.3 @@ -1,4 +1,4 @@ -.TH "decode.h" 3 "Wed Aug 2 2017" "Brotli" \" -*- nroff -*- +.TH "decode.h" 3 "Fri Dec 8 2017" "Brotli" \" -*- nroff -*- .ad l .nh .SH NAME @@ -169,13 +169,13 @@ Partially done; should be called again with more output\&. .PP Creates an instance of \fBBrotliDecoderState\fP and initializes it\&. The instance can be used once for decoding and should then be destroyed with \fBBrotliDecoderDestroyInstance\fP, it cannot be reused for a new decoding session\&. .PP -\fCalloc_func\fP and \fCfree_func\fP \fBMUST\fP be both zero or both non-zero\&. In the case they are both zero, default memory allocators are used\&. \fCopaque\fP is passed to \fCalloc_func\fP and \fCfree_func\fP when they are called\&. +\fCalloc_func\fP and \fCfree_func\fP \fBMUST\fP be both zero or both non-zero\&. In the case they are both zero, default memory allocators are used\&. \fCopaque\fP is passed to \fCalloc_func\fP and \fCfree_func\fP when they are called\&. \fCfree_func\fP has to return without doing anything when asked to free a NULL pointer\&. .PP \fBParameters:\fP .RS 4 \fIalloc_func\fP custom memory allocation function .br -\fIfree_func\fP custom memory fee function +\fIfree_func\fP custom memory free function .br \fIopaque\fP custom memory manager handle .RE diff --git a/docs/encode.h.3 b/docs/encode.h.3 index 0ce776f..1e1193e 100644 --- a/docs/encode.h.3 +++ b/docs/encode.h.3 @@ -1,4 +1,4 @@ -.TH "encode.h" 3 "Wed Sep 20 2017" "Brotli" \" -*- nroff -*- +.TH "encode.h" 3 "Fri Dec 8 2017" "Brotli" \" -*- nroff -*- .ad l .nh .SH NAME @@ -391,13 +391,13 @@ When flushing and finishing, \fCop\fP should not change until operation is compl .SS "\fBBrotliEncoderState\fP* BrotliEncoderCreateInstance (\fBbrotli_alloc_func\fP alloc_func, \fBbrotli_free_func\fP free_func, void * opaque)" .PP -Creates an instance of \fBBrotliEncoderState\fP and initializes it\&. \fCalloc_func\fP and \fCfree_func\fP \fBMUST\fP be both zero or both non-zero\&. In the case they are both zero, default memory allocators are used\&. \fCopaque\fP is passed to \fCalloc_func\fP and \fCfree_func\fP when they are called\&. +Creates an instance of \fBBrotliEncoderState\fP and initializes it\&. \fCalloc_func\fP and \fCfree_func\fP \fBMUST\fP be both zero or both non-zero\&. In the case they are both zero, default memory allocators are used\&. \fCopaque\fP is passed to \fCalloc_func\fP and \fCfree_func\fP when they are called\&. \fCfree_func\fP has to return without doing anything when asked to free a NULL pointer\&. .PP \fBParameters:\fP .RS 4 \fIalloc_func\fP custom memory allocation function .br -\fIfree_func\fP custom memory fee function +\fIfree_func\fP custom memory free function .br \fIopaque\fP custom memory manager handle .RE @@ -464,7 +464,7 @@ Calculates the output size bound for the given \fCinput_size\fP\&. .PP \fBWarning:\fP .RS 4 -Result is not applicable to \fBBrotliEncoderCompressStream\fP output, because every 'flush' adds extra overhead bytes, and some encoder settings (e\&.g\&. quality \fC0\fP and \fC1\fP) might imply a 'soft flush' after every chunk of input\&. +Result is only valid if quality is at least \fC2\fP and, in case \fBBrotliEncoderCompressStream\fP was used, no flushes (\fBBROTLI_OPERATION_FLUSH\fP) were performed\&. .RE .PP \fBParameters:\fP