]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/BrotliCompress/enc/histogram.c
BaseTools: Copy Brotli algorithm 3rd party source code for tool
[mirror_edk2.git] / BaseTools / Source / C / BrotliCompress / enc / histogram.c
CommitLineData
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
11#include "./block_splitter.h"\r
12#include "./command.h"\r
13#include "./context.h"\r
14\r
15#if defined(__cplusplus) || defined(c_plusplus)\r
16extern "C" {\r
17#endif\r
18\r
19typedef 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
26static 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
34static 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
43void 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
66 for (j = cmd->insert_len_; j != 0; --j) {\r
67 size_t context;\r
68 BlockSplitIteratorNext(&literal_it);\r
69 context = (literal_it.type_ << BROTLI_LITERAL_CONTEXT_BITS) +\r
70 Context(prev_byte, prev_byte2, context_modes[literal_it.type_]);\r
71 HistogramAddLiteral(&literal_histograms[context],\r
72 ringbuffer[pos & mask]);\r
73 prev_byte2 = prev_byte;\r
74 prev_byte = ringbuffer[pos & mask];\r
75 ++pos;\r
76 }\r
77 pos += CommandCopyLen(cmd);\r
78 if (CommandCopyLen(cmd)) {\r
79 prev_byte2 = ringbuffer[(pos - 2) & mask];\r
80 prev_byte = ringbuffer[(pos - 1) & mask];\r
81 if (cmd->cmd_prefix_ >= 128) {\r
82 size_t context;\r
83 BlockSplitIteratorNext(&dist_it);\r
84 context = (dist_it.type_ << BROTLI_DISTANCE_CONTEXT_BITS) +\r
85 CommandDistanceContext(cmd);\r
86 HistogramAddDistance(&copy_dist_histograms[context],\r
87 cmd->dist_prefix_);\r
88 }\r
89 }\r
90 }\r
91}\r
92\r
93#if defined(__cplusplus) || defined(c_plusplus)\r
94} /* extern "C" */\r
95#endif\r