// Copyright 2016 The Draco Authors. // // 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. // #include "core/symbol_encoding.h" #include #include #include "core/bit_utils.h" #include "core/rans_symbol_encoder.h" #include "core/shannon_entropy.h" namespace draco { constexpr int32_t kMaxTagSymbolBitLength = 32; constexpr int kMaxRawEncodingBitLength = 18; typedef uint64_t TaggedBitLengthFrequencies[kMaxTagSymbolBitLength]; void ConvertSignedIntsToSymbols(const int32_t *in, int in_values, uint32_t *out) { // Convert the quantized values into a format more suitable for entropy // encoding. // Put the sign bit into LSB pos and shift the rest one bit left. for (int i = 0; i < in_values; ++i) { out[i] = ConvertSignedIntToSymbol(in[i]); } } // Computes bit lengths of the input values. If num_components > 1, the values // are processed in "num_components" sized chunks and the bit length is always // computed for the largest value from the chunk. static void ComputeBitLengths(const uint32_t *symbols, int num_values, int num_components, std::vector *out_bit_lengths, uint32_t *out_max_value) { out_bit_lengths->reserve(num_values); *out_max_value = 0; // Maximum integer value across all components. for (int i = 0; i < num_values; i += num_components) { // Get the maximum value for a given entry across all attribute components. uint32_t max_component_value = symbols[i]; for (int j = 1; j < num_components; ++j) { if (max_component_value < symbols[i + j]) max_component_value = symbols[i + j]; } int value_msb_pos = 0; if (max_component_value > 0) { value_msb_pos = bits::MostSignificantBit(max_component_value); } if (max_component_value > *out_max_value) { *out_max_value = max_component_value; } out_bit_lengths->push_back(value_msb_pos + 1); } } static int64_t ApproximateTaggedSchemeBits( const std::vector bit_lengths, int num_components) { // Compute the total bit length used by all values (the length of data encode // after tags). uint64_t total_bit_length = 0; for (size_t i = 0; i < bit_lengths.size(); ++i) { total_bit_length += bit_lengths[i]; } // Compute the number of entropy bits for tags. int num_unique_symbols; const int64_t tag_bits = ComputeShannonEntropy( bit_lengths.data(), bit_lengths.size(), 32, &num_unique_symbols); const int64_t tag_table_bits = ApproximateRAnsFrequencyTableBits(num_unique_symbols, num_unique_symbols); return tag_bits + tag_table_bits + total_bit_length * num_components; } static int64_t ApproximateRawSchemeBits(const uint32_t *symbols, int num_symbols, uint32_t max_value) { int num_unique_symbols; const int64_t data_bits = ComputeShannonEntropy( symbols, num_symbols, max_value, &num_unique_symbols); const int64_t table_bits = ApproximateRAnsFrequencyTableBits(max_value, num_unique_symbols); return table_bits + data_bits; } template