OLD | NEW |
| (Empty) |
1 /* Copyright 2013 Google Inc. All Rights Reserved. | |
2 | |
3 Distributed under MIT license. | |
4 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | |
5 */ | |
6 | |
7 // Build per-context histograms of literals, commands and distance codes. | |
8 | |
9 #include "./histogram.h" | |
10 | |
11 #include <cmath> | |
12 | |
13 #include "./block_splitter.h" | |
14 #include "./command.h" | |
15 #include "./context.h" | |
16 #include "./prefix.h" | |
17 | |
18 namespace brotli { | |
19 | |
20 void BuildHistograms( | |
21 const Command* cmds, | |
22 const size_t num_commands, | |
23 const BlockSplit& literal_split, | |
24 const BlockSplit& insert_and_copy_split, | |
25 const BlockSplit& dist_split, | |
26 const uint8_t* ringbuffer, | |
27 size_t start_pos, | |
28 size_t mask, | |
29 uint8_t prev_byte, | |
30 uint8_t prev_byte2, | |
31 const std::vector<ContextType>& context_modes, | |
32 std::vector<HistogramLiteral>* literal_histograms, | |
33 std::vector<HistogramCommand>* insert_and_copy_histograms, | |
34 std::vector<HistogramDistance>* copy_dist_histograms) { | |
35 size_t pos = start_pos; | |
36 BlockSplitIterator literal_it(literal_split); | |
37 BlockSplitIterator insert_and_copy_it(insert_and_copy_split); | |
38 BlockSplitIterator dist_it(dist_split); | |
39 for (size_t i = 0; i < num_commands; ++i) { | |
40 const Command &cmd = cmds[i]; | |
41 insert_and_copy_it.Next(); | |
42 (*insert_and_copy_histograms)[insert_and_copy_it.type_].Add( | |
43 cmd.cmd_prefix_); | |
44 for (size_t j = cmd.insert_len_; j != 0; --j) { | |
45 literal_it.Next(); | |
46 size_t context = (literal_it.type_ << kLiteralContextBits) + | |
47 Context(prev_byte, prev_byte2, context_modes[literal_it.type_]); | |
48 (*literal_histograms)[context].Add(ringbuffer[pos & mask]); | |
49 prev_byte2 = prev_byte; | |
50 prev_byte = ringbuffer[pos & mask]; | |
51 ++pos; | |
52 } | |
53 pos += cmd.copy_len(); | |
54 if (cmd.copy_len()) { | |
55 prev_byte2 = ringbuffer[(pos - 2) & mask]; | |
56 prev_byte = ringbuffer[(pos - 1) & mask]; | |
57 if (cmd.cmd_prefix_ >= 128) { | |
58 dist_it.Next(); | |
59 size_t context = (dist_it.type_ << kDistanceContextBits) + | |
60 cmd.DistanceContext(); | |
61 (*copy_dist_histograms)[context].Add(cmd.dist_prefix_); | |
62 } | |
63 } | |
64 } | |
65 } | |
66 | |
67 } // namespace brotli | |
OLD | NEW |