#include "./static_dict.h"\r
\r
#include "../common/dictionary.h"\r
+#include "../common/platform.h"\r
+#include "../common/transform.h"\r
+#include "./encoder_dict.h"\r
#include "./find_match_length.h"\r
-#include "./port.h"\r
-#include "./static_dict_lut.h"\r
\r
#if defined(__cplusplus) || defined(c_plusplus)\r
extern "C" {\r
#endif\r
\r
-static const uint8_t kUppercaseFirst = 10;\r
-static const uint8_t kOmitLastNTransforms[10] = {\r
- 0, 12, 27, 23, 42, 63, 56, 48, 59, 64,\r
-};\r
-\r
-static BROTLI_INLINE uint32_t Hash(const uint8_t *data) {\r
- uint32_t h = BROTLI_UNALIGNED_LOAD32(data) * kDictHashMul32;\r
+static BROTLI_INLINE uint32_t Hash(const uint8_t* data) {\r
+ uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kDictHashMul32;\r
/* The higher bits contain more mixture from the multiplication,\r
so we take our results from there. */\r
return h >> (32 - kDictNumBits);\r
matches[len] = BROTLI_MIN(uint32_t, matches[len], match);\r
}\r
\r
-static BROTLI_INLINE size_t DictMatchLength(const uint8_t* data,\r
+static BROTLI_INLINE size_t DictMatchLength(const BrotliDictionary* dictionary,\r
+ const uint8_t* data,\r
size_t id,\r
size_t len,\r
size_t maxlen) {\r
- const size_t offset = kBrotliDictionaryOffsetsByLength[len] + len * id;\r
- return FindMatchLengthWithLimit(&kBrotliDictionary[offset], data,\r
+ const size_t offset = dictionary->offsets_by_length[len] + len * id;\r
+ return FindMatchLengthWithLimit(&dictionary->data[offset], data,\r
BROTLI_MIN(size_t, len, maxlen));\r
}\r
\r
-static BROTLI_INLINE BROTLI_BOOL IsMatch(\r
+static BROTLI_INLINE BROTLI_BOOL IsMatch(const BrotliDictionary* dictionary,\r
DictWord w, const uint8_t* data, size_t max_length) {\r
if (w.len > max_length) {\r
return BROTLI_FALSE;\r
} else {\r
- const size_t offset = kBrotliDictionaryOffsetsByLength[w.len] +\r
+ const size_t offset = dictionary->offsets_by_length[w.len] +\r
(size_t)w.len * (size_t)w.idx;\r
- const uint8_t* dict = &kBrotliDictionary[offset];\r
+ const uint8_t* dict = &dictionary->data[offset];\r
if (w.transform == 0) {\r
/* Match against base dictionary word. */\r
return\r
}\r
\r
BROTLI_BOOL BrotliFindAllStaticDictionaryMatches(\r
- const uint8_t* data, size_t min_length, size_t max_length,\r
- uint32_t* matches) {\r
+ const BrotliEncoderDictionary* dictionary, const uint8_t* data,\r
+ size_t min_length, size_t max_length, uint32_t* matches) {\r
BROTLI_BOOL has_found_match = BROTLI_FALSE;\r
{\r
- size_t offset = kStaticDictionaryBuckets[Hash(data)];\r
+ size_t offset = dictionary->buckets[Hash(data)];\r
BROTLI_BOOL end = !offset;\r
while (!end) {\r
- DictWord w = kStaticDictionaryWords[offset++];\r
- const size_t l = w.len & 0x7F;\r
- const size_t n = (size_t)1 << kBrotliDictionarySizeBitsByLength[l];\r
+ DictWord w = dictionary->dict_words[offset++];\r
+ const size_t l = w.len & 0x1F;\r
+ const size_t n = (size_t)1 << dictionary->words->size_bits_by_length[l];\r
const size_t id = w.idx;\r
end = !!(w.len & 0x80);\r
w.len = (uint8_t)l;\r
if (w.transform == 0) {\r
- const size_t matchlen = DictMatchLength(data, id, l, max_length);\r
+ const size_t matchlen =\r
+ DictMatchLength(dictionary->words, data, id, l, max_length);\r
const uint8_t* s;\r
size_t minlen;\r
size_t maxlen;\r
size_t len;\r
- /* Transform "" + kIdentity + "" */\r
+ /* Transform "" + BROTLI_TRANSFORM_IDENTITY + "" */\r
if (matchlen == l) {\r
AddMatch(id, l, l, matches);\r
has_found_match = BROTLI_TRUE;\r
}\r
- /* Transforms "" + kOmitLast1 + "" and "" + kOmitLast1 + "ing " */\r
+ /* Transforms "" + BROTLI_TRANSFORM_OMIT_LAST_1 + "" and\r
+ "" + BROTLI_TRANSFORM_OMIT_LAST_1 + "ing " */\r
if (matchlen >= l - 1) {\r
AddMatch(id + 12 * n, l - 1, l, matches);\r
if (l + 2 < max_length &&\r
}\r
has_found_match = BROTLI_TRUE;\r
}\r
- /* Transform "" + kOmitLastN + "" (N = 2 .. 9) */\r
+ /* Transform "" + BROTLI_TRANSFORM_OMIT_LAST_# + "" (# = 2 .. 9) */\r
minlen = min_length;\r
if (l > 9) minlen = BROTLI_MAX(size_t, minlen, l - 9);\r
maxlen = BROTLI_MIN(size_t, matchlen, l - 2);\r
for (len = minlen; len <= maxlen; ++len) {\r
- AddMatch(id + kOmitLastNTransforms[l - len] * n, len, l, matches);\r
+ size_t cut = l - len;\r
+ size_t transform_id = (cut << 2) +\r
+ (size_t)((dictionary->cutoffTransforms >> (cut * 6)) & 0x3F);\r
+ AddMatch(id + transform_id * n, len, l, matches);\r
has_found_match = BROTLI_TRUE;\r
}\r
if (matchlen < l || l + 6 >= max_length) {\r
continue;\r
}\r
s = &data[l];\r
- /* Transforms "" + kIdentity + <suffix> */\r
+ /* Transforms "" + BROTLI_TRANSFORM_IDENTITY + <suffix> */\r
if (s[0] == ' ') {\r
AddMatch(id + n, l + 1, l, matches);\r
if (s[1] == 'a') {\r
}\r
}\r
} else {\r
- /* Set is_all_caps=0 for kUppercaseFirst and\r
- is_all_caps=1 otherwise (kUppercaseAll) transform. */\r
+ /* Set is_all_caps=0 for BROTLI_TRANSFORM_UPPERCASE_FIRST and\r
+ is_all_caps=1 otherwise (BROTLI_TRANSFORM_UPPERCASE_ALL)\r
+ transform. */\r
const BROTLI_BOOL is_all_caps =\r
- TO_BROTLI_BOOL(w.transform != kUppercaseFirst);\r
+ TO_BROTLI_BOOL(w.transform != BROTLI_TRANSFORM_UPPERCASE_FIRST);\r
const uint8_t* s;\r
- if (!IsMatch(w, data, max_length)) {\r
+ if (!IsMatch(dictionary->words, w, data, max_length)) {\r
continue;\r
}\r
/* Transform "" + kUppercase{First,All} + "" */\r
/* Transforms with prefixes " " and "." */\r
if (max_length >= 5 && (data[0] == ' ' || data[0] == '.')) {\r
BROTLI_BOOL is_space = TO_BROTLI_BOOL(data[0] == ' ');\r
- size_t offset = kStaticDictionaryBuckets[Hash(&data[1])];\r
+ size_t offset = dictionary->buckets[Hash(&data[1])];\r
BROTLI_BOOL end = !offset;\r
while (!end) {\r
- DictWord w = kStaticDictionaryWords[offset++];\r
- const size_t l = w.len & 0x7F;\r
- const size_t n = (size_t)1 << kBrotliDictionarySizeBitsByLength[l];\r
+ DictWord w = dictionary->dict_words[offset++];\r
+ const size_t l = w.len & 0x1F;\r
+ const size_t n = (size_t)1 << dictionary->words->size_bits_by_length[l];\r
const size_t id = w.idx;\r
end = !!(w.len & 0x80);\r
w.len = (uint8_t)l;\r
if (w.transform == 0) {\r
const uint8_t* s;\r
- if (!IsMatch(w, &data[1], max_length - 1)) {\r
+ if (!IsMatch(dictionary->words, w, &data[1], max_length - 1)) {\r
continue;\r
}\r
- /* Transforms " " + kIdentity + "" and "." + kIdentity + "" */\r
+ /* Transforms " " + BROTLI_TRANSFORM_IDENTITY + "" and\r
+ "." + BROTLI_TRANSFORM_IDENTITY + "" */\r
AddMatch(id + (is_space ? 6 : 32) * n, l + 1, l, matches);\r
has_found_match = BROTLI_TRUE;\r
if (l + 2 >= max_length) {\r
continue;\r
}\r
- /* Transforms " " + kIdentity + <suffix> and "." + kIdentity + <suffix>\r
+ /* Transforms " " + BROTLI_TRANSFORM_IDENTITY + <suffix> and\r
+ "." + BROTLI_TRANSFORM_IDENTITY + <suffix>\r
*/\r
s = &data[l + 1];\r
if (s[0] == ' ') {\r
}\r
}\r
} else if (is_space) {\r
- /* Set is_all_caps=0 for kUppercaseFirst and\r
- is_all_caps=1 otherwise (kUppercaseAll) transform. */\r
+ /* Set is_all_caps=0 for BROTLI_TRANSFORM_UPPERCASE_FIRST and\r
+ is_all_caps=1 otherwise (BROTLI_TRANSFORM_UPPERCASE_ALL)\r
+ transform. */\r
const BROTLI_BOOL is_all_caps =\r
- TO_BROTLI_BOOL(w.transform != kUppercaseFirst);\r
+ TO_BROTLI_BOOL(w.transform != BROTLI_TRANSFORM_UPPERCASE_FIRST);\r
const uint8_t* s;\r
- if (!IsMatch(w, &data[1], max_length - 1)) {\r
+ if (!IsMatch(dictionary->words, w, &data[1], max_length - 1)) {\r
continue;\r
}\r
/* Transforms " " + kUppercase{First,All} + "" */\r
}\r
}\r
if (max_length >= 6) {\r
- /* Transforms with prefixes "e ", "s ", ", " and "\xc2\xa0" */\r
+ /* Transforms with prefixes "e ", "s ", ", " and "\xC2\xA0" */\r
if ((data[1] == ' ' &&\r
(data[0] == 'e' || data[0] == 's' || data[0] == ',')) ||\r
- (data[0] == 0xc2 && data[1] == 0xa0)) {\r
- size_t offset = kStaticDictionaryBuckets[Hash(&data[2])];\r
+ (data[0] == 0xC2 && data[1] == 0xA0)) {\r
+ size_t offset = dictionary->buckets[Hash(&data[2])];\r
BROTLI_BOOL end = !offset;\r
while (!end) {\r
- DictWord w = kStaticDictionaryWords[offset++];\r
- const size_t l = w.len & 0x7F;\r
- const size_t n = (size_t)1 << kBrotliDictionarySizeBitsByLength[l];\r
+ DictWord w = dictionary->dict_words[offset++];\r
+ const size_t l = w.len & 0x1F;\r
+ const size_t n = (size_t)1 << dictionary->words->size_bits_by_length[l];\r
const size_t id = w.idx;\r
end = !!(w.len & 0x80);\r
w.len = (uint8_t)l;\r
- if (w.transform == 0 && IsMatch(w, &data[2], max_length - 2)) {\r
- if (data[0] == 0xc2) {\r
+ if (w.transform == 0 &&\r
+ IsMatch(dictionary->words, w, &data[2], max_length - 2)) {\r
+ if (data[0] == 0xC2) {\r
AddMatch(id + 102 * n, l + 2, l, matches);\r
has_found_match = BROTLI_TRUE;\r
} else if (l + 2 < max_length && data[l + 2] == ' ') {\r
data[3] == 'e' && data[4] == ' ') ||\r
(data[0] == '.' && data[1] == 'c' && data[2] == 'o' &&\r
data[3] == 'm' && data[4] == '/')) {\r
- size_t offset = kStaticDictionaryBuckets[Hash(&data[5])];\r
+ size_t offset = dictionary->buckets[Hash(&data[5])];\r
BROTLI_BOOL end = !offset;\r
while (!end) {\r
- DictWord w = kStaticDictionaryWords[offset++];\r
- const size_t l = w.len & 0x7F;\r
- const size_t n = (size_t)1 << kBrotliDictionarySizeBitsByLength[l];\r
+ DictWord w = dictionary->dict_words[offset++];\r
+ const size_t l = w.len & 0x1F;\r
+ const size_t n = (size_t)1 << dictionary->words->size_bits_by_length[l];\r
const size_t id = w.idx;\r
end = !!(w.len & 0x80);\r
w.len = (uint8_t)l;\r
- if (w.transform == 0 && IsMatch(w, &data[5], max_length - 5)) {\r
+ if (w.transform == 0 &&\r
+ IsMatch(dictionary->words, w, &data[5], max_length - 5)) {\r
AddMatch(id + (data[0] == ' ' ? 41 : 72) * n, l + 5, l, matches);\r
has_found_match = BROTLI_TRUE;\r
if (l + 5 < max_length) {\r