react-native-nitro-zxing 0.1.0-alpha.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 (423) hide show
  1. package/README.md +34 -0
  2. package/VisionCameraZxing.podspec +48 -0
  3. package/android/CMakeLists.txt +43 -0
  4. package/android/build.gradle +150 -0
  5. package/android/fix-prefab.gradle +51 -0
  6. package/android/gradle.properties +5 -0
  7. package/android/src/main/AndroidManifest.xml +3 -0
  8. package/android/src/main/cpp/cpp-adapter.cpp +7 -0
  9. package/android/src/main/java/com/margelo/nitro/camera/zxing/VisionCameraZxingPackage.kt +21 -0
  10. package/cpp/BarcodeValueTypeClassifier.cpp +70 -0
  11. package/cpp/BarcodeValueTypeClassifier.hpp +14 -0
  12. package/cpp/FrameImageView.cpp +75 -0
  13. package/cpp/FrameImageView.hpp +34 -0
  14. package/cpp/HybridBarcode.cpp +59 -0
  15. package/cpp/HybridBarcode.hpp +26 -0
  16. package/cpp/HybridBarcodeScanner.cpp +121 -0
  17. package/cpp/HybridBarcodeScanner.hpp +26 -0
  18. package/cpp/HybridBarcodeScannerFactory.cpp +11 -0
  19. package/cpp/HybridBarcodeScannerFactory.hpp +14 -0
  20. package/cpp/ImageDownscaler.cpp +34 -0
  21. package/cpp/ImageDownscaler.hpp +21 -0
  22. package/cpp/ZXingDecoder.cpp +189 -0
  23. package/cpp/ZXingDecoder.hpp +72 -0
  24. package/cpp/zxing-core/LICENSE +202 -0
  25. package/cpp/zxing-core/README.md +156 -0
  26. package/cpp/zxing-core/core/CMakeLists.txt +784 -0
  27. package/cpp/zxing-core/core/Version.h.in +28 -0
  28. package/cpp/zxing-core/core/ZXingConfig.cmake.in +9 -0
  29. package/cpp/zxing-core/core/src/Barcode.cpp +255 -0
  30. package/cpp/zxing-core/core/src/Barcode.h +191 -0
  31. package/cpp/zxing-core/core/src/BarcodeData.h +100 -0
  32. package/cpp/zxing-core/core/src/BarcodeFormat.cpp +286 -0
  33. package/cpp/zxing-core/core/src/BarcodeFormat.h +272 -0
  34. package/cpp/zxing-core/core/src/BinaryBitmap.cpp +111 -0
  35. package/cpp/zxing-core/core/src/BinaryBitmap.h +66 -0
  36. package/cpp/zxing-core/core/src/BitArray.cpp +38 -0
  37. package/cpp/zxing-core/core/src/BitArray.h +181 -0
  38. package/cpp/zxing-core/core/src/BitMatrix.cpp +175 -0
  39. package/cpp/zxing-core/core/src/BitMatrix.h +199 -0
  40. package/cpp/zxing-core/core/src/BitMatrixCursor.h +253 -0
  41. package/cpp/zxing-core/core/src/BitMatrixIO.cpp +101 -0
  42. package/cpp/zxing-core/core/src/BitMatrixIO.h +21 -0
  43. package/cpp/zxing-core/core/src/BitSource.cpp +77 -0
  44. package/cpp/zxing-core/core/src/BitSource.h +72 -0
  45. package/cpp/zxing-core/core/src/ByteArray.h +42 -0
  46. package/cpp/zxing-core/core/src/CharacterSet.cpp +78 -0
  47. package/cpp/zxing-core/core/src/CharacterSet.h +58 -0
  48. package/cpp/zxing-core/core/src/ConcentricFinder.cpp +312 -0
  49. package/cpp/zxing-core/core/src/ConcentricFinder.h +156 -0
  50. package/cpp/zxing-core/core/src/Content.cpp +471 -0
  51. package/cpp/zxing-core/core/src/Content.h +82 -0
  52. package/cpp/zxing-core/core/src/ContentType.h +19 -0
  53. package/cpp/zxing-core/core/src/CreateBarcode.cpp +490 -0
  54. package/cpp/zxing-core/core/src/CreateBarcode.h +132 -0
  55. package/cpp/zxing-core/core/src/DecoderResult.h +92 -0
  56. package/cpp/zxing-core/core/src/DetectorResult.h +44 -0
  57. package/cpp/zxing-core/core/src/ECI.cpp +81 -0
  58. package/cpp/zxing-core/core/src/ECI.h +78 -0
  59. package/cpp/zxing-core/core/src/Error.cpp +29 -0
  60. package/cpp/zxing-core/core/src/Error.h +79 -0
  61. package/cpp/zxing-core/core/src/Flags.h +165 -0
  62. package/cpp/zxing-core/core/src/GTIN.cpp +253 -0
  63. package/cpp/zxing-core/core/src/GTIN.h +58 -0
  64. package/cpp/zxing-core/core/src/GlobalHistogramBinarizer.cpp +197 -0
  65. package/cpp/zxing-core/core/src/GlobalHistogramBinarizer.h +34 -0
  66. package/cpp/zxing-core/core/src/GridSampler.cpp +124 -0
  67. package/cpp/zxing-core/core/src/GridSampler.h +59 -0
  68. package/cpp/zxing-core/core/src/HRI.cpp +343 -0
  69. package/cpp/zxing-core/core/src/HRI.h +16 -0
  70. package/cpp/zxing-core/core/src/HybridBinarizer.cpp +315 -0
  71. package/cpp/zxing-core/core/src/HybridBinarizer.h +40 -0
  72. package/cpp/zxing-core/core/src/ImageView.h +168 -0
  73. package/cpp/zxing-core/core/src/JSON.cpp +154 -0
  74. package/cpp/zxing-core/core/src/JSON.h +66 -0
  75. package/cpp/zxing-core/core/src/LocalGrid.cpp +242 -0
  76. package/cpp/zxing-core/core/src/LocalGrid.h +91 -0
  77. package/cpp/zxing-core/core/src/LogMatrix.h +105 -0
  78. package/cpp/zxing-core/core/src/Matrix.h +125 -0
  79. package/cpp/zxing-core/core/src/MultiFormatReader.cpp +107 -0
  80. package/cpp/zxing-core/core/src/MultiFormatReader.h +34 -0
  81. package/cpp/zxing-core/core/src/MultiFormatWriter.cpp +111 -0
  82. package/cpp/zxing-core/core/src/MultiFormatWriter.h +62 -0
  83. package/cpp/zxing-core/core/src/Pattern.h +472 -0
  84. package/cpp/zxing-core/core/src/PerspectiveTransform.cpp +81 -0
  85. package/cpp/zxing-core/core/src/PerspectiveTransform.h +47 -0
  86. package/cpp/zxing-core/core/src/Point.h +185 -0
  87. package/cpp/zxing-core/core/src/Quadrilateral.h +215 -0
  88. package/cpp/zxing-core/core/src/Range.h +112 -0
  89. package/cpp/zxing-core/core/src/ReadBarcode.cpp +335 -0
  90. package/cpp/zxing-core/core/src/ReadBarcode.h +33 -0
  91. package/cpp/zxing-core/core/src/Reader.h +32 -0
  92. package/cpp/zxing-core/core/src/ReaderOptions.h +210 -0
  93. package/cpp/zxing-core/core/src/ReedSolomon.cpp +100 -0
  94. package/cpp/zxing-core/core/src/ReedSolomon.h +66 -0
  95. package/cpp/zxing-core/core/src/RegressionLine.h +161 -0
  96. package/cpp/zxing-core/core/src/ResultPoint.cpp +20 -0
  97. package/cpp/zxing-core/core/src/ResultPoint.h +35 -0
  98. package/cpp/zxing-core/core/src/StdGenerator.h +121 -0
  99. package/cpp/zxing-core/core/src/StdPrint.h +38 -0
  100. package/cpp/zxing-core/core/src/StdScope.h +55 -0
  101. package/cpp/zxing-core/core/src/StructuredAppend.h +19 -0
  102. package/cpp/zxing-core/core/src/SymbologyIdentifier.h +29 -0
  103. package/cpp/zxing-core/core/src/TextDecoder.cpp +59 -0
  104. package/cpp/zxing-core/core/src/TextDecoder.h +23 -0
  105. package/cpp/zxing-core/core/src/TextEncoder.cpp +75 -0
  106. package/cpp/zxing-core/core/src/TextEncoder.h +31 -0
  107. package/cpp/zxing-core/core/src/ThresholdBinarizer.h +58 -0
  108. package/cpp/zxing-core/core/src/TritMatrix.h +29 -0
  109. package/cpp/zxing-core/core/src/Utf.cpp +276 -0
  110. package/cpp/zxing-core/core/src/Utf.h +26 -0
  111. package/cpp/zxing-core/core/src/WhiteRectDetector.cpp +276 -0
  112. package/cpp/zxing-core/core/src/WhiteRectDetector.h +36 -0
  113. package/cpp/zxing-core/core/src/WriteBarcode.cpp +213 -0
  114. package/cpp/zxing-core/core/src/WriteBarcode.h +72 -0
  115. package/cpp/zxing-core/core/src/ZXAlgorithms.h +353 -0
  116. package/cpp/zxing-core/core/src/ZXConfig.h +17 -0
  117. package/cpp/zxing-core/core/src/ZXTestSupport.h +9 -0
  118. package/cpp/zxing-core/core/src/ZXVersion.h +14 -0
  119. package/cpp/zxing-core/core/src/ZXingC.cpp +460 -0
  120. package/cpp/zxing-core/core/src/ZXingC.h +296 -0
  121. package/cpp/zxing-core/core/src/ZXingCpp.cpp +18 -0
  122. package/cpp/zxing-core/core/src/ZXingCpp.h +76 -0
  123. package/cpp/zxing-core/core/src/ZXingQt.h +606 -0
  124. package/cpp/zxing-core/core/src/aztec/AZDecoder.cpp +376 -0
  125. package/cpp/zxing-core/core/src/aztec/AZDecoder.h +20 -0
  126. package/cpp/zxing-core/core/src/aztec/AZDetector.cpp +508 -0
  127. package/cpp/zxing-core/core/src/aztec/AZDetector.h +25 -0
  128. package/cpp/zxing-core/core/src/aztec/AZDetectorResult.h +51 -0
  129. package/cpp/zxing-core/core/src/aztec/AZEncoder.cpp +318 -0
  130. package/cpp/zxing-core/core/src/aztec/AZEncoder.h +44 -0
  131. package/cpp/zxing-core/core/src/aztec/AZEncodingState.h +40 -0
  132. package/cpp/zxing-core/core/src/aztec/AZHighLevelEncoder.cpp +377 -0
  133. package/cpp/zxing-core/core/src/aztec/AZHighLevelEncoder.h +36 -0
  134. package/cpp/zxing-core/core/src/aztec/AZReader.cpp +45 -0
  135. package/cpp/zxing-core/core/src/aztec/AZReader.h +21 -0
  136. package/cpp/zxing-core/core/src/aztec/AZToken.cpp +44 -0
  137. package/cpp/zxing-core/core/src/aztec/AZToken.h +39 -0
  138. package/cpp/zxing-core/core/src/aztec/AZWriter.cpp +38 -0
  139. package/cpp/zxing-core/core/src/aztec/AZWriter.h +55 -0
  140. package/cpp/zxing-core/core/src/datamatrix/DMBitLayout.cpp +194 -0
  141. package/cpp/zxing-core/core/src/datamatrix/DMBitLayout.h +21 -0
  142. package/cpp/zxing-core/core/src/datamatrix/DMDataBlock.cpp +63 -0
  143. package/cpp/zxing-core/core/src/datamatrix/DMDataBlock.h +41 -0
  144. package/cpp/zxing-core/core/src/datamatrix/DMDecoder.cpp +457 -0
  145. package/cpp/zxing-core/core/src/datamatrix/DMDecoder.h +19 -0
  146. package/cpp/zxing-core/core/src/datamatrix/DMDetector.cpp +1230 -0
  147. package/cpp/zxing-core/core/src/datamatrix/DMDetector.h +23 -0
  148. package/cpp/zxing-core/core/src/datamatrix/DMECEncoder.cpp +137 -0
  149. package/cpp/zxing-core/core/src/datamatrix/DMECEncoder.h +26 -0
  150. package/cpp/zxing-core/core/src/datamatrix/DMEncoderContext.h +128 -0
  151. package/cpp/zxing-core/core/src/datamatrix/DMHighLevelEncoder.cpp +919 -0
  152. package/cpp/zxing-core/core/src/datamatrix/DMHighLevelEncoder.h +29 -0
  153. package/cpp/zxing-core/core/src/datamatrix/DMReader.cpp +40 -0
  154. package/cpp/zxing-core/core/src/datamatrix/DMReader.h +21 -0
  155. package/cpp/zxing-core/core/src/datamatrix/DMSymbolInfo.cpp +141 -0
  156. package/cpp/zxing-core/core/src/datamatrix/DMSymbolInfo.h +78 -0
  157. package/cpp/zxing-core/core/src/datamatrix/DMSymbolShape.h +17 -0
  158. package/cpp/zxing-core/core/src/datamatrix/DMVersion.cpp +82 -0
  159. package/cpp/zxing-core/core/src/datamatrix/DMVersion.h +76 -0
  160. package/cpp/zxing-core/core/src/datamatrix/DMWriter.cpp +114 -0
  161. package/cpp/zxing-core/core/src/datamatrix/DMWriter.h +62 -0
  162. package/cpp/zxing-core/core/src/librscpp/README.md +65 -0
  163. package/cpp/zxing-core/core/src/librscpp/decode.h +258 -0
  164. package/cpp/zxing-core/core/src/librscpp/encode.h +124 -0
  165. package/cpp/zxing-core/core/src/librscpp/field.h +158 -0
  166. package/cpp/zxing-core/core/src/librscpp/poly.h +194 -0
  167. package/cpp/zxing-core/core/src/libzint/2of5inter.c +1 -0
  168. package/cpp/zxing-core/core/src/libzint/2of5inter_based.c +1 -0
  169. package/cpp/zxing-core/core/src/libzint/aztec.c +1 -0
  170. package/cpp/zxing-core/core/src/libzint/aztec.h +1 -0
  171. package/cpp/zxing-core/core/src/libzint/big5.h +1 -0
  172. package/cpp/zxing-core/core/src/libzint/codabar.c +1 -0
  173. package/cpp/zxing-core/core/src/libzint/code.c +1 -0
  174. package/cpp/zxing-core/core/src/libzint/code128.c +1 -0
  175. package/cpp/zxing-core/core/src/libzint/code128.h +1 -0
  176. package/cpp/zxing-core/core/src/libzint/common.c +1 -0
  177. package/cpp/zxing-core/core/src/libzint/common.h +1 -0
  178. package/cpp/zxing-core/core/src/libzint/dmatrix.c +1 -0
  179. package/cpp/zxing-core/core/src/libzint/dmatrix.h +1 -0
  180. package/cpp/zxing-core/core/src/libzint/dxfilmedge.c +1 -0
  181. package/cpp/zxing-core/core/src/libzint/eci.c +1 -0
  182. package/cpp/zxing-core/core/src/libzint/eci.h +1 -0
  183. package/cpp/zxing-core/core/src/libzint/eci_sb.h +1 -0
  184. package/cpp/zxing-core/core/src/libzint/filemem.c +1 -0
  185. package/cpp/zxing-core/core/src/libzint/filemem.h +1 -0
  186. package/cpp/zxing-core/core/src/libzint/fonts/normal_woff2.h +1 -0
  187. package/cpp/zxing-core/core/src/libzint/fonts/upcean_woff2.h +1 -0
  188. package/cpp/zxing-core/core/src/libzint/gb18030.h +1 -0
  189. package/cpp/zxing-core/core/src/libzint/gb2312.h +1 -0
  190. package/cpp/zxing-core/core/src/libzint/gbk.h +1 -0
  191. package/cpp/zxing-core/core/src/libzint/general_field.c +1 -0
  192. package/cpp/zxing-core/core/src/libzint/general_field.h +1 -0
  193. package/cpp/zxing-core/core/src/libzint/gs1.c +1 -0
  194. package/cpp/zxing-core/core/src/libzint/gs1.h +1 -0
  195. package/cpp/zxing-core/core/src/libzint/gs1_lint.h +1 -0
  196. package/cpp/zxing-core/core/src/libzint/iso3166.h +1 -0
  197. package/cpp/zxing-core/core/src/libzint/iso4217.h +1 -0
  198. package/cpp/zxing-core/core/src/libzint/ksx1001.h +1 -0
  199. package/cpp/zxing-core/core/src/libzint/large.c +1 -0
  200. package/cpp/zxing-core/core/src/libzint/large.h +1 -0
  201. package/cpp/zxing-core/core/src/libzint/library.c +1 -0
  202. package/cpp/zxing-core/core/src/libzint/maxicode.c +1 -0
  203. package/cpp/zxing-core/core/src/libzint/maxicode.h +1 -0
  204. package/cpp/zxing-core/core/src/libzint/medical.c +1 -0
  205. package/cpp/zxing-core/core/src/libzint/output.c +1 -0
  206. package/cpp/zxing-core/core/src/libzint/output.h +1 -0
  207. package/cpp/zxing-core/core/src/libzint/pdf417.c +1 -0
  208. package/cpp/zxing-core/core/src/libzint/pdf417.h +1 -0
  209. package/cpp/zxing-core/core/src/libzint/pdf417_tabs.h +1 -0
  210. package/cpp/zxing-core/core/src/libzint/qr.c +1 -0
  211. package/cpp/zxing-core/core/src/libzint/qr.h +1 -0
  212. package/cpp/zxing-core/core/src/libzint/raster.c +1 -0
  213. package/cpp/zxing-core/core/src/libzint/raster_font.h +1 -0
  214. package/cpp/zxing-core/core/src/libzint/reedsol.c +1 -0
  215. package/cpp/zxing-core/core/src/libzint/reedsol.h +1 -0
  216. package/cpp/zxing-core/core/src/libzint/reedsol_logs.h +1 -0
  217. package/cpp/zxing-core/core/src/libzint/rss.c +1 -0
  218. package/cpp/zxing-core/core/src/libzint/rss.h +1 -0
  219. package/cpp/zxing-core/core/src/libzint/sjis.h +1 -0
  220. package/cpp/zxing-core/core/src/libzint/stubs.c +137 -0
  221. package/cpp/zxing-core/core/src/libzint/svg.c +1 -0
  222. package/cpp/zxing-core/core/src/libzint/telepen.c +1 -0
  223. package/cpp/zxing-core/core/src/libzint/upcean.c +1 -0
  224. package/cpp/zxing-core/core/src/libzint/vector.c +1 -0
  225. package/cpp/zxing-core/core/src/libzint/zfiletypes.h +1 -0
  226. package/cpp/zxing-core/core/src/libzint/zint.h +1 -0
  227. package/cpp/zxing-core/core/src/libzint/zintconfig.h +1 -0
  228. package/cpp/zxing-core/core/src/libzueci/README.md +11 -0
  229. package/cpp/zxing-core/core/src/libzueci/zueci.c +1718 -0
  230. package/cpp/zxing-core/core/src/libzueci/zueci.h +179 -0
  231. package/cpp/zxing-core/core/src/libzueci/zueci_big5.h +3884 -0
  232. package/cpp/zxing-core/core/src/libzueci/zueci_common.h +31 -0
  233. package/cpp/zxing-core/core/src/libzueci/zueci_gb18030.h +264 -0
  234. package/cpp/zxing-core/core/src/libzueci/zueci_gb2312.h +2381 -0
  235. package/cpp/zxing-core/core/src/libzueci/zueci_gbk.h +4047 -0
  236. package/cpp/zxing-core/core/src/libzueci/zueci_ksx1001.h +2932 -0
  237. package/cpp/zxing-core/core/src/libzueci/zueci_sb.h +1112 -0
  238. package/cpp/zxing-core/core/src/libzueci/zueci_sjis.h +2286 -0
  239. package/cpp/zxing-core/core/src/maxicode/MCBitMatrixParser.cpp +68 -0
  240. package/cpp/zxing-core/core/src/maxicode/MCBitMatrixParser.h +30 -0
  241. package/cpp/zxing-core/core/src/maxicode/MCDecoder.cpp +329 -0
  242. package/cpp/zxing-core/core/src/maxicode/MCDecoder.h +19 -0
  243. package/cpp/zxing-core/core/src/maxicode/MCReader.cpp +65 -0
  244. package/cpp/zxing-core/core/src/maxicode/MCReader.h +21 -0
  245. package/cpp/zxing-core/core/src/oned/ODCodabarReader.cpp +102 -0
  246. package/cpp/zxing-core/core/src/oned/ODCodabarReader.h +21 -0
  247. package/cpp/zxing-core/core/src/oned/ODCodabarWriter.cpp +136 -0
  248. package/cpp/zxing-core/core/src/oned/ODCodabarWriter.h +34 -0
  249. package/cpp/zxing-core/core/src/oned/ODCode128Patterns.h +130 -0
  250. package/cpp/zxing-core/core/src/oned/ODCode128Reader.cpp +236 -0
  251. package/cpp/zxing-core/core/src/oned/ODCode128Reader.h +21 -0
  252. package/cpp/zxing-core/core/src/oned/ODCode128Writer.cpp +261 -0
  253. package/cpp/zxing-core/core/src/oned/ODCode128Writer.h +34 -0
  254. package/cpp/zxing-core/core/src/oned/ODCode39Reader.cpp +213 -0
  255. package/cpp/zxing-core/core/src/oned/ODCode39Reader.h +26 -0
  256. package/cpp/zxing-core/core/src/oned/ODCode39Writer.cpp +176 -0
  257. package/cpp/zxing-core/core/src/oned/ODCode39Writer.h +34 -0
  258. package/cpp/zxing-core/core/src/oned/ODCode93Patterns.h +80 -0
  259. package/cpp/zxing-core/core/src/oned/ODCode93Reader.cpp +112 -0
  260. package/cpp/zxing-core/core/src/oned/ODCode93Reader.h +21 -0
  261. package/cpp/zxing-core/core/src/oned/ODCode93Writer.cpp +192 -0
  262. package/cpp/zxing-core/core/src/oned/ODCode93Writer.h +32 -0
  263. package/cpp/zxing-core/core/src/oned/ODDXFilmEdgeReader.cpp +246 -0
  264. package/cpp/zxing-core/core/src/oned/ODDXFilmEdgeReader.h +26 -0
  265. package/cpp/zxing-core/core/src/oned/ODDataBarCommon.cpp +172 -0
  266. package/cpp/zxing-core/core/src/oned/ODDataBarCommon.h +204 -0
  267. package/cpp/zxing-core/core/src/oned/ODDataBarExpandedBitDecoder.cpp +253 -0
  268. package/cpp/zxing-core/core/src/oned/ODDataBarExpandedBitDecoder.h +19 -0
  269. package/cpp/zxing-core/core/src/oned/ODDataBarExpandedReader.cpp +383 -0
  270. package/cpp/zxing-core/core/src/oned/ODDataBarExpandedReader.h +25 -0
  271. package/cpp/zxing-core/core/src/oned/ODDataBarLimitedReader.cpp +163 -0
  272. package/cpp/zxing-core/core/src/oned/ODDataBarLimitedReader.h +23 -0
  273. package/cpp/zxing-core/core/src/oned/ODDataBarReader.cpp +240 -0
  274. package/cpp/zxing-core/core/src/oned/ODDataBarReader.h +25 -0
  275. package/cpp/zxing-core/core/src/oned/ODEAN13Writer.cpp +62 -0
  276. package/cpp/zxing-core/core/src/oned/ODEAN13Writer.h +34 -0
  277. package/cpp/zxing-core/core/src/oned/ODEAN8Writer.cpp +51 -0
  278. package/cpp/zxing-core/core/src/oned/ODEAN8Writer.h +34 -0
  279. package/cpp/zxing-core/core/src/oned/ODITFReader.cpp +97 -0
  280. package/cpp/zxing-core/core/src/oned/ODITFReader.h +33 -0
  281. package/cpp/zxing-core/core/src/oned/ODITFWriter.cpp +78 -0
  282. package/cpp/zxing-core/core/src/oned/ODITFWriter.h +34 -0
  283. package/cpp/zxing-core/core/src/oned/ODMultiUPCEANReader.cpp +323 -0
  284. package/cpp/zxing-core/core/src/oned/ODMultiUPCEANReader.h +32 -0
  285. package/cpp/zxing-core/core/src/oned/ODReader.cpp +259 -0
  286. package/cpp/zxing-core/core/src/oned/ODReader.h +35 -0
  287. package/cpp/zxing-core/core/src/oned/ODRowReader.h +222 -0
  288. package/cpp/zxing-core/core/src/oned/ODTelepenReader.cpp +199 -0
  289. package/cpp/zxing-core/core/src/oned/ODTelepenReader.h +25 -0
  290. package/cpp/zxing-core/core/src/oned/ODUPCAWriter.cpp +33 -0
  291. package/cpp/zxing-core/core/src/oned/ODUPCAWriter.h +34 -0
  292. package/cpp/zxing-core/core/src/oned/ODUPCEANCommon.cpp +80 -0
  293. package/cpp/zxing-core/core/src/oned/ODUPCEANCommon.h +129 -0
  294. package/cpp/zxing-core/core/src/oned/ODUPCEWriter.cpp +56 -0
  295. package/cpp/zxing-core/core/src/oned/ODUPCEWriter.h +34 -0
  296. package/cpp/zxing-core/core/src/oned/ODWriterHelper.cpp +39 -0
  297. package/cpp/zxing-core/core/src/oned/ODWriterHelper.h +48 -0
  298. package/cpp/zxing-core/core/src/pdf417/MicroPDFReader.cpp +796 -0
  299. package/cpp/zxing-core/core/src/pdf417/MicroPDFReader.h +23 -0
  300. package/cpp/zxing-core/core/src/pdf417/PDF417.cpp +85 -0
  301. package/cpp/zxing-core/core/src/pdf417/PDF417.h +81 -0
  302. package/cpp/zxing-core/core/src/pdf417/PDFBarcodeMetadata.h +53 -0
  303. package/cpp/zxing-core/core/src/pdf417/PDFBarcodeValue.cpp +48 -0
  304. package/cpp/zxing-core/core/src/pdf417/PDFBarcodeValue.h +38 -0
  305. package/cpp/zxing-core/core/src/pdf417/PDFBoundingBox.cpp +116 -0
  306. package/cpp/zxing-core/core/src/pdf417/PDFBoundingBox.h +75 -0
  307. package/cpp/zxing-core/core/src/pdf417/PDFCodeword.h +71 -0
  308. package/cpp/zxing-core/core/src/pdf417/PDFCodewordDecoder.cpp +588 -0
  309. package/cpp/zxing-core/core/src/pdf417/PDFCodewordDecoder.h +41 -0
  310. package/cpp/zxing-core/core/src/pdf417/PDFCompaction.h +20 -0
  311. package/cpp/zxing-core/core/src/pdf417/PDFCustomData.h +32 -0
  312. package/cpp/zxing-core/core/src/pdf417/PDFDecoder.cpp +725 -0
  313. package/cpp/zxing-core/core/src/pdf417/PDFDecoder.h +20 -0
  314. package/cpp/zxing-core/core/src/pdf417/PDFDetectionResult.cpp +247 -0
  315. package/cpp/zxing-core/core/src/pdf417/PDFDetectionResult.h +74 -0
  316. package/cpp/zxing-core/core/src/pdf417/PDFDetectionResultColumn.cpp +321 -0
  317. package/cpp/zxing-core/core/src/pdf417/PDFDetectionResultColumn.h +83 -0
  318. package/cpp/zxing-core/core/src/pdf417/PDFDetector.cpp +371 -0
  319. package/cpp/zxing-core/core/src/pdf417/PDFDetector.h +45 -0
  320. package/cpp/zxing-core/core/src/pdf417/PDFEncoder.cpp +570 -0
  321. package/cpp/zxing-core/core/src/pdf417/PDFEncoder.h +182 -0
  322. package/cpp/zxing-core/core/src/pdf417/PDFHighLevelEncoder.cpp +570 -0
  323. package/cpp/zxing-core/core/src/pdf417/PDFHighLevelEncoder.h +32 -0
  324. package/cpp/zxing-core/core/src/pdf417/PDFReader.cpp +333 -0
  325. package/cpp/zxing-core/core/src/pdf417/PDFReader.h +28 -0
  326. package/cpp/zxing-core/core/src/pdf417/PDFScanningDecoder.cpp +559 -0
  327. package/cpp/zxing-core/core/src/pdf417/PDFScanningDecoder.h +41 -0
  328. package/cpp/zxing-core/core/src/pdf417/PDFWriter.cpp +170 -0
  329. package/cpp/zxing-core/core/src/pdf417/PDFWriter.h +74 -0
  330. package/cpp/zxing-core/core/src/pdf417/ZXBigInteger.cpp +623 -0
  331. package/cpp/zxing-core/core/src/pdf417/ZXBigInteger.h +81 -0
  332. package/cpp/zxing-core/core/src/pdf417/ZXNullable.h +105 -0
  333. package/cpp/zxing-core/core/src/qrcode/QRBitMatrixParser.cpp +294 -0
  334. package/cpp/zxing-core/core/src/qrcode/QRBitMatrixParser.h +41 -0
  335. package/cpp/zxing-core/core/src/qrcode/QRCodecMode.cpp +95 -0
  336. package/cpp/zxing-core/core/src/qrcode/QRCodecMode.h +59 -0
  337. package/cpp/zxing-core/core/src/qrcode/QRDataBlock.cpp +93 -0
  338. package/cpp/zxing-core/core/src/qrcode/QRDataBlock.h +52 -0
  339. package/cpp/zxing-core/core/src/qrcode/QRDataMask.h +50 -0
  340. package/cpp/zxing-core/core/src/qrcode/QRDecoder.cpp +359 -0
  341. package/cpp/zxing-core/core/src/qrcode/QRDecoder.h +19 -0
  342. package/cpp/zxing-core/core/src/qrcode/QRDetector.cpp +920 -0
  343. package/cpp/zxing-core/core/src/qrcode/QRDetector.h +45 -0
  344. package/cpp/zxing-core/core/src/qrcode/QRECB.h +52 -0
  345. package/cpp/zxing-core/core/src/qrcode/QREncodeResult.h +33 -0
  346. package/cpp/zxing-core/core/src/qrcode/QREncoder.cpp +568 -0
  347. package/cpp/zxing-core/core/src/qrcode/QREncoder.h +21 -0
  348. package/cpp/zxing-core/core/src/qrcode/QRErrorCorrectionLevel.cpp +51 -0
  349. package/cpp/zxing-core/core/src/qrcode/QRErrorCorrectionLevel.h +39 -0
  350. package/cpp/zxing-core/core/src/qrcode/QRFormatInformation.cpp +160 -0
  351. package/cpp/zxing-core/core/src/qrcode/QRFormatInformation.h +61 -0
  352. package/cpp/zxing-core/core/src/qrcode/QRMaskUtil.cpp +156 -0
  353. package/cpp/zxing-core/core/src/qrcode/QRMaskUtil.h +15 -0
  354. package/cpp/zxing-core/core/src/qrcode/QRMatrixUtil.cpp +318 -0
  355. package/cpp/zxing-core/core/src/qrcode/QRMatrixUtil.h +25 -0
  356. package/cpp/zxing-core/core/src/qrcode/QRReader.cpp +149 -0
  357. package/cpp/zxing-core/core/src/qrcode/QRReader.h +21 -0
  358. package/cpp/zxing-core/core/src/qrcode/QRVersion.cpp +754 -0
  359. package/cpp/zxing-core/core/src/qrcode/QRVersion.h +127 -0
  360. package/cpp/zxing-core/core/src/qrcode/QRWriter.cpp +51 -0
  361. package/cpp/zxing-core/core/src/qrcode/QRWriter.h +74 -0
  362. package/cpp/zxing-core/core/version.rc.in +34 -0
  363. package/cpp/zxing-core/core/zxing.pc.in +8 -0
  364. package/cpp/zxing-core/wrappers/ios/README.md +25 -0
  365. package/cpp/zxing-core/wrappers/ios/Sources/Wrapper/Version.h +29 -0
  366. package/cpp/zxing-core/zxing-cpp.podspec +45 -0
  367. package/lib/factory.d.ts +10 -0
  368. package/lib/factory.js +12 -0
  369. package/lib/index.d.ts +9 -0
  370. package/lib/index.js +9 -0
  371. package/lib/specs/Barcode.nitro.d.ts +63 -0
  372. package/lib/specs/Barcode.nitro.js +1 -0
  373. package/lib/specs/BarcodeFormat.d.ts +11 -0
  374. package/lib/specs/BarcodeFormat.js +1 -0
  375. package/lib/specs/BarcodeScanner.nitro.d.ts +89 -0
  376. package/lib/specs/BarcodeScanner.nitro.js +1 -0
  377. package/lib/specs/BarcodeScannerFactory.nitro.d.ts +26 -0
  378. package/lib/specs/BarcodeScannerFactory.nitro.js +1 -0
  379. package/lib/specs/BarcodeValueType.d.ts +9 -0
  380. package/lib/specs/BarcodeValueType.js +1 -0
  381. package/lib/specs/Point.d.ts +14 -0
  382. package/lib/specs/Point.js +1 -0
  383. package/lib/specs/Rect.d.ts +22 -0
  384. package/lib/specs/Rect.js +1 -0
  385. package/lib/useBarcodeScanner.d.ts +23 -0
  386. package/lib/useBarcodeScanner.js +25 -0
  387. package/nitro.json +20 -0
  388. package/nitrogen/generated/.gitattributes +1 -0
  389. package/nitrogen/generated/android/VisionCameraZxing+autolinking.cmake +83 -0
  390. package/nitrogen/generated/android/VisionCameraZxing+autolinking.gradle +27 -0
  391. package/nitrogen/generated/android/VisionCameraZxingOnLoad.cpp +49 -0
  392. package/nitrogen/generated/android/VisionCameraZxingOnLoad.hpp +34 -0
  393. package/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/zxing/VisionCameraZxingOnLoad.kt +35 -0
  394. package/nitrogen/generated/ios/VisionCameraZxing+autolinking.rb +62 -0
  395. package/nitrogen/generated/ios/VisionCameraZxing-Swift-Cxx-Bridge.cpp +17 -0
  396. package/nitrogen/generated/ios/VisionCameraZxing-Swift-Cxx-Bridge.hpp +27 -0
  397. package/nitrogen/generated/ios/VisionCameraZxing-Swift-Cxx-Umbrella.hpp +38 -0
  398. package/nitrogen/generated/ios/VisionCameraZxingAutolinking.mm +35 -0
  399. package/nitrogen/generated/ios/VisionCameraZxingAutolinking.swift +16 -0
  400. package/nitrogen/generated/shared/c++/BarcodeFormat.hpp +124 -0
  401. package/nitrogen/generated/shared/c++/BarcodeScannerOptions.hpp +85 -0
  402. package/nitrogen/generated/shared/c++/BarcodeValueType.hpp +120 -0
  403. package/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.cpp +23 -0
  404. package/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.hpp +74 -0
  405. package/nitrogen/generated/shared/c++/HybridBarcodeSpec.cpp +27 -0
  406. package/nitrogen/generated/shared/c++/HybridBarcodeSpec.hpp +82 -0
  407. package/nitrogen/generated/shared/c++/HybridZXingBarcodeScannerFactorySpec.cpp +21 -0
  408. package/nitrogen/generated/shared/c++/HybridZXingBarcodeScannerFactorySpec.hpp +67 -0
  409. package/nitrogen/generated/shared/c++/Point.hpp +87 -0
  410. package/nitrogen/generated/shared/c++/Rect.hpp +95 -0
  411. package/nitrogen/generated/shared/c++/TargetBarcodeFormat.hpp +124 -0
  412. package/package.json +108 -0
  413. package/react-native.config.js +16 -0
  414. package/src/factory.ts +26 -0
  415. package/src/index.ts +9 -0
  416. package/src/specs/Barcode.nitro.ts +70 -0
  417. package/src/specs/BarcodeFormat.ts +31 -0
  418. package/src/specs/BarcodeScanner.nitro.ts +91 -0
  419. package/src/specs/BarcodeScannerFactory.nitro.ts +27 -0
  420. package/src/specs/BarcodeValueType.ts +25 -0
  421. package/src/specs/Point.ts +14 -0
  422. package/src/specs/Rect.ts +22 -0
  423. package/src/useBarcodeScanner.ts +36 -0
