entangledstate-isbn 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (290) hide show
  1. data/README +1 -1
  2. data/Rakefile +0 -18
  3. data/VERSION +1 -0
  4. data/isbn.gemspec +290 -7
  5. data/lib/isbn.rb +6 -6
  6. data/src/gocr-0.48/.cvsignore +6 -0
  7. data/src/gocr-0.48/AUTHORS +7 -0
  8. data/src/gocr-0.48/BUGS +55 -0
  9. data/src/gocr-0.48/CREDITS +17 -0
  10. data/src/gocr-0.48/HISTORY +243 -0
  11. data/src/gocr-0.48/INSTALL +83 -0
  12. data/src/gocr-0.48/Makefile +193 -0
  13. data/src/gocr-0.48/Makefile.in +193 -0
  14. data/src/gocr-0.48/README +165 -0
  15. data/src/gocr-0.48/READMEde.txt +80 -0
  16. data/src/gocr-0.48/REMARK.txt +18 -0
  17. data/src/gocr-0.48/REVIEW +538 -0
  18. data/src/gocr-0.48/TODO +65 -0
  19. data/src/gocr-0.48/bin/.cvsignore +2 -0
  20. data/src/gocr-0.48/bin/create_db +38 -0
  21. data/src/gocr-0.48/bin/gocr.tcl +527 -0
  22. data/src/gocr-0.48/bin/gocr_chk.sh +44 -0
  23. data/src/gocr-0.48/configure +4689 -0
  24. data/src/gocr-0.48/configure.in +71 -0
  25. data/src/gocr-0.48/doc/.#Makefile.1.6 +39 -0
  26. data/src/gocr-0.48/doc/.cvsignore +2 -0
  27. data/src/gocr-0.48/doc/Makefile +39 -0
  28. data/src/gocr-0.48/doc/Makefile.in +39 -0
  29. data/src/gocr-0.48/doc/example.dtd +53 -0
  30. data/src/gocr-0.48/doc/example.xml +21 -0
  31. data/src/gocr-0.48/doc/examples.txt +67 -0
  32. data/src/gocr-0.48/doc/gocr.html +578 -0
  33. data/src/gocr-0.48/doc/unicode.txt +57 -0
  34. data/src/gocr-0.48/examples/.#Makefile.1.22 +166 -0
  35. data/src/gocr-0.48/examples/4x6.png +0 -0
  36. data/src/gocr-0.48/examples/4x6.txt +2 -0
  37. data/src/gocr-0.48/examples/5x7.png +0 -0
  38. data/src/gocr-0.48/examples/5x7.png.txt +2 -0
  39. data/src/gocr-0.48/examples/5x8.png +0 -0
  40. data/src/gocr-0.48/examples/5x8.png.txt +2 -0
  41. data/src/gocr-0.48/examples/Makefile +166 -0
  42. data/src/gocr-0.48/examples/color.fig +20 -0
  43. data/src/gocr-0.48/examples/ex.fig +16 -0
  44. data/src/gocr-0.48/examples/font.tex +22 -0
  45. data/src/gocr-0.48/examples/font1.tex +46 -0
  46. data/src/gocr-0.48/examples/font2.fig +27 -0
  47. data/src/gocr-0.48/examples/font_nw.tex +24 -0
  48. data/src/gocr-0.48/examples/handwrt1.jpg +0 -0
  49. data/src/gocr-0.48/examples/handwrt1.txt +10 -0
  50. data/src/gocr-0.48/examples/inverse.fig +20 -0
  51. data/src/gocr-0.48/examples/matrix.jpg +0 -0
  52. data/src/gocr-0.48/examples/ocr-a-subset.png +0 -0
  53. data/src/gocr-0.48/examples/ocr-a-subset.png.txt +4 -0
  54. data/src/gocr-0.48/examples/ocr-a.png +0 -0
  55. data/src/gocr-0.48/examples/ocr-a.txt +6 -0
  56. data/src/gocr-0.48/examples/ocr-b.png +0 -0
  57. data/src/gocr-0.48/examples/ocr-b.png.txt +4 -0
  58. data/src/gocr-0.48/examples/polish.tex +28 -0
  59. data/src/gocr-0.48/examples/rotate45.fig +14 -0
  60. data/src/gocr-0.48/examples/score +36 -0
  61. data/src/gocr-0.48/examples/text.tex +28 -0
  62. data/src/gocr-0.48/gocr.spec +143 -0
  63. data/src/gocr-0.48/gpl.html +537 -0
  64. data/src/gocr-0.48/include/.cvsignore +2 -0
  65. data/src/gocr-0.48/include/config.h +36 -0
  66. data/src/gocr-0.48/include/config.h.in +36 -0
  67. data/src/gocr-0.48/include/version.h +2 -0
  68. data/src/gocr-0.48/install-sh +3 -0
  69. data/src/gocr-0.48/make.bat +57 -0
  70. data/src/gocr-0.48/man/.cvsignore +2 -0
  71. data/src/gocr-0.48/man/Makefile +29 -0
  72. data/src/gocr-0.48/man/Makefile.in +29 -0
  73. data/src/gocr-0.48/man/man1/gocr.1 +166 -0
  74. data/src/gocr-0.48/src/.cvsignore +4 -0
  75. data/src/gocr-0.48/src/Makefile +132 -0
  76. data/src/gocr-0.48/src/Makefile.in +132 -0
  77. data/src/gocr-0.48/src/amiga.h +31 -0
  78. data/src/gocr-0.48/src/barcode.c +846 -0
  79. data/src/gocr-0.48/src/barcode.c.orig +593 -0
  80. data/src/gocr-0.48/src/barcode.h +11 -0
  81. data/src/gocr-0.48/src/box.c +372 -0
  82. data/src/gocr-0.48/src/database.c +462 -0
  83. data/src/gocr-0.48/src/detect.c +943 -0
  84. data/src/gocr-0.48/src/gocr.c +373 -0
  85. data/src/gocr-0.48/src/gocr.h +288 -0
  86. data/src/gocr-0.48/src/jconv.c +168 -0
  87. data/src/gocr-0.48/src/job.c +84 -0
  88. data/src/gocr-0.48/src/lines.c +350 -0
  89. data/src/gocr-0.48/src/list.c +334 -0
  90. data/src/gocr-0.48/src/list.h +90 -0
  91. data/src/gocr-0.48/src/ocr0.c +6756 -0
  92. data/src/gocr-0.48/src/ocr0.h +63 -0
  93. data/src/gocr-0.48/src/ocr0n.c +1475 -0
  94. data/src/gocr-0.48/src/ocr1.c +85 -0
  95. data/src/gocr-0.48/src/ocr1.h +3 -0
  96. data/src/gocr-0.48/src/otsu.c +289 -0
  97. data/src/gocr-0.48/src/otsu.h +23 -0
  98. data/src/gocr-0.48/src/output.c +289 -0
  99. data/src/gocr-0.48/src/output.h +37 -0
  100. data/src/gocr-0.48/src/pcx.c +153 -0
  101. data/src/gocr-0.48/src/pcx.h +9 -0
  102. data/src/gocr-0.48/src/pgm2asc.c +2893 -0
  103. data/src/gocr-0.48/src/pgm2asc.h +105 -0
  104. data/src/gocr-0.48/src/pixel.c +537 -0
  105. data/src/gocr-0.48/src/pnm.c +533 -0
  106. data/src/gocr-0.48/src/pnm.h +35 -0
  107. data/src/gocr-0.48/src/progress.c +87 -0
  108. data/src/gocr-0.48/src/progress.h +42 -0
  109. data/src/gocr-0.48/src/remove.c +703 -0
  110. data/src/gocr-0.48/src/tga.c +87 -0
  111. data/src/gocr-0.48/src/tga.h +6 -0
  112. data/src/gocr-0.48/src/unicode.c +1314 -0
  113. data/src/gocr-0.48/src/unicode.h +1257 -0
  114. data/src/jpeg-7/Makefile.am +133 -0
  115. data/src/jpeg-7/Makefile.in +1089 -0
  116. data/src/jpeg-7/README +322 -0
  117. data/src/jpeg-7/aclocal.m4 +8990 -0
  118. data/src/jpeg-7/ansi2knr.1 +36 -0
  119. data/src/jpeg-7/ansi2knr.c +739 -0
  120. data/src/jpeg-7/cderror.h +132 -0
  121. data/src/jpeg-7/cdjpeg.c +181 -0
  122. data/src/jpeg-7/cdjpeg.h +187 -0
  123. data/src/jpeg-7/change.log +270 -0
  124. data/src/jpeg-7/cjpeg.1 +325 -0
  125. data/src/jpeg-7/cjpeg.c +616 -0
  126. data/src/jpeg-7/ckconfig.c +402 -0
  127. data/src/jpeg-7/coderules.txt +118 -0
  128. data/src/jpeg-7/config.guess +1561 -0
  129. data/src/jpeg-7/config.sub +1686 -0
  130. data/src/jpeg-7/configure +17139 -0
  131. data/src/jpeg-7/configure.ac +317 -0
  132. data/src/jpeg-7/depcomp +630 -0
  133. data/src/jpeg-7/djpeg.1 +251 -0
  134. data/src/jpeg-7/djpeg.c +617 -0
  135. data/src/jpeg-7/example.c +433 -0
  136. data/src/jpeg-7/filelist.txt +215 -0
  137. data/src/jpeg-7/install-sh +520 -0
  138. data/src/jpeg-7/install.txt +1097 -0
  139. data/src/jpeg-7/jaricom.c +148 -0
  140. data/src/jpeg-7/jcapimin.c +282 -0
  141. data/src/jpeg-7/jcapistd.c +161 -0
  142. data/src/jpeg-7/jcarith.c +921 -0
  143. data/src/jpeg-7/jccoefct.c +453 -0
  144. data/src/jpeg-7/jccolor.c +459 -0
  145. data/src/jpeg-7/jcdctmgr.c +482 -0
  146. data/src/jpeg-7/jchuff.c +1612 -0
  147. data/src/jpeg-7/jcinit.c +65 -0
  148. data/src/jpeg-7/jcmainct.c +293 -0
  149. data/src/jpeg-7/jcmarker.c +667 -0
  150. data/src/jpeg-7/jcmaster.c +770 -0
  151. data/src/jpeg-7/jcomapi.c +106 -0
  152. data/src/jpeg-7/jconfig.bcc +48 -0
  153. data/src/jpeg-7/jconfig.cfg +45 -0
  154. data/src/jpeg-7/jconfig.dj +38 -0
  155. data/src/jpeg-7/jconfig.mac +43 -0
  156. data/src/jpeg-7/jconfig.manx +43 -0
  157. data/src/jpeg-7/jconfig.mc6 +52 -0
  158. data/src/jpeg-7/jconfig.sas +43 -0
  159. data/src/jpeg-7/jconfig.st +42 -0
  160. data/src/jpeg-7/jconfig.txt +155 -0
  161. data/src/jpeg-7/jconfig.vc +45 -0
  162. data/src/jpeg-7/jconfig.vms +37 -0
  163. data/src/jpeg-7/jconfig.wat +38 -0
  164. data/src/jpeg-7/jcparam.c +632 -0
  165. data/src/jpeg-7/jcprepct.c +358 -0
  166. data/src/jpeg-7/jcsample.c +545 -0
  167. data/src/jpeg-7/jctrans.c +381 -0
  168. data/src/jpeg-7/jdapimin.c +396 -0
  169. data/src/jpeg-7/jdapistd.c +275 -0
  170. data/src/jpeg-7/jdarith.c +762 -0
  171. data/src/jpeg-7/jdatadst.c +151 -0
  172. data/src/jpeg-7/jdatasrc.c +212 -0
  173. data/src/jpeg-7/jdcoefct.c +736 -0
  174. data/src/jpeg-7/jdcolor.c +396 -0
  175. data/src/jpeg-7/jdct.h +393 -0
  176. data/src/jpeg-7/jddctmgr.c +382 -0
  177. data/src/jpeg-7/jdhuff.c +1309 -0
  178. data/src/jpeg-7/jdinput.c +384 -0
  179. data/src/jpeg-7/jdmainct.c +512 -0
  180. data/src/jpeg-7/jdmarker.c +1360 -0
  181. data/src/jpeg-7/jdmaster.c +663 -0
  182. data/src/jpeg-7/jdmerge.c +400 -0
  183. data/src/jpeg-7/jdpostct.c +290 -0
  184. data/src/jpeg-7/jdsample.c +361 -0
  185. data/src/jpeg-7/jdtrans.c +136 -0
  186. data/src/jpeg-7/jerror.c +252 -0
  187. data/src/jpeg-7/jerror.h +304 -0
  188. data/src/jpeg-7/jfdctflt.c +174 -0
  189. data/src/jpeg-7/jfdctfst.c +230 -0
  190. data/src/jpeg-7/jfdctint.c +4348 -0
  191. data/src/jpeg-7/jidctflt.c +242 -0
  192. data/src/jpeg-7/jidctfst.c +368 -0
  193. data/src/jpeg-7/jidctint.c +5137 -0
  194. data/src/jpeg-7/jinclude.h +91 -0
  195. data/src/jpeg-7/jmemansi.c +167 -0
  196. data/src/jpeg-7/jmemdos.c +638 -0
  197. data/src/jpeg-7/jmemdosa.asm +379 -0
  198. data/src/jpeg-7/jmemmac.c +289 -0
  199. data/src/jpeg-7/jmemmgr.c +1118 -0
  200. data/src/jpeg-7/jmemname.c +276 -0
  201. data/src/jpeg-7/jmemnobs.c +109 -0
  202. data/src/jpeg-7/jmemsys.h +198 -0
  203. data/src/jpeg-7/jmorecfg.h +369 -0
  204. data/src/jpeg-7/jpegint.h +395 -0
  205. data/src/jpeg-7/jpeglib.h +1135 -0
  206. data/src/jpeg-7/jpegtran.1 +272 -0
  207. data/src/jpeg-7/jpegtran.c +546 -0
  208. data/src/jpeg-7/jquant1.c +856 -0
  209. data/src/jpeg-7/jquant2.c +1310 -0
  210. data/src/jpeg-7/jutils.c +179 -0
  211. data/src/jpeg-7/jversion.h +14 -0
  212. data/src/jpeg-7/libjpeg.map +4 -0
  213. data/src/jpeg-7/libjpeg.txt +3067 -0
  214. data/src/jpeg-7/ltmain.sh +8406 -0
  215. data/src/jpeg-7/makcjpeg.st +36 -0
  216. data/src/jpeg-7/makdjpeg.st +36 -0
  217. data/src/jpeg-7/makeadsw.vc6 +77 -0
  218. data/src/jpeg-7/makeasln.vc9 +33 -0
  219. data/src/jpeg-7/makecdep.vc6 +82 -0
  220. data/src/jpeg-7/makecdsp.vc6 +130 -0
  221. data/src/jpeg-7/makecmak.vc6 +159 -0
  222. data/src/jpeg-7/makecvcp.vc9 +186 -0
  223. data/src/jpeg-7/makeddep.vc6 +82 -0
  224. data/src/jpeg-7/makeddsp.vc6 +130 -0
  225. data/src/jpeg-7/makedmak.vc6 +159 -0
  226. data/src/jpeg-7/makedvcp.vc9 +186 -0
  227. data/src/jpeg-7/makefile.ansi +220 -0
  228. data/src/jpeg-7/makefile.bcc +291 -0
  229. data/src/jpeg-7/makefile.dj +226 -0
  230. data/src/jpeg-7/makefile.manx +220 -0
  231. data/src/jpeg-7/makefile.mc6 +255 -0
  232. data/src/jpeg-7/makefile.mms +224 -0
  233. data/src/jpeg-7/makefile.sas +258 -0
  234. data/src/jpeg-7/makefile.unix +234 -0
  235. data/src/jpeg-7/makefile.vc +217 -0
  236. data/src/jpeg-7/makefile.vms +142 -0
  237. data/src/jpeg-7/makefile.wat +239 -0
  238. data/src/jpeg-7/makejdep.vc6 +423 -0
  239. data/src/jpeg-7/makejdsp.vc6 +285 -0
  240. data/src/jpeg-7/makejdsw.vc6 +29 -0
  241. data/src/jpeg-7/makejmak.vc6 +425 -0
  242. data/src/jpeg-7/makejsln.vc9 +17 -0
  243. data/src/jpeg-7/makejvcp.vc9 +328 -0
  244. data/src/jpeg-7/makeproj.mac +213 -0
  245. data/src/jpeg-7/makerdep.vc6 +6 -0
  246. data/src/jpeg-7/makerdsp.vc6 +78 -0
  247. data/src/jpeg-7/makermak.vc6 +110 -0
  248. data/src/jpeg-7/makervcp.vc9 +133 -0
  249. data/src/jpeg-7/maketdep.vc6 +43 -0
  250. data/src/jpeg-7/maketdsp.vc6 +122 -0
  251. data/src/jpeg-7/maketmak.vc6 +131 -0
  252. data/src/jpeg-7/maketvcp.vc9 +178 -0
  253. data/src/jpeg-7/makewdep.vc6 +6 -0
  254. data/src/jpeg-7/makewdsp.vc6 +78 -0
  255. data/src/jpeg-7/makewmak.vc6 +110 -0
  256. data/src/jpeg-7/makewvcp.vc9 +133 -0
  257. data/src/jpeg-7/makljpeg.st +68 -0
  258. data/src/jpeg-7/maktjpeg.st +30 -0
  259. data/src/jpeg-7/makvms.opt +4 -0
  260. data/src/jpeg-7/missing +376 -0
  261. data/src/jpeg-7/rdbmp.c +439 -0
  262. data/src/jpeg-7/rdcolmap.c +253 -0
  263. data/src/jpeg-7/rdgif.c +38 -0
  264. data/src/jpeg-7/rdjpgcom.1 +63 -0
  265. data/src/jpeg-7/rdjpgcom.c +515 -0
  266. data/src/jpeg-7/rdppm.c +459 -0
  267. data/src/jpeg-7/rdrle.c +387 -0
  268. data/src/jpeg-7/rdswitch.c +365 -0
  269. data/src/jpeg-7/rdtarga.c +500 -0
  270. data/src/jpeg-7/structure.txt +945 -0
  271. data/src/jpeg-7/testimg.bmp +0 -0
  272. data/src/jpeg-7/testimg.jpg +0 -0
  273. data/src/jpeg-7/testimg.ppm +4 -0
  274. data/src/jpeg-7/testimgp.jpg +0 -0
  275. data/src/jpeg-7/testorig.jpg +0 -0
  276. data/src/jpeg-7/testprog.jpg +0 -0
  277. data/src/jpeg-7/transupp.c +1533 -0
  278. data/src/jpeg-7/transupp.h +205 -0
  279. data/src/jpeg-7/usage.txt +605 -0
  280. data/src/jpeg-7/wizard.txt +211 -0
  281. data/src/jpeg-7/wrbmp.c +442 -0
  282. data/src/jpeg-7/wrgif.c +399 -0
  283. data/src/jpeg-7/wrjpgcom.1 +103 -0
  284. data/src/jpeg-7/wrjpgcom.c +583 -0
  285. data/src/jpeg-7/wrppm.c +269 -0
  286. data/src/jpeg-7/wrrle.c +305 -0
  287. data/src/jpeg-7/wrtarga.c +253 -0
  288. metadata +287 -6
  289. data/LICENSE +0 -20
  290. data/VERSION.yml +0 -4
