command.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package brotli
  2. var kInsBase = []uint32{
  3. 0,
  4. 1,
  5. 2,
  6. 3,
  7. 4,
  8. 5,
  9. 6,
  10. 8,
  11. 10,
  12. 14,
  13. 18,
  14. 26,
  15. 34,
  16. 50,
  17. 66,
  18. 98,
  19. 130,
  20. 194,
  21. 322,
  22. 578,
  23. 1090,
  24. 2114,
  25. 6210,
  26. 22594,
  27. }
  28. var kInsExtra = []uint32{
  29. 0,
  30. 0,
  31. 0,
  32. 0,
  33. 0,
  34. 0,
  35. 1,
  36. 1,
  37. 2,
  38. 2,
  39. 3,
  40. 3,
  41. 4,
  42. 4,
  43. 5,
  44. 5,
  45. 6,
  46. 7,
  47. 8,
  48. 9,
  49. 10,
  50. 12,
  51. 14,
  52. 24,
  53. }
  54. var kCopyBase = []uint32{
  55. 2,
  56. 3,
  57. 4,
  58. 5,
  59. 6,
  60. 7,
  61. 8,
  62. 9,
  63. 10,
  64. 12,
  65. 14,
  66. 18,
  67. 22,
  68. 30,
  69. 38,
  70. 54,
  71. 70,
  72. 102,
  73. 134,
  74. 198,
  75. 326,
  76. 582,
  77. 1094,
  78. 2118,
  79. }
  80. var kCopyExtra = []uint32{
  81. 0,
  82. 0,
  83. 0,
  84. 0,
  85. 0,
  86. 0,
  87. 0,
  88. 0,
  89. 1,
  90. 1,
  91. 2,
  92. 2,
  93. 3,
  94. 3,
  95. 4,
  96. 4,
  97. 5,
  98. 5,
  99. 6,
  100. 7,
  101. 8,
  102. 9,
  103. 10,
  104. 24,
  105. }
  106. func getInsertLengthCode(insertlen uint) uint16 {
  107. if insertlen < 6 {
  108. return uint16(insertlen)
  109. } else if insertlen < 130 {
  110. var nbits uint32 = log2FloorNonZero(insertlen-2) - 1
  111. return uint16((nbits << 1) + uint32((insertlen-2)>>nbits) + 2)
  112. } else if insertlen < 2114 {
  113. return uint16(log2FloorNonZero(insertlen-66) + 10)
  114. } else if insertlen < 6210 {
  115. return 21
  116. } else if insertlen < 22594 {
  117. return 22
  118. } else {
  119. return 23
  120. }
  121. }
  122. func getCopyLengthCode(copylen uint) uint16 {
  123. if copylen < 10 {
  124. return uint16(copylen - 2)
  125. } else if copylen < 134 {
  126. var nbits uint32 = log2FloorNonZero(copylen-6) - 1
  127. return uint16((nbits << 1) + uint32((copylen-6)>>nbits) + 4)
  128. } else if copylen < 2118 {
  129. return uint16(log2FloorNonZero(copylen-70) + 12)
  130. } else {
  131. return 23
  132. }
  133. }
  134. func combineLengthCodes(inscode uint16, copycode uint16, use_last_distance bool) uint16 {
  135. var bits64 uint16 = uint16(copycode&0x7 | (inscode&0x7)<<3)
  136. if use_last_distance && inscode < 8 && copycode < 16 {
  137. if copycode < 8 {
  138. return bits64
  139. } else {
  140. return bits64 | 64
  141. }
  142. } else {
  143. /* Specification: 5 Encoding of ... (last table) */
  144. /* offset = 2 * index, where index is in range [0..8] */
  145. var offset uint32 = 2 * ((uint32(copycode) >> 3) + 3*(uint32(inscode)>>3))
  146. /* All values in specification are K * 64,
  147. where K = [2, 3, 6, 4, 5, 8, 7, 9, 10],
  148. i + 1 = [1, 2, 3, 4, 5, 6, 7, 8, 9],
  149. K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1, 2] = D.
  150. All values in D require only 2 bits to encode.
  151. Magic constant is shifted 6 bits left, to avoid final multiplication. */
  152. offset = (offset << 5) + 0x40 + ((0x520D40 >> offset) & 0xC0)
  153. return uint16(offset | uint32(bits64))
  154. }
  155. }
  156. func getLengthCode(insertlen uint, copylen uint, use_last_distance bool, code *uint16) {
  157. var inscode uint16 = getInsertLengthCode(insertlen)
  158. var copycode uint16 = getCopyLengthCode(copylen)
  159. *code = combineLengthCodes(inscode, copycode, use_last_distance)
  160. }
  161. func getInsertBase(inscode uint16) uint32 {
  162. return kInsBase[inscode]
  163. }
  164. func getInsertExtra(inscode uint16) uint32 {
  165. return kInsExtra[inscode]
  166. }
  167. func getCopyBase(copycode uint16) uint32 {
  168. return kCopyBase[copycode]
  169. }
  170. func getCopyExtra(copycode uint16) uint32 {
  171. return kCopyExtra[copycode]
  172. }
  173. type command struct {
  174. insert_len_ uint32
  175. copy_len_ uint32
  176. dist_extra_ uint32
  177. cmd_prefix_ uint16
  178. dist_prefix_ uint16
  179. }
  180. /* distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. */
  181. func makeCommand(dist *distanceParams, insertlen uint, copylen uint, copylen_code_delta int, distance_code uint) (cmd command) {
  182. /* Don't rely on signed int representation, use honest casts. */
  183. var delta uint32 = uint32(byte(int8(copylen_code_delta)))
  184. cmd.insert_len_ = uint32(insertlen)
  185. cmd.copy_len_ = uint32(uint32(copylen) | delta<<25)
  186. /* The distance prefix and extra bits are stored in this Command as if
  187. npostfix and ndirect were 0, they are only recomputed later after the
  188. clustering if needed. */
  189. prefixEncodeCopyDistance(distance_code, uint(dist.num_direct_distance_codes), uint(dist.distance_postfix_bits), &cmd.dist_prefix_, &cmd.dist_extra_)
  190. getLengthCode(insertlen, uint(int(copylen)+copylen_code_delta), (cmd.dist_prefix_&0x3FF == 0), &cmd.cmd_prefix_)
  191. return cmd
  192. }
  193. func makeInsertCommand(insertlen uint) (cmd command) {
  194. cmd.insert_len_ = uint32(insertlen)
  195. cmd.copy_len_ = 4 << 25
  196. cmd.dist_extra_ = 0
  197. cmd.dist_prefix_ = numDistanceShortCodes
  198. getLengthCode(insertlen, 4, false, &cmd.cmd_prefix_)
  199. return cmd
  200. }
  201. func commandRestoreDistanceCode(self *command, dist *distanceParams) uint32 {
  202. if uint32(self.dist_prefix_&0x3FF) < numDistanceShortCodes+dist.num_direct_distance_codes {
  203. return uint32(self.dist_prefix_) & 0x3FF
  204. } else {
  205. var dcode uint32 = uint32(self.dist_prefix_) & 0x3FF
  206. var nbits uint32 = uint32(self.dist_prefix_) >> 10
  207. var extra uint32 = self.dist_extra_
  208. var postfix_mask uint32 = (1 << dist.distance_postfix_bits) - 1
  209. var hcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) >> dist.distance_postfix_bits
  210. var lcode uint32 = (dcode - dist.num_direct_distance_codes - numDistanceShortCodes) & postfix_mask
  211. var offset uint32 = ((2 + (hcode & 1)) << nbits) - 4
  212. return ((offset + extra) << dist.distance_postfix_bits) + lcode + dist.num_direct_distance_codes + numDistanceShortCodes
  213. }
  214. }
  215. func commandDistanceContext(self *command) uint32 {
  216. var r uint32 = uint32(self.cmd_prefix_) >> 6
  217. var c uint32 = uint32(self.cmd_prefix_) & 7
  218. if (r == 0 || r == 2 || r == 4 || r == 7) && (c <= 2) {
  219. return c
  220. }
  221. return 3
  222. }
  223. func commandCopyLen(self *command) uint32 {
  224. return self.copy_len_ & 0x1FFFFFF
  225. }
  226. func commandCopyLenCode(self *command) uint32 {
  227. var modifier uint32 = self.copy_len_ >> 25
  228. var delta int32 = int32(int8(byte(modifier | (modifier&0x40)<<1)))
  229. return uint32(int32(self.copy_len_&0x1FFFFFF) + delta)
  230. }