UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
varbits.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#ifndef __VARBITSH__
3#define __VARBITSH__
4
5#ifndef __RADRR_CORE2H__
6#include "rrCore.h"
7#endif
8
9#ifdef WRAP_PUBLICS
10#define rfmerge3(name,add) name##add
11#define rfmerge2(name,add) rfmerge3(name,add)
12#define rfmerge(name) rfmerge2(name,WRAP_PUBLICS)
13#define VarBitsCopy rfmerge(VarBitsCopy)
14#define VarBitsLens rfmerge(VarBitsLens)
15#endif
16
17
18// variable bit macros
19//#if defined(__RADX86__)
21//#endif
22
23/*************
24
25VARBITS can either be in a struct , or in local variables set up by VARBITSLOCAL(name)
26
27the "Local" macros make the names of the local variables using ##
28
29***************/
30
31//#define USE64BITVB
32#ifdef USE64BITVB
33
34#define BITSTYPE U64
35#define BITSTYPELEN 64
36#define BITSTYPEBYTES 8
37#define BITSTOPMASK (1UL64<<(BITSTYPELEN-1))
38
39//NOTE this is read-only on USE64BITVB!
40#define VarBitsOpen(vb,pointer) { (vb).init=pointer; if (((U32)pointer)&4) { (vb).bits = *((U32* RADRESTRICT )pointer); (vb).cur = ((char*)pointer)+4; (vb).bitlen = 32; } else { (vb).cur=pointer; (vb).bits=(vb).bitlen=0; } }
41#define VarBitsLocalOpen(vb,pointer) { if (((U32)pointer)&4) { vb##bits = *((U32 * RADRESTRICT)pointer); vb##cur = ((char*)pointer)+4; vb##bitlen = 32; } else { vb##cur=pointer; vb##bits=vb##bitlen=0; } }
42
43#else
44
45#define BITSTYPE U32
46#define BITSTYPELEN 32
47#define BITSTYPEBYTES 4
48#define BITSTOPMASK (1UL<<(BITSTYPELEN-1))
49
50#define VarBitsOpen(vb,pointer) { (vb).cur=(vb).init=pointer; (vb).bits=(vb).bitlen=0; }
51#define VarBitsLocalOpen(vb,pointer) { vb##cur=pointer; vb##bits=vb##bitlen=0; }
52
53#endif
54
55#define VARBITSTEMP BITSTYPE
56
64
65// FG: same as VARBITS (and can be used with the same macros), but has space for an "end" pointer
66// not used by the macros, but useful if you need to propagate the "end" pointer downstream in
67// a decoder.
76
77// CB : WARNING : these functions are generally NOT safe to call with # bits = 0
78
79#define VarBitsPut(vb,val,size) { U32 __s=size; U32 __v=(val)&VarBitsLens[__s]; (vb).bits|=__v<<((vb).bitlen); (vb).bitlen+=__s; if ((vb).bitlen>=32) { *((U32*)(vb).cur)=(vb).bits; (vb).cur=((char*)((vb).cur)+4); (vb).bitlen-=32; (vb).bits=0; if ((vb).bitlen) { (vb).bits=__v>>(__s-(vb).bitlen); } } }
80#define VarBitsPut1(vb,boolean) { if (boolean) (vb).bits|=(1<<(vb).bitlen); if ((++(vb).bitlen)==32) { *((U32*)(vb).cur)=(vb).bits; (vb).cur=((char*)((vb).cur)+4); (vb).bits=(vb).bitlen=0; } }
81#define VarBitsPuta1(vb) { (vb).bits|=(1<<(vb).bitlen); if ((++(vb).bitlen)==32) { *((U32*)(vb).cur)=(vb).bits; (vb).cur=((char*)((vb).cur)+4); (vb).bits=(vb).bitlen=0; } }
82#define VarBitsPuta0(vb) { if ((++(vb).bitlen)==32) { *((U32*)(vb).cur)=(vb).bits; (vb).cur=((char*)((vb).cur)+4); (vb).bits=(vb).bitlen=0; } }
83#define VarBitsPutAlign(vb) { U32 __s2=(32-(vb).bitlen)&31; if (__s2) { VarBitsPut((vb),0,__s2); } }
84#define VarBitsFlushtoMemOnly(vb) { if (((vb).bitlen)) { *((U32*)(vb).cur)=(vb).bits; } }
85#define VarBitsConvertPutToGet(gvb,pvb) { if (((pvb).bitlen)) { (gvb).bits=(*((U32*)(pvb).cur))>>(pvb).bitlen; (gvb).bitlen=BITSTYPELEN-(pvb).bitlen; (gvb).cur=((char*)((pvb).cur)+4); } else { (gvb).bits=0; (gvb).bitlen=0; (gvb).cur=(pvb).cur; } (gvb).init=(pvb).init; }
86#define VarBitsFlush(vb) VarBitsPutAlign(vb)
87#define VarBitsSize(vb) ((U32)( (((char*)(vb).cur)-((char*)(vb).init))*8 +(vb).bitlen )) // in bits !!
88
89// VarBitsCopy size is in bits of course; don't use this for big copies
91
92// getbitlevel :
93// getbitlevel(n) is the number of bits that n uses for its on bits
94// eg. n < (1<<getbitlevel(n)) , n >= (1<<(getbitlevel(n)-1))
95// getbitlevel(n)-1 is the bit position of the leftmost 1 bit in 'n'
96// NOTE : getbitlevel(0) = 0
97// getbitlevel(n) = ilog2ceil except on powers of two
98//---------------------------------------
99
100
101// WARNING : this getbitlevel only works on *constant* U16 values ! (up to 65535)
102// it will fail to compile with strange errors if you use a variable
103#define getbitlevelconst(level) \
104( \
105 (((level)< 1)?0: \
106 (((level)< 2)?1: \
107 (((level)< 4)?2: \
108 (((level)< 8)?3: \
109 (((level)< 16)?4: \
110 (((level)< 32)?5: \
111 (((level)< 64)?6: \
112 (((level)< 128)?7: \
113 (((level)< 256)?8: \
114 (((level)< 512)?9: \
115 (((level)< 1024)?10: \
116 (((level)< 2048)?11: \
117 (((level)< 4096)?12: \
118 (((level)< 8192)?13: \
119 (((level)<16384)?14: \
120 (((level)<32768)?15: \
121 (((level)<65536)?16:sizeof(char[65535-level]) \
122 ))))))))))))))))) \
123)
124
125
126#if defined(__RADPPC__)
127
128 #if defined(__GNUC__)
129
130 #if defined(__SNC__)
131 #define count_leading_zeros(count, x) count = __cntlzw(x)
132 #elif defined(__ghs__)
133 RADDEFFUNC unsigned int __CLZ32(unsigned int a);
134 #define count_leading_zeros(count, x) count = __CLZ32(x)
135 #else
136 #define count_leading_zeros(count, x) \
137 __asm__ ("{cntlz|cntlzw} %0,%1" \
138 : "=r" (count) \
139 : "r" (x))
140 #endif
141
142
143 static RADINLINE U32 getbitlevelvar( register U32 n )
144 {
145 count_leading_zeros( n, n );
146 return( 32 - n );
147 }
148
149 #else
150
151 #ifdef _MSC_VER
152 #include <ppcintrinsics.h>
153 #define __cntlzw _CountLeadingZeros
154 #endif
155
156 #define getbitlevelvar(n) (U32) (32 - __cntlzw(n))
157
158 #endif
159
160#elif defined(__RADSPU__)
161
162 static RADINLINE U32 getbitlevelvar( register U32 n )
163 {
164 vector unsigned int v;
165 v[0]=n;
166 v = __builtin_spu_cntlz( v );
167 return( 32 - v[0] );
168 }
169
170#elif defined(__RADARM__)
171
172 #ifdef _MSC_VER
173
174 #ifdef _M_ARM64
175
176 #define getbitlevelvar(n) (U32) (32 - _CountLeadingZeros(n))
177
178 #else
179
180 #define getbitlevelvar(n) (U32) (32 - _arm_clz(n))
181
182 #endif
183
184 #else
185
186 #define getbitlevelvar(n) (U32) (32 - __builtin_clz(n))
187
188 #endif
189
190#elif (_MSC_FULL_VER >= 13012035 )
191
193 unsigned char _BitScanReverse(unsigned long* Index, unsigned long Mask);
194 #pragma intrinsic(_BitScanReverse)
196
197 static RADINLINE U32 getbitlevelvar( register U32 val )
198 {
199 if ( val )
200 {
201 U32 b = 0;
202 _BitScanReverse( (unsigned long*)&b, val );
203 return b + 1;
204 }
205 return 0;
206 }
207
208#else
209
210 static RADINLINE U32 getbitlevelvar( register U32 val )
211 {
212 static char vs[16]={0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4};
213 int bits=0;
214
215 if ( val & 0xffff0000 )
216 {
217 bits = 16;
218 val >>= 16;
219 }
220
221 if ( val & 0xff00 )
222 {
223 bits += 8;
224 val >>= 8;
225 }
226
227 if ( val & 0xf0 )
228 {
229 bits += 4;
230 val >>= 4;
231 }
232
233 bits += vs[ val ];
234
235 return bits;
236 }
237
238#endif
239
240#define VarBitsGetAlign(vb) { (vb).bitlen=0; }
241#define VarBitsPos(vb) ((U32)( (((U8*)(vb).cur)-((U8*)(vb).init))*8-(vb).bitlen ))
242
243// CB : GetBitsLen(bits) = (1<<bits)-1
244// except that values for bits=32 , GetBitsLen fails for bits=0
245// don't pass zero to this function
246#define GetBitsLen(val) (((U32)0xffffffff)>>(U32)(32-(val)))
247// for debugging: causes crash on zero: #define GetBitsLen(val) (((val)==0)?(((U8*)val)[0]=0):(0xffffffffL>>(U32)(32-(val))))
248
249// get 1 bit
250// best to use like : if ( VarBitsGet1(vb,i) )
251//
252// This *doesn't* set i to the result - that's just a temp - the expression is the result!!!
253// i will be the unmasked bits, but that's not guaranteed!
254#define VarBitsGet1(vb,i) \
255( \
256 ((vb).bitlen==0)? \
257 ( \
258 i=*((BITSTYPE* RADRESTRICT)((vb).cur)), \
259 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES, \
260 ((vb).bits)=((BITSTYPE)i)>>1, \
261 ((vb).bitlen)=(BITSTYPELEN-1) \
262 ):( \
263 i=((vb).bits), \
264 ((vb).bits)>>=1, \
265 --((vb).bitlen) \
266 ),(i&1) \
267)
268
269//not USE64BITVB safe!
270#define VarBitsGet1LE(vb,i) \
271( \
272 ((vb).bitlen==0)? \
273 ( \
274 i=radloadu32ptr((vb).cur), \
275 ((vb).cur)=((char*)((vb).cur))+4, \
276 ((vb).bits)=((U32)i)>>1, \
277 ((vb).bitlen)=31 \
278 ):( \
279 i=((vb).bits), \
280 ((vb).bits)>>=1, \
281 --((vb).bitlen) \
282 ),(i&1) \
283)
284
285
286#define VarBitsGet(v,typ,vb,len) \
287{ \
288 if (((vb).bitlen)<(len)) { \
289 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)((vb).cur)); \
290 v=(typ)((((vb).bits)|(nb<<((vb).bitlen)))&GetBitsLen(len)); \
291 ((vb).bits)=nb>>((len)-((vb).bitlen)); \
292 ((vb).bitlen)=((vb).bitlen)+BITSTYPELEN-(len); \
293 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES; \
294 } else { \
295 v=(typ)(((vb).bits)&GetBitsLen(len)); \
296 ((vb).bits)>>=(len); \
297 ((vb).bitlen)-=(len); \
298 } \
299}
300
301#define VarBitsGetWithCheck(v,typ,vb,len,endp,dowhat) \
302{ \
303 if (((vb).bitlen)<(len)) { \
304 register BITSTYPE nb; \
305 if ( ( (U8*)((vb).cur) ) >= ( (U8*) (endp) ) ) dowhat \
306 nb=*((BITSTYPE* RADRESTRICT)((vb).cur)); \
307 v=(typ)((((vb).bits)|(nb<<((vb).bitlen)))&GetBitsLen(len)); \
308 ((vb).bits)=nb>>((len)-((vb).bitlen)); \
309 ((vb).bitlen)=((vb).bitlen)+BITSTYPELEN-(len); \
310 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES; \
311 } else { \
312 v=(typ)(((vb).bits)&GetBitsLen(len)); \
313 ((vb).bits)>>=(len); \
314 ((vb).bitlen)-=(len); \
315 } \
316}
317
318#define VarBitsGetWithCheckBE(v,typ,vb,len,endp,dowhat) \
319{ \
320 if (((vb).bitlen)<(len)) { \
321 register BITSTYPE nb; \
322 if ( ( (U8*)((vb).cur) ) >= ( (U8*) (endp) ) ) dowhat \
323 nb=radloadu32ptrBE((vb).cur); \
324 v=(typ)((((vb).bits)|(nb<<((vb).bitlen)))&GetBitsLen(len)); \
325 ((vb).bits)=nb>>((len)-((vb).bitlen)); \
326 ((vb).bitlen)=((vb).bitlen)+BITSTYPELEN-(len); \
327 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES; \
328 } else { \
329 v=(typ)(((vb).bits)&GetBitsLen(len)); \
330 ((vb).bits)>>=(len); \
331 ((vb).bitlen)-=(len); \
332 } \
333}
334
335#define VarBitsGetWithCheckLE(v,typ,vb,len,endp,dowhat) \
336{ \
337 if (((vb).bitlen)<(len)) { \
338 register BITSTYPE nb; \
339 if ( ( (U8*)((vb).cur) ) >= ( (U8*) (endp) ) ) dowhat \
340 nb=radloadu32ptr((vb).cur); \
341 v=(typ)((((vb).bits)|(nb<<((vb).bitlen)))&GetBitsLen(len)); \
342 ((vb).bits)=nb>>((len)-((vb).bitlen)); \
343 ((vb).bitlen)=((vb).bitlen)+BITSTYPELEN-(len); \
344 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES; \
345 } else { \
346 v=(typ)(((vb).bits)&GetBitsLen(len)); \
347 ((vb).bits)>>=(len); \
348 ((vb).bitlen)-=(len); \
349 } \
350}
351
352// Peek : put len bits in v but don't shift the read pointer
353#define VarBitsPeek(v,typ,vb,len) \
354{ \
355 if (((vb).bitlen)<(len)) { \
356 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)((vb).cur)); \
357 v=(typ)((((vb).bits)|(nb<<((vb).bitlen)))&GetBitsLen(len)); \
358 } else { \
359 v=(typ)(((vb).bits)&GetBitsLen(len)); \
360 } \
361}
362
363//not USE64BITVB safe!
364#define VarBitsGetLE(v,typ,vb,len) \
365{ \
366 if (((vb).bitlen)<(len)) { \
367 register U32 nb=radloadu32ptr((vb).cur); \
368 v=(typ)((((vb).bits)|(nb<<((vb).bitlen)))&GetBitsLen(len)); \
369 ((vb).bits)=nb>>((len)-((vb).bitlen)); \
370 ((vb).bitlen)=((vb).bitlen)+32-(len); \
371 ((vb).cur)=((char*)((vb).cur))+4; \
372 } else { \
373 v=(typ)(((vb).bits)&GetBitsLen(len)); \
374 ((vb).bits)>>=(len); \
375 ((vb).bitlen)-=(len); \
376 } \
377}
378
379// VarBitsUse : just skip 'len' bits ; useful after a Peek
380#define VarBitsUse(vb,len) \
381{ \
382 if (((vb).bitlen)<(len)) { \
383 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)((vb).cur)); \
384 ((vb).bits)=nb>>((len)-((vb).bitlen)); \
385 ((vb).bitlen)=((vb).bitlen)+BITSTYPELEN-(len); \
386 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES; \
387 } else { \
388 ((vb).bits)>>=(len); \
389 ((vb).bitlen)-=(len); \
390 } \
391}
392
393//-------------------------------------------------------------------------------------
394// VarBitsLocal stuff for even more speed
395
396// VARBITSLOCAL defines the local vars to hold the varbits goodies
397// VarBitsCopyToLocal() at the start
398// VarBitsCopyFromLocal() at the end
399
400#define VARBITSLOCAL(name) void * name##cur; BITSTYPE name##bits; U32 name##bitlen
401
402
403#ifdef __RAD64REGS__
404
405#ifdef INC_BINK2
406
407#if defined(__RADX86__)
408#include <xmmintrin.h>
409#define VBPREFETCH( ptr ) _mm_prefetch(((char*)(ptr))+1024, _MM_HINT_T0 )
410#elif defined(__RADARM64__)
411// should we do this??
412#define VBPREFETCH( ptr ) __builtin_prefetch(((char*)(ptr))+1024)
413#else
414#define VBPREFETCH( ptr )
415#endif
416#else
417#define VBPREFETCH( ptr )
418#endif
419
420#define VarBitsLocalGet(v,typ,vb,len) \
421{ \
422 register U64 _bits = (vb##bits); \
423 if ((vb##bitlen)<len) { \
424 _bits |= (((U64)(*((U32* RADRESTRICT)(vb##cur))))<<(vb##bitlen)); \
425 (vb##bitlen)=(vb##bitlen)+32; \
426 VBPREFETCH((vb##cur)); \
427 (vb##cur)=((char*)(vb##cur))+4; \
428 } \
429 (vb##bits)=(U32)(_bits>>(len)); \
430 (vb##bitlen)-=(len); \
431 v=(typ)(((U32)_bits)&GetBitsLen(len)); \
432}
433
434// mask == GetBitsLen(len) - for when you know this in advance.
435// load == what to do to load
436#define VarBitsLocalGetWithCheckBase(v,typ,vb,len,mask,endp,dowhat,load) \
437{ \
438 register U64 _bits = (vb##bits); \
439 if ((vb##bitlen)<len) { \
440 if ( ( (U8*)(vb##cur) ) >= ( (U8*) (endp) ) ) dowhat \
441 _bits|=((U64) (load(vb##cur))) << (vb##bitlen); \
442 (vb##bitlen)+=32; \
443 (vb##cur)=((char*)(vb##cur))+4; \
444 } \
445 v=(typ)(_bits & (mask)); \
446 (vb##bits)=(U32)(_bits>>(len)); \
447 (vb##bitlen)-=(len); \
448}
449
450#else
451
452#define VarBitsLocalGet(v,typ,vb,len) \
453{ \
454 if ((vb##bitlen)<len) { \
455 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)(vb##cur)); \
456 v=(typ)(((vb##bits)|(nb<<(vb##bitlen)))&GetBitsLen(len)); \
457 (vb##bits)=nb>>((len)-(vb##bitlen)); \
458 (vb##bitlen)=(vb##bitlen)+BITSTYPELEN-(len); \
459 (vb##cur)=((char*)(vb##cur))+BITSTYPEBYTES; \
460 } else { \
461 v=(typ)((vb##bits)&GetBitsLen(len)); \
462 (vb##bits)>>=(len); \
463 (vb##bitlen)-=(len); \
464 } \
465}
466
467// mask == GetBitsLen(len) - for when you know this in advance.
468// load == what to do to load
469#define VarBitsLocalGetWithCheckBase(v,typ,vb,len,mask,endp,dowhat,load) \
470{ \
471 if ((vb##bitlen)<len) { \
472 register BITSTYPE nb; \
473 if ( ( (U8*)(vb##cur) ) >= ( (U8*) (endp) ) ) dowhat \
474 nb=load(vb##cur); \
475 v=(typ)(((vb##bits)|(nb<<(vb##bitlen)))&(mask)); \
476 (vb##bits)=nb>>((len)-(vb##bitlen)); \
477 (vb##bitlen)=(vb##bitlen)+BITSTYPELEN-(len); \
478 (vb##cur)=((char*)(vb##cur))+BITSTYPEBYTES; \
479 } else { \
480 v=(typ)((vb##bits)&(mask)); \
481 (vb##bits)>>=(len); \
482 (vb##bitlen)-=(len); \
483 } \
484}
485
486#endif
487
488#define radloadbitsnative(ptr) (*((BITSTYPE* RADRESTRICT)(ptr)))
489
490#define VarBitsLocalGetWithCheck(v,typ,vb,len,endp,dowhat) VarBitsLocalGetWithCheckBase(v,typ,vb,len,GetBitsLen(len),endp,dowhat,radloadbitsnative)
491#define VarBitsLocalGetWithCheckBE(v,typ,vb,len,endp,dowhat) VarBitsLocalGetWithCheckBase(v,typ,vb,len,GetBitsLen(len),endp,dowhat,radloadu32ptrBE)
492#define VarBitsLocalGetWithCheckLE(v,typ,vb,len,endp,dowhat) VarBitsLocalGetWithCheckBase(v,typ,vb,len,GetBitsLen(len),endp,dowhat,radloadu32ptr)
493
494// same as LocalGetWithCheck, but passing in the bit mask yourself
495#define VarBitsLocalGetWithCheckM(v,typ,vb,len,mask,endp,dowhat) VarBitsLocalGetWithCheckBase(v,typ,vb,len,mask,endp,dowhat,radloadbitsnative)
496#define VarBitsLocalGetWithCheckMBE(v,typ,vb,len,mask,endp,dowhat) VarBitsLocalGetWithCheckBase(v,typ,vb,len,mask,endp,dowhat,radloadu32ptrBE)
497#define VarBitsLocalGetWithCheckMLE(v,typ,vb,len,mask,endp,dowhat) VarBitsLocalGetWithCheckBase(v,typ,vb,len,mask,endp,dowhat,radloadu32ptr)
498
499// just the refill for a VarBitsLocalGet1WithCheck, and with an extra conditional
500// this turns out to be really useful to have in Bink Audio.
501#define VarBitsLocalFill1WithCheckBase(vb,endp,cond,dowhat,load)\
502{ \
503 if ((vb##bitlen)==0 && (cond)) { \
504 if ( ( (U8*)(vb##cur) ) >= ( (U8*) (endp) ) ) dowhat \
505 (vb##bits)=load(vb##cur); \
506 (vb##cur)=((char*)(vb##cur))+BITSTYPEBYTES; \
507 (vb##bitlen)=(BITSTYPELEN); \
508 } \
509}
510
511#define VarBitsLocalGet1WithCheckBase(v,vb,endp,dowhat,load) \
512{ \
513 VarBitsLocalFill1WithCheckBase(vb,endp,1,dowhat,load) \
514 --(vb##bitlen); \
515 v=(vb##bits); \
516 (vb##bits)>>=1; \
517 v&=1; \
518}
519
520#define VarBitsLocalFill1WithCheck(vb,endp,cond,dowhat) VarBitsLocalFill1WithCheckBase(vb,endp,cond,dowhat,radloadbitsnative)
521#define VarBitsLocalFill1WithCheckBE(vb,endp,cond,dowhat) VarBitsLocalFill1WithCheckBase(vb,endp,cond,dowhat,radloadu32ptrBE)
522#define VarBitsLocalFill1WithCheckLE(vb,endp,cond,dowhat) VarBitsLocalFill1WithCheckBase(vb,endp,cond,dowhat,radloadu32ptr)
523
524#define VarBitsLocalGet1WithCheck(v,vb,endp,dowhat) VarBitsLocalGet1WithCheckBase(v,vb,endp,dowhat,radloadbitsnative)
525#define VarBitsLocalGet1WithCheckBE(v,vb,endp,dowhat) VarBitsLocalGet1WithCheckBase(v,vb,endp,dowhat,radloadu32ptrBE)
526#define VarBitsLocalGet1WithCheckLE(v,vb,endp,dowhat) VarBitsLocalGet1WithCheckBase(v,vb,endp,dowhat,radloadu32ptr)
527
528
529// get the value, if the next bit is X (mask bits with mask)
530// usually, you will use the two wrapper macros below
531
532#define VarBitsLocalGetIfxSM(v,typ,vb,len,i,x,mask) \
533 (vb##bitlen==0)? \
534 ( \
535 i=*((BITSTYPE* RADRESTRICT)(vb##cur)), \
536 (vb##cur)=((char*)(vb##cur))+BITSTYPEBYTES, \
537 ( ( i & 1 ) == x ) ? \
538 ( \
539 v = (typ)( ( i >> 1 ) mask ), \
540 (vb##bits)=((BITSTYPE)i)>>(len+1), \
541 (vb##bitlen)=(BITSTYPELEN - 1 - len), \
542 x \
543 ):( \
544 (vb##bits)=(((BITSTYPE)i)>>1), \
545 (vb##bitlen)=(BITSTYPELEN-1), \
546 !x \
547 ) \
548 ):( \
549 --(vb##bitlen), \
550 ( ( (vb##bits) & 1 ) == x ) ? \
551 ( \
552 ( ( vb##bitlen ) < len )? \
553 ( \
554 i=*((BITSTYPE* RADRESTRICT)(vb##cur)), \
555 (vb##cur)=(((char*)(vb##cur))+BITSTYPEBYTES ), \
556 v=(typ)(((vb##bits>>1)|(i<<vb##bitlen)) mask ), \
557 (vb##bits)=(i>>((len)-vb##bitlen)), \
558 (vb##bitlen)=((vb##bitlen)+BITSTYPELEN-(len)), \
559 x \
560 ):( \
561 v = (typ) ( ( (vb##bits) >> 1 ) mask ), \
562 (vb##bits)>>=(len+1), \
563 (vb##bitlen)-=len, \
564 x \
565 ) \
566 ):( \
567 (vb##bits)>>=1, \
568 !x \
569 ) \
570 ) \
571
572
573// get the value, if the next bit is x (0 or 1)
574
575#define VarBitsLocalGetIfx(v,typ,vb,len,i,x) \
576 VarBitsLocalGetIfxSM(v,typ,vb,len,i,x,&GetBitLen(len))
577
578// get the value, if the next bit is x (0 or 1), but don't
579// mask off the high bits of the value
580
581#define VarBitsLocalGetIfxNM(v,typ,vb,len,i,x) \
582 VarBitsLocalGetIfxSM(v,typ,vb,len,i,x, )
583
584
585#define VarBitsLocalPeek(v,typ,vb,len) \
586{ \
587 if ((vb##bitlen)<(len)) { \
588 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)(vb##cur)); \
589 v=(typ)(((vb##bits)|(nb<<(vb##bitlen)))&GetBitsLen(len)); \
590 } else { \
591 v=(typ)((vb##bits)&GetBitsLen(len)); \
592 } \
593}
594
595#define VarBitsLocalGet1BE(vb,i) \
596( \
597 (vb##bitlen==0)? \
598 ( \
599 i=radloadu32ptrBE(vb##cur), \
600 (vb##cur)=((char*)(vb##cur))+BITSTYPEBYTES, \
601 (vb##bits)=((BITSTYPE)i)>>1, \
602 (vb##bitlen)=(BITSTYPELEN-1) \
603 ):( \
604 i=(vb##bits), \
605 (vb##bits)>>=1, \
606 --(vb##bitlen) \
607 ),(i&1) \
608)
609
610#define VarBitsLocalGet1LE(vb,i) \
611( \
612 (vb##bitlen==0)? \
613 ( \
614 i=radloadu32ptr(vb##cur), \
615 (vb##cur)=((char*)(vb##cur))+BITSTYPEBYTES, \
616 (vb##bits)=((BITSTYPE)i)>>1, \
617 (vb##bitlen)=(BITSTYPELEN-1) \
618 ):( \
619 i=(vb##bits), \
620 (vb##bits)>>=1, \
621 --(vb##bitlen) \
622 ),(i&1) \
623)
624
625// if imask is -1, then read a bit and then &-it with input mask
626// so now you have a mask that you can (v^m)-m to neg a value
627#define VarBitsLocalMaskFromMaskAndUse1(omask,vb,imask) \
628 if (vb##bitlen==0) \
629 { \
630 (vb##bits)=*((BITSTYPE* RADRESTRICT)(vb##cur)); \
631 (vb##bitlen)=BITSTYPELEN; \
632 (vb##cur)=((char*)(vb##cur))+BITSTYPEBYTES; \
633 } \
634 (vb##bitlen)+=imask; \
635 omask=(((S32)(vb##bits)<<31)>>31)&imask; \
636 (vb##bits)=((vb##bits>>1)&imask)|(vb##bits&~imask); \
637
638#ifdef __RAD64REGS__
639
640#define VarBitsLocalGet1(vb,i) \
641( \
642 ((vb##bitlen==0)? \
643 ( \
644 (vb##bits)=*((BITSTYPE* RADRESTRICT)(vb##cur)), \
645 (vb##cur)=((char*)(vb##cur))+4, \
646 (vb##bitlen)=32 \
647 ):0), \
648 ( \
649 i=(vb##bits)&1, \
650 (vb##bits)>>=1, \
651 --(vb##bitlen) \
652 ),(i) \
653)
654
655#else
656
657#define VarBitsLocalGet1(vb,i) \
658( \
659 (vb##bitlen==0)? \
660 ( \
661 i=*((BITSTYPE* RADRESTRICT)(vb##cur)), \
662 (vb##cur)=((char*)(vb##cur))+BITSTYPEBYTES, \
663 (vb##bits)=((BITSTYPE)i)>>1, \
664 (vb##bitlen)=(BITSTYPELEN-1) \
665 ):( \
666 i=(vb##bits), \
667 (vb##bits)>>=1, \
668 --(vb##bitlen) \
669 ),(i&1) \
670)
671
672#endif
673
674#define VarBitsLocalUse(vb,len) \
675{ \
676 if ((vb##bitlen)<(len)) { \
677 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)(vb##cur)); \
678 (vb##bits)=nb>>((len)-(vb##bitlen)); \
679 (vb##bitlen)=(vb##bitlen)+BITSTYPELEN-(len); \
680 (vb##cur)=((char*)(vb##cur))+BITSTYPEBYTES; \
681 } else { \
682 (vb##bits)>>=(len); \
683 (vb##bitlen)-=(len); \
684 } \
685}
686
687#define VarBitsLocalPos(vb,origvb) ((U32)( (((char*)vb##cur)-((char*)(origvb)->init))*8 +(32-vb##bitlen) )) // in bits !!
688
689
690
691#define VarBitsCopyToLocal( local, vb ) local##cur = (vb).cur; local##bits = (vb).bits; local##bitlen = (vb).bitlen;
692
693#define VarBitsCopyFromLocal( vb, local ) (vb).cur = local##cur; (vb).bits = local##bits; (vb).bitlen = local##bitlen;
694
695
696
697
698// classifies a signed value into: 0 = zero, 1 = neg, 2 = pos
699#define CLASSIFY_SIGN( val ) ( (((U32)((S32)(val))) >> 31 ) + ((((U32)(-(S32)(val))) >> 30 ) & 2 ) )
700
701//=========================================================================================================
702
703// VARBITSB = backward !
704//
705// CB : these *do* work with len == 0 , VarBits does not
706
707typedef struct _VARBITSB
708{
713 int isPut; // CB maybe temp ; help me find bugs
715
716#define VarBitsBPutOpen(vb,ptr) { (vb).cur=(vb).init=(void *)(ptr); (vb).bits=(vb).bitlen=0; (vb).isPut = 1; }
717#define VarBitsBGetOpen(vb,ptr) { (vb).cur=(vb).init=(void *)(ptr); (vb).bits=(vb).bitlen=0; (vb).isPut = 0; }
718
719// __v=(val)&VarBitsLens[__s]
720#define VarBitsBPut(vb,val,size) do { U32 __s=size; U32 __v=(val); \
721 radassert( __v < (1UL<<__s) ); \
722if ((vb).bitlen+__s >=BITSTYPELEN) { U32 __r = __s + (vb).bitlen - BITSTYPELEN; \
723 (vb).bits <<= (BITSTYPELEN-(vb).bitlen); (vb).bits |= __v >> __r; \
724 *((U32*)(vb).cur)=(vb).bits; (vb).cur=((char*)((vb).cur)+4); \
725(vb).bitlen = __r; (vb).bits = __v&VarBitsLens[__r]; } \
726else { (vb).bits = ((vb).bits<<__s) | __v; (vb).bitlen+=__s; } } while(0)
727
728#define VarBitsBPuta1(vb) { (vb).bits = (vb).bits + (vb).bits + 1; if ((++(vb).bitlen)==BITSTYPELEN) { *((U32*)(vb).cur)=(vb).bits; (vb).cur=((char*)((vb).cur)+4); (vb).bits=(vb).bitlen=0; } }
729#define VarBitsBPuta0(vb) { (vb).bits <<= 1; if ((++(vb).bitlen)==BITSTYPELEN) { *((U32*)(vb).cur)=(vb).bits; (vb).cur=((char*)((vb).cur)+4); (vb).bits=(vb).bitlen=0; } }
730#define VarBitsBPut1(vb,bit) { (vb).bits = (vb).bits + (vb).bits + ((bit)?1:0); if ((++(vb).bitlen)==BITSTYPELEN) { *((U32*)(vb).cur)=(vb).bits; (vb).cur=((char*)((vb).cur)+4); (vb).bits=(vb).bitlen=0; } }
731
732#define VarBitsBPutAlign(vb) { U32 __s2=(32-(vb).bitlen)&31; if (__s2) { VarBitsBPut((vb),0,__s2); } }
733#define VarBitsBPutFlush(vb) VarBitsBPutAlign(vb)
734#define VarBitsBGetAlign(vb) { (vb).bitlen=0; }
735#define VarBitsBPutSize(vb) ((U32)( (((char*)(vb).cur)-((char*)(vb).init))*8 +(vb).bitlen )) // in bits !!
736#define VarBitsBGetSize(vb) ((U32)( (((char*)(vb).cur)-((char*)(vb).init))*8 -(vb).bitlen )) // in bits !!
737
738// CB : stupid & with VarBitsLens just for len = 0 !
739// this is because >>32 = NOP !! (on x86 anyway)
740#define VarBitsBGet(v,typ,vb,len) \
741{ \
742 if (((vb).bitlen)<(len)) { \
743 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)((vb).cur)); \
744 v=(typ)((((vb).bits)|(nb>>((vb).bitlen)))>>(BITSTYPELEN-len));\
745 ((vb).bits)=nb<<((len)-((vb).bitlen)); \
746 ((vb).bitlen)=((vb).bitlen)+BITSTYPELEN-(len); \
747 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES; \
748 } else { \
749 v=(typ)(((vb).bits)>>(BITSTYPELEN-len)); \
750 ((vb).bits)<<=(len); \
751 ((vb).bitlen)-=(len); \
752 v &= (len)?0xffffffff:0; \
753 } \
754}
755
756#define VarBitsBPeek(v,typ,vb,len) \
757{ \
758 if (((vb).bitlen)<(len)) { \
759 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)((vb).cur)); \
760 v=(typ)((((vb).bits)|(nb>>((vb).bitlen)))>>(BITSTYPELEN-len));\
761 } else { \
762 v=(typ)(((vb).bits)>>(BITSTYPELEN-len)); \
763 } \
764}
765
766#define VarBitsBUse(vb,len) \
767{ \
768 if (((vb).bitlen)<(len)) { \
769 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)((vb).cur)); \
770 ((vb).bits)=nb<<((len)-((vb).bitlen)); \
771 ((vb).bitlen)=((vb).bitlen)+BITSTYPELEN-(len); \
772 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES; \
773 } else { \
774 ((vb).bits)<<=(len); \
775 ((vb).bitlen)-=(len); \
776 } \
777}
778
779// get 1 bit
780// best to use like : if ( VarBitsGet1(vb,i) )
781// or bit = VarBitsGet1(vb,temp);
782// WARNING : CB: i is NOT masked by &1 in this function, you must do it yourself !
783// 'temp_u32' MUST be a U32 !!
784#define VarBitsBGet1(vb,temp_u32) \
785( \
786 ((vb).bitlen==0)? \
787 ( \
788 temp_u32=*((BITSTYPE* RADRESTRICT)((vb).cur)),\
789 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES, \
790 ((vb).bits)=((BITSTYPE)temp_u32)<<1, \
791 ((vb).bitlen)=(BITSTYPELEN-1) \
792 ):( \
793 temp_u32=((vb).bits), \
794 ((vb).bits)<<=1, \
795 --((vb).bitlen) \
796 ), \
797 (temp_u32>>(BITSTYPELEN-1)) \
798)
799
800
801
802//*
803#ifdef __RADX86__
804#ifdef _DEBUG
805#ifdef __cplusplus
806
807inline void _VarBitsBGet(U32 & v,VARBITSB & vb,int len)
808{
809 radassert( ! vb.isPut );
810
811 if ( (int)((vb).bitlen) < (len))
812 {
813 register BITSTYPE nb=*((BITSTYPE* RADRESTRICT)((vb).cur));
814 v=((((vb).bits)|(nb>>((vb).bitlen)))>>(BITSTYPELEN-len));
815 ((vb).bits)=nb<<((len)-((vb).bitlen));
816 ((vb).bitlen)=((vb).bitlen)+BITSTYPELEN-(len);
817 ((vb).cur)=((char*)((vb).cur))+BITSTYPEBYTES;
818 v &= VarBitsLens[len];
819 }
820 else
821 {
822 int shift = BITSTYPELEN - len;
823 v=(((vb).bits)>>shift);
824 ((vb).bits)<<=(len);
825 ((vb).bitlen)-=(len);
826 v &= VarBitsLens[len];
827 }
828}
829
830#undef VarBitsBGet
831#define VarBitsBGet(v,typ,vb,len) _VarBitsBGet((U32 &)v,vb,len)
832
833
834// __v=(val)&VarBitsLens[__s]
835inline void _VarBitsBPut(VARBITSB & vb,U32 val,int size)
836{
837 radassert( vb.isPut );
838
839 S32 __s=size;
840 U32 __v=(val);
841 radassert( __v < (1UL<<__s) );
842
843 if ((vb).bitlen+__s >=BITSTYPELEN)
844 {
845 S32 __r = __s + (vb).bitlen - BITSTYPELEN;
846 radassert( __r >= 0 && __r < 32 );
847 radassert( (vb).bitlen != 0 );
848 (vb).bits <<= (BITSTYPELEN-(vb).bitlen);
849 (vb).bits |= __v >> __r;
850 *((U32*)(vb).cur)=(vb).bits;
851 (vb).cur=((char*)((vb).cur)+4);
852 (vb).bitlen = __r;
853 (vb).bits = __v&VarBitsLens[__r];
854 }
855 else
856 {
857 radassert( __s < 32 );
858 (vb).bits = ((vb).bits<<__s) | __v;
859 (vb).bitlen+=__s;
860 }
861}
862
863#undef VarBitsBPut
864#define VarBitsBPut(vb,val,size) _VarBitsBPut(vb,val,size)
865
866#endif // cplusplus
867#endif // _DEBUG
868#endif // __RADX86__
869
870
871
872#endif
#define RADDEFEND
Definition egttypes.h:68
RAD_U32 U32
Definition egttypes.h:501
#define RADRESTRICT
Definition egttypes.h:282
#define RADDEFSTART
Definition egttypes.h:67
#define RADDEFFUNC
Definition egttypes.h:66
RAD_S32 S32
Definition egttypes.h:496
#define RADINLINE
Definition egttypes.h:387
#define RADDECLAREDATA
Definition rrCore.h:674
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
float shift(float inValue, float expShift)
Definition RenderCore.cpp:859
char * dest
Definition lz4.h:709
float v
Definition radaudio_mdct.cpp:62
U16 Index
Definition radfft.cpp:71
Definition varbits.h:708
U32 bitlen
Definition varbits.h:711
BITSTYPE bits
Definition varbits.h:709
int isPut
Definition varbits.h:713
void *RADRESTRICT init
Definition varbits.h:712
void *RADRESTRICT cur
Definition varbits.h:710
Definition varbits.h:69
void *RADRESTRICT end
Definition varbits.h:74
BITSTYPE bits
Definition varbits.h:70
U32 bitlen
Definition varbits.h:72
void *RADRESTRICT init
Definition varbits.h:73
void *RADRESTRICT cur
Definition varbits.h:71
Definition varbits.h:58
void *RADRESTRICT init
Definition varbits.h:62
void *RADRESTRICT cur
Definition varbits.h:60
BITSTYPE bits
Definition varbits.h:59
U32 bitlen
Definition varbits.h:61
#define BITSTYPE
Definition varbits.h:45
struct _VARBITSEND VARBITSEND
struct _VARBITS VARBITS
struct _VARBITSB VARBITSB
#define BITSTYPEBYTES
Definition varbits.h:47
RADDECLAREDATA const RAD_ALIGN(U32, VarBitsLens[33], 32)
#define BITSTYPELEN
Definition varbits.h:46
RADDEFFUNC void VarBitsCopy(VARBITS *dest, VARBITS *src, U32 size)
Definition varbits.c:19