@@ -0,0 +1,63 @@
1
+ #ifndef _OCR0_H
2
+ #define _OCR0_H
3
+ #include "pgm2asc.h"
4
+
5
+ /* ----------------------------------------------------------------
6
+ - functions with thousand of lines make the compilation very slow
7
+ therefore the ocr0-function is splitted in subfunctions
8
+ - shared data used often in ocr0-subroutines are stored
9
+ in ocr0_shared structure.
10
+ * ------------------------------------------------------------ */
11
+
12
+ typedef struct ocr0_shared { /* shared variables and properties */
13
+
14
+ struct box *box1; /* box in whole image */
15
+ pix *bp; /* extracted temporarly box, cleaned */
16
+ int cs; /* global threshold value (gray level) */
17
+
18
+ /* ToDo: or MACROS: X0 = box1->x0 */
19
+ int x0, x1, y0, y1; /* box coordinates related to box1 */
20
+ int dx, dy; /* size of box */
21
+ int hchar, gchar; /* relation to m1..m4 */
22
+ int aa[4][4]; /* corner points, see xX (x,y,dist^2,vector_idx) v0.41 */
23
+ holes_t holes; /* list of holes (max MAX_HOLES) */
24
+
25
+ } ocr0_shared_t;
26
+
27
+ /* tests for umlaut */
28
+ int testumlaut(struct box *box1, int cs, int m, wchar_t *modifier);
29
+ /* detect chars */
30
+ wchar_t ocr0(struct box *box1, pix *b, int cs);
31
+ /* detect numbers */
32
+ wchar_t ocr0n(ocr0_shared_t *sdata);
33
+
34
+ static inline int sq(int x) { return x*x; } /* square */
35
+
36
+ /*
37
+ * go from vector j1 to vector j2 and measure maximum deviation of
38
+ * the steps from the line connecting j1 and j2
39
+ * return the squared maximum distance
40
+ * in units of the box size times 1024
41
+ */
42
+ int line_deviation( struct box *box1, int j1, int j2 );
43
+
44
+ /*
45
+ * search vectors between j1 and j2 for nearest point a to point r
46
+ * example:
47
+ *
48
+ * r-> $$...$$ $ - mark vectors
49
+ * @@$..@@ @ - black pixels
50
+ * @@$..@@ . - white pixels
51
+ * @@@@.$@
52
+ * a-> @@$@$@@
53
+ * @$.@@@@
54
+ * @@..$@@
55
+ * @@..$@@
56
+ * j1 --> $$...$$ <-- j2
57
+ *
58
+ * ToDo: vector aa[5] = {rx,ry,x,y,d^2,idx} statt rx,ry?
59
+ * j1 and j2 must be in the same frame
60
+ * return aa?
61
+ */
62
+ int nearest_frame_vector( struct box *box1, int j1, int j2, int rx, int ry);
63
+ #endif
@@ -0,0 +1,1475 @@
1
+ /* ocr-engine numbers only */
2
+ /*
3
+ This is a Optical-Character-Recognition program
4
+ Copyright (C) 2000-2009 Joerg Schulenburg
5
+
6
+ This program is free software; you can redistribute it and/or
7
+ modify it under the terms of the GNU General Public License
8
+ as published by the Free Software Foundation; either version 2
9
+ of the License, or (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program; if not, write to the Free Software
18
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
+
20
+ see README for EMAIL-address
21
+
22
+ OCR engine (c) Joerg Schulenburg
23
+ first engine: rule based --- numbers 0..9
24
+
25
+ */
26
+
27
+ #include <stdlib.h>
28
+ #include <stdio.h>
29
+ /* #include "pgm2asc.h" */
30
+ #include "ocr0.h"
31
+ #include "ocr1.h"
32
+ #include "amiga.h"
33
+ #include "pnm.h"
34
+ #include "gocr.h"
35
+
36
+ /* only for debugging and development */
37
+ #define IFV if(JOB->cfg.verbose&4)
38
+ #define MM {IFV fprintf(stderr,"\nDBG %c L%04d (%d,%d): ",(char)c_ask,__LINE__,box1->x0,box1->y0);}
39
+
40
+ /* the old debug mode (0.40) was only for a special char, for another char
41
+ * code must be recompiled with C_ASK='char'
42
+ * new debug mode (0.41) explains why char is declined or accepted as ABC...
43
+ * the output can be filtered by external scripts
44
+ * ToDo: we could reduce output to filter string
45
+ */
46
+ #ifndef DO_DEBUG /* can be defined outside */
47
+ #define DO_DEBUG 0 /* 0 is the default */
48
+ #endif
49
+
50
+ /* this macro is for debugging output: "if char is declined, why?" */
51
+ #if DO_DEBUG /* 0=Work mode, 1=debugging mode */
52
+ // Setac: output, that char is choosen with a probability
53
+ // Break: output, why the char is not choosen
54
+ // MSG: debugging functions for char C_ASK, mostly messages
55
+ // DBG: definitions usefull only for debugging
56
+ #define Setac(box1,ac,ad) { MM;IFV fprintf(stderr,"setac %d",ad);setac(box1,ac,ad); }
57
+ #define Break { MM;IFV fprintf(stderr,"break"); break; }
58
+ #define MSG(x) { MM;IFV x }
59
+ #define DBG(x) x
60
+ #else
61
+ #define Setac(box1,ac,ad) setac(box1,ac,ad)
62
+ #define Break break
63
+ #define MSG(x)
64
+ #define DBG(x)
65
+ #endif
66
+
67
+ /* extern "C"{ */
68
+
69
+ // OCR engine ;)
70
+ wchar_t ocr0n(ocr0_shared_t *sdata){
71
+ struct box *box1=sdata->box1;
72
+ pix *bp=sdata->bp;
73
+ int d,x,y,x0=box1->x0,x1=box1->x1,y0=box1->y0,y1=box1->y1;
74
+ int dx=x1-x0+1,dy=y1-y0+1,cs=sdata->cs; // size
75
+ int xa,xb,ya,yb, /* tmp-vars */
76
+ i1,i2,i3,i4,i,j;
77
+ int (*aa)[4]=sdata->aa; /* corner-points, (x,y,dist^2,vector_idx) */
78
+ wchar_t bc=UNKNOWN; // best char
79
+ int ad=0; // propability 0..100
80
+ int hchar=sdata->hchar; // char is higher than 'e'
81
+ int gchar=sdata->gchar; // char has ink lower than m3
82
+ int dots=box1->dots;
83
+ // --- test 5 near S ---------------------------------------------------
84
+ for(ad=d=100;dx>2 && dy>4;){ // min 3x4
85
+ DBG( char c_ask='5'; )
86
+ if (sdata->holes.num > 1) Break; /* be tolerant */
87
+ if( num_cross( dx/2, dx/2,0,dy-1,bp,cs)!=3
88
+ && num_cross(5*dx/8,3*dx/8,0,dy-1,bp,cs)!=3 ) Break;
89
+
90
+ i1=loop(bp,dx-1,dy-1,dx,cs,0,LE);
91
+ i2=loop(bp,dx-1,dy-2,dx,cs,0,LE);
92
+ if (i2-i1 >= dx/4) Break; // ~{ 5x7font
93
+
94
+ // get the upper and lower hole koords, y around dy/4 ???
95
+ x=5*dx/8;
96
+ y =loop(bp,x,0,dy,cs,0,DO); if(y>dy/8) Break;
97
+ y +=loop(bp,x,y,dy,cs,1,DO); if(y>dy/4) Break;
98
+ i1 =loop(bp,x,y,dy,cs,0,DO)+y; if(i1>5*dy/8) Break;
99
+ i3=y=(y+i1)/2; // upper end can be shifted to the right for italic
100
+ x =loop(bp,0,y,dx,cs,0,RI); if(x>4*dx/8) Break;
101
+ x +=loop(bp,x,y,dx,cs,1,RI); if(x>5*dx/8) Break;
102
+ i1 =loop(bp,x,y,dx,cs,0,RI); i1=(i1+2*x)/2; // upper center (i1,i3)
103
+ y=11*dy/16;
104
+ x =loop(bp,dx-1 ,y,dx,cs,0,LE); if(x>dx/4) Break;
105
+ x +=loop(bp,dx-1-x,y,dx,cs,1,LE); if(x>dx/2) Break;
106
+ i2 =loop(bp,dx-1-x,y,dx,cs,0,LE); i2=dx-1-(i2+2*x)/2; // lower center x
107
+
108
+ MSG( fprintf(stderr,"i1,i3=%d,%d i2=%d (upper+lower center)",i1,i3,i2);)
109
+
110
+ y =loop(bp,i1,0,dy,cs,0,DO);
111
+ y +=loop(bp,i1,y,dy,cs,1,DO);
112
+ y =(3*y+i3)/4;
113
+ if( num_cross( i1, dx-1, y, y,bp,cs)>0 ){ /* S or serif5 ? */
114
+ y =loop(bp,i1 ,i3,dy,cs,0,DO);
115
+ i =loop(bp,i1-1,i3,dy,cs,0,DO);
116
+ if (y>i ) ad=99*ad/100; /* looks like S */
117
+ y =loop(bp,i1 ,i3,dy,cs,0,UP);
118
+ i =loop(bp,i1+1,i3,dy,cs,0,UP);
119
+ if (i<y ) ad=99*ad/100; /* looks like S */
120
+ x =loop(bp,dx-1,0,dx,cs,0,LE);
121
+ i =loop(bp,dx-1,1,dx,cs,0,LE);
122
+ if (x>i ) ad=99*ad/100; /* looks like S */
123
+ if( num_cross( 0, dx/2, dy-1, dy-1,bp,cs)>1
124
+ && num_cross( dx/2,dx-1, 0, 0,bp,cs)>1 ) ad=98*ad/100; /* serifs */
125
+ if (loop(bp,0,dy-1,dx,cs,0,RI)==0) ad=98*ad/100; /* S or 7segment */
126
+ ad=99*ad/100;
127
+ }
128
+
129
+ for(y=dy/5;y<3*dy/4;y++) // right gap?
130
+ if( num_cross(i1,dx-1,y,y,bp,cs)==0 ) break;
131
+ if( y==3*dy/4 ) Break;
132
+
133
+ for(y=dy/4;y<=11*dy/16;y++) // left gap?
134
+ if( num_cross(0,i2,y,y,bp,cs)==0 ) break;
135
+ if( y>11*dy/16 ) Break;
136
+
137
+ // if( num_hole( x0, x1, y0, y1, box1->p,cs,NULL) > 0 ) break;
138
+ if (sdata->holes.num>0) Break;
139
+
140
+ // sS5 \sl z left upper v-bow ?
141
+ for(x=dx,i=y=dy/4;y<dy/2;y++){
142
+ j=loop(bp,0,y,dx,cs,0,RI); if(j<x) { x=j; i=y; }
143
+ } y=i;
144
+ i1=loop(bp,0, dy/16 ,dx,cs,0,RI);
145
+ i2=loop(bp,0,(y+dy/16)/2 ,dx,cs,0,RI);
146
+ i =loop(bp,0,(y+dy/16)/2+1,dx,cs,0,RI); if( i>i2 ) i2=i;
147
+ i3=loop(bp,0, y ,dx,cs,0,RI);
148
+ i =loop(bp,0, y-1,dx,cs,0,RI); if( i<i3 ) i3=i;
149
+ if( 2*i2+1+dx/16 < i1+i3 ) Break;
150
+
151
+ if( dy>=20 && dx<16 ) /* tall S */
152
+ if( loop(bp,0, dy/5 ,dx,cs,0,RI)
153
+ ==loop(bp,0, dy/4 ,dx,cs,0,RI)
154
+ &&
155
+ loop(bp,0, dy/10 ,dx,cs,0,RI)
156
+ >loop(bp,0, dy/4 ,dx,cs,0,RI)
157
+ &&
158
+ loop(bp,0, 1 ,dx,cs,0,RI)
159
+ >loop(bp,0, dy/4 ,dx,cs,0,RI)+1
160
+ &&
161
+ loop(bp,dx-1, 0 ,dx,cs,0,LE)
162
+ >loop(bp,dx-1, 1 ,dx,cs,0,LE) ) Break;
163
+
164
+ if( dy>=30 && dx>15 ) /* large S */
165
+ if( loop(bp,dx/4,3*dy/10,dy,cs,1,DO)>0 ) // check start
166
+ if( loop(bp,dx-2,3*dy/4 ,dy,cs,1,UP)>0 ) // check end
167
+ if( num_cross(dx/4,dx-2,3*dy/10,3*dy/4,bp,cs)==1 ) Break; // connected?
168
+ MSG(fprintf(stderr,"~S ad=%d",ad);)
169
+
170
+ // small fat s is very similar to rounded serif 5
171
+ // but has a fat diagonal arrea (Oct08 JS)
172
+ if ( num_cross(dx/8,dx-1-dx/8,3*dy/10,3*dy/4,bp,cs)==1 ) ad=98*ad/100;
173
+ MSG(fprintf(stderr,"~S ad=%d",ad);)
174
+
175
+ if( dy>17 && dx>9 ) /* S */
176
+ if( loop(bp, 0,dy/2 ,dx,cs,0,RI)<dx/2
177
+ || loop(bp, 0,dy/2-1 ,dx,cs,0,RI)<dx/2 )
178
+ if( loop(bp,dx/4,3*dy/10,dy,cs,1,DO)>0 ) // check start
179
+ if( loop(bp,dx-2,2*dy/3 ,dy,cs,1,UP)>0 ) // check end
180
+ if( loop(bp, 0, dy/16,dx,cs,0,RI)
181
+ >= loop(bp,dx-1, dy-1-dy/16,dx,cs,0,LE) ) ad=ad*98/100;
182
+ MSG(fprintf(stderr,"~S ad=%d",ad);)
183
+ if( loop(bp,3*dx/4 , 0,dy,cs,1,DO) // ToDo: improve!
184
+ < loop(bp, dx/4 ,dy-1,dy,cs,1,UP)
185
+ && loop(bp,3*dx/4-1, 0,dy,cs,0,DO)
186
+ < loop(bp, dx/4+1,dy-1,dy,cs,0,UP) ) ad=ad*98/100;
187
+ MSG(fprintf(stderr,"~S ad=%d",ad);)
188
+
189
+ if ( gchar) ad=99*ad/100;
190
+ if (!hchar) ad=99*ad/100;
191
+ Setac(box1,(wchar_t)'5',ad);
192
+ if (ad==100) return '5';
193
+ break;
194
+
195
+ }
196
+ // --- test 1 ---------------------------------------------------
197
+ for(ad=d=100;dy>4 && dy>dx && 2*dy>box1->m3-box1->m2;){ // min 3x4
198
+ DBG( char c_ask='1'; )
199
+ if( dots==1 ) Break;
200
+ if (sdata->holes.num > 1) Break; /* be tolerant */
201
+
202
+ if( num_cross(0, dx-1, 0 , 0 ,bp,cs) != 1
203
+ && num_cross(0, dx-1, 1 , 1 ,bp,cs) != 1 ) Break;
204
+ if( num_cross(0, dx-1,dy/2,dy/2,bp,cs) != 1 ) Break;
205
+ if( num_cross(0, dx-1,dy-1,dy-1,bp,cs) != 1
206
+ && num_cross(0, dx-1,dy-2,dy-2,bp,cs) != 1 ) Break;
207
+ /* 5x7 micr ocr-a
208
+
209
+ ooo @@@..
210
+ .$. ooo ..@..
211
+ $@. oo ..@..
212
+ .$. oo ..@..
213
+ .@. ooooo ..@.@
214
+ .$. ooooo ..@.@
215
+ $@$ ooooo @@@@@
216
+
217
+ */
218
+ i4=0; // human font
219
+ if( num_cross(0, dx-1,3*dy/4,3*dy/4,bp,cs) != 2 ) { // except ocr-a
220
+ for( y=1; y<dy/2; y++ ){
221
+ if( num_cross(0, dx-1, y , y ,bp,cs) == 2 ) break;
222
+ } if (y>=dy/2) ad=98*ad/100;
223
+ for( i=dy/8,y=7*dy/16;y<dy-1 && i;y++ ){
224
+ if( num_cross(0, dx-1, y , y ,bp,cs) != 1 ) i--;
225
+ } if( dy>8 && !i ) Break;
226
+ } else { // ocr-a-1
227
+ i= loop(bp,dx/2,0,dy,cs,0,DO);
228
+ if (loop(bp,dx/2,i,dy,cs,1,DO)<dy-1) Break;
229
+ i= loop(bp,dx -1,dy-1-dy/16,dx,cs,0,LE);
230
+ if (loop(bp,dx-i-1,dy-1-dy/16,dx,cs,1,LE)<dx-1) Break;
231
+ i= loop(bp,0,dy/16,dx,cs,0,RI);
232
+ if (loop(bp,i,dy/16,dx,cs,1,RI)<dx/2) Break;
233
+ i4=1;
234
+ MSG(fprintf(stderr,"ocr-a-1 detected ad= %d", ad);)
235
+ }
236
+
237
+ if( num_cross(0, dx-1, 0 , 0 ,bp,cs) > 1
238
+ && num_cross(0, dx-1, 1 , 1 ,bp,cs) > 1 ) Break; // ~/it_7
239
+
240
+ // calculate upper and lower mass center (without lower serif)
241
+
242
+ x =loop(bp,0,7*dy/8-1,dx,cs,0,RI); i2=x;
243
+ x+=loop(bp,x,7*dy/8-1,dx,cs,1,RI)-1; i2=(i2+x)/2;
244
+
245
+ i1=loop(bp,dx-1 ,1+0* dy/4,dx,cs,0,LE); i1=dx-1-i1-(x-i2)/2;
246
+
247
+ x =(i1-i2+4)/8; i1+=x; i2-=x;
248
+
249
+ if( get_line2(i1,0,i2,dy-1,bp,cs,100)<95 ) { // dont work for ocr-a-1
250
+ i1=loop(bp,dx-1 ,1+0* dy/4,dx,cs,0,LE); i1=dx-1-i1;
251
+ if( get_line2(i1,0,i2,dy-1,bp,cs,100)<95 ) Break;
252
+ }
253
+ // upper and lower width
254
+ x =loop(bp,(i1+i2)/2,dy/2,dx,cs,1,RI); i=x; i3=0;
255
+ for(y=0;y<7*dy/8;y++)
256
+ if( loop(bp,i1+y*(i2-i1)/dy, y,dx,cs,1,RI)-i > 1+dx/8 ) break;
257
+ if(y<7*dy/8) ad=98*ad/100; // serif or ocr-a-1 ?
258
+ if(y<6*dy/8) ad=99*ad/100; /* MICR E-13B font Jan07 */
259
+ if(y<4*dy/8) Break;
260
+ MSG(fprintf(stderr,"i12 %d %d ad= %d", i1,i2,ad);)
261
+ // out_x(box1); printf(" i12=%d %d\n",i1,i2);
262
+ x =loop(bp,i2,dy-1,dx,cs,1,LE); j=x;
263
+ x =loop(bp,i2,dy-2,dx,cs,1,LE); if(x>j)j=x; i=j;
264
+ x =loop(bp,i2,dy-1,dx,cs,1,RI); j=x;
265
+ x =loop(bp,i2,dy-2,dx,cs,1,RI); if(x>j)j=x;
266
+ if(abs(i-j)>1+dx/8) i3|=1;
267
+ if(i3) Break;
268
+ // out_x(box1);printf(" 11 i=%d j=%d i2=%d dx=%d\n",i,j,i1,dx);
269
+ // get most left upper point (i,j)
270
+ for(i=dx,j=y=0;y<7*dy/16;y++){
271
+ x =loop(bp,0,y,dx,cs,0,RI); if(x<i) { i=x;j=y; }
272
+ }
273
+ if ( i1-i<7*dx/16 ) ad=ad*98/100;
274
+ if ( i1-i<6*dx/16 ) ad=ad*98/100; // 4*dx/8 => 7*dx/16 MICR E-13B font
275
+ if ( i1-i<4*dx/16 ) Break;
276
+ MSG(fprintf(stderr,"i12 %d %d ad= %d", i1,i2,ad);)
277
+ x =loop(bp,0,dy/2,dx,cs,0,RI); // right distance
278
+ j =loop(bp,x,dy/2,dx,cs,1,RI); // thickness
279
+ if( j>x+(dy+16)/32 ) ad=98*ad/100; // ~l but MICR E-13B font
280
+ x =loop(bp,0,0,dx,cs,0,RI); // straight line ???
281
+ j =loop(bp,0,1,dx,cs,0,RI); if( j>x ) Break; // ~l
282
+ if( x==j ) j =loop(bp,0,dy/8,dx,cs,0,RI); if( j>x && !i4) Break;
283
+ if( x==j ) if(loop(bp,0,dy/4,dx,cs,0,RI)>x) { // ~l
284
+ // check micr-1 first before taken as 'l'
285
+ if (loop(bp,dx-1,dy/8,dx,cs,0,LE)<=dx/4
286
+ && loop(bp, 0,3*dy/4,dx,cs,1,RI)< dx-1) ad=97*ad/100;
287
+ }
288
+ MSG(fprintf(stderr,"1l check ad= %d", ad);)
289
+ x=j;
290
+ // j =loop(bp,0,2,dx,cs,0,RI); if( j>=x ) Break; x=j; // ~l
291
+ // j =loop(bp,0, 0,dx,cs,0,DO); if( !j ) Break; // ~7
292
+ if( !hchar ) // ~ right part of n
293
+ /* look for upper right side, not going from nw to se */
294
+ if( loop(bp,dx-1, 1,dx,cs,0,LE)-dy/6
295
+ > loop(bp,dx-1,dy/4,dx,cs,0,LE)
296
+ // failes on small fonts with 1 point spaces between chars
297
+ // also do not know what the purpose of this line was (JS Oct08)
298
+ // || get_bw(x1+1,x1+2,y0,y0+dy/8,box1->p,cs,1)==1
299
+ ) Break; // Mai00
300
+ if( loop(bp,dx-1,3*dy/4,dx,cs,0,LE) > dx/2
301
+ && get_bw(x1-dx/4,x1,y1-1,y1,box1->p,cs,1)==1 ) Break; // ~z Jun00
302
+
303
+ i=loop(bp, dx/8,0,dy,cs,0,DO);
304
+ for (y=dy,x=dx/2;x<3*dx/4;x++){ /* get upper end y */
305
+ j=loop(bp,x,0,dy,cs,0,DO); if (j<y) { y=j; }
306
+ }
307
+ if(y<dy/2 && y+dy/16>=i) ad=98*ad/100; // ~\tt l ??? ocr-a_1
308
+ MSG(fprintf(stderr,"1l check i= %d y= %d ad= %d", i, y, ad);)
309
+
310
+ if( loop(bp, 0, dy/8,dx,cs,0,RI)
311
+ -(dx-loop(bp,dx-1,7*dy/8,dx,cs,0,LE)) > dx/4 ) Break; // ~/
312
+
313
+ i= loop(bp, 0, 0,dy,cs,0,DO); // horizontal line?
314
+ if(dy>=12 && i>dy/8 && i<dy/2){
315
+ if( loop(bp,dx-1,3*dy/16,dx,cs,0,LE)-dx/8
316
+ >loop(bp,dx-1, i,dx,cs,0,LE)
317
+ || loop(bp,dx-1,3*dy/16,dx,cs,0,LE)-dx/8
318
+ >loop(bp,dx-1, i+1,dx,cs,0,LE) ) Break; // ~t,~f
319
+ i= loop(bp, 0,dy-1-dy/32,dx,cs,0,RI);
320
+ x= loop(bp, 0,dy-2-dy/32,dx,cs,0,RI); if (i<x) x=i;
321
+ if( x-loop(bp, 0, 3*dy/4,dx,cs,0,RI)>dx/8
322
+ && loop(bp,dx-1, 3*dy/4,dx,cs,0,LE)-dx/8
323
+ >loop(bp,dx-1,dy-1-dy/32,dx,cs,0,LE) ) Break; // ~t
324
+ if( loop(bp, 0,i-1,dx,cs,0,RI)>1 && dx<6) {
325
+ ad=99*ad/100;
326
+ if ( loop(bp,dx-1,i-1,dx,cs,0,LE)>1 ) Break; // ~t
327
+ }
328
+ }
329
+
330
+ if (dx>8){
331
+ if (loop(bp,0,3*dy/4,dx,cs,0,RI)-
332
+ loop(bp,0,dy/2-1,dx,cs,0,RI)>dx/4) ad=95*ad/100; // ~3
333
+ if (loop(bp,dx-1,dy/2-1,dx,cs,0,LE)-
334
+ loop(bp,dx-1,3*dy/4,dx,cs,0,LE)>dx/8) ad=99*ad/100; // ~3 ocr-a?
335
+ if (loop(bp,dx-1, dy/16,dx,cs,0,LE)-
336
+ loop(bp,dx-1, dy/4,dx,cs,0,LE)>dx/8) ad=95*ad/100; // ~23
337
+ MSG(fprintf(stderr,"23 check ad= %d", ad);)
338
+ }
339
+ /* font 5x9 "2" recognized as "1" */
340
+ i=loop(bp,dx-1-dx/8,dy-1,dy,cs,0,UP);
341
+ if (i<=dy/4) {
342
+ i+=loop(bp,dx-1-dx/8,dy-1-i,dy,cs,1,UP);
343
+ if (i<=dy/4) {
344
+ i=loop(bp,dx-1-dx/8,dy-1-i,dy,cs,0,LE);
345
+ if (2*i>=dx && loop(bp,dx/4,0,dy,cs,0,DO)<dy/2) {
346
+ if (dx<17) ad=98*ad/100;
347
+ if (dx<9) ad=97*ad/100;
348
+ MSG(fprintf(stderr,"5x9 2 check ad= %d", ad);)
349
+ }
350
+ }
351
+ }
352
+
353
+ // looking for ###
354
+ // ..# pattern (its important, we dont want perp. lines as 1)
355
+ // ToDo: better check that we have exact one on top
356
+ for (i2=0,i=dx,y=0;y<dy/2;y++) {
357
+ j=loop(bp,0,y,dx,cs,0,RI); if (j<i) i=j;
358
+ if (j>i+dx/8) { break; }
359
+ } if (y>=dy/2) ad=95*ad/100; // Feb07 care plates, right black border
360
+ MSG(fprintf(stderr,"ad= %d", ad);)
361
+
362
+ if (sdata->holes.num > 0) Break; // mini holes should be filtered
363
+ if (!box1->m3 && ad>98) ad=98; else {
364
+ if (!hchar) ad=99*ad/100;
365
+ if (box1->y0>box1->m2) ad=98*ad/100;
366
+ if (box1->y1<(1*box1->m2+3*box1->m3)/4) ad=98*ad/100;
367
+ if (box1->y1-box1->y0<(box1->m3-box1->m1)/2) ad=98*ad/100;
368
+ if ( gchar) ad=99*ad/100;
369
+ }
370
+
371
+ Setac(box1,(wchar_t)'1',ad);
372
+ break;
373
+ }
374
+ // --- test 2 old pixelbased - remove! -----------------------------
375
+ #ifdef Old_pixel_based
376
+ for(ad=d=100;dx>2 && dy>4;){ // min 3x4
377
+ DBG( char c_ask='2'; )
378
+ if (sdata->holes.num > 1) Break; /* be tolerant */
379
+ if( get_bw(x0+dx/2, x0+dx/2 , y1-dy/5, y1 ,box1->p,cs,1) != 1 ) Break;
380
+ if( get_bw(x0+dx/2, x0+dx/2 , y0 , y0+dy/5,box1->p,cs,1) != 1 ) Break;
381
+ if( get_bw(x0+dx/8, x1-dx/3 , y1-dy/3, y1-dy/3,box1->p,cs,1) != 1 ) Break;
382
+
383
+ if( get_bw(x1-dx/3, x1 , y0+dy/3 , y0+dy/3,box1->p,cs,1) != 1 ) Break;
384
+ if( get_bw(x0 , x0+dx/ 8, y1-dy/16, y1 ,box1->p,cs,1) != 1 ) Break;
385
+ if( num_cross(x0, x1-dx/8, y0+dy/2, y0+dy/2,box1->p,cs) != 1 ) Break;
386
+ if( get_bw(x0, x0+dx/9 , y0 , y0 ,box1->p,cs,1) == 1
387
+ && get_bw(x0, x0+dx/2 ,y0+3*dy/16,y0+3*dy/16,box1->p,cs,1) == 1 ) Break;
388
+ if( get_bw(x0, x0+dx/9 , y0 , y0 ,box1->p,cs,1)
389
+ != get_bw(x1-dx/9, x1 , y0 , y0 ,box1->p,cs,1) )
390
+ { if (dx<6 && dy<9) ad=99*ad/100; else Break; }
391
+ // out_x(box1);
392
+
393
+ for( x=x0+dx/4;x<x1-dx/6;x++ ) // C
394
+ if( num_cross( x, x, y0, y0+dy/2,box1->p,cs) == 2 ) break;
395
+ if( x>=x1-dx/6 ) Break;
396
+
397
+ for( x=x0+dx/4;x<x1-dx/6;x++ ) // C, but acr-a
398
+ if( num_cross( x, x, y0+3*dy/8,y1,box1->p,cs) == 2 ) break;
399
+ if( x>=x1-dx/6 ) Break;
400
+
401
+ for(i=1,y=y0;y<y0+dy/2;y++ )
402
+ if( num_cross( x0, x1, y, y,box1->p,cs) == 2 ) i=0;
403
+ if( i ) ad=99*ad/100; // ToDo: ocr-a-2 should have 100%
404
+
405
+ for(i=1,y=y0+dy/5;y<y0+3*dy/4;y++ )
406
+ if( get_bw( x0, x0+dx/3, y, y,box1->p,cs,1) == 0 ) i=0;
407
+ if( i ) Break;
408
+
409
+ x=x1-dx/3,y=y1; /* center bottom */
410
+ turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,UP,ST); if( y<y1-dy/5 ) Break;
411
+ turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,ST,UP); if( y<y1-dy/4 ) ad=99*ad/100;
412
+ if( y<y1-dy/3 ) Break;
413
+ turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,UP,ST); if( y<y0+dy/3 ) Break; y++;
414
+ turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,RI,ST);
415
+ if( x<x1 ){ x--; // hmm thick font and serifs
416
+ turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,UP,ST); if( y<y0+dy/2 ) Break; y++;
417
+ turmite(box1->p,&x,&y,x0,x1,y0,y1,cs,RI,ST);
418
+ if( x<x1 ) Break;
419
+ }
420
+
421
+ // test ob rechte Kante ansteigend
422
+ for(x=0,y=dy/18;y<=dy/3;y++){ // rechts abfallende Kante/Rund?
423
+ i=loop(box1->p,x1,y0+y,dx,cs,0,LE); // use p (not b) for broken chars
424
+ if( i<x ) break; // rund
425
+ if( i>x ) x=i;
426
+ }
427
+ if (y>dy/3 ) Break; // z
428
+
429
+ // hole is only allowed in beauty fonts
430
+ // if( num_hole( x0, x1, y0, y1,box1->p,cs,NULL) > 0 ) // there is no hole
431
+ // if( num_hole( x0, x0+dx/2, y0, y0+dy/2,box1->p,cs,NULL) == 0 ) // except in some beauty fonts
432
+ if (sdata->holes.num>0)
433
+ if (sdata->holes.hole[0].x1 >= dx/2 || sdata->holes.hole[0].y1 >= dy/2)
434
+ Break;
435
+
436
+ if (loop(bp,dx-1, 0,dx,cs,0,LE)
437
+ <loop(bp,dx-1,dy/4,dx,cs,0,LE)-dx/8) Break; // 5x7,5x8 z Jul09
438
+ i1=loop(bp,dx-1-dx/16,0,dy,cs,0,DO); // Jul00
439
+ i2=loop(bp, dx/ 2,0,dy,cs,0,DO); if( i2+dy/32>=i1 ) Break; // ~z
440
+ i1=loop(bp,dx-1,dy-3*dy/16,dx,cs,0,LE);
441
+ i2=loop(bp, 0,dy-3*dy/16,dx,cs,0,RI); if( i2>i1 ) ad=98*ad/100; // ~i
442
+ if (dots) ad=98*ad/100; // i
443
+ if (loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)>dx/4) ad=96*ad/100; // \it i
444
+
445
+ if ((!hchar) && box1->m4!=0) ad=80*ad/100;
446
+ Setac(box1,(wchar_t)'2',ad);
447
+ if (ad==100) return '2';
448
+ break;
449
+ }
450
+ #endif
451
+ // --- test 2 new edge based v0.44 --------------------------------------
452
+ for(ad=d=100;dx>2 && dy>4;){ // min 3x4
453
+ // rewritten for vectors 0.42
454
+ int ld, i1, i2, i3, i4, i5, i6, i7; // line derivation + corners
455
+ DBG( wchar_t c_ask='2'; )
456
+ if (sdata->holes.num > 0) Break; /* no hole */
457
+ /* half distance to the center */
458
+ d=2*sq(128/4);
459
+ /* now we check for the lower ends, must be near to the corner */
460
+ if (aa[1][2]>d/4) Break; /* [2] = distance, ~7... */
461
+ if (aa[2][2]>d/2) Break; /* [2] = distance, ~r... */
462
+ if (aa[0][2]>d/1) Break; /* [2] = distance, ~d... */
463
+ if (aa[3][2]>d/1) Break; /* [2] = distance, ~bhk... */
464
+ /* searching for 4 notches between neighbouring ends */
465
+
466
+ /*
467
+ type A B
468
+
469
+ 1OOO OO
470
+ 2 1 2 <- 6
471
+ 7-> OOOO O
472
+ O O <- 5
473
+ 3OO4 3OO4
474
+ */
475
+
476
+ // ToDo: replace by vector code (get point on line at dy/4)
477
+ if (loop(bp,dx-1, 0,dx,cs,0,LE)
478
+ <loop(bp,dx-1,dy/4,dx,cs,0,LE)-dx/8) Break; // 5x7,5x8 z Jul09
479
+
480
+ /* get a point on the inner low left side of the J */
481
+ i =box1->num_frame_vectors[0] - 1;
482
+ /* rightmost point on upper left side */
483
+ i2=nearest_frame_vector(box1, aa[0][3], aa[1][3], x1+dx, y0+dy/4);
484
+ /* upper leftmost vector */
485
+ i1=nearest_frame_vector(box1, aa[0][3], i2, x0-dx, (y0+y1)/2);
486
+ i3=aa[1][3];
487
+ /* low leftmost vector */
488
+ i5=nearest_frame_vector(box1, aa[2][3], aa[3][3], x0, y1);
489
+ /* low mostright vector */
490
+ i4=nearest_frame_vector(box1, aa[1][3], i5, x1+dx, y1);
491
+ /* next local max_x-point after i5 */
492
+ i6=i5;
493
+ for (i=i5;i!=aa[0][3];i=(i+1)%box1->num_frame_vectors[0]) {
494
+ if (box1->frame_vector[ i][0]
495
+ >box1->frame_vector[i6][0]) i6=i; // get next maximum
496
+ if (box1->frame_vector[ i][0]<x0+dx/3
497
+ && box1->frame_vector[ i][1]<y0+dy/3
498
+ && box1->frame_vector[i6][0]>x0+dx/2) break; // 5
499
+ }
500
+ /* which type? ToDo: have a more sure algorithm */
501
+ i7=nearest_frame_vector(box1, i2, i3, x0-dx/8, (y0+y1)/2);
502
+ if (box1->frame_vector[i7][0]<=x0+ dx/4
503
+ && box1->frame_vector[i7][1]<=y0+2*dy/3) {
504
+ MSG(fprintf(stderr,"7-segment-type");)
505
+ } else { /* regular-book-type */
506
+ MSG( fprintf(stderr,"upper bow not z-like? ad %d", ad); )
507
+ if (aa[3][0]>=x1-dx/8 // x of upper right point
508
+ && aa[3][1]< y0+dy/8) ad=99*ad/100; // y of upper right point
509
+ if (aa[0][0]<=x0+dx/8 // x of upper left point
510
+ && aa[0][1]< y0+dy/8) ad=99*ad/100; // y of upper left point
511
+ if (aa[3][2]<=aa[1][2]) ad=97*ad/100; // dist to (maxx,0) <= (0,maxy)
512
+ }
513
+ // ToDo: output no=(x,y)
514
+ MSG( fprintf(stderr,"i1-7 %d %d %d %d %d %d %d ad %d",
515
+ i1,i2,i3,i4,i5,i6,i7,ad); )
516
+ if (i5==i6) Break; // ~+
517
+
518
+ if (box1->frame_vector[i5][1]
519
+ -box1->frame_vector[i6][1]<dy/4) Break; // ~5
520
+ if (box1->frame_vector[i1][1]>y0+dy/2) Break; // not to low
521
+ if (box1->frame_vector[i1][0]>x0+dx/8+dx/16) Break; // slanted ?
522
+ if (box1->frame_vector[i2][1]>(y0+ y1)/2) Break;
523
+ if (box1->frame_vector[i2][1]>(5*y0+3*y1)/8) ad=99*ad/100;
524
+ MSG( fprintf(stderr,"ad %d", ad); )
525
+ if (box1->frame_vector[i2][0]<(x0+x1+1)/2) Break; // fat tiny fonts?
526
+ if (box1->frame_vector[i2][0]<(x0+2*x1)/3) ad=99*ad/100;
527
+ MSG( fprintf(stderr,"ad %d", ad); )
528
+ if (box1->frame_vector[i3][0]>(3*x0+x1)/4) Break;
529
+ if (box1->frame_vector[i3][0]>(7*x0+x1)/8) ad=99*ad/100;
530
+ MSG( fprintf(stderr,"ad %d", ad); )
531
+ /* check lowest left point */
532
+ if (box1->frame_vector[i3][1]<(y0+3*y1)/4) Break;
533
+ if (box1->frame_vector[i3][1]<(y0+7*y1)/8) ad=99*ad/100;
534
+ MSG( fprintf(stderr,"ad %d", ad); )
535
+ /* check lower leftmost point from right side */
536
+ if (box1->frame_vector[i5][0]>(x0+2*x1)/3) Break;
537
+ if (box1->frame_vector[i5][0]>(x0+ x1)/2) ad=98*ad/100;
538
+ if (box1->frame_vector[i5][0]>(2*x0+2+x1)/3) ad=99*ad/100; /* 9x10 2 */
539
+ MSG( fprintf(stderr,"ad %d", ad); )
540
+ if (box1->frame_vector[i5][1]<(3*y0+5*y1)/8) Break;
541
+ if (box1->frame_vector[i5][1]<(y0+3*y1)/4) ad=99*ad/100;
542
+ MSG( fprintf(stderr,"ad %d", ad); )
543
+ if (box1->frame_vector[i6][1]>(y0+2*y1)/3) Break;
544
+ if (box1->frame_vector[i6][1]>(y0+ y1)/2) ad=99*ad/100;
545
+ MSG( fprintf(stderr,"ad %d", ad); )
546
+ if (box1->frame_vector[i6][0]<(x0+3*x1)/4) Break;
547
+ if (box1->frame_vector[i6][0]<(x0+7*x1)/8) ad=99*ad/100;
548
+
549
+ /* check for zZ */
550
+
551
+ /* check if lower left and right points are joined directly */
552
+ ld=line_deviation(box1, i3, i4);
553
+ MSG(fprintf(stderr,"i1-i2 %d %d dist= %d/%d",i1,i2,ld,2*sq(1024/4));)
554
+ if (ld >2*sq(1024/4)) Break;
555
+ if (ld > sq(1024/4)) ad=99*ad/100;
556
+
557
+ if (box1->m3) {
558
+ if(!hchar){ ad=99*ad/100; }
559
+ if( gchar){ ad=99*ad/100; }
560
+ } else { if (ad==100) ad=99; } /* not 100% sure */
561
+ Setac(box1,'2',ad);
562
+ if (ad==100) return '2';
563
+ break;
564
+ }
565
+ // --- test 3 -------
566
+ for(ad=d=100;dx>3 && dy>4;){ // dy<=dx nicht perfekt! besser mittleres
567
+ // min-suchen fuer m
568
+ int i1, i2, i3, i4, i5, i6, i7, i8; // line derivation + corners
569
+ DBG( char c_ask='3'; )
570
+ if (sdata->holes.num > 1) Break; /* be tolerant */
571
+ if (sdata->holes.num > 0) ad=98*ad/100; /* be tolerant */
572
+ if (4*dx<dy) ad=98*ad/100; // to tall 1:2 - 1:3 is usual
573
+ // --- vector based code ---
574
+ /* half distance to the center */
575
+ d=2*sq(128/4);
576
+ /* now we check for the lower ends, must be near to the corner */
577
+ if (aa[1][2]>d/1) Break; /* [2] = distance, ~7... */
578
+ if (aa[2][2]>d/1) Break; /* [2] = distance, ~r... */
579
+ if (aa[0][2]>d/1) Break; /* [2] = distance, ~d... */
580
+ if (aa[3][2]>d/1) Break; /* [2] = distance, ~bhk... */
581
+ /*
582
+ type A B C
583
+
584
+ 1OO8 1OO 1OO8
585
+ O 8 2 <- 7,8
586
+ 2 2 7
587
+ 1-5-> 3OO7 37 3OO
588
+ 4 4 4
589
+ O 6 6 <- 6
590
+ 5OO6 5OO 5OO
591
+ */
592
+ /* rightmost point on upper left side */
593
+ i2=nearest_frame_vector(box1, aa[0][3], aa[1][3], x1, y0+3*dy/16);
594
+ /* rightmost point on lower left side */
595
+ i4=nearest_frame_vector(box1, aa[0][3], aa[1][3], x1, y1-dy/4);
596
+ /* leftmost point on middle left side */
597
+ i3=nearest_frame_vector(box1, i2, i4, x0, y0+dy/2);
598
+ /* upper leftmost vector */
599
+ i1=nearest_frame_vector(box1, aa[0][3], i2, x0-dx, (y0+y1)/2);
600
+ i5=aa[1][3]; // points to vector point in point list
601
+ i6=aa[2][3];
602
+ i8=aa[3][3];
603
+ /* leftmost point on middle right side */
604
+ i7=nearest_frame_vector(box1, i6, i8, x0 , y0+dy/2);
605
+ /* which type? ToDo: have a more sure algorithm */
606
+ if (box1->frame_vector[i7][0]>=x1- dx/4
607
+ && box1->frame_vector[i6][0]>=x1- dx/8 // ToDo: ...
608
+ && box1->frame_vector[i6][1]>=y1- dy/8) {
609
+ MSG(fprintf(stderr,"7-segment-type");)
610
+ } else { /* regular-book-type */
611
+ }
612
+ // ToDo: output no=(x,y)
613
+ MSG(fprintf(stderr,"i1-8 %d %d %d %d %d %d %d %d",i1,i2,i3,i4,i5,i6,i7,i8);)
614
+ // if (i5==i6) Break; // ~+
615
+
616
+ // i2 = upper left gap ) , i3 = middle left <
617
+ if (box1->frame_vector[i2][0]
618
+ -box1->frame_vector[i3][0]<dx/4) Break; // video samples
619
+ if (box1->frame_vector[i4][0]
620
+ -box1->frame_vector[i3][0]<dx/4) Break; // video samples
621
+ if (box1->frame_vector[i4][0]
622
+ -box1->frame_vector[i5][0]<dx/2) Break; // video samples
623
+ if (box1->frame_vector[i2][0]
624
+ -box1->frame_vector[i1][0]<dx/2) Break; // video samples
625
+ if (box1->frame_vector[i1][1]>y0+dy/2) Break; // not to low
626
+ if (box1->frame_vector[i1][0]>x0+dx/4+dx/16) Break; // slanted?
627
+ if (box1->frame_vector[i5][1]<y1-dy/2) Break; // not to high
628
+ if (box1->frame_vector[i5][0]>x0+dx/4) Break;
629
+ // ToDo ....
630
+
631
+ // --- pixel based old code ---
632
+ // if( get_bw(x0+dx/2,x0+dx/2,y0,y0+dy/4,box1->p,cs,1) == 0 ) Break; // ~4
633
+ // if( get_bw(x0+dx/2,x0+dx/2,y1-dy/8,y1,box1->p,cs,1) == 0 ) Break; // ~4
634
+ // if( num_cross(x0+dx/2,x0+dx/2,y0 ,y1,box1->p,cs) < 2 ) Break;
635
+ // if( num_cross(x0+dx/4,x0+dx/4,y1-dy/2,y1,box1->p,cs) == 0 ) Break;
636
+ if( get_bw(dx/2,dx/2, 0,dy/6,bp,cs,1) == 0 ) Break; // ~4
637
+ if( get_bw(dx/2,dx-1, dy/6,dy/6,bp,cs,1) == 0 ) Break; // ~j
638
+ if( get_bw(dx/2,dx/2,dy-1-dy/8,dy-1,bp,cs,1) == 0 ) Break; // ~4
639
+ if( num_cross(dx/2,dx/2,0 ,dy-1,bp,cs) < 2 // normal
640
+ && num_cross(dx/3,dx/3,0 ,dy-1,bp,cs) < 2 ) Break; // fat LCD
641
+ if( num_cross(dx/4,dx/4,dy-1-dy/2,dy-1,bp,cs) == 0 ) Break;
642
+ if( loop(bp,dx/2, 0 ,dy,cs,0,DO)>dy/4 ) Break;
643
+ if( loop(bp,dx/2, dy-1,dy,cs,0,UP)>dy/4 ) Break;
644
+ if( loop(bp,dx-1, dy/3,dy,cs,0,LE)>dy/4 /* 3 with upper bow */
645
+ && loop(bp,dx-1, dy/8,dy,cs,0,LE)>dy/4 /* 3 with horizontal line */
646
+ && loop(bp,dx/4, dy/8,dy,cs,1,RI)<dy/2 ) Break;
647
+ if( loop(bp,dx-1,2*dy/3,dy,cs,0,LE)>dy/4 ) Break;
648
+ if( loop(bp,dx-1,3*dy/4,dy,cs,0,LE)>dy/2 ) Break; // ~2 Feb06
649
+ if( loop(bp,dx-1,7*dy/8,dy,cs,0,LE)>dy/2 ) Break; // ~2 Feb06
650
+ // search upper right half circle (may fail on 4x5 font)
651
+ for( i3=x=0,i1=y=dy/5;y<dy/2;y++ ){
652
+ i=loop(bp,0,y,dx,cs,0,RI);
653
+ if (i>x) { i3=x=i; i1=y; }
654
+ } i3--;
655
+ if( loop(bp,i3,i1,1,cs,0,UP)==1 ) { // find hidden gap in tiny fonts
656
+ i1--; i3+=loop(bp,i3,i1,dx,cs,0,RI)-1;
657
+ }
658
+ if (i3<dx/3 && i3+1+loop(bp,i3+1,i1,dx,cs,1,RI)<3*dx/4) Break;
659
+ if (loop(bp,dx-1,i1,dx,cs,0,LE)>1+dx/8) ad=ad*99/100; // ~1 with a pixel
660
+ // search lower right half circle
661
+ for( i4=x=0,i2=y=dy-1-dy/8;y>=dy/2;y-- ){
662
+ i=loop(bp,0,y,dx,cs,0,RI);
663
+ if( i>x ) { i4=x=i;i2=y; }
664
+ } i4--; if(i4<dx/3 && i4+1+loop(bp,i4+1,i2,dx,cs,1,RI)<3*dx/4) Break;
665
+ if (loop(bp,dx-1,i2,dx,cs,0,LE)>1+dx/8) ad=ad*99/100; // ~1 with a pixel
666
+
667
+ for( x=xa=0,ya=y=dy/4;y<3*dy/4;y++ ){ // right gap, not on LCD-font
668
+ i=loop(bp,dx-1,y,dx,cs,0,LE);
669
+ if (i>=xa) { xa=i;ya=y;x=xa+loop(bp,dx-1-xa,y,dx,cs,1,LE); }
670
+ } if (dy>3*dx) if (xa<2 && x-xa<dx/2) Break; // ~]
671
+ if (xa>1+dx/8 // noLCD
672
+ && xa<=loop(bp,dx-1,i2,dx,cs,0,LE)) ad=ad*99/100; // ~1 with a pixel
673
+ if (xa>1+dx/8 // noLCD
674
+ && xa<=loop(bp,dx-1,i1,dx,cs,0,LE)) ad=ad*99/100; // ~1 with a pixel
675
+
676
+ // upper left gap = (i3,i1)
677
+ // lower left gap = (i4,i2)
678
+ MSG(fprintf(stderr,"left white gaps (%d,%d) (%d,%d)",i3,i1,i4,i2);)
679
+ if( get_bw(i3,i3,i1,i2 ,bp,cs,1) != 1 ) Break; // no hor. middle line?
680
+ if( get_bw(i4,i4,i1,i2 ,bp,cs,1) != 1 ) Break;
681
+ if( get_bw(i3,i3,0 ,i1 ,bp,cs,1) != 1 ) Break; // no upper bow?
682
+ if( get_bw(i4,i4,i2,dy-1,bp,cs,1) != 1 ) Break; // no lower bow?
683
+ // hole is only allowed in beauty fonts
684
+ // if( num_hole( x0, x1, y0, y1,box1->p,cs,NULL) > 0 ) // there is no hole
685
+ // if( num_hole( x0, x0+dx/2, y0, y0+dy/2,box1->p,cs,NULL) == 0 ) // except in some beauty fonts
686
+ if (sdata->holes.num>0)
687
+ if (sdata->holes.hole[0].x1 >= dx/2 || sdata->holes.hole[0].y1 >= dy/2)
688
+ Break;
689
+ Setac(box1,(wchar_t)'3',ad);
690
+ if (ad==100) return '3';
691
+ break;
692
+ }
693
+ // --- test 4 --------------------------------------------------- 25Nov06
694
+ for(ad=d=100;dy>3 && dx>2;){ // min 3x4 ~<gA',
695
+ // rewritten for vectors 0.42
696
+ int ld, i1, i2, i3, i4, i5, i6, i7; // line derivation + corners
697
+ DBG( wchar_t c_ask='4'; )
698
+ if (sdata->holes.num > 1) Break; /* no or one hole */
699
+ /* half distance to the center */
700
+ d=2*sq(128/4); /* 2048 */
701
+ /* now we check for the lower left end, must be far away */
702
+ /* lowest is 144 for 9x10 screen font (Apr2009) */
703
+ if (aa[1][2]<d/16) { /* Apr09: d/8=256 to d/16=128 */
704
+ MSG( fprintf(stderr," low-left-dist= %d < max= %d", aa[1][2], d); )
705
+ Break; /* [2] = distance, ~ABDEF... */
706
+ }
707
+ /* searching for 4 notches between neighbouring ends */
708
+
709
+ /*
710
+ type A B C D
711
+
712
+ 1 5 1 1 1
713
+ O O O O5 O5
714
+ 2OO3 O 5 O O O O <- 7 6
715
+ O 2O3O 2OO3 2OO3O
716
+ 4 4 4 4
717
+
718
+ y4-y3 should be significant (bigger y3-y6)?
719
+ */
720
+
721
+ /* Warning: aa0 can be left upper or left lower point for type B */
722
+ /* get a point on the inner low left side of the J */
723
+ i =box1->num_frame_vectors[0] - 1;
724
+ /* leftmost upper point */
725
+ i1=nearest_frame_vector(box1, 0, i, x0, y0-dy);
726
+ /* lowest from leftmost vector can be very low (20/23) */
727
+ i2=nearest_frame_vector(box1, 0, i, x0-2*dx, (y0+7*y1)/8);
728
+ /* lowest vector */
729
+ i4=nearest_frame_vector(box1, 0, i, (x0+2*x1)/3, y1+dy);
730
+ /* right center crossing point */
731
+ i3=nearest_frame_vector(box1, i2, i4, x1, (3*y0+y1)/4);
732
+ /* get a point on the outer right side below top serif */
733
+ /* next local max_y-point after i4 */
734
+ i5=i4;
735
+ for (i=i4;i!=i2;i=(i+1)%box1->num_frame_vectors[0]) {
736
+ if (box1->frame_vector[ i][1]
737
+ <box1->frame_vector[i5][1]) i5=i; // get next maximum
738
+ if (box1->frame_vector[ i][1]
739
+ >box1->frame_vector[i5][1]+1) break; // break after maximum
740
+ if (box1->frame_vector[ i][0]<x0+dx/4) break; // type A B
741
+ }
742
+ if (box1->num_frames>1) { // type C D
743
+ i = box1->num_frame_vectors[0] - 1; // end outer loop
744
+ j = box1->num_frame_vectors[1] - 1; // end inner loop
745
+ if (box1->num_frames>2) { // see font2.png, 2nd one pixel hole
746
+ j = box1->num_frame_vectors[2] - 1; // end inner loop
747
+ ad=99*ad/100; // little bit unsure
748
+ }
749
+ i6=nearest_frame_vector(box1, i+1, j, x1, y1);
750
+ i7=nearest_frame_vector(box1, i+1, j, x0, y1);
751
+ if (box1->frame_vector[i1][0]
752
+ -box1->frame_vector[i2][0]<dx/4+1) ad=96*ad/100; // ~4x6q
753
+ i =nearest_frame_vector(box1, i+1, j, x0, y0); // top left
754
+ MSG(fprintf(stderr,"triangle type top-left i=%d",i);)
755
+ if (box1->frame_vector[i ][0]-x0<dx/4+1
756
+ && box1->frame_vector[i ][1]-y0<dy/4+1
757
+ && dx>7) ad=97*ad/100; // q
758
+
759
+ } else { // type A B
760
+ i6=nearest_frame_vector(box1, i5, i1, (x0+3*x1)/4, y1-dy/8);
761
+ i7=nearest_frame_vector(box1, i5, i1, x0 , y1-dy/8);
762
+ MSG(fprintf(stderr,"open type");)
763
+ if (box1->frame_vector[i6][1]-y0>3*dy/4
764
+ || box1->frame_vector[i7][1]-y0>3*dy/4) ad=96*ad/100; // ~uU
765
+ }
766
+ // ToDo: output no=(x,y)
767
+ MSG(fprintf(stderr,"i1-7 %d %d %d %d %d %d %d",i1,i2,i3,i4,i5,i6,i7);)
768
+ if (i5==i6) Break; // ~+
769
+
770
+ if (box1->frame_vector[i1][1]>y0+dy/8) Break; // not to low
771
+ if (box1->frame_vector[i2][1]
772
+ -box1->frame_vector[i1][1]<dy/2) Break;
773
+ if (box1->frame_vector[i3][0]
774
+ -box1->frame_vector[i2][0]<dx/4) Break;
775
+ if (abs(box1->frame_vector[i3][1]
776
+ -box1->frame_vector[i2][1])>dy/4) Break;
777
+ if (box1->frame_vector[i2][0]>x0+dx/8) Break;
778
+ if (box1->frame_vector[i2][1]>y1-dy/8) Break;
779
+ if (box1->frame_vector[i4][1]
780
+ -box1->frame_vector[i2][1]<dy/8) Break;
781
+ if (box1->frame_vector[i4][1]
782
+ -box1->frame_vector[i2][1]<dy/6) ad=99*ad/100;
783
+ /* min. distance of the horizontal bar to the ground */
784
+ /* y4-y3 should be significant (bigger y3-y6)? */
785
+ if (box1->frame_vector[i4][1]
786
+ -box1->frame_vector[i3][1]<1+dy/16) Break;
787
+ if ((box1->frame_vector[i4][1]
788
+ -box1->frame_vector[i3][1])*2<=
789
+ (box1->frame_vector[i3][1]
790
+ -box1->frame_vector[i6][1])) Break; // 090728 gas_meter (flat-ulike)
791
+ if ((box1->frame_vector[i4][1]
792
+ -box1->frame_vector[i3][1])<
793
+ (box1->frame_vector[i3][1]
794
+ -box1->frame_vector[i6][1])) ad=99*ad/100;
795
+ if (box1->frame_vector[i4][1]
796
+ -box1->frame_vector[i3][1]<dy/6) ad=99*ad/100; /* tall chars */
797
+ if (box1->frame_vector[i4][1]
798
+ -box1->frame_vector[i3][1]<dy/8) ad=99*ad/100;
799
+ if (box1->frame_vector[i4][1]<y1-1-dy/8) Break;
800
+ if (box1->frame_vector[i3][0]<x0+dx/4) Break;
801
+ if (box1->frame_vector[i3][0]<x0+dx/2) ad=98*ad/100;
802
+ /* on very tall chars the i3 point can be near to the groundline */
803
+ if (box1->frame_vector[i3][1]>y1-1) Break;
804
+ if (box1->frame_vector[i3][1]>y1-dy/16) Break;
805
+ if (box1->frame_vector[i3][1]>=y1) Break; // ~5x5#
806
+ if (box1->frame_vector[i5][0]<x0+dx/3) Break;
807
+ /* upper end of right vertical line */
808
+ if (box1->frame_vector[i5][1]>y0+2*dy/3) Break;
809
+ if (box1->frame_vector[i6][1]
810
+ -box1->frame_vector[i5][1]<1+dy/16) Break;
811
+ if (box1->frame_vector[i6][0]<x0+dx/3) Break;
812
+ if (box1->frame_vector[i7][0]>x0+dx/2) Break;
813
+ if (box1->frame_vector[i7][0]>x0+dx/3) ad=ad*99/100;
814
+ if (box1->frame_vector[i6][1]<y0+dy/3) Break;
815
+ if (box1->frame_vector[i6][0]<x0+dx/2) ad=96*ad/100; // ~ 42
816
+ if (box1->frame_vector[i6][0]<aa[2][0]-dx/2
817
+ && aa[2][1]>=y1-1-dy/8) ad=96*ad/100; // ~ 42
818
+ if (box1->frame_vector[i7][1]<y0+dy/3) Break;
819
+ if (abs(box1->frame_vector[i3][1]
820
+ -box1->frame_vector[i2][1])>dy/4) Break;
821
+
822
+ /* check if upper left and lower left points are joined directly */
823
+ ld=line_deviation(box1, i1, i2);
824
+ MSG(fprintf(stderr," i1-i2 %d %d dist= %d/%d",i1,i2,ld,2*sq(1024/4));)
825
+ if (ld >2*sq(1024/4)) Break;
826
+ /* check if lower right and upper right points are joined directly */
827
+ ld=line_deviation(box1, i2, i3);
828
+ MSG(fprintf(stderr," i2-i3 %d %d dist= %d/%d",i2,i3,ld,2*sq(1024/4));)
829
+ if (ld > sq(1024/4)) Break;
830
+ /* check if lower right and upper right points are joined directly */
831
+ ld=line_deviation(box1, i3, i4);
832
+ MSG(fprintf(stderr," i3-i4 %d %d dist= %d/%d",i3,i4,ld,2*sq(1024/4));)
833
+ if (ld > sq(1024/4)) Break;
834
+ /* check if lower right and upper right points are joined directly */
835
+ ld=line_deviation(box1, i6, i7);
836
+ MSG(fprintf(stderr," i6-i7 %d %d dist= %d/%d",i6,i7,ld,2*sq(1024/4));)
837
+ if (ld >2*sq(1024/4)) Break;
838
+
839
+ // 4 exists as gchar and ~gchar
840
+ if(!hchar){ ad=99*ad/100; }
841
+ Setac(box1,'4',ad);
842
+ break;
843
+ }
844
+ #ifdef Old_pixel_based
845
+ // --- old test 4 pixelbased ------- remove!
846
+ for(ad=d=100;dx>3 && dy>5;){ // dy>dx, min 4x6 font
847
+ DBG( char c_ask='4'; )
848
+ if (sdata->holes.num > 2) Break; /* be tolerant */
849
+ if (sdata->holes.num > 1) ad=97*ad/100;
850
+ // upper raising or vertical line
851
+ if( loop(bp,0 ,3*dy/16,dx,cs,0,RI)
852
+ < loop(bp,0 ,2*dy/4 ,dx,cs,0,RI)-dx/8 ) Break;
853
+ // search for a vertical line on lower end
854
+ for (y=0;y<dy/4;y++)
855
+ if( loop(bp,0 ,dy-1-y,dx,cs,0,RI)
856
+ + loop(bp,dx-1,dy-1-y,dx,cs,0,LE) >= dx/2 ) break;
857
+ if (y>=dy/4) Break;
858
+ if( loop(bp,0 ,dy-1-dy/8,dx,cs,0,RI) < dx/4 ) Break;
859
+ // --- follow line from (1,0) to (0,.7)
860
+ y=0; x=loop(bp,0,0,dx,cs,0,RI);
861
+ if (x<=dx/4) { // ocr-a-4
862
+ i=loop(bp,0,dy/4,dx,cs,0,RI); if (i>dx/4) Break;
863
+ i=loop(bp,i,dy/4,dx,cs,1,RI); if (i>dx/2) Break;
864
+ j=loop(bp,i,dy/4,dy,cs,0,DO)+dy/4; if (j>7*dy/8) Break;
865
+ }
866
+ turmite(bp,&x,&y,0,dx-1,0,dy-1,cs,DO,LE); if( x>=0 ) Break;
867
+
868
+ y=loop(bp,0,0,dy,cs,0,DO);
869
+ if( (y+loop(bp,0,y,dy,cs,1,DO)) < dy/2 ) Break;
870
+ if( get_bw(x0 , x0+3*dx/8, y1-dy/7, y1-dy/7,box1->p,cs,1) == 1 ) Break;
871
+ if( get_bw(x0+dx/2, x1 , y1-dy/3, y1-dy/3,box1->p,cs,1) != 1 ) Break;
872
+ if( get_bw(x0+dx/2, x0+dx/2, y0+dy/3, y1-dy/5,box1->p,cs,1) != 1 ) Break;
873
+ i=loop(bp,bp->x-1, bp->y/4,dx,cs,0,LE);
874
+ if( i > loop(bp,bp->x-1,2*bp->y/4,dx,cs,0,LE)+1
875
+ && i > loop(bp,bp->x-1,3*bp->y/8,dx,cs,0,LE)+1 ) Break;
876
+ if (loop(bp,0,0,dx,cs,0,RI)>dx/4) {
877
+ for(i=dx/8+1,x=0;x<dx && i;x++){
878
+ if( num_cross(x ,x ,0 ,dy-1, bp,cs) == 2 ) i--;
879
+ } if( i ) Break;
880
+ }
881
+ for(i=dy/6+1,y=dy/4;y<dy && i;y++){
882
+ if( num_cross(0 ,dx-1,y ,y , bp,cs) == 2 ) i--;
883
+ } if( dy>15 && i ) Break;
884
+ for(i=dy/10+1,y=dy-1-dy/4;y<dy && i;y++){
885
+ if( num_cross(0 ,dx-1,y ,y , bp,cs) == 1 )
886
+ if( num_cross(dx/2,dx-1,y ,y , bp,cs) == 1 ) i--;
887
+ } if( i ) Break;
888
+ // i4 = num_hole ( x0, x1, y0, y1,box1->p,cs,NULL);
889
+ // ToDo:
890
+ // - get start and endpoint of left edge of left vert. line
891
+ // and check if that is an streight line
892
+ // - check the right edge of the inner hole (if there) too
893
+ i4 = sdata->holes.num;
894
+ if (sdata->holes.num >0) { // ~q
895
+ i = loop(bp,0,dy/16,dx,cs,0,RI);
896
+ if (i < dx/3) Break;
897
+ if (i < dx/2) ad=98*ad/100; // hole?
898
+ if ( loop(bp, 0,dy-1,dy,cs,0,UP)
899
+ -loop(bp,dx/8+1,dy-1,dy,cs,0,UP)>dy/16) ad=97*ad/100;
900
+ }
901
+ // thickness of left vertical line
902
+ for (j=y=0;y<dy/6;y++) {
903
+ i=loop(bp,dx-1 ,y,dx,cs,0,LE);
904
+ i=loop(bp,dx-1-i,y,dx,cs,1,LE); if (i>j) j=i;
905
+ }
906
+ if (j>=dx/2) ad=98*ad/100; // ~q handwritten a (or very thinn 4)
907
+ // ToDo: check y of masscenter of the hole q4
908
+
909
+ if( i4 ) if( dx > 15 )
910
+ if( loop(bp, dx/2, 0,dy,cs,0,DO)<dy/16
911
+ && loop(bp, dx/4, 0,dy,cs,0,DO)<dy/8
912
+ && loop(bp,3*dx/4, 0,dy,cs,0,DO)<dy/8
913
+ && loop(bp, dx/4,dy-1,dy,cs,0,UP)<dy/8
914
+ && loop(bp, dx/2,dy-1,dy,cs,0,UP)<dy/8
915
+ && loop(bp,3*dx/4,dy-1,dy,cs,0,UP)<dy/4 ) Break; // ~9
916
+
917
+ i =loop(bp,dx-1 ,dy-1,dx,cs,0,LE); // ~9
918
+ i+=loop(bp,dx-1-i,dy-1,dx,cs,1,LE);
919
+ if( i>3*dx/4
920
+ && i-loop(bp,dx-1,dy-1-dy/8,dx,cs,0,LE)>dx/4 ) Break;
921
+
922
+ i =loop(bp,dx-1-dx/4,dy-1,dx,cs,0,UP);
923
+ if (i> dy/2) ad=97*ad/100;
924
+ if (i>3*dy/4) ad=97*ad/100; /* handwritten n */
925
+
926
+ if( num_cross(0 ,dx-1,dy/16 ,dy/16 , bp,cs) == 2 // ~9
927
+ && loop(bp,dx-1,dy/16 ,dx,cs,0,LE)>
928
+ loop(bp,dx-1,dy/16+1+dy/32,dx,cs,0,LE) ) Break;
929
+ if ( !hchar) ad=99*ad/100;
930
+ if (gchar && !hchar) ad=98*ad/100; // ~q
931
+ Setac(box1,(wchar_t)'4',ad);
932
+ if (ad>99) bc='4';
933
+ break;
934
+ }
935
+ #endif
936
+ // --- test 6 ------- ocr-a-6 looks like a b :(
937
+ for(ad=d=100;dx>3 && dy>4;){ // dy>dx
938
+ DBG( char c_ask='6'; )
939
+ if (sdata->holes.num > 2) Break; /* be tolerant */
940
+ if( loop(bp, 0, dy/4,dx,cs,0,RI)>dx/2 // ocr-a=6
941
+ && loop(bp,dx-1, 0,dy,cs,0,DO)>dy/4 ) Break; // italic-6
942
+ if( loop(bp, 0, dy/2,dx,cs,0,RI)>dx/4 ) Break;
943
+ if( loop(bp, 0,3*dy/4,dx,cs,0,RI)>dx/4 ) Break;
944
+ if( loop(bp,dx-1,3*dy/4,dx,cs,0,LE)>dx/2 ) Break;
945
+ if( num_cross(x0+ dx/2,x0+ dx/2,y0 ,y1 ,box1->p,cs) != 3
946
+ && num_cross(x0+5*dx/8,x0+5*dx/8,y0 ,y1 ,box1->p,cs) != 3 ) {
947
+ if( num_cross(x0+ dx/2,x0+ dx/2,y0+dy/4,y1 ,box1->p,cs) != 2
948
+ && num_cross(x0+5*dx/8,x0+5*dx/8,y0+dy/4,y1 ,box1->p,cs) != 2 ) Break;
949
+ // here we have the problem to decide between ocr-a-6 and b
950
+ if ( loop(box1->p,(x0+x1)/2,y0,dy,cs,0,DO)<dy/2 ) Break;
951
+ ad=99*ad/100;
952
+ } else {
953
+ if (loop(box1->p,x0+dx/2,y0,dx,cs,0,DO)>dy/8
954
+ && loop(box1->p,x1-dx/4,y0,dx,cs,0,DO)>dy/8 ) Break;
955
+ }
956
+ if( num_cross(x0 ,x1 ,y1-dy/4,y1-dy/4,box1->p,cs) != 2 ) Break;
957
+ for( y=y0+dy/6;y<y0+dy/2;y++ ){
958
+ x =loop(box1->p,x1 ,y ,dx,cs,0,LE); if( x>dx/2 ) break;
959
+ x+=loop(box1->p,x1-x+1,y-1,dx,cs,0,LE); if( x>dx/2 ) break;
960
+ } if( y>=y0+dy/2 ) Break;
961
+ if (loop(box1->p,x0,y1-dy/3,dx,cs,0,RI)>dx/4 ) Break;
962
+ if (loop(box1->p,x1,y1-dy/3,dx,cs,0,LE)>dx/4 ) Break;
963
+
964
+ if (sdata->holes.num != 1) Break;
965
+ if (sdata->holes.hole[0].y1 < dy/2) ad=95*ad/100; // whats good for?
966
+ if (sdata->holes.hole[0].y0 < dy/4) Break;
967
+ MSG( fprintf(stderr,"hole[0].x0,x1 %d %d", sdata->holes.hole[0].x0,
968
+ sdata->holes.hole[0].x1); )
969
+ if (sdata->holes.hole[0].x0<1
970
+ && dx-1-sdata->holes.hole[0].x1>2) ad=ad*99/100; // melted serif sS ?
971
+ if (loop(box1->p,x0,y0+dy/2,dx,cs,0,RI)>0
972
+ && loop(box1->p,x0,y0+dy/4,dx,cs,0,RI)==0
973
+ && loop(box1->p,x0,y1-dy/4,dx,cs,0,RI)==0) ad=97*ad/100; // molten serif sS
974
+ // if( num_hole ( x0, x1, y0, y0+dy/2,box1->p,cs,NULL) > 0 ) ad=95*ad/100;
975
+ // if( num_hole ( x0, x1, y0+dy/4, y1,box1->p,cs,NULL) != 1 ) Break;
976
+ // if( num_hole ( x0, x1, y0 , y1,box1->p,cs,NULL) != 1 ) Break;
977
+ // out_x(box1); printf(" x0 y0 %d %d\n",x0,y0);
978
+ /* check left vertical bow */
979
+ i1=loop(bp,0,dy/8 ,dx,cs,0,RI);
980
+ i3=loop(bp,0,dy-1-dy/8,dx,cs,0,RI);
981
+ i2=loop(bp,0,dy/2 ,dx,cs,0,RI);
982
+ if(i1+i3-2*i2<-2-dx/16 && i1+i2+i3>0) Break; // convex from left
983
+ if(i1+i3-2*i2<1 && i1+i2+i3>0) ad=99*ad/100; // 7-segment-font
984
+ for( x=dx,y=0;y<dy/4;y++ ){ // ~ b (serife?)
985
+ i1=loop(bp, 0,y,dx,cs,0,RI);
986
+ i2=loop(bp,i1,y,dx,cs,1,RI);
987
+ if (i2+i1>dx/2 && i2>dx/4) break; /* its a 6 (example: 7-segment) */
988
+ if (i1<x) x=i1; else if (i1>x) break; /* may be serifen b */
989
+ } if (y<dy/4 && i1+i2<=dx/2) Break;
990
+ // ~& (with open upper loop)
991
+ for( i=0,y=dy/2;y<dy;y++){
992
+ if( num_cross(dx/2,dx-1,y,y,bp,cs) > 1 ) i++; if( i>dy/8 ) break;
993
+ } if( y<dy ) Break;
994
+ if ( gchar) ad=99*ad/100;
995
+ if (!hchar) ad=98*ad/100;
996
+ if ( box1->dots ) ad=98*ad/100;
997
+ Setac(box1,(wchar_t)'6',ad);
998
+ bc='6';
999
+ break;
1000
+ }
1001
+ // --- test 7 ---------------------------------------------------
1002
+ for(ad=d=100;dx>2 && dy>4;){ // dx>1 dy>2*dx
1003
+ DBG( char c_ask='7'; )
1004
+ if (sdata->holes.num > 1) Break; /* be tolerant */
1005
+ if( loop(bp,dx/2,0,dy,cs,0,DO)>dy/8 ) Break;
1006
+ if( num_cross(0,dx-1,3*dy/4,3*dy/4,bp,cs) != 1 ) Break; // preselect
1007
+ for( yb=xb=y=0;y<dy/2;y++){ // upper h-line and gap
1008
+ j=loop(bp,0,y,dx,cs,0,RI);if(xb>0 && j>dx/4) break; // gap after h-line
1009
+ j=loop(bp,j,y,dx,cs,1,RI);if(j>xb){ xb=j;yb=y; } // h-line
1010
+ } if( xb<dx/4 || y==dy/2 ) Break;
1011
+ j=loop(bp,0,dy/2,dx,cs,0,RI);
1012
+ j=loop(bp,j,dy/2,dx,cs,1,RI); if(xb<2*j) Break; // minimum thickness
1013
+ for(x=0,y+=dy/16;y<dy;y++){ // one v-line?
1014
+ if( num_cross(0,dx-1,y,y,bp,cs) != 1 ) break;
1015
+ j=loop(bp,dx-1,y,dx,cs,0,LE); if( j<x ) break; if( j-1>x ) x=j-1;
1016
+ } if( y<dy || x<dx/3 ) {
1017
+ MSG( fprintf(stderr,"xy= %d %d",x,y); )
1018
+ Break;
1019
+ }
1020
+ j =loop(bp,dx-1,0,dy,cs,0,DO); // ~T
1021
+ j+=loop(bp,dx-1,j,dy,cs,1,DO)+dy/16;
1022
+ i =loop(bp,dx-1,j,dx,cs,0,LE); if(j<dy/2) {
1023
+ if (i>j) Break;
1024
+ j=loop(bp, 0,j,dx,cs,0,RI);
1025
+ if(j>dx/4 && j<=i+dx/16) Break; // tall T
1026
+ }
1027
+
1028
+ MSG( fprintf(stderr,"7: ad= %d",ad); )
1029
+ if( loop(bp, 0,3*dy/8,dx,cs,0,RI)
1030
+ <=loop(bp,dx-1,3*dy/8,dx,cs,0,LE)+dx/8 ) ad=ad*98/100; // l
1031
+ MSG( fprintf(stderr,"7: ad= %d",ad); )
1032
+ if( num_cross(0,dx-1,dy/4,dy/4,bp,cs) == 1
1033
+ && loop(bp,0,dy/4,dx,cs,0,RI) < dx/2 ) ad=ad*96/100; // J
1034
+ MSG( fprintf(stderr,"7: ad= %d",ad); )
1035
+
1036
+ if (box1->m3 && dy<box1->m3-box1->m2) ad=99*ad/100; // too small
1037
+ if (box1->m3 && 2*dy<box1->m3-box1->m2) ad=96*ad/100; // too small
1038
+ if (dy>3*dx) ad=99*ad/100; // )
1039
+ if ( gchar) ad=99*ad/100; // J
1040
+ if (!hchar) ad=99*ad/100;
1041
+ Setac(box1,(wchar_t)'7',ad);
1042
+ break;
1043
+ }
1044
+ // --- test 8 ---------------------------------------------------
1045
+ // last change: May15th,2000 JS
1046
+ for(ad=d=100;dx>2 && dy>4;){ // or we need large height
1047
+ DBG( char c_ask='8'; )
1048
+ if (sdata->holes.num != 2) Break;
1049
+ if( num_cross(x0,x1,y0 +dy/4,y0 +dy/4,box1->p,cs) != 2 ) Break; // ~gr (glued)
1050
+ if( num_cross(x0,x1,y1 -dy/4,y1 -dy/4,box1->p,cs) != 2
1051
+ && num_cross(x0,x1,y1-3*dy/8,y1-3*dy/8,box1->p,cs) != 2 ) Break;
1052
+ if( get_bw(x0,x0+dx/4,y1-dy/4,y1-dy/4,box1->p,cs,1) == 0 ) Break; // ~9
1053
+ if( get_bw(x0,x0+dx/2,y0+dy/4,y0+dy/4,box1->p,cs,1) == 0 ) Break;
1054
+ if( get_bw(x0+dx/2,x0+dx/2,y0+dy/4,y1-dy/4,box1->p,cs,1) == 0 ) Break; // ~0
1055
+ // MSG( printf(" x0 y0 %d %d\n",x0,y0); )
1056
+ for( i2=i1=x=0,i=y=y0+dy/3;y<=y1-dy/3;y++){ // check left middle nick
1057
+ j=loop(box1->p,x0,y,dx,cs,0,RI);
1058
+ if (j>x || (abs(j-x)<=dx/8 /* care about MICR E-13B font */
1059
+ && (i1=loop(box1->p,x0+j,y,dx,cs,1,RI))>dx/2)) {
1060
+ if (j>x) x=j; i=y; if (i1>i2) i2=i1; }
1061
+ } if(i>=y1-dy/3 || (x<dx/8 && i2<=dx/2) || x>dx/2) Break; // no gB
1062
+ if (x< dx/4) ad=99*ad/100; // no B
1063
+ if (x<=dx/8) ad=98*ad/100; // no B
1064
+ j = loop(box1->p,x1,y1- dy/4,dx,cs,0,LE);
1065
+ if( j>loop(box1->p,x1,y1- dy/5,dx,cs,0,LE)
1066
+ && j>loop(box1->p,x1,y1-2*dy/5,dx,cs,0,LE) ) Break; // &
1067
+ // check for upper hole
1068
+ for (j=0;j<sdata->holes.num;j++) {
1069
+ if (sdata->holes.hole[j].y1 < i-y0+1 ) break;
1070
+ if (sdata->holes.hole[j].y1 < i-y0+dy/8) break;
1071
+ } if (j==sdata->holes.num) Break; // not found
1072
+ // if( num_hole(x0,x1,y0,i+1 ,box1->p,cs,NULL)!=1 )
1073
+ // if( num_hole(x0,x1,y0,i+dy/8,box1->p,cs,NULL)!=1 ) Break; // upper hole
1074
+ // check for lower hole
1075
+ for (j=0;j<sdata->holes.num;j++) {
1076
+ if (sdata->holes.hole[j].y0 > i-y0-1 ) break;
1077
+ } if (j==sdata->holes.num) Break; // not found
1078
+ // if( num_hole(x0,x1,i-1,y1,box1->p,cs,NULL)!=1 ) Break;
1079
+ i1=i; // left middle nick
1080
+ /* find the middle right nick */
1081
+ for( x=0,i2=i=y=y0+dy/3;y<=y1-dy/3;y++){
1082
+ j=loop(box1->p,x1,y,dx,cs,0,LE); if( j>=x ) i2=y;
1083
+ /* we care also for 7-segment and unusual fonts */
1084
+ if (j>x || (abs(j-x)<=(dx+4)/8
1085
+ && loop(box1->p,x1-j,y,dx,cs,1,LE)>dx/2)){
1086
+ if (j>x) x=j; i=y; }
1087
+ // MSG(fprintf(stderr," yjix %d %d %d %d %d %d",y-y0,j,i-y0,x,loop(box1->p,x1-j,y,dx,cs,1,LE),dx/2);)
1088
+ }
1089
+ if( i>y0+dy/2+dy/10 ) Break;
1090
+ // if( x<dx/8 ) Break;
1091
+ if( x>dx/2 ) Break;
1092
+ MSG(fprintf(stderr,"center bar at y= %d %d x=%d+%d i1=%d",i-y0,i2-y0,x,j,i1);)
1093
+ if( num_cross(x0,x1, i , i ,box1->p,cs) != 1
1094
+ && num_cross(x0,x1, i+1 , i+1 ,box1->p,cs) != 1
1095
+ && num_cross(x0,x1,(i+i2)/2,(i+i2)/2,box1->p,cs) != 1 ) Break; // no g
1096
+ if(abs(i1-i)>(dy+5)/10) ad=99*ad/100; // y-distance right-left-nick
1097
+ if(abs(i1-i)>(dy+4)/8) ad=99*ad/100; // y-distance right-left-nick
1098
+ if(abs(i1-i)>(dy+2)/4) Break;
1099
+ // ~B ff
1100
+ for(i=dx,y=0;y<dy/8+2;y++){
1101
+ j=loop(bp,0,y,dx,cs,0,RI); if( j<i ) i=j; if( j>i+dx/16 ) break;
1102
+ } if( y<dy/8+2 ) Break;
1103
+ for(i=dx,y=0;y<dy/8+2;y++){
1104
+ j=loop(bp,0,dy-1-y,dx,cs,0,RI);
1105
+ if( j<i ) i=j; if( j>i+dx/16 ) break;
1106
+ } if( y<dy/8+2 ) Break;
1107
+ if( dy>16 && num_cross(0,dx-1,dy-1,dy-1,bp,cs) > 1
1108
+ && loop(bp,0,dy-1,dx,cs,0,RI) <dx/8+1 ) Break; // no fat serif S
1109
+ for( i=0,y=dy/2;y<dy;y++){
1110
+ if( num_cross(0,dx-1,y,y,bp,cs) > 2 ) i++; if( i>dy/8 ) break;
1111
+ } if( y<dy ) Break;
1112
+ if ( loop(bp,dx-1,0,dx,cs,0,LE)==0 ) ad=99*ad/100;
1113
+ if (num_cross( 0,dx-1,dy-1,dy-1,bp,cs) > 1) ad=98*ad/100; // &
1114
+ if (num_cross(dx-1,dx-1,dy/2,dy-1,bp,cs) > 1) ad=98*ad/100; // &
1115
+ if (num_cross( 0,dx-1, 0, 0,bp,cs) > 1) ad=98*ad/100;
1116
+ if (dy>15)
1117
+ if (num_cross( 0,dx-1, 1, 1,bp,cs) > 1) ad=98*ad/100;
1118
+ /* if m1..4 is unsure ignore hchar and gchar ~ga */
1119
+ if (!hchar) {
1120
+ if ((box1->m2-box1->y0)*8>=dy) ad=98*ad/100;
1121
+ else ad=99*ad/100;
1122
+ }
1123
+ if ( gchar
1124
+ && (box1->y1-box1->m3)*8>=dy) ad=99*ad/100;
1125
+ Setac(box1,(wchar_t)'8',ad);
1126
+ break;
1127
+ }
1128
+ // --- test 9 \it g ---------------------------------------------------
1129
+ /*
1130
+ *
1131
+ * lcd micr round
1132
+ * ooo ooo ooo
1133
+ * o o o o o o
1134
+ * ooo ooo ooo
1135
+ * o o o
1136
+ * ooo o o
1137
+ */
1138
+ for(ad=d=100;dx>2 && dy>4;){ // dx>1 dy>2*dx
1139
+ DBG( char c_ask='9'; )
1140
+ if (sdata->holes.num > 1) Break;
1141
+ if( num_cross(x0+ dx/2,x0+ dx/2,y0,y1-dy/4,box1->p,cs) != 2 // pre select
1142
+ && num_cross(x0+ dx/2,x0+ dx/2,y0, y1,box1->p,cs) != 3 // pre select
1143
+ && num_cross(x0+3*dx/8,x0+3*dx/8,y0,y1,box1->p,cs) != 3
1144
+ && num_cross(x0+ dx/4,x1 -dx/4,y0,y1,box1->p,cs) != 3 ) Break;
1145
+ if( num_cross(x0+ dx/2,x0 +dx/2,y0,y0+dy/4,box1->p,cs) < 1 ) Break;
1146
+ if( num_cross(x0+ dx/2,x1, y0+dy/2 ,y0+dy/2,box1->p,cs) < 1 ) Break;
1147
+ if( num_cross(x0,x1, y0+ dy/4 ,y0+ dy/4,box1->p,cs) != 2
1148
+ && num_cross(x0,x1, y0+3*dy/8 ,y0+3*dy/8,box1->p,cs) != 2 ) Break;
1149
+ if( num_cross(x1-dx/8,x1,y0+dy/4,y0+dy/4,box1->p,cs) == 0) ad=ad*97/100; // ~4
1150
+ for( x=0,i=y=y0+dy/2;y<=y1-dy/4;y++){ // find notch (suche kerbe)
1151
+ j=loop(box1->p,x0,y,dx,cs,0,RI);
1152
+ if( j>x ) { x=j; i=y; }
1153
+ } if (x<1 || x<dx/8) Break; y=i;
1154
+ // fprintf(stderr," debug 9: %d %d\n",x,i-y0);
1155
+ if( x<dx/2 ) { /* big bow? */
1156
+ j=loop(box1->p,x0+x-1,y,dy/8+1,cs,0,DO)/2; y=i=y+j;
1157
+ j=loop(box1->p,x0+x-1,y,dx/2 ,cs,0,RI); x+=j;
1158
+ if (x<dx/2) Break;
1159
+ }
1160
+ // check for the right lower bow
1161
+ MSG( fprintf(stderr,"bow-y0= %d",i-y0); )
1162
+ if (dx>5)
1163
+ if( num_cross(x0+dx/2,x1,i,y1 ,box1->p,cs) != 1 /* fails on 5x8 */
1164
+ && num_cross(x0+dx/2,x1,i,y1-dy/8,box1->p,cs) != 1 ) Break;
1165
+ if( num_cross(x0+dx/2,x0+dx/2,i,y1,box1->p,cs) > 1 ) Break;
1166
+ if( num_cross(x0+dx/2,x1 ,i, i,box1->p,cs) != 1 ) Break;
1167
+
1168
+ if (sdata->holes.num < 1) { /* happens for 5x7 font */
1169
+ if (dx<8) ad=98*ad/100; else Break; }
1170
+ else {
1171
+ if (sdata->holes.hole[0].y1 >= i+1) Break;
1172
+ if (sdata->holes.hole[0].y0 > i-1) Break;
1173
+ if (sdata->holes.num > 1)
1174
+ if (sdata->holes.hole[1].y0 > i-1) Break;
1175
+ // if( num_hole(x0,x1,y0,i+1,box1->p,cs,NULL)!=1 ) Break;
1176
+ // if( num_hole(x0,x1,i-1,y1,box1->p,cs,NULL)!=0 ) Break;
1177
+ }
1178
+ if( loop(box1->p,x0,y1 ,dy,cs,0,RI)>dx/3 &&
1179
+ loop(box1->p,x0,y1-1,dy,cs,0,RI)>dx/3
1180
+ && (box1->m3==0 || (box1->m3!=0 && (!hchar || gchar)))) ad=98*ad/100; // no q OR ocr-a-9
1181
+ for( x=0,i=y=y0+dy/3;y<=y1-dy/3;y++){ // suche kerbe
1182
+ j=loop(box1->p,x1,y,dx,cs,0,LE);
1183
+ if( j>x ) { x=j; i=y; }
1184
+ } if( x>dx/2 ) Break; // no g
1185
+ i1=loop(bp,dx-1,dy/8 ,dx,cs,0,LE); if(i1>dx/2) Break;
1186
+ i3=loop(bp,dx-1,dy-1-dy/8,dx,cs,0,LE);
1187
+ i2=loop(bp,dx-1,dy/2 ,dx,cs,0,LE); if(i1+i3-2*i2<-1-dx/16) Break; // konvex
1188
+ i1=loop(bp,dx-1,dy/4 ,dx,cs,0,LE); if(i1>dx/2) Break;
1189
+ i3=loop(bp,dx-1,dy-1-dy/8,dx,cs,0,LE);
1190
+ for(y=dy/4;y<dy-1-dy/4;y++){ // may fail on type=round
1191
+ i2=loop(bp,dx-1,y,dx,cs,0,LE);
1192
+ // konvex from right ~g ~3 Jul09
1193
+ if(i2>i1+(i3-i1)*(2*y-dy/2)/dy+dx/16) break;
1194
+ // MSG(fprintf(stderr," y i2 %d %d %d",y,i2,i1+(i3-i1)*(2*y-dy/2)/dy);)
1195
+ } if(y<dy-1-dy/4) Break;
1196
+ x=loop(bp,dx -1,6*dy/8,dx,cs,0,LE); if(x>0){
1197
+ x--; // robust
1198
+ y=loop(bp,dx-x-1, dy-1,dy,cs,0,UP);
1199
+ if(y<dy/8) Break; // ~q (serif!)
1200
+ }
1201
+ // check for agglutinated serif y
1202
+ if (dy>=16 && dx>9
1203
+ && loop(bp, 0,dy/ 4,dx,cs,0,RI)
1204
+ -loop(bp, 0,dy/16,dx,cs,0,RI)>dx/6
1205
+ && loop(bp,dx-1,dy/ 4,dx,cs,0,LE)
1206
+ -loop(bp,dx-1,dy/16,dx,cs,0,LE)>dx/6) Break; // ~ serif yY
1207
+
1208
+ if (box1->m3) {
1209
+ if ( gchar) ad=99*ad/100; /* unsure (italic g)? */
1210
+ if (box1->m2 && (!gchar) && y1 > box1->m3){
1211
+ ad=99*ad/100;
1212
+ if (box1->m4-box1->m3<3) ad=99*ad/100;
1213
+ // if (!hchar) ad = 99*ad/100;
1214
+ }
1215
+ if (!hchar) ad=99*ad/100; /* unsure */
1216
+ } else { if (ad==100) ad=99; } /* not 100% sure */
1217
+ Setac(box1,(wchar_t)'9',ad);
1218
+ break;
1219
+ }
1220
+ // 0 is same as O !?
1221
+ // --- test 0 (with one big hole in it ) -----------------------------
1222
+ for(d=ad=100;dx>2 && dy>3;){ // min 3x4
1223
+ DBG( char c_ask='0'; )
1224
+ if (sdata->holes.num > 1) Break; /* be tolerant */
1225
+ if( get_bw(x0 , x0+dx/3,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1226
+ if( get_bw(x1-dx/3 , x1 ,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1227
+ /* could be an O, unless we find a dot in the center */
1228
+ if( get_bw(x0 , x1 ,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 3 ) ad=99;
1229
+ if( get_bw(x0+dx/2 , x0+dx/2,y1-dy/3 , y1,box1->p,cs,1) != 1 ) Break;
1230
+ if( get_bw(x0+dx/2 , x0+dx/2,y0 , y0+dy/3,box1->p,cs,1) != 1 ) Break;
1231
+ /* accept 0 with dot in center, accept \/0 too ... */
1232
+ if( get_bw(x0+dx/2 , x0+dx/2,y0+dy/3 , y1-dy/3,box1->p,cs,1) != 0 ) Break;
1233
+
1234
+ if( num_cross(x0+dx/2,x0+dx/2,y0 , y1 ,box1->p,cs) != 2 ) Break;
1235
+ if( num_cross(x0+dx/3,x1-dx/3,y0 , y0 ,box1->p,cs) != 1 ) // AND
1236
+ if( num_cross(x0+dx/3,x1-dx/3,y0+1 , y0+1 ,box1->p,cs) != 1 ) Break;
1237
+ if( num_cross(x0+dx/3,x1-dx/3,y1 , y1 ,box1->p,cs) != 1 ) // against "rauschen"
1238
+ if( num_cross(x0+dx/3,x1-dx/3,y1-1 , y1-1 ,box1->p,cs) != 1 ) Break;
1239
+ if( num_cross(x0 ,x0 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1240
+ if( num_cross(x0+1 ,x0+1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1241
+ if( num_cross(x1 ,x1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1242
+ if( num_cross(x1-1 ,x1-1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1243
+ // if( num_hole(x0,x1,y0,y1,box1->p,cs,NULL) != 1 ) Break;
1244
+ if (sdata->holes.num != 1) Break;
1245
+
1246
+ i= loop(bp,0 ,0 ,x1-x0,cs,0,RI)-
1247
+ loop(bp,0 ,2 ,x1-x0,cs,0,RI);
1248
+ if (i<0) Break;
1249
+ if (i==0) {
1250
+ if (loop(bp,dx-1,0 ,x1-x0,cs,0,LE)>
1251
+ loop(bp,dx-1,2 ,x1-x0,cs,0,LE) ) ad=98*ad/100;
1252
+ ad=99*ad/100; /* LCD-type? */
1253
+ }
1254
+
1255
+ x=loop(bp,dx-1,dy-1-dy/3,x1-x0,cs,0,LE); // should be minimum
1256
+ for (y=dy-1-dy/3;y<dy;y++){
1257
+ i=loop(bp,dx-1,y,x1-x0,cs,0,LE);
1258
+ if (i<x-dx/16-1) break; if (i>x) x=i;
1259
+ }
1260
+ if( y<dy ) Break;
1261
+
1262
+ // ~D (but ocr-a-font)
1263
+ i= loop(bp, 0, dy/16,dx,cs,0,RI)
1264
+ + loop(bp, 0,dy-1-dy/16,dx,cs,0,RI)
1265
+ - 2*loop(bp, 0, dy/2 ,dx,cs,0,RI);
1266
+ j= loop(bp,dx-1, dy/16,dx,cs,0,LE)
1267
+ + loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)
1268
+ <= 2*loop(bp,dx-1, dy/2 ,dx,cs,0,LE);
1269
+ if (i<-dx/8 || i+dx/8<j) Break; // not konvex
1270
+
1271
+ if( loop(bp,dx-1, dy/16,dx,cs,0,LE)>dx/8 )
1272
+ if( loop(bp,0 , dy/16,dx,cs,0,RI)<dx/16 ) Break;
1273
+ if( loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)>dx/8 )
1274
+ if( loop(bp,0 ,dy-1-dy/16,dx,cs,0,RI)<dx/16 ) Break;
1275
+ if( get_bw(x1-dx/32,x1,y0,y0+dy/32,box1->p,cs,1) == 0
1276
+ && get_bw(x1-dx/32,x1,y1-dy/32,y1,box1->p,cs,1) == 0
1277
+ && ( get_bw(x0,x0+dx/32,y0,y0+dy/32,box1->p,cs,1) == 1
1278
+ || get_bw(x0,x0+dx/32,y1-dy/32,y1,box1->p,cs,1) == 1 ) ) {
1279
+ if (dx<32) ad=ad*99/100; else Break; // ~D
1280
+ }
1281
+
1282
+ // search lowest inner white point
1283
+ for(y=dy,j=x=0;x<dx;x++) {
1284
+ i =loop(bp,x,dy-1 ,y1-y0,cs,0,UP);
1285
+ i+=loop(bp,x,dy-1-i,y1-y0,cs,1,UP);
1286
+ if (i<=y) { y=i; j=x; }
1287
+ } i=y;
1288
+ // italic a
1289
+ for(y=dy-1-i;y<dy-1;y++)
1290
+ if( num_cross(j,dx-1,y,y,bp,cs) > 1 ) ad=99*ad/100; // ~a \it a
1291
+
1292
+ if (loop(bp, 0, 0,x1-x0,cs,0,RI)>=dx/8) { // round, notLCD
1293
+ if (loop(bp,dx-1,dy-1,x1-x0,cs,0,LE)<dx/8) ad=98*ad/100; // \it a
1294
+ if (loop(bp,dx-1, 0,x1-x0,cs,0,LE)<dx/8) ad=98*ad/100; // \it a
1295
+ }
1296
+
1297
+ if (abs(loop(bp,dx/2, 0,dy,cs,0,DO)
1298
+ -loop(bp,dx/2,dy-1,dy,cs,0,UP))>dy/8
1299
+ || num_cross(0,dx-1, 0, 0,bp,cs) > 1
1300
+ || num_cross(0,dx-1,dy-1,dy-1,bp,cs) > 1
1301
+ ) ad=98*ad/100; // ~bq
1302
+
1303
+ if (box1->m3) {
1304
+ if (!hchar) ad=98*ad/100; else // ~o
1305
+ if ( gchar) ad=99*ad/100; // wrong line detection?
1306
+ } else { if (ad==100) ad=99; } /* not 100% sure */
1307
+ if (ad>99) ad=99; /* we can never be sure having a O,
1308
+ let context correction decide, see below! */
1309
+ Setac(box1,(wchar_t)'0',ad);
1310
+ break;
1311
+ }
1312
+ // --- test 0 with a straight line in it -------------------
1313
+ for(ad=100;dx>4 && dy>5;){ /* v0.3.1+ */
1314
+ DBG( char c_ask='0'; )
1315
+ if (sdata->holes.num > 3) Break; /* be tolerant */
1316
+ if (sdata->holes.num < 1) Break;
1317
+ if (sdata->holes.num != 2) ad=95*ad/100;
1318
+ if( get_bw(x0 , x0+dx/2,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1319
+ if( get_bw(x1-dx/2 , x1 ,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1320
+ if( get_bw(x0+dx/2 , x0+dx/2,y1-dy/2 , y1,box1->p,cs,1) != 1 ) Break;
1321
+ if( get_bw(x0+dx/2 , x0+dx/2,y0 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1322
+ if( get_bw(x0+dx/2 , x0+dx/2,y0+dy/3 , y1-dy/3,box1->p,cs,1) != 1 ) Break;
1323
+ // out_x(box1); printf(" x0 y0 %d %d\n",x0,y0);
1324
+ if( num_cross(x0+dx/2,x0+dx/2,y0 , y1 ,box1->p,cs) != 3 ) Break;
1325
+ if( num_cross(x0+dx/3,x1-dx/3,y0 , y0 ,box1->p,cs) != 1 ) // AND
1326
+ if( num_cross(x0+dx/3,x1-dx/3,y0+1 , y0+1 ,box1->p,cs) != 1 ) Break;
1327
+ if( num_cross(x0+dx/3,x1-dx/3,y1 , y1 ,box1->p,cs) != 1 ) // against "rauschen"
1328
+ if( num_cross(x0+dx/3,x1-dx/3,y1-1 , y1-1 ,box1->p,cs) != 1 ) Break;
1329
+ if( num_cross(x0 ,x0 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1330
+ if( num_cross(x0+1 ,x0+1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1331
+ if( num_cross(x1 ,x1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1332
+ if( num_cross(x1-1 ,x1-1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1333
+ // if( num_hole(x0,x1,y0,y1,box1->p,cs,NULL) != 2 ) Break;
1334
+ if (sdata->holes.num != 2) ad=85*ad/100;
1335
+
1336
+ if( loop(bp,0 , 0,x1-x0,cs,0,RI)<=
1337
+ loop(bp,0 , 2+dy/32,x1-x0,cs,0,RI) ) Break;
1338
+ x= loop(bp,0 ,dy/2 ,x1-x0,cs,0,RI);
1339
+ i= loop(bp,0 ,dy/2-1,x1-x0,cs,0,RI); if (i>x) x=i;
1340
+ i= loop(bp,0 ,dy/2-2,x1-x0,cs,0,RI); if (i>x && dy>8) x=i;
1341
+ if( loop(bp,0 , dy/4,x1-x0,cs,0,RI)<x ) Break; // ~8
1342
+ x= loop(bp,dx-1,dy/2 ,x1-x0,cs,0,LE);
1343
+ i= loop(bp,dx-1,dy/2-1,x1-x0,cs,0,LE); if(i>x) x=i;
1344
+ i= loop(bp,dx-1,dy/2-1,x1-x0,cs,0,LE); if(i>x && dy>8) x=i;
1345
+ if( loop(bp,dx-1,3*dy/4,x1-x0,cs,0,LE)<x) Break; // ~8
1346
+
1347
+ x=loop(bp,dx-1,dy-1-dy/3,x1-x0,cs,0,LE); // should be minimum
1348
+ for( y=dy-1-dy/3;y<dy;y++ ){
1349
+ i=loop(bp,dx-1,y,x1-x0,cs,0,LE);
1350
+ if (i<x-dx/16) break;
1351
+ if (i>x) x=i;
1352
+ }
1353
+ if( y<dy ) Break;
1354
+
1355
+ /* test for straight line */
1356
+ y =loop(bp,dx/2,dy-1 ,y1-y0,cs,0,UP); if(y>dy/4) Break;
1357
+ y+=loop(bp,dx/2,dy-1-y,y1-y0,cs,1,UP); if(y>dy/3) Break; if (y>dy/4) ad=ad*99/100;
1358
+ y+=loop(bp,dx/2,dy-1-y,y1-y0,cs,0,UP); if(3*y>2*dy) Break;
1359
+ x =loop(bp,dx/2,dy-y,dx/2,cs,0,RI); if(x==0) Break;
1360
+ // MM; fprintf(stderr," y=%d x=%d\n",y-1,x);
1361
+ if( loop(bp,dx/2+x-1-dx/16,dy-y,y1-y0,cs,0,UP)==0 ) Break;
1362
+ // $
1363
+ for(i=0,y=dy/4;y<dy-dy/4-1;y++)
1364
+ if( loop(bp, 0,y,dx-1,cs,0,RI) > dx/4
1365
+ || loop(bp,dx-1,y,dx-1,cs,0,LE) > dx/4 ) break;
1366
+ if( y<dy-dy/4-1 ) Break;
1367
+
1368
+ // ~D
1369
+ if( loop(bp,0, dy/16,dx,cs,0,RI)
1370
+ + loop(bp,0,dy-1-dy/16,dx,cs,0,RI)
1371
+ <= 2*loop(bp,0, dy/2 ,dx,cs,0,RI)+dx/8 ) Break; // not konvex
1372
+
1373
+ if( loop(bp,dx-1, dy/16,dx,cs,0,LE)>dx/8 )
1374
+ if( loop(bp,0 , dy/16,dx,cs,0,RI)<dx/16 ) Break;
1375
+ if( loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)>dx/8 )
1376
+ if( loop(bp,0 ,dy-1-dy/16,dx,cs,0,RI)<dx/16 ) Break;
1377
+ if( get_bw(x1-dx/32,x1,y0,y0+dy/32,box1->p,cs,1) == 0
1378
+ && get_bw(x1-dx/32,x1,y1-dy/32,y1,box1->p,cs,1) == 0
1379
+ && ( get_bw(x0,x0+dx/32,y0,y0+dy/32,box1->p,cs,1) == 1
1380
+ || get_bw(x0,x0+dx/32,y1-dy/32,y1,box1->p,cs,1) == 1 ) ) Break; // ~D
1381
+
1382
+ /* 5x9 font "9" is like "0" */
1383
+ if (dx<16)
1384
+ if ( num_cross(x0,x0,y0,y1,box1->p,cs) != 1 ) ad=98*ad/100;
1385
+
1386
+ // italic a
1387
+ for(i=0,y=6*dy/8;y<dy-dy/16;y++)
1388
+ if( num_cross(0,dx-1,y,y,bp,cs) > 2 ) i++; else i--;
1389
+ if(i>0) ad=ad*98/100; // ~'a' \it a
1390
+ if( !hchar ) ad=90*ad/100;
1391
+ Setac(box1,(wchar_t)'0',ad);
1392
+ break;
1393
+ }
1394
+ // --- test 0 with a straight dot in it -------------------
1395
+ for(ad=100;dx>4 && dy>5;){ /* v0.46+ */
1396
+ DBG( char c_ask='0'; )
1397
+ if (sdata->holes.num != 1) Break; /* do not be tolerant */
1398
+ if (sdata->box1->num_frames != 2) ad=85*ad/100;
1399
+ if( get_bw(x0 , x0+dx/2,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1400
+ if( get_bw(x1-dx/2 , x1 ,y0+dy/2 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1401
+ if( get_bw(x0+dx/2 , x0+dx/2,y1-dy/2 , y1,box1->p,cs,1) != 1 ) Break;
1402
+ if( get_bw(x0+dx/2 , x0+dx/2,y0 , y0+dy/2,box1->p,cs,1) != 1 ) Break;
1403
+ if( get_bw(x0+dx/2 , x0+dx/2,y0+dy/3 , y1-dy/3,box1->p,cs,1) != 1 ) Break;
1404
+ // out_x(box1); printf(" x0 y0 %d %d\n",x0,y0);
1405
+ if( num_cross(x0+dx/2,x0+dx/2,y0 , y1 ,box1->p,cs) != 3 ) Break;
1406
+ if( num_cross(x0+dx/3,x1-dx/3,y0 , y0 ,box1->p,cs) != 1 ) // AND
1407
+ if( num_cross(x0+dx/3,x1-dx/3,y0+1 , y0+1 ,box1->p,cs) != 1 ) Break;
1408
+ if( num_cross(x0+dx/3,x1-dx/3,y1 , y1 ,box1->p,cs) != 1 ) // against "rauschen"
1409
+ if( num_cross(x0+dx/3,x1-dx/3,y1-1 , y1-1 ,box1->p,cs) != 1 ) Break;
1410
+ if( num_cross(x0 ,x0 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1411
+ if( num_cross(x0+1 ,x0+1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1412
+ if( num_cross(x1 ,x1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 )
1413
+ if( num_cross(x1-1 ,x1-1 ,y0+dy/3 , y1-dy/3,box1->p,cs) != 1 ) Break;
1414
+ // if( num_hole(x0,x1,y0,y1,box1->p,cs,NULL) != 2 ) Break;
1415
+
1416
+ if( loop(bp,0 , 0,x1-x0,cs,0,RI)<=
1417
+ loop(bp,0 , 2+dy/32,x1-x0,cs,0,RI) ) Break;
1418
+ x= loop(bp,0 ,dy/2 ,x1-x0,cs,0,RI);
1419
+ i= loop(bp,0 ,dy/2-1,x1-x0,cs,0,RI); if (i>x) x=i;
1420
+ i= loop(bp,0 ,dy/2-2,x1-x0,cs,0,RI); if (i>x && dy>8) x=i;
1421
+ if( loop(bp,0 , dy/4,x1-x0,cs,0,RI)<x ) Break; // ~8
1422
+ x= loop(bp,dx-1,dy/2 ,x1-x0,cs,0,LE);
1423
+ i= loop(bp,dx-1,dy/2-1,x1-x0,cs,0,LE); if(i>x) x=i;
1424
+ i= loop(bp,dx-1,dy/2-1,x1-x0,cs,0,LE); if(i>x && dy>8) x=i;
1425
+ if( loop(bp,dx-1,3*dy/4,x1-x0,cs,0,LE)<x) Break; // ~8
1426
+
1427
+ x=loop(bp,dx-1,dy-1-dy/3,x1-x0,cs,0,LE); // should be minimum
1428
+ for( y=dy-1-dy/3;y<dy;y++ ){
1429
+ i=loop(bp,dx-1,y,x1-x0,cs,0,LE);
1430
+ if (i<x-dx/16) break;
1431
+ if (i>x) x=i;
1432
+ }
1433
+ if( y<dy ) Break;
1434
+
1435
+ /* test for straight line */
1436
+ y =loop(bp,dx/2,dy-1 ,y1-y0,cs,0,UP); if(y>dy/4) Break;
1437
+ y+=loop(bp,dx/2,dy-1-y,y1-y0,cs,1,UP); if(y>dy/3) Break; if (y>dy/4) ad=ad*99/100;
1438
+ y+=loop(bp,dx/2,dy-1-y,y1-y0,cs,0,UP); if(3*y>2*dy) Break;
1439
+ x =loop(bp,dx/2,dy-y,dx/2,cs,0,RI); if(x==0) Break;
1440
+ // MM; fprintf(stderr," y=%d x=%d\n",y-1,x);
1441
+ if( loop(bp,dx/2+x-1-dx/16,dy-y,y1-y0,cs,0,UP)==0 ) Break;
1442
+ // $
1443
+ for(i=0,y=dy/4;y<dy-dy/4-1;y++)
1444
+ if( loop(bp, 0,y,dx-1,cs,0,RI) > dx/4
1445
+ || loop(bp,dx-1,y,dx-1,cs,0,LE) > dx/4 ) break;
1446
+ if( y<dy-dy/4-1 ) Break;
1447
+
1448
+ // ~D
1449
+ if( loop(bp,0, dy/16,dx,cs,0,RI)
1450
+ + loop(bp,0,dy-1-dy/16,dx,cs,0,RI)
1451
+ <= 2*loop(bp,0, dy/2 ,dx,cs,0,RI)+dx/8 ) Break; // not konvex
1452
+
1453
+ if( loop(bp,dx-1, dy/16,dx,cs,0,LE)>dx/8 )
1454
+ if( loop(bp,0 , dy/16,dx,cs,0,RI)<dx/16 ) Break;
1455
+ if( loop(bp,dx-1,dy-1-dy/16,dx,cs,0,LE)>dx/8 )
1456
+ if( loop(bp,0 ,dy-1-dy/16,dx,cs,0,RI)<dx/16 ) Break;
1457
+ if( get_bw(x1-dx/32,x1,y0,y0+dy/32,box1->p,cs,1) == 0
1458
+ && get_bw(x1-dx/32,x1,y1-dy/32,y1,box1->p,cs,1) == 0
1459
+ && ( get_bw(x0,x0+dx/32,y0,y0+dy/32,box1->p,cs,1) == 1
1460
+ || get_bw(x0,x0+dx/32,y1-dy/32,y1,box1->p,cs,1) == 1 ) ) Break; // ~D
1461
+
1462
+ /* 5x9 font "9" is like "0" */
1463
+ if (dx<16)
1464
+ if ( num_cross(x0,x0,y0,y1,box1->p,cs) != 1 ) ad=98*ad/100;
1465
+
1466
+ // italic a
1467
+ for(i=0,y=6*dy/8;y<dy-dy/16;y++)
1468
+ if( num_cross(0,dx-1,y,y,bp,cs) > 2 ) i++; else i--;
1469
+ if(i>0) ad=ad*98/100; // ~'a' \it a
1470
+ if( !hchar ) ad=90*ad/100;
1471
+ Setac(box1,(wchar_t)'0',ad);
1472
+ break;
1473
+ }
1474
+ return box1->c;
1475
+ }