blob: d25842b55d67eab56edefb05513b7546206427c6 [file] [log] [blame]
// Copyright 2019 Google LLC
//
// 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
//
// https://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.
// -----------------------------------------------------------------------------
//
// Defines utilities to quantize a distribution to better store it and the
// population it represents.
//
// Author: Vincent Rabaud (vrabaud@google.com)
#ifndef WP2_ENC_LOSSLESS_QUANTIZER_H_
#define WP2_ENC_LOSSLESS_QUANTIZER_H_
#include "src/utils/ans_utils.h"
#include "src/utils/vector.h"
#include "src/wp2/format_constants.h"
namespace WP2 {
class Quantizer {
public:
enum ConfigType { Raw, Huffman };
// Config defining how a histogram is stored.
// E.g. [0,1,8,0,4]
// If 'is_sparse' is true, it is stored as sparse, 'histo' contains [1,8,4]
// and "runs" the mapping differences minus 1: [2,1,2] (the first element is
// a difference to -1) minus 1 hence [1,0,1]
// 'histogram_to_write' contains how 'histo' will be finally written, which
// in Raw type is the same, but in Huffman is [0,3,2] (the powers of 2 used to
// represent the histogram).
// 'histo' represents a distribution of symbol and if we were to write
// data with it, it would have an overall cost of 'cost'. Overall means the
// cost of writing the symbols with probabilities defined by 'histo' but also
// of storing 'histo'.
struct ConfigParam {
// The following members differentiate the different configurations.
ConfigType type;
bool is_sparse;
uint8_t max_freq_bits;
// Golomb specific parameters.
uint32_t golomb_size;
uint32_t golomb_prefix_size;
};
struct HistogramSparse {
uint32_t* counts;
uint16_t* mapping;
uint32_t nnz; // number of non-zero counts
};
struct Config {
ConfigParam param;
// The following members are the results of the above parameters.
uint32_t* histogram_to_write;
size_t size_to_write;
HistogramSparse histo;
float cost;
// Filled by QuantizeImpl():
void Reset() { used = false; }
private:
bool used = false;
// For each recursion level, each set of param can be Raw/Huffman, sparse or
// not and have several levels of recursion.
uint8_t bits[kMaxFreqBits];
Vector_u32 histogram_sub;
Vector_u16 mapping_sub;
uint32_t* histogram_quantized;
uint32_t* tmp_histogram_to_write;
friend Quantizer;
};
// range_max is the maximum range of the used symbols (maximum value + 1).
WP2Status Allocate(uint32_t range_max);
// Given a histogram of symbols, their range, as well as the bit size
// of the number of pixels n_pixels_bits, find the best way to store the
// symbols represented by 'histogram' with the data in 'histogram' by
// minimizing their overall size. 'size_sparse' is an upper bound of the
// number of non-zero counts. 'effort' is between 0 (fastest) and 9 (slowest).
// 'max_count' is the maximum value a count can take.
void Quantize(const uint32_t* const histogram, const uint16_t* const mapping,
size_t size_sparse, uint32_t symbol_range, uint32_t max_count,
int effort, Config** const config_best);
private:
// Implementation of the quantization that can call itself to compress its own
// coefficients.
// 'cost_max' is the value above which we can early exit.
void QuantizeImpl(const uint32_t* const histogram,
const uint16_t* const mapping, size_t size_sparse,
uint32_t symbol_range, uint32_t n_pixels_bits, int effort,
float cost_max, Config* const config);
// TODO(vrabaud) Investigate to see if it is worth having more levels.
static constexpr size_t kConfigNbr = 2;
Config configs_[kConfigNbr];
uint32_t histogram_size_max_;
Data buffer32_; // Big memory chunk storing the uint32_t buffers above.
Data buffer16_; // Big memory chunk storing the uint16_t buffers above.
VectorNoCtor<OptimizeArrayStorageStat> stats_buffer_;
};
} // namespace WP2
#endif // WP2_ENC_LOSSLESS_QUANTIZER_H_