├── examples ├── Makefile.am ├── simple │ ├── simple.dsp │ ├── simple.dsw │ ├── Makefile.am │ ├── simple.dep │ ├── simpletest.cpp │ └── simple.mak └── webcam │ ├── webcam.dsp │ ├── webcam.dsw │ ├── Makefile.am │ ├── webcam.dep │ ├── webcam.mak │ └── webcam.cpp ├── img ├── 125.bmp ├── qr.png ├── 01-1.jpg ├── 01-2.jpg ├── 01-3.jpg ├── 01-4.jpg ├── 02-1.jpg ├── 02-2.jpg ├── 02-3.jpg ├── 02-4.jpg ├── 03-1.jpg ├── 03-2.jpg ├── 03-3.jpg ├── 03-4.jpg ├── 04-1.jpg ├── 04-2.jpg ├── 04-3.jpg ├── 04-4.jpg ├── 05-1.jpg ├── 05-2.jpg ├── 05-3.jpg ├── 05-4.jpg ├── 06-1.jpg ├── 06-2.jpg ├── 06-3.jpg └── 06-4.jpg ├── Makefile.am ├── libdecodeqr ├── libdecodeqr.dsp ├── libdecodeqr.dsw ├── Makefile.am ├── qrtypes.h ├── bitstream.h ├── qrerror.h ├── version.h ├── libdecodeqr.dep ├── codedata.h ├── ecidecoder.h ├── formatinfo.h ├── galois.h ├── bitstream.cpp ├── imagereader.h ├── container.h ├── formatinfo.cpp ├── libdecodeqr.cpp ├── libdecodeqr.mak ├── container.cpp ├── decodeqr.h ├── ecidecoder.cpp ├── codedata.cpp └── galois.cpp ├── test ├── Makefile.am ├── test_galois.cpp └── test_codedata.cpp ├── configure.ac ├── README ├── doc ├── HackingGuide.ja └── ApiReference.ja └── COPYING /examples/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = simple webcam 2 | -------------------------------------------------------------------------------- /img/125.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/125.bmp -------------------------------------------------------------------------------- /img/qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/qr.png -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = libdecodeqr test examples 2 | AM_CPPFLAGS = $(DEPS_CFLAGS) 3 | -------------------------------------------------------------------------------- /img/01-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/01-1.jpg -------------------------------------------------------------------------------- /img/01-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/01-2.jpg -------------------------------------------------------------------------------- /img/01-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/01-3.jpg -------------------------------------------------------------------------------- /img/01-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/01-4.jpg -------------------------------------------------------------------------------- /img/02-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/02-1.jpg -------------------------------------------------------------------------------- /img/02-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/02-2.jpg -------------------------------------------------------------------------------- /img/02-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/02-3.jpg -------------------------------------------------------------------------------- /img/02-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/02-4.jpg -------------------------------------------------------------------------------- /img/03-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/03-1.jpg -------------------------------------------------------------------------------- /img/03-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/03-2.jpg -------------------------------------------------------------------------------- /img/03-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/03-3.jpg -------------------------------------------------------------------------------- /img/03-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/03-4.jpg -------------------------------------------------------------------------------- /img/04-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/04-1.jpg -------------------------------------------------------------------------------- /img/04-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/04-2.jpg -------------------------------------------------------------------------------- /img/04-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/04-3.jpg -------------------------------------------------------------------------------- /img/04-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/04-4.jpg -------------------------------------------------------------------------------- /img/05-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/05-1.jpg -------------------------------------------------------------------------------- /img/05-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/05-2.jpg -------------------------------------------------------------------------------- /img/05-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/05-3.jpg -------------------------------------------------------------------------------- /img/05-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/05-4.jpg -------------------------------------------------------------------------------- /img/06-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/06-1.jpg -------------------------------------------------------------------------------- /img/06-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/06-2.jpg -------------------------------------------------------------------------------- /img/06-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/06-3.jpg -------------------------------------------------------------------------------- /img/06-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/img/06-4.jpg -------------------------------------------------------------------------------- /examples/simple/simple.dsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/examples/simple/simple.dsp -------------------------------------------------------------------------------- /examples/simple/simple.dsw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/examples/simple/simple.dsw -------------------------------------------------------------------------------- /examples/webcam/webcam.dsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/examples/webcam/webcam.dsp -------------------------------------------------------------------------------- /examples/webcam/webcam.dsw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/examples/webcam/webcam.dsw -------------------------------------------------------------------------------- /libdecodeqr/libdecodeqr.dsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/libdecodeqr/libdecodeqr.dsp -------------------------------------------------------------------------------- /libdecodeqr/libdecodeqr.dsw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephholsten/libdecodeqr/HEAD/libdecodeqr/libdecodeqr.dsw -------------------------------------------------------------------------------- /examples/webcam/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = $(DEPS_CFLAGS) 2 | EXTRA_DIST = webcam.dep webcam.dsp webcam.dsw webcam.mak 3 | noinst_PROGRAMS = webcam 4 | webcam_SOURCES = webcam.cpp 5 | webcam_LDADD = ../../libdecodeqr/libdecodeqr.la 6 | webcam_LDADD += $(DEPS_LIBS) 7 | -------------------------------------------------------------------------------- /examples/simple/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = $(DEPS_CFLAGS) 2 | EXTRA_DIST = simple.dep simple.dsp simple.dsw simple.mak 3 | noinst_PROGRAMS = simpletest 4 | simpletest_SOURCES = simpletest.cpp 5 | simpletest_LDADD = ../../libdecodeqr/libdecodeqr.la 6 | simpletest_LDADD += $(DEPS_LIBS) 7 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | TESTS = $(check_PROGRAMS) 2 | check_PROGRAMS = test_galois test_codedata 3 | test_codedata_SOURCES = test_codedata.cpp 4 | test_codedata_LDADD = ../libdecodeqr/libdecodeqr.la 5 | test_galois_SOURCES = test_galois.cpp 6 | test_galois_LDADD = ../libdecodeqr/libdecodeqr.la 7 | -------------------------------------------------------------------------------- /libdecodeqr/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = $(DEPS_CFLAGS) 2 | EXTRA_DIST = bitstream.h codedata.h container.h ecidecoder.h formatinfo.h galois.h imagereader.h libdecodeqr.cpp libdecodeqr.dep libdecodeqr.dsp libdecodeqr.dsw libdecodeqr.mak version.h 3 | lib_LTLIBRARIES = libdecodeqr.la 4 | libdecodeqr_la_SOURCES = bitstream.cpp codedata.cpp container.cpp ecidecoder.cpp formatinfo.cpp galois.cpp imagereader.cpp libdecodeqr.cpp 5 | libdecodeqr_la_LIBADD = $(DEPS_LIBS) 6 | include_HEADERS = decodeqr.h qrerror.h qrtypes.h 7 | 8 | -------------------------------------------------------------------------------- /examples/simple/simple.dep: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Generated Dependency File, included by simple.mak 2 | 3 | .\simpletest.cpp : \ 4 | "..\..\..\..\..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\ 5 | "..\..\..\..\..\..\..\..\..\program files\opencv\cv\include\cv.h"\ 6 | "..\..\..\..\..\..\..\..\..\program files\opencv\cv\include\cvcompat.h"\ 7 | "..\..\..\..\..\..\..\..\..\program files\opencv\cv\include\cvtypes.h"\ 8 | "..\..\..\..\..\..\..\..\..\program files\opencv\cxcore\include\cxcore.h"\ 9 | "..\..\..\..\..\..\..\..\..\program files\opencv\cxcore\include\cxerror.h"\ 10 | "..\..\..\..\..\..\..\..\..\program files\opencv\cxcore\include\cxtypes.h"\ 11 | "..\..\..\..\..\..\..\..\..\program files\opencv\otherlibs\highgui\highgui.h"\ 12 | "..\..\decodeqr.h"\ 13 | "..\..\errorcode.h"\ 14 | "..\..\qrtypes.h"\ 15 | 16 | -------------------------------------------------------------------------------- /examples/webcam/webcam.dep: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Generated Dependency File, included by webcam.mak 2 | 3 | .\webcam.cpp : \ 4 | "..\..\..\..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\ 5 | "..\..\..\..\..\..\..\..\program files\opencv\cv\include\cv.h"\ 6 | "..\..\..\..\..\..\..\..\program files\opencv\cv\include\cvcompat.h"\ 7 | "..\..\..\..\..\..\..\..\program files\opencv\cv\include\cvtypes.h"\ 8 | "..\..\..\..\..\..\..\..\program files\opencv\cxcore\include\cxcore.h"\ 9 | "..\..\..\..\..\..\..\..\program files\opencv\cxcore\include\cxerror.h"\ 10 | "..\..\..\..\..\..\..\..\program files\opencv\cxcore\include\cxtypes.h"\ 11 | "..\..\..\..\..\..\..\..\program files\opencv\otherlibs\highgui\highgui.h"\ 12 | "..\..\libdecodeqr\decodeqr.h"\ 13 | "..\..\libdecodeqr\qrerror.h"\ 14 | "..\..\libdecodeqr\qrtypes.h"\ 15 | 16 | -------------------------------------------------------------------------------- /libdecodeqr/qrtypes.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // qrtypes.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __QR_TYPES__ 15 | #define __QR_TYPES__ 16 | 17 | #define QR_LEVEL_M 0 18 | #define QR_LEVEL_L 1 19 | #define QR_LEVEL_H 2 20 | #define QR_LEVEL_Q 3 21 | 22 | #define QR_MODE_NUMBER 1 23 | #define QR_MODE_ALPHABET 2 24 | #define QR_MODE_JOINT 3 25 | #define QR_MODE_8BIT 4 26 | #define QR_MODE_FNC1_1 5 27 | #define QR_MODE_ECI 7 28 | #define QR_MODE_KANJI 8 29 | #define QR_MODE_FNC1_2 9 30 | 31 | typedef void * QrDecoderHandle; 32 | typedef struct{ 33 | int model; 34 | int version; 35 | int level; 36 | //int mode; //not supported yet 37 | //int eci_mode; //not supported yet 38 | int charactor_size; 39 | int byte_size; 40 | } QrCodeHeader; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /libdecodeqr/bitstream.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // bitstream.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __QR_BITSTREAM__ 15 | #define __QR_BITSTREAM__ 16 | 17 | #include 18 | 19 | #ifndef NULL 20 | #define NULL 0 21 | #endif 22 | 23 | namespace Qr{ 24 | class BitStream{ 25 | public: 26 | unsigned char *data; 27 | int byte_size; 28 | int bit_size; 29 | 30 | private: 31 | int _pos; 32 | 33 | public: 34 | BitStream(); 35 | BitStream(void *src,int size); 36 | ~BitStream(); 37 | 38 | bool is_eod(); 39 | int position(); 40 | int seek(int pos); 41 | void rewind(); 42 | 43 | unsigned char *read(int read_bits); 44 | int read(void *dst,int buf_size,int bitsize); 45 | }; 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /libdecodeqr/qrerror.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // qrerror.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __QR_ERROR_CODE__ 15 | #define __QR_ERROR_CODE__ 16 | 17 | #define QR_IMAGEREADER_WORKING 0x1000 18 | #define QR_IMAGEREADER_DECODED 0x2000 19 | 20 | #define QR_VERSIONINFO_ERROR 0x0f00 21 | #define QR_VERSIONINFO_INVALID 0x0100 22 | #define QR_VERSIONINFO_MISMATCH 0x0200 23 | #define QR_VERSIONINFO_UNRECOVERABLE 0x0800 24 | 25 | #define QR_FORMATINFO_ERROR 0x00f0 26 | #define QR_FORMATINFO_INVALID_LEVEL 0x0010 27 | #define QR_FORMATINFO_UNRECOVERABLE 0x0080 28 | 29 | #define QR_CODEDATA_ERROR 0x000f 30 | #define QR_CODEDATA_NOT_SUPPORT_ECI 0x0001 31 | #define QR_CODEDATA_LENGTH_MISMATCH 0x0002 32 | #define QR_CODEDATA_UNRECOVERABLE 0x0008 33 | 34 | #define QR_IMAGEREADER_ERROR 0x4000 35 | #define QR_IMAGEREADER_NOT_INVALID_SRC_IMAGE 0x0100 36 | #define QR_IMAGEREADER_NOT_FOUND_FINDER_PATTERN 0x0200 37 | #define QR_IMAGEREADER_NOT_FOUND_CODE_AREA 0x0400 38 | #define QR_IMAGEREADER_NOT_DETERMINABLE_CODE_AREA 0x0800 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /libdecodeqr/version.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // version.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __QR_LIBDECODEQR_VERSION__ 15 | #define __QR_LIBDECODEQR_VERSION__ 16 | 17 | #define LIBDECODEQR_PRODUCTNAME "libdecodeqr" 18 | #define LIBDECODEQR_VERSION_MAJOR 0 19 | #define LIBDECODEQR_VERSION_MINOR 9 20 | #define LIBDECODEQR_VERSION_TEENY 4 21 | #define LIBDECODEQR_VERSION_SUFFIX "-dev" 22 | #define LIBDECODEQR_VERSION_REVISION "$Rev$" 23 | 24 | // 25 | // a voodoo magic 26 | // 27 | #define LIBDECODEQR_VERSION_CAT(a,b,c,d,e) LIBDECODEQR_VERSION_CATX(a,b,c,d,e) 28 | #define LIBDECODEQR_VERSION_CATX(a,b,c,d,e) #a "." #b "." #c d " (" e ")" 29 | 30 | #define LIBDECODEQR_VERSION LIBDECODEQR_VERSION_CAT(\ 31 | LIBDECODEQR_VERSION_MAJOR,\ 32 | LIBDECODEQR_VERSION_MINOR,\ 33 | LIBDECODEQR_VERSION_TEENY,\ 34 | LIBDECODEQR_VERSION_SUFFIX,\ 35 | LIBDECODEQR_VERSION_REVISION) 36 | 37 | #define LIBDECODEQR_VERSION_DESCRIPTION \ 38 | LIBDECODEQR_PRODUCTNAME " " LIBDECODEQR_VERSION 39 | 40 | static const char *libdecodeqr_version_description= 41 | LIBDECODEQR_VERSION_DESCRIPTION; 42 | #endif 43 | -------------------------------------------------------------------------------- /test/test_galois.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // test_galois.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #include 15 | #include 16 | #include "../libdecodeqr/galois.h" 17 | 18 | int main(int argc,char *argv[]) 19 | { 20 | puts("testing gaussian elimination on GF(2^8)"); 21 | 22 | Galois::Field *gf=new Galois::Field(8); 23 | 24 | // 25 | // may return (1,2); 26 | // 27 | Galois::Polynomial *mat=new Galois::Polynomial(2,3); 28 | 29 | mat->set(0,0,gf->exp2nomial(1)); 30 | mat->set(0,1,gf->exp2nomial(2)); 31 | mat->set(0,2,&(*gf->exp2nomial(1)* 32 | *gf->exp2nomial(1)+ 33 | *gf->exp2nomial(2)* 34 | *gf->exp2nomial(2))); //a^52 35 | mat->set(1,0,gf->exp2nomial(2)); 36 | mat->set(1,1,gf->exp2nomial(4)); 37 | mat->set(1,2,&(*gf->exp2nomial(2)* 38 | *gf->exp2nomial(1)+ 39 | *gf->exp2nomial(4)* 40 | *gf->exp2nomial(2))); //a^226 41 | 42 | Galois::Polynomial *a=mat->solve(); 43 | 44 | assert(a&&a->nomial[0]->val==1&&a->nomial[1]->val==2); 45 | 46 | delete a; 47 | delete mat; 48 | delete gf; 49 | 50 | puts("done"); 51 | return(0); 52 | } 53 | -------------------------------------------------------------------------------- /libdecodeqr/libdecodeqr.dep: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Generated Dependency File, included by libdecodeqr.mak 2 | 3 | .\bitstream.cpp : \ 4 | ".\bitstream.h"\ 5 | 6 | 7 | .\codedata.cpp : \ 8 | ".\bitstream.h"\ 9 | ".\codedata.h"\ 10 | ".\ecidecoder.h"\ 11 | ".\galois.h"\ 12 | ".\qrerror.h"\ 13 | 14 | 15 | .\container.cpp : \ 16 | ".\bitstream.h"\ 17 | ".\codedata.h"\ 18 | ".\container.h"\ 19 | ".\ecidecoder.h"\ 20 | ".\formatinfo.h"\ 21 | ".\galois.h"\ 22 | ".\qrerror.h"\ 23 | 24 | 25 | .\ecidecoder.cpp : \ 26 | ".\bitstream.h"\ 27 | ".\ecidecoder.h"\ 28 | 29 | 30 | .\formatinfo.cpp : \ 31 | ".\formatinfo.h"\ 32 | ".\galois.h"\ 33 | ".\qrerror.h"\ 34 | 35 | 36 | .\galois.cpp : \ 37 | ".\galois.h"\ 38 | 39 | 40 | .\imagereader.cpp : \ 41 | ".\bitstream.h"\ 42 | ".\codedata.h"\ 43 | ".\container.h"\ 44 | ".\ecidecoder.h"\ 45 | ".\formatinfo.h"\ 46 | ".\galois.h"\ 47 | ".\imagereader.h"\ 48 | ".\qrerror.h"\ 49 | {$(INCLUDE)}"cv.h"\ 50 | {$(INCLUDE)}"cvcompat.h"\ 51 | {$(INCLUDE)}"cvtypes.h"\ 52 | {$(INCLUDE)}"cxcore.h"\ 53 | {$(INCLUDE)}"cxerror.h"\ 54 | {$(INCLUDE)}"cxtypes.h"\ 55 | {$(INCLUDE)}"emmintrin.h"\ 56 | {$(INCLUDE)}"mmintrin.h"\ 57 | {$(INCLUDE)}"xmmintrin.h"\ 58 | 59 | 60 | .\libdecodeqr.cpp : \ 61 | ".\bitstream.h"\ 62 | ".\codedata.h"\ 63 | ".\container.h"\ 64 | ".\ecidecoder.h"\ 65 | ".\formatinfo.h"\ 66 | ".\galois.h"\ 67 | ".\imagereader.h"\ 68 | ".\qrerror.h"\ 69 | ".\qrtypes.h"\ 70 | ".\version.h"\ 71 | {$(INCLUDE)}"cv.h"\ 72 | {$(INCLUDE)}"cvcompat.h"\ 73 | {$(INCLUDE)}"cvtypes.h"\ 74 | {$(INCLUDE)}"cxcore.h"\ 75 | {$(INCLUDE)}"cxerror.h"\ 76 | {$(INCLUDE)}"cxtypes.h"\ 77 | {$(INCLUDE)}"emmintrin.h"\ 78 | {$(INCLUDE)}"mmintrin.h"\ 79 | {$(INCLUDE)}"xmmintrin.h"\ 80 | 81 | -------------------------------------------------------------------------------- /examples/simple/simpletest.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // simpletest.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #include 15 | #include 16 | #include "../../libdecodeqr/decodeqr.h" 17 | 18 | int main(int argc,char *argv[]) 19 | { 20 | cvNamedWindow("src",1); 21 | // 22 | // load image 23 | // 24 | IplImage *src=cvLoadImage(argv[1],1); 25 | cvShowImage("src",src); 26 | 27 | // 28 | // show version info 29 | // 30 | printf("libdecodeqr version %s\n",qr_decoder_version()); 31 | 32 | // 33 | // initialize 34 | // 35 | QrDecoderHandle decoder=qr_decoder_open(); 36 | 37 | // 38 | // do decode using default parameter 39 | // 40 | short stat=qr_decoder_decode_image(decoder,src); 41 | printf("STATUS=%04x\n",stat); 42 | 43 | // 44 | // get QR code header 45 | // 46 | QrCodeHeader header; 47 | if(qr_decoder_get_header(decoder,&header)){ 48 | // 49 | // get QR code text 50 | // To null terminate, a buffer size is larger than body size. 51 | // 52 | char *buf=new char[header.byte_size+1]; 53 | qr_decoder_get_body(decoder,(unsigned char *)buf,header.byte_size+1); 54 | printf("%s\n",buf); 55 | } 56 | 57 | // 58 | // finalize 59 | // 60 | qr_decoder_close(decoder); 61 | 62 | puts(""); 63 | puts("Hit any key to end."); 64 | cvWaitKey(0); 65 | 66 | cvDestroyAllWindows(); 67 | cvReleaseImage(&src); 68 | 69 | return(0); 70 | } 71 | -------------------------------------------------------------------------------- /test/test_codedata.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // test_codedata.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #include 15 | #include 16 | #include "../libdecodeqr/codedata.h" 17 | 18 | int main(int argc,char *argv[]) 19 | { 20 | int i; 21 | /* 22 | Qr::CodeData *words=new Qr::CodeData(1,1); 23 | unsigned char test_data2[26]={ 24 | 128,68,133,167,73,167,139,108, 25 | 0,236,17,236,17,236,17,236, 26 | 17,236,17,249,187,11,161,75, 27 | 69,244 28 | }; 29 | for(i=0;i<26;i++){ 30 | words->push(test_data2[i]); 31 | } 32 | */ 33 | 34 | Qr::CodeData *words=new Qr::CodeData(1,2); 35 | 36 | puts("testing no-error data"); 37 | unsigned char sent[26]={ 38 | 32,65,205,69,41,220,46,128, 39 | 236,42,159,74,221,244,169,239, 40 | 150,138,70,237,85,224,96,74, 41 | 219,61 42 | }; 43 | for(i=0;i<26;i++){ 44 | words->push(sent[i]); 45 | } 46 | assert(words->decode()==0); 47 | 48 | puts("testing 2 errors data"); 49 | words->clear(); 50 | unsigned char recv[26]={ 51 | 33,64,205,69,41,220,46,128, 52 | 236,42,159,74,221,244,169,239, 53 | 150,138,70,237,85,224,96,74, 54 | 219,61 55 | }; 56 | for(i=0;i<26;i++){ 57 | words->push(recv[i]); 58 | } 59 | assert(words->decode()==2); 60 | 61 | puts("verifing corrected data"); 62 | unsigned char *corrected=words->dump(); 63 | for(i=0;i<26;i++){ 64 | assert(corrected[i]==sent[i]); 65 | } 66 | 67 | delete corrected; 68 | delete words; 69 | 70 | puts("done"); 71 | return(0); 72 | } 73 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.63]) 5 | AC_INIT(libdecodeqr, 0.9.4, zophos@koka-in.org) 6 | AC_CONFIG_AUX_DIR([build-aux]) 7 | AM_INIT_AUTOMAKE([-Wall -Werror foreign]) 8 | AC_CONFIG_SRCDIR([libdecodeqr/bitstream.cpp]) 9 | 10 | # Fix for recent changes in automake 11 | m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) 12 | 13 | # Checks for programs. 14 | AC_LANG([C++]) 15 | AC_PROG_CXX 16 | AC_PROG_INSTALL 17 | AC_PROG_LN_S 18 | AC_PROG_LIBTOOL 19 | AC_CHECK_TOOL(AR,ar) 20 | AC_CHECK_TOOL(LD,ld) 21 | 22 | # 23 | # Check if don't want -g option 24 | # 25 | AC_ARG_ENABLE(optimize, 26 | [ --enable-optimize turn off debug information (CC -g option). ], 27 | [enable_optimize=$enableval], [enable_optimize=no]) 28 | if test x"$enable_optimize" = xyes; then 29 | CXXFLAGS="$CXXFLAGS -O2" 30 | fi 31 | 32 | AC_ARG_ENABLE(debug, 33 | [ --enable-debugmessage turn on debug message.], 34 | [enable_debugmessage=$enableval], [enable_debugmessage=no]) 35 | if test x"$enable_debugmessage" = xyes; then 36 | CPPFLAGS="$CPPFLAGS -D_DEBUG" 37 | fi 38 | 39 | CPPFLAGS="$CPPFLAGS -fpermissive" 40 | 41 | PKG_CHECK_MODULES([DEPS], [opencv]) 42 | AC_SUBST(DEPS_CFLAGS) 43 | AC_SUBST(DEPS_LDFLAGS) 44 | 45 | # Checks for header files. 46 | AC_CHECK_HEADERS([memory.h netinet/in.h]) 47 | 48 | # Checks for typedefs, structures, and compiler characteristics. 49 | AC_HEADER_STDBOOL 50 | AC_C_CONST 51 | AC_C_INLINE 52 | AC_TYPE_SIZE_T 53 | 54 | # Checks for library functions. 55 | AC_HEADER_STDC 56 | AC_CHECK_FUNCS([memset memcpy snprintf]) 57 | # Get version info 58 | # DECODEQR_VERSION(ID) 59 | # ---------------------------- 60 | # ID should be MAJOR, MINOR, or TEENY 61 | AC_DEFUN([DECODEQR_VERSION], [ 62 | $1=`grep '#define LIBDECODEQR_VERSION_$1' $srcdir/libdecodeqr/version.h | sed 's/#define LIBDECODEQR_VERSION_$1 \([0-9]*\)/\1/'` 63 | AC_SUBST($1) 64 | ]) 65 | 66 | DECODEQR_VERSION(MAJOR) 67 | DECODEQR_VERSION(MINOR) 68 | DECODEQR_VERSION(TEENY) 69 | 70 | AC_CONFIG_FILES([ 71 | Makefile 72 | libdecodeqr/Makefile 73 | examples/Makefile 74 | examples/simple/Makefile 75 | examples/webcam/Makefile 76 | test/Makefile 77 | ]) 78 | AC_OUTPUT 79 | -------------------------------------------------------------------------------- /libdecodeqr/codedata.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // codedata.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __QR_CODE_DATA__ 15 | #define __QR_CODE_DATA__ 16 | 17 | #include 18 | #include "galois.h" 19 | #include "bitstream.h" 20 | #include "ecidecoder.h" 21 | #include "qrerror.h" 22 | 23 | #ifndef NULL 24 | #define NULL 0 25 | #endif 26 | 27 | #define QR_CODE_DATA_GX 0x11d //G(x)=x^8+x^4+x^3+x^2+1 28 | 29 | namespace Qr{ 30 | class CodeBlock{ 31 | public: 32 | int total_words; 33 | int data_words; 34 | int capability; 35 | unsigned char *data; 36 | short status; 37 | 38 | private: 39 | int _size; 40 | Galois::Field *_gf; 41 | 42 | public: 43 | CodeBlock(int total_words,int data_words,int capability, 44 | Galois::Field *gf); 45 | ~CodeBlock(); 46 | 47 | void clear(); 48 | unsigned char *push(unsigned char data); 49 | bool has_vacant_data(); 50 | 51 | int error_correct(); 52 | }; 53 | 54 | class CodeData{ 55 | public: 56 | int version; 57 | int level; 58 | 59 | int total_words; // total words (data+ecc) 60 | int data_words; // number of data words 61 | int data_blocks; // number of rs_block 62 | CodeBlock **data; 63 | 64 | int length; // number of decoded charactors 65 | int byte_length; 66 | 67 | short status; 68 | private: 69 | Galois::Field *_gf; 70 | 71 | int _size; 72 | int _index; 73 | 74 | unsigned char *_raw_data; 75 | 76 | public: 77 | CodeData(int version,int level); 78 | ~CodeData(); 79 | 80 | void clear(); 81 | unsigned char *push(unsigned char data); 82 | 83 | unsigned char *dump(); 84 | unsigned char *dump_block(int index); 85 | unsigned char *dump_data(); 86 | unsigned char *raw_data(); 87 | 88 | int decode(); 89 | 90 | private: 91 | int _error_correct(); 92 | }; 93 | }; 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | = libdecodeqr = 2 | 3 | == Whta's this? == 4 | "libdecodeqr" is a C/C++ library for docoding QR code, which based on JIS X 0510 and ISO/IEC18004. 5 | 6 | This library is able to decode miscellaneous images those are taken with a file, with a webcam, with a scanner, and so on. 7 | 8 | == Features == 9 | * Supports miscellaneous image formats and input devices. 10 | * Hi-Speed decoding. 11 | * Completely Free. 12 | 13 | == Requirements == 14 | * g++ / VC++6 15 | * [http://www.sourceforge.net/projects/opencvlibrary/ OpenCV] 0.9.7 or later 16 | * Gtk2 for UN*X (required by OpenCV) 17 | 18 | == Download == 19 | === Binary Release === 20 | Sorry, Not available yet. 21 | 22 | === Latest Stable Source Code === 23 | * version 0.9.3 http://http://trac.koka-in.org/libdecodeqr/attachment/wiki/WikiStart/libdecodeqr-0.9.3.tar.bz2 24 | 25 | === Latest Development Source Code === 26 | We use Subversion for source revision control and code sharing. 27 | 28 | {{{ 29 | svn co svn://svn.koka-in.org/libdecodeqr/trunk 30 | }}} 31 | 32 | == How to use == 33 | === Build and Intstall === 34 | see BuildAndInstall for detail. 35 | 36 | ==== Windows ==== 37 | 1. open $(archive_dir)/src/libdecodeqr/libdecodeqr.dsw 38 | 1. build the project (press [F7] key) 39 | or 40 | 1. start command prompt 41 | 1. run VCVARS32.BAT 42 | 1. nmake libdecodeqr.mak 43 | 44 | The Libraly file and header files are NOT installed automaticaly. 45 | After building, set places of decodeqr.h, qrtypes.h, qrerror.h and libdecodeqr.lib to your environments if you need. 46 | 47 | ==== UN*X ==== 48 | 1. $ cd $(archive_dir)/src/ 49 | 1. $ ./configure 50 | 1. $ make 51 | 1. $ sudo make install 52 | 53 | === API Reference === 54 | see ApiReference 55 | 56 | === Sample Codes === 57 | * [source:trunk/src/sample/simple/simpletest.cpp#latest simple usage] 58 | * [source:trunk/src/sample/webcam/webcam.cpp#latest with webcam] 59 | 60 | == How to Hack == 61 | see HackingGuide 62 | 63 | == Contact Us == 64 | === Web Page === 65 | http://trac.koka-in.org/libdecodeqr 66 | 67 | === Mailing List === 68 | mailto:libdecodeqr@koka-in.org 69 | 70 | To subscribe this list, please send the following phrase 71 | {{{ 72 | subscribe Your-Last-Name Your-First-Name 73 | }}} 74 | e.g. 75 | {{{ 76 | subscribe NISHI Takao 77 | }}} 78 | in the mail body (not subject) to the address . 79 | 80 | == Copying == 81 | Copyright (c) 2007 NISHI Takao , 82 | JMA (Japan Medical Association) and 83 | !NaCl (Network Applied Communication Laboratory Ltd.) All rights reserved.[[BR]] 84 | This is free software with ABSOLUTELY NO WARRANTY. 85 | 86 | You can redistribute and/or modify it under the terms of LGPL. 87 | -------------------------------------------------------------------------------- /libdecodeqr/ecidecoder.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // ecidecoder.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __QR_ECI_DECODER__ 15 | #define __QR_ECI_DECODER__ 16 | 17 | #include 18 | 19 | #ifdef WIN32 20 | #include 21 | #define snprintf _snprintf 22 | #else 23 | #include 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 111 | -------------------------------------------------------------------------------- /libdecodeqr/formatinfo.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // formatinfo.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 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 114 | -------------------------------------------------------------------------------- /libdecodeqr/galois.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // galois.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __GALOIS__ 15 | #define __GALOIS__ 16 | 17 | #include 18 | 19 | #ifndef NULL 20 | #define NULL 0 21 | #endif 22 | 23 | namespace Galois{ 24 | class Nomial{ 25 | public: 26 | unsigned int val; 27 | 28 | private: 29 | void *_gf; 30 | 31 | public: 32 | static Nomial *instance(void * gf,unsigned int x); 33 | Nomial *dup(); 34 | 35 | unsigned int to_exp(); 36 | unsigned int to_vect(); 37 | 38 | inline int m(); 39 | inline int n(); 40 | inline unsigned int exp2vect(unsigned int x); 41 | inline unsigned int vect2exp(unsigned int x); 42 | 43 | bool is_zero(); 44 | bool operator==(Nomial x); 45 | bool operator!=(Nomial x); 46 | Nomial operator+(Nomial x); 47 | Nomial operator-(Nomial x); 48 | Nomial operator*(Nomial x); 49 | Nomial operator/(Nomial x); 50 | 51 | protected: 52 | Nomial(void * gf,unsigned int x); 53 | }; 54 | 55 | class Field{ 56 | public: 57 | int m; 58 | int n; 59 | unsigned int *exp2vect; 60 | unsigned int *vect2exp; 61 | Nomial **pool; 62 | private: 63 | int _pool_size; 64 | bool _need_delete; 65 | 66 | public: 67 | Field(int m); 68 | ~Field(); 69 | 70 | int pool_size(); 71 | 72 | Nomial *exp2nomial(unsigned int x); 73 | Nomial *vect2nomial(unsigned int x); 74 | Nomial *zero(); 75 | }; 76 | 77 | 78 | class Polynomial{ 79 | public: 80 | int cols; 81 | int rows; 82 | Nomial **nomial; 83 | 84 | Polynomial(); 85 | Polynomial(int rows); 86 | Polynomial(int cols,int rows); 87 | ~Polynomial(); 88 | 89 | Polynomial *dup(); 90 | Polynomial *dup(int count); 91 | Polynomial *dup(int start_col,int start_row,int count); 92 | Polynomial *dup(int start_col,int start_row, 93 | int col_count,int row_count); 94 | 95 | Nomial *set(int row,Nomial *val); 96 | Nomial *set(int col,int row,Nomial *val); 97 | 98 | Nomial *get(int row); 99 | Nomial *get(int col,int row); 100 | 101 | Polynomial *lu(); 102 | Polynomial *lu(int count); 103 | Polynomial *lu(int start_col,int start_row,int count); 104 | Polynomial *_lu(Polynomial *buf); 105 | 106 | Polynomial *solve(); 107 | Polynomial *solve(Polynomial *lu); 108 | 109 | void swap_col(int i,int j); 110 | }; 111 | 112 | class BCH :public Polynomial{ 113 | public: 114 | int error_size; 115 | int *error_pos; 116 | int syndrome_size; 117 | Galois::Nomial **syndromes; 118 | 119 | private: 120 | Field *_gf; 121 | int _capability; 122 | 123 | public: 124 | BCH(Field *gf,int size,int capability); 125 | ~BCH(); 126 | 127 | int decode(int syndorome_base=0); 128 | 129 | private: 130 | Galois::Nomial *_error_syndrome(int d); 131 | }; 132 | } 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /doc/HackingGuide.ja: -------------------------------------------------------------------------------- 1 | = Hacking Guide = 2 | 覚え書きなど 3 | 4 | == 認識アルゴリズム == 5 | ''FIXME'' 6 | 7 | == BCHおよびリードソロモン復号 == 8 | JIS X 0510に書いてあるデコード方法を使うよりは普通にピーターソン法で解いた方が楽。 9 | 特に「附属書B 誤り訂正復号手順」は誤訳も多く,わざとわかりにくく書いてあるとしか思えない。 10 | 11 | 型番情報および形式情報のBCH復号は,ピーターソン法で誤り位置を求め,求まった位置のbitを反転するだけ。 12 | 13 | 本文の復号は,ピーターソン法でm個の誤り位置J(0)~J(m-1)を検出した後,エラーシンドロームS(n)が 14 | 15 | {{{ 16 | S(n) = Σ{r(i) * a(n*i)} 17 | = Σ{s(i) * a(n*i)} + Σ{e(J(x)) * a(J(x)*n)} 18 | = Σ{e(J(x)) * a(J(x)*n)} 19 | 20 | ただし 21 | r(x): 末尾からx byte目の受信データ 22 | s(x): 末尾からx byte目の送信データ 23 | e(x): 末尾からx byte目のエラーの大きさ 24 | a(x): GF(2^8)の指数表現xの元 25 | }}} 26 | 27 | となることを利用して連立方程式 28 | 29 | {{{ 30 | e(J(0)) + ... + e(J(m-1)) = S(0) 31 | e(J(0)) * a(J(0)) + ... + e(J(m-1)) * a(J(m-1)) = S(1) 32 | : 33 | e(J(0)) * a(J(0) * (m-1)) + ... + e(J(m-1)) * a(J(m-1) * (m-1)) = S(m-1) 34 | }}} 35 | 36 | を解いてe(J(0))~e(J(m-1))を求め,求まった値をr(J(x))に加算することで行える。 37 | 38 | {{{ 39 | r(x) = s(x) + e(x) 40 | s(x) = r(x) - e(x) 41 | 42 | ガロア体では減算と加算は等価だから 43 | 44 | s(x) = r(x) + e(x) 45 | }}} 46 | 47 | 本来GF(n^m)のリードソロモンはデータ長がn^m-1である必要があるが,未使用の上位桁を0で埋めることによりデータ長を縮小することができる。JIS X 0510の表12~18で定義されている「RSブロック」はこれを利用してデータ長(総コード長)を縮小しているものと考えられる(ただし未検証)。[[BR]] 48 | リードソロモン復号を既存のライブラリ(ex. http://www.ka9q.net/code/fec/ など)に置き換える場合には,上位byteを0パディングしてデータ長を255byteにしなければならない可能性がある。 49 | 50 | == 内部構造 == 51 | いいかげんなクラス図:[[BR]] 52 | [[Image(class_diagram.png)]] 53 | 54 | === Qr === 55 | ==== ImageReader ==== 56 | 画像解析クラス 57 | * [source:/trunk/src/libdecodeqr/imagereader.h#latest imagereader.h] 58 | * [source:/trunk/src/libdecodeqr/imagereader.cpp#latest imagereader.cpp] 59 | 60 | ==== Qr ==== 61 | QRコード (Iterator) 62 | 63 | * [source:/trunk/src/libdecodeqr/container.h#latest container.h] 64 | * [source:/trunk/src/libdecodeqr/container.cpp#latest container.cpp] 65 | 66 | ==== FormatInfo ==== 67 | 形式情報 (Iterator) 68 | 69 | * [source:/trunk/src/libdecodeqr/formatinfo.h#latest formatinfo.h] 70 | * [source:/trunk/src/libdecodeqr/formatinfo.cpp#latest formatinfo.cpp] 71 | 72 | ==== PattarnMaker ==== 73 | マスクパターン生成抽象クラス 74 | * [source:/trunk/src/libdecodeqr/formatinfo.h#latest formatinfo.h] 75 | * [source:/trunk/src/libdecodeqr/formatinfo.cpp#latest formatinfo.cpp] 76 | 77 | ==== PattarnMaker000 ==== 78 | ==== PattarnMaker001 ==== 79 | ==== PattarnMaker010 ==== 80 | ==== PattarnMaker011 ==== 81 | ==== PattarnMaker100 ==== 82 | ==== PattarnMaker101 ==== 83 | ==== PattarnMaker110 ==== 84 | ==== PattarnMaker111 ==== 85 | 86 | ==== CodeData ==== 87 | QRコード本文 (Iterator) 88 | * [source:/trunk/src/libdecodeqr/codedata.h#latest codedata.h] 89 | * [source:/trunk/src/libdecodeqr/codedata.cpp#latest codedata.cpp] 90 | 91 | ==== CodeBlock ==== 92 | QRコード本文リードソロモンデータブロック (Iterator) 93 | * [source:/trunk/src/libdecodeqr/codedata.h#latest codedata.h] 94 | * [source:/trunk/src/libdecodeqr/codedata.cpp#latest codedata.cpp] 95 | 96 | ==== BitStream ==== 97 | bit処理用疑似IO 98 | * [source:/trunk/src/libdecodeqr/bitstream.h#latest bitstream.h] 99 | * [source:/trunk/src/libdecodeqr/bitstream.cpp#latest bitstream.cpp] 100 | 101 | ==== ECI ==== 102 | ECI構造体デコードモジュール 103 | * [source:/trunk/src/libdecodeqr/ecidecoder.h#latest ecidecoder.h] 104 | * [source:/trunk/src/libdecodeqr/ecidecoder.cpp#latest ecidecoder.cpp] 105 | 106 | ===== Decoder ===== 107 | ===== NumericalDecoder ===== 108 | ===== AlphabeticalDecoder ===== 109 | ===== ByteDecoder ===== 110 | ===== GenericDecoder ===== 111 | ===== KanjiDecoder ===== 112 | 113 | === Galois === 114 | ガロア体演算パッケージ 115 | * [source:/trunk/src/libdecodeqr/galois.h#latest galois.h] 116 | * [source:/trunk/src/libdecodeqr/galois.cpp#latest galois.cpp] 117 | 118 | ==== Field ==== 119 | ガロア体母集合 (Flyweight Factory) 120 | 121 | 同じ生成多項式を持つNomialを全て格納 122 | 123 | ==== Nomial ==== 124 | ガロア体要素 (Flyweight) 125 | 126 | オブジェクトはFieldクラス生成時に生成される 127 | 128 | ==== Polynomial ==== 129 | ガロア体多項式および行列 130 | 131 | ==== BCH ==== 132 | BCH演算 133 | -------------------------------------------------------------------------------- /libdecodeqr/bitstream.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // bitstream.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #include "bitstream.h" 15 | 16 | namespace Qr{ 17 | BitStream::BitStream() 18 | { 19 | this->data=NULL; 20 | this->byte_size=0; 21 | this->bit_size=0; 22 | this->_pos=0; 23 | } 24 | BitStream::BitStream(void *src,int size) 25 | { 26 | this->byte_size=size; 27 | this->bit_size=size<<3; 28 | this->data=new unsigned char[size]; 29 | memcpy(this->data,src,size); 30 | this->_pos=0; 31 | } 32 | BitStream::~BitStream() 33 | { 34 | if(this->data) 35 | delete this->data; 36 | } 37 | 38 | bool BitStream::is_eod() 39 | { 40 | return(this->_pos>=this->bit_size); 41 | } 42 | int BitStream::position() 43 | { 44 | return(this->_pos); 45 | } 46 | int BitStream::seek(int pos) 47 | { 48 | this->_pos+=pos; 49 | if(this->_pos<0) 50 | this->_pos=0; 51 | if(this->_pos>this->bit_size) 52 | this->_pos=this->bit_size; 53 | 54 | return(this->_pos); 55 | } 56 | void BitStream::rewind() 57 | { 58 | this->_pos=0; 59 | } 60 | 61 | unsigned char *BitStream::read(int read_bits) 62 | { 63 | int byte_size=(read_bits>>3)+(read_bits&0x07?1:0); 64 | unsigned char *buf=new unsigned char[byte_size]; 65 | memset(buf,0,byte_size); 66 | 67 | this->read(buf,byte_size,read_bits); 68 | 69 | return(buf); 70 | } 71 | int BitStream::read(void *dst,int buf_size,int read_bits) 72 | { 73 | memset(dst,0,buf_size); 74 | 75 | if(read_bits>(buf_size<<3)) 76 | read_bits=buf_size<<3; 77 | 78 | int end_bit=this->_pos+read_bits-1; 79 | if(end_bit>=this->bit_size){ 80 | end_bit=this->bit_size-1; 81 | read_bits=this->bit_size-this->_pos; 82 | } 83 | int remain_bits=(end_bit+1)&0x07; 84 | int offset=this->_pos>>3; 85 | int read_bytes=(read_bits>>3)+(read_bits&0x07?1:0); 86 | 87 | if(read_bytes>3)-offset+1){ 100 | tmp++; 101 | i++; 102 | } 103 | for(;i>3); 108 | tmp--; 109 | for(i=0;i>remain_bits; 111 | } 112 | } 113 | else{ 114 | memcpy(dst,this->data+offset,read_bytes); 115 | } 116 | 117 | unsigned char mask=0xff; 118 | switch(8-(read_bits&0x07)){ 119 | case 1: 120 | mask=0x7f; 121 | break; 122 | case 2: 123 | mask=0x3f; 124 | break; 125 | case 3: 126 | mask=0x1f; 127 | break; 128 | case 4: 129 | mask=0x0f; 130 | break; 131 | case 5: 132 | mask=0x07; 133 | break; 134 | case 6: 135 | mask=0x03; 136 | break; 137 | case 7: 138 | mask=0x01; 139 | break; 140 | } 141 | *((unsigned char *)dst)&=mask; 142 | this->_pos+=read_bits; 143 | 144 | return(read_bits); 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /libdecodeqr/imagereader.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // imagereader.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __QR_IMAGE_READER__ 15 | #define __QR_IMAGE_READER__ 16 | 17 | #ifdef _DEBUG 18 | #include 19 | #endif 20 | 21 | #include 22 | #include 23 | #include "qrerror.h" 24 | #include "container.h" 25 | 26 | 27 | ///////////////////////////////////////////////////////////////////////// 28 | // 29 | // image processing parameters 30 | // 31 | #define DEFAULT_ADAPTIVE_TH_SIZE 25 32 | #define DEFAULT_ADAPTIVE_TH_DELTA 10 33 | #define MIN_AREA 49 34 | #define MIN_AREA_RATIO .65 35 | #define MIN_FERET_RATIO .7 36 | #define FIND_CODE_AREA_POLY_APPROX_TH 50 37 | #define POSTERIZED_TH_LOW 64 38 | #define POSTERIZED_TH_HI 96 39 | #define POSTERIZED_TH_STEP 8 40 | 41 | namespace Qr{ 42 | class ImageReader{ 43 | public: 44 | Qr *qr; 45 | short status; 46 | 47 | private: 48 | IplImage *_img_src_internal; 49 | IplImage *_img_src; 50 | IplImage *_img_transformed; 51 | IplImage *_img_binarized; 52 | IplImage *_img_tmp_1c; 53 | CvMemStorage *_stor; 54 | CvMemStorage *_stor_tmp; 55 | CvSeq *_seq_finder_pattern; 56 | CvSeq *_seq_code_area_contour; 57 | CvPoint _coderegion_vertexes[4]; 58 | CvBox2D _finderpattern_boxes[3]; 59 | 60 | public: 61 | ImageReader(); 62 | ImageReader(int width,int height, 63 | int depth=IPL_DEPTH_8U, 64 | int channel=3); 65 | ~ImageReader(); 66 | 67 | IplImage *set_image(IplImage *src); 68 | uchar *set_image(uchar *buffer,int size); 69 | IplImage *set_image(int width,int height, 70 | int depth,int channel); 71 | void release_image(); 72 | 73 | IplImage *src_buffer(); 74 | IplImage *transformed_buffer(); 75 | IplImage *binarized_buffer(); 76 | IplImage *tmp_buffer(); 77 | CvPoint *coderegion_vertexes(); 78 | CvBox2D *finderpattern_boxes(); 79 | 80 | Qr *decode(int adaptive_th_size= 81 | DEFAULT_ADAPTIVE_TH_SIZE, 82 | int adaptive_th_delta= 83 | DEFAULT_ADAPTIVE_TH_DELTA); 84 | Qr *decode(IplImage *src, 85 | int adaptive_th_size= 86 | DEFAULT_ADAPTIVE_TH_SIZE, 87 | int adaptive_th_delta= 88 | DEFAULT_ADAPTIVE_TH_DELTA); 89 | 90 | private: 91 | void _init(); 92 | void _alloc_image(int width,int height, 93 | int depth,int channel); 94 | 95 | Qr *_decode(int adaptive_th_size,int adaptive_th_delta); 96 | 97 | CvSeq *_find_finder_pattern(); 98 | CvSeq *_find_code_area_contour(double th); 99 | CvRect _transform_image(); 100 | void _create_posterized_image(int block_size, 101 | double delta, 102 | int low_th, 103 | int hi_th); 104 | IplImage *_get_code_matrix(); 105 | int _get_format_info(IplImage *src,int pos=0); 106 | IplImage *_get_function_patterns(); 107 | void _unmask_code_matrix(IplImage *src, 108 | IplImage *function_patterns); 109 | int _read_code_word(IplImage *src,IplImage *mask); 110 | 111 | double _get_cell_size(); 112 | IplImage *_get_mask_pattern(); 113 | 114 | }; 115 | 116 | static int seq_cmp_by_clockwise(const void *_a, 117 | const void *_b, 118 | void *_cog); 119 | 120 | void apaptive_white_leveling(const CvArr* src,CvArr* dst, 121 | double middle_value,int adaptive_method, 122 | int threshold_type,int block_size, 123 | double param1); 124 | 125 | } 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /examples/simple/simple.mak: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Generated NMAKE File, Based on simple.dsp 2 | !IF "$(CFG)" == "" 3 | CFG=simple - Win32 Debug 4 | !MESSAGE Missing target. Using defualt "simple - Win32 Debug". 5 | !ENDIF 6 | 7 | !IF "$(CFG)" != "simple - Win32 Release" && "$(CFG)" != "simple - Win32 Debug" 8 | !MESSAGE Mode "$(CFG)" is not valid. 9 | !MESSAGE 10 | !MESSAGE Valid modes are: 11 | !MESSAGE 12 | !MESSAGE "simple - Win32 Release" (for "Win32 (x86) Static Library") 13 | !MESSAGE "simple - Win32 Debug" (for "Win32 (x86) Static Library") 14 | !MESSAGE 15 | !MESSAGE eg: 16 | !MESSAGE 17 | !MESSAGE NMAKE /f "simple.mak" CFG="webcam - Win32 Debug" 18 | !ERROR Invalid target are gaven. 19 | !ENDIF 20 | 21 | !IF "$(OS)" == "Windows_NT" 22 | NULL= 23 | !ELSE 24 | NULL=nul 25 | !ENDIF 26 | 27 | !IF "$(CFG)" == "simple - Win32 Release" 28 | 29 | OUTDIR=.\Release 30 | INTDIR=.\Release 31 | # Begin Custom Macros 32 | OutDir=.\Release 33 | # End Custom Macros 34 | 35 | ALL : "$(OUTDIR)\simple.exe" 36 | 37 | 38 | CLEAN : 39 | -@erase "$(INTDIR)\simpletest.obj" 40 | -@erase "$(INTDIR)\vc60.idb" 41 | -@erase "$(OUTDIR)\simple.exe" 42 | 43 | "$(OUTDIR)" : 44 | if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" 45 | 46 | CPP=cl.exe 47 | CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\simple.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 48 | 49 | .c{$(INTDIR)}.obj:: 50 | $(CPP) @<< 51 | $(CPP_PROJ) $< 52 | << 53 | 54 | .cpp{$(INTDIR)}.obj:: 55 | $(CPP) @<< 56 | $(CPP_PROJ) $< 57 | << 58 | 59 | .cxx{$(INTDIR)}.obj:: 60 | $(CPP) @<< 61 | $(CPP_PROJ) $< 62 | << 63 | 64 | .c{$(INTDIR)}.sbr:: 65 | $(CPP) @<< 66 | $(CPP_PROJ) $< 67 | << 68 | 69 | .cpp{$(INTDIR)}.sbr:: 70 | $(CPP) @<< 71 | $(CPP_PROJ) $< 72 | << 73 | 74 | .cxx{$(INTDIR)}.sbr:: 75 | $(CPP) @<< 76 | $(CPP_PROJ) $< 77 | << 78 | 79 | RSC=rc.exe 80 | BSC32=bscmake.exe 81 | BSC32_FLAGS=/nologo /o"$(OUTDIR)\simple.bsc" 82 | BSC32_SBRS= \ 83 | 84 | LINK32=link.exe 85 | LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\simple.pdb" /machine:I386 /out:"$(OUTDIR)\simple.exe" 86 | LINK32_OBJS= \ 87 | "$(INTDIR)\simpletest.obj" \ 88 | "..\..\Debug\libdecodeqr.lib" 89 | 90 | "$(OUTDIR)\simple.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) 91 | $(LINK32) @<< 92 | $(LINK32_FLAGS) $(LINK32_OBJS) 93 | << 94 | 95 | !ELSEIF "$(CFG)" == "simple - Win32 Debug" 96 | 97 | OUTDIR=.\Debug 98 | INTDIR=.\Debug 99 | # Begin Custom Macros 100 | OutDir=.\Debug 101 | # End Custom Macros 102 | 103 | ALL : "$(OUTDIR)\simple.exe" 104 | 105 | 106 | CLEAN : 107 | -@erase "$(INTDIR)\simpletest.obj" 108 | -@erase "$(INTDIR)\vc60.idb" 109 | -@erase "$(INTDIR)\vc60.pdb" 110 | -@erase "$(OUTDIR)\simple.exe" 111 | -@erase "$(OUTDIR)\simple.ilk" 112 | -@erase "$(OUTDIR)\simple.pdb" 113 | 114 | "$(OUTDIR)" : 115 | if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" 116 | 117 | CPP=cl.exe 118 | CPP_PROJ=/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\simple.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 119 | 120 | .c{$(INTDIR)}.obj:: 121 | $(CPP) @<< 122 | $(CPP_PROJ) $< 123 | << 124 | 125 | .cpp{$(INTDIR)}.obj:: 126 | $(CPP) @<< 127 | $(CPP_PROJ) $< 128 | << 129 | 130 | .cxx{$(INTDIR)}.obj:: 131 | $(CPP) @<< 132 | $(CPP_PROJ) $< 133 | << 134 | 135 | .c{$(INTDIR)}.sbr:: 136 | $(CPP) @<< 137 | $(CPP_PROJ) $< 138 | << 139 | 140 | .cpp{$(INTDIR)}.sbr:: 141 | $(CPP) @<< 142 | $(CPP_PROJ) $< 143 | << 144 | 145 | .cxx{$(INTDIR)}.sbr:: 146 | $(CPP) @<< 147 | $(CPP_PROJ) $< 148 | << 149 | 150 | RSC=rc.exe 151 | BSC32=bscmake.exe 152 | BSC32_FLAGS=/nologo /o"$(OUTDIR)\simple.bsc" 153 | BSC32_SBRS= \ 154 | 155 | LINK32=link.exe 156 | LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib cv.lib cxcore.lib highgui.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\simple.pdb" /debug /machine:I386 /out:"$(OUTDIR)\simple.exe" /pdbtype:sept 157 | LINK32_OBJS= \ 158 | "$(INTDIR)\simpletest.obj" \ 159 | "..\..\Debug\libdecodeqr.lib" 160 | 161 | "$(OUTDIR)\simple.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) 162 | $(LINK32) @<< 163 | $(LINK32_FLAGS) $(LINK32_OBJS) 164 | << 165 | 166 | !ENDIF 167 | 168 | 169 | !IF "$(NO_EXTERNAL_DEPS)" != "1" 170 | !IF EXISTS("simple.dep") 171 | !INCLUDE "simple.dep" 172 | !ELSE 173 | !MESSAGE Warning: cannot find "simple.dep" 174 | !ENDIF 175 | !ENDIF 176 | 177 | 178 | !IF "$(CFG)" == "simple - Win32 Release" || "$(CFG)" == "simple - Win32 Debug" 179 | SOURCE=.\simpletest.cpp 180 | 181 | "$(INTDIR)\simpletest.obj" : $(SOURCE) "$(INTDIR)" 182 | 183 | 184 | 185 | !ENDIF 186 | 187 | -------------------------------------------------------------------------------- /examples/webcam/webcam.mak: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Generated NMAKE File, Based on webcam.dsp 2 | !IF "$(CFG)" == "" 3 | CFG=webcam - Win32 Debug 4 | !MESSAGE Missing target. Using defualt "webcam - Win32 Debug". 5 | !ENDIF 6 | 7 | !IF "$(CFG)" != "webcam - Win32 Release" && "$(CFG)" != "webcam - Win32 Debug" 8 | !MESSAGE Mode "$(CFG)" is not valid. 9 | !MESSAGE 10 | !MESSAGE Valid modes are: 11 | !MESSAGE 12 | !MESSAGE "webcam - Win32 Release" (for "Win32 (x86) Static Library") 13 | !MESSAGE "webcam - Win32 Debug" (for "Win32 (x86) Static Library") 14 | !MESSAGE 15 | !MESSAGE eg: 16 | !MESSAGE 17 | !MESSAGE NMAKE /f "webcam.mak" CFG="webcam - Win32 Debug" 18 | !ERROR Invalid target are gaven. 19 | !ENDIF 20 | 21 | !IF "$(OS)" == "Windows_NT" 22 | NULL= 23 | !ELSE 24 | NULL=nul 25 | !ENDIF 26 | 27 | !IF "$(CFG)" == "webcam - Win32 Release" 28 | 29 | OUTDIR=.\Release 30 | INTDIR=.\Release 31 | # Begin Custom Macros 32 | OutDir=.\Release 33 | # End Custom Macros 34 | 35 | ALL : "$(OUTDIR)\webcam.exe" 36 | 37 | 38 | CLEAN : 39 | -@erase "$(INTDIR)\vc60.idb" 40 | -@erase "$(INTDIR)\webcam.obj" 41 | -@erase "$(OUTDIR)\webcam.exe" 42 | 43 | "$(OUTDIR)" : 44 | if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" 45 | 46 | CPP=cl.exe 47 | CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\webcam.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 48 | 49 | .c{$(INTDIR)}.obj:: 50 | $(CPP) @<< 51 | $(CPP_PROJ) $< 52 | << 53 | 54 | .cpp{$(INTDIR)}.obj:: 55 | $(CPP) @<< 56 | $(CPP_PROJ) $< 57 | << 58 | 59 | .cxx{$(INTDIR)}.obj:: 60 | $(CPP) @<< 61 | $(CPP_PROJ) $< 62 | << 63 | 64 | .c{$(INTDIR)}.sbr:: 65 | $(CPP) @<< 66 | $(CPP_PROJ) $< 67 | << 68 | 69 | .cpp{$(INTDIR)}.sbr:: 70 | $(CPP) @<< 71 | $(CPP_PROJ) $< 72 | << 73 | 74 | .cxx{$(INTDIR)}.sbr:: 75 | $(CPP) @<< 76 | $(CPP_PROJ) $< 77 | << 78 | 79 | RSC=rc.exe 80 | BSC32=bscmake.exe 81 | BSC32_FLAGS=/nologo /o"$(OUTDIR)\webcam.bsc" 82 | BSC32_SBRS= \ 83 | 84 | LINK32=link.exe 85 | LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\webcam.pdb" /machine:I386 /out:"$(OUTDIR)\webcam.exe" 86 | LINK32_OBJS= \ 87 | "$(INTDIR)\webcam.obj" \ 88 | "..\..\libdecodeqr\Debug\libdecodeqr.lib" 89 | 90 | "$(OUTDIR)\webcam.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) 91 | $(LINK32) @<< 92 | $(LINK32_FLAGS) $(LINK32_OBJS) 93 | << 94 | 95 | !ELSEIF "$(CFG)" == "webcam - Win32 Debug" 96 | 97 | OUTDIR=.\Debug 98 | INTDIR=.\Debug 99 | # Begin Custom Macros 100 | OutDir=.\Debug 101 | # End Custom Macros 102 | 103 | ALL : "$(OUTDIR)\webcam.exe" 104 | 105 | 106 | CLEAN : 107 | -@erase "$(INTDIR)\vc60.idb" 108 | -@erase "$(INTDIR)\vc60.pdb" 109 | -@erase "$(INTDIR)\webcam.obj" 110 | -@erase "$(OUTDIR)\webcam.exe" 111 | -@erase "$(OUTDIR)\webcam.ilk" 112 | -@erase "$(OUTDIR)\webcam.pdb" 113 | 114 | "$(OUTDIR)" : 115 | if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" 116 | 117 | CPP=cl.exe 118 | CPP_PROJ=/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"$(INTDIR)\webcam.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 119 | 120 | .c{$(INTDIR)}.obj:: 121 | $(CPP) @<< 122 | $(CPP_PROJ) $< 123 | << 124 | 125 | .cpp{$(INTDIR)}.obj:: 126 | $(CPP) @<< 127 | $(CPP_PROJ) $< 128 | << 129 | 130 | .cxx{$(INTDIR)}.obj:: 131 | $(CPP) @<< 132 | $(CPP_PROJ) $< 133 | << 134 | 135 | .c{$(INTDIR)}.sbr:: 136 | $(CPP) @<< 137 | $(CPP_PROJ) $< 138 | << 139 | 140 | .cpp{$(INTDIR)}.sbr:: 141 | $(CPP) @<< 142 | $(CPP_PROJ) $< 143 | << 144 | 145 | .cxx{$(INTDIR)}.sbr:: 146 | $(CPP) @<< 147 | $(CPP_PROJ) $< 148 | << 149 | 150 | RSC=rc.exe 151 | BSC32=bscmake.exe 152 | BSC32_FLAGS=/nologo /o"$(OUTDIR)\webcam.bsc" 153 | BSC32_SBRS= \ 154 | 155 | LINK32=link.exe 156 | LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib cv.lib cxcore.lib highgui.lib ws2_32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\webcam.pdb" /debug /machine:I386 /out:"$(OUTDIR)\webcam.exe" /pdbtype:sept 157 | LINK32_OBJS= \ 158 | "$(INTDIR)\webcam.obj" \ 159 | "..\..\libdecodeqr\Debug\libdecodeqr.lib" 160 | 161 | "$(OUTDIR)\webcam.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) 162 | $(LINK32) @<< 163 | $(LINK32_FLAGS) $(LINK32_OBJS) 164 | << 165 | 166 | !ENDIF 167 | 168 | 169 | !IF "$(NO_EXTERNAL_DEPS)" != "1" 170 | !IF EXISTS("webcam.dep") 171 | !INCLUDE "webcam.dep" 172 | !ELSE 173 | !MESSAGE Warning: cannot find "webcam.dep" 174 | !ENDIF 175 | !ENDIF 176 | 177 | 178 | !IF "$(CFG)" == "webcam - Win32 Release" || "$(CFG)" == "webcam - Win32 Debug" 179 | SOURCE=.\webcam.cpp 180 | 181 | "$(INTDIR)\webcam.obj" : $(SOURCE) "$(INTDIR)" 182 | 183 | 184 | 185 | !ENDIF 186 | 187 | -------------------------------------------------------------------------------- /libdecodeqr/container.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // container.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __QR_CONTAINER__ 15 | #define __QR_CONTAINER__ 16 | 17 | #include "qrerror.h" 18 | #include "formatinfo.h" 19 | #include "codedata.h" 20 | 21 | #ifndef NULL 22 | #define NULL 0 23 | #endif 24 | 25 | #define QR_VERSION_INFO_GX 0x1f25 // G(x)=x^12+x^11+x^10+x^9+x^8+x^5+x^2+1 26 | #define QR_VERSION_INFO_DATA_SIZE 18 27 | 28 | namespace Qr{ 29 | // 30 | // alignment pattern center coordinates 31 | // ( from JISX0510(2004) Appendix E Table.1 p.71) 32 | // 33 | // {{number of data without me,coord_1,...coord_n},...} 34 | // 35 | // number of alignment pattern = (number of data)^2 - 3 36 | // 37 | const int alignment_pattern_addr[41][8]={ 38 | // version 0 (not exist, just a dummy) 39 | {0,0,0,0,0,0,0,0}, 40 | 41 | // version 1 42 | {0,0,0,0,0,0,0,0}, 43 | {2,6,18,0,0,0,0,0}, 44 | {2,6,22,0,0,0,0,0}, 45 | {2,6,26,0,0,0,0,0}, 46 | 47 | {2,6,30,0,0,0,0,0}, 48 | {2,6,34,0,0,0,0,0}, 49 | {3,6,22,38,0,0,0,0}, 50 | {3,6,24,42,0,0,0,0}, 51 | {3,6,26,46,0,0,0,0}, 52 | 53 | // version 10 54 | {3,6,28,50,0,0,0,0}, 55 | {3,6,30,54,0,0,0,0}, 56 | {3,6,32,58,0,0,0,0}, 57 | {3,6,34,62,0,0,0,0}, 58 | {4,6,26,46,66,0,0,0}, 59 | 60 | {4,6,26,48,70,0,0,0}, 61 | {4,6,26,50,74,0,0,0}, 62 | {4,6,30,54,78,0,0,0}, 63 | {4,6,30,56,82,0,0,0}, 64 | {4,6,30,58,86,0,0,0}, 65 | 66 | // version 20 67 | {4,6,34,62,90,0,0,0}, 68 | {5,6,28,50,72,94,0,0}, 69 | {5,6,26,50,74,98,0,0}, 70 | {5,6,30,54,78,102,0,0}, 71 | {5,6,28,54,80,106,0,0}, 72 | 73 | {5,6,32,58,84,110,0,0}, 74 | {5,6,30,58,86,114,0,0}, 75 | {5,6,34,62,90,118,0,0}, 76 | {6,6,26,50,74,98,122,0}, 77 | {6,6,30,54,78,102,126,0}, 78 | 79 | // version 30 80 | {6,6,26,52,78,104,130,0}, 81 | {6,6,30,56,82,108,134,0}, 82 | {6,6,34,60,86,112,138,0}, 83 | {6,6,30,58,86,114,142,0}, 84 | {6,6,34,62,90,118,146,0}, 85 | 86 | {7,6,30,54,78,102,126,150}, 87 | {7,6,24,50,76,102,128,154}, 88 | {7,6,28,54,80,106,132,158}, 89 | {7,6,32,58,84,110,136,162}, 90 | {7,6,26,54,82,110,138,166}, 91 | 92 | // version 40 93 | {7,6,30,58,86,114,142,170} 94 | }; 95 | 96 | // 97 | // version info; 98 | // array of {x,y}; minus value means SymbolLength - Value; 99 | // e.g; symbol size = 21 x 21, values {1,-1} points {1,20} module 100 | // 101 | const int version_info_addr[2][18][2]={ 102 | { 103 | {-11,0},{-10,0},{-9,0}, 104 | {-11,1},{-10,1},{-9,1}, 105 | {-11,2},{-10,2},{-9,2}, 106 | {-11,3},{-10,3},{-9,3}, 107 | {-11,4},{-10,4},{-9,4}, 108 | {-11,5},{-10,5},{-9,5} 109 | }, 110 | { 111 | {0,-11},{0,-10},{0,-9}, 112 | {1,-11},{1,-10},{1,-9}, 113 | {2,-11},{2,-10},{2,-9}, 114 | {3,-11},{3,-10},{3,-9}, 115 | {4,-11},{4,-10},{4,-9}, 116 | {5,-11},{5,-10},{5,-9} 117 | } 118 | }; 119 | 120 | class Qr{ 121 | public: 122 | int model; 123 | int version; 124 | int cells_par_side; 125 | 126 | //int finder_pattern; 127 | //int timing_pattern; 128 | //int alignment_pattern; 129 | 130 | short status; 131 | 132 | FormatInfo *formatinfo; 133 | CodeData *codedata; 134 | 135 | private: 136 | int _finder_c; 137 | int _timing_c; 138 | int _alignment_x; 139 | int _alignment_y; 140 | int _alignment_i; 141 | int _alignment_j; 142 | int _version_c; 143 | 144 | public: 145 | Qr(); 146 | ~Qr(); 147 | 148 | int set_version(int v); 149 | int decode_version(unsigned char *data); //FIXME 150 | 151 | int decode_formatinfo(unsigned short data); 152 | 153 | Qr *init_each_finder_pattern_pixel(); 154 | Qr *init_each_timing_pattern_pixel(); 155 | Qr *init_each_alignment_pattern_pixel(); 156 | Qr *init_each_version_pattern_pixel(); 157 | Qr *init_each_formatinfo_pattern_pixel(); 158 | Qr *init_each_function_pattern_pixel(); 159 | 160 | Qr *each_finder_pattern_pixel(int *x,int *y); 161 | Qr *each_timing_pattern_pixel(int *x,int *y); 162 | Qr *each_alignment_pattern_pixel(int *x,int *y); 163 | Qr *each_version_pattern_pixel(int *x,int *y); 164 | Qr *each_version_pattern_pixel(int pos,int *x,int *y); 165 | Qr *each_formatinfo_pattern_pixel(int *x,int *y); 166 | Qr *each_formatinfo_pattern_pixel(int pos,int *x,int *y); 167 | Qr *each_function_pattern_pixel(int *x,int *y); 168 | 169 | unsigned char *push_codedata(unsigned char data); 170 | int decode_codedata(); 171 | }; 172 | 173 | } 174 | 175 | #endif 176 | -------------------------------------------------------------------------------- /libdecodeqr/formatinfo.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // formatinfo.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 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;ierror_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 | } 196 | -------------------------------------------------------------------------------- /examples/webcam/webcam.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // webcam.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #include 15 | #include 16 | #include 17 | #include "../../libdecodeqr/decodeqr.h" 18 | 19 | int usage(char *program_name); 20 | 21 | int main(int argc,char *argv[]) 22 | { 23 | int show_bin_image=0; 24 | 25 | if(argc>1){ 26 | if(strcmp(argv[1],"-d")) 27 | return(usage(argv[0])); 28 | else 29 | show_bin_image=1; 30 | } 31 | 32 | 33 | // 34 | // start camera 35 | // 36 | CvCapture *capture=cvCaptureFromCAM(0); 37 | if(!capture) 38 | return(-1); 39 | 40 | // 41 | // initialize qr decoder 42 | // 43 | QrDecoderHandle decoder=qr_decoder_open(); 44 | printf("libdecodeqr version %s\n",qr_decoder_version()); 45 | 46 | 47 | cvNamedWindow("src",1); 48 | 49 | if(show_bin_image) 50 | cvNamedWindow("bin",1); 51 | 52 | puts("Hit [SPACE] key to grab, or any key to end."); 53 | puts(""); 54 | 55 | // 56 | // 1 shot grabing 57 | // 58 | // 59 | // allocate grabed buffer to decoder 60 | // 61 | int key=-1; 62 | 63 | IplImage *camera=cvQueryFrame(capture); 64 | IplImage *src=NULL,*bin=NULL; 65 | if(camera){ 66 | src=cvCloneImage(camera); 67 | qr_decoder_set_image_buffer(decoder,src); 68 | } 69 | else 70 | key=1; 71 | 72 | unsigned char *text=NULL; 73 | int text_size=0; 74 | 75 | while(key<=0){ 76 | cvShowImage("src",camera); 77 | key=cvWaitKey(150); 78 | 79 | // 80 | // when [SPACE] key pressed, do decode. 81 | // 82 | if((key==0x20 || key==1048608)&&!qr_decoder_is_busy(decoder)){ 83 | key=-1; 84 | 85 | // 86 | // if left-bottom origin (MS-Windows style) format, 87 | // it must be converted to left-top origin. 88 | // 89 | if(camera->origin) 90 | cvConvertImage(camera,src,CV_CVTIMG_FLIP); 91 | else 92 | cvCopy(camera,src); 93 | 94 | // 95 | // While decoding is a failure, decrease the 96 | // adaptive_th_size parameter. 97 | // Note that the adaptive_th_size must be odd. 98 | // 99 | short sz,stat; 100 | for(sz=25,stat=0; 101 | (sz>=3)&&((stat&QR_IMAGEREADER_DECODED)==0); 102 | sz-=2) 103 | stat=qr_decoder_decode(decoder,sz); 104 | 105 | // 106 | // for debug, show binarized image. 107 | // 108 | if(bin) 109 | cvReleaseImage(&bin); 110 | if(show_bin_image){ 111 | bin=cvCloneImage(qr_decoder_get_binarized_image_buffer(decoder)); 112 | cvShowImage("bin",bin); 113 | } 114 | printf("adaptive_th_size=%d, status=%04x\n",sz,stat); 115 | 116 | // 117 | // on suceed decoding, print decoded text. 118 | // 119 | QrCodeHeader header; 120 | if(qr_decoder_get_header(decoder,&header)){ 121 | if(text_sizeorigin) 158 | cvConvertImage(src,src,CV_CVTIMG_FLIP); 159 | 160 | cvShowImage("src",src); 161 | 162 | // 163 | // wait 1500msec. 164 | // 165 | key=cvWaitKey(1500); 166 | } 167 | } 168 | 169 | camera=cvQueryFrame(capture); 170 | if(!camera) 171 | break; 172 | } 173 | 174 | if(text) 175 | delete [] text; 176 | 177 | qr_decoder_close(decoder); 178 | if(bin) 179 | cvReleaseImage(&bin); 180 | if(src) 181 | cvReleaseImage(&src); 182 | 183 | cvReleaseCapture(&capture); 184 | 185 | return(0); 186 | } 187 | 188 | 189 | int usage(char *program_name) 190 | { 191 | fprintf(stderr,"usage: %s [-d|-h]\n",program_name); 192 | fprintf(stderr,"-d\tturn on debug mode.\n"); 193 | fprintf(stderr,"-h\tshow thismessage and quit.\n\n"); 194 | 195 | return(-1); 196 | } 197 | -------------------------------------------------------------------------------- /libdecodeqr/libdecodeqr.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // libdecodeqr.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #include "imagereader.h" 15 | #include "qrtypes.h" 16 | #include "version.h" 17 | 18 | extern "C" { 19 | 20 | QrDecoderHandle qr_decoder_open() 21 | { 22 | Qr::ImageReader *imagereader=new Qr::ImageReader(); 23 | return((QrDecoderHandle)imagereader); 24 | } 25 | 26 | QrDecoderHandle qr_decoder_open_with_image_size(int width,int height, 27 | int depth,int channel) 28 | { 29 | Qr::ImageReader *imagereader=new Qr::ImageReader(width,height, 30 | depth,channel); 31 | return((QrDecoderHandle)imagereader); 32 | } 33 | 34 | void qr_decoder_close(QrDecoderHandle decoder) 35 | { 36 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 37 | delete imagereader; 38 | } 39 | 40 | short qr_decoder_get_status(QrDecoderHandle decoder) 41 | { 42 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 43 | return(imagereader->status); 44 | } 45 | 46 | int qr_decoder_is_busy(QrDecoderHandle decoder) 47 | { 48 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 49 | return(imagereader->status&QR_IMAGEREADER_WORKING?1:0); 50 | } 51 | 52 | 53 | QrDecoderHandle qr_decoder_set_image_size(QrDecoderHandle decoder, 54 | int width,int height, 55 | int depth,int channel) 56 | { 57 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 58 | imagereader->set_image(width,height,depth,channel); 59 | 60 | return((QrDecoderHandle)imagereader); 61 | } 62 | 63 | 64 | IplImage *qr_decoder_get_image_buffer(QrDecoderHandle decoder) 65 | { 66 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 67 | return(imagereader->src_buffer()); 68 | } 69 | IplImage *qr_decoder_get_transformed_image_buffer(QrDecoderHandle decoder) 70 | { 71 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 72 | return(imagereader->transformed_buffer()); 73 | } 74 | IplImage *qr_decoder_get_binarized_image_buffer(QrDecoderHandle decoder) 75 | { 76 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 77 | return(imagereader->binarized_buffer()); 78 | } 79 | IplImage *qr_decoder_get_tmp_image_buffer(QrDecoderHandle decoder) 80 | { 81 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 82 | return(imagereader->tmp_buffer()); 83 | } 84 | 85 | QrDecoderHandle qr_decoder_set_image_buffer(QrDecoderHandle decoder, 86 | IplImage *src) 87 | { 88 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 89 | imagereader->set_image(src); 90 | 91 | return((QrDecoderHandle)imagereader); 92 | } 93 | 94 | short qr_decoder_decode(QrDecoderHandle decoder, 95 | int adaptive_th_size, 96 | int adaptive_th_delta) 97 | { 98 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 99 | imagereader->decode(adaptive_th_size,adaptive_th_delta); 100 | return(imagereader->status); 101 | } 102 | 103 | short qr_decoder_decode_image(QrDecoderHandle decoder, 104 | IplImage *src, 105 | int adaptive_th_size, 106 | int adaptive_th_delta) 107 | { 108 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 109 | imagereader->decode(src,adaptive_th_size,adaptive_th_delta); 110 | return(imagereader->status); 111 | } 112 | 113 | int qr_decoder_get_header(QrDecoderHandle decoder, 114 | QrCodeHeader *header) 115 | { 116 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 117 | if(!(imagereader->status&QR_IMAGEREADER_DECODED)) 118 | return(0); 119 | 120 | header->model=imagereader->qr->model; 121 | header->version=imagereader->qr->version; 122 | header->level=imagereader->qr->formatinfo->level; 123 | //header->mode=0; 124 | //header->eci_mode=0; 125 | header->charactor_size=imagereader->qr->codedata->length; 126 | header->byte_size=imagereader->qr->codedata->byte_length; 127 | 128 | return(1); 129 | } 130 | 131 | int qr_decoder_get_body(QrDecoderHandle decoder, 132 | unsigned char *buf, 133 | int buf_size) 134 | { 135 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 136 | if(!(imagereader->status&QR_IMAGEREADER_DECODED)) 137 | return(0); 138 | 139 | memset(buf,0,buf_size); 140 | int size=imagereader->qr->codedata->byte_length; 141 | if(size>buf_size) 142 | size=buf_size; 143 | 144 | memcpy(buf,imagereader->qr->codedata->raw_data(),size); 145 | 146 | return(size); 147 | } 148 | 149 | CvPoint *qr_decoder_get_coderegion_vertexes(QrDecoderHandle decoder) 150 | { 151 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 152 | return(imagereader->coderegion_vertexes()); 153 | } 154 | 155 | CvBox2D *qr_decoder_get_finderpattern_boxes(QrDecoderHandle decoder) 156 | { 157 | Qr::ImageReader *imagereader=(Qr::ImageReader *)decoder; 158 | return(imagereader->finderpattern_boxes()); 159 | } 160 | 161 | 162 | char *qr_decoder_version() 163 | { 164 | return(LIBDECODEQR_VERSION); 165 | } 166 | char *qr_decoder_version_description() 167 | { 168 | return(LIBDECODEQR_VERSION_DESCRIPTION); 169 | } 170 | char *qr_decoder_version_product() 171 | { 172 | return(LIBDECODEQR_PRODUCTNAME); 173 | } 174 | int qr_decoder_version_major() 175 | { 176 | return(LIBDECODEQR_VERSION_MAJOR); 177 | } 178 | int qr_decoder_version_minor() 179 | { 180 | return(LIBDECODEQR_VERSION_MINOR); 181 | } 182 | int qr_decoder_version_teeny() 183 | { 184 | return(LIBDECODEQR_VERSION_TEENY); 185 | } 186 | char *qr_decoder_version_suffix() 187 | { 188 | return(LIBDECODEQR_VERSION_SUFFIX); 189 | } 190 | char *qr_decoder_version_revision() 191 | { 192 | return(LIBDECODEQR_VERSION_REVISION); 193 | } 194 | 195 | } 196 | -------------------------------------------------------------------------------- /libdecodeqr/libdecodeqr.mak: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Generated NMAKE File, Based on libdecodeqr.dsp 2 | !IF "$(CFG)" == "" 3 | CFG=libdecodeqr - Win32 Debug 4 | !MESSAGE Missing target. Using defualt "libdecodeqr - Win32 Debug". 5 | !ENDIF 6 | 7 | !IF "$(CFG)" != "libdecodeqr - Win32 Release" && "$(CFG)" != "libdecodeqr - Win32 Debug" 8 | !MESSAGE Mode "$(CFG)" is not valid. 9 | !MESSAGE 10 | !MESSAGE Valid modes are: 11 | !MESSAGE 12 | !MESSAGE "libdecodeqr - Win32 Release" (for "Win32 (x86) Static Library") 13 | !MESSAGE "libdecodeqr - Win32 Debug" (for "Win32 (x86) Static Library") 14 | !MESSAGE 15 | !MESSAGE eg: 16 | !MESSAGE 17 | !MESSAGE NMAKE /f "libdecodeqr.mak" CFG="libdecodeqr - Win32 Debug" 18 | !ERROR Invalid target are gaven. 19 | !ENDIF 20 | 21 | !IF "$(OS)" == "Windows_NT" 22 | NULL= 23 | !ELSE 24 | NULL=nul 25 | !ENDIF 26 | 27 | !IF "$(CFG)" == "libdecodeqr - Win32 Release" 28 | 29 | OUTDIR=.\Release 30 | INTDIR=.\Release 31 | # Begin Custom Macros 32 | OutDir=.\Release 33 | # End Custom Macros 34 | 35 | ALL : "$(OUTDIR)\libdecodeqr.lib" 36 | 37 | 38 | CLEAN : 39 | -@erase "$(INTDIR)\bitstream.obj" 40 | -@erase "$(INTDIR)\codedata.obj" 41 | -@erase "$(INTDIR)\container.obj" 42 | -@erase "$(INTDIR)\ecidecoder.obj" 43 | -@erase "$(INTDIR)\formatinfo.obj" 44 | -@erase "$(INTDIR)\galois.obj" 45 | -@erase "$(INTDIR)\imagereader.obj" 46 | -@erase "$(INTDIR)\libdecodeqr.obj" 47 | -@erase "$(INTDIR)\vc60.idb" 48 | -@erase "$(OUTDIR)\libdecodeqr.lib" 49 | 50 | "$(OUTDIR)" : 51 | if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" 52 | 53 | CPP=cl.exe 54 | CPP_PROJ=/nologo /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"$(INTDIR)\libdecodeqr.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 55 | 56 | .c{$(INTDIR)}.obj:: 57 | $(CPP) @<< 58 | $(CPP_PROJ) $< 59 | << 60 | 61 | .cpp{$(INTDIR)}.obj:: 62 | $(CPP) @<< 63 | $(CPP_PROJ) $< 64 | << 65 | 66 | .cxx{$(INTDIR)}.obj:: 67 | $(CPP) @<< 68 | $(CPP_PROJ) $< 69 | << 70 | 71 | .c{$(INTDIR)}.sbr:: 72 | $(CPP) @<< 73 | $(CPP_PROJ) $< 74 | << 75 | 76 | .cpp{$(INTDIR)}.sbr:: 77 | $(CPP) @<< 78 | $(CPP_PROJ) $< 79 | << 80 | 81 | .cxx{$(INTDIR)}.sbr:: 82 | $(CPP) @<< 83 | $(CPP_PROJ) $< 84 | << 85 | 86 | RSC=rc.exe 87 | BSC32=bscmake.exe 88 | BSC32_FLAGS=/nologo /o"$(OUTDIR)\libdecodeqr.bsc" 89 | BSC32_SBRS= \ 90 | 91 | LIB32=link.exe -lib 92 | LIB32_FLAGS=/nologo /out:"$(OUTDIR)\libdecodeqr.lib" 93 | LIB32_OBJS= \ 94 | "$(INTDIR)\bitstream.obj" \ 95 | "$(INTDIR)\codedata.obj" \ 96 | "$(INTDIR)\container.obj" \ 97 | "$(INTDIR)\ecidecoder.obj" \ 98 | "$(INTDIR)\formatinfo.obj" \ 99 | "$(INTDIR)\galois.obj" \ 100 | "$(INTDIR)\imagereader.obj" \ 101 | "$(INTDIR)\libdecodeqr.obj" 102 | 103 | "$(OUTDIR)\libdecodeqr.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) 104 | $(LIB32) @<< 105 | $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) 106 | << 107 | 108 | !ELSEIF "$(CFG)" == "libdecodeqr - Win32 Debug" 109 | 110 | OUTDIR=.\Debug 111 | INTDIR=.\Debug 112 | # Begin Custom Macros 113 | OutDir=.\Debug 114 | # End Custom Macros 115 | 116 | ALL : "$(OUTDIR)\libdecodeqr.lib" 117 | 118 | 119 | CLEAN : 120 | -@erase "$(INTDIR)\bitstream.obj" 121 | -@erase "$(INTDIR)\codedata.obj" 122 | -@erase "$(INTDIR)\container.obj" 123 | -@erase "$(INTDIR)\ecidecoder.obj" 124 | -@erase "$(INTDIR)\formatinfo.obj" 125 | -@erase "$(INTDIR)\galois.obj" 126 | -@erase "$(INTDIR)\imagereader.obj" 127 | -@erase "$(INTDIR)\libdecodeqr.obj" 128 | -@erase "$(INTDIR)\vc60.idb" 129 | -@erase "$(INTDIR)\vc60.pdb" 130 | -@erase "$(OUTDIR)\libdecodeqr.lib" 131 | 132 | "$(OUTDIR)" : 133 | if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" 134 | 135 | CPP=cl.exe 136 | CPP_PROJ=/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /Fp"$(INTDIR)\libdecodeqr.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 137 | 138 | .c{$(INTDIR)}.obj:: 139 | $(CPP) @<< 140 | $(CPP_PROJ) $< 141 | << 142 | 143 | .cpp{$(INTDIR)}.obj:: 144 | $(CPP) @<< 145 | $(CPP_PROJ) $< 146 | << 147 | 148 | .cxx{$(INTDIR)}.obj:: 149 | $(CPP) @<< 150 | $(CPP_PROJ) $< 151 | << 152 | 153 | .c{$(INTDIR)}.sbr:: 154 | $(CPP) @<< 155 | $(CPP_PROJ) $< 156 | << 157 | 158 | .cpp{$(INTDIR)}.sbr:: 159 | $(CPP) @<< 160 | $(CPP_PROJ) $< 161 | << 162 | 163 | .cxx{$(INTDIR)}.sbr:: 164 | $(CPP) @<< 165 | $(CPP_PROJ) $< 166 | << 167 | 168 | RSC=rc.exe 169 | BSC32=bscmake.exe 170 | BSC32_FLAGS=/nologo /o"$(OUTDIR)\libdecodeqr.bsc" 171 | BSC32_SBRS= \ 172 | 173 | LIB32=link.exe -lib 174 | LIB32_FLAGS=/nologo /out:"$(OUTDIR)\libdecodeqr.lib" 175 | LIB32_OBJS= \ 176 | "$(INTDIR)\bitstream.obj" \ 177 | "$(INTDIR)\codedata.obj" \ 178 | "$(INTDIR)\container.obj" \ 179 | "$(INTDIR)\ecidecoder.obj" \ 180 | "$(INTDIR)\formatinfo.obj" \ 181 | "$(INTDIR)\galois.obj" \ 182 | "$(INTDIR)\imagereader.obj" \ 183 | "$(INTDIR)\libdecodeqr.obj" 184 | 185 | "$(OUTDIR)\libdecodeqr.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) 186 | $(LIB32) @<< 187 | $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) 188 | << 189 | 190 | !ENDIF 191 | 192 | 193 | !IF "$(NO_EXTERNAL_DEPS)" != "1" 194 | !IF EXISTS("libdecodeqr.dep") 195 | !INCLUDE "libdecodeqr.dep" 196 | !ELSE 197 | !MESSAGE Warning: cannot find "libdecodeqr.dep" 198 | !ENDIF 199 | !ENDIF 200 | 201 | 202 | !IF "$(CFG)" == "libdecodeqr - Win32 Release" || "$(CFG)" == "libdecodeqr - Win32 Debug" 203 | SOURCE=.\bitstream.cpp 204 | 205 | "$(INTDIR)\bitstream.obj" : $(SOURCE) "$(INTDIR)" 206 | 207 | 208 | SOURCE=.\codedata.cpp 209 | 210 | "$(INTDIR)\codedata.obj" : $(SOURCE) "$(INTDIR)" 211 | 212 | 213 | SOURCE=.\container.cpp 214 | 215 | "$(INTDIR)\container.obj" : $(SOURCE) "$(INTDIR)" 216 | 217 | 218 | SOURCE=.\ecidecoder.cpp 219 | 220 | "$(INTDIR)\ecidecoder.obj" : $(SOURCE) "$(INTDIR)" 221 | 222 | 223 | SOURCE=.\formatinfo.cpp 224 | 225 | "$(INTDIR)\formatinfo.obj" : $(SOURCE) "$(INTDIR)" 226 | 227 | 228 | SOURCE=.\galois.cpp 229 | 230 | "$(INTDIR)\galois.obj" : $(SOURCE) "$(INTDIR)" 231 | 232 | 233 | SOURCE=.\imagereader.cpp 234 | 235 | "$(INTDIR)\imagereader.obj" : $(SOURCE) "$(INTDIR)" 236 | 237 | 238 | SOURCE=.\libdecodeqr.cpp 239 | 240 | "$(INTDIR)\libdecodeqr.obj" : $(SOURCE) "$(INTDIR)" 241 | 242 | 243 | 244 | !ENDIF 245 | 246 | -------------------------------------------------------------------------------- /libdecodeqr/container.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // container.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #include "container.h" 15 | 16 | namespace Qr{ 17 | 18 | Qr::Qr() 19 | { 20 | this->model=2; 21 | this->version=0; 22 | this->cells_par_side=0; 23 | 24 | this->formatinfo=new FormatInfo(); 25 | this->codedata=NULL; 26 | 27 | this->status=0; 28 | } 29 | Qr::~Qr() 30 | { 31 | if(this->codedata) 32 | delete this->codedata; 33 | 34 | delete this->formatinfo; 35 | } 36 | 37 | int Qr::set_version(int v) 38 | { 39 | if(v<1||v>40){ 40 | this->status|=QR_VERSIONINFO_INVALID; 41 | throw(0); 42 | } 43 | 44 | this->version=v; 45 | this->cells_par_side=this->version*4+17; 46 | return(this->version); 47 | } 48 | int Qr::decode_version(unsigned char *data) 49 | { 50 | // FIXME 51 | return(this->version); 52 | } 53 | 54 | int Qr::decode_formatinfo(unsigned short data) 55 | { 56 | this->status&=(~QR_FORMATINFO_ERROR); 57 | 58 | int ret=this->formatinfo->decode_formatinfo(data); 59 | this->status|=this->formatinfo->status; 60 | 61 | if(this->codedata) 62 | delete this->codedata; 63 | 64 | this->codedata=new CodeData(this->version,this->formatinfo->level); 65 | 66 | return(ret); 67 | } 68 | 69 | Qr *Qr::init_each_finder_pattern_pixel() 70 | { 71 | this->_finder_c=0; 72 | return(this); 73 | } 74 | Qr *Qr::init_each_timing_pattern_pixel() 75 | { 76 | this->_timing_c=0; 77 | return(this); 78 | } 79 | Qr *Qr::init_each_alignment_pattern_pixel() 80 | { 81 | this->_alignment_x=2; 82 | this->_alignment_y=1; 83 | this->_alignment_i=-2; 84 | this->_alignment_j=-2; 85 | return(this); 86 | } 87 | Qr *Qr::init_each_version_pattern_pixel() 88 | { 89 | this->_version_c=0; 90 | return(this); 91 | } 92 | Qr *Qr::init_each_formatinfo_pattern_pixel() 93 | { 94 | this->formatinfo->init_each_pattern_pixel(); 95 | return(this); 96 | } 97 | Qr *Qr::init_each_function_pattern_pixel() 98 | { 99 | this->init_each_finder_pattern_pixel(); 100 | this->init_each_timing_pattern_pixel(); 101 | this->init_each_alignment_pattern_pixel(); 102 | this->init_each_version_pattern_pixel(); 103 | this->init_each_formatinfo_pattern_pixel(); 104 | return(this); 105 | } 106 | 107 | Qr *Qr::each_finder_pattern_pixel(int *x,int *y) 108 | { 109 | int c=this->_finder_c; 110 | 111 | // 112 | // 8x8x3 pixels 113 | // 114 | if(this->_finder_c<64){ 115 | *x=c%8; 116 | *y=c/8; 117 | } 118 | else if(this->_finder_c<128){ 119 | c-=64; 120 | *x=this->cells_par_side-8+c%8; 121 | *y=c/8; 122 | } 123 | else if(this->_finder_c<192){ 124 | c-=128; 125 | *x=c%8; 126 | *y=this->cells_par_side-8+c/8; 127 | } 128 | else 129 | return(NULL); 130 | 131 | this->_finder_c++; 132 | return(this); 133 | } 134 | 135 | Qr *Qr::each_timing_pattern_pixel(int *x,int *y) 136 | { 137 | if(this->_timing_ccells_par_side){ 138 | *x=6; 139 | *y=this->_timing_c; 140 | } 141 | else if(this->_timing_ccells_par_side*2){ 142 | *x=this->_timing_c-this->cells_par_side; 143 | *y=6; 144 | } 145 | else 146 | return(NULL); 147 | 148 | this->_timing_c++; 149 | return(this); 150 | } 151 | 152 | Qr *Qr::each_alignment_pattern_pixel(int *x,int *y) 153 | { 154 | int c=alignment_pattern_addr[this->version][0]+1; 155 | 156 | if((this->_alignment_y==1)&&(this->_alignment_x>=c-1)){ 157 | this->_alignment_y++; 158 | if(this->_alignment_y==1||this->_alignment_y==c-1) 159 | this->_alignment_x=2; 160 | else 161 | this->_alignment_x=1; 162 | } 163 | if(this->_alignment_y>=c) 164 | return(NULL); 165 | 166 | *x=alignment_pattern_addr[version][this->_alignment_x]+ 167 | this->_alignment_j; 168 | *y=alignment_pattern_addr[version][this->_alignment_y]+ 169 | this->_alignment_i; 170 | 171 | this->_alignment_j++; 172 | if(this->_alignment_j>2){ 173 | this->_alignment_j=-2; 174 | this->_alignment_i++; 175 | 176 | if(this->_alignment_i>2){ 177 | this->_alignment_i=-2; 178 | this->_alignment_x++; 179 | 180 | if((this->_alignment_x>=c)|| 181 | ((this->_alignment_y==1)&&(this->_alignment_x>=c-1))){ 182 | this->_alignment_y++; 183 | if(this->_alignment_y==1||this->_alignment_y==c-1) 184 | this->_alignment_x=2; 185 | else 186 | this->_alignment_x=1; 187 | } 188 | } 189 | } 190 | 191 | return(this); 192 | } 193 | 194 | Qr *Qr::each_version_pattern_pixel(int *x,int *y) 195 | { 196 | if(this->version<7) 197 | return(NULL); 198 | 199 | if(this->_version_c<18){ 200 | *x=version_info_addr[0][this->_version_c][0]; 201 | *y=version_info_addr[0][this->_version_c][1]; 202 | } 203 | else if(this->_version_c<36){ 204 | *x=version_info_addr[1][this->_version_c-18][0]; 205 | *y=version_info_addr[1][this->_version_c-18][1]; 206 | } 207 | else 208 | return(NULL); 209 | 210 | if(*x<0) 211 | *x+=this->cells_par_side; 212 | if(*y<0) 213 | *y+=this->cells_par_side; 214 | this->_version_c++; 215 | return(this); 216 | } 217 | Qr *Qr::each_version_pattern_pixel(int pos,int *x,int *y) 218 | { 219 | if(this->version<7) 220 | return(NULL); 221 | 222 | if(this->_version_c<18){ 223 | *x=version_info_addr[pos][this->_version_c][0]; 224 | *y=version_info_addr[pos][this->_version_c][1]; 225 | } 226 | else 227 | return(NULL); 228 | 229 | if(*x<0) 230 | *x+=this->cells_par_side; 231 | if(*y<0) 232 | *y+=this->cells_par_side; 233 | this->_version_c++; 234 | return(this); 235 | } 236 | 237 | Qr *Qr::each_formatinfo_pattern_pixel(int *x,int *y) 238 | { 239 | if(this->formatinfo->each_pattern_pixel(x,y)){ 240 | if(*x<0) 241 | *x+=this->cells_par_side; 242 | if(*y<0) 243 | *y+=this->cells_par_side; 244 | return(this); 245 | } 246 | else 247 | return(NULL); 248 | } 249 | Qr *Qr::each_formatinfo_pattern_pixel(int pos,int *x,int *y) 250 | { 251 | if(this->formatinfo->each_pattern_pixel(pos,x,y)){ 252 | if(*x<0) 253 | *x+=this->cells_par_side; 254 | if(*y<0) 255 | *y+=this->cells_par_side; 256 | return(this); 257 | } 258 | else 259 | return(NULL); 260 | } 261 | 262 | Qr *Qr::each_function_pattern_pixel(int *x,int *y) 263 | { 264 | if(this->each_finder_pattern_pixel(x,y)) 265 | return(this); 266 | if(this->each_timing_pattern_pixel(x,y)) 267 | return(this); 268 | if(this->each_alignment_pattern_pixel(x,y)) 269 | return(this); 270 | if(this->each_version_pattern_pixel(x,y)) 271 | return(this); 272 | return(this->each_formatinfo_pattern_pixel(x,y)); 273 | } 274 | 275 | unsigned char *Qr::push_codedata(unsigned char data) 276 | { 277 | return(this->codedata->push(data)); 278 | } 279 | 280 | 281 | int Qr::decode_codedata() 282 | { 283 | int ret=this->codedata->decode(); 284 | this->status|=this->codedata->status; 285 | 286 | return(ret); 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /libdecodeqr/decodeqr.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // libdecodeqr.h --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #ifndef __QR_DECODER__ 15 | #define __QR_DECODER__ 16 | 17 | #include 18 | #include "qrerror.h" 19 | #include "qrtypes.h" 20 | 21 | #define DEFAULT_ADAPTIVE_TH_SIZE 25 22 | #define DEFAULT_ADAPTIVE_TH_DELTA 10 23 | 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | ///////////////////////////////////////////////////////////////////////// 30 | // 31 | // initializer 32 | // 33 | // ARGS: none 34 | // RETURN: 35 | // QrDecoderHandle handle 36 | // 37 | extern QrDecoderHandle qr_decoder_open(); 38 | 39 | ///////////////////////////////////////////////////////////////////////// 40 | // 41 | // initializer with source image size 42 | // 43 | // ARGS: 44 | // int width: pixel width of source image 45 | // int height: pixel height of source image 46 | // int depth: image depth (bit par pixel; use OpenCV IPL_DEPTH_*) 47 | // int channel: number of image channel 48 | // 49 | // RETURN: 50 | // QrDecoderHandle handle 51 | // 52 | // NOTE: 53 | // 24-bit full color image has IPL_DEPTH_8U depth and 3 channels. 54 | // 55 | extern QrDecoderHandle qr_decoder_open_with_image_size( 56 | int width,int height,int depth,int channel); 57 | 58 | 59 | ///////////////////////////////////////////////////////////////////////// 60 | // 61 | // finalizer 62 | // 63 | // ARGS: 64 | // QrDecoderHandle decoder: handler 65 | // 66 | // RETURN: none 67 | // 68 | extern void qr_decoder_close(QrDecoderHandle decoder); 69 | 70 | 71 | ///////////////////////////////////////////////////////////////////////// 72 | // 73 | // get status 74 | // 75 | // ARGS: 76 | // QrDecoderHandle decoder: handler 77 | // 78 | // RETURN: status code 79 | // 80 | extern short qr_decoder_get_status(QrDecoderHandle decoder); 81 | 82 | ///////////////////////////////////////////////////////////////////////// 83 | // 84 | // get working status 85 | // 86 | // ARGS: 87 | // QrDecoderHandle decoder: handler 88 | // 89 | // RETURN: status code 90 | // 91 | extern int qr_decoder_is_busy(QrDecoderHandle decoder); 92 | 93 | 94 | ///////////////////////////////////////////////////////////////////////// 95 | // 96 | // set source image size 97 | // 98 | // ARGS: 99 | // QrDecoderHandle decoder: handler 100 | // int width: pixel width of source image 101 | // int height: pixel height of source image 102 | // int depth: image depth (bit par pixel; use OpenCV IPL_DEPTH_*) 103 | // int channel: number of image channel 104 | // 105 | // RETURN: 106 | // QrDecoderHandle handle 107 | // 108 | // NOTE: 109 | // This method provide same function as qr_decoder_open_with_image_size(). 110 | // 111 | extern QrDecoderHandle qr_decoder_set_image_size( 112 | QrDecoderHandle decoder,int width,int height,int depth,int channel); 113 | 114 | 115 | ///////////////////////////////////////////////////////////////////////// 116 | // 117 | // preset gaven image as source image 118 | // 119 | // ARGS: 120 | // QrDecoderHandle decoder: handler 121 | // IplImage *src: source image 122 | // 123 | // RETURN: 124 | // QrDecoderHandle handle 125 | // 126 | extern QrDecoderHandle qr_decoder_set_image_buffer( 127 | QrDecoderHandle decoder,IplImage *src); 128 | 129 | ///////////////////////////////////////////////////////////////////////// 130 | // 131 | // get source image buffer 132 | // 133 | // ARGS: 134 | // QrDecoderHandle decoder: handler 135 | // 136 | // RETURN: 137 | // IplImage *: pointer to buffer source image|NULL 138 | // 139 | // NOTE: 140 | // See OpenCV reference manual to access to IplImage * 141 | // 142 | extern IplImage *qr_decoder_get_image_buffer(QrDecoderHandle decoder); 143 | 144 | extern IplImage *qr_decoder_get_transformed_image_buffer( 145 | QrDecoderHandle decoder); 146 | extern IplImage *qr_decoder_get_binarized_image_buffer( 147 | QrDecoderHandle decoder); 148 | extern IplImage *qr_decoder_get_tmp_image_buffer( 149 | QrDecoderHandle decoder); 150 | 151 | ///////////////////////////////////////////////////////////////////////// 152 | // 153 | // decode preset source image 154 | // 155 | // ARGS: 156 | // QrDecoderHandle decoder: handler 157 | // int adaptive_th_size: value of AdaptiveThreshold size 158 | // int adaptive_th_delta: value of AdaptiveThreshold delta 159 | // 160 | // RETURN: 161 | // short: status code of decoder 162 | // 163 | // NOTE: 164 | // On succeeded, status code has 0x2000. 165 | // See qrtypes.h for details of status code. 166 | // 167 | // In case of adaptive_th_size=0, binarizing methods will be 168 | // used cvThreshlod() instead of cvAdaptiveThreshold() 169 | // 170 | #ifdef __cplusplus 171 | extern short qr_decoder_decode(QrDecoderHandle decoder, 172 | int adaptive_th_size= 173 | DEFAULT_ADAPTIVE_TH_SIZE, 174 | int adaptive_th_delta= 175 | DEFAULT_ADAPTIVE_TH_DELTA); 176 | #else 177 | extern short qr_decoder_decode(QrDecoderHandle decoder, 178 | int adaptive_th_size, 179 | int adaptive_th_delta); 180 | #endif 181 | 182 | ///////////////////////////////////////////////////////////////////////// 183 | // 184 | // decode gaven image 185 | // 186 | // ARGS: 187 | // QrDecoderHandle decoder: handler 188 | // IplImage *src: image to decode 189 | // int adaptive_th_size: value of AdaptiveThreshold size 190 | // int adaptive_th_delta: value of AdaptiveThreshold delta 191 | // 192 | // RETURN: 193 | // short: status code of decoder 194 | // 195 | #ifdef __cplusplus 196 | extern short qr_decoder_decode_image(QrDecoderHandle decoder, 197 | IplImage *src, 198 | int adaptive_th_size= 199 | DEFAULT_ADAPTIVE_TH_SIZE, 200 | int adaptive_th_delta= 201 | DEFAULT_ADAPTIVE_TH_DELTA); 202 | #else 203 | extern short qr_decoder_decode_image(QrDecoderHandle decoder, 204 | IplImage *src, 205 | int adaptive_th_size, 206 | int adaptive_th_delta); 207 | #endif 208 | 209 | ///////////////////////////////////////////////////////////////////////// 210 | // 211 | // get abstruction of decoded data 212 | // 213 | // ARGS: 214 | // QrDecoderHandle decoder: handler 215 | // QrCodeHeader *header: pointer to buffer of header 216 | // 217 | // RETURN: 218 | // 1 (on success)||0 (on error) 219 | // 220 | extern int qr_decoder_get_header(QrDecoderHandle decoder, 221 | QrCodeHeader *header); 222 | 223 | ///////////////////////////////////////////////////////////////////////// 224 | // 225 | // get decoded text data 226 | // 227 | // ARGS: 228 | // QrDecoderHandle decoder: handler 229 | // unsigned char *buf: pointer to buffer of header 230 | // int buf_size: buffer size 231 | // 232 | // RETURN: 233 | // copied data size||0 (on error) 234 | // 235 | // NOTE: 236 | // The data DOES NOT TERMINATE with null. 237 | // To get actual buffer size, use QrCodeHeader's .byte_size element. 238 | // 239 | extern int qr_decoder_get_body(QrDecoderHandle decoder, 240 | unsigned char *buf,int buf_size); 241 | 242 | 243 | ///////////////////////////////////////////////////////////////////////// 244 | // 245 | // get vertexes of decoded code region 246 | // 247 | // ARGS: 248 | // QrDecoderHandle decoder: handler 249 | // 250 | // RETURN: 251 | // Pointer to CvPoint[4] which consist vertexes of code region 252 | // 253 | extern CvPoint *qr_decoder_get_coderegion_vertexes(QrDecoderHandle decoder); 254 | 255 | 256 | ///////////////////////////////////////////////////////////////////////// 257 | // 258 | // get Box array of decoded finder patterns 259 | // 260 | // ARGS: 261 | // QrDecoderHandle decoder: handler 262 | // 263 | // RETURN: 264 | // Pointer to CvBox2D[3] which consist boxes of finder pattern 265 | // 266 | extern CvBox2D *qr_decoder_get_finderpattern_boxes(QrDecoderHandle decoder); 267 | 268 | 269 | ///////////////////////////////////////////////////////////////////////// 270 | // 271 | // version information 272 | // 273 | extern char *qr_decoder_version(); 274 | extern char *qr_decoder_version_description(); 275 | extern char *qr_decoder_version_product(); 276 | extern int qr_decoder_version_major(); 277 | extern int qr_decoder_version_minor(); 278 | extern int qr_decoder_version_teeny(); 279 | extern char *qr_decoder_version_suffix(); 280 | extern char *qr_decoder_version_revision(); 281 | 282 | #ifdef __cplusplus 283 | } 284 | #endif 285 | 286 | #endif 287 | -------------------------------------------------------------------------------- /doc/ApiReference.ja: -------------------------------------------------------------------------------- 1 | = API = 2 | [[TOC(inline,depth=3)]] 3 | 4 | == 型および構造体 == 5 | 6 | === QrDecoderHandle === 7 | {{{ 8 | typedef void * QrDecoderHandle; 9 | }}} 10 | 11 | QRデコーダハンドル 12 | 13 | === QrCodeHeader === 14 | {{{ 15 | typedef struct{ 16 | int model; // モデル番号 17 | int version; // 型番 18 | int level; // 誤り訂正レベル 19 | //int mode; // 本文モード (未実装) 20 | //int eci_mode; // 本文ECIモード (未実装) 21 | int charactor_size; // 本文文字数 22 | int byte_size; // 本文バイト数 23 | } QrCodeHeader; 24 | }}} 25 | 26 | QRコードヘッダ構造体 27 | 28 | == コンストラクタ == 29 | 30 | === qr_decoder_open === 31 | {{{ 32 | QrDecoderHandle qr_decoder_open(); 33 | }}} 34 | 35 | * 引数: なし 36 | * 戻り値: QRデコーダハンドル 37 | 38 | デコーダを初期化する。 39 | 40 | === qr_decoder_open_with_image_size === 41 | {{{ 42 | QrDecoderHandle qr_decoder_open_with_image_size( 43 | int width, 44 | int height, 45 | int depth, 46 | int channel 47 | ); 48 | }}} 49 | 50 | * 引数: 51 | * int width : 画像バッファの幅(pixel) 52 | * int height : 画像バッファの高さ(pixel) 53 | * int depth : 画像バッファのピクセルあたりのbit数 54 | * int channel : 画像バッファのチャンネル数 55 | * 戻り値: QRデコーダハンドル 56 | 57 | 画像バッファの幅,高さ,ピクセルあたりのbit数,チャンネル数を指定してデコーダを初期化する。[[BR]] 58 | ピクセルあたりのbit数はIPL_DEPTH_8UなどOpenCVの定数を指定する。[[BR]] 59 | 一般的な24bitフルカラー画像では depth = IPL_DEPTH_8U, channel = 3 と指定する。 60 | 61 | 入力画像のサイズが既知の場合,バッファサイズを指定してデコーダを初期化することで,バッファ確保にかかるオーバーヘッドを低減できる。 62 | 63 | == デストラクタ == 64 | === qr_decoder_close === 65 | {{{ 66 | void qr_decoder_close(QrDecoderHandle decoder); 67 | }}} 68 | 69 | * 引数: 70 | * !QrDecoderHandle decoder : QRデコーダハンドル 71 | * 戻り値:なし 72 | 73 | デコーダ内の各バッファを破壊し終了処理を行う。 74 | 75 | == バッファ初期化 == 76 | 77 | Webカメラからの入力など,フォーマットの一定した画像を連続で扱う際に使用する。 78 | 79 | === qr_decoder_set_image_size === 80 | {{{ 81 | qr_decoder_set_image_size( 82 | QrDecoderHandle decoder, 83 | int width, 84 | int height, 85 | int depth, 86 | int channel 87 | ); 88 | }}} 89 | 90 | * 引数: 91 | * !QrDecoderHandle decoder : QRデコーダハンドル 92 | * int width : 画像バッファの幅(pixel) 93 | * int height : 画像バッファの高さ(pixel) 94 | * int depth : 画像バッファのピクセルあたりのbit数 95 | * int channel : 画像バッファのチャンネル数 96 | * 戻り値: QRデコーダハンドル 97 | 98 | デコーダの入力画像バッファの幅,高さ,ピクセルあたりのbit数,チャンネル数を指定する。[[BR]] 99 | qr_decoder_open()で初期化したデコーダのバッファのサイズ指定,およびqr_decoder_open_with_image_size()で初期化したデコーダのバッファサイズの再指定を行う。 100 | 101 | === qr_decoder_set_image_buffer === 102 | {{{ 103 | QrDecoderHandle qr_decoder_set_image_buffer( 104 | QrDecoderHandle decoder, 105 | IplImage *src 106 | ); 107 | }}} 108 | 109 | * 引数: 110 | * !QrDecoderHandle decoder : QRデコーダハンドル 111 | * !IplImage *src : 画像バッファへのポインタ 112 | * 戻り値: QRデコーダハンドル 113 | 114 | srcとして指定したIplImage形式の画像バッファをデコーダの画像バッファとする。[[BR]] 115 | 指定するバッファはtop-left origin (src->origin==0)で無ければならない。[[BR]] 116 | bottom-left origin (src->origin==1)の場合は,highguiのcvConvertImage()などでtop-left originに変換すること。 117 | 118 | IplImageの構造は[http://opencvlibrary.sourceforge.net/CxCore#head-b9f1e08636cc1f2bc532f3970cc41deaf5eedd9b OpenCVのマニュアル]を参照のこと。 119 | 120 | == バッファ取得 == 121 | === qr_decoder_get_image_buffer === 122 | {{{ 123 | IplImage *qr_decoder_get_image_buffer(QrDecoderHandle decoder); 124 | }}} 125 | 126 | * 引数: 127 | * !QrDecoderHandle decoder : QRデコーダハンドル 128 | * 戻り値: IplImage型のバッファへのポインタ 129 | 130 | qr_decoder_open_with_image_size(), qr_decoder_set_image_size()およびqr_decoder_set_image()で設定された原画像を格納するバッファのアドレスを取得する。 131 | 132 | === qr_decoder_get_transformed_image_buffer === 133 | {{{ 134 | IplImage *qr_decoder_get_transformed_image_buffer(QrDecoderHandle decoder); 135 | }}} 136 | * 引数: 137 | * !QrDecoderHandle decoder : QRデコーダハンドル 138 | * 戻り値: IplImage型のバッファへのポインタ 139 | 140 | 歪み補正済みカラー画像を格納するバッファのアドレスを取得する。(デバッグ用) 141 | 142 | === qr_decoder_get_binarized_image_buffer === 143 | {{{ 144 | IplImage *qr_decoder_get_binarized_image_buffer(QrDecoderHandle decoder); 145 | }}} 146 | * 引数: 147 | * !QrDecoderHandle decoder : QRデコーダハンドル 148 | * 戻り値: IplImage型のバッファへのポインタ 149 | 150 | 二値画像を格納するバッファのアドレスを取得する。(デバッグ用) 151 | 152 | === qr_decoder_get_tmp_image_buffer === 153 | {{{ 154 | IplImage *qr_decoder_get_tmp_image_buffer(QrDecoderHandle decoder); 155 | }}} 156 | * 引数: 157 | * !QrDecoderHandle decoder : QRデコーダハンドル 158 | * 戻り値: IplImage型のバッファへのポインタ 159 | 160 | ワークバッファのアドレスを取得する。(デバッグ用) 161 | 162 | == デコード == 163 | === qr_decoder_decode === 164 | {{{ 165 | short qr_decoder_decode( 166 | QrDecoderHandle decoder, 167 | int adaptive_th_size=DEFAULT_ADAPTIVE_TH_SIZE, 168 | int adaptive_th_delta=DEFAULT_ADAPTIVE_TH_DELTA 169 | ); 170 | }}} 171 | 172 | * 引数: 173 | * !QrDecoderHandle decoder : QRデコーダハンドル 174 | * int adaptive_th_size : 動的二値化処理ブロックサイズ 175 | * int adaptive_th_delta : 動的二値化処理差分閾値 176 | * 戻り値: デコード結果ステータス 177 | 178 | 初期化済みバッファの内容をデコードする。[[BR]] 179 | adaptive_th_sizeは3以上の奇数または0以下の値を指定すること。[[BR]] 180 | adaptive_th_sizeに0以下の値を指定したときは,adaptive_th_deltaを閾値とする固定二値化処理が行われる。 181 | 182 | デコード結果ステータスは[source:/trunk/src/libdecodeqr/qrerror.h#latest qrerror.h]で定義された値のうち該当するものをOR処理したものとなる。 183 | 184 | ex) 185 | * デコード成功時: QR_IMAGEREADER_DECODED 186 | * デコードには成功したが本文に修復不能なエラーが含まれていたとき: QR_IMAGEREADER_DECODED|QR_CODEDATA_UNRECOVERABLE 187 | * 画像からQRコードを特定できずデコードに失敗したとき: QR_IMAGEREADER_ERROR|QR_IMAGEREADER_NOT_FOUND_FINDER_PATTERN 188 | 189 | 190 | === qr_decoder_decode_image === 191 | {{{ 192 | short qr_decoder_decode_image( 193 | QrDecoderHandle decoder, 194 | IplImage *src, 195 | int adaptive_th_size=DEFAULT_ADAPTIVE_TH_SIZE, 196 | int adaptive_th_delta=DEFAULT_ADAPTIVE_TH_DELTA 197 | ); 198 | }}} 199 | 200 | * 引数: 201 | * !QrDecoderHandle decoder : QRデコーダハンドル 202 | * !IplImage *src : 画像バッファへのポインタ 203 | * int adaptive_th_size : 動的二値化処理ブロックサイズ 204 | * int adaptive_th_delta : 動的二値化処理差分閾値 205 | * 戻り値: デコード結果ステータス。 206 | 207 | srcに与えられた画像をデコードする。 208 | 209 | srcとして指定したIplImage形式の画像バッファをデコーダの画像バッファとする。[[BR]] 210 | 指定するバッファはtop-left origin (src->origin==0)で無ければならない。[[BR]] 211 | bottom-left origin (src->origin==1)の場合は,highguiのcvConvertImage()などでtop-left originに変換すること。 212 | 213 | == デコード済みデータ取得 == 214 | === qr_decoder_get_header === 215 | {{{ 216 | int qr_decoder_get_header( 217 | QrDecoderHandle decoder, 218 | QrCodeHeader *header 219 | ); 220 | }}} 221 | 222 | * 引数: 223 | * !QrDecoderHandle decoder : QRデコーダハンドル 224 | * !QrCodeHeader *header : QRコードヘッダ構造体を格納するバッファへのポインタ 225 | * 戻り値: 失敗時:0,成功時:1 226 | 227 | QRコードヘッダ構造体を取得し,headerに指定されたバッファに格納する。 228 | 229 | 230 | === qr_decoder_get_body === 231 | {{{ 232 | int qr_decoder_get_body( 233 | QrDecoderHandle decoder, 234 | unsigned char *buf, 235 | int buf_size 236 | ); 237 | }}} 238 | 239 | * 引数: 240 | * !QrDecoderHandle decoder : QRデコーダハンドル 241 | * unsigned char *buf : QRコード本文を格納するバッファへのポインタ 242 | * int buf_size : バッファサイズ(byte) 243 | * 戻り値: 失敗時:0,成功時:格納された本文のbyte数 244 | 245 | QRコード本文を取得し,bufに指定されたバッファに格納する。 246 | 247 | 格納された本文には,その形式に関わらず,終端文字'\0'が'''追加されない'''。[[BR]] 248 | ただしバッファは事前に0クリアされるので,qr_decoder_get_header()で取得できる本文のbyte数より大きなサイズのバッファを用意することで終端文字のかわりとできる。 249 | 250 | == デコーダ状態取得 == 251 | === qr_decoder_get_status === 252 | {{{ 253 | short qr_decoder_get_status(QrDecoderHandle decoder); 254 | }}} 255 | 256 | * 引数: 257 | * !QrDecoderHandle decoder : QRデコーダハンドル 258 | * 戻り値: ステータスコード 259 | 260 | ステータスは[source:/trunk/src/libdecodeqr/qrerror.h#latest qrerror.h]で定義された値のうち該当するものをOR処理したものとなる。 261 | 262 | === qr_decoder_is_busy === 263 | {{{ 264 | int qr_decoder_is_busy(QrDecoderHandle decoder); 265 | }}} 266 | 267 | * 引数: 268 | * !QrDecoderHandle decoder : QRデコーダハンドル 269 | * 戻り値: デコード中:1, アイドル:0 270 | 271 | デコード実行中か否かの状態を戻す。 272 | 273 | == バージョン情報 == 274 | バージョン情報は "Major.Minor.Teeny Suffix (Revision)" から構成され,Major, Minor, Teenyはリリース時に更新される。[[BR]] 275 | 開発中バージョンは,時期リリース予定の"Major.Minor.Teeny"のあとにSuffixとして"-dev"を付加し,開発中バージョン間は Revisionで区別する。 276 | 277 | === qr_decoder_version === 278 | {{{ 279 | char *qr_decoder_version(); 280 | }}} 281 | 282 | * 引数: なし 283 | * 戻り値: バージョン情報 (文字列)へのポインタ 284 | 285 | === qr_decoder_version_major === 286 | {{{ 287 | int qr_decoder_version_major(); 288 | }}} 289 | 290 | * 引数: なし 291 | * 戻り値: メジャーバージョン 292 | 293 | === qr_decoder_version_minor === 294 | {{{ 295 | int qr_decoder_version_minor(); 296 | }}} 297 | 298 | * 引数: なし 299 | * 戻り値: マイナーバージョン 300 | 301 | === qr_decoder_version_teeny === 302 | {{{ 303 | int qr_decoder_version_teeny(); 304 | }}} 305 | 306 | * 引数: なし 307 | * 戻り値: ティニアバージョン 308 | 309 | 310 | === qr_decoder_version_suffix === 311 | {{{ 312 | char *qr_decoder_version_suffix(); 313 | }}} 314 | 315 | * 引数: なし 316 | * 戻り値: バージョンサフィックス(文字列)へのポインタ 317 | 318 | === qr_decoder_version_revision === 319 | {{{ 320 | char *qr_decoder_version_revision(); 321 | }}} 322 | 323 | * 引数: なし 324 | * 戻り値: リビジョン情報(文字列)へのポインタ 325 | 326 | ---- 327 | {{{ 328 | #!html 329 |
330 | }}} 331 | Last-modified: [[LastModified]] 332 | {{{ 333 | #!html 334 |
335 | }}} 336 | -------------------------------------------------------------------------------- /libdecodeqr/ecidecoder.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // ecidecoder.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 13 | // 14 | #include "ecidecoder.h" 15 | 16 | namespace Qr{ 17 | namespace ECI{ 18 | 19 | // 20 | // length of charactor count indicator 21 | // [version][mode] 22 | // 23 | const static int CHARACTOR_COUNTS[41][4]={ 24 | // 25 | // version 0 (not exist, just a dummy) 26 | // 27 | {0,0,0,0}, 28 | // 29 | // version 1-9 30 | // 31 | {10,9,8,8},{10,9,8,8},{10,9,8,8},{10,9,8,8}, 32 | {10,9,8,8},{10,9,8,8},{10,9,8,8},{10,9,8,8},{10,9,8,8}, 33 | // 34 | // version 10-26 35 | // 36 | {12,11,16,10},{12,11,16,10},{12,11,16,10},{12,11,16,10},{12,11,16,10}, 37 | {12,11,16,10},{12,11,16,10},{12,11,16,10},{12,11,16,10},{12,11,16,10}, 38 | {12,11,16,10},{12,11,16,10},{12,11,16,10},{12,11,16,10},{12,11,16,10}, 39 | {12,11,16,10},{12,11,16,10}, 40 | // 41 | // version 27-40 42 | // 43 | {14,13,16,12},{14,13,16,12},{14,13,16,12}, 44 | {14,13,16,12},{14,13,16,12},{14,13,16,12},{14,13,16,12},{14,13,16,12}, 45 | {14,13,16,12},{14,13,16,12},{14,13,16,12},{14,13,16,12},{14,13,16,12}, 46 | {14,13,16,12} 47 | }; 48 | 49 | // 50 | // number to alphabet conversion table 51 | // 52 | const static char NUM2ALPABET[45]={ 53 | 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39, // 0-9 54 | 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a, // A-J 55 | 0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54, // K-T 56 | 0x55,0x56,0x57,0x58,0x59,0x5a, // U-Z 57 | 0x20,0x23,0x25,0x2a,0x2b,0x2d,0x2e,0x2f,0x3a 58 | }; 59 | 60 | Decoder::Decoder() 61 | { 62 | this->mode=0; 63 | this->length=0; 64 | this->byte_length=0; 65 | this->eci_mode=20; 66 | 67 | this->_raw_data=NULL; 68 | this->_bit_par_block=0; 69 | this->_char_par_block=0; 70 | this->_byte_par_char=0; 71 | 72 | this->_read_length=0; 73 | this->_written_length=0; 74 | } 75 | 76 | Decoder::~Decoder() 77 | { 78 | if(this->_raw_data) 79 | delete [] this->_raw_data; 80 | } 81 | 82 | unsigned char *Decoder::raw_data() 83 | { 84 | return(this->_raw_data); 85 | } 86 | 87 | int Decoder::decode(int version,BitStream *bitstream) 88 | { 89 | this->_read_header(version,bitstream); 90 | int blocks=this->length/this->_char_par_block+ 91 | (this->length%this->_char_par_block?1:0); 92 | 93 | for(int i=0;i_read_data(bitstream)) 95 | break; 96 | } 97 | 98 | return(this->length); 99 | } 100 | int Decoder::_read_header(int version,BitStream *bitstream) 101 | { 102 | int charactor_count=this->_get_charactor_count(version); 103 | bitstream->read(&(this->length),sizeof(this->length), 104 | charactor_count); 105 | this->length=ntohl(this->length); 106 | this->byte_length=this->length*this->_byte_par_char; 107 | 108 | int storage_sz=this->byte_length; 109 | if(this->mode!=4) 110 | storage_sz++; 111 | 112 | this->_raw_data=new unsigned char[storage_sz]; 113 | memset(this->_raw_data,0,storage_sz); 114 | this->_current_pos=this->_raw_data; 115 | 116 | return(bitstream->position()); 117 | } 118 | int Decoder::_get_charactor_count(int version) 119 | { 120 | return(0); 121 | } 122 | int Decoder::_read_data(BitStream *bitstream) 123 | { 124 | return(0); 125 | } 126 | 127 | NumericalDecoder::NumericalDecoder() 128 | { 129 | this->mode=1; 130 | this->_bit_par_block=10; 131 | this->_char_par_block=3; 132 | this->_byte_par_char=1; 133 | } 134 | int NumericalDecoder::_get_charactor_count(int version) 135 | { 136 | return(CHARACTOR_COUNTS[version][0]); 137 | } 138 | int NumericalDecoder::_read_data(BitStream *bitstream) 139 | { 140 | if(bitstream->is_eod()) 141 | return(0); 142 | 143 | int read_bits=this->_bit_par_block; 144 | int write_bytes=this->_char_par_block*this->_byte_par_char; 145 | switch(this->length-this->_read_length){ 146 | case 0: 147 | return(0); 148 | case 1: 149 | read_bits=4; 150 | write_bytes=1; 151 | break; 152 | case 2: 153 | read_bits=7; 154 | write_bytes=2; 155 | break; 156 | } 157 | this->_read_buf=0; 158 | bitstream->read(&(this->_read_buf),sizeof(this->_read_buf), 159 | read_bits); 160 | this->_read_buf=ntohs(this->_read_buf); 161 | this->_read_length+=write_bytes; 162 | 163 | int remain_bytes=this->byte_length-this->_written_length; 164 | if(write_bytes>remain_bytes) 165 | write_bytes=remain_bytes; 166 | 167 | char format_str[5]; 168 | snprintf(format_str,5,"%%0%dd",write_bytes); 169 | int ret=snprintf((char *)this->_current_pos, 170 | write_bytes+1, 171 | format_str, 172 | this->_read_buf); 173 | 174 | if(ret<0) 175 | ret=0-ret; 176 | this->_current_pos+=ret; 177 | this->_written_length+=ret; 178 | 179 | return(ret); 180 | } 181 | 182 | 183 | AlphabeticalDecoder::AlphabeticalDecoder() 184 | { 185 | this->mode=2; 186 | this->_bit_par_block=11; 187 | this->_char_par_block=2; 188 | this->_byte_par_char=1; 189 | } 190 | int AlphabeticalDecoder::_get_charactor_count(int version) 191 | { 192 | return(CHARACTOR_COUNTS[version][1]); 193 | } 194 | int AlphabeticalDecoder::_read_data(BitStream *bitstream) 195 | { 196 | if(bitstream->is_eod()) 197 | return(0); 198 | 199 | int read_bits=this->_bit_par_block; 200 | int write_bytes=this->_char_par_block*this->_byte_par_char; 201 | switch(this->length-this->_read_length){ 202 | case 0: 203 | return(0); 204 | case 1: 205 | read_bits=6; 206 | write_bytes=1; 207 | break; 208 | } 209 | this->_read_buf=0; 210 | bitstream->read(&(this->_read_buf),sizeof(this->_read_buf), 211 | read_bits); 212 | this->_read_buf=ntohs(this->_read_buf); 213 | this->_read_length+=write_bytes; 214 | 215 | int remain_bytes=this->byte_length-this->_written_length; 216 | int ret=0; 217 | if(read_bits==this->_bit_par_block){ 218 | int x=this->_read_buf/45; 219 | char c=NUM2ALPABET[x]; 220 | if(remain_bytes>0){ 221 | if(snprintf((char *)this->_current_pos,2,"%c",c)>0){ 222 | ret++; 223 | this->_current_pos++; 224 | remain_bytes--; 225 | this->_written_length++; 226 | } 227 | } 228 | } 229 | if(remain_bytes>0){ 230 | int x=this->_read_buf%45; 231 | char c=NUM2ALPABET[x]; 232 | if(snprintf((char *)this->_current_pos,2,"%c",c)>0){ 233 | ret++; 234 | this->_current_pos++; 235 | remain_bytes--; 236 | this->_written_length++; 237 | } 238 | } 239 | 240 | return(ret); 241 | } 242 | 243 | ByteDecoder::ByteDecoder() 244 | { 245 | this->mode=4; 246 | this->_bit_par_block=8; 247 | this->_char_par_block=1; 248 | this->_byte_par_char=1; 249 | } 250 | int ByteDecoder::_get_charactor_count(int version) 251 | { 252 | return(CHARACTOR_COUNTS[version][2]); 253 | } 254 | int ByteDecoder::_read_data(BitStream *bitstream) 255 | { 256 | if(bitstream->is_eod()) 257 | return(0); 258 | 259 | int read_bits=this->_bit_par_block; 260 | int write_bytes=this->_char_par_block*this->_byte_par_char; 261 | this->_read_buf=0; 262 | bitstream->read(&(this->_read_buf),sizeof(this->_read_buf), 263 | read_bits); 264 | this->_read_length+=write_bytes; 265 | 266 | if(this->byte_length-this->_written_length){ 267 | *this->_current_pos=(unsigned char)this->_read_buf; 268 | this->_current_pos++; 269 | this->_written_length++; 270 | return(1); 271 | } 272 | else{ 273 | return(0); 274 | } 275 | } 276 | 277 | GenericDecoder::GenericDecoder() 278 | { 279 | this->mode=7; 280 | } 281 | int GenericDecoder::_get_charactor_count(int version) 282 | { 283 | return(0); 284 | } 285 | int GenericDecoder::_read_data(BitStream *bitstream) 286 | { 287 | return(0); 288 | } 289 | 290 | KanjiDecoder::KanjiDecoder() 291 | { 292 | this->mode=8; 293 | this->_bit_par_block=13; 294 | this->_char_par_block=1; 295 | this->_byte_par_char=2; 296 | } 297 | int KanjiDecoder::_get_charactor_count(int version) 298 | { 299 | return(CHARACTOR_COUNTS[version][3]); 300 | } 301 | int KanjiDecoder::_read_data(BitStream *bitstream) 302 | { 303 | if(bitstream->is_eod()) 304 | return(0); 305 | 306 | int read_bits=this->_bit_par_block; 307 | int write_bytes=this->_char_par_block*this->_byte_par_char; 308 | if(this->length-this->_read_length<=0) 309 | return(0); 310 | 311 | this->_read_buf=0; 312 | bitstream->read(&(this->_read_buf),sizeof(this->_read_buf), 313 | read_bits); 314 | this->_read_buf=ntohs(this->_read_buf); 315 | this->_read_length++; 316 | 317 | if(this->byte_length-this->_written_length>=write_bytes){ 318 | int c=this->_read_buf/0xc0; 319 | c*=0x100; 320 | c+=this->_read_buf%0xc0; 321 | if(c>=0x1f00) 322 | c+=0xc140; 323 | else 324 | c+=0x8140; 325 | 326 | unsigned char c1=(unsigned char)(c/0x100); 327 | unsigned char c2=(unsigned char)(c%0x100); 328 | 329 | *this->_current_pos=c1; 330 | *(this->_current_pos+1)=c2; 331 | this->_current_pos+=2; 332 | this->_written_length+=2; 333 | return(2); 334 | } 335 | else 336 | return(0); 337 | } 338 | }; 339 | }; 340 | 341 | 342 | -------------------------------------------------------------------------------- /libdecodeqr/codedata.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // codedata.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 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,13}}, 74 | {{532,8,59,37,11},{532,4,133,107,13}, 75 | {532,12,33,11,11},{532,8,44,20,12}}, 76 | {{581,4,64,40,12},{581,3,145,115,15}, 77 | {581,11,36,12,12},{581,11,36,16,10}}, 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,53,23,15}}, 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,59,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->_sizedata_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;jset(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;itotal_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;idata[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];idata_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;idata_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;idata_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->_sizedata_words){ 361 | for(int i=0;idata_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;idata[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;idata[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;idata_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 | } 507 | -------------------------------------------------------------------------------- /libdecodeqr/galois.cpp: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | // 3 | // galois.cpp --a part of libdecodeqr 4 | // 5 | // Copyright(C) 2007 NISHI Takao 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$ 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;in*=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_pool_size;i++){ 231 | this->pool[i]=NULL; 232 | Nomial::instance(this,i); 233 | } 234 | } 235 | Field::~Field() 236 | { 237 | for(int i=0;i_pool_size;i++){ 238 | if(this->pool[i]) 239 | delete this->pool[i]; 240 | } 241 | delete [] this->pool; 242 | 243 | if(this->_need_delete){ 244 | delete this->exp2vect; 245 | delete this->vect2exp; 246 | } 247 | } 248 | 249 | int Field::pool_size() 250 | { 251 | return(this->_pool_size); 252 | } 253 | 254 | Nomial *Field::exp2nomial(unsigned int x) 255 | { 256 | return(this->pool[x%(this->n)]); 257 | } 258 | Nomial *Field::vect2nomial(unsigned int x) 259 | { 260 | return(this->pool[this->vect2exp[x%(this->n)]]); 261 | } 262 | Nomial *Field::zero() 263 | { 264 | return(this->pool[this->n]); 265 | } 266 | 267 | //////////////////////////////////////////////////////////////////////// 268 | // 269 | // 270 | // 271 | Polynomial::Polynomial() 272 | { 273 | this->cols=0; 274 | this->rows=0; 275 | 276 | this->nomial=NULL; 277 | } 278 | 279 | Polynomial::Polynomial(int rows) 280 | { 281 | this->cols=1; 282 | this->rows=rows; 283 | 284 | this->nomial=new Galois::Nomial *[this->rows]; 285 | } 286 | Polynomial::Polynomial(int cols,int rows) 287 | { 288 | this->cols=cols; 289 | this->rows=rows; 290 | 291 | this->nomial=new Nomial *[this->cols*this->rows]; 292 | } 293 | Polynomial::~Polynomial() 294 | { 295 | delete this->nomial; 296 | } 297 | 298 | Polynomial *Polynomial::dup() 299 | { 300 | Polynomial *ret=new Polynomial(this->cols,this->rows); 301 | memcpy(ret->nomial,this->nomial, 302 | sizeof(Nomial *)*this->cols*this->rows); 303 | 304 | return(ret); 305 | } 306 | Polynomial *Polynomial::dup(int count) 307 | { 308 | return(this->dup(0,0,count,count)); 309 | } 310 | Polynomial *Polynomial::dup(int start_col,int start_row,int count) 311 | { 312 | return(this->dup(start_col,start_row,count,count)); 313 | } 314 | Polynomial *Polynomial::dup(int start_col,int start_row, 315 | int col_count,int row_count) 316 | { 317 | Polynomial *ret=new Polynomial(col_count,row_count); 318 | 319 | for(int i=0,c=start_col;iset(i,j,this->get(c,r)); 322 | } 323 | } 324 | 325 | return(ret); 326 | } 327 | 328 | 329 | Nomial *Polynomial::set(int row,Nomial *val) 330 | { 331 | return(this->set(0,row,val)); 332 | } 333 | Nomial *Polynomial::set(int col,int row,Nomial *val) 334 | { 335 | this->nomial[col*rows+row]=val->dup(); 336 | return(this->nomial[col*rows+row]); 337 | } 338 | 339 | Nomial *Polynomial::get(int row) 340 | { 341 | return(this->get(0,row)); 342 | } 343 | Nomial *Polynomial::get(int col,int row) 344 | { 345 | return(this->nomial[col*rows+row]->dup()); 346 | } 347 | 348 | 349 | ///////////////////////////////////////////////////////////////////// 350 | // 351 | // LU analyze with pivot selection 352 | // 353 | Polynomial *Polynomial::lu() 354 | { 355 | Polynomial *buf=this->dup(); 356 | Polynomial *ret=buf->_lu(buf); 357 | if(!ret) 358 | delete buf; 359 | return(ret); 360 | } 361 | Polynomial *Polynomial::lu(int count) 362 | { 363 | Polynomial *buf=this->dup(0,0,count); 364 | Polynomial *ret=buf->_lu(buf); 365 | if(!ret) 366 | delete buf; 367 | return(ret); 368 | } 369 | Polynomial *Polynomial::lu(int start_col,int start_row,int count) 370 | { 371 | Polynomial *buf=this->dup(start_col,start_row,count); 372 | Polynomial *ret=buf->_lu(buf); 373 | if(!ret) 374 | delete buf; 375 | return(ret); 376 | } 377 | 378 | Polynomial *Polynomial::_lu(Polynomial *buf) 379 | { 380 | int count=buf->cols,i,j; 381 | if(buf->rowscols) 382 | count=buf->rows; 383 | 384 | for(j=0;jget(i,j); 391 | if(!l->is_zero()) 392 | break; 393 | } 394 | if(i>=count) 395 | return(NULL); 396 | else if(i>j) 397 | buf->swap_col(j,i); 398 | 399 | for(i=j+1;iget(i,j)/(*l)); 401 | buf->set(i,j,n); 402 | for(int k=j+1;kget(i,k)-*buf->get(j,k)**n); 404 | *buf->set(i,k,m); 405 | } 406 | } 407 | } 408 | return(buf); 409 | } 410 | 411 | ///////////////////////////////////////////////////////////////////// 412 | // 413 | // Gaussian elimination 414 | // 415 | Polynomial *Polynomial::solve() 416 | { 417 | Polynomial *lu=this->lu(); 418 | if(lu){ 419 | Polynomial *ret=this->solve(lu); 420 | delete lu; 421 | return(ret); 422 | } 423 | else{ 424 | return(NULL); 425 | } 426 | } 427 | 428 | Polynomial *Polynomial::solve(Polynomial *lu) 429 | { 430 | if(!lu) 431 | return(NULL); 432 | 433 | if(lu->rows!=this->cols+1) 434 | throw((void *)NULL); 435 | 436 | // 437 | // check rank 438 | // 439 | int rank=0,i,j,k; 440 | for(j=0;jcols;j++){ 441 | bool is_zero_cols=true; 442 | for(k=j;kcols;k++){ 443 | is_zero_cols&=lu->get(j,k)->is_zero(); 444 | } 445 | if(!is_zero_cols) 446 | rank++; 447 | } 448 | if(rankcols) 449 | return(NULL); 450 | 451 | Polynomial *ret=new Polynomial(lu->cols); 452 | for(i=0;icols;i++){ 453 | ret->set(i,lu->get(i,lu->cols)); 454 | } 455 | 456 | for(j=0;jcols;j++){ 457 | for(i=j+1;icols;i++){ 458 | ret->set(i,&(*ret->get(i)-*ret->get(j)**lu->get(i,j))); 459 | } 460 | } 461 | for(j=lu->cols-1;j>=0;j--){ 462 | for(int i=j+1;icols;i++){ 463 | ret->set(j,&(*ret->get(j)- 464 | *lu->get(j,i)**ret->get(i))); 465 | } 466 | ret->set(j,&(*ret->get(j)/(*lu->get(j,j)))); 467 | } 468 | return(ret); 469 | } 470 | 471 | void Polynomial::swap_col(int i,int j) 472 | { 473 | size_t sz=sizeof(Nomial *)*this->rows; 474 | 475 | Nomial **tmp=new Nomial *[this->rows]; 476 | 477 | memcpy(tmp,this->nomial+i*this->rows,sz); 478 | memcpy(this->nomial+i*this->rows, 479 | this->nomial+j*this->rows,sz); 480 | memcpy(this->nomial+j*this->rows,tmp,sz); 481 | 482 | delete [] tmp; 483 | } 484 | 485 | 486 | ///////////////////////////////////////////////////////////////////// 487 | // 488 | // 489 | // 490 | BCH::BCH(Field *gf,int size,int capability) 491 | { 492 | this->_gf=gf; 493 | this->rows=size; 494 | this->cols=1; 495 | this->_capability=capability; 496 | this->error_size=0; 497 | this->error_pos=NULL; 498 | this->nomial=new Galois::Nomial *[this->rows]; 499 | this->syndrome_size=0; 500 | this->syndromes=NULL; 501 | } 502 | BCH::~BCH() 503 | { 504 | if(this->error_pos) 505 | delete this->error_pos; 506 | 507 | if(this->syndromes) 508 | delete this->syndromes; 509 | } 510 | 511 | int BCH::decode(int syndrome_base) 512 | { 513 | // 514 | // error syndromes 515 | // 516 | this->syndrome_size=this->_capability*2+syndrome_base; 517 | this->syndromes=new Galois::Nomial *[this->syndrome_size]; 518 | 519 | int errors=0,i; 520 | for(i=0;isyndrome_size;i++){ 521 | this->syndromes[i]=this->_error_syndrome(i); 522 | if(!this->syndromes[i]->is_zero()) 523 | errors++; 524 | } 525 | if(!errors) 526 | return(0); 527 | 528 | // 529 | // calculate error position variables 530 | // 531 | Galois::Polynomial *err=NULL; 532 | for(errors=this->_capability;errors>0;errors--){ 533 | Galois::Polynomial *mat=new Galois::Polynomial(errors, 534 | errors+1); 535 | 536 | for(int j=0;jset(j,i,this->syndromes[i+j+syndrome_base]); 539 | } 540 | } 541 | 542 | err=mat->solve(); 543 | delete mat; 544 | 545 | if(err) 546 | break; 547 | } 548 | if(!err){ 549 | this->error_size=-1; 550 | return(-1); 551 | } 552 | 553 | if(err){ 554 | // 555 | // get error position 556 | // 557 | this->error_pos=new int[errors]; 558 | memset(this->error_pos,-1,errors); 559 | 560 | int c,i,j; 561 | for(j=0,c=0;jrows;j++){ 562 | Galois::Nomial *sigma=err->get(0); 563 | for(i=1;iget(i)* 565 | *this->_gf->exp2nomial(j*i)); 566 | } 567 | sigma=&(*sigma+*this->_gf->exp2nomial(j*i)); 568 | 569 | if(sigma->is_zero()){ 570 | if(cerror_pos[c]=j; 572 | } 573 | c++; 574 | } 575 | } 576 | delete err; 577 | if(c==errors) 578 | this->error_size=errors; 579 | else 580 | this->error_size=-1; 581 | } 582 | 583 | return(this->error_size); 584 | } 585 | 586 | Galois::Nomial *BCH::_error_syndrome(int d) 587 | { 588 | Galois::Nomial *x=this->_gf->zero(); 589 | 590 | for(int i=0;irows;i++){ 591 | x=&(*x+*this->get(i)* 592 | *this->_gf->exp2nomial(i*d)); 593 | } 594 | 595 | return(x->dup()); 596 | } 597 | 598 | } 599 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 489 | 490 | Also add information on how to contact you by electronic and paper mail. 491 | 492 | You should also get your employer (if you work as a programmer) or your 493 | school, if any, to sign a "copyright disclaimer" for the library, if 494 | necessary. Here is a sample; alter the names: 495 | 496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 | 499 | , 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | 504 | 505 | --------------------------------------------------------------------------------