]>
Commit | Line | Data |
---|---|---|
11b7501a SB |
1 | /* Copyright 2013 Google Inc. All Rights Reserved.\r |
2 | \r | |
3 | Distributed under MIT license.\r | |
4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT\r | |
5 | */\r | |
6 | \r | |
7 | /* Build per-context histograms of literals, commands and distance codes. */\r | |
8 | \r | |
9 | #include "./histogram.h"\r | |
10 | \r | |
dd4f667e | 11 | #include "../common/context.h"\r |
11b7501a SB |
12 | #include "./block_splitter.h"\r |
13 | #include "./command.h"\r | |
11b7501a SB |
14 | \r |
15 | #if defined(__cplusplus) || defined(c_plusplus)\r | |
16 | extern "C" {\r | |
17 | #endif\r | |
18 | \r | |
19 | typedef struct BlockSplitIterator {\r | |
20 | const BlockSplit* split_; /* Not owned. */\r | |
21 | size_t idx_;\r | |
22 | size_t type_;\r | |
23 | size_t length_;\r | |
24 | } BlockSplitIterator;\r | |
25 | \r | |
26 | static void InitBlockSplitIterator(BlockSplitIterator* self,\r | |
27 | const BlockSplit* split) {\r | |
28 | self->split_ = split;\r | |
29 | self->idx_ = 0;\r | |
30 | self->type_ = 0;\r | |
31 | self->length_ = split->lengths ? split->lengths[0] : 0;\r | |
32 | }\r | |
33 | \r | |
34 | static void BlockSplitIteratorNext(BlockSplitIterator* self) {\r | |
35 | if (self->length_ == 0) {\r | |
36 | ++self->idx_;\r | |
37 | self->type_ = self->split_->types[self->idx_];\r | |
38 | self->length_ = self->split_->lengths[self->idx_];\r | |
39 | }\r | |
40 | --self->length_;\r | |
41 | }\r | |
42 | \r | |
43 | void BrotliBuildHistogramsWithContext(\r | |
44 | const Command* cmds, const size_t num_commands,\r | |
45 | const BlockSplit* literal_split, const BlockSplit* insert_and_copy_split,\r | |
46 | const BlockSplit* dist_split, const uint8_t* ringbuffer, size_t start_pos,\r | |
47 | size_t mask, uint8_t prev_byte, uint8_t prev_byte2,\r | |
48 | const ContextType* context_modes, HistogramLiteral* literal_histograms,\r | |
49 | HistogramCommand* insert_and_copy_histograms,\r | |
50 | HistogramDistance* copy_dist_histograms) {\r | |
51 | size_t pos = start_pos;\r | |
52 | BlockSplitIterator literal_it;\r | |
53 | BlockSplitIterator insert_and_copy_it;\r | |
54 | BlockSplitIterator dist_it;\r | |
55 | size_t i;\r | |
56 | \r | |
57 | InitBlockSplitIterator(&literal_it, literal_split);\r | |
58 | InitBlockSplitIterator(&insert_and_copy_it, insert_and_copy_split);\r | |
59 | InitBlockSplitIterator(&dist_it, dist_split);\r | |
60 | for (i = 0; i < num_commands; ++i) {\r | |
61 | const Command* cmd = &cmds[i];\r | |
62 | size_t j;\r | |
63 | BlockSplitIteratorNext(&insert_and_copy_it);\r | |
64 | HistogramAddCommand(&insert_and_copy_histograms[insert_and_copy_it.type_],\r | |
65 | cmd->cmd_prefix_);\r | |
dd4f667e | 66 | /* TODO: unwrap iterator blocks. */\r |
11b7501a SB |
67 | for (j = cmd->insert_len_; j != 0; --j) {\r |
68 | size_t context;\r | |
69 | BlockSplitIteratorNext(&literal_it);\r | |
dd4f667e LG |
70 | context = literal_it.type_;\r |
71 | if (context_modes) {\r | |
72 | ContextLut lut = BROTLI_CONTEXT_LUT(context_modes[context]);\r | |
73 | context = (context << BROTLI_LITERAL_CONTEXT_BITS) +\r | |
74 | BROTLI_CONTEXT(prev_byte, prev_byte2, lut);\r | |
75 | }\r | |
11b7501a SB |
76 | HistogramAddLiteral(&literal_histograms[context],\r |
77 | ringbuffer[pos & mask]);\r | |
78 | prev_byte2 = prev_byte;\r | |
79 | prev_byte = ringbuffer[pos & mask];\r | |
80 | ++pos;\r | |
81 | }\r | |
82 | pos += CommandCopyLen(cmd);\r | |
83 | if (CommandCopyLen(cmd)) {\r | |
84 | prev_byte2 = ringbuffer[(pos - 2) & mask];\r | |
85 | prev_byte = ringbuffer[(pos - 1) & mask];\r | |
86 | if (cmd->cmd_prefix_ >= 128) {\r | |
87 | size_t context;\r | |
88 | BlockSplitIteratorNext(&dist_it);\r | |
89 | context = (dist_it.type_ << BROTLI_DISTANCE_CONTEXT_BITS) +\r | |
90 | CommandDistanceContext(cmd);\r | |
91 | HistogramAddDistance(©_dist_histograms[context],\r | |
dd4f667e | 92 | cmd->dist_prefix_ & 0x3FF);\r |
11b7501a SB |
93 | }\r |
94 | }\r | |
95 | }\r | |
96 | }\r | |
97 | \r | |
98 | #if defined(__cplusplus) || defined(c_plusplus)\r | |
99 | } /* extern "C" */\r | |
100 | #endif\r |