gocr-ruby 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +21 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +29 -0
  7. data/Rakefile +49 -0
  8. data/ext/gocr/Makefile +141 -0
  9. data/ext/gocr/Makefile.in +140 -0
  10. data/ext/gocr/amiga.h +31 -0
  11. data/ext/gocr/barcode.c +2108 -0
  12. data/ext/gocr/barcode.h +11 -0
  13. data/ext/gocr/box.c +496 -0
  14. data/ext/gocr/config.h +37 -0
  15. data/ext/gocr/config.h.in +36 -0
  16. data/ext/gocr/database.c +468 -0
  17. data/ext/gocr/detect.c +1003 -0
  18. data/ext/gocr/extconf.rb +6 -0
  19. data/ext/gocr/gocr.c +436 -0
  20. data/ext/gocr/gocr.h +290 -0
  21. data/ext/gocr/jconv.c +168 -0
  22. data/ext/gocr/job.c +92 -0
  23. data/ext/gocr/lines.c +364 -0
  24. data/ext/gocr/list.c +334 -0
  25. data/ext/gocr/list.h +91 -0
  26. data/ext/gocr/ocr0.c +7312 -0
  27. data/ext/gocr/ocr0.h +63 -0
  28. data/ext/gocr/ocr0n.c +1527 -0
  29. data/ext/gocr/ocr1.c +85 -0
  30. data/ext/gocr/ocr1.h +3 -0
  31. data/ext/gocr/otsu.c +310 -0
  32. data/ext/gocr/otsu.h +23 -0
  33. data/ext/gocr/output.c +291 -0
  34. data/ext/gocr/output.h +37 -0
  35. data/ext/gocr/pcx.c +153 -0
  36. data/ext/gocr/pcx.h +9 -0
  37. data/ext/gocr/pgm2asc.c +3259 -0
  38. data/ext/gocr/pgm2asc.h +105 -0
  39. data/ext/gocr/pixel.c +538 -0
  40. data/ext/gocr/pnm.c +538 -0
  41. data/ext/gocr/pnm.h +35 -0
  42. data/ext/gocr/progress.c +87 -0
  43. data/ext/gocr/progress.h +42 -0
  44. data/ext/gocr/remove.c +715 -0
  45. data/ext/gocr/tga.c +87 -0
  46. data/ext/gocr/tga.h +6 -0
  47. data/ext/gocr/unicode.c +1318 -0
  48. data/ext/gocr/unicode.h +62 -0
  49. data/ext/gocr/unicode_defs.h +1245 -0
  50. data/ext/gocr/version.h +2 -0
  51. data/gocr-ruby.gemspec +28 -0
  52. data/image.png +0 -0
  53. data/lib/gocr.rb +6 -0
  54. data/lib/gocr/image.rb +8 -0
  55. data/lib/gocr/version.rb +3 -0
  56. metadata +156 -0
