backward_references.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /* Copyright 2013 Google Inc. All Rights Reserved.
  2. Distributed under MIT license.
  3. See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
  4. */
  5. /* Function to find backward reference copies. */
  6. #include "backward_references.h"
  7. #include <brotli/types.h>
  8. #include "../common/constants.h"
  9. #include "../common/dictionary.h"
  10. #include "../common/platform.h"
  11. #include "command.h"
  12. #include "compound_dictionary.h"
  13. #include "dictionary_hash.h"
  14. #include "encoder_dict.h"
  15. #include "memory.h"
  16. #include "quality.h"
  17. #if defined(__cplusplus) || defined(c_plusplus)
  18. extern "C" {
  19. #endif
  20. static BROTLI_INLINE size_t ComputeDistanceCode(size_t distance,
  21. size_t max_distance,
  22. const int* dist_cache) {
  23. if (distance <= max_distance) {
  24. size_t distance_plus_3 = distance + 3;
  25. size_t offset0 = distance_plus_3 - (size_t)dist_cache[0];
  26. size_t offset1 = distance_plus_3 - (size_t)dist_cache[1];
  27. if (distance == (size_t)dist_cache[0]) {
  28. return 0;
  29. } else if (distance == (size_t)dist_cache[1]) {
  30. return 1;
  31. } else if (offset0 < 7) {
  32. return (0x9750468 >> (4 * offset0)) & 0xF;
  33. } else if (offset1 < 7) {
  34. return (0xFDB1ACE >> (4 * offset1)) & 0xF;
  35. } else if (distance == (size_t)dist_cache[2]) {
  36. return 2;
  37. } else if (distance == (size_t)dist_cache[3]) {
  38. return 3;
  39. }
  40. }
  41. return distance + BROTLI_NUM_DISTANCE_SHORT_CODES - 1;
  42. }
  43. #define EXPAND_CAT(a, b) CAT(a, b)
  44. #define CAT(a, b) a ## b
  45. #define FN(X) EXPAND_CAT(X, HASHER())
  46. #define EXPORT_FN(X) EXPAND_CAT(X, EXPAND_CAT(PREFIX(), HASHER()))
  47. #define PREFIX() N
  48. #define ENABLE_COMPOUND_DICTIONARY 0
  49. #define HASHER() H2
  50. /* NOLINTNEXTLINE(build/include) */
  51. #include "backward_references_inc.h"
  52. #undef HASHER
  53. #define HASHER() H3
  54. /* NOLINTNEXTLINE(build/include) */
  55. #include "backward_references_inc.h"
  56. #undef HASHER
  57. #define HASHER() H4
  58. /* NOLINTNEXTLINE(build/include) */
  59. #include "backward_references_inc.h"
  60. #undef HASHER
  61. #define HASHER() H5
  62. /* NOLINTNEXTLINE(build/include) */
  63. #include "backward_references_inc.h"
  64. #undef HASHER
  65. #define HASHER() H6
  66. /* NOLINTNEXTLINE(build/include) */
  67. #include "backward_references_inc.h"
  68. #undef HASHER
  69. #define HASHER() H40
  70. /* NOLINTNEXTLINE(build/include) */
  71. #include "backward_references_inc.h"
  72. #undef HASHER
  73. #define HASHER() H41
  74. /* NOLINTNEXTLINE(build/include) */
  75. #include "backward_references_inc.h"
  76. #undef HASHER
  77. #define HASHER() H42
  78. /* NOLINTNEXTLINE(build/include) */
  79. #include "backward_references_inc.h"
  80. #undef HASHER
  81. #define HASHER() H54
  82. /* NOLINTNEXTLINE(build/include) */
  83. #include "backward_references_inc.h"
  84. #undef HASHER
  85. #define HASHER() H35
  86. /* NOLINTNEXTLINE(build/include) */
  87. #include "backward_references_inc.h"
  88. #undef HASHER
  89. #define HASHER() H55
  90. /* NOLINTNEXTLINE(build/include) */
  91. #include "backward_references_inc.h"
  92. #undef HASHER
  93. #define HASHER() H65
  94. /* NOLINTNEXTLINE(build/include) */
  95. #include "backward_references_inc.h"
  96. #undef HASHER
  97. #if defined(BROTLI_MAX_SIMD_QUALITY)
  98. #define HASHER() H58
  99. /* NOLINTNEXTLINE(build/include) */
  100. #include "backward_references_inc.h"
  101. #undef HASHER
  102. #define HASHER() H68
  103. /* NOLINTNEXTLINE(build/include) */
  104. #include "backward_references_inc.h"
  105. #undef HASHER
  106. #endif
  107. #undef ENABLE_COMPOUND_DICTIONARY
  108. #undef PREFIX
  109. #define PREFIX() D
  110. #define ENABLE_COMPOUND_DICTIONARY 1
  111. #define HASHER() H5
  112. /* NOLINTNEXTLINE(build/include) */
  113. #include "backward_references_inc.h"
  114. #undef HASHER
  115. #define HASHER() H6
  116. /* NOLINTNEXTLINE(build/include) */
  117. #include "backward_references_inc.h"
  118. #undef HASHER
  119. #define HASHER() H40
  120. /* NOLINTNEXTLINE(build/include) */
  121. #include "backward_references_inc.h"
  122. #undef HASHER
  123. #define HASHER() H41
  124. /* NOLINTNEXTLINE(build/include) */
  125. #include "backward_references_inc.h"
  126. #undef HASHER
  127. #define HASHER() H42
  128. /* NOLINTNEXTLINE(build/include) */
  129. #include "backward_references_inc.h"
  130. #undef HASHER
  131. #define HASHER() H55
  132. /* NOLINTNEXTLINE(build/include) */
  133. #include "backward_references_inc.h"
  134. #undef HASHER
  135. #define HASHER() H65
  136. /* NOLINTNEXTLINE(build/include) */
  137. #include "backward_references_inc.h"
  138. #undef HASHER
  139. #if defined(BROTLI_MAX_SIMD_QUALITY)
  140. #define HASHER() H58
  141. /* NOLINTNEXTLINE(build/include) */
  142. #include "backward_references_inc.h"
  143. #undef HASHER
  144. #define HASHER() H68
  145. /* NOLINTNEXTLINE(build/include) */
  146. #include "backward_references_inc.h"
  147. #undef HASHER
  148. #endif
  149. #undef ENABLE_COMPOUND_DICTIONARY
  150. #undef PREFIX
  151. #undef EXPORT_FN
  152. #undef FN
  153. #undef CAT
  154. #undef EXPAND_CAT
  155. void BrotliCreateBackwardReferences(size_t num_bytes,
  156. size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask,
  157. ContextLut literal_context_lut, const BrotliEncoderParams* params,
  158. Hasher* hasher, int* dist_cache, size_t* last_insert_len,
  159. Command* commands, size_t* num_commands, size_t* num_literals) {
  160. if (params->dictionary.compound.num_chunks != 0) {
  161. switch (params->hasher.type) {
  162. #define CASE_(N) \
  163. case N: \
  164. CreateBackwardReferencesDH ## N(num_bytes, \
  165. position, ringbuffer, ringbuffer_mask, \
  166. literal_context_lut, params, hasher, dist_cache, \
  167. last_insert_len, commands, num_commands, num_literals); \
  168. return;
  169. CASE_(5)
  170. CASE_(6)
  171. #if defined(BROTLI_MAX_SIMD_QUALITY)
  172. CASE_(58)
  173. CASE_(68)
  174. #endif
  175. CASE_(40)
  176. CASE_(41)
  177. CASE_(42)
  178. CASE_(55)
  179. CASE_(65)
  180. #undef CASE_
  181. default:
  182. BROTLI_DCHECK(false);
  183. break;
  184. }
  185. }
  186. switch (params->hasher.type) {
  187. #define CASE_(N) \
  188. case N: \
  189. CreateBackwardReferencesNH ## N(num_bytes, \
  190. position, ringbuffer, ringbuffer_mask, \
  191. literal_context_lut, params, hasher, dist_cache, \
  192. last_insert_len, commands, num_commands, num_literals); \
  193. return;
  194. FOR_GENERIC_HASHERS(CASE_)
  195. #undef CASE_
  196. default:
  197. BROTLI_DCHECK(false);
  198. break;
  199. }
  200. }
  201. #if defined(__cplusplus) || defined(c_plusplus)
  202. } /* extern "C" */
  203. #endif