-
Notifications
You must be signed in to change notification settings - Fork 0
/
BitUnpacker.c
70 lines (60 loc) · 2.65 KB
/
BitUnpacker.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
* Copyright Software Innovations
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define UINT_SIZE 32
#define UINT_MASK 0xFFFFFFFF
typedef unsigned int UInt;
typedef struct {
UInt curData;
UInt nextData;
int bitsLeft;
int validNext;
} BitUnpacker;
void buInit(BitUnpacker *bup) { // Base: 3, Surcharge: 0
bup->curData = 0x00000000; // Base: 3, Surcharge: 0
bup->bitsLeft = 0; // Base: 3, Surcharge: 0
bup->nextData = 0x00000000; // Base: 3, Surcharge: 0
bup->validNext = 1; // Base: 3, Surcharge: 0
}
void BuTakeData(BitUnpacker *bup, UInt data) { // Base: 4, Surcharge: 0
bup->nextData = data; // Base: 3, Surcharge: 0
}
int BuUnpack(BitUnpacker *bup, int size, UInt *out) {
int ret = 0;
int nsize = UINT_SIZE - size;
if (bup->validNext == 1) {
bup->curData = bup->nextData;
bup->nextData <<= bup->bitsLeft;
bup->validNext = 0;
}
if (bup->validNext == 2) {
*out = (bup->curData) | (bup->nextData >> (UINT_SIZE - bup->bitsLeft));
bup->validNext = 1;
ret = 1;
}
else if (bup->bitsLeft + size < UINT_SIZE) {
*out = bup->nextData >> nsize;
bup->bitsLeft += size;
bup->nextData <<= size;
bup->validNext = 0;
ret = 1;
}
else if (bup->bitsLeft + size > UINT_SIZE) {
bup->validNext = 2;
bup->bitsLeft = bup->bitsLeft + size - UINT_SIZE;
bup->curData = bup->nextData >> nsize;
ret = 0;
bup->validNext = 2;
}
else {
*out = bup->curData = bup->nextData >> nsize;
bup->nextData = 0;
ret = 1;
bup->validNext = 1;
bup->bitsLeft = 32;
}
return ret;
}