GameApi 28
Library used by GameApi Builder tool
Loading...
Searching...
No Matches
decoder_buffer.h
Go to the documentation of this file.
1// Copyright 2016 The Draco Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15#ifndef DRACO_CORE_DECODER_BUFFER_H_
16#define DRACO_CORE_DECODER_BUFFER_H_
17
18#include <stdint.h>
19
20#include <cstring>
21#include <memory>
22
23#include "draco/core/macros.h"
25
26namespace draco {
27
28// Class is a wrapper around input data used by MeshDecoder. It provides a
29// basic interface for decoding either typed or variable-bit sized data.
31 public:
33 DecoderBuffer(const DecoderBuffer &buf) = default;
34
35 DecoderBuffer &operator=(const DecoderBuffer &buf) = default;
36
37 // Sets the buffer's internal data. Note that no copy of the input data is
38 // made so the data owner needs to keep the data valid and unchanged for
39 // runtime of the decoder.
40 void Init(const char *data, size_t data_size);
41
42 // Sets the buffer's internal data. |version| is the Draco bitstream version.
43 void Init(const char *data, size_t data_size, uint16_t version);
44
45 // Starts decoding a bit sequence.
46 // decode_size must be true if the size of the encoded bit data was included,
47 // during encoding. The size is then returned to out_size.
48 // Returns false on error.
49 bool StartBitDecoding(bool decode_size, uint64_t *out_size);
50
51 // Ends the decoding of the bit sequence and return to the default
52 // byte-aligned decoding.
53 void EndBitDecoding();
54
55 // Decodes up to 32 bits into out_val. Can be called only in between
56 // StartBitDecoding and EndBitDecoding. Otherwise returns false.
57 bool DecodeLeastSignificantBits32(uint32_t nbits, uint32_t *out_value) {
58 if (!bit_decoder_active()) {
59 return false;
60 }
61 return bit_decoder_.GetBits(nbits, out_value);
62 }
63
64 // Decodes an arbitrary data type.
65 // Can be used only when we are not decoding a bit-sequence.
66 // Returns false on error.
67 template <typename T>
68 bool Decode(T *out_val) {
69 if (!Peek(out_val)) {
70 return false;
71 }
72 pos_ += sizeof(T);
73 return true;
74 }
75
76 bool Decode(void *out_data, size_t size_to_decode) {
77 if (data_size_ < static_cast<int64_t>(pos_ + size_to_decode)) {
78 return false; // Buffer overflow.
79 }
80 memcpy(out_data, (data_ + pos_), size_to_decode);
81 pos_ += size_to_decode;
82 return true;
83 }
84
85 // Decodes an arbitrary data, but does not advance the reading position.
86 template <typename T>
87 bool Peek(T *out_val) {
88 const size_t size_to_decode = sizeof(T);
89 if (data_size_ < static_cast<int64_t>(pos_ + size_to_decode)) {
90 return false; // Buffer overflow.
91 }
92 memcpy(out_val, (data_ + pos_), size_to_decode);
93 return true;
94 }
95
96 bool Peek(void *out_data, size_t size_to_peek) {
97 if (data_size_ < static_cast<int64_t>(pos_ + size_to_peek)) {
98 return false; // Buffer overflow.
99 }
100 memcpy(out_data, (data_ + pos_), size_to_peek);
101 return true;
102 }
103
104 // Discards #bytes from the input buffer.
105 void Advance(int64_t bytes) { pos_ += bytes; }
106
107 // Moves the parsing position to a specific offset from the beginning of the
108 // input data.
109 void StartDecodingFrom(int64_t offset) { pos_ = offset; }
110
111 void set_bitstream_version(uint16_t version) { bitstream_version_ = version; }
112
113 // Returns the data array at the current decoder position.
114 const char *data_head() const { return data_ + pos_; }
115 int64_t remaining_size() const { return data_size_ - pos_; }
116 int64_t decoded_size() const { return pos_; }
117 bool bit_decoder_active() const { return bit_mode_; }
118
119 // Returns the bitstream associated with the data. Returns 0 if unknown.
120 uint16_t bitstream_version() const { return bitstream_version_; }
121
122 private:
123 // Internal helper class to decode bits from a bit buffer.
124 class BitDecoder {
125 public:
126 BitDecoder();
127 ~BitDecoder();
128
129 // Sets the bit buffer to |b|. |s| is the size of |b| in bytes.
130 inline void reset(const void *b, size_t s) {
131 bit_offset_ = 0;
132 bit_buffer_ = static_cast<const uint8_t *>(b);
133 bit_buffer_end_ = bit_buffer_ + s;
134 }
135
136 // Returns number of bits decoded so far.
137 inline uint64_t BitsDecoded() const {
138 return static_cast<uint64_t>(bit_offset_);
139 }
140
141 // Return number of bits available for decoding
142 inline uint64_t AvailBits() const {
143 return ((bit_buffer_end_ - bit_buffer_) * 8) - bit_offset_;
144 }
145
146 inline uint32_t EnsureBits(int k) {
147 DRACO_DCHECK_LE(k, 24);
148 DRACO_DCHECK_LE(static_cast<uint64_t>(k), AvailBits());
149
150 uint32_t buf = 0;
151 for (int i = 0; i < k; ++i) {
152 buf |= PeekBit(i) << i;
153 }
154 return buf; // Okay to return extra bits
155 }
156
157 inline void ConsumeBits(int k) { bit_offset_ += k; }
158
159 // Returns |nbits| bits in |x|.
160 inline bool GetBits(uint32_t nbits, uint32_t *x) {
161 if (nbits > 32) {
162 return false;
163 }
164 uint32_t value = 0;
165 for (uint32_t bit = 0; bit < nbits; ++bit) {
166 value |= GetBit() << bit;
167 }
168 *x = value;
169 return true;
170 }
171
172 private:
173 // TODO(fgalligan): Add support for error reporting on range check.
174 // Returns one bit from the bit buffer.
175 inline int GetBit() {
176 const size_t off = bit_offset_;
177 const size_t byte_offset = off >> 3;
178 const int bit_shift = static_cast<int>(off & 0x7);
179 if (bit_buffer_ + byte_offset < bit_buffer_end_) {
180 const int bit = (bit_buffer_[byte_offset] >> bit_shift) & 1;
181 bit_offset_ = off + 1;
182 return bit;
183 }
184 return 0;
185 }
186
187 inline int PeekBit(int offset) {
188 const size_t off = bit_offset_ + offset;
189 const size_t byte_offset = off >> 3;
190 const int bit_shift = static_cast<int>(off & 0x7);
191 if (bit_buffer_ + byte_offset < bit_buffer_end_) {
192 const int bit = (bit_buffer_[byte_offset] >> bit_shift) & 1;
193 return bit;
194 }
195 return 0;
196 }
197
198 const uint8_t *bit_buffer_;
199 const uint8_t *bit_buffer_end_;
200 size_t bit_offset_;
201 };
203
204 const char *data_;
205 int64_t data_size_;
206
207 // Current parsing position of the decoder.
208 int64_t pos_;
209 BitDecoder bit_decoder_;
210 bool bit_mode_;
211 uint16_t bitstream_version_;
212};
213
214} // namespace draco
215
216#endif // DRACO_CORE_DECODER_BUFFER_H_
DecoderBuffer & operator=(const DecoderBuffer &buf)=default
void Init(const char *data, size_t data_size)
Definition decoder_buffer.cc:29
friend class BufferBitCodingTest
Definition decoder_buffer.h:202
void Advance(int64_t bytes)
Definition decoder_buffer.h:105
const char * data_head() const
Definition decoder_buffer.h:114
bool StartBitDecoding(bool decode_size, uint64_t *out_size)
Definition decoder_buffer.cc:40
bool Decode(void *out_data, size_t size_to_decode)
Definition decoder_buffer.h:76
uint16_t bitstream_version() const
Definition decoder_buffer.h:120
DecoderBuffer()
Definition decoder_buffer.cc:22
void StartDecodingFrom(int64_t offset)
Definition decoder_buffer.h:109
DecoderBuffer(const DecoderBuffer &buf)=default
bool Decode(T *out_val)
Definition decoder_buffer.h:68
void EndBitDecoding()
Definition decoder_buffer.cc:60
bool bit_decoder_active() const
Definition decoder_buffer.h:117
int64_t remaining_size() const
Definition decoder_buffer.h:115
bool Peek(T *out_val)
Definition decoder_buffer.h:87
bool DecodeLeastSignificantBits32(uint32_t nbits, uint32_t *out_value)
Definition decoder_buffer.h:57
bool Peek(void *out_data, size_t size_to_peek)
Definition decoder_buffer.h:96
void set_bitstream_version(uint16_t version)
Definition decoder_buffer.h:111
int64_t decoded_size() const
Definition decoder_buffer.h:116
#define DRACO_DCHECK_LE(a, b)
Definition macros.h:85
lazy data
Definition meshpage.php:1583
Definition attribute_octahedron_transform.cc:21
Definition GameApi.h:42