qrtools 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +6 -0
- data/Manifest.txt +65 -0
- data/README.txt +75 -0
- data/Rakefile +49 -0
- data/bin/qrdecode +14 -0
- data/ext/qrtools/Makefile.in +65 -0
- data/ext/qrtools/bitstream.cpp +147 -0
- data/ext/qrtools/bitstream.h +48 -0
- data/ext/qrtools/codedata.cpp +506 -0
- data/ext/qrtools/codedata.h +95 -0
- data/ext/qrtools/container.cpp +288 -0
- data/ext/qrtools/container.h +175 -0
- data/ext/qrtools/decodeqr.h +286 -0
- data/ext/qrtools/ecidecoder.cpp +341 -0
- data/ext/qrtools/ecidecoder.h +110 -0
- data/ext/qrtools/extconf.rb +24 -0
- data/ext/qrtools/formatinfo.cpp +195 -0
- data/ext/qrtools/formatinfo.h +113 -0
- data/ext/qrtools/galois.cpp +593 -0
- data/ext/qrtools/galois.h +134 -0
- data/ext/qrtools/imagereader.cpp +1099 -0
- data/ext/qrtools/imagereader.h +127 -0
- data/ext/qrtools/libdecodeqr.cpp +195 -0
- data/ext/qrtools/libdecodeqr.dep +80 -0
- data/ext/qrtools/libdecodeqr.dsp +160 -0
- data/ext/qrtools/libdecodeqr.dsw +29 -0
- data/ext/qrtools/libdecodeqr.mak +245 -0
- data/ext/qrtools/qrerror.h +40 -0
- data/ext/qrtools/qrtools.c +17 -0
- data/ext/qrtools/qrtools.h +21 -0
- data/ext/qrtools/qrtools_decoder.c +123 -0
- data/ext/qrtools/qrtools_decoder.h +10 -0
- data/ext/qrtools/qrtools_encoder.c +63 -0
- data/ext/qrtools/qrtools_encoder.h +10 -0
- data/ext/qrtools/qrtools_header.c +51 -0
- data/ext/qrtools/qrtools_header.h +10 -0
- data/ext/qrtools/qrtools_image.c +80 -0
- data/ext/qrtools/qrtools_image.h +11 -0
- data/ext/qrtools/qrtools_qrcode.c +36 -0
- data/ext/qrtools/qrtools_qrcode.h +10 -0
- data/ext/qrtools/qrtools_ui_camera.c +58 -0
- data/ext/qrtools/qrtools_ui_camera.h +10 -0
- data/ext/qrtools/qrtools_ui_window.c +40 -0
- data/ext/qrtools/qrtools_ui_window.h +10 -0
- data/ext/qrtools/qrtypes.h +42 -0
- data/ext/qrtools/version.h +42 -0
- data/lib/qrtools.rb +11 -0
- data/lib/qrtools/decoder.rb +17 -0
- data/lib/qrtools/encoder.rb +14 -0
- data/lib/qrtools/image.rb +43 -0
- data/lib/qrtools/qrcode.rb +54 -0
- data/lib/qrtools/ui/camera.rb +28 -0
- data/lib/qrtools/ui/window.rb +16 -0
- data/lib/qrtools/version.rb +3 -0
- data/qrtools.gemspec +38 -0
- data/test/assets/01-1.jpg +0 -0
- data/test/helper.rb +17 -0
- data/test/test_decoder.rb +67 -0
- data/test/test_encoder.rb +35 -0
- data/test/test_header.rb +14 -0
- data/test/test_image.rb +19 -0
- data/test/test_qrcode.rb +78 -0
- data/test/test_qrdecode.rb +0 -0
- data/test/ui/test_camera.rb +43 -0
- data/test/ui/test_window.rb +34 -0
- metadata +138 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
/////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// codedata.cpp --a part of libdecodeqr
|
|
4
|
+
//
|
|
5
|
+
// Copyright(C) 2007 NISHI Takao <zophos@koka-in.org>
|
|
6
|
+
// JMA (Japan Medical Association)
|
|
7
|
+
// NaCl (Network Applied Communication Laboratory Ltd.)
|
|
8
|
+
//
|
|
9
|
+
// This is free software with ABSOLUTELY NO WARRANTY.
|
|
10
|
+
// You can redistribute and/or modify it under the terms of LGPL.
|
|
11
|
+
//
|
|
12
|
+
// $Id: codedata.cpp 36 2007-02-21 23:22:03Z zophos $
|
|
13
|
+
//
|
|
14
|
+
#include "codedata.h"
|
|
15
|
+
|
|
16
|
+
namespace Qr{
|
|
17
|
+
|
|
18
|
+
/////////////////////////////////////////////////////////////////////////
|
|
19
|
+
//
|
|
20
|
+
// RS block structure table
|
|
21
|
+
// ( from JISX0510(2004) 8.5.1 Table.12-18 pp.30-36)
|
|
22
|
+
//
|
|
23
|
+
// [version][level]={
|
|
24
|
+
// Tw: total words,
|
|
25
|
+
// Sb: number of smaller RS blocks,
|
|
26
|
+
// Tcs: total codes in each smaller RS block,
|
|
27
|
+
// Dcs: data codes in each smaller RS block,
|
|
28
|
+
// Ec: error correctable words in each block
|
|
29
|
+
// }
|
|
30
|
+
//
|
|
31
|
+
// level M: 0
|
|
32
|
+
// L: 1
|
|
33
|
+
// H: 2
|
|
34
|
+
// Q: 3
|
|
35
|
+
//
|
|
36
|
+
// Tcl: total codes in each largerer RS block = Tcs + 1
|
|
37
|
+
// Dcs: data codes in each larger RS block = Dcs + 1
|
|
38
|
+
// Lb: Number of larger RS blocks = (Tw - Sb * Tcs) / Tcl
|
|
39
|
+
// Tb: Total RS Blocks = Sb + Lb
|
|
40
|
+
//
|
|
41
|
+
const static int RS_BLOCK_ALIGN[41][4][5]={
|
|
42
|
+
// version 0 (not exist, just a dummy)
|
|
43
|
+
{{0,0,0,0,0},{0,0,0,0,0},
|
|
44
|
+
{0,0,0,0,0},{0,0,0,0,0}},
|
|
45
|
+
|
|
46
|
+
// version 1
|
|
47
|
+
{{26,1,26,16,4},{26,1,26,19,2},
|
|
48
|
+
{26,1,26,9,8},{26,1,26,13,6}},
|
|
49
|
+
{{44,1,44,28,8},{44,1,44,34,4},
|
|
50
|
+
{44,1,44,16,14},{44,1,44,22,11}},
|
|
51
|
+
{{70,1,70,44,13},{70,1,70,55,7},
|
|
52
|
+
{70,2,35,13,11},{70,2,35,17,9}},
|
|
53
|
+
{{100,2,50,32,9},{100,1,100,80,10},
|
|
54
|
+
{100,4,25,9,8},{100,2,50,24,13}},
|
|
55
|
+
|
|
56
|
+
{{134,2,67,43,12},{134,1,134,108,13},
|
|
57
|
+
{134,2,33,11,11},{134,2,33,15,9}},
|
|
58
|
+
{{172,4,43,27,8},{172,2,86,68,9},
|
|
59
|
+
{172,4,43,15,14},{172,4,43,19,12}},
|
|
60
|
+
{{196,4,49,31,9},{196,2,98,78,10},
|
|
61
|
+
{196,4,39,13,13},{196,2,32,14,9}},
|
|
62
|
+
{{242,2,60,38,11},{242,2,121,97,12},
|
|
63
|
+
{242,4,40,14,13},{242,4,40,18,11}},
|
|
64
|
+
{{292,3,58,36,11},{292,2,146,116,15},
|
|
65
|
+
{292,4,36,12,12},{292,4,36,16,10}},
|
|
66
|
+
|
|
67
|
+
// version 10
|
|
68
|
+
{{346,4,69,43,13},{346,2,86,68,9},
|
|
69
|
+
{346,6,43,15,14},{346,6,43,19,12}},
|
|
70
|
+
{{404,1,80,50,15},{404,4,101,81,10},
|
|
71
|
+
{404,3,36,12,12},{404,4,50,22,14}},
|
|
72
|
+
{{466,6,58,36,11},{466,2,116,92,12},
|
|
73
|
+
{466,7,42,14,14},{466,4,46,20,14}},
|
|
74
|
+
{{532,8,59,37,11},{532,4,133,107,13},
|
|
75
|
+
{532,12,33,11,11},{532,8,44,20,12}},
|
|
76
|
+
{{581,5,65,41,12},{581,5,109,87,11},
|
|
77
|
+
{581,11,36,12,12},{581,5,54,24,15}},
|
|
78
|
+
|
|
79
|
+
{{655,5,65,41,12},{655,5,109,87,11},
|
|
80
|
+
{655,11,36,12,12},{655,5,54,24,15}},
|
|
81
|
+
{{733,7,73,45,14},{733,5,122,98,12},
|
|
82
|
+
{733,3,45,15,15},{733,15,43,19,12}},
|
|
83
|
+
{{815,10,74,46,14},{815,1,135,107,14},
|
|
84
|
+
{815,2,42,14,14},{815,1,50,22,14}},
|
|
85
|
+
{{901,9,69,43,13},{901,5,150,120,15},
|
|
86
|
+
{901,2,42,14,14},{901,17,50,22,14}},
|
|
87
|
+
{{991,3,70,44,13},{991,3,141,113,14},
|
|
88
|
+
{991,9,39,13,13},{991,17,47,21,13}},
|
|
89
|
+
|
|
90
|
+
// version 20
|
|
91
|
+
{{1085,3,67,41,13},{1085,3,135,107,14},
|
|
92
|
+
{1085,15,43,15,14},{1085,15,54,24,15}},
|
|
93
|
+
{{1156,17,68,42,13},{1156,4,144,116,14},
|
|
94
|
+
{1156,19,46,16,15},{1156,17,50,22,14}},
|
|
95
|
+
{{1258,17,74,46,14},{1258,2,139,111,14},
|
|
96
|
+
{1258,34,37,13,12},{1258,7,54,24,15}},
|
|
97
|
+
{{1364,4,75,47,14},{1364,4,151,121,15},
|
|
98
|
+
{1364,16,45,15,15},{1364,11,54,24,15}},
|
|
99
|
+
{{1474,6,73,45,14},{1474,6,147,117,15},
|
|
100
|
+
{1474,30,46,16,15},{1474,11,54,24,15}},
|
|
101
|
+
|
|
102
|
+
{{1588,8,75,47,14},{1588,8,132,106,13},
|
|
103
|
+
{1588,22,45,15,15},{1588,7,54,24,15}},
|
|
104
|
+
{{1706,19,74,46,14},{1706,10,142,114,14},
|
|
105
|
+
{1706,33,46,16,15},{1706,28,50,22,14}},
|
|
106
|
+
{{1828,22,73,45,14},{1828,8,152,122,15},
|
|
107
|
+
{1828,12,45,15,15},{1828,8,53,23,15}},
|
|
108
|
+
{{1921,3,73,45,14},{1921,3,147,117,15},
|
|
109
|
+
{1921,11,45,15,15},{1921,4,54,24,15}},
|
|
110
|
+
{{2051,21,73,45,14},{2051,7,146,116,15},
|
|
111
|
+
{2051,19,45,15,15},{2051,21,73,45,14}},
|
|
112
|
+
|
|
113
|
+
// version 30
|
|
114
|
+
{{2185,19,75,47,14},{2185,5,145,115,15},
|
|
115
|
+
{2185,23,45,15,15},{2185,15,54,24,15}},
|
|
116
|
+
{{2323,2,74,46,14},{2323,13,145,115,15},
|
|
117
|
+
{2323,23,45,15,15},{2323,42,54,24,15}},
|
|
118
|
+
{{2465,10,74,46,14},{2465,17,145,115,15},
|
|
119
|
+
{2465,19,45,15,15},{2465,10,54,24,15}},
|
|
120
|
+
{{2611,14,74,46,14},{2611,17,145,115,15},
|
|
121
|
+
{2611,11,45,15,15},{2611,29,54,24,15}},
|
|
122
|
+
{{2761,14,74,46,14},{2761,13,145,115,15},
|
|
123
|
+
{2761,46,16,15,},{2761,44,54,24,15}},
|
|
124
|
+
|
|
125
|
+
{{2876,12,75,47,14},{2876,12,151,121,15},
|
|
126
|
+
{2876,22,45,15,15},{2876,39,54,24,15}},
|
|
127
|
+
{{3034,6,75,47,14},{3034,6,151,121,15},
|
|
128
|
+
{3034,2,45,15,15},{3034,46,54,24,15}},
|
|
129
|
+
{{3196,29,74,46,14},{3196,17,152,122,15},
|
|
130
|
+
{3196,24,45,15,15},{3196,49,54,24,15}},
|
|
131
|
+
{{3362,13,74,46,14},{3362,4,152,122,15},
|
|
132
|
+
{3362,42,45,15,15},{3362,48,54,24,15}},
|
|
133
|
+
{{3532,40,75,47,14},{3532,20,147,117,15},
|
|
134
|
+
{3532,10,45,15,15},{3532,43,54,24,15}},
|
|
135
|
+
|
|
136
|
+
// version 40
|
|
137
|
+
{{3706,18,75,47,14},{3706,19,148,118,15},
|
|
138
|
+
{3706,20,45,15,15},{3706,34,54,24,15}}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/////////////////////////////////////////////////////////////////////////
|
|
142
|
+
//
|
|
143
|
+
//
|
|
144
|
+
//
|
|
145
|
+
CodeBlock::CodeBlock(int total_words,int data_words,int capability,
|
|
146
|
+
Galois::Field *gf)
|
|
147
|
+
{
|
|
148
|
+
this->total_words=total_words;
|
|
149
|
+
this->data_words=data_words;
|
|
150
|
+
this->capability=capability;
|
|
151
|
+
this->_gf=gf;
|
|
152
|
+
|
|
153
|
+
this->data=new unsigned char[this->total_words];
|
|
154
|
+
this->clear();
|
|
155
|
+
}
|
|
156
|
+
CodeBlock::~CodeBlock()
|
|
157
|
+
{
|
|
158
|
+
delete this->data;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
void CodeBlock::clear()
|
|
162
|
+
{
|
|
163
|
+
memset(this->data,0,this->total_words);
|
|
164
|
+
this->_size=0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
unsigned char *CodeBlock::push(unsigned char data)
|
|
168
|
+
{
|
|
169
|
+
if(this->_size>=this->total_words)
|
|
170
|
+
return(NULL);
|
|
171
|
+
|
|
172
|
+
this->data[this->_size]=data;
|
|
173
|
+
this->_size++;
|
|
174
|
+
return(&(this->data[this->_size-1]));
|
|
175
|
+
}
|
|
176
|
+
bool CodeBlock::has_vacant_data()
|
|
177
|
+
{
|
|
178
|
+
return(this->_size<this->data_words);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
int CodeBlock::error_correct()
|
|
182
|
+
{
|
|
183
|
+
Galois::BCH *bch=new Galois::BCH(this->_gf,
|
|
184
|
+
this->total_words,
|
|
185
|
+
this->capability);
|
|
186
|
+
|
|
187
|
+
int i,j;
|
|
188
|
+
for(i=this->total_words-1,j=0;i>=0;i--,j++){
|
|
189
|
+
bch->set(j,this->_gf->vect2nomial(this->data[i]));
|
|
190
|
+
}
|
|
191
|
+
int errors=bch->decode();
|
|
192
|
+
if(errors<=0){
|
|
193
|
+
delete bch;
|
|
194
|
+
return(errors);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
//
|
|
199
|
+
// get each error size
|
|
200
|
+
//
|
|
201
|
+
//
|
|
202
|
+
// JISX0510:2004 Appendix B (p.64) step c) makes us mistake.
|
|
203
|
+
//
|
|
204
|
+
// s(n): n.th digit of sent data on GF(2^8)
|
|
205
|
+
// r(n): n.th digit of received data on GF(2^8)
|
|
206
|
+
// e(n): n.th error data on GF(2^8)
|
|
207
|
+
//
|
|
208
|
+
// If there was 3 errors on 1st ,2nd ,and n.th digit, received
|
|
209
|
+
// data R can be express shown as below;
|
|
210
|
+
//
|
|
211
|
+
// R = ( r(0), r(1), r(2), ... r(n) )
|
|
212
|
+
// = ( s(0), s(1)+e(0), s(2)+e(1), ... s(n)+e(2) )
|
|
213
|
+
//
|
|
214
|
+
// Error syndromes ES(n) are;
|
|
215
|
+
//
|
|
216
|
+
// ES(0) = sum{r(i) * a(0*i)}
|
|
217
|
+
// = sum{s(i)} +e(0) +e(1) +e(2)
|
|
218
|
+
// = e(0) +e(1) +e(2)
|
|
219
|
+
// ES(1) = sum{r(i)*a(1*i)}
|
|
220
|
+
// = sum{s(i)*a(i)} +a(1)*e(0) +a(2)*e(1) +a(n)*e(2)
|
|
221
|
+
// = a(1)*e(0) +a(2)*e(1) +a(n)*e(2)
|
|
222
|
+
// :
|
|
223
|
+
//
|
|
224
|
+
// ES(x) = sum{r(i)*a(x*i)}
|
|
225
|
+
// = sum{s(i)*a(x*i)} +a(x)*e(0) +a(2*x)*e(1) +a(n*x)*e(2)
|
|
226
|
+
// = a(x)*e(0) +a(2*x)*e(1) +a(n*x)*e(2)
|
|
227
|
+
//
|
|
228
|
+
// where a(x) is primitive of GF(2^8)
|
|
229
|
+
//
|
|
230
|
+
// So, each error size e(n) can be taken following equatation;
|
|
231
|
+
//
|
|
232
|
+
// e(0) +e(1) +e(2) =ES(0)
|
|
233
|
+
// a(1)*e(0) +a(2)*e(1) +a(n)*e(2) =ES(1)
|
|
234
|
+
// a(2)*e(0) +a(4)*e(1) +a(2*n)*e(2) =ES(2)
|
|
235
|
+
//
|
|
236
|
+
Galois::Polynomial *mat=new Galois::Polynomial(errors,
|
|
237
|
+
errors+1);
|
|
238
|
+
for(j=0;j<errors;j++){
|
|
239
|
+
for(i=0;i<errors;i++){
|
|
240
|
+
mat->set(j,i,this->_gf->exp2nomial(j*bch->error_pos[i]));
|
|
241
|
+
}
|
|
242
|
+
mat->set(j,i,bch->syndromes[j]);
|
|
243
|
+
}
|
|
244
|
+
Galois::Polynomial *err=mat->solve();
|
|
245
|
+
|
|
246
|
+
if(err){
|
|
247
|
+
//
|
|
248
|
+
// correct received data
|
|
249
|
+
//
|
|
250
|
+
//
|
|
251
|
+
// s(n) = r(n) + e(n)
|
|
252
|
+
//
|
|
253
|
+
// s(n): n.th digit of send data on GF(2^8)
|
|
254
|
+
// r(n): n.th digit of recieved data on GF(2^8)
|
|
255
|
+
// e(n): error size of n.th digit on GF(2^8)
|
|
256
|
+
//
|
|
257
|
+
for(i=0;i<errors;i++){
|
|
258
|
+
int p=this->total_words-bch->error_pos[i]-1;
|
|
259
|
+
this->data[p]=(*this->_gf->vect2nomial(this->data[p])+
|
|
260
|
+
*err->get(i)).to_vect();
|
|
261
|
+
}
|
|
262
|
+
delete err;
|
|
263
|
+
}
|
|
264
|
+
else{
|
|
265
|
+
errors=-1;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
delete mat;
|
|
269
|
+
delete bch;
|
|
270
|
+
|
|
271
|
+
return(errors);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
/////////////////////////////////////////////////////////////////////////
|
|
276
|
+
//
|
|
277
|
+
//
|
|
278
|
+
//
|
|
279
|
+
CodeData::CodeData(int version,int level)
|
|
280
|
+
{
|
|
281
|
+
this->_gf=new Galois::Field(8);
|
|
282
|
+
|
|
283
|
+
this->version=version;
|
|
284
|
+
this->level=level;
|
|
285
|
+
|
|
286
|
+
this->total_words=RS_BLOCK_ALIGN[version][level][0];
|
|
287
|
+
int larger_block_words=RS_BLOCK_ALIGN[version][level][2]+1;
|
|
288
|
+
int larger_block_datas=RS_BLOCK_ALIGN[version][level][3]+1;
|
|
289
|
+
int larger_blocks=(this->total_words-
|
|
290
|
+
RS_BLOCK_ALIGN[version][level][1]*
|
|
291
|
+
RS_BLOCK_ALIGN[version][level][2]
|
|
292
|
+
)/larger_block_words;
|
|
293
|
+
|
|
294
|
+
this->data_blocks=RS_BLOCK_ALIGN[version][level][1]+larger_blocks;
|
|
295
|
+
|
|
296
|
+
this->data_words=RS_BLOCK_ALIGN[version][level][1]*
|
|
297
|
+
RS_BLOCK_ALIGN[version][level][3]+
|
|
298
|
+
larger_blocks*larger_block_datas;
|
|
299
|
+
|
|
300
|
+
this->data=new CodeBlock *[this->data_blocks];
|
|
301
|
+
|
|
302
|
+
int i;
|
|
303
|
+
for(i=0;i<RS_BLOCK_ALIGN[version][level][1];i++){
|
|
304
|
+
this->data[i]=new CodeBlock(
|
|
305
|
+
RS_BLOCK_ALIGN[version][level][2],
|
|
306
|
+
RS_BLOCK_ALIGN[version][level][3],
|
|
307
|
+
RS_BLOCK_ALIGN[version][level][4],
|
|
308
|
+
this->_gf);
|
|
309
|
+
}
|
|
310
|
+
for(i=RS_BLOCK_ALIGN[version][level][1];i<this->data_blocks;i++){
|
|
311
|
+
this->data[i]=new CodeBlock(
|
|
312
|
+
larger_block_words,
|
|
313
|
+
larger_block_datas,
|
|
314
|
+
RS_BLOCK_ALIGN[version][level][4],
|
|
315
|
+
this->_gf);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
this->length=0;
|
|
319
|
+
this->byte_length=0;
|
|
320
|
+
this->_raw_data=NULL;
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
this->_size=0;
|
|
324
|
+
this->_index=0;
|
|
325
|
+
|
|
326
|
+
this->status=0;
|
|
327
|
+
}
|
|
328
|
+
CodeData::~CodeData()
|
|
329
|
+
{
|
|
330
|
+
if(this->_raw_data)
|
|
331
|
+
delete this->_raw_data;
|
|
332
|
+
|
|
333
|
+
for(int i=0;i<this->data_blocks;i++){
|
|
334
|
+
delete this->data[i];
|
|
335
|
+
}
|
|
336
|
+
delete this->data;
|
|
337
|
+
delete this->_gf;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
void CodeData::clear()
|
|
341
|
+
{
|
|
342
|
+
for(int i=0;i<this->data_blocks;i++){
|
|
343
|
+
this->data[i]->clear();
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
this->length=0;
|
|
347
|
+
this->byte_length=0;
|
|
348
|
+
if(this->_raw_data){
|
|
349
|
+
delete this->_raw_data;
|
|
350
|
+
this->_raw_data=NULL;
|
|
351
|
+
}
|
|
352
|
+
this->_size=0;
|
|
353
|
+
this->_index=0;
|
|
354
|
+
|
|
355
|
+
this->status=0;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
unsigned char *CodeData::push(unsigned char data)
|
|
359
|
+
{
|
|
360
|
+
if(this->_size<this->data_words){
|
|
361
|
+
for(int i=0;i<this->data_blocks;i++){
|
|
362
|
+
this->_index=(this->_index+i)%this->data_blocks;
|
|
363
|
+
if(this->data[this->_index]->has_vacant_data()){
|
|
364
|
+
unsigned char *ret=this->data[this->_index]->push(data);
|
|
365
|
+
this->_size++;
|
|
366
|
+
this->_index++;
|
|
367
|
+
return(ret);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
throw;
|
|
371
|
+
}
|
|
372
|
+
else{
|
|
373
|
+
this->_index=this->_index%this->data_blocks;
|
|
374
|
+
unsigned char *ret=this->data[this->_index]->push(data);
|
|
375
|
+
this->_size++;
|
|
376
|
+
this->_index++;
|
|
377
|
+
return(ret);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
unsigned char *CodeData::dump()
|
|
382
|
+
{
|
|
383
|
+
unsigned char *buf=new unsigned char[this->total_words];
|
|
384
|
+
for(int i=0,j=0;i<data_blocks;i++){
|
|
385
|
+
memcpy(buf+j,this->data[i]->data,
|
|
386
|
+
this->data[i]->total_words);
|
|
387
|
+
j+=this->data[i]->total_words;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return(buf);
|
|
391
|
+
}
|
|
392
|
+
unsigned char *CodeData::dump_block(int index)
|
|
393
|
+
{
|
|
394
|
+
unsigned char *buf=new unsigned char[this->data[index]->total_words];
|
|
395
|
+
memcpy(buf,this->data[index]->data,
|
|
396
|
+
this->data[index]->total_words);
|
|
397
|
+
|
|
398
|
+
return(buf);
|
|
399
|
+
}
|
|
400
|
+
unsigned char *CodeData::dump_data()
|
|
401
|
+
{
|
|
402
|
+
unsigned char *buf=new unsigned char[this->data_words];
|
|
403
|
+
for(int i=0,j=0;i<data_blocks;i++){
|
|
404
|
+
memcpy(buf+j,this->data[i]->data,
|
|
405
|
+
this->data[i]->data_words);
|
|
406
|
+
j+=this->data[i]->data_words;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
return(buf);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
unsigned char *CodeData::raw_data()
|
|
413
|
+
{
|
|
414
|
+
return(this->_raw_data);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
int CodeData::decode()
|
|
418
|
+
{
|
|
419
|
+
if(this->_raw_data)
|
|
420
|
+
return(0);
|
|
421
|
+
|
|
422
|
+
int ret=this->_error_correct();
|
|
423
|
+
if(ret<0)
|
|
424
|
+
this->status|=QR_CODEDATA_UNRECOVERABLE;
|
|
425
|
+
|
|
426
|
+
unsigned char *tmp=this->dump_data();
|
|
427
|
+
BitStream *bitstream=new BitStream(tmp,this->data_words);
|
|
428
|
+
delete tmp;
|
|
429
|
+
|
|
430
|
+
unsigned char mode=0;
|
|
431
|
+
Qr::ECI::Decoder *decoder=NULL;
|
|
432
|
+
do{
|
|
433
|
+
bitstream->read(&mode,sizeof(mode),4);
|
|
434
|
+
switch(mode){
|
|
435
|
+
case 0: // end of data
|
|
436
|
+
decoder=NULL;
|
|
437
|
+
break;
|
|
438
|
+
case 1:
|
|
439
|
+
decoder=new Qr::ECI::NumericalDecoder();
|
|
440
|
+
break;
|
|
441
|
+
case 2: // arabic and numeric
|
|
442
|
+
decoder=new Qr::ECI::AlphabeticalDecoder();
|
|
443
|
+
break;
|
|
444
|
+
case 4: // 8-bit byte
|
|
445
|
+
decoder=new Qr::ECI::ByteDecoder();
|
|
446
|
+
break;
|
|
447
|
+
case 8: // kanji
|
|
448
|
+
decoder=new Qr::ECI::KanjiDecoder();
|
|
449
|
+
break;
|
|
450
|
+
case 7: // ECI
|
|
451
|
+
case 3: // joint
|
|
452
|
+
case 5: // FNC1 1st
|
|
453
|
+
case 9: // FNC1 2nd
|
|
454
|
+
default:
|
|
455
|
+
this->status|=QR_CODEDATA_NOT_SUPPORT_ECI;
|
|
456
|
+
decoder=NULL;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if(!decoder)
|
|
460
|
+
break;
|
|
461
|
+
|
|
462
|
+
int ret=decoder->decode(this->version,bitstream);
|
|
463
|
+
if(ret){
|
|
464
|
+
if(this->_raw_data){
|
|
465
|
+
unsigned char *buf=this->_raw_data;
|
|
466
|
+
int sz=this->byte_length+decoder->byte_length;
|
|
467
|
+
this->_raw_data=new unsigned char[sz];
|
|
468
|
+
memcpy(this->_raw_data,buf,this->byte_length);
|
|
469
|
+
delete buf;
|
|
470
|
+
memcpy(this->_raw_data+this->byte_length,
|
|
471
|
+
decoder->raw_data(),
|
|
472
|
+
decoder->byte_length);
|
|
473
|
+
}
|
|
474
|
+
else{
|
|
475
|
+
this->_raw_data=new unsigned char[decoder->byte_length];
|
|
476
|
+
memcpy(this->_raw_data,
|
|
477
|
+
decoder->raw_data(),
|
|
478
|
+
decoder->byte_length);
|
|
479
|
+
}
|
|
480
|
+
this->length+=decoder->length;
|
|
481
|
+
this->byte_length+=decoder->byte_length;
|
|
482
|
+
|
|
483
|
+
delete decoder;
|
|
484
|
+
}
|
|
485
|
+
}while(!bitstream->is_eod());
|
|
486
|
+
|
|
487
|
+
delete bitstream;
|
|
488
|
+
|
|
489
|
+
return(ret);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
int CodeData::_error_correct()
|
|
493
|
+
{
|
|
494
|
+
int ret=0;
|
|
495
|
+
for(int i=0;i<this->data_blocks;i++){
|
|
496
|
+
int c=this->data[i]->error_correct();
|
|
497
|
+
if(ret<0||c<0){
|
|
498
|
+
ret=-1;
|
|
499
|
+
}
|
|
500
|
+
else
|
|
501
|
+
ret+=c;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return(ret);
|
|
505
|
+
}
|
|
506
|
+
}
|