/work/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 | ruiVal = xReadUvlc(); |
70 | 0 | } |
71 | | |
72 | | void VLCReader::xReadSvlc( int32_t& riVal ) |
73 | 0 | { |
74 | 0 | riVal = xReadSvlc(); |
75 | 0 | } |
76 | | |
77 | | void VLCReader::xReadCode( uint32_t uiLength, uint32_t& ruiCode ) |
78 | 0 | { |
79 | 0 | CHECK( uiLength == 0, "Reading a code of lenght '0'" ); |
80 | 0 | ruiCode = m_pcBitstream->read( uiLength ); |
81 | 0 | } |
82 | | |
83 | | void VLCReader::xReadSCode( uint32_t length, int32_t& value ) |
84 | 0 | { |
85 | 0 | CHECK( length == 0 || length > 31, "wrong" ); |
86 | 0 | uint32_t val = m_pcBitstream->read( length ); |
87 | 0 | value = length >= 32 ? int32_t( val ) : ( ( -int32_t( val & ( uint32_t( 1 ) << ( length - 1 ) ) ) ) | int32_t( val ) ); |
88 | 0 | } |
89 | | |
90 | | void VLCReader::xReadFlag( uint32_t& rValue, const char *pSymbolName ) |
91 | 0 | { |
92 | 0 | xReadFlag( rValue ); |
93 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(1) : %d\n", pSymbolName, rValue ); |
94 | 0 | } |
95 | | |
96 | | void VLCReader::xReadUvlc( uint32_t& rValue, const char *pSymbolName ) |
97 | 0 | { |
98 | 0 | xReadUvlc( rValue ); |
99 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s ue(v) : %u\n", pSymbolName, rValue ); |
100 | 0 | } |
101 | | |
102 | | void VLCReader::xReadSvlc( int32_t& rValue, const char *pSymbolName ) |
103 | 0 | { |
104 | 0 | xReadSvlc( rValue ); |
105 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s se(v) : %d\n", pSymbolName, rValue ); |
106 | 0 | } |
107 | | |
108 | | void VLCReader::xReadCode( uint32_t length, uint32_t& rValue, const char *pSymbolName ) |
109 | 0 | { |
110 | 0 | xReadCode( length, rValue ); |
111 | 0 | if( length < 10 ) |
112 | 0 | { |
113 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %u\n", pSymbolName, length, rValue ); |
114 | 0 | } |
115 | 0 | else |
116 | 0 | { |
117 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %u\n", pSymbolName, length, rValue ); |
118 | 0 | } |
119 | 0 | } |
120 | | |
121 | | void VLCReader::xReadSCode( uint32_t length, int32_t& value, const char *pSymbolName ) |
122 | 0 | { |
123 | 0 | xReadSCode( length, value ); |
124 | |
|
125 | 0 | if( length < 10 ) |
126 | 0 | { |
127 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d) : %d\n", pSymbolName, length, value ); |
128 | 0 | } |
129 | 0 | else |
130 | 0 | { |
131 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d) : %d\n", pSymbolName, length, value ); |
132 | 0 | } |
133 | 0 | } |
134 | | |
135 | | // ==================================================================================================================== |
136 | | // read functions returning the result value |
137 | | // ==================================================================================================================== |
138 | | |
139 | | bool VLCReader::xReadFlag() |
140 | 0 | { |
141 | 0 | return m_pcBitstream->read( 1 ) & 0x1; |
142 | 0 | } |
143 | | |
144 | | uint32_t VLCReader::xReadUvlc() |
145 | 0 | { |
146 | 0 | uint32_t uiVal = 0; |
147 | 0 | uint32_t uiCode = 0; |
148 | 0 | uint32_t uiLength = 0; |
149 | |
|
150 | 0 | uiCode = m_pcBitstream->read( 1 ); |
151 | 0 | if( 0 == uiCode ) |
152 | 0 | { |
153 | 0 | uiLength = 0; |
154 | |
|
155 | 0 | while( ! ( uiCode & 1 ) ) |
156 | 0 | { |
157 | 0 | uiCode = m_pcBitstream->read( 1 ); |
158 | 0 | uiLength++; |
159 | 0 | } |
160 | 0 | CHECK( uiLength > 31, "UVLC length overflow" ); |
161 | |
|
162 | 0 | uiVal = m_pcBitstream->read( uiLength ); |
163 | |
|
164 | 0 | uiVal += ( 1u << uiLength ) - 1; |
165 | 0 | } |
166 | | |
167 | 0 | return uiVal; |
168 | 0 | } |
169 | | |
170 | | int32_t VLCReader::xReadSvlc() |
171 | 0 | { |
172 | 0 | uint32_t uiBits = m_pcBitstream->read( 1 ); |
173 | 0 | if( 0 == uiBits ) |
174 | 0 | { |
175 | 0 | uint32_t uiLength = 0; |
176 | |
|
177 | 0 | while( ! ( uiBits & 1 ) ) |
178 | 0 | { |
179 | 0 | uiBits = m_pcBitstream->read( 1 ); |
180 | 0 | uiLength++; |
181 | 0 | } |
182 | 0 | CHECK( uiLength > 30, "SVLC length overflow" ); |
183 | |
|
184 | 0 | uiBits = m_pcBitstream->read( uiLength ); |
185 | |
|
186 | 0 | uiBits += ( 1u << uiLength ); |
187 | 0 | return ( uiBits & 1 ) ? -(int32_t)( uiBits>>1 ) : (int32_t)( uiBits>>1 ); |
188 | 0 | } |
189 | 0 | else |
190 | 0 | { |
191 | 0 | return 0; |
192 | 0 | } |
193 | 0 | } |
194 | | |
195 | | uint32_t VLCReader::xReadCode( uint32_t uiLength ) |
196 | 0 | { |
197 | 0 | CHECK( uiLength == 0, "Reading a code of lenght '0'" ); |
198 | 0 | return m_pcBitstream->read( uiLength ); |
199 | 0 | } |
200 | | |
201 | | int32_t VLCReader::xReadSCode( uint32_t length ) |
202 | 0 | { |
203 | 0 | CHECK( length == 0 || length > 31, "wrong" ); |
204 | 0 | uint32_t val = m_pcBitstream->read( length ); |
205 | 0 | return ( -int32_t( val & ( 1u << ( length - 1 ) ) ) ) | int32_t( val ) ; |
206 | 0 | } |
207 | | |
208 | | bool VLCReader::xReadFlag( const char* pSymbolName ) |
209 | 0 | { |
210 | 0 | bool value = xReadFlag(); |
211 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(1) : %d\n", pSymbolName, value ); |
212 | 0 | return value; |
213 | 0 | } |
214 | | |
215 | | uint32_t VLCReader::xReadUvlc( const char* pSymbolName ) |
216 | 0 | { |
217 | 0 | uint32_t value = xReadUvlc(); |
218 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s ue(v) : %u\n", pSymbolName, value ); |
219 | 0 | return value; |
220 | 0 | } |
221 | | |
222 | | int32_t VLCReader::xReadSvlc( const char* pSymbolName ) |
223 | 0 | { |
224 | 0 | int32_t value = xReadSvlc(); |
225 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s se(v) : %d\n", pSymbolName, value ); |
226 | 0 | return value; |
227 | 0 | } |
228 | | |
229 | | uint32_t VLCReader::xReadCode( uint32_t length, const char* pSymbolName ) |
230 | 0 | { |
231 | 0 | uint32_t value = xReadCode( length ); |
232 | 0 | if( length < 10 ) |
233 | 0 | { |
234 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %u\n", pSymbolName, length, value ); |
235 | 0 | } |
236 | 0 | else |
237 | 0 | { |
238 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s u(%d) : %u\n", pSymbolName, length, value ); |
239 | 0 | } |
240 | 0 | return value; |
241 | 0 | } |
242 | | |
243 | | int32_t VLCReader::xReadSCode( uint32_t length, const char* pSymbolName ) |
244 | 0 | { |
245 | 0 | int32_t value = xReadSCode( length ); |
246 | |
|
247 | 0 | if( length < 10 ) |
248 | 0 | { |
249 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d) : %d\n", pSymbolName, length, value ); |
250 | 0 | } |
251 | 0 | else |
252 | 0 | { |
253 | 0 | DTRACE( g_trace_ctx, D_HEADER, "%-50s i(%d) : %d\n", pSymbolName, length, value ); |
254 | 0 | } |
255 | 0 | return value; |
256 | 0 | } |
257 | | |
258 | | void VLCReader::xReadRbspTrailingBits() |
259 | 0 | { |
260 | 0 | X_READ_FLAG( rbsp_stop_one_bit ); |
261 | 0 | CHECK( rbsp_stop_one_bit != 1, "Trailing bit not '1'" ); |
262 | 0 | int cnt = 0; |
263 | 0 | while( m_pcBitstream->getNumBitsUntilByteAligned() ) |
264 | 0 | { |
265 | 0 | X_READ_FLAG( rbsp_alignment_zero_bit ); |
266 | 0 | CHECK( rbsp_alignment_zero_bit != 0, "Alignment bit is not '0'" ); |
267 | 0 | cnt++; |
268 | 0 | } |
269 | 0 | CHECK( cnt >= 8, "Read more than '8' trailing bits" ); |
270 | 0 | } |
271 | | |
272 | | } // namespace vvdec |