zxing_cpp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.gitmodules +3 -0
  4. data/CHANGELOG.rdoc +6 -0
  5. data/Gemfile +3 -0
  6. data/Manifest.txt +331 -0
  7. data/README.rdoc +138 -0
  8. data/Rakefile +28 -0
  9. data/bin/zxd +87 -0
  10. data/bin/zxe +53 -0
  11. data/ext/zxing/extconf.rb +27 -0
  12. data/ext/zxing/zxing-cpp/.gitignore +4 -0
  13. data/ext/zxing/zxing-cpp/AUTHORS +115 -0
  14. data/ext/zxing/zxing-cpp/CMakeLists.txt +84 -0
  15. data/ext/zxing/zxing-cpp/COPYING +201 -0
  16. data/ext/zxing/zxing-cpp/NOTICE +65 -0
  17. data/ext/zxing/zxing-cpp/README.md +50 -0
  18. data/ext/zxing/zxing-cpp/cli/src/ImageReaderSource.cpp +112 -0
  19. data/ext/zxing/zxing-cpp/cli/src/ImageReaderSource.h +40 -0
  20. data/ext/zxing/zxing-cpp/cli/src/jpgd.cpp +3174 -0
  21. data/ext/zxing/zxing-cpp/cli/src/jpgd.h +319 -0
  22. data/ext/zxing/zxing-cpp/cli/src/lodepng.cpp +6261 -0
  23. data/ext/zxing/zxing-cpp/cli/src/lodepng.h +1695 -0
  24. data/ext/zxing/zxing-cpp/cli/src/main.cpp +297 -0
  25. data/ext/zxing/zxing-cpp/cmake/FindCPPUNIT.cmake +54 -0
  26. data/ext/zxing/zxing-cpp/cmake/FindIconv.cmake +57 -0
  27. data/ext/zxing/zxing-cpp/core/src/bigint/.gitignore +6 -0
  28. data/ext/zxing/zxing-cpp/core/src/bigint/BigInteger.cc +405 -0
  29. data/ext/zxing/zxing-cpp/core/src/bigint/BigInteger.hh +215 -0
  30. data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerAlgorithms.cc +70 -0
  31. data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerAlgorithms.hh +25 -0
  32. data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerLibrary.hh +8 -0
  33. data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerUtils.cc +50 -0
  34. data/ext/zxing/zxing-cpp/core/src/bigint/BigIntegerUtils.hh +72 -0
  35. data/ext/zxing/zxing-cpp/core/src/bigint/BigUnsigned.cc +697 -0
  36. data/ext/zxing/zxing-cpp/core/src/bigint/BigUnsigned.hh +418 -0
  37. data/ext/zxing/zxing-cpp/core/src/bigint/BigUnsignedInABase.cc +125 -0
  38. data/ext/zxing/zxing-cpp/core/src/bigint/BigUnsignedInABase.hh +122 -0
  39. data/ext/zxing/zxing-cpp/core/src/bigint/ChangeLog +146 -0
  40. data/ext/zxing/zxing-cpp/core/src/bigint/Makefile +73 -0
  41. data/ext/zxing/zxing-cpp/core/src/bigint/NumberlikeArray.hh +177 -0
  42. data/ext/zxing/zxing-cpp/core/src/bigint/README +71 -0
  43. data/ext/zxing/zxing-cpp/core/src/win32/zxing/iconv.h +14 -0
  44. data/ext/zxing/zxing-cpp/core/src/win32/zxing/stdint.h +247 -0
  45. data/ext/zxing/zxing-cpp/core/src/win32/zxing/win_iconv.c +2035 -0
  46. data/ext/zxing/zxing-cpp/core/src/zxing/BarcodeFormat.cpp +40 -0
  47. data/ext/zxing/zxing-cpp/core/src/zxing/BarcodeFormat.h +60 -0
  48. data/ext/zxing/zxing-cpp/core/src/zxing/Binarizer.cpp +45 -0
  49. data/ext/zxing/zxing-cpp/core/src/zxing/Binarizer.h +50 -0
  50. data/ext/zxing/zxing-cpp/core/src/zxing/BinaryBitmap.cpp +70 -0
  51. data/ext/zxing/zxing-cpp/core/src/zxing/BinaryBitmap.h +56 -0
  52. data/ext/zxing/zxing-cpp/core/src/zxing/ChecksumException.cpp +28 -0
  53. data/ext/zxing/zxing-cpp/core/src/zxing/ChecksumException.h +34 -0
  54. data/ext/zxing/zxing-cpp/core/src/zxing/DecodeHints.cpp +142 -0
  55. data/ext/zxing/zxing-cpp/core/src/zxing/DecodeHints.h +85 -0
  56. data/ext/zxing/zxing-cpp/core/src/zxing/Exception.cpp +43 -0
  57. data/ext/zxing/zxing-cpp/core/src/zxing/Exception.h +51 -0
  58. data/ext/zxing/zxing-cpp/core/src/zxing/FormatException.cpp +41 -0
  59. data/ext/zxing/zxing-cpp/core/src/zxing/FormatException.h +37 -0
  60. data/ext/zxing/zxing-cpp/core/src/zxing/IllegalStateException.h +35 -0
  61. data/ext/zxing/zxing-cpp/core/src/zxing/InvertedLuminanceSource.cpp +68 -0
  62. data/ext/zxing/zxing-cpp/core/src/zxing/InvertedLuminanceSource.h +48 -0
  63. data/ext/zxing/zxing-cpp/core/src/zxing/LuminanceSource.cpp +86 -0
  64. data/ext/zxing/zxing-cpp/core/src/zxing/LuminanceSource.h +59 -0
  65. data/ext/zxing/zxing-cpp/core/src/zxing/MultiFormatReader.cpp +124 -0
  66. data/ext/zxing/zxing-cpp/core/src/zxing/MultiFormatReader.h +48 -0
  67. data/ext/zxing/zxing-cpp/core/src/zxing/NotFoundException.h +35 -0
  68. data/ext/zxing/zxing-cpp/core/src/zxing/Reader.cpp +31 -0
  69. data/ext/zxing/zxing-cpp/core/src/zxing/Reader.h +40 -0
  70. data/ext/zxing/zxing-cpp/core/src/zxing/ReaderException.h +37 -0
  71. data/ext/zxing/zxing-cpp/core/src/zxing/Result.cpp +61 -0
  72. data/ext/zxing/zxing-cpp/core/src/zxing/Result.h +55 -0
  73. data/ext/zxing/zxing-cpp/core/src/zxing/ResultIO.cpp +34 -0
  74. data/ext/zxing/zxing-cpp/core/src/zxing/ResultPoint.cpp +108 -0
  75. data/ext/zxing/zxing-cpp/core/src/zxing/ResultPoint.h +55 -0
  76. data/ext/zxing/zxing-cpp/core/src/zxing/ResultPointCallback.cpp +26 -0
  77. data/ext/zxing/zxing-cpp/core/src/zxing/ResultPointCallback.h +39 -0
  78. data/ext/zxing/zxing-cpp/core/src/zxing/ZXing.h +133 -0
  79. data/ext/zxing/zxing-cpp/core/src/zxing/aztec/AztecDetectorResult.cpp +54 -0
  80. data/ext/zxing/zxing-cpp/core/src/zxing/aztec/AztecDetectorResult.h +48 -0
  81. data/ext/zxing/zxing-cpp/core/src/zxing/aztec/AztecReader.cpp +68 -0
  82. data/ext/zxing/zxing-cpp/core/src/zxing/aztec/AztecReader.h +49 -0
  83. data/ext/zxing/zxing-cpp/core/src/zxing/aztec/decoder/Decoder.cpp +489 -0
  84. data/ext/zxing/zxing-cpp/core/src/zxing/aztec/decoder/Decoder.h +69 -0
  85. data/ext/zxing/zxing-cpp/core/src/zxing/aztec/detector/Detector.cpp +548 -0
  86. data/ext/zxing/zxing-cpp/core/src/zxing/aztec/detector/Detector.h +92 -0
  87. data/ext/zxing/zxing-cpp/core/src/zxing/common/Array.h +170 -0
  88. data/ext/zxing/zxing-cpp/core/src/zxing/common/BitArray.cpp +155 -0
  89. data/ext/zxing/zxing-cpp/core/src/zxing/common/BitArray.h +81 -0
  90. data/ext/zxing/zxing-cpp/core/src/zxing/common/BitArrayIO.cpp +31 -0
  91. data/ext/zxing/zxing-cpp/core/src/zxing/common/BitMatrix.cpp +143 -0
  92. data/ext/zxing/zxing-cpp/core/src/zxing/common/BitMatrix.h +91 -0
  93. data/ext/zxing/zxing-cpp/core/src/zxing/common/BitSource.cpp +76 -0
  94. data/ext/zxing/zxing-cpp/core/src/zxing/common/BitSource.h +74 -0
  95. data/ext/zxing/zxing-cpp/core/src/zxing/common/CharacterSetECI.cpp +104 -0
  96. data/ext/zxing/zxing-cpp/core/src/zxing/common/CharacterSetECI.h +53 -0
  97. data/ext/zxing/zxing-cpp/core/src/zxing/common/Counted.h +140 -0
  98. data/ext/zxing/zxing-cpp/core/src/zxing/common/DecoderResult.cpp +46 -0
  99. data/ext/zxing/zxing-cpp/core/src/zxing/common/DecoderResult.h +51 -0
  100. data/ext/zxing/zxing-cpp/core/src/zxing/common/DetectorResult.cpp +39 -0
  101. data/ext/zxing/zxing-cpp/core/src/zxing/common/DetectorResult.h +43 -0
  102. data/ext/zxing/zxing-cpp/core/src/zxing/common/GlobalHistogramBinarizer.cpp +212 -0
  103. data/ext/zxing/zxing-cpp/core/src/zxing/common/GlobalHistogramBinarizer.h +48 -0
  104. data/ext/zxing/zxing-cpp/core/src/zxing/common/GreyscaleLuminanceSource.cpp +80 -0
  105. data/ext/zxing/zxing-cpp/core/src/zxing/common/GreyscaleLuminanceSource.h +53 -0
  106. data/ext/zxing/zxing-cpp/core/src/zxing/common/GreyscaleRotatedLuminanceSource.cpp +81 -0
  107. data/ext/zxing/zxing-cpp/core/src/zxing/common/GreyscaleRotatedLuminanceSource.h +46 -0
  108. data/ext/zxing/zxing-cpp/core/src/zxing/common/GridSampler.cpp +122 -0
  109. data/ext/zxing/zxing-cpp/core/src/zxing/common/GridSampler.h +45 -0
  110. data/ext/zxing/zxing-cpp/core/src/zxing/common/HybridBinarizer.cpp +226 -0
  111. data/ext/zxing/zxing-cpp/core/src/zxing/common/HybridBinarizer.h +67 -0
  112. data/ext/zxing/zxing-cpp/core/src/zxing/common/IllegalArgumentException.cpp +27 -0
  113. data/ext/zxing/zxing-cpp/core/src/zxing/common/IllegalArgumentException.h +36 -0
  114. data/ext/zxing/zxing-cpp/core/src/zxing/common/PerspectiveTransform.cpp +107 -0
  115. data/ext/zxing/zxing-cpp/core/src/zxing/common/PerspectiveTransform.h +49 -0
  116. data/ext/zxing/zxing-cpp/core/src/zxing/common/Point.h +47 -0
  117. data/ext/zxing/zxing-cpp/core/src/zxing/common/Str.cpp +61 -0
  118. data/ext/zxing/zxing-cpp/core/src/zxing/common/Str.h +51 -0
  119. data/ext/zxing/zxing-cpp/core/src/zxing/common/StringUtils.cpp +198 -0
  120. data/ext/zxing/zxing-cpp/core/src/zxing/common/StringUtils.h +52 -0
  121. data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/JavaMath.h +43 -0
  122. data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/MathUtils.h +57 -0
  123. data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/MonochromeRectangleDetector.cpp +174 -0
  124. data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/MonochromeRectangleDetector.h +62 -0
  125. data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/WhiteRectangleDetector.cpp +330 -0
  126. data/ext/zxing/zxing-cpp/core/src/zxing/common/detector/WhiteRectangleDetector.h +59 -0
  127. data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/GenericGF.cpp +150 -0
  128. data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/GenericGF.h +73 -0
  129. data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/GenericGFPoly.cpp +218 -0
  130. data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/GenericGFPoly.h +56 -0
  131. data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/ReedSolomonDecoder.cpp +174 -0
  132. data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/ReedSolomonDecoder.h +49 -0
  133. data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/ReedSolomonException.cpp +30 -0
  134. data/ext/zxing/zxing-cpp/core/src/zxing/common/reedsolomon/ReedSolomonException.h +33 -0
  135. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/DataMatrixReader.cpp +54 -0
  136. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/DataMatrixReader.h +45 -0
  137. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/Version.cpp +199 -0
  138. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/Version.h +87 -0
  139. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/BitMatrixParser.cpp +361 -0
  140. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/BitMatrixParser.h +59 -0
  141. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/DataBlock.cpp +113 -0
  142. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/DataBlock.h +49 -0
  143. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/DecodedBitStreamParser.cpp +416 -0
  144. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/DecodedBitStreamParser.h +104 -0
  145. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/Decoder.cpp +93 -0
  146. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/decoder/Decoder.h +49 -0
  147. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/CornerPoint.cpp +46 -0
  148. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/CornerPoint.h +43 -0
  149. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/Detector.cpp +446 -0
  150. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/Detector.h +94 -0
  151. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/DetectorException.cpp +23 -0
  152. data/ext/zxing/zxing-cpp/core/src/zxing/datamatrix/detector/DetectorException.h +23 -0
  153. data/ext/zxing/zxing-cpp/core/src/zxing/multi/ByQuadrantReader.cpp +75 -0
  154. data/ext/zxing/zxing-cpp/core/src/zxing/multi/ByQuadrantReader.h +42 -0
  155. data/ext/zxing/zxing-cpp/core/src/zxing/multi/GenericMultipleBarcodeReader.cpp +137 -0
  156. data/ext/zxing/zxing-cpp/core/src/zxing/multi/GenericMultipleBarcodeReader.h +51 -0
  157. data/ext/zxing/zxing-cpp/core/src/zxing/multi/MultipleBarcodeReader.cpp +29 -0
  158. data/ext/zxing/zxing-cpp/core/src/zxing/multi/MultipleBarcodeReader.h +41 -0
  159. data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/QRCodeMultiReader.cpp +58 -0
  160. data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/QRCodeMultiReader.h +36 -0
  161. data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/detector/MultiDetector.cpp +47 -0
  162. data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/detector/MultiDetector.h +37 -0
  163. data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/detector/MultiFinderPatternFinder.cpp +236 -0
  164. data/ext/zxing/zxing-cpp/core/src/zxing/multi/qrcode/detector/MultiFinderPatternFinder.h +47 -0
  165. data/ext/zxing/zxing-cpp/core/src/zxing/oned/CodaBarReader.cpp +340 -0
  166. data/ext/zxing/zxing-cpp/core/src/zxing/oned/CodaBarReader.h +57 -0
  167. data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code128Reader.cpp +496 -0
  168. data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code128Reader.h +48 -0
  169. data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code39Reader.cpp +328 -0
  170. data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code39Reader.h +63 -0
  171. data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code93Reader.cpp +293 -0
  172. data/ext/zxing/zxing-cpp/core/src/zxing/oned/Code93Reader.h +58 -0
  173. data/ext/zxing/zxing-cpp/core/src/zxing/oned/EAN13Reader.cpp +85 -0
  174. data/ext/zxing/zxing-cpp/core/src/zxing/oned/EAN13Reader.h +49 -0
  175. data/ext/zxing/zxing-cpp/core/src/zxing/oned/EAN8Reader.cpp +65 -0
  176. data/ext/zxing/zxing-cpp/core/src/zxing/oned/EAN8Reader.h +47 -0
  177. data/ext/zxing/zxing-cpp/core/src/zxing/oned/ITFReader.cpp +337 -0
  178. data/ext/zxing/zxing-cpp/core/src/zxing/oned/ITFReader.h +54 -0
  179. data/ext/zxing/zxing-cpp/core/src/zxing/oned/MultiFormatOneDReader.cpp +96 -0
  180. data/ext/zxing/zxing-cpp/core/src/zxing/oned/MultiFormatOneDReader.h +38 -0
  181. data/ext/zxing/zxing-cpp/core/src/zxing/oned/MultiFormatUPCEANReader.cpp +110 -0
  182. data/ext/zxing/zxing-cpp/core/src/zxing/oned/MultiFormatUPCEANReader.h +41 -0
  183. data/ext/zxing/zxing-cpp/core/src/zxing/oned/OneDReader.cpp +227 -0
  184. data/ext/zxing/zxing-cpp/core/src/zxing/oned/OneDReader.h +81 -0
  185. data/ext/zxing/zxing-cpp/core/src/zxing/oned/OneDResultPoint.cpp +28 -0
  186. data/ext/zxing/zxing-cpp/core/src/zxing/oned/OneDResultPoint.h +35 -0
  187. data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCAReader.cpp +71 -0
  188. data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCAReader.h +50 -0
  189. data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCEANReader.cpp +309 -0
  190. data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCEANReader.h +88 -0
  191. data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCEReader.cpp +146 -0
  192. data/ext/zxing/zxing-cpp/core/src/zxing/oned/UPCEReader.h +47 -0
  193. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/PDF417Reader.cpp +170 -0
  194. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/PDF417Reader.h +49 -0
  195. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/BitMatrixParser.cpp +997 -0
  196. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/BitMatrixParser.h +84 -0
  197. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/DecodedBitStreamParser.cpp +563 -0
  198. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/DecodedBitStreamParser.h +84 -0
  199. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/Decoder.cpp +118 -0
  200. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/Decoder.h +62 -0
  201. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ErrorCorrection.cpp +214 -0
  202. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ErrorCorrection.h +71 -0
  203. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ModulusGF.cpp +120 -0
  204. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ModulusGF.h +72 -0
  205. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ModulusPoly.cpp +284 -0
  206. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/decoder/ec/ModulusPoly.h +68 -0
  207. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/detector/Detector.cpp +664 -0
  208. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/detector/Detector.h +106 -0
  209. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/detector/LinesSampler.cpp +714 -0
  210. data/ext/zxing/zxing-cpp/core/src/zxing/pdf417/detector/LinesSampler.h +122 -0
  211. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/ErrorCorrectionLevel.cpp +65 -0
  212. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/ErrorCorrectionLevel.h +52 -0
  213. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/FormatInformation.cpp +117 -0
  214. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/FormatInformation.h +54 -0
  215. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/QRCodeReader.cpp +52 -0
  216. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/QRCodeReader.h +48 -0
  217. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/Version.cpp +560 -0
  218. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/Version.h +85 -0
  219. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/BitMatrixParser.cpp +183 -0
  220. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/BitMatrixParser.h +56 -0
  221. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DataBlock.cpp +118 -0
  222. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DataBlock.h +50 -0
  223. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DataMask.cpp +159 -0
  224. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DataMask.h +50 -0
  225. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DecodedBitStreamParser.cpp +425 -0
  226. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/DecodedBitStreamParser.h +72 -0
  227. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/Decoder.cpp +107 -0
  228. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/Decoder.h +46 -0
  229. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/Mode.cpp +90 -0
  230. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/decoder/Mode.h +57 -0
  231. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/AlignmentPattern.cpp +47 -0
  232. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/AlignmentPattern.h +45 -0
  233. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/AlignmentPatternFinder.cpp +208 -0
  234. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/AlignmentPatternFinder.h +68 -0
  235. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/Detector.cpp +314 -0
  236. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/Detector.h +69 -0
  237. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPattern.cpp +69 -0
  238. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPattern.h +48 -0
  239. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPatternFinder.cpp +559 -0
  240. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPatternFinder.h +76 -0
  241. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPatternInfo.cpp +41 -0
  242. data/ext/zxing/zxing-cpp/core/src/zxing/qrcode/detector/FinderPatternInfo.h +47 -0
  243. data/ext/zxing/zxing-cpp/core/tests/src/TestRunner.cpp +30 -0
  244. data/ext/zxing/zxing-cpp/core/tests/src/common/BitArrayTest.cpp +216 -0
  245. data/ext/zxing/zxing-cpp/core/tests/src/common/BitArrayTest.h +61 -0
  246. data/ext/zxing/zxing-cpp/core/tests/src/common/BitMatrixTest.cpp +106 -0
  247. data/ext/zxing/zxing-cpp/core/tests/src/common/BitMatrixTest.h +55 -0
  248. data/ext/zxing/zxing-cpp/core/tests/src/common/BitSourceTest.cpp +49 -0
  249. data/ext/zxing/zxing-cpp/core/tests/src/common/BitSourceTest.h +42 -0
  250. data/ext/zxing/zxing-cpp/core/tests/src/common/CountedTest.cpp +58 -0
  251. data/ext/zxing/zxing-cpp/core/tests/src/common/CountedTest.h +46 -0
  252. data/ext/zxing/zxing-cpp/core/tests/src/common/PerspectiveTransformTest.cpp +69 -0
  253. data/ext/zxing/zxing-cpp/core/tests/src/common/PerspectiveTransformTest.h +47 -0
  254. data/ext/zxing/zxing-cpp/core/tests/src/common/reedsolomon/ReedSolomonTest.cpp +129 -0
  255. data/ext/zxing/zxing-cpp/core/tests/src/common/reedsolomon/ReedSolomonTest.h +62 -0
  256. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/ErrorCorrectionLevelTest.cpp +47 -0
  257. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/ErrorCorrectionLevelTest.h +45 -0
  258. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/FormatInformationTest.cpp +88 -0
  259. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/FormatInformationTest.h +47 -0
  260. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/VersionTest.cpp +88 -0
  261. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/VersionTest.h +49 -0
  262. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/decoder/DataMaskTest.cpp +132 -0
  263. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/decoder/DataMaskTest.h +91 -0
  264. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/decoder/ModeTest.cpp +52 -0
  265. data/ext/zxing/zxing-cpp/core/tests/src/qrcode/decoder/ModeTest.h +47 -0
  266. data/ext/zxing/zxing.cc +224 -0
  267. data/lib/zxing.rb +50 -0
  268. data/lib/zxing/.gitignore +2 -0
  269. data/lib/zxing/aztec.rb +5 -0
  270. data/lib/zxing/aztec/aztec_reader.rb +14 -0
  271. data/lib/zxing/bad_image_exception.rb +4 -0
  272. data/lib/zxing/binarizer.rb +8 -0
  273. data/lib/zxing/binary_bitmap.rb +15 -0
  274. data/lib/zxing/checksum_exception.rb +4 -0
  275. data/lib/zxing/common.rb +7 -0
  276. data/lib/zxing/common/bit_matrix.rb +9 -0
  277. data/lib/zxing/common/hybrid_binarizer.rb +17 -0
  278. data/lib/zxing/common/illegal_argument_exception.rb +4 -0
  279. data/lib/zxing/datamatrix.rb +5 -0
  280. data/lib/zxing/datamatrix/data_matrix_reader.rb +14 -0
  281. data/lib/zxing/decodable.rb +11 -0
  282. data/lib/zxing/exception.rb +4 -0
  283. data/lib/zxing/ffi.rb +20 -0
  284. data/lib/zxing/ffi/aztec.rb +6 -0
  285. data/lib/zxing/ffi/aztec/aztec_reader.rb +9 -0
  286. data/lib/zxing/ffi/binarizer.rb +25 -0
  287. data/lib/zxing/ffi/binary_bitmap.rb +15 -0
  288. data/lib/zxing/ffi/common.rb +8 -0
  289. data/lib/zxing/ffi/common/bit_matrix.rb +12 -0
  290. data/lib/zxing/ffi/common/greyscale_luminance_source.rb +30 -0
  291. data/lib/zxing/ffi/common/hybrid_binarizer.rb +10 -0
  292. data/lib/zxing/ffi/datamatrix.rb +6 -0
  293. data/lib/zxing/ffi/datamatrix/data_matrix_reader.rb +9 -0
  294. data/lib/zxing/ffi/library.rb +102 -0
  295. data/lib/zxing/ffi/luminance_source.rb +18 -0
  296. data/lib/zxing/ffi/multi_format_reader.rb +9 -0
  297. data/lib/zxing/ffi/oned.rb +6 -0
  298. data/lib/zxing/ffi/oned/code_39_reader.rb +10 -0
  299. data/lib/zxing/ffi/qrcode.rb +8 -0
  300. data/lib/zxing/ffi/qrcode/decoder.rb +10 -0
  301. data/lib/zxing/ffi/qrcode/detector.rb +10 -0
  302. data/lib/zxing/ffi/reader.rb +58 -0
  303. data/lib/zxing/ffi/result.rb +23 -0
  304. data/lib/zxing/format_exception.rb +4 -0
  305. data/lib/zxing/illegal_argument_exception.rb +4 -0
  306. data/lib/zxing/image.rb +15 -0
  307. data/lib/zxing/luminance_source.rb +18 -0
  308. data/lib/zxing/multi_format_reader.rb +11 -0
  309. data/lib/zxing/not_found_exception.rb +4 -0
  310. data/lib/zxing/oned.rb +5 -0
  311. data/lib/zxing/oned/code_39_reader.rb +15 -0
  312. data/lib/zxing/qrcode.rb +8 -0
  313. data/lib/zxing/qrcode/decoder.rb +14 -0
  314. data/lib/zxing/qrcode/detector.rb +14 -0
  315. data/lib/zxing/qrcode/encoder.rb +8 -0
  316. data/lib/zxing/qrcode/encoder/byte_matrix.rb +18 -0
  317. data/lib/zxing/qrcode/encoder/encoder.rb +9 -0
  318. data/lib/zxing/qrcode/encoder/qrcode.rb +18 -0
  319. data/lib/zxing/reader.rb +8 -0
  320. data/lib/zxing/reader_exception.rb +4 -0
  321. data/lib/zxing/reed_solomon_exception.rb +2 -0
  322. data/lib/zxing/result.rb +18 -0
  323. data/lib/zxing/rmagick.rb +5 -0
  324. data/lib/zxing/rmagick/image.rb +104 -0
  325. data/lib/zxing/version.rb +33 -0
  326. data/test/qrcode.png +0 -0
  327. data/test/test_helper.rb +5 -0
  328. data/test/test_zxing.rb +58 -0
  329. data/test/vendor.rb +360 -0
  330. data/test/zxing/test_decodable.rb +38 -0
  331. data/zxing_cpp.gemspec +48 -0
  332. metadata +473 -0
