prefix.h revision 771eb107985566d2e458e3f06f2c7bd1b21c2dca
1771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov/* Copyright 2013 Google Inc. All Rights Reserved. 2771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov 3771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov Distributed under MIT license, or public domain if desired and 4771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov recognized in your jurisdiction. 5771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov See file LICENSE for detail or copy at https://opensource.org/licenses/MIT 6771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov*/ 7771eb107985566d2e458e3f06f2c7bd1b21c2dcaEugene Klyuchnikov 8c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka// Functions for encoding of integers into prefix codes the amount of extra 9c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka// bits, and the actual values of the extra bits. 10c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 11c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka#ifndef BROTLI_ENC_PREFIX_H_ 12c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka#define BROTLI_ENC_PREFIX_H_ 13c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 14b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka#include "./fast_log.h" 154a7024dcde1aaf30d824ade299e70711a30f4399Zoltan Szabadka#include "./types.h" 16c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 17c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadkanamespace brotli { 18c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 19c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadkastatic const int kNumInsertLenPrefixes = 24; 20c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadkastatic const int kNumCopyLenPrefixes = 24; 21c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadkastatic const int kNumCommandPrefixes = 704; 22c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadkastatic const int kNumBlockLenPrefixes = 26; 23c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadkastatic const int kNumDistanceShortCodes = 16; 24c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadkastatic const int kNumDistancePrefixes = 520; 25c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 26467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka// Represents the range of values belonging to a prefix code: 27467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka// [offset, offset + 2^nbits) 28467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadkastruct PrefixCodeRange { 29467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka int offset; 30467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka int nbits; 31467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka}; 32467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka 33467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadkastatic const PrefixCodeRange kBlockLengthPrefixCode[kNumBlockLenPrefixes] = { 34467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka { 1, 2}, { 5, 2}, { 9, 2}, { 13, 2}, 35467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka { 17, 3}, { 25, 3}, { 33, 3}, { 41, 3}, 36467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka { 49, 4}, { 65, 4}, { 81, 4}, { 97, 4}, 37467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka { 113, 5}, { 145, 5}, { 177, 5}, { 209, 5}, 38467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka { 241, 6}, { 305, 6}, { 369, 7}, { 497, 8}, 39467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka { 753, 9}, { 1265, 10}, {2289, 11}, {4337, 12}, 40467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka {8433, 13}, {16625, 24} 41467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka}; 42467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka 43467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadkainline void GetBlockLengthPrefixCode(int len, 44467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka int* code, int* n_extra, int* extra) { 45467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka *code = 0; 46467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka while (*code < 25 && len >= kBlockLengthPrefixCode[*code + 1].offset) { 47467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka ++(*code); 48467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka } 49467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka *n_extra = kBlockLengthPrefixCode[*code].nbits; 50467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka *extra = len - kBlockLengthPrefixCode[*code].offset; 51467e6eef80d4967cf2020a54b0841855349dfc45Zoltan Szabadka} 52c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 53b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadkainline void PrefixEncodeCopyDistance(int distance_code, 54b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka int num_direct_codes, 55b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka int postfix_bits, 56b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka uint16_t* code, 57b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka uint32_t* extra_bits) { 58b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka if (distance_code < kNumDistanceShortCodes + num_direct_codes) { 59ea48ce5a6fa8a3224dd270a7f60428084e7b590dZoltan Szabadka *code = static_cast<uint16_t>(distance_code); 60b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka *extra_bits = 0; 61b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka return; 62b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka } 63b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka distance_code -= kNumDistanceShortCodes + num_direct_codes; 64b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka distance_code += (1 << (postfix_bits + 2)); 65b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka int bucket = Log2Floor(distance_code) - 1; 66b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka int postfix_mask = (1 << postfix_bits) - 1; 67b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka int postfix = distance_code & postfix_mask; 68b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka int prefix = (distance_code >> bucket) & 1; 69b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka int offset = (2 + prefix) << bucket; 70b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka int nbits = bucket - postfix_bits; 71ea48ce5a6fa8a3224dd270a7f60428084e7b590dZoltan Szabadka *code = static_cast<uint16_t>( 72ea48ce5a6fa8a3224dd270a7f60428084e7b590dZoltan Szabadka (kNumDistanceShortCodes + num_direct_codes + 73ea48ce5a6fa8a3224dd270a7f60428084e7b590dZoltan Szabadka ((2 * (nbits - 1) + prefix) << postfix_bits) + postfix)); 74b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka *extra_bits = (nbits << 24) | ((distance_code - offset) >> postfix_bits); 75b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka} 76b4f39bf540c7755909105b6a96c7ac89b79364adZoltan Szabadka 77c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka} // namespace brotli 78c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka 79c66e4e3e4fc3ba36ca36a43eee3b704f7b989c60Zoltan Szabadka#endif // BROTLI_ENC_PREFIX_H_ 80