Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/draco/draco/src/draco/compression/entropy/rans_symbol_decoder.h')
-rw-r--r--extern/draco/draco/src/draco/compression/entropy/rans_symbol_decoder.h164
1 files changed, 164 insertions, 0 deletions
diff --git a/extern/draco/draco/src/draco/compression/entropy/rans_symbol_decoder.h b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_decoder.h
new file mode 100644
index 00000000000..10cdc6781a0
--- /dev/null
+++ b/extern/draco/draco/src/draco/compression/entropy/rans_symbol_decoder.h
@@ -0,0 +1,164 @@
+// 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.
+//
+#ifndef DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_DECODER_H_
+#define DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_DECODER_H_
+
+#include "draco/compression/config/compression_shared.h"
+#include "draco/compression/entropy/rans_symbol_coding.h"
+#include "draco/core/decoder_buffer.h"
+#include "draco/core/varint_decoding.h"
+#include "draco/draco_features.h"
+
+namespace draco {
+
+// A helper class for decoding symbols using the rANS algorithm (see ans.h).
+// The class can be used to decode the probability table and the data encoded
+// by the RAnsSymbolEncoder. |unique_symbols_bit_length_t| must be the same as
+// the one used for the corresponding RAnsSymbolEncoder.
+template <int unique_symbols_bit_length_t>
+class RAnsSymbolDecoder {
+ public:
+ RAnsSymbolDecoder() : num_symbols_(0) {}
+
+ // Initialize the decoder and decode the probability table.
+ bool Create(DecoderBuffer *buffer);
+
+ uint32_t num_symbols() const { return num_symbols_; }
+
+ // Starts decoding from the buffer. The buffer will be advanced past the
+ // encoded data after this call.
+ bool StartDecoding(DecoderBuffer *buffer);
+ uint32_t DecodeSymbol() { return ans_.rans_read(); }
+ void EndDecoding();
+
+ private:
+ static constexpr int rans_precision_bits_ =
+ ComputeRAnsPrecisionFromUniqueSymbolsBitLength(
+ unique_symbols_bit_length_t);
+ static constexpr int rans_precision_ = 1 << rans_precision_bits_;
+
+ std::vector<uint32_t> probability_table_;
+ uint32_t num_symbols_;
+ RAnsDecoder<rans_precision_bits_> ans_;
+};
+
+template <int unique_symbols_bit_length_t>
+bool RAnsSymbolDecoder<unique_symbols_bit_length_t>::Create(
+ DecoderBuffer *buffer) {
+ // Check that the DecoderBuffer version is set.
+ if (buffer->bitstream_version() == 0) {
+ return false;
+ }
+ // Decode the number of alphabet symbols.
+#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
+ if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
+ if (!buffer->Decode(&num_symbols_)) {
+ return false;
+ }
+
+ } else
+#endif
+ {
+ if (!DecodeVarint(&num_symbols_, buffer)) {
+ return false;
+ }
+ }
+ probability_table_.resize(num_symbols_);
+ if (num_symbols_ == 0) {
+ return true;
+ }
+ // Decode the table.
+ for (uint32_t i = 0; i < num_symbols_; ++i) {
+ uint8_t prob_data = 0;
+ // Decode the first byte and extract the number of extra bytes we need to
+ // get, or the offset to the next symbol with non-zero probability.
+ if (!buffer->Decode(&prob_data)) {
+ return false;
+ }
+ // Token is stored in the first two bits of the first byte. Values 0-2 are
+ // used to indicate the number of extra bytes, and value 3 is a special
+ // symbol used to denote run-length coding of zero probability entries.
+ // See rans_symbol_encoder.h for more details.
+ const int token = prob_data & 3;
+ if (token == 3) {
+ const uint32_t offset = prob_data >> 2;
+ if (i + offset >= num_symbols_) {
+ return false;
+ }
+ // Set zero probability for all symbols in the specified range.
+ for (uint32_t j = 0; j < offset + 1; ++j) {
+ probability_table_[i + j] = 0;
+ }
+ i += offset;
+ } else {
+ const int extra_bytes = token;
+ uint32_t prob = prob_data >> 2;
+ for (int b = 0; b < extra_bytes; ++b) {
+ uint8_t eb;
+ if (!buffer->Decode(&eb)) {
+ return false;
+ }
+ // Shift 8 bits for each extra byte and subtract 2 for the two first
+ // bits.
+ prob |= static_cast<uint32_t>(eb) << (8 * (b + 1) - 2);
+ }
+ probability_table_[i] = prob;
+ }
+ }
+ if (!ans_.rans_build_look_up_table(&probability_table_[0], num_symbols_)) {
+ return false;
+ }
+ return true;
+}
+
+template <int unique_symbols_bit_length_t>
+bool RAnsSymbolDecoder<unique_symbols_bit_length_t>::StartDecoding(
+ DecoderBuffer *buffer) {
+ uint64_t bytes_encoded;
+ // Decode the number of bytes encoded by the encoder.
+#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
+ if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 0)) {
+ if (!buffer->Decode(&bytes_encoded)) {
+ return false;
+ }
+
+ } else
+#endif
+ {
+ if (!DecodeVarint<uint64_t>(&bytes_encoded, buffer)) {
+ return false;
+ }
+ }
+ if (bytes_encoded > static_cast<uint64_t>(buffer->remaining_size())) {
+ return false;
+ }
+ const uint8_t *const data_head =
+ reinterpret_cast<const uint8_t *>(buffer->data_head());
+ // Advance the buffer past the rANS data.
+ buffer->Advance(bytes_encoded);
+ if (ans_.read_init(data_head, static_cast<int>(bytes_encoded)) != 0) {
+ return false;
+ }
+ return true;
+}
+
+template <int unique_symbols_bit_length_t>
+void RAnsSymbolDecoder<unique_symbols_bit_length_t>::EndDecoding() {
+ ans_.read_end();
+}
+
+} // namespace draco
+
+#endif // DRACO_COMPRESSION_ENTROPY_RANS_SYMBOL_DECODER_H_