@@ -0,0 +1,69 @@
1
+ // -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
2
+ #ifndef __DETECTOR_H__
3
+ #define __DETECTOR_H__
4
+
5
+ /*
6
+ * Detector.h
7
+ * zxing
8
+ *
9
+ * Copyright 2010 ZXing authors All rights reserved.
10
+ *
11
+ * Licensed under the Apache License, Version 2.0 (the "License");
12
+ * you may not use this file except in compliance with the License.
13
+ * You may obtain a copy of the License at
14
+ *
15
+ * http://www.apache.org/licenses/LICENSE-2.0
16
+ *
17
+ * Unless required by applicable law or agreed to in writing, software
18
+ * distributed under the License is distributed on an "AS IS" BASIS,
19
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ * See the License for the specific language governing permissions and
21
+ * limitations under the License.
22
+ */
23
+
24
+ #include <zxing/common/Counted.h>
25
+ #include <zxing/common/DetectorResult.h>
26
+ #include <zxing/common/BitMatrix.h>
27
+ #include <zxing/qrcode/detector/AlignmentPattern.h>
28
+ #include <zxing/common/PerspectiveTransform.h>
29
+ #include <zxing/ResultPointCallback.h>
30
+ #include <zxing/qrcode/detector/FinderPatternInfo.h>
31
+
32
+ namespace zxing {
33
+
34
+ class DecodeHints;
35
+
36
+ namespace qrcode {
37
+
38
+ class Detector : public Counted {
39
+ private:
40
+ Ref<BitMatrix> image_;
41
+ Ref<ResultPointCallback> callback_;
42
+
43
+ protected:
44
+ Ref<BitMatrix> getImage() const;
45
+ Ref<ResultPointCallback> getResultPointCallback() const;
46
+
47
+ static Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform>);
48
+ static int computeDimension(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft,
49
+ float moduleSize);
50
+ float calculateModuleSize(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft);
51
+ float calculateModuleSizeOneWay(Ref<ResultPoint> pattern, Ref<ResultPoint> otherPattern);
52
+ float sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY);
53
+ float sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY);
54
+ Ref<AlignmentPattern> findAlignmentInRegion(float overallEstModuleSize, int estAlignmentX, int estAlignmentY,
55
+ float allowanceFactor);
56
+ Ref<DetectorResult> processFinderPatternInfo(Ref<FinderPatternInfo> info);
57
+ public:
58
+ virtual Ref<PerspectiveTransform> createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <
59
+ ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension);
60
+
61
+ Detector(Ref<BitMatrix> image);
62
+ Ref<DetectorResult> detect(DecodeHints const& hints);
63
+
64
+
65
+ };
66
+ }
67
+ }
68
+
69
+ #endif // __DETECTOR_H__
@@ -0,0 +1,69 @@
1
+ // -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
2
+ /*
3
+ * FinderPattern.cpp
4
+ * zxing
5
+ *
6
+ * Created by Christian Brunschen on 13/05/2008.
7
+ * Copyright 2008 ZXing authors All rights reserved.
8
+ *
9
+ * Licensed under the Apache License, Version 2.0 (the "License");
10
+ * you may not use this file except in compliance with the License.
11
+ * You may obtain a copy of the License at
12
+ *
13
+ * http://www.apache.org/licenses/LICENSE-2.0
14
+ *
15
+ * Unless required by applicable law or agreed to in writing, software
16
+ * distributed under the License is distributed on an "AS IS" BASIS,
17
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ * See the License for the specific language governing permissions and
19
+ * limitations under the License.
20
+ */
21
+
22
+ #include <zxing/qrcode/detector/FinderPattern.h>
23
+
24
+ using std::abs;
25
+ using zxing::Ref;
26
+ using zxing::qrcode::FinderPattern;
27
+
28
+ FinderPattern::FinderPattern(float posX, float posY, float estimatedModuleSize)
29
+ : ResultPoint(posX,posY), estimatedModuleSize_(estimatedModuleSize), count_(1) {}
30
+
31
+ FinderPattern::FinderPattern(float posX, float posY, float estimatedModuleSize, int count)
32
+ : ResultPoint(posX,posY), estimatedModuleSize_(estimatedModuleSize), count_(count) {}
33
+
34
+ int FinderPattern::getCount() const {
35
+ return count_;
36
+ }
37
+
38
+ float FinderPattern::getEstimatedModuleSize() const {
39
+ return estimatedModuleSize_;
40
+ }
41
+
42
+ void FinderPattern::incrementCount() {
43
+ count_++;
44
+ // cerr << "ic " << getX() << " " << getY() << " " << count_ << endl;
45
+ }
46
+
47
+ /*
48
+ bool FinderPattern::aboutEquals(float moduleSize, float i, float j) const {
49
+ return abs(i - posY_) <= moduleSize && abs(j - posX_) <= moduleSize && (abs(moduleSize - estimatedModuleSize_)
50
+ <= 1.0f || abs(moduleSize - estimatedModuleSize_) / estimatedModuleSize_ <= 0.1f);
51
+ }
52
+ */
53
+ bool FinderPattern::aboutEquals(float moduleSize, float i, float j) const {
54
+ if (abs(i - getY()) <= moduleSize && abs(j - getX()) <= moduleSize) {
55
+ float moduleSizeDiff = abs(moduleSize - estimatedModuleSize_);
56
+ return moduleSizeDiff <= 1.0f || moduleSizeDiff <= estimatedModuleSize_;
57
+ }
58
+ return false;
59
+ }
60
+
61
+ Ref<FinderPattern> FinderPattern::combineEstimate(float i, float j, float newModuleSize) const {
62
+ // fprintf(stderr, "ce %f %f %f\n", i, j, newModuleSize);
63
+
64
+ int combinedCount = count_ + 1;
65
+ float combinedX = (count_ * getX() + j) / combinedCount;
66
+ float combinedY = (count_ * getY() + i) / combinedCount;
67
+ float combinedModuleSize = (count_ * getEstimatedModuleSize() + newModuleSize) / combinedCount;
68
+ return Ref<FinderPattern>(new FinderPattern(combinedX, combinedY, combinedModuleSize, combinedCount));
69
+ }
@@ -0,0 +1,48 @@
1
+ // -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
2
+ #ifndef __FINDER_PATTERN_H__
3
+ #define __FINDER_PATTERN_H__
4
+
5
+ /*
6
+ * FinderPattern.h
7
+ * zxing
8
+ *
9
+ * Copyright 2010 ZXing authors All rights reserved.
10
+ *
11
+ * Licensed under the Apache License, Version 2.0 (the "License");
12
+ * you may not use this file except in compliance with the License.
13
+ * You may obtain a copy of the License at
14
+ *
15
+ * http://www.apache.org/licenses/LICENSE-2.0
16
+ *
17
+ * Unless required by applicable law or agreed to in writing, software
18
+ * distributed under the License is distributed on an "AS IS" BASIS,
19
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ * See the License for the specific language governing permissions and
21
+ * limitations under the License.
22
+ */
23
+
24
+ #include <zxing/ResultPoint.h>
25
+ #include <cmath>
26
+
27
+ namespace zxing {
28
+ namespace qrcode {
29
+
30
+ class FinderPattern : public ResultPoint {
31
+ private:
32
+ float estimatedModuleSize_;
33
+ int count_;
34
+
35
+ FinderPattern(float posX, float posY, float estimatedModuleSize, int count);
36
+
37
+ public:
38
+ FinderPattern(float posX, float posY, float estimatedModuleSize);
39
+ int getCount() const;
40
+ float getEstimatedModuleSize() const;
41
+ void incrementCount();
42
+ bool aboutEquals(float moduleSize, float i, float j) const;
43
+ Ref<FinderPattern> combineEstimate(float i, float j, float newModuleSize) const;
44
+ };
45
+ }
46
+ }
47
+
48
+ #endif // __FINDER_PATTERN_H__
@@ -0,0 +1,559 @@
1
+ // -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
2
+ /*
3
+ * FinderPatternFinder.cpp
4
+ * zxing
5
+ *
6
+ * Created by Christian Brunschen on 13/05/2008.
7
+ * Copyright 2008 ZXing authors All rights reserved.
8
+ *
9
+ * Licensed under the Apache License, Version 2.0 (the "License");
10
+ * you may not use this file except in compliance with the License.
11
+ * You may obtain a copy of the License at
12
+ *
13
+ * http://www.apache.org/licenses/LICENSE-2.0
14
+ *
15
+ * Unless required by applicable law or agreed to in writing, software
16
+ * distributed under the License is distributed on an "AS IS" BASIS,
17
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ * See the License for the specific language governing permissions and
19
+ * limitations under the License.
20
+ */
21
+
22
+ #include <algorithm>
23
+ #include <zxing/qrcode/detector/FinderPatternFinder.h>
24
+ #include <zxing/ReaderException.h>
25
+ #include <zxing/DecodeHints.h>
26
+
27
+ using std::sort;
28
+ using std::max;
29
+ using std::abs;
30
+ using std::vector;
31
+ using zxing::Ref;
32
+ using zxing::qrcode::FinderPatternFinder;
33
+ using zxing::qrcode::FinderPattern;
34
+ using zxing::qrcode::FinderPatternInfo;
35
+
36
+ // VC++
37
+
38
+ using zxing::BitMatrix;
39
+ using zxing::ResultPointCallback;
40
+ using zxing::ResultPoint;
41
+ using zxing::DecodeHints;
42
+
43
+ namespace {
44
+
45
+ class FurthestFromAverageComparator {
46
+ private:
47
+ const float averageModuleSize_;
48
+ public:
49
+ FurthestFromAverageComparator(float averageModuleSize) :
50
+ averageModuleSize_(averageModuleSize) {
51
+ }
52
+ bool operator()(Ref<FinderPattern> a, Ref<FinderPattern> b) {
53
+ float dA = abs(a->getEstimatedModuleSize() - averageModuleSize_);
54
+ float dB = abs(b->getEstimatedModuleSize() - averageModuleSize_);
55
+ return dA > dB;
56
+ }
57
+ };
58
+
59
+ class CenterComparator {
60
+ const float averageModuleSize_;
61
+ public:
62
+ CenterComparator(float averageModuleSize) :
63
+ averageModuleSize_(averageModuleSize) {
64
+ }
65
+ bool operator()(Ref<FinderPattern> a, Ref<FinderPattern> b) {
66
+ // N.B.: we want the result in descending order ...
67
+ if (a->getCount() != b->getCount()) {
68
+ return a->getCount() > b->getCount();
69
+ } else {
70
+ float dA = abs(a->getEstimatedModuleSize() - averageModuleSize_);
71
+ float dB = abs(b->getEstimatedModuleSize() - averageModuleSize_);
72
+ return dA < dB;
73
+ }
74
+ }
75
+ };
76
+
77
+ }
78
+
79
+ int FinderPatternFinder::CENTER_QUORUM = 2;
80
+ int FinderPatternFinder::MIN_SKIP = 3;
81
+ int FinderPatternFinder::MAX_MODULES = 57;
82
+
83
+ float FinderPatternFinder::centerFromEnd(int* stateCount, int end) {
84
+ return (float)(end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;
85
+ }
86
+
87
+ bool FinderPatternFinder::foundPatternCross(int* stateCount) {
88
+ int totalModuleSize = 0;
89
+ for (int i = 0; i < 5; i++) {
90
+ if (stateCount[i] == 0) {
91
+ return false;
92
+ }
93
+ totalModuleSize += stateCount[i];
94
+ }
95
+ if (totalModuleSize < 7) {
96
+ return false;
97
+ }
98
+ float moduleSize = (float)totalModuleSize / 7.0f;
99
+ float maxVariance = moduleSize / 2.0f;
100
+ // Allow less than 50% variance from 1-1-3-1-1 proportions
101
+ return abs(moduleSize - stateCount[0]) < maxVariance && abs(moduleSize - stateCount[1]) < maxVariance && abs(3.0f
102
+ * moduleSize - stateCount[2]) < 3.0f * maxVariance && abs(moduleSize - stateCount[3]) < maxVariance && abs(
103
+ moduleSize - stateCount[4]) < maxVariance;
104
+ }
105
+
106
+ float FinderPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal) {
107
+
108
+ int maxI = image_->getHeight();
109
+ int stateCount[5];
110
+ for (int i = 0; i < 5; i++)
111
+ stateCount[i] = 0;
112
+
113
+
114
+ // Start counting up from center
115
+ int i = startI;
116
+ while (i >= 0 && image_->get(centerJ, i)) {
117
+ stateCount[2]++;
118
+ i--;
119
+ }
120
+ if (i < 0) {
121
+ return nan();
122
+ }
123
+ while (i >= 0 && !image_->get(centerJ, i) && stateCount[1] <= maxCount) {
124
+ stateCount[1]++;
125
+ i--;
126
+ }
127
+ // If already too many modules in this state or ran off the edge:
128
+ if (i < 0 || stateCount[1] > maxCount) {
129
+ return nan();
130
+ }
131
+ while (i >= 0 && image_->get(centerJ, i) && stateCount[0] <= maxCount) {
132
+ stateCount[0]++;
133
+ i--;
134
+ }
135
+ if (stateCount[0] > maxCount) {
136
+ return nan();
137
+ }
138
+
139
+ // Now also count down from center
140
+ i = startI + 1;
141
+ while (i < maxI && image_->get(centerJ, i)) {
142
+ stateCount[2]++;
143
+ i++;
144
+ }
145
+ if (i == maxI) {
146
+ return nan();
147
+ }
148
+ while (i < maxI && !image_->get(centerJ, i) && stateCount[3] < maxCount) {
149
+ stateCount[3]++;
150
+ i++;
151
+ }
152
+ if (i == maxI || stateCount[3] >= maxCount) {
153
+ return nan();
154
+ }
155
+ while (i < maxI && image_->get(centerJ, i) && stateCount[4] < maxCount) {
156
+ stateCount[4]++;
157
+ i++;
158
+ }
159
+ if (stateCount[4] >= maxCount) {
160
+ return nan();
161
+ }
162
+
163
+ // If we found a finder-pattern-like section, but its size is more than 40% different than
164
+ // the original, assume it's a false positive
165
+ int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
166
+ if (5 * abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {
167
+ return nan();
168
+ }
169
+
170
+ return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : nan();
171
+ }
172
+
173
+ float FinderPatternFinder::crossCheckHorizontal(size_t startJ, size_t centerI, int maxCount,
174
+ int originalStateCountTotal) {
175
+
176
+ int maxJ = image_->getWidth();
177
+ int stateCount[5];
178
+ for (int i = 0; i < 5; i++)
179
+ stateCount[i] = 0;
180
+
181
+ int j = startJ;
182
+ while (j >= 0 && image_->get(j, centerI)) {
183
+ stateCount[2]++;
184
+ j--;
185
+ }
186
+ if (j < 0) {
187
+ return nan();
188
+ }
189
+ while (j >= 0 && !image_->get(j, centerI) && stateCount[1] <= maxCount) {
190
+ stateCount[1]++;
191
+ j--;
192
+ }
193
+ if (j < 0 || stateCount[1] > maxCount) {
194
+ return nan();
195
+ }
196
+ while (j >= 0 && image_->get(j, centerI) && stateCount[0] <= maxCount) {
197
+ stateCount[0]++;
198
+ j--;
199
+ }
200
+ if (stateCount[0] > maxCount) {
201
+ return nan();
202
+ }
203
+
204
+ j = startJ + 1;
205
+ while (j < maxJ && image_->get(j, centerI)) {
206
+ stateCount[2]++;
207
+ j++;
208
+ }
209
+ if (j == maxJ) {
210
+ return nan();
211
+ }
212
+ while (j < maxJ && !image_->get(j, centerI) && stateCount[3] < maxCount) {
213
+ stateCount[3]++;
214
+ j++;
215
+ }
216
+ if (j == maxJ || stateCount[3] >= maxCount) {
217
+ return nan();
218
+ }
219
+ while (j < maxJ && image_->get(j, centerI) && stateCount[4] < maxCount) {
220
+ stateCount[4]++;
221
+ j++;
222
+ }
223
+ if (stateCount[4] >= maxCount) {
224
+ return nan();
225
+ }
226
+
227
+ // If we found a finder-pattern-like section, but its size is significantly different than
228
+ // the original, assume it's a false positive
229
+ int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
230
+ if (5 * abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
231
+ return nan();
232
+ }
233
+
234
+ return foundPatternCross(stateCount) ? centerFromEnd(stateCount, j) : nan();
235
+ }
236
+
237
+ bool FinderPatternFinder::handlePossibleCenter(int* stateCount, size_t i, size_t j) {
238
+ int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
239
+ float centerJ = centerFromEnd(stateCount, j);
240
+ float centerI = crossCheckVertical(i, (size_t)centerJ, stateCount[2], stateCountTotal);
241
+ if (!isnan(centerI)) {
242
+ // Re-cross check
243
+ centerJ = crossCheckHorizontal((size_t)centerJ, (size_t)centerI, stateCount[2], stateCountTotal);
244
+ if (!isnan(centerJ)) {
245
+ float estimatedModuleSize = (float)stateCountTotal / 7.0f;
246
+ bool found = false;
247
+ size_t max = possibleCenters_.size();
248
+ for (size_t index = 0; index < max; index++) {
249
+ Ref<FinderPattern> center = possibleCenters_[index];
250
+ // Look for about the same center and module size:
251
+ if (center->aboutEquals(estimatedModuleSize, centerI, centerJ)) {
252
+ possibleCenters_[index] = center->combineEstimate(centerI, centerJ, estimatedModuleSize);
253
+ found = true;
254
+ break;
255
+ }
256
+ }
257
+ if (!found) {
258
+ Ref<FinderPattern> newPattern(new FinderPattern(centerJ, centerI, estimatedModuleSize));
259
+ possibleCenters_.push_back(newPattern);
260
+ if (callback_ != 0) {
261
+ callback_->foundPossibleResultPoint(*newPattern);
262
+ }
263
+ }
264
+ return true;
265
+ }
266
+ }
267
+ return false;
268
+ }
269
+
270
+ int FinderPatternFinder::findRowSkip() {
271
+ size_t max = possibleCenters_.size();
272
+ if (max <= 1) {
273
+ return 0;
274
+ }
275
+ Ref<FinderPattern> firstConfirmedCenter;
276
+ for (size_t i = 0; i < max; i++) {
277
+ Ref<FinderPattern> center = possibleCenters_[i];
278
+ if (center->getCount() >= CENTER_QUORUM) {
279
+ if (firstConfirmedCenter == 0) {
280
+ firstConfirmedCenter = center;
281
+ } else {
282
+ // We have two confirmed centers
283
+ // How far down can we skip before resuming looking for the next
284
+ // pattern? In the worst case, only the difference between the
285
+ // difference in the x / y coordinates of the two centers.
286
+ // This is the case where you find top left first. Draw it out.
287
+ hasSkipped_ = true;
288
+ return (int)(abs(firstConfirmedCenter->getX() - center->getX()) - abs(firstConfirmedCenter->getY()
289
+ - center->getY()))/2;
290
+ }
291
+ }
292
+ }
293
+ return 0;
294
+ }
295
+
296
+ bool FinderPatternFinder::haveMultiplyConfirmedCenters() {
297
+ int confirmedCount = 0;
298
+ float totalModuleSize = 0.0f;
299
+ size_t max = possibleCenters_.size();
300
+ for (size_t i = 0; i < max; i++) {
301
+ Ref<FinderPattern> pattern = possibleCenters_[i];
302
+ if (pattern->getCount() >= CENTER_QUORUM) {
303
+ confirmedCount++;
304
+ totalModuleSize += pattern->getEstimatedModuleSize();
305
+ }
306
+ }
307
+ if (confirmedCount < 3) {
308
+ return false;
309
+ }
310
+ // OK, we have at least 3 confirmed centers, but, it's possible that one is a "false positive"
311
+ // and that we need to keep looking. We detect this by asking if the estimated module sizes
312
+ // vary too much. We arbitrarily say that when the total deviation from average exceeds
313
+ // 5% of the total module size estimates, it's too much.
314
+ float average = totalModuleSize / max;
315
+ float totalDeviation = 0.0f;
316
+ for (size_t i = 0; i < max; i++) {
317
+ Ref<FinderPattern> pattern = possibleCenters_[i];
318
+ totalDeviation += abs(pattern->getEstimatedModuleSize() - average);
319
+ }
320
+ return totalDeviation <= 0.05f * totalModuleSize;
321
+ }
322
+
323
+ vector< Ref<FinderPattern> > FinderPatternFinder::selectBestPatterns() {
324
+ size_t startSize = possibleCenters_.size();
325
+
326
+ if (startSize < 3) {
327
+ // Couldn't find enough finder patterns
328
+ throw zxing::ReaderException("Could not find three finder patterns");
329
+ }
330
+
331
+ // Filter outlier possibilities whose module size is too different
332
+ if (startSize > 3) {
333
+ // But we can only afford to do so if we have at least 4 possibilities to choose from
334
+ float totalModuleSize = 0.0f;
335
+ float square = 0.0f;
336
+ for (size_t i = 0; i < startSize; i++) {
337
+ float size = possibleCenters_[i]->getEstimatedModuleSize();
338
+ totalModuleSize += size;
339
+ square += size * size;
340
+ }
341
+ float average = totalModuleSize / (float) startSize;
342
+ float stdDev = (float)sqrt(square / startSize - average * average);
343
+
344
+ sort(possibleCenters_.begin(), possibleCenters_.end(), FurthestFromAverageComparator(average));
345
+
346
+ float limit = max(0.2f * average, stdDev);
347
+
348
+ for (size_t i = 0; i < possibleCenters_.size() && possibleCenters_.size() > 3; i++) {
349
+ if (abs(possibleCenters_[i]->getEstimatedModuleSize() - average) > limit) {
350
+ possibleCenters_.erase(possibleCenters_.begin()+i);
351
+ i--;
352
+ }
353
+ }
354
+ }
355
+
356
+ if (possibleCenters_.size() > 3) {
357
+ // Throw away all but those first size candidate points we found.
358
+ float totalModuleSize = 0.0f;
359
+ for (size_t i = 0; i < possibleCenters_.size(); i++) {
360
+ float size = possibleCenters_[i]->getEstimatedModuleSize();
361
+ totalModuleSize += size;
362
+ }
363
+ float average = totalModuleSize / (float) possibleCenters_.size();
364
+ sort(possibleCenters_.begin(), possibleCenters_.end(), CenterComparator(average));
365
+ }
366
+
367
+ if (possibleCenters_.size() > 3) {
368
+ possibleCenters_.erase(possibleCenters_.begin()+3,possibleCenters_.end());
369
+ }
370
+
371
+ vector<Ref<FinderPattern> > result(3);
372
+ result[0] = possibleCenters_[0];
373
+ result[1] = possibleCenters_[1];
374
+ result[2] = possibleCenters_[2];
375
+ return result;
376
+ }
377
+
378
+ vector<Ref<FinderPattern> > FinderPatternFinder::orderBestPatterns(vector<Ref<FinderPattern> > patterns) {
379
+ // Find distances between pattern centers
380
+ float abDistance = distance(patterns[0], patterns[1]);
381
+ float bcDistance = distance(patterns[1], patterns[2]);
382
+ float acDistance = distance(patterns[0], patterns[2]);
383
+
384
+ Ref<FinderPattern> topLeft;
385
+ Ref<FinderPattern> topRight;
386
+ Ref<FinderPattern> bottomLeft;
387
+ // Assume one closest to other two is top left;
388
+ // topRight and bottomLeft will just be guesses below at first
389
+ if (bcDistance >= abDistance && bcDistance >= acDistance) {
390
+ topLeft = patterns[0];
391
+ topRight = patterns[1];
392
+ bottomLeft = patterns[2];
393
+ } else if (acDistance >= bcDistance && acDistance >= abDistance) {
394
+ topLeft = patterns[1];
395
+ topRight = patterns[0];
396
+ bottomLeft = patterns[2];
397
+ } else {
398
+ topLeft = patterns[2];
399
+ topRight = patterns[0];
400
+ bottomLeft = patterns[1];
401
+ }
402
+
403
+ // Use cross product to figure out which of other1/2 is the bottom left
404
+ // pattern. The vector "top-left -> bottom-left" x "top-left -> top-right"
405
+ // should yield a vector with positive z component
406
+ if ((bottomLeft->getY() - topLeft->getY()) * (topRight->getX() - topLeft->getX()) < (bottomLeft->getX()
407
+ - topLeft->getX()) * (topRight->getY() - topLeft->getY())) {
408
+ Ref<FinderPattern> temp = topRight;
409
+ topRight = bottomLeft;
410
+ bottomLeft = temp;
411
+ }
412
+
413
+ vector<Ref<FinderPattern> > results(3);
414
+ results[0] = bottomLeft;
415
+ results[1] = topLeft;
416
+ results[2] = topRight;
417
+ return results;
418
+ }
419
+
420
+ float FinderPatternFinder::distance(Ref<ResultPoint> p1, Ref<ResultPoint> p2) {
421
+ float dx = p1->getX() - p2->getX();
422
+ float dy = p1->getY() - p2->getY();
423
+ return (float)sqrt(dx * dx + dy * dy);
424
+ }
425
+
426
+ FinderPatternFinder::FinderPatternFinder(Ref<BitMatrix> image,
427
+ Ref<ResultPointCallback>const& callback) :
428
+ image_(image), possibleCenters_(), hasSkipped_(false), callback_(callback) {
429
+ }
430
+
431
+ Ref<FinderPatternInfo> FinderPatternFinder::find(DecodeHints const& hints) {
432
+ bool tryHarder = hints.getTryHarder();
433
+
434
+ size_t maxI = image_->getHeight();
435
+ size_t maxJ = image_->getWidth();
436
+
437
+
438
+ // We are looking for black/white/black/white/black modules in
439
+ // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far
440
+
441
+ // As this is used often, we use an integer array instead of vector
442
+ int stateCount[5];
443
+ bool done = false;
444
+
445
+
446
+ // Let's assume that the maximum version QR Code we support takes up 1/4
447
+ // the height of the image, and then account for the center being 3
448
+ // modules in size. This gives the smallest number of pixels the center
449
+ // could be, so skip this often. When trying harder, look for all
450
+ // QR versions regardless of how dense they are.
451
+ int iSkip = (3 * maxI) / (4 * MAX_MODULES);
452
+ if (iSkip < MIN_SKIP || tryHarder) {
453
+ iSkip = MIN_SKIP;
454
+ }
455
+
456
+ // This is slightly faster than using the Ref. Efficiency is important here
457
+ BitMatrix& matrix = *image_;
458
+
459
+ for (size_t i = iSkip - 1; i < maxI && !done; i += iSkip) {
460
+ // Get a row of black/white values
461
+
462
+ stateCount[0] = 0;
463
+ stateCount[1] = 0;
464
+ stateCount[2] = 0;
465
+ stateCount[3] = 0;
466
+ stateCount[4] = 0;
467
+ int currentState = 0;
468
+ for (size_t j = 0; j < maxJ; j++) {
469
+ if (matrix.get(j, i)) {
470
+ // Black pixel
471
+ if ((currentState & 1) == 1) { // Counting white pixels
472
+ currentState++;
473
+ }
474
+ stateCount[currentState]++;
475
+ } else { // White pixel
476
+ if ((currentState & 1) == 0) { // Counting black pixels
477
+ if (currentState == 4) { // A winner?
478
+ if (foundPatternCross(stateCount)) { // Yes
479
+ bool confirmed = handlePossibleCenter(stateCount, i, j);
480
+ if (confirmed) {
481
+ // Start examining every other line. Checking each line turned out to be too
482
+ // expensive and didn't improve performance.
483
+ iSkip = 2;
484
+ if (hasSkipped_) {
485
+ done = haveMultiplyConfirmedCenters();
486
+ } else {
487
+ int rowSkip = findRowSkip();
488
+ if (rowSkip > stateCount[2]) {
489
+ // Skip rows between row of lower confirmed center
490
+ // and top of presumed third confirmed center
491
+ // but back up a bit to get a full chance of detecting
492
+ // it, entire width of center of finder pattern
493
+
494
+ // Skip by rowSkip, but back off by stateCount[2] (size
495
+ // of last center of pattern we saw) to be conservative,
496
+ // and also back off by iSkip which is about to be
497
+ // re-added
498
+ i += rowSkip - stateCount[2] - iSkip;
499
+ j = maxJ - 1;
500
+ }
501
+ }
502
+ } else {
503
+ stateCount[0] = stateCount[2];
504
+ stateCount[1] = stateCount[3];
505
+ stateCount[2] = stateCount[4];
506
+ stateCount[3] = 1;
507
+ stateCount[4] = 0;
508
+ currentState = 3;
509
+ continue;
510
+ }
511
+ // Clear state to start looking again
512
+ currentState = 0;
513
+ stateCount[0] = 0;
514
+ stateCount[1] = 0;
515
+ stateCount[2] = 0;
516
+ stateCount[3] = 0;
517
+ stateCount[4] = 0;
518
+ } else { // No, shift counts back by two
519
+ stateCount[0] = stateCount[2];
520
+ stateCount[1] = stateCount[3];
521
+ stateCount[2] = stateCount[4];
522
+ stateCount[3] = 1;
523
+ stateCount[4] = 0;
524
+ currentState = 3;
525
+ }
526
+ } else {
527
+ stateCount[++currentState]++;
528
+ }
529
+ } else { // Counting white pixels
530
+ stateCount[currentState]++;
531
+ }
532
+ }
533
+ }
534
+ if (foundPatternCross(stateCount)) {
535
+ bool confirmed = handlePossibleCenter(stateCount, i, maxJ);
536
+ if (confirmed) {
537
+ iSkip = stateCount[0];
538
+ if (hasSkipped_) {
539
+ // Found a third one
540
+ done = haveMultiplyConfirmedCenters();
541
+ }
542
+ }
543
+ }
544
+ }
545
+
546
+ vector<Ref<FinderPattern> > patternInfo = selectBestPatterns();
547
+ patternInfo = orderBestPatterns(patternInfo);
548
+
549
+ Ref<FinderPatternInfo> result(new FinderPatternInfo(patternInfo));
550
+ return result;
551
+ }
552
+
553
+ Ref<BitMatrix> FinderPatternFinder::getImage() {
554
+ return image_;
555
+ }
556
+
557
+ vector<Ref<FinderPattern> >& FinderPatternFinder::getPossibleCenters() {
558
+ return possibleCenters_;
559
+ }