/
bitstream.cpp
147 lines (133 loc) · 3.55 KB
/
bitstream.cpp
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
/////////////////////////////////////////////////////////////////////////
//
// bitstream.cpp --a part of libdecodeqr
//
// Copyright(C) 2007 NISHI Takao <zophos@koka-in.org>
// JMA (Japan Medical Association)
// NaCl (Network Applied Communication Laboratory Ltd.)
//
// This is free software with ABSOLUTELY NO WARRANTY.
// You can redistribute and/or modify it under the terms of LGPL.
//
// $Id: bitstream.cpp 36 2007-02-21 23:22:03Z zophos $
//
#include "bitstream.h"
namespace Qr{
BitStream::BitStream()
{
this->data=NULL;
this->byte_size=0;
this->bit_size=0;
this->_pos=0;
}
BitStream::BitStream(void *src,int size)
{
this->byte_size=size;
this->bit_size=size<<3;
this->data=new unsigned char[size];
memcpy(this->data,src,size);
this->_pos=0;
}
BitStream::~BitStream()
{
if(this->data)
delete this->data;
}
bool BitStream::is_eod()
{
return(this->_pos>=this->bit_size);
}
int BitStream::position()
{
return(this->_pos);
}
int BitStream::seek(int pos)
{
this->_pos+=pos;
if(this->_pos<0)
this->_pos=0;
if(this->_pos>this->bit_size)
this->_pos=this->bit_size;
return(this->_pos);
}
void BitStream::rewind()
{
this->_pos=0;
}
unsigned char *BitStream::read(int read_bits)
{
int byte_size=(read_bits>>3)+(read_bits&0x07?1:0);
unsigned char *buf=new unsigned char[byte_size];
memset(buf,0,byte_size);
this->read(buf,byte_size,read_bits);
return(buf);
}
int BitStream::read(void *dst,int buf_size,int read_bits)
{
memset(dst,0,buf_size);
if(read_bits>(buf_size<<3))
read_bits=buf_size<<3;
int end_bit=this->_pos+read_bits-1;
if(end_bit>=this->bit_size){
end_bit=this->bit_size-1;
read_bits=this->bit_size-this->_pos;
}
int remain_bits=(end_bit+1)&0x07;
int offset=this->_pos>>3;
int read_bytes=(read_bits>>3)+(read_bits&0x07?1:0);
if(read_bytes<buf_size){
int diff=buf_size-read_bytes;
unsigned char *tmp=(unsigned char *)dst;
tmp+=diff;
dst=tmp;
}
if(remain_bits){
unsigned char *src=data+offset;
unsigned char *tmp=(unsigned char *)dst;
int i=0;
if(read_bytes==(end_bit>>3)-offset+1){
tmp++;
i++;
}
for(;i<read_bytes;i++,src++,tmp++){
*tmp=*src<<remain_bits;
}
remain_bits=8-remain_bits;
src=data+(end_bit>>3);
tmp--;
for(i=0;i<read_bytes;i++,src--,tmp--){
*tmp|=*src>>remain_bits;
}
}
else{
memcpy(dst,this->data+offset,read_bytes);
}
unsigned char mask=0xff;
switch(8-(read_bits&0x07)){
case 1:
mask=0x7f;
break;
case 2:
mask=0x3f;
break;
case 3:
mask=0x1f;
break;
case 4:
mask=0x0f;
break;
case 5:
mask=0x07;
break;
case 6:
mask=0x03;
break;
case 7:
mask=0x01;
break;
}
*((unsigned char *)dst)&=mask;
this->_pos+=read_bits;
return(read_bits);
}
}