/src/vvdec/source/Lib/DecoderLib/VLCReader.cpp
Line | Count | Source |
1 | | /* ----------------------------------------------------------------------------- |
2 | | The copyright in this software is being made available under the Clear BSD |
3 | | License, included below. No patent rights, trademark rights and/or |
4 | | other Intellectual Property Rights other than the copyrights concerning |
5 | | the Software are granted under this license. |
6 | | |
7 | | The Clear BSD License |
8 | | |
9 | | Copyright (c) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC Authors. |
10 | | All rights reserved. |
11 | | |
12 | | Redistribution and use in source and binary forms, with or without modification, |
13 | | are permitted (subject to the limitations in the disclaimer below) provided that |
14 | | the following conditions are met: |
15 | | |
16 | | * Redistributions of source code must retain the above copyright notice, |
17 | | this list of conditions and the following disclaimer. |
18 | | |
19 | | * Redistributions in binary form must reproduce the above copyright |
20 | | notice, this list of conditions and the following disclaimer in the |
21 | | documentation and/or other materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the copyright holder nor the names of its |
24 | | contributors may be used to endorse or promote products derived from this |
25 | | software without specific prior written permission. |
26 | | |
27 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY |
28 | | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
29 | | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
30 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
31 | | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
32 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
33 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
34 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
35 | | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
36 | | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
37 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | | POSSIBILITY OF SUCH DAMAGE. |
39 | | |
40 | | |
41 | | ------------------------------------------------------------------------------------------- */ |
42 | | |
43 | | /** \file VLCReader.cpp |
44 | | * \brief Reader for high level syntax |
45 | | */ |
46 | | |
47 | | //! \ingroup DecoderLib |
48 | | //! \{ |
49 | | |
50 | | #include "VLCReader.h" |
51 | | |
52 | | #include "CommonLib/CommonDef.h" |
53 | | #include "CommonLib/dtrace_next.h" |
54 | | |
55 | | namespace vvdec |
56 | | { |
57 | | |
58 | | // ==================================================================================================================== |
59 | | // read functions taking a reference for the result value |
60 | | // ==================================================================================================================== |
61 | | |
62 | | void VLCReader::xReadFlag( uint32_t& ruiCode ) |
63 | 0 | { |
64 | 0 | ruiCode = m_pcBitstream->read( 1 ); |
65 | 0 | } |
66 | | |
67 | | void VLCReader::xReadUvlc( uint32_t& ruiVal ) |
68 | 0 | { |
69 | 0 | uint32_t uiVal = 0; |
70 | 0 | uint32_t uiCode = 0; |
71 | 0 | uint32_t uiLength = 0; |
72 | |
|
73 | 0 | uiCode = m_pcBitstream->read( 1 ); |
74 | 0 | if( 0 == uiCode ) |
75 | 0 | { |
76 | 0 | uiLength = 0; |
77 | |
|
78 | 0 | while( ! ( uiCode & 1 ) ) |
79 | 0 | { |
80 | 0 | uiCode = m_pcBitstream->read( 1 ); |
81 | 0 | uiLength++; |
82 | 0 | } |
83 | |
|
84 | 0 | uiVal = m_pcBitstream->read( uiLength ); |
85 | |
|
86 | 0 | uiVal += ( 1 << uiLength ) - 1; |
87 | 0 | } |
88 | |
|
89 | 0 | ruiVal = uiVal; |
90 | 0 | } |
91 | | |
92 | | void VLCReader::xReadSvlc( int32_t& riVal ) |
93 | 0 | { |
94 | 0 | uint32_t uiBits = m_pcBitstream->read( 1 ); |
95 | 0 | if( 0 == uiBits ) |
96 | 0 | { |
97 | 0 | uint32_t uiLength = 0; |
98 | |
|
99 | 0 | while( ! ( uiBits & 1 ) ) |
100 | 0 | { |
101 | 0 | uiBits = m_pcBitstream->read( 1 ); |
102 | 0 | uiLength++; |
103 | 0 | } |
104 | |
|
105 | 0 | uiBits = m_pcBitstream->read( uiLength ); |
106 | |
|
107 | 0 | uiBits += ( 1 << uiLength ); |
108 | 0 | riVal = ( uiBits & 1 ) ? -(int32_t)( uiBits>>1 ) : (int32_t)( uiBits>>1 ); |
109 | 0 | } |
110 | 0 | else |
111 | 0 | { |
112 | 0 | riVal = 0; |
113 | 0 | } |
114 | 0 | } |
115 | | |
116 | | void VLCReader::xReadCode( uint32_t uiLength, uint32_t& ruiCode ) |
117 | 0 | { |
118 | 0 | CHECK( uiLength == 0, "Reading a code of lenght '0'" ); |
119 | 0 | ruiCode = m_pcBitstream->read( uiLength ); |
120 | 0 | } |
121 | | |
122 | | void VLCReader::xReadSCode( uint32_t length, int32_t& value ) |
123 | 0 | { |
124 | 0 | CHECK( length == 0 || length > 31, "wrong" ); |
125 | 0 | uint32_t val = m_pcBitstream->read( length ); |
126 | 0 | value = length >= 32 ? int32_t( val ) : ( ( -int32_t( val & ( uint32_t( 1 ) << ( length - 1 ) ) ) ) | int32_t( val ) ); |
127 | 0 | } |
128 | | |
129 | | void VLCReader::xReadFlag( uint32_t& rValue, const char *pSymbolName ) |
130 | 0 | { |
131 | 0 | xReadFlag( rValue ); |
132 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(1) : %d\n", pSymbolName, rValue ); |
133 | 0 | } |
134 | | |
135 | | void VLCReader::xReadUvlc( uint32_t& rValue, const char *pSymbolName ) |
136 | 0 | { |
137 | 0 | xReadUvlc( rValue ); |
138 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s ue(v) : %u\n", pSymbolName, rValue ); |
139 | 0 | } |
140 | | |
141 | | void VLCReader::xReadSvlc( int32_t& rValue, const char *pSymbolName ) |
142 | 0 | { |
143 | 0 | xReadSvlc( rValue ); |
144 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s se(v) : %d\n", pSymbolName, rValue ); |
145 | 0 | } |
146 | | |
147 | | void VLCReader::xReadCode( uint32_t length, uint32_t& rValue, const char *pSymbolName ) |
148 | 0 | { |
149 | 0 | xReadCode( length, rValue ); |
150 | 0 | if( length < 10 ) |
151 | 0 | { |
152 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %u\n", pSymbolName, length, rValue ); |
153 | 0 | } |
154 | 0 | else |
155 | 0 | { |
156 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %u\n", pSymbolName, length, rValue ); |
157 | 0 | } |
158 | 0 | } |
159 | | |
160 | | void VLCReader::xReadSCode( uint32_t length, int32_t& value, const char *pSymbolName ) |
161 | 0 | { |
162 | 0 | xReadSCode( length, value ); |
163 | |
|
164 | 0 | if( length < 10 ) |
165 | 0 | { |
166 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d) : %d\n", pSymbolName, length, value ); |
167 | 0 | } |
168 | 0 | else |
169 | 0 | { |
170 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d) : %d\n", pSymbolName, length, value ); |
171 | 0 | } |
172 | 0 | } |
173 | | |
174 | | // ==================================================================================================================== |
175 | | // read functions returning the result value |
176 | | // ==================================================================================================================== |
177 | | |
178 | | bool VLCReader::xReadFlag() |
179 | 0 | { |
180 | 0 | return m_pcBitstream->read( 1 ) & 0x1; |
181 | 0 | } |
182 | | |
183 | | uint32_t VLCReader::xReadUvlc() |
184 | 0 | { |
185 | 0 | uint32_t uiVal = 0; |
186 | 0 | uint32_t uiCode = 0; |
187 | 0 | uint32_t uiLength = 0; |
188 | |
|
189 | 0 | uiCode = m_pcBitstream->read( 1 ); |
190 | 0 | if( 0 == uiCode ) |
191 | 0 | { |
192 | 0 | uiLength = 0; |
193 | |
|
194 | 0 | while( ! ( uiCode & 1 ) ) |
195 | 0 | { |
196 | 0 | uiCode = m_pcBitstream->read( 1 ); |
197 | 0 | uiLength++; |
198 | 0 | } |
199 | |
|
200 | 0 | uiVal = m_pcBitstream->read( uiLength ); |
201 | |
|
202 | 0 | uiVal += ( 1 << uiLength ) - 1; |
203 | 0 | } |
204 | |
|
205 | 0 | return uiVal; |
206 | 0 | } |
207 | | |
208 | | int32_t VLCReader::xReadSvlc() |
209 | 0 | { |
210 | 0 | uint32_t uiBits = m_pcBitstream->read( 1 ); |
211 | 0 | if( 0 == uiBits ) |
212 | 0 | { |
213 | 0 | uint32_t uiLength = 0; |
214 | |
|
215 | 0 | while( ! ( uiBits & 1 ) ) |
216 | 0 | { |
217 | 0 | uiBits = m_pcBitstream->read( 1 ); |
218 | 0 | uiLength++; |
219 | 0 | } |
220 | |
|
221 | 0 | uiBits = m_pcBitstream->read( uiLength ); |
222 | |
|
223 | 0 | uiBits += ( 1 << uiLength ); |
224 | 0 | return ( uiBits & 1 ) ? -(int32_t)( uiBits>>1 ) : (int32_t)( uiBits>>1 ); |
225 | 0 | } |
226 | 0 | else |
227 | 0 | { |
228 | 0 | return 0; |
229 | 0 | } |
230 | 0 | } |
231 | | |
232 | | uint32_t VLCReader::xReadCode( uint32_t uiLength ) |
233 | 0 | { |
234 | 0 | CHECK( uiLength == 0, "Reading a code of lenght '0'" ); |
235 | 0 | return m_pcBitstream->read( uiLength ); |
236 | 0 | } |
237 | | |
238 | | int32_t VLCReader::xReadSCode( uint32_t length ) |
239 | 0 | { |
240 | 0 | CHECK( length == 0 || length > 31, "wrong" ); |
241 | 0 | uint32_t val = m_pcBitstream->read( length ); |
242 | 0 | return length >= 32 ? int32_t( val ) : ( ( -int32_t( val & ( uint32_t( 1 ) << ( length - 1 ) ) ) ) | int32_t( val ) ); |
243 | 0 | } |
244 | | |
245 | | bool VLCReader::xReadFlag( const char* pSymbolName ) |
246 | 0 | { |
247 | 0 | bool value = xReadFlag(); |
248 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(1) : %d\n", pSymbolName, value ); |
249 | 0 | return value; |
250 | 0 | } |
251 | | |
252 | | uint32_t VLCReader::xReadUvlc( const char* pSymbolName ) |
253 | 0 | { |
254 | 0 | uint32_t value = xReadUvlc(); |
255 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s ue(v) : %u\n", pSymbolName, value ); |
256 | 0 | return value; |
257 | 0 | } |
258 | | |
259 | | int32_t VLCReader::xReadSvlc( const char* pSymbolName ) |
260 | 0 | { |
261 | 0 | int32_t value = xReadSvlc(); |
262 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s se(v) : %d\n", pSymbolName, value ); |
263 | 0 | return value; |
264 | 0 | } |
265 | | |
266 | | uint32_t VLCReader::xReadCode( uint32_t length, const char* pSymbolName ) |
267 | 0 | { |
268 | 0 | uint32_t value = xReadCode( length ); |
269 | 0 | if( length < 10 ) |
270 | 0 | { |
271 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %u\n", pSymbolName, length, value ); |
272 | 0 | } |
273 | 0 | else |
274 | 0 | { |
275 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %u\n", pSymbolName, length, value ); |
276 | 0 | } |
277 | 0 | return value; |
278 | 0 | } |
279 | | |
280 | | int32_t VLCReader::xReadSCode( uint32_t length, const char* pSymbolName ) |
281 | 0 | { |
282 | 0 | int32_t value = xReadSCode( length ); |
283 | |
|
284 | 0 | if( length < 10 ) |
285 | 0 | { |
286 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d) : %d\n", pSymbolName, length, value ); |
287 | 0 | } |
288 | 0 | else |
289 | 0 | { |
290 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d) : %d\n", pSymbolName, length, value ); |
291 | 0 | } |
292 | 0 | return value; |
293 | 0 | } |
294 | | |
295 | | void VLCReader::xReadRbspTrailingBits() |
296 | 0 | { |
297 | 0 | X_READ_FLAG( rbsp_stop_one_bit ); |
298 | 0 | CHECK( rbsp_stop_one_bit != 1, "Trailing bit not '1'" ); |
299 | 0 | int cnt = 0; |
300 | 0 | while( m_pcBitstream->getNumBitsUntilByteAligned() ) |
301 | 0 | { |
302 | 0 | X_READ_FLAG( rbsp_alignment_zero_bit ); |
303 | 0 | CHECK( rbsp_alignment_zero_bit != 0, "Alignment bit is not '0'" ); |
304 | 0 | cnt++; |
305 | 0 | } |
306 | 0 | CHECK( cnt >= 8, "Read more than '8' trailing bits" ); |
307 | 0 | } |
308 | | |
309 | | } // namespace vvdec |