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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
#include <algorithm>
#include <fstream>
#include <vector>
class outBitFile {
public:
outBitFile(const char* filename): outcnt(0), outfile(filename, std::ios::binary) {}
~outBitFile() { putbuf(); }
void putbits(unsigned int data, unsigned int n) {
unsigned int mask = 1 << (n-1);
for( unsigned int i = 0 ; i < n; i++) {
outbuf <<= 1;
if (data & mask) outbuf |= 1;
mask >>= 1;
outcnt++;
if (outcnt == 8) {
outfile.put(outbuf);
outcnt = 0;
}
}
}
void putbuf() {
if (outcnt > 0) putbits(0, 8-outcnt);
}
void put_dcs_y(int len) {
switch (len) {
case 0: putbits(4,3); break;
case 1: putbits(0,2); break;
case 2: putbits(1,2); break;
case 3: putbits(5,3); break;
case 4: putbits(6,3); break;
case 5: putbits(14,4); break;
case 6: putbits(30,5); break;
case 7: putbits(62,6); break;
case 8: putbits(126,7); break;
case 9: putbits(254,8); break;
case 10: putbits(510,9); break;
case 11: putbits(511,9); break;
}
}
void put_dcs_c(int len) {
switch (len) {
case 0: putbits(0,2); break;
case 1: putbits(1,2); break;
case 2: putbits(2,2); break;
case 3: putbits(6,3); break;
case 4: putbits(14,4); break;
case 5: putbits(30,5); break;
case 6: putbits(62,6); break;
case 7: putbits(126,7); break;
case 8: putbits(254,8); break;
case 9: putbits(510,9); break;
case 10: putbits(1022,10); break;
case 11: putbits(1023,10); break;
}
}
private:
int outcnt;
std::ofstream outfile;
unsigned char outbuf;
std::vector<char> outdata;
};
#define BUFFER_SIZE 4096
#define START_CODE 0x000001
#define BYTE_ALIGN 0x80
#define BYTE_START 0x80
class inBitFile {
public:
inBitFile(std::vector<char> const& data): indata(data) {
wdMask = BYTE_START;
wdIndex = 0;
}
void setpos(long int byte, unsigned int bit) {
wdIndex = byte;
wdMask = BYTE_START;
get(bit);
}
void getpos( long int *byte, unsigned int *bit) {
unsigned wdMaskSave = wdMask;
unsigned count;
for(count = 0; wdMaskSave != 0x80; count++) wdMaskSave <<= 1;
*bit = count; // 0x80=0,0x40=1,0x20=2 usw
*byte = wdIndex;
}
int get(int num_bits) {
unsigned int buf;
if (!get_bits(&buf, num_bits)) return 0;
return buf;
}
int next_start_code() {
unsigned int buf;
/* locate next start code */
if (wdMask != BYTE_ALIGN) {
/* not byte aligned */
/* skip stuffed zero bits */
wdMask = BYTE_ALIGN;
wdIndex++;
}
if (!next_bits(&buf, 24)) return 0; /* end of bitstream */
while (buf != START_CODE) {
if (!get_bits(&buf, 8)) return 0;/* zero byte */
if (!next_bits(&buf, 24)) return 0;
}
return 1;
}
int get_dcs_y() {
int bits;
if(!(bits = get(2))) return 1; // 00
if(bits == 1) return 2; // 01
bits <<= 1;
bits |= get(1);
if(bits == 4) return 0; // 100
if(bits == 5) return 3; // 101
if(bits == 6) return 4; // 110
if(!get(1)) return 5;
if(!get(1)) return 6;
if(!get(1)) return 7;
if(!get(1)) return 8;
if(!get(1)) return 9;
if(!get(1)) return 10;
return 11;
}
int get_dcs_c() {
int bits;
if(!(bits = get(2))) return 0; // 00
if(bits == 1) return 1; // 01
if(bits == 2) return 2; // 10
if(!get(1)) return 3;
if(!get(1)) return 4;
if(!get(1)) return 5;
if(!get(1)) return 6;
if(!get(1)) return 7;
if(!get(1)) return 8;
if(!get(1)) return 9;
if(!get(1)) return 10;
return 11;
}
private:
int get_bits(unsigned int *destBuf, unsigned int num_bits) {
*destBuf = 0;
for (unsigned int index = 0; index < num_bits; ++index) {
if (wdIndex >= indata.size()) return 0;
/* get next bit */
*destBuf <<= 1;
if (indata[wdIndex] & wdMask) *destBuf |= 1;
/* update bit pointer */
if (wdMask > 1) wdMask >>= 1;
else {
wdIndex++;
wdMask = BYTE_START;
}
}
return 1;
}
int next_bits(unsigned int *destBuf, int num_bits) {
/* save current buffer state */
unsigned wdMaskSave = wdMask;
unsigned wdIndexSave = wdIndex;
int ret = get_bits(destBuf, num_bits);
/* restore previous buffer state */
wdMask = wdMaskSave;
wdIndex = wdIndexSave;
return ret;
}
unsigned wdIndex;
unsigned wdMask;
std::vector<char> const& indata;
};
|