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.
- package/README.md +34 -0
- package/VisionCameraZxing.podspec +48 -0
- package/android/CMakeLists.txt +43 -0
- package/android/build.gradle +150 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/cpp/cpp-adapter.cpp +7 -0
- package/android/src/main/java/com/margelo/nitro/camera/zxing/VisionCameraZxingPackage.kt +21 -0
- package/cpp/BarcodeValueTypeClassifier.cpp +70 -0
- package/cpp/BarcodeValueTypeClassifier.hpp +14 -0
- package/cpp/FrameImageView.cpp +75 -0
- package/cpp/FrameImageView.hpp +34 -0
- package/cpp/HybridBarcode.cpp +59 -0
- package/cpp/HybridBarcode.hpp +26 -0
- package/cpp/HybridBarcodeScanner.cpp +121 -0
- package/cpp/HybridBarcodeScanner.hpp +26 -0
- package/cpp/HybridBarcodeScannerFactory.cpp +11 -0
- package/cpp/HybridBarcodeScannerFactory.hpp +14 -0
- package/cpp/ImageDownscaler.cpp +34 -0
- package/cpp/ImageDownscaler.hpp +21 -0
- package/cpp/ZXingDecoder.cpp +189 -0
- package/cpp/ZXingDecoder.hpp +72 -0
- package/cpp/zxing-core/LICENSE +202 -0
- package/cpp/zxing-core/README.md +156 -0
- package/cpp/zxing-core/core/CMakeLists.txt +784 -0
- package/cpp/zxing-core/core/Version.h.in +28 -0
- package/cpp/zxing-core/core/ZXingConfig.cmake.in +9 -0
- package/cpp/zxing-core/core/src/Barcode.cpp +255 -0
- package/cpp/zxing-core/core/src/Barcode.h +191 -0
- package/cpp/zxing-core/core/src/BarcodeData.h +100 -0
- package/cpp/zxing-core/core/src/BarcodeFormat.cpp +286 -0
- package/cpp/zxing-core/core/src/BarcodeFormat.h +272 -0
- package/cpp/zxing-core/core/src/BinaryBitmap.cpp +111 -0
- package/cpp/zxing-core/core/src/BinaryBitmap.h +66 -0
- package/cpp/zxing-core/core/src/BitArray.cpp +38 -0
- package/cpp/zxing-core/core/src/BitArray.h +181 -0
- package/cpp/zxing-core/core/src/BitMatrix.cpp +175 -0
- package/cpp/zxing-core/core/src/BitMatrix.h +199 -0
- package/cpp/zxing-core/core/src/BitMatrixCursor.h +253 -0
- package/cpp/zxing-core/core/src/BitMatrixIO.cpp +101 -0
- package/cpp/zxing-core/core/src/BitMatrixIO.h +21 -0
- package/cpp/zxing-core/core/src/BitSource.cpp +77 -0
- package/cpp/zxing-core/core/src/BitSource.h +72 -0
- package/cpp/zxing-core/core/src/ByteArray.h +42 -0
- package/cpp/zxing-core/core/src/CharacterSet.cpp +78 -0
- package/cpp/zxing-core/core/src/CharacterSet.h +58 -0
- package/cpp/zxing-core/core/src/ConcentricFinder.cpp +312 -0
- package/cpp/zxing-core/core/src/ConcentricFinder.h +156 -0
- package/cpp/zxing-core/core/src/Content.cpp +471 -0
- package/cpp/zxing-core/core/src/Content.h +82 -0
- package/cpp/zxing-core/core/src/ContentType.h +19 -0
- package/cpp/zxing-core/core/src/CreateBarcode.cpp +490 -0
- package/cpp/zxing-core/core/src/CreateBarcode.h +132 -0
- package/cpp/zxing-core/core/src/DecoderResult.h +92 -0
- package/cpp/zxing-core/core/src/DetectorResult.h +44 -0
- package/cpp/zxing-core/core/src/ECI.cpp +81 -0
- package/cpp/zxing-core/core/src/ECI.h +78 -0
- package/cpp/zxing-core/core/src/Error.cpp +29 -0
- package/cpp/zxing-core/core/src/Error.h +79 -0
- package/cpp/zxing-core/core/src/Flags.h +165 -0
- package/cpp/zxing-core/core/src/GTIN.cpp +253 -0
- package/cpp/zxing-core/core/src/GTIN.h +58 -0
- package/cpp/zxing-core/core/src/GlobalHistogramBinarizer.cpp +197 -0
- package/cpp/zxing-core/core/src/GlobalHistogramBinarizer.h +34 -0
- package/cpp/zxing-core/core/src/GridSampler.cpp +124 -0
- package/cpp/zxing-core/core/src/GridSampler.h +59 -0
- package/cpp/zxing-core/core/src/HRI.cpp +343 -0
- package/cpp/zxing-core/core/src/HRI.h +16 -0
- package/cpp/zxing-core/core/src/HybridBinarizer.cpp +315 -0
- package/cpp/zxing-core/core/src/HybridBinarizer.h +40 -0
- package/cpp/zxing-core/core/src/ImageView.h +168 -0
- package/cpp/zxing-core/core/src/JSON.cpp +154 -0
- package/cpp/zxing-core/core/src/JSON.h +66 -0
- package/cpp/zxing-core/core/src/LocalGrid.cpp +242 -0
- package/cpp/zxing-core/core/src/LocalGrid.h +91 -0
- package/cpp/zxing-core/core/src/LogMatrix.h +105 -0
- package/cpp/zxing-core/core/src/Matrix.h +125 -0
- package/cpp/zxing-core/core/src/MultiFormatReader.cpp +107 -0
- package/cpp/zxing-core/core/src/MultiFormatReader.h +34 -0
- package/cpp/zxing-core/core/src/MultiFormatWriter.cpp +111 -0
- package/cpp/zxing-core/core/src/MultiFormatWriter.h +62 -0
- package/cpp/zxing-core/core/src/Pattern.h +472 -0
- package/cpp/zxing-core/core/src/PerspectiveTransform.cpp +81 -0
- package/cpp/zxing-core/core/src/PerspectiveTransform.h +47 -0
- package/cpp/zxing-core/core/src/Point.h +185 -0
- package/cpp/zxing-core/core/src/Quadrilateral.h +215 -0
- package/cpp/zxing-core/core/src/Range.h +112 -0
- package/cpp/zxing-core/core/src/ReadBarcode.cpp +335 -0
- package/cpp/zxing-core/core/src/ReadBarcode.h +33 -0
- package/cpp/zxing-core/core/src/Reader.h +32 -0
- package/cpp/zxing-core/core/src/ReaderOptions.h +210 -0
- package/cpp/zxing-core/core/src/ReedSolomon.cpp +100 -0
- package/cpp/zxing-core/core/src/ReedSolomon.h +66 -0
- package/cpp/zxing-core/core/src/RegressionLine.h +161 -0
- package/cpp/zxing-core/core/src/ResultPoint.cpp +20 -0
- package/cpp/zxing-core/core/src/ResultPoint.h +35 -0
- package/cpp/zxing-core/core/src/StdGenerator.h +121 -0
- package/cpp/zxing-core/core/src/StdPrint.h +38 -0
- package/cpp/zxing-core/core/src/StdScope.h +55 -0
- package/cpp/zxing-core/core/src/StructuredAppend.h +19 -0
- package/cpp/zxing-core/core/src/SymbologyIdentifier.h +29 -0
- package/cpp/zxing-core/core/src/TextDecoder.cpp +59 -0
- package/cpp/zxing-core/core/src/TextDecoder.h +23 -0
- package/cpp/zxing-core/core/src/TextEncoder.cpp +75 -0
- package/cpp/zxing-core/core/src/TextEncoder.h +31 -0
- package/cpp/zxing-core/core/src/ThresholdBinarizer.h +58 -0
- package/cpp/zxing-core/core/src/TritMatrix.h +29 -0
- package/cpp/zxing-core/core/src/Utf.cpp +276 -0
- package/cpp/zxing-core/core/src/Utf.h +26 -0
- package/cpp/zxing-core/core/src/WhiteRectDetector.cpp +276 -0
- package/cpp/zxing-core/core/src/WhiteRectDetector.h +36 -0
- package/cpp/zxing-core/core/src/WriteBarcode.cpp +213 -0
- package/cpp/zxing-core/core/src/WriteBarcode.h +72 -0
- package/cpp/zxing-core/core/src/ZXAlgorithms.h +353 -0
- package/cpp/zxing-core/core/src/ZXConfig.h +17 -0
- package/cpp/zxing-core/core/src/ZXTestSupport.h +9 -0
- package/cpp/zxing-core/core/src/ZXVersion.h +14 -0
- package/cpp/zxing-core/core/src/ZXingC.cpp +460 -0
- package/cpp/zxing-core/core/src/ZXingC.h +296 -0
- package/cpp/zxing-core/core/src/ZXingCpp.cpp +18 -0
- package/cpp/zxing-core/core/src/ZXingCpp.h +76 -0
- package/cpp/zxing-core/core/src/ZXingQt.h +606 -0
- package/cpp/zxing-core/core/src/aztec/AZDecoder.cpp +376 -0
- package/cpp/zxing-core/core/src/aztec/AZDecoder.h +20 -0
- package/cpp/zxing-core/core/src/aztec/AZDetector.cpp +508 -0
- package/cpp/zxing-core/core/src/aztec/AZDetector.h +25 -0
- package/cpp/zxing-core/core/src/aztec/AZDetectorResult.h +51 -0
- package/cpp/zxing-core/core/src/aztec/AZEncoder.cpp +318 -0
- package/cpp/zxing-core/core/src/aztec/AZEncoder.h +44 -0
- package/cpp/zxing-core/core/src/aztec/AZEncodingState.h +40 -0
- package/cpp/zxing-core/core/src/aztec/AZHighLevelEncoder.cpp +377 -0
- package/cpp/zxing-core/core/src/aztec/AZHighLevelEncoder.h +36 -0
- package/cpp/zxing-core/core/src/aztec/AZReader.cpp +45 -0
- package/cpp/zxing-core/core/src/aztec/AZReader.h +21 -0
- package/cpp/zxing-core/core/src/aztec/AZToken.cpp +44 -0
- package/cpp/zxing-core/core/src/aztec/AZToken.h +39 -0
- package/cpp/zxing-core/core/src/aztec/AZWriter.cpp +38 -0
- package/cpp/zxing-core/core/src/aztec/AZWriter.h +55 -0
- package/cpp/zxing-core/core/src/datamatrix/DMBitLayout.cpp +194 -0
- package/cpp/zxing-core/core/src/datamatrix/DMBitLayout.h +21 -0
- package/cpp/zxing-core/core/src/datamatrix/DMDataBlock.cpp +63 -0
- package/cpp/zxing-core/core/src/datamatrix/DMDataBlock.h +41 -0
- package/cpp/zxing-core/core/src/datamatrix/DMDecoder.cpp +457 -0
- package/cpp/zxing-core/core/src/datamatrix/DMDecoder.h +19 -0
- package/cpp/zxing-core/core/src/datamatrix/DMDetector.cpp +1230 -0
- package/cpp/zxing-core/core/src/datamatrix/DMDetector.h +23 -0
- package/cpp/zxing-core/core/src/datamatrix/DMECEncoder.cpp +137 -0
- package/cpp/zxing-core/core/src/datamatrix/DMECEncoder.h +26 -0
- package/cpp/zxing-core/core/src/datamatrix/DMEncoderContext.h +128 -0
- package/cpp/zxing-core/core/src/datamatrix/DMHighLevelEncoder.cpp +919 -0
- package/cpp/zxing-core/core/src/datamatrix/DMHighLevelEncoder.h +29 -0
- package/cpp/zxing-core/core/src/datamatrix/DMReader.cpp +40 -0
- package/cpp/zxing-core/core/src/datamatrix/DMReader.h +21 -0
- package/cpp/zxing-core/core/src/datamatrix/DMSymbolInfo.cpp +141 -0
- package/cpp/zxing-core/core/src/datamatrix/DMSymbolInfo.h +78 -0
- package/cpp/zxing-core/core/src/datamatrix/DMSymbolShape.h +17 -0
- package/cpp/zxing-core/core/src/datamatrix/DMVersion.cpp +82 -0
- package/cpp/zxing-core/core/src/datamatrix/DMVersion.h +76 -0
- package/cpp/zxing-core/core/src/datamatrix/DMWriter.cpp +114 -0
- package/cpp/zxing-core/core/src/datamatrix/DMWriter.h +62 -0
- package/cpp/zxing-core/core/src/librscpp/README.md +65 -0
- package/cpp/zxing-core/core/src/librscpp/decode.h +258 -0
- package/cpp/zxing-core/core/src/librscpp/encode.h +124 -0
- package/cpp/zxing-core/core/src/librscpp/field.h +158 -0
- package/cpp/zxing-core/core/src/librscpp/poly.h +194 -0
- package/cpp/zxing-core/core/src/libzint/2of5inter.c +1 -0
- package/cpp/zxing-core/core/src/libzint/2of5inter_based.c +1 -0
- package/cpp/zxing-core/core/src/libzint/aztec.c +1 -0
- package/cpp/zxing-core/core/src/libzint/aztec.h +1 -0
- package/cpp/zxing-core/core/src/libzint/big5.h +1 -0
- package/cpp/zxing-core/core/src/libzint/codabar.c +1 -0
- package/cpp/zxing-core/core/src/libzint/code.c +1 -0
- package/cpp/zxing-core/core/src/libzint/code128.c +1 -0
- package/cpp/zxing-core/core/src/libzint/code128.h +1 -0
- package/cpp/zxing-core/core/src/libzint/common.c +1 -0
- package/cpp/zxing-core/core/src/libzint/common.h +1 -0
- package/cpp/zxing-core/core/src/libzint/dmatrix.c +1 -0
- package/cpp/zxing-core/core/src/libzint/dmatrix.h +1 -0
- package/cpp/zxing-core/core/src/libzint/dxfilmedge.c +1 -0
- package/cpp/zxing-core/core/src/libzint/eci.c +1 -0
- package/cpp/zxing-core/core/src/libzint/eci.h +1 -0
- package/cpp/zxing-core/core/src/libzint/eci_sb.h +1 -0
- package/cpp/zxing-core/core/src/libzint/filemem.c +1 -0
- package/cpp/zxing-core/core/src/libzint/filemem.h +1 -0
- package/cpp/zxing-core/core/src/libzint/fonts/normal_woff2.h +1 -0
- package/cpp/zxing-core/core/src/libzint/fonts/upcean_woff2.h +1 -0
- package/cpp/zxing-core/core/src/libzint/gb18030.h +1 -0
- package/cpp/zxing-core/core/src/libzint/gb2312.h +1 -0
- package/cpp/zxing-core/core/src/libzint/gbk.h +1 -0
- package/cpp/zxing-core/core/src/libzint/general_field.c +1 -0
- package/cpp/zxing-core/core/src/libzint/general_field.h +1 -0
- package/cpp/zxing-core/core/src/libzint/gs1.c +1 -0
- package/cpp/zxing-core/core/src/libzint/gs1.h +1 -0
- package/cpp/zxing-core/core/src/libzint/gs1_lint.h +1 -0
- package/cpp/zxing-core/core/src/libzint/iso3166.h +1 -0
- package/cpp/zxing-core/core/src/libzint/iso4217.h +1 -0
- package/cpp/zxing-core/core/src/libzint/ksx1001.h +1 -0
- package/cpp/zxing-core/core/src/libzint/large.c +1 -0
- package/cpp/zxing-core/core/src/libzint/large.h +1 -0
- package/cpp/zxing-core/core/src/libzint/library.c +1 -0
- package/cpp/zxing-core/core/src/libzint/maxicode.c +1 -0
- package/cpp/zxing-core/core/src/libzint/maxicode.h +1 -0
- package/cpp/zxing-core/core/src/libzint/medical.c +1 -0
- package/cpp/zxing-core/core/src/libzint/output.c +1 -0
- package/cpp/zxing-core/core/src/libzint/output.h +1 -0
- package/cpp/zxing-core/core/src/libzint/pdf417.c +1 -0
- package/cpp/zxing-core/core/src/libzint/pdf417.h +1 -0
- package/cpp/zxing-core/core/src/libzint/pdf417_tabs.h +1 -0
- package/cpp/zxing-core/core/src/libzint/qr.c +1 -0
- package/cpp/zxing-core/core/src/libzint/qr.h +1 -0
- package/cpp/zxing-core/core/src/libzint/raster.c +1 -0
- package/cpp/zxing-core/core/src/libzint/raster_font.h +1 -0
- package/cpp/zxing-core/core/src/libzint/reedsol.c +1 -0
- package/cpp/zxing-core/core/src/libzint/reedsol.h +1 -0
- package/cpp/zxing-core/core/src/libzint/reedsol_logs.h +1 -0
- package/cpp/zxing-core/core/src/libzint/rss.c +1 -0
- package/cpp/zxing-core/core/src/libzint/rss.h +1 -0
- package/cpp/zxing-core/core/src/libzint/sjis.h +1 -0
- package/cpp/zxing-core/core/src/libzint/stubs.c +137 -0
- package/cpp/zxing-core/core/src/libzint/svg.c +1 -0
- package/cpp/zxing-core/core/src/libzint/telepen.c +1 -0
- package/cpp/zxing-core/core/src/libzint/upcean.c +1 -0
- package/cpp/zxing-core/core/src/libzint/vector.c +1 -0
- package/cpp/zxing-core/core/src/libzint/zfiletypes.h +1 -0
- package/cpp/zxing-core/core/src/libzint/zint.h +1 -0
- package/cpp/zxing-core/core/src/libzint/zintconfig.h +1 -0
- package/cpp/zxing-core/core/src/libzueci/README.md +11 -0
- package/cpp/zxing-core/core/src/libzueci/zueci.c +1718 -0
- package/cpp/zxing-core/core/src/libzueci/zueci.h +179 -0
- package/cpp/zxing-core/core/src/libzueci/zueci_big5.h +3884 -0
- package/cpp/zxing-core/core/src/libzueci/zueci_common.h +31 -0
- package/cpp/zxing-core/core/src/libzueci/zueci_gb18030.h +264 -0
- package/cpp/zxing-core/core/src/libzueci/zueci_gb2312.h +2381 -0
- package/cpp/zxing-core/core/src/libzueci/zueci_gbk.h +4047 -0
- package/cpp/zxing-core/core/src/libzueci/zueci_ksx1001.h +2932 -0
- package/cpp/zxing-core/core/src/libzueci/zueci_sb.h +1112 -0
- package/cpp/zxing-core/core/src/libzueci/zueci_sjis.h +2286 -0
- package/cpp/zxing-core/core/src/maxicode/MCBitMatrixParser.cpp +68 -0
- package/cpp/zxing-core/core/src/maxicode/MCBitMatrixParser.h +30 -0
- package/cpp/zxing-core/core/src/maxicode/MCDecoder.cpp +329 -0
- package/cpp/zxing-core/core/src/maxicode/MCDecoder.h +19 -0
- package/cpp/zxing-core/core/src/maxicode/MCReader.cpp +65 -0
- package/cpp/zxing-core/core/src/maxicode/MCReader.h +21 -0
- package/cpp/zxing-core/core/src/oned/ODCodabarReader.cpp +102 -0
- package/cpp/zxing-core/core/src/oned/ODCodabarReader.h +21 -0
- package/cpp/zxing-core/core/src/oned/ODCodabarWriter.cpp +136 -0
- package/cpp/zxing-core/core/src/oned/ODCodabarWriter.h +34 -0
- package/cpp/zxing-core/core/src/oned/ODCode128Patterns.h +130 -0
- package/cpp/zxing-core/core/src/oned/ODCode128Reader.cpp +236 -0
- package/cpp/zxing-core/core/src/oned/ODCode128Reader.h +21 -0
- package/cpp/zxing-core/core/src/oned/ODCode128Writer.cpp +261 -0
- package/cpp/zxing-core/core/src/oned/ODCode128Writer.h +34 -0
- package/cpp/zxing-core/core/src/oned/ODCode39Reader.cpp +213 -0
- package/cpp/zxing-core/core/src/oned/ODCode39Reader.h +26 -0
- package/cpp/zxing-core/core/src/oned/ODCode39Writer.cpp +176 -0
- package/cpp/zxing-core/core/src/oned/ODCode39Writer.h +34 -0
- package/cpp/zxing-core/core/src/oned/ODCode93Patterns.h +80 -0
- package/cpp/zxing-core/core/src/oned/ODCode93Reader.cpp +112 -0
- package/cpp/zxing-core/core/src/oned/ODCode93Reader.h +21 -0
- package/cpp/zxing-core/core/src/oned/ODCode93Writer.cpp +192 -0
- package/cpp/zxing-core/core/src/oned/ODCode93Writer.h +32 -0
- package/cpp/zxing-core/core/src/oned/ODDXFilmEdgeReader.cpp +246 -0
- package/cpp/zxing-core/core/src/oned/ODDXFilmEdgeReader.h +26 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarCommon.cpp +172 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarCommon.h +204 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarExpandedBitDecoder.cpp +253 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarExpandedBitDecoder.h +19 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarExpandedReader.cpp +383 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarExpandedReader.h +25 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarLimitedReader.cpp +163 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarLimitedReader.h +23 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarReader.cpp +240 -0
- package/cpp/zxing-core/core/src/oned/ODDataBarReader.h +25 -0
- package/cpp/zxing-core/core/src/oned/ODEAN13Writer.cpp +62 -0
- package/cpp/zxing-core/core/src/oned/ODEAN13Writer.h +34 -0
- package/cpp/zxing-core/core/src/oned/ODEAN8Writer.cpp +51 -0
- package/cpp/zxing-core/core/src/oned/ODEAN8Writer.h +34 -0
- package/cpp/zxing-core/core/src/oned/ODITFReader.cpp +97 -0
- package/cpp/zxing-core/core/src/oned/ODITFReader.h +33 -0
- package/cpp/zxing-core/core/src/oned/ODITFWriter.cpp +78 -0
- package/cpp/zxing-core/core/src/oned/ODITFWriter.h +34 -0
- package/cpp/zxing-core/core/src/oned/ODMultiUPCEANReader.cpp +323 -0
- package/cpp/zxing-core/core/src/oned/ODMultiUPCEANReader.h +32 -0
- package/cpp/zxing-core/core/src/oned/ODReader.cpp +259 -0
- package/cpp/zxing-core/core/src/oned/ODReader.h +35 -0
- package/cpp/zxing-core/core/src/oned/ODRowReader.h +222 -0
- package/cpp/zxing-core/core/src/oned/ODTelepenReader.cpp +199 -0
- package/cpp/zxing-core/core/src/oned/ODTelepenReader.h +25 -0
- package/cpp/zxing-core/core/src/oned/ODUPCAWriter.cpp +33 -0
- package/cpp/zxing-core/core/src/oned/ODUPCAWriter.h +34 -0
- package/cpp/zxing-core/core/src/oned/ODUPCEANCommon.cpp +80 -0
- package/cpp/zxing-core/core/src/oned/ODUPCEANCommon.h +129 -0
- package/cpp/zxing-core/core/src/oned/ODUPCEWriter.cpp +56 -0
- package/cpp/zxing-core/core/src/oned/ODUPCEWriter.h +34 -0
- package/cpp/zxing-core/core/src/oned/ODWriterHelper.cpp +39 -0
- package/cpp/zxing-core/core/src/oned/ODWriterHelper.h +48 -0
- package/cpp/zxing-core/core/src/pdf417/MicroPDFReader.cpp +796 -0
- package/cpp/zxing-core/core/src/pdf417/MicroPDFReader.h +23 -0
- package/cpp/zxing-core/core/src/pdf417/PDF417.cpp +85 -0
- package/cpp/zxing-core/core/src/pdf417/PDF417.h +81 -0
- package/cpp/zxing-core/core/src/pdf417/PDFBarcodeMetadata.h +53 -0
- package/cpp/zxing-core/core/src/pdf417/PDFBarcodeValue.cpp +48 -0
- package/cpp/zxing-core/core/src/pdf417/PDFBarcodeValue.h +38 -0
- package/cpp/zxing-core/core/src/pdf417/PDFBoundingBox.cpp +116 -0
- package/cpp/zxing-core/core/src/pdf417/PDFBoundingBox.h +75 -0
- package/cpp/zxing-core/core/src/pdf417/PDFCodeword.h +71 -0
- package/cpp/zxing-core/core/src/pdf417/PDFCodewordDecoder.cpp +588 -0
- package/cpp/zxing-core/core/src/pdf417/PDFCodewordDecoder.h +41 -0
- package/cpp/zxing-core/core/src/pdf417/PDFCompaction.h +20 -0
- package/cpp/zxing-core/core/src/pdf417/PDFCustomData.h +32 -0
- package/cpp/zxing-core/core/src/pdf417/PDFDecoder.cpp +725 -0
- package/cpp/zxing-core/core/src/pdf417/PDFDecoder.h +20 -0
- package/cpp/zxing-core/core/src/pdf417/PDFDetectionResult.cpp +247 -0
- package/cpp/zxing-core/core/src/pdf417/PDFDetectionResult.h +74 -0
- package/cpp/zxing-core/core/src/pdf417/PDFDetectionResultColumn.cpp +321 -0
- package/cpp/zxing-core/core/src/pdf417/PDFDetectionResultColumn.h +83 -0
- package/cpp/zxing-core/core/src/pdf417/PDFDetector.cpp +371 -0
- package/cpp/zxing-core/core/src/pdf417/PDFDetector.h +45 -0
- package/cpp/zxing-core/core/src/pdf417/PDFEncoder.cpp +570 -0
- package/cpp/zxing-core/core/src/pdf417/PDFEncoder.h +182 -0
- package/cpp/zxing-core/core/src/pdf417/PDFHighLevelEncoder.cpp +570 -0
- package/cpp/zxing-core/core/src/pdf417/PDFHighLevelEncoder.h +32 -0
- package/cpp/zxing-core/core/src/pdf417/PDFReader.cpp +333 -0
- package/cpp/zxing-core/core/src/pdf417/PDFReader.h +28 -0
- package/cpp/zxing-core/core/src/pdf417/PDFScanningDecoder.cpp +559 -0
- package/cpp/zxing-core/core/src/pdf417/PDFScanningDecoder.h +41 -0
- package/cpp/zxing-core/core/src/pdf417/PDFWriter.cpp +170 -0
- package/cpp/zxing-core/core/src/pdf417/PDFWriter.h +74 -0
- package/cpp/zxing-core/core/src/pdf417/ZXBigInteger.cpp +623 -0
- package/cpp/zxing-core/core/src/pdf417/ZXBigInteger.h +81 -0
- package/cpp/zxing-core/core/src/pdf417/ZXNullable.h +105 -0
- package/cpp/zxing-core/core/src/qrcode/QRBitMatrixParser.cpp +294 -0
- package/cpp/zxing-core/core/src/qrcode/QRBitMatrixParser.h +41 -0
- package/cpp/zxing-core/core/src/qrcode/QRCodecMode.cpp +95 -0
- package/cpp/zxing-core/core/src/qrcode/QRCodecMode.h +59 -0
- package/cpp/zxing-core/core/src/qrcode/QRDataBlock.cpp +93 -0
- package/cpp/zxing-core/core/src/qrcode/QRDataBlock.h +52 -0
- package/cpp/zxing-core/core/src/qrcode/QRDataMask.h +50 -0
- package/cpp/zxing-core/core/src/qrcode/QRDecoder.cpp +359 -0
- package/cpp/zxing-core/core/src/qrcode/QRDecoder.h +19 -0
- package/cpp/zxing-core/core/src/qrcode/QRDetector.cpp +920 -0
- package/cpp/zxing-core/core/src/qrcode/QRDetector.h +45 -0
- package/cpp/zxing-core/core/src/qrcode/QRECB.h +52 -0
- package/cpp/zxing-core/core/src/qrcode/QREncodeResult.h +33 -0
- package/cpp/zxing-core/core/src/qrcode/QREncoder.cpp +568 -0
- package/cpp/zxing-core/core/src/qrcode/QREncoder.h +21 -0
- package/cpp/zxing-core/core/src/qrcode/QRErrorCorrectionLevel.cpp +51 -0
- package/cpp/zxing-core/core/src/qrcode/QRErrorCorrectionLevel.h +39 -0
- package/cpp/zxing-core/core/src/qrcode/QRFormatInformation.cpp +160 -0
- package/cpp/zxing-core/core/src/qrcode/QRFormatInformation.h +61 -0
- package/cpp/zxing-core/core/src/qrcode/QRMaskUtil.cpp +156 -0
- package/cpp/zxing-core/core/src/qrcode/QRMaskUtil.h +15 -0
- package/cpp/zxing-core/core/src/qrcode/QRMatrixUtil.cpp +318 -0
- package/cpp/zxing-core/core/src/qrcode/QRMatrixUtil.h +25 -0
- package/cpp/zxing-core/core/src/qrcode/QRReader.cpp +149 -0
- package/cpp/zxing-core/core/src/qrcode/QRReader.h +21 -0
- package/cpp/zxing-core/core/src/qrcode/QRVersion.cpp +754 -0
- package/cpp/zxing-core/core/src/qrcode/QRVersion.h +127 -0
- package/cpp/zxing-core/core/src/qrcode/QRWriter.cpp +51 -0
- package/cpp/zxing-core/core/src/qrcode/QRWriter.h +74 -0
- package/cpp/zxing-core/core/version.rc.in +34 -0
- package/cpp/zxing-core/core/zxing.pc.in +8 -0
- package/cpp/zxing-core/wrappers/ios/README.md +25 -0
- package/cpp/zxing-core/wrappers/ios/Sources/Wrapper/Version.h +29 -0
- package/cpp/zxing-core/zxing-cpp.podspec +45 -0
- package/lib/factory.d.ts +10 -0
- package/lib/factory.js +12 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.js +9 -0
- package/lib/specs/Barcode.nitro.d.ts +63 -0
- package/lib/specs/Barcode.nitro.js +1 -0
- package/lib/specs/BarcodeFormat.d.ts +11 -0
- package/lib/specs/BarcodeFormat.js +1 -0
- package/lib/specs/BarcodeScanner.nitro.d.ts +89 -0
- package/lib/specs/BarcodeScanner.nitro.js +1 -0
- package/lib/specs/BarcodeScannerFactory.nitro.d.ts +26 -0
- package/lib/specs/BarcodeScannerFactory.nitro.js +1 -0
- package/lib/specs/BarcodeValueType.d.ts +9 -0
- package/lib/specs/BarcodeValueType.js +1 -0
- package/lib/specs/Point.d.ts +14 -0
- package/lib/specs/Point.js +1 -0
- package/lib/specs/Rect.d.ts +22 -0
- package/lib/specs/Rect.js +1 -0
- package/lib/useBarcodeScanner.d.ts +23 -0
- package/lib/useBarcodeScanner.js +25 -0
- package/nitro.json +20 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/VisionCameraZxing+autolinking.cmake +83 -0
- package/nitrogen/generated/android/VisionCameraZxing+autolinking.gradle +27 -0
- package/nitrogen/generated/android/VisionCameraZxingOnLoad.cpp +49 -0
- package/nitrogen/generated/android/VisionCameraZxingOnLoad.hpp +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/camera/zxing/VisionCameraZxingOnLoad.kt +35 -0
- package/nitrogen/generated/ios/VisionCameraZxing+autolinking.rb +62 -0
- package/nitrogen/generated/ios/VisionCameraZxing-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/VisionCameraZxing-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/VisionCameraZxing-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/VisionCameraZxingAutolinking.mm +35 -0
- package/nitrogen/generated/ios/VisionCameraZxingAutolinking.swift +16 -0
- package/nitrogen/generated/shared/c++/BarcodeFormat.hpp +124 -0
- package/nitrogen/generated/shared/c++/BarcodeScannerOptions.hpp +85 -0
- package/nitrogen/generated/shared/c++/BarcodeValueType.hpp +120 -0
- package/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridBarcodeScannerSpec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridBarcodeSpec.cpp +27 -0
- package/nitrogen/generated/shared/c++/HybridBarcodeSpec.hpp +82 -0
- package/nitrogen/generated/shared/c++/HybridZXingBarcodeScannerFactorySpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridZXingBarcodeScannerFactorySpec.hpp +67 -0
- package/nitrogen/generated/shared/c++/Point.hpp +87 -0
- package/nitrogen/generated/shared/c++/Rect.hpp +95 -0
- package/nitrogen/generated/shared/c++/TargetBarcodeFormat.hpp +124 -0
- package/package.json +108 -0
- package/react-native.config.js +16 -0
- package/src/factory.ts +26 -0
- package/src/index.ts +9 -0
- package/src/specs/Barcode.nitro.ts +70 -0
- package/src/specs/BarcodeFormat.ts +31 -0
- package/src/specs/BarcodeScanner.nitro.ts +91 -0
- package/src/specs/BarcodeScannerFactory.nitro.ts +27 -0
- package/src/specs/BarcodeValueType.ts +25 -0
- package/src/specs/Point.ts +14 -0
- package/src/specs/Rect.ts +22 -0
- package/src/useBarcodeScanner.ts +36 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# librscpp
|
|
2
|
+
|
|
3
|
+
`librscpp` is a small header-only Reed-Solomon implementation in C++20.
|
|
4
|
+
|
|
5
|
+
Pick a Galois field that matches your symbology or protocol, then call `encode()` or `decode()` on a codeword.
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```cpp
|
|
10
|
+
#include "librscpp/encode.h"
|
|
11
|
+
#include "librscpp/decode.h"
|
|
12
|
+
|
|
13
|
+
#include <string>
|
|
14
|
+
#include <print>
|
|
15
|
+
|
|
16
|
+
int main()
|
|
17
|
+
{
|
|
18
|
+
// GF(256) used in QR Codes with polynomial = x^8 + x^4 + x^3 + x^2 + 1 and fcr = 0.
|
|
19
|
+
auto field = librscpp::GF2n<uint8_t>(0b1'0001'1101, 0);
|
|
20
|
+
std::println("Using field: GF({}) and fcr: {}", field.size(), field.fcr());
|
|
21
|
+
|
|
22
|
+
const std::string data = "Hello, World!";
|
|
23
|
+
constexpr int paritySize = 4;
|
|
24
|
+
|
|
25
|
+
auto codeword = librscpp::encode(field, data, paritySize);
|
|
26
|
+
std::println("Encoded codeword: '{}'", codeword);
|
|
27
|
+
|
|
28
|
+
// Simulate a couple of symbol errors.
|
|
29
|
+
codeword[3] = codeword[8] = '*';
|
|
30
|
+
std::println("Corrupt codeword: '{}'", codeword);
|
|
31
|
+
|
|
32
|
+
auto res = librscpp::decode(field, codeword, paritySize);
|
|
33
|
+
if (res)
|
|
34
|
+
std::println("Decoded codeword: '{}'\nUsed parity symbols: {}", codeword, *res);
|
|
35
|
+
else
|
|
36
|
+
std::println("Failed to decode codeword.");
|
|
37
|
+
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Running this example program produces the following output:
|
|
43
|
+
```
|
|
44
|
+
Using field: GF(256) and fcr: 0
|
|
45
|
+
Encoded codeword: 'Hello, World!??t'
|
|
46
|
+
Corrupt codeword: 'Hel*o, W*rld!??t'
|
|
47
|
+
Decoded codeword: 'Hello, World!??t'
|
|
48
|
+
Used parity symbols: 4
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
|
|
53
|
+
The PDF417 symbology uses the prime GF(929) with primitive root 3 and fcr 1: `librscpp::GFp<>(929, 3, 1)`.
|
|
54
|
+
|
|
55
|
+
If you are low on memory, you can `#define LIBRSCPP_SAVE_MEMORY` before including the header to save 1/3 of runtime memory used by the GF internal lookup tables. Without that, each GF2n/GFp instance allocates 3 * field_size * sizeof(T) bytes. Also the default `value_type` of `GF2n<>` and `GFp<>` is `uint16_t`. If your field size is <=256 (like the one in the sample code), you can save 50% by using `uint8_t`.
|
|
56
|
+
|
|
57
|
+
Other common/usable `GF2n` configurations are:
|
|
58
|
+
```c++
|
|
59
|
+
GF2n<> gf_0x0013(0x0013, 1); // x^4 + x + 1
|
|
60
|
+
GF2n<> gf_0x0043(0x0043, 1); // x^6 + x + 1
|
|
61
|
+
GF2n<> gf_0x012D(0x012D, 1); // x^8 + x^5 + x^3 + x^2 + 1 : DataMatrix
|
|
62
|
+
GF2n<> gf_0x011D(0x011D, 0); // x^8 + x^4 + x^3 + x^2 + 1 : QRCode
|
|
63
|
+
GF2n<> gf_0x0409(0x0409, 1); // x^10 + x^3 + 1
|
|
64
|
+
GF2n<> gf_0x1069(0x1069, 1); // x^12 + x^6 + x^5 + x^3 + 1
|
|
65
|
+
```
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
// Copyright 2016 ZXing authors
|
|
2
|
+
// Copyright 2017-2026 Axel Waggershauser
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
#include "field.h"
|
|
6
|
+
#include "poly.h"
|
|
7
|
+
|
|
8
|
+
#include <algorithm>
|
|
9
|
+
#include <optional>
|
|
10
|
+
#include <stdexcept>
|
|
11
|
+
#include <type_traits>
|
|
12
|
+
#include <utility>
|
|
13
|
+
|
|
14
|
+
namespace librscpp {
|
|
15
|
+
|
|
16
|
+
namespace {
|
|
17
|
+
|
|
18
|
+
template <typename Field>
|
|
19
|
+
std::optional<std::tuple<Poly<Field>, Poly<Field>>> sugiyama_algorithm(Poly<Field>&& syndromes)
|
|
20
|
+
{
|
|
21
|
+
// See https://en.wikipedia.org/wiki/Reed–Solomon_error_correction#Sugiyama_decoder
|
|
22
|
+
auto& field = syndromes.field;
|
|
23
|
+
int R = syndromes.size();
|
|
24
|
+
syndromes.normalize();
|
|
25
|
+
size_t fullSize = R + 1;
|
|
26
|
+
size_t halfSize = (R + 1) / 2 + 1; // ceil(R / 2) + 1
|
|
27
|
+
Poly<Field> r(field, std::move(syndromes), fullSize), rLast(field, fullSize);
|
|
28
|
+
Poly<Field> tLast(field, halfSize), t(field, halfSize), q(field, halfSize);
|
|
29
|
+
|
|
30
|
+
rLast.set(1, R);
|
|
31
|
+
tLast.set(0);
|
|
32
|
+
t.set(1);
|
|
33
|
+
|
|
34
|
+
// Run extended Euclidean algorithm until r's degree is less than R/2
|
|
35
|
+
while (r.deg() >= R / 2) {
|
|
36
|
+
swap(tLast, t);
|
|
37
|
+
swap(rLast, r);
|
|
38
|
+
|
|
39
|
+
// Divide r by rLast, with quotient in q and remainder in r
|
|
40
|
+
r.div(rLast, q);
|
|
41
|
+
assert(r.deg() < rLast.deg());
|
|
42
|
+
|
|
43
|
+
q.mul(tLast);
|
|
44
|
+
t.sub(q);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (t.coef(0) == 0)
|
|
48
|
+
return {};
|
|
49
|
+
|
|
50
|
+
int inv_t0 = field.inv(t.coef(0));
|
|
51
|
+
t.mul(inv_t0);
|
|
52
|
+
r.mul(inv_t0);
|
|
53
|
+
|
|
54
|
+
// locator/lamda is t, evaluator/omega is r
|
|
55
|
+
return std::tuple{std::move(t), std::move(r)};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
template <typename Field>
|
|
59
|
+
static std::vector<int> find_locations(const Poly<Field>& locator)
|
|
60
|
+
{
|
|
61
|
+
// This is a brute force search for roots of locator (not Chien's search)
|
|
62
|
+
std::vector<int> res;
|
|
63
|
+
res.reserve(locator.deg());
|
|
64
|
+
|
|
65
|
+
for (int i = 1; i < locator.field.size() && res.size() < res.capacity(); i++)
|
|
66
|
+
if (locator.evaluate(i) == 0)
|
|
67
|
+
res.push_back(locator.field.inv(i));
|
|
68
|
+
|
|
69
|
+
return res;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
template <typename Field>
|
|
73
|
+
static std::vector<int> find_magnitudes(const Poly<Field>& evaluator, const Poly<Field>& locator [[maybe_unused]],
|
|
74
|
+
const std::vector<int>& locations)
|
|
75
|
+
{
|
|
76
|
+
// This is directly applying Forney's Formula
|
|
77
|
+
auto& field = evaluator.field;
|
|
78
|
+
int numErrors = std::ssize(locations);
|
|
79
|
+
std::vector<int> res(numErrors);
|
|
80
|
+
for (int i = 0; i < numErrors; ++i) {
|
|
81
|
+
int xiInverse = field.inv(locations[i]);
|
|
82
|
+
int denom = 1;
|
|
83
|
+
for (int j = 0; j < numErrors; ++j)
|
|
84
|
+
if (i != j)
|
|
85
|
+
denom = field.mul(denom, field.sub(1, field.mul(locations[j], xiInverse)));
|
|
86
|
+
res[i] = field.mul(evaluator.evaluate(xiInverse), field.inv(denom));
|
|
87
|
+
if (field.fcr() != 0)
|
|
88
|
+
res[i] = field.mul(res[i], xiInverse);
|
|
89
|
+
}
|
|
90
|
+
return res;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#if 0
|
|
94
|
+
template <>
|
|
95
|
+
std::vector<int> find_magnitudes(const Poly<GFpPDF417>& evaluator, const Poly<GFpPDF417>& locator,
|
|
96
|
+
const std::vector<int>& locations)
|
|
97
|
+
{
|
|
98
|
+
const auto& field = evaluator.field;
|
|
99
|
+
|
|
100
|
+
Poly<GFpPDF417> formalDerivative(field, locator.size());
|
|
101
|
+
formalDerivative.resize(locator.deg());
|
|
102
|
+
for (int i = 1; i <= locator.deg(); i++)
|
|
103
|
+
formalDerivative.coef(i - 1) = field.mul(i, locator.coef(i));
|
|
104
|
+
|
|
105
|
+
// This is directly applying Forney's Formula
|
|
106
|
+
std::vector<int> result(locations.size());
|
|
107
|
+
for (size_t i = 0; i < result.size(); i++) {
|
|
108
|
+
int xiInverse = field.inv(locations[i]);
|
|
109
|
+
int numerator = field.sub(0, evaluator.evaluate(xiInverse));
|
|
110
|
+
int denominator = field.inv(formalDerivative.evaluate(xiInverse));
|
|
111
|
+
result[i] = field.mul(numerator, denominator);
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
#endif
|
|
116
|
+
|
|
117
|
+
// Compute the Reed-Solomon syndrome polynomial for the given codeword.
|
|
118
|
+
// The returned polynomial has degree < numECC and is zero iff the codeword is valid.
|
|
119
|
+
template <typename Field, typename T>
|
|
120
|
+
Poly<Field> compute_syndromes(const Field& field, std::span<const T> codeword, int numECC)
|
|
121
|
+
{
|
|
122
|
+
#if 0
|
|
123
|
+
Poly<Field> syndromes(field, numECC + 1);
|
|
124
|
+
for (int i = 0; i < numECC; i++)
|
|
125
|
+
syndromes.push_back(Poly<Field>::evaluate(field, codeword, field.exp(numECC - 1 - i + field.fcr())));
|
|
126
|
+
return syndromes;
|
|
127
|
+
#else
|
|
128
|
+
// The following cache friendlier version is 2x to 5x faster than the straightforward one above
|
|
129
|
+
std::vector<typename Field::value_type> roots(numECC);
|
|
130
|
+
for (int i = 0; i < numECC; ++i)
|
|
131
|
+
roots[i] = field.exp(numECC - 1 - i + field.fcr());
|
|
132
|
+
|
|
133
|
+
std::vector<typename Field::value_type> res(numECC + 1, 0);
|
|
134
|
+
for (auto coeff : codeword)
|
|
135
|
+
for (int i = 0; i < numECC; ++i)
|
|
136
|
+
res[i] = field.add(field.mul(roots[i], res[i]), static_cast<std::make_unsigned_t<T>>(coeff));
|
|
137
|
+
res.resize(numECC);
|
|
138
|
+
|
|
139
|
+
return Poly<Field>(field, std::move(res));
|
|
140
|
+
#endif
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Decode and correct a Reed-Solomon codeword in place.
|
|
147
|
+
*
|
|
148
|
+
* @param field Finite field instance used by the RS code.
|
|
149
|
+
* @param codeword Input/output codeword symbols; corrected in place on success.
|
|
150
|
+
* @param numECC Number of ECC/parity symbols in the codeword.
|
|
151
|
+
* @param erasures Optional symbol indices known to be erased.
|
|
152
|
+
* @return Number of parity symbols consumed for correction (2*errors + erasures),
|
|
153
|
+
* 0 if no correction was needed, or std::nullopt if decoding failed.
|
|
154
|
+
* @throws std::invalid_argument If erasure count exceeds numECC or an erasure index is out of range.
|
|
155
|
+
*/
|
|
156
|
+
template <typename Field, std::integral T>
|
|
157
|
+
[[nodiscard]] std::optional<int> decode(const Field& field, std::span<T> codeword, int numECC, std::span<const int> erasures = {})
|
|
158
|
+
{
|
|
159
|
+
// See https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction and
|
|
160
|
+
// https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders for details on how RS works. See
|
|
161
|
+
// https://mthsc.clemson.edu/misc/MAM_2014/bmj9b.pdf for details on how to handle erasures and potential optimizations.
|
|
162
|
+
|
|
163
|
+
int cwLen = std::ssize(codeword);
|
|
164
|
+
int numErasures = std::ssize(erasures);
|
|
165
|
+
|
|
166
|
+
if (numErasures > numECC)
|
|
167
|
+
throw std::invalid_argument("Too many erasures to correct");
|
|
168
|
+
if (std::ranges::any_of(erasures, [cwLen](int e) { return e < 0 || e >= cwLen; }))
|
|
169
|
+
throw std::invalid_argument("Erasure position out of range");
|
|
170
|
+
|
|
171
|
+
if constexpr (std::is_same_v<Field, GFp<typename Field::value_type>>) {
|
|
172
|
+
// prevent potentially out-of-range values from causing out-of-bounds access in GFp's exp/log tables
|
|
173
|
+
for (auto& symbol : codeword)
|
|
174
|
+
symbol = std::clamp(symbol, 0, field.size() - 1);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
auto syndromes = compute_syndromes<Field, T>(field, codeword, numECC);
|
|
178
|
+
|
|
179
|
+
if (std::ranges::all_of(syndromes, [](auto c) { return c == 0; }))
|
|
180
|
+
return 0;
|
|
181
|
+
|
|
182
|
+
Poly<Field> oriSyndromes(field), erasureLocator(field, numErasures + 1);
|
|
183
|
+
|
|
184
|
+
// If there are erasures, we modify the syndromes to "remove" the effect of those...
|
|
185
|
+
if (!erasures.empty()) {
|
|
186
|
+
// Keep a copy of the original syndromes for later use in Forney's formula
|
|
187
|
+
oriSyndromes = syndromes.copy();
|
|
188
|
+
|
|
189
|
+
// Erasure locator: Λe(x) = ∏ (1 - Xi x), Xi = α^(cwLen - 1 - pos)
|
|
190
|
+
erasureLocator.set(1);
|
|
191
|
+
Poly<Field> term(field, {0, 1});
|
|
192
|
+
for (int pos : erasures) {
|
|
193
|
+
term.coef(1) = field.neg(field.exp((cwLen - 1 - pos)));
|
|
194
|
+
erasureLocator.mul(term);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// S'(x) = Λe(x) * S(x)
|
|
198
|
+
syndromes.mul(erasureLocator, numECC); // keep only the hightest numECC coefficients
|
|
199
|
+
syndromes.trimLeft(numErasures); // remove the highest numErasures coefficients, equivalent to dividing by x^(numECC - numErasures)
|
|
200
|
+
// syndromes now only contains the "error syndromes"
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
auto result = sugiyama_algorithm(std::move(syndromes));
|
|
204
|
+
if (!result)
|
|
205
|
+
return {};
|
|
206
|
+
|
|
207
|
+
auto [locator, evaluator] = std::move(*result); // Λ is error locator, Ω is error evaluator
|
|
208
|
+
|
|
209
|
+
int numErrors = locator.deg();
|
|
210
|
+
if (2 * numErrors + numErasures > numECC)
|
|
211
|
+
return {};
|
|
212
|
+
|
|
213
|
+
if (!erasures.empty()) {
|
|
214
|
+
// Λ'(x) = Λ(x) * Λe(x), i.e. merge erasure locator into error locator
|
|
215
|
+
locator.reserve(locator.size() + erasureLocator.size());
|
|
216
|
+
locator.mul(erasureLocator);
|
|
217
|
+
|
|
218
|
+
// Recompute evaluator/Ω so it matches the final combined locator/Λ'.
|
|
219
|
+
evaluator = std::move(oriSyndromes);
|
|
220
|
+
evaluator.mul(locator, -numECC); // keep only the lowest numECC coefficients
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
auto locations = find_locations(locator);
|
|
224
|
+
if (std::ssize(locations) != numErrors + numErasures)
|
|
225
|
+
return {}; // Error locator degree does not match number of roots, most likely there are more errors than can be recovered
|
|
226
|
+
|
|
227
|
+
auto magnitudes = find_magnitudes(evaluator, locator, locations);
|
|
228
|
+
|
|
229
|
+
for (int i = 0; i < numErrors + numErasures; ++i) {
|
|
230
|
+
int pos = cwLen - 1 - field.log(locations[i]);
|
|
231
|
+
if (pos < 0)
|
|
232
|
+
return {};
|
|
233
|
+
codeword[pos] = field.sub(codeword[pos], magnitudes[i]);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
#if 1
|
|
237
|
+
// re-evaluate the syndromes of the recovered codeword to make sure it is a valid codeword now (see #940-3)
|
|
238
|
+
syndromes = compute_syndromes<Field, T>(field, codeword, numECC);
|
|
239
|
+
if (std::ranges::any_of(syndromes, [](auto c) { return c != 0; }))
|
|
240
|
+
return {};
|
|
241
|
+
#endif
|
|
242
|
+
|
|
243
|
+
// if (numErasures)
|
|
244
|
+
// printf("erasures: %d, errors: %d, ecc: %d\n", numErasures, numErrors, numECC);
|
|
245
|
+
|
|
246
|
+
// Correcting 1 error consumes 2 parity symbols, correcting 1 erasure consumes 1 parity symbol.
|
|
247
|
+
return 2 * numErrors + numErasures;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
template <typename Field, std::ranges::contiguous_range R>
|
|
251
|
+
requires std::integral<std::ranges::range_value_t<R>>
|
|
252
|
+
[[nodiscard]] std::optional<int> decode(const Field& field, R&& codeword, int numECC, std::span<const int> erasures = {})
|
|
253
|
+
{
|
|
254
|
+
using T = std::ranges::range_value_t<R>;
|
|
255
|
+
return decode<Field, T>(field, std::span(codeword), numECC, erasures);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
} // namespace librscpp
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Copyright 2016 ZXing authors
|
|
2
|
+
// Copyright 2017-2026 Axel Waggershauser
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
#include "field.h"
|
|
6
|
+
#include "poly.h"
|
|
7
|
+
|
|
8
|
+
#include <algorithm>
|
|
9
|
+
#include <stdexcept>
|
|
10
|
+
#include <type_traits>
|
|
11
|
+
#include <utility>
|
|
12
|
+
|
|
13
|
+
namespace librscpp {
|
|
14
|
+
|
|
15
|
+
namespace {
|
|
16
|
+
|
|
17
|
+
template <typename Field>
|
|
18
|
+
Poly<Field> build_generator(const Field& field, int degree)
|
|
19
|
+
{
|
|
20
|
+
Poly<Field> generator(field, degree + 1);
|
|
21
|
+
generator.set(1);
|
|
22
|
+
Poly<Field> term(field, {1, 0});
|
|
23
|
+
for (int d = 1; d <= degree; d++) {
|
|
24
|
+
term.coef(0) = field.neg(field.exp(d - 1 + field.fcr()));
|
|
25
|
+
generator.mul(term);
|
|
26
|
+
}
|
|
27
|
+
return generator;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @brief Reed-Solomon systematic encoder.
|
|
34
|
+
*
|
|
35
|
+
* Computes parity symbols for @p data in the given Galois field and writes them to @p parity.
|
|
36
|
+
*
|
|
37
|
+
* @param field Galois field instance used for generator construction and arithmetic.
|
|
38
|
+
* @param data Data symbols.
|
|
39
|
+
* @param parity Output buffer for parity symbols. It's size determines the number of parity symbols.
|
|
40
|
+
*/
|
|
41
|
+
template <typename Field, std::integral T>
|
|
42
|
+
void encode(const Field& field, std::span<const T> data, std::span<T> parity)
|
|
43
|
+
{
|
|
44
|
+
if (data.empty() || parity.empty())
|
|
45
|
+
throw std::invalid_argument("Invalid number of data or parity symbols");
|
|
46
|
+
|
|
47
|
+
using FT = typename Field::value_type;
|
|
48
|
+
std::vector<FT> tmp;
|
|
49
|
+
std::span<FT const> data_;
|
|
50
|
+
if constexpr (!std::is_same_v<T, FT>) {
|
|
51
|
+
// If the message type is different from the field's value type, we need to copy it into a temporary buffer of the right type.
|
|
52
|
+
tmp.resize(data.size());
|
|
53
|
+
std::ranges::transform(data, tmp.begin(), [](T sym) { return static_cast<FT>(static_cast<std::make_unsigned_t<T>>(sym)); });
|
|
54
|
+
data_ = tmp;
|
|
55
|
+
} else {
|
|
56
|
+
data_ = std::span(data);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// See https://en.wikipedia.org/wiki/Reed–Solomon_error_correction#Systematic_encoding_procedure
|
|
60
|
+
|
|
61
|
+
auto generator = build_generator(field, parity.size());
|
|
62
|
+
|
|
63
|
+
Poly<Field> C(field, data_, data_.size() + parity.size());
|
|
64
|
+
Poly<Field> _(field, data_.size() + 1);
|
|
65
|
+
C.resize(data_.size() + parity.size()); // left-shift == multiply by x^(parity.size())
|
|
66
|
+
C.div(generator, _);
|
|
67
|
+
C.neg();
|
|
68
|
+
auto out = std::fill_n(parity.begin(), parity.size() - C.size(), 0);
|
|
69
|
+
std::ranges::transform(C, out, [](FT symbol) { return static_cast<T>(symbol); });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
template <typename Field, std::ranges::contiguous_range R, std::ranges::contiguous_range S>
|
|
73
|
+
requires std::same_as<std::ranges::range_value_t<R>, std::ranges::range_value_t<S>>
|
|
74
|
+
void encode(const Field& field, R&& data, S&& parity)
|
|
75
|
+
{
|
|
76
|
+
using T = std::ranges::range_value_t<R>;
|
|
77
|
+
encode<Field, T>(field, std::span<const T>(data), std::span<T>(parity));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @brief Reed-Solomon in-place systematic encoder.
|
|
82
|
+
*
|
|
83
|
+
* Computes parity symbols for the data prefix in @p codeword and stores them
|
|
84
|
+
* in the last @p num_parity elements of the same buffer.
|
|
85
|
+
*
|
|
86
|
+
* @param field Galois field instance used for generator construction and arithmetic.
|
|
87
|
+
* @param codeword Buffer containing data symbols followed by parity storage.
|
|
88
|
+
* @param num_parity Number of parity symbols to compute and write at the end of @p codeword.
|
|
89
|
+
*/
|
|
90
|
+
template <typename Field, std::ranges::contiguous_range R>
|
|
91
|
+
void encode_inplace(const Field& field, R&& codeword, int num_parity)
|
|
92
|
+
{
|
|
93
|
+
std::span cw(codeword);
|
|
94
|
+
auto data_size = std::ranges::ssize(codeword) - num_parity;
|
|
95
|
+
if (data_size <= 0 || num_parity <= 0)
|
|
96
|
+
throw std::invalid_argument("Invalid number of data or parity symbols");
|
|
97
|
+
encode(field, cw.subspan(0, data_size), cw.subspan(data_size));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @brief Reed-Solomon systematic encoder returning a full codeword.
|
|
102
|
+
*
|
|
103
|
+
* Appends @p num_parity parity symbols to @p data and returns the combined
|
|
104
|
+
* codeword in a container of type @p Result.
|
|
105
|
+
*
|
|
106
|
+
* @param field Galois field instance used for generator construction and arithmetic.
|
|
107
|
+
* @param data Input data symbols.
|
|
108
|
+
* @param num_parity Number of parity symbols to append.
|
|
109
|
+
* @return Result Codeword consisting of input data followed by parity symbols.
|
|
110
|
+
*/
|
|
111
|
+
template <typename Out = void, typename Field, std::ranges::contiguous_range In>
|
|
112
|
+
[[nodiscard]]
|
|
113
|
+
auto encode(const Field& field, In&& data, int num_parity)
|
|
114
|
+
{
|
|
115
|
+
using T = std::conditional_t<std::is_void_v<Out>, std::remove_cvref_t<In>, Out>;
|
|
116
|
+
T res;
|
|
117
|
+
res.reserve(std::ranges::size(data) + num_parity);
|
|
118
|
+
res.insert(res.end(), std::ranges::begin(data), std::ranges::end(data));
|
|
119
|
+
res.resize(res.size() + num_parity);
|
|
120
|
+
encode_inplace(field, res, num_parity);
|
|
121
|
+
return res;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
} // namespace librscpp
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Copyright 2016 ZXing authors
|
|
2
|
+
// Copyright 2017-2026 Axel Waggershauser
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
#include <cassert>
|
|
8
|
+
#include <concepts>
|
|
9
|
+
#include <cstdint>
|
|
10
|
+
#include <bit>
|
|
11
|
+
#include <functional>
|
|
12
|
+
#include <stdexcept>
|
|
13
|
+
#include <vector>
|
|
14
|
+
|
|
15
|
+
// #define LIBRSCPP_SAVE_MEMORY
|
|
16
|
+
|
|
17
|
+
namespace librscpp {
|
|
18
|
+
|
|
19
|
+
template <std::unsigned_integral T, std::integral HP>
|
|
20
|
+
class GFBase
|
|
21
|
+
{
|
|
22
|
+
static_assert(sizeof(T) <= sizeof(HP) && sizeof(HP) >= 2,
|
|
23
|
+
"HP must be able to hold values of type T and the result of their addition");
|
|
24
|
+
|
|
25
|
+
protected:
|
|
26
|
+
const int _size;
|
|
27
|
+
const int _fcr;
|
|
28
|
+
std::vector<T> _expTable, _logTable;
|
|
29
|
+
|
|
30
|
+
// avoid using the '%' modulo operator => decode computation can be more than twice as fast (depending on architecture)
|
|
31
|
+
// see also https://stackoverflow.com/a/33333636/2088798
|
|
32
|
+
inline static T fast_mod(HP input, HP mod) { return input < mod ? input : input - mod; }
|
|
33
|
+
|
|
34
|
+
GFBase(int size, int fcr, std::function<T(T)> next) : _size(size), _fcr(fcr)
|
|
35
|
+
{
|
|
36
|
+
if (size <= 0 || size > (1 << (sizeof(T) * 8)))
|
|
37
|
+
throw std::invalid_argument("Invalid field size " + std::to_string(size));
|
|
38
|
+
if (fcr < 0 || fcr >= size)
|
|
39
|
+
throw std::invalid_argument("Invalid first consecutive root " + std::to_string(fcr) + " for field of size "
|
|
40
|
+
+ std::to_string(size));
|
|
41
|
+
|
|
42
|
+
#ifdef LIBRSCPP_SAVE_MEMORY
|
|
43
|
+
_expTable.resize(size, 0);
|
|
44
|
+
#else
|
|
45
|
+
_expTable.resize(size * 2, 0);
|
|
46
|
+
#endif
|
|
47
|
+
_logTable.resize(size, 0);
|
|
48
|
+
int x = 1;
|
|
49
|
+
for (int i = 0; i < size; ++i) {
|
|
50
|
+
_expTable[i] = x;
|
|
51
|
+
x = next(x);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#ifndef LIBRSCPP_SAVE_MEMORY
|
|
55
|
+
for (int i = size - 1; i < size * 2; ++i)
|
|
56
|
+
_expTable[i] = _expTable[i - (size - 1)];
|
|
57
|
+
#endif
|
|
58
|
+
|
|
59
|
+
for (int i = 0; i < size - 1; ++i)
|
|
60
|
+
_logTable[_expTable[i]] = i;
|
|
61
|
+
// logTable[0] == 0 but this should never be used
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public:
|
|
65
|
+
using value_type = T;
|
|
66
|
+
|
|
67
|
+
// 2 to the power of a
|
|
68
|
+
T exp(T a) const { return _expTable.at((a)); }
|
|
69
|
+
|
|
70
|
+
// base 2 log of a
|
|
71
|
+
T log(T a) const
|
|
72
|
+
{
|
|
73
|
+
assert(a != 0);
|
|
74
|
+
return _logTable.at((a));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// multiplicative inverse of a (== 1/a)
|
|
78
|
+
T inv(T a) const { return _expTable[_size - 1 - log(a)]; }
|
|
79
|
+
|
|
80
|
+
// product of a and b
|
|
81
|
+
T mul(T a, T b) const noexcept
|
|
82
|
+
{
|
|
83
|
+
if (a == 0 || b == 0)
|
|
84
|
+
return 0;
|
|
85
|
+
|
|
86
|
+
// this is in the hot path, operator[] is around 20% faster than at() for the unit tests
|
|
87
|
+
#ifdef LIBRSCPP_SAVE_MEMORY
|
|
88
|
+
return _expTable[fast_mod(HP(_logTable[a]) + HP(_logTable[b]), _size - 1)];
|
|
89
|
+
#else
|
|
90
|
+
return _expTable[HP(_logTable[a]) + HP(_logTable[b])];
|
|
91
|
+
#endif
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
int size() const noexcept { return _size; }
|
|
95
|
+
|
|
96
|
+
// first consecutive root of the RS generator polynomial, sometimes also called "b" or "base"
|
|
97
|
+
int fcr() const noexcept { return _fcr; }
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @brief Represents an extension Galois Field GF(2^n).
|
|
102
|
+
*/
|
|
103
|
+
template <std::unsigned_integral T = uint16_t, std::integral HP = uint32_t>
|
|
104
|
+
class GF2n : public GFBase<T, HP>
|
|
105
|
+
{
|
|
106
|
+
public:
|
|
107
|
+
/**
|
|
108
|
+
* @brief Create a Galois Field GF(2^n) using the given primitive polynomial.
|
|
109
|
+
*
|
|
110
|
+
* @param poly irreducible polynomial whose coefficients are represented by
|
|
111
|
+
* the bits of an int, where the least-significant bit represents the constant
|
|
112
|
+
* coefficient and the most-significant bit represents the x^n coefficient and defines the size of the field.
|
|
113
|
+
* For example, 0b1'0001'1101 represents the primitive polynomial x^8 + x^4 + x^3 + x^2 + 1.
|
|
114
|
+
* @param fcr the first consecutive root of the RS generator polynomial, sometimes also called "b" or "base"
|
|
115
|
+
* (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))). This is typically 1, but for e.g. QR Code it is 0.
|
|
116
|
+
* It is technially not a property of the field but instead a property of the RS code defined over the field.
|
|
117
|
+
*/
|
|
118
|
+
GF2n(uint32_t poly, int fcr)
|
|
119
|
+
: GFBase<T, HP>(1 << (std::bit_width(poly) - 1), fcr, [poly, size = HP(1 << (std::bit_width(poly) - 1))](T x) {
|
|
120
|
+
HP ix = x;
|
|
121
|
+
ix *= 2; // multiply by the primitive element / generator α (== x^1)
|
|
122
|
+
if (ix >= size) // if deg(ix) == deg(poly), reduce modulo poly by subtracting it (== XOR)
|
|
123
|
+
ix ^= poly;
|
|
124
|
+
return ix;
|
|
125
|
+
})
|
|
126
|
+
{}
|
|
127
|
+
|
|
128
|
+
T add(T a, T b) const { return a ^ b; }
|
|
129
|
+
T sub(T a, T b) const { return a ^ b; } // a - b == a + b in GF(2^n)
|
|
130
|
+
T neg(T a) const { return a; } // -a == a in GF(2^n)
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @brief Represents a prime Galois Field GF(p).
|
|
135
|
+
*/
|
|
136
|
+
template <std::unsigned_integral T = uint16_t, std::integral HP = uint32_t>
|
|
137
|
+
class GFp : public GFBase<T, HP>
|
|
138
|
+
{
|
|
139
|
+
using Base = GFBase<T, HP>;
|
|
140
|
+
|
|
141
|
+
public:
|
|
142
|
+
/**
|
|
143
|
+
* @brief Create a Galois Field GF(p) using the given prime.
|
|
144
|
+
*
|
|
145
|
+
* @param prime a prime number representing the size of the field
|
|
146
|
+
* @param generator a primitive root modulo prime, used as the generator α of GF(p)
|
|
147
|
+
* @param fcr the first consecutive root of the RS generator polynomial, sometimes also called "b" or "base"
|
|
148
|
+
*/
|
|
149
|
+
GFp(uint32_t prime, uint32_t generator, int fcr)
|
|
150
|
+
: GFBase<T, HP>(prime, fcr, [prime, generator](T x) { return (x * generator) % prime; })
|
|
151
|
+
{}
|
|
152
|
+
|
|
153
|
+
T add(T a, T b) const { return Base::fast_mod(HP(a) + HP(b), Base::size()); }
|
|
154
|
+
T sub(T a, T b) const { return Base::fast_mod(Base::size() + HP(a) - HP(b), Base::size()); }
|
|
155
|
+
T neg(T a) const { return sub(0, a); }
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
} // namespace librscpp
|