diff options
Diffstat (limited to 'chromium/third_party/brotli/src/brotli/enc/histogram.cc')
-rw-r--r-- | chromium/third_party/brotli/src/brotli/enc/histogram.cc | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/chromium/third_party/brotli/src/brotli/enc/histogram.cc b/chromium/third_party/brotli/src/brotli/enc/histogram.cc new file mode 100644 index 00000000000..910b9872b1b --- /dev/null +++ b/chromium/third_party/brotli/src/brotli/enc/histogram.cc @@ -0,0 +1,94 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Build per-context histograms of literals, commands and distance codes. + +#include "./histogram.h" + +#include <stdint.h> +#include <cmath> + +#include "./block_splitter.h" +#include "./command.h" +#include "./context.h" +#include "./prefix.h" + +namespace brotli { + +void BuildHistograms( + const std::vector<Command>& cmds, + const BlockSplit& literal_split, + const BlockSplit& insert_and_copy_split, + const BlockSplit& dist_split, + const uint8_t* ringbuffer, + size_t pos, + size_t mask, + const std::vector<int>& context_modes, + std::vector<HistogramLiteral>* literal_histograms, + std::vector<HistogramCommand>* insert_and_copy_histograms, + std::vector<HistogramDistance>* copy_dist_histograms) { + BlockSplitIterator literal_it(literal_split); + BlockSplitIterator insert_and_copy_it(insert_and_copy_split); + BlockSplitIterator dist_it(dist_split); + for (int i = 0; i < cmds.size(); ++i) { + const Command &cmd = cmds[i]; + insert_and_copy_it.Next(); + (*insert_and_copy_histograms)[insert_and_copy_it.type_].Add( + cmd.command_prefix_); + for (int j = 0; j < cmd.insert_length_; ++j) { + literal_it.Next(); + uint8_t prev_byte = pos > 0 ? ringbuffer[(pos - 1) & mask] : 0; + uint8_t prev_byte2 = pos > 1 ? ringbuffer[(pos - 2) & mask] : 0; + int context = (literal_it.type_ << kLiteralContextBits) + + Context(prev_byte, prev_byte2, context_modes[literal_it.type_]); + (*literal_histograms)[context].Add(ringbuffer[pos & mask]); + ++pos; + } + pos += cmd.copy_length_; + if (cmd.copy_length_ > 0 && cmd.distance_prefix_ != 0xffff) { + dist_it.Next(); + int context = (dist_it.type_ << kDistanceContextBits) + + ((cmd.copy_length_code_ > 4) ? 3 : cmd.copy_length_code_ - 2); + (*copy_dist_histograms)[context].Add(cmd.distance_prefix_); + } + } +} + +void BuildLiteralHistogramsForBlockType( + const std::vector<Command>& cmds, + const BlockSplit& literal_split, + const uint8_t* ringbuffer, + size_t pos, + size_t mask, + int block_type, + int context_mode, + std::vector<HistogramLiteral>* histograms) { + BlockSplitIterator literal_it(literal_split); + for (int i = 0; i < cmds.size(); ++i) { + const Command &cmd = cmds[i]; + for (int j = 0; j < cmd.insert_length_; ++j) { + literal_it.Next(); + if (literal_it.type_ == block_type) { + uint8_t prev_byte = pos > 0 ? ringbuffer[(pos - 1) & mask] : 0; + uint8_t prev_byte2 = pos > 1 ? ringbuffer[(pos - 2) & mask] : 0; + int context = Context(prev_byte, prev_byte2, context_mode); + (*histograms)[context].Add(ringbuffer[pos & mask]); + } + ++pos; + } + pos += cmd.copy_length_; + } +} + +} // namespace brotli |