@@ -0,0 +1,2108 @@
1
+ /*
2
+ This is a Optical-Character-Recognition program
3
+ Copyright (C) GPLv2 2000-2013 Joerg Schulenburg
4
+
5
+ This program is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU General Public License
7
+ as published by the Free Software Foundation; either version 2
8
+ of the License, or (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the Free Software
17
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
+
19
+ see README for email address
20
+
21
+ ToDo:
22
+ - transform special xml bar code symbols (<>&) to xml symbols (&lt;&gt;&amp;)
23
+
24
+ */
25
+
26
+ #include <stdlib.h>
27
+ #include <stdio.h>
28
+ #include <string.h>
29
+ /* #include <math.h> -- we do not want unnecessary dependencies */
30
+ #include "pgm2asc.h"
31
+ #include "gocr.h"
32
+ #include "pnm.h"
33
+ #include "unicode_defs.h" /* define UNKNOWN + PICTURE */
34
+
35
+ #ifndef DO_DEBUG /* can be defined outside (configure --with-debug) */
36
+ #define DO_DEBUG 0 /* 0 is the default */
37
+ #endif
38
+
39
+ #undef g_debug
40
+ #if DO_DEBUG
41
+ # define g_debug(a) if (OCR_JOB->cfg.verbose&1) { a }
42
+ #else
43
+ # define g_debug(a)
44
+ #endif
45
+
46
+ /*
47
+ detect barcode and add a XML-string to the box (obj-pointer, ToDo)
48
+ ToDo: barcode-output stderr->stdout
49
+ */
50
+
51
+ double sqr(double x) { return(x*x); }
52
+
53
+ /* ----------------------------- code128 ---------------------------- *
54
+ * "BSBSBS", B=Bar, S=Space, better using 2*6=12bit-integer? */
55
+ #define Num128 107
56
+ const char *code128[Num128+1]={ /* can be generated by an algorithm? */
57
+ /* 00 */"212222","222122","222221","121223","121322","131222","122213","122312",
58
+ /* 08 */"132212","221213","221312","231212","112232","122132","122231","113222",
59
+ /* 16 */"123122","123221","223211","221132","221231","213212","223112","312131",
60
+ /* 24 */"311222","321122","321221","312212","322112","322211","212123","212321",
61
+ /* 32 */"232121","111323","131123","131321","112313","132113","132311","211313",
62
+ /* 40 */"231113","231311","112133","112331","132131","113123","113321","133121",
63
+ /* 48 */"313121","211331","231131","213113","213311","213131","311123","311321",
64
+ /* 56 */"331121","312113","312311","332111","314111","221411","431111","111224",
65
+ /* 64 */"111422","121124","121421","141122","141221","112214","112412","122114",
66
+ /* 72 */"122411","142112","142211","241211","221114","413111","241112","134111",
67
+ /* 80 */"111242","121142","121241","114212","124112","124211","411212","421112",
68
+ /* 88 */"421211","212141","214121","412121","111143","111341","131141","114113",
69
+ /* 96 */"114311","411113","411311","113141","114131","311141","411131","211412",
70
+ /*104 */"211214","211232","2331112","???"};
71
+
72
+ /*
73
+ code128: see code128.tex by Petr Olsak (108 codes)
74
+ quiet_zone: size=10 (before and after code128)
75
+ num_bars=3*(start+chars[N]+crc+stop)+1
76
+ B=bar S=space char=BSBSBS (size=11), stop=BSBSBSB (size=11+2)
77
+ Width: Bar,Space=1,[2,3,4] char=11 code=11*(N+3)+2 sumB=even,sumS=odd
78
+ startA="211412"=103 startB="211214"=104 startC="211232"=105(2dec_digits)
79
+ mode/code 0..95 96 97 98 99 100 101 102 103 104 105 106
80
+ 1=A x20-x5f,0-x20 F3 F2 uB mC mB F4 F1 ^A ^B ^C $
81
+ 2=B x20-x7f F3 F2 uA mC F4 mA F1 ^A ^B ^C $
82
+ 3=C "00"-"95" "96" "97" "98" "99" mB mA F1 ^A ^B ^C $
83
+ uA,uB: switch mode for next char, mA,mB: switch mode permanently
84
+ crc=(start+1*char1+2*char2+3*char3+...+N*charN) mod 103
85
+ $=stop="2331112"=106 (4bars, with=13) => start/end==211
86
+ return num of chars or string
87
+ StartStopWidths: Bars=123 Spaces=123
88
+
89
+ size B+W even-variants odd-variants num_codes
90
+ 11 = 8+3 = (1+3+4,2+2+4,2+3+3)+(1+1+1) => (6+3+3)*(1) = 12
91
+ = 6+5 = (1+1+4,1+2+3,2+2+2)+(1+1+3,1+2+2) => (3+6+1)*(3+3) = 60
92
+ = 4+7 = (1+1+2)+(1+2+4,1+3+3,2+2+3) => (3)*(6+3+3) = 36
93
+ sum = 108
94
+ */
95
+ /* example: barcode -E -e 128c -b 1434600120000884 >a.eps */
96
+ /* example: barcode -E -e 128b -b 14Test41 >a.eps */
97
+ /* example: barcode -E -e 128raw -b 105 17 14 30 >a.eps */
98
+
99
+ char *decode_code128(int *wb, int num_bars){
100
+ int i, w, i1, i2, i3=0, i4, i4old, i5=0, crc, mode=1;
101
+ int minB, maxB, minS, maxS; /* min/max bars/spaces sample: 3-10 1-8 */
102
+ int wb6[6], addS, addB; /* normalized bars, normalization summand */
103
+ double dww, dw, err, min_err; char cc, *buf;
104
+ char *result=NULL; /* malloc and store the result */
105
+
106
+ minB=maxB=wb[0];
107
+ minS=maxS=wb[1];
108
+ /* sample090916 showed maxS = minB so we normalize first */
109
+ for(i=0; i<2*num_bars-1; i++){
110
+ if (i&1) { if (minS>wb[i]) minS=wb[i]; if (maxS<wb[i]) maxS=wb[i]; }
111
+ else { if (minB>wb[i]) minB=wb[i]; if (maxB<wb[i]) maxB=wb[i]; }
112
+ }
113
+ /* sample: 05 02 03 ...
114
+ distortion: wb[0]=2*sb+db wb[1]=sb-db wb[2]=sb+db (scale+diff)
115
+ back: sb = wb[0]-wb[2] = 2
116
+ db = wb[2]-sb = 2wb[2]-wb[0] = 1
117
+ = (wb[2]-wb[1]+1)/2 = 1
118
+ */
119
+ addS=(minB-minS+1)/2; addB=-(minB-minS)/2;
120
+ for(w=i=0;i<2*num_bars-1;i++){
121
+ w+=wb[i]+((i&1)?addS:addB); /* summ all bars and spaces */
122
+ }
123
+
124
+ /* test code128 characteristics, ToDo: look for correct start/stop 211 seq. */
125
+ if ((num_bars-1)%3!=0 || num_bars<10 || w<11*(num_bars-1)/3+2)
126
+ return 0;
127
+ g_debug(fprintf(stderr," code128 BS= %d-%d %d-%d chars=%d 211... %02d %02d %02d\n",minB,maxB,minS,maxS,(num_bars-1)/3,wb[0],wb[1],wb[2]);)
128
+ if (3*(wb[0]+addB)<4* (wb[1]+addS)
129
+ || 3* wb[0] <4* wb[2]
130
+ || 4* wb[0] <3*(wb[1]+wb[2])
131
+ || 3* wb[0] >4*(wb[1]+wb[2])) return 0; /* start=211.. */
132
+ dw=3.0*w/((num_bars-1)*11+6);
133
+ /* get enough memory for all digits in longest mode C */
134
+ buf =(char *) malloc( (num_bars-7)/3*2+1); if (!buf) return result;
135
+ result=(char *) malloc(256+(num_bars-7)/3*2+1);
136
+
137
+ dww=crc=0;
138
+ for(i4=i1=0;i1<(num_bars-1)/3;i1++) {
139
+ for (i2=0;i2<6;i2++) wb6[i2]=wb[i1*6+i2]+((i2&1)?addS:addB);
140
+ for(min_err=1e8,i3=Num128,i5=0;i5<Num128;i5++){ /* get best fit */
141
+ for(err=i2=0;i2<6;i2++) err+=sqr(code128[i5][i2]-'0'-wb6[i2]/dw);
142
+ if (err<min_err) { min_err=err; i3=i5; }
143
+ } dww+=min_err;
144
+ g_debug(for(i2=0;i2<6;i2++)fprintf(stderr," %2d",wb[i1*6+i2]);
145
+ fprintf(stderr," %7s %3d err=%.3f",code128[i3],i3,min_err);)
146
+ i4old=i4;
147
+ if(i3<Num128){ /* valid symbol */
148
+ if(i1==0){ if (i3>102 && i3<106) mode=i3-103+1; crc=i3; } /* start */
149
+ if(i1>0 && i1<(num_bars-1)/3-2){
150
+ crc+=i3*(i1); cc=0; /* first * 1 + second * 2 + third * 3 ... */
151
+ i5=((mode>3)?mode>>2:mode&3); mode&=3; /* mode can be modified now */
152
+ switch (i5) { /* mode=1..3=modeA..modeC */
153
+ case 1: if (i3>=64 && i3<96) cc=i3-64; /* modeA: x20-x5f,0-x20 */
154
+ else cc=i3+32;
155
+ if (i3==101) mode=1; /* switch to mode A */
156
+ if (i3== 99) mode=3; /* switch to mode C */
157
+ if (i3== 98) mode|=2<<2; /* shift to mode B */
158
+ break;
159
+ case 2: cc=i3+32; /* modeB: x20-x7f */
160
+ if (i3==100) mode=2; /* switch to mode B */
161
+ if (i3== 99) mode=3; /* switch to mode C */
162
+ if (i3== 98) mode|=1<<2; /* shift to mode A */
163
+ break;
164
+ case 3:
165
+ if (i3==101) mode=1; /* switch to mode A */
166
+ if (i3==100) mode=2; /* switch to mode B */
167
+ }
168
+ if (i5==3 && i3<100) { buf[i4]='0'+i3/10; i4++;
169
+ buf[i4]='0'+i3%10; i4++; } /* modeC: 00-99 */
170
+ if (i5!=3) {
171
+ if (cc>=0x20 && i3<=0x7f) { buf[i4]=cc; i4++; } /* modeA+B: one digit */
172
+ if (cc>=0 && cc< 0x20) { buf[i4]='^'; i4++;
173
+ buf[i4]=cc+'@'; i4++; }
174
+ }
175
+ }
176
+ if(i1==(num_bars-1)/3-2){ crc=(crc+103-i3)%103; }
177
+ if(i1==(num_bars-1)/3-1){ if(i3!=106) i3=-1; } /* stop code */
178
+ mode &= 3; /* remove shift */
179
+ }
180
+ else fprintf(stderr," %s=%02d? ",buf,i5);
181
+ g_debug(fprintf(stderr," m%c %c%c\n",'A'-1+mode,
182
+ ((i4-i4old>1)?buf[i4-2]:' '), /* two digged modeC, Apr08 */
183
+ ((i4-i4old>0)?buf[i4-1]:' '));)
184
+ }
185
+ buf[i4]=0; /* end of string */
186
+ if (result)
187
+ sprintf(result,"<barcode type=\"128\" chars=\"%d\" code=\"%s\" "
188
+ "crc=\"%d\" error=\"%.3f\" />",
189
+ i4,buf,crc,dww/((num_bars-1)));
190
+ free(buf);
191
+ return result;
192
+ }
193
+
194
+ /* -------------------------------------------------------------------- UPC
195
+ EAN 13 (UPC,(1+6+1+6+1)*2bars,size=3+6*7+5+6*7+3=95)
196
+ EAN 8 (UPC,(1+4+1+4+1)*2bars,size=3+4*7+5+4*7+3=67)
197
+ UPC: (10 codes)
198
+ BSB SBSB^n SBSBS BSBS^n BSB
199
+ bsb ...... sbsbs ...... bsb
200
+ 111 ...... 11111 ...... 111
201
+ num_bars=2*(2*6+3) middle=SBSBS=11111 right/left=BSB=111="101"
202
+ char: left=SBSB right=BSBS (size=7) only_dec_digits
203
+ SS+BB = (S+S) + (B+B) => BB:SS = 5:2 or 3:4
204
+ size ev+odd even + odd => variants
205
+ 7 = 2 + 5 = (1+1) + (1+4,2+3) => (1)*(2+2) = 4 codes
206
+ = 4 + 3 = (1+3,2+2) + (1+3) => (2+1)*(2) = 6 codes += 10 codes
207
+ ToDo: make it more robust
208
+ - return error as mean deviation
209
+ * -------------------------------------------------------------------- */
210
+ /* example: barcode -E -e upc -b 12345678901 >a.eps # ok */
211
+ /* example: barcode -E -e ean -b 123456789012 >a.eps # ok */
212
+ #define NumUPC 20
213
+ const char *codeUPC[NumUPC+1]={ /* 0..9, first n = SBSB, last n = BSBS */
214
+ "3211","2221","2122","1411","1132", /* 0,1,2,3,4 normal (+0bit) */
215
+ "1231","1114","1312","1213","3112", /* 5,6,7,8,9 */
216
+ "1123","1222","2212","1141","2311", /* 0,1,2,3,4 mirrored (+1bit) */
217
+ "1321","4111","2131","3121","2113", /* 5,6,7,8,9 */
218
+ "????"}; /* not found */
219
+
220
+ char *decode_UPC(int *wb, int num_bars){ /* ToDo: char *dest, int len */
221
+ int i, w, i1, i2, i3, i4, i5, crc, mirrored, ean;
222
+ double err, min_err, dw, dww=0.0; char digit;
223
+ char *result=NULL, *buf=NULL; /* malloc and store the result */
224
+ int minB, maxB, minS, maxS; /* min/max bars/spaces */
225
+ int addS, addB; /* corrections, JS1002 sample090916 */
226
+
227
+ minB=maxB=wb[0];
228
+ minS=maxS=wb[1];
229
+ /* sample090916 showed maxS = minB so we normalize first */
230
+ for(i=0; i<2*num_bars-1; i++){
231
+ if (i&1) { if (minS>wb[i]) minS=wb[i]; if (maxS<wb[i]) maxS=wb[i]; }
232
+ else { if (minB>wb[i]) minB=wb[i]; if (maxB<wb[i]) maxB=wb[i]; }
233
+ }
234
+ addS=(minB-minS)/2; addB=-(minB-minS)/2;
235
+ for(w=i=0;i<2*num_bars-1;i++) w+=wb[i]+((i&1)?addS:addB);
236
+
237
+ dw=2.0*w/((num_bars-6)*7+2*11); /* or min(wb[]) */
238
+ crc=0;
239
+ if ((num_bars)%2!=0 || num_bars<10 || w<7*(num_bars-6)/2+11
240
+ || ((num_bars-6)/2)%2!=0) return 0; /* should be balanced */
241
+ g_debug(fprintf(stderr," UPC/EAN BS= %d-%d %d-%d\n",minB,maxB,minS,maxS);)
242
+ /* check front BSB, middle SBSBS and end BSB */
243
+ dww=0;
244
+ for(i=0;i<3;i++){dww=sqr((wb[i ]+((i&1)?addS:addB))/dw-1);if(dww>0.4)return 0;}
245
+ for(i=0;i<5;i++){dww=sqr((wb[i+ num_bars-3]+((i&1)?addB:addS))/dw-1);if(dww>0.4)return 0;}
246
+ for(i=0;i<3;i++){dww=sqr((wb[i+2*num_bars-4]+((i&1)?addS:addB))/dw-1);if(dww>0.4)return 0;}
247
+ buf =(char *)malloc( (num_bars-6)/2+1); if (!buf) return result;
248
+ result=(char *)malloc(256+(num_bars-6)/2+1);
249
+
250
+ for(ean=i5=0,i1=3;i1<2*num_bars-4;i1+=4) { /* each digit (2bars+2spaces) */
251
+ if (i1==num_bars-3) { i1++; continue; } /* skip middle sync SBSBS */
252
+ for (i4=NumUPC,mirrored=0,digit='?',min_err=16e8,i2=0;i2<NumUPC;i2++) {
253
+ for (err=0,i3=0;i3<4;i3++)
254
+ err+=sqr(codeUPC[i2][i3]-'0'-(wb[i1+i3]+(((i1+i3)&1)?addS:addB))/dw);
255
+ if (err<min_err) { min_err=err; i4=i2; digit='0'+i2%10; mirrored=i2/10; }
256
+ } dww+=min_err; crc+=(digit-'0')*((i5&1)?1:3); /* even*3+odd, last char is even */
257
+ buf[i5++]=digit; if (i5<7) ean=(ean<<1)|mirrored;
258
+ /* ToDo: error as deviation wb from ideal */
259
+ g_debug(fprintf(stderr,"\nDBG: UPC digit=%c mirrored=%d err=%.3f err_m=%.3f ",
260
+ digit,mirrored,min_err/4,dww/(i5*4));)
261
+ }
262
+ /* EAN has a 13th leading digit build by 3 of 6 mirorred digits */
263
+ if (ean & 0x20) ean^=0x3f; /* UPC-E mirrored 1xxxxx => 0yyyyy */
264
+ switch (ean) {
265
+ case 11: ean=1; break;
266
+ case 13: ean=2; break;
267
+ case 14: ean=3; break;
268
+ case 19: ean=4; break;
269
+ case 25: ean=5; break;
270
+ case 28: ean=6; break;
271
+ case 21: ean=7; break;
272
+ case 22: ean=8; break;
273
+ case 26: ean=9; break;
274
+ default: ean=0; /* no or invalid EAN digit or UPC-extension */
275
+ } crc+=ean*1;
276
+ /* ToDo: fix possible buffer OVL, complement crc */
277
+ buf[i5]=0;
278
+ if (result)
279
+ sprintf(result,"<barcode type=\"UPC\" chars=\"%d\" code=\"%d%s\" "
280
+ "crc=\"%d\" error=\"%.3f\" />",
281
+ i5+1,ean,buf,(10-crc%10)%10,dww/((num_bars-6)*2));
282
+ free(buf);
283
+ return result;
284
+ }
285
+
286
+ /* EAN/UPC add-on is either 2 or 5 digits. It always starts with a
287
+ * guard bar BSB, followed by ([digit + SB] * (N-1)) + digit. Digit is
288
+ * SBSB. Two digit add-on's have 7 bars, and 5 digit add ons have 16.
289
+ */
290
+ char *decode_UPC_addon(int *wb, int num_bars){ /* ToDo: char *dest, int len */
291
+ int i, w, i1, i2, i3, i4, i5, digits=num_bars/3;
292
+ double err, min_err, dw, dww=0.0; char digit;
293
+ char *result=NULL, *buf=NULL; /* malloc and store the result */
294
+ int minB, maxB, minS, maxS; /* min/max bars/spaces */
295
+ int addS, addB; /* corrections, JS1002 sample090916 */
296
+
297
+ minB=maxB=wb[0];
298
+ minS=maxS=wb[1];
299
+ /* sample090916 showed maxS = minB so we normalize first */
300
+ for(i=0; i<2*num_bars-1; i++){
301
+ if (i&1) { if (minS>wb[i]) minS=wb[i]; if (maxS<wb[i]) maxS=wb[i]; }
302
+ else { if (minB>wb[i]) minB=wb[i]; if (maxB<wb[i]) maxB=wb[i]; }
303
+ }
304
+ addS=(minB-minS)/2; addB=-(minB-minS)/2;
305
+ if (num_bars!=7 && num_bars!=16)
306
+ return 0;
307
+ for(w=i=0;i<2*num_bars-1;i++) w+=wb[i];
308
+ g_debug(fprintf(stderr," UPC_addon BS= %d-%d %d-%d\n",minB,maxB,minS,maxS);)
309
+
310
+ dw=1.0*w/(digits*7+4 + (digits-1)*2);
311
+ /* check front BSB, and delineators SB */
312
+ dww=0;
313
+ for (i=0;i<2;i++) {
314
+ dww=sqr((wb[i]+((i&1)?addS:addB))/dw-1); if (dww>0.4) return 0; }
315
+ dww=sqr((wb[i]+((i&1)?addS:addB))*0.5/dw-1); if (dww>0.4) return 0;
316
+ for (i=1;i<digits; i++) {
317
+ for (i1=0; i1<2; i1++) {
318
+ dww = sqr((wb[i*6 + 1 + i1]+((i1&1)?addB:addS))/dw-1);
319
+ if (dww > 0.4) return 0;
320
+ }
321
+ }
322
+ buf =(char *)malloc( digits+1); if (!buf) return result;
323
+ result=(char *)malloc(256+digits+1);
324
+
325
+ for(i5=0,i1=3;i1<2*num_bars-1;i1+=6) { /* each digit (2bars+2spaces) */
326
+ for (i4=NumUPC,digit='?',min_err=16e8,i2=0;i2<NumUPC;i2++) {
327
+ for (err=0,i3=0;i3<4;i3++)
328
+ err+=sqr(codeUPC[i2][i3]-'0'-(wb[i1+i3]+(((i1+i3)&1)?addS:addB))/dw);
329
+ if (err<min_err) { min_err=err; i4=i2; digit='0'+i2%10; }
330
+ }
331
+ dww+=min_err;
332
+ buf[i5++]=digit;
333
+ /* ToDo: error as deviation wb from ideal */
334
+ g_debug(fprintf(stderr,"\nDBG: UPC digit=%c err=%.3f err_m=%.3f ",
335
+ digit, min_err/4, dww/(i5*4));)
336
+ }
337
+ buf[i5]=0;
338
+ if (result)
339
+ sprintf(result, "<barcode type=\"UPC_addon\" chars=\"%d\" code=\"%s\" "
340
+ "error=\"%.3f\" />",
341
+ i5, buf, dww/((num_bars-6)*2));
342
+ free(buf);
343
+ return result;
344
+ }
345
+
346
+
347
+ /* --------------------------------------------------------- *
348
+ * code 3 of 9, 3 thick of 9 bars
349
+ * BSBSBSBSB<S> size=7+3*aw aw=2(3), sumS/sumB=2/1?
350
+ * two widths: size=1 or size=2or3, digit_width=13(16)
351
+ * 5 bars and 4(+1) spaces per digit, last space is not used
352
+ * with 2 (or 0) wide bars, 1 (or 3) wide spaces per digit
353
+ * => 3 of 9 => max=9*8*7=504
354
+ * evenBB=(0of5)+(2of5) oddSS=(1of4)+(3of4) max=44
355
+ * ToDo: better code -...-.-.. as 046 or 083 (even,even,odd)
356
+ * sample 090916: width of wide space may be smaller than narrow bar
357
+ */
358
+ #define Num39 (40+4) /* (3of9)=(2of5)(1of4)+(0of5)(3of4), (2of5)(.-..)=0..9 */
359
+ const char *code39= /* rearranged to BBBBBSSSS<S> (bars,spaces) */
360
+ "0..--..-.."
361
+ "1-...-.-..""2.-..-.-..""3--....-..""4..-.-.-..""5-.-...-.."
362
+ "6.--...-..""7...--.-..""8-..-..-..""9.-.-..-.."
363
+ "A-...-..-.""B.-..-..-.""C--.....-.""D..-.-..-.""E-.-....-."
364
+ "F.--....-.""G...--..-.""H-..-...-.""I.-.-...-.""J..--...-."
365
+ "K-...-...-""L.-..-...-""M--......-""N..-.-...-""O-.-.....-"
366
+ "P.--.....-""Q...--...-""R-..-....-""S.-.-....-""T..--....-"
367
+ "U-...--...""V.-..--...""W--...-...""X..-.--...""Y-.-..-..."
368
+ "Z.--..-...""-...---..."".-..-.-..."" .-.-.-...""*..--.-..."
369
+ /* (0of5)(3of4)=(.....)(3of4) store only 3of4? */
370
+ "$.....---.""/.....--.-""+.....-.--""%......---"
371
+ "?xxxxxxxxx";
372
+
373
+ /* example: barcode -E -e 39 -b 123abc | gs -sDEVICE=pnggray -r100 */
374
+
375
+ /* return index[] according to sorted values[], big first */
376
+ void sort(int *value, int *idx, int len){
377
+ int i,j;
378
+ for (j=0;j<len;j++) idx[j]=j; /* initialize */
379
+ for(i=1;i;) { /* bubble sort, len...len^2 steps */
380
+ for(i=j=0;j<len-1;j++) if(value[idx[j]]<value[idx[j+1]]) {
381
+ i=idx[j]; idx[j]=idx[j+1]; idx[j+1]=i; i=1;
382
+ }
383
+ }
384
+ }
385
+
386
+ char *decode_39(int *wb, int num_bars){ /* ToDo: char *dest, int len */
387
+ int i, w, i1, i3, i5, crc,
388
+ idx[9], /* indices sorted by length of wb9[idx] */
389
+ wb9[9], /* next 9 normalized bars and spaces BWBWBWBWB (JS1002) */
390
+ addS, addB, /* normalization diffs */
391
+ minB, maxB, minS, maxS; /* min/max bar/space (JS1002) */
392
+ double dw,dww,err; char *buf;
393
+ char *result=NULL; /* malloc and store the result */
394
+
395
+ /* check for multiple of 5 bars and minimum start+1char+stop=15 bars */
396
+ if ((num_bars)%5!=0 || num_bars<15) return 0;
397
+ minB=maxB=wb[0];
398
+ minS=maxS=wb[1];
399
+ /* sample090916 showed maxS = minB so we normalize first */
400
+ for(i=0; i<2*num_bars-1; i++){
401
+ if (i&1) { if (minS>wb[i]) minS=wb[i]; if (maxS<wb[i]) maxS=wb[i]; }
402
+ else { if (minB>wb[i]) minB=wb[i]; if (maxB<wb[i]) maxB=wb[i]; }
403
+ }
404
+ addS=(minB-minS)/2; addB=-(minB-minS)/2;
405
+ for(w=i=0; i<2*num_bars-1; i++){
406
+ #if 1
407
+ if (i&1) { w+=wb[i]+addS; }
408
+ else { w+=wb[i]+addB; }
409
+ #else
410
+ w+=wb[i]; /* summ width to w */
411
+ #endif
412
+ }
413
+ dw=w*1.0/(16*(num_bars/5)); /* threshold = 1.5..2 */
414
+ /* whats best and most rigorosely for dw=threshold_width?
415
+ * - (1.5..2)*mean_width of every 5th space
416
+ * - (1.5..2)*summ(5bars+5spaces)/(13..16)
417
+ * - 3/4*summ(three thickest)/3
418
+ */
419
+ dww=crc=0; /* error and checksum (not supported yet) */
420
+ #if 0 /* should we exclude any non-standard code39? */
421
+ /* check for correct start and end symbol * or NwNnWnWnN Narrow+Wide */
422
+ for (i=0;i<9;i++) wb9[i]=wb[i]+((i&1)?addS:addB); /* good for sample090916 */
423
+ if (wb9[0]>dw*2 || wb9[1]<=dw*2 || wb9[2]> dw*2) return 0; /* # # */
424
+ for (i=0;i<9;i++) wb9[i]=wb[2*num_bars-2-i]+((i&1)?addS:addB); /* good for sample090916 */
425
+ if (wb9[0]>dw*2 || wb9[1]> dw*2 || wb9[2]<=dw*2) return 0; /* ## # */
426
+ #endif
427
+ g_debug(fprintf(stderr," code39 base=%.3f B=%d-%d S=%d-%d chars=%2d\n ",dw,minB,maxB,minS,maxS,(num_bars)/5);)
428
+ buf =(char *)malloc( 1+(num_bars)/5); if (!buf) return result;
429
+ result=(char *)malloc(256+(num_bars)/5);
430
+
431
+ for(i5=i1=0;i1<2*num_bars-3;i1+=10) {
432
+ /* normalization, good for sample090916 */
433
+ for (i=0;i<9;i++) wb9[i]=wb[i1+i]+((i&1)?addS:addB);
434
+ /* ToDo: looking for three widest bars/gaps, 0 or 2 bars, 1 or 3 spaces */
435
+ sort(wb9,idx,9);
436
+ for(err=0,i3=3;i3<9;i3++) // estimate error ??
437
+ err+=sqr((wb9[idx[i3]])/dw-1.0); /* narrow=1, wide=2..3 */
438
+ dww+=err;
439
+ for(i3=0;i3<Num39;i3++)
440
+ if (code39[10*i3+1+(idx[0]%2)*5+idx[0]/2]=='-'
441
+ && code39[10*i3+1+(idx[1]%2)*5+idx[1]/2]=='-'
442
+ && code39[10*i3+1+(idx[2]%2)*5+idx[2]/2]=='-') break;
443
+ if (i5>0 && i5<num_bars/5-2) crc+=i3;
444
+ buf[i5++]=code39[10*i3];
445
+
446
+ /* ToDo: check if we have even number of black bars within 3 biggest */
447
+ g_debug(for(i3=0;i3<9;i3++)fprintf(stderr,"%02d ",wb[i1+i3]);
448
+ fprintf(stderr," posWide=%d,%d,%d %c err=%.3f\n ",
449
+ idx[0],idx[1],idx[2],buf[i5-1],err/6);)
450
+ { int num_ws=0; // Jul09 ~codabar
451
+ if (idx[0]&1) num_ws++;
452
+ if (idx[1]&1) num_ws++;
453
+ if (idx[2]&1) num_ws++;
454
+ if ((num_ws&1)==0) { // num wide spaces must be 1 or 3
455
+ free (buf); free(result);
456
+ g_debug(fprintf(stderr," num wide spaces = %d, abort code39\n", num_ws);)
457
+ return 0;
458
+ }
459
+ }
460
+ }
461
+ buf[i5]=0;
462
+ if (result)
463
+ sprintf(result,"<barcode type=\"39\" chars=\"%d\" code=\"%s\" "
464
+ "crc=\"%c\" error=\"%.3f\" />",
465
+ i5,buf,code39[(crc%44)*10],dww/((num_bars/5)*6));
466
+ free(buf);
467
+ return result;
468
+ }
469
+
470
+ /* code interleaved 2 of 5 numbers-only (10 bars+spaces = 2 decimal digits)
471
+ B B B B B <= digit1 bars=1,3,5,...
472
+ S S S S S <= digit2 spaces=2,4,6,...
473
+ 1122447700 <= weight digit=sum(bit*weight)%11 (except 7+4=11 means 0)
474
+ N = narrow bar, W = wide bar, n = narrow space, w = wide space
475
+ "NnNn"+interleaved+"WnN" (odd num W, even num w)
476
+ 18 digits/inch
477
+ see http://www.barcode-1.net/i25code.html (Jun 2009)
478
+ minN=0.19mm=0.0075inch
479
+ sizeN>0.02inch: sizeW=2..3*sizeN (but constant)
480
+ sizeN<0.02inch: sizeW=2.2..3*sizeN
481
+ quite zones 10*sizeN or 0.25inch
482
+ heigh=max(0.15*symbol_length,0.25inch)
483
+ Len = (numChars*(2*(sizeW/sizeN)+3) + 6 + (sizeW/sizeN)) * sizeN
484
+ */
485
+ #define Num25 10
486
+ const char *code25= /* is the code sorted randomly? */
487
+ "1-...-2.-..-3--...4..-.-5-.-..6.--..7...--8-..-.9.-.-.0..--.";
488
+
489
+ /* example: barcode -E -e i25 -b 123456 >a.eps */
490
+
491
+ /*
492
+ add i25, patch by: Chris Lee, 13 Jul 2009
493
+ ToDo: check correctness
494
+ */
495
+ char *decode_i25(int *wb, int num_bars){ /* ToDo: char *dest, int len */
496
+ int i, w, i1, i3, i5, crc, idx[7], pos;
497
+ double dw, dww, err; char *buf;
498
+ char *result=NULL; /* malloc and store the result */
499
+
500
+ int *wb_temp;
501
+ int *wb_check;
502
+ int code_chars;
503
+
504
+ if ((num_bars)%5!=4) return 0; /* chars*5bars + 4 start/stop bars */
505
+ code_chars = ((num_bars - 4) / 5) * 2;
506
+ // dw=w*1.0/(9*(num_bars/3)); /* threshold = 1.5..2 */
507
+
508
+ wb_temp = (int *)malloc((code_chars * 5)*sizeof(int)); if (!wb_temp) { return NULL; }
509
+ wb_check = (int *)malloc( 7 *sizeof(int));
510
+ if (!wb_check) { free(wb_temp); return NULL; }
511
+ buf =malloc( code_chars);
512
+ if (!buf) { free(wb_temp); free(wb_check); return NULL; }
513
+
514
+ for (i=0; i<(code_chars * 5)+7; i++) {
515
+ if (i<4) { wb_check[i] = wb[i]; } /* start sequence NnNn... */
516
+ else if (i > ((code_chars*5)+3)) { /* end sequence ...WnN */
517
+ wb_check[i-(code_chars*5)] = wb[i]; }
518
+ else {
519
+ pos = i - 4;
520
+ /* reinterleave 0,5,1,6,2,7,3,8,4,9,... to 0,1,2,3,4,5,6,7,8,9,... */
521
+ // pos = (int)(10*(int)(pos/10) + 1.0*(pos%10)/2.0 + 4.5*(pos%2));
522
+ pos = 10*(pos/10) + (pos%10)/2 + 5*(pos&1);
523
+ wb_temp[pos] = wb[i];
524
+ }
525
+ }
526
+ wb = wb_temp;
527
+
528
+ /* check start / finish codes */
529
+ sort(wb_check,idx,7);
530
+ if (idx[0] != 4 /* widest bar W must be the 4th = 1st of end */
531
+ || wb_check[idx[0]]==wb_check[idx[1]]) { /* exact 1 widest */
532
+ free(wb_temp);
533
+ free(wb_check);
534
+ g_debug(fprintf(stderr," need exact 1 widest at start of end, abort\n");)
535
+ return 0;
536
+ }
537
+
538
+ for(w=i=0; i<5*code_chars;i++ ) w+=wb[i]; /* summ width */
539
+ dw=w*1.0/(16*(num_bars/5)); /* threshold = 1.5..2 */
540
+ /* whats best and most rigorosely for dw=threshold_width?
541
+ * - (1.5..2)*mean_width of every 5th space
542
+ * - (1.5..2)*summ(5bars+5spaces)/(13..16)
543
+ * - 3/4*summ(three thickest)/3
544
+ */
545
+ dww=crc=0; /* error and checksum (not supported yet) */
546
+ #if 0 /* should we exclude any non-standard code39? */
547
+ /* check for correct start and end symbol * or NwNnWnWnN Narrow+Wide */
548
+ i=2*num_bars-2;
549
+ if (wb[ 0]>dw*2 || wb[ 1]<=dw*2 || wb[ 2]> dw*2) return 0;
550
+ if (wb[i-0]>dw*2 || wb[i-1]> dw*2 || wb[i-2]<=dw*2) return 0;
551
+ #endif
552
+ g_debug(fprintf(stderr," code25 base=%.3f chars=%2d\n ",dw,code_chars);)
553
+
554
+ for(i5=i1=0;i1<5*code_chars;i1+=5) {
555
+ /* ToDo: looking for three widest bars/gaps */
556
+ sort(wb+i1,idx,5);
557
+ for(err=0,i3=2;i3<5;i3++)
558
+ err+=sqr(wb[i1+idx[i3]]/dw-1.0); /* narrow=1, wide=2..3 */
559
+ dww+=err;
560
+ for(i3=0;i3<Num25;i3++)
561
+ if (code25[6*i3+1+idx[0]]=='-'
562
+ && code25[6*i3+1+idx[1]]=='-') break;
563
+ //if (i5>0 && i5<num_bars/3-2) crc+=i3;
564
+ buf[i5++]=code25[6*i3];
565
+
566
+ /* ToDo: check if we have even number of black bars within 3 biggest */
567
+ g_debug(for(i3=0;i3<5;i3++)fprintf(stderr,"%02d ",wb[i1+i3]);
568
+ fprintf(stderr," posWide=%d,%d %c err=%.3f\n ",
569
+ idx[0], idx[1], buf[i5-1], err/6);)
570
+ {
571
+ /* check that we have exact 2 widest bars, 2nd widest > 3th widest */
572
+ if (wb[i1+idx[1]]==wb[i1+idx[2]]) {
573
+ free(buf);
574
+ free(wb_temp);
575
+ free(wb_check);
576
+ g_debug(fprintf(stderr," need exact 2 widest, abort\n");)
577
+ return 0;
578
+ }
579
+ }
580
+ }
581
+ buf[i5]=0;
582
+ result=malloc(256+code_chars);
583
+ if (result) // ToDo: fix CRC (not defined?)
584
+ sprintf(result,"<barcode type=\"i25\" chars=\"%d\" code=\"%s\" crc=\"%c\""
585
+ " error=\"%.3f\" />", i5,buf,code25[(crc%10)*10],dww/((num_bars/5)*6));
586
+
587
+ free(wb_temp);
588
+ free(wb_check);
589
+ free(buf);
590
+ return result;
591
+ }
592
+
593
+ /* code codabar, numbers only, 4 bars per char (1*wide bar, 1*wide space)
594
+ robust code (dot-matrix printer)
595
+ characters have same length (distance between 1st bar to 4th space)
596
+ ??? codeproject: 6*n+2*w=12 or 5*n+3*w=14
597
+ ??? suchymips.de:
598
+ variant 1: 18 different bar widths (Monarch code)
599
+ variant 2: 2 different bar widths (Codabar Matrix or ABC-Codabar)
600
+ 9..11 digits/inch, N=narrow bar, W=wide bar, n=narrow space, w=wide space
601
+ see http://www.barcodeman.com/info/codabar.php (Jul 2009)
602
+ minN=0.17mm=0.0065inch, 11 digits/inch = 0.0909 = 14*minN
603
+ 2of7 + extensions
604
+ extensions: 1 wide bar + 2 wide spaces (no narrow space between 2 wide)
605
+ 4 start/stop sets = a/t, b/m, c/ *, d/e
606
+ - mean wide = thickest of 4 bars
607
+ - mean narrow = thinnest of 4 bars, thinnest of 3 (4) spaces or every 4th
608
+ wiki-sample: a31117013206375b (wide spaces between chars) schraeg!
609
+ barcode: t1234567t n=N=1 w=W=3 c=12,14 (not const.)
610
+ */
611
+ const char *code27= /* 4bars+3spaces, 12+12 chars */
612
+ // 0..11: 3 nbar + 1 wbar + 2 nspace + 1 wspace
613
+ "0.....--1....--.2...-..-3--.....4..-..-."
614
+ "5-....-.6.-....-7.-..-..8.--....9-..-...-...--..$..--..."
615
+ // 12..15: 1 nbar + 3 wbar + 3 nspace + 0 wspace
616
+ ":-...-.-/-.-...-.-.-.-..+..-.-.-"
617
+ // 16..23: 3 nbar + 1 wbar + 1 nspace + 2 wspace
618
+ "a..--.-.b.-.-..-c...-.--d...---.t..--.-.n.-.-..-*...-.--e...---."
619
+ // EOS
620
+ "????????";
621
+
622
+ /* example: barcode -E -e cbr -b 123456 >a.eps */
623
+
624
+ char *decode_27(int *wb, int num_bars){ /* ToDo: char *dest, int len */
625
+ int i, i1, i2, i3, i4, i5, b_idx[4], s_idx[3], b_w[4], s_w[3],
626
+ max_wdiff, err=0;
627
+ // double dw, err;
628
+ char *buf, char27[8]="......";
629
+ char *result=NULL; /* malloc and store the result */
630
+
631
+ int code_chars;
632
+ #if 0 // ToDo: verifications nb_max < wb_min etc.
633
+ int nb_min=99999, nb_max=0, nb_sum=0, nb_num=0; // narrow bar
634
+ int ns_min=99999, ns_max=0, ns_sum=0, ns_num=0; // narrow space
635
+ int wb_min=99999, wb_max=0, wb_sum=0, wb_num=0; // wide bar
636
+ int ws_min=99999, ws_max=0, ws_sum=0, ws_num=0; // wide space
637
+ #endif
638
+
639
+ if ((num_bars)%4!=0) return 0; /* chars*4bars */
640
+ code_chars = num_bars / 4;
641
+ // dw=w*1.0/(9*(num_bars/3)); /* threshold = 1.5..2 */
642
+
643
+ g_debug(fprintf(stderr," codabar chars= %d\n ", code_chars);)
644
+ buf =malloc( code_chars); if (!buf) return result;
645
+ result=malloc(256+code_chars);
646
+ i5=0; // index output string
647
+ for (i=0; i< code_chars; i++) {
648
+ b_w[0]=wb[i*8+0]; // 1st bar
649
+ b_w[1]=wb[i*8+2]; // 2nd bar
650
+ b_w[2]=wb[i*8+4]; // 3th bar
651
+ b_w[3]=wb[i*8+6]; // 4th bar
652
+ s_w[0]=wb[i*8+1]; // 1st space
653
+ s_w[1]=wb[i*8+3]; // 2nd space
654
+ s_w[2]=wb[i*8+5]; // 3th space
655
+ sort(b_w,b_idx,4); /* idx[0] points to widest bar */
656
+ sort(s_w,s_idx,3); /* idx[0] points to widest space */
657
+ g_debug(for(i3=0;i3<7;i3++)fprintf(stderr,"%02d ",wb[8*i+i3]);)
658
+ if (b_w[b_idx[0]]==b_w[b_idx[3]]) { err=__LINE__; break; } // min. 1 wide + narrow
659
+ // search max. diff between sorted widths
660
+ i2=b_w[b_idx[0]]-b_w[b_idx[1]]; i1=1; max_wdiff=i2; // diff widest - 2nd wides
661
+ i2=b_w[b_idx[1]]-b_w[b_idx[2]]; if (i2>max_wdiff) { i1=2; max_wdiff=i2; }
662
+ i2=b_w[b_idx[2]]-b_w[b_idx[3]]; if (i2>max_wdiff) { i1=3; max_wdiff=i2; }
663
+ if (i1==2) { err=__LINE__; break; } // 2 wide + 2 narrow bars not allowed
664
+ for (i3=0;i3<7;i3++) char27[i3]='.'; // reset char
665
+ if (i1==1) { // 1 wide bar (1 or 2 wspaces)
666
+ if (s_w[s_idx[0]]-s_w[s_idx[1]]
667
+ >s_w[s_idx[1]]-s_w[s_idx[2]]) { // 1 wspace
668
+ char27[2*b_idx[0]+0]='-';
669
+ char27[2*s_idx[0]+1]='-';
670
+ } else { // assume 2 wspaces
671
+ if (s_w[s_idx[2]]==s_w[s_idx[1]]) { err=__LINE__; break; }
672
+ char27[2*b_idx[0]+0]='-';
673
+ char27[2*s_idx[0]+1]='-';
674
+ char27[2*s_idx[1]+1]='-';
675
+ }
676
+ } else { // assume 3 wbars + 0 wspaces
677
+ char27[2*s_idx[0]+0]='-';
678
+ char27[2*s_idx[1]+0]='-';
679
+ char27[2*s_idx[2]+0]='-';
680
+ }
681
+ for(i4=24,i3=0;i3<24;i3++) {
682
+ if (code27[8*i3+1]==char27[0]
683
+ && code27[8*i3+2]==char27[1]
684
+ && code27[8*i3+3]==char27[2]
685
+ && code27[8*i3+4]==char27[3]
686
+ && code27[8*i3+5]==char27[4]
687
+ && code27[8*i3+6]==char27[5]
688
+ && code27[8*i3+7]==char27[6]) {
689
+ i4=i3; buf[i5++]=code27[8*i3]; break; }
690
+ }
691
+ g_debug(fprintf(stderr," %s c27= %c\n ", char27, ((i5)?buf[i5-1]:'?'));)
692
+ if (i4==24) { err=__LINE__; break; }
693
+ } // each char
694
+ if (i>=code_chars) { // else: inconsistent char
695
+ g_debug(fprintf(stderr," code27 base=%.3f chars=%2d\n ",0.0,code_chars);)
696
+ } else {
697
+ g_debug(fprintf(stderr," error %d at char %d, abort\n", err, i);)
698
+ free(result); result=0;
699
+ }
700
+ buf[i5]=0;
701
+ if (result) // ToDo: fix CRC (not defined?)
702
+ sprintf(result,"<barcode type=\"codabar\" chars=\"%d\" code=\"%s\""
703
+ " crc=\"%c\" error=\"%.3f\" />", i5,buf,'?',0.0);
704
+
705
+ free(buf);
706
+ return result; // free at parent!
707
+ }
708
+
709
+
710
+ /*
711
+ decode barcode
712
+ - check main characteristics (num bars, min+max width, etc.)
713
+ - detect code type
714
+ - the current algorithm measures the width of bars and spaces
715
+ called by detect_barcode()
716
+ ToDo: - like storing sequence of widths for 1D code
717
+ store array of bits for 2D matrix code and decode later
718
+ */
719
+ char *decode_barcode(struct box *bb){ /* ToDo: char *dest, int len */
720
+ job_t *job=OCR_JOB; /* fixme */
721
+ int i, num_bars, yy, w, ww, dx, xx, cs=job->cfg.cs, *wb;
722
+ char *result=NULL; /* store the result */
723
+ yy=(bb->y0+bb->y1)/2;
724
+ w=ww=bb->x1-bb->x0+1;
725
+ num_bars = num_cross(bb->x0,bb->x1,yy,yy,bb->p,job->cfg.cs);
726
+ if(job->cfg.verbose)
727
+ fprintf(stderr,"\n# ... detect bars=%3d w=%4d",num_bars,ww);
728
+
729
+ /* store width of bars and spaces to buffer wb */
730
+ wb=(int *)malloc(2*num_bars*sizeof(int)); if(!wb) return NULL;
731
+ xx=bb->x0;
732
+ xx-=loop(bb->p,xx,yy, 8,cs,1,LE);
733
+ xx+=loop(bb->p,xx,yy,ww,cs,0,RI); /* start with a bar! */
734
+ for (i=0;i<2*num_bars;i++) {
735
+ dx=loop(bb->p,xx,yy,w,cs,1^(i&1),RI);
736
+ xx+=dx;
737
+ w-=dx;
738
+ wb[i]=dx;
739
+ } wb[2*num_bars-1]=0;
740
+
741
+ /* ToDo: what about probability? if not unique
742
+ * - add argument char *result which can be modified or not,
743
+ * - or add box2? (would reuse of this code more difficult)
744
+ */
745
+ /* test code128 characteristics, ToDo: look for correct start/stop 211 seq. */
746
+ if ((num_bars-1)%3==0 && num_bars>=10 && ww>=11*(num_bars-1)/3+2){
747
+ if (!result) result=decode_code128(wb,num_bars);
748
+ }
749
+ /* test UPC/EAN characteristics */
750
+ if ((num_bars)%2==0 && num_bars>=8 && ww>=7*(num_bars-6)/2+11
751
+ && ((num_bars-6)/2)%2==0){ /* should be balanced */
752
+ if (!result) result=decode_UPC(wb,num_bars);
753
+ }
754
+ /* test UPC_addon by Michael van Rooyen, often on books */
755
+ if (num_bars==7 || num_bars==16)
756
+ if (!result) result=decode_UPC_addon(wb,num_bars);
757
+
758
+ /* test code39 characteristics */
759
+ if ((num_bars)%5==0 && num_bars>14){
760
+ if (!result) result=decode_39(wb,num_bars);
761
+ }
762
+ /* test i2of5 chartacteristics */
763
+ if ((num_bars)%5==4 && num_bars>3) {
764
+ if (!result) result=decode_i25(wb,num_bars);
765
+ }
766
+
767
+ /* test codabar chartacteristics */
768
+ if ((num_bars)%4==0 && num_bars>3) {
769
+ if (!result) result=decode_27(wb,num_bars);
770
+ }
771
+
772
+ free(wb);
773
+ return result;
774
+ }
775
+
776
+ // RS Reed Solomon Code
777
+ // Definition of Galois Field GF(2^m) (de: Zahlenraum, endl. Koerper)
778
+ // 1bit: m=1 dual GF2={0,1}
779
+ // 0+0=0 0+1=1 1+0=1 1+1=0 0*0=0*1=1*0=0 1*1=1 a^1=1?
780
+ // a^0=1 a^1=1
781
+ // 8bit: m=8 byte GF256= a=primitiv_element=2 a^255=1
782
+ // exp[0]=1; expa[i+1]=expa[i]*a;
783
+ // i: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ... 254 255
784
+ // a^i: 1 2 4 8 16 32 64 128 29 58 116 232 205 135 19 ... 142 1
785
+ // generated by shift-register
786
+ // representation of GF(256) using the given primitive polynomial
787
+ // GF256_QR_CODE_FIELD = GF256(0x011D); // x^8 + x^4 + x^3 + x^2 + 1
788
+ // GF256_DATA_MATRIX_FIELD = GF256(0x012D); // x^8 + x^5 + x^3 + x^2 + 1
789
+ // based on LGPL code by Phil Karn, KA9Q 2004 + qrencode by Kentaro Fukuchi
790
+
791
+ typedef unsigned char uchar;
792
+ /**
793
+ * Reed-Solomon codec control block
794
+ */
795
+ struct _RS {
796
+ int mm; /* Bits per symbol, max=8 */
797
+ int nn; /* Symbols per block (= (1<<mm)-1) */
798
+ uchar alpha_exp[256]; /* log lookup table x=alpha^i, max_mm=8 */
799
+ uchar alpha_log[256]; /* Antilog lookup table i=loga(x), max_mm=8 */
800
+ uchar genpoly[256]; /* Generator polynomial, nroots_man=2^8-1 */
801
+ int nroots; /* Number of generator roots = number of parity symbols */
802
+ int fcr; /* First consecutive root, index form */
803
+ int prim; /* Primitive element, index form */
804
+ int iprim; /* prim-th root of 1, index form */
805
+ int pad; /* Padding bytes in shortened block */
806
+ int gfpoly;
807
+ };
808
+
809
+ static struct _RS rs;
810
+
811
+
812
+ static int GF256_mult(int a, int b) { // a*b
813
+ int i, r=0, t=b; // result + temp var
814
+ int primitive = 0x011D;
815
+ for (i=0; i<8; i++) {
816
+ // <<= 1 is multiplication by a=2, ^= primitive_polynomial
817
+ r <<= 1; if (r & 0x100) r ^= primitive;
818
+ t <<= 1; if (t & 0x100) r ^= a;
819
+ }
820
+ return r;
821
+ }
822
+
823
+ static int GF256_invers_mult(int b) { // 1/b, (a/b)=a*(1/b)
824
+ int i, r = b;
825
+ for (i=1; i<7; i++) r = GF256_mult( GF256_mult(r,r), b);
826
+ return r;
827
+ }
828
+ /* Initialize a Reed-Solomon codec
829
+ * symsize = symbol size, bits (8 for GF256=GF(2^8))
830
+ * gfpoly = Field generator polynomial coefficients (0x011D for QR-Code)
831
+ * fcr = 1st root of RS code generator polynomial, index form (0..2^symsize-1)
832
+ * fcr = 0
833
+ * prim = primitive element to generate polynomial roots (1..2^symsize-1)
834
+ * prim = 1
835
+ * nroots = RS code generator polynomial degree (number of roots) (0..2^8-1)
836
+ nroots = num_ecc_bytes
837
+ * pad = padding bytes at front of shortened block (0..2^8-2-nroots)
838
+ * pad = 255 - num_ecc_bytes - num_data_bytes
839
+ */
840
+ static inline int modnn(struct _RS *rs, int x){
841
+ while (x >= rs->nn) { // 255
842
+ x -= rs->nn; // 255
843
+ x = (x >> rs->mm) + (x & rs->nn); // 8 , 255
844
+ }
845
+ return x;
846
+ }
847
+ static void init_rs(int symsize, int gfpoly, int fcr,
848
+ int prim, int nroots, int pad) {
849
+ int i,j,x,root,iprim;
850
+ rs.mm= symsize;
851
+ rs.nn= (1<<symsize)-1;
852
+ rs.pad= pad;
853
+ rs.nroots= nroots;
854
+
855
+ g_debug(fprintf(stderr,"\n# init_rs symsize= %d gfpoly=0x%04x necc= %4d\n# ",
856
+ symsize, gfpoly, nroots);)
857
+ /* Generate Galois field lookup tables using
858
+ * primitive field generator polynomial gfpoly */
859
+ rs.alpha_log[0]= rs.nn; // nn=255, log(0) = -inf
860
+ rs.alpha_exp[rs.nn]= 0; // alha^(-inf) = 0
861
+ x=1;
862
+ for (i=0; i<255; i++) {
863
+ rs.alpha_log[x] = i;
864
+ rs.alpha_exp[i] = x;
865
+ x <<= 1; if (x >= 0x100) { x ^= gfpoly; }
866
+ // g_debug(fprintf(stderr," %3d",x);)
867
+ }
868
+ if (x!=1) fprintf(stderr,"init_rs failed, bad primitive gfpoly x=%d\n# ",x);
869
+ // for (i=0; i<256; i++)
870
+ // printf(" i a^i loga(i) %3d %3d %3d\n", i, alpha_exp[i], alpha_log[i]);
871
+ /* Form RS code generator polynomial from its roots */
872
+ /* Find prim-th root of 1, used in decoding, prim=1, rs.nn=255, iprim=1 */
873
+ for(iprim=1; (iprim % prim) != 0; iprim += rs.nn);
874
+ rs.iprim = iprim / prim;
875
+ rs.genpoly[0]=1; // alpha0*x^nroot + ...
876
+ for (i = 0, root=fcr*prim; i < nroots; i++, root += prim) {
877
+ rs.genpoly[i+1] = 1;
878
+ /* Multiply rs.genpoly[] by alpha^(root + x) */
879
+ for (j = i; j > 0; j--){
880
+ if (rs.genpoly[j] != 0)
881
+ rs.genpoly[j] = rs.genpoly[j-1] ^ rs.alpha_exp[
882
+ modnn(&rs,rs.alpha_log[rs.genpoly[j]] + root)];
883
+ else
884
+ rs.genpoly[j] = rs.genpoly[j-1];
885
+ }
886
+ /* rs.genpoly[0] can never be zero */
887
+ rs.genpoly[0] = rs.alpha_exp[modnn(&rs,rs.alpha_log[rs.genpoly[0]] + root)];
888
+ }
889
+ #if DO_DEBUG
890
+ if (OCR_JOB->cfg.verbose&1) {
891
+ int i;
892
+ for (i=0; i <= nroots; i++)
893
+ fprintf(stderr,"%3d ", i);
894
+ fprintf(stderr,"\n# ");
895
+ for (i=0; i <= nroots; i++)
896
+ fprintf(stderr,"%3d ", rs.genpoly[i]); // coefficient * x^i
897
+ fprintf(stderr,"\n# ");
898
+ }
899
+ #endif
900
+ /* convert rs.genpoly[] to index form for quicker encoding */
901
+ for (i = 0; i <= nroots; i++)
902
+ rs.genpoly[i] = rs.alpha_log[rs.genpoly[i]];
903
+ #if DO_DEBUG
904
+ if (OCR_JOB->cfg.verbose&1) {
905
+ int i;
906
+ for (i=0; i <= nroots; i++)
907
+ fprintf(stderr,"%3d ", rs.genpoly[i]); // exponent i of alpha^i
908
+ fprintf(stderr,"\n# ");
909
+ }
910
+ #endif
911
+ }
912
+ void encode_rs_char(struct _RS *rs, const uchar *data, uchar *parity) {
913
+ int i, j; uchar feedback;
914
+ memset(parity,0,rs->nroots*sizeof(uchar));
915
+
916
+ for(i=0;i<rs->nn - rs->nroots - rs->pad;i++){
917
+ feedback = rs->alpha_log[data[i] ^ parity[0]];
918
+ if(feedback != rs->nn){ /* feedback term is non-zero */
919
+ #ifdef UNNORMALIZED
920
+ // unnecessary when genpoly[nroots] = 1, as constructed by init_rs()
921
+ feedback = modnn(rs, rs->nn - rs->genpoly[rs->nroots] + feedback);
922
+ #endif
923
+ for(j=1;j<rs->nroots;j++)
924
+ parity[j] ^= rs->alpha_exp[modnn(rs, feedback + rs->genpoly[rs->nroots-j])];
925
+ }
926
+ /* Shift */
927
+ memmove(&parity[0],&parity[1],sizeof(uchar)*(rs->nroots-1));
928
+ if(feedback != rs->nn)
929
+ parity[rs->nroots-1] = rs->alpha_exp[modnn(rs, feedback + rs->genpoly[0])];
930
+ else
931
+ parity[rs->nroots-1] = 0;
932
+ }
933
+ #if DO_DEBUG
934
+ if (OCR_JOB->cfg.verbose&1) {
935
+ int i;
936
+ fprintf(stderr,"\n# ecc\n# ");
937
+ for (i=0; i <= rs->nroots; i++)
938
+ fprintf(stderr,"%3d ", parity[i]); // exponent i of alpha^i
939
+ fprintf(stderr,"\n# ");
940
+ for (i=0; i <= rs->nroots; i++)
941
+ fprintf(stderr," %02x ", parity[i]); // exponent i of alpha^i
942
+ fprintf(stderr,"\n# ");
943
+ }
944
+ #endif
945
+ }
946
+
947
+ /*
948
+ * taking the list of boxes and search for groups of bars (1D-barcodes)
949
+ */
950
+ int detect_barcode(job_t *job)
951
+ {
952
+ int j=0, j2=0, bx0, by0, bx1, by1, bdx, bdy, bbx, bby, rm,
953
+ nbars, x0, y0, dx, dy, cs, x, y, yl0, yl1, yr0, yr1,
954
+ regx, regy; // regions for 2D barcode
955
+ struct box *box2, *box3;
956
+
957
+ if(job->cfg.verbose)
958
+ fprintf(stderr,"# barcode.c detect_barcode ");
959
+ x0=y0=0; rm=0; dx=job->src.p.x; dy=job->src.p.y; cs=job->cfg.cs;
960
+ bdx=0; bdy=0;
961
+ for_each_data(&(job->res.boxlist)) {
962
+ box2 = (struct box *)list_get_current(&(job->res.boxlist));
963
+ /* detect width (bdx) and height (bdy) of possible bar */
964
+ /* ToDo: better check for a line */
965
+ bdx=box2->x1-box2->x0+1 /* substract correction for skewed bars */
966
+ -loop(box2->p,box2->x1,(box2->y0+box2->y1)/2,box2->x1-box2->x0,cs,0,LE)
967
+ -loop(box2->p,box2->x0,(box2->y0+box2->y1)/2,box2->x1-box2->x0,cs,0,RI);
968
+ bdy=box2->y1-box2->y0+1;
969
+ if (box2->c == PICTURE || box2->c == UNKNOWN)
970
+ if (box2->y0 >= y0 && box2->y1 <= y0 + dy /* within frame? */
971
+ && box2->x0 >= x0 && box2->x1 <= x0 + dx
972
+ && box2->y1 - box2->y0 > 19 /* min. length */
973
+ && box2->y1 - box2->y0 > 8 * bdx
974
+ ) { /* a bar? */
975
+ j=1; /* number of bars */
976
+ bx0=box2->x0; bx1=box2->x1; /* initial values for barcode frame */
977
+ by0=box2->y0; by1=box2->y1;
978
+ bbx=bx1-bx0+2; /* width of bar */
979
+ /* this is for scans which are not exactly horizontal */
980
+ yl0=yr0=by0; /* left and right upper bound */
981
+ yl1=yr1=by1; /* left and right lower bound */
982
+ /* --- iteratively take into account next nearest bar ---
983
+ * this is important, because bar-boxes are not in right order */
984
+ for (j2=1;j2;) {
985
+ j2=0;
986
+ /* expand a frame around the potential barcode (bx0,by0,bx1,by1) */
987
+ for_each_data(&(job->res.boxlist)) {
988
+ box3 = (struct box *)list_get_current(&(job->res.boxlist));
989
+ /* bdy=box3->y1-box3->y0+1; */
990
+ if (box2!=box3)
991
+ if (box3->c == PICTURE || box3->c == UNKNOWN)
992
+ if (box3->y0 >= y0 && box3->y1 <= y0 + dy /* within image */
993
+ && box3->x0 >= x0 && box3->x1 <= x0 + dx
994
+ && box3->y1 - box3->y0 > 19 /* min. length */
995
+ && box3->y1 - box3->y0 > 4 * (bdx) /* height > 4*width2 */
996
+ && box3->x1 - box3->x0 < 4 * (bdy) /* width < height/4 = bar */
997
+ && (( abs(box3->y0-by0)<bdy/16+4 /* within bar-box ? */
998
+ && abs(box3->y1-by1)<bdy/2 ) /* lower ends of UPC could be longer */
999
+ ||( abs(box3->y0-yl0)<bdy/16+4 /* left side of frame */
1000
+ && abs(box3->y1-yl1)<bdy/2
1001
+ && box3->x0 <= bx0 )
1002
+ ||( abs(box3->y0-yr0)<bdy/16+4 /* right side of frame */
1003
+ && abs(box3->y1-yr1)<bdy/2
1004
+ && box3->x0 >= bx1 ) )
1005
+ && box3->x0 > bx0 - 12*bbx /* startspace=5...10 */
1006
+ && box3->x1 < bx1 + 12*bbx
1007
+ && box3->x0 > bx0 - bdy/2 /* dont glue two barcodes together */
1008
+ && box3->x1 < bx1 + bdy/2 /* ex: ean13a.jpg */
1009
+ /* dont check bars which already within the frame twice ? */
1010
+ && ( box3->x1 > bx1 || box3->x0 < bx0 )
1011
+ ) { /* a bar? -> extend barcode frame only in x direction */
1012
+ /* take minimum of y to have valid barcode for all y */
1013
+ if (box3->x0<bx0) { bx0=box3->x0; yl0=box3->y0; yl1=box3->y1; }
1014
+ if (box3->x1>bx1) { bx1=box3->x1; yr0=box3->y0; yr1=box3->y1; }
1015
+ if (4*(box3->y1-box3->y0)>3*(by1-by0)) { /* carefull reduce */
1016
+ if (box3->y0>by0) by0=box3->y0; /* ToDo: fix for non-horizontal */
1017
+ if (box3->y1<by1) by1=box3->y1;
1018
+ }
1019
+ j++; /* found a near bar and count to num bars */
1020
+ j2=1; /* continue searching (endless loop?) */
1021
+ }
1022
+ } end_for_each(&(job->res.boxlist));
1023
+ }
1024
+ /* j is the num of bars found above, some inner bars are not counted */
1025
+ /* ToDo: better iterative add next nearest bars from sorted list near bars? */
1026
+ if (j>5) {
1027
+ char *code=0;
1028
+ box2->c=PICTURE; /* BARCODE */
1029
+ box2->x0=bx0; box2->y0=by0;
1030
+ box2->x1=bx1; box2->y1=by1;
1031
+ /* ToDo: add pointer to decoded text */
1032
+
1033
+ y=(box2->y0+box2->y1)/2;
1034
+ if (job->cfg.verbose){
1035
+ int nbars;
1036
+ nbars=num_cross(box2->x0,box2->x1,y,y,box2->p,job->cfg.cs);
1037
+ fprintf(stderr,"\n# barcode at %3d %3d size %3d %3d nbars %d (%d)",
1038
+ bx0,by0,bx1-bx0+1,by1-by0+1,nbars,j);
1039
+ if (j!=nbars)
1040
+ fprintf(stderr,"\n# ... trouble: num_found_bars != num_cross");
1041
+ /* this is because some far bars are detected before near bars */
1042
+ }
1043
+ /* transport the info to the gocr-output (development) */
1044
+ /* ToDo: decode and print/store barcode bars=j */
1045
+ code=decode_barcode(box2); /* ToDo: char *dest, int len */
1046
+ if (!code) { /* failed */
1047
+ code=(char *)malloc(128);
1048
+ /* ToDo: analyze and output num_bars, width of bars etc. */
1049
+ if(code) strncpy(code,"<barcode type=\"unknown\" />",128);
1050
+ }
1051
+ if (job->cfg.verbose)
1052
+ fprintf(stderr,"\n# ... decoded as: %s", code);
1053
+ setas(box2,code,99); /* ToDo: set a better weight */
1054
+ free(code);
1055
+
1056
+ /* remove inner boxes, only if sure!? (ToDo: use cfg.certainty) */
1057
+ for_each_data(&(job->res.boxlist)) {
1058
+ box3 = (struct box *)list_get_current(&(job->res.boxlist));
1059
+ /* bdy=box3->y1-box3->y0+1; */
1060
+ if (box2!=box3)
1061
+ if (box3->c == PICTURE || box3->c == UNKNOWN)
1062
+ if ( abs(box3->y0-by0)<bdy/16+4 /* within bar-box ? */
1063
+ && abs(box3->y1-by1)<bdy/2 /* lower ends of UPC could be longer */
1064
+ && box3->x1 <= bx1
1065
+ && box3->x0 >= bx0
1066
+ ) {
1067
+ rm++; /* count removed boxes */
1068
+ list_del(&(job->res.boxlist),box3);
1069
+ free_box(box3);
1070
+ }
1071
+ } end_for_each(&(job->res.boxlist));
1072
+ if (job->cfg.verbose)
1073
+ fprintf(stderr,"\n# ... removed boxes: %d", rm);
1074
+ rm=0;
1075
+ }
1076
+ }
1077
+ } end_for_each(&(job->res.boxlist));
1078
+
1079
+ /* recalculate averages without bars */
1080
+ job->res.numC=job->res.sumX=job->res.sumY=j2=0;
1081
+ for_each_data(&(job->res.boxlist)) {
1082
+ j2++;
1083
+ box3 = (struct box *)list_get_current(&(job->res.boxlist));
1084
+ if (box3->c==PICTURE) continue;
1085
+ job->res.numC++; /* count remaining boxes */
1086
+ job->res.sumX+=box3->x1-box3->x0+1;
1087
+ job->res.sumY+=box3->y1-box3->y0+1;
1088
+ } end_for_each(&(job->res.boxlist));
1089
+ if(job->cfg.verbose)
1090
+ fprintf(stderr,"\n# ... boxes %d nC %d\n",
1091
+ j2, job->res.numC);
1092
+
1093
+
1094
+ /* ---------------------------------------------------------------
1095
+ * ToDo: detect DataMatrix = iec16022 (ecc200, 24 sizes)
1096
+ * search square of 2 lines and 2 dottet lines (first no rotation)
1097
+ * output characteristics pixel size, bytes, code type, etc.
1098
+ * symbolsize: 10^2...26^2, 32^2 ... 104^2, 120^2 ... 144^2
1099
+ * dataregion: 8^2...24^2, (4,16)*(14...24)^2, 36*(18,20,22)^2
1100
+ * codewords: 3...44, 62...816, 1050...1558
1101
+ * errorwords: 5...28, 36...336, 408...620
1102
+ * fill byte = 129, ASCIIdata = ASCII + 1
1103
+ *
1104
+ * ToDo: !!! no Reed Solomon Error Correction at the moment !!!
1105
+ * ToDo: !!! raw data output, no ASCII decoding !!!
1106
+ * see http://grandzebu.net/ ... datamatrix.htm
1107
+ * sample: iec16022 -f PNG 123456 > datamatrix_123456.png
1108
+ */
1109
+
1110
+ if(job->cfg.verbose)
1111
+ fprintf(stderr,"# barcode.c detect_barcode search datamatrix ");
1112
+ x0=y0=0; rm=0; dx=job->src.p.x; dy=job->src.p.y; cs=job->cfg.cs;
1113
+ for_each_data(&(job->res.boxlist)) {
1114
+ box2 = (struct box *)list_get_current(&(job->res.boxlist));
1115
+ /* detect width (bdx) and height (bdy) of possible matrix */
1116
+ /* ToDo: better check for a line */
1117
+ bdx=box2->x1-box2->x0+1; /* ToDo: correction for skewed matrix */
1118
+ bdy=box2->y1-box2->y0+1;
1119
+ if (bdx<10 || bdy<10) continue; // 2010-09-28 reduce output + computation
1120
+ // g_debug(fprintf(stderr,"\n# datamatrix box size %4d %4d", bdx, bdy);)
1121
+ by0=0; bx1=0; /* x of hor. max_num_crosses, max_num_crosses */
1122
+ bx0=0; by1=0; /* y of vert. max_num_crosses, max_num_crosses */
1123
+ x=num_cross(box2->x0,box2->x1,box2->y1,box2->y1,box2->p,job->cfg.cs);
1124
+ y=num_cross(box2->x0,box2->x0,box2->y0,box2->y1,box2->p,job->cfg.cs);
1125
+ for (j = box2->y0; j <= box2->y1; j++) {
1126
+ nbars=num_cross(box2->x0,box2->x1,j,j,box2->p,job->cfg.cs);
1127
+ for (j2=0; j2<nbars; j2++) {
1128
+ int t = box2->x0+j2*bdx/(nbars);
1129
+ // fprintf(stderr,"\n# %3d %3d %d %d",j,j2,((getpixel(box2->p,t+1*bdx/(4*nbars),j)<cs)?1:0),
1130
+ // ((getpixel(box2->p,t+3*bdx/(4*nbars),j)<cs)?1:0));
1131
+ if (((getpixel(box2->p,t+1*bdx/(4*nbars),j)<cs)?1:0)!=1) break;
1132
+ if (((getpixel(box2->p,t+3*bdx/(4*nbars),j)<cs)?1:0)!=0) break;
1133
+ } if (j2!=nbars) continue;
1134
+ if (nbars> bx1) { bx1=nbars; by0=j; } // search most upper
1135
+ }
1136
+ for (j = box2->x0; j <= box2->x1; j++) {
1137
+ nbars=num_cross(j,j,box2->y0,box2->y1,box2->p,job->cfg.cs);
1138
+ for (j2=0; j2<nbars; j2++) {
1139
+ int t = box2->y0+j2*bdy/(nbars);
1140
+ // fprintf(stderr,"\n# %3d %3d %d %d",j,j2,((getpixel(box2->p,j,t+1*bdy/(4*nbars))<cs)?1:0),
1141
+ // ((getpixel(box2->p,j,t+3*bdy/(4*nbars))<cs)?1:0));
1142
+ if (((getpixel(box2->p,j,t+1*bdy/(4*nbars))<cs)?1:0)!=0) break;
1143
+ if (((getpixel(box2->p,j,t+3*bdy/(4*nbars))<cs)?1:0)!=1) break;
1144
+ } if (j2!=nbars) continue;
1145
+ if (nbars>=by1) { by1=nbars; bx0=j; } // search most right
1146
+ }
1147
+ bbx=(bx1)?bdx/(2*bx1):1; /* width of base square */
1148
+ bby=(by1)?bdy/(2*by1):1; /* height of base square*/
1149
+ // ToDo: check upper and left finder pattern
1150
+ if (box2->c != PICTURE && box2->c != UNKNOWN) continue;
1151
+ if (x!=1 || y!=1) continue;
1152
+ // 30 possible ECC 200 datamatrix size versions
1153
+ if (( ( ( (bx1>=5 && bx1<=13)
1154
+ || (bx1>=16 && bx1<=26 && bx1%2==0)
1155
+ || (bx1>=32 && bx1<=52 && bx1%4==0)
1156
+ || (bx1>=60 && bx1<=72 && bx1%6==0))
1157
+ && bx1==by1)
1158
+ || (by1==4 && bx1==9)
1159
+ || (by1==6 && bx1==13)
1160
+ || (by1==8 && bx1==36)
1161
+ || (by1==4 && bx1==16)
1162
+ || (by1==6 && bx1==18)
1163
+ || (by1==8 && bx1==24))
1164
+ && by0 < box2->y0 + bby // alternating b/w border
1165
+ && bx0 > box2->x1 - bbx // alternating b/w border
1166
+ ) { /* a bar? */
1167
+ g_debug(fprintf(stderr,"\n# datamatrix box size %4d %4d ncross %d %d %d %d bb %d %d", bdx, bdy, x, y, bx1, by1, bbx, bby);)
1168
+ regx=1; regy=1; // regx*regy regions (2x2,4x4,6x6,1x2)
1169
+ if (bx1>=16) { regx=2; } // 13 < x <= 16
1170
+ if (bx1>=32) { regx=4; } // 26 < x <= 32
1171
+ if (bx1>=60) { regx=6; } // 52 < x <= 60
1172
+ if (by1>=16) { regy=2; }
1173
+ if (by1>=32) { regy=4; }
1174
+ if (by1>=60) { regy=6; }
1175
+ g_debug(fprintf(stderr," mark%03d %dx%d reg %d %d bb %d %d bytes %d",
1176
+ __LINE__,2*bx1,2*by1,regx,regy,bbx,bby,(bx1-regx)*(by1-regy)/2);)
1177
+ /* j is the num of bars found above, some inner bars are not counted */
1178
+ /* ToDo: better iterative add next nearest bars from sorted list near bars? */
1179
+ {
1180
+ int row, col;
1181
+ char *dm_bitmap=NULL;
1182
+
1183
+ // store pattern without finder pattern into dm_bitmap
1184
+ dm_bitmap=(char *)malloc(4*(bx1-regx)*(by1-regy));
1185
+ if (!dm_bitmap) { fprintf(stderr," ERROR: mallocDM1 failed\n"); continue; }
1186
+ for (row=0;row<2*(by1-regy);row++) {
1187
+ for (col=0;col<2*(bx1-regx);col++) {
1188
+ x = box2->x0+bbx*(col+1+2*((col+2)/(2*bx1/regx)))+bbx/2;
1189
+ y = box2->y0+bby*(row+1+2*((row+2)/(2*by1/regy)))+bby/2;
1190
+ dm_bitmap[row*2*(bx1-regx)+col]=
1191
+ ((getpixel(box2->p,x,y)<cs)?1:0);
1192
+ }
1193
+ }
1194
+
1195
+ /* transport the info to the gocr-output (development) */
1196
+ if (job->cfg.verbose) {
1197
+ fprintf(stderr,"\n# ");
1198
+ for (col=0;col<2*bx1;col++)
1199
+ if (col<=8) fprintf(stderr," %1d",col); else
1200
+ if (col<=98 && col%2==0) fprintf(stderr," %3d",col); else
1201
+ if (col%4==0) fprintf(stderr," %7d",col);
1202
+ for (row=0;row<2*by1;row++) {
1203
+ fprintf(stderr,"\n# %3d: ", row);
1204
+ for (col=0;col<2*bx1;col++)
1205
+ fprintf(stderr," %c",
1206
+ ((getpixel(box2->p,box2->x0+bbx*col+bbx/2,
1207
+ box2->y0+bby*row+bby/2)<cs)?
1208
+ (( col%(2*bx1/regx)==0
1209
+ || col%(2*bx1/regx)==2*bx1/regx-1
1210
+ || row%(2*by1/regy)==0
1211
+ || row%(2*by1/regy)==2*by1/regy-1
1212
+ )?'x':'o'):' ')); // 'o' = data1, 'x' = finder1
1213
+ }
1214
+ // show pure data
1215
+ fprintf(stderr,"\n# now without finder pattern\n# ");
1216
+ for (col=0;col<2*(bx1-regx);col++)
1217
+ if (col<=8) fprintf(stderr," %1d",col); else
1218
+ if (col<=98 && col%2==0) fprintf(stderr," %3d",col); else
1219
+ if (col%4==0) fprintf(stderr," %7d",col);
1220
+ for (row=0;row<2*(by1-regy);row++) {
1221
+ fprintf(stderr,"\n# %3d: ", row);
1222
+ for (col=0;col<2*(bx1-regx);col++) {
1223
+ fprintf(stderr," %c",
1224
+ (dm_bitmap[row*2*(bx1-regx)+col])?'o':' ');
1225
+ }
1226
+ }
1227
+ }
1228
+
1229
+ char *code=0; int cpos=0;
1230
+ box2->c=PICTURE; /* BARCODE */
1231
+ code=NULL;
1232
+ code=(char *)malloc(6*4*bx1*by1/8+128); /* maxlen: &#%3d; = 6 */
1233
+ if (!code) { fprintf(stderr," ERROR: mallocDM2 failed\n"); continue; }
1234
+ code[0]=0;
1235
+ strncpy(code,"<barcode type=\"datamatrix ecc200\" rawcode=\"\" />",128);
1236
+ cpos=43; // insert chars at position 40
1237
+ /* pixel 32x32 = (2*2)*(2*7+2)^2 = 4*196/8bit - 12B (Reed Solomon),
1238
+ * = 98-12 B = 86B */
1239
+
1240
+ // code=decode_datamatrix(box2); /* ToDo: char *dest, int len */
1241
+ // for 8x8 (10x10) first CW is at 1: -2,+2, 2: +0,+0, 3: +2,-2,
1242
+ // 4: +5,-1, 5: +3,+1, 6: +1,+3, 7: -1,+5, 8: +4,+4
1243
+ // = diagonal zick/zack
1244
+ // --> x=c 7 6 (start: r=4, c=0) up/right=(r-=2, c+=2)
1245
+ // | 5 4 3 down/left=(r+=2, c-=2)
1246
+ // v y=r 2 1 0 turn=(r+=3, c+=1)
1247
+ // sample ascii=\x30='0' \x40='@' \x20=' '
1248
+ /* ToDo: decode and print/store barcode bars=j */
1249
+ x = +0; // col += 2
1250
+ y = +4; // row -= 2
1251
+ int nc=2*(bx1-regx), nr=2*(by1-regy),
1252
+ // dm_mode=0, // ECC200-mode: 0=ASCII+digitpair, 230=C40
1253
+ dm_d=+1; // direction right/down
1254
+ for (j=0;j<(bx1-regx)*(by1-regy)/2;j++) { // each byte
1255
+ int dm_byte=0;
1256
+ const int *pp; /* pointer to (const int) */
1257
+ const int // bitmatrix + 4 special cases for lower left corner
1258
+ pn[8*2]={ 0, 0, -1, 0, -2, 0, 0,-1, -1,-1, -2,-1, -1,-2, -2,-2},
1259
+ pa[8*2]={-1,+3, -1,+2, -1,+1, -1,+0, -2,+0, +2,-1, +1,-1, +0,-1},
1260
+ pb[8*2]={-1,+3, -1,+2, -2,+2, -3,+2, -4,+2, +0,+1, +0,+0, +0,-1},
1261
+ pc[8*2]={-1,+5, -1,+4, -1,+3, -1,+2, -2,+2, +0,+1, +0,+0, +0,-1},
1262
+ pd[8*2]={-3,-3, -4,-3, -5,-3, -3,-4, -4,-4, -5,-4, -3,-5, -2,-5};
1263
+ pp=pn;
1264
+ if (x==0 && y==nr) { pp=pa; }
1265
+ if (x==0 && y==nr-2 && (nc%4)) { pp=pb; }
1266
+ if (x==0 && y==nr-2 && (nc%8)==4) { pp=pc; }
1267
+ if (x==2 && y==nr+4 && (nc%8)==0) { pp=pd; }
1268
+ for (j2=0;j2<8;j2++) { // each bit
1269
+ col= (x + pp[2*j2+0]);
1270
+ row= (y + pp[2*j2+1]);
1271
+ if (pp!=pn) { col=(col+nc)%nc; row=(row+nr)%nr; }
1272
+ if (row<0) { row+=nr; col+=4-((nr+4)%8); }
1273
+ if (col<0) { col+=nc; row+=4-((nc+4)%8); }
1274
+ col=(col+nc)%nc; row=(row+nr)%nr;
1275
+ dm_byte += (dm_bitmap[row*nc+col])<<j2;
1276
+ // fprintf(stderr," @ %3d %3d",col,row);
1277
+ }
1278
+ if ((dm_d>0 && x>=0 && y<nr)
1279
+ ||(dm_d<0 && y>=0 && x<nc)) {
1280
+ fprintf(stderr,"\n# @ %3d %3d : %02x %3d d %2d pos %3d decode= ",
1281
+ x, y, dm_byte, dm_byte, dm_d, cpos);
1282
+ if (dm_byte>=' '+1 && dm_byte<=128)
1283
+ { code[cpos++]=(char)(dm_byte-1);
1284
+ fprintf(stderr,"%c", dm_byte-1); }
1285
+ else if (dm_byte>=130 && dm_byte<=229) // 130 + 00..99
1286
+ { code[cpos++]=(char)((dm_byte-130)/10)+'0';
1287
+ code[cpos++]=(char)((dm_byte-130)%10)+'0';
1288
+ fprintf(stderr,"%02d", dm_byte-130); }
1289
+ else {
1290
+ int nout=0;
1291
+ if (dm_byte==129) fprintf(stderr,"[Padding]");
1292
+ if (dm_byte==230) fprintf(stderr,"[C40]"); // 1.5 uppercase/B
1293
+ if (dm_byte==231) fprintf(stderr,"[Base256]"); // 1 byte/B
1294
+ if (dm_byte==232) fprintf(stderr,"[FNC1]");
1295
+ if (dm_byte==235) fprintf(stderr,"[ShiftASC]"); // next -127
1296
+ if (dm_byte==238) fprintf(stderr,"[AnsiX12]");
1297
+ if (dm_byte==239) fprintf(stderr,"[Text]"); // 1.5 lowercase/B
1298
+ if (dm_byte==240) fprintf(stderr,"[EDIFACT]"); // 1.33char/byte
1299
+ if (dm_byte==254) fprintf(stderr,"[EOTorRET2Text]");
1300
+ // ToDo: store bytes + interprete it later for output
1301
+ {
1302
+ nout = sprintf(code+cpos,"&#%d;",dm_byte);
1303
+ if (nout>0) cpos+=nout;
1304
+ }
1305
+ }
1306
+ } else j--; // missing reed-solomon chars from skipping!?
1307
+ if (cpos > 6*4*bx1*by1/8+128 - 10) break; // avoid buffer overflow
1308
+
1309
+ x += dm_d * 2;
1310
+ y -= dm_d * 2;
1311
+ if (dm_d>0 && (y<0 || x>=nc)) { y++; x+=3; dm_d*=-1; } else
1312
+ if (dm_d<0 && (x<0 || y>=nr)) { x++; y+=3; dm_d*=-1; }
1313
+ if (dm_d>0 && x>=nc && y>=nr) break;
1314
+ }
1315
+
1316
+ if (job->cfg.verbose){
1317
+ fprintf(stderr,"\n# datamatrix at %3d %3d size %3d %3d npix %d*%d unit %d*%d",
1318
+ box2->x0,box2->y0,bdx,bdy,2*bx1,2*by1,bbx,bby);
1319
+ }
1320
+ if (code && cpos<2*4*bx1*by1/8+128-6)
1321
+ strncpy(code+cpos,"\" />",6); // terminate xml string
1322
+ code[2*4*bx1*by1/8+127]=0;
1323
+ if (!code) { /* failed */
1324
+ code=(char *)malloc(128);
1325
+ /* ToDo: analyze and output num_bars, width of bars etc. */
1326
+ if (code) strncpy(code,"<barcode type=\"unknown datamatrix\" />",128);
1327
+ }
1328
+ if (job->cfg.verbose)
1329
+ fprintf(stderr,"\n# ... decoded as: %s", code);
1330
+ setas(box2,code,99); /* ToDo: set a better weight */
1331
+ free(code);
1332
+
1333
+ /* remove inner boxes, only if sure!? (ToDo: use cfg.certainty) */
1334
+ for_each_data(&(job->res.boxlist)) {
1335
+ box3 = (struct box *)list_get_current(&(job->res.boxlist));
1336
+ /* bdy=box3->y1-box3->y0+1; */
1337
+ if (box2!=box3)
1338
+ if (box3->c == PICTURE || box3->c == UNKNOWN)
1339
+ if ( box3->y0 >= box2->y0 /* within datamatrix ? */
1340
+ && box3->y1 <= box2->y1
1341
+ && box3->x1 <= box2->x1
1342
+ && box3->x0 >= box2->x0
1343
+ ) {
1344
+ rm++; /* count removed boxes */
1345
+ list_del(&(job->res.boxlist),box3);
1346
+ free_box(box3);
1347
+ }
1348
+ } end_for_each(&(job->res.boxlist));
1349
+ if (job->cfg.verbose)
1350
+ fprintf(stderr,"\n# ... removed boxes: %d", rm);
1351
+ rm=0;
1352
+ free(dm_bitmap);
1353
+ }
1354
+ }
1355
+ } end_for_each(&(job->res.boxlist));
1356
+
1357
+ /* ---------------------------------------------------------------
1358
+ * ToDo: QR-Code (Quick-Response)
1359
+ * Version 1..40: size= ((17+version*4) modules)^2 = 21,25,...,177 ^2
1360
+ * Data-Bits = size^2-3*64-2*version-2-formatbits
1361
+ * Data-Bits for ECC-Level=L: 152 ... 23648 (2953B)
1362
+ * (21,21): start(lower right corner=20,20)
1363
+ * - go up (width=2) +(-1,0) +(+1,-1) until upper border ??
1364
+ * - than go down (width=2) until lower border, etc. ??
1365
+ * - bits masked (8versions)
1366
+ * ...
1367
+ * two weeks of work to find out all the mysteries of QR-Code 2010-10-JS
1368
+ * (no access to the iso papers, which cost money)
1369
+ bit0
1370
+ v
1371
+ @@@@@@@.fxxxx.@@@@@@@ fff= format-bits (2*14bit)
1372
+ @.....@.fxxxx.@.....@ xxx= data-bits starting right bottom, going up
1373
+ @.@@@.@.fxxxx.@.@@@.@ @@.= finder pattern + timing pattern
1374
+ @.@@@.@.fxxxx.@.@@@.@
1375
+ @.@@@.@.fxxxx.@.@@@.@
1376
+ @.....@.fxxxx.@.....@
1377
+ @@@@@@@.@.@.@.@@@@@@@
1378
+ ........fxxxx........
1379
+ ffffff@ffxxxxffffffff<-bit0
1380
+ xxxxxx.xxxxxxxxxxxxxx
1381
+ xxxxxx@xxxxxxxxxxxxxx
1382
+ xxxxxx.xxxxxxxxxxxxxx
1383
+ xxxxxx@xxxxxxxxxxxxxx
1384
+ ........@xxxxxxxxxxxx
1385
+ @@@@@@@.fxxxxxxxxxxxx
1386
+ @.....@.fxxxxxxxxxxxx
1387
+ @.@@@.@.fxxxxxxxxxxxx
1388
+ @.@@@.@.fxxxxxxxxxxxx
1389
+ @.@@@.@.fxxxxxxxxxxxx
1390
+ @.....@.fxxxxxxxxxxxx
1391
+ @@@@@@@.fxxxxxxxxxxxx
1392
+ ^-bit14
1393
+ */
1394
+
1395
+ { // qrcode 2010-10-13
1396
+ // taken from qrencode-3.0.3/qrspec.c RS blocks
1397
+ // ToDo: rawbytes and bits can be computed, but what about ecc0..3 ???
1398
+ // rawbytes mod (b1+b2) == b2
1399
+ // ecc mod (b1+b2) == 0
1400
+ static int qrConst[40][6+8]= {
1401
+ // raw_bytes+bitrest, ecc_bytes, byte_interleaving
1402
+ // L M Q H L M Q H
1403
+ // rawB R ecc0 ecc1 ecc2 ecc3 b1 b2 b1 b2 b1 b2 b1 b2
1404
+ { 26, 0, 7, 10, 13, 17, 1, 0, 1, 0, 1, 0, 1, 0}, // 1
1405
+ { 44, 7, 10, 16, 22, 28, 1, 0, 1, 0, 1, 0, 1, 0},
1406
+ { 70, 7, 15, 26, 36, 44, 1, 0, 1, 0, 2, 0, 2, 0},
1407
+ { 100, 7, 20, 36, 52, 64, 1, 0, 2, 0, 2, 0, 4, 0},
1408
+ { 134, 7, 26, 48, 72, 88, 1, 0, 2, 0, 2, 2, 2, 2}, // 5
1409
+ { 172, 7, 36, 64, 96, 112, 2, 0, 4, 0, 4, 0, 4, 0},
1410
+ { 196, 0, 40, 72, 108, 130, 2, 0, 4, 0, 2, 4, 4, 1},
1411
+ { 242, 0, 48, 88, 132, 156, 2, 0, 2, 2, 4, 2, 4, 2},
1412
+ { 292, 0, 60, 110, 160, 192, 2, 0, 3, 2, 4, 4, 4, 4},
1413
+ { 346, 0, 72, 130, 192, 224, 2, 2, 4, 1, 6, 2, 6, 2}, //10
1414
+ { 404, 0, 80, 150, 224, 264, 4, 0, 1, 4, 4, 4, 3, 8},
1415
+ { 466, 0, 96, 176, 260, 308, 2, 2, 6, 2, 4, 6, 7, 4},
1416
+ { 532, 0, 104, 198, 288, 352, 4, 0, 8, 1, 8, 4, 12, 4},
1417
+ { 581, 3, 120, 216, 320, 384, 3, 1, 4, 5, 11, 5, 11, 5},
1418
+ { 655, 3, 132, 240, 360, 432, 5, 1, 5, 5, 5, 7, 11, 7}, //15
1419
+ { 733, 3, 144, 280, 408, 480, 5, 1, 7, 3, 15, 2, 3, 13},
1420
+ { 815, 3, 168, 308, 448, 532, 1, 5, 10, 1, 1, 15, 2, 17},
1421
+ { 901, 3, 180, 338, 504, 588, 5, 1, 9, 4, 17, 1, 2, 19},
1422
+ { 991, 3, 196, 364, 546, 650, 3, 4, 3, 11, 17, 4, 9, 16},
1423
+ { 1085, 3, 224, 416, 600, 700, 3, 5, 3, 13, 15, 5, 15, 10}, //20
1424
+ { 1156, 4, 224, 442, 644, 750, 4, 4, 17, 0, 17, 6, 19, 6},
1425
+ { 1258, 4, 252, 476, 690, 816, 2, 7, 17, 0, 7, 16, 34, 0},
1426
+ { 1364, 4, 270, 504, 750, 900, 4, 5, 4, 14, 11, 14, 16, 14},
1427
+ { 1474, 4, 300, 560, 810, 960, 6, 4, 6, 14, 11, 16, 30, 2},
1428
+ { 1588, 4, 312, 588, 870, 1050, 8, 4, 8, 13, 7, 22, 22, 13}, //25
1429
+ { 1706, 4, 336, 644, 952, 1110, 10, 2, 19, 4, 28, 6, 33, 4},
1430
+ { 1828, 4, 360, 700, 1020, 1200, 8, 4, 22, 3, 8, 26, 12, 28},
1431
+ { 1921, 3, 390, 728, 1050, 1260, 3, 10, 3, 23, 4, 31, 11, 31},
1432
+ { 2051, 3, 420, 784, 1140, 1350, 7, 7, 21, 7, 1, 37, 19, 26},
1433
+ { 2185, 3, 450, 812, 1200, 1440, 5, 10, 19, 10, 15, 25, 23, 25}, //30
1434
+ { 2323, 3, 480, 868, 1290, 1530, 13, 3, 2, 29, 42, 1, 23, 28},
1435
+ { 2465, 3, 510, 924, 1350, 1620, 17, 0, 10, 23, 10, 35, 19, 35},
1436
+ { 2611, 3, 540, 980, 1440, 1710, 17, 1, 14, 21, 29, 19, 11, 46},
1437
+ { 2761, 3, 570, 1036, 1530, 1800, 13, 6, 14, 23, 44, 7, 59, 1},
1438
+ { 2876, 0, 570, 1064, 1590, 1890, 12, 7, 12, 26, 39, 14, 22, 41}, //35
1439
+ { 3034, 0, 600, 1120, 1680, 1980, 6, 14, 6, 34, 46, 10, 2, 64},
1440
+ { 3196, 0, 630, 1204, 1770, 2100, 17, 4, 29, 14, 49, 10, 24, 46},
1441
+ { 3362, 0, 660, 1260, 1860, 2220, 4, 18, 13, 32, 48, 14, 42, 32},
1442
+ { 3532, 0, 720, 1316, 1950, 2310, 20, 4, 40, 7, 43, 22, 10, 67},
1443
+ { 3706, 0, 750, 1372, 2040, 2430, 19, 6, 18, 31, 34, 34, 20, 61}}; //40
1444
+ // rawbytes/blocks = 3706 / (19+6) = 148 Bytes per Block (30 ecc bytes)
1445
+ // rawbytes/blocks = 3706 / (20+61) = 45 Bytes per Block (30 ecc bytes)
1446
+ // 4 bits (mode) + 10,9,8,8 | 12,11,16,10 | 14,13,16,12 bits (size_of_len)
1447
+ // 012 AB byte kanji
1448
+ static int head_bits09[16]={0,14,13,0,12,0,0,0,12,0,0,0,0,0,0,0};
1449
+ static int head_bits26[16]={0,16,15,0,20,0,0,0,14,0,0,0,0,0,0,0};
1450
+ static int head_bits40[16]={0,18,17,0,20,0,0,0,16,0,0,0,0,0,0,0};
1451
+ static int word_bits[16]= {0,10,11,0, 8,0,0,0,13,0,0,0,0,0,0,0};
1452
+ static int word_nchr[16]= {0, 3, 2,0, 1,0,0,0, 2,0,0,0,0,0,0,0};
1453
+ int *head_bits=NULL;
1454
+ int x02,y02,dx2,dy2, x03,y03,dx3,dy3,
1455
+ interleave=1, // = qrConst[qr_version-1][6+2*qr_ecclevel+0];
1456
+ num_marker=0, /* number of detected big marker squares */
1457
+ qrcode=0; /* 1=detected, -1=detected_but_invalid_code */
1458
+ int qr_marker[3][4]; // x,y,dx,dy
1459
+ unsigned char *qrbytes=NULL, *qrtext=NULL; // for real data
1460
+ char *bits=NULL, *code=NULL;
1461
+ int fbits=0, // 15 formatbits (put in a 16..32bit word)
1462
+ bbits, wbits; // 8bits_per_byte, 11bits_per_word
1463
+ int i, j, num_bars, block_nbits=0, nbits=0, nwbits, ix, iy,
1464
+ nchars=0, // number chars encoded per block
1465
+ dchars=0, block_dchars=0, // number of decoded chars
1466
+ qr_mode=0, qr_mask=0, qr_version=0, qr_ecclevel=0;
1467
+ int an2, ad1, ad2, // allignment parts, rest distance, main distance
1468
+ num_rawbits;
1469
+
1470
+ if(job->cfg.verbose)
1471
+ fprintf(stderr,"#\n# barcode.c detect_barcode search qrcode ");
1472
+ #if 1
1473
+ for (j=0;j<4;j++) // LMQH: ecc % (b1+b2) == 0
1474
+ for (i=0;i<40;i++)
1475
+ if (qrConst[i][2+j]%(qrConst[i][6+2*j+0]+qrConst[i][6+2*j+1])!=0)
1476
+ fprintf(stderr,"ERROR qrcode L%04d i=%d j=%d\n", __LINE__,i,j);
1477
+ for (j=0;j<4;j++) // LMQH: rawbytes % (b1+b2) == b2
1478
+ for (i=0;i<40;i++)
1479
+ if (qrConst[i][0]%(qrConst[i][6+2*j+0]+qrConst[i][6+2*j+1])
1480
+ !=qrConst[i][6+2*j+1])
1481
+ fprintf(stderr,"ERROR qrcode L%04d i=%d j=%d\n", __LINE__,i,j);
1482
+ #endif
1483
+ // first searching biggest square objects = marker (min=3)
1484
+ x0=y0=0; rm=0; dx=job->src.p.x; dy=job->src.p.y; cs=job->cfg.cs;
1485
+ for_each_data(&(job->res.boxlist)) {
1486
+ box2 = (struct box *)list_get_current(&(job->res.boxlist));
1487
+ x02=box2->x0; dx2=box2->x1 - x02 + 1; /* ToDo: correction for skewed matrix */
1488
+ y02=box2->y0; dy2=box2->y1 - y02 + 1;
1489
+ /* detect width (bdx) and height (bdy) of possible matrix */
1490
+ /* ToDo: better check for a line */
1491
+ if (dx2<7 || dy2<7 || 8*abs(dx2-dy2)>dx2+dy2) continue;
1492
+ // ToDo: get center point c0, get max distance point from center = i1,
1493
+ // (in upper left region)
1494
+ // get max distance point from i1 = i2, get max dist from i0,i2 = i3
1495
+ // get max distance from i3 = i4 , check square
1496
+ #if 0
1497
+ int i1, i2, i3, i4, d;
1498
+ if (!box2->num_frames) continue;
1499
+ j=0; ix=x0+dx/2; iy=y0+dy/2;
1500
+ for (i=0;i<box2->num_frame_vectors[0];i++) {
1501
+ x=box2->frame_vector[i][0]; /* take a vector */
1502
+ y=box2->frame_vector[i][1];
1503
+ /* distance to upper left end, normalized to 128 */
1504
+ // d=sq((x-rx)*128/dx)+sq((y-ry)*128/dy); // old 2009-07
1505
+ d=abs(ix-x) + abs(iy-y);
1506
+ if (d>=j) { j=d; i1=i; }
1507
+ }
1508
+ #endif
1509
+ y= y02+dy2/2;
1510
+ x= loop(box2->p,x02 ,y,dx2,cs,0,RI); if ( x >dx2/16) continue;
1511
+ x+=loop(box2->p,x02+x,y,dx2,cs,1,RI); if (abs(x- dx2/7)>dx2/16) continue;
1512
+ x+=loop(box2->p,x02+x,y,dx2,cs,0,RI); if (abs(x-2*dx2/7)>dx2/16) continue;
1513
+ x+=loop(box2->p,x02+x,y,dx2,cs,1,RI); if (abs(x-5*dx2/7)>dx2/16) continue;
1514
+ x+=loop(box2->p,x02+x,y,dx2,cs,0,RI); if (abs(x-6*dx2/7)>dx2/16) continue;
1515
+ y= y02+dy2/14;
1516
+ x= loop(box2->p,x02 ,y,dx2,cs,0,RI); if (abs(x-0*dx2/7)>dx2/16) continue;
1517
+ x+=loop(box2->p,x02+x,y,dx2,cs,1,RI); if (abs(x-7*dx2/7)>dx2/16) continue;
1518
+ y= y02+13*dy2/14;
1519
+ x= loop(box2->p,x02 ,y,dx2,cs,0,RI); if (abs(x-0*dx2/7)>dx2/16) continue;
1520
+ x+=loop(box2->p,x02+x,y,dx2,cs,1,RI); if (abs(x-7*dx2/7)>dx2/16) continue;
1521
+ y= y02+3*dy2/14;
1522
+ x= loop(box2->p,x02 ,y,dx2,cs,0,RI); if (abs(x-0*dx2/7)>dx2/16) continue;
1523
+ x+=loop(box2->p,x02+x,y,dx2,cs,1,RI); if (abs(x-1*dx2/7)>dx2/16) continue;
1524
+ x+=loop(box2->p,x02+x,y,dx2,cs,0,RI); if (abs(x-6*dx2/7)>dx2/16) continue;
1525
+ y= y02+11*dy2/14;
1526
+ x= loop(box2->p,x02 ,y,dx2,cs,0,RI); if (abs(x-0*dx2/7)>dx2/16) continue;
1527
+ x+=loop(box2->p,x02+x,y,dx2,cs,1,RI); if (abs(x-1*dx2/7)>dx2/16) continue;
1528
+ x+=loop(box2->p,x02+x,y,dx2,cs,0,RI); if (abs(x-6*dx2/7)>dx2/16) continue;
1529
+ x= x02+dx2/2;
1530
+ y= loop(box2->p,x,y02 ,dy2,cs,0,DO); if ( y >dy2/16) continue;
1531
+ y+=loop(box2->p,x,y02+y,dy2,cs,1,DO); if (abs(y- dy2/7)>dy2/16) continue;
1532
+ y+=loop(box2->p,x,y02+y,dy2,cs,0,DO); if (abs(y-2*dy2/7)>dy2/16) continue;
1533
+ y+=loop(box2->p,x,y02+y,dy2,cs,1,DO); if (abs(y-5*dy2/7)>dy2/16) continue;
1534
+ y+=loop(box2->p,x,y02+y,dy2,cs,0,DO); if (abs(y-6*dy2/7)>dy2/16) continue;
1535
+ x= x02+dx2/14;
1536
+ y= loop(box2->p,x,y02 ,dy2,cs,0,DO); if (abs(y-0*dy2/7)>dy2/16) continue;
1537
+ y+=loop(box2->p,x,y02+y,dy2,cs,1,DO); if (abs(y-7*dy2/7)>dy2/16) continue;
1538
+ x= x02+13*dx2/14;
1539
+ y= loop(box2->p,x,y02 ,dy2,cs,0,DO); if (abs(y-0*dy2/7)>dy2/16) continue;
1540
+ y+=loop(box2->p,x,y02+y,dy2,cs,1,DO); if (abs(y-7*dy2/7)>dy2/16) continue;
1541
+ x= x02+3*dx2/14;
1542
+ y= loop(box2->p,x,y02 ,dy2,cs,0,DO); if (abs(y-0*dy2/7)>dy2/16) continue;
1543
+ y+=loop(box2->p,x,y02+y,dy2,cs,1,DO); if (abs(y-1*dy2/7)>dy2/16) continue;
1544
+ y+=loop(box2->p,x,y02+y,dy2,cs,0,DO); if (abs(y-6*dy2/7)>dy2/16) continue;
1545
+ x= x02+11*dx2/14;
1546
+ y= loop(box2->p,x,y02 ,dy2,cs,0,DO); if (abs(y-0*dy2/7)>dy2/16) continue;
1547
+ y+=loop(box2->p,x,y02+y,dy2,cs,1,DO); if (abs(y-1*dy2/7)>dy2/16) continue;
1548
+ y+=loop(box2->p,x,y02+y,dy2,cs,0,DO); if (abs(y-6*dy2/7)>dy2/16) continue;
1549
+ g_debug(fprintf(stderr,"\n# qrcode marker %d %4d %4d at %4d %4d",num_marker,dx2,dy2,x02,y02);)
1550
+ if (num_marker<3) {
1551
+ qr_marker[num_marker][0]=x02;
1552
+ qr_marker[num_marker][1]=y02;
1553
+ qr_marker[num_marker][2]=dx2;
1554
+ qr_marker[num_marker][3]=dy2;
1555
+ } else qrcode=-1;
1556
+ num_marker++;
1557
+ } end_for_each(&(job->res.boxlist));
1558
+ if (num_marker==3 && qr_marker[0][0]>qr_marker[1][0]) {
1559
+ // sort upper markers
1560
+ i=qr_marker[0][0]; qr_marker[0][0]=qr_marker[1][0]; qr_marker[1][0]=i;
1561
+ i=qr_marker[0][1]; qr_marker[0][1]=qr_marker[1][1]; qr_marker[1][1]=i;
1562
+ i=qr_marker[0][2]; qr_marker[0][2]=qr_marker[1][2]; qr_marker[1][2]=i;
1563
+ i=qr_marker[0][3]; qr_marker[0][3]=qr_marker[1][3]; qr_marker[1][3]=i;
1564
+ }
1565
+ if (num_marker==3 // check right order (ToDo: sort it)
1566
+ // a.x0 a.dx b.x0
1567
+ && qr_marker[0][0]+qr_marker[0][2]<qr_marker[1][0]
1568
+ // a.y0 a.dy c.y0
1569
+ && qr_marker[0][1]+qr_marker[0][3]<qr_marker[2][1]) { // qrcode detected
1570
+ x03=qr_marker[0][0];
1571
+ y03=qr_marker[0][1];
1572
+ dx3=qr_marker[1][0]+qr_marker[1][2]-qr_marker[0][0];
1573
+ dy3=qr_marker[2][1]+qr_marker[2][3]-qr_marker[0][1];
1574
+ i = num_cross(x03,x03+dx3-1,y03+13*qr_marker[1][3]/14,
1575
+ y03+13*qr_marker[1][3]/14,box2->p,job->cfg.cs);
1576
+ i = 2*(i-2)+15; // num_pixel from timing pattern
1577
+ j = num_cross(x03+13*qr_marker[1][2]/14,
1578
+ x03+13*qr_marker[1][2]/14,y03,y03+dy3-1,box2->p,job->cfg.cs);
1579
+ j = 2*(j-2)+15; // num_pixel from timing pattern
1580
+ x= 14 * dx3 / (qr_marker[0][2]+qr_marker[1][2]);
1581
+ y= 14 * dy3 / (qr_marker[0][3]+qr_marker[2][3]);
1582
+ num_bars= i;
1583
+ if ((i-17)%4!=0 && (j-17)%4==0) num_bars=j; // bad i, but good j ?
1584
+ qr_version= (num_bars-17) / 4; // size 21..177 to version 1..40
1585
+ // ToDo: check syncs and mark all boxes within qr_code as picture
1586
+ // num_cross = distance / base
1587
+ g_debug(fprintf(stderr,"\n# qrcode at %4d %4d %4d %4d px %d %d = %d %d %d v= %d ",
1588
+ x03,y03,dx3,dy3,x,y, i,j,num_bars, qr_version);)
1589
+ x=y=num_bars; // better?
1590
+ // num alignments/per_direction: 1-1 0, 2-11 1, 12-20++ 2
1591
+ // num alignments = (na+1)^2-3 , adist= (x-13)/(2*na)
1592
+ // distance from 6 to first and further alignment patterns (ad1,ad2,ad2,..)
1593
+ // v1: +8
1594
+ // v2-6: +12 +16 +20 +24 +28
1595
+ // v7-13: +16,16 +18,18 +20,20 +22,22 +24,24 +26,26 +28,28
1596
+ // v14-20: +20,20*2 +20,22*2 +20,24*2 +24,24*2 +24,26*2 +24,28*2 +28,28*2
1597
+ // v21-27: +22,22*3 +20,24*3 +24,24*3 +22,26*3 +26,26*3 +24,28*3 +28,28*3
1598
+ // v28-34: +20,24*4 +24,24*4 +20,26*4 +24,26*4 +28,26*4 +24,28*4 +28,28*4
1599
+ // v35-40: +24,24*5 +18,26*5 +22,26*5 +26,26*5 +20,28*5 +24,28*5
1600
+ // start: v=2
1601
+ // ad2 must be set, to avoid endeless loop later!?
1602
+ ad1=ad2=28; an2=0; // num alignments - 1 (after initial alignment)
1603
+ for (i=2;i<=qr_version;i++){
1604
+ if (an2) ad2=(4*i+17-13+an2-an2/4*2)/(an2+1); // main distance
1605
+ ad2=2*((ad2+1)/2); // round up
1606
+ ad1=(4*i+17-13)-an2*ad2; // rest distance for the leftmost pattern
1607
+ if (ad1+an2*ad2 >= 28+an2*28) an2++;
1608
+ // max distance alignments reached
1609
+ }
1610
+ num_rawbits= (4*qr_version+17)*(4*qr_version+17) // square area
1611
+ - 3 * 8*8 // - 8*8 finder pattern
1612
+ - ((an2>=0) ? 5*5 * (an2+1)*(an2+1) : 0) // alignment pattern
1613
+ - 2*((an2>=1) ? 4*5 * (an2 ) : 0) // alignment pattern
1614
+ - 2*(4*qr_version+17-16) // timing pattern
1615
+ - ((qr_version<=6)?0:2*3*6) // undocumented extra pattern?
1616
+ - 2*15 // - 2 * 15 bit format pattern (hor + vert)
1617
+ - 1; // black bit at (8,maxy-7)
1618
+ g_debug(fprintf(stderr,"\n# qrcode v= %2d dist= %2d %2d * %d rawbits= %5d bytes= %5d",
1619
+ qr_version, ad1, ad2, an2, num_rawbits, num_rawbits/8);)
1620
+ // additional alignment patterns (against skewness)
1621
+ // v1M= head=2Byte + data=16Byte=128bit + ecc=7B? = 25Byte=206bit?
1622
+ // v9 53 v9L=1856bits=230byte(8bit)
1623
+ // v40 177 v40L=2953 bytes (2^12) = 23624+24 Bit
1624
+ if (x==y && (x-17)%4==0 && x>=21 && x<=177) { // if square and v=1..40
1625
+ bits= (char *)malloc(x*y);
1626
+ if (bits) {
1627
+ for (i=0;i<x*y;i++) {
1628
+ bits[i]=((getpixel(box2->p,
1629
+ x03 + ((i%x)*dx3 + dx3/2) / x,
1630
+ y03 + ((i/x)*dy3 + dy3/2) / y) < job->cfg.cs) ? 1 : 0);
1631
+ //g_debug(if (i%x==0) fprintf(stderr,"\n# qrcode ");)
1632
+ //g_debug(fprintf(stderr,"%c",((bits[i])?'@':'.'));)
1633
+ }
1634
+ qrcode=1;
1635
+ // ToDo: check finder pattern
1636
+ for (i=0;i<x-14;i++) {
1637
+ if ((bits[6*x+(7+i)]&1)!=(i&1)){
1638
+ qrcode=-1;
1639
+ g_debug(fprintf(stderr,"\n# qrcode bad finder bit at %d %d",7+i,6);)
1640
+ }
1641
+ if ((bits[6+(7+i)*x]&1)!=(i&1)){
1642
+ qrcode=-2;
1643
+ g_debug(fprintf(stderr,"\n# qrcode bad finder bit at %d %d",6,7+i);)
1644
+ }
1645
+ bits[6*x+(7+i)]|=2; // mark as finder
1646
+ bits[6+(7+i)*x]|=2;
1647
+ }
1648
+ if ((bits[8+(x-7-1)*x]&1)==0){ qrcode=-3;
1649
+ g_debug(fprintf(stderr,"\n# qrcode bad bit at %d %d",8,x-7);)
1650
+ }
1651
+ bits[8+(x-7-1)*x]|=2;
1652
+ if (ad1) { // mark alignment pattern
1653
+ for (i=6;i<y;i+=(i==6 || ad2==0)?ad1:ad2)
1654
+ for (j=6;j<x;j+=(j==6 || ad2==0)?ad1:ad2)
1655
+ if ((i<8 && j>6 && j<x-8)
1656
+ || (j<8 && i>6 && i<y-8)
1657
+ || (i>6 && j>6)) {
1658
+ int ti, tj;
1659
+ for (ti=-2;ti<3;ti++)
1660
+ for (tj=-2;tj<3;tj++) bits[(i+ti)*x+(j+tj)]|=2;
1661
+ }
1662
+ }
1663
+ for (i=0;i<8*8;i++) { // qr-marker pixel
1664
+ bits[ (i%8)+x*( i/8)]|=2;
1665
+ bits[x-8+(i%8)+x*( i/8)]|=2;
1666
+ bits[ (i%8)+x*(x-8+i/8)]|=2;
1667
+ }
1668
+ if (qr_version>6)
1669
+ for (i=0;i<3*6;i++) { // qr-marker pixel
1670
+ bits[x-11+(i%3)+x*( i/3)]|=2;
1671
+ bits[ (i%6)+x*(x-11+i/6)]|=2;
1672
+ }
1673
+ // ToDo: check format bits (30 for v<=6, 66 for v>6) ???
1674
+ // from right to left
1675
+ g_debug(fprintf(stderr,"\n# qrcode h-format bits 0..14: ");)
1676
+ for (i=0;i<15;i++) {
1677
+ fbits|= (bits[8*x+((i<8)?x-i-1:((i<9)?7:5+9-i))]&1)<<i;
1678
+ g_debug(fprintf(stderr,"%d",(fbits>>i)&1);) // bit0 first
1679
+ bits[8*x+((i<8)?x-i-1:((i<9)?7:5+9-i))]|=2;
1680
+ }
1681
+ // from top to bottom
1682
+ g_debug(fprintf(stderr,"\n# qrcode v-format bits 0..14: ");)
1683
+ for (i=0;i<15;i++) {
1684
+ j= (bits[8+x*((i<6)?i:((i<8)?i+1:i+x-7-8))]&1);
1685
+ if (((fbits>>i)&1)!=j) qrcode=-4;
1686
+ g_debug(fprintf(stderr,"%d",j);) // bit0 first
1687
+ bits[8+x*((i<6)?i:((i<8)?i+1:i+x-7-8))]|=2;
1688
+ }
1689
+ g_debug(if(qrcode<0)fprintf(stderr,"\n# qrcode error %d ",qrcode);)
1690
+ // err mask ecc
1691
+ fbits ^= 0x5412; // 10 101 0000010010 = 0x5412
1692
+ g_debug(fprintf(stderr,"\n# qrcode format bits 0..14: ");)
1693
+ // ToDo: check ECC
1694
+ for (i=0;i<15;i++) {
1695
+ g_debug(fprintf(stderr,"%d",(fbits>>i)&1);) // bit0 first
1696
+ }
1697
+ // errorlevel: 0..3 = 00=M(15%) 01=L(7%) 10=H(30%) 11=Q(25%) maxlost
1698
+ // 21x21 = level1 H: 9 bytes + 17 bytes RedSolomon
1699
+ // mask pattern: 0..7: invers pixel rules
1700
+ // mask needed to avoid finder and timing pattern in data
1701
+ qr_mask= 7 & (fbits>>10); // 0..7
1702
+ { // BCH_15_5 (3*5bit) Reed-Solomon-encode
1703
+ int data, wk=0;
1704
+ data= 31 & (fbits>>10);
1705
+ data <<= 5;
1706
+ for (i=0; i<5; i++) {
1707
+ wk <<= 1; data <<= 1;
1708
+ if ((wk^data) & 0x400) wk ^= 0x137;
1709
+ } data = (data & 0x7c00) | (wk & 0x3ff);
1710
+ g_debug(fprintf(stderr,"\n# qrcode ECC check: 0x%04x == 0x%04x",fbits,data);)
1711
+ // ToDo: if not equal try to encode all 5-bit-BCH-words and compute
1712
+ // number of different bits, if num_diff_bits<=3 we found it
1713
+ }
1714
+ qr_ecclevel= 1 ^ (3 & (fbits>>13));
1715
+ g_debug(fprintf(stderr,"\n# qrcode errorlevel^1 = %d (2bit)",qr_ecclevel);)
1716
+ g_debug(fprintf(stderr,"\n# qrcode mask pattern = %d (3bit)",qr_mask);)
1717
+ g_debug(fprintf(stderr,"\n# qrcode 10bit-ECC = 0x%04x",1023&(fbits>>0));)
1718
+ for (i=0;i<x*y;i++) {
1719
+ const char xx[4]=".o_@";
1720
+ g_debug(if (i%x==0) fprintf(stderr,"\n# qrcode ");)
1721
+ g_debug(fprintf(stderr,"%c",xx[bits[i]&3]);)
1722
+ }
1723
+ // ToDo: check ECC Bose-Chaudhuri-Hocquenghem(BCH)(15,5) 15bit,5data
1724
+ // G(x)=x^10+x^8+x^5+x^4+x^2+x+1 = 10100110111 = 0x0A37 ???
1725
+ // F(x)=x^14+x^11+x^10 = 10011.......... = 0x4C00 (data=10011)
1726
+ // R(x)=x^8+x^7+x^6+x = 0111000010 = 0x01C2 (ecc)
1727
+ // http://de.wikipedia.org/wiki/BCH-Code
1728
+ // http://www.swetake.com/qr/qr6_en.html
1729
+ // first 4+8..10 bit data
1730
+ // data: 1:3*[0-9]=10bit + 7bit_for_rest2*[0-9] + 3bit_for_rest1*[0..9]
1731
+ // 2:2*[0-9A-Z $%*+-./:]=11bit + 6bit_rest1 (45*char1+char2)
1732
+ // 4:8byte, 8:Kanji=13bit
1733
+ // 4bit-mode={1=numeric,2=alpha,4=byte,8=kanji}
1734
+ // 8..10bit-len: 8bit for byte+kanjy, 9bit for alpha, 10bit for numeric
1735
+ // fillbits=0, fillbytes=0xEC,0x11 (see below)
1736
+ // get data, start at x,y
1737
+ // ToDo: mark non_data_pixel using 2nd+3th bit?
1738
+ i=0; // count data bits = valid bits
1739
+ for (iy=0;iy<x;iy++)
1740
+ for (ix=0;ix<x;ix++) {
1741
+ int i2 = iy*x + ix;
1742
+ if ((bits[i2]&6)==0) // valid pixel?
1743
+ if ( (qr_mask==0 && (iy+ix)%2==0)
1744
+ || (qr_mask==1 && (iy )%2==0)
1745
+ || (qr_mask==2 && ( ix)%3==0)
1746
+ || (qr_mask==3 && (iy+ix)%3==0) // OK
1747
+ || (qr_mask==4 && (iy/2+ix/3)%2==0) // OK
1748
+ || (qr_mask==5 && (iy*ix)%2 + (iy*ix)%3 ==0) // OK
1749
+ || (qr_mask==6 && ((iy*ix)%2 + (iy*ix)%3) %2 ==0)
1750
+ || (qr_mask==7 && ((iy*ix)%3 + (iy+ix)%2) %2 ==0) ) bits[i2]^=1;
1751
+ if ((bits[i2]&6)==0) i++;
1752
+ }
1753
+ num_rawbits= i; // overwrite bad computed num_rawbits
1754
+ g_debug(fprintf(stderr,"\n# qrcode rawbits= %5d bytes= %5d", i, i/8);)
1755
+ #if 1
1756
+ g_debug(fprintf(stderr,"\n# qrcode unmasked: ");)
1757
+ for (i=0;i<x*y;i++) {
1758
+ const char xx[4]=".x _";
1759
+ g_debug(if (i%x==0) fprintf(stderr,"\n# qrcode ");)
1760
+ g_debug(fprintf(stderr,"%c",xx[bits[i]&3]);)
1761
+ }
1762
+ #endif
1763
+ // testing deinterleave 2+2 for v5 = 46 data + 88 ecc, head=12bit nchars=44
1764
+ // bit-data fitting to mod 8: no way (best fit is 4bit-shift)
1765
+ // interleave-sequence data 11 11 12 12 (!!) ecc 22 22 22 22 (??)
1766
+ // qrencode -8 -lH -v5 -oa.png '333333333D3333333333U33333333333f3333333333w'
1767
+ // # 3=0x33 D=0x44 U=0x55 f=0x66 w=0x77 as byte position marker!
1768
+ // # nbytes=2+100=5*12+3 interleave=2+2
1769
+ // testing b1+b2=3+2 data=292raw-110ecc=182 182/(3+2)=36
1770
+ // interleave sequence: 36 36 36 37 37
1771
+ // qrencode -8 -lM -v9 -oa.png '(34*3)D(34*3)4U(34*3)3f(34*3)33w(34*3)3"'
1772
+ // (34*3)=3333333333333333333333333333333333
1773
+ qrbytes=(unsigned char *)malloc(x*x/8); // enough space for data bits + ecc
1774
+ nbits=0; // num valid data bits 0..x*x-- of all data blocks
1775
+ bbits=0; // 8 bits
1776
+ int num_data_bytes, num_ecc_bytes; // data bytes include header bits
1777
+ interleave= qrConst[qr_version-1][6+2*qr_ecclevel+0] // 1-40 0123=LMQH
1778
+ + qrConst[qr_version-1][6+2*qr_ecclevel+1];
1779
+ // raw_bytes, raw_bits_mod, ecc0 .. ecc3
1780
+ num_ecc_bytes= qrConst[qr_version-1][2+qr_ecclevel];
1781
+ num_data_bytes= qrConst[qr_version-1][0]-num_ecc_bytes;
1782
+ g_debug(fprintf(stderr,"\n# qrcode v%d numbytes= %4d == %4d = %4d data + %4d ecc",
1783
+ qr_version, num_rawbits/8, num_data_bytes+num_ecc_bytes,
1784
+ num_data_bytes, num_ecc_bytes);)
1785
+ g_debug(fprintf(stderr,"\n# qrcode v%d interleave= %d = %d + %d\n# ",
1786
+ qr_version,interleave,qrConst[qr_version-1][6+2*qr_ecclevel+0],
1787
+ qrConst[qr_version-1][6+2*qr_ecclevel+1]);)
1788
+ j=-1; // -x means upwards, +x means downwards
1789
+ iy=ix=x-1; // start pixel
1790
+ if (qrbytes)
1791
+ while (ix>=0 && iy>=0) { // de-interleave bytes
1792
+ int i2 = iy*x+ix, idx; // help pixel index, old+new byte index
1793
+ int b1, b2;
1794
+ b1 = qrConst[qr_version-1][6+2*qr_ecclevel+0];
1795
+ b2 = qrConst[qr_version-1][6+2*qr_ecclevel+1];
1796
+ if ((bits[i2]&6)==0) { // valid pixel?
1797
+ // g_debug(fprintf(stderr,"\n %2d %2d %2d %d",i2%x,i2/x,j,bits[i2]);)
1798
+ g_debug(fprintf(stderr,"%d",bits[i2]);)
1799
+ bbits = (bbits << 1) | (bits[i2]&1); // byte
1800
+ nbits++; // all valid data bits
1801
+ // store all bits in 8bit words
1802
+ // no warranty that this impirical code works
1803
+ // ToDo: replace by better readable code, or create
1804
+ // better 2D-coding standart replacing QR-Code
1805
+ if ((nbits&7)==0) {
1806
+ if (nbits/8-1 < num_data_bytes) {
1807
+ idx= (nbits/8-1)/interleave
1808
+ +((nbits/8-1)%interleave)*(num_data_bytes/interleave);
1809
+ if (idx >= b1*(num_data_bytes/interleave)) // interleaveblock
1810
+ idx= (nbits/8-1-b1)/interleave
1811
+ +((nbits/8-1-b1)%interleave)*(num_data_bytes/interleave+1)
1812
+ + b1*(num_data_bytes/interleave);
1813
+ if (nbits/8-1 >= num_data_bytes-b2)
1814
+ idx= (nbits/8-1)/interleave
1815
+ +((nbits/8-1)%interleave)*(num_data_bytes/interleave+1)
1816
+ + b1*(num_data_bytes/interleave);
1817
+ }
1818
+ else { // ToDo: ecc de-interleave is not proved
1819
+ idx= (nbits/8-num_data_bytes-1)/interleave
1820
+ +((nbits/8-num_data_bytes-1)%interleave)*(num_ecc_bytes/interleave)
1821
+ +num_data_bytes;
1822
+ if ((nbits/8-1)/interleave >= num_rawbits/8-b2) // interleaveblock
1823
+ idx+= num_rawbits/8-b2 + ((nbits/8-1)%interleave);
1824
+ }
1825
+ qrbytes[idx]= bbits;
1826
+ g_debug(fprintf(stderr," %3d %02x ",idx,bbits);)
1827
+ g_debug(if (nbits/8==num_data_bytes) fprintf(stderr,"\n# end_data\n#");)
1828
+ g_debug(fprintf(stderr,(((nbits/8)%interleave==0)?"\n# ":" "));)
1829
+ if (nbits/8==num_data_bytes - b2)
1830
+ for (i=0;i<b1;i++) {
1831
+ g_debug(fprintf(stderr,"%17s"," ");)
1832
+ }
1833
+ bbits=0;
1834
+ } // used for head+data+ECC
1835
+ } // valid bit
1836
+ // (x,maxy) x=max,..,20,18,16,14,12,10,8,(skip6)5,3,1
1837
+ // next step (up, down or 2 left)
1838
+ // g_debug(fprintf(stderr,"\n# qr1 xy= %3d %3d %+2d ", ix, iy, j);)
1839
+ if (ix%2==((ix<6)?1:0) || ix==6) ix--; // go left
1840
+ else if (iy+j>=0 && iy+j<x) { iy+=j; ix++; } // go right up/down
1841
+ else { ix--; j*=-1; } // go 2*left + change direction
1842
+ // g_debug(fprintf(stderr,"\n# qr2 xy= %3d %3d %+2d ", ix, iy, j);)
1843
+ } // i=max(x*x-x-1)..0
1844
+ // RS-check/decoding
1845
+ // needed to define addition and multiplication and finaly a^i
1846
+ // now wen need the RS generator polynom g(x) depending from size
1847
+ // ToDo: ECC check and correction, test=tmp10/qrcode_21c4m4e2.png
1848
+ // qrencode 3.1.1 Kentaro Fukuchi 2010 0123=LMQH
1849
+ // -l H -v 10 -o a.png '000000000000000000000000000'
1850
+ // v1 H m1=17= 3*5+2= 57bit 57..59 bit+18 raw= 9+17ecc
1851
+ // Q raw=13+13ecc
1852
+ // L m1=41=3*13+2=137bit 137..139 bit+18 raw=19 +7ecc
1853
+ // v2 H m1=34=3*11+1=114bit
1854
+ // L m1=77=3*25+2=257bit
1855
+ // v3 e2=Q m1= raw=34+36ecc=70(ok)rest7
1856
+ int b1, b2;
1857
+ int dl=0, el=0, i_ecc=num_data_bytes, i_data=0; // data and ecc length
1858
+ unsigned char qr_ecc[256]; // buffer for generated ecc data
1859
+ b1 = qrConst[qr_version-1][6+2*qr_ecclevel+0];
1860
+ b2 = qrConst[qr_version-1][6+2*qr_ecclevel+1];
1861
+ // for b1 and b2 we have different datasize ???
1862
+ for (i=0; i<b1+b2; i++) { // (interleaved) block nr.
1863
+ if (i==0 || i==b1) {
1864
+ dl = num_data_bytes/(b1+b2); // divided in blocks to reduce RS size
1865
+ if (i==b1) dl++;
1866
+ el = num_ecc_bytes/(b1+b2);
1867
+ init_rs(8,0x11D,0,1,el,255-dl-el);
1868
+ }
1869
+ // gfpoly = 0x11D is the primitive polynom for QR-Code
1870
+ // max. data+ecc=255
1871
+ encode_rs_char(&rs, qrbytes + i_data, qr_ecc);
1872
+ g_debug(for(j=0;j<el;j++)fprintf(stderr," %02x ",qr_ecc[j]);fprintf(stderr,"\n# ");)
1873
+ g_debug(for(j=0;j<el;j++)fprintf(stderr," %02x ",qrbytes[i_ecc+j]);fprintf(stderr,"\n# ");)
1874
+ for (j=0;j<el;j++) if (qr_ecc[j]!=qrbytes[i_ecc+j])
1875
+ {qrcode=-3;g_debug(fprintf(stderr," ECC-Error ");)break;}
1876
+ i_data += dl;
1877
+ i_ecc += el;
1878
+ }
1879
+
1880
+ // get 1..2 bits from bits[i] and bits[i-1]
1881
+ // 1st bit + 2nd bit stored in i2, i2-1
1882
+ if (qr_version<=40) head_bits=head_bits40;
1883
+ if (qr_version<=26) head_bits=head_bits26;
1884
+ if (qr_version<= 9) head_bits=head_bits09;
1885
+ block_nbits=0; // num valid data bits per block
1886
+ nwbits=0; // num bits per local word 0..14
1887
+ nchars=0; // num chars (nwords*cpw+rest) expected
1888
+ dchars=0; // num chars decoded
1889
+ wbits=0; // data bits of local word
1890
+ int next_wbits=1023; // bits of the next dataword
1891
+ unsigned char *ptext=NULL; // pointer to char tuple of next word
1892
+ // get bits and words from deinterleaved byte stream
1893
+ g_debug(fprintf(stderr,"\n# qrcode bytes: %02x %02x %02x ...\n# qr new_block ",
1894
+ 255&(int)qrbytes[0], 255&(int)qrbytes[1], 255&(int)qrbytes[2]);)
1895
+ // read all blocks
1896
+ // qrencode -l H -v 5 -o a.png '0123456789abcdefghijklmnopqrstuvwxyz'
1897
+ // # 10c1=0123456789=34bit + 26c4=abcdefghijklmnopqrstuvwxyz=26byte
1898
+ if (!qrtext) qrtext= (unsigned char *)malloc(3*num_rawbits/10+1); // 70%
1899
+ if (qrtext)
1900
+ // for (nbits=0; nbits<num_rawbits; nbits++)
1901
+ for (nbits=0; nbits<num_data_bytes*8; nbits++)
1902
+ {
1903
+ // g_debug(fprintf(stderr,"\n %2d %2d %2d %d",i2%x,i2/x,j,bits[i2]);)
1904
+ g_debug(fprintf(stderr,"%d",1&(qrbytes[nbits/8]>>(7-nbits%8)));)
1905
+ wbits = (wbits << 1) | (1&(qrbytes[nbits/8]>>(7-nbits%8))); // word
1906
+ block_nbits++;
1907
+ nwbits++; // local word
1908
+
1909
+ if (qr_mode==0 && block_nbits==4) {
1910
+ qr_mode= wbits & 15;
1911
+ wbits=0; nwbits=0; // word bits and valid number of bits
1912
+ // if (qr_mode==3) qr_mode=1; // auto correction ???
1913
+ g_debug(fprintf(stderr," mode=%d numbits=%d wordbits=%d wchr=%d\n"
1914
+ "# qr data ", qr_mode, head_bits[qr_mode]-4,
1915
+ word_bits[qr_mode],
1916
+ word_nchr[qr_mode]);)
1917
+ nchars=0; // flag new block
1918
+ }
1919
+ // set extra nchars flag!?
1920
+ // ToDo: what about bad qr_mode? (not 1,2,4,8)
1921
+ if (nchars==0 && head_bits[qr_mode]!=0
1922
+ && head_bits[qr_mode]==block_nbits) {
1923
+ nchars= wbits; // 8..14 bits
1924
+ wbits=0; nwbits= 0; // sync to data words
1925
+ next_wbits= word_bits[qr_mode];
1926
+ if (nchars==0) { qr_mode=0; block_nbits=0; } // reset, new block?
1927
+ g_debug(fprintf(stderr," nchars=%d\n# qr data ", nchars);)
1928
+ }
1929
+ if (dchars==0) qrtext[0]=0;
1930
+ if (qr_mode==0 || !nchars) continue; // we dont have chars to read
1931
+ if (block_dchars>=nchars) continue; // all block chars read
1932
+ if (nwbits < next_wbits) continue; // not enough bits read
1933
+ ptext = &(qrtext[dchars]); // for debugging word
1934
+ // reading chars
1935
+ if (dchars + word_nchr[qr_mode] >= 3*num_rawbits/10) // safety
1936
+ { fprintf(stderr,"qrcode.unexpected_overflow\n");break; }
1937
+ // decode
1938
+ if (qr_mode==8) { // 13bit??? UTF ??? JIS ?
1939
+ int c1 = (wbits/192) + wbits % 192;
1940
+ if (c1+0x8140 <= 0x9FFC) c1+=0x8140;
1941
+ else c1+=0xC140;
1942
+ qrtext[dchars ]= c1>>8; // ToDo ??
1943
+ qrtext[dchars+1]= c1&255; // ToDo
1944
+ dchars += 2;
1945
+ block_dchars += 2;
1946
+ if (nchars-block_dchars==1) next_wbits=8;
1947
+ }
1948
+ if (qr_mode==4){ // 8bit
1949
+ qrtext[dchars]= wbits; // ToDo: what about ""<>&?
1950
+ dchars += 1;
1951
+ block_dchars += 1;
1952
+ }
1953
+ if (qr_mode==2) { // 45*45=2025=11bit ToDo: error if 2025++
1954
+ int c1 = (wbits/45)%45, c2 = wbits%45;
1955
+ char crest[9+1]=" $%*+-./:";
1956
+ if (next_wbits==11) {
1957
+ qrtext[dchars ]= c1+'0';
1958
+ qrtext[dchars+1]= c2+'0';
1959
+ if (c1> 9) qrtext[dchars ]= c1-10+'A';
1960
+ if (c2> 9) qrtext[dchars+1]= c2-10+'A';
1961
+ if (c1>35) qrtext[dchars ]= crest[c1-36];
1962
+ if (c2>35) qrtext[dchars+1]= crest[c2-36];
1963
+ dchars += 2;
1964
+ block_dchars += 2;
1965
+ if (nchars-block_dchars==1) next_wbits=6;
1966
+ } else if (next_wbits==6) {
1967
+ qrtext[dchars ]= c2+'0';
1968
+ if (c2> 9) qrtext[dchars ]= c2-10+'A';
1969
+ if (c2>35) qrtext[dchars ]= crest[c2-36];
1970
+ dchars += 1;
1971
+ block_dchars += 1;
1972
+ next_wbits=0;
1973
+ }
1974
+ // ToDo: odd numchars?
1975
+ }
1976
+ if (qr_mode==1) { // 10*10*10=1000=10bit ToDo: error 1001++
1977
+ if (next_wbits==10) {
1978
+ qrtext[dchars ]= '0'+ (wbits)/100;
1979
+ qrtext[dchars+1]= '0'+((wbits)/10)%10;
1980
+ qrtext[dchars+2]= '0'+ (wbits)%10;
1981
+ dchars += 3;
1982
+ block_dchars += 3;
1983
+ }
1984
+ if (next_wbits==7) {
1985
+ qrtext[dchars ]= '0'+ (wbits)/10;
1986
+ qrtext[dchars+1]= '0'+ (wbits)%10;
1987
+ dchars += 2;
1988
+ block_dchars += 2;
1989
+ next_wbits=0;
1990
+ }
1991
+ if (next_wbits==4) {
1992
+ qrtext[dchars ]= '0'+ (wbits)%10;
1993
+ dchars += 1;
1994
+ block_dchars += 1;
1995
+ next_wbits=0;
1996
+ }
1997
+ if (nchars-block_dchars==1) next_wbits=4;
1998
+ if (nchars-block_dchars==2) next_wbits=7;
1999
+ // ToDo: %3!=0 rest nchars?
2000
+ }
2001
+ if (dchars<=3*num_rawbits/10) qrtext[dchars]=0; // end of string
2002
+ #if DO_DEBUG
2003
+ if ((job->cfg.verbose&1) && block_dchars < nchars+word_nchr[qr_mode])
2004
+ fprintf(stderr," %4s next_wbits= %2d byte= %3d", ptext, next_wbits, nbits/8);
2005
+ if ((job->cfg.verbose&1) && block_dchars < nchars)
2006
+ fprintf(stderr,"\n# qr data ");
2007
+ #endif
2008
+ wbits=0; nwbits=0;
2009
+ if (block_dchars >= nchars) { // reset block
2010
+ block_dchars=0; nchars=0; qr_mode=0; block_nbits=0;
2011
+ g_debug(fprintf(stderr,"\n# qr new_block ");)
2012
+ }
2013
+ // end reading data word = char tuple
2014
+ } // i=0..num_rawbits
2015
+ } else fprintf(stderr,"qrcode.malloc failed\n");
2016
+ } // if square and v=1..40
2017
+
2018
+ g_debug(fprintf(stderr,"\n# qr dchars=%d nbits=%d ", dchars, nbits);)
2019
+ // Reed-Solomon
2020
+ // size+errlevel = headbits+databits+fillbits + ecbits + ?
2021
+ // 21H 9*8 17*8 215 RS: 1block (26,9,8) = (allbytes,databytes,errbytes)
2022
+ // sample 21H 9data+17ecc=26byte+
2023
+ // f(x)=byte0*x^25+byte1*x^24+...+byte8*x^17 (9byte data)
2024
+ // byte0=32=a^5 byte1=7=a^198 ... (table4)
2025
+ // n=17 g(x)=sum(i=0..n)a^ai*x^i where a^255=1
2026
+ // ai=136,163,243,39,150,99,24,147,214,206,123,239,43,78,206,139,43,17,0
2027
+ // a^ai=79,99,125,53,85,134,143,41,249,83,197,22,119,120,83,66,119,152,1
2028
+ // rest of g(x)/f(x) is r(x)=byte16*x^16+byte15*x^15+...bye1*x+byte0
2029
+ // 21L 19*8 7*8 ... RS: 1block (26,19,2)
2030
+ // n=7 g(x)=sum(i=0..n)a^ai*x^i
2031
+ // ai=21,102,238,149,146,229,87,0
2032
+ // check? f/g=x+R?
2033
+ // gpg --export -a 0x26D124F8 | qrencode -oa.png # v31 nc=1723
2034
+ // gpg --export -a --export-options export-minimal 0x26D124F8
2035
+ // | qrencode -8 -oa.png # v30 137*137 nc=1723
2036
+ // 300dpi(12dot/mm) 3dot=0.25mm 4dot=0.33mm 5dot=0.42mm 6dot=0.5mm
2037
+ // 177x177 = 45x45mm^2
2038
+ if (qrcode>0) {
2039
+ code= (char *)malloc(4000);
2040
+ if (code && qrtext) {
2041
+ code[0]='_'; code[1]=0;
2042
+ // if (dchars<512) // ToDo: limited output buffer? or stdout?
2043
+ sprintf(code,"<barcode type=\"qrcode%d\" chars=\"%d\""
2044
+ " ecclevel=\"%d\" >\n%s\n</barcode>",
2045
+ qr_version, dchars, qr_ecclevel, qrtext);
2046
+ // else printf("<barcode type=\"qrcode%d\" chars=\"%d\""
2047
+ // " ecclevel=\"%d\" >\n%s\n</barcode>",
2048
+ // qr_version, dchars, qr_ecclevel, qrtext);
2049
+ // ToDo: error=...
2050
+ }
2051
+ }
2052
+ if (qrcode<0) {
2053
+ code= (char *)malloc(128);
2054
+ if (code) {
2055
+ strncpy(code,"<barcode type=\"unknown qrcode\" />",128);
2056
+ }
2057
+ }
2058
+ if (qrtext) free(qrtext);
2059
+ if (qrbytes) free(qrbytes);
2060
+ box3=NULL;
2061
+ for_each_data(&(job->res.boxlist)) {
2062
+ box2 = (struct box *)list_get_current(&(job->res.boxlist));
2063
+ x02=box2->x0; dx2=box2->x1-x02+1; /* ToDo: correction for skewed matrix */
2064
+ y02=box2->y0; dy2=box2->y1-y02+1;
2065
+ if (x02>=x03-qr_marker[0][2]/14
2066
+ && y02>=y03-qr_marker[0][3]/14
2067
+ && x02+dx2<=x03+dx3+qr_marker[0][2]/14
2068
+ && y02+dy2<=y03+dy3+qr_marker[0][3]/14 ) { // object inside QR area
2069
+ box2->c=PICTURE; /* BARCODE */
2070
+ box2->x0=x03;
2071
+ box2->y0=y03;
2072
+ box2->x1=x03+dx3-1;
2073
+ box2->y1=y03+dy3-1;
2074
+ if (!box3) {
2075
+ box3=box2;
2076
+ if (code) setas(box3,code,99); /* ToDo: set a better weight */
2077
+ } else {
2078
+ // ToDo: list_del except one
2079
+ rm++; /* count removed boxes */
2080
+ list_del(&(job->res.boxlist),box2);
2081
+ free_box(box2);
2082
+ }
2083
+ }
2084
+ } end_for_each(&(job->res.boxlist));
2085
+ if (code) free(code);
2086
+ if (job->cfg.verbose)
2087
+ fprintf(stderr,"\n# ... removed boxes: %d", rm);
2088
+ rm=0;
2089
+ } // qrcode detected
2090
+ } // qrcode
2091
+
2092
+ /* recalculate averages without bars */
2093
+ job->res.numC=job->res.sumX=job->res.sumY=j2=0;
2094
+ for_each_data(&(job->res.boxlist)) {
2095
+ j2++;
2096
+ box3 = (struct box *)list_get_current(&(job->res.boxlist));
2097
+ if (box3->c==PICTURE) continue;
2098
+ job->res.numC++; /* count remaining boxes */
2099
+ job->res.sumX+=box3->x1-box3->x0+1;
2100
+ job->res.sumY+=box3->y1-box3->y0+1;
2101
+ } end_for_each(&(job->res.boxlist));
2102
+ if(job->cfg.verbose)
2103
+ fprintf(stderr,"\n# ... boxes %d nC %d\n",
2104
+ j2, job->res.numC);
2105
+
2106
+ return 0;
2107
+ }
2108
+