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