@@ -0,0 +1,796 @@
1
+ /*
2
+ * Copyright 2026 Axel Waggershauser
3
+ */
4
+ // SPDX-License-Identifier: Apache-2.0
5
+
6
+ #include "MicroPDFReader.h"
7
+
8
+ #include "BinaryBitmap.h"
9
+ #include "BitArray.h"
10
+ #include "BitMatrixCursor.h"
11
+ #include "ReaderOptions.h"
12
+ #include "DecoderResult.h"
13
+ #include "LogMatrix.h"
14
+ #include "PDF417.h"
15
+ #include "PDFCodewordDecoder.h"
16
+ #include "PDFScanningDecoder.h"
17
+ #include "Pattern.h"
18
+ #include "PerspectiveTransform.h"
19
+ #include "RegressionLine.h"
20
+
21
+ #include <list>
22
+ #include <limits>
23
+ #include <vector>
24
+
25
+ #define LRAP_WITH_CW 1
26
+ #define USE_E2E_PATTERNS
27
+
28
+ namespace ZXing::MicroPdf417 {
29
+
30
+ using namespace PDF417;
31
+
32
+ static constexpr FixedPattern<6, 10> LRRAPs[] = {
33
+ {2, 2, 1, 3, 1, 1}, /* 1*/
34
+ {3, 1, 1, 3, 1, 1}, /* 2*/
35
+ {3, 1, 2, 2, 1, 1}, /* 3*/
36
+ {2, 2, 2, 2, 1, 1}, /* 4*/
37
+ {2, 1, 3, 2, 1, 1}, /* 5*/
38
+ {2, 1, 4, 1, 1, 1}, /* 6*/
39
+ {2, 2, 3, 1, 1, 1}, /* 7*/
40
+ {3, 1, 3, 1, 1, 1}, /* 8*/
41
+ {3, 2, 2, 1, 1, 1}, /* 9*/
42
+ {4, 1, 2, 1, 1, 1}, /*10*/
43
+ {4, 2, 1, 1, 1, 1}, /*11*/
44
+ {3, 3, 1, 1, 1, 1}, /*12*/
45
+ {2, 4, 1, 1, 1, 1}, /*13*/
46
+ {2, 3, 2, 1, 1, 1}, /*14*/
47
+ {2, 3, 1, 2, 1, 1}, /*15*/
48
+ {3, 2, 1, 2, 1, 1}, /*16*/
49
+ {4, 1, 1, 2, 1, 1}, /*17*/
50
+ {4, 1, 1, 1, 2, 1}, /*18*/
51
+ {4, 1, 1, 1, 1, 2}, /*19*/
52
+ {3, 2, 1, 1, 1, 2}, /*20*/
53
+ {3, 1, 2, 1, 1, 2}, /*21*/
54
+ {3, 1, 1, 2, 1, 2}, /*22*/
55
+ {3, 1, 1, 2, 2, 1}, /*23*/
56
+ {3, 1, 1, 1, 3, 1}, /*24*/
57
+ {3, 1, 1, 1, 2, 2}, /*25*/
58
+ {3, 1, 1, 1, 1, 3}, /*26*/
59
+ {2, 2, 1, 1, 1, 3}, /*27*/
60
+ {2, 2, 1, 1, 2, 2}, /*28*/
61
+ {2, 2, 1, 1, 3, 1}, /*29*/
62
+ {2, 2, 1, 2, 2, 1}, /*30*/
63
+ {2, 2, 2, 1, 2, 1}, /*31*/
64
+ {3, 1, 2, 1, 2, 1}, /*32*/
65
+ {3, 2, 1, 1, 2, 1}, /*33*/
66
+ {2, 3, 1, 1, 2, 1}, /*34*/
67
+ {2, 3, 1, 1, 1, 2}, /*35*/
68
+ {2, 2, 2, 1, 1, 2}, /*36*/
69
+ {2, 1, 3, 1, 1, 2}, /*37*/
70
+ {2, 1, 2, 2, 1, 2}, /*38*/
71
+ {2, 1, 2, 2, 2, 1}, /*39*/
72
+ {2, 1, 2, 1, 3, 1}, /*40*/
73
+ {2, 1, 2, 1, 2, 2}, /*41*/
74
+ {2, 1, 2, 1, 1, 3}, /*42*/
75
+ {2, 1, 1, 2, 1, 3}, /*43*/
76
+ {2, 1, 1, 1, 2, 3}, /*44*/
77
+ {2, 1, 1, 1, 3, 2}, /*45*/
78
+ {2, 1, 1, 1, 4, 1}, /*46*/
79
+ {2, 1, 1, 2, 3, 1}, /*47*/
80
+ {2, 1, 1, 2, 2, 2}, /*48*/
81
+ {2, 1, 1, 3, 1, 2}, /*49*/
82
+ {2, 1, 1, 3, 2, 1}, /*50*/
83
+ {2, 1, 1, 4, 1, 1}, /*51*/
84
+ {2, 1, 2, 3, 1, 1}, /*52*/
85
+ };
86
+
87
+ static constexpr FixedPattern<6, 10> CRAPs[] = {
88
+ {1, 1, 2, 2, 3, 1}, /*01*/
89
+ {1, 2, 1, 2, 3, 1}, /*02*/
90
+ {1, 2, 2, 1, 3, 1}, /*03*/
91
+ {1, 3, 1, 1, 3, 1}, /*04*/
92
+ {1, 3, 1, 2, 2, 1}, /*05*/
93
+ {1, 3, 2, 1, 2, 1}, /*06*/
94
+ {1, 4, 1, 1, 2, 1}, /*07*/
95
+ {1, 4, 1, 2, 1, 1}, /*08*/
96
+ {1, 4, 2, 1, 1, 1}, /*09*/
97
+ {1, 3, 3, 1, 1, 1}, /*10*/
98
+ {1, 3, 2, 2, 1, 1}, /*11*/
99
+ {1, 3, 1, 3, 1, 1}, /*12*/
100
+ {1, 2, 2, 3, 1, 1}, /*13*/
101
+ {1, 2, 3, 2, 1, 1}, /*14*/
102
+ {1, 2, 4, 1, 1, 1}, /*15*/
103
+ {1, 1, 5, 1, 1, 1}, /*16*/
104
+ {1, 1, 4, 2, 1, 1}, /*17*/
105
+ {1, 1, 4, 1, 2, 1}, /*18*/
106
+ {1, 2, 3, 1, 2, 1}, /*19*/
107
+ {1, 2, 3, 1, 1, 2}, /*20*/
108
+ {1, 2, 2, 2, 1, 2}, /*21*/
109
+ {1, 2, 2, 2, 2, 1}, /*22*/
110
+ {1, 2, 1, 3, 2, 1}, /*23*/
111
+ {1, 2, 1, 4, 1, 1}, /*24*/
112
+ {1, 1, 2, 4, 1, 1}, /*25*/
113
+ {1, 1, 3, 3, 1, 1}, /*26*/
114
+ {1, 1, 3, 2, 2, 1}, /*27*/
115
+ {1, 1, 3, 2, 1, 2}, /*28*/
116
+ {1, 1, 3, 1, 2, 2}, /*29*/
117
+ {1, 2, 2, 1, 2, 2}, /*30*/
118
+ {1, 3, 1, 1, 2, 2}, /*31*/
119
+ {1, 3, 1, 1, 1, 3}, /*32*/
120
+ {1, 2, 2, 1, 1, 3}, /*33*/
121
+ {1, 1, 3, 1, 1, 3}, /*34*/
122
+ {1, 1, 2, 2, 1, 3}, /*35*/
123
+ {1, 1, 2, 2, 2, 2}, /*36*/
124
+ {1, 1, 2, 3, 1, 2}, /*37*/
125
+ {1, 1, 2, 3, 2, 1}, /*38*/
126
+ {1, 1, 1, 4, 2, 1}, /*39*/
127
+ {1, 1, 1, 3, 3, 1}, /*40*/
128
+ {1, 1, 1, 3, 2, 2}, /*41*/
129
+ {1, 1, 1, 2, 3, 2}, /*42*/
130
+ {1, 1, 1, 2, 2, 3}, /*43*/
131
+ {1, 1, 1, 1, 3, 3}, /*44*/
132
+ {1, 1, 1, 1, 2, 4}, /*45*/
133
+ {1, 1, 1, 2, 1, 4}, /*46*/
134
+ {1, 1, 2, 1, 1, 4}, /*47*/
135
+ {1, 2, 1, 1, 1, 4}, /*48*/
136
+ {1, 2, 1, 1, 2, 3}, /*49*/
137
+ {1, 2, 1, 1, 3, 2}, /*50*/
138
+ {1, 1, 2, 1, 3, 2}, /*51*/
139
+ {1, 1, 2, 1, 4, 1}, /*52*/
140
+ };
141
+
142
+ static constexpr auto ToInts(const FixedPattern<6, 10> in[52])
143
+ {
144
+ std::array<int, 52> res{};
145
+ for (int i = 0; i < 52; ++i)
146
+ #ifdef USE_E2E_PATTERNS
147
+ res[i] = ToInt(NormalizedE2EPattern<6, 10, 5>(in[i]));
148
+ #else
149
+ res[i] = ToInt(in[i]);
150
+ #endif
151
+ return res;
152
+ }
153
+
154
+ static constexpr auto LRRAPInts = ToInts(LRRAPs);
155
+ static constexpr auto CRAPInts = ToInts(CRAPs);
156
+
157
+ enum class RAP {L, C, R};
158
+
159
+ static int RAPIndex(int v, RAP t)
160
+ {
161
+ if (v == 0)
162
+ return 0;
163
+ return IndexOf(t == RAP::C ? CRAPInts : LRRAPInts, v) + 1;
164
+ }
165
+
166
+ static int RAPCluster(int idx)
167
+ {
168
+ return ((idx - 1) % 3) * 3;
169
+ }
170
+
171
+ using PatternRAP = std::array<uint16_t, 6>;
172
+
173
+ static int ReadRAP(BitMatrixModuleCursorF& cur, RAP type)
174
+ {
175
+ log(cur.p, 2);
176
+ auto pattern = cur.readPatternFromBlack<PatternRAP>(cur.ms * 1, cur.ms * (10 + MS_THR), cur.ms * (10 - MS_THR));
177
+ #ifdef USE_E2E_PATTERNS
178
+ int res = RAPIndex(ToInt(NormalizedE2EPattern<6, 10, 5>(pattern)), type);
179
+ #else
180
+ int res = RAPIndex(ToInt(NormalizedPattern<6, 10>(pattern)), type);
181
+ #endif
182
+ if (res) {
183
+ cur.ms = Reduce(pattern) / 10.;
184
+ if (type == RAP::R) {
185
+ auto c = cur;
186
+ auto ms_thr = cur.ms * 1.5 + 1;
187
+ if (cur.stepToEdge(1, ms_thr) == 0 || ((c = cur).stepToEdge(1, ms_thr) != 0 && c.isIn()))
188
+ res = 0;
189
+ }
190
+ }
191
+ log(cur.p, res ? -1 : 1);
192
+ return res;
193
+ }
194
+
195
+ static int IsLRAP(const PatternView& view)
196
+ {
197
+ int l = view.sum(6);
198
+ #if LRAP_WITH_CW
199
+ int r = view.subView(6).sum(8);
200
+
201
+ // nominal l:r ratio is 10:17, accept ratios between 10:13 and 10:22 (approx. 45° tolerance)
202
+ if (l < 10 || r < 17 || l * 20 < r * 10 || l * 14 > r * 10 || (!view.isAtFirstBar() && view[-1] < l / 10))
203
+ #else
204
+ if (l < 10 || (!view.isAtFirstBar() && view[-1] < l / 10))
205
+ #endif
206
+ return 0;
207
+
208
+ #if 1
209
+ auto m = view[0];
210
+ auto M = m;
211
+ for (int i = 1; i < 6; ++i)
212
+ UpdateMinMax(m, M, view[i]);
213
+
214
+ // the first bar is nominally >= 2 * m, M is nominally <= 4 * m
215
+ if (view[0] < m * 3 / 2 || M > m * 6 || view[5] > 5 * m)
216
+ return 0;
217
+ #endif
218
+ #ifdef USE_E2E_PATTERNS
219
+ auto v = RAPIndex(ToInt(NormalizedE2EPattern<6, 10, 5>(view)), RAP::L);
220
+ #else
221
+ auto v = RAPIndex(ToInt(NormalizedPattern<6, 10>(view)), RAP::L);
222
+ #endif
223
+
224
+ return v;
225
+ };
226
+
227
+ static std::tuple<PatternView, int> FindLRAP(const PatternView& view)
228
+ {
229
+ constexpr int minSize = 6 + 8 * LRAP_WITH_CW; // 1 column
230
+ auto window = view.subView(0, 6 + 8 * LRAP_WITH_CW);
231
+ #if 1
232
+ for (auto end = view.end() - minSize; window.data() < end; window.skipPair())
233
+ #else
234
+ if (window.data() < view.end() - minSize)
235
+ #endif
236
+ if (int i = IsLRAP(window))
237
+ return {window, i};
238
+
239
+ return {};
240
+ };
241
+
242
+ struct LRAP : PointI
243
+ {
244
+ int idx, width;
245
+ };
246
+
247
+ struct Segment
248
+ {
249
+ int idx;
250
+ std::vector<LRAP*> lraps;
251
+ };
252
+
253
+ struct RAPPair
254
+ {
255
+ int first, second, offset, family;
256
+
257
+ RAPPair(int f, int s): first(f), second(s), offset(0), family(0) {
258
+ int diff = second - first;
259
+ if (diff < -4)
260
+ diff += 52;
261
+ family = (diff + 4) / 8 * 8;
262
+ offset = diff - family;
263
+ }
264
+
265
+ bool isValid() const { return first != 0 && second != 0 && family <= 24 && std::abs(offset) <= 3; }
266
+ };
267
+
268
+ using Cluster = std::vector<LRAP>;
269
+ using Clusters = std::list<Cluster>;
270
+
271
+ static Clusters FindCandidates(const BitMatrix& image, bool tryHarder, bool reversed)
272
+ {
273
+ const int height = image.height();
274
+ const int width = image.width();
275
+
276
+ if (height < 4 || width < 27)
277
+ return {};
278
+
279
+ int minClusterSize = 4; // shortest MicroPDF417 has 4 rows
280
+ int margin = tryHarder ? std::min(8, height / 44) : height / 4; // tallest MicroPDF417 has 44 rows
281
+ int skip = tryHarder ? 8 : std::max((height - 2 * margin) / 32, 8); // shortest MicroPDF417 symbol is 8 pixels high
282
+
283
+ PatternRow row;
284
+ Clusters res;
285
+
286
+ for (int y = margin; y < height - margin; y += skip) {
287
+ GetPatternRow(image, reversed ? height - 1 - y : y, row, false);
288
+ if (reversed)
289
+ std::ranges::reverse(row);
290
+
291
+ PatternView next = row;
292
+ int idx;
293
+ #if 1
294
+ while
295
+ #else
296
+ if
297
+ #endif
298
+ (std::tie(next, idx) = FindLRAP(next), next.isValid()) {
299
+ LRAP p{{next.pixelsInFront(), y}, idx, next.sum()};
300
+ log(centered(PointF(reversed ? width - 1 - p.x : p.x, reversed ? height - 1 - p.y : p.y)), 1);
301
+
302
+ // Try to attach this LRAP to an existing cluster by proximity in x/y; prune stale short
303
+ // clusters and create a new cluster if no suitable match was found.
304
+ for (auto pCluster = res.begin(); pCluster != res.end();) {
305
+ auto diff = p - pCluster->back();
306
+ if (diff.y <= 3 * skip && std::abs(diff.x) <= std::max(diff.y, 2)) {
307
+ pCluster->push_back(p);
308
+ p = {};
309
+ break;
310
+ } else if (diff.y > 2 * skip && Size(*pCluster) < minClusterSize) {
311
+ res.erase(pCluster++);
312
+ } else {
313
+ ++pCluster;
314
+ }
315
+ }
316
+
317
+ if (p != PointI{}) {
318
+ #ifdef ZXING_SUPPORT_MINIMAL_SIZE_MIRCOPDF417
319
+ if (tryHarder) {
320
+ int rowHeight = 2 * p.width / 27; // p is 27 modules wide, a row is nominally 2 modules high
321
+ if (rowHeight < skip) {
322
+ // TODO: this skip adjustment + 'restart' to detect very small symbols may break detection of multiple symbls
323
+ // with different sizes horizontally next to each other
324
+ y = std::max(0, y - skip); // the for loop will add `skip` back, so this effectively y - skip + rowHeight
325
+ skip = rowHeight;
326
+ printf("decreasing skip to %d at x=%3d, y=%3d, p.width=%d\n", skip, p.x, y, p.width);
327
+ break;
328
+ } else if (rowHeight > 2 * skip
329
+ && std::ranges::all_of(res, [&](const Cluster& c) { return p.y - c.back().y > 2 * skip; })) {
330
+ skip = std::min(8, rowHeight); // reset skip to default when starting a new cluster
331
+ printf("increasing skip to %d at x=%3d, y=%3d, p.width=%d\n", skip, p.x, y, p.width);
332
+ }
333
+ }
334
+ #endif
335
+ res.emplace_back(Cluster{p});
336
+ }
337
+
338
+ next.skipPair();
339
+ next.extend();
340
+ }
341
+ }
342
+
343
+ res.remove_if([&](Cluster& lraps) { return Size(lraps) < minClusterSize; });
344
+ res.remove_if([&](Cluster& lraps) {
345
+ // `segs` groups consecutive LRAP points by idx so we can denoise, enforce monotonic order,
346
+ // and keep one representative center point per streak for robust cluster cleanup.
347
+ std::list<Segment> segs = {{lraps.front().idx, {}}};
348
+ for (LRAP& p : lraps) {
349
+ if (p.idx != segs.back().idx)
350
+ segs.push_back({p.idx, {}});
351
+ segs.back().lraps.push_back(&p);
352
+ }
353
+ // remove noise from the segment, i.e. streaks that are less than half as long as the longest streak
354
+ int M = Size(std::ranges::max(segs, {}, [](const auto& seg) { return Size(seg.lraps); }).lraps);
355
+ segs.remove_if([M](Segment& h) { return Size(h.lraps) < M / 2; });
356
+
357
+ // remove duplicates (can appear after small ones are dropped)
358
+ segs.unique([](auto& l, auto& r) { return l.idx == r.idx; });
359
+
360
+ // remove non-monotonic and too far away elements from the front and the back
361
+ int diff = 0;
362
+ while (segs.size() > 1 && ((diff = std::next(segs.begin())->idx - segs.begin()->idx) < 0 || diff > 3))
363
+ segs.pop_front();
364
+ while (segs.size() > 1 && ((diff = std::next(segs.rbegin())->idx - segs.rbegin()->idx) > 0 || diff < -3))
365
+ segs.pop_back();
366
+
367
+ #if LRAP_WITH_CW == 0 // support rotated symbols > 30°
368
+ if (Size(segs) < 3)
369
+ return true;
370
+ // remove single elements that are not part of a monotonic sequence
371
+ for (auto it = std::next(segs.begin()); it != std::prev(segs.end());) {
372
+ if (it->idx > std::next(it)->idx && std::next(it)->idx > std::prev(it)->idx)
373
+ it = segs.erase(it);
374
+ else
375
+ ++it;
376
+ }
377
+ #endif
378
+
379
+ // remove complete segment if too small, too spread out or contains non-monotonic sequence
380
+ if (Size(segs) < 3 || std::abs(segs.back().idx - segs.front().idx) > 2 * Size(segs)
381
+ || (LRAP_WITH_CW && !std::ranges::is_sorted(segs, {}, &Segment::idx)))
382
+ return true;
383
+
384
+ // replace current segment with one containing only the center points of each lrap streak
385
+ auto center = [](auto& h) { return *h.lraps[Size(h.lraps) / 2]; };
386
+ lraps.erase(std::ranges::transform(segs, lraps.begin(), center).out, lraps.end());
387
+
388
+ return false;
389
+ });
390
+
391
+ if (reversed)
392
+ for (auto& cluster : res)
393
+ for (auto& lrap : cluster) {
394
+ lrap.x = width - 1 - lrap.x;
395
+ lrap.y = height - 1 - lrap.y;
396
+ }
397
+
398
+ #ifdef PRINT_DEBUG
399
+ printf("\n# found LRAPs: %d\n", Size(res));
400
+ for (const auto& cluster : res) {
401
+ for (auto lrap : cluster)
402
+ printf("%d @ %dx%d (width: %d)\n", lrap.idx, lrap.x, lrap.y, lrap.width);
403
+ printf("\n");
404
+ }
405
+ #endif
406
+ return res;
407
+ }
408
+
409
+ static int DetermineNumCols(BitMatrixModuleCursorF& start, const Cluster& lraps)
410
+ {
411
+ printf("right: %s, ms: %.1f\n", ToString(start.d).c_str(), start.ms);
412
+ std::array<int, 16> colHist = {}, offsets = {};
413
+ for (int s = 0; s < 2 && std::ranges::max(colHist) < 3; ++s)
414
+ for (auto& p : lraps) {
415
+ auto cur = start;
416
+ auto tmp = cur;
417
+ cur.p = centered(p) + s * cur.ms * right(cur.d); // if we don't have enough LRAPs, scan again with 1 modSize offset
418
+
419
+ auto pair = RAPPair(ReadRAP(cur, RAP::L), 0);
420
+ if (!pair.first || !SkipCodeword(cur))
421
+ continue;
422
+
423
+ printf("\nLRAP: %2d @ %5.1fx%5.1f ", pair.first, cur.p.x, cur.p.y);
424
+
425
+ auto checkRAP = [&](RAP rap, int colI) {
426
+ --colI;
427
+ pair = RAPPair(pair.first, ReadRAP((tmp = cur), rap));
428
+ if (pair.isValid()) {
429
+ colHist[colI * 4 + pair.family / 8] += 1;
430
+ offsets[colI * 4 + pair.family / 8] += pair.offset;
431
+ }
432
+ printf("%2d/%2d: %2d %s ", pair.first, pair.second, pair.offset, pair.isValid() ? "< " : " ");
433
+ return pair.isValid();
434
+ };
435
+
436
+ checkRAP(RAP::R, 1);
437
+ if (checkRAP(RAP::C, 3)) {
438
+ pair.first = pair.second;
439
+ cur = tmp;
440
+ if (SkipCodeword(cur) && SkipCodeword(cur) && checkRAP(RAP::R, 3))
441
+ continue;
442
+ }
443
+ if (SkipCodeword(cur)) {
444
+ checkRAP(RAP::R, 2);
445
+ if (checkRAP(RAP::C, 4)) {
446
+ pair.first = pair.second;
447
+ cur = tmp;
448
+ if (SkipCodeword(cur) && SkipCodeword(cur) && checkRAP(RAP::R, 4))
449
+ continue;
450
+ }
451
+ }
452
+ }
453
+
454
+ printv("\ncolHist: ", "%2d ", "", colHist);
455
+ printv("\noffsets: ", "%2d ", "\n", offsets);
456
+ int nCol = std::ranges::max_element(colHist) - colHist.begin();
457
+
458
+ if (colHist[nCol]) {
459
+ auto offset = double(offsets[nCol]) / colHist[nCol];
460
+ start.d = bresenhamDirection((10. + 17. * 2) * start.d - 2. * offset * start.right());
461
+ printf("average offset: %.1f, new right: %s, ms: %.1f\n", offset, ToString(start.d).c_str(), start.ms);
462
+ }
463
+
464
+ return nCol / 4 + 1;
465
+ }
466
+
467
+ struct SymbolInfo
468
+ {
469
+ int nCols = 0, nRows = 0, nECCs = 0, rotFam = 0, startRow = 0, rowB = 0, rowE = 0;
470
+ int nCWs() const { return nCols * nRows; }
471
+ int lastRow() const { return startRow + nRows - 1; }
472
+ int width() const { return 21 + nCols * 17 + (nCols > 2) * 10; }
473
+ int height() const { return nRows * 2; }
474
+ bool isValid() const { return nCols > 0 && nRows > 0; }
475
+ };
476
+
477
+ static constexpr std::array<SymbolInfo, 35> SYMBOLS = {{
478
+ // the first element is a dummy
479
+ {0, 0, 0, 0, 0, 0},
480
+ // see tables 1, 10, 11, 12 in ISO 24728::2006
481
+ {1, 11, 7, 8, 1, 1, 8},
482
+ {1, 14, 7, 0, 8, 8, 18},
483
+ {1, 17, 7, 0, 36, 39, 52},
484
+ {1, 20, 8, 0, 19, 22, 35},
485
+ {1, 24, 8, 8, 9, 12, 24},
486
+ {1, 28, 8, 8, 25, 33, 52},
487
+ {2, 8, 8, 0, 1, 1, 7},
488
+ {2, 11, 9, 8, 1, 1, 8},
489
+ {2, 14, 9, 0, 8, 9, 18},
490
+ {2, 17, 10, 0, 36, 39, 52},
491
+ {2, 20, 11, 0, 19, 22, 35},
492
+ {2, 23, 13, 8, 9, 12, 26},
493
+ {2, 26, 15, 8, 27, 32, 52},
494
+ {3, 6, 12, 0, 1, 1, 6},
495
+ {3, 8, 14, 0, 7, 7, 14},
496
+ {3, 10, 16, 0, 15, 15, 24},
497
+ {3, 12, 18, 0, 25, 25, 36},
498
+ {3, 15, 21, 0, 37, 37, 51},
499
+ {3, 20, 26, 16, 1, 1, 14},
500
+ {3, 26, 32, 8, 1, 1, 20},
501
+ {3, 32, 38, 8, 21, 27, 52},
502
+ {3, 38, 44, 16, 15, 21, 52},
503
+ {3, 44, 50, 24, 1, 1, 44},
504
+ {4, 4, 8, 24, 47, 47, 50},
505
+ {4, 6, 12, 0, 1, 1, 6},
506
+ {4, 8, 14, 0, 7, 7, 14},
507
+ {4, 10, 16, 0, 15, 15, 24},
508
+ {4, 12, 18, 0, 25, 25, 36},
509
+ {4, 15, 21, 0, 37, 37, 51},
510
+ {4, 20, 26, 16, 1, 1, 14},
511
+ {4, 26, 32, 8, 1, 1, 20},
512
+ {4, 32, 38, 8, 21, 27, 52},
513
+ {4, 38, 44, 16, 15, 21, 52},
514
+ {4, 44, 50, 24, 1, 1, 44},
515
+ }};
516
+
517
+ static const SymbolInfo& DetermineSymbolInfo(const Matrix<Codeword>& cwMat, const std::array<int, 4>& rotFamHist [[maybe_unused]])
518
+ {
519
+ auto rotFamMax = std::ranges::max_element(rotFamHist);
520
+ int rotFam = *rotFamMax && *rotFamMax > Reduce(rotFamHist) / 2 ? static_cast<int>(rotFamMax - rotFamHist.begin()) * 8 : -1;
521
+ // rotFam = -1; // uncomment to test symbol detection without rotation family filtering
522
+
523
+ std::vector<int> sightsPerRow(cwMat.height(), 0);
524
+ for (int y = 1; y < cwMat.height(); ++y)
525
+ for (int x = 0; x < cwMat.width(); ++x)
526
+ sightsPerRow[y] += cwMat(x, y).count;
527
+
528
+ const SymbolInfo* bestSym = SYMBOLS.data();
529
+ int minError = std::numeric_limits<int>::max();
530
+ float meanCount = Reduce(cwMat, 0.f, [](float acc, const Codeword& e) { return acc + e.count; })
531
+ / std::ranges::count_if(cwMat, [](const auto& e) { return e.count > 0; });
532
+
533
+ for (const auto& s : SYMBOLS) {
534
+ if (s.nCols != cwMat.width() || (rotFam != -1 && s.rotFam != rotFam))
535
+ continue;
536
+
537
+ int error = s.nCWs() * meanCount; // with all inside filled and outside empty, this will result in 0 error
538
+ for (int y = 1; y < cwMat.height(); ++y) {
539
+ bool isOutside = y < s.startRow || y > s.lastRow();
540
+ error += (isOutside ? 1 : -1) * sightsPerRow[y];
541
+ }
542
+
543
+ printf("symbol: %d, %2dx%2d, rotFam: %2d, firstRow: %2d, error: %d\n",
544
+ static_cast<int>(&s - SYMBOLS.data()), s.nCols, s.nRows, s.rotFam, s.startRow, error);
545
+
546
+ if (error < minError) {
547
+ minError = error;
548
+ bestSym = &s;
549
+ }
550
+ }
551
+
552
+ return *bestSym;
553
+ }
554
+
555
+ static BarcodeData ScanCandidate(const BitMatrix& image, const Cluster& lraps)
556
+ {
557
+ auto inward = (lraps.back().y > lraps.front().y ? 1 : -1) * PointF(1, 0);
558
+ RegressionLine lineL, lineR;
559
+ lineL.setDirectionInward(inward);
560
+ lineR.setDirectionInward(inward);
561
+ for (auto& p : lraps) {
562
+ lineL.add(PointF(p));
563
+ lineR.add(PointF(p) + p.width * inward);
564
+ }
565
+ lineL.evaluate(2, true);
566
+ lineR.evaluate(2, true);
567
+ auto down = bresenhamDirection(right(lineL.normal()));
568
+ printf("down: %s\n", ToString(down).c_str());
569
+ BitMatrixModuleCursorF startCur(image, centered(lraps.front()), bresenhamDirection(lineR.normal()),
570
+ lraps.front().width / (10. + 17. * LRAP_WITH_CW));
571
+ startCur.step(-1);
572
+
573
+ int nCols = DetermineNumCols(startCur, lraps);
574
+ printf("nCols: %d\n", nCols);
575
+ if (!nCols)
576
+ return {};
577
+
578
+ int failedTries = 0;
579
+ while(failedTries < 10 && image.isIn(startCur.p - down)) {
580
+ startCur.p += -down;
581
+ auto cur = startCur;
582
+ log(cur.p);
583
+ if (!ReadRAP(cur, RAP::L))
584
+ ++failedTries;
585
+ }
586
+
587
+ startCur.p += failedTries * down;
588
+
589
+ // Matrix with vector of codewords for each cell, to collect all codeword sightings and their counts.
590
+ Matrix<std::vector<Codeword>> histMat(nCols, 52 + 1);
591
+ // Histogram of rotation family votes (4 possible families) collected while scanning RAP pairs.
592
+ std::array<int, 4> rotFamHist = {};
593
+ Position pos;
594
+
595
+ auto checkRAP = [&](int li, int ri) {
596
+ auto rap = RAPPair(li, ri);
597
+ if (!rap.isValid())
598
+ return false;
599
+ // printf("li: %2d, ri: %2d, ri-li: %2d, fam: %d, offset: %d\n", li, ri, rap.second - rap.first, rap.family, rap.offset);
600
+ rotFamHist.at(rap.family/8)++;
601
+ failedTries = 0;
602
+ return true;
603
+ };
604
+
605
+ auto inSweepRange = [&](PointF p) { return dot(PointF(lraps.back()) - p, down) >= 0; };
606
+
607
+ failedTries = 1;
608
+ for (; image.isIn(startCur.p + down) && (inSweepRange(startCur.p) || failedTries < 10 * startCur.ms); startCur.p += down, failedTries++) {
609
+ auto cur = startCur;
610
+ log(cur.p);
611
+
612
+ auto li = ReadRAP(cur, RAP::L);
613
+ // printf("li: %2d @ (%f, %f)\n", li, cur.p.x, cur.p.y);
614
+ if (!li)
615
+ continue;
616
+ startCur.ms = cur.ms;
617
+ Codeword cw[4];
618
+ int ci = 0, ri = 0, cluster = RAPCluster(li);
619
+
620
+ cw[0] = ReadCodeword(cur, cluster);
621
+ if (nCols == 2) {
622
+ cw[1] = ReadCodeword(cur, cluster);
623
+ } else if (nCols == 3) {
624
+ ci = ReadRAP(cur, RAP::C);
625
+ if (checkRAP(li, ci))
626
+ cluster = RAPCluster(ci);
627
+ cw[1] = ReadCodeword(cur, cluster);
628
+ cw[2] = ReadCodeword(cur, cluster);
629
+ } else if (nCols == 4) {
630
+ cw[1] = ReadCodeword(cur, cluster);
631
+ ci = ReadRAP(cur, RAP::C);
632
+ if (checkRAP(li, ci))
633
+ cluster = RAPCluster(ci);
634
+ cw[2] = ReadCodeword(cur, cluster);
635
+ cw[3] = ReadCodeword(cur, cluster);
636
+ }
637
+ ri = ReadRAP(cur, RAP::R);
638
+
639
+ if (nCols <= 2) {
640
+ checkRAP(li, ri);
641
+ } else {
642
+ checkRAP(li, ci);
643
+ checkRAP(ci, ri);
644
+ }
645
+
646
+ if (ci || ri || cw[0] || cw[1] || cw[2] || cw[3]) {
647
+ // collect crude approximation as fallback
648
+ if (pos[0] == PointI()) {
649
+ pos[0] = PointI(startCur.p);
650
+ pos[1] = PointI(cur.p);
651
+ } else {
652
+ pos[2] = PointI(cur.p);
653
+ pos[3] = PointI(startCur.p);
654
+ }
655
+ }
656
+
657
+ auto rowOffset = [cluster = RAPCluster(li)](int nextCluster) mutable {
658
+ int o = ((nextCluster - cluster + 9) / 3) % 3;
659
+ if (o == 2)
660
+ o = -1;
661
+ cluster = nextCluster;
662
+ return o;
663
+ };
664
+
665
+ printf("%2d/%d -> ", li, RAPCluster(li));
666
+ for (int x = 0; x < nCols; ++x) {
667
+ printf("%3d/%d ", cw[x].codeword, cw[x].cluster);
668
+ if (cw[x]) {
669
+ li += rowOffset(cw[x].cluster);
670
+ if (li < 1 || li > 52)
671
+ continue;
672
+ auto& cell = histMat(x, li);
673
+ auto cwPtr = std::ranges::find(cell, cw[x]);
674
+ if (cwPtr != cell.end()) {
675
+ cwPtr->count++;
676
+ cwPtr->left += cw[x].left;
677
+ cwPtr->right += cw[x].right;
678
+ }
679
+ else
680
+ cell.push_back(cw[x]);
681
+ }
682
+ }
683
+ printf("\n");
684
+ }
685
+
686
+ Matrix<Codeword> cwMat(nCols, 53, {});
687
+ std::ranges::transform(histMat, cwMat.begin(), [](std::vector<Codeword>& hist) {
688
+ if (hist.empty())
689
+ return Codeword{};
690
+ if (hist.size() == 1)
691
+ return hist.front();
692
+
693
+ auto best = std::ranges::max_element(hist, [](const auto& a, const auto& b) { return a.count < b.count; });
694
+ bool bestIsUnique = std::ranges::all_of(hist, [&](const auto& a) { return &a == &*best || a.count < best->count; });
695
+
696
+ return bestIsUnique ? *best : Codeword{};
697
+ });
698
+
699
+ #ifdef PRINT_DEBUG
700
+ for (int y = 0; y < cwMat.height(); ++y) {
701
+ printf("%2d: ", y);
702
+ for (int x = 0; x < cwMat.width(); ++x) {
703
+ auto& e = cwMat(x, y);
704
+ e.count ? printf("%3d %2d | ", e.codeword, e.count) : printf(" | ");
705
+ }
706
+ printf("\n");
707
+ }
708
+ #endif
709
+
710
+ auto si = DetermineSymbolInfo(cwMat, rotFamHist);
711
+ if (!si.isValid())
712
+ return {};
713
+
714
+ std::vector<int> codewords(si.nCWs() + 1);
715
+ // MicroPDF417 does not encode the number of codewords in the symbol but the DecodeCodewords() function expects the first element
716
+ // to contain the number of codewords. The ReedSolomon algorithm can gracefully handle prepended zeros, the VerifyCodewordCount()
717
+ // function will autocorrect the number of codewords if the first element is zero.
718
+ codewords[0] = 0;
719
+ for (int i = 0; i < si.nCWs(); ++i)
720
+ codewords[i + 1] = (&cwMat(0, si.startRow))[i].codeword;
721
+
722
+ std::vector<int> erasures;
723
+ for (int i=0; i < Size(codewords); ++i)
724
+ if (codewords[i] == -1)
725
+ erasures.push_back(i);
726
+
727
+ if (Size(erasures) > si.nECCs)
728
+ return {};
729
+
730
+ // TODO: implement proper handling of ECI Descriptor codeword at the start of the codeword sequence
731
+ // (see ISO 24728:2006, section 5.2.4.2 ECI Descriptor codeword)
732
+ DecoderResult decoderResult = Pdf417::DecodeCodewords(codewords, si.nECCs, erasures);
733
+ printf("size: %dx%d, firstRow: %d, cws: %d, rotFamHist: %d/%d/%d/%d, rotFam: %d, nEECs: %d, erasures: %d, valid: %d\n", si.nCols,
734
+ si.nRows, si.startRow, si.nCWs(), rotFamHist[0], rotFamHist[1], rotFamHist[2], rotFamHist[3], si.rotFam, si.nECCs,
735
+ Size(erasures), decoderResult.isValid());
736
+
737
+ // Extrapolate the symbol corners from a perspective transform created from detected codeword positions near the corners of the symbol.
738
+ auto closestCorner = [&](PointI corner, PointI dir) -> PointI {
739
+ for (int x = 0; x <= si.nCols / 2; ++x)
740
+ for (int y = 0; y < si.nRows / 2; ++y) {
741
+ auto offset = PointI{x, y} * dir;
742
+ if (cwMat(corner + offset).count > 1)
743
+ return offset;
744
+ }
745
+ return {};
746
+ };
747
+ PointI tlI = closestCorner({0, si.startRow}, {1, 1}), trI = closestCorner({si.nCols - 1, si.startRow}, {-1, 1}),
748
+ brI = closestCorner({si.nCols - 1, si.lastRow()}, {-1, -1}), blI = closestCorner({0, si.lastRow()}, {1, -1});
749
+ PointI cell(17, 2);
750
+
751
+ auto src = QuadrilateralF(PointI{10, 1} + tlI * cell, PointI{si.width() - 11, 1} + trI * cell,
752
+ PointI{si.width() - 11, si.height() - 1} + brI * cell, PointI{10, si.height() - 1} + blI * cell);
753
+ auto dst =
754
+ QuadrilateralF(cwMat(PointI{0, si.startRow} + tlI).leftPos(), cwMat(PointI{si.nCols - 1, si.startRow} + trI).rightPos(),
755
+ cwMat(PointI{si.nCols - 1, si.lastRow()} + brI).rightPos(), cwMat(PointI{0, si.lastRow()} + blI).leftPos());
756
+ auto mod2pix = PerspectiveTransform(src, dst);
757
+ if (mod2pix.isValid())
758
+ pos = Position{mod2pix({0, 0}), mod2pix({(double)si.width(), 0}), mod2pix({(double)si.width(), (double)si.height()}),
759
+ mod2pix({0, (double)si.height()})};
760
+
761
+ return MatrixBarcode(std::move(decoderResult), DetectorResult({}, std::move(pos)), BarcodeFormat::MicroPDF417);
762
+ }
763
+
764
+ BarcodesData Reader::read(const BinaryBitmap& image, int maxSymbols) const
765
+ {
766
+ BarcodesData res;
767
+ // TODO: implement proper isPure mode (performace)
768
+ bool tryRotate = _opts.tryRotate() && !_opts.isPure();
769
+ for (int rotate90 = 0; rotate90 <= static_cast<int>(tryRotate); ++rotate90) {
770
+ // TODO: implement rotation support without full image rotation (performance)
771
+ auto binImg = image.getBitMatrix(rotate90);
772
+ if (!binImg)
773
+ return {};
774
+
775
+ #ifdef PRINT_DEBUG
776
+ LogMatrixWriter lmw(log, *binImg, 5, "mpdf-log.pnm");
777
+ #endif
778
+
779
+ for (bool reversed : {false, true}) {
780
+ for (const auto& x : FindCandidates(*binImg, _opts.tryHarder(), reversed)) {
781
+ auto v = ScanCandidate(*binImg, x);
782
+ if (rotate90)
783
+ for (auto& p : v.position)
784
+ p = {binImg->height() - 1 - p.y, p.x};
785
+ if ((v.isValid() || _opts.returnErrors()) && !Contains(res, v))
786
+ res.push_back(std::move(v));
787
+ if (maxSymbols && Size(res) >= maxSymbols)
788
+ return res;
789
+ }
790
+ }
791
+ }
792
+
793
+ return res;
794
+ }
795
+
796
+ } // namespace ZXing::MicroPdf417