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,110 @@
|
|
|
1
|
+
/////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// ecidecoder.h --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: ecidecoder.h 36 2007-02-21 23:22:03Z zophos $
|
|
13
|
+
//
|
|
14
|
+
#ifndef __QR_ECI_DECODER__
|
|
15
|
+
#define __QR_ECI_DECODER__
|
|
16
|
+
|
|
17
|
+
#include <stdio.h>
|
|
18
|
+
|
|
19
|
+
#ifdef WIN32
|
|
20
|
+
#include <winsock2.h>
|
|
21
|
+
#define snprintf _snprintf
|
|
22
|
+
#else
|
|
23
|
+
#include <netinet/in.h>
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
#include "bitstream.h"
|
|
27
|
+
|
|
28
|
+
namespace Qr{
|
|
29
|
+
namespace ECI{
|
|
30
|
+
class Decoder{
|
|
31
|
+
public:
|
|
32
|
+
int mode;
|
|
33
|
+
int length;
|
|
34
|
+
int byte_length;
|
|
35
|
+
int eci_mode;
|
|
36
|
+
|
|
37
|
+
protected:
|
|
38
|
+
unsigned char *_raw_data;
|
|
39
|
+
int _bit_par_block;
|
|
40
|
+
int _char_par_block;
|
|
41
|
+
int _byte_par_char;
|
|
42
|
+
|
|
43
|
+
int _read_length;
|
|
44
|
+
int _written_length;
|
|
45
|
+
unsigned char *_current_pos;
|
|
46
|
+
|
|
47
|
+
public:
|
|
48
|
+
Decoder();
|
|
49
|
+
~Decoder();
|
|
50
|
+
|
|
51
|
+
unsigned char *raw_data();
|
|
52
|
+
virtual int decode(int version,BitStream *bitstream);
|
|
53
|
+
|
|
54
|
+
private:
|
|
55
|
+
virtual int _read_header(int version,BitStream *bitstream);
|
|
56
|
+
virtual int _get_charactor_count(int version)=0;
|
|
57
|
+
virtual int _read_data(BitStream *bitstream);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
class NumericalDecoder :public Decoder{
|
|
61
|
+
private:
|
|
62
|
+
short _read_buf;
|
|
63
|
+
public:
|
|
64
|
+
NumericalDecoder();
|
|
65
|
+
private:
|
|
66
|
+
virtual int _get_charactor_count(int version);
|
|
67
|
+
virtual int _read_data(BitStream *bitstream);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
class AlphabeticalDecoder :public Decoder{
|
|
71
|
+
private:
|
|
72
|
+
short _read_buf;
|
|
73
|
+
public:
|
|
74
|
+
AlphabeticalDecoder();
|
|
75
|
+
private:
|
|
76
|
+
virtual int _get_charactor_count(int version);
|
|
77
|
+
virtual int _read_data(BitStream *bitstream);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
class ByteDecoder :public Decoder{
|
|
81
|
+
private:
|
|
82
|
+
char _read_buf;
|
|
83
|
+
public:
|
|
84
|
+
ByteDecoder();
|
|
85
|
+
private:
|
|
86
|
+
virtual int _get_charactor_count(int version);
|
|
87
|
+
virtual int _read_data(BitStream *bitstream);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
class GenericDecoder :public Decoder{
|
|
91
|
+
public:
|
|
92
|
+
GenericDecoder();
|
|
93
|
+
private:
|
|
94
|
+
virtual int _get_charactor_count(int version);
|
|
95
|
+
virtual int _read_data(BitStream *bitstream);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
class KanjiDecoder :public Decoder{
|
|
99
|
+
private:
|
|
100
|
+
short _read_buf;
|
|
101
|
+
public:
|
|
102
|
+
KanjiDecoder();
|
|
103
|
+
private:
|
|
104
|
+
virtual int _get_charactor_count(int version);
|
|
105
|
+
virtual int _read_data(BitStream *bitstream);
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
#endif
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
ENV["ARCHFLAGS"] = "-arch #{`uname -p` =~ /powerpc/ ? 'ppc' : 'i386'}"
|
|
2
|
+
|
|
3
|
+
require 'mkmf'
|
|
4
|
+
|
|
5
|
+
LIBDIR = Config::CONFIG['libdir']
|
|
6
|
+
INCLUDEDIR = Config::CONFIG['includedir']
|
|
7
|
+
|
|
8
|
+
HEADER_DIRS = [
|
|
9
|
+
'/opt/local/include/opencv',
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
LIB_DIRS = [
|
|
13
|
+
LIBDIR,
|
|
14
|
+
'/opt/local/lib',
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
dir_config('opencv', "/opt/local/include/opencv", "/opt/local/lib")
|
|
18
|
+
dir_config('qrencode', "/opt/local/include", "/opt/local/lib")
|
|
19
|
+
%w{ qrencode cxcore cv highgui }.each do |lib|
|
|
20
|
+
abort "need #{lib}" unless have_library(lib)
|
|
21
|
+
end
|
|
22
|
+
find_header('qrencode.h')
|
|
23
|
+
have_library('stdc++')
|
|
24
|
+
create_makefile('qrtools')
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// formatinfo.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: formatinfo.cpp 36 2007-02-21 23:22:03Z zophos $
|
|
13
|
+
//
|
|
14
|
+
#include "formatinfo.h"
|
|
15
|
+
|
|
16
|
+
namespace Qr{
|
|
17
|
+
unsigned char MaskPatterner000::pixel(int i,int j)
|
|
18
|
+
{
|
|
19
|
+
return((i+j)%2?0:255);
|
|
20
|
+
}
|
|
21
|
+
unsigned char MaskPatterner001::pixel(int i,int j)
|
|
22
|
+
{
|
|
23
|
+
return(i%2?0:255);
|
|
24
|
+
}
|
|
25
|
+
unsigned char MaskPatterner010::pixel(int i,int j)
|
|
26
|
+
{
|
|
27
|
+
return(j%3?0:255);
|
|
28
|
+
}
|
|
29
|
+
unsigned char MaskPatterner011::pixel(int i,int j)
|
|
30
|
+
{
|
|
31
|
+
return((i+j)%3?0:255);
|
|
32
|
+
}
|
|
33
|
+
unsigned char MaskPatterner100::pixel(int i,int j)
|
|
34
|
+
{
|
|
35
|
+
return((i/2+j/3)%2?0:255);
|
|
36
|
+
}
|
|
37
|
+
unsigned char MaskPatterner101::pixel(int i,int j)
|
|
38
|
+
{
|
|
39
|
+
return(((i*j)%2)+((i*j)%3)?0:255);
|
|
40
|
+
}
|
|
41
|
+
unsigned char MaskPatterner110::pixel(int i,int j)
|
|
42
|
+
{
|
|
43
|
+
return((((i*j)%2)+((i*j)%3))%2?0:255);
|
|
44
|
+
}
|
|
45
|
+
unsigned char MaskPatterner111::pixel(int i,int j)
|
|
46
|
+
{
|
|
47
|
+
return((((i*j)%3)+((i*j)%2))%2?0:255);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
FormatInfo::FormatInfo()
|
|
51
|
+
{
|
|
52
|
+
this->level=0;
|
|
53
|
+
this->mask_pattern=0;
|
|
54
|
+
this->status=0;
|
|
55
|
+
|
|
56
|
+
this->_patterner=NULL;
|
|
57
|
+
}
|
|
58
|
+
FormatInfo::~FormatInfo()
|
|
59
|
+
{
|
|
60
|
+
if(this->_patterner)
|
|
61
|
+
delete this->_patterner;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
int FormatInfo::set_level(int l)
|
|
65
|
+
{
|
|
66
|
+
this->level=l;
|
|
67
|
+
if(l<0||l>3){
|
|
68
|
+
this->status|=QR_FORMATINFO_INVALID_LEVEL;
|
|
69
|
+
this->level=0;
|
|
70
|
+
}
|
|
71
|
+
return(this->level);
|
|
72
|
+
}
|
|
73
|
+
int FormatInfo::set_mask_pattern(int m)
|
|
74
|
+
{
|
|
75
|
+
if(this->_patterner)
|
|
76
|
+
delete this->_patterner;
|
|
77
|
+
|
|
78
|
+
this->mask_pattern=m;
|
|
79
|
+
switch(this->mask_pattern){
|
|
80
|
+
case 0:
|
|
81
|
+
this->_patterner=new MaskPatterner000();
|
|
82
|
+
break;
|
|
83
|
+
case 1:
|
|
84
|
+
this->_patterner=new MaskPatterner001();
|
|
85
|
+
break;
|
|
86
|
+
case 2:
|
|
87
|
+
this->_patterner=new MaskPatterner010();
|
|
88
|
+
break;
|
|
89
|
+
case 3:
|
|
90
|
+
this->_patterner=new MaskPatterner011();
|
|
91
|
+
break;
|
|
92
|
+
case 4:
|
|
93
|
+
this->_patterner=new MaskPatterner100();
|
|
94
|
+
break;
|
|
95
|
+
case 5:
|
|
96
|
+
this->_patterner=new MaskPatterner101();
|
|
97
|
+
break;
|
|
98
|
+
case 6:
|
|
99
|
+
this->_patterner=new MaskPatterner110();
|
|
100
|
+
break;
|
|
101
|
+
case 7:
|
|
102
|
+
this->_patterner=new MaskPatterner111();
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return(this->mask_pattern);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
int FormatInfo::decode_formatinfo(unsigned short data)
|
|
110
|
+
{
|
|
111
|
+
data^=QR_FORMAT_INFO_XOR_MASK;
|
|
112
|
+
|
|
113
|
+
this->status=0;
|
|
114
|
+
int ret=this->_error_correct(&data);
|
|
115
|
+
|
|
116
|
+
this->set_level(data>>13);
|
|
117
|
+
this->set_mask_pattern((data>>10)&0x7);
|
|
118
|
+
|
|
119
|
+
if(ret<0)
|
|
120
|
+
this->status|=QR_FORMATINFO_UNRECOVERABLE;
|
|
121
|
+
|
|
122
|
+
return(ret);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
int FormatInfo::_error_correct(unsigned short *src)
|
|
126
|
+
{
|
|
127
|
+
Galois::Field *gf=new Galois::Field(4);
|
|
128
|
+
Galois::BCH *bch=new Galois::BCH(gf,15,3);
|
|
129
|
+
unsigned short mask=0x01;
|
|
130
|
+
int i;
|
|
131
|
+
for(i=0;i<15;i++,mask<<=1){
|
|
132
|
+
if(*src&mask)
|
|
133
|
+
bch->set(i,gf->exp2nomial(0));
|
|
134
|
+
else
|
|
135
|
+
bch->set(i,gf->zero());
|
|
136
|
+
}
|
|
137
|
+
int errors=bch->decode();
|
|
138
|
+
if(errors>0){
|
|
139
|
+
mask=0x01;
|
|
140
|
+
for(i=0;i<errors;i++)
|
|
141
|
+
(*src)^=(mask<<bch->error_pos[i]);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
delete bch;
|
|
145
|
+
delete gf;
|
|
146
|
+
return(errors);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
unsigned char FormatInfo::mask_pixel(int i,int j){
|
|
150
|
+
return(this->_patterner->pixel(i,j));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
FormatInfo *FormatInfo::init_each_pattern_pixel()
|
|
154
|
+
{
|
|
155
|
+
this->_pattern_c=0;
|
|
156
|
+
return(this);
|
|
157
|
+
}
|
|
158
|
+
FormatInfo *FormatInfo::each_pattern_pixel(int *x,int *y)
|
|
159
|
+
{
|
|
160
|
+
if(this->_pattern_c<16){
|
|
161
|
+
*x=format_info_addr[0][this->_pattern_c][0];
|
|
162
|
+
*y=format_info_addr[0][this->_pattern_c][1];
|
|
163
|
+
}
|
|
164
|
+
else if(this->_pattern_c<32){
|
|
165
|
+
*x=format_info_addr[1][this->_pattern_c-16][0];
|
|
166
|
+
*y=format_info_addr[1][this->_pattern_c-16][1];
|
|
167
|
+
}
|
|
168
|
+
else
|
|
169
|
+
return(NULL);
|
|
170
|
+
|
|
171
|
+
this->_pattern_c++;
|
|
172
|
+
return(this);
|
|
173
|
+
}
|
|
174
|
+
FormatInfo *FormatInfo::each_pattern_pixel(int pos,int *x,int *y)
|
|
175
|
+
{
|
|
176
|
+
switch(pos){
|
|
177
|
+
case 0:
|
|
178
|
+
if(this->_pattern_c>14)
|
|
179
|
+
return(NULL);
|
|
180
|
+
break;
|
|
181
|
+
case 1:
|
|
182
|
+
if(this->_pattern_c>15)
|
|
183
|
+
return(NULL);
|
|
184
|
+
break;
|
|
185
|
+
default:
|
|
186
|
+
return(NULL);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
*x=format_info_addr[pos][this->_pattern_c][0];
|
|
190
|
+
*y=format_info_addr[pos][this->_pattern_c][1];
|
|
191
|
+
|
|
192
|
+
this->_pattern_c++;
|
|
193
|
+
return(this);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// formatinfo.h --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: formatinfo.h 36 2007-02-21 23:22:03Z zophos $
|
|
13
|
+
//
|
|
14
|
+
#ifndef __QR_FORMAT_INFO__
|
|
15
|
+
#define __QR_FORMAT_INFO__
|
|
16
|
+
|
|
17
|
+
#ifndef NULL
|
|
18
|
+
#define NULL 0
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
#include "qrerror.h"
|
|
22
|
+
#include "galois.h"
|
|
23
|
+
|
|
24
|
+
#define QR_FORMAT_INFO_GX 0x537 // G(x)=x^10+x^8+x^5+x^4+x^2+x+1
|
|
25
|
+
#define QR_FORMAT_INFO_XOR_MASK 0x5412 //0101010000010010B
|
|
26
|
+
#define QR_FORMAT_INFO_DATA_SIZE 15
|
|
27
|
+
|
|
28
|
+
namespace Qr{
|
|
29
|
+
//
|
|
30
|
+
// format info;
|
|
31
|
+
// matrix of (x,y); minus value means SymbolLength - Value;
|
|
32
|
+
// e.g; symbol size = 21 x 21, values {1,-1} points {1,20} module
|
|
33
|
+
//
|
|
34
|
+
const int format_info_addr[2][16][2]={
|
|
35
|
+
{
|
|
36
|
+
{0,8},{1,8},{2,8},{3,8},{4,8},{5,8},{7,8},
|
|
37
|
+
{8,8},{8,7},{8,5},{8,4},{8,3},{8,2},{8,1},{8,0}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
{8,-8}, // always black
|
|
41
|
+
{8,-1},{8,-2},{8,-3},{8,-4},{8,-5},{8,-6},{8,-7},
|
|
42
|
+
{-8,8},{-7,8},{-6,8},{-5,8},{-4,8},{-3,8},{-2,8},{-1,8}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
class MaskPatterner{
|
|
47
|
+
public:
|
|
48
|
+
virtual unsigned char pixel(int i,int j)=0;
|
|
49
|
+
};
|
|
50
|
+
class MaskPatterner000:public MaskPatterner{
|
|
51
|
+
public:
|
|
52
|
+
virtual unsigned char pixel(int i,int j);
|
|
53
|
+
};
|
|
54
|
+
class MaskPatterner001:public MaskPatterner{
|
|
55
|
+
public:
|
|
56
|
+
virtual unsigned char pixel(int i,int j);
|
|
57
|
+
};
|
|
58
|
+
class MaskPatterner010:public MaskPatterner{
|
|
59
|
+
public:
|
|
60
|
+
virtual unsigned char pixel(int i,int j);
|
|
61
|
+
};
|
|
62
|
+
class MaskPatterner011:public MaskPatterner{
|
|
63
|
+
public:
|
|
64
|
+
virtual unsigned char pixel(int i,int j);
|
|
65
|
+
};
|
|
66
|
+
class MaskPatterner100:public MaskPatterner{
|
|
67
|
+
public:
|
|
68
|
+
virtual unsigned char pixel(int i,int j);
|
|
69
|
+
};
|
|
70
|
+
class MaskPatterner101:public MaskPatterner{
|
|
71
|
+
public:
|
|
72
|
+
virtual unsigned char pixel(int i,int j);
|
|
73
|
+
};
|
|
74
|
+
class MaskPatterner110:public MaskPatterner{
|
|
75
|
+
public:
|
|
76
|
+
virtual unsigned char pixel(int i,int j);
|
|
77
|
+
};
|
|
78
|
+
class MaskPatterner111:public MaskPatterner{
|
|
79
|
+
public:
|
|
80
|
+
virtual unsigned char pixel(int i,int j);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
class FormatInfo{
|
|
84
|
+
public:
|
|
85
|
+
int level;
|
|
86
|
+
int mask_pattern;
|
|
87
|
+
short status;
|
|
88
|
+
|
|
89
|
+
private:
|
|
90
|
+
MaskPatterner *_patterner;
|
|
91
|
+
|
|
92
|
+
int _pattern_c;
|
|
93
|
+
|
|
94
|
+
public:
|
|
95
|
+
FormatInfo();
|
|
96
|
+
~FormatInfo();
|
|
97
|
+
|
|
98
|
+
int set_level(int l);
|
|
99
|
+
int set_mask_pattern(int m);
|
|
100
|
+
|
|
101
|
+
int decode_formatinfo(unsigned short data);
|
|
102
|
+
|
|
103
|
+
unsigned char mask_pixel(int i,int j);
|
|
104
|
+
|
|
105
|
+
FormatInfo *init_each_pattern_pixel();
|
|
106
|
+
FormatInfo *each_pattern_pixel(int *x,int *y);
|
|
107
|
+
FormatInfo *each_pattern_pixel(int pos,int *x,int *y);
|
|
108
|
+
|
|
109
|
+
private:
|
|
110
|
+
int _error_correct(unsigned short *src);
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
#endif
|
|
@@ -0,0 +1,593 @@
|
|
|
1
|
+
/////////////////////////////////////////////////////////////////////////
|
|
2
|
+
//
|
|
3
|
+
// galois.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: galois.cpp 38 2007-02-23 21:16:42Z zophos $
|
|
13
|
+
//
|
|
14
|
+
#include "galois.h"
|
|
15
|
+
|
|
16
|
+
namespace Galois{
|
|
17
|
+
|
|
18
|
+
/////////////////////////////////////////////////////////////////////
|
|
19
|
+
//
|
|
20
|
+
// galois field GF(2^4); G(x)=x^10+x^8+x^5+x^4+x^2+x+1
|
|
21
|
+
//
|
|
22
|
+
|
|
23
|
+
//
|
|
24
|
+
// generator polynomial
|
|
25
|
+
//
|
|
26
|
+
static const int bch_15_5_generator_polynomial[11]={
|
|
27
|
+
1,1,1,0,1,1,0,0,1,0,1
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
//
|
|
31
|
+
// exponent -> vector notation convert table
|
|
32
|
+
//
|
|
33
|
+
static const unsigned int gf2_4_exp2vect[16]={
|
|
34
|
+
1,2,4,8,3,6,12,11,5,10,7,14,15,13,9,0
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
//
|
|
38
|
+
// vector -> exponent notation convert table
|
|
39
|
+
//
|
|
40
|
+
static const unsigned int gf2_4_vect2exp[16]={
|
|
41
|
+
15,0,1,4,2,8,5,10,3,14,9,7,6,13,11,12
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/////////////////////////////////////////////////////////////////////
|
|
45
|
+
//
|
|
46
|
+
// galois field GF(2^8); G(x)=X^8+x^4+x^3+x^2+1
|
|
47
|
+
//
|
|
48
|
+
|
|
49
|
+
//
|
|
50
|
+
// generator polynomial
|
|
51
|
+
//
|
|
52
|
+
static const int bch_16_8_generator_polynomial[9]={
|
|
53
|
+
1,0,1,1,1,0,0,0,1
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
//
|
|
57
|
+
// exponent -> vector notation convert table
|
|
58
|
+
//
|
|
59
|
+
static const unsigned int gf2_8_exp2vect[256]={
|
|
60
|
+
1,2,4,8,16,32,64,128,29,58,116,232,205,135,19,38,
|
|
61
|
+
76,152,45,90,180,117,234,201,143,3,6,12,24,48,96,192,
|
|
62
|
+
157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,
|
|
63
|
+
70,140,5,10,20,40,80,160,93,186,105,210,185,111,222,161,
|
|
64
|
+
95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,
|
|
65
|
+
253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,
|
|
66
|
+
217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,
|
|
67
|
+
129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,
|
|
68
|
+
133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,
|
|
69
|
+
168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,
|
|
70
|
+
230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,
|
|
71
|
+
227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,
|
|
72
|
+
130,25,50,100,200,141,7,14,28,56,112,224,221,167,83,166,
|
|
73
|
+
81,162,89,178,121,242,249,239,195,155,43,86,172,69,138,9,
|
|
74
|
+
18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,
|
|
75
|
+
44,88,176,125,250,233,207,131,27,54,108,216,173,71,142,0
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
//
|
|
79
|
+
// vector -> exponent notation convert table
|
|
80
|
+
//
|
|
81
|
+
static const unsigned int gf2_8_vect2exp[256]={
|
|
82
|
+
255,0,1,25,2,50,26,198,3,223,51,238,27,104,199,75,
|
|
83
|
+
4,100,224,14,52,141,239,129,28,193,105,248,200,8,76,113,
|
|
84
|
+
5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,
|
|
85
|
+
29,181,194,125,106,39,249,185,201,154,9,120,77,228,114,166,
|
|
86
|
+
6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,
|
|
87
|
+
54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,
|
|
88
|
+
30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,
|
|
89
|
+
202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87,
|
|
90
|
+
7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,
|
|
91
|
+
227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,
|
|
92
|
+
55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,
|
|
93
|
+
242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,
|
|
94
|
+
31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,
|
|
95
|
+
108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,
|
|
96
|
+
203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,
|
|
97
|
+
79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
//
|
|
101
|
+
// G(x)=x^12+x^11+x^10+x^9+x^8+x^5+x^2+1
|
|
102
|
+
//
|
|
103
|
+
static const int bch_18_6_generator_polynomial[13]={
|
|
104
|
+
1,0,1,0,0,1,0,0,1,1,1,1,1
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
/////////////////////////////////////////////////////////////////////
|
|
109
|
+
//
|
|
110
|
+
//
|
|
111
|
+
//
|
|
112
|
+
Nomial::Nomial(void *gf,unsigned int x)
|
|
113
|
+
{
|
|
114
|
+
this->val=x;
|
|
115
|
+
this->_gf=gf;
|
|
116
|
+
((Field *)(this->_gf))->pool[x]=this;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
Nomial *Nomial::instance(void *gf,unsigned int x)
|
|
120
|
+
{
|
|
121
|
+
x=x%(((Field *)gf)->pool_size());
|
|
122
|
+
if(!((Field *)gf)->pool[x])
|
|
123
|
+
new Nomial(gf,x);
|
|
124
|
+
|
|
125
|
+
return(((Field *)gf)->pool[x]);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
Nomial *Nomial::dup()
|
|
129
|
+
{
|
|
130
|
+
return(Nomial::instance(this->_gf,this->val));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
unsigned int Nomial::to_exp()
|
|
135
|
+
{
|
|
136
|
+
return(this->val);
|
|
137
|
+
}
|
|
138
|
+
unsigned int Nomial::to_vect()
|
|
139
|
+
{
|
|
140
|
+
return(((Field *)this->_gf)->exp2vect[this->val]);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
inline int Nomial::m()
|
|
144
|
+
{
|
|
145
|
+
return(((Field *)(this->_gf))->m);
|
|
146
|
+
}
|
|
147
|
+
inline int Nomial::n()
|
|
148
|
+
{
|
|
149
|
+
return(((Field *)(this->_gf))->n);
|
|
150
|
+
}
|
|
151
|
+
inline unsigned int Nomial::exp2vect(unsigned int x)
|
|
152
|
+
{
|
|
153
|
+
return(((Field *)(this->_gf))->exp2vect[x]);
|
|
154
|
+
}
|
|
155
|
+
inline unsigned int Nomial::vect2exp(unsigned int x)
|
|
156
|
+
{
|
|
157
|
+
return(((Field *)(this->_gf))->vect2exp[x]);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
bool Nomial::is_zero()
|
|
161
|
+
{
|
|
162
|
+
return(this->to_vect()==0);
|
|
163
|
+
}
|
|
164
|
+
bool Nomial::operator==(Nomial x)
|
|
165
|
+
{
|
|
166
|
+
return(this->val==x.val);
|
|
167
|
+
}
|
|
168
|
+
bool Nomial::operator!=(Nomial x)
|
|
169
|
+
{
|
|
170
|
+
return(this->val!=x.val);
|
|
171
|
+
}
|
|
172
|
+
Nomial Nomial::operator+(Nomial x)
|
|
173
|
+
{
|
|
174
|
+
return(*Nomial::instance(this->_gf,
|
|
175
|
+
this->vect2exp(this->to_vect()^
|
|
176
|
+
x.to_vect())));
|
|
177
|
+
}
|
|
178
|
+
Nomial Nomial::operator-(Nomial x)
|
|
179
|
+
{
|
|
180
|
+
return(*this+x);
|
|
181
|
+
}
|
|
182
|
+
Nomial Nomial::operator*(Nomial x)
|
|
183
|
+
{
|
|
184
|
+
if(this->is_zero()||x.is_zero())
|
|
185
|
+
return(*(((Field *)(this->_gf))->zero()));
|
|
186
|
+
else
|
|
187
|
+
return(*Nomial::instance(this->_gf,(this->val+x.val)%this->n()));
|
|
188
|
+
|
|
189
|
+
}
|
|
190
|
+
Nomial Nomial::operator/(Nomial x)
|
|
191
|
+
{
|
|
192
|
+
if(x.is_zero())
|
|
193
|
+
throw(x);
|
|
194
|
+
else if(this->is_zero())
|
|
195
|
+
return(*(((Field *)(this->_gf))->zero()));
|
|
196
|
+
else
|
|
197
|
+
return(*Nomial::instance(this->_gf,
|
|
198
|
+
(this->val+this->n()-x.val)%this->n()));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/////////////////////////////////////////////////////////////////////
|
|
202
|
+
//
|
|
203
|
+
//
|
|
204
|
+
//
|
|
205
|
+
Field::Field(int m)
|
|
206
|
+
{
|
|
207
|
+
this->_need_delete=false;
|
|
208
|
+
|
|
209
|
+
this->m=m;
|
|
210
|
+
int i;
|
|
211
|
+
for(i=0,this->n=1;i<m;i++)
|
|
212
|
+
this->n*=2;
|
|
213
|
+
this->n-=1;
|
|
214
|
+
|
|
215
|
+
switch(this->m){
|
|
216
|
+
case 4:
|
|
217
|
+
this->exp2vect=(unsigned int *)gf2_4_exp2vect;
|
|
218
|
+
this->vect2exp=(unsigned int *)gf2_4_vect2exp;
|
|
219
|
+
break;
|
|
220
|
+
case 8:
|
|
221
|
+
this->exp2vect=(unsigned int *)gf2_8_exp2vect;
|
|
222
|
+
this->vect2exp=(unsigned int *)gf2_8_vect2exp;
|
|
223
|
+
break;
|
|
224
|
+
default:
|
|
225
|
+
throw;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
this->_pool_size=this->n+1;
|
|
229
|
+
this->pool=new Nomial *[this->_pool_size];
|
|
230
|
+
for(i=0;i<this->_pool_size;i++){
|
|
231
|
+
this->pool[i]=NULL;
|
|
232
|
+
Nomial::instance(this,i);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
Field::~Field()
|
|
236
|
+
{
|
|
237
|
+
delete this->pool;
|
|
238
|
+
if(this->_need_delete){
|
|
239
|
+
delete this->exp2vect;
|
|
240
|
+
delete this->vect2exp;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
int Field::pool_size()
|
|
245
|
+
{
|
|
246
|
+
return(this->_pool_size);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
Nomial *Field::exp2nomial(unsigned int x)
|
|
250
|
+
{
|
|
251
|
+
return(this->pool[x%(this->n)]);
|
|
252
|
+
}
|
|
253
|
+
Nomial *Field::vect2nomial(unsigned int x)
|
|
254
|
+
{
|
|
255
|
+
return(this->pool[this->vect2exp[x%(this->n)]]);
|
|
256
|
+
}
|
|
257
|
+
Nomial *Field::zero()
|
|
258
|
+
{
|
|
259
|
+
return(this->pool[this->n]);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
////////////////////////////////////////////////////////////////////////
|
|
263
|
+
//
|
|
264
|
+
//
|
|
265
|
+
//
|
|
266
|
+
Polynomial::Polynomial()
|
|
267
|
+
{
|
|
268
|
+
this->cols=0;
|
|
269
|
+
this->rows=0;
|
|
270
|
+
|
|
271
|
+
this->nomial=NULL;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
Polynomial::Polynomial(int rows)
|
|
275
|
+
{
|
|
276
|
+
this->cols=1;
|
|
277
|
+
this->rows=rows;
|
|
278
|
+
|
|
279
|
+
this->nomial=new Galois::Nomial *[this->rows];
|
|
280
|
+
}
|
|
281
|
+
Polynomial::Polynomial(int cols,int rows)
|
|
282
|
+
{
|
|
283
|
+
this->cols=cols;
|
|
284
|
+
this->rows=rows;
|
|
285
|
+
|
|
286
|
+
this->nomial=new Nomial *[this->cols*this->rows];
|
|
287
|
+
}
|
|
288
|
+
Polynomial::~Polynomial()
|
|
289
|
+
{
|
|
290
|
+
delete this->nomial;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
Polynomial *Polynomial::dup()
|
|
294
|
+
{
|
|
295
|
+
Polynomial *ret=new Polynomial(this->cols,this->rows);
|
|
296
|
+
memcpy(ret->nomial,this->nomial,
|
|
297
|
+
sizeof(Nomial *)*this->cols*this->rows);
|
|
298
|
+
|
|
299
|
+
return(ret);
|
|
300
|
+
}
|
|
301
|
+
Polynomial *Polynomial::dup(int count)
|
|
302
|
+
{
|
|
303
|
+
return(this->dup(0,0,count,count));
|
|
304
|
+
}
|
|
305
|
+
Polynomial *Polynomial::dup(int start_col,int start_row,int count)
|
|
306
|
+
{
|
|
307
|
+
return(this->dup(start_col,start_row,count,count));
|
|
308
|
+
}
|
|
309
|
+
Polynomial *Polynomial::dup(int start_col,int start_row,
|
|
310
|
+
int col_count,int row_count)
|
|
311
|
+
{
|
|
312
|
+
Polynomial *ret=new Polynomial(col_count,row_count);
|
|
313
|
+
|
|
314
|
+
for(int i=0,c=start_col;i<col_count;i++,c++){
|
|
315
|
+
for(int j=0,r=start_row;j<row_count;j++,r++){
|
|
316
|
+
ret->set(i,j,this->get(c,r));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return(ret);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
Nomial *Polynomial::set(int row,Nomial *val)
|
|
325
|
+
{
|
|
326
|
+
return(this->set(0,row,val));
|
|
327
|
+
}
|
|
328
|
+
Nomial *Polynomial::set(int col,int row,Nomial *val)
|
|
329
|
+
{
|
|
330
|
+
this->nomial[col*rows+row]=val->dup();
|
|
331
|
+
return(this->nomial[col*rows+row]);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
Nomial *Polynomial::get(int row)
|
|
335
|
+
{
|
|
336
|
+
return(this->get(0,row));
|
|
337
|
+
}
|
|
338
|
+
Nomial *Polynomial::get(int col,int row)
|
|
339
|
+
{
|
|
340
|
+
return(this->nomial[col*rows+row]->dup());
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
/////////////////////////////////////////////////////////////////////
|
|
345
|
+
//
|
|
346
|
+
// LU analyze with pivot selection
|
|
347
|
+
//
|
|
348
|
+
Polynomial *Polynomial::lu()
|
|
349
|
+
{
|
|
350
|
+
Polynomial *buf=this->dup();
|
|
351
|
+
Polynomial *ret=buf->_lu(buf);
|
|
352
|
+
if(!ret)
|
|
353
|
+
delete buf;
|
|
354
|
+
return(ret);
|
|
355
|
+
}
|
|
356
|
+
Polynomial *Polynomial::lu(int count)
|
|
357
|
+
{
|
|
358
|
+
Polynomial *buf=this->dup(0,0,count);
|
|
359
|
+
Polynomial *ret=buf->_lu(buf);
|
|
360
|
+
if(!ret)
|
|
361
|
+
delete buf;
|
|
362
|
+
return(ret);
|
|
363
|
+
}
|
|
364
|
+
Polynomial *Polynomial::lu(int start_col,int start_row,int count)
|
|
365
|
+
{
|
|
366
|
+
Polynomial *buf=this->dup(start_col,start_row,count);
|
|
367
|
+
Polynomial *ret=buf->_lu(buf);
|
|
368
|
+
if(!ret)
|
|
369
|
+
delete buf;
|
|
370
|
+
return(ret);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
Polynomial *Polynomial::_lu(Polynomial *buf)
|
|
374
|
+
{
|
|
375
|
+
int count=buf->cols,i,j;
|
|
376
|
+
if(buf->rows<buf->cols)
|
|
377
|
+
count=buf->rows;
|
|
378
|
+
|
|
379
|
+
for(j=0;j<count;j++){
|
|
380
|
+
Nomial *l;
|
|
381
|
+
//
|
|
382
|
+
// pivot
|
|
383
|
+
//
|
|
384
|
+
for(i=j;i<count;i++){
|
|
385
|
+
l=buf->get(i,j);
|
|
386
|
+
if(!l->is_zero())
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
if(i>=count)
|
|
390
|
+
return(NULL);
|
|
391
|
+
else if(i>j)
|
|
392
|
+
buf->swap_col(j,i);
|
|
393
|
+
|
|
394
|
+
for(i=j+1;i<count;i++){
|
|
395
|
+
Nomial *n=&(*buf->get(i,j)/(*l));
|
|
396
|
+
buf->set(i,j,n);
|
|
397
|
+
for(int k=j+1;k<count;k++){
|
|
398
|
+
Nomial *m=&(*buf->get(i,k)-*buf->get(j,k)**n);
|
|
399
|
+
*buf->set(i,k,m);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return(buf);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/////////////////////////////////////////////////////////////////////
|
|
407
|
+
//
|
|
408
|
+
// Gaussian elimination
|
|
409
|
+
//
|
|
410
|
+
Polynomial *Polynomial::solve()
|
|
411
|
+
{
|
|
412
|
+
Polynomial *lu=this->lu();
|
|
413
|
+
if(lu){
|
|
414
|
+
Polynomial *ret=this->solve(lu);
|
|
415
|
+
delete lu;
|
|
416
|
+
return(ret);
|
|
417
|
+
}
|
|
418
|
+
else{
|
|
419
|
+
return(NULL);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
Polynomial *Polynomial::solve(Polynomial *lu)
|
|
424
|
+
{
|
|
425
|
+
if(!lu)
|
|
426
|
+
return(NULL);
|
|
427
|
+
|
|
428
|
+
if(lu->rows!=this->cols+1)
|
|
429
|
+
throw((void *)NULL);
|
|
430
|
+
|
|
431
|
+
//
|
|
432
|
+
// check rank
|
|
433
|
+
//
|
|
434
|
+
int rank=0,i,j,k;
|
|
435
|
+
for(j=0;j<lu->cols;j++){
|
|
436
|
+
bool is_zero_cols=true;
|
|
437
|
+
for(k=j;k<lu->cols;k++){
|
|
438
|
+
is_zero_cols&=lu->get(j,k)->is_zero();
|
|
439
|
+
}
|
|
440
|
+
if(!is_zero_cols)
|
|
441
|
+
rank++;
|
|
442
|
+
}
|
|
443
|
+
if(rank<lu->cols)
|
|
444
|
+
return(NULL);
|
|
445
|
+
|
|
446
|
+
Polynomial *ret=new Polynomial(lu->cols);
|
|
447
|
+
for(i=0;i<lu->cols;i++){
|
|
448
|
+
ret->set(i,lu->get(i,lu->cols));
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
for(j=0;j<lu->cols;j++){
|
|
452
|
+
for(i=j+1;i<lu->cols;i++){
|
|
453
|
+
ret->set(i,&(*ret->get(i)-*ret->get(j)**lu->get(i,j)));
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
for(j=lu->cols-1;j>=0;j--){
|
|
457
|
+
for(int i=j+1;i<lu->cols;i++){
|
|
458
|
+
ret->set(j,&(*ret->get(j)-
|
|
459
|
+
*lu->get(j,i)**ret->get(i)));
|
|
460
|
+
}
|
|
461
|
+
ret->set(j,&(*ret->get(j)/(*lu->get(j,j))));
|
|
462
|
+
}
|
|
463
|
+
return(ret);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
void Polynomial::swap_col(int i,int j)
|
|
467
|
+
{
|
|
468
|
+
size_t sz=sizeof(Nomial *)*this->rows;
|
|
469
|
+
|
|
470
|
+
Nomial **tmp=new Nomial *[this->rows];
|
|
471
|
+
|
|
472
|
+
memcpy(tmp,this->nomial+i*this->rows,sz);
|
|
473
|
+
memcpy(this->nomial+i*this->rows,
|
|
474
|
+
this->nomial+j*this->rows,sz);
|
|
475
|
+
memcpy(this->nomial+j*this->rows,tmp,sz);
|
|
476
|
+
|
|
477
|
+
delete tmp;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
/////////////////////////////////////////////////////////////////////
|
|
482
|
+
//
|
|
483
|
+
//
|
|
484
|
+
//
|
|
485
|
+
BCH::BCH(Field *gf,int size,int capability)
|
|
486
|
+
{
|
|
487
|
+
this->_gf=gf;
|
|
488
|
+
this->rows=size;
|
|
489
|
+
this->cols=1;
|
|
490
|
+
this->_capability=capability;
|
|
491
|
+
this->error_size=0;
|
|
492
|
+
this->error_pos=NULL;
|
|
493
|
+
this->nomial=new Galois::Nomial *[this->rows];
|
|
494
|
+
this->syndrome_size=0;
|
|
495
|
+
this->syndromes=NULL;
|
|
496
|
+
}
|
|
497
|
+
BCH::~BCH()
|
|
498
|
+
{
|
|
499
|
+
if(this->error_pos)
|
|
500
|
+
delete this->error_pos;
|
|
501
|
+
|
|
502
|
+
if(this->syndromes)
|
|
503
|
+
delete this->syndromes;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
int BCH::decode(int syndrome_base)
|
|
507
|
+
{
|
|
508
|
+
//
|
|
509
|
+
// error syndromes
|
|
510
|
+
//
|
|
511
|
+
this->syndrome_size=this->_capability*2+syndrome_base;
|
|
512
|
+
this->syndromes=new Galois::Nomial *[this->syndrome_size];
|
|
513
|
+
|
|
514
|
+
int errors=0,i;
|
|
515
|
+
for(i=0;i<this->syndrome_size;i++){
|
|
516
|
+
this->syndromes[i]=this->_error_syndrome(i);
|
|
517
|
+
if(!this->syndromes[i]->is_zero())
|
|
518
|
+
errors++;
|
|
519
|
+
}
|
|
520
|
+
if(!errors)
|
|
521
|
+
return(0);
|
|
522
|
+
|
|
523
|
+
//
|
|
524
|
+
// calculate error position variables
|
|
525
|
+
//
|
|
526
|
+
Galois::Polynomial *err=NULL;
|
|
527
|
+
for(errors=this->_capability;errors>0;errors--){
|
|
528
|
+
Galois::Polynomial *mat=new Galois::Polynomial(errors,
|
|
529
|
+
errors+1);
|
|
530
|
+
|
|
531
|
+
for(int j=0;j<errors;j++){
|
|
532
|
+
for(i=0;i<=errors;i++){
|
|
533
|
+
mat->set(j,i,this->syndromes[i+j+syndrome_base]);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
err=mat->solve();
|
|
538
|
+
delete mat;
|
|
539
|
+
|
|
540
|
+
if(err)
|
|
541
|
+
break;
|
|
542
|
+
}
|
|
543
|
+
if(!err){
|
|
544
|
+
this->error_size=-1;
|
|
545
|
+
return(-1);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if(err){
|
|
549
|
+
//
|
|
550
|
+
// get error position
|
|
551
|
+
//
|
|
552
|
+
this->error_pos=new int[errors];
|
|
553
|
+
memset(this->error_pos,-1,errors);
|
|
554
|
+
|
|
555
|
+
int c,i,j;
|
|
556
|
+
for(j=0,c=0;j<this->rows;j++){
|
|
557
|
+
Galois::Nomial *sigma=err->get(0);
|
|
558
|
+
for(i=1;i<errors;i++){
|
|
559
|
+
sigma=&(*sigma+*err->get(i)*
|
|
560
|
+
*this->_gf->exp2nomial(j*i));
|
|
561
|
+
}
|
|
562
|
+
sigma=&(*sigma+*this->_gf->exp2nomial(j*i));
|
|
563
|
+
|
|
564
|
+
if(sigma->is_zero()){
|
|
565
|
+
if(c<errors){
|
|
566
|
+
this->error_pos[c]=j;
|
|
567
|
+
}
|
|
568
|
+
c++;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
delete err;
|
|
572
|
+
if(c==errors)
|
|
573
|
+
this->error_size=errors;
|
|
574
|
+
else
|
|
575
|
+
this->error_size=-1;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
return(this->error_size);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
Galois::Nomial *BCH::_error_syndrome(int d)
|
|
582
|
+
{
|
|
583
|
+
Galois::Nomial *x=this->_gf->zero();
|
|
584
|
+
|
|
585
|
+
for(int i=0;i<this->rows;i++){
|
|
586
|
+
x=&(*x+*this->get(i)*
|
|
587
|
+
*this->_gf->exp2nomial(i*d));
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
return(x->dup());
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
}
|