add decoder static init PiperOrigin-RevId: 802473490
diff --git a/c/dec/decode.c b/c/dec/decode.c index 05f1d37..e03f7b3 100644 --- a/c/dec/decode.c +++ b/c/dec/decode.c
@@ -17,6 +17,7 @@ #include "huffman.h" #include "prefix.h" #include "state.h" +#include "static_init.h" #if defined(BROTLI_TARGET_NEON) #include <arm_neon.h> @@ -78,6 +79,10 @@ BrotliDecoderState* BrotliDecoderCreateInstance( brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { BrotliDecoderState* state = 0; + if (!BrotliDecoderEnsureStaticInit()) { + BROTLI_DUMP(); + return 0; + } if (!alloc_func && !free_func) { state = (BrotliDecoderState*)malloc(sizeof(BrotliDecoderState)); } else if (alloc_func && free_func) {
diff --git a/c/dec/prefix.c b/c/dec/prefix.c index b31b505..ce3998f 100644 --- a/c/dec/prefix.c +++ b/c/dec/prefix.c
@@ -7,13 +7,60 @@ #include "prefix.h" #include "../common/platform.h" /* IWYU pragma: keep */ +#include "../common/static_init.h" + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +#include "../common/constants.h" +#endif #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_NONE) /* Embed kCmdLut. */ #include "prefix_inc.h" +#else +BROTLI_COLD BROTLI_BOOL BrotliDecoderInitCmdLut(CmdLutElement* items) { + static const uint8_t kInsertLengthExtraBits[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, + 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0E, 0x18}; + static const uint8_t kCopyLengthExtraBits[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, + 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x18}; + static const uint8_t kCellPos[11] = {0, 1, 0, 1, 8, 9, 2, 16, 10, 17, 18}; + + uint16_t insert_length_offsets[24]; + uint16_t copy_length_offsets[24]; + insert_length_offsets[0] = 0; + copy_length_offsets[0] = 2; + for (size_t i = 0; i < 23; ++i) { + insert_length_offsets[i + 1] = + insert_length_offsets[i] + (uint16_t)(1u << kInsertLengthExtraBits[i]); + copy_length_offsets[i + 1] = + copy_length_offsets[i] + (uint16_t)(1u << kCopyLengthExtraBits[i]); + } + + for (size_t symbol = 0; symbol < BROTLI_NUM_COMMAND_SYMBOLS; ++symbol) { + CmdLutElement* item = items + symbol; + const size_t cell_idx = symbol >> 6; + const size_t cell_pos = kCellPos[cell_idx]; + const size_t copy_code = ((cell_pos << 3) & 0x18) + (symbol & 0x7); + const uint16_t copy_len_offset = copy_length_offsets[copy_code]; + const size_t insert_code = (cell_pos & 0x18) + ((symbol >> 3) & 0x7); + item->copy_len_extra_bits = kCopyLengthExtraBits[copy_code]; + item->context = (copy_len_offset > 4) ? 3 : ((uint8_t)copy_len_offset - 2); + item->copy_len_offset = copy_len_offset; + item->distance_code = (cell_idx >= 2) ? -1 : 0; + item->insert_len_extra_bits = kInsertLengthExtraBits[insert_code]; + item->insert_len_offset = insert_length_offsets[insert_code]; + } + return BROTLI_TRUE; +} + +BROTLI_MODEL("small") +CmdLutElement kCmdLut[BROTLI_NUM_COMMAND_SYMBOLS]; +#endif /* BROTLI_STATIC_INIT */ #if defined(__cplusplus) || defined(c_plusplus) } /* extern "C" */
diff --git a/c/dec/prefix.h b/c/dec/prefix.h index 66aa52a..f45b8be 100644 --- a/c/dec/prefix.h +++ b/c/dec/prefix.h
@@ -12,6 +12,11 @@ #include "../common/constants.h" #include "../common/platform.h" /* IWYU pragma: keep */ +#include "../common/static_init.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif typedef struct CmdLutElement { uint8_t insert_len_extra_bits; @@ -22,7 +27,17 @@ uint16_t copy_len_offset; } CmdLutElement; +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_NONE) BROTLI_INTERNAL extern const BROTLI_MODEL("small") CmdLutElement kCmdLut[BROTLI_NUM_COMMAND_SYMBOLS]; +#else +BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderInitCmdLut(CmdLutElement* items); +BROTLI_INTERNAL extern BROTLI_MODEL("small") + CmdLutElement kCmdLut[BROTLI_NUM_COMMAND_SYMBOLS]; +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif #endif /* BROTLI_DEC_PREFIX_H_ */
diff --git a/c/dec/static_init.c b/c/dec/static_init.c new file mode 100644 index 0000000..1345052 --- /dev/null +++ b/c/dec/static_init.c
@@ -0,0 +1,53 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "static_init.h" + +#include "../common/platform.h" +#include "../common/static_init.h" + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +#include "../common/dictionary.h" +#include "prefix.h" +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +static BROTLI_BOOL DoBrotliDecoderStaticInit(void) { + BROTLI_BOOL ok = BrotliDecoderInitCmdLut(kCmdLut); + if (!ok) return BROTLI_FALSE; + return BROTLI_TRUE; +} +#endif /* BROTLI_STATIC_INIT_NONE */ + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) +static BROTLI_BOOL kEarlyInitOk; +static __attribute__((constructor)) void BrotliDecoderStaticInitEarly(void) { + kEarlyInitOk = DoBrotliDecoderStaticInit(); +} +#elif (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_LAZY) +static BROTLI_BOOL kLazyInitOk; +void BrotliDecoderLazyStaticInitInner(void) { + kLazyInitOk = DoBrotliDecoderStaticInit(); +} +#endif /* BROTLI_STATIC_INIT_EARLY */ + +BROTLI_BOOL BrotliDecoderEnsureStaticInit(void) { +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_NONE) + return BROTLI_TRUE; +#elif (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) + return kEarlyInitOk; +#else + return kLazyInitOk; +#endif +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif
diff --git a/c/dec/static_init.h b/c/dec/static_init.h new file mode 100644 index 0000000..4ae063e --- /dev/null +++ b/c/dec/static_init.h
@@ -0,0 +1,30 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Central point for static initialization. */ + +#ifndef THIRD_PARTY_BROTLI_DEC_STATIC_INIT_H_ +#define THIRD_PARTY_BROTLI_DEC_STATIC_INIT_H_ + +#include "../common/platform.h" +#include "../common/static_init.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_LAZY) +BROTLI_INTERNAL void BrotliDecoderLazyStaticInitInner(void); +BROTLI_INTERNAL void BrotliDecoderLazyStaticInit(void); +#endif /* BROTLI_STATIC_INIT */ + +BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderEnsureStaticInit(void); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif // THIRD_PARTY_BROTLI_DEC_STATIC_INIT_H_
diff --git a/c/enc/dictionary_hash.c b/c/enc/dictionary_hash.c index f367046..193f7a4 100644 --- a/c/enc/dictionary_hash.c +++ b/c/enc/dictionary_hash.c
@@ -9,7 +9,7 @@ #include "dictionary_hash.h" #include "../common/platform.h" /* IWYU pragma: keep */ -#include "static_init.h" +#include "../common/static_init.h" #if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) #include "../common/dictionary.h"
diff --git a/c/enc/dictionary_hash.h b/c/enc/dictionary_hash.h index 8d08f57..dfddc01 100644 --- a/c/enc/dictionary_hash.h +++ b/c/enc/dictionary_hash.h
@@ -10,7 +10,7 @@ #define BROTLI_ENC_DICTIONARY_HASH_H_ #include "../common/platform.h" -#include "static_init.h" +#include "../common/static_init.h" #if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) #include "../common/dictionary.h"
diff --git a/c/enc/static_dict_lut.c b/c/enc/static_dict_lut.c index b7a8706..109366f 100644 --- a/c/enc/static_dict_lut.c +++ b/c/enc/static_dict_lut.c
@@ -9,7 +9,7 @@ #include "static_dict_lut.h" #include "../common/platform.h" /* IWYU pragma: keep */ -#include "static_init.h" +#include "../common/static_init.h" #if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) #include "../common/dictionary.h"
diff --git a/c/enc/static_dict_lut.h b/c/enc/static_dict_lut.h index 6aa9613..078f554 100644 --- a/c/enc/static_dict_lut.h +++ b/c/enc/static_dict_lut.h
@@ -11,7 +11,7 @@ #include "../common/dictionary.h" #include "../common/platform.h" -#include "static_init.h" +#include "../common/static_init.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" {
diff --git a/c/enc/static_init_lazy.cc b/c/enc/static_init_lazy.cc index 300357e..6e00cd3 100644 --- a/c/enc/static_init_lazy.cc +++ b/c/enc/static_init_lazy.cc
@@ -1,10 +1,10 @@ -#include "third_party/brotli/common/platform.h" +#include "../common/platform.h" +#include "../common/static_init.h" #include "static_init.h" #if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_LAZY) #error "BROTLI_STATIC_INIT should be BROTLI_STATIC_INIT_LAZY" -#endif - +#else void BrotliEncoderLazyStaticInit(void) { /* From https://en.cppreference.com/w/cpp/language/storage_duration.html: ### Static block variables ### @@ -23,3 +23,4 @@ }(); if (!ok) BROTLI_CRASH(); } +#endif /* BROTLI_STATIC_INIT_LAZY */
diff --git a/setup.py b/setup.py index 5355ed8..d73d6dd 100644 --- a/setup.py +++ b/setup.py
@@ -235,6 +235,7 @@ 'c/dec/huffman.c', 'c/dec/prefix.c', 'c/dec/state.c', + 'c/dec/static_init.c', 'c/enc/backward_references.c', 'c/enc/backward_references_hq.c', 'c/enc/bit_cost.c', @@ -273,6 +274,7 @@ 'c/dec/prefix.h', 'c/dec/prefix_inc.h', 'c/dec/state.h', + 'c/dec/static_init.h', 'c/enc/backward_references.h', 'c/enc/backward_references_hq.h', 'c/enc/backward_references_inc.h',