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 #include "draco/compression/entropy/symbol_decoding.h"
16 
17 #include <algorithm>
18 #include <cmath>
19 
20 #include "draco/compression/entropy/rans_symbol_decoder.h"
21 
22 namespace draco {
23 
24 template <template <int> class SymbolDecoderT>
25 bool DecodeTaggedSymbols(uint32_t num_values, int num_components,
26                          DecoderBuffer *src_buffer, uint32_t *out_values);
27 
28 template <template <int> class SymbolDecoderT>
29 bool DecodeRawSymbols(uint32_t num_values, DecoderBuffer *src_buffer,
30                       uint32_t *out_values);
31 
DecodeSymbols(uint32_t num_values,int num_components,DecoderBuffer * src_buffer,uint32_t * out_values)32 bool DecodeSymbols(uint32_t num_values, int num_components,
33                    DecoderBuffer *src_buffer, uint32_t *out_values) {
34   if (num_values == 0) {
35     return true;
36   }
37   // Decode which scheme to use.
38   uint8_t scheme;
39   if (!src_buffer->Decode(&scheme)) {
40     return false;
41   }
42   if (scheme == SYMBOL_CODING_TAGGED) {
43     return DecodeTaggedSymbols<RAnsSymbolDecoder>(num_values, num_components,
44                                                   src_buffer, out_values);
45   } else if (scheme == SYMBOL_CODING_RAW) {
46     return DecodeRawSymbols<RAnsSymbolDecoder>(num_values, src_buffer,
47                                                out_values);
48   }
49   return false;
50 }
51 
52 template <template <int> class SymbolDecoderT>
DecodeTaggedSymbols(uint32_t num_values,int num_components,DecoderBuffer * src_buffer,uint32_t * out_values)53 bool DecodeTaggedSymbols(uint32_t num_values, int num_components,
54                          DecoderBuffer *src_buffer, uint32_t *out_values) {
55   // Decode the encoded data.
56   SymbolDecoderT<5> tag_decoder;
57   if (!tag_decoder.Create(src_buffer)) {
58     return false;
59   }
60 
61   if (!tag_decoder.StartDecoding(src_buffer)) {
62     return false;
63   }
64 
65   if (num_values > 0 && tag_decoder.num_symbols() == 0) {
66     return false;  // Wrong number of symbols.
67   }
68 
69   // src_buffer now points behind the encoded tag data (to the place where the
70   // values are encoded).
71   src_buffer->StartBitDecoding(false, nullptr);
72   int value_id = 0;
73   for (uint32_t i = 0; i < num_values; i += num_components) {
74     // Decode the tag.
75     const uint32_t bit_length = tag_decoder.DecodeSymbol();
76     // Decode the actual value.
77     for (int j = 0; j < num_components; ++j) {
78       uint32_t val;
79       if (!src_buffer->DecodeLeastSignificantBits32(bit_length, &val)) {
80         return false;
81       }
82       out_values[value_id++] = val;
83     }
84   }
85   tag_decoder.EndDecoding();
86   src_buffer->EndBitDecoding();
87   return true;
88 }
89 
90 template <class SymbolDecoderT>
DecodeRawSymbolsInternal(uint32_t num_values,DecoderBuffer * src_buffer,uint32_t * out_values)91 bool DecodeRawSymbolsInternal(uint32_t num_values, DecoderBuffer *src_buffer,
92                               uint32_t *out_values) {
93   SymbolDecoderT decoder;
94   if (!decoder.Create(src_buffer)) {
95     return false;
96   }
97 
98   if (num_values > 0 && decoder.num_symbols() == 0) {
99     return false;  // Wrong number of symbols.
100   }
101 
102   if (!decoder.StartDecoding(src_buffer)) {
103     return false;
104   }
105   for (uint32_t i = 0; i < num_values; ++i) {
106     // Decode a symbol into the value.
107     const uint32_t value = decoder.DecodeSymbol();
108     out_values[i] = value;
109   }
110   decoder.EndDecoding();
111   return true;
112 }
113 
114 template <template <int> class SymbolDecoderT>
DecodeRawSymbols(uint32_t num_values,DecoderBuffer * src_buffer,uint32_t * out_values)115 bool DecodeRawSymbols(uint32_t num_values, DecoderBuffer *src_buffer,
116                       uint32_t *out_values) {
117   uint8_t max_bit_length;
118   if (!src_buffer->Decode(&max_bit_length)) {
119     return false;
120   }
121   switch (max_bit_length) {
122     case 1:
123       return DecodeRawSymbolsInternal<SymbolDecoderT<1>>(num_values, src_buffer,
124                                                          out_values);
125     case 2:
126       return DecodeRawSymbolsInternal<SymbolDecoderT<2>>(num_values, src_buffer,
127                                                          out_values);
128     case 3:
129       return DecodeRawSymbolsInternal<SymbolDecoderT<3>>(num_values, src_buffer,
130                                                          out_values);
131     case 4:
132       return DecodeRawSymbolsInternal<SymbolDecoderT<4>>(num_values, src_buffer,
133                                                          out_values);
134     case 5:
135       return DecodeRawSymbolsInternal<SymbolDecoderT<5>>(num_values, src_buffer,
136                                                          out_values);
137     case 6:
138       return DecodeRawSymbolsInternal<SymbolDecoderT<6>>(num_values, src_buffer,
139                                                          out_values);
140     case 7:
141       return DecodeRawSymbolsInternal<SymbolDecoderT<7>>(num_values, src_buffer,
142                                                          out_values);
143     case 8:
144       return DecodeRawSymbolsInternal<SymbolDecoderT<8>>(num_values, src_buffer,
145                                                          out_values);
146     case 9:
147       return DecodeRawSymbolsInternal<SymbolDecoderT<9>>(num_values, src_buffer,
148                                                          out_values);
149     case 10:
150       return DecodeRawSymbolsInternal<SymbolDecoderT<10>>(
151           num_values, src_buffer, out_values);
152     case 11:
153       return DecodeRawSymbolsInternal<SymbolDecoderT<11>>(
154           num_values, src_buffer, out_values);
155     case 12:
156       return DecodeRawSymbolsInternal<SymbolDecoderT<12>>(
157           num_values, src_buffer, out_values);
158     case 13:
159       return DecodeRawSymbolsInternal<SymbolDecoderT<13>>(
160           num_values, src_buffer, out_values);
161     case 14:
162       return DecodeRawSymbolsInternal<SymbolDecoderT<14>>(
163           num_values, src_buffer, out_values);
164     case 15:
165       return DecodeRawSymbolsInternal<SymbolDecoderT<15>>(
166           num_values, src_buffer, out_values);
167     case 16:
168       return DecodeRawSymbolsInternal<SymbolDecoderT<16>>(
169           num_values, src_buffer, out_values);
170     case 17:
171       return DecodeRawSymbolsInternal<SymbolDecoderT<17>>(
172           num_values, src_buffer, out_values);
173     case 18:
174       return DecodeRawSymbolsInternal<SymbolDecoderT<18>>(
175           num_values, src_buffer, out_values);
176     default:
177       return false;
178   }
179 }
180 
181 }  // namespace draco
182