diff --git a/Package.swift b/Package.swift new file mode 100644 index 000000000..de0e74193 --- /dev/null +++ b/Package.swift @@ -0,0 +1,74 @@ +// swift-tools-version:5.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "ZXingObjC", + products: [ + // Products define the executables and libraries produced by a package, and make them visible to other packages. + .library( + name: "ZXingObjC", + targets: ["ZXingObjC"] + ), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target( + name: "ZXingObjC", + dependencies: [], + path: "ZXingObjC", + publicHeadersPath: "include", + cxxSettings: [ + .headerSearchPath("aztec"), + .headerSearchPath("aztec/decoder"), + .headerSearchPath("aztec/detector"), + .headerSearchPath("aztec/encoder"), + + .headerSearchPath("client"), + .headerSearchPath("client/result"), + + .headerSearchPath("common"), + .headerSearchPath("common/detector"), + .headerSearchPath("common/reedsolomon"), + + .headerSearchPath("core"), + + .headerSearchPath("datamatrix"), + .headerSearchPath("datamatrix/decoder"), + .headerSearchPath("datamatrix/detector"), + .headerSearchPath("datamatrix/encoder"), + + .headerSearchPath("maxicode"), + .headerSearchPath("maxicode/decoder"), + + .headerSearchPath("multi"), + + .headerSearchPath("oned"), + .headerSearchPath("oned/rss"), + .headerSearchPath("oned/rss/expanded"), + .headerSearchPath("oned/rss/expanded/decoders"), + + .headerSearchPath("pdf417"), + .headerSearchPath("pdf417/decoder"), + .headerSearchPath("pdf417/decoder/ec"), + .headerSearchPath("pdf417/detector"), + .headerSearchPath("pdf417/encoder"), + + .headerSearchPath("qrcode"), + .headerSearchPath("qrcode/decoder"), + .headerSearchPath("qrcode/detector"), + .headerSearchPath("qrcode/encoder"), + .headerSearchPath("qrcode/multi"), + .headerSearchPath("qrcode/multi/detector"), + ], + linkerSettings: [ + .unsafeFlags(["-fprofile-instr-generate"]) + ] + ) + ] +) diff --git a/README.md b/README.md index 977614f80..9401fc9e5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -ZXingObjC -========= +# zxingify-objc ZXingObjC is a full Objective-C port of [ZXing](https://github.com/zxing/zxing) ("Zebra Crossing"), a Java barcode image processing library. It is designed to be used on both iOS devices and in Mac applications. @@ -15,14 +14,15 @@ The following barcodes are currently supported for both encoding and decoding: * RSS-14 (all variants) * QR Code * Data Matrix +* Maxicode * Aztec ('beta' quality) -* PDF 417 ('alpha' quality) +* PDF 417 ('beta' quality) -ZXingObjC currently has feature parity with ZXing version 3.0. +ZXingObjC currently has feature parity with ZXing version 3.3.3. ## Requirements -ZXingObjC requires Xcode 5, targeting either iOS 6.0 and above, or Mac OS X 10.8 Mountain Lion and above. +ZXingObjC requires Xcode 13.0 and above, targeting either iOS 11.0 and above, or Mac OS X 10.15 Catalina and above. ## Usage @@ -37,9 +37,11 @@ ZXBitMatrix* result = [writer encode:@"A string to encode" height:500 error:&error]; if (result) { - CGImageRef image = [[ZXImage imageWithMatrix:result] cgimage]; + CGImageRef image = CGImageRetain([[ZXImage imageWithMatrix:result] cgimage]); // This CGImageRef image can be placed in a UIImage, NSImage, or written to a file. + + CGImageRelease(image); } else { NSString *errorMessage = [error localizedDescription]; } @@ -78,11 +80,23 @@ if (result) { ## Installation -The recommended way to install ZXingObjC is with [CocoaPods](http://cocoapods.org), a dependency mananger for Objective-C projects. After installing CocoaPods just add ZXingObjC to your Podfile: +We highly recommend Carthage as module manager. + +#### Carthage + +ZXingObjC can be installed using [Carthage](https://github.com/Carthage/Carthage). After installing Carthage just add ZXingObjC to your Cartfile: + +```ogdl +github "zxingify/zxingify-objc" ~> 3.6.9 +``` + +#### CocoaPods + +[CocoaPods](http://cocoapods.org) is a dependency manager for Swift and Objective-C Cocoa projects. After installing CocoaPods add ZXingObjC to your Podfile: ```ruby -platform :ios, '7.0' -pod 'ZXingObjC', '~> 3.0' +platform :ios, '11.0' +pod 'ZXingObjC', '~> 3.6.9' ``` ## Examples @@ -90,8 +104,13 @@ pod 'ZXingObjC', '~> 3.0' ZXingObjC includes several example applications found in "examples" folder: * BarcodeScanner - An iOS application that captures video from the camera, scans for barcodes and displays results on screen. -* BarcodeScannerOSX - An OS X application that captures video from the camera, scans for barcodes and displays results on screen. -* QrCodeTest - A basic QR code generator that accepts input, encodes it as a QR code, and displays it on screen. +* BarcodeScannerSwift - An iOS application that captures video from the camera, scans for barcodes and displays results on screen, completely rewritten in Swift. + +## Kudos + +- [cwalcott](https://github.com/cwalcott) initial creator of this project +- [neacao](https://github.com/neacao) for his unparalleled support lately +- [claybridges](https://github.com/claybridges) for all the help regarding the project move ## License diff --git a/ZXingObjC.podspec b/ZXingObjC.podspec index f7c55c300..ed38291db 100644 --- a/ZXingObjC.podspec +++ b/ZXingObjC.podspec @@ -1,16 +1,16 @@ Pod::Spec.new do |s| s.name = 'ZXingObjC' - s.version = '3.1.0' + s.version = '3.6.9' s.summary = 'An Objective-C Port of the ZXing barcode framework.' - s.homepage = 'https://github.com/TheLevelUp/ZXingObjC' - s.author = 'ZXingObjC team' + s.homepage = 'https://github.com/zxingify/zxingify-objc' + s.author = 'zxingify' s.license = { :type => 'Apache License 2.0', :file => 'COPYING' } - s.source = { :git => 'https://github.com/TheLevelUp/ZXingObjC.git', :tag => "#{s.version}" } + s.source = { :git => 'https://github.com/zxingify/zxingify-objc.git', :tag => "#{s.version}" } s.requires_arc = true s.xcconfig = { "OTHER_LDFLAGS" => "-ObjC" } - s.ios.deployment_target = '6.0' - s.osx.deployment_target = '10.8' + s.ios.deployment_target = '11.0' + s.osx.deployment_target = '10.15' s.ios.frameworks = 'AVFoundation', 'CoreGraphics', 'CoreMedia', 'CoreVideo', 'ImageIO', 'QuartzCore' s.osx.frameworks = 'AVFoundation', 'CoreMedia', 'QuartzCore' @@ -19,10 +19,12 @@ Pod::Spec.new do |s| s.subspec 'All' do |ss| ss.source_files = 'ZXingObjC/**/*.{h,m}' + ss.exclude_files = 'ZXingObjC/include/**/*.h' end s.subspec 'Core' do |ss| ss.source_files = 'ZXingObjC/*.{h,m}', 'ZXingObjC/client/*.{h,m}', 'ZXingObjC/common/**/*.{h,m}', 'ZXingObjC/core/**/*.{h,m}', 'ZXingObjC/multi/**/*.{h,m}' + ss.xcconfig = { "GCC_PREPROCESSOR_DEFINITIONS" => "ZXINGOBJC_USE_SUBSPECS" } end s.subspec 'Aztec' do |ss| diff --git a/ZXingObjC.xcodeproj/project.pbxproj b/ZXingObjC.xcodeproj/project.pbxproj index 49ff8fa7e..ea4b01c83 100644 --- a/ZXingObjC.xcodeproj/project.pbxproj +++ b/ZXingObjC.xcodeproj/project.pbxproj @@ -541,10 +541,18 @@ 02DD029B1AC1C648009E4D65 /* ZXPDF417EncoderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 02DD02991AC1C648009E4D65 /* ZXPDF417EncoderTestCase.m */; }; 02DD029F1AC1DBAD009E4D65 /* ZXAztecDecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 02DD029E1AC1DBAD009E4D65 /* ZXAztecDecoderTest.m */; }; 02DD02A01AC1DBAD009E4D65 /* ZXAztecDecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 02DD029E1AC1DBAD009E4D65 /* ZXAztecDecoderTest.m */; }; - 074684321BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 074684311BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m */; settings = {ASSET_TAGS = (); }; }; - 074684331BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 074684311BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m */; settings = {ASSET_TAGS = (); }; }; - 074684361BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 074684351BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m */; settings = {ASSET_TAGS = (); }; }; - 074684371BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 074684351BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m */; settings = {ASSET_TAGS = (); }; }; + 074684321BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 074684311BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m */; }; + 074684331BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 074684311BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m */; }; + 074684361BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 074684351BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m */; }; + 074684371BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 074684351BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m */; }; + 2172BAF91E1C6087004327CB /* ZXUPCEWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2172BAF71E1C6087004327CB /* ZXUPCEWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2172BAFA1E1C6087004327CB /* ZXUPCEWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2172BAF81E1C6087004327CB /* ZXUPCEWriter.m */; }; + 2172BAFB1E1C6090004327CB /* ZXUPCEWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2172BAF71E1C6087004327CB /* ZXUPCEWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2172BAFC1E1C6090004327CB /* ZXUPCEWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2172BAF81E1C6087004327CB /* ZXUPCEWriter.m */; }; + 2172BAFD1E1C6091004327CB /* ZXUPCEWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2172BAF71E1C6087004327CB /* ZXUPCEWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2172BAFE1E1C6091004327CB /* ZXUPCEWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2172BAF81E1C6087004327CB /* ZXUPCEWriter.m */; }; + 2172BAFF1E1C6091004327CB /* ZXUPCEWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2172BAF71E1C6087004327CB /* ZXUPCEWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2172BB001E1C6091004327CB /* ZXUPCEWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2172BAF81E1C6087004327CB /* ZXUPCEWriter.m */; }; 2504D9D016FFD2E200DF8882 /* ZXAztecCode.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9CE16FFD2E200DF8882 /* ZXAztecCode.m */; }; 2504D9D116FFD3A100DF8882 /* ZXAztecCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504D9CD16FFD2E200DF8882 /* ZXAztecCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2504D9D316FFD3B300DF8882 /* ZXAztecCode.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9CE16FFD2E200DF8882 /* ZXAztecCode.m */; }; @@ -1660,6 +1668,57 @@ 25FE5D4016D0B84C00826CDB /* ZXRSSExpandedStackedInternalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3F16D0B84C00826CDB /* ZXRSSExpandedStackedInternalTestCase.m */; }; 25FE5D4316D0B8B200826CDB /* ZXTestCaseUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D4216D0B8B200826CDB /* ZXTestCaseUtil.m */; }; 25FE5D4516D1997C00826CDB /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 25FE5D4416D1997C00826CDB /* Resources */; }; + 4B2058252155B4F1009146DB /* ZXRGBLuminanceSourceTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B20581C2155B19C009146DB /* ZXRGBLuminanceSourceTestCase.m */; }; + 4B2058262155B4F1009146DB /* ZXRGBLuminanceSourceTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B20581C2155B19C009146DB /* ZXRGBLuminanceSourceTestCase.m */; }; + 4B42B89F215904EB0010C328 /* ZXUPCEWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B42B89E215904EB0010C328 /* ZXUPCEWriterTestCase.m */; }; + 4B42B8A421590C920010C328 /* ZXITFWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B42B8A321590C920010C328 /* ZXITFWriterTestCase.m */; }; + 4B42B8A521590C920010C328 /* ZXITFWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B42B8A321590C920010C328 /* ZXITFWriterTestCase.m */; }; + 4B42B8A7215917A40010C328 /* ZXCode39ExtendedModeTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B42B8A6215917A40010C328 /* ZXCode39ExtendedModeTestCase.m */; }; + 4B42B8A8215917A40010C328 /* ZXCode39ExtendedModeTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B42B8A6215917A40010C328 /* ZXCode39ExtendedModeTestCase.m */; }; + 4B501858215A2EB800ACD238 /* ZXPDF417DecoderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B501857215A2EB800ACD238 /* ZXPDF417DecoderTestCase.m */; }; + 4B501859215A2EB800ACD238 /* ZXPDF417DecoderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B501857215A2EB800ACD238 /* ZXPDF417DecoderTestCase.m */; }; + 4B50185C215A379300ACD238 /* ZXGenericGFPolyTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B50185B215A379200ACD238 /* ZXGenericGFPolyTestCase.m */; }; + 4B50185D215A379300ACD238 /* ZXGenericGFPolyTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B50185B215A379200ACD238 /* ZXGenericGFPolyTestCase.m */; }; + 4B5D6CBB215B851F00EE122A /* ZXDecimal.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5D6CBA215B851F00EE122A /* ZXDecimal.m */; }; + 4B5D6CBC215B851F00EE122A /* ZXDecimal.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5D6CBA215B851F00EE122A /* ZXDecimal.m */; }; + 4B5D6CBD215B851F00EE122A /* ZXDecimal.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5D6CBA215B851F00EE122A /* ZXDecimal.m */; }; + 4B5D6CBE215B851F00EE122A /* ZXDecimal.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5D6CBA215B851F00EE122A /* ZXDecimal.m */; }; + 4B5D6CC5215B8E7600EE122A /* ZXDecimalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5D6CC0215B8E2300EE122A /* ZXDecimalTestCase.m */; }; + 4B5D6CC6215B8E7800EE122A /* ZXDecimalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B5D6CC0215B8E2300EE122A /* ZXDecimalTestCase.m */; }; + 4B674F132157E84200F97DEE /* ZXMaxicodeBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B674F0F2157E7FD00F97DEE /* ZXMaxicodeBlackBox1TestCase.m */; }; + 4B674F142157E84200F97DEE /* ZXMaxicodeBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B674F0F2157E7FD00F97DEE /* ZXMaxicodeBlackBox1TestCase.m */; }; + 4B7ACDA52153D8AA001EB8A5 /* ZXCode93Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7ACDA42153D8AA001EB8A5 /* ZXCode93Writer.m */; }; + 4B7ACDA62153D8AA001EB8A5 /* ZXCode93Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7ACDA42153D8AA001EB8A5 /* ZXCode93Writer.m */; }; + 4B7ACDA72153D8AA001EB8A5 /* ZXCode93Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7ACDA42153D8AA001EB8A5 /* ZXCode93Writer.m */; }; + 4B7ACDA82153D8AA001EB8A5 /* ZXCode93Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B7ACDA42153D8AA001EB8A5 /* ZXCode93Writer.m */; }; + 4B7ACDAA2153D8B8001EB8A5 /* ZXCode93Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B7ACDA92153D8B8001EB8A5 /* ZXCode93Writer.h */; }; + 4B7ACDAB2153D8B8001EB8A5 /* ZXCode93Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B7ACDA92153D8B8001EB8A5 /* ZXCode93Writer.h */; }; + 4B7ACDAC2153D8B8001EB8A5 /* ZXCode93Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B7ACDA92153D8B8001EB8A5 /* ZXCode93Writer.h */; }; + 4B7ACDAD2153D8B8001EB8A5 /* ZXCode93Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B7ACDA92153D8B8001EB8A5 /* ZXCode93Writer.h */; }; + 4B9DB4472158C1D800A10495 /* ZXPDF417WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB4462158C1D800A10495 /* ZXPDF417WriterTestCase.m */; }; + 4B9DB4482158C1D800A10495 /* ZXPDF417WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB4462158C1D800A10495 /* ZXPDF417WriterTestCase.m */; }; + 4B9DB44B2158CCF400A10495 /* ZXMultiTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB44A2158CCF400A10495 /* ZXMultiTestCase.m */; }; + 4B9DB44C2158CCF400A10495 /* ZXMultiTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB44A2158CCF400A10495 /* ZXMultiTestCase.m */; }; + 4B9DB4502158D3F700A10495 /* ZXCode39WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB44F2158D3F700A10495 /* ZXCode39WriterTestCase.m */; }; + 4B9DB4512158D3F700A10495 /* ZXCode39WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB44F2158D3F700A10495 /* ZXCode39WriterTestCase.m */; }; + 4B9DB4532158D40A00A10495 /* ZXCode93WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB4522158D40A00A10495 /* ZXCode93WriterTestCase.m */; }; + 4B9DB4542158D40A00A10495 /* ZXCode93WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB4522158D40A00A10495 /* ZXCode93WriterTestCase.m */; }; + 4B9E58CE215CDCEB0045E4BD /* ZXDataMatrixWriterAdditionalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9E58CD215CDCEB0045E4BD /* ZXDataMatrixWriterAdditionalTestCase.m */; }; + 4B9E58CF215CDCEB0045E4BD /* ZXDataMatrixWriterAdditionalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B9E58CD215CDCEB0045E4BD /* ZXDataMatrixWriterAdditionalTestCase.m */; }; + 4BA2FEC021B1711E0030F557 /* ZXCode93ReaderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA2FEBF21B1711E0030F557 /* ZXCode93ReaderTestCase.m */; }; + 4BA2FEC121B1711E0030F557 /* ZXCode93ReaderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA2FEBF21B1711E0030F557 /* ZXCode93ReaderTestCase.m */; }; + 4BFDC4A2215BCF7B00580F5C /* ZXPDF417BlackBox5TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDC4A1215BCF7B00580F5C /* ZXPDF417BlackBox5TestCase.m */; }; + 4BFDC4A3215BCF7B00580F5C /* ZXPDF417BlackBox5TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDC4A1215BCF7B00580F5C /* ZXPDF417BlackBox5TestCase.m */; }; + 7967E67E2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7967E67C2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7967E67F2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 7967E67D2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.m */; }; + 7967E68B21646DC300C28E42 /* ZXCGImageLuminanceSourceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 7967E67D2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.m */; }; + 7967E68C21646DC300C28E42 /* ZXCGImageLuminanceSourceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 7967E67D2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.m */; }; + 7967E68D21646DC300C28E42 /* ZXCGImageLuminanceSourceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 7967E67D2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.m */; }; + 7967E68E21646DCA00C28E42 /* ZXCGImageLuminanceSourceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7967E67C2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7967E68F21646DCB00C28E42 /* ZXCGImageLuminanceSourceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7967E67C2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7967E69021646DCB00C28E42 /* ZXCGImageLuminanceSourceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7967E67C2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79983A472164756000E311F8 /* ZXQRCodeBlackBox7TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 79983A442164755400E311F8 /* ZXQRCodeBlackBox7TestCase.m */; }; + 79983A482164756100E311F8 /* ZXQRCodeBlackBox7TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 79983A442164755400E311F8 /* ZXQRCodeBlackBox7TestCase.m */; }; DB7257521A52420400EFF81B /* ZXAztecDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CEF166A999D00E13304 /* ZXAztecDecoder.m */; }; DB7257531A52420400EFF81B /* ZXAztecWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB3317FD1EC000A71C45 /* ZXAztecWriter.m */; }; DB7257541A52420400EFF81B /* ZXAztecDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF2166A999D00E13304 /* ZXAztecDetector.m */; }; @@ -2234,6 +2293,8 @@ 074684311BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGenericMultipleBarcodeReaderTestCase.m; sourceTree = ""; }; 074684341BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMultiAbstractBlackBoxTestCase.h; sourceTree = ""; }; 074684351BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMultiAbstractBlackBoxTestCase.m; sourceTree = ""; }; + 2172BAF71E1C6087004327CB /* ZXUPCEWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCEWriter.h; sourceTree = ""; }; + 2172BAF81E1C6087004327CB /* ZXUPCEWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCEWriter.m; sourceTree = ""; }; 2504D9CD16FFD2E200DF8882 /* ZXAztecCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXAztecCode.h; path = encoder/ZXAztecCode.h; sourceTree = ""; }; 2504D9CE16FFD2E200DF8882 /* ZXAztecCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXAztecCode.m; path = encoder/ZXAztecCode.m; sourceTree = ""; }; 2504D9DA16FFD4CD00DF8882 /* ZXAztecEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXAztecEncoder.h; path = encoder/ZXAztecEncoder.h; sourceTree = ""; }; @@ -2873,6 +2934,45 @@ 25FE5D4116D0B8B100826CDB /* ZXTestCaseUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXTestCaseUtil.h; sourceTree = ""; }; 25FE5D4216D0B8B200826CDB /* ZXTestCaseUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXTestCaseUtil.m; sourceTree = ""; }; 25FE5D4416D1997C00826CDB /* Resources */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Resources; sourceTree = ""; }; + 4B20581B2155B19C009146DB /* ZXRGBLuminanceSourceTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXRGBLuminanceSourceTestCase.h; sourceTree = ""; }; + 4B20581C2155B19C009146DB /* ZXRGBLuminanceSourceTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZXRGBLuminanceSourceTestCase.m; sourceTree = ""; }; + 4B42B89E215904EB0010C328 /* ZXUPCEWriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCEWriterTestCase.m; sourceTree = ""; }; + 4B42B8A1215904F30010C328 /* ZXUPCEWriterTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXUPCEWriterTestCase.h; sourceTree = ""; }; + 4B42B8A221590C880010C328 /* ZXITFWriterTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXITFWriterTestCase.h; sourceTree = ""; }; + 4B42B8A321590C920010C328 /* ZXITFWriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXITFWriterTestCase.m; sourceTree = ""; }; + 4B42B8A6215917A40010C328 /* ZXCode39ExtendedModeTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode39ExtendedModeTestCase.m; sourceTree = ""; }; + 4B42B8A9215917AD0010C328 /* ZXCode39ExtendedModeTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXCode39ExtendedModeTestCase.h; sourceTree = ""; }; + 4B501856215A2EA900ACD238 /* ZXPDF417DecoderTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXPDF417DecoderTestCase.h; sourceTree = ""; }; + 4B501857215A2EB800ACD238 /* ZXPDF417DecoderTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417DecoderTestCase.m; sourceTree = ""; }; + 4B50185A215A378C00ACD238 /* ZXGenericGFPolyTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXGenericGFPolyTestCase.h; sourceTree = ""; }; + 4B50185B215A379200ACD238 /* ZXGenericGFPolyTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGenericGFPolyTestCase.m; sourceTree = ""; }; + 4B5D6CB9215B850B00EE122A /* ZXDecimal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDecimal.h; sourceTree = ""; }; + 4B5D6CBA215B851F00EE122A /* ZXDecimal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDecimal.m; sourceTree = ""; }; + 4B5D6CBF215B8E1400EE122A /* ZXDecimalTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDecimalTestCase.h; sourceTree = ""; }; + 4B5D6CC0215B8E2300EE122A /* ZXDecimalTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDecimalTestCase.m; sourceTree = ""; }; + 4B674F0F2157E7FD00F97DEE /* ZXMaxicodeBlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMaxicodeBlackBox1TestCase.m; sourceTree = ""; }; + 4B674F112157E82A00F97DEE /* ZXMaxicodeBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMaxicodeBlackBox1TestCase.h; sourceTree = ""; }; + 4B7ACDA42153D8AA001EB8A5 /* ZXCode93Writer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode93Writer.m; sourceTree = ""; }; + 4B7ACDA92153D8B8001EB8A5 /* ZXCode93Writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCode93Writer.h; sourceTree = ""; }; + 4B9DB4462158C1D800A10495 /* ZXPDF417WriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417WriterTestCase.m; sourceTree = ""; }; + 4B9DB4492158C1E300A10495 /* ZXPDF417WriterTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXPDF417WriterTestCase.h; sourceTree = ""; }; + 4B9DB44A2158CCF400A10495 /* ZXMultiTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMultiTestCase.m; sourceTree = ""; }; + 4B9DB44D2158CCFD00A10495 /* ZXMultiTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXMultiTestCase.h; sourceTree = ""; }; + 4B9DB44E2158D3EF00A10495 /* ZXCode39WriterTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXCode39WriterTestCase.h; sourceTree = ""; }; + 4B9DB44F2158D3F700A10495 /* ZXCode39WriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode39WriterTestCase.m; sourceTree = ""; }; + 4B9DB4522158D40A00A10495 /* ZXCode93WriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode93WriterTestCase.m; sourceTree = ""; }; + 4B9DB4552158D41200A10495 /* ZXCode93WriterTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXCode93WriterTestCase.h; sourceTree = ""; }; + 4B9E58CD215CDCEB0045E4BD /* ZXDataMatrixWriterAdditionalTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixWriterAdditionalTestCase.m; sourceTree = ""; }; + 4B9E58D0215CDD320045E4BD /* ZXDataMatrixWriterAdditionalTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixWriterAdditionalTestCase.h; sourceTree = ""; }; + 4BA2FEBF21B1711E0030F557 /* ZXCode93ReaderTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode93ReaderTestCase.m; sourceTree = ""; }; + 4BA2FEC221B171330030F557 /* ZXCode93ReaderTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXCode93ReaderTestCase.h; sourceTree = ""; }; + 4BFDC4A1215BCF7B00580F5C /* ZXPDF417BlackBox5TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417BlackBox5TestCase.m; sourceTree = ""; }; + 4BFDC4A4215BCF9000580F5C /* ZXPDF417BlackBox5TestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXPDF417BlackBox5TestCase.h; sourceTree = ""; }; + 7967E67C2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCGImageLuminanceSourceInfo.h; sourceTree = ""; }; + 7967E67D2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCGImageLuminanceSourceInfo.m; sourceTree = ""; }; + 79983A432164755300E311F8 /* ZXQRCodeBlackBox7TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeBlackBox7TestCase.h; sourceTree = ""; }; + 79983A442164755400E311F8 /* ZXQRCodeBlackBox7TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeBlackBox7TestCase.m; sourceTree = ""; }; + 79DFDC2B2164735D00AC0F20 /* mac-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "mac-Info.plist"; sourceTree = SOURCE_ROOT; }; DB72547F1A523C9200EFF81B /* ZXingObjC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ZXingObjC.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DB7254821A523C9200EFF81B /* ios-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ios-Info.plist"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ @@ -3074,6 +3174,8 @@ children = ( 0224F41E1BC6BB8400B0E1F9 /* ZXGenericMultipleBarcodeReaderTestCase.h */, 074684311BC3BA3C00E47A35 /* ZXGenericMultipleBarcodeReaderTestCase.m */, + 4B9DB44D2158CCFD00A10495 /* ZXMultiTestCase.h */, + 4B9DB44A2158CCF400A10495 /* ZXMultiTestCase.m */, ); path = multi; sourceTree = ""; @@ -3170,6 +3272,7 @@ 25403CB9166A96FA00E13304 /* Supporting Files */ = { isa = PBXGroup; children = ( + 79DFDC2B2164735D00AC0F20 /* mac-Info.plist */, DB7254821A523C9200EFF81B /* ios-Info.plist */, 25403CE1166A979700E13304 /* ios-Prefix.pch */, 2540418D166AADEF00E13304 /* osx-Prefix.pch */, @@ -3181,10 +3284,12 @@ 25403CCD166A96FA00E13304 /* ZXingObjCTests */ = { isa = PBXGroup; children = ( + 4B9E58CC215CDCC90045E4BD /* additional */, 25403FED166AA0F100E13304 /* aztec */, 25403FF2166AA0F100E13304 /* client */, 2540400C166AA0F100E13304 /* common */, 25404028166AA0F100E13304 /* datamatrix */, + 4B674F0E2157E7DD00F97DEE /* maxicode */, 074684301BC3B9F400E47A35 /* multi */, 25404030166AA0F100E13304 /* negative */, 25404039166AA0F100E13304 /* oned */, @@ -3194,6 +3299,8 @@ 02BDA2ED1803109E0039B326 /* Supporting Files */, 02DD02931AC1C3B5009E4D65 /* ZXPlanarYUVLuminanceSourceTestCase.h */, 02DD02941AC1C3B5009E4D65 /* ZXPlanarYUVLuminanceSourceTestCase.m */, + 4B20581B2155B19C009146DB /* ZXRGBLuminanceSourceTestCase.h */, + 4B20581C2155B19C009146DB /* ZXRGBLuminanceSourceTestCase.m */, ); path = ZXingObjCTests; sourceTree = ""; @@ -3242,6 +3349,8 @@ 25403D48166A9A0800E13304 /* ZXCaptureDelegate.h */, 25403D4B166A9A0800E13304 /* ZXCGImageLuminanceSource.h */, 25403D4C166A9A0800E13304 /* ZXCGImageLuminanceSource.m */, + 7967E67C2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.h */, + 7967E67D2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.m */, 25403D4D166A9A0800E13304 /* ZXImage.h */, 25403D4E166A9A0800E13304 /* ZXImage.m */, ); @@ -3346,6 +3455,8 @@ 028BB96918D9E8D100BDF709 /* ZXByteArray.m */, 25403DB6166A9C0E00E13304 /* ZXCharacterSetECI.h */, 25403DB7166A9C0E00E13304 /* ZXCharacterSetECI.m */, + 4B5D6CB9215B850B00EE122A /* ZXDecimal.h */, + 4B5D6CBA215B851F00EE122A /* ZXDecimal.m */, 25403DB8166A9C0E00E13304 /* ZXDecoderResult.h */, 25403DB9166A9C0E00E13304 /* ZXDecoderResult.m */, 25403DBA166A9C0E00E13304 /* ZXDefaultGridSampler.h */, @@ -3491,6 +3602,8 @@ 25403E83166A9DF300E13304 /* ZXCode39Writer.m */, 25403E84166A9DF300E13304 /* ZXCode93Reader.h */, 25403E85166A9DF300E13304 /* ZXCode93Reader.m */, + 4B7ACDA92153D8B8001EB8A5 /* ZXCode93Writer.h */, + 4B7ACDA42153D8AA001EB8A5 /* ZXCode93Writer.m */, 25403E86166A9DF300E13304 /* ZXEAN13Reader.h */, 25403E87166A9DF300E13304 /* ZXEAN13Reader.m */, 25403E88166A9DF300E13304 /* ZXEAN13Writer.h */, @@ -3530,6 +3643,8 @@ 25403EA9166A9DF300E13304 /* ZXUPCEANWriter.m */, 25403EAA166A9DF300E13304 /* ZXUPCEReader.h */, 25403EAB166A9DF300E13304 /* ZXUPCEReader.m */, + 2172BAF71E1C6087004327CB /* ZXUPCEWriter.h */, + 2172BAF81E1C6087004327CB /* ZXUPCEWriter.m */, ); path = oned; sourceTree = ""; @@ -3856,6 +3971,8 @@ 25404021166AA0F100E13304 /* ZXBitSourceBuilder.m */, 25404022166AA0F100E13304 /* ZXBitSourceTestCase.h */, 25404023166AA0F100E13304 /* ZXBitSourceTestCase.m */, + 4B5D6CBF215B8E1400EE122A /* ZXDecimalTestCase.h */, + 4B5D6CC0215B8E2300EE122A /* ZXDecimalTestCase.m */, 074684341BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.h */, 074684351BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m */, 25404024166AA0F100E13304 /* ZXPerspectiveTransformTestCase.h */, @@ -3871,6 +3988,8 @@ 25404011166AA0F100E13304 /* reedsolomon */ = { isa = PBXGroup; children = ( + 4B50185A215A378C00ACD238 /* ZXGenericGFPolyTestCase.h */, + 4B50185B215A379200ACD238 /* ZXGenericGFPolyTestCase.m */, 2504D9EA170005FE00DF8882 /* ZXReedSolomonTestCase.h */, 2504D9EB170005FE00DF8882 /* ZXReedSolomonTestCase.m */, ); @@ -3938,8 +4057,16 @@ 25404045166AA0F100E13304 /* ZXCode39BlackBox3TestCase.m */, 25404046166AA0F100E13304 /* ZXCode39ExtendedBlackBox2TestCase.h */, 25404047166AA0F100E13304 /* ZXCode39ExtendedBlackBox2TestCase.m */, + 4B42B8A9215917AD0010C328 /* ZXCode39ExtendedModeTestCase.h */, + 4B42B8A6215917A40010C328 /* ZXCode39ExtendedModeTestCase.m */, + 4B9DB44E2158D3EF00A10495 /* ZXCode39WriterTestCase.h */, + 4B9DB44F2158D3F700A10495 /* ZXCode39WriterTestCase.m */, 25404048166AA0F100E13304 /* ZXCode93BlackBox1TestCase.h */, 25404049166AA0F100E13304 /* ZXCode93BlackBox1TestCase.m */, + 4BA2FEC221B171330030F557 /* ZXCode93ReaderTestCase.h */, + 4BA2FEBF21B1711E0030F557 /* ZXCode93ReaderTestCase.m */, + 4B9DB4552158D41200A10495 /* ZXCode93WriterTestCase.h */, + 4B9DB4522158D40A00A10495 /* ZXCode93WriterTestCase.m */, 2540404A166AA0F100E13304 /* ZXEAN13BlackBox1TestCase.h */, 2540404B166AA0F100E13304 /* ZXEAN13BlackBox1TestCase.m */, 2540404C166AA0F100E13304 /* ZXEAN13BlackBox2TestCase.h */, @@ -3962,6 +4089,8 @@ 25404057166AA0F100E13304 /* ZXITFBlackBox1TestCase.m */, 25404058166AA0F100E13304 /* ZXITFBlackBox2TestCase.h */, 25404059166AA0F100E13304 /* ZXITFBlackBox2TestCase.m */, + 4B42B8A221590C880010C328 /* ZXITFWriterTestCase.h */, + 4B42B8A321590C920010C328 /* ZXITFWriterTestCase.m */, 25404083166AA0F100E13304 /* ZXUPCABlackBox1TestCase.h */, 25404084166AA0F100E13304 /* ZXUPCABlackBox1TestCase.m */, 25404085166AA0F100E13304 /* ZXUPCABlackBox2TestCase.h */, @@ -3984,6 +4113,8 @@ 25404094166AA0F100E13304 /* ZXUPCEBlackBox2TestCase.m */, 25404095166AA0F100E13304 /* ZXUPCEBlackBox3ReflectiveTestCase.h */, 25404096166AA0F100E13304 /* ZXUPCEBlackBox3ReflectiveTestCase.m */, + 4B42B8A1215904F30010C328 /* ZXUPCEWriterTestCase.h */, + 4B42B89E215904EB0010C328 /* ZXUPCEWriterTestCase.m */, ); path = oned; sourceTree = ""; @@ -4070,6 +4201,8 @@ 25E9E91817FA555400364861 /* ZXPDF417BlackBox3TestCase.m */, 25B582971816F7B00013634A /* ZXPDF417BlackBox4TestCase.h */, 25B582981816F7B00013634A /* ZXPDF417BlackBox4TestCase.m */, + 4B9DB4492158C1E300A10495 /* ZXPDF417WriterTestCase.h */, + 4B9DB4462158C1D800A10495 /* ZXPDF417WriterTestCase.m */, ); path = pdf417; sourceTree = ""; @@ -4078,6 +4211,8 @@ isa = PBXGroup; children = ( 254040A7166AA0F100E13304 /* ec */, + 4B501856215A2EA900ACD238 /* ZXPDF417DecoderTestCase.h */, + 4B501857215A2EB800ACD238 /* ZXPDF417DecoderTestCase.m */, ); path = decoder; sourceTree = ""; @@ -4110,6 +4245,8 @@ 254040D2166AA0F100E13304 /* ZXQRCodeBlackBox5TestCase.m */, 254040D3166AA0F100E13304 /* ZXQRCodeBlackBox6TestCase.h */, 254040D4166AA0F100E13304 /* ZXQRCodeBlackBox6TestCase.m */, + 79983A432164755300E311F8 /* ZXQRCodeBlackBox7TestCase.h */, + 79983A442164755400E311F8 /* ZXQRCodeBlackBox7TestCase.m */, 254040D5166AA0F100E13304 /* ZXQRCodeWriterTestCase.h */, 254040D6166AA0F100E13304 /* ZXQRCodeWriterTestCase.m */, ); @@ -4212,6 +4349,26 @@ name = encoder; sourceTree = ""; }; + 4B674F0E2157E7DD00F97DEE /* maxicode */ = { + isa = PBXGroup; + children = ( + 4B674F112157E82A00F97DEE /* ZXMaxicodeBlackBox1TestCase.h */, + 4B674F0F2157E7FD00F97DEE /* ZXMaxicodeBlackBox1TestCase.m */, + ); + path = maxicode; + sourceTree = ""; + }; + 4B9E58CC215CDCC90045E4BD /* additional */ = { + isa = PBXGroup; + children = ( + 4B9E58D0215CDD320045E4BD /* ZXDataMatrixWriterAdditionalTestCase.h */, + 4B9E58CD215CDCEB0045E4BD /* ZXDataMatrixWriterAdditionalTestCase.m */, + 4BFDC4A4215BCF9000580F5C /* ZXPDF417BlackBox5TestCase.h */, + 4BFDC4A1215BCF7B00580F5C /* ZXPDF417BlackBox5TestCase.m */, + ); + path = additional; + sourceTree = ""; + }; DB7254801A523C9200EFF81B /* iOS Framework */ = { isa = PBXGroup; children = ( @@ -4391,6 +4548,7 @@ 0210FB9318E0A62300B1F4CE /* ZXByteArray.h in Headers */, 0210FBE018E0A92900B1F4CE /* ZXCode93Reader.h in Headers */, 0210FBCA18E0A8DA00B1F4CE /* ZXRSSExpandedDecodedChar.h in Headers */, + 4B7ACDAA2153D8B8001EB8A5 /* ZXCode93Writer.h in Headers */, 0210FBC218E0A8DA00B1F4CE /* ZXAI013x0x1xDecoder.h in Headers */, 0210FBB318E0A85900B1F4CE /* ZXMaxiCodeBitMatrixParser.h in Headers */, 0294D111190ED90B00BBACCB /* ZXDimension.h in Headers */, @@ -4413,6 +4571,7 @@ 0210FBE618E0A92900B1F4CE /* ZXITFWriter.h in Headers */, 0210FBFA18E0A97200B1F4CE /* ZXPDF417Codeword.h in Headers */, 0210FBBC18E0A89500B1F4CE /* ZXMultipleBarcodeReader.h in Headers */, + 7967E67E2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.h in Headers */, 0210FBBD18E0A8A500B1F4CE /* ZXAbstractExpandedDecoder.h in Headers */, 0210FB9918E0A62400B1F4CE /* ZXGridSampler.h in Headers */, 0210FB9A18E0A62400B1F4CE /* ZXHybridBinarizer.h in Headers */, @@ -4448,6 +4607,7 @@ 0210FB8C18E0A62200B1F4CE /* ZXGenericGFPoly.h in Headers */, 0294D14D190ED90B00BBACCB /* ZXRGBLuminanceSource.h in Headers */, 0210FBAC18E0A82500B1F4CE /* ZXDataMatrixSymbolInfo144.h in Headers */, + 2172BAF91E1C6087004327CB /* ZXUPCEWriter.h in Headers */, 0210FB5F18E0A5FC00B1F4CE /* ZXAbstractDoCoMoResultParser.h in Headers */, 0294D13B190ED90B00BBACCB /* ZXResult.h in Headers */, 0210FC1418E0A9F700B1F4CE /* ZXQRCodeFormatInformation.h in Headers */, @@ -4635,6 +4795,7 @@ 2504D9E216FFEB8100DF8882 /* ZXAztecEncoder.h in Headers */, 2542997F16D470E600D4C045 /* ZXDataMatrixWriter.h in Headers */, 2542998716D478A000D4C045 /* ZXDataMatrixASCIIEncoder.h in Headers */, + 4B7ACDAB2153D8B8001EB8A5 /* ZXCode93Writer.h in Headers */, 0294D112190ED90B00BBACCB /* ZXDimension.h in Headers */, 2542999016D47BC000D4C045 /* ZXDataMatrixBase256Encoder.h in Headers */, 2504D9D116FFD3A100DF8882 /* ZXAztecCode.h in Headers */, @@ -4657,6 +4818,7 @@ 255E490F18143AC600A03A28 /* ZXRSSExpandedDecodedChar.h in Headers */, 255E491018143AC600A03A28 /* ZXRSSExpandedDecodedInformation.h in Headers */, 255E491118143AC600A03A28 /* ZXRSSExpandedDecodedNumeric.h in Headers */, + 7967E68E21646DCA00C28E42 /* ZXCGImageLuminanceSourceInfo.h in Headers */, 255E491218143AC600A03A28 /* ZXRSSExpandedDecodedObject.h in Headers */, 255E491318143AC600A03A28 /* ZXRSSExpandedFieldParser.h in Headers */, 255E491418143AC600A03A28 /* ZXRSSExpandedGeneralAppIdDecoder.h in Headers */, @@ -4692,6 +4854,7 @@ 0294D14E190ED90B00BBACCB /* ZXRGBLuminanceSource.h in Headers */, 255E492C18143AC600A03A28 /* ZXITFWriter.h in Headers */, 255E492D18143AC600A03A28 /* ZXMultiFormatOneDReader.h in Headers */, + 2172BAFB1E1C6090004327CB /* ZXUPCEWriter.h in Headers */, 0294D13C190ED90B00BBACCB /* ZXResult.h in Headers */, 255E492E18143AC600A03A28 /* ZXMultiFormatUPCEANReader.h in Headers */, 255E492F18143AC600A03A28 /* ZXOneDimensionalCodeWriter.h in Headers */, @@ -4879,6 +5042,7 @@ 255E48AD18143A8800A03A28 /* ZXEANManufacturerOrgSupport.h in Headers */, 255E48AE18143A8800A03A28 /* ZXITFReader.h in Headers */, 255E48AF18143A8800A03A28 /* ZXITFWriter.h in Headers */, + 4B7ACDAC2153D8B8001EB8A5 /* ZXCode93Writer.h in Headers */, 255E48B018143A8800A03A28 /* ZXMultiFormatOneDReader.h in Headers */, 255E48B118143A8800A03A28 /* ZXMultiFormatUPCEANReader.h in Headers */, 0294D113190ED90B00BBACCB /* ZXDimension.h in Headers */, @@ -4901,6 +5065,7 @@ 255E48C018143A8800A03A28 /* ZXPDF417BarcodeMetadata.h in Headers */, 255E48C118143A8800A03A28 /* ZXPDF417BarcodeValue.h in Headers */, 255E48C218143A8800A03A28 /* ZXPDF417BoundingBox.h in Headers */, + 7967E68F21646DCB00C28E42 /* ZXCGImageLuminanceSourceInfo.h in Headers */, 255E48C318143A8800A03A28 /* ZXPDF417Codeword.h in Headers */, 255E48C418143A8800A03A28 /* ZXPDF417CodewordDecoder.h in Headers */, 255E48C518143A8800A03A28 /* ZXPDF417DecodedBitStreamParser.h in Headers */, @@ -4936,6 +5101,7 @@ 255E48E018143A8800A03A28 /* ZXQRCodeAlignmentPattern.h in Headers */, 0294D14F190ED90B00BBACCB /* ZXRGBLuminanceSource.h in Headers */, 0218B85718D230CC0005E7EC /* ZXAztecBinaryShiftToken.h in Headers */, + 2172BAFD1E1C6091004327CB /* ZXUPCEWriter.h in Headers */, 255E48E118143A8800A03A28 /* ZXQRCodeAlignmentPatternFinder.h in Headers */, 0294D13D190ED90B00BBACCB /* ZXResult.h in Headers */, 255E48E218143A8800A03A28 /* ZXQRCodeFinderPatternFinder.h in Headers */, @@ -4958,6 +5124,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 7967E69021646DCB00C28E42 /* ZXCGImageLuminanceSourceInfo.h in Headers */, DB7259E11A52466B00EFF81B /* ZXPDF417ScanningDecoder.h in Headers */, DB7259851A52452500EFF81B /* ZXDataMatrixASCIIEncoder.h in Headers */, DB7259AF1A5245B000EFF81B /* ZXRSSExpandedGeneralAppIdDecoder.h in Headers */, @@ -5123,6 +5290,7 @@ DB725A0C1A5247AC00EFF81B /* ZXMultiFormatWriter.h in Headers */, DB725A031A52476700EFF81B /* ZXQRCodeMatrixUtil.h in Headers */, DB7259461A52445500EFF81B /* ZXTelParsedResult.h in Headers */, + 4B7ACDAD2153D8B8001EB8A5 /* ZXCode93Writer.h in Headers */, DB7259FD1A52475000EFF81B /* ZXQRCodeFinderPatternFinder.h in Headers */, DB7259D01A52461B00EFF81B /* ZXUPCEANExtension5Support.h in Headers */, DB72597D1A5244FC00EFF81B /* ZXRGBLuminanceSource.h in Headers */, @@ -5180,6 +5348,7 @@ DB7259B81A5245F300EFF81B /* ZXRSSPair.h in Headers */, DB7259711A5244FC00EFF81B /* ZXDimension.h in Headers */, DB7259FF1A52475700EFF81B /* ZXQRCode.h in Headers */, + 2172BAFF1E1C6091004327CB /* ZXUPCEWriter.h in Headers */, DB7259E71A5246DF00EFF81B /* ZXPDF417Dimensions.h in Headers */, DB72596D1A5244FC00EFF81B /* ZXBinarizer.h in Headers */, DB72598F1A52454B00EFF81B /* ZXDataMatrixX12Encoder.h in Headers */, @@ -5315,7 +5484,7 @@ attributes = { CLASSPREFIX = ZX; LastTestingUpgradeCheck = 0510; - LastUpgradeCheck = 0700; + LastUpgradeCheck = 1000; ORGANIZATIONNAME = zxing; TargetAttributes = { 25404177166AADAC00E13304 = { @@ -5331,6 +5500,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 25403CA8166A96F900E13304; @@ -5467,6 +5637,7 @@ 25403E08166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.m in Sources */, 25403E0A166A9CCB00E13304 /* ZXDataMatrixDecoder.m in Sources */, 25403E0C166A9CCB00E13304 /* ZXDataMatrixVersion.m in Sources */, + 7967E67F2163B98C00C28E42 /* ZXCGImageLuminanceSourceInfo.m in Sources */, 25403E0E166A9CCB00E13304 /* ZXDataMatrixDetector.m in Sources */, 25403E10166A9CCB00E13304 /* ZXDataMatrixReader.m in Sources */, 25403E1C166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.m in Sources */, @@ -5525,6 +5696,7 @@ 25403EF3166A9DF400E13304 /* ZXEAN13Reader.m in Sources */, 25403EF5166A9DF400E13304 /* ZXEAN13Writer.m in Sources */, 25403EF7166A9DF400E13304 /* ZXEAN8Reader.m in Sources */, + 2172BAFA1E1C6087004327CB /* ZXUPCEWriter.m in Sources */, 25403EF9166A9DF400E13304 /* ZXEAN8Writer.m in Sources */, 25389B8C18010B9A00772392 /* ZXPDF417DetectorResult.m in Sources */, 25403EFB166A9DF400E13304 /* ZXEANManufacturerOrgSupport.m in Sources */, @@ -5576,6 +5748,7 @@ 25403FA8166A9F2D00E13304 /* ZXQRCodeDetector.m in Sources */, 25403FAA166A9F2D00E13304 /* ZXQRCodeFinderPattern.m in Sources */, 25403FAC166A9F2D00E13304 /* ZXQRCodeBlockPair.m in Sources */, + 4B5D6CBB215B851F00EE122A /* ZXDecimal.m in Sources */, 0294D102190ED90B00BBACCB /* ZXBinarizer.m in Sources */, 25403FB0166A9F2D00E13304 /* ZXQRCodeEncoder.m in Sources */, 25403FB2166A9F2D00E13304 /* ZXQRCodeMaskUtil.m in Sources */, @@ -5592,6 +5765,7 @@ 2542997E16D470D600D4C045 /* ZXDataMatrixWriter.m in Sources */, 2542998916D478A000D4C045 /* ZXDataMatrixASCIIEncoder.m in Sources */, 2542999216D47BC000D4C045 /* ZXDataMatrixBase256Encoder.m in Sources */, + 4B7ACDA52153D8AA001EB8A5 /* ZXCode93Writer.m in Sources */, 0294D0D4190ED8DA00BBACCB /* ZXMultiFormatReader.m in Sources */, 2542999C16D482F900D4C045 /* ZXDataMatrixC40Encoder.m in Sources */, 254299A416D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m in Sources */, @@ -5613,12 +5787,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4B42B89F215904EB0010C328 /* ZXUPCEWriterTestCase.m in Sources */, 023E696B18C0EF26001FF123 /* ZXAztecBlackBox1TestCase.m in Sources */, 023E696C18C0EF26001FF123 /* ZXAztecBlackBox2TestCase.m in Sources */, 023E696D18C0EF26001FF123 /* ZXAbstractBlackBoxTestCase.m in Sources */, + 4B42B8A421590C920010C328 /* ZXITFWriterTestCase.m in Sources */, 023E696E18C0EF26001FF123 /* ZXAbstractNegativeBlackBoxTestCase.m in Sources */, 023E696F18C0EF26001FF123 /* ZXTestResult.m in Sources */, 023E697018C0EF26001FF123 /* ZXDataMatrixBlackBox1TestCase.m in Sources */, + 4B50185C215A379300ACD238 /* ZXGenericGFPolyTestCase.m in Sources */, 023E697118C0EF26001FF123 /* ZXDataMatrixBlackBox2TestCase.m in Sources */, 023E697218C0EF26001FF123 /* ZXFalsePositives2BlackBoxTestCase.m in Sources */, 023E697318C0EF26001FF123 /* ZXFalsePositivesBlackBoxTestCase.m in Sources */, @@ -5633,6 +5810,7 @@ 023E697C18C0EF26001FF123 /* ZXCode39ExtendedBlackBox2TestCase.m in Sources */, 023E697D18C0EF26001FF123 /* ZXCode93BlackBox1TestCase.m in Sources */, 023E697E18C0EF26001FF123 /* ZXEAN13BlackBox1TestCase.m in Sources */, + 4B9DB4472158C1D800A10495 /* ZXPDF417WriterTestCase.m in Sources */, 023E697F18C0EF26001FF123 /* ZXEAN13BlackBox2TestCase.m in Sources */, 02DD029F1AC1DBAD009E4D65 /* ZXAztecDecoderTest.m in Sources */, 023E698018C0EF26001FF123 /* ZXEAN13BlackBox3TestCase.m in Sources */, @@ -5652,6 +5830,7 @@ 023E698C18C0EF26001FF123 /* ZXRSS14BlackBox2TestCase.m in Sources */, 023E698D18C0EF26001FF123 /* ZXUPCABlackBox1TestCase.m in Sources */, 023E698E18C0EF26001FF123 /* ZXUPCABlackBox2TestCase.m in Sources */, + 4B2058252155B4F1009146DB /* ZXRGBLuminanceSourceTestCase.m in Sources */, 023E698F18C0EF26001FF123 /* ZXUPCABlackBox3ReflectiveTestCase.m in Sources */, 023E699018C0EF26001FF123 /* ZXUPCABlackBox4TestCase.m in Sources */, 023E699118C0EF26001FF123 /* ZXUPCABlackBox5TestCase.m in Sources */, @@ -5662,6 +5841,7 @@ 023E699618C0EF26001FF123 /* ZXUPCEBlackBox3ReflectiveTestCase.m in Sources */, 023E699718C0EF26001FF123 /* ZXPDF417BlackBox1TestCase.m in Sources */, 023E699818C0EF26001FF123 /* ZXPDF417BlackBox2TestCase.m in Sources */, + 4BA2FEC021B1711E0030F557 /* ZXCode93ReaderTestCase.m in Sources */, 023E699918C0EF26001FF123 /* ZXPDF417BlackBox3TestCase.m in Sources */, 023E699A18C0EF26001FF123 /* ZXPDF417BlackBox4TestCase.m in Sources */, 023E699B18C0EF26001FF123 /* ZXQRCodeBlackBox1TestCase.m in Sources */, @@ -5669,12 +5849,14 @@ 023E699D18C0EF26001FF123 /* ZXQRCodeBlackBox3TestCase.m in Sources */, 023E699E18C0EF26001FF123 /* ZXQRCodeBlackBox4TestCase.m in Sources */, 023E699F18C0EF26001FF123 /* ZXQRCodeBlackBox5TestCase.m in Sources */, + 4B9DB44B2158CCF400A10495 /* ZXMultiTestCase.m in Sources */, 023E69A018C0EF26001FF123 /* ZXQRCodeBlackBox6TestCase.m in Sources */, 254040D9166AA0F100E13304 /* ZXAddressBookParsedResultTestCase.m in Sources */, 254040DA166AA0F100E13304 /* ZXCalendarParsedResultTestCase.m in Sources */, 254040DB166AA0F100E13304 /* ZXEmailAddressParsedResultTestCase.m in Sources */, 254040DC166AA0F100E13304 /* ZXExpandedProductParsedResultTestCase.m in Sources */, 074684361BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m in Sources */, + 4B9E58CE215CDCEB0045E4BD /* ZXDataMatrixWriterAdditionalTestCase.m in Sources */, 254040DD166AA0F100E13304 /* ZXGeoParsedResultTestCase.m in Sources */, 254040DE166AA0F100E13304 /* ZXISBNParsedResultTestCase.m in Sources */, 254040DF166AA0F100E13304 /* ZXParsedReaderResultTestCase.m in Sources */, @@ -5686,6 +5868,8 @@ 254040E4166AA0F100E13304 /* ZXWifiParsedResultTestCase.m in Sources */, 254040EC166AA0F100E13304 /* ZXBitArrayTestCase.m in Sources */, 254040ED166AA0F100E13304 /* ZXBitMatrixTestCase.m in Sources */, + 4B9DB4532158D40A00A10495 /* ZXCode93WriterTestCase.m in Sources */, + 4B9DB4502158D3F700A10495 /* ZXCode39WriterTestCase.m in Sources */, 254040EE166AA0F100E13304 /* ZXBitSourceBuilder.m in Sources */, 254040EF166AA0F100E13304 /* ZXBitSourceTestCase.m in Sources */, 254040F0166AA0F100E13304 /* ZXPerspectiveTransformTestCase.m in Sources */, @@ -5695,6 +5879,7 @@ 2540410A166AA0F100E13304 /* ZXAI01_3103_DecoderTest.m in Sources */, 2540410B166AA0F100E13304 /* ZXAI01_3202_3203_DecoderTest.m in Sources */, 2540410C166AA0F100E13304 /* ZXAI01_3X0X_1X_DecoderTest.m in Sources */, + 4B5D6CC5215B8E7600EE122A /* ZXDecimalTestCase.m in Sources */, 2540410D166AA0F100E13304 /* ZXAnyAIDecoderTest.m in Sources */, 2540410E166AA0F100E13304 /* ZXRSSExpandedFieldParserTest.m in Sources */, 25404112166AA0F100E13304 /* ZXRSSExpandedImage2binaryTestCase.m in Sources */, @@ -5706,6 +5891,7 @@ 25404118166AA0F100E13304 /* ZXBitArrayBuilderTest.m in Sources */, 25404119166AA0F100E13304 /* ZXRSSExpandedInformationDecoderTest.m in Sources */, 25404126166AA0F100E13304 /* ZXCodaBarWriterTestCase.m in Sources */, + 4B501858215A2EB800ACD238 /* ZXPDF417DecoderTestCase.m in Sources */, 255E986C18DF258C000A2681 /* ZXCode128WriterTestCase.m in Sources */, 25404128166AA0F100E13304 /* ZXEAN13WriterTestCase.m in Sources */, 25404129166AA0F100E13304 /* ZXEAN8WriterTestCase.m in Sources */, @@ -5713,7 +5899,9 @@ 2540412C166AA0F100E13304 /* ZXUPCAWriterTestCase.m in Sources */, 2540412D166AA0F100E13304 /* ZXPDF417AbstractErrorCorrectionTestCase.m in Sources */, 2540412E166AA0F100E13304 /* ZXPDF417ECErrorCorrectionTestCase.m in Sources */, + 79983A472164756000E311F8 /* ZXQRCodeBlackBox7TestCase.m in Sources */, 25404131166AA0F100E13304 /* ZXQRCodeDataMaskTestCase.m in Sources */, + 4B674F132157E84200F97DEE /* ZXMaxicodeBlackBox1TestCase.m in Sources */, 25404132166AA0F100E13304 /* ZXQRCodeErrorCorrectionLevelTestCase.m in Sources */, 25404133166AA0F100E13304 /* ZXQRCodeFormatInformationTestCase.m in Sources */, 024A231C18D3B292006AE14A /* ZXAztecDetectorTest.m in Sources */, @@ -5723,6 +5911,7 @@ 25404137166AA0F100E13304 /* ZXBitVectorTestCase.m in Sources */, 25404138166AA0F100E13304 /* ZXQRCodeEncoderTestCase.m in Sources */, 25404139166AA0F100E13304 /* ZXQRCodeMaskUtilTestCase.m in Sources */, + 4BFDC4A2215BCF7B00580F5C /* ZXPDF417BlackBox5TestCase.m in Sources */, 2540413A166AA0F100E13304 /* ZXQRCodeMatrixUtilTestCase.m in Sources */, 2540413B166AA0F100E13304 /* ZXQRCodeTestCase.m in Sources */, 25404142166AA0F100E13304 /* ZXQRCodeWriterTestCase.m in Sources */, @@ -5734,6 +5923,7 @@ 25429A0016D5DFD800D4C045 /* ZXDataMatrixDebugPlacement.m in Sources */, 25429A0416D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m in Sources */, 25429A0816D5E21C00D4C045 /* ZXDataMatrixHighLevelEncodeTestCase.m in Sources */, + 4B42B8A7215917A40010C328 /* ZXCode39ExtendedModeTestCase.m in Sources */, 25429A0C16D5F4E000D4C045 /* ZXDataMatrixPlacementTestCase.m in Sources */, 25429A1016D5F66D00D4C045 /* ZXDataMatrixSymbolInfoTestCase.m in Sources */, 2504D9E916FFF2A900DF8882 /* ZXAztecEncoderTest.m in Sources */, @@ -5826,6 +6016,7 @@ 254041CE166AAE6000E13304 /* ZXDataMatrixDataBlock.m in Sources */, 254041CF166AAE6000E13304 /* ZXDataMatrixDecodedBitStreamParser.m in Sources */, 254041D0166AAE6000E13304 /* ZXDataMatrixDecoder.m in Sources */, + 7967E68B21646DC300C28E42 /* ZXCGImageLuminanceSourceInfo.m in Sources */, 254041D1166AAE6000E13304 /* ZXDataMatrixVersion.m in Sources */, 254041D2166AAE6000E13304 /* ZXDataMatrixDetector.m in Sources */, 254041D3166AAE6000E13304 /* ZXDataMatrixReader.m in Sources */, @@ -5884,6 +6075,7 @@ 25404200166AAE6000E13304 /* ZXEAN13Reader.m in Sources */, 25404201166AAE6000E13304 /* ZXEAN13Writer.m in Sources */, 25404202166AAE6000E13304 /* ZXEAN8Reader.m in Sources */, + 2172BAFC1E1C6090004327CB /* ZXUPCEWriter.m in Sources */, 25404203166AAE6000E13304 /* ZXEAN8Writer.m in Sources */, 25389B8D18010B9A00772392 /* ZXPDF417DetectorResult.m in Sources */, 25404204166AAE6000E13304 /* ZXEANManufacturerOrgSupport.m in Sources */, @@ -5935,6 +6127,7 @@ 2540422E166AAE6000E13304 /* ZXQRCodeFinderPatternInfo.m in Sources */, 2540422F166AAE6000E13304 /* ZXQRCodeDetector.m in Sources */, 25404230166AAE6000E13304 /* ZXQRCodeFinderPattern.m in Sources */, + 4B5D6CBC215B851F00EE122A /* ZXDecimal.m in Sources */, 0294D103190ED90B00BBACCB /* ZXBinarizer.m in Sources */, 25404231166AAE6000E13304 /* ZXQRCodeBlockPair.m in Sources */, 25404233166AAE6000E13304 /* ZXQRCodeEncoder.m in Sources */, @@ -5951,6 +6144,7 @@ 2542998216D470F400D4C045 /* ZXDataMatrixWriter.m in Sources */, 2542998A16D478A000D4C045 /* ZXDataMatrixASCIIEncoder.m in Sources */, 2542999316D47BC000D4C045 /* ZXDataMatrixBase256Encoder.m in Sources */, + 4B7ACDA62153D8AA001EB8A5 /* ZXCode93Writer.m in Sources */, 0294D0D5190ED8DA00BBACCB /* ZXMultiFormatReader.m in Sources */, 2542999D16D482F900D4C045 /* ZXDataMatrixC40Encoder.m in Sources */, 254299A516D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m in Sources */, @@ -5975,9 +6169,11 @@ 023E69A118C0EF55001FF123 /* ZXAztecBlackBox1TestCase.m in Sources */, 023E69A218C0EF55001FF123 /* ZXAztecBlackBox2TestCase.m in Sources */, 023E69A318C0EF55001FF123 /* ZXAbstractBlackBoxTestCase.m in Sources */, + 4B42B8A521590C920010C328 /* ZXITFWriterTestCase.m in Sources */, 023E69A418C0EF55001FF123 /* ZXAbstractNegativeBlackBoxTestCase.m in Sources */, 023E69A518C0EF55001FF123 /* ZXTestResult.m in Sources */, 023E69A618C0EF55001FF123 /* ZXDataMatrixBlackBox1TestCase.m in Sources */, + 4B50185D215A379300ACD238 /* ZXGenericGFPolyTestCase.m in Sources */, 023E69A718C0EF55001FF123 /* ZXDataMatrixBlackBox2TestCase.m in Sources */, 023E69A818C0EF55001FF123 /* ZXFalsePositives2BlackBoxTestCase.m in Sources */, 023E69A918C0EF55001FF123 /* ZXFalsePositivesBlackBoxTestCase.m in Sources */, @@ -5992,6 +6188,7 @@ 023E69B218C0EF55001FF123 /* ZXCode39ExtendedBlackBox2TestCase.m in Sources */, 023E69B318C0EF55001FF123 /* ZXCode93BlackBox1TestCase.m in Sources */, 023E69B418C0EF55001FF123 /* ZXEAN13BlackBox1TestCase.m in Sources */, + 4B9DB4482158C1D800A10495 /* ZXPDF417WriterTestCase.m in Sources */, 023E69B518C0EF55001FF123 /* ZXEAN13BlackBox2TestCase.m in Sources */, 02DD02A01AC1DBAD009E4D65 /* ZXAztecDecoderTest.m in Sources */, 023E69B618C0EF55001FF123 /* ZXEAN13BlackBox3TestCase.m in Sources */, @@ -6011,6 +6208,7 @@ 023E69C218C0EF55001FF123 /* ZXRSS14BlackBox2TestCase.m in Sources */, 023E69C318C0EF55001FF123 /* ZXUPCABlackBox1TestCase.m in Sources */, 023E69C418C0EF55001FF123 /* ZXUPCABlackBox2TestCase.m in Sources */, + 4B2058262155B4F1009146DB /* ZXRGBLuminanceSourceTestCase.m in Sources */, 023E69C518C0EF55001FF123 /* ZXUPCABlackBox3ReflectiveTestCase.m in Sources */, 023E69C618C0EF55001FF123 /* ZXUPCABlackBox4TestCase.m in Sources */, 023E69C718C0EF55001FF123 /* ZXUPCABlackBox5TestCase.m in Sources */, @@ -6021,6 +6219,7 @@ 023E69CC18C0EF55001FF123 /* ZXUPCEBlackBox3ReflectiveTestCase.m in Sources */, 023E69CD18C0EF55001FF123 /* ZXPDF417BlackBox1TestCase.m in Sources */, 023E69CE18C0EF55001FF123 /* ZXPDF417BlackBox2TestCase.m in Sources */, + 4BA2FEC121B1711E0030F557 /* ZXCode93ReaderTestCase.m in Sources */, 023E69CF18C0EF55001FF123 /* ZXPDF417BlackBox3TestCase.m in Sources */, 023E69D018C0EF55001FF123 /* ZXPDF417BlackBox4TestCase.m in Sources */, 023E69D118C0EF55001FF123 /* ZXQRCodeBlackBox1TestCase.m in Sources */, @@ -6028,12 +6227,14 @@ 023E69D318C0EF55001FF123 /* ZXQRCodeBlackBox3TestCase.m in Sources */, 023E69D418C0EF55001FF123 /* ZXQRCodeBlackBox4TestCase.m in Sources */, 023E69D518C0EF55001FF123 /* ZXQRCodeBlackBox5TestCase.m in Sources */, + 4B9DB44C2158CCF400A10495 /* ZXMultiTestCase.m in Sources */, 023E69D618C0EF55001FF123 /* ZXQRCodeBlackBox6TestCase.m in Sources */, 255E481E18143A3900A03A28 /* ZXRSSExpandedStackedInternalTestCase.m in Sources */, 255E481F18143A3900A03A28 /* ZXTestCaseUtil.m in Sources */, 2540431D166AB8B800E13304 /* ZXAddressBookParsedResultTestCase.m in Sources */, 2540431E166AB8B800E13304 /* ZXCalendarParsedResultTestCase.m in Sources */, 074684371BC3BC9400E47A35 /* ZXMultiAbstractBlackBoxTestCase.m in Sources */, + 4B9E58CF215CDCEB0045E4BD /* ZXDataMatrixWriterAdditionalTestCase.m in Sources */, 2540431F166AB8B800E13304 /* ZXEmailAddressParsedResultTestCase.m in Sources */, 25404320166AB8B800E13304 /* ZXExpandedProductParsedResultTestCase.m in Sources */, 25404321166AB8B800E13304 /* ZXGeoParsedResultTestCase.m in Sources */, @@ -6045,6 +6246,8 @@ 25404326166AB8B800E13304 /* ZXTelParsedResultTestCase.m in Sources */, 25404327166AB8B800E13304 /* ZXURIParsedResultTestCase.m in Sources */, 25404328166AB8B800E13304 /* ZXWifiParsedResultTestCase.m in Sources */, + 4B9DB4542158D40A00A10495 /* ZXCode93WriterTestCase.m in Sources */, + 4B9DB4512158D3F700A10495 /* ZXCode39WriterTestCase.m in Sources */, 25404330166AB8B800E13304 /* ZXBitArrayTestCase.m in Sources */, 25404331166AB8B800E13304 /* ZXBitMatrixTestCase.m in Sources */, 25404332166AB8B800E13304 /* ZXBitSourceBuilder.m in Sources */, @@ -6054,6 +6257,7 @@ 25404338166AB8B800E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.m in Sources */, 2540434D166AB8B800E13304 /* ZXAbstractExpandedDecoderTest.m in Sources */, 2540434E166AB8B800E13304 /* ZXAI01_3103_DecoderTest.m in Sources */, + 4B5D6CC6215B8E7800EE122A /* ZXDecimalTestCase.m in Sources */, 2540434F166AB8B800E13304 /* ZXAI01_3202_3203_DecoderTest.m in Sources */, 25404350166AB8B800E13304 /* ZXAI01_3X0X_1X_DecoderTest.m in Sources */, 25404351166AB8B800E13304 /* ZXAnyAIDecoderTest.m in Sources */, @@ -6065,6 +6269,7 @@ 2540435A166AB8B800E13304 /* ZXBinaryUtil.m in Sources */, 2540435B166AB8B800E13304 /* ZXBinaryUtilTest.m in Sources */, 2540435C166AB8B800E13304 /* ZXBitArrayBuilderTest.m in Sources */, + 4B501859215A2EB800ACD238 /* ZXPDF417DecoderTestCase.m in Sources */, 255E986D18DF258C000A2681 /* ZXCode128WriterTestCase.m in Sources */, 2540435D166AB8B800E13304 /* ZXRSSExpandedInformationDecoderTest.m in Sources */, 2540436A166AB8B800E13304 /* ZXCodaBarWriterTestCase.m in Sources */, @@ -6072,7 +6277,9 @@ 2540436D166AB8B800E13304 /* ZXEAN8WriterTestCase.m in Sources */, 2540436E166AB8B800E13304 /* ZXEANManufacturerOrgSupportTest.m in Sources */, 25404370166AB8B800E13304 /* ZXUPCAWriterTestCase.m in Sources */, + 79983A482164756100E311F8 /* ZXQRCodeBlackBox7TestCase.m in Sources */, 25404371166AB8B800E13304 /* ZXPDF417AbstractErrorCorrectionTestCase.m in Sources */, + 4B674F142157E84200F97DEE /* ZXMaxicodeBlackBox1TestCase.m in Sources */, 25404372166AB8B800E13304 /* ZXPDF417ECErrorCorrectionTestCase.m in Sources */, 25404375166AB8B800E13304 /* ZXQRCodeDataMaskTestCase.m in Sources */, 024A231D18D3B292006AE14A /* ZXAztecDetectorTest.m in Sources */, @@ -6082,6 +6289,7 @@ 25404379166AB8B800E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.m in Sources */, 2540437A166AB8B800E13304 /* ZXQRCodeVersionTestCase.m in Sources */, 2540437B166AB8B800E13304 /* ZXBitVectorTestCase.m in Sources */, + 4BFDC4A3215BCF7B00580F5C /* ZXPDF417BlackBox5TestCase.m in Sources */, 2540437C166AB8B800E13304 /* ZXQRCodeEncoderTestCase.m in Sources */, 2540437D166AB8B800E13304 /* ZXQRCodeMaskUtilTestCase.m in Sources */, 2540437E166AB8B800E13304 /* ZXQRCodeMatrixUtilTestCase.m in Sources */, @@ -6093,6 +6301,7 @@ 25429A0116D5DFD800D4C045 /* ZXDataMatrixDebugPlacement.m in Sources */, 25429A0516D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m in Sources */, 25429A0916D5E21C00D4C045 /* ZXDataMatrixHighLevelEncodeTestCase.m in Sources */, + 4B42B8A8215917A40010C328 /* ZXCode39ExtendedModeTestCase.m in Sources */, 25429A0D16D5F4E000D4C045 /* ZXDataMatrixPlacementTestCase.m in Sources */, 25429A1116D5F66D00D4C045 /* ZXDataMatrixSymbolInfoTestCase.m in Sources */, 2504D9E816FFF27C00DF8882 /* ZXAztecEncoderTest.m in Sources */, @@ -6185,6 +6394,7 @@ 25404688166ABBED00E13304 /* ZXDataMatrixDecodedBitStreamParser.m in Sources */, 25404689166ABBED00E13304 /* ZXDataMatrixDecoder.m in Sources */, 2540468A166ABBED00E13304 /* ZXDataMatrixVersion.m in Sources */, + 7967E68C21646DC300C28E42 /* ZXCGImageLuminanceSourceInfo.m in Sources */, 2540468B166ABBED00E13304 /* ZXDataMatrixDetector.m in Sources */, 2540468C166ABBED00E13304 /* ZXDataMatrixReader.m in Sources */, 2540468D166ABBED00E13304 /* ZXMaxiCodeBitMatrixParser.m in Sources */, @@ -6243,6 +6453,7 @@ 254046BB166ABBED00E13304 /* ZXEAN8Reader.m in Sources */, 254046BC166ABBED00E13304 /* ZXEAN8Writer.m in Sources */, 254046BD166ABBED00E13304 /* ZXEANManufacturerOrgSupport.m in Sources */, + 2172BAFE1E1C6091004327CB /* ZXUPCEWriter.m in Sources */, 254046BE166ABBED00E13304 /* ZXITFReader.m in Sources */, 254046BF166ABBED00E13304 /* ZXITFWriter.m in Sources */, 25389B7617FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m in Sources */, @@ -6294,6 +6505,7 @@ 254046E6166ABBED00E13304 /* ZXQRCodeFinderPatternFinder.m in Sources */, 254046E7166ABBED00E13304 /* ZXQRCodeFinderPatternInfo.m in Sources */, 254046E8166ABBED00E13304 /* ZXQRCodeDetector.m in Sources */, + 4B5D6CBD215B851F00EE122A /* ZXDecimal.m in Sources */, 0294D104190ED90B00BBACCB /* ZXBinarizer.m in Sources */, 254046E9166ABBED00E13304 /* ZXQRCodeFinderPattern.m in Sources */, 254046EA166ABBED00E13304 /* ZXQRCodeBlockPair.m in Sources */, @@ -6310,6 +6522,7 @@ 2542998B16D478A000D4C045 /* ZXDataMatrixASCIIEncoder.m in Sources */, 2542999416D47BC000D4C045 /* ZXDataMatrixBase256Encoder.m in Sources */, 254299A616D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m in Sources */, + 4B7ACDA72153D8AA001EB8A5 /* ZXCode93Writer.m in Sources */, 0294D0D6190ED8DA00BBACCB /* ZXMultiFormatReader.m in Sources */, 2519AB6317FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m in Sources */, 254299AE16D4886100D4C045 /* ZXDataMatrixDefaultPlacement.m in Sources */, @@ -6412,6 +6625,7 @@ DB7257A01A52420400EFF81B /* ZXDataMatrixDecodedBitStreamParser.m in Sources */, DB7257A11A52420400EFF81B /* ZXDataMatrixDecoder.m in Sources */, DB7257A21A52420400EFF81B /* ZXDataMatrixVersion.m in Sources */, + 7967E68D21646DC300C28E42 /* ZXCGImageLuminanceSourceInfo.m in Sources */, DB7257A31A52420400EFF81B /* ZXDataMatrixDetector.m in Sources */, DB7257A41A52420400EFF81B /* ZXDataMatrixReader.m in Sources */, DB7257A51A52420400EFF81B /* ZXMaxiCodeBitMatrixParser.m in Sources */, @@ -6470,6 +6684,7 @@ DB7257DA1A52420400EFF81B /* ZXEAN13Reader.m in Sources */, DB7257DB1A52420400EFF81B /* ZXEAN13Writer.m in Sources */, DB7257DC1A52420400EFF81B /* ZXEAN8Reader.m in Sources */, + 2172BB001E1C6091004327CB /* ZXUPCEWriter.m in Sources */, DB7257DD1A52420400EFF81B /* ZXEAN8Writer.m in Sources */, DB7257DE1A52420400EFF81B /* ZXPDF417DetectorResult.m in Sources */, DB7257DF1A52420400EFF81B /* ZXEANManufacturerOrgSupport.m in Sources */, @@ -6521,6 +6736,7 @@ DB72580D1A52420400EFF81B /* ZXQRCodeDetector.m in Sources */, DB72580E1A52420400EFF81B /* ZXQRCodeFinderPattern.m in Sources */, DB72580F1A52420400EFF81B /* ZXQRCodeBlockPair.m in Sources */, + 4B5D6CBE215B851F00EE122A /* ZXDecimal.m in Sources */, DB7258101A52420400EFF81B /* ZXBinarizer.m in Sources */, DB7258111A52420400EFF81B /* ZXQRCodeEncoder.m in Sources */, DB7258121A52420400EFF81B /* ZXQRCodeMaskUtil.m in Sources */, @@ -6537,6 +6753,7 @@ DB72581D1A52420400EFF81B /* ZXDataMatrixWriter.m in Sources */, DB72581E1A52420400EFF81B /* ZXDataMatrixASCIIEncoder.m in Sources */, DB72581F1A52420400EFF81B /* ZXDataMatrixBase256Encoder.m in Sources */, + 4B7ACDA82153D8AA001EB8A5 /* ZXCode93Writer.m in Sources */, DB7258201A52420400EFF81B /* ZXMultiFormatReader.m in Sources */, DB7258211A52420400EFF81B /* ZXDataMatrixC40Encoder.m in Sources */, DB7258221A52420400EFF81B /* ZXDataMatrixSymbolInfo144.m in Sources */, @@ -6575,20 +6792,39 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; - FRAMEWORK_VERSION = 3.1.0; + ENABLE_BITCODE = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = 3.6.4; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - MACOSX_DEPLOYMENT_TARGET = 10.8; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 10.15; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; @@ -6603,8 +6839,10 @@ COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; DSTROOT = /tmp/ZXingObjC.dst; + ENABLE_BITCODE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ios-Prefix.pch"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "ZXingObjC-iOS"; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)Headers"; @@ -6649,6 +6887,7 @@ GCC_PREFIX_HEADER = "ZXingObjCTests/Supporting Files/Tests-OSX-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; INFOPLIST_FILE = "ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.15; PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; @@ -6659,20 +6898,25 @@ 02AF34741672527F003B9255 /* Distribution */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", - "$(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks", - ); + DYLIB_INSTALL_NAME_BASE = "$(INSTALL_PATH)"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + FRAMEWORK_VERSION = A; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "osx-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + INFOPLIST_FILE = "mac-Info.plist"; + LD_DYLIB_INSTALL_NAME = "@rpath/../Frameworks/$(EXECUTABLE_PATH)"; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.15; + PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = ZXingObjC; SDKROOT = macosx; WRAPPER_EXTENSION = framework; @@ -6684,16 +6928,31 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + ENABLE_BITCODE = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - FRAMEWORK_VERSION = 3.1.0; + FRAMEWORK_VERSION = 3.6.4; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -6701,11 +6960,15 @@ ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - MACOSX_DEPLOYMENT_TARGET = 10.8; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 10.15; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; @@ -6717,20 +6980,39 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; - FRAMEWORK_VERSION = 3.1.0; + ENABLE_BITCODE = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_VERSION = 3.6.4; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - MACOSX_DEPLOYMENT_TARGET = 10.8; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MACOSX_DEPLOYMENT_TARGET = 10.15; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; @@ -6745,8 +7027,10 @@ COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; DSTROOT = /tmp/ZXingObjC.dst; + ENABLE_BITCODE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ios-Prefix.pch"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "ZXingObjC-iOS"; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)Headers"; @@ -6762,8 +7046,10 @@ COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = NO; DSTROOT = /tmp/ZXingObjC.dst; + ENABLE_BITCODE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ios-Prefix.pch"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "ZXingObjC-iOS"; PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)Headers"; @@ -6832,6 +7118,7 @@ GCC_PREFIX_HEADER = "ZXingObjCTests/Supporting Files/Tests-OSX-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; INFOPLIST_FILE = "ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.15; PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; @@ -6849,6 +7136,7 @@ GCC_PREFIX_HEADER = "ZXingObjCTests/Supporting Files/Tests-OSX-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; INFOPLIST_FILE = "ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.15; PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; @@ -6859,19 +7147,24 @@ 254043B1166ABA0A00E13304 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", - "$(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks", - ); + DYLIB_INSTALL_NAME_BASE = "$(INSTALL_PATH)"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + FRAMEWORK_VERSION = A; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "osx-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + INFOPLIST_FILE = "mac-Info.plist"; + LD_DYLIB_INSTALL_NAME = "@rpath/../Frameworks/$(EXECUTABLE_PATH)"; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.15; + PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = ZXingObjC; SDKROOT = macosx; WRAPPER_EXTENSION = framework; @@ -6881,20 +7174,25 @@ 254043B2166ABA0A00E13304 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", - "$(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks", - ); + DYLIB_INSTALL_NAME_BASE = "$(INSTALL_PATH)"; + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + FRAMEWORK_VERSION = A; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "osx-Prefix.pch"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + INFOPLIST_FILE = "mac-Info.plist"; + LD_DYLIB_INSTALL_NAME = "@rpath/../Frameworks/$(EXECUTABLE_PATH)"; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.15; + PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = ZXingObjC; SDKROOT = macosx; WRAPPER_EXTENSION = framework; @@ -6904,6 +7202,7 @@ DB7254921A523C9300EFF81B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -6911,12 +7210,13 @@ CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ios-Prefix.pch"; @@ -6931,7 +7231,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = "ios-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.$(PRODUCT_NAME:rfc1034identifier)"; @@ -6946,6 +7246,7 @@ DB7254931A523C9300EFF81B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -6953,12 +7254,13 @@ CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ios-Prefix.pch"; @@ -6969,7 +7271,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = "ios-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.$(PRODUCT_NAME:rfc1034identifier)"; @@ -6984,6 +7286,7 @@ DB7254941A523C9300EFF81B /* Distribution */ = { isa = XCBuildConfiguration; buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -6991,12 +7294,13 @@ CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "ios-Prefix.pch"; @@ -7007,7 +7311,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = "ios-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.$(PRODUCT_NAME:rfc1034identifier)"; diff --git a/ZXingObjC.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ZXingObjC.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/ZXingObjC.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ZXingObjC.xcodeproj/xcshareddata/xcschemes/OS X Framework.xcscheme b/ZXingObjC.xcodeproj/xcshareddata/xcschemes/OS X Framework.xcscheme index 1eb86aca6..15ebf7e87 100644 --- a/ZXingObjC.xcodeproj/xcshareddata/xcschemes/OS X Framework.xcscheme +++ b/ZXingObjC.xcodeproj/xcshareddata/xcschemes/OS X Framework.xcscheme @@ -1,6 +1,6 @@ #import "ZXReader.h" @class ZXDecodeHints; diff --git a/ZXingObjC/ZXMultiFormatWriter.h b/ZXingObjC/ZXMultiFormatWriter.h index 356d9227b..d2b697bb8 100644 --- a/ZXingObjC/ZXMultiFormatWriter.h +++ b/ZXingObjC/ZXMultiFormatWriter.h @@ -14,6 +14,7 @@ * limitations under the License. */ +#import #import "ZXWriter.h" /** diff --git a/ZXingObjC/ZXMultiFormatWriter.m b/ZXingObjC/ZXMultiFormatWriter.m index c86c98f85..98f68b1b6 100644 --- a/ZXingObjC/ZXMultiFormatWriter.m +++ b/ZXingObjC/ZXMultiFormatWriter.m @@ -24,11 +24,13 @@ #if defined(ZXINGOBJC_ONED) || !defined(ZXINGOBJC_USE_SUBSPECS) #import "ZXCodaBarWriter.h" #import "ZXCode39Writer.h" +#import "ZXCode93Writer.h" #import "ZXCode128Writer.h" #import "ZXEAN8Writer.h" #import "ZXEAN13Writer.h" #import "ZXITFWriter.h" #import "ZXUPCAWriter.h" +#import "ZXUPCEWriter.h" #endif #if defined(ZXINGOBJC_DATAMATRIX) || !defined(ZXINGOBJC_USE_SUBSPECS) #import "ZXDataMatrixWriter.h" @@ -66,10 +68,18 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt writer = [[ZXUPCAWriter alloc] init]; break; + case kBarcodeFormatUPCE: + writer = [[ZXUPCEWriter alloc] init]; + break; + case kBarcodeFormatCode39: writer = [[ZXCode39Writer alloc] init]; break; + case kBarcodeFormatCode93: + writer = [[ZXCode93Writer alloc] init]; + break; + case kBarcodeFormatCode128: writer = [[ZXCode128Writer alloc] init]; break; @@ -111,7 +121,15 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt if (error) *error = [NSError errorWithDomain:ZXErrorDomain code:ZXWriterError userInfo:@{NSLocalizedDescriptionKey: @"No encoder available for format"}]; return nil; } - return [writer encode:contents format:format width:width height:height hints:hints error:error]; + + @try { + return [writer encode:contents format:format width:width height:height hints:hints error:error]; + } @catch (NSException *exception) { + if (error) { + *error = [NSError errorWithDomain:ZXErrorDomain code:ZXWriterError userInfo:@{NSLocalizedDescriptionKey: exception.reason}]; + } + return nil; + } } @end diff --git a/ZXingObjC/aztec/ZXAztecReader.m b/ZXingObjC/aztec/ZXAztecReader.m index adf8fd27c..c8909620a 100644 --- a/ZXingObjC/aztec/ZXAztecReader.m +++ b/ZXingObjC/aztec/ZXAztecReader.m @@ -68,7 +68,7 @@ - (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error: } } - ZXResult *result = [ZXResult resultWithText:decoderResult.text rawBytes:decoderResult.rawBytes resultPoints:points format:kBarcodeFormatAztec]; + ZXResult *result = [ZXResult resultWithText:decoderResult.text rawBytes:decoderResult.rawBytes numBits:decoderResult.numBits resultPoints:points format:kBarcodeFormatAztec]; NSMutableArray *byteSegments = decoderResult.byteSegments; if (byteSegments != nil) { diff --git a/ZXingObjC/aztec/decoder/ZXAztecDecoder.h b/ZXingObjC/aztec/decoder/ZXAztecDecoder.h index 491f1c9bc..96ae2f15f 100644 --- a/ZXingObjC/aztec/decoder/ZXAztecDecoder.h +++ b/ZXingObjC/aztec/decoder/ZXAztecDecoder.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import "ZXByteArray.h" + @class ZXAztecDetectorResult, ZXBoolArray, ZXDecoderResult; /** @@ -26,5 +28,6 @@ // This method is used for testing the high-level encoder + (NSString *)highLevelDecode:(ZXBoolArray *)correctedBits; ++ (ZXByteArray *)convertBoolArrayToByteArray:(ZXBoolArray *) boolArr; @end diff --git a/ZXingObjC/aztec/decoder/ZXAztecDecoder.m b/ZXingObjC/aztec/decoder/ZXAztecDecoder.m index f38a6a6d6..77a2c5dfd 100644 --- a/ZXingObjC/aztec/decoder/ZXAztecDecoder.m +++ b/ZXingObjC/aztec/decoder/ZXAztecDecoder.m @@ -23,6 +23,7 @@ #import "ZXGenericGF.h" #import "ZXIntArray.h" #import "ZXReedSolomonDecoder.h" +#import "ZXByteArray.h" typedef enum { ZXAztecTableUpper = 0, @@ -79,9 +80,19 @@ - (ZXDecoderResult *)decode:(ZXAztecDetectorResult *)detectorResult error:(NSErr if (!correctedBits) { return nil; } - + ZXByteArray *rawBytes = [ZXAztecDecoder convertBoolArrayToByteArray:correctedBits]; NSString *result = [[self class] encodedData:correctedBits]; - return [[ZXDecoderResult alloc] initWithRawBytes:nil text:result byteSegments:nil ecLevel:nil]; + + NSUInteger rawBytesSize = rawBytes.length; + ZXByteArray *rawBytesReturned = [[ZXByteArray alloc] initWithLength:(unsigned int)rawBytesSize]; + for (int i = 0; i < rawBytesSize; i++) { + rawBytesReturned.array[i] = (int8_t)rawBytes.array[i]; + } + + ZXDecoderResult *decoderResult = [[ZXDecoderResult alloc] initWithRawBytes:rawBytesReturned text:result byteSegments:nil ecLevel:nil]; + decoderResult.numBits = correctedBits.length; + + return decoderResult; } + (NSString *)highLevelDecode:(ZXBoolArray *)correctedBits { @@ -136,6 +147,10 @@ + (NSString *)encodedData:(ZXBoolArray *)correctedBits { NSString *str = [self character:shiftTable code:code]; if ([str hasPrefix:@"CTRL_"]) { // Table changes + // ISO/IEC 24778:2008 prescibes ending a shift sequence in the mode from which it was invoked. + // That's including when that mode is a shift. + // Our test case dlusbs.png for issue #642 exercises that. + latchTable = shiftTable; // Latch the current mode, so as to return to Upper after U/S B/S shiftTable = [self table:[str characterAtIndex:5]]; if ([str characterAtIndex:6] == 'L') { latchTable = shiftTable; @@ -344,6 +359,30 @@ + (int)readCode:(ZXBoolArray *)rawbits startIndex:(int)startIndex length:(int)le return res; } +/** + * Reads a code of length 8 in an array of bits, padding with zeros + */ ++ (int8_t) readByte:(ZXBoolArray *) rawbits startIndex:(int) startIndex { + int n = rawbits.length - startIndex; + if (n >= 8) { + return (int8_t) [self readCode:rawbits startIndex:startIndex length:8]; + } + return (int8_t) ([self readCode:rawbits startIndex:startIndex length:n] << (8 - n)); +} + +/** + * Packs a bit array into bytes, most significant bit first + */ ++ (ZXByteArray *)convertBoolArrayToByteArray:(ZXBoolArray *) boolArr { + int byteArrLength = (boolArr.length + 7) / 8; + ZXByteArray *byteArr = [[ZXByteArray alloc] initWithLength:byteArrLength]; + for (int i = 0; i < byteArrLength; i++) { + int8_t code = [self readByte:boolArr startIndex:8 * i]; + byteArr.array[i] = code; + } + return byteArr; +} + - (int)totalBitsInLayer:(int)layers compact:(BOOL)compact { return ((compact ? 88 : 112) + 16 * layers) * layers; } diff --git a/ZXingObjC/aztec/detector/ZXAztecDetector.h b/ZXingObjC/aztec/detector/ZXAztecDetector.h index 31aad24c6..90134f5a1 100644 --- a/ZXingObjC/aztec/detector/ZXAztecDetector.h +++ b/ZXingObjC/aztec/detector/ZXAztecDetector.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @interface ZXAztecPoint : NSObject @property (nonatomic, assign, readonly) int x; @@ -38,7 +40,9 @@ /** * Detects an Aztec Code in an image. * - * @return ZXAztecDetectorResult encapsulating results of detecting an Aztec Code, or nil if no Aztec Code can be found + * @param isMirror if true, image is a mirror-image of original + * @return ZXAztecDetectorResult encapsulating results of detecting an Aztec Code, or nil if no + * Aztec Code can be found */ - (ZXAztecDetectorResult *)detectWithMirror:(BOOL)isMirror error:(NSError **)error; diff --git a/ZXingObjC/aztec/encoder/ZXAztecCode.h b/ZXingObjC/aztec/encoder/ZXAztecCode.h index 41a086e51..ca7363c7d 100644 --- a/ZXingObjC/aztec/encoder/ZXAztecCode.h +++ b/ZXingObjC/aztec/encoder/ZXAztecCode.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBitMatrix; /** @@ -22,27 +24,27 @@ @interface ZXAztecCode : NSObject /** - * Number of data codewords + * @return number of data codewords */ @property (nonatomic, assign) int codeWords; /** - * Compact or full symbol indicator + * @return YES if compact instead of full mode */ @property (nonatomic, assign, getter = isCompact) BOOL compact; /** - * Number of levels + * @return number of levels */ @property (nonatomic, assign) int layers; /** - * The symbol image + * @return the symbol image */ @property (nonatomic, strong) ZXBitMatrix *matrix; /** - * Size in pixels (width and height) + * @return size in pixels (width and height) */ @property (nonatomic, assign) int size; diff --git a/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.h b/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.h index 9355b8682..57d040da3 100644 --- a/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.h +++ b/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + extern NSArray *ZX_AZTEC_MODE_NAMES; extern const int ZX_AZTEC_MODE_UPPER; @@ -43,7 +45,7 @@ extern int ZX_AZTEC_SHIFT_TABLE[ZX_AZTEC_SHIFT_TABLE_SIZE][ZX_AZTEC_SHIFT_TABLE_ - (id)initWithText:(ZXByteArray *)text; /** - * Convert the text represented by this High Level Encoder into a BitArray. + * @return text represented by this encoder encoded as a ZXBitArray */ - (ZXBitArray *)encode; diff --git a/ZXingObjC/aztec/encoder/ZXAztecState.m b/ZXingObjC/aztec/encoder/ZXAztecState.m index 4a7ad500b..e32271519 100644 --- a/ZXingObjC/aztec/encoder/ZXAztecState.m +++ b/ZXingObjC/aztec/encoder/ZXAztecState.m @@ -77,8 +77,8 @@ - (ZXAztecState *)addBinaryShiftChar:(int)index { mode = ZX_AZTEC_MODE_UPPER; } int deltaBitCount = - (self.binaryShiftByteCount == 0 || self.binaryShiftByteCount == 31) ? 18 : - (self.binaryShiftByteCount == 62) ? 9 : 8; + (self.binaryShiftByteCount == 0 || self.binaryShiftByteCount == 31) ? 18 : + (self.binaryShiftByteCount == 62) ? 9 : 8; ZXAztecState *result = [[ZXAztecState alloc] initWithToken:token mode:mode binaryBytes:self.binaryShiftByteCount + 1 bitCount:bitCount + deltaBitCount]; if (result.binaryShiftByteCount == 2047 + 31) { // The string is as long as it's allowed to be. We should end it. @@ -101,12 +101,28 @@ - (ZXAztecState *)endBinaryShift:(int)index { // Returns true if "this" state is better (or equal) to be in than "that" // state under all possible circumstances. - (BOOL)isBetterThanOrEqualTo:(ZXAztecState *)other { - int mySize = self.bitCount + (ZX_AZTEC_LATCH_TABLE[self.mode][other.mode] >> 16); - if (other.binaryShiftByteCount > 0 && - (self.binaryShiftByteCount == 0 || self.binaryShiftByteCount > other.binaryShiftByteCount)) { - mySize += 10; // Cost of entering Binary Shift mode. + int newModeBitCount = self.bitCount + (ZX_AZTEC_LATCH_TABLE[self.mode][other.mode] >> 16); + if (self.binaryShiftByteCount < other.binaryShiftByteCount) { + // add additional B/S encoding cost of other, if any + newModeBitCount += [self calculateBinaryShiftCost:other] - [self calculateBinaryShiftCost:self]; + } else if (self.binaryShiftByteCount > other.binaryShiftByteCount && other.binaryShiftByteCount > 0) { + // maximum possible additional cost (we end up exceeding the 31 byte boundary and other state can stay beneath it) + newModeBitCount += 10; } - return mySize <= other.bitCount; + return newModeBitCount <= other.bitCount; +} + +- (int)calculateBinaryShiftCost:(ZXAztecState *)state { + if (state.binaryShiftByteCount > 62) { + return 21; // B/S with extended length + } + if (state.binaryShiftByteCount > 31) { + return 20; // two B/S + } + if (state.binaryShiftByteCount > 0) { + return 10; // one B/S + } + return 0; } - (ZXBitArray *)toBitArray:(ZXByteArray *)text { diff --git a/ZXingObjC/aztec/encoder/ZXAztecToken.h b/ZXingObjC/aztec/encoder/ZXAztecToken.h index a95ff3209..f666f4410 100644 --- a/ZXingObjC/aztec/encoder/ZXAztecToken.h +++ b/ZXingObjC/aztec/encoder/ZXAztecToken.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBitArray, ZXByteArray; @interface ZXAztecToken : NSObject diff --git a/ZXingObjC/client/ZXCGImageLuminanceSource.h b/ZXingObjC/client/ZXCGImageLuminanceSource.h index cfee4fb79..f592f2cdf 100644 --- a/ZXingObjC/client/ZXCGImageLuminanceSource.h +++ b/ZXingObjC/client/ZXCGImageLuminanceSource.h @@ -16,12 +16,14 @@ #import #import "ZXLuminanceSource.h" +#import "ZXCGImageLuminanceSourceInfo.h" @class ZXImage; @interface ZXCGImageLuminanceSource : ZXLuminanceSource + (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer CF_RETURNS_RETAINED; + + (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer left:(size_t)left top:(size_t)top @@ -44,6 +46,8 @@ - (id)initWithCGImage:(CGImageRef)image; +- (id)initWithCGImage:(CGImageRef)image sourceInfo: (ZXCGImageLuminanceSourceInfo *)sourceInfo; + - (id)initWithBuffer:(CVPixelBufferRef)buffer left:(size_t)left top:(size_t)top diff --git a/ZXingObjC/client/ZXCGImageLuminanceSource.m b/ZXingObjC/client/ZXCGImageLuminanceSource.m index 393a74556..e1f2f0b66 100644 --- a/ZXingObjC/client/ZXCGImageLuminanceSource.m +++ b/ZXingObjC/client/ZXCGImageLuminanceSource.m @@ -18,6 +18,7 @@ #import "ZXByteArray.h" #import "ZXCGImageLuminanceSource.h" #import "ZXImage.h" +#import "ZXDecodeHints.h" @interface ZXCGImageLuminanceSource () @@ -25,6 +26,7 @@ @interface ZXCGImageLuminanceSource () @property (nonatomic, assign, readonly) int8_t *data; @property (nonatomic, assign, readonly) size_t left; @property (nonatomic, assign, readonly) size_t top; +@property (nonatomic, assign, readonly) ZXCGImageLuminanceSourceInfo *sourceInfo; @end @@ -46,18 +48,18 @@ + (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer size_t bytesPerRow = CVPixelBufferGetBytesPerRow(buffer); size_t dataWidth = CVPixelBufferGetWidth(buffer); size_t dataHeight = CVPixelBufferGetHeight(buffer); - + if (left + width > dataWidth || top + height > dataHeight) { [NSException raise:NSInvalidArgumentException format:@"Crop rectangle does not fit within image data."]; } - + size_t newBytesPerRow = ((width*4+0xf)>>4)<<4; - + CVPixelBufferLockBaseAddress(buffer,0); - + int8_t *baseAddress = (int8_t *)CVPixelBufferGetBaseAddress(buffer); - + size_t size = newBytesPerRow*height; int8_t *bytes = (int8_t *)malloc(size * sizeof(int8_t)); if (newBytesPerRow == bytesPerRow) { @@ -70,7 +72,7 @@ + (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer } } CVPixelBufferUnlockBaseAddress(buffer, 0); - + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef newContext = CGBitmapContextCreate(bytes, width, @@ -81,13 +83,13 @@ + (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer kCGBitmapByteOrder32Little| kCGImageAlphaNoneSkipFirst); CGColorSpaceRelease(colorSpace); - + CGImageRef result = CGBitmapContextCreateImage(newContext); - + CGContextRelease(newContext); - + free(bytes); - + return result; } @@ -111,7 +113,7 @@ - (id)initWithCGImage:(CGImageRef)image if (self = [super initWithWidth:(int)width height:(int)height]) { [self initializeWithImage:image left:left top:top width:width height:height]; } - + return self; } @@ -119,27 +121,39 @@ - (id)initWithCGImage:(CGImageRef)image { return [self initWithCGImage:image left:0 top:0 width:CGImageGetWidth(image) height:CGImageGetHeight(image)]; } +- (id)initWithCGImage:(CGImageRef)image sourceInfo: (ZXCGImageLuminanceSourceInfo *)sourceInfo { + size_t width = CGImageGetWidth(image); + size_t height = CGImageGetHeight(image); + + if (self = [super initWithWidth:(int)width height:(int)height]) { + _sourceInfo = sourceInfo; + [self initializeWithImage:image left: 0 top: 0 width:width height:height]; + } + + return self; +} + - (id)initWithBuffer:(CVPixelBufferRef)buffer left:(size_t)left top:(size_t)top width:(size_t)width height:(size_t)height { CGImageRef image = [ZXCGImageLuminanceSource createImageFromBuffer:buffer left:left top:top width:width height:height]; - + self = [self initWithCGImage:image]; - + CGImageRelease(image); - + return self; } - (id)initWithBuffer:(CVPixelBufferRef)buffer { CGImageRef image = [ZXCGImageLuminanceSource createImageFromBuffer:buffer]; - + self = [self initWithCGImage:image]; - + CGImageRelease(image); - + return self; } @@ -156,7 +170,7 @@ - (ZXByteArray *)rowAtY:(int)y row:(ZXByteArray *)row { if (y < 0 || y >= self.height) { [NSException raise:NSInvalidArgumentException format:@"Requested row is outside the image: %d", y]; } - + if (!row || row.length < self.width) { row = [[ZXByteArray alloc] initWithLength:self.width]; } @@ -167,7 +181,7 @@ - (ZXByteArray *)rowAtY:(int)y row:(ZXByteArray *)row { - (ZXByteArray *)matrix { int area = self.width * self.height; - + ZXByteArray *matrix = [[ZXByteArray alloc] initWithLength:area]; memcpy(matrix.array, self.data, area * sizeof(int8_t)); return matrix; @@ -182,42 +196,42 @@ - (void)initializeWithImage:(CGImageRef)cgimage left:(size_t)left top:(size_t)to size_t sourceHeight = CGImageGetHeight(cgimage); size_t selfWidth = self.width; size_t selfHeight= self.height; - + if (left + selfWidth > sourceWidth || top + selfHeight > sourceHeight) { [NSException raise:NSInvalidArgumentException format:@"Crop rectangle does not fit within image data."]; } - + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, selfWidth, selfHeight, 8, selfWidth * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); - + CGContextSetAllowsAntialiasing(context, FALSE); CGContextSetInterpolationQuality(context, kCGInterpolationNone); - + if (top || left) { CGContextClipToRect(context, CGRectMake(0, 0, selfWidth, selfHeight)); } - + CGContextDrawImage(context, CGRectMake(-left, -top, selfWidth, selfHeight), self.image); - + uint32_t *pixelData = CGBitmapContextGetData(context); - + _data = (int8_t *)malloc(selfWidth * selfHeight * sizeof(int8_t)); - + dispatch_apply(selfHeight, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(size_t idx) { size_t stripe_start = idx * selfWidth; size_t stripe_stop = stripe_start + selfWidth; - + for (size_t i = stripe_start; i < stripe_stop; i++) { uint32_t rgbPixelIn = pixelData[i]; uint32_t rgbPixelOut = 0; - + uint32_t red = (rgbPixelIn >> 24) & 0xFF; uint32_t green = (rgbPixelIn >> 16) & 0xFF; uint32_t blue = (rgbPixelIn >> 8) & 0xFF; uint32_t alpha = (rgbPixelIn & 0xFF); - + // ImageIO premultiplies all PNGs, so we have to "un-premultiply them": // http://code.google.com/p/cocos2d-iphone/issues/detail?id=697#c26 if (alpha != 0xFF) { @@ -225,48 +239,91 @@ - (void)initializeWithImage:(CGImageRef)cgimage left:(size_t)left top:(size_t)to green = green > 0 ? ((green << 20) / (alpha << 2)) >> 10 : 0; blue = blue > 0 ? ((blue << 20) / (alpha << 2)) >> 10 : 0; } - + if (red == green && green == blue) { rgbPixelOut = red; } else { - rgbPixelOut = (306 * red + - 601 * green + - 117 * blue + - (0x200)) >> 10; // 0x200 = 1<<9, half an lsb of the result to force rounding + rgbPixelOut = [self calculateRed:red green:green blue:blue]; } - + if (rgbPixelOut > 255) { rgbPixelOut = 255; } - - _data[i] = rgbPixelOut; + + // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent + // black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a + // barcode image. Force any such pixel to be white: + if (rgbPixelOut == 0 && alpha == 0) { + rgbPixelOut = 255; + } + + self->_data[i] = rgbPixelOut; } }); - + CGContextRelease(context); - + _top = top; _left = left; } +- (uint32_t)calculateRed:(uint32_t)red green:(uint32_t)green blue:(uint32_t)blue { + // Normal formula + if (_sourceInfo == nil || _sourceInfo.type == ZXCGImageLuminanceSourceNormal) { + uint32_t ret = (306 * red + 601 * green + 117 * blue + (0x200)) >> 10; // 0x200 = 1<<9, half an lsb of the result to force rounding + return ret; + } + + switch (_sourceInfo.type) { + case ZXCGImageLuminanceSourceLuma: { + uint32_t result = (red * 0.2126 + green * 0.7152 + blue * 0.0722); + return result; + } + + // shades formula - ref: http://www.tannerhelland.com/3643/grayscale-image-algorithm-vb6/ + case ZXCGImageLuminanceSourceShades: { + if (_sourceInfo.numberOfShades > 1) { + float conversationFactor = 255.0 / (_sourceInfo.numberOfShades - 1); + float averageValue = (red + green + blue) / 3.0; + uint32_t result = ((averageValue / conversationFactor) + 0.5) * conversationFactor; + return result; + } + + return 0; + } + + case ZXCGImageLuminanceSourceDigital: + return green; + + case ZXCGImageLuminanceSourceDecomposingMin: + return MIN(MIN(red, green), blue); + + case ZXCGImageLuminanceSourceDecomposingMax: + return MAX(MAX(red, green), blue); + + default: + return 0; + } +} + - (BOOL)rotateSupported { return YES; } - (ZXLuminanceSource *)rotateCounterClockwise { double radians = 270.0f * M_PI / 180; - + #if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR radians = -1 * radians; #endif - + int sourceWidth = self.width; int sourceHeight = self.height; - + CGRect imgRect = CGRectMake(0, 0, sourceWidth, sourceHeight); CGAffineTransform transform = CGAffineTransformMakeRotation(radians); CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform); - + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, rotatedRect.size.width, @@ -278,36 +335,38 @@ - (ZXLuminanceSource *)rotateCounterClockwise { CGContextSetAllowsAntialiasing(context, FALSE); CGContextSetInterpolationQuality(context, kCGInterpolationNone); CGColorSpaceRelease(colorSpace); - + CGContextTranslateCTM(context, +(rotatedRect.size.width/2), +(rotatedRect.size.height/2)); CGContextRotateCTM(context, radians); - + CGContextDrawImage(context, CGRectMake(-imgRect.size.width/2, -imgRect.size.height/2, imgRect.size.width, imgRect.size.height), self.image); - + CGImageRef rotatedImage = CGBitmapContextCreateImage(context); - + CFRelease(context); - + ZXCGImageLuminanceSource *result = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage left:self.top top:sourceWidth - (self.left + self.width) width:self.height height:self.width]; - + CGImageRelease(rotatedImage); - + return result; } - (ZXLuminanceSource *)crop:(int)left top:(int)top width:(int)width height:(int)height { CGImageRef croppedImageRef = CGImageCreateWithImageInRect(self.image, CGRectMake(left, top, width, height)); - return [[ZXCGImageLuminanceSource alloc] initWithCGImage:croppedImageRef]; + ZXCGImageLuminanceSource *result = [[ZXCGImageLuminanceSource alloc] initWithCGImage:croppedImageRef]; + CGImageRelease(croppedImageRef); + return result; } @end diff --git a/ZXingObjC/client/ZXCGImageLuminanceSourceInfo.h b/ZXingObjC/client/ZXCGImageLuminanceSourceInfo.h new file mode 100644 index 000000000..5fa4a533e --- /dev/null +++ b/ZXingObjC/client/ZXCGImageLuminanceSourceInfo.h @@ -0,0 +1,49 @@ +/* + * Copyright 2018 ZXing contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +typedef enum { + ZXCGImageLuminanceSourceNormal = 0, + ZXCGImageLuminanceSourceLuma, + ZXCGImageLuminanceSourceShades, + ZXCGImageLuminanceSourceDigital, + ZXCGImageLuminanceSourceDecomposingMax, + ZXCGImageLuminanceSourceDecomposingMin, +} ZXCGImageLuminanceSourceType; + + +@interface ZXCGImageLuminanceSourceInfo : NSObject + +@property (nonatomic, assign, readonly) uint32_t numberOfShades; + +@property (nonatomic, assign, readonly) ZXCGImageLuminanceSourceType type; + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithLuma; + +- (instancetype)initWithShades: (uint32_t)numberOfShades; + +- (instancetype)initWithNormal; + +- (instancetype)initWithDigital; + +- (instancetype)initWithDecomposingMax; + +- (instancetype)initWithDecomposingMin; + +@end diff --git a/ZXingObjC/client/ZXCGImageLuminanceSourceInfo.m b/ZXingObjC/client/ZXCGImageLuminanceSourceInfo.m new file mode 100644 index 000000000..4fb34f4bd --- /dev/null +++ b/ZXingObjC/client/ZXCGImageLuminanceSourceInfo.m @@ -0,0 +1,70 @@ +/* + * Copyright 2018 ZXing contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXCGImageLuminanceSourceInfo.h" + +@implementation ZXCGImageLuminanceSourceInfo + +- (instancetype)initWithNormal { + self = [super init]; + if (self) { + _type = ZXCGImageLuminanceSourceNormal; + } + return self; +} + +- (instancetype)initWithLuma { + self = [super init]; + if (self) { + _type = ZXCGImageLuminanceSourceLuma; + } + return self; +} + +- (instancetype)initWithShades:(uint32_t)numberOfShades { + self = [super init]; + if (self) { + _type = ZXCGImageLuminanceSourceShades; + _numberOfShades = numberOfShades; + } + return self; +} + +- (instancetype)initWithDigital { + self = [super init]; + if (self) { + _type = ZXCGImageLuminanceSourceDigital; + } + return self; +} + +- (instancetype)initWithDecomposingMax { + self = [super init]; + if (self) { + _type = ZXCGImageLuminanceSourceDecomposingMax; + } + return self; +} + +- (instancetype)initWithDecomposingMin { + self = [super init]; + if (self) { + _type = ZXCGImageLuminanceSourceDecomposingMin; + } + return self; +} + +@end diff --git a/ZXingObjC/client/ZXCapture.h b/ZXingObjC/client/ZXCapture.h index d8e529d76..caf4b639f 100644 --- a/ZXingObjC/client/ZXCapture.h +++ b/ZXingObjC/client/ZXCapture.h @@ -19,7 +19,11 @@ @protocol ZXCaptureDelegate, ZXReader; @class ZXDecodeHints; -@interface ZXCapture : NSObject +@interface ZXCapture : NSObject = __MAC_10_12 || defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 +, CALayerDelegate +#endif +> @property (nonatomic, assign) int camera; @property (nonatomic, strong) AVCaptureDevice *captureDevice; @@ -39,6 +43,7 @@ @property (nonatomic, copy) NSString *sessionPreset; @property (nonatomic, assign) BOOL torch; @property (nonatomic, assign) CGAffineTransform transform; +@property (nonatomic, assign) CGFloat captureFramesPerSec; - (int)back; - (int)front; @@ -57,4 +62,13 @@ - (void)start; - (void)stop; +/** + * This enables `ZXCapture` to try additional heuristics to decode + * the barcode. + * + * @see `ZXCGImageLuminanceSourceInfo` + * Currently: make the grayscale image darker to process + */ +- (void)enableHeuristic; + @end diff --git a/ZXingObjC/client/ZXCapture.m b/ZXingObjC/client/ZXCapture.m index ec7139c18..235e62ef2 100644 --- a/ZXingObjC/client/ZXCapture.m +++ b/ZXingObjC/client/ZXCapture.m @@ -41,6 +41,8 @@ @interface ZXCapture () @property (nonatomic, assign) BOOL running; @property (nonatomic, strong) AVCaptureSession *session; +@property (nonatomic, assign) BOOL heuristic; +@property (nonatomic, copy) dispatch_queue_t parallelQueue; @end @implementation ZXCapture @@ -56,18 +58,18 @@ - (ZXCapture *)init { _onScreen = NO; _orderInSkip = 0; _orderOutSkip = 0; - + _captureFramesPerSec = 3.0f; + if (NSClassFromString(@"ZXMultiFormatReader")) { _reader = [NSClassFromString(@"ZXMultiFormatReader") performSelector:@selector(reader)]; } - + _rotation = 0.0f; _running = NO; - _sessionPreset = AVCaptureSessionPresetMedium; _transform = CGAffineTransformIdentity; _scanRect = CGRectZero; } - + return self; } @@ -75,13 +77,13 @@ - (void)dealloc { if (_lastScannedImage) { CGImageRelease(_lastScannedImage); } - + if (_session && _session.inputs) { for (AVCaptureInput *input in _session.inputs) { [_session removeInput:input]; } } - + if (_session && _session.outputs) { for (AVCaptureOutput *output in _session.outputs) { [_session removeOutput:output]; @@ -97,9 +99,8 @@ - (CALayer *)layer { layer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session]; layer.affineTransform = self.transform; layer.delegate = self; - layer.videoGravity = AVLayerVideoGravityResizeAspect; layer.videoGravity = AVLayerVideoGravityResizeAspectFill; - + _layer = layer; } return layer; @@ -109,14 +110,14 @@ - (AVCaptureVideoDataOutput *)output { if (!_output) { _output = [[AVCaptureVideoDataOutput alloc] init]; [_output setVideoSettings:@{ - (NSString *)kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA] - }]; + (NSString *)kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA] + }]; [_output setAlwaysDiscardsLateVideoFrames:YES]; [_output setSampleBufferDelegate:self queue:_captureQueue]; - + [self.session addOutput:_output]; } - + return _output; } @@ -133,7 +134,7 @@ - (void)setCamera:(int)camera { - (void)setDelegate:(id)delegate { _delegate = delegate; - + if (delegate) { self.hardStop = NO; } @@ -143,7 +144,7 @@ - (void)setDelegate:(id)delegate { - (void)setFocusMode:(AVCaptureFocusMode)focusMode { if ([self.input.device isFocusModeSupported:focusMode] && self.input.device.focusMode != focusMode) { _focusMode = focusMode; - + [self.input.device lockForConfiguration:nil]; self.input.device.focusMode = focusMode; [self.input.device unlockForConfiguration]; @@ -154,11 +155,11 @@ - (void)setLastScannedImage:(CGImageRef)lastScannedImage { if (_lastScannedImage) { CGImageRelease(_lastScannedImage); } - + if (lastScannedImage) { CGImageRetain(lastScannedImage); } - + _lastScannedImage = lastScannedImage; } @@ -176,9 +177,14 @@ - (void)setMirror:(BOOL)mirror { - (void)setTorch:(BOOL)torch { _torch = torch; - + [self.input.device lockForConfiguration:nil]; - self.input.device.torchMode = self.torch ? AVCaptureTorchModeOn : AVCaptureTorchModeOff; + + AVCaptureTorchMode torchMode = self.torch ? AVCaptureTorchModeOn : AVCaptureTorchModeOff; + if ([self.input.device isTorchModeSupported:torchMode]) { + self.input.device.torchMode = torchMode; + } + [self.input.device unlockForConfiguration]; } @@ -187,6 +193,13 @@ - (void)setTransform:(CGAffineTransform)transform { [self.layer setAffineTransform:transform]; } +- (void)enableHeuristic { + if (_heuristic) { return; } + _heuristic = YES; + _parallelQueue = dispatch_queue_create("com.zxing.parallelQueue", DISPATCH_QUEUE_CONCURRENT); +} + + #pragma mark - Back, Front, Torch - (int)back { @@ -198,12 +211,18 @@ - (int)front { } - (BOOL)hasFront { - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - return [devices count] > 1; + AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] + mediaType:AVMediaTypeVideo + position:AVCaptureDevicePositionFront]; + NSArray *devices = [captureDeviceDiscoverySession devices]; + return [devices count] > 0; } - (BOOL)hasBack { - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] + mediaType:AVMediaTypeVideo + position:AVCaptureDevicePositionBack]; + NSArray *devices = [captureDeviceDiscoverySession devices]; return [devices count] > 0; } @@ -247,7 +266,7 @@ - (void)setLuminance:(BOOL)on { - (void)hard_stop { self.hardStop = YES; - + if (self.running) { [self stop]; } @@ -262,17 +281,17 @@ - (void)start { if (self.hardStop) { return; } - + if (self.delegate || self.luminanceLayer || self.binaryLayer) { (void)[self output]; } - + if (!self.session.running) { static int i = 0; if (++i == -2) { abort(); } - + [self.session startRunning]; } self.running = YES; @@ -282,11 +301,11 @@ - (void)stop { if (!self.running) { return; } - + if (self.session.running) { [self.session stopRunning]; } - + self.running = NO; } @@ -294,11 +313,11 @@ - (void)stop { - (id)actionForLayer:(CALayer *)_layer forKey:(NSString *)event { [CATransaction setValue:[NSNumber numberWithFloat:0.0f] forKey:kCATransactionAnimationDuration]; - + if ([event isEqualToString:kCAOnOrderIn] || [event isEqualToString:kCAOnOrderOut]) { return self; } - + return nil; } @@ -308,7 +327,7 @@ - (void)runActionForKey:(NSString *)key object:(id)anObject arguments:(NSDiction self.orderInSkip--; return; } - + self.onScreen = YES; [self startStop]; } else if ([key isEqualToString:kCAOnOrderOut]) { @@ -316,7 +335,7 @@ - (void)runActionForKey:(NSString *)key object:(id)anObject arguments:(NSDiction self.orderOutSkip--; return; } - + self.onScreen = NO; [self startStop]; } @@ -328,7 +347,7 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { if (!self.running) return; - + @autoreleasepool { if (!self.cameraIsReady) { self.cameraIsReady = YES; @@ -338,73 +357,144 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput }); } } - + if (!self.captureToFilename && !self.luminanceLayer && !self.binaryLayer && !self.delegate) { return; } - - CVImageBufferRef videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer); - - CGImageRef videoFrameImage = [ZXCGImageLuminanceSource createImageFromBuffer:videoFrame]; - CGImageRef rotatedImage = [self createRotatedImage:videoFrameImage degrees:self.rotation]; - CGImageRelease(videoFrameImage); - - // If scanRect is set, crop the current image to include only the desired rect - if (!CGRectIsEmpty(self.scanRect)) { - CGImageRef croppedImage = CGImageCreateWithImageInRect(rotatedImage, self.scanRect); - CFRelease(rotatedImage); - rotatedImage = croppedImage; + + // reduce CPU usage by around 30%, reference: https://github.com/TheLevelUp/ZXingObjC/issues/314 + // Default capture 3 frames per second or customize them. if you want lower CPU usage, can adjust captureFramesPerSec to 1.0f make a better performace. + float kMinMargin = 1.0 / _captureFramesPerSec; + + // Gets the timestamp for each frame. + CMTime presentTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); + + static double curFrameTimeStamp = 0; + static double lastFrameTimeStamp = 0; + + curFrameTimeStamp = (double)presentTimeStamp.value / presentTimeStamp.timescale; + + if (curFrameTimeStamp - lastFrameTimeStamp > kMinMargin) { + lastFrameTimeStamp = curFrameTimeStamp; + + CVImageBufferRef videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer); + CGImageRef videoFrameImage = [ZXCGImageLuminanceSource createImageFromBuffer:videoFrame]; + [self decodeImage:videoFrameImage]; } + } +} - self.lastScannedImage = rotatedImage; - - if (self.captureToFilename) { - NSURL *url = [NSURL fileURLWithPath:self.captureToFilename]; - CGImageDestinationRef dest = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, (__bridge CFStringRef)@"public.png", 1, nil); - CGImageDestinationAddImage(dest, rotatedImage, nil); - CGImageDestinationFinalize(dest); - CFRelease(dest); - self.captureToFilename = nil; +- (void)decodeImage: (CGImageRef)image { + // If scanRect is set, crop the current image to include only the desired rect + if (!CGRectIsEmpty(self.scanRect)) { + CGImageRef croppedImage = CGImageCreateWithImageInRect(image, self.scanRect); + CGImageRelease(image); + image = croppedImage; + } + + CGImageRef rotatedImage = [self createRotatedImage:image degrees:self.rotation]; + CGImageRelease(image); + self.lastScannedImage = rotatedImage; + + if (self.captureToFilename) { + NSURL *url = [NSURL fileURLWithPath:self.captureToFilename]; + CGImageDestinationRef dest = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, (__bridge CFStringRef)@"public.png", 1, nil); + CGImageDestinationAddImage(dest, rotatedImage, nil); + CGImageDestinationFinalize(dest); + CFRelease(dest); + self.captureToFilename = nil; + } + + if (_heuristic) { + [self decodeImageAdv:rotatedImage]; + } + + ZXCGImageLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage: rotatedImage]; + CGImageRelease(rotatedImage); + + if (self.luminanceLayer) { + CGImageRef image = source.image; + CGImageRetain(image); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{ + self.luminanceLayer.contents = (__bridge id)image; + CGImageRelease(image); + }); + } + + if (!self.binaryLayer && !self.delegate) { return; } + + ZXHybridBinarizer *binarizer = [[ZXHybridBinarizer alloc] initWithSource:source]; + + if (self.binaryLayer) { + CGImageRef image = [binarizer createImage]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{ + self.binaryLayer.contents = (__bridge id)image; + CGImageRelease(image); + }); + } + + if (self.delegate) { + ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:binarizer]; + + NSError *error; + ZXResult *result = [self.reader decode:bitmap hints:self.hints error:&error]; + if (result) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self.delegate captureResult:self result:result]; + }); + return; } - - ZXCGImageLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage]; - CGImageRelease(rotatedImage); - - if (self.luminanceLayer) { - CGImageRef image = source.image; - CGImageRetain(image); + } + + // Try decoding inverted image + if (self.binaryLayer || self.delegate) { + ZXHybridBinarizer *invertedBinarizer = [[ZXHybridBinarizer alloc] initWithSource:[source invert]]; + + if (self.binaryLayer) { + CGImageRef image = [invertedBinarizer createImage]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{ - self.luminanceLayer.contents = (__bridge id)image; + self.binaryLayer.contents = (__bridge id)image; CGImageRelease(image); }); } - - if (self.binaryLayer || self.delegate) { - ZXHybridBinarizer *binarizer = [[ZXHybridBinarizer alloc] initWithSource:self.invert ? [source invert] : source]; - - if (self.binaryLayer) { - CGImageRef image = [binarizer createImage]; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{ - self.binaryLayer.contents = (__bridge id)image; - CGImageRelease(image); + + if (self.delegate) { + ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:invertedBinarizer]; + + NSError *error; + ZXResult *result = [self.reader decode:bitmap hints:self.hints error:&error]; + if (result) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self.delegate captureResult:self result:result]; }); } - - if (self.delegate) { - ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:binarizer]; - - NSError *error; - ZXResult *result = [self.reader decode:bitmap hints:self.hints error:&error]; - if (result) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self.delegate captureResult:self result:result]; - }); - } - } } } } +/** + * This function try to make the grayscale image darker to process + */ +- (void)decodeImageAdv:(CGImageRef)cgImage { + CGImageRef img = CGImageCreateCopy(cgImage); + dispatch_async(_parallelQueue, ^{ + ZXCGImageLuminanceSourceInfo *sourceInfo = [[ZXCGImageLuminanceSourceInfo alloc] initWithDecomposingMin]; + ZXCGImageLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:img + sourceInfo:sourceInfo]; + CGImageRelease(img); + + ZXHybridBinarizer *binarizer = [[ZXHybridBinarizer alloc] initWithSource:source]; + ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:binarizer]; + NSError *error; + ZXResult *result = [self.reader decode:bitmap hints: self.hints error:&error]; + if (result && [self.delegate respondsToSelector: @selector(captureResult:result:)]) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self.delegate captureResult:self result:result]; + }); + } + }); +} + #pragma mark - Private // Adapted from http://blog.coriolis.ch/2009/09/04/arbitrary-rotation-of-a-cgimage/ and https://github.com/JanX2/CreateRotateWriteCGImage @@ -414,18 +504,18 @@ - (CGImageRef)createRotatedImage:(CGImageRef)original degrees:(float)degrees CF_ return original; } else { double radians = degrees * M_PI / 180; - + #if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR radians = -1 * radians; #endif - + size_t _width = CGImageGetWidth(original); size_t _height = CGImageGetHeight(original); - + CGRect imgRect = CGRectMake(0, 0, _width, _height); CGAffineTransform __transform = CGAffineTransformMakeRotation(radians); CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, __transform); - + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, rotatedRect.size.width, @@ -437,21 +527,21 @@ - (CGImageRef)createRotatedImage:(CGImageRef)original degrees:(float)degrees CF_ CGContextSetAllowsAntialiasing(context, FALSE); CGContextSetInterpolationQuality(context, kCGInterpolationNone); CGColorSpaceRelease(colorSpace); - + CGContextTranslateCTM(context, +(rotatedRect.size.width/2), +(rotatedRect.size.height/2)); CGContextRotateCTM(context, radians); - + CGContextDrawImage(context, CGRectMake(-imgRect.size.width/2, -imgRect.size.height/2, imgRect.size.width, imgRect.size.height), original); - + CGImageRef rotatedImage = CGBitmapContextCreateImage(context); CFRelease(context); - + return rotatedImage; } } @@ -460,10 +550,13 @@ - (AVCaptureDevice *)device { if (self.captureDevice) { return self.captureDevice; } - + AVCaptureDevice *zxd = nil; - - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + + AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] + mediaType:AVMediaTypeVideo + position:AVCaptureDevicePositionUnspecified]; + NSArray *devices = [captureDeviceDiscoverySession devices]; if ([devices count] > 0) { if (self.captureDeviceIndex == -1) { @@ -471,7 +564,7 @@ - (AVCaptureDevice *)device { if (self.camera == self.front) { position = AVCaptureDevicePositionFront; } - + for (unsigned int i = 0; i < [devices count]; ++i) { AVCaptureDevice *dev = [devices objectAtIndex:i]; if (dev.position == position) { @@ -481,41 +574,44 @@ - (AVCaptureDevice *)device { } } } - + if (!zxd && self.captureDeviceIndex != -1) { zxd = [devices objectAtIndex:self.captureDeviceIndex]; } } - + if (!zxd) { zxd = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; } - + self.captureDevice = zxd; - + return zxd; } - (void)replaceInput { [self.session beginConfiguration]; - + if (self.session && self.input) { [self.session removeInput:self.input]; self.input = nil; } - + AVCaptureDevice *zxd = [self device]; - + if (zxd) { self.input = [AVCaptureDeviceInput deviceInputWithDevice:zxd error:nil]; self.focusMode = self.focusMode; } - + if (self.input) { + if (!self.sessionPreset) { + self.sessionPreset = AVCaptureSessionPreset1280x720; + } self.session.sessionPreset = self.sessionPreset; [self.session addInput:self.input]; } - + [self.session commitConfiguration]; } @@ -524,7 +620,6 @@ - (AVCaptureSession *)session { _session = [[AVCaptureSession alloc] init]; [self replaceInput]; } - return _session; } @@ -535,7 +630,7 @@ - (void)startStop { (self.onScreen && (self.luminanceLayer || self.binaryLayer))))) { [self start]; } - + if (self.running && !self.delegate && !self.onScreen) { [self stop]; } diff --git a/ZXingObjC/client/ZXImage.m b/ZXingObjC/client/ZXImage.m index 7c09d6bcb..e825b9bcc 100644 --- a/ZXingObjC/client/ZXImage.m +++ b/ZXingObjC/client/ZXImage.m @@ -83,53 +83,53 @@ + (ZXImage *)imageWithMatrix:(ZXBitMatrix *)matrix { } + (ZXImage *)imageWithMatrix:(ZXBitMatrix *)matrix onColor:(CGColorRef)onColor offColor:(CGColorRef)offColor { - int8_t onIntensities[4], offIntensities[4]; - - [self setColorIntensities:onIntensities color:onColor]; - [self setColorIntensities:offIntensities color:offColor]; - - int width = matrix.width; - int height = matrix.height; - int8_t *bytes = (int8_t *)malloc(width * height * 4); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - BOOL bit = [matrix getX:x y:y]; - for (int i = 0; i < 4; i++) { - int8_t intensity = bit ? onIntensities[i] : offIntensities[i]; - bytes[y * width * 4 + x * 4 + i] = intensity; - } + uint8_t onIntensities[4], offIntensities[4]; + + [self setColorIntensities:onIntensities color:onColor]; + [self setColorIntensities:offIntensities color:offColor]; + + int width = matrix.width; + int height = matrix.height; + int8_t *bytes = (int8_t *)malloc(width * height * 4); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + BOOL bit = [matrix getX:x y:y]; + for (int i = 0; i < 4; i++) { + int8_t intensity = bit ? onIntensities[i] : offIntensities[i]; + bytes[y * width * 4 + x * 4 + i] = intensity; + } + } } - } - - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef c = CGBitmapContextCreate(bytes, width, height, 8, 4 * width, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast); - CFRelease(colorSpace); - CGImageRef image = CGBitmapContextCreateImage(c); - CFRelease(c); - free(bytes); - - ZXImage *zxImage = [[ZXImage alloc] initWithCGImageRef:image]; - - CFRelease(image); - return zxImage; + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef c = CGBitmapContextCreate(bytes, width, height, 8, 4 * width, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast); + CFRelease(colorSpace); + CGImageRef image = CGBitmapContextCreateImage(c); + CFRelease(c); + free(bytes); + + ZXImage *zxImage = [[ZXImage alloc] initWithCGImageRef:image]; + + CFRelease(image); + return zxImage; } -+ (void)setColorIntensities:(int8_t *)intensities color:(CGColorRef)color { - memset(intensities, 0, 4); - - size_t numberOfComponents = CGColorGetNumberOfComponents(color); - const CGFloat *components = CGColorGetComponents(color); - - if (numberOfComponents == 4) { - for (int i = 0; i < 4; i++) { - intensities[i] = components[i] * 255; ++ (void)setColorIntensities:(uint8_t *)intensities color:(CGColorRef)color { + memset(intensities, 0, 4); + + size_t numberOfComponents = CGColorGetNumberOfComponents(color); + const CGFloat *components = CGColorGetComponents(color); + + if (numberOfComponents == 4) { + for (int i = 0; i < 4; i++) { + intensities[i] = MIN(1.0, MAX(0, components[i])) * 255; + } + } else if (numberOfComponents == 2) { + for (int i = 0; i < 3; i++) { + intensities[i] = MIN(1.0, MAX(0, components[0])) * 255; + } + intensities[3] = MIN(1.0, MAX(0, components[1])) * 255; } - } else if (numberOfComponents == 2) { - for (int i = 0; i < 3; i++) { - intensities[i] = components[0] * 255; - } - intensities[3] = components[1] * 255; - } } @end diff --git a/ZXingObjC/client/result/ZXResultParser.h b/ZXingObjC/client/result/ZXResultParser.h index 688a438ac..8db25c13a 100644 --- a/ZXingObjC/client/result/ZXResultParser.h +++ b/ZXingObjC/client/result/ZXResultParser.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXParsedResult, ZXResult; /** @@ -31,6 +33,9 @@ * Attempts to parse the raw ZXResult's contents as a particular type * of information (email, URL, etc.) and return a ZXParsedResult encapsulating * the result of parsing. + * + * @param result the raw ZXResult to parse + * @return ZXParsedResult encapsulating the parsing result */ - (ZXParsedResult *)parse:(ZXResult *)result; diff --git a/ZXingObjC/client/result/ZXResultParser.m b/ZXingObjC/client/result/ZXResultParser.m index 8981f7e6d..0d4abb12e 100644 --- a/ZXingObjC/client/result/ZXResultParser.m +++ b/ZXingObjC/client/result/ZXResultParser.m @@ -249,7 +249,7 @@ - (void)appendKeyValue:(NSString *)keyValue result:(NSMutableDictionary *)result + (NSString *)urlDecode:(NSString *)encoded { NSString *result = [encoded stringByReplacingOccurrencesOfString:@"+" withString:@" "]; - result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + result = [result stringByRemovingPercentEncoding]; return result; } diff --git a/ZXingObjC/client/result/ZXVINResultParser.m b/ZXingObjC/client/result/ZXVINResultParser.m index 6865792ca..c9a0ec7bc 100644 --- a/ZXingObjC/client/result/ZXVINResultParser.m +++ b/ZXingObjC/client/result/ZXVINResultParser.m @@ -35,7 +35,7 @@ - (ZXVINParsedResult *)parse:(ZXResult *)result { } NSString *rawText = result.text; rawText = [[ZX_IOQ stringByReplacingMatchesInString:rawText options:0 range:NSMakeRange(0, rawText.length) withTemplate:@""] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - if ([ZX_AZ09 matchesInString:rawText options:0 range:NSMakeRange(0, rawText.length)] == 0) { + if ([ZX_AZ09 numberOfMatchesInString:rawText options:0 range:NSMakeRange(0, rawText.length)] == 0) { return nil; } if (![self checkChecksum:rawText]) { diff --git a/ZXingObjC/common/ZXBitArray.h b/ZXingObjC/common/ZXBitArray.h index 02432647d..2a01fd2c0 100644 --- a/ZXingObjC/common/ZXBitArray.h +++ b/ZXingObjC/common/ZXBitArray.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXByteArray, ZXIntArray; /** @@ -60,6 +62,11 @@ */ - (int)nextSet:(int)from; +/** + * @param from index to start looking for unset bit + * @return index of next unset bit, or size if none are unset until the end + * @see nextSet: + */ - (int)nextUnset:(int)from; /** @@ -101,6 +108,9 @@ * Appends the least-significant bits, from value, in order from most-significant to * least-significant. For example, appending 6 bits from 0x000001E will append the bits * 0, 1, 1, 1, 1, 0 in that order. + * + * @param value in32_t containing bits to append + * @param numBits bits from value to append */ - (void)appendBits:(int32_t)value numBits:(int)numBits; @@ -112,7 +122,7 @@ * * @param bitOffset first bit to start writing * @param array array to write into. Bytes are written most-significant byte first. This is the opposite - * of the internal representation, which is exposed by {@link #getBitArray()} + * of the internal representation, which is exposed by `bitArray` * @param offset position in array to start writing * @param numBytes how many bytes to write */ diff --git a/ZXingObjC/common/ZXBitArray.m b/ZXingObjC/common/ZXBitArray.m index 9e415d3d5..cdd4befb4 100644 --- a/ZXingObjC/common/ZXBitArray.m +++ b/ZXingObjC/common/ZXBitArray.m @@ -74,9 +74,15 @@ - (int)sizeInBytes { - (void)ensureCapacity:(int)size { if (size > self.bitsLength * 32) { int newBitsLength = (size + 31) / 32; - self.bits = realloc(self.bits, newBitsLength * sizeof(int32_t)); - memset(self.bits + self.bitsLength, 0, (newBitsLength - self.bitsLength) * sizeof(int32_t)); + // basically realloc + int32_t *newBits = (int32_t *)malloc(newBitsLength * sizeof(int32_t)); + memcpy(newBits, self.bits, self.bitsLength * sizeof(int32_t)); + memset(newBits + self.bitsLength, 0, (newBitsLength - self.bitsLength) * sizeof(int32_t)); + free(self.bits); + self.bits = NULL; + + self.bits = newBits; self.bitsLength = newBitsLength; } } @@ -134,7 +140,7 @@ - (void)setBulk:(int)i newBits:(int32_t)newBits { } - (void)setRange:(int)start end:(int)end { - if (end < start) { + if (end < start || start < 0 || end > self.size) { @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Start greater than end" userInfo:nil]; } if (end == start) { @@ -146,18 +152,8 @@ - (void)setRange:(int)start end:(int)end { for (int i = firstInt; i <= lastInt; i++) { int firstBit = i > firstInt ? 0 : start & 0x1F; int lastBit = i < lastInt ? 31 : end & 0x1F; - int32_t mask; - if (lastBit > 31) { - @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Bit-shift operand does not support more than 31 bits" userInfo:nil]; - } - if (firstBit == 0 && lastBit == 31) { - mask = -1; - } else { - mask = 0; - for (int j = firstBit; j <= lastBit; j++) { - mask |= 1 << j; - } - } + // Ones from firstBit to lastBit, inclusive + int32_t mask = (2 << lastBit) - (1 << firstBit); _bits[i] |= mask; } } @@ -167,7 +163,7 @@ - (void)clear { } - (BOOL)isRange:(int)start end:(int)end value:(BOOL)value { - if (end < start) { + if (end < start || start < 0 || end > self.size) { @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Start greater than end" userInfo:nil]; } if (end == start) { @@ -179,18 +175,8 @@ - (BOOL)isRange:(int)start end:(int)end value:(BOOL)value { for (int i = firstInt; i <= lastInt; i++) { int firstBit = i > firstInt ? 0 : start & 0x1F; int lastBit = i < lastInt ? 31 : end & 0x1F; - int32_t mask; - if (lastBit > 31) { - @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Bit-shift operand does not support more than 31 bits" userInfo:nil]; - } - if (firstBit == 0 && lastBit == 31) { - mask = -1; - } else { - mask = 0; - for (int j = firstBit; j <= lastBit; j++) { - mask |= 1 << j; - } - } + // Ones from firstBit to lastBit, inclusive + int32_t mask = (2 << lastBit) - (1 << firstBit); // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is, // equals the mask, or we're looking for 0s and the masked portion is not all 0s @@ -232,14 +218,14 @@ - (void)appendBitArray:(ZXBitArray *)other { } - (void)xor:(ZXBitArray *)other { - if (self.bitsLength != other.bitsLength) { + if (self.size != other.size) { @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Sizes don't match" userInfo:nil]; } for (int i = 0; i < self.bitsLength; i++) { - // The last byte could be incomplete (i.e. not have 8 bits in + // The last int could be incomplete (i.e. not have 32 bits in // it) but there is no problem since 0 XOR 0 == 0. self.bits[i] ^= other.bits[i]; } @@ -269,11 +255,27 @@ - (BOOL)isEqual:(id)o { return NO; } ZXBitArray *other = (ZXBitArray *)o; - return self.size == other.size && memcmp(self.bits, other.bits, self.bitsLength) != 0; + if (self.size != other.size) { + return NO; + } + for (int i = 0; i < self.bitsLength; i++) { + if (self.bits[i] != other.bits[i]) { + return NO; + } + } + return YES; } - (NSUInteger)hash { - return 31 * self.size; + if (self.bitsLength == 0) { + return 31 * self.size; + } + + NSUInteger bitsHash = 1; + for (int i = 0; i < self.bitsLength; i++) { + bitsHash = 31 * bitsHash + self.bits[i]; + } + return 31 * self.size + bitsHash; } - (void)reverse { diff --git a/ZXingObjC/common/ZXBitMatrix.h b/ZXingObjC/common/ZXBitMatrix.h index be65fcf8d..2335ccd21 100644 --- a/ZXingObjC/common/ZXBitMatrix.h +++ b/ZXingObjC/common/ZXBitMatrix.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBitArray, ZXIntArray; /** diff --git a/ZXingObjC/common/ZXBitMatrix.m b/ZXingObjC/common/ZXBitMatrix.m index 4e031038e..3f4a0d24a 100644 --- a/ZXingObjC/common/ZXBitMatrix.m +++ b/ZXingObjC/common/ZXBitMatrix.m @@ -271,8 +271,8 @@ - (ZXIntArray *)enclosingRectangle { } } - NSInteger width = right - left; - NSInteger height = bottom - top; + NSInteger width = right - left + 1; + NSInteger height = bottom - top + 1; if (width < 0 || height < 0) { return nil; @@ -347,6 +347,7 @@ - (NSUInteger)hash { return hash; } +// string representation using "X" for set and " " for unset bits - (NSString *)description { return [self descriptionWithSetString:@"X " unsetString:@" "]; } diff --git a/ZXingObjC/common/ZXBitSource.h b/ZXingObjC/common/ZXBitSource.h index 6cc0d5ecb..ae31e10e6 100644 --- a/ZXingObjC/common/ZXBitSource.h +++ b/ZXingObjC/common/ZXBitSource.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXByteArray; /** @@ -26,12 +28,12 @@ @interface ZXBitSource : NSObject /** - * @return index of next bit in current byte which would be read by the next call to {@link #readBits(int)}. + * @return index of next bit in current byte which would be read by the next call to `readBits:`. */ @property (nonatomic, assign, readonly) int bitOffset; /** - * @return index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}. + * @return index of next byte in input byte array which would be read by the next call to `readBits:`. */ @property (nonatomic, assign, readonly) int byteOffset; diff --git a/ZXingObjC/common/ZXBoolArray.h b/ZXingObjC/common/ZXBoolArray.h index 582d3a375..d25a1b59a 100644 --- a/ZXingObjC/common/ZXBoolArray.h +++ b/ZXingObjC/common/ZXBoolArray.h @@ -14,11 +14,14 @@ * limitations under the License. */ +#import + @interface ZXBoolArray : NSObject @property (nonatomic, assign, readonly) BOOL *array; @property (nonatomic, assign, readonly) unsigned int length; - (id)initWithLength:(unsigned int)length; +- (id)initWithLength:(unsigned int)length values:(int)value1, ...; @end diff --git a/ZXingObjC/common/ZXBoolArray.m b/ZXingObjC/common/ZXBoolArray.m index 9639f879c..b740a4c16 100644 --- a/ZXingObjC/common/ZXBoolArray.m +++ b/ZXingObjC/common/ZXBoolArray.m @@ -27,6 +27,21 @@ - (id)initWithLength:(unsigned int)length { return self; } +- (id)initWithLength:(unsigned int)length values:(int)value1, ... { + if ((self = [self initWithLength:length]) && (length > 0)) { + va_list args; + va_start(args, value1); + _array[0] = value1 == 1 ? true : false; + for (int i = 1; i < length; i++) { + int value = va_arg(args, int); + _array[i] = value == 1 ? true : false; + } + va_end(args); + } + + return self; +} + - (void)dealloc { if (_array) { free(_array); diff --git a/ZXingObjC/common/ZXByteArray.h b/ZXingObjC/common/ZXByteArray.h index e837cc60f..2f12b8363 100644 --- a/ZXingObjC/common/ZXByteArray.h +++ b/ZXingObjC/common/ZXByteArray.h @@ -14,12 +14,16 @@ * limitations under the License. */ +#import + @interface ZXByteArray : NSObject @property (nonatomic, assign, readonly) int8_t *array; @property (nonatomic, assign, readonly) unsigned int length; - (id)initWithLength:(unsigned int)length; -- (id)initWithBytes:(int8_t)byte1, ...; +- (id)initWithArray:(int8_t *)array length:(unsigned int)length; +- (id)initWithBytes:(int)byte1, ...; +- (id)initWithLength:(unsigned int)length bytes:(int)byte1, ...; @end diff --git a/ZXingObjC/common/ZXByteArray.m b/ZXingObjC/common/ZXByteArray.m index 8c4ca5880..f7d544db2 100644 --- a/ZXingObjC/common/ZXByteArray.m +++ b/ZXingObjC/common/ZXByteArray.m @@ -31,7 +31,30 @@ - (id)initWithLength:(unsigned int)length { return self; } -- (id)initWithBytes:(int8_t)byte1, ... { +- (id)initWithArray:(int8_t *)array length:(unsigned int)length { + if (self = [super init]) { + _array = array; + _length = length; + } + return self; +} + +- (id)initWithLength:(unsigned int)length bytes:(int)byte1, ... { + if ((self = [self initWithLength:length]) && (length > 0)) { + va_list args; + va_start(args, byte1); + _array[0] = (int8_t) byte1; + for (int i = 1; i < length; i++) { + int byte = va_arg(args, int); + _array[i] = (int8_t) byte; + } + va_end(args); + } + + return self; +} + +- (id)initWithBytes:(int)byte1, ... { va_list args; va_start(args, byte1); unsigned int length = 0; @@ -63,7 +86,7 @@ - (NSString *)description { NSMutableString *s = [NSMutableString stringWithFormat:@"length=%u, array=(", self.length]; for (int i = 0; i < self.length; i++) { - [s appendFormat:@"%d", self.array[i]]; + [s appendFormat:@"%hhx", self.array[i]]; if (i < self.length - 1) { [s appendString:@", "]; } diff --git a/ZXingObjC/common/ZXCharacterSetECI.h b/ZXingObjC/common/ZXCharacterSetECI.h index 00326753d..49ec26f5c 100644 --- a/ZXingObjC/common/ZXCharacterSetECI.h +++ b/ZXingObjC/common/ZXCharacterSetECI.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * Encapsulates a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1 * of ISO 18004. diff --git a/examples/QrCodeTest/AppDelegate.h b/ZXingObjC/common/ZXDecimal.h similarity index 51% rename from examples/QrCodeTest/AppDelegate.h rename to ZXingObjC/common/ZXDecimal.h index 97fda8db3..ce483c4e4 100644 --- a/examples/QrCodeTest/AppDelegate.h +++ b/ZXingObjC/common/ZXDecimal.h @@ -14,13 +14,24 @@ * limitations under the License. */ -#import +#import -@class ViewController; +/** + * Drop-in replacement for `NSDecimalNumber`. + * @see ZXPDF417DecodedBitStreamParser.m#L696 + */ +@interface ZXDecimal : NSObject + +@property (nonatomic, strong, readonly) NSString *value; + +- (id)initWithValue:(NSString *)value; -@interface AppDelegate : UIResponder ++ (ZXDecimal *)zero; ++ (ZXDecimal *)decimalWithDecimalNumber:(NSDecimalNumber *)decimalNumber; ++ (ZXDecimal *)decimalWithString:(NSString *)string; ++ (ZXDecimal *)decimalWithInt:(int)integer; -@property (nonatomic, strong) UIWindow *window; -@property (nonatomic, strong) ViewController *viewController; +- (ZXDecimal *)decimalByMultiplyingBy:(ZXDecimal *)number; +- (ZXDecimal *)decimalByAdding:(ZXDecimal *)number; @end diff --git a/ZXingObjC/common/ZXDecimal.m b/ZXingObjC/common/ZXDecimal.m new file mode 100644 index 000000000..3e350e394 --- /dev/null +++ b/ZXingObjC/common/ZXDecimal.m @@ -0,0 +1,211 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ZXDecimal.h" + +@interface ZXDecimal () + +@property (nonatomic, strong) NSString *value; + +@end + +@implementation ZXDecimal + +- (id)initWithValue:(NSString *)value { + if (self = [super init]) { + self.value = value; + } + return self; +} + ++ (ZXDecimal *)zero { + return [[self alloc] initWithValue:@"0"]; +} + ++ (ZXDecimal *)decimalWithInt:(int)integer { + return [[self alloc] initWithValue:[NSString stringWithFormat:@"%d", integer]]; +} + ++ (ZXDecimal *)decimalWithString:(NSString *)string { + if (string.length == 0) { + return [[self alloc] initWithValue:@"0"]; + } else { + return [[self alloc] initWithValue:string]; + } +} + ++ (ZXDecimal *)decimalWithDecimalNumber:(NSDecimalNumber *)decimalNumber { + return [self decimalWithString:[decimalNumber stringValue]]; +} + +- (BOOL)isEqual:(id)object { + if (object == self) + return YES; + if (!object || ![object isKindOfClass:[self class]]) + return NO; + ZXDecimal *other = (ZXDecimal *)object; + return [other.value isEqual:self.value]; +} + +// @see https://stackoverflow.com/a/22610446/5173688 +- (NSString *)reversedString:(NSString *)string { + NSUInteger length = [string length]; + if (length < 2) { + return string; + } + + NSStringEncoding encoding = NSHostByteOrder() == NS_BigEndian ? NSUTF32BigEndianStringEncoding : NSUTF32LittleEndianStringEncoding; + NSUInteger utf32ByteCount = [string lengthOfBytesUsingEncoding:encoding]; + uint32_t *characters = malloc(utf32ByteCount); + + [string getBytes:characters maxLength:utf32ByteCount usedLength:NULL encoding:encoding options:0 range:NSMakeRange(0, length) remainingRange:NULL]; + + NSUInteger utf32Length = utf32ByteCount / sizeof(uint32_t); + NSUInteger halfwayPoint = utf32Length / 2; + for (NSUInteger i = 0; i < halfwayPoint; ++i) { + uint32_t character = characters[utf32Length - i - 1]; + characters[utf32Length - i - 1] = characters[i]; + characters[i] = character; + } + + return [[NSString alloc] initWithBytesNoCopy:characters length:utf32ByteCount encoding:encoding freeWhenDone:YES]; +} + +- (int8_t *)intArrayFromString:(NSString *)string { + NSUInteger length = [string length]; + if (length < 2) { + int8_t *result = malloc(length * sizeof(int8_t)); + result[0] = [string intValue]; + return result; + } + + NSStringEncoding encoding = NSHostByteOrder() == NS_BigEndian ? NSUTF32BigEndianStringEncoding : NSUTF32LittleEndianStringEncoding; + NSUInteger utf32ByteCount = [string lengthOfBytesUsingEncoding:encoding]; + uint32_t *characters = malloc(utf32ByteCount); + + [string getBytes:characters maxLength:utf32ByteCount usedLength:NULL encoding:encoding options:0 range:NSMakeRange(0, length) remainingRange:NULL]; + + int8_t *result = malloc(length * sizeof(int8_t)); + + NSUInteger utf32Length = utf32ByteCount / sizeof(uint32_t); + for (NSUInteger i = 0; i < utf32Length; ++i) { + result[i] = (int) characters[i] - '0'; + } + + return result; +} + +- (ZXDecimal *)decimalByMultiplyingBy:(ZXDecimal *)number { + int leftLength = (int) _value.length; + int rightLength = (int) number.value.length; + int8_t *left = [self intArrayFromString:[self reversedString:_value]]; + int8_t *right = [self intArrayFromString:[self reversedString:number.value]]; + + int length = (int) _value.length + (int) number.value.length; + int8_t *result = calloc(length, sizeof(int8_t)); + + for (int leftIndex = 0; leftIndex < leftLength; leftIndex++) { + for (int rightIndex = 0; rightIndex < rightLength; rightIndex++) { + int resultIndex = leftIndex + rightIndex; + + int leftValue = left[leftIndex]; + int rightValue = right[rightIndex]; + + result[resultIndex] = leftValue * rightValue + (resultIndex >= length ? 0 : result[resultIndex]); + + if (result[resultIndex] > 9) { + result[resultIndex + 1] = (result[resultIndex] / 10) + (resultIndex + 1 >= length ? 0 : result[resultIndex + 1]); + result[resultIndex] -= (result[resultIndex] / 10) * 10; + } + } + } + + free(left); + free(right); + + NSMutableString *retVal = [NSMutableString string]; + for (int i = 0; i < length; i++) { + if (result[i] == 0) { + [retVal appendString:@"0"]; + } else { + [retVal appendFormat:@"%d", result[i]]; + } + } + + retVal = [[self reversedString:retVal] mutableCopy]; + // remove '0' prefixes + while (retVal.length > 0 && [[retVal substringWithRange:NSMakeRange(0, 1)] isEqualToString:@"0"]) { + retVal = [[retVal substringFromIndex:1] mutableCopy]; + } + + free(result); + + if (retVal.length == 0) { + return [ZXDecimal decimalWithString:@"0"]; + } + return [ZXDecimal decimalWithString:retVal]; +} + +- (ZXDecimal *)decimalByAdding:(ZXDecimal *)number { + int leftLength = (int) _value.length; + int rightLength = (int) number.value.length; + + int8_t *left = [self intArrayFromString:[self reversedString:_value]]; + int8_t *right = [self intArrayFromString:[self reversedString:number.value]]; + + int length = rightLength + 1; + if (leftLength > rightLength) { + length = leftLength + 1; + } + + int8_t *result = calloc(length, sizeof(int8_t)); + + for (int i = 0; i < length - 1; i++) { + int leftValue = leftLength > i ? left[i] : 0; + int rightValue = rightLength > i ? right[i] : 0; + + int add = leftValue + rightValue + result[i]; + if (add >= 10) { + result[i] = (add % 10); + result[i + 1] = 1; + } else { + result[i] = add; + } + } + + free(left); + free(right); + + NSMutableString *retVal = [NSMutableString string]; + for (int i = 0; i < length; i++) { + [retVal appendFormat:@"%d", result[i]]; + } + + retVal = [[self reversedString:retVal] mutableCopy]; + // remove '0' prefixes + while (retVal.length > 0 && [[retVal substringWithRange:NSMakeRange(0, 1)] isEqualToString:@"0"]) { + retVal = [[retVal substringFromIndex:1] mutableCopy]; + } + + free(result); + + if (retVal.length == 0) { + return [ZXDecimal decimalWithString:@"0"]; + } + return [ZXDecimal decimalWithString:retVal]; +} + +@end diff --git a/ZXingObjC/common/ZXDecoderResult.h b/ZXingObjC/common/ZXDecoderResult.h index 4d92c3aae..fc70038b3 100644 --- a/ZXingObjC/common/ZXDecoderResult.h +++ b/ZXingObjC/common/ZXDecoderResult.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import "ZXByteArray.h" + @class ZXByteArray; /** @@ -24,6 +26,7 @@ @interface ZXDecoderResult : NSObject @property (nonatomic, strong, readonly) ZXByteArray *rawBytes; +@property (nonatomic) int numBits; @property (nonatomic, copy, readonly) NSString *text; @property (nonatomic, strong, readonly) NSMutableArray *byteSegments; @property (nonatomic, copy, readonly) NSString *ecLevel; diff --git a/ZXingObjC/common/ZXDecoderResult.m b/ZXingObjC/common/ZXDecoderResult.m index 3e605569f..69520257b 100644 --- a/ZXingObjC/common/ZXDecoderResult.m +++ b/ZXingObjC/common/ZXDecoderResult.m @@ -28,6 +28,7 @@ - (id)initWithRawBytes:(ZXByteArray *)rawBytes text:(NSString *)text saSequence:(int)saSequence saParity:(int)saParity { if (self = [super init]) { _rawBytes = rawBytes; + _numBits = rawBytes == nil ? 0 : 8 * rawBytes.length; _text = text; _byteSegments = byteSegments; _ecLevel = ecLevel; diff --git a/ZXingObjC/common/ZXGlobalHistogramBinarizer.m b/ZXingObjC/common/ZXGlobalHistogramBinarizer.m index 4dc07f8ab..f48fe7c0a 100644 --- a/ZXingObjC/common/ZXGlobalHistogramBinarizer.m +++ b/ZXingObjC/common/ZXGlobalHistogramBinarizer.m @@ -57,8 +57,7 @@ - (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error { ZXByteArray *localLuminances = [source rowAtY:y row:self.luminances]; ZXIntArray *localBuckets = self.buckets; for (int x = 0; x < width; x++) { - int pixel = localLuminances.array[x] & 0xff; - localBuckets.array[pixel >> ZX_LUMINANCE_SHIFT]++; + localBuckets.array[(localLuminances.array[x] & 0xff) >> ZX_LUMINANCE_SHIFT]++; } int blackPoint = [self estimateBlackPoint:localBuckets]; if (blackPoint == -1) { @@ -66,17 +65,25 @@ - (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error { return nil; } - int left = localLuminances.array[0] & 0xff; - int center = localLuminances.array[1] & 0xff; - for (int x = 1; x < width - 1; x++) { - int right = localLuminances.array[x + 1] & 0xff; - // A simple -1 4 -1 box filter with a weight of 2. - int luminance = ((center * 4) - left - right) >> 1; - if (luminance < blackPoint) { - [row set:x]; + if (width < 3) { + // Special case for very small images + for (int x = 0; x < width; x++) { + if ((localLuminances.array[x] & 0xff) < blackPoint) { + [row set:x]; + } + } + } else { + int left = localLuminances.array[0] & 0xff; + int center = localLuminances.array[1] & 0xff; + for (int x = 1; x < width - 1; x++) { + int right = localLuminances.array[x + 1] & 0xff; + // A simple -1 4 -1 box filter with a weight of 2. + if (((center * 4) - left - right) / 2 < blackPoint) { + [row set:x]; + } + left = center; + center = right; } - left = center; - center = right; } return row; diff --git a/ZXingObjC/common/ZXGridSampler.h b/ZXingObjC/common/ZXGridSampler.h index 2ccfd1b95..8e333dd4e 100644 --- a/ZXingObjC/common/ZXGridSampler.h +++ b/ZXingObjC/common/ZXGridSampler.h @@ -24,7 +24,7 @@ * Imaging library, but which may not be available in other environments such as J2ME, and vice * versa. * - * The implementation used can be controlled by calling {@link #setGridSampler(GridSampler)} + * The implementation used can be controlled by calling `setGridSampler:` * with an instance of a class which implements this interface. */ @interface ZXGridSampler : NSObject @@ -46,10 +46,29 @@ + (ZXGridSampler *)instance; /** - * Samples an image for a rectangular matrix of bits of the given dimension. + * Samples an image for a rectangular matrix of bits of the given dimension. The sampling + * transformation is determined by the coordinates of 4 points, in the original and transformed + * image space. + * * @param image image to sample * @param dimensionX width of ZXBitMatrix to sample from image * @param dimensionY height of ZXBitMatrix to sample from image + * @param p1ToX point 1 preimage X + * @param p1ToY point 1 preimage Y + * @param p2ToX point 2 preimage X + * @param p2ToY point 2 preimage Y + * @param p3ToX point 3 preimage X + * @param p3ToY point 3 preimage Y + * @param p4ToX point 4 preimage X + * @param p4ToY point 4 preimage Y + * @param p1FromX point 1 image X + * @param p1FromY point 1 image Y + * @param p2FromX point 2 image X + * @param p2FromY point 2 image Y + * @param p3FromX point 3 image X + * @param p3FromY point 3 image Y + * @param p4FromX point 4 image X + * @param p4FromY point 4 image Y * @return ZXBitMatrix representing a grid of points sampled from the image within a region * defined by the "from" parameters or nil if image can't be sampled, for example, if the transformation defined * by the given points is invalid or results in sampling outside the image boundaries diff --git a/ZXingObjC/common/ZXHybridBinarizer.m b/ZXingObjC/common/ZXHybridBinarizer.m index 5742cb0ac..fe9ec3c9a 100644 --- a/ZXingObjC/common/ZXHybridBinarizer.m +++ b/ZXingObjC/common/ZXHybridBinarizer.m @@ -17,6 +17,7 @@ #import "ZXByteArray.h" #import "ZXHybridBinarizer.h" #import "ZXIntArray.h" +#import "ZXErrors.h" // This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels. // So this is the smallest dimension in each axis we can accept. @@ -46,6 +47,11 @@ - (ZXBitMatrix *)blackMatrixWithError:(NSError **)error { ZXLuminanceSource *source = [self luminanceSource]; int width = source.width; int height = source.height; + if (width <= 0 || height <= 0) { + NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Source is empty or misbehaving."}; + if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:userInfo]; + return nil; + } if (width >= ZX_MINIMUM_DIMENSION && height >= ZX_MINIMUM_DIMENSION) { ZXByteArray *luminances = source.matrix; int subWidth = width >> ZX_BLOCK_SIZE_POWER; @@ -89,20 +95,20 @@ - (void)calculateThresholdForBlock:(int8_t *)luminances height:(int)height blackPoints:(int **)blackPoints matrix:(ZXBitMatrix *)matrix { + int maxYOffset = height - ZX_BLOCK_SIZE; + int maxXOffset = width - ZX_BLOCK_SIZE; for (int y = 0; y < subHeight; y++) { int yoffset = y << ZX_BLOCK_SIZE_POWER; - int maxYOffset = height - ZX_BLOCK_SIZE; if (yoffset > maxYOffset) { yoffset = maxYOffset; } + int top = [self cap:y min:2 max:subHeight - 3]; for (int x = 0; x < subWidth; x++) { int xoffset = x << ZX_BLOCK_SIZE_POWER; - int maxXOffset = width - ZX_BLOCK_SIZE; if (xoffset > maxXOffset) { xoffset = maxXOffset; } int left = [self cap:x min:2 max:subWidth - 3]; - int top = [self cap:y min:2 max:subHeight - 3]; int sum = 0; for (int z = -2; z <= 2; z++) { int *blackRow = blackPoints[top + z]; @@ -148,17 +154,17 @@ - (int **)calculateBlackPoints:(int8_t *)luminances width:(int)width height:(int)height { int **blackPoints = (int **)malloc(subHeight * sizeof(int *)); + int maxYOffset = height - ZX_BLOCK_SIZE; + int maxXOffset = width - ZX_BLOCK_SIZE; for (int y = 0; y < subHeight; y++) { blackPoints[y] = (int *)malloc(subWidth * sizeof(int)); int yoffset = y << ZX_BLOCK_SIZE_POWER; - int maxYOffset = height - ZX_BLOCK_SIZE; if (yoffset > maxYOffset) { yoffset = maxYOffset; } for (int x = 0; x < subWidth; x++) { int xoffset = x << ZX_BLOCK_SIZE_POWER; - int maxXOffset = width - ZX_BLOCK_SIZE; if (xoffset > maxXOffset) { xoffset = maxXOffset; } diff --git a/ZXingObjC/common/ZXIntArray.h b/ZXingObjC/common/ZXIntArray.h index 0b45e6217..f0dbf1028 100644 --- a/ZXingObjC/common/ZXIntArray.h +++ b/ZXingObjC/common/ZXIntArray.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @interface ZXIntArray : NSObject @property (nonatomic, assign, readonly) int32_t *array; diff --git a/ZXingObjC/common/ZXIntArray.m b/ZXingObjC/common/ZXIntArray.m index 40221d1fd..1caa81969 100644 --- a/ZXingObjC/common/ZXIntArray.m +++ b/ZXingObjC/common/ZXIntArray.m @@ -53,6 +53,25 @@ - (id)initWithInts:(int32_t)int1, ... { return self; } +- (BOOL)isEqual:(id)o { + if (![o isKindOfClass:[self class]]) { + return NO; + } + ZXIntArray *other = (ZXIntArray *) o; + if (other == self) { + return YES; + } + if (other.length != self.length) { + return NO; + } + for (int i = 0; i < self.length; i++) { + if (other.array[i] != self.array[i]) { + return NO; + } + } + return YES; +} + - (id)copyWithZone:(NSZone *)zone { ZXIntArray *copy = [[ZXIntArray allocWithZone:zone] initWithLength:self.length]; memcpy(copy.array, self.array, self.length * sizeof(int32_t)); diff --git a/ZXingObjC/common/ZXPerspectiveTransform.h b/ZXingObjC/common/ZXPerspectiveTransform.h index ab8cceb19..c2b0cf318 100644 --- a/ZXingObjC/common/ZXPerspectiveTransform.h +++ b/ZXingObjC/common/ZXPerspectiveTransform.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * This class implements a perspective transform in two dimensions. Given four source and four * destination points, it will compute the transformation implied between them. The code is based diff --git a/ZXingObjC/common/ZXPerspectiveTransform.m b/ZXingObjC/common/ZXPerspectiveTransform.m index 442b5c5c5..cfe64f362 100644 --- a/ZXingObjC/common/ZXPerspectiveTransform.m +++ b/ZXingObjC/common/ZXPerspectiveTransform.m @@ -65,9 +65,6 @@ - (void)transformPoints:(float *)points pointsLen:(int)pointsLen { } } -/** - * Convenience method, not optimized for performance. - */ - (void)transformPoints:(float *)xValues yValues:(float *)yValues pointsLen:(int)pointsLen { int n = pointsLen; for (int i = 0; i < n; i ++) { diff --git a/ZXingObjC/common/detector/ZXMathUtils.h b/ZXingObjC/common/detector/ZXMathUtils.h index cd38da4a2..350733ecc 100644 --- a/ZXingObjC/common/detector/ZXMathUtils.h +++ b/ZXingObjC/common/detector/ZXMathUtils.h @@ -14,10 +14,21 @@ * limitations under the License. */ +#import + @interface ZXMathUtils : NSObject +/** + * Ends up being a bit faster than round(). This merely rounds its + * argument to the nearest int, where x.5 rounds up to x+1. + * + * @param d real value to round + * @return nearest int + */ + (int)round:(float)d; + + (float)distance:(float)aX aY:(float)aY bX:(float)bX bY:(float)bY; + + (float)distanceInt:(int)aX aY:(int)aY bX:(int)bX bY:(int)bY; @end diff --git a/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m b/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m index 8549d2761..51c914770 100644 --- a/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m +++ b/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m @@ -103,7 +103,7 @@ - (NSArray *)detectWithError:(NSError **)error { * @param bottom maximum value of y * @param maxWhiteRun maximum run of white pixels that can still be considered to be within * the barcode - * @return a {@link com.google.zxing.ResultPoint} encapsulating the corner that was found + * @return a ZXResultPoint encapsulating the corner that was found * or nil if such a point cannot be found */ - (ZXResultPoint *)findCornerFromCenter:(int)centerX deltaX:(int)deltaX left:(int)left right:(int)right centerY:(int)centerY deltaY:(int)deltaY top:(int)top bottom:(int)bottom maxWhiteRun:(int)maxWhiteRun { diff --git a/ZXingObjC/common/detector/ZXWhiteRectangleDetector.h b/ZXingObjC/common/detector/ZXWhiteRectangleDetector.h index 09dbb461e..adb84088d 100644 --- a/ZXingObjC/common/detector/ZXWhiteRectangleDetector.h +++ b/ZXingObjC/common/detector/ZXWhiteRectangleDetector.h @@ -26,6 +26,14 @@ @interface ZXWhiteRectangleDetector : NSObject - (id)initWithImage:(ZXBitMatrix *)image error:(NSError **)error; + +/** + * @param image barcode image to find a rectangle in + * @param initSize initial size of search area around center + * @param x x position of search center + * @param y y position of search center + * @return nil if image is too small to accommodate initSize + */ - (id)initWithImage:(ZXBitMatrix *)image initSize:(int)initSize x:(int)x y:(int)y error:(NSError **)error; /** @@ -33,7 +41,7 @@ * starts around the center of the image, increases the size of the candidate * region until it finds a white rectangular region. * - * @return {@link ResultPoint}[] describing the corners of the rectangular + * @return NSArray of `ZXResultPoint`s describing the corners of the rectangular * region. The first and last points are opposed on the diagonal, as * are the second and third. The first point will be the topmost * point and the last, the bottommost. The second point will be diff --git a/ZXingObjC/common/reedsolomon/ZXGenericGF.h b/ZXingObjC/common/reedsolomon/ZXGenericGF.h index f5d0b6292..09c21aa31 100644 --- a/ZXingObjC/common/reedsolomon/ZXGenericGF.h +++ b/ZXingObjC/common/reedsolomon/ZXGenericGF.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXGenericGFPoly; /** diff --git a/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h b/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h index feae94afb..764bb08ed 100644 --- a/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h +++ b/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h @@ -28,7 +28,7 @@ @property (nonatomic, strong, readonly) ZXIntArray *coefficients; /** - * @param field the {@link GenericGF} instance representing the field to use + * @param field the ZXGenericGF instance representing the field to use * to perform computations * @param coefficients coefficients as ints representing elements of GF(size), arranged * from most significant (highest-power term) coefficient to least significant diff --git a/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m b/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m index 5df43dbbb..a3d612807 100644 --- a/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m +++ b/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m @@ -206,12 +206,19 @@ - (NSArray *)divide:(ZXGenericGFPoly *)other { } - (NSString *)description { + if (self.zero) { + return @"0"; + } NSMutableString *result = [NSMutableString stringWithCapacity:8 * [self degree]]; for (int degree = [self degree]; degree >= 0; degree--) { int coefficient = [self coefficient:degree]; if (coefficient != 0) { if (coefficient < 0) { - [result appendString:@" - "]; + if (degree == [self degree]) { + [result appendString:@"-"]; + } else { + [result appendString:@" - "]; + } coefficient = -coefficient; } else { if ([result length] > 0) { diff --git a/ZXingObjC/core/ZXBinarizer.h b/ZXingObjC/core/ZXBinarizer.h index c6fe676b6..108f0d513 100644 --- a/ZXingObjC/core/ZXBinarizer.h +++ b/ZXingObjC/core/ZXBinarizer.h @@ -42,10 +42,10 @@ * and passed in with each call for performance. However it is legal to keep more than one row * at a time if needed. * - * @param y The row to fetch, 0 <= y < bitmap height. + * @param y The row to fetch, which must be in [0, bitmap height) * @param row An optional preallocated array. If null or too small, it will be ignored. * If used, the Binarizer will call ZXBitArray clear. Always use the returned object. - * @return The array of bits for this row (true means black). + * @return The array of bits for this row (true means black) or nil if row can't be binarized. */ - (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error; @@ -55,7 +55,8 @@ * may not apply sharpening. Therefore, a row from this matrix may not be identical to one * fetched using getBlackRow(), so don't mix and match between them. * - * @return The 2D array of bits for the image (true means black). + * @return The 2D array of bits for the image (true means black) or nil if image can't be binarized + * to make a matrix. */ - (ZXBitMatrix *)blackMatrixWithError:(NSError **)error; diff --git a/ZXingObjC/core/ZXBinarizer.m b/ZXingObjC/core/ZXBinarizer.m index d87e551d2..7d0e52aa4 100644 --- a/ZXingObjC/core/ZXBinarizer.m +++ b/ZXingObjC/core/ZXBinarizer.m @@ -16,7 +16,7 @@ #import "ZXBinarizer.h" -#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR +#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR || TARGET_OS_MACCATALYST #import #define ZXBlack [[UIColor blackColor] CGColor] #define ZXWhite [[UIColor whiteColor] CGColor] diff --git a/ZXingObjC/core/ZXBinaryBitmap.h b/ZXingObjC/core/ZXBinaryBitmap.h index d584e1a8b..4e64e83d2 100644 --- a/ZXingObjC/core/ZXBinaryBitmap.h +++ b/ZXingObjC/core/ZXBinaryBitmap.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBinarizer, ZXBitArray, ZXBitMatrix; /** @@ -51,10 +53,10 @@ * cached data. Callers should assume this method is expensive and call it as seldom as possible. * This method is intended for decoding 1D barcodes and may choose to apply sharpening. * - * @param y The row to fetch, 0 <= y < bitmap height. + * @param y The row to fetch, which must be in [0, bitmap height) * @param row An optional preallocated array. If null or too small, it will be ignored. * If used, the Binarizer will call BitArray.clear(). Always use the returned object. - * @return The array of bits for this row (true means black). + * @return The array of bits for this row (true means black) or nil if row can't be binarized. */ - (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error; @@ -64,7 +66,8 @@ * may not apply sharpening. Therefore, a row from this matrix may not be identical to one * fetched using getBlackRow(), so don't mix and match between them. * - * @return The 2D array of bits for the image (true means black). + * @return The 2D array of bits for the image (true means black) or nil if image can't be binarized + * to make a matrix. */ - (ZXBitMatrix *)blackMatrixWithError:(NSError **)error; @@ -72,8 +75,8 @@ * Returns a new object with cropped image data. Implementations may keep a reference to the * original data rather than a copy. Only callable if isCropSupported() is true. * - * @param left The left coordinate, 0 <= left < getWidth(). - * @param top The top coordinate, 0 <= top <= getHeight(). + * @param left The left coordinate, which must be in [0,getWidth()) + * @param top The top coordinate, which must be in [0,getHeight()) * @param width The width of the rectangle to crop. * @param height The height of the rectangle to crop. * @return A cropped version of this object. @@ -82,7 +85,7 @@ /** * Returns a new object with rotated image data by 90 degrees counterclockwise. - * Only callable if {@link #isRotateSupported()} is true. + * Only callable if `rotateSupported` is true. * * @return A rotated version of this object. */ @@ -90,7 +93,7 @@ /** * Returns a new object with rotated image data by 45 degrees counterclockwise. - * Only callable if {@link #isRotateSupported()} is true. + * Only callable if `rotateSupported` is true. * * @return A rotated version of this object. */ diff --git a/ZXingObjC/core/ZXByteMatrix.h b/ZXingObjC/core/ZXByteMatrix.h index 84b820daf..e8f620c07 100644 --- a/ZXingObjC/core/ZXByteMatrix.h +++ b/ZXingObjC/core/ZXByteMatrix.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @interface ZXByteMatrix : NSObject @property (nonatomic, assign, readonly) int8_t **array; diff --git a/ZXingObjC/core/ZXDecodeHints.h b/ZXingObjC/core/ZXDecodeHints.h index 37fb2c6f2..c6ab66c40 100644 --- a/ZXingObjC/core/ZXDecodeHints.h +++ b/ZXingObjC/core/ZXDecodeHints.h @@ -14,6 +14,7 @@ * limitations under the License. */ +#import #import "ZXBarcodeFormat.h" @protocol ZXResultPointCallback; @@ -89,9 +90,12 @@ /** * Image is known to be of one of a few possible formats. */ + +@property (nonatomic, strong) NSDictionary *substitutions; + - (void)addPossibleFormat:(ZXBarcodeFormat)format; - (BOOL)containsFormat:(ZXBarcodeFormat)format; - (int)numberOfPossibleFormats; - (void)removePossibleFormat:(ZXBarcodeFormat)format; -@end \ No newline at end of file +@end diff --git a/ZXingObjC/core/ZXDecodeHints.m b/ZXingObjC/core/ZXDecodeHints.m index 2c1f5cab8..c96becade 100644 --- a/ZXingObjC/core/ZXDecodeHints.m +++ b/ZXingObjC/core/ZXDecodeHints.m @@ -59,11 +59,11 @@ - (id)copyWithZone:(NSZone *)zone { } - (void)addPossibleFormat:(ZXBarcodeFormat)format { - [self.barcodeFormats addObject:[NSNumber numberWithInt:format]]; + [self.barcodeFormats addObject:@(format)]; } - (BOOL)containsFormat:(ZXBarcodeFormat)format { - return [self.barcodeFormats containsObject:[NSNumber numberWithInt:format]]; + return [self.barcodeFormats containsObject:@(format)]; } - (int)numberOfPossibleFormats { @@ -71,7 +71,7 @@ - (int)numberOfPossibleFormats { } - (void)removePossibleFormat:(ZXBarcodeFormat)format { - [self.barcodeFormats removeObject:[NSNumber numberWithInt:format]]; + [self.barcodeFormats removeObject:@(format)]; } -@end \ No newline at end of file +@end diff --git a/ZXingObjC/core/ZXDimension.h b/ZXingObjC/core/ZXDimension.h index 809584707..aadc4f66c 100644 --- a/ZXingObjC/core/ZXDimension.h +++ b/ZXingObjC/core/ZXDimension.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * Simply encapsulates a width and height. */ diff --git a/ZXingObjC/core/ZXEncodeHints.h b/ZXingObjC/core/ZXEncodeHints.h index b3571eb81..64468a7b5 100644 --- a/ZXingObjC/core/ZXEncodeHints.h +++ b/ZXingObjC/core/ZXEncodeHints.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * Enumeration for DataMatrix symbol shape hint. It can be used to force square or rectangular * symbols. @@ -72,6 +74,12 @@ typedef enum { */ @property (nonatomic, strong) ZXQRCodeErrorCorrectionLevel *errorCorrectionLevel; +/** + * Specifies what degree of error correction to use, for example in PDF417 Codes. + * For PDF417 valid values are 0 to 8. + */ +@property (nonatomic, strong) NSNumber *errorCorrectionLevelPDF417; + /** * Specifies what percent of error correction to use. * For Aztec it represents the minimal percentage of error correction words. @@ -86,6 +94,11 @@ typedef enum { */ @property (nonatomic, strong) NSNumber *margin; +/** + * Specifies if long lines should be drawn, only applies to {`ean13`, `ean8`}. + */ +@property (nonatomic, assign) BOOL showLongLines; + /** * Specifies whether to use compact mode for PDF417. */ @@ -109,4 +122,15 @@ typedef enum { */ @property (nonatomic, strong) NSNumber *aztecLayers; +/** + * Specifies the exact version of QR code to be encoded. An integer. If the data specified + * cannot fit within the required version, nil we be returned. + */ +@property (nonatomic, strong) NSNumber *qrVersion; + +/** + * Specifies whether the data should be encoded to the GS1 standard. + */ +@property (nonatomic, assign) BOOL gs1Format; + @end diff --git a/ZXingObjC/core/ZXErrors.h b/ZXingObjC/core/ZXErrors.h index 20e6e882f..46efdd375 100644 --- a/ZXingObjC/core/ZXErrors.h +++ b/ZXingObjC/core/ZXErrors.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + #define ZXErrorDomain @"ZXErrorDomain" enum { diff --git a/ZXingObjC/core/ZXErrors.m b/ZXingObjC/core/ZXErrors.m index 08730cf28..aa5715f7b 100644 --- a/ZXingObjC/core/ZXErrors.m +++ b/ZXingObjC/core/ZXErrors.m @@ -16,19 +16,19 @@ #import "ZXErrors.h" -NSError *ZXChecksumErrorInstance() { +NSError *ZXChecksumErrorInstance(void) { NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"This barcode failed its checksum"}; return [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXChecksumError userInfo:userInfo]; } -NSError *ZXFormatErrorInstance() { +NSError *ZXFormatErrorInstance(void) { NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"This barcode does not confirm to the format's rules"}; return [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXFormatError userInfo:userInfo]; } -NSError *ZXNotFoundErrorInstance() { +NSError *ZXNotFoundErrorInstance(void) { NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"A barcode was not found in this image"}; return [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:userInfo]; diff --git a/ZXingObjC/core/ZXLuminanceSource.h b/ZXingObjC/core/ZXLuminanceSource.h index d279afdc6..c08dbfeef 100644 --- a/ZXingObjC/core/ZXLuminanceSource.h +++ b/ZXingObjC/core/ZXLuminanceSource.h @@ -54,7 +54,7 @@ * to only fetch this row rather than the whole image, since no 2D Readers may be installed and * getMatrix() may never be called. * - * @param y The row to fetch, 0 <= y < getHeight(). + * @param y The row to fetch, which must be in [0,getHeight()) * @param row An optional preallocated array. If null or too small, it will be ignored. * Always use the returned object, and ignore the .length of the array. * @return An array containing the luminance data. @@ -75,8 +75,8 @@ * Returns a new object with cropped image data. Implementations may keep a reference to the * original data rather than a copy. Only callable if isCropSupported() is true. * - * @param left The left coordinate, 0 <= left < getWidth(). - * @param top The top coordinate, 0 <= top <= getHeight(). + * @param left The left coordinate, which must be in [0,getWidth()) + * @param top The top coordinate, which must be in [0,getHeight()) * @param width The width of the rectangle to crop. * @param height The height of the rectangle to crop. * @return A cropped version of this object. diff --git a/ZXingObjC/core/ZXRGBLuminanceSource.m b/ZXingObjC/core/ZXRGBLuminanceSource.m index 91aa1979c..18efdc249 100644 --- a/ZXingObjC/core/ZXRGBLuminanceSource.m +++ b/ZXingObjC/core/ZXRGBLuminanceSource.m @@ -38,45 +38,49 @@ - (id)initWithWidth:(int)width height:(int)height pixels:(int *)pixels pixelsLen // In order to measure pure decoding speed, we convert the entire image to a greyscale array // up front, which is the same as the Y channel of the YUVLuminanceSource in the real app. - _luminances = [[ZXByteArray alloc] initWithLength:width * height]; - for (int y = 0; y < height; y++) { - int offset = y * width; - for (int x = 0; x < width; x++) { - int pixel = pixels[offset + x]; - int r = (pixel >> 16) & 0xff; - int g = (pixel >> 8) & 0xff; - int b = pixel & 0xff; - if (r == g && g == b) { - // Image is already greyscale, so pick any channel. - _luminances.array[offset + x] = (int8_t) r; - } else { - // Calculate luminance cheaply, favoring green. - _luminances.array[offset + x] = (int8_t) ((r + g + g + b) / 4); - } - } + int size = width * height; + _luminances = [[ZXByteArray alloc] initWithLength:size]; + for (int offset = 0; offset < size; offset++) { + int pixel = pixels[offset]; + int r = (pixel >> 16) & 0xff; // red + int g2 = (pixel >> 7) & 0x1fe; // 2 * green + int b = pixel & 0xff; // blue + // Calculate green-favouring average cheaply + _luminances.array[offset] = (int8_t) ((r + g2 + b) / 4); } } return self; } -- (id)initWithPixels:(ZXByteArray *)pixels dataWidth:(int)dataWidth dataHeight:(int)dataHeight - left:(int)left top:(int)top width:(int)width height:(int)height { +- (id)initWithPixels:(int8_t *)pixels width:(int)width height:(int)height { if (self = [super initWithWidth:width height:height]) { - if (left + self.width > dataWidth || top + self.height > dataHeight) { - [NSException raise:NSInvalidArgumentException format:@"Crop rectangle does not fit within image data."]; - } - - _luminances = pixels; - _dataWidth = dataWidth; - _dataHeight = dataHeight; - _left = left; - _top = top; + _dataWidth = width; + _dataHeight = height; + _left = 0; + _top = 0; + _luminances = [[ZXByteArray alloc] initWithArray:pixels length:width * height]; } - return self; } +- (id)initWithPixels:(ZXByteArray *)pixels dataWidth:(int)dataWidth dataHeight:(int)dataHeight + left:(int)left top:(int)top width:(int)width height:(int)height { + if (self = [super initWithWidth:width height:height]) { + if (left + self.width > dataWidth || top + self.height > dataHeight) { + [NSException raise:NSInvalidArgumentException format:@"Crop rectangle does not fit within image data."]; + } + + _luminances = pixels; + _dataWidth = dataWidth; + _dataHeight = dataHeight; + _left = left; + _top = top; + } + + return self; +} + - (ZXByteArray *)rowAtY:(int)y row:(ZXByteArray *)row { if (y < 0 || y >= self.height) { [NSException raise:NSInvalidArgumentException format:@"Requested row is outside the image: %d", y]; @@ -106,7 +110,7 @@ - (ZXByteArray *)matrix { // If the width matches the full width of the underlying data, perform a single copy. if (self.width == self.dataWidth) { - memcpy(matrix.array, self.luminances.array + inputOffset, (area - inputOffset) * sizeof(int8_t)); + memcpy(matrix.array, self.luminances.array + inputOffset, area * sizeof(int8_t)); return matrix; } diff --git a/ZXingObjC/core/ZXReader.h b/ZXingObjC/core/ZXReader.h index d1a5d8685..d03137761 100644 --- a/ZXingObjC/core/ZXReader.h +++ b/ZXingObjC/core/ZXReader.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBinaryBitmap, ZXDecodeHints, ZXResult; /** @@ -31,8 +33,10 @@ * Locates and decodes a barcode in some format within an image. * * @param image image of barcode to decode - * @return String which the barcode encodes or nil if - * the barcode cannot be located or decoded for any reason + * @return String which the barcode encodes or nil if: + * - no potential barcode is found + * - a potential barcode is found but does not pass its checksum + * - a potential barcode is found but format is invalid */ - (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error; @@ -41,12 +45,13 @@ * hints, each possibly associated to some data, which may help the implementation decode. * * @param image image of barcode to decode - * @param hints passed as a {@link java.util.Map} from {@link com.google.zxing.DecodeHintType} - * to arbitrary data. The + * @param hints passed as a ZXDecodeHints. The * meaning of the data depends upon the hint type. The implementation may or may not do * anything with these hints. * @return String which the barcode encodes or nil if - * the barcode cannot be located or decoded for any reason + * - no potential barcode is found + * - a potential barcode is found but does not pass its checksum + * - a potential barcode is found but format is invalid */ - (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error; diff --git a/ZXingObjC/core/ZXResult.h b/ZXingObjC/core/ZXResult.h index dab3e97a9..09f9f4592 100644 --- a/ZXingObjC/core/ZXResult.h +++ b/ZXingObjC/core/ZXResult.h @@ -16,6 +16,7 @@ #import "ZXBarcodeFormat.h" #import "ZXResultMetadataType.h" +#import "ZXByteArray.h" @class ZXByteArray; @@ -34,6 +35,11 @@ */ @property (nonatomic, strong, readonly) ZXByteArray *rawBytes; +/** + * @return how many bits of `rawBytes` are valid; typically 8 times its length + */ +@property (nonatomic) int numBits; + /** * @return points related to the barcode in the image. These are typically points * identifying finder patterns or the corners of the barcode. The exact meaning is @@ -57,8 +63,11 @@ - (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format; - (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp; +- (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes numBits:(int)numBits resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp; + (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format; ++ (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes numBits:(int)numBits resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format; + (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp; ++ (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes numBits:(int)numBits resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp; - (void)putMetadata:(ZXResultMetadataType)type value:(id)value; - (void)putAllMetadata:(NSMutableDictionary *)metadata; - (void)addResultPoints:(NSArray *)newPoints; diff --git a/ZXingObjC/core/ZXResult.m b/ZXingObjC/core/ZXResult.m index c2ae7cf20..47144af1e 100644 --- a/ZXingObjC/core/ZXResult.m +++ b/ZXingObjC/core/ZXResult.m @@ -29,10 +29,15 @@ - (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoint return [self initWithText:text rawBytes:rawBytes resultPoints:resultPoints format:format timestamp:CFAbsoluteTimeGetCurrent()]; } +- (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes numBits:(int)numBits resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format { + return [self initWithText:text rawBytes:rawBytes numBits:numBits resultPoints:resultPoints format:format timestamp:CFAbsoluteTimeGetCurrent()]; +} + - (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp { if (self = [super init]) { _text = text; _rawBytes = rawBytes; + _numBits = rawBytes == nil ? 0 : 8 * rawBytes.length; _resultPoints = [resultPoints mutableCopy]; _barcodeFormat = format; _resultMetadata = nil; @@ -42,14 +47,36 @@ - (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoint return self; } +- (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes numBits:(int)numBits resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp { + if (self = [super init]) { + _text = text; + _rawBytes = rawBytes; + _numBits = numBits; + _resultPoints = [resultPoints mutableCopy]; + _barcodeFormat = format; + _resultMetadata = nil; + _timestamp = timestamp; + } + + return self; +} + + (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format { return [[self alloc] initWithText:text rawBytes:rawBytes resultPoints:resultPoints format:format]; } ++ (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes numBits:(int)numBits resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format { + return [[self alloc] initWithText:text rawBytes:rawBytes numBits:numBits resultPoints:resultPoints format:format]; +} + + (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp { return [[self alloc] initWithText:text rawBytes:rawBytes resultPoints:resultPoints format:format timestamp:timestamp]; } ++ (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes numBits:(int)numBits resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp { + return [[self alloc] initWithText:text rawBytes:rawBytes numBits:numBits resultPoints:resultPoints format:format timestamp:timestamp]; +} + - (void)putMetadata:(ZXResultMetadataType)type value:(id)value { if (self.resultMetadata == nil) { self.resultMetadata = [NSMutableDictionary dictionary]; diff --git a/ZXingObjC/core/ZXResultMetadataType.h b/ZXingObjC/core/ZXResultMetadataType.h index e466f0263..f34697146 100644 --- a/ZXingObjC/core/ZXResultMetadataType.h +++ b/ZXingObjC/core/ZXResultMetadataType.h @@ -35,7 +35,7 @@ typedef enum { /** * 2D barcode formats typically encode text, but allow for a sort of 'byte mode' - * which is sometimes used to encode binary data. While {@link Result} makes available + * which is sometimes used to encode binary data. While ZXResult makes available * the complete raw bytes in the barcode for these formats, it does not offer the bytes * from the byte segments alone. * diff --git a/ZXingObjC/core/ZXResultPoint.h b/ZXingObjC/core/ZXResultPoint.h index 8435c07a0..754a8810b 100644 --- a/ZXingObjC/core/ZXResultPoint.h +++ b/ZXingObjC/core/ZXResultPoint.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * Encapsulates a point of interest in an image containing a barcode. Typically, this * would be the location of a finder pattern or the corner of the barcode, for example. @@ -28,12 +30,16 @@ + (id)resultPointWithX:(float)x y:(float)y; /** - * Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and - * BC < AC and the angle between BC and BA is less than 180 degrees. + * Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC + * and BC is less than AC, and the angle between BC and BA is less than 180 degrees. + * + * @param patterns array of three ZXResultPoints to order */ + (void)orderBestPatterns:(NSMutableArray *)patterns; /** + * @param pattern1 first pattern + * @param pattern2 second pattern * @return distance between two points */ + (float)distance:(ZXResultPoint *)pattern1 pattern2:(ZXResultPoint *)pattern2; diff --git a/ZXingObjC/core/ZXWriter.h b/ZXingObjC/core/ZXWriter.h index a46850d29..41d92d538 100644 --- a/ZXingObjC/core/ZXWriter.h +++ b/ZXingObjC/core/ZXWriter.h @@ -14,6 +14,7 @@ * limitations under the License. */ +#import #import "ZXBarcodeFormat.h" @class ZXBitMatrix, ZXEncodeHints; @@ -30,6 +31,8 @@ * @param format The barcode format to generate * @param width The preferred width in pixels * @param height The preferred height in pixels + * @return ZXBitMatrix representing encoded barcode image or nil if contents cannot be encoded + * legally in a format */ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error; @@ -40,6 +43,8 @@ * @param width The preferred width in pixels * @param height The preferred height in pixels * @param hints Additional parameters to supply to the encoder + * @return ZXBitMatrix representing encoded barcode image or nil if contents cannot be encoded + * legally in a format */ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error; diff --git a/ZXingObjC/datamatrix/ZXDataMatrixWriter.m b/ZXingObjC/datamatrix/ZXDataMatrixWriter.m index d47c33c6c..7abfc2712 100644 --- a/ZXingObjC/datamatrix/ZXDataMatrixWriter.m +++ b/ZXingObjC/datamatrix/ZXDataMatrixWriter.m @@ -40,8 +40,7 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt } if (width < 0 || height < 0) { - [NSException raise:NSInvalidArgumentException - format:@"Requested dimensions are too small: %dx%d", width, height]; + [NSException raise:NSInvalidArgumentException format:@"Requested dimensions cannot be negative: %dx%d", width, height]; } // Try to get force shape & min / max size @@ -141,24 +140,36 @@ - (ZXBitMatrix *)encodeLowLevel:(ZXDataMatrixDefaultPlacement *)placement symbol /** * Convert the ZXByteMatrix to ZXBitMatrix. * - * @param input The input matrix. + * @param matrix The input matrix. + * @param width The requested width of the image (in pixels) with the Datamatrix code + * @param height The requested height of the image (in pixels) with the Datamatrix code * @return The output matrix. */ -- (ZXBitMatrix *)convertByteMatrixToBitMatrix:(ZXByteMatrix *)input width:(int)width height:(int)height { - int inputWidth = input.width; - int inputHeight = input.height; - int outputWidth = MAX(width, inputWidth); - int outputHeight = MAX(height, inputHeight); - - int multiple = MIN(outputWidth / inputWidth, outputHeight / inputHeight); - int leftPadding = (outputWidth - (inputWidth * multiple)) / 2; - int topPadding = (outputHeight - (inputHeight * multiple)) / 2; - - ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:outputWidth height:outputHeight]; +- (ZXBitMatrix *)convertByteMatrixToBitMatrix:(ZXByteMatrix *)matrix width:(int)width height:(int)height { + int matrixWidth = matrix.width; + int matrixHeight = matrix.height; + int outputWidth = MAX(width, matrixWidth); + int outputHeight = MAX(height, matrixHeight); + + int multiple = MIN(outputWidth / matrixWidth, outputHeight / matrixHeight); + + int leftPadding = (outputWidth - (matrixWidth * multiple)) / 2; + int topPadding = (outputHeight - (matrixHeight * multiple)) / 2; + + ZXBitMatrix *output; + + // remove padding if requested width and height are too small + if (height < matrixHeight || width < matrixWidth) { + leftPadding = 0; + topPadding = 0; + output = [[ZXBitMatrix alloc] initWithWidth:matrixWidth height:matrixHeight]; + } else { + output = [[ZXBitMatrix alloc] initWithWidth:width height:height]; + } - for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) { - for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) { - if ([input getX:inputX y:inputY] == 1) { + for (int inputY = 0, outputY = topPadding; inputY < matrixHeight; inputY++, outputY += multiple) { + for (int inputX = 0, outputX = leftPadding; inputX < matrixWidth; inputX++, outputX += multiple) { + if ([matrix getX:inputX y:inputY] == 1) { [output setRegionAtLeft:outputX top:outputY width:multiple height:multiple]; } } diff --git a/ZXingObjC/datamatrix/ZXingObjCDataMatrix.h b/ZXingObjC/datamatrix/ZXingObjCDataMatrix.h index 39bbd4bd3..630b4c5d4 100644 --- a/ZXingObjC/datamatrix/ZXingObjCDataMatrix.h +++ b/ZXingObjC/datamatrix/ZXingObjCDataMatrix.h @@ -21,6 +21,9 @@ #import "ZXDataMatrixDecoder.h" #import "ZXDataMatrixDefaultPlacement.h" #import "ZXDataMatrixDetector.h" +#import "ZXDataMatrixEdifactEncoder.h" +#import "ZXDataMatrixEncoder.h" +#import "ZXDataMatrixEncoderContext.h" #import "ZXDataMatrixErrorCorrection.h" #import "ZXDataMatrixHighLevelEncoder.h" #import "ZXDataMatrixReader.h" diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.m b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.m index 245b5f31c..a41d9bb81 100644 --- a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.m +++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.m @@ -167,10 +167,10 @@ + (int)decodeAsciiSegment:(ZXBitSource *)bits result:(NSMutableString *)result r } else if (oneByte == 235) { // Upper Shift (shift to Extended ASCII) upperShift = YES; } else if (oneByte == 236) { // 05 Macro - [result appendFormat:@"[)>%C%C", (unichar)0x001E05, (unichar)0x001D]; + [result appendFormat:@"[)>%C05%C", (unichar)0x001E, (unichar)0x001D]; [resultTrailer insertString:[NSString stringWithFormat:@"%C%C", (unichar)0x001E, (unichar)0x0004] atIndex:0]; } else if (oneByte == 237) { // 06 Macro - [result appendFormat:@"[)>%C%C", (unichar)0x001E06, (unichar)0x001D]; + [result appendFormat:@"[)>%C06%C", (unichar)0x001E, (unichar)0x001D]; [resultTrailer insertString:[NSString stringWithFormat:@"%C%C", (unichar)0x001E, (unichar)0x0004] atIndex:0]; } else if (oneByte == 238) { // Latch to ANSI X12 encodation return ANSIX12_ENCODE; @@ -221,7 +221,7 @@ + (BOOL)decodeC40Segment:(ZXBitSource *)bits result:(NSMutableString *)result { case 0: if (cValue < 3) { shift = cValue + 1; - } else if (cValue < sizeof(C40_BASIC_SET_CHARS) / sizeof(char)) { + } else if (cValue < sizeof(C40_BASIC_SET_CHARS) / sizeof(unichar)) { unichar c40char = C40_BASIC_SET_CHARS[cValue]; if (upperShift) { [result appendFormat:@"%C", (unichar)(c40char + 128)]; @@ -243,7 +243,7 @@ + (BOOL)decodeC40Segment:(ZXBitSource *)bits result:(NSMutableString *)result { shift = 0; break; case 2: - if (cValue < sizeof(C40_SHIFT2_SET_CHARS) / sizeof(char)) { + if (cValue < 27) { unichar c40char = C40_SHIFT2_SET_CHARS[cValue]; if (upperShift) { [result appendFormat:@"%C", (unichar)(c40char + 128)]; @@ -308,7 +308,7 @@ + (BOOL)decodeTextSegment:(ZXBitSource *)bits result:(NSMutableString *)result { case 0: if (cValue < 3) { shift = cValue + 1; - } else if (cValue < sizeof(TEXT_BASIC_SET_CHARS) / sizeof(char)) { + } else if (cValue < sizeof(TEXT_BASIC_SET_CHARS) / sizeof(unichar)) { unichar textChar = TEXT_BASIC_SET_CHARS[cValue]; if (upperShift) { [result appendFormat:@"%C", (unichar)(textChar + 128)]; @@ -331,7 +331,7 @@ + (BOOL)decodeTextSegment:(ZXBitSource *)bits result:(NSMutableString *)result { break; case 2: // Shift 2 for Text is the same encoding as C40 - if (cValue < sizeof(TEXT_SHIFT2_SET_CHARS) / sizeof(unichar)) { + if (cValue < 27) { unichar textChar = TEXT_SHIFT2_SET_CHARS[cValue]; if (upperShift) { [result appendFormat:@"%C", (unichar)(textChar + 128)]; @@ -349,7 +349,7 @@ + (BOOL)decodeTextSegment:(ZXBitSource *)bits result:(NSMutableString *)result { shift = 0; break; case 3: - if (cValue < sizeof(TEXT_SHIFT3_SET_CHARS) / sizeof(char)) { + if (cValue < sizeof(TEXT_SHIFT3_SET_CHARS) / sizeof(unichar)) { unichar textChar = TEXT_SHIFT3_SET_CHARS[cValue]; if (upperShift) { [result appendFormat:@"%C", (unichar)(textChar + 128)]; diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.h b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.h index cf7660af4..1fb9a5c77 100644 --- a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.h +++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.h @@ -34,7 +34,7 @@ - (ZXDecoderResult *)decode:(NSArray *)image error:(NSError **)error; /** - * Decodes a Data Matrix Code represented as a {@link BitMatrix}. A 1 or "true" is taken + * Decodes a Data Matrix Code represented as a ZXBitMatrix. A 1 or "true" is taken * to mean a black module. * * @param bits booleans representing white/black Data Matrix Code modules diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h b/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h index 82e01a9b3..49fd53e34 100644 --- a/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h +++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * Encapsulates a set of error-correction blocks in one symbol version. Most versions will * use blocks of differing sizes within one version, so, this encapsulates the parameters for diff --git a/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.h b/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.h index babf9e104..9eb2d7a23 100644 --- a/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.h +++ b/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBitMatrix, ZXDetectorResult, ZXWhiteRectangleDetector; /** diff --git a/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m b/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m index ada6c2fc2..dbce7badb 100644 --- a/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m +++ b/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m @@ -22,39 +22,6 @@ #import "ZXResultPoint.h" #import "ZXWhiteRectangleDetector.h" -/** - * Simply encapsulates two points and a number of transitions between them. - */ -@interface ZXResultPointsAndTransitions : NSObject - -@property (nonatomic, strong, readonly) ZXResultPoint *from; -@property (nonatomic, strong, readonly) ZXResultPoint *to; -@property (nonatomic, assign, readonly) int transitions; - -@end - -@implementation ZXResultPointsAndTransitions - -- (id)initWithFrom:(ZXResultPoint *)from to:(ZXResultPoint *)to transitions:(int)transitions { - if (self = [super init]) { - _from = from; - _to = to; - _transitions = transitions; - } - - return self; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"%@/%@/%d", self.from, self.to, self.transitions]; -} - -- (NSComparisonResult)compare:(ZXResultPointsAndTransitions *)otherObject { - return [@(self.transitions) compare:@(otherObject.transitions)]; -} - -@end - @interface ZXDataMatrixDetector () @@ -82,213 +49,255 @@ - (ZXDetectorResult *)detectWithError:(NSError **)error { if (!cornerPoints) { return nil; } - ZXResultPoint *pointA = cornerPoints[0]; - ZXResultPoint *pointB = cornerPoints[1]; - ZXResultPoint *pointC = cornerPoints[2]; - ZXResultPoint *pointD = cornerPoints[3]; - - NSMutableArray *transitions = [NSMutableArray arrayWithCapacity:4]; - [transitions addObject:[self transitionsBetween:pointA to:pointB]]; - [transitions addObject:[self transitionsBetween:pointA to:pointC]]; - [transitions addObject:[self transitionsBetween:pointB to:pointD]]; - [transitions addObject:[self transitionsBetween:pointC to:pointD]]; - [transitions sortUsingSelector:@selector(compare:)]; - - ZXResultPointsAndTransitions *lSideOne = (ZXResultPointsAndTransitions *)transitions[0]; - ZXResultPointsAndTransitions *lSideTwo = (ZXResultPointsAndTransitions *)transitions[1]; - - NSMutableDictionary *pointCount = [NSMutableDictionary dictionary]; - [self increment:pointCount key:[lSideOne from]]; - [self increment:pointCount key:[lSideOne to]]; - [self increment:pointCount key:[lSideTwo from]]; - [self increment:pointCount key:[lSideTwo to]]; - - ZXResultPoint *maybeTopLeft = nil; - ZXResultPoint *bottomLeft = nil; - ZXResultPoint *maybeBottomRight = nil; - for (ZXResultPoint *point in [pointCount allKeys]) { - NSNumber *value = pointCount[point]; - if ([value intValue] == 2) { - bottomLeft = point; - } else { - if (maybeTopLeft == nil) { - maybeTopLeft = point; - } else { - maybeBottomRight = point; - } - } - } - if (maybeTopLeft == nil || bottomLeft == nil || maybeBottomRight == nil) { - if (error) *error = ZXNotFoundErrorInstance(); + NSMutableArray *points = [self detectSolid1:[cornerPoints mutableCopy]]; + points = [self detectSolid2:points]; + ZXResultPoint *correctedTopRight = [self correctTopRight:points]; + if (!correctedTopRight) { return nil; } + points[3] = correctedTopRight; + points = [self shiftToModuleCenter:points]; - NSMutableArray *corners = [NSMutableArray arrayWithObjects:maybeTopLeft, bottomLeft, maybeBottomRight, nil]; - [ZXResultPoint orderBestPatterns:corners]; + ZXResultPoint *topLeft = points[0]; + ZXResultPoint *bottomLeft = points[1]; + ZXResultPoint *bottomRight = points[2]; + ZXResultPoint *topRight = points[3]; - ZXResultPoint *bottomRight = corners[0]; - bottomLeft = corners[1]; - ZXResultPoint *topLeft = corners[2]; - - ZXResultPoint *topRight; - if (!pointCount[pointA]) { - topRight = pointA; - } else if (!pointCount[pointB]) { - topRight = pointB; - } else if (!pointCount[pointC]) { - topRight = pointC; - } else { - topRight = pointD; - } - - int dimensionTop = [[self transitionsBetween:topLeft to:topRight] transitions]; - int dimensionRight = [[self transitionsBetween:bottomRight to:topRight] transitions]; + int dimensionTop = [self transitionsBetween:topLeft to:topRight] + 1; + int dimensionRight = [self transitionsBetween:bottomRight to:topRight] + 1; if ((dimensionTop & 0x01) == 1) { - dimensionTop++; + dimensionTop += 1; } - dimensionTop += 2; - if ((dimensionRight & 0x01) == 1) { - dimensionRight++; + dimensionRight += 1; } - dimensionRight += 2; - ZXBitMatrix *bits; - ZXResultPoint *correctedTopRight; + if (4 * dimensionTop < 7 * dimensionRight && 4 * dimensionRight < 7 * dimensionTop) { + // The matrix is square + dimensionTop = dimensionRight = MAX(dimensionTop, dimensionRight); + } - if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dimensionTop) { - correctedTopRight = [self correctTopRightRectangular:bottomLeft bottomRight:bottomRight topLeft:topLeft topRight:topRight dimensionTop:dimensionTop dimensionRight:dimensionRight]; - if (correctedTopRight == nil) { - correctedTopRight = topRight; - } + ZXBitMatrix *bits = [self sampleGrid:self.image topLeft:topLeft bottomLeft:bottomLeft bottomRight:bottomRight topRight:topRight dimensionX:dimensionTop dimensionY:dimensionRight error:error]; - dimensionTop = [[self transitionsBetween:topLeft to:correctedTopRight] transitions]; - dimensionRight = [[self transitionsBetween:bottomRight to:correctedTopRight] transitions]; + return [[ZXDetectorResult alloc] initWithBits:bits points:@[topLeft, bottomLeft, bottomRight, topRight]]; +} - if ((dimensionTop & 0x01) == 1) { - dimensionTop++; - } +- (ZXResultPoint *)shiftPoint:(ZXResultPoint *)point to:(ZXResultPoint *)to div:(int)div { + float x = (to.x - point.x) / (div + 1); + float y = (to.y - point.y) / (div + 1); + return [[ZXResultPoint alloc] initWithX:point.x + x y:point.y + y]; +} - if ((dimensionRight & 0x01) == 1) { - dimensionRight++; - } +- (ZXResultPoint *)moveAway:(ZXResultPoint *)point fromX:(float)fromX fromY:(float)fromY { + float x = point.x; + float y = point.y; - bits = [self sampleGrid:self.image topLeft:topLeft bottomLeft:bottomLeft bottomRight:bottomRight topRight:correctedTopRight dimensionX:dimensionTop dimensionY:dimensionRight error:error]; - if (!bits) { - return nil; - } + if (x < fromX) { + x -= 1; } else { - int dimension = MIN(dimensionRight, dimensionTop); - correctedTopRight = [self correctTopRight:bottomLeft bottomRight:bottomRight topLeft:topLeft topRight:topRight dimension:dimension]; - if (correctedTopRight == nil) { - correctedTopRight = topRight; - } - - int dimensionCorrected = MAX([[self transitionsBetween:topLeft to:correctedTopRight] transitions], [[self transitionsBetween:bottomRight to:correctedTopRight] transitions]); - dimensionCorrected++; - if ((dimensionCorrected & 0x01) == 1) { - dimensionCorrected++; - } + x += 1; + } - bits = [self sampleGrid:self.image topLeft:topLeft bottomLeft:bottomLeft bottomRight:bottomRight topRight:correctedTopRight dimensionX:dimensionCorrected dimensionY:dimensionCorrected error:error]; - if (!bits) { - return nil; - } + if (y < fromY) { + y -= 1; + } else { + y += 1; } - return [[ZXDetectorResult alloc] initWithBits:bits points:@[topLeft, bottomLeft, bottomRight, correctedTopRight]]; + + return [[ZXResultPoint alloc] initWithX:x y:y]; } /** - * Calculates the position of the white top right module using the output of the rectangle detector - * for a rectangular matrix + * Detect a solid side which has minimum transition. */ -- (ZXResultPoint *)correctTopRightRectangular:(ZXResultPoint *)bottomLeft bottomRight:(ZXResultPoint *)bottomRight - topLeft:(ZXResultPoint *)topLeft topRight:(ZXResultPoint *)topRight - dimensionTop:(int)dimensionTop dimensionRight:(int)dimensionRight { - float corr = [self distance:bottomLeft b:bottomRight] / (float)dimensionTop; - int norm = [self distance:topLeft b:topRight]; - float cos = ([topRight x] - [topLeft x]) / norm; - float sin = ([topRight y] - [topLeft y]) / norm; - - ZXResultPoint *c1 = [[ZXResultPoint alloc] initWithX:[topRight x] + corr * cos y:[topRight y] + corr * sin]; - - corr = [self distance:bottomLeft b:topLeft] / (float)dimensionRight; - norm = [self distance:bottomRight b:topRight]; - cos = ([topRight x] - [bottomRight x]) / norm; - sin = ([topRight y] - [bottomRight y]) / norm; - - ZXResultPoint *c2 = [[ZXResultPoint alloc] initWithX:[topRight x] + corr * cos y:[topRight y] + corr * sin]; - - if (![self isValid:c1]) { - if ([self isValid:c2]) { - return c2; - } - return nil; - } else if (![self isValid:c2]) { - return c1; +- (NSMutableArray *)detectSolid1:(NSMutableArray *)cornerPoints { + // 0 2 + // 1 3 + ZXResultPoint *pointA = cornerPoints[0]; + ZXResultPoint *pointB = cornerPoints[1]; + ZXResultPoint *pointC = cornerPoints[3]; + ZXResultPoint *pointD = cornerPoints[2]; + + int trAB = [self transitionsBetween:pointA to:pointB]; + int trBC = [self transitionsBetween:pointB to:pointC]; + int trCD = [self transitionsBetween:pointC to:pointD]; + int trDA = [self transitionsBetween:pointD to:pointA]; + + // 0..3 + // : : + // 1--2 + int min = trAB; + NSMutableArray *points = [@[pointD, pointA, pointB, pointC] mutableCopy]; + if (min > trBC) { + min = trBC; + points[0] = pointA; + points[1] = pointB; + points[2] = pointC; + points[3] = pointD; } - - int l1 = abs(dimensionTop - [[self transitionsBetween:topLeft to:c1] transitions]) + abs(dimensionRight - [[self transitionsBetween:bottomRight to:c1] transitions]); - int l2 = abs(dimensionTop - [[self transitionsBetween:topLeft to:c2] transitions]) + abs(dimensionRight - [[self transitionsBetween:bottomRight to:c2] transitions]); - - if (l1 <= l2) { - return c1; + if (min > trCD) { + min = trCD; + points[0] = pointB; + points[1] = pointC; + points[2] = pointD; + points[3] = pointA; + } + if (min > trDA) { + points[0] = pointC; + points[1] = pointD; + points[2] = pointA; + points[3] = pointB; } - return c2; + return points; } /** - * Calculates the position of the white top right module using the output of the rectangle detector - * for a square matrix + * Detect a second solid side next to first solid side. */ -- (ZXResultPoint *)correctTopRight:(ZXResultPoint *)bottomLeft bottomRight:(ZXResultPoint *)bottomRight - topLeft:(ZXResultPoint *)topLeft topRight:(ZXResultPoint *)topRight dimension:(int)dimension { - float corr = [self distance:bottomLeft b:bottomRight] / (float)dimension; - int norm = [self distance:topLeft b:topRight]; - float cos = ([topRight x] - [topLeft x]) / norm; - float sin = ([topRight y] - [topLeft y]) / norm; - - ZXResultPoint *c1 = [[ZXResultPoint alloc] initWithX:[topRight x] + corr * cos y:[topRight y] + corr * sin]; - - corr = [self distance:bottomLeft b:topLeft] / (float)dimension; - norm = [self distance:bottomRight b:topRight]; - cos = ([topRight x] - [bottomRight x]) / norm; - sin = ([topRight y] - [bottomRight y]) / norm; +- (NSMutableArray *)detectSolid2:(NSMutableArray *)points { + // A..D + // : : + // B--C + ZXResultPoint *pointA = points[0]; + ZXResultPoint *pointB = points[1]; + ZXResultPoint *pointC = points[2]; + ZXResultPoint *pointD = points[3]; + + // Transition detection on the edge is not stable. + // To safely detect, shift the points to the module center. + int tr = [self transitionsBetween:pointA to:pointD]; + ZXResultPoint *pointBs = [self shiftPoint:pointB to:pointC div:(tr + 1) * 4]; + ZXResultPoint *pointCs = [self shiftPoint:pointC to:pointB div:(tr + 1) * 4]; + int trBA = [self transitionsBetween:pointBs to:pointA]; + int trCD = [self transitionsBetween:pointCs to:pointD]; + + // 0..3 + // | : + // 1--2 + if (trBA < trCD) { + // solid sides: A-B-C + points[0] = pointA; + points[1] = pointB; + points[2] = pointC; + points[3] = pointD; + } else { + // solid sides: B-C-D + points[0] = pointB; + points[1] = pointC; + points[2] = pointD; + points[3] = pointA; + } - ZXResultPoint *c2 = [[ZXResultPoint alloc] initWithX:[topRight x] + corr * cos y:[topRight y] + corr * sin]; + return points; +} - if (![self isValid:c1]) { - if ([self isValid:c2]) { - return c2; +/** + * Calculates the corner position of the white top right module. + */ +- (ZXResultPoint *)correctTopRight:(NSMutableArray *)points { + // A..D + // | : + // B--C + ZXResultPoint *pointA = points[0]; + ZXResultPoint *pointB = points[1]; + ZXResultPoint *pointC = points[2]; + ZXResultPoint *pointD = points[3]; + + // shift points for safe transition detection. + int trTop = [self transitionsBetween:pointA to:pointD]; + int trRight = [self transitionsBetween:pointB to:pointD]; + ZXResultPoint *pointAs = [self shiftPoint:pointA to:pointB div:(trRight + 1) * 4]; + ZXResultPoint *pointCs = [self shiftPoint:pointC to:pointB div:(trTop + 1) * 4]; + + trTop = [self transitionsBetween:pointAs to:pointD]; + trRight = [self transitionsBetween:pointCs to:pointD]; + + ZXResultPoint *candidate1 = [[ZXResultPoint alloc] initWithX:pointD.x + (pointC.x - pointB.x) / (trTop + 1) + y:pointD.y + (pointC.y - pointB.y) / (trTop + 1)]; + + ZXResultPoint *candidate2 = [[ZXResultPoint alloc] initWithX:pointD.x + (pointA.x - pointB.x) / (trRight + 1) + y:pointD.y + (pointA.y - pointB.y) / (trRight + 1)]; + + if (![self isValid:candidate1]) { + if ([self isValid:candidate2]) { + return candidate2; } return nil; - } else if (![self isValid:c2]) { - return c1; + } + if (![self isValid:candidate2]) { + return candidate1; } - int l1 = abs([[self transitionsBetween:topLeft to:c1] transitions] - [[self transitionsBetween:bottomRight to:c1] transitions]); - int l2 = abs([[self transitionsBetween:topLeft to:c2] transitions] - [[self transitionsBetween:bottomRight to:c2] transitions]); + int sumc1 = [self transitionsBetween:pointAs to:candidate1] + [self transitionsBetween:pointCs to:candidate1]; + int sumc2 = [self transitionsBetween:pointAs to:candidate2] + [self transitionsBetween:pointCs to:candidate2]; - return l1 <= l2 ? c1 : c2; + if (sumc1 > sumc2) { + return candidate1; + } else { + return candidate2; + } } - (BOOL) isValid:(ZXResultPoint *)p { return [p x] >= 0 && [p x] < self.image.width && [p y] > 0 && [p y] < self.image.height; } -- (int)distance:(ZXResultPoint *)a b:(ZXResultPoint *)b { - return [ZXMathUtils round:[ZXResultPoint distance:a pattern2:b]]; -} - /** - * Increments the Integer associated with a key by one. + * Shift the edge points to the module center. */ -- (void)increment:(NSMutableDictionary *)table key:(ZXResultPoint *)key { - NSNumber *value = table[key]; - table[key] = value == nil ? @1 : @([value intValue] + 1); +- (NSMutableArray *)shiftToModuleCenter:(NSMutableArray *)points { + // A..D + // | : + // B--C + ZXResultPoint *pointA = points[0]; + ZXResultPoint *pointB = points[1]; + ZXResultPoint *pointC = points[2]; + ZXResultPoint *pointD = points[3]; + + // calculate pseudo dimensions + int dimH = [self transitionsBetween:pointA to:pointD] + 1; + int dimV = [self transitionsBetween:pointC to:pointD] + 1; + + // shift points for safe dimension detection + ZXResultPoint *pointAs = [self shiftPoint:pointA to:pointB div:dimV * 4]; + ZXResultPoint *pointCs = [self shiftPoint:pointC to:pointB div:dimH * 4]; + + // calculate more precise dimensions + dimH = [self transitionsBetween:pointAs to:pointD] + 1; + dimV = [self transitionsBetween:pointCs to:pointD] + 1; + if ((dimH & 0x01) == 1) { + dimH += 1; + } + if ((dimV & 0x01) == 1) { + dimV += 1; + } + + // WhiteRectangleDetector returns points inside of the rectangle. + // I want points on the edges. + float centerX = (pointA.x + pointB.x + pointC.x + pointD.x) / 4; + float centerY = (pointA.y + pointB.y + pointC.y + pointD.y) / 4; + pointA = [self moveAway:pointA fromX:centerX fromY:centerY]; + pointB = [self moveAway:pointB fromX:centerX fromY:centerY]; + pointC = [self moveAway:pointC fromX:centerX fromY:centerY]; + pointD = [self moveAway:pointD fromX:centerX fromY:centerY]; + + ZXResultPoint *pointBs; + ZXResultPoint *pointDs; + + // shift points to the center of each modules + pointAs = [self shiftPoint:pointA to:pointB div:dimV * 4]; + pointAs = [self shiftPoint:pointAs to:pointD div:dimH * 4]; + pointBs = [self shiftPoint:pointB to:pointA div:dimV * 4]; + pointBs = [self shiftPoint:pointBs to:pointC div:dimH * 4]; + pointCs = [self shiftPoint:pointC to:pointD div:dimV * 4]; + pointCs = [self shiftPoint:pointCs to:pointB div:dimH * 4]; + pointDs = [self shiftPoint:pointD to:pointC div:dimV * 4]; + pointDs = [self shiftPoint:pointDs to:pointA div:dimH * 4]; + + return [@[pointAs, pointBs, pointCs, pointDs] mutableCopy]; } - (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image @@ -316,7 +325,7 @@ - (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image /** * Counts the number of black/white transitions between two points, using something like Bresenham's algorithm. */ -- (ZXResultPointsAndTransitions *)transitionsBetween:(ZXResultPoint *)from to:(ZXResultPoint *)to { +- (int)transitionsBetween:(ZXResultPoint *)from to:(ZXResultPoint *)to { int fromX = (int)[from x]; int fromY = (int)[from y]; int toX = (int)[to x]; @@ -353,7 +362,7 @@ - (ZXResultPointsAndTransitions *)transitionsBetween:(ZXResultPoint *)from to:(Z error -= dx; } } - return [[ZXResultPointsAndTransitions alloc] initWithFrom:from to:to transitions:transitions]; + return transitions; } @end diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.m b/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.m index ede8fa9a3..7880f6906 100644 --- a/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.m +++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.m @@ -36,7 +36,8 @@ - (void)encode:(ZXDataMatrixEncoderContext *)context { int newMode = [ZXDataMatrixHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]]; if (newMode != [self encodingMode]) { - [context signalEncoderChange:newMode]; + // Return to ASCII encodation, which will actually handle latch to new mode + [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder asciiEncodation]]; break; } } diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.m b/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.m index 4a72603a5..8c26b811b 100644 --- a/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.m +++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.m @@ -48,8 +48,7 @@ - (void)encode:(ZXDataMatrixEncoderContext *)context { lastCharSize = [self backtrackOneCharacter:context buffer:buffer removed:removed lastCharSize:lastCharSize]; } } - while ((buffer.length % 3) == 1 - && ((lastCharSize <= 3 && available != 1) || lastCharSize > 3)) { + while ((buffer.length % 3) == 1 && (lastCharSize > 3 || available != 1)) { lastCharSize = [self backtrackOneCharacter:context buffer:buffer removed:removed lastCharSize:lastCharSize]; } break; @@ -59,7 +58,8 @@ - (void)encode:(ZXDataMatrixEncoderContext *)context { if ((count % 3) == 0) { int newMode = [ZXDataMatrixHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]]; if (newMode != [self encodingMode]) { - [context signalEncoderChange:newMode]; + // Return to ASCII encodation, which will actually handle latch to new mode + [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder asciiEncodation]]; break; } } diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.h b/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.h index a7e0fc7ff..afde208a4 100644 --- a/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.h +++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * Symbol Character Placement Program. Adapted from Annex M.1 in ISO/IEC 16022:2000(E). */ diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.m b/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.m index 81c50096a..9ed85c969 100644 --- a/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.m +++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.m @@ -40,6 +40,7 @@ - (void)encode:(ZXDataMatrixEncoderContext *)context { int newMode = [ZXDataMatrixHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]]; if (newMode != [self encodingMode]) { + // Return to ASCII encodation, which will actually handle latch to new mode [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder asciiEncodation]]; break; } @@ -66,7 +67,12 @@ - (void)handleEOD:(ZXDataMatrixEncoderContext *)context buffer:(NSMutableString [context updateSymbolInfo]; int available = context.symbolInfo.dataCapacity - context.codewordCount; int remaining = [context remainingCharacters]; - if (remaining == 0 && available <= 2) { + // The following two lines are a hack inspired by the 'fix' from https://sourceforge.net/p/barcode4j/svn/221/ + if (remaining > available) { + [context updateSymbolInfoWithLength:context.codewordCount + 1]; + available = context.symbolInfo.dataCapacity - context.codewordCount; + } + if (remaining <= available && available <= 2) { return; //No unlatch } } diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoder.h b/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoder.h index 4d3c63d3f..804d9b5ab 100644 --- a/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoder.h +++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoder.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXDataMatrixEncoderContext; @protocol ZXDataMatrixEncoder diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h b/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h index d93d3fd60..6eaa7e274 100644 --- a/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h +++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXDataMatrixSymbolInfo; /** diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m b/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m index 6c9f658b9..2439d50f1 100644 --- a/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m +++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m @@ -64,7 +64,7 @@ const int ZX_MODULO_VALUE = 0x12D; -static int ZX_LOG[256], ZX_ALOG[256]; +static int ZX_LOG[256], ZX_ALOG[255]; @implementation ZXDataMatrixErrorCorrection @@ -115,7 +115,7 @@ + (NSString *)encodeECC200:(NSString *)codewords symbolInfo:(ZXDataMatrixSymbolI for (int block = 0; block < blockCount; block++) { NSMutableString *temp = [NSMutableString stringWithCapacity:dataSizes[block]]; for (int d = block; d < symbolInfo.dataCapacity; d += blockCount) { - [temp appendFormat:@"%c", [codewords characterAtIndex:d]]; + [temp appendFormat:@"%C", [codewords characterAtIndex:d]]; } NSString *ecc = [self createECCBlock:temp numECWords:errorSizes[block]]; int pos = 0; diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.m b/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.m index b323d23d4..717f4b20d 100644 --- a/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.m +++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.m @@ -170,7 +170,7 @@ + (NSString *)encodeHighLevel:(NSString *)msg shape:(ZXDataMatrixSymbolShapeHint [context updateSymbolInfo]; int capacity = context.symbolInfo.dataCapacity; if (len < capacity) { - if (encodingMode != [self asciiEncodation] && encodingMode != [self base256Encodation]) { + if (encodingMode != [self asciiEncodation] && encodingMode != [self base256Encodation] && encodingMode != [self edifactEncodation]) { [context writeCodeword:(unichar)0x00fe]; //Unlatch (254) } } diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.m b/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.m index b377531b1..1eaf872da 100644 --- a/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.m +++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.m @@ -40,7 +40,8 @@ - (void)encode:(ZXDataMatrixEncoderContext *)context { int newMode = [ZXDataMatrixHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]]; if (newMode != [self encodingMode]) { - [context signalEncoderChange:newMode]; + // Return to ASCII encodation, which will actually handle latch to new mode + [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder asciiEncodation]]; break; } } diff --git a/ZXingObjC/include/ZXingObjC/ZXAbstractDoCoMoResultParser.h b/ZXingObjC/include/ZXingObjC/ZXAbstractDoCoMoResultParser.h new file mode 120000 index 000000000..a3a296505 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAbstractDoCoMoResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXAbstractDoCoMoResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAbstractExpandedDecoder.h b/ZXingObjC/include/ZXingObjC/ZXAbstractExpandedDecoder.h new file mode 120000 index 000000000..d1164514d --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAbstractExpandedDecoder.h @@ -0,0 +1 @@ +../../oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAbstractRSSReader.h b/ZXingObjC/include/ZXingObjC/ZXAbstractRSSReader.h new file mode 120000 index 000000000..b35511afd --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAbstractRSSReader.h @@ -0,0 +1 @@ +../../oned/rss/ZXAbstractRSSReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAddressBookAUResultParser.h b/ZXingObjC/include/ZXingObjC/ZXAddressBookAUResultParser.h new file mode 120000 index 000000000..57f579dad --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAddressBookAUResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXAddressBookAUResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAddressBookDoCoMoResultParser.h b/ZXingObjC/include/ZXingObjC/ZXAddressBookDoCoMoResultParser.h new file mode 120000 index 000000000..839a9b27b --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAddressBookDoCoMoResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXAddressBookDoCoMoResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAddressBookParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXAddressBookParsedResult.h new file mode 120000 index 000000000..9d636f4d3 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAddressBookParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXAddressBookParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAztecCode.h b/ZXingObjC/include/ZXingObjC/ZXAztecCode.h new file mode 120000 index 000000000..4a22950a4 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAztecCode.h @@ -0,0 +1 @@ +../../aztec/encoder/ZXAztecCode.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAztecDecoder.h b/ZXingObjC/include/ZXingObjC/ZXAztecDecoder.h new file mode 120000 index 000000000..115a4223c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAztecDecoder.h @@ -0,0 +1 @@ +../../aztec/decoder/ZXAztecDecoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAztecDetector.h b/ZXingObjC/include/ZXingObjC/ZXAztecDetector.h new file mode 120000 index 000000000..78c9f685d --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAztecDetector.h @@ -0,0 +1 @@ +../../aztec/detector/ZXAztecDetector.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAztecDetectorResult.h b/ZXingObjC/include/ZXingObjC/ZXAztecDetectorResult.h new file mode 120000 index 000000000..fc605829a --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAztecDetectorResult.h @@ -0,0 +1 @@ +../../aztec/ZXAztecDetectorResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAztecEncoder.h b/ZXingObjC/include/ZXingObjC/ZXAztecEncoder.h new file mode 120000 index 000000000..284cee269 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAztecEncoder.h @@ -0,0 +1 @@ +../../aztec/encoder/ZXAztecEncoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAztecHighLevelEncoder.h b/ZXingObjC/include/ZXingObjC/ZXAztecHighLevelEncoder.h new file mode 120000 index 000000000..a979c43ba --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAztecHighLevelEncoder.h @@ -0,0 +1 @@ +../../aztec/encoder/ZXAztecHighLevelEncoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAztecReader.h b/ZXingObjC/include/ZXingObjC/ZXAztecReader.h new file mode 120000 index 000000000..1628a6469 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAztecReader.h @@ -0,0 +1 @@ +../../aztec/ZXAztecReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXAztecWriter.h b/ZXingObjC/include/ZXingObjC/ZXAztecWriter.h new file mode 120000 index 000000000..081bdd4ca --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXAztecWriter.h @@ -0,0 +1 @@ +../../aztec/ZXAztecWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXBarcodeFormat.h b/ZXingObjC/include/ZXingObjC/ZXBarcodeFormat.h new file mode 120000 index 000000000..e977d3048 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXBarcodeFormat.h @@ -0,0 +1 @@ +../../core/ZXBarcodeFormat.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXBinarizer.h b/ZXingObjC/include/ZXingObjC/ZXBinarizer.h new file mode 120000 index 000000000..a4adeaaee --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXBinarizer.h @@ -0,0 +1 @@ +../../core/ZXBinarizer.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXBinaryBitmap.h b/ZXingObjC/include/ZXingObjC/ZXBinaryBitmap.h new file mode 120000 index 000000000..a0456513a --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXBinaryBitmap.h @@ -0,0 +1 @@ +../../core/ZXBinaryBitmap.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXBitArray.h b/ZXingObjC/include/ZXingObjC/ZXBitArray.h new file mode 120000 index 000000000..dbd5427be --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXBitArray.h @@ -0,0 +1 @@ +../../common/ZXBitArray.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXBitMatrix.h b/ZXingObjC/include/ZXingObjC/ZXBitMatrix.h new file mode 120000 index 000000000..ed363a6e2 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXBitMatrix.h @@ -0,0 +1 @@ +../../common/ZXBitMatrix.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXBitSource.h b/ZXingObjC/include/ZXingObjC/ZXBitSource.h new file mode 120000 index 000000000..fcb150973 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXBitSource.h @@ -0,0 +1 @@ +../../common/ZXBitSource.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXBizcardResultParser.h b/ZXingObjC/include/ZXingObjC/ZXBizcardResultParser.h new file mode 120000 index 000000000..ce02f5188 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXBizcardResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXBizcardResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXBookmarkDoCoMoResultParser.h b/ZXingObjC/include/ZXingObjC/ZXBookmarkDoCoMoResultParser.h new file mode 120000 index 000000000..0c7fd72e2 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXBookmarkDoCoMoResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXBookmarkDoCoMoResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXBoolArray.h b/ZXingObjC/include/ZXingObjC/ZXBoolArray.h new file mode 120000 index 000000000..6300ef1b7 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXBoolArray.h @@ -0,0 +1 @@ +../../common/ZXBoolArray.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXByQuadrantReader.h b/ZXingObjC/include/ZXingObjC/ZXByQuadrantReader.h new file mode 120000 index 000000000..bc2fa54a3 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXByQuadrantReader.h @@ -0,0 +1 @@ +../../multi/ZXByQuadrantReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXByteArray.h b/ZXingObjC/include/ZXingObjC/ZXByteArray.h new file mode 120000 index 000000000..a98241a08 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXByteArray.h @@ -0,0 +1 @@ +../../common/ZXByteArray.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXByteMatrix.h b/ZXingObjC/include/ZXingObjC/ZXByteMatrix.h new file mode 120000 index 000000000..dce4e0246 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXByteMatrix.h @@ -0,0 +1 @@ +../../core/ZXByteMatrix.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCGImageLuminanceSource.h b/ZXingObjC/include/ZXingObjC/ZXCGImageLuminanceSource.h new file mode 120000 index 000000000..7c66815c3 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCGImageLuminanceSource.h @@ -0,0 +1 @@ +../../client/ZXCGImageLuminanceSource.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCGImageLuminanceSourceInfo.h b/ZXingObjC/include/ZXingObjC/ZXCGImageLuminanceSourceInfo.h new file mode 120000 index 000000000..7b96048fb --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCGImageLuminanceSourceInfo.h @@ -0,0 +1 @@ +../../client/ZXCGImageLuminanceSourceInfo.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCalendarParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXCalendarParsedResult.h new file mode 120000 index 000000000..9b7f76815 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCalendarParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXCalendarParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCapture.h b/ZXingObjC/include/ZXingObjC/ZXCapture.h new file mode 120000 index 000000000..ea8482e12 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCapture.h @@ -0,0 +1 @@ +../../client/ZXCapture.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCaptureDelegate.h b/ZXingObjC/include/ZXingObjC/ZXCaptureDelegate.h new file mode 120000 index 000000000..3ac36da0c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCaptureDelegate.h @@ -0,0 +1 @@ +../../client/ZXCaptureDelegate.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCharacterSetECI.h b/ZXingObjC/include/ZXingObjC/ZXCharacterSetECI.h new file mode 120000 index 000000000..8a924d075 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCharacterSetECI.h @@ -0,0 +1 @@ +../../common/ZXCharacterSetECI.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCodaBarReader.h b/ZXingObjC/include/ZXingObjC/ZXCodaBarReader.h new file mode 120000 index 000000000..9ff6ef243 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCodaBarReader.h @@ -0,0 +1 @@ +../../oned/ZXCodaBarReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCodaBarWriter.h b/ZXingObjC/include/ZXingObjC/ZXCodaBarWriter.h new file mode 120000 index 000000000..4552a968d --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCodaBarWriter.h @@ -0,0 +1 @@ +../../oned/ZXCodaBarWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCode128Reader.h b/ZXingObjC/include/ZXingObjC/ZXCode128Reader.h new file mode 120000 index 000000000..552df134f --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCode128Reader.h @@ -0,0 +1 @@ +../../oned/ZXCode128Reader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCode128Writer.h b/ZXingObjC/include/ZXingObjC/ZXCode128Writer.h new file mode 120000 index 000000000..d9e796b66 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCode128Writer.h @@ -0,0 +1 @@ +../../oned/ZXCode128Writer.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCode39Reader.h b/ZXingObjC/include/ZXingObjC/ZXCode39Reader.h new file mode 120000 index 000000000..be4d5fd8d --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCode39Reader.h @@ -0,0 +1 @@ +../../oned/ZXCode39Reader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCode39Writer.h b/ZXingObjC/include/ZXingObjC/ZXCode39Writer.h new file mode 120000 index 000000000..eccde6f0e --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCode39Writer.h @@ -0,0 +1 @@ +../../oned/ZXCode39Writer.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXCode93Reader.h b/ZXingObjC/include/ZXingObjC/ZXCode93Reader.h new file mode 120000 index 000000000..3733409b9 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXCode93Reader.h @@ -0,0 +1 @@ +../../oned/ZXCode93Reader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixDecoder.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixDecoder.h new file mode 120000 index 000000000..dcdb20cc9 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixDecoder.h @@ -0,0 +1 @@ +../../datamatrix/decoder/ZXDataMatrixDecoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixDefaultPlacement.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixDefaultPlacement.h new file mode 120000 index 000000000..07c639d4d --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixDefaultPlacement.h @@ -0,0 +1 @@ +../../datamatrix/encoder/ZXDataMatrixDefaultPlacement.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixDetector.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixDetector.h new file mode 120000 index 000000000..3bd7a6443 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixDetector.h @@ -0,0 +1 @@ +../../datamatrix/detector/ZXDataMatrixDetector.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixEdifactEncoder.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixEdifactEncoder.h new file mode 120000 index 000000000..1a27cadc5 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixEdifactEncoder.h @@ -0,0 +1 @@ +../../datamatrix/encoder/ZXDataMatrixEdifactEncoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixEncoder.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixEncoder.h new file mode 120000 index 000000000..a48b9308c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixEncoder.h @@ -0,0 +1 @@ +../../datamatrix/encoder/ZXDataMatrixEncoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixEncoderContext.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixEncoderContext.h new file mode 120000 index 000000000..358b2be03 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixEncoderContext.h @@ -0,0 +1 @@ +../../datamatrix/encoder/ZXDataMatrixEncoderContext.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixErrorCorrection.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixErrorCorrection.h new file mode 120000 index 000000000..12dc2a173 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixErrorCorrection.h @@ -0,0 +1 @@ +../../datamatrix/encoder/ZXDataMatrixErrorCorrection.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixHighLevelEncoder.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixHighLevelEncoder.h new file mode 120000 index 000000000..b259af617 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixHighLevelEncoder.h @@ -0,0 +1 @@ +../../datamatrix/encoder/ZXDataMatrixHighLevelEncoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixReader.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixReader.h new file mode 120000 index 000000000..f59cc05c8 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixReader.h @@ -0,0 +1 @@ +../../datamatrix/ZXDataMatrixReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixSymbolInfo.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixSymbolInfo.h new file mode 120000 index 000000000..793141809 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixSymbolInfo.h @@ -0,0 +1 @@ +../../datamatrix/encoder/ZXDataMatrixSymbolInfo.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixVersion.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixVersion.h new file mode 120000 index 000000000..b28529f0f --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixVersion.h @@ -0,0 +1 @@ +../../datamatrix/decoder/ZXDataMatrixVersion.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDataMatrixWriter.h b/ZXingObjC/include/ZXingObjC/ZXDataMatrixWriter.h new file mode 120000 index 000000000..5cc15146d --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDataMatrixWriter.h @@ -0,0 +1 @@ +../../datamatrix/ZXDataMatrixWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDecodeHints.h b/ZXingObjC/include/ZXingObjC/ZXDecodeHints.h new file mode 120000 index 000000000..10230dab2 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDecodeHints.h @@ -0,0 +1 @@ +../../core/ZXDecodeHints.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDecoderResult.h b/ZXingObjC/include/ZXingObjC/ZXDecoderResult.h new file mode 120000 index 000000000..58715d463 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDecoderResult.h @@ -0,0 +1 @@ +../../common/ZXDecoderResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDefaultGridSampler.h b/ZXingObjC/include/ZXingObjC/ZXDefaultGridSampler.h new file mode 120000 index 000000000..d4ad038ff --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDefaultGridSampler.h @@ -0,0 +1 @@ +../../common/ZXDefaultGridSampler.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDetectorResult.h b/ZXingObjC/include/ZXingObjC/ZXDetectorResult.h new file mode 120000 index 000000000..dcf80b88c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDetectorResult.h @@ -0,0 +1 @@ +../../common/ZXDetectorResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXDimension.h b/ZXingObjC/include/ZXingObjC/ZXDimension.h new file mode 120000 index 000000000..0798cf7fb --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXDimension.h @@ -0,0 +1 @@ +../../core/ZXDimension.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXEAN13Reader.h b/ZXingObjC/include/ZXingObjC/ZXEAN13Reader.h new file mode 120000 index 000000000..48428f1c4 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXEAN13Reader.h @@ -0,0 +1 @@ +../../oned/ZXEAN13Reader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXEAN13Writer.h b/ZXingObjC/include/ZXingObjC/ZXEAN13Writer.h new file mode 120000 index 000000000..240e4a1d1 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXEAN13Writer.h @@ -0,0 +1 @@ +../../oned/ZXEAN13Writer.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXEAN8Reader.h b/ZXingObjC/include/ZXingObjC/ZXEAN8Reader.h new file mode 120000 index 000000000..5e15e7907 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXEAN8Reader.h @@ -0,0 +1 @@ +../../oned/ZXEAN8Reader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXEAN8Writer.h b/ZXingObjC/include/ZXingObjC/ZXEAN8Writer.h new file mode 120000 index 000000000..dec813873 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXEAN8Writer.h @@ -0,0 +1 @@ +../../oned/ZXEAN8Writer.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXEmailAddressParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXEmailAddressParsedResult.h new file mode 120000 index 000000000..25d2799f7 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXEmailAddressParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXEmailAddressParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXEmailAddressResultParser.h b/ZXingObjC/include/ZXingObjC/ZXEmailAddressResultParser.h new file mode 120000 index 000000000..dca828d2a --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXEmailAddressResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXEmailAddressResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXEmailDoCoMoResultParser.h b/ZXingObjC/include/ZXingObjC/ZXEmailDoCoMoResultParser.h new file mode 120000 index 000000000..e4bdfcf21 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXEmailDoCoMoResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXEmailDoCoMoResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXEncodeHints.h b/ZXingObjC/include/ZXingObjC/ZXEncodeHints.h new file mode 120000 index 000000000..9d05e0061 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXEncodeHints.h @@ -0,0 +1 @@ +../../core/ZXEncodeHints.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXErrors.h b/ZXingObjC/include/ZXingObjC/ZXErrors.h new file mode 120000 index 000000000..cecf1ee86 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXErrors.h @@ -0,0 +1 @@ +../../core/ZXErrors.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXExpandedProductParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXExpandedProductParsedResult.h new file mode 120000 index 000000000..282ce5287 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXExpandedProductParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXExpandedProductParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXExpandedProductResultParser.h b/ZXingObjC/include/ZXingObjC/ZXExpandedProductResultParser.h new file mode 120000 index 000000000..dcbb249f5 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXExpandedProductResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXExpandedProductResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXGenericGF.h b/ZXingObjC/include/ZXingObjC/ZXGenericGF.h new file mode 120000 index 000000000..36ae2badc --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXGenericGF.h @@ -0,0 +1 @@ +../../common/reedsolomon/ZXGenericGF.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXGenericMultipleBarcodeReader.h b/ZXingObjC/include/ZXingObjC/ZXGenericMultipleBarcodeReader.h new file mode 120000 index 000000000..71cce8e3d --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXGenericMultipleBarcodeReader.h @@ -0,0 +1 @@ +../../multi/ZXGenericMultipleBarcodeReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXGeoParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXGeoParsedResult.h new file mode 120000 index 000000000..16daac6f8 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXGeoParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXGeoParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXGeoResultParser.h b/ZXingObjC/include/ZXingObjC/ZXGeoResultParser.h new file mode 120000 index 000000000..582a5a88c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXGeoResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXGeoResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXGlobalHistogramBinarizer.h b/ZXingObjC/include/ZXingObjC/ZXGlobalHistogramBinarizer.h new file mode 120000 index 000000000..88be8826f --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXGlobalHistogramBinarizer.h @@ -0,0 +1 @@ +../../common/ZXGlobalHistogramBinarizer.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXGridSampler.h b/ZXingObjC/include/ZXingObjC/ZXGridSampler.h new file mode 120000 index 000000000..b1181645c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXGridSampler.h @@ -0,0 +1 @@ +../../common/ZXGridSampler.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXHybridBinarizer.h b/ZXingObjC/include/ZXingObjC/ZXHybridBinarizer.h new file mode 120000 index 000000000..fe550d324 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXHybridBinarizer.h @@ -0,0 +1 @@ +../../common/ZXHybridBinarizer.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXISBNParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXISBNParsedResult.h new file mode 120000 index 000000000..b171c8cc7 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXISBNParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXISBNParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXISBNResultParser.h b/ZXingObjC/include/ZXingObjC/ZXISBNResultParser.h new file mode 120000 index 000000000..0629d0c57 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXISBNResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXISBNResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXITFReader.h b/ZXingObjC/include/ZXingObjC/ZXITFReader.h new file mode 120000 index 000000000..bb24f2c6b --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXITFReader.h @@ -0,0 +1 @@ +../../oned/ZXITFReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXITFWriter.h b/ZXingObjC/include/ZXingObjC/ZXITFWriter.h new file mode 120000 index 000000000..26dc35298 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXITFWriter.h @@ -0,0 +1 @@ +../../oned/ZXITFWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXImage.h b/ZXingObjC/include/ZXingObjC/ZXImage.h new file mode 120000 index 000000000..83db09af7 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXImage.h @@ -0,0 +1 @@ +../../client/ZXImage.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXIntArray.h b/ZXingObjC/include/ZXingObjC/ZXIntArray.h new file mode 120000 index 000000000..0ad818d33 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXIntArray.h @@ -0,0 +1 @@ +../../common/ZXIntArray.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXInvertedLuminanceSource.h b/ZXingObjC/include/ZXingObjC/ZXInvertedLuminanceSource.h new file mode 120000 index 000000000..70e560b90 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXInvertedLuminanceSource.h @@ -0,0 +1 @@ +../../core/ZXInvertedLuminanceSource.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXLuminanceSource.h b/ZXingObjC/include/ZXingObjC/ZXLuminanceSource.h new file mode 120000 index 000000000..51429f74d --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXLuminanceSource.h @@ -0,0 +1 @@ +../../core/ZXLuminanceSource.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMathUtils.h b/ZXingObjC/include/ZXingObjC/ZXMathUtils.h new file mode 120000 index 000000000..f8dcd9708 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMathUtils.h @@ -0,0 +1 @@ +../../common/detector/ZXMathUtils.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMaxiCodeDecoder.h b/ZXingObjC/include/ZXingObjC/ZXMaxiCodeDecoder.h new file mode 120000 index 000000000..5e4761b6a --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMaxiCodeDecoder.h @@ -0,0 +1 @@ +../../maxicode/decoder/ZXMaxiCodeDecoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMaxiCodeReader.h b/ZXingObjC/include/ZXingObjC/ZXMaxiCodeReader.h new file mode 120000 index 000000000..b750fa7ae --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMaxiCodeReader.h @@ -0,0 +1 @@ +../../maxicode/ZXMaxiCodeReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXModulusGF.h b/ZXingObjC/include/ZXingObjC/ZXModulusGF.h new file mode 120000 index 000000000..e2d9e04db --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXModulusGF.h @@ -0,0 +1 @@ +../../pdf417/decoder/ec/ZXModulusGF.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMonochromeRectangleDetector.h b/ZXingObjC/include/ZXingObjC/ZXMonochromeRectangleDetector.h new file mode 120000 index 000000000..08df88564 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMonochromeRectangleDetector.h @@ -0,0 +1 @@ +../../common/detector/ZXMonochromeRectangleDetector.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMultiDetector.h b/ZXingObjC/include/ZXingObjC/ZXMultiDetector.h new file mode 120000 index 000000000..959df32b8 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMultiDetector.h @@ -0,0 +1 @@ +../../qrcode/multi/detector/ZXMultiDetector.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMultiFormatOneDReader.h b/ZXingObjC/include/ZXingObjC/ZXMultiFormatOneDReader.h new file mode 120000 index 000000000..56dfa4987 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMultiFormatOneDReader.h @@ -0,0 +1 @@ +../../oned/ZXMultiFormatOneDReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMultiFormatReader.h b/ZXingObjC/include/ZXingObjC/ZXMultiFormatReader.h new file mode 120000 index 000000000..6c7b0d7ed --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMultiFormatReader.h @@ -0,0 +1 @@ +../../ZXMultiFormatReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMultiFormatUPCEANReader.h b/ZXingObjC/include/ZXingObjC/ZXMultiFormatUPCEANReader.h new file mode 120000 index 000000000..c6267d0bb --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMultiFormatUPCEANReader.h @@ -0,0 +1 @@ +../../oned/ZXMultiFormatUPCEANReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMultiFormatWriter.h b/ZXingObjC/include/ZXingObjC/ZXMultiFormatWriter.h new file mode 120000 index 000000000..f1c576dcb --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMultiFormatWriter.h @@ -0,0 +1 @@ +../../ZXMultiFormatWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXMultipleBarcodeReader.h b/ZXingObjC/include/ZXingObjC/ZXMultipleBarcodeReader.h new file mode 120000 index 000000000..34ad5cfb7 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXMultipleBarcodeReader.h @@ -0,0 +1 @@ +../../multi/ZXMultipleBarcodeReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXOneDReader.h b/ZXingObjC/include/ZXingObjC/ZXOneDReader.h new file mode 120000 index 000000000..c74ba43c3 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXOneDReader.h @@ -0,0 +1 @@ +../../oned/ZXOneDReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXOneDimensionalCodeWriter.h b/ZXingObjC/include/ZXingObjC/ZXOneDimensionalCodeWriter.h new file mode 120000 index 000000000..e1bc23463 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXOneDimensionalCodeWriter.h @@ -0,0 +1 @@ +../../oned/ZXOneDimensionalCodeWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417.h b/ZXingObjC/include/ZXingObjC/ZXPDF417.h new file mode 120000 index 000000000..e33335b03 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417.h @@ -0,0 +1 @@ +../../pdf417/encoder/ZXPDF417.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417BarcodeMatrix.h b/ZXingObjC/include/ZXingObjC/ZXPDF417BarcodeMatrix.h new file mode 120000 index 000000000..98a00db85 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417BarcodeMatrix.h @@ -0,0 +1 @@ +../../pdf417/encoder/ZXPDF417BarcodeMatrix.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417Common.h b/ZXingObjC/include/ZXingObjC/ZXPDF417Common.h new file mode 120000 index 000000000..dde2fb5d6 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417Common.h @@ -0,0 +1 @@ +../../pdf417/ZXPDF417Common.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417Detector.h b/ZXingObjC/include/ZXingObjC/ZXPDF417Detector.h new file mode 120000 index 000000000..b8cc84ea9 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417Detector.h @@ -0,0 +1 @@ +../../pdf417/detector/ZXPDF417Detector.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417DetectorResult.h b/ZXingObjC/include/ZXingObjC/ZXPDF417DetectorResult.h new file mode 120000 index 000000000..392d97f47 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417DetectorResult.h @@ -0,0 +1 @@ +../../pdf417/detector/ZXPDF417DetectorResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417Dimensions.h b/ZXingObjC/include/ZXingObjC/ZXPDF417Dimensions.h new file mode 120000 index 000000000..7c5badc26 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417Dimensions.h @@ -0,0 +1 @@ +../../pdf417/encoder/ZXPDF417Dimensions.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417ECErrorCorrection.h b/ZXingObjC/include/ZXingObjC/ZXPDF417ECErrorCorrection.h new file mode 120000 index 000000000..5a2cf7b80 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417ECErrorCorrection.h @@ -0,0 +1 @@ +../../pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417Reader.h b/ZXingObjC/include/ZXingObjC/ZXPDF417Reader.h new file mode 120000 index 000000000..b090ecb9c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417Reader.h @@ -0,0 +1 @@ +../../pdf417/ZXPDF417Reader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417ResultMetadata.h b/ZXingObjC/include/ZXingObjC/ZXPDF417ResultMetadata.h new file mode 120000 index 000000000..8f937d9e5 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417ResultMetadata.h @@ -0,0 +1 @@ +../../pdf417/ZXPDF417ResultMetadata.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417ScanningDecoder.h b/ZXingObjC/include/ZXingObjC/ZXPDF417ScanningDecoder.h new file mode 120000 index 000000000..c3aa668c9 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417ScanningDecoder.h @@ -0,0 +1 @@ +../../pdf417/decoder/ZXPDF417ScanningDecoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPDF417Writer.h b/ZXingObjC/include/ZXingObjC/ZXPDF417Writer.h new file mode 120000 index 000000000..77f93e224 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPDF417Writer.h @@ -0,0 +1 @@ +../../pdf417/ZXPDF417Writer.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXParsedResult.h new file mode 120000 index 000000000..252e55b05 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXParsedResultType.h b/ZXingObjC/include/ZXingObjC/ZXParsedResultType.h new file mode 120000 index 000000000..f097d6bb1 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXParsedResultType.h @@ -0,0 +1 @@ +../../client/result/ZXParsedResultType.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPerspectiveTransform.h b/ZXingObjC/include/ZXingObjC/ZXPerspectiveTransform.h new file mode 120000 index 000000000..b26c8b1c0 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPerspectiveTransform.h @@ -0,0 +1 @@ +../../common/ZXPerspectiveTransform.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXPlanarYUVLuminanceSource.h b/ZXingObjC/include/ZXingObjC/ZXPlanarYUVLuminanceSource.h new file mode 120000 index 000000000..3d5d329ba --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXPlanarYUVLuminanceSource.h @@ -0,0 +1 @@ +../../core/ZXPlanarYUVLuminanceSource.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXProductParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXProductParsedResult.h new file mode 120000 index 000000000..9e9cc7e45 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXProductParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXProductParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXProductResultParser.h b/ZXingObjC/include/ZXingObjC/ZXProductResultParser.h new file mode 120000 index 000000000..44c69bc9f --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXProductResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXProductResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCode.h b/ZXingObjC/include/ZXingObjC/ZXQRCode.h new file mode 120000 index 000000000..030577ed4 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCode.h @@ -0,0 +1 @@ +../../qrcode/encoder/ZXQRCode.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeAlignmentPattern.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeAlignmentPattern.h new file mode 120000 index 000000000..4ceccfb98 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeAlignmentPattern.h @@ -0,0 +1 @@ +../../qrcode/detector/ZXQRCodeAlignmentPattern.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeDecoder.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeDecoder.h new file mode 120000 index 000000000..3868bbb0f --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeDecoder.h @@ -0,0 +1 @@ +../../qrcode/decoder/ZXQRCodeDecoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeDecoderMetaData.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeDecoderMetaData.h new file mode 120000 index 000000000..dae05fa4c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeDecoderMetaData.h @@ -0,0 +1 @@ +../../qrcode/decoder/ZXQRCodeDecoderMetaData.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeDetector.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeDetector.h new file mode 120000 index 000000000..6237a73f7 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeDetector.h @@ -0,0 +1 @@ +../../qrcode/detector/ZXQRCodeDetector.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeEncoder.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeEncoder.h new file mode 120000 index 000000000..9a03dbdbf --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeEncoder.h @@ -0,0 +1 @@ +../../qrcode/encoder/ZXQRCodeEncoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeErrorCorrectionLevel.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeErrorCorrectionLevel.h new file mode 120000 index 000000000..d2963d3c8 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeErrorCorrectionLevel.h @@ -0,0 +1 @@ +../../qrcode/decoder/ZXQRCodeErrorCorrectionLevel.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeFinderPattern.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeFinderPattern.h new file mode 120000 index 000000000..2619f76f5 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeFinderPattern.h @@ -0,0 +1 @@ +../../qrcode/detector/ZXQRCodeFinderPattern.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeFinderPatternFinder.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeFinderPatternFinder.h new file mode 120000 index 000000000..a32f9a10b --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeFinderPatternFinder.h @@ -0,0 +1 @@ +../../qrcode/detector/ZXQRCodeFinderPatternFinder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeFinderPatternInfo.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeFinderPatternInfo.h new file mode 120000 index 000000000..1fb0dfc45 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeFinderPatternInfo.h @@ -0,0 +1 @@ +../../qrcode/detector/ZXQRCodeFinderPatternInfo.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeMode.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeMode.h new file mode 120000 index 000000000..af0608d31 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeMode.h @@ -0,0 +1 @@ +../../qrcode/decoder/ZXQRCodeMode.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeMultiReader.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeMultiReader.h new file mode 120000 index 000000000..79c5f8924 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeMultiReader.h @@ -0,0 +1 @@ +../../qrcode/multi/ZXQRCodeMultiReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeReader.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeReader.h new file mode 120000 index 000000000..c711708de --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeReader.h @@ -0,0 +1 @@ +../../qrcode/ZXQRCodeReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeVersion.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeVersion.h new file mode 120000 index 000000000..99d58fecc --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeVersion.h @@ -0,0 +1 @@ +../../qrcode/decoder/ZXQRCodeVersion.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXQRCodeWriter.h b/ZXingObjC/include/ZXingObjC/ZXQRCodeWriter.h new file mode 120000 index 000000000..d89d45b17 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXQRCodeWriter.h @@ -0,0 +1 @@ +../../qrcode/ZXQRCodeWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXRGBLuminanceSource.h b/ZXingObjC/include/ZXingObjC/ZXRGBLuminanceSource.h new file mode 120000 index 000000000..37684464f --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXRGBLuminanceSource.h @@ -0,0 +1 @@ +../../core/ZXRGBLuminanceSource.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXRSS14Reader.h b/ZXingObjC/include/ZXingObjC/ZXRSS14Reader.h new file mode 120000 index 000000000..fd819a5de --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXRSS14Reader.h @@ -0,0 +1 @@ +../../oned/rss/ZXRSS14Reader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXRSSDataCharacter.h b/ZXingObjC/include/ZXingObjC/ZXRSSDataCharacter.h new file mode 120000 index 000000000..da59379dc --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXRSSDataCharacter.h @@ -0,0 +1 @@ +../../oned/rss/ZXRSSDataCharacter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXRSSExpandedReader.h b/ZXingObjC/include/ZXingObjC/ZXRSSExpandedReader.h new file mode 120000 index 000000000..99ee989ab --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXRSSExpandedReader.h @@ -0,0 +1 @@ +../../oned/rss/expanded/ZXRSSExpandedReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXRSSFinderPattern.h b/ZXingObjC/include/ZXingObjC/ZXRSSFinderPattern.h new file mode 120000 index 000000000..94bb17bf5 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXRSSFinderPattern.h @@ -0,0 +1 @@ +../../oned/rss/ZXRSSFinderPattern.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXRSSUtils.h b/ZXingObjC/include/ZXingObjC/ZXRSSUtils.h new file mode 120000 index 000000000..c7877b782 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXRSSUtils.h @@ -0,0 +1 @@ +../../oned/rss/ZXRSSUtils.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXReader.h b/ZXingObjC/include/ZXingObjC/ZXReader.h new file mode 120000 index 000000000..5721d09fd --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXReader.h @@ -0,0 +1 @@ +../../core/ZXReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXReedSolomonDecoder.h b/ZXingObjC/include/ZXingObjC/ZXReedSolomonDecoder.h new file mode 120000 index 000000000..4a766b032 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXReedSolomonDecoder.h @@ -0,0 +1 @@ +../../common/reedsolomon/ZXReedSolomonDecoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXReedSolomonEncoder.h b/ZXingObjC/include/ZXingObjC/ZXReedSolomonEncoder.h new file mode 120000 index 000000000..9ad0cbec5 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXReedSolomonEncoder.h @@ -0,0 +1 @@ +../../common/reedsolomon/ZXReedSolomonEncoder.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXResult.h b/ZXingObjC/include/ZXingObjC/ZXResult.h new file mode 120000 index 000000000..93946903d --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXResult.h @@ -0,0 +1 @@ +../../core/ZXResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXResultMetadataType.h b/ZXingObjC/include/ZXingObjC/ZXResultMetadataType.h new file mode 120000 index 000000000..96056de7c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXResultMetadataType.h @@ -0,0 +1 @@ +../../core/ZXResultMetadataType.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXResultParser.h b/ZXingObjC/include/ZXingObjC/ZXResultParser.h new file mode 120000 index 000000000..6e73f9c68 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXResultPoint.h b/ZXingObjC/include/ZXingObjC/ZXResultPoint.h new file mode 120000 index 000000000..84e1de693 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXResultPoint.h @@ -0,0 +1 @@ +../../core/ZXResultPoint.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXResultPointCallback.h b/ZXingObjC/include/ZXingObjC/ZXResultPointCallback.h new file mode 120000 index 000000000..91f6827e7 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXResultPointCallback.h @@ -0,0 +1 @@ +../../core/ZXResultPointCallback.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXSMSMMSResultParser.h b/ZXingObjC/include/ZXingObjC/ZXSMSMMSResultParser.h new file mode 120000 index 000000000..2cefaba07 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXSMSMMSResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXSMSMMSResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXSMSParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXSMSParsedResult.h new file mode 120000 index 000000000..210a03736 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXSMSParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXSMSParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXSMSTOMMSTOResultParser.h b/ZXingObjC/include/ZXingObjC/ZXSMSTOMMSTOResultParser.h new file mode 120000 index 000000000..9a3c3fa1a --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXSMSTOMMSTOResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXSMSTOMMSTOResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXSMTPResultParser.h b/ZXingObjC/include/ZXingObjC/ZXSMTPResultParser.h new file mode 120000 index 000000000..bff56bcbb --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXSMTPResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXSMTPResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXStringUtils.h b/ZXingObjC/include/ZXingObjC/ZXStringUtils.h new file mode 120000 index 000000000..06bcbfffd --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXStringUtils.h @@ -0,0 +1 @@ +../../common/ZXStringUtils.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXTelParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXTelParsedResult.h new file mode 120000 index 000000000..8ee1ab6dc --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXTelParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXTelParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXTelResultParser.h b/ZXingObjC/include/ZXingObjC/ZXTelResultParser.h new file mode 120000 index 000000000..1cccf3372 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXTelResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXTelResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXTextParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXTextParsedResult.h new file mode 120000 index 000000000..8236c2193 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXTextParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXTextParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXUPCAReader.h b/ZXingObjC/include/ZXingObjC/ZXUPCAReader.h new file mode 120000 index 000000000..51289400b --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXUPCAReader.h @@ -0,0 +1 @@ +../../oned/ZXUPCAReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXUPCAWriter.h b/ZXingObjC/include/ZXingObjC/ZXUPCAWriter.h new file mode 120000 index 000000000..ee9e20b1b --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXUPCAWriter.h @@ -0,0 +1 @@ +../../oned/ZXUPCAWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXUPCEANReader.h b/ZXingObjC/include/ZXingObjC/ZXUPCEANReader.h new file mode 120000 index 000000000..3073d497e --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXUPCEANReader.h @@ -0,0 +1 @@ +../../oned/ZXUPCEANReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXUPCEANWriter.h b/ZXingObjC/include/ZXingObjC/ZXUPCEANWriter.h new file mode 120000 index 000000000..4d54ea719 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXUPCEANWriter.h @@ -0,0 +1 @@ +../../oned/ZXUPCEANWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXUPCEReader.h b/ZXingObjC/include/ZXingObjC/ZXUPCEReader.h new file mode 120000 index 000000000..9d34690d5 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXUPCEReader.h @@ -0,0 +1 @@ +../../oned/ZXUPCEReader.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXUPCEWriter.h b/ZXingObjC/include/ZXingObjC/ZXUPCEWriter.h new file mode 120000 index 000000000..5c603aca7 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXUPCEWriter.h @@ -0,0 +1 @@ +../../oned/ZXUPCEWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXURIParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXURIParsedResult.h new file mode 120000 index 000000000..763b0ef11 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXURIParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXURIParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXURIResultParser.h b/ZXingObjC/include/ZXingObjC/ZXURIResultParser.h new file mode 120000 index 000000000..364af1be4 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXURIResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXURIResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXURLTOResultParser.h b/ZXingObjC/include/ZXingObjC/ZXURLTOResultParser.h new file mode 120000 index 000000000..1ff0f14c4 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXURLTOResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXURLTOResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXVCardResultParser.h b/ZXingObjC/include/ZXingObjC/ZXVCardResultParser.h new file mode 120000 index 000000000..6207cb728 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXVCardResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXVCardResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXVEventResultParser.h b/ZXingObjC/include/ZXingObjC/ZXVEventResultParser.h new file mode 120000 index 000000000..dd92480ff --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXVEventResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXVEventResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXVINParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXVINParsedResult.h new file mode 120000 index 000000000..8822e657f --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXVINParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXVINParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXVINResultParser.h b/ZXingObjC/include/ZXingObjC/ZXVINResultParser.h new file mode 120000 index 000000000..b4c346983 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXVINResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXVINResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXWhiteRectangleDetector.h b/ZXingObjC/include/ZXingObjC/ZXWhiteRectangleDetector.h new file mode 120000 index 000000000..8b51cae18 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXWhiteRectangleDetector.h @@ -0,0 +1 @@ +../../common/detector/ZXWhiteRectangleDetector.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXWifiParsedResult.h b/ZXingObjC/include/ZXingObjC/ZXWifiParsedResult.h new file mode 120000 index 000000000..0e3b74148 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXWifiParsedResult.h @@ -0,0 +1 @@ +../../client/result/ZXWifiParsedResult.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXWifiResultParser.h b/ZXingObjC/include/ZXingObjC/ZXWifiResultParser.h new file mode 120000 index 000000000..91fa0ee1e --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXWifiResultParser.h @@ -0,0 +1 @@ +../../client/result/ZXWifiResultParser.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXWriter.h b/ZXingObjC/include/ZXingObjC/ZXWriter.h new file mode 120000 index 000000000..0ac885a4c --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXWriter.h @@ -0,0 +1 @@ +../../core/ZXWriter.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXingObjC.h b/ZXingObjC/include/ZXingObjC/ZXingObjC.h new file mode 120000 index 000000000..af79084d8 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXingObjC.h @@ -0,0 +1 @@ +../../ZXingObjC.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXingObjCAztec.h b/ZXingObjC/include/ZXingObjC/ZXingObjCAztec.h new file mode 120000 index 000000000..36b96f360 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXingObjCAztec.h @@ -0,0 +1 @@ +../../aztec/ZXingObjCAztec.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXingObjCCore.h b/ZXingObjC/include/ZXingObjC/ZXingObjCCore.h new file mode 120000 index 000000000..f75d17e64 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXingObjCCore.h @@ -0,0 +1 @@ +../../core/ZXingObjCCore.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXingObjCDataMatrix.h b/ZXingObjC/include/ZXingObjC/ZXingObjCDataMatrix.h new file mode 120000 index 000000000..c4bf3193a --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXingObjCDataMatrix.h @@ -0,0 +1 @@ +../../datamatrix/ZXingObjCDataMatrix.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXingObjCMaxiCode.h b/ZXingObjC/include/ZXingObjC/ZXingObjCMaxiCode.h new file mode 120000 index 000000000..6d40b19d7 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXingObjCMaxiCode.h @@ -0,0 +1 @@ +../../maxicode/ZXingObjCMaxiCode.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXingObjCOneD.h b/ZXingObjC/include/ZXingObjC/ZXingObjCOneD.h new file mode 120000 index 000000000..7e55e0cec --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXingObjCOneD.h @@ -0,0 +1 @@ +../../oned/ZXingObjCOneD.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXingObjCPDF417.h b/ZXingObjC/include/ZXingObjC/ZXingObjCPDF417.h new file mode 120000 index 000000000..859aa49f9 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXingObjCPDF417.h @@ -0,0 +1 @@ +../../pdf417/ZXingObjCPDF417.h \ No newline at end of file diff --git a/ZXingObjC/include/ZXingObjC/ZXingObjCQRCode.h b/ZXingObjC/include/ZXingObjC/ZXingObjCQRCode.h new file mode 120000 index 000000000..4423efe90 --- /dev/null +++ b/ZXingObjC/include/ZXingObjC/ZXingObjCQRCode.h @@ -0,0 +1 @@ +../../qrcode/ZXingObjCQRCode.h \ No newline at end of file diff --git a/ZXingObjC/include/module.modulemap b/ZXingObjC/include/module.modulemap new file mode 100644 index 000000000..3d66496c5 --- /dev/null +++ b/ZXingObjC/include/module.modulemap @@ -0,0 +1,5 @@ +module ZXingObjC { + umbrella header "ZXingObjC/ZXingObjC.h" + export * + module * { export * } +} diff --git a/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m index d2d95b63c..120c2a54b 100644 --- a/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m +++ b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m @@ -36,30 +36,32 @@ const unichar GS = 0x001D; const unichar RS = 0x001E; -const unichar SETS[1][383] = { - '\n', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', ECI, FS, GS, RS, NS, ' ', PAD, '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', - '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', SHIFTB, SHIFTC, SHIFTD, SHIFTE, LATCHB, - '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' , 'q', 'r', 's', 't', 'u', 'v', 'w', - 'x', 'y', 'z', ECI, FS, GS, RS, NS, '{', PAD, '}', '~', 0x007F, ';', '<', '=', '>', '?', '[', '\\', ']', '^', '_', ' ', - ',', '.', '/', ':', '@', '!', '|', PAD, TWOSHIFTA, THREESHIFTA, PAD, SHIFTA, SHIFTC, SHIFTD, SHIFTE, LATCHA, - 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, - 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, ECI, FS, GS, RS, 0x00DB, - 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00AA, 0x00AC, 0x00B1, 0x00B2, 0x00B3, 0x00B5, 0x00B9, 0x00BA, 0x00BC, 0x00BD, 0x00BE, - 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, LATCHA, ' ', LOCK, SHIFTD, SHIFTE, LATCHB, - 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, - 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, ECI, FS, GS, RS, NS, - 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, 0x00A1, 0x00A8, 0x00AB, 0x00AF, 0x00B0, 0x00B4, 0x00B7, 0x00B8, 0x00BB, 0x00BF, - 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, LATCHA, ' ', SHIFTC, LOCK, SHIFTE, - LATCHB, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, '\n', 0x000B, 0x000C, '\r', - 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, ECI, PAD, PAD, - 0x001B, NS, FS, GS, RS, 0x001F, 0x009F, 0x00A0, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A9, 0x00AD, 0x00AE, - 0x00B6, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, LATCHA, ' ', SHIFTC, SHIFTD, LOCK, - LATCHB, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, '\n', 0x000B, 0x000C, '\r', - 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, - 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, '"', 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, - 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, - 0x003B, 0x003C, 0x003D, 0x003E, 0x003F +const unichar SETS[6][383] = { + { '\n', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', ECI, FS, GS, RS, NS, ' ', PAD, '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', + '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', SHIFTB, SHIFTC, SHIFTD, SHIFTE, LATCHB }, + { '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' , 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', ECI, FS, GS, RS, NS, '{', PAD, '}', '~', 0x007F, ';', '<', '=', '>', '?', '[', '\\', ']', '^', '_', ' ', + ',', '.', '/', ':', '@', '!', '|', PAD, TWOSHIFTA, THREESHIFTA, PAD, SHIFTA, SHIFTC, SHIFTD, SHIFTE, LATCHA }, + { 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, + 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, ECI, FS, GS, RS, 0x00DB, + 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00AA, 0x00AC, 0x00B1, 0x00B2, 0x00B3, 0x00B5, 0x00B9, 0x00BA, 0x00BC, 0x00BD, 0x00BE, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, LATCHA, ' ', LOCK, SHIFTD, SHIFTE, LATCHB }, + { 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, + 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, ECI, FS, GS, RS, NS, + 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, 0x00A1, 0x00A8, 0x00AB, 0x00AF, 0x00B0, 0x00B4, 0x00B7, 0x00B8, 0x00BB, 0x00BF, + 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, LATCHA, ' ', SHIFTC, LOCK, SHIFTE, + LATCHB }, + { 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, '\n', 0x000B, 0x000C, '\r', + 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, ECI, PAD, PAD, + 0x001B, NS, FS, GS, RS, 0x001F, 0x009F, 0x00A0, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A9, 0x00AD, 0x00AE, + 0x00B6, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, LATCHA, ' ', SHIFTC, SHIFTD, LOCK, + LATCHB }, + { 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, '\n', 0x000B, 0x000C, '\r', + 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, + 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, '"', 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, + 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, + 0x003B, 0x003C, 0x003D, 0x003E, 0x003F } }; @implementation ZXMaxiCodeDecodedBitStreamParser diff --git a/ZXingObjC/multi/ZXByQuadrantReader.m b/ZXingObjC/multi/ZXByQuadrantReader.m index 22f009f68..313514521 100644 --- a/ZXingObjC/multi/ZXByQuadrantReader.m +++ b/ZXingObjC/multi/ZXByQuadrantReader.m @@ -113,7 +113,9 @@ - (void)makeAbsolute:(NSMutableArray *)points leftOffset:(int)leftOffset topOffs if (points) { for (int i = 0; i < points.count; i++) { ZXResultPoint *relative = points[i]; - points[i] = [[ZXResultPoint alloc] initWithX:relative.x + leftOffset y:relative.y + topOffset]; + if (relative) { + points[i] = [[ZXResultPoint alloc] initWithX:relative.x + leftOffset y:relative.y + topOffset]; + } } } } diff --git a/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m b/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m index f3d6875aa..39511f848 100644 --- a/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m +++ b/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m @@ -24,7 +24,7 @@ @interface ZXGenericMultipleBarcodeReader () -@property (nonatomic, weak, readonly) id delegate; +@property (nonatomic, readonly) id delegate; @end @@ -130,7 +130,7 @@ - (ZXResult *)translateResultPoints:(ZXResult *)result xOffset:(int)xOffset yOff } } - ZXResult *newResult = [ZXResult resultWithText:result.text rawBytes:result.rawBytes resultPoints:newResultPoints format:result.barcodeFormat]; + ZXResult *newResult = [ZXResult resultWithText:result.text rawBytes:result.rawBytes numBits:result.numBits resultPoints:newResultPoints format:result.barcodeFormat]; [newResult putAllMetadata:result.resultMetadata]; return newResult; } diff --git a/ZXingObjC/oned/ZXCode128Reader.h b/ZXingObjC/oned/ZXCode128Reader.h index ff0a0c81b..69b9471fe 100644 --- a/ZXingObjC/oned/ZXCode128Reader.h +++ b/ZXingObjC/oned/ZXCode128Reader.h @@ -18,8 +18,10 @@ extern const int ZX_CODE128_CODE_PATTERNS[][7]; +extern const int ZX_CODE128_CODE_START_A; extern const int ZX_CODE128_CODE_START_B; extern const int ZX_CODE128_CODE_START_C; +extern const int ZX_CODE128_CODE_CODE_A; extern const int ZX_CODE128_CODE_CODE_B; extern const int ZX_CODE128_CODE_CODE_C; extern const int ZX_CODE128_CODE_STOP; diff --git a/ZXingObjC/oned/ZXCode128Reader.m b/ZXingObjC/oned/ZXCode128Reader.m index 90d25743f..1b9be88c5 100644 --- a/ZXingObjC/oned/ZXCode128Reader.m +++ b/ZXingObjC/oned/ZXCode128Reader.m @@ -236,7 +236,7 @@ - (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHint int startCode = startPatternInfo.array[2]; int codeSet; - NSMutableArray *rawCodes = [NSMutableArray arrayWithObject:@(startCode)]; + NSMutableArray *rawCodes = [@[@(startCode)] mutableCopy]; switch (startCode) { case ZX_CODE128_CODE_START_A: @@ -286,13 +286,11 @@ - (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHint [rawCodes addObject:@(code)]; - // Remember whether the last code was printable or not (excluding ZX_CODE128_CODE_STOP) + // Remember whether the last code was printable or not + // and Add to checksum computation + // (excluding ZX_CODE128_CODE_STOP) if (code != ZX_CODE128_CODE_STOP) { lastCharacterWasPrintable = YES; - } - - // Add to checksum computation (if not ZX_CODE128_CODE_STOP of course) - if (code != ZX_CODE128_CODE_STOP) { multiplier++; checksumTotal += multiplier * code; } @@ -310,13 +308,23 @@ - (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHint return nil; } + bool wasAlreadyAppended = NO; + if(hints.substitutions != nil && hints.substitutions.count > 0) { + NSString *signCandidate = [hints.substitutions valueForKey:[NSString stringWithFormat:@"%d", code]]; + if (signCandidate != nil) { + // Substitute + [result appendString:signCandidate]; + wasAlreadyAppended = YES; + } + } + switch (codeSet) { case ZX_CODE128_CODE_CODE_A: if (code < 64) { if (shiftUpperMode == upperMode) { - [result appendFormat:@"%C", (unichar)(' ' + code)]; + if(!wasAlreadyAppended) [result appendFormat:@"%C", (unichar)(' ' + code)]; } else { - [result appendFormat:@"%C", (unichar)(' ' + code + 128)]; + if(!wasAlreadyAppended) [result appendFormat:@"%C", (unichar)(' ' + code + 128)]; } shiftUpperMode = NO; } else if (code < 96) { @@ -380,9 +388,9 @@ - (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHint case ZX_CODE128_CODE_CODE_B: if (code < 96) { if (shiftUpperMode == upperMode) { - [result appendFormat:@"%C", (unichar)(' ' + code)]; + if(!wasAlreadyAppended) [result appendFormat:@"%C", (unichar)(' ' + code)]; } else { - [result appendFormat:@"%C", (unichar)(' ' + code + 128)]; + if(!wasAlreadyAppended) [result appendFormat:@"%C", (unichar)(' ' + code + 128)]; } shiftUpperMode = NO; } else { @@ -436,10 +444,12 @@ - (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHint break; case ZX_CODE128_CODE_CODE_C: if (code < 100) { - if (code < 10) { - [result appendString:@"0"]; + if(!wasAlreadyAppended) { + if (code < 10) { + [result appendString:@"0"]; + } + [result appendFormat:@"%d", code]; } - [result appendFormat:@"%d", code]; } else { if (code != ZX_CODE128_CODE_STOP) { lastCharacterWasPrintable = NO; @@ -470,6 +480,9 @@ - (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHint } } break; + + default: + break; } // Unshift back to another code set if we were shifted diff --git a/ZXingObjC/oned/ZXCode128Writer.m b/ZXingObjC/oned/ZXCode128Writer.m index 77656c779..92b47aeba 100644 --- a/ZXingObjC/oned/ZXCode128Writer.m +++ b/ZXingObjC/oned/ZXCode128Writer.m @@ -24,6 +24,14 @@ const unichar ZX_CODE128_ESCAPE_FNC_3 = L'\u00f3'; const unichar ZX_CODE128_ESCAPE_FNC_4 = L'\u00f4'; +// Results of minimal lookahead for Code C +typedef enum { + ZXCTypeUncodable = 0, + ZXCTypeOneDigit, + ZXCTypeTwoDigits, + ZXCTypeFNC1 +} ZXCType; + @implementation ZXCode128Writer - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error { @@ -42,16 +50,17 @@ - (ZXBoolArray *)encode:(NSString *)contents { // Check content for (int i = 0; i < length; i++) { unichar c = [contents characterAtIndex:i]; - if (c < ' ' || c > '~') { - switch (c) { - case ZX_CODE128_ESCAPE_FNC_1: - case ZX_CODE128_ESCAPE_FNC_2: - case ZX_CODE128_ESCAPE_FNC_3: - case ZX_CODE128_ESCAPE_FNC_4: - break; - default: + switch (c) { + case ZX_CODE128_ESCAPE_FNC_1: + case ZX_CODE128_ESCAPE_FNC_2: + case ZX_CODE128_ESCAPE_FNC_3: + case ZX_CODE128_ESCAPE_FNC_4: + break; + default: + if (c > 127) { + // support for FNC4 isn't implemented, no full Latin-1 character set available at the moment [NSException raise:NSInvalidArgumentException format:@"Bad character in input: %C", c]; - } + } } } @@ -63,13 +72,7 @@ - (ZXBoolArray *)encode:(NSString *)contents { while (position < length) { //Select code to use - int requiredDigitCount = codeSet == ZX_CODE128_CODE_CODE_C ? 2 : 4; - int newCodeSet; - if ([self isDigits:contents start:position length:requiredDigitCount]) { - newCodeSet = ZX_CODE128_CODE_CODE_C; - } else { - newCodeSet = ZX_CODE128_CODE_CODE_B; - } + int newCodeSet = [self chooseCodeFrom:contents position:position oldCode:codeSet]; //Get the pattern index int patternIndex; @@ -87,13 +90,24 @@ - (ZXBoolArray *)encode:(NSString *)contents { patternIndex = ZX_CODE128_CODE_FNC_3; break; case ZX_CODE128_ESCAPE_FNC_4: - patternIndex = ZX_CODE128_CODE_FNC_4_B; // FIXME if this ever outputs Code A + if (codeSet == ZX_CODE128_CODE_CODE_A) { + patternIndex = ZX_CODE128_CODE_FNC_4_A; + } else { + patternIndex = ZX_CODE128_CODE_FNC_4_B; + } break; default: // Then handle normal characters otherwise - if (codeSet == ZX_CODE128_CODE_CODE_B) { + if (codeSet == ZX_CODE128_CODE_CODE_A) { + patternIndex = [contents characterAtIndex:position] - ' '; + if (patternIndex < 0) { + // everything below a space character comes behind the underscore in the code patterns table + patternIndex += '`'; + } + } else if (codeSet == ZX_CODE128_CODE_CODE_B) { patternIndex = [contents characterAtIndex:position] - ' '; - } else { // CODE_CODE_C + } else { + // CODE_CODE_C patternIndex = [[contents substringWithRange:NSMakeRange(position, 2)] intValue]; position++; // Also incremented below } @@ -104,7 +118,9 @@ - (ZXBoolArray *)encode:(NSString *)contents { // Do we have a code set? if (codeSet == 0) { // No, we don't have a code set - if (newCodeSet == ZX_CODE128_CODE_CODE_B) { + if (newCodeSet == ZX_CODE128_CODE_CODE_A) { + patternIndex = ZX_CODE128_CODE_START_A; + } else if (newCodeSet == ZX_CODE128_CODE_CODE_B) { patternIndex = ZX_CODE128_CODE_START_B; } else { // CODE_CODE_C @@ -170,19 +186,88 @@ - (ZXBoolArray *)encode:(NSString *)contents { return result; } -- (BOOL)isDigits:(NSString *)value start:(int)start length:(unsigned int)length { - int end = start + length; +- (ZXCType)findCTypeIn:(NSString *)value start:(int)start { int last = (int)[value length]; - for (int i = start; i < end && i < last; i++) { - unichar c = [value characterAtIndex:i]; - if (c < '0' || c > '9') { - if (c != ZX_CODE128_ESCAPE_FNC_1) { - return NO; + if (start >= last) { + return ZXCTypeUncodable; + } + unichar c = [value characterAtIndex:start]; + if (c == ZX_CODE128_ESCAPE_FNC_1) { + return ZXCTypeFNC1; + } + if (c < '0' || c > '9') { + return ZXCTypeUncodable; + } + if (start + 1 >= last) { + return ZXCTypeOneDigit; + } + c = [value characterAtIndex:start + 1]; + if (c < '0' || c > '9') { + return ZXCTypeOneDigit; + } + return ZXCTypeTwoDigits; +} + +- (int)chooseCodeFrom:(NSString *)contents position:(int)position oldCode:(int)oldCode { + ZXCType lookahead = [self findCTypeIn:contents start:position]; + if (lookahead == ZXCTypeOneDigit) { + if (oldCode == ZX_CODE128_CODE_CODE_A) { + return ZX_CODE128_CODE_CODE_A; + } + return ZX_CODE128_CODE_CODE_B; + } + if (lookahead == ZXCTypeUncodable) { + if (position < contents.length) { + unichar c = [contents characterAtIndex:position]; + if (c < ' ' || (oldCode == ZX_CODE128_CODE_CODE_A && (c < '`' || (c >= ZX_CODE128_ESCAPE_FNC_1 && c <= ZX_CODE128_ESCAPE_FNC_4)))) { + // can continue in code A, encodes ASCII 0 to 95 or FNC1 to FNC4 + return ZX_CODE128_CODE_CODE_A; } - end++; // ignore FNC_1 } + return ZX_CODE128_CODE_CODE_B; // no choice + } + if (oldCode == ZX_CODE128_CODE_CODE_A && lookahead == ZXCTypeFNC1) { + return ZX_CODE128_CODE_CODE_A; + } + if (oldCode == ZX_CODE128_CODE_CODE_C) { // can continue in code C + return ZX_CODE128_CODE_CODE_C; + } + if (oldCode == ZX_CODE128_CODE_CODE_B) { + if (lookahead == ZXCTypeFNC1) { + return ZX_CODE128_CODE_CODE_B; // can continue in code B + } + // Seen two consecutive digits, see what follows + lookahead = [self findCTypeIn:contents start:position + 2]; + if (lookahead == ZXCTypeUncodable || lookahead == ZXCTypeOneDigit) { + return ZX_CODE128_CODE_CODE_B; // not worth switching now + } + if (lookahead == ZXCTypeFNC1) { // two digits, then FNC_1... + lookahead = [self findCTypeIn:contents start:position + 3]; + if (lookahead == ZXCTypeTwoDigits) { // then two more digits, switch + return ZX_CODE128_CODE_CODE_C; + } else { + return ZX_CODE128_CODE_CODE_B; // otherwise not worth switching + } + } + // At this point, there are at least 4 consecutive digits. + // Look ahead to choose whether to switch now or on the next round. + int index = position + 4; + while ((lookahead = [self findCTypeIn:contents start:index]) == ZXCTypeTwoDigits) { + index += 2; + } + if (lookahead == ZXCTypeOneDigit) { // odd number of digits, switch later + return ZX_CODE128_CODE_CODE_B; + } + return ZX_CODE128_CODE_CODE_C; // even number of digits, switch now + } + // Here oldCode == 0, which means we are choosing the initial code + if (lookahead == ZXCTypeFNC1) { // ignore FNC_1 + lookahead = [self findCTypeIn:contents start:position + 1]; + } + if (lookahead == ZXCTypeTwoDigits) { // at least two digits, start in code C + return ZX_CODE128_CODE_CODE_C; } - return end <= last; // end > last if we've run out of string + return ZX_CODE128_CODE_CODE_B; } @end diff --git a/ZXingObjC/oned/ZXCode39Reader.h b/ZXingObjC/oned/ZXCode39Reader.h index d6211487e..ff1381b22 100644 --- a/ZXingObjC/oned/ZXCode39Reader.h +++ b/ZXingObjC/oned/ZXCode39Reader.h @@ -19,11 +19,12 @@ extern unichar ZX_CODE39_ALPHABET[]; extern NSString *ZX_CODE39_ALPHABET_STRING; extern const int ZX_CODE39_CHARACTER_ENCODINGS[]; +extern const int ZX_CODE39_ASTERISK_ENCODING; @class ZXDecodeHints, ZXResult; /** - * Decodes Code 39 barcodes. This does not support "Full ASCII Code 39" yet. + * Decodes Code 39 barcodes. Supports "Full ASCII Code 39" if USE_CODE_39_EXTENDED_MODE is set. */ @interface ZXCode39Reader : ZXOneDReader diff --git a/ZXingObjC/oned/ZXCode39Reader.m b/ZXingObjC/oned/ZXCode39Reader.m index 944a390a6..c2558e27d 100644 --- a/ZXingObjC/oned/ZXCode39Reader.m +++ b/ZXingObjC/oned/ZXCode39Reader.m @@ -23,7 +23,7 @@ unichar ZX_CODE39_ALPHABET[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', '-', '.', ' ', '*', '$', '/', '+', '%'}; + 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%'}; NSString *ZX_CODE39_ALPHABET_STRING = nil; @@ -36,8 +36,8 @@ 0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, // 0-9 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, // A-J 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, // K-T - 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x094, // U-* - 0x0A8, 0x0A2, 0x08A, 0x02A // $-% + 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x0A8, // U-$ + 0x0A2, 0x08A, 0x02A // /-% }; const int ZX_CODE39_ASTERISK_ENCODING = 0x094; @@ -114,14 +114,17 @@ - (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHint // Read off white space nextStart = [row nextSet:nextStart]; } while (decodedChar != '*'); - [result deleteCharactersInRange:NSMakeRange([result length] - 1, 1)]; + [result deleteCharactersInRange:NSMakeRange([result length] - 1, 1)]; // remove asterisk + // Look for whitespace after pattern: int lastPatternSize = 0; for (int i = 0; i < theCounters.length; i++) { lastPatternSize += theCounters.array[i]; } int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize; - if (nextStart != end && (whiteSpaceAfterEnd * 2) < lastPatternSize) { + // If 50% of last pattern size, following last pattern, is not whitespace, fail + // (but if it's whitespace to the very end of the image, that's OK) + if (nextStart != end && (whiteSpaceAfterEnd << 1) < lastPatternSize) { if (error) *error = ZXNotFoundErrorInstance(); return nil; } @@ -181,6 +184,7 @@ - (ZXIntArray *)findAsteriskPattern:(ZXBitArray *)row counters:(ZXIntArray *)cou array[counterPosition]++; } else { if (counterPosition == patternLength - 1) { + // Look for whitespace before start pattern, >= 50% of width of start pattern if ([self toNarrowWidePattern:counters] == ZX_CODE39_ASTERISK_ENCODING && [row isRange:MAX(0, patternStart - ((i - patternStart) / 2)) end:patternStart value:NO]) { return [[ZXIntArray alloc] initWithInts:patternLength, i, -1]; @@ -203,6 +207,8 @@ - (ZXIntArray *)findAsteriskPattern:(ZXBitArray *)row counters:(ZXIntArray *)cou return nil; } +// For efficiency, returns -1 on failure. Not throwing here saved as many as 700 exceptions +// per image when using some of our blackbox images. - (int)toNarrowWidePattern:(ZXIntArray *)counters { int numCounters = counters.length; int maxNarrowCounter = 0; @@ -229,10 +235,14 @@ - (int)toNarrowWidePattern:(ZXIntArray *)counters { } } if (wideCounters == 3) { + // Found 3 wide counters, but are they close enough in width? + // We can perform a cheap, conservative check to see if any individual + // counter is more than 1.5 times the average: for (int i = 0; i < numCounters && wideCounters > 0; i++) { int counter = array[i]; if (array[i] > maxNarrowCounter) { wideCounters--; + // totalWideCountersWidth = 3 * average, so this checks if counter >= 3/2 * average if ((counter * 2) >= totalWideCountersWidth) { return -1; } @@ -250,6 +260,9 @@ - (unichar)patternToChar:(int)pattern { return ZX_CODE39_ALPHABET[i]; } } + if (pattern == ZX_CODE39_ASTERISK_ENCODING) { + return '*'; + } return 0; } @@ -264,40 +277,58 @@ - (NSString *)decodeExtended:(NSMutableString *)encoded { unichar decodedChar = '\0'; switch (c) { - case '+': - if (next >= 'A' && next <= 'Z') { - decodedChar = (unichar)(next + 32); - } else { - return nil; - } - break; - case '$': - if (next >= 'A' && next <= 'Z') { - decodedChar = (unichar)(next - 64); - } else { - return nil; - } - break; - case '%': - if (next >= 'A' && next <= 'E') { - decodedChar = (unichar)(next - 38); - } else if (next >= 'F' && next <= 'W') { - decodedChar = (unichar)(next - 11); - } else { - return nil; - } - break; - case '/': - if (next >= 'A' && next <= 'O') { - decodedChar = (unichar)(next - 32); - } else if (next == 'Z') { - decodedChar = ':'; - } else { - return nil; - } - break; + case '+': + // +A to +Z map to a to z + if (next >= 'A' && next <= 'Z') { + decodedChar = (unichar)(next + 32); + } else { + return nil; + } + break; + case '$': + // $A to $Z map to control codes SH to SB + if (next >= 'A' && next <= 'Z') { + decodedChar = (unichar)(next - 64); + } else { + return nil; + } + break; + case '%': + // %A to %E map to control codes ESC to US + if (next >= 'A' && next <= 'E') { + decodedChar = (unichar)(next - 38); + } else if (next >= 'F' && next <= 'J') { + decodedChar = (unichar)(next - 11); + } else if (next >= 'K' && next <= 'O') { + decodedChar = (unichar) (next + 16); + } else if (next >= 'P' && next <= 'T') { + decodedChar = (unichar) (next + 43); + } else if (next == 'U') { + decodedChar = (unichar) 0; + } else if (next == 'V') { + decodedChar = '@'; + } else if (next == 'W') { + decodedChar = '`'; + } else if (next == 'X' || next == 'Y' || next == 'Z') { + decodedChar = (unichar) 127; + + } else { + return nil; + } + break; + case '/': + // /A to /O map to ! to , and /Z maps to : + if (next >= 'A' && next <= 'O') { + decodedChar = (unichar)(next - 32); + } else if (next == 'Z') { + decodedChar = ':'; + } else { + return nil; + } + break; } [decoded appendFormat:@"%C", decodedChar]; + // bump up i again since we read two characters i++; } else { [decoded appendFormat:@"%C", c]; diff --git a/ZXingObjC/oned/ZXCode39Writer.m b/ZXingObjC/oned/ZXCode39Writer.m index 6a1503796..11750f47b 100644 --- a/ZXingObjC/oned/ZXCode39Writer.m +++ b/ZXingObjC/oned/ZXCode39Writer.m @@ -36,18 +36,21 @@ - (ZXBoolArray *)encode:(NSString *)contents { format:@"Requested contents should be less than 80 digits long, but got %d", length]; } - ZXIntArray *widths = [[ZXIntArray alloc] initWithLength:9]; - int codeWidth = 24 + 1 + length; for (int i = 0; i < length; i++) { NSUInteger indexInString = [ZX_CODE39_ALPHABET_STRING rangeOfString:[contents substringWithRange:NSMakeRange(i, 1)]].location; if (indexInString == NSNotFound) { - [NSException raise:NSInvalidArgumentException format:@"Bad contents: %@", contents]; + contents = [self tryToConvertToExtendedMode:contents]; + length = (int)[contents length]; + if (length > 80) { + [NSException raise:NSInvalidArgumentException format:@"Requested contents should be less than 80 digits long, but got %d (extended full ASCII mode)", length]; + } } - [self toIntArray:ZX_CODE39_CHARACTER_ENCODINGS[indexInString] toReturn:widths]; - codeWidth += [widths sum]; } + + ZXIntArray *widths = [[ZXIntArray alloc] initWithLength:9]; + int codeWidth = 24 + 1 + (13 * length); ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:codeWidth]; - [self toIntArray:ZX_CODE39_CHARACTER_ENCODINGS[39] toReturn:widths]; + [self toIntArray:ZX_CODE39_ASTERISK_ENCODING toReturn:widths]; int pos = [self appendPattern:result pos:0 pattern:widths.array patternLen:widths.length startColor:YES]; ZXIntArray *narrowWhite = [[ZXIntArray alloc] initWithInts:1, -1]; pos += [self appendPattern:result pos:pos pattern:narrowWhite.array patternLen:narrowWhite.length startColor:NO]; @@ -59,7 +62,7 @@ - (ZXBoolArray *)encode:(NSString *)contents { pos += [self appendPattern:result pos:pos pattern:narrowWhite.array patternLen:narrowWhite.length startColor:NO]; } - [self toIntArray:ZX_CODE39_CHARACTER_ENCODINGS[39] toReturn:widths]; + [self toIntArray:ZX_CODE39_ASTERISK_ENCODING toReturn:widths]; [self appendPattern:result pos:pos pattern:widths.array patternLen:widths.length startColor:YES]; return result; } @@ -71,4 +74,61 @@ - (void)toIntArray:(int)a toReturn:(ZXIntArray *)toReturn { } } +- (NSString *)tryToConvertToExtendedMode:(NSString *)contents { + int length = (int)[contents length]; + NSMutableString *extendedContent = [NSMutableString new]; + + for (int i = 0; i < length; i++) { + unichar character = [contents characterAtIndex:i]; + switch (character) { + case 0x0000: + [extendedContent appendString:@"%U"]; + break; + case ' ': + case '-': + case '.': + [extendedContent appendFormat:@"%C", character]; + break; + case '@': + [extendedContent appendString:@"%V"]; + break; + case '`': + [extendedContent appendString:@"%W"]; + break; + default: + if (character > 0 && character < 27) { + [extendedContent appendFormat:@"%C", (unichar) '$']; + [extendedContent appendFormat:@"%C", (unichar) ('A' + (character - 1))]; + } else if (character > 26 && character < ' ') { + [extendedContent appendFormat:@"%C", (unichar) '%']; + [extendedContent appendFormat:@"%C", (unichar) ('A' + (character - 27))]; + } else if ((character > ' ' && character < '-') || character == '/' || character == ':') { + [extendedContent appendFormat:@"%C", (unichar) '/']; + [extendedContent appendFormat:@"%C", (unichar) ('A' + (character - 33))]; + } else if (character > '/' && character < ':') { + [extendedContent appendFormat:@"%C", (unichar) ('0' + (character - 48))]; + } else if (character > ':' && character < '@') { + [extendedContent appendFormat:@"%C", (unichar) '%']; + [extendedContent appendFormat:@"%C", (unichar) ('F' + (character - 59))]; + } else if (character > '@' && character < '[') { + [extendedContent appendFormat:@"%C", (unichar) ('A' + (character - 65))]; + } else if (character > 'Z' && character < '`') { + [extendedContent appendFormat:@"%C", (unichar) '%']; + [extendedContent appendFormat:@"%C", (unichar) ('K' + (character - 91))]; + } else if (character > '`' && character < '{') { + [extendedContent appendFormat:@"%C", (unichar) '+']; + [extendedContent appendFormat:@"%C", (unichar) ('A' + (character - 97))]; + } else if (character > 'z' && character < 128) { + [extendedContent appendFormat:@"%C", (unichar) '%']; + [extendedContent appendFormat:@"%C", (unichar) ('P' + (character - 123))]; + } else { + [NSException raise:NSInvalidArgumentException format:@"Requested content contains a non-encodable character: '%@'", [contents substringWithRange:NSMakeRange(i, 1)]]; + } + break; + } + } + + return extendedContent; +} + @end diff --git a/ZXingObjC/oned/ZXCode93Reader.h b/ZXingObjC/oned/ZXCode93Reader.h index e3368f469..0341ed647 100644 --- a/ZXingObjC/oned/ZXCode93Reader.h +++ b/ZXingObjC/oned/ZXCode93Reader.h @@ -16,6 +16,11 @@ #import "ZXOneDReader.h" +extern const unichar ZX_CODE93_ALPHABET[]; +extern const NSString *ZX_CODE93_ALPHABET_STRING; +extern const int ZX_CODE93_CHARACTER_ENCODINGS[]; +extern const int ZX_CODE93_ASTERISK_ENCODING; + /** * Decodes Code 93 barcodes. */ diff --git a/ZXingObjC/oned/ZXCode93Reader.m b/ZXingObjC/oned/ZXCode93Reader.m index 7d8be2751..7776d2116 100644 --- a/ZXingObjC/oned/ZXCode93Reader.m +++ b/ZXingObjC/oned/ZXCode93Reader.m @@ -21,7 +21,7 @@ #import "ZXResult.h" #import "ZXResultPoint.h" -NSString *ZX_CODE93_ALPHABET_STRING = nil; +const NSString *ZX_CODE93_ALPHABET_STRING = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*"; const unichar ZX_CODE93_ALPHABET[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%', 'a', 'b', 'c', 'd', '*'}; @@ -49,13 +49,6 @@ @interface ZXCode93Reader () @implementation ZXCode93Reader -+ (void)initialize { - if ([self class] != [ZXCode93Reader class]) return; - - ZX_CODE93_ALPHABET_STRING = [[NSString alloc] initWithCharacters:ZX_CODE93_ALPHABET - length:sizeof(ZX_CODE93_ALPHABET) / sizeof(unichar)]; -} - - (id)init { if (self = [super init]) { _counters = [[ZXIntArray alloc] initWithLength:6]; @@ -235,9 +228,29 @@ - (NSString *)decodeExtended:(NSMutableString *)encoded { break; case 'b': if (next >= 'A' && next <= 'E') { + // %A to %E map to control codes ESC to USep decodedChar = (unichar)(next - 38); - } else if (next >= 'F' && next <= 'W') { + } else if (next >= 'F' && next <= 'J') { + // %F to %J map to ; < = > ? decodedChar = (unichar)(next - 11); + } else if (next >= 'K' && next <= 'O') { + // %K to %O map to [ \ ] ^ _ + decodedChar = (unichar) (next + 16); + } else if (next >= 'P' && next <= 'T') { + // %P to %T map to { | } ~ DEL + decodedChar = (unichar) (next + 43); + } else if (next == 'U') { + // %U map to NUL + decodedChar = '\0'; + } else if (next == 'V') { + // %V map to @ + decodedChar = '@'; + } else if (next == 'W') { + // %W map to ` + decodedChar = '`'; + } else if (next >= 'X' && next <= 'Z') { + // %X to %Z all map to DEL (127) + decodedChar = 127; } else { return nil; } diff --git a/examples/QrCodeTest/main.m b/ZXingObjC/oned/ZXCode93Writer.h similarity index 75% rename from examples/QrCodeTest/main.m rename to ZXingObjC/oned/ZXCode93Writer.h index 415db6f8e..98094c36b 100644 --- a/examples/QrCodeTest/main.m +++ b/ZXingObjC/oned/ZXCode93Writer.h @@ -14,13 +14,11 @@ * limitations under the License. */ -#import +#import "ZXOneDimensionalCodeWriter.h" -#import "AppDelegate.h" +/** + * This object renders a CODE93 code as a ZXBitMatrix. + */ +@interface ZXCode93Writer : ZXOneDimensionalCodeWriter -int main(int argc, char *argv[]) -{ - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} +@end diff --git a/ZXingObjC/oned/ZXCode93Writer.m b/ZXingObjC/oned/ZXCode93Writer.m new file mode 100644 index 000000000..001889549 --- /dev/null +++ b/ZXingObjC/oned/ZXCode93Writer.m @@ -0,0 +1,172 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXBitMatrix.h" +#import "ZXBoolArray.h" +#import "ZXCode93Reader.h" +#import "ZXCode93Writer.h" +#import "ZXIntArray.h" + +@implementation ZXCode93Writer + +- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error { + if (format != kBarcodeFormatCode93) { + [NSException raise:NSInvalidArgumentException format:@"Can only encode CODE_93."]; + } + return [super encode:contents format:format width:width height:height hints:hints error:error]; +} + +/** + * @param contents barcode contents to encode. It should not be encoded for extended characters. + * @return a {@code boolean[]} of horizontal pixels (false = white, true = black) + */ +- (ZXBoolArray *)encode:(NSString *)contents { + contents = [self convertToExtended:contents]; + int length = (int)[contents length]; + if (length > 80) { + [NSException raise:NSInvalidArgumentException + format:@"Requested contents should be less than 80 digits long after converting to extended encoding, but got %d", length]; + } + + //lenght of code + 2 start/stop characters + 2 checksums, each of 9 bits, plus a termination bar + int codeWidth = (length + 2 + 2) * 9 + 1; + ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:codeWidth]; + + //start character (*) + int pos = [self appendPattern:result pos:0 a:ZX_CODE93_ASTERISK_ENCODING]; + + for (int i = 0; i < length; i++) { + NSUInteger indexInString = [ZX_CODE93_ALPHABET_STRING rangeOfString:[contents substringWithRange:NSMakeRange(i, 1)]].location; + if (indexInString == NSNotFound) { + [NSException raise:NSInvalidArgumentException format:@"Bad contents: %@", contents]; + } + pos += [self appendPattern:result pos:pos a:ZX_CODE93_CHARACTER_ENCODINGS[indexInString]]; + } + + //add two checksums + int check1 = [self computeChecksumIndexFrom:contents withMaxWeight:20]; + pos += [self appendPattern:result pos:pos a:ZX_CODE93_CHARACTER_ENCODINGS[check1]]; + + //append the contents to reflect the first checksum added + contents = [contents stringByAppendingString:[ZX_CODE93_ALPHABET_STRING substringWithRange:NSMakeRange(check1, 1)]]; + + int check2 = [self computeChecksumIndexFrom:contents withMaxWeight:15]; + pos += [self appendPattern:result pos:pos a:ZX_CODE93_CHARACTER_ENCODINGS[check2]]; + + //end character (*) + pos += [self appendPattern:result pos:pos a:ZX_CODE93_ASTERISK_ENCODING]; + + //termination bar (single black bar) + result.array[pos] = true; + + return result; +} + +- (NSString *)convertToExtended:(NSString *)contents { + int length = (int)[contents length]; + NSMutableString *extendedContent = [[NSMutableString alloc] initWithCapacity:length * 2]; + for (int i = 0; i < length; i++) { + unichar character = [contents characterAtIndex:i]; + // ($)=a, (%)=b, (/)=c, (+)=d. see Code93Reader.ALPHABET_STRING + if (character == 0) { + // NUL: (%)U + [extendedContent appendString:@"bU"]; + } else if (character <= 26) { + // SOH - SUB: ($)A - ($)Z + [extendedContent appendFormat:@"%c", 'a']; + [extendedContent appendFormat:@"%c", ('A' + character - 1)]; + } else if (character <= 31) { + // ESC - US: (%)A - (%)E + [extendedContent appendFormat:@"%c", 'b']; + [extendedContent appendFormat:@"%c", ('A' + character - 27)]; + } else if (character == ' ' || character == '$' || character == '%' || character == '+') { + // space $ % + + [extendedContent appendFormat:@"%c", character]; + } else if (character <= ',') { + // ! " # & ' ( ) * ,: (/)A - (/)L + [extendedContent appendFormat:@"%c", 'c']; + [extendedContent appendFormat:@"%c", ('A' + character - '!')]; + } else if (character <= '9') { + [extendedContent appendFormat:@"%c", character]; + } else if (character == ':') { + // :: (/)Z + [extendedContent appendString:@"cZ"]; + } else if (character <= '?') { + // ; - ?: (%)F - (%)J + [extendedContent appendFormat:@"%c", 'b']; + [extendedContent appendFormat:@"%c", ('F' + character - ';')]; + } else if (character == '@') { + // @: (%)V + [extendedContent appendString:@"bV"]; + } else if (character <= 'Z') { + // A - Z + [extendedContent appendFormat:@"%c", character]; + } else if (character <= '_') { + // [ - _: (%)K - (%)O + [extendedContent appendFormat:@"%c", 'b']; + [extendedContent appendFormat:@"%c", ('K' + character - '[')]; + } else if (character == '`') { + // `: (%)W + [extendedContent appendString:@"bW"]; + } else if (character <= 'z') { + // a - z: (*)A - (*)Z + [extendedContent appendFormat:@"%c", 'd']; + [extendedContent appendFormat:@"%c", ('A' + character - 'a')]; + } else if (character <= 127) { + // { - DEL: (%)P - (%)T + [extendedContent appendFormat:@"%c", 'b']; + [extendedContent appendFormat:@"%c", ('P' + character - '{')]; + } else { + [NSException raise:NSInvalidArgumentException + format:@"Requested content contains a non-encodable character: '%c'", character]; + } + } + return extendedContent; +} + +- (int)appendPattern:(ZXBoolArray *)target pos:(int)pos pattern:(const int[])pattern patternLen:(int)patternLen { + for (int i = 0; i < patternLen; i++) { + target.array[pos++] = pattern[i] != 0; + } + return 9; +} + +- (int)appendPattern:(ZXBoolArray *)target pos:(int)pos a:(int)a { + for (int i = 0; i < 9; i++) { + int temp = a & (1 << (8 - i)); + target.array[pos + i] = temp != 0; + } + return 9; +} + +- (int)computeChecksumIndexFrom:(NSString *)contents withMaxWeight:(int)maxWeight { + int weight = 1; + int total = 0; + int length = (int)[contents length]; + for (int i = length - 1; i >= 0; i--) { + NSUInteger indexInString = [ZX_CODE93_ALPHABET_STRING rangeOfString:[contents substringWithRange:NSMakeRange(i, 1)]].location; + if (indexInString == NSNotFound) { + [NSException raise:NSInvalidArgumentException format:@"Bad contents: %@", contents]; + } + total += indexInString * weight; + if (++weight > maxWeight) { + weight = 1; + } + } + return total % 47; +} + +@end diff --git a/ZXingObjC/oned/ZXEAN13Writer.m b/ZXingObjC/oned/ZXEAN13Writer.m index b9ad4bd20..807e9e21e 100644 --- a/ZXingObjC/oned/ZXEAN13Writer.m +++ b/ZXingObjC/oned/ZXEAN13Writer.m @@ -39,14 +39,29 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt } - (ZXBoolArray *)encode:(NSString *)contents { - if ([contents length] != 13) { - [NSException raise:NSInvalidArgumentException - format:@"Requested contents should be 13 digits long, but got %d", (int)[contents length]]; + int length = (int) [contents length]; + switch (length) { + case 12: + // No check digit present, calculate it and add it + contents = [contents stringByAppendingString:[NSString stringWithFormat:@"%d", [ZXUPCEANReader standardUPCEANChecksum:contents]]]; + break; + case 13: + if (![ZXUPCEANReader checkStandardUPCEANChecksum:contents]) { + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:@"Contents do not pass checksum" + userInfo:nil]; + } + break; + default: + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:[NSString stringWithFormat:@"Requested contents should be 12 or 13 digits long, but got %d", (int)[contents length]] + userInfo:nil]; } - if (![ZXUPCEANReader checkStandardUPCEANChecksum:contents]) { - [NSException raise:NSInvalidArgumentException - format:@"Contents do not pass checksum"]; + if (![self isNumeric:contents]) { + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:@"Input should only contain digits 0-9" + userInfo:nil]; } int firstDigit = [[contents substringToIndex:1] intValue]; diff --git a/ZXingObjC/oned/ZXEAN8Writer.m b/ZXingObjC/oned/ZXEAN8Writer.m index 7307bd151..e00080740 100644 --- a/ZXingObjC/oned/ZXEAN8Writer.m +++ b/ZXingObjC/oned/ZXEAN8Writer.m @@ -34,8 +34,29 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt * Returns a byte array of horizontal pixels (FALSE = white, TRUE = black) */ - (ZXBoolArray *)encode:(NSString *)contents { - if ([contents length] != 8) { - [NSException raise:NSInvalidArgumentException format:@"Requested contents should be 8 digits long, but got %d", (int)[contents length]]; + int length = (int) [contents length]; + switch (length) { + case 7: + // No check digit present, calculate it and add it + contents = [contents stringByAppendingString:[NSString stringWithFormat:@"%d", [ZXUPCEANReader standardUPCEANChecksum:contents]]]; + break; + case 8: + if (![ZXUPCEANReader checkStandardUPCEANChecksum:contents]) { + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:@"Contents do not pass checksum" + userInfo:nil]; + } + break; + default: + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:[NSString stringWithFormat:@"Requested contents should be 7 or 8 digits long, but got %d", (int)[contents length]] + userInfo:nil]; + } + + if (![self isNumeric:contents]) { + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:@"Input should only contain digits 0-9" + userInfo:nil]; } ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:ZX_EAN8_CODE_WIDTH]; diff --git a/ZXingObjC/oned/ZXEANManufacturerOrgSupport.h b/ZXingObjC/oned/ZXEANManufacturerOrgSupport.h index 60b385af2..da7028278 100644 --- a/ZXingObjC/oned/ZXEANManufacturerOrgSupport.h +++ b/ZXingObjC/oned/ZXEANManufacturerOrgSupport.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * Records EAN prefix to GS1 Member Organization, where the member organization * correlates strongly with a country. This is an imperfect means of identifying diff --git a/ZXingObjC/oned/ZXITFReader.h b/ZXingObjC/oned/ZXITFReader.h index bc145f4ad..f4ded8b82 100644 --- a/ZXingObjC/oned/ZXITFReader.h +++ b/ZXingObjC/oned/ZXITFReader.h @@ -16,8 +16,6 @@ #import "ZXOneDReader.h" -extern const int ZX_ITF_PATTERNS[][5]; - /** * Implements decoding of the ITF format, or Interleaved Two of Five. * diff --git a/ZXingObjC/oned/ZXITFReader.m b/ZXingObjC/oned/ZXITFReader.m index c9b41d06b..773ce894f 100644 --- a/ZXingObjC/oned/ZXITFReader.m +++ b/ZXingObjC/oned/ZXITFReader.m @@ -23,9 +23,10 @@ #import "ZXResultPoint.h" static float ZX_ITF_MAX_AVG_VARIANCE = 0.38f; -static float ZX_ITF_MAX_INDIVIDUAL_VARIANCE = 0.78f; +static float ZX_ITF_MAX_INDIVIDUAL_VARIANCE = 0.5f; -static const int ZX_ITF_W = 3; // Pixel width of a wide line +static const int ZX_ITF_W3 = 3; // Pixel width of a 3x wide line +static const int ZX_ITF_W2 = 2; // Pixel width of a 2x wide line static const int ZX_ITF_N = 1; // Pixel width of a narrow line /** Valid ITF lengths. Anything longer than the largest value is also allowed. */ @@ -38,23 +39,36 @@ * searching for the END_PATTERN */ const int ZX_ITF_ITF_START_PATTERN[] = {ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N}; -const int ZX_ITF_END_PATTERN_REVERSED[] = {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W}; +const int ZX_ITF_END_PATTERN_REVERSED[2][3] = { + { ZX_ITF_N, ZX_ITF_N, ZX_ITF_W2 }, // 2x + { ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3 }, // 3x +}; /** * Patterns of Wide / Narrow lines to indicate each digit */ -const int ZX_ITF_PATTERNS_LEN = 10; +const int ZX_ITF_PATTERNS_LEN = 20; const int ZX_ITF_PATTERNS[ZX_ITF_PATTERNS_LEN][5] = { - {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W, ZX_ITF_W, ZX_ITF_N}, // 0 - {ZX_ITF_W, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W}, // 1 - {ZX_ITF_N, ZX_ITF_W, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W}, // 2 - {ZX_ITF_W, ZX_ITF_W, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N}, // 3 - {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W, ZX_ITF_N, ZX_ITF_W}, // 4 - {ZX_ITF_W, ZX_ITF_N, ZX_ITF_W, ZX_ITF_N, ZX_ITF_N}, // 5 - {ZX_ITF_N, ZX_ITF_W, ZX_ITF_W, ZX_ITF_N, ZX_ITF_N}, // 6 - {ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W, ZX_ITF_W}, // 7 - {ZX_ITF_W, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W, ZX_ITF_N}, // 8 - {ZX_ITF_N, ZX_ITF_W, ZX_ITF_N, ZX_ITF_W, ZX_ITF_N} // 9 + {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W2, ZX_ITF_W2, ZX_ITF_N}, // 0 + {ZX_ITF_W2, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W2}, // 1 + {ZX_ITF_N, ZX_ITF_W2, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W2}, // 2 + {ZX_ITF_W2, ZX_ITF_W2, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N}, // 3 + {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W2, ZX_ITF_N, ZX_ITF_W2}, // 4 + {ZX_ITF_W2, ZX_ITF_N, ZX_ITF_W2, ZX_ITF_N, ZX_ITF_N}, // 5 + {ZX_ITF_N, ZX_ITF_W2, ZX_ITF_W2, ZX_ITF_N, ZX_ITF_N}, // 6 + {ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W2, ZX_ITF_W2}, // 7 + {ZX_ITF_W2, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W2, ZX_ITF_N}, // 8 + {ZX_ITF_N, ZX_ITF_W2, ZX_ITF_N, ZX_ITF_W2, ZX_ITF_N}, // 9 + {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_W3, ZX_ITF_N}, // 0 + {ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3}, // 1 + {ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3}, // 2 + {ZX_ITF_W3, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N}, // 3 + {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_W3}, // 4 + {ZX_ITF_W3, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N}, // 5 + {ZX_ITF_N, ZX_ITF_W3, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N}, // 6 + {ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_W3}, // 7 + {ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N}, // 8 + {ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N} // 9 }; @interface ZXITFReader () @@ -258,6 +272,8 @@ - (int)skipWhiteSpace:(ZXBitArray *)row { * block' */ - (ZXIntArray *)decodeEnd:(ZXBitArray *)row { + // For convenience, reverse the row and then + // search from 'the start' for the end block [row reverse]; int endStart = [self skipWhiteSpace:row]; @@ -265,19 +281,35 @@ - (ZXIntArray *)decodeEnd:(ZXBitArray *)row { [row reverse]; return nil; } - ZXIntArray *endPattern = [self findGuardPattern:row rowOffset:endStart pattern:ZX_ITF_END_PATTERN_REVERSED patternLen:sizeof(ZX_ITF_END_PATTERN_REVERSED)/sizeof(int)]; + + ZXIntArray *endPattern = [self findGuardPattern:row rowOffset:endStart pattern:ZX_ITF_END_PATTERN_REVERSED[0] patternLen:sizeof(ZX_ITF_END_PATTERN_REVERSED[0])/sizeof(int)]; + + if (!endPattern) { + endPattern = [self findGuardPattern:row rowOffset:endStart pattern:ZX_ITF_END_PATTERN_REVERSED[1] patternLen:sizeof(ZX_ITF_END_PATTERN_REVERSED[1])/sizeof(int)]; + } + if (!endPattern) { [row reverse]; return nil; } + + // The start & end patterns must be pre/post fixed by a quiet zone. This + // zone must be at least 10 times the width of a narrow line. + // ref: http://www.barcode-1.net/i25code.html if (![self validateQuietZone:row startPattern:endPattern.array[0]]) { [row reverse]; return nil; } + + // Now recalculate the indices of where the 'endblock' starts & stops to + // accommodate the reversed nature of the search int temp = endPattern.array[0]; endPattern.array[0] = [row size] - endPattern.array[1]; endPattern.array[1] = [row size] - temp; + + // Put the row back the right way. [row reverse]; + return endPattern; } @@ -344,10 +376,13 @@ - (int)decodeDigit:(ZXIntArray *)counters { if (variance < bestVariance) { bestVariance = variance; bestMatch = i; + } else if (variance == bestVariance) { + // if we find a second 'best match' with the same variance, we can not reliably report to have a suitable match + bestMatch = -1; } } if (bestMatch >= 0) { - return bestMatch; + return bestMatch % 10; } else { return -1; } diff --git a/ZXingObjC/oned/ZXITFWriter.m b/ZXingObjC/oned/ZXITFWriter.m index 5a58048cf..8657e887e 100644 --- a/ZXingObjC/oned/ZXITFWriter.m +++ b/ZXingObjC/oned/ZXITFWriter.m @@ -21,6 +21,26 @@ const int ZX_ITF_WRITER_START_PATTERN[] = {1, 1, 1, 1}; const int ZX_ITF_WRITER_END_PATTERN[] = {3, 1, 1}; +static const int ZX_ITF_W3 = 3; // Pixel width of a 3x wide line +static const int ZX_ITF_N = 1; // Pixel width of a narrow line + +/** + * Patterns of Wide / Narrow lines to indicate each digit + */ +const int ZX_ITF_WRITER_PATTERNS_LEN = 10; +const int ZX_ITF_WRITER_PATTERNS[ZX_ITF_WRITER_PATTERNS_LEN][5] = { + {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_W3, ZX_ITF_N}, // 0 + {ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3}, // 1 + {ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3}, // 2 + {ZX_ITF_W3, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N}, // 3 + {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_W3}, // 4 + {ZX_ITF_W3, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N}, // 5 + {ZX_ITF_N, ZX_ITF_W3, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N}, // 6 + {ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_W3}, // 7 + {ZX_ITF_W3, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N}, // 8 + {ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N, ZX_ITF_W3, ZX_ITF_N} // 9 +}; + @implementation ZXITFWriter - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error { @@ -40,17 +60,23 @@ - (ZXBoolArray *)encode:(NSString *)contents { [NSException raise:NSInvalidArgumentException format:@"Requested contents should be less than 80 digits long, but got %d", length]; } + if (![self isNumeric:contents]) { + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:@"Input should only contain digits 0-9" + userInfo:nil]; + } + ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:9 + 9 * length]; int pos = [self appendPattern:result pos:0 pattern:ZX_ITF_WRITER_START_PATTERN patternLen:sizeof(ZX_ITF_WRITER_START_PATTERN)/sizeof(int) startColor:YES]; for (int i = 0; i < length; i += 2) { int one = [[contents substringWithRange:NSMakeRange(i, 1)] intValue]; int two = [[contents substringWithRange:NSMakeRange(i + 1, 1)] intValue]; - const int encodingLen = 18; + const int encodingLen = 10; int encoding[encodingLen]; memset(encoding, 0, encodingLen * sizeof(int)); for (int j = 0; j < 5; j++) { - encoding[2 * j] = ZX_ITF_PATTERNS[one][j]; - encoding[2 * j + 1] = ZX_ITF_PATTERNS[two][j]; + encoding[2 * j] = ZX_ITF_WRITER_PATTERNS[one][j]; + encoding[2 * j + 1] = ZX_ITF_WRITER_PATTERNS[two][j]; } pos += [super appendPattern:result pos:pos pattern:encoding patternLen:encodingLen startColor:YES]; } diff --git a/ZXingObjC/oned/ZXOneDReader.m b/ZXingObjC/oned/ZXOneDReader.m index 7e4f68507..10b6302b8 100644 --- a/ZXingObjC/oned/ZXOneDReader.m +++ b/ZXingObjC/oned/ZXOneDReader.m @@ -83,7 +83,10 @@ - (void)reset { * * @param image The image to decode * @param hints Any hints that were requested - * @return The contents of the decoded barcode or nil if an error occurs + * @return The contents of the decoded barcode or nil if: + * - no potential barcode is found + * - a potential barcode is found but does not pass its checksum + * - a potential barcode is found but format is invalid */ - (ZXResult *)doDecode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error { int width = image.width; @@ -185,10 +188,8 @@ + (BOOL)recordPattern:(ZXBitArray *)row start:(int)start counters:(ZXIntArray *) i++; } - if (!(counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end))) { - return NO; - } - return YES; + return counterPosition == numCounters || + (counterPosition == numCounters - 1 && i == end); } + (BOOL)recordPatternInReverse:(ZXBitArray *)row start:(int)start counters:(ZXIntArray *)counters { @@ -201,10 +202,7 @@ + (BOOL)recordPatternInReverse:(ZXBitArray *)row start:(int)start counters:(ZXIn } } - if (numTransitionsLeft >= 0 || ![self recordPattern:row start:start + 1 counters:counters]) { - return NO; - } - return YES; + return !(numTransitionsLeft >= 0 || ![self recordPattern:row start:start + 1 counters:counters]); } /** diff --git a/ZXingObjC/oned/ZXOneDimensionalCodeWriter.h b/ZXingObjC/oned/ZXOneDimensionalCodeWriter.h index 170e00de3..5805f50d9 100644 --- a/ZXingObjC/oned/ZXOneDimensionalCodeWriter.h +++ b/ZXingObjC/oned/ZXOneDimensionalCodeWriter.h @@ -24,6 +24,7 @@ @interface ZXOneDimensionalCodeWriter : NSObject - (ZXBoolArray *)encode:(NSString *)contents; +- (BOOL)isNumeric:(NSString *)contents; - (int)appendPattern:(ZXBoolArray *)target pos:(int)pos pattern:(const int[])pattern patternLen:(int)patternLen startColor:(BOOL)startColor; - (int)defaultMargin; diff --git a/ZXingObjC/oned/ZXOneDimensionalCodeWriter.m b/ZXingObjC/oned/ZXOneDimensionalCodeWriter.m index eb69f84d9..9f157534f 100644 --- a/ZXingObjC/oned/ZXOneDimensionalCodeWriter.m +++ b/ZXingObjC/oned/ZXOneDimensionalCodeWriter.m @@ -18,6 +18,13 @@ #import "ZXBoolArray.h" #import "ZXEncodeHints.h" #import "ZXOneDimensionalCodeWriter.h" +#import "ZXUPCAReader.h" +@interface ZXOneDimensionalCodeWriter () + +@property NSMutableArray *longLinePositions; +@property BOOL showLongLines; + +@end @implementation ZXOneDimensionalCodeWriter @@ -33,7 +40,7 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt * or height, IllegalArgumentException is thrown. */ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height - hints:(ZXEncodeHints *)hints error:(NSError **)error { + hints:(ZXEncodeHints *)hints error:(NSError **)error { if (contents.length == 0) { @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Found empty contents" userInfo:nil]; } @@ -44,6 +51,17 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt userInfo:nil]; } + self.longLinePositions = [NSMutableArray new]; + self.showLongLines = NO; + if (hints.showLongLines) { + if (format == kBarcodeFormatEan13) { + self.showLongLines = YES; + } + if (format == kBarcodeFormatEan8) { + self.showLongLines = YES; + } + } + int sidesMargin = [self defaultMargin]; if (hints && hints.margin) { sidesMargin = hints.margin.intValue; @@ -53,6 +71,18 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt return [self renderResult:code width:width height:height sidesMargin:sidesMargin]; } +/** + * @return BOOL, YES iff input contains no other characters than digits 0-9. + */ +- (BOOL)isNumeric:(NSString *)contents { + NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; + if ([contents rangeOfCharacterFromSet:notDigits].location == NSNotFound) { + return YES; + } else { + return NO; + } +} + /** * @return a byte array of horizontal pixels (0 = white, 1 = black) */ @@ -69,15 +99,23 @@ - (ZXBitMatrix *)renderResult:(ZXBoolArray *)code width:(int)width height:(int)h ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:outputWidth height:outputHeight]; for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) { if (code.array[inputX]) { - [output setRegionAtLeft:outputX top:0 width:multiple height:outputHeight]; + int barcodeHeight = outputHeight; + if (self.showLongLines) { + // if the position is not in the list for long lines we shorten the line by 10% + if (![self containsPos:inputX]) { + barcodeHeight = (int) ((float) outputHeight * 0.90f); + } + } + [output setRegionAtLeft:outputX top:0 width:multiple height:barcodeHeight]; } } return output; } /** - * Appends the given pattern to the target array starting at pos. - * + * @param target encode black/white pattern into this array + * @param pos position to start encoding at in target + * @param pattern lengths of black/white runs to encode * * @param startColor starting color - false for white, true for black * @return the number of elements added to target. */ @@ -86,6 +124,9 @@ - (int)appendPattern:(ZXBoolArray *)target pos:(int)pos pattern:(const int[])pat int numAdded = 0; for (int i = 0; i < patternLen; i++) { for (int j = 0; j < pattern[i]; j++) { + if (self.showLongLines && [self isLongLinePattern:pattern]) { + [self.longLinePositions addObject:[NSNumber numberWithInt:pos]]; + } target.array[pos++] = color; } numAdded += pattern[i]; @@ -94,6 +135,27 @@ - (int)appendPattern:(ZXBoolArray *)target pos:(int)pos pattern:(const int[])pat return numAdded; } +- (BOOL)isLongLinePattern:(const int[])pattern +{ + if (pattern == ZX_UPC_EAN_MIDDLE_PATTERN) { + return YES; + } + if (pattern == ZX_UPC_EAN_START_END_PATTERN) { + return YES; + } + return NO; +} + +- (BOOL)containsPos:(int)pos +{ + for (NSNumber *number in self.longLinePositions) { + if (number.intValue == pos) { + return YES; + } + } + return NO; +} + - (int)defaultMargin { // CodaBar spec requires a side margin to be more than ten times wider than narrow space. // This seems like a decent idea for a default for all formats. @@ -104,6 +166,7 @@ - (int)defaultMargin { * Encode the contents to boolean array expression of one-dimensional barcode. * Start code and end code should be included in result, and side margins should not be included. * + * @param contents barcode contents to encode * @return a ZXBoolArray of horizontal pixels (false = white, true = black) */ - (ZXBoolArray *)encode:(NSString *)contents { diff --git a/ZXingObjC/oned/ZXUPCAReader.m b/ZXingObjC/oned/ZXUPCAReader.m index 659a71e2a..44965e8ed 100644 --- a/ZXingObjC/oned/ZXUPCAReader.m +++ b/ZXingObjC/oned/ZXUPCAReader.m @@ -102,10 +102,12 @@ - (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSM - (ZXResult *)maybeReturnResult:(ZXResult *)result { NSString *text = result.text; if ([text characterAtIndex:0] == '0') { - return [ZXResult resultWithText:[text substringFromIndex:1] - rawBytes:nil - resultPoints:result.resultPoints - format:kBarcodeFormatUPCA]; + ZXResult *upcaResult = [ZXResult resultWithText:[text substringFromIndex:1] + rawBytes:nil + resultPoints:result.resultPoints + format:kBarcodeFormatUPCA]; + [upcaResult putAllMetadata:[result resultMetadata]]; + return upcaResult; } else { return nil; } diff --git a/ZXingObjC/oned/ZXUPCAWriter.m b/ZXingObjC/oned/ZXUPCAWriter.m index 6cbc3d1f5..1ac7edc60 100644 --- a/ZXingObjC/oned/ZXUPCAWriter.m +++ b/ZXingObjC/oned/ZXUPCAWriter.m @@ -39,29 +39,8 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt reason:[NSString stringWithFormat:@"Can only encode UPC-A, but got %d", format] userInfo:nil]; } - return [self.subWriter encode:[self preencode:contents] format:kBarcodeFormatEan13 width:width height:height hints:hints error:error]; -} - -/** - * Transform a UPC-A code into the equivalent EAN-13 code, and add a check digit if it is not - * already present. - */ -- (NSString *)preencode:(NSString *)contents { - NSUInteger length = [contents length]; - if (length == 11) { - int sum = 0; - - for (int i = 0; i < 11; ++i) { - sum += ([contents characterAtIndex:i] - '0') * (i % 2 == 0 ? 3 : 1); - } - - contents = [contents stringByAppendingFormat:@"%d", (1000 - sum) % 10]; - } else if (length != 12) { - @throw [NSException exceptionWithName:NSInvalidArgumentException - reason:[NSString stringWithFormat:@"Requested contents should be 11 or 12 digits long, but got %ld", (unsigned long)[contents length]] - userInfo:nil]; - } - return [NSString stringWithFormat:@"0%@", contents]; + // Transform a UPC-A code into the equivalent EAN-13 code and write it that way + return [self.subWriter encode:[NSString stringWithFormat:@"0%@", contents] format:kBarcodeFormatEan13 width:width height:height hints:hints error:error]; } @end diff --git a/ZXingObjC/oned/ZXUPCEANExtensionSupport.h b/ZXingObjC/oned/ZXUPCEANExtensionSupport.h index b94101ca5..4ad9e975b 100644 --- a/ZXingObjC/oned/ZXUPCEANExtensionSupport.h +++ b/ZXingObjC/oned/ZXUPCEANExtensionSupport.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBitArray, ZXResult; @interface ZXUPCEANExtensionSupport : NSObject diff --git a/ZXingObjC/oned/ZXUPCEANReader.h b/ZXingObjC/oned/ZXUPCEANReader.h index 74aa91adb..87fa5641d 100644 --- a/ZXingObjC/oned/ZXUPCEANReader.h +++ b/ZXingObjC/oned/ZXUPCEANReader.h @@ -18,8 +18,8 @@ #import "ZXOneDReader.h" typedef enum { - ZX_UPC_EAN_PATTERNS_L_PATTERNS = 0, - ZX_UPC_EAN_PATTERNS_L_AND_G_PATTERNS + ZX_UPC_EAN_PATTERNS_L_PATTERNS = 0, + ZX_UPC_EAN_PATTERNS_L_AND_G_PATTERNS } ZX_UPC_EAN_PATTERNS; extern const int ZX_UPC_EAN_START_END_PATTERN_LEN; @@ -46,11 +46,22 @@ extern const int ZX_UPC_EAN_L_AND_G_PATTERNS[][4]; /** * Like decodeRow:row:hints:, but allows caller to inform method about where the UPC/EAN start pattern is * found. This allows this to be computed once and reused across many implementations. + * + * + * @param rowNumber row index into the image + * @param row encoding of the row of the barcode image + * @param startGuardRange start/end column where the opening start pattern was found + * @param hints optional hints that influence decoding + * @return ZXResult encapsulating the result of decoding a barcode in the row or nil if: + * - no potential barcode is found + * - a potential barcode is found but does not pass its checksum + * - a potential barcode is found but format is invalid */ - (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row startGuardRange:(NSRange)startGuardRange hints:(ZXDecodeHints *)hints error:(NSError **)error; /** - * @return checkStandardUPCEANChecksum: + * @param s string of digits to check + * @return checkStandardUPCEANChecksum: or nil if the string does not contain only digits */ - (BOOL)checkChecksum:(NSString *)s error:(NSError **)error; @@ -64,6 +75,8 @@ extern const int ZX_UPC_EAN_L_AND_G_PATTERNS[][4]; */ + (BOOL)checkStandardUPCEANChecksum:(NSString *)s; ++ (int)standardUPCEANChecksum:(NSString *)s; + - (NSRange)decodeEnd:(ZXBitArray *)row endStart:(int)endStart error:(NSError **)error; + (NSRange)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset whiteFirst:(BOOL)whiteFirst pattern:(const int[])pattern patternLen:(int)patternLen error:(NSError **)error; diff --git a/ZXingObjC/oned/ZXUPCEANReader.m b/ZXingObjC/oned/ZXUPCEANReader.m index 1c6edf0ea..a333f04fe 100644 --- a/ZXingObjC/oned/ZXUPCEANReader.m +++ b/ZXingObjC/oned/ZXUPCEANReader.m @@ -242,9 +242,15 @@ + (BOOL)checkStandardUPCEANChecksum:(NSString *)s { if (length == 0) { return NO; } + int check = [[s substringWithRange:NSMakeRange((length - 1), 1)] intValue]; + return [self standardUPCEANChecksum:[s substringWithRange:NSMakeRange(0, length - 1)]] == check; +} + ++ (int)standardUPCEANChecksum:(NSString *)s { + int length = (int)[s length]; int sum = 0; - for (int i = length - 2; i >= 0; i -= 2) { + for (int i = length - 1; i >= 0; i -= 2) { int digit = (int)[s characterAtIndex:i] - (int)'0'; if (digit < 0 || digit > 9) { return NO; @@ -254,7 +260,7 @@ + (BOOL)checkStandardUPCEANChecksum:(NSString *)s { sum *= 3; - for (int i = length - 1; i >= 0; i -= 2) { + for (int i = length - 2; i >= 0; i -= 2) { int digit = (int)[s characterAtIndex:i] - (int)'0'; if (digit < 0 || digit > 9) { return NO; @@ -262,7 +268,7 @@ + (BOOL)checkStandardUPCEANChecksum:(NSString *)s { sum += digit; } - return sum % 10 == 0; + return (1000 - sum) % 10; } - (NSRange)decodeEnd:(ZXBitArray *)row endStart:(int)endStart error:(NSError **)error { diff --git a/ZXingObjC/oned/ZXUPCEANWriter.m b/ZXingObjC/oned/ZXUPCEANWriter.m index 27ba3834e..97c2c55fb 100644 --- a/ZXingObjC/oned/ZXUPCEANWriter.m +++ b/ZXingObjC/oned/ZXUPCEANWriter.m @@ -23,7 +23,7 @@ @implementation ZXUPCEANWriter - (int)defaultMargin { // Use a different default more appropriate for UPC/EAN - return ZX_UPC_EAN_START_END_PATTERN_LEN; + return 9; } @end diff --git a/ZXingObjC/oned/ZXUPCEReader.h b/ZXingObjC/oned/ZXUPCEReader.h index 7553319b5..86596f02b 100644 --- a/ZXingObjC/oned/ZXUPCEReader.h +++ b/ZXingObjC/oned/ZXUPCEReader.h @@ -17,6 +17,10 @@ #import "ZXBarcodeFormat.h" #import "ZXUPCEANReader.h" +extern const int ZX_UCPE_NUMSYS_AND_CHECK_DIGIT_PATTERNS[][10]; +extern const int ZX_UPCE_MIDDLE_END_PATTERN_LEN; +extern const int ZX_UPCE_MIDDLE_END_PATTERN[]; + /** * Implements decoding of the UPC-E format. * diff --git a/ZXingObjC/oned/ZXUPCEReader.m b/ZXingObjC/oned/ZXUPCEReader.m index 949861b21..c3e99c7c4 100644 --- a/ZXingObjC/oned/ZXUPCEReader.m +++ b/ZXingObjC/oned/ZXUPCEReader.m @@ -23,7 +23,32 @@ * The pattern that marks the middle, and end, of a UPC-E pattern. * There is no "second half" to a UPC-E barcode. */ -const int ZX_UCPE_MIDDLE_END_PATTERN[] = {1, 1, 1, 1, 1, 1}; +const int ZX_UPCE_MIDDLE_END_PATTERN_LEN = 6; +const int ZX_UPCE_MIDDLE_END_PATTERN[] = {1, 1, 1, 1, 1, 1}; + +// For an UPC-E barcode, the final digit is represented by the parities used +// to encode the middle six digits, according to the table below. +// +// Parity of next 6 digits +// Digit 0 1 2 3 4 5 +// 0 Even Even Even Odd Odd Odd +// 1 Even Even Odd Even Odd Odd +// 2 Even Even Odd Odd Even Odd +// 3 Even Even Odd Odd Odd Even +// 4 Even Odd Even Even Odd Odd +// 5 Even Odd Odd Even Even Odd +// 6 Even Odd Odd Odd Even Even +// 7 Even Odd Even Odd Even Odd +// 8 Even Odd Even Odd Odd Even +// 9 Even Odd Odd Even Odd Even +// +// The encoding is represented by the following array, which is a bit pattern +// using Odd = 0 and Even = 1. For example, 5 is represented by: +// +// Odd Even Even Odd Odd Even +// in binary: +// 0 1 1 0 0 1 == 0x19 +// /** * See ZX_UCPE_L_AND_G_PATTERNS; these values similarly represent patterns of @@ -84,13 +109,13 @@ - (NSRange)decodeEnd:(ZXBitArray *)row endStart:(int)endStart error:(NSError **) return [ZXUPCEANReader findGuardPattern:row rowOffset:endStart whiteFirst:YES - pattern:ZX_UCPE_MIDDLE_END_PATTERN - patternLen:sizeof(ZX_UCPE_MIDDLE_END_PATTERN) / sizeof(int) + pattern:ZX_UPCE_MIDDLE_END_PATTERN + patternLen:sizeof(ZX_UPCE_MIDDLE_END_PATTERN) / sizeof(int) error:error]; } -- (BOOL)checkChecksum:(NSString *)s error:(NSError **)error { - return [super checkChecksum:[ZXUPCEReader convertUPCEtoUPCA:s] error:error]; ++ (BOOL)checkStandardUPCEANChecksum:(NSString *)s { + return [super checkStandardUPCEANChecksum:[ZXUPCEReader convertUPCEtoUPCA:s]]; } - (BOOL)determineNumSysAndCheckDigit:(NSMutableString *)resultString lgPatternFound:(int)lgPatternFound { @@ -147,7 +172,10 @@ + (NSString *)convertUPCEtoUPCA:(NSString *)upce { [result appendFormat:@"%C", lastChar]; break; } - [result appendFormat:@"%C", [upce characterAtIndex:7]]; + // Only append check digit in conversion if supplied + if (upce.length >= 8) { + [result appendFormat:@"%C", [upce characterAtIndex:7]]; + } return result; } diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerOSX-Prefix.pch b/ZXingObjC/oned/ZXUPCEWriter.h similarity index 83% rename from examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerOSX-Prefix.pch rename to ZXingObjC/oned/ZXUPCEWriter.h index 85aaa2c5c..7e2374c60 100644 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerOSX-Prefix.pch +++ b/ZXingObjC/oned/ZXUPCEWriter.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 ZXing authors + * Copyright 2012 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,8 @@ * limitations under the License. */ -#ifdef __OBJC__ - #import - #import -#endif +#import "ZXUPCEANWriter.h" + +@interface ZXUPCEWriter : ZXUPCEANWriter + +@end diff --git a/ZXingObjC/oned/ZXUPCEWriter.m b/ZXingObjC/oned/ZXUPCEWriter.m new file mode 100644 index 000000000..37a37805a --- /dev/null +++ b/ZXingObjC/oned/ZXUPCEWriter.m @@ -0,0 +1,89 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXUPCEWriter.h" +#import "ZXUPCEANReader.h" +#import "ZXUPCEReader.h" +#import "ZXBoolArray.h" + +// start guard 3 +// bars 7 * 6 +// end guard 6 +const int ZX_UPCE_CODE_WIDTH = 3 + (7 * 6) + 6; + +@implementation ZXUPCEWriter + +- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error { + if (format != kBarcodeFormatUPCE) { + [NSException raise:NSInvalidArgumentException format:@"Can only encode UPC_E"]; + } + return [super encode:contents format:format width:width height:height hints:hints error:error]; +} + +- (ZXBoolArray *)encode:(NSString *)contents { + int length = (int) [contents length]; + switch (length) { + case 7: + // No check digit present, calculate it and add it + contents = [contents stringByAppendingString:[NSString stringWithFormat:@"%d", [ZXUPCEANReader standardUPCEANChecksum:[ZXUPCEReader convertUPCEtoUPCA:contents]]]]; + break; + case 8: + if (![ZXUPCEReader checkStandardUPCEANChecksum:contents]) { + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:@"Contents do not pass checksum" + userInfo:nil]; + } + break; + default: + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:[NSString stringWithFormat:@"Requested contents should be 7 or 8 digits long, but got %d", (int)[contents length]] + userInfo:nil]; + } + + if (![self isNumeric:contents]) { + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:@"Input should only contain digits 0-9" + userInfo:nil]; + } + + int firstDigit = [[contents substringWithRange:NSMakeRange(0, 1)] intValue]; + if (firstDigit != 0 && firstDigit != 1) { + @throw [NSException exceptionWithName:@"IllegalArgumentException" + reason:@"Number system must be 0 or 1" + userInfo:nil]; + } + + int checkDigit = [[contents substringWithRange:NSMakeRange(7, 1)] intValue]; + int parities = ZX_UCPE_NUMSYS_AND_CHECK_DIGIT_PATTERNS[firstDigit][checkDigit]; + ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:ZX_UPCE_CODE_WIDTH]; + int pos = 0; + + pos += [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_START_END_PATTERN patternLen:ZX_UPC_EAN_START_END_PATTERN_LEN startColor:YES]; + + for (int i = 1; i <= 6; i++) { + int digit = [[contents substringWithRange:NSMakeRange(i, 1)] intValue]; + if ((parities >> (6 - i) & 1) == 1) { + digit += 10; + } + pos += [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_L_AND_G_PATTERNS[digit] patternLen:ZX_UPC_EAN_L_PATTERNS_SUB_LEN startColor:NO]; + } + + [self appendPattern:result pos:pos pattern:ZX_UPCE_MIDDLE_END_PATTERN patternLen:ZX_UPCE_MIDDLE_END_PATTERN_LEN startColor:NO]; + + return result; +} + +@end diff --git a/ZXingObjC/oned/ZXingObjCOneD.h b/ZXingObjC/oned/ZXingObjCOneD.h index 205b3e16c..5241e4e95 100644 --- a/ZXingObjC/oned/ZXingObjCOneD.h +++ b/ZXingObjC/oned/ZXingObjCOneD.h @@ -49,6 +49,7 @@ #import "ZXUPCEANReader.h" #import "ZXUPCEANWriter.h" #import "ZXUPCEReader.h" +#import "ZXUPCEWriter.h" // Result Parsers diff --git a/ZXingObjC/oned/rss/ZXRSSDataCharacter.h b/ZXingObjC/oned/rss/ZXRSSDataCharacter.h index 78a99019f..5e5a1de76 100644 --- a/ZXingObjC/oned/rss/ZXRSSDataCharacter.h +++ b/ZXingObjC/oned/rss/ZXRSSDataCharacter.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @interface ZXRSSDataCharacter : NSObject @property (nonatomic, assign, readonly) int value; diff --git a/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.h b/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.h index d6933666e..d549cdf29 100644 --- a/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.h +++ b/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * One row of an RSS Expanded Stacked symbol, consisting of 1+ expanded pairs. */ diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h index f272ca29c..2f9fbc148 100644 --- a/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h +++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBitArray, ZXRSSExpandedGeneralAppIdDecoder; @interface ZXAbstractExpandedDecoder : NSObject diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.h b/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.h index 691ebd710..4a70d93cb 100644 --- a/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.h +++ b/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXRSSExpandedDecodedInformation; @interface ZXRSSExpandedBlockParsedResult : NSObject diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.h b/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.h index b4c88c82c..ba2f8c72b 100644 --- a/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.h +++ b/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @interface ZXRSSExpandedCurrentParsingState : NSObject @property (nonatomic, assign) int position; diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.h b/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.h index 5dce8c8e4..32fdcb6a6 100644 --- a/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.h +++ b/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @interface ZXRSSExpandedDecodedObject : NSObject @property (nonatomic, assign, readonly) int theNewPosition; diff --git a/ZXingObjC/pdf417/ZXPDF417Common.h b/ZXingObjC/pdf417/ZXPDF417Common.h index 62efac228..15f116584 100644 --- a/ZXingObjC/pdf417/ZXPDF417Common.h +++ b/ZXingObjC/pdf417/ZXPDF417Common.h @@ -33,8 +33,7 @@ extern const int ZX_PDF417_MODULES_IN_STOP_PATTERN; + (ZXIntArray *)toIntArray:(NSArray *)list; /** - * Translate the symbol into a codeword. - * + * @param symbol encoded symbol to translate to a codeword * @return the codeword corresponding to the symbol. */ + (int)codeword:(int)symbol; diff --git a/ZXingObjC/pdf417/ZXPDF417ResultMetadata.h b/ZXingObjC/pdf417/ZXPDF417ResultMetadata.h index 166004921..71a606e5b 100644 --- a/ZXingObjC/pdf417/ZXPDF417ResultMetadata.h +++ b/ZXingObjC/pdf417/ZXPDF417ResultMetadata.h @@ -14,11 +14,20 @@ * limitations under the License. */ +#import + @interface ZXPDF417ResultMetadata : NSObject @property (nonatomic, assign) int segmentIndex; @property (nonatomic, copy) NSString *fileId; -@property (nonatomic, strong) NSArray *optionalData; @property (nonatomic, assign) BOOL lastSegment; +@property (nonatomic, assign) int segmentCount; +@property (nonatomic, copy) NSString *sender; +@property (nonatomic, copy) NSString *addressee; +@property (nonatomic, copy) NSString *fileName; +@property (nonatomic, assign) long long fileSize; +@property (nonatomic, assign) long long timestamp; +@property (nonatomic, assign) int checksum; +@property (nonatomic, strong) NSArray *optionalData; @end diff --git a/ZXingObjC/pdf417/ZXPDF417ResultMetadata.m b/ZXingObjC/pdf417/ZXPDF417ResultMetadata.m index c5e2d8aec..fa54ba2ba 100644 --- a/ZXingObjC/pdf417/ZXPDF417ResultMetadata.m +++ b/ZXingObjC/pdf417/ZXPDF417ResultMetadata.m @@ -18,4 +18,14 @@ @implementation ZXPDF417ResultMetadata +- (id)init { + if (self = [super init]) { + _segmentCount = -1; + _fileSize = -1; + _timestamp = -1; + _checksum = -1; + } + return self; +} + @end diff --git a/ZXingObjC/pdf417/ZXPDF417Writer.m b/ZXingObjC/pdf417/ZXPDF417Writer.m index 2f5a0223d..b2943e849 100644 --- a/ZXingObjC/pdf417/ZXPDF417Writer.m +++ b/ZXingObjC/pdf417/ZXPDF417Writer.m @@ -27,6 +27,12 @@ */ const int ZX_PDF417_WHITE_SPACE = 30; +/** + * default error correction level + */ +const int ZX_PDF417_DEFAULT_ERROR_CORRECTION_LEVEL = 2; + + @implementation ZXPDF417Writer - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height @@ -37,6 +43,7 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt ZXPDF417 *encoder = [[ZXPDF417 alloc] init]; int margin = ZX_PDF417_WHITE_SPACE; + int errorCorrectionLevel = ZX_PDF417_DEFAULT_ERROR_CORRECTION_LEVEL; if (hints != nil) { encoder.compact = hints.pdf417Compact; @@ -51,12 +58,15 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt if (hints.margin) { margin = [hints.margin intValue]; } + if (hints.errorCorrectionLevelPDF417) { + errorCorrectionLevel = hints.errorCorrectionLevelPDF417.intValue; + } if (hints.encoding > 0) { encoder.encoding = hints.encoding; } } - return [self bitMatrixFromEncoder:encoder contents:contents width:width height:height margin:margin error:error]; + return [self bitMatrixFromEncoder:encoder contents:contents errorCorrectionLevel:errorCorrectionLevel width:width height:height margin:margin error:error]; } - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error { @@ -68,18 +78,17 @@ - (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format widt */ - (ZXBitMatrix *)bitMatrixFromEncoder:(ZXPDF417 *)encoder contents:(NSString *)contents + errorCorrectionLevel:(int)errorCorrectionLevel width:(int)width height:(int)height margin:(int)margin error:(NSError **)error { - int errorCorrectionLevel = 2; if (![encoder generateBarcodeLogic:contents errorCorrectionLevel:errorCorrectionLevel error:error]) { return nil; } - int lineThickness = 2; int aspectRatio = 4; - NSArray *originalScale = [[encoder barcodeMatrix] scaledMatrixWithXScale:lineThickness yScale:aspectRatio * lineThickness]; + NSArray *originalScale = [[encoder barcodeMatrix] scaledMatrixWithXScale:1 yScale:aspectRatio]; BOOL rotated = NO; if ((height > width) ^ ([(ZXByteArray *)originalScale[0] length] < [originalScale count])) { originalScale = [self rotateArray:originalScale]; @@ -97,14 +106,13 @@ - (ZXBitMatrix *)bitMatrixFromEncoder:(ZXPDF417 *)encoder } if (scale > 1) { - NSArray *scaledMatrix = - [[encoder barcodeMatrix] scaledMatrixWithXScale:scale * lineThickness yScale:scale * aspectRatio * lineThickness]; + NSArray *scaledMatrix = [[encoder barcodeMatrix] scaledMatrixWithXScale:scale yScale:scale * aspectRatio]; if (rotated) { scaledMatrix = [self rotateArray:scaledMatrix]; } - return [self bitMatrixFrombitArray:scaledMatrix margin:margin]; + return [self bitMatrixFromBitArray:scaledMatrix margin:margin]; } - return [self bitMatrixFrombitArray:originalScale margin:margin]; + return [self bitMatrixFromBitArray:originalScale margin:margin]; } /** @@ -114,13 +122,13 @@ - (ZXBitMatrix *)bitMatrixFromEncoder:(ZXPDF417 *)encoder * @param margin border around the barcode * @return BitMatrix of the input */ -- (ZXBitMatrix *)bitMatrixFrombitArray:(NSArray *)input margin:(int)margin { +- (ZXBitMatrix *)bitMatrixFromBitArray:(NSArray *)input margin:(int)margin { // Creates the bitmatrix with extra space for whtespace ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:[(ZXByteArray *)input[0] length] + 2 * margin height:(int)[input count] + 2 * margin]; [output clear]; - for (int y = 0, yOutput = output.height - margin; y < [input count]; y++, yOutput--) { + for (int y = 0, yOutput = output.height - margin - 1; y < [input count]; y++, yOutput--) { for (int x = 0; x < [(ZXByteArray *)input[0] length]; x++) { - // Zero is white in the bytematrix + // Zero is white in the byte matrix if ([(ZXByteArray *)input[y] array][x] == 1) { [output setX:x + margin y:yOutput]; } diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.h b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.h index f2fb7d9fd..e60263d7e 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.h +++ b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @interface ZXPDF417BarcodeMetadata : NSObject @property (nonatomic, assign, readonly) int columnCount; diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h index 76147a264..514de6069 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h +++ b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXIntArray; @interface ZXPDF417BarcodeValue : NSObject diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.h b/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.h index da74a7894..44161b172 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.h +++ b/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBitMatrix, ZXResultPoint; @interface ZXPDF417BoundingBox : NSObject diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.h b/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.h index d64bf47c6..af0d21dfe 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.h +++ b/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @interface ZXPDF417Codeword : NSObject @property (nonatomic, assign, readonly) int startX; diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.h b/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.h index a50e3478f..32f1f3b35 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.h +++ b/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @interface ZXPDF417CodewordDecoder : NSObject + (int)decodedValue:(NSArray *)moduleBitCount; diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m b/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m index 2a3b82389..3dee80b78 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m +++ b/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m @@ -88,8 +88,10 @@ + (int)bitValue:(NSArray *)moduleBitCount { + (int)closestDecodedValue:(NSArray *)moduleBitCount { int bitCountSum = [ZXPDF417Common bitCountSum:moduleBitCount]; float bitCountRatios[ZX_PDF417_BARS_IN_MODULE]; - for (int i = 0; i < ZX_PDF417_BARS_IN_MODULE; i++) { - bitCountRatios[i] = [moduleBitCount[i] intValue] / (float) bitCountSum; + if (bitCountSum > 1) { + for (int i = 0; i < ZX_PDF417_BARS_IN_MODULE; i++) { + bitCountRatios[i] = [moduleBitCount[i] intValue] / (float) bitCountSum; + } } float bestMatchError = MAXFLOAT; int bestMatch = -1; diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.h b/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.h index a90df6297..ce0b46f3b 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.h +++ b/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import "ZXPDF417ResultMetadata.h" + @class ZXDecoderResult, ZXIntArray; /** @@ -22,5 +24,6 @@ @interface ZXPDF417DecodedBitStreamParser : NSObject + (ZXDecoderResult *)decode:(ZXIntArray *)codewords ecLevel:(NSString *)ecLevel error:(NSError **)error; ++ (int)decodeMacroBlock:(ZXIntArray *)codewords codeIndex:(int)codeIndex resultMetadata:(ZXPDF417ResultMetadata *)resultMetadata; @end diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m b/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m index 8a8d99961..6c4f9ec4b 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m +++ b/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m @@ -14,12 +14,12 @@ * limitations under the License. */ +#import "ZXPDF417DecodedBitStreamParser.h" #import "ZXCharacterSetECI.h" #import "ZXDecoderResult.h" #import "ZXErrors.h" #import "ZXIntArray.h" -#import "ZXPDF417DecodedBitStreamParser.h" -#import "ZXPDF417ResultMetadata.h" +#import "ZXDecimal.h" typedef enum { ZXPDF417ModeAlpha = 0, @@ -43,6 +43,14 @@ const int ZX_PDF417_MODE_SHIFT_TO_BYTE_COMPACTION_MODE = 913; const int ZX_PDF417_MAX_NUMERIC_CODEWORDS = 15; +const int ZX_MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME = 0; +const int ZX_MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT = 1; +const int ZX_MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP = 2; +const int ZX_MACRO_PDF417_OPTIONAL_FIELD_SENDER = 3; +const int ZX_MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE = 4; +const int ZX_MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE = 5; +const int ZX_MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM = 6; + const int ZX_PDF417_PL = 25; const int ZX_PDF417_LL = 27; const int ZX_PDF417_AS = 27; @@ -113,8 +121,7 @@ + (ZXDecoderResult *)decode:(ZXIntArray *)codewords ecLevel:(NSString *)ecLevel } break; case ZX_PDF417_ECI_CHARSET: { - ZXCharacterSetECI *charsetECI = - [ZXCharacterSetECI characterSetECIByValue:codewords.array[codeIndex++]]; + ZXCharacterSetECI *charsetECI = [ZXCharacterSetECI characterSetECIByValue:codewords.array[codeIndex++]]; encoding = charsetECI.encoding; break; } @@ -124,7 +131,7 @@ + (ZXDecoderResult *)decode:(ZXIntArray *)codewords ecLevel:(NSString *)ecLevel break; case ZX_PDF417_ECI_USER_DEFINED: // Can't do anything with user ECI; skip its 1 character - codeIndex ++; + codeIndex++; break; case ZX_PDF417_BEGIN_MACRO_PDF417_CONTROL_BLOCK: codeIndex = [self decodeMacroBlock:codewords codeIndex:codeIndex resultMetadata:resultMetadata]; @@ -177,32 +184,91 @@ + (int)decodeMacroBlock:(ZXIntArray *)codewords codeIndex:(int)codeIndex resultM codeIndex = [self textCompaction:codewords codeIndex:codeIndex result:fileId]; resultMetadata.fileId = [NSString stringWithString:fileId]; + int optionalFieldsStart = -1; if (codewords.array[codeIndex] == ZX_PDF417_BEGIN_MACRO_PDF417_OPTIONAL_FIELD) { - codeIndex++; - NSMutableArray *additionalOptionCodeWords = [NSMutableArray array]; + optionalFieldsStart = codeIndex + 1; + } - BOOL end = NO; - while ((codeIndex < codewords.array[0]) && !end) { - int code = codewords.array[codeIndex++]; - if (code < ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) { - [additionalOptionCodeWords addObject:@(code)]; - } else { - switch (code) { - case ZX_PDF417_MACRO_PDF417_TERMINATOR: - resultMetadata.lastSegment = YES; - codeIndex++; - end = YES; + while (codeIndex < codewords.array[0]) { + switch (codewords.array[codeIndex]) { + case ZX_PDF417_BEGIN_MACRO_PDF417_OPTIONAL_FIELD: + codeIndex++; + switch (codewords.array[codeIndex]) { + case ZX_MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME: + { + NSMutableString *fileName = [NSMutableString new]; + codeIndex = [self textCompaction:codewords codeIndex:codeIndex + 1 result:fileName]; + resultMetadata.fileName = fileName; + break; + } + case ZX_MACRO_PDF417_OPTIONAL_FIELD_SENDER: + { + NSMutableString *sender = [NSMutableString new]; + codeIndex = [self textCompaction:codewords codeIndex:codeIndex + 1 result:sender]; + resultMetadata.sender = sender; + break; + } + case ZX_MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE: + { + NSMutableString *addressee = [NSMutableString new]; + codeIndex = [self textCompaction:codewords codeIndex:codeIndex + 1 result:addressee]; + resultMetadata.addressee = addressee; break; + } + case ZX_MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT: + { + NSMutableString *segmentCount = [NSMutableString new]; + codeIndex = [self numericCompaction:codewords codeIndex:codeIndex + 1 result:segmentCount]; + resultMetadata.segmentCount = [segmentCount intValue]; + break; + } + case ZX_MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP: + { + NSMutableString *timestamp = [NSMutableString new]; + codeIndex = [self numericCompaction:codewords codeIndex:codeIndex + 1 result:timestamp]; + resultMetadata.timestamp = [timestamp longLongValue]; + break; + } + case ZX_MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM: + { + NSMutableString *checksum = [NSMutableString new]; + codeIndex = [self numericCompaction:codewords codeIndex:codeIndex + 1 result:checksum]; + resultMetadata.checksum = [checksum intValue]; + break; + } + case ZX_MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE: + { + NSMutableString *fileSize = [NSMutableString new]; + codeIndex = [self numericCompaction:codewords codeIndex:codeIndex + 1 result:fileSize]; + resultMetadata.fileSize = [fileSize longLongValue]; + break; + } default: - return -1; + [NSException raise:NSInvalidArgumentException format:@"MacroPDF417 invalid format"]; } - } + break; + case ZX_PDF417_MACRO_PDF417_TERMINATOR: + codeIndex++; + resultMetadata.lastSegment = YES; + break; + default: + [NSException raise:NSInvalidArgumentException format:@"MacroPDF417 invalid format"]; } - resultMetadata.optionalData = additionalOptionCodeWords; - } else if (codewords.array[codeIndex] == ZX_PDF417_MACRO_PDF417_TERMINATOR) { - resultMetadata.lastSegment = YES; - codeIndex++; + // copy optional fields to additional options + if (optionalFieldsStart != -1) { + int optionalFieldsLength = codeIndex - optionalFieldsStart; + if (resultMetadata.lastSegment) { + // do not include terminator + optionalFieldsLength--; + } + NSMutableArray *additionalOptionCodeWords = [NSMutableArray array]; + for (int i = optionalFieldsStart; i < (optionalFieldsStart + optionalFieldsLength); i++) { + int code = codewords.array[i]; + [additionalOptionCodeWords addObject:@(code)]; + } + resultMetadata.optionalData = additionalOptionCodeWords; + } } return codeIndex; @@ -629,11 +695,13 @@ + (int)numericCompaction:(ZXIntArray *)codewords codeIndex:(int)codeIndex result Remove leading 1 => Result is 000213298174000 */ + (NSString *)decodeBase900toBase10:(ZXIntArray *)codewords count:(int)count { - NSDecimalNumber *result = [NSDecimalNumber zero]; + ZXDecimal *result = [ZXDecimal decimalWithString:@"0"]; // zero for (int i = 0; i < count; i++) { - result = [result decimalNumberByAdding:[ZX_PDF417_EXP900[count - i - 1] decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithDecimal:[@(codewords.array[i]) decimalValue]]]]; + ZXDecimal *toAdd = [ZXDecimal decimalWithDecimalNumber:ZX_PDF417_EXP900[count - i - 1]]; + ZXDecimal *multiplyWith = [ZXDecimal decimalWithString:[@(codewords.array[i]) stringValue]]; + result = [result decimalByAdding:[toAdd decimalByMultiplyingBy:multiplyWith]]; } - NSString *resultString = [result stringValue]; + NSString *resultString = result.value; if (![resultString hasPrefix:@"1"]) { return nil; } diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m index 05a5a0312..c8baa1ada 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m +++ b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m @@ -125,7 +125,8 @@ - (BOOL)getRowHeights:(ZXIntArray **)rowHeights { int rowNumber = codeword.rowNumber; if (rowNumber >= result.length) { *rowHeights = nil; - return NO; + // We have more rows than the barcode metadata allows for, ignore them. + continue; } result.array[rowNumber]++; } // else throw exception? diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m b/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m index 43d08317e..4dd47ba1b 100644 --- a/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m +++ b/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m @@ -382,7 +382,8 @@ + (NSArray *)createBarcodeMatrix:(ZXPDF417DetectionResult *)detectionResult { int rowNumber = codeword.rowNumber; if (rowNumber >= 0) { if (rowNumber >= barcodeMatrix.count) { - return nil; + // We have more rows than the barcode metadata allows for, ignore them. + continue; } [(ZXPDF417BarcodeValue *)barcodeMatrix[rowNumber][column] setValue:codeword.value]; } diff --git a/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h b/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h index 3f89cfb03..225863b95 100644 --- a/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h +++ b/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXIntArray; /** @@ -25,7 +27,10 @@ @interface ZXPDF417ECErrorCorrection : NSObject /** - * @return number of errors + * @param received received codewords + * @param numECCodewords number of those codewords used for EC + * @param erasures location of erasures + * @return number of errors or nil if errors cannot be corrected, maybe because of too many errors */ - (int)decode:(ZXIntArray *)received numECCodewords:(int)numECCodewords erasures:(ZXIntArray *)erasures; diff --git a/ZXingObjC/pdf417/detector/ZXPDF417Detector.h b/ZXingObjC/pdf417/detector/ZXPDF417Detector.h index 2ebaee8b2..0252dc18e 100644 --- a/ZXingObjC/pdf417/detector/ZXPDF417Detector.h +++ b/ZXingObjC/pdf417/detector/ZXPDF417Detector.h @@ -25,6 +25,7 @@ /** * Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations. * + * @param image barcode image to decode * @param hints optional hints to detector * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will * be found and returned diff --git a/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.h b/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.h index b7e8c9250..7d741cf91 100644 --- a/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.h +++ b/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXBitMatrix; @interface ZXPDF417DetectorResult : NSObject diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417.h b/ZXingObjC/pdf417/encoder/ZXPDF417.h index 76a45a182..23f862a6a 100644 --- a/ZXingObjC/pdf417/encoder/ZXPDF417.h +++ b/ZXingObjC/pdf417/encoder/ZXPDF417.h @@ -31,9 +31,9 @@ - (id)initWithCompact:(BOOL)compact; /** - * Generates the barcode logic. - * - * @param msg the message to encode + * @param msg message to encode + * @param errorCorrectionLevel PDF417 error correction level to use or nil if the contents cannot be + * encoded in this format */ - (BOOL)generateBarcodeLogic:(NSString *)msg errorCorrectionLevel:(int)errorCorrectionLevel error:(NSError **)error; @@ -49,6 +49,11 @@ /** * Sets max/min row/col values + * + * @param maxCols maximum allowed columns + * @param minCols minimum allowed columns + * @param maxRows maximum allowed rows + * @param minRows minimum allowed rows */ - (void)setDimensionsWithMaxCols:(int)maxCols minCols:(int)minCols maxRows:(int)maxRows minRows:(int)minRows; diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.h b/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.h index 9ff0aed5f..5f423fbfb 100644 --- a/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.h +++ b/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXPDF417BarcodeRow; /** diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.h b/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.h index 0e1f155ff..991193463 100644 --- a/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.h +++ b/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * Data object to specify the minimum and maximum number of rows and columns for a PDF417 barcode. */ diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m b/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m index 7e1e8197e..5f062052e 100644 --- a/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m +++ b/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m @@ -160,11 +160,10 @@ + (NSString *)encodeHighLevel:(NSString *)msg compaction:(ZXPDF417Compaction)com int textSubMode = ZX_PDF417_SUBMODE_ALPHA; // User selected encoding mode - ZXByteArray *bytes = nil; //Fill later and only if needed if (compaction == ZXPDF417CompactionText) { [self encodeText:msg startpos:p count:(int)len buffer:sb initialSubmode:textSubMode]; } else if (compaction == ZXPDF417CompactionByte) { - bytes = [self bytesForMessage:msg encoding:encoding]; + ZXByteArray *bytes = [self bytesForMessage:msg encoding:encoding]; [self encodeBinary:bytes startpos:p count:(int)msg.length startmode:ZX_PDF417_BYTE_COMPACTION buffer:sb]; } else if (compaction == ZXPDF417CompactionNumeric) { [sb appendFormat:@"%C", (unichar) ZX_PDF417_LATCH_TO_NUMERIC]; @@ -190,21 +189,20 @@ + (NSString *)encodeHighLevel:(NSString *)msg compaction:(ZXPDF417Compaction)com textSubMode = [self encodeText:msg startpos:p count:t buffer:sb initialSubmode:textSubMode]; p += t; } else { - if (bytes == NULL) { - bytes = [self bytesForMessage:msg encoding:encoding]; - } - int b = [self determineConsecutiveBinaryCount:msg bytes:bytes startpos:p error:error]; + int b = [self determineConsecutiveBinaryCount:msg startpos:p encoding:encoding error:error]; if (b == -1) { return nil; } else if (b == 0) { b = 1; } - if (b == 1 && encodingMode == ZX_PDF417_TEXT_COMPACTION) { + NSString *submsg = [msg substringWithRange:NSMakeRange(p, b)]; + ZXByteArray *bytes = [self bytesForMessage:submsg encoding:encoding]; + if (bytes.length ==1 && encodingMode == ZX_PDF417_TEXT_COMPACTION) { //Switch for one byte (instead of latch) - [self encodeBinary:bytes startpos:p count:1 startmode:ZX_PDF417_TEXT_COMPACTION buffer:sb]; + [self encodeBinary:bytes startpos:0 count:1 startmode:ZX_PDF417_TEXT_COMPACTION buffer:sb]; } else { //Mode latch performed by encodeBinary - [self encodeBinary:bytes startpos:p count:b startmode:encodingMode buffer:sb]; + [self encodeBinary:bytes startpos:0 count:bytes.length startmode:encodingMode buffer:sb]; encodingMode = ZX_PDF417_BYTE_COMPACTION; textSubMode = ZX_PDF417_SUBMODE_ALPHA; //Reset after latch } @@ -516,11 +514,12 @@ + (int)determineConsecutiveTextCount:(NSString *)msg startpos:(int)startpos { * Determines the number of consecutive characters that are encodable using binary compaction. * * @param msg the message - * @param bytes the message converted to a byte array * @param startpos the start position within the message + * @param encoding the charset used to convert the message to a byte array * @return the requested character count */ -+ (int)determineConsecutiveBinaryCount:(NSString *)msg bytes:(ZXByteArray *)bytes startpos:(int)startpos error:(NSError **)error { ++ (int)determineConsecutiveBinaryCount:(NSString *)msg startpos:(int)startpos encoding:(NSStringEncoding)encoding error:(NSError **)error { + NSUInteger len = msg.length; int idx = startpos; while (idx < len) { @@ -540,11 +539,8 @@ + (int)determineConsecutiveBinaryCount:(NSString *)msg bytes:(ZXByteArray *)byte return idx - startpos; } ch = [msg characterAtIndex:idx]; - - //Check if character is encodable - //Sun returns a ASCII 63 (?) for a character that cannot be mapped. Let's hope all - //other VMs do the same - if (bytes.array[idx] == 63 && ch != '?') { + NSString *chString = [NSString stringWithFormat: @"%c", ch]; + if (![chString canBeConvertedToEncoding:encoding]) { NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Non-encodable character detected: %c (Unicode: %C)", ch, (unichar)ch]}; if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo]; diff --git a/ZXingObjC/qrcode/ZXQRCodeReader.m b/ZXingObjC/qrcode/ZXQRCodeReader.m index 1bb828645..166fce664 100644 --- a/ZXingObjC/qrcode/ZXQRCodeReader.m +++ b/ZXingObjC/qrcode/ZXQRCodeReader.m @@ -142,6 +142,10 @@ - (ZXBitMatrix *)extractPureBits:(ZXBitMatrix *)image { // Special case, where bottom-right module wasn't black so we found something else in the last row // Assume it's a square, so use height as the width right = left + (bottom - top); + if (right >= image.width) { + // Abort if that would not make sense -- off image + return nil; + } } int matrixWidth = round((right - left + 1) / moduleSize); diff --git a/ZXingObjC/qrcode/ZXingObjCQRCode.h b/ZXingObjC/qrcode/ZXingObjCQRCode.h index 0672a3bb6..f8769b6c4 100644 --- a/ZXingObjC/qrcode/ZXingObjCQRCode.h +++ b/ZXingObjC/qrcode/ZXingObjCQRCode.h @@ -20,6 +20,7 @@ #define _ZXINGOBJC_QRCODE_ +#import "ZXMultiDetector.h" #import "ZXQRCode.h" #import "ZXQRCodeAlignmentPattern.h" #import "ZXQRCodeDecoder.h" @@ -32,6 +33,7 @@ #import "ZXQRCodeFinderPatternFinder.h" #import "ZXQRCodeFinderPatternInfo.h" #import "ZXQRCodeMode.h" +#import "ZXQRCodeMultiReader.h" #import "ZXQRCodeReader.h" #import "ZXQRCodeVersion.h" #import "ZXQRCodeWriter.h" diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.m b/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.m index 108bd397f..b75dcae86 100644 --- a/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.m +++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.m @@ -17,6 +17,8 @@ #import "ZXBitMatrix.h" #import "ZXQRCodeDataMask.h" +// See ISO 18004:2006 6.8.1 + /** * 000: mask bits for which (x + y) mod 2 == 0 */ @@ -99,6 +101,7 @@ - (BOOL)isMasked:(int)i j:(int)j { /** * 101: mask bits for which xy mod 2 + xy mod 3 == 0 + * equivalently, such that xy mod 6 == 0 */ @interface ZXDataMask101 : ZXQRCodeDataMask @@ -107,8 +110,7 @@ @interface ZXDataMask101 : ZXQRCodeDataMask @implementation ZXDataMask101 - (BOOL)isMasked:(int)i j:(int)j { - int temp = i * j; - return (temp & 0x01) + (temp % 3) == 0; + return (i * j) % 6 == 0; } @end @@ -116,6 +118,7 @@ - (BOOL)isMasked:(int)i j:(int)j { /** * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0 + * equivalently, such that xy mod 6 < 3 */ @interface ZXDataMask110 : ZXQRCodeDataMask @@ -124,8 +127,7 @@ @interface ZXDataMask110 : ZXQRCodeDataMask @implementation ZXDataMask110 - (BOOL)isMasked:(int)i j:(int)j { - int temp = i * j; - return (((temp & 0x01) + (temp % 3)) & 0x01) == 0; + return ((i * j) % 6) < 3; } @end @@ -133,6 +135,7 @@ - (BOOL)isMasked:(int)i j:(int)j { /** * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0 + * equivalently, such that (x + y + xy mod 3) mod 2 == 0 */ @interface ZXDataMask111 : ZXQRCodeDataMask @@ -141,7 +144,7 @@ @interface ZXDataMask111 : ZXQRCodeDataMask @implementation ZXDataMask111 - (BOOL)isMasked:(int)i j:(int)j { - return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0; + return ((i + j + ((i * j) % 3)) & 0x01) == 0; } @end diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m b/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m index b725d471f..e57800055 100644 --- a/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m +++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m @@ -153,9 +153,11 @@ + (BOOL)decodeHanziSegment:(ZXBitSource *)bits result:(NSMutableString *)result while (count > 0) { int twoBytes = [bits readBits:13]; int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060); - if (assembledTwoBytes < 0x003BF) { + if (assembledTwoBytes < 0x00A00) { + // In the 0xA1A1 to 0xAAFE range assembledTwoBytes += 0x0A1A1; } else { + // In the 0xB0A1 to 0xFAFE range assembledTwoBytes += 0x0A6A1; } int8_t bytes[2]; diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h b/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h index 5578557a0..1b12f876b 100644 --- a/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h +++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h @@ -22,29 +22,31 @@ */ @interface ZXQRCodeDecoder : NSObject +- (ZXDecoderResult *)decode:(NSArray *)image error:(NSError **)error; + /** * Convenience method that can decode a QR Code represented as a 2D array of booleans. * "true" is taken to mean a black module. * * @param image booleans representing white/black QR Code modules - * @return text and bytes encoded within the QR Code - * @return nil if the QR Code cannot be decoded - * @return nil if error correction fails + * @param hints decoding hints that should be used to influence decoding + * @return text and bytes encoded within the QR Code or nil if: + * - the QR Code cannot be decoded + * - error correction fails */ -- (ZXDecoderResult *)decode:(NSArray *)image error:(NSError **)error; +- (ZXDecoderResult *)decode:(NSArray *)image hints:(ZXDecodeHints *)hints error:(NSError **)error; + +- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits error:(NSError **)error; /** - * Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black module. + * Decodes a QR Code represented as a ZXBitMatrix. A 1 or "true" is taken to mean a black module. * * @param bits booleans representing white/black QR Code modules + * @param hints decoding hints that should be used to influence decoding * @return text and bytes encoded within the QR Code * @return nil if the QR Code cannot be decoded * @return nil if error correction fails */ -- (ZXDecoderResult *)decode:(NSArray *)image hints:(ZXDecodeHints *)hints error:(NSError **)error; - -- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits error:(NSError **)error; - - (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits hints:(ZXDecodeHints *)hints error:(NSError **)error; @end diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.h b/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.h index f31f497fc..46a9b0dfb 100644 --- a/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.h +++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * Meta-data container for QR Code decoding. Instances of this class may be used to convey information back to the * decoding caller. Callers are expected to process this. diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.h b/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.h index 72230a88f..fdd54e928 100644 --- a/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.h +++ b/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + /** * See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels * defined by the QR code standard. diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeMode.h b/ZXingObjC/qrcode/decoder/ZXQRCodeMode.h index af5822b86..b74c05cec 100644 --- a/ZXingObjC/qrcode/decoder/ZXQRCodeMode.h +++ b/ZXingObjC/qrcode/decoder/ZXQRCodeMode.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXQRCodeVersion; /** @@ -35,8 +37,8 @@ /** * @param version version in question - * @return number of bits used, in this QR Code symbol {@link Version}, to encode the - * count of characters that will follow encoded in this Mode + * @return number of bits used, in this QR Code symbol `ZXQRCodeVersion`, to encode the + * count of characters that will follow encoded in this Mode */ - (int)characterCountBits:(ZXQRCodeVersion *)version; diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.m b/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.m index a0127394f..05b2f140e 100644 --- a/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.m +++ b/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.m @@ -265,7 +265,7 @@ + (void)initialize { ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:13 dataCodewords:16]]], [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:17 - alignmentPatternCenters:[[ZXIntArray alloc] initWithInts:6, 30, 50, 78, -1] + alignmentPatternCenters:[[ZXIntArray alloc] initWithInts:6, 30, 54, 78, -1] ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:1 dataCodewords:107] ecBlocks2:[ZXQRCodeECB ecbWithCount:5 dataCodewords:108]] ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:10 dataCodewords:46] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:47]] ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:1 dataCodewords:22] ecBlocks2:[ZXQRCodeECB ecbWithCount:15 dataCodewords:23]] diff --git a/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.h b/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.h index 6c0af369a..78e95c339 100644 --- a/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.h +++ b/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.h @@ -23,7 +23,7 @@ * * At the moment this only looks for the bottom-right alignment pattern. * - * This is mostly a simplified copy of {@link FinderPatternFinder}. It is copied, + * This is mostly a simplified copy of ZXFinderPatternFinder. It is copied, * pasted and stripped down here for maximum performance but does unfortunately duplicate * some code. * diff --git a/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.m b/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.m index e9cde0c2d..c7462042b 100644 --- a/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.m +++ b/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.m @@ -149,7 +149,7 @@ - (BOOL)foundPatternCross:(int *)stateCount { * @param centerJ center of the section that appears to cross an alignment pattern * @param maxCount maximum reasonable number of modules that should be * observed in any reading state, based on the results of the horizontal scan - * @return vertical center of alignment pattern, or {@link Float#NaN} if not found + * @return vertical center of alignment pattern, or `NAN` if not found */ - (float)crossCheckVertical:(int)startI centerJ:(int)centerJ maxCount:(int)maxCount originalStateCountTotal:(int)originalStateCountTotal { int maxI = self.image.height; diff --git a/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h b/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h index dcad42d50..03e775c5e 100644 --- a/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h +++ b/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h @@ -29,20 +29,21 @@ - (id)initWithImage:(ZXBitMatrix *)image; /** - * Detects a QR Code in an image, simply. + * Detects a QR Code in an image. * - * @return ZXDetectorResult encapsulating results of detecting a QR Code or nil - * if no QR Code can be found + * @return ZXDetectorResult encapsulating results of detecting a QR Code or nil if: + * - no QR Code can be found + * - a QR Code cannot be decoded */ - (ZXDetectorResult *)detectWithError:(NSError **)error; /** - * Detects a QR Code in an image, simply. + * Detects a QR Code in an image. * * @param hints optional hints to detector - * @return ZXDetectorResult encapsulating results of detecting a QR Code - * @return nil if QR Code cannot be found - * @return nil if a QR Code cannot be decoded + * @return ZXDetectorResult encapsulating results of detecting a QR Code or nil if: + * - QR Code cannot be found + * - a QR Code cannot be decoded */ - (ZXDetectorResult *)detect:(ZXDecodeHints *)hints error:(NSError **)error; @@ -51,6 +52,11 @@ /** * Computes an average estimated module size based on estimated derived from the positions * of the three finder patterns. + * + * @param topLeft detected top-left finder pattern center + * @param topRight detected top-right finder pattern center + * @param bottomLeft detected bottom-left finder pattern center + * @return estimated module size */ - (float)calculateModuleSize:(ZXResultPoint *)topLeft topRight:(ZXResultPoint *)topRight bottomLeft:(ZXResultPoint *)bottomLeft; diff --git a/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.h b/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.h index ada43ad22..022bbe3bd 100644 --- a/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.h +++ b/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.h @@ -66,6 +66,6 @@ extern const int ZX_FINDER_PATTERN_MAX_MODULES; * @param j end of possible finder pattern in row * @return true if a finder pattern candidate was found this time */ -- (BOOL)handlePossibleCenter:(const int[])stateCount i:(int)i j:(int)j pureBarcode:(BOOL)pureBarcode; +- (BOOL)handlePossibleCenter:(const int[])stateCount i:(int)i j:(int)j; @end diff --git a/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.m b/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.m index 3a3b7b2f0..dc8d39ca0 100644 --- a/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.m +++ b/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.m @@ -25,7 +25,7 @@ const int ZX_CENTER_QUORUM = 2; const int ZX_FINDER_PATTERN_MIN_SKIP = 3; -const int ZX_FINDER_PATTERN_MAX_MODULES = 57; +const int ZX_FINDER_PATTERN_MAX_MODULES = 97; @interface ZXQRCodeFinderPatternFinder () @@ -56,7 +56,6 @@ - (id)initWithImage:(ZXBitMatrix *)image resultPointCallback:(id= i && centerJ >= i && [self.image getX:centerJ - i y:startI - i]) { + while (centerI >= i && centerJ >= i && [self.image getX:centerJ - i y:centerI - i]) { stateCount[2]++; i++; } - if (startI < i || centerJ < i) { + if (stateCount[2] == 0) { return NO; } // Continue up, left finding white space - while (startI >= i && centerJ >= i && ![self.image getX:centerJ - i y:startI - i] && - stateCount[1] <= maxCount) { + while (centerI >= i && centerJ >= i && ![self.image getX:centerJ - i y:centerI - i]) { stateCount[1]++; i++; } - - // If already too many modules in this state or ran off the edge: - if (startI < i || centerJ < i || stateCount[1] > maxCount) { + if (stateCount[1] == 0) { return NO; } // Continue up, left finding black border - while (startI >= i && centerJ >= i && [self.image getX:centerJ - i y:startI - i] && - stateCount[0] <= maxCount) { + while (centerI >= i && centerJ >= i && [self.image getX:centerJ - i y:centerI - i]) { stateCount[0]++; i++; } - if (stateCount[0] > maxCount) { + if (stateCount[0] == 0) { return NO; } @@ -232,42 +257,30 @@ - (BOOL)crossCheckDiagonal:(int)startI centerJ:(int)centerJ maxCount:(int)maxCou // Now also count down, right from center i = 1; - while (startI + i < maxI && centerJ + i < maxJ && [self.image getX:centerJ + i y:startI + i]) { + while (centerI + i < maxI && centerJ + i < maxJ && [self.image getX:centerJ + i y:centerI + i]) { stateCount[2]++; i++; } - // Ran off the edge? - if (startI + i >= maxI || centerJ + i >= maxJ) { - return NO; - } - - while (startI + i < maxI && centerJ + i < maxJ && ![self.image getX:centerJ + i y:startI + i] && - stateCount[3] < maxCount) { + while (centerI + i < maxI && centerJ + i < maxJ && ![self.image getX:centerJ + i y:centerI + i]) { stateCount[3]++; i++; } - if (startI + i >= maxI || centerJ + i >= maxJ || stateCount[3] >= maxCount) { + if (stateCount[3] == 0) { return NO; } - while (startI + i < maxI && centerJ + i < maxJ && [self.image getX:centerJ + i y:startI + i] && - stateCount[4] < maxCount) { + while (centerI + i < maxI && centerJ + i < maxJ && [self.image getX:centerJ + i y:centerI + i]) { stateCount[4]++; i++; } - if (stateCount[4] >= maxCount) { + if (stateCount[4] == 0) { return NO; } - // If we found a finder-pattern-like section, but its size is more than 100% different than - // the original, assume it's a false positive - int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4]; - return - abs(stateCountTotal - originalStateCountTotal) < 2 * originalStateCountTotal && - [ZXQRCodeFinderPatternFinder foundPatternCross:stateCount]; + return [ZXQRCodeFinderPatternFinder foundPatternDiagonal:stateCount]; } /** @@ -279,7 +292,7 @@ - (BOOL)crossCheckDiagonal:(int)startI centerJ:(int)centerJ maxCount:(int)maxCou * @param centerJ center of the section that appears to cross a finder pattern * @param maxCount maximum reasonable number of modules that should be * observed in any reading state, based on the results of the horizontal scan - * @return vertical center of finder pattern, or {@link Float#NaN} if not found + * @return vertical center of finder pattern, or `NAN` if not found */ - (float)crossCheckVertical:(int)startI centerJ:(int)centerJ maxCount:(int)maxCount originalStateCountTotal:(int)originalStateCountTotal { int maxI = self.image.height; @@ -401,14 +414,13 @@ - (float)crossCheckHorizontal:(int)startJ centerI:(int)centerI maxCount:(int)max return [ZXQRCodeFinderPatternFinder foundPatternCross:stateCount] ? [self centerFromEnd:stateCount end:j] : NAN; } -- (BOOL)handlePossibleCenter:(const int[])stateCount i:(int)i j:(int)j pureBarcode:(BOOL)pureBarcode { +- (BOOL)handlePossibleCenter:(const int[])stateCount i:(int)i j:(int)j { int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4]; float centerJ = [self centerFromEnd:stateCount end:j]; float centerI = [self crossCheckVertical:i centerJ:(int)centerJ maxCount:stateCount[2] originalStateCountTotal:stateCountTotal]; if (!isnan(centerI)) { centerJ = [self crossCheckHorizontal:(int)centerJ centerI:(int)centerI maxCount:stateCount[2] originalStateCountTotal:stateCountTotal]; - if (!isnan(centerJ) && - (!pureBarcode || [self crossCheckDiagonal:(int)centerI centerJ:(int) centerJ maxCount:stateCount[2] originalStateCountTotal:stateCountTotal])) { + if (!isnan(centerJ) && [self crossCheckDiagonal:(int)centerI centerJ:(int)centerJ]) { float estimatedModuleSize = (float)stateCountTotal / 7.0f; BOOL found = NO; int max = (int)[self.possibleCenters count]; diff --git a/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.h b/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.h index 16c6882ec..16c39e770 100644 --- a/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.h +++ b/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import + @class ZXByteArray; @interface ZXQRCodeBlockPair : NSObject diff --git a/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.h b/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.h index a5cd02654..3f822d127 100644 --- a/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.h +++ b/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.h @@ -21,15 +21,10 @@ extern const NSStringEncoding ZX_DEFAULT_BYTE_MODE_ENCODING; @interface ZXQRCodeEncoder : NSObject /** - * Encode "bytes" with the error correction level "ecLevel". The encoding mode will be chosen - * internally by chooseMode:. On success, store the result in "qrCode". - * - * We recommend you to use QRCode.EC_LEVEL_L (the lowest level) for - * "getECLevel" since our primary use is to show QR code on desktop screens. We don't need very - * strong error correction for this purpose. - * - * Note that there is no way to encode bytes in MODE_KANJI. We might want to add EncodeWithMode() - * with which clients can specify the encoding mode. For now, we don't need the functionality. + * @param content text to encode + * @param ecLevel error correction level to use + * @return ZXQRCode representing the encoded QR code or nil if encoding can't succeed, because of + * for example invalid content or configuration. */ + (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel error:(NSError **)error; diff --git a/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.m b/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.m index f0d163fa1..12b175419 100644 --- a/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.m +++ b/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.m @@ -82,6 +82,12 @@ + (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXQRCodeErrorCorrectionLevel * } } + // Append the FNC1 mode header for GS1 formatted data if applicable + if (hints.gs1Format) { + // GS1 formatted codes are prefixed with a FNC1 in first position mode header + [self appendModeInfo:[ZXQRCodeMode fnc1FirstPositionMode] bits:headerBits]; + } + // (With ECI in place,) Write the mode marker [self appendModeInfo:mode bits:headerBits]; @@ -92,24 +98,22 @@ + (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXQRCodeErrorCorrectionLevel * return nil; } - // Hard part: need to know version to know how many bits length takes. But need to know how many - // bits it takes to know version. First we take a guess at version by assuming version will be - // the minimum, 1: - - int provisionalBitsNeeded = headerBits.size - + [mode characterCountBits:[ZXQRCodeVersion versionForNumber:1]] - + dataBits.size; - ZXQRCodeVersion *provisionalVersion = [self chooseVersion:provisionalBitsNeeded ecLevel:ecLevel error:error]; - if (!provisionalVersion) { - return nil; + ZXQRCodeVersion *version = nil; + if (hints.qrVersion != nil) { + ZXQRCodeVersion *requestedVersion = [ZXQRCodeVersion versionForNumber:[hints.qrVersion intValue]]; + int bitsNeeded = [self calculateBitsNeededForMode:mode + headerBits:headerBits + dataBits:dataBits + version:requestedVersion]; + if ([self willFitIn:bitsNeeded version:requestedVersion ecLevel:ecLevel]) { + version = requestedVersion; + } else { + NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Data too big"}; + if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo]; + } + } else { + version = [self recommendVersionFor:ecLevel mode:mode headerBits:headerBits dataBits:dataBits error:error]; } - - // Use that guess to calculate the right version. I am still not sure this works in 100% of cases. - - int bitsNeeded = headerBits.size - + [mode characterCountBits:provisionalVersion] - + dataBits.size; - ZXQRCodeVersion *version = [self chooseVersion:bitsNeeded ecLevel:ecLevel error:error]; if (!version) { return nil; } @@ -163,6 +167,29 @@ + (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXQRCodeErrorCorrectionLevel * return qrCode; } ++ (ZXQRCodeVersion *)recommendVersionFor:(ZXQRCodeErrorCorrectionLevel *)ecLevel mode:(ZXQRCodeMode *)mode headerBits:(ZXBitArray *)headerBits dataBits:(ZXBitArray *)dataBits error:(NSError **)error { + // Hard part: need to know version to know how many bits length takes. But need to know how many + // bits it takes to know version. First we take a guess at version by assuming version will be + // the minimum, 1: + int provisionalBitsNeeded = [self calculateBitsNeededForMode:mode + headerBits:headerBits + dataBits:dataBits + version:[ZXQRCodeVersion versionForNumber:1]]; + + // Use that guess to calculate the right version. I am still not sure this works in 100% of cases. + ZXQRCodeVersion *provisionalVersion = [self chooseVersion:provisionalBitsNeeded ecLevel:ecLevel error:error]; + int bitsNeeded = [self calculateBitsNeededForMode:mode + headerBits:headerBits + dataBits:dataBits + version:provisionalVersion]; + return [self chooseVersion:bitsNeeded ecLevel:ecLevel error:error]; +} + ++ (int)calculateBitsNeededForMode:(ZXQRCodeMode *)mode headerBits:(ZXBitArray *)headerBits dataBits:(ZXBitArray *)dataBits version:(ZXQRCodeVersion *)version { + int bitsNeeded = headerBits.size + [mode characterCountBits:version] + dataBits.size; + return bitsNeeded; +} + + (int)alphanumericCode:(int)code { if (code < sizeof(ZX_ALPHANUMERIC_TABLE) / sizeof(int)) { return ZX_ALPHANUMERIC_TABLE[code]; @@ -176,11 +203,12 @@ + (ZXQRCodeMode *)chooseMode:(NSString *)content { /** * Choose the best mode by examining the content. Note that 'encoding' is used as a hint; - * if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}. + * if it is Shift_JIS, and the input is only double-byte Kanji, then we return `kanjiMode`. */ + (ZXQRCodeMode *)chooseMode:(NSString *)content encoding:(NSStringEncoding)encoding { - if (NSShiftJISStringEncoding == encoding) { - return [self isOnlyDoubleByteKanji:content] ? [ZXQRCodeMode kanjiMode] : [ZXQRCodeMode byteMode]; + if (NSShiftJISStringEncoding == encoding && [self isOnlyDoubleByteKanji:content]) { + // Choose Kanji mode if all input are double-byte characters + return [ZXQRCodeMode kanjiMode]; } BOOL hasNumeric = NO; BOOL hasAlphanumeric = NO; @@ -240,25 +268,33 @@ + (ZXQRCodeVersion *)chooseVersion:(int)numInputBits ecLevel:(ZXQRCodeErrorCorre // In the following comments, we use numbers of Version 7-H. for (int versionNum = 1; versionNum <= 40; versionNum++) { ZXQRCodeVersion *version = [ZXQRCodeVersion versionForNumber:versionNum]; - // numBytes = 196 - int numBytes = version.totalCodewords; - // getNumECBytes = 130 - ZXQRCodeECBlocks *ecBlocks = [version ecBlocksForLevel:ecLevel]; - int numEcBytes = ecBlocks.totalECCodewords; - // getNumDataBytes = 196 - 130 = 66 - int numDataBytes = numBytes - numEcBytes; - int totalInputBytes = (numInputBits + 7) / 8; - if (numDataBytes >= totalInputBytes) { + if ([self willFitIn:numInputBits version:version ecLevel:ecLevel]) { return version; } } - NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Data too big"}; - if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo]; return nil; } +/** + * @return true if the number of input bits will fit in a code with the specified version and + * error correction level. + */ ++ (BOOL)willFitIn:(int)numInputBits version:(ZXQRCodeVersion *)version ecLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel { + // In the following comments, we use numbers of Version 7-H. + // numBytes = 196 + int numBytes = version.totalCodewords; + // getNumECBytes = 130 + ZXQRCodeECBlocks *ecBlocks = [version ecBlocksForLevel:ecLevel]; + int numEcBytes = ecBlocks.totalECCodewords; + // getNumDataBytes = 196 - 130 = 66 + int numDataBytes = numBytes - numEcBytes; + int totalInputBytes = (numInputBits + 7) / 8; + + return numDataBytes >= totalInputBytes; +} + + (int)totalInputBytes:(int)numInputBits version:(ZXQRCodeVersion *)version mode:(ZXQRCodeMode *)mode { int modeInfoBits = 4; int charCountBits = [mode characterCountBits:version]; diff --git a/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.m b/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.m index d49f3b417..1f6518c74 100644 --- a/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.m +++ b/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.m @@ -46,8 +46,8 @@ @implementation ZXMultiFinderPatternFinder /** - * Returns the 3 best {@link FinderPattern}s from our list of candidates. The "best" are - * those that have been detected at least {@link #CENTER_QUORUM} times, and whose module + * Returns the 3 best `ZXFinderPattern`s from our list of candidates. The "best" are + * those that have been detected at least ZXCENTER_QUORUM times, and whose module * size differs from the average among those patterns the least */ - (NSArray *)selectBestPatternsWithError:(NSError **)error { @@ -155,7 +155,6 @@ - (NSArray *)selectBestPatternsWithError:(NSError **)error { - (NSArray *)findMulti:(ZXDecodeHints *)hints error:(NSError **)error { BOOL tryHarder = hints != nil && hints.tryHarder; - BOOL pureBarcode = hints != nil && hints.pureBarcode; int maxI = self.image.height; int maxJ = self.image.width; // We are looking for black/white/black/white/black modules in @@ -165,7 +164,7 @@ - (NSArray *)findMulti:(ZXDecodeHints *)hints error:(NSError **)error { // image, and then account for the center being 3 modules in size. This gives the smallest // number of pixels the center could be, so skip this often. When trying harder, look for all // QR versions regardless of how dense they are. - int iSkip = (int)(maxI / (ZX_FINDER_PATTERN_MAX_MODULES * 4.0f) * 3); + int iSkip = (3 * maxI) / (4 * ZX_FINDER_PATTERN_MAX_MODULES); if (iSkip < ZX_FINDER_PATTERN_MIN_SKIP || tryHarder) { iSkip = ZX_FINDER_PATTERN_MIN_SKIP; } @@ -188,7 +187,7 @@ - (NSArray *)findMulti:(ZXDecodeHints *)hints error:(NSError **)error { } else { if ((currentState & 1) == 0) { if (currentState == 4) { - if ([ZXQRCodeFinderPatternFinder foundPatternCross:stateCount] && [self handlePossibleCenter:stateCount i:i j:j pureBarcode:pureBarcode]) { + if ([ZXQRCodeFinderPatternFinder foundPatternCross:stateCount] && [self handlePossibleCenter:stateCount i:i j:j]) { currentState = 0; stateCount[0] = 0; stateCount[1] = 0; @@ -213,7 +212,7 @@ - (NSArray *)findMulti:(ZXDecodeHints *)hints error:(NSError **)error { } if ([ZXQRCodeFinderPatternFinder foundPatternCross:stateCount]) { - [self handlePossibleCenter:stateCount i:i j:maxJ pureBarcode:pureBarcode]; + [self handlePossibleCenter:stateCount i:i j:maxJ]; } } NSArray *patternInfo = [self selectBestPatternsWithError:error]; diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/dlusbs.png b/ZXingObjCTests/Resources/blackbox/aztec-1/dlusbs.png new file mode 100644 index 000000000..8574be762 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/aztec-1/dlusbs.png differ diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/dlusbs.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/dlusbs.txt new file mode 100644 index 000000000..fc21ac800 --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/aztec-1/dlusbs.txt @@ -0,0 +1 @@ +3333h3i3jITIT \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/C40.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/C40.png new file mode 100644 index 000000000..4d3915942 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/datamatrix-1/C40.png differ diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/C40.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/C40.txt new file mode 100644 index 000000000..1dfb73f9f --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/C40.txt @@ -0,0 +1 @@ +Testing C40 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/EDIFACT.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/EDIFACT.png new file mode 100644 index 000000000..cbf9006fa Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/datamatrix-1/EDIFACT.png differ diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/EDIFACT.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/EDIFACT.txt new file mode 100644 index 000000000..ea5d8129c --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/EDIFACT.txt @@ -0,0 +1 @@ +EDIFACTEDIFACT \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/X12.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/X12.png new file mode 100644 index 000000000..af766f555 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/datamatrix-1/X12.png differ diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/X12.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/X12.txt new file mode 100644 index 000000000..68f83f84e --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/X12.txt @@ -0,0 +1 @@ +X12X12X12X12 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE2.png b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE2.png new file mode 100644 index 000000000..6ac2539a2 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE2.png differ diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE2.txt b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE2.txt new file mode 100644 index 000000000..ad5f7f6aa --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE2.txt @@ -0,0 +1 @@ +[)>0196123450000222111MODE2 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE3.png b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE3.png new file mode 100644 index 000000000..007987185 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE3.png differ diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE3.txt b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE3.txt new file mode 100644 index 000000000..08d77829b --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE3.txt @@ -0,0 +1 @@ +[)>0196123450000222111MODE3 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE4.png b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE4.png new file mode 100644 index 000000000..e4470f38c Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE4.png differ diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE4.txt b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE4.txt new file mode 100644 index 000000000..8224acc67 --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE4.txt @@ -0,0 +1 @@ +[)>0196123450000222111MODE4 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE5.png b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE5.png new file mode 100644 index 000000000..154594643 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE5.png differ diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE5.txt b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE5.txt new file mode 100644 index 000000000..deeeba36e --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE5.txt @@ -0,0 +1 @@ +[)>0196123450000222111MODE5 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE6.png b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE6.png new file mode 100644 index 000000000..333a0f809 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE6.png differ diff --git a/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE6.txt b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE6.txt new file mode 100644 index 000000000..f5e22c3d9 --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/maxicode-1/MODE6.txt @@ -0,0 +1 @@ +[)>0196123450000222111MODE6 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/multi-1/1.png b/ZXingObjCTests/Resources/blackbox/multi-1/1.png new file mode 100644 index 000000000..ff0f8b514 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/multi-1/1.png differ diff --git a/ZXingObjCTests/Resources/blackbox/multi-qrcode-1/1.png b/ZXingObjCTests/Resources/blackbox/multi-qrcode-1/1.png new file mode 100644 index 000000000..c82508b24 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/multi-qrcode-1/1.png differ diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/11.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/11.png new file mode 100644 index 000000000..a18dd8376 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/pdf417-1/11.png differ diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/11.txt b/ZXingObjCTests/Resources/blackbox/pdf417-1/11.txt new file mode 100644 index 000000000..25f399193 --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/11.txt @@ -0,0 +1 @@ +This is just a test. \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/19.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/19.png new file mode 100644 index 000000000..fcf4b6582 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/pdf417-3/19.png differ diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/19.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/19.txt new file mode 100644 index 000000000..49db7a0da --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/19.txt @@ -0,0 +1 @@ +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-4/04-01.png b/ZXingObjCTests/Resources/blackbox/pdf417-4/04-01.png new file mode 100644 index 000000000..5a301e157 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/pdf417-4/04-01.png differ diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-4/04.txt b/ZXingObjCTests/Resources/blackbox/pdf417-4/04.txt new file mode 100644 index 000000000..9da7d8c0d --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/pdf417-4/04.txt @@ -0,0 +1 @@ +01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-5/1.png b/ZXingObjCTests/Resources/blackbox/pdf417-5/1.png new file mode 100644 index 000000000..ea1ae88d3 Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/pdf417-5/1.png differ diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-5/1.txt b/ZXingObjCTests/Resources/blackbox/pdf417-5/1.txt new file mode 100644 index 000000000..bea27cc78 --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/pdf417-5/1.txt @@ -0,0 +1 @@ +J090018900004751310097170889111928578075473 \ No newline at end of file diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-7/2.png b/ZXingObjCTests/Resources/blackbox/qrcode-7/2.png new file mode 100644 index 000000000..498f4584b Binary files /dev/null and b/ZXingObjCTests/Resources/blackbox/qrcode-7/2.png differ diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-7/2.txt b/ZXingObjCTests/Resources/blackbox/qrcode-7/2.txt new file mode 100644 index 000000000..be9b7dc69 --- /dev/null +++ b/ZXingObjCTests/Resources/blackbox/qrcode-7/2.txt @@ -0,0 +1 @@ +https://techcrunch.com/2017/02/02/google-chrome-gets-its-own-qr-code-barcode-scanner/ diff --git a/ZXingObjCTests/ZXPlanarYUVLuminanceSourceTestCase.m b/ZXingObjCTests/ZXPlanarYUVLuminanceSourceTestCase.m index 2dfcd2422..541b75227 100644 --- a/ZXingObjCTests/ZXPlanarYUVLuminanceSourceTestCase.m +++ b/ZXingObjCTests/ZXPlanarYUVLuminanceSourceTestCase.m @@ -47,9 +47,14 @@ - (void)testNoCrop { - (void)testCrop { ZXPlanarYUVLuminanceSource *source = [[ZXPlanarYUVLuminanceSource alloc] initWithYuvData:(int8_t *)YUV yuvDataLen:COLS * ROWS dataWidth:COLS dataHeight:ROWS left:1 top:1 width:COLS-2 height:ROWS-2 reverseHorizontal:NO]; + XCTAssertTrue([source cropSupported]); + ZXByteArray *cropMatrix = [source matrix]; for (int r = 0; r < ROWS-2; r++) { [self assertEqualsExpected:Y expectedFrom:(r + 1) * COLS + 1 actual:[source rowAtY:r row:nil].array actualFrom:0 length:COLS-2]; } + for (int r = 0; r < ROWS-2; r++) { + [self assertEqualsExpected:Y expectedFrom:(r + 1) * COLS + 1 actual:cropMatrix.array actualFrom:r * (COLS - 2) length:COLS-2]; + } } - (void)assertEqualsExpected:(int8_t *)expected expectedFrom:(int)expectedFrom diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX/main.m b/ZXingObjCTests/ZXRGBLuminanceSourceTestCase.h similarity index 78% rename from examples/BarcodeScannerOSX/BarcodeScannerOSX/main.m rename to ZXingObjCTests/ZXRGBLuminanceSourceTestCase.h index b492d39f0..fc30b9a08 100644 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX/main.m +++ b/ZXingObjCTests/ZXRGBLuminanceSourceTestCase.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 ZXing authors + * Copyright 2012 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,9 +14,6 @@ * limitations under the License. */ -#import +@interface ZXRGBLuminanceSourceTestCase : XCTestCase -int main(int argc, char *argv[]) -{ - return NSApplicationMain(argc, (const char **) argv); -} +@end diff --git a/ZXingObjCTests/ZXRGBLuminanceSourceTestCase.m b/ZXingObjCTests/ZXRGBLuminanceSourceTestCase.m new file mode 100644 index 000000000..e52d4bd19 --- /dev/null +++ b/ZXingObjCTests/ZXRGBLuminanceSourceTestCase.m @@ -0,0 +1,88 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXRGBLuminanceSource.h" +#import "ZXRGBLuminanceSourceTestCase.h" + +@implementation ZXRGBLuminanceSourceTestCase + +static ZXRGBLuminanceSource *SOURCE = nil; + ++ (void)initialize { + int pixels[9] = { + 0x000000, 0x7F7F7F, 0xFFFFFF, + 0xFF0000, 0x00FF00, 0x0000FF, + 0x0000FF, 0x00FF00, 0xFF0000 + }; + SOURCE = [[ZXRGBLuminanceSource alloc] initWithWidth:3 height:3 pixels:pixels pixelsLen:sizeof(int32_t)]; +} + +- (void)testCrop { + XCTAssertTrue([SOURCE cropSupported]); + ZXLuminanceSource *crop = [SOURCE crop:1 top:1 width:1 height:1]; + XCTAssertEqual(1, crop.width); + XCTAssertEqual(1, crop.height); + ZXByteArray *row = [crop rowAtY:0 row:nil]; + XCTAssertEqual(0x7F, row.array[0]); +} + +- (void)testMatrix { + ZXByteArray *matrix = [SOURCE matrix]; + int8_t pixels[9] = { + 0x00, 0x7F, 0xFF, 0x3F, 0x7F, 0x3F, 0x3F, 0x7F, 0x3F + }; + for (int i = 0; i < matrix.length; i++) { + XCTAssertEqual(matrix.array[i], pixels[i]); + } +} + +- (void)testCropFullWidth { + ZXLuminanceSource *croppedFullWidth = [SOURCE crop:0 top:1 width:3 height:2]; + ZXByteArray *matrix = [croppedFullWidth matrix]; + int8_t pixels[6] = { + 0x3F, 0x7F, 0x3F, 0x3F, 0x7F, 0x3F + }; + for (int i = 0; i < matrix.length; i++) { + XCTAssertEqual(matrix.array[i], pixels[i]); + } +} + +- (void)testCropCorner { + ZXLuminanceSource *croppedCorner = [SOURCE crop:1 top:1 width:2 height:2]; + ZXByteArray *matrix = [croppedCorner matrix]; + int8_t pixels[4] = { + 0x7F, 0x3F, 0x7F, 0x3F + }; + for (int i = 0; i < matrix.length; i++) { + XCTAssertEqual(matrix.array[i], pixels[i]); + } +} + +- (void)testGetRow { + ZXByteArray *row = [SOURCE rowAtY:2 row:nil]; + int8_t pixels[3] = { + 0x3F, 0x7F, 0x3F + }; + for (int i = 0; i < row.length; i++) { + XCTAssertEqual(row.array[i], pixels[i]); + } +} + +- (void)testDescription { + XCTAssertEqualObjects(@"#+ \n#+#\n#+#\n", [SOURCE description]); +} + +@end diff --git a/ZXingObjCTests/additional/ZXDataMatrixWriterAdditionalTestCase.h b/ZXingObjCTests/additional/ZXDataMatrixWriterAdditionalTestCase.h new file mode 100644 index 000000000..53dc26544 --- /dev/null +++ b/ZXingObjCTests/additional/ZXDataMatrixWriterAdditionalTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXDataMatrixWriterAdditionalTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/additional/ZXDataMatrixWriterAdditionalTestCase.m b/ZXingObjCTests/additional/ZXDataMatrixWriterAdditionalTestCase.m new file mode 100644 index 000000000..506d5c335 --- /dev/null +++ b/ZXingObjCTests/additional/ZXDataMatrixWriterAdditionalTestCase.m @@ -0,0 +1,59 @@ +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXDataMatrixWriterAdditionalTestCase.h" + +@implementation ZXDataMatrixWriterAdditionalTestCase + +- (void)testDataMatrixWriterIssueLongText { + NSString *hugeString = @"

"; + ZXDataMatrixWriter *writer = [[ZXDataMatrixWriter alloc] init]; + ZXBitMatrix *matrix = [writer encode:hugeString format:kBarcodeFormatDataMatrix width:0 height:0 hints:nil error:nil]; + ZXImage *image = [ZXImage imageWithMatrix:matrix]; + XCTAssertNotNil(image); + + ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:image.cgimage]; + ZXBinaryBitmap *bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]]; + + ZXDataMatrixReader *reader = [[ZXDataMatrixReader alloc] init]; + ZXDecodeHints *hints = [ZXDecodeHints hints]; + hints.pureBarcode = YES; + ZXResult *result = [reader decode:bitmap hints:hints error:nil]; + XCTAssertNotNil(result); + XCTAssertEqualObjects(result.text, hugeString); +} + +- (void)testDataMatrixWriterIssueLongTextSquareForced { + NSString *hugeString = @"abGQiCU413ZlK5sxgqBnLxysXWEQsmZzAykxtbvkpVzEshILHtqYYDvAYolgOh9g8OPD9eFMHbwKxh1NH5Li4snQczwRmivbJdt9EiPTG4WcpOEvzhnAyPc6Acuw1zyjAwY5aCr61JWFs5HqCzEFVyo2Ur69eLBwA3vWdlqbxDNkTnzV0L61QwKq8KPg97VugF3GiYeZEPxanYctznrktw2Q1LTGdekmbgA1Jzy3vytscRBiI8xvtbw6R6dafeZg9bUUjKT8OYWgWmIdZ54L60DY4foAaVbwqZlXATtGCRwY"; + ZXDataMatrixWriter *writer = [[ZXDataMatrixWriter alloc] init]; + ZXEncodeHints *encodeHints = [ZXEncodeHints hints]; + encodeHints.dataMatrixShape = ZXDataMatrixSymbolShapeHintForceSquare; + ZXBitMatrix *matrix = [writer encode:hugeString format:kBarcodeFormatDataMatrix width:0 height:0 hints:encodeHints error:nil]; + ZXImage *image = [ZXImage imageWithMatrix:matrix]; + XCTAssertNotNil(image); + + ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:image.cgimage]; + ZXBinaryBitmap *bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]]; + + ZXDataMatrixReader *reader = [[ZXDataMatrixReader alloc] init]; + ZXDecodeHints *decodeHints = [ZXDecodeHints hints]; + decodeHints.pureBarcode = YES; + ZXResult *result = [reader decode:bitmap hints:decodeHints error:nil]; + XCTAssertNotNil(result); + XCTAssertEqualObjects(result.text, hugeString); +} + +@end diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerDocument.h b/ZXingObjCTests/additional/ZXPDF417BlackBox5TestCase.h similarity index 79% rename from examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerDocument.h rename to ZXingObjCTests/additional/ZXPDF417BlackBox5TestCase.h index b519018ff..754de8a50 100644 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerDocument.h +++ b/ZXingObjCTests/additional/ZXPDF417BlackBox5TestCase.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 ZXing authors + * Copyright 2013 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,8 +14,8 @@ * limitations under the License. */ -@interface BarcodeScannerDocument : NSDocument +#import "ZXAbstractBlackBoxTestCase.h" -@property (assign) IBOutlet NSView *previewView; +@interface ZXPDF417BlackBox5TestCase : ZXAbstractBlackBoxTestCase @end diff --git a/ZXingObjCTests/additional/ZXPDF417BlackBox5TestCase.m b/ZXingObjCTests/additional/ZXPDF417BlackBox5TestCase.m new file mode 100644 index 000000000..a6f6ccd95 --- /dev/null +++ b/ZXingObjCTests/additional/ZXPDF417BlackBox5TestCase.m @@ -0,0 +1,39 @@ +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXPDF417BlackBox5TestCase.h" + +@implementation ZXPDF417BlackBox5TestCase + +- (id)initWithInvocation:(NSInvocation *)invocation { + self = [super initWithInvocation:invocation + testBasePathSuffix:@"Resources/blackbox/pdf417-5" + barcodeReader:[[ZXMultiFormatReader alloc] init] + expectedFormat:kBarcodeFormatPDF417]; + + if (self) { + [self addTest:1 tryHarderCount:1 rotation:0.0f]; + [self addTest:1 tryHarderCount:1 rotation:180.0f]; + } + + return self; +} + +- (void)testBlackBox { + [super runTests]; +} + +@end diff --git a/ZXingObjCTests/aztec/ZXAztecBlackBox1TestCase.m b/ZXingObjCTests/aztec/ZXAztecBlackBox1TestCase.m index f6963ca73..9172487f8 100644 --- a/ZXingObjCTests/aztec/ZXAztecBlackBox1TestCase.m +++ b/ZXingObjCTests/aztec/ZXAztecBlackBox1TestCase.m @@ -25,10 +25,10 @@ - (id)initWithInvocation:(NSInvocation *)invocation { expectedFormat:kBarcodeFormatAztec]; if (self) { - [self addTest:12 tryHarderCount:12 rotation:0.0f]; - [self addTest:12 tryHarderCount:12 rotation:90.0f]; - [self addTest:12 tryHarderCount:12 rotation:180.0f]; - [self addTest:12 tryHarderCount:12 rotation:270.0f]; + [self addTest:13 tryHarderCount:13 rotation:0.0f]; + [self addTest:13 tryHarderCount:13 rotation:90.0f]; + [self addTest:13 tryHarderCount:13 rotation:180.0f]; + [self addTest:13 tryHarderCount:13 rotation:270.0f]; } return self; @@ -39,3 +39,4 @@ - (void)testBlackBox { } @end + diff --git a/ZXingObjCTests/aztec/decoder/ZXAztecDecoderTest.m b/ZXingObjCTests/aztec/decoder/ZXAztecDecoderTest.m index 2c7d34289..1e118af70 100644 --- a/ZXingObjCTests/aztec/decoder/ZXAztecDecoderTest.m +++ b/ZXingObjCTests/aztec/decoder/ZXAztecDecoderTest.m @@ -14,41 +14,82 @@ * limitations under the License. */ +#import "ZXByteArray.h" #import "ZXBitMatrix.h" +#import "ZXBoolArray.h" #import "ZXAztecDecoder.h" #import "ZXAztecDecoderTest.h" @implementation ZXAztecDecoderTest +- (void)testAztecResult { + ZXBitMatrix *matrix = [ZXBitMatrix parse:@"X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X \n" + " X X X X X X X X X X \n" + " X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X \n" + " X X X X X X X X X X X \n" + " X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X \n" + " X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X \n" + "X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X \n" + setString:@"X " unsetString:@" "]; + ZXAztecDetectorResult *r = [[ZXAztecDetectorResult alloc] initWithBits:matrix points:nil compact:NO nbDatablocks:30 nbLayers:2]; + ZXDecoderResult *res = [[[ZXAztecDecoder alloc] init] decode:r error:nil]; + XCTAssertEqualObjects(@"88888TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT", res.text); + int expectedBytes[23] = { + -11, 85, 85, 117, 107, 90, -42, -75, -83, 107, + 90, -42, -75, -83, 107, 90, -42, -75, -83, 107, + 90, -42, -80 + }; + for(int i = 0; i < 23; i++) { + XCTAssertEqual(expectedBytes[i], res.rawBytes.array[i], @"Failed at %d", i); + } + XCTAssertEqual(180, res.numBits); +} + - (void)testDecodeTooManyErrors { ZXBitMatrix *matrix = [ZXBitMatrix parse:@"" - "X X . X . . . X X . . . X . . X X X . X . X X X X X . \n" - "X X . . X X . . . . . X X . . . X X . . . X . X . . X \n" - "X . . . X X . . X X X . X X . X X X X . X X . . X . . \n" - ". . . . X . X X . . X X . X X . X . X X X X . X . . X \n" - "X X X . . X X X X X . . . . . X X . . . X . X . X . X \n" - "X X . . . . . . . . X . . . X . X X X . X . . X . . . \n" - "X X . . X . . . . . X X . . . . . X . . . . X . . X X \n" - ". . . X . X . X . . . . . X X X X X X . . . . . . X X \n" - "X . . . X . X X X X X X . . X X X . X . X X X X X X . \n" - "X . . X X X . X X X X X X X X X X X X X . . . X . X X \n" - ". . . . X X . . . X . . . . . . . X X . . . X X . X . \n" - ". . . X X X . . X X . X X X X X . X . . X . . . . . . \n" - "X . . . . X . X . X . X . . . X . X . X X . X X . X X \n" - "X . X . . X . X . X . X . X . X . X . . . . . X . X X \n" - "X . X X X . . X . X . X . . . X . X . X X X . . . X X \n" - "X X X X X X X X . X . X X X X X . X . X . X . X X X . \n" - ". . . . . . . X . X . . . . . . . X X X X . . . X X X \n" - "X X . . X . . X . X X X X X X X X X X X X X . . X . X \n" - "X X X . X X X X . . X X X X . . X . . . . X . . X X X \n" - ". . . . X . X X X . . . . X X X X . . X X X X . . . . \n" - ". . X . . X . X . . . X . X X . X X . X . . . X . X . \n" - "X X . . X . . X X X X X X X . . X . X X X X X X X . . \n" - "X . X X . . X X . . . . . X . . . . . . X X . X X X . \n" - "X . . X X . . X X . X . X . . . . X . X . . X . . X . \n" - "X . X . X . . X . X X X X X X X X . X X X X . . X X . \n" - "X X X X . . . X . . X X X . X X . . X . . . . X X X . \n" - "X X . X . X . . . X . X . . . . X X . X . . X X . . . \n" + "X X . X . . . X X . . . X . . X X X . X . X X X X X . \n" + "X X . . X X . . . . . X X . . . X X . . . X . X . . X \n" + "X . . . X X . . X X X . X X . X X X X . X X . . X . . \n" + ". . . . X . X X . . X X . X X . X . X X X X . X . . X \n" + "X X X . . X X X X X . . . . . X X . . . X . X . X . X \n" + "X X . . . . . . . . X . . . X . X X X . X . . X . . . \n" + "X X . . X . . . . . X X . . . . . X . . . . X . . X X \n" + ". . . X . X . X . . . . . X X X X X X . . . . . . X X \n" + "X . . . X . X X X X X X . . X X X . X . X X X X X X . \n" + "X . . X X X . X X X X X X X X X X X X X . . . X . X X \n" + ". . . . X X . . . X . . . . . . . X X . . . X X . X . \n" + ". . . X X X . . X X . X X X X X . X . . X . . . . . . \n" + "X . . . . X . X . X . X . . . X . X . X X . X X . X X \n" + "X . X . . X . X . X . X . X . X . X . . . . . X . X X \n" + "X . X X X . . X . X . X . . . X . X . X X X . . . X X \n" + "X X X X X X X X . X . X X X X X . X . X . X . X X X . \n" + ". . . . . . . X . X . . . . . . . X X X X . . . X X X \n" + "X X . . X . . X . X X X X X X X X X X X X X . . X . X \n" + "X X X . X X X X . . X X X X . . X . . . . X . . X X X \n" + ". . . . X . X X X . . . . X X X X . . X X X X . . . . \n" + ". . X . . X . X . . . X . X X . X X . X . . . X . X . \n" + "X X . . X . . X X X X X X X . . X . X X X X X X X . . \n" + "X . X X . . X X . . . . . X . . . . . . X X . X X X . \n" + "X . . X X . . X X . X . X . . . . X . X . . X . . X . \n" + "X . X . X . . X . X X X X X X X X . X X X X . . X X . \n" + "X X X X . . . X . . X X X . X X . . X . . . . X X X . \n" + "X X . X . X . . . X . X . . . . X X . X . . X X . . . \n" setString:@"X " unsetString:@". "]; ZXAztecDetectorResult *r = [[ZXAztecDetectorResult alloc] initWithBits:matrix points:nil compact:YES nbDatablocks:16 nbLayers:4]; ZXDecoderResult *res = [[[ZXAztecDecoder alloc] init] decode:r error:nil]; @@ -57,37 +98,74 @@ - (void)testDecodeTooManyErrors { - (void)testDecodeTooManyErrors2 { ZXBitMatrix *matrix = [ZXBitMatrix parse:@"" - ". X X . . X . X X . . . X . . X X X . . . X X . X X . \n" - "X X . X X . . X . . . X X . . . X X . X X X . X . X X \n" - ". . . . X . . . X X X . X X . X X X X . X X . . X . . \n" - "X . X X . . X . . . X X . X X . X . X X . . . . . X . \n" - "X X . X . . X . X X . . . . . X X . . . . . X . . . X \n" - "X . . X . . . . . . X . . . X . X X X X X X X . . . X \n" - "X . . X X . . X . . X X . . . . . X . . . . . X X X . \n" - ". . X X X X . X . . . . . X X X X X X . . . . . . X X \n" - "X . . . X . X X X X X X . . X X X . X . X X X X X X . \n" - "X . . X X X . X X X X X X X X X X X X X . . . X . X X \n" - ". . . . X X . . . X . . . . . . . X X . . . X X . X . \n" - ". . . X X X . . X X . X X X X X . X . . X . . . . . . \n" - "X . . . . X . X . X . X . . . X . X . X X . X X . X X \n" - "X . X . . X . X . X . X . X . X . X . . . . . X . X X \n" - "X . X X X . . X . X . X . . . X . X . X X X . . . X X \n" - "X X X X X X X X . X . X X X X X . X . X . X . X X X . \n" - ". . . . . . . X . X . . . . . . . X X X X . . . X X X \n" - "X X . . X . . X . X X X X X X X X X X X X X . . X . X \n" - "X X X . X X X X . . X X X X . . X . . . . X . . X X X \n" - ". . X X X X X . X . . . . X X X X . . X X X . X . X . \n" - ". . X X . X . X . . . X . X X . X X . . . . X X . . . \n" - "X . . . X . X . X X X X X X . . X . X X X X X . X . . \n" - ". X . . . X X X . . . . . X . . . . . X X X X X . X . \n" - "X . . X . X X X X . X . X . . . . X . X X . X . . X . \n" - "X . . . X X . X . X X X X X X X X . X X X X . . X X . \n" - ". X X X X . . X . . X X X . X X . . X . . . . X X X . \n" - "X X . . . X X . . X . X . . . . X X . X . . X . X . X \n" + ". X X . . X . X X . . . X . . X X X . . . X X . X X . \n" + "X X . X X . . X . . . X X . . . X X . X X X . X . X X \n" + ". . . . X . . . X X X . X X . X X X X . X X . . X . . \n" + "X . X X . . X . . . X X . X X . X . X X . . . . . X . \n" + "X X . X . . X . X X . . . . . X X . . . . . X . . . X \n" + "X . . X . . . . . . X . . . X . X X X X X X X . . . X \n" + "X . . X X . . X . . X X . . . . . X . . . . . X X X . \n" + ". . X X X X . X . . . . . X X X X X X . . . . . . X X \n" + "X . . . X . X X X X X X . . X X X . X . X X X X X X . \n" + "X . . X X X . X X X X X X X X X X X X X . . . X . X X \n" + ". . . . X X . . . X . . . . . . . X X . . . X X . X . \n" + ". . . X X X . . X X . X X X X X . X . . X . . . . . . \n" + "X . . . . X . X . X . X . . . X . X . X X . X X . X X \n" + "X . X . . X . X . X . X . X . X . X . . . . . X . X X \n" + "X . X X X . . X . X . X . . . X . X . X X X . . . X X \n" + "X X X X X X X X . X . X X X X X . X . X . X . X X X . \n" + ". . . . . . . X . X . . . . . . . X X X X . . . X X X \n" + "X X . . X . . X . X X X X X X X X X X X X X . . X . X \n" + "X X X . X X X X . . X X X X . . X . . . . X . . X X X \n" + ". . X X X X X . X . . . . X X X X . . X X X . X . X . \n" + ". . X X . X . X . . . X . X X . X X . . . . X X . . . \n" + "X . . . X . X . X X X X X X . . X . X X X X X . X . . \n" + ". X . . . X X X . . . . . X . . . . . X X X X X . X . \n" + "X . . X . X X X X . X . X . . . . X . X X . X . . X . \n" + "X . . . X X . X . X X X X X X X X . X X X X . . X X . \n" + ". X X X X . . X . . X X X . X X . . X . . . . X X X . \n" + "X X . . . X X . . X . X . . . . X X . X . . X . X . X \n" setString:@"X " unsetString:@". "]; ZXAztecDetectorResult *r = [[ZXAztecDetectorResult alloc] initWithBits:matrix points:nil compact:YES nbDatablocks:16 nbLayers:4]; ZXDecoderResult *res = [[[ZXAztecDecoder alloc] init] decode:r error:nil]; XCTAssertNil(res); } +- (void)testRawBytes { + ZXBoolArray *bool0 = [[ZXBoolArray alloc] initWithLength:0]; + ZXBoolArray *bool1 = [[ZXBoolArray alloc] initWithLength:1 values:1]; + ZXBoolArray *bool7 = [[ZXBoolArray alloc] initWithLength:7 values:1, 0, 1, 0, 1, 0, 1]; + ZXBoolArray *bool8 = [[ZXBoolArray alloc] initWithLength:8 values:1, 0, 1, 0, 1, 0, 1, 0]; + ZXBoolArray *bool9 = [[ZXBoolArray alloc] initWithLength:9 values:1, 0, 1, 0, 1, 0, 1, 0, 1]; + ZXBoolArray *bool16 = [[ZXBoolArray alloc] initWithLength:16 values:0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1]; + + ZXByteArray *byte0actual = [ZXAztecDecoder convertBoolArrayToByteArray:bool0]; + ZXByteArray *byte1actual = [ZXAztecDecoder convertBoolArrayToByteArray:bool1]; + ZXByteArray *byte7actual = [ZXAztecDecoder convertBoolArrayToByteArray:bool7]; + ZXByteArray *byte8actual = [ZXAztecDecoder convertBoolArrayToByteArray:bool8]; + ZXByteArray *byte9actual = [ZXAztecDecoder convertBoolArrayToByteArray:bool9]; + ZXByteArray *byte16actual = [ZXAztecDecoder convertBoolArrayToByteArray:bool16]; + + ZXByteArray *byte0expected = [[ZXByteArray alloc] initWithLength:0]; + ZXByteArray *byte1expected = [[ZXByteArray alloc] initWithLength:1 bytes:-128]; + ZXByteArray *byte7expected = [[ZXByteArray alloc] initWithLength:1 bytes:-86]; + ZXByteArray *byte8expected = [[ZXByteArray alloc] initWithLength:1 bytes:-86]; + ZXByteArray *byte9expected = [[ZXByteArray alloc] initWithLength:2 bytes:-86, -128]; + ZXByteArray *byte16expected = [[ZXByteArray alloc] initWithLength:2 bytes:99, -63]; + + [self assertEqualByteArrays:byte0actual expected:byte0expected]; + [self assertEqualByteArrays:byte1actual expected:byte1expected]; + [self assertEqualByteArrays:byte7actual expected:byte7expected]; + [self assertEqualByteArrays:byte8actual expected:byte8expected]; + [self assertEqualByteArrays:byte9actual expected:byte9expected]; + [self assertEqualByteArrays:byte16actual expected:byte16expected]; +} + +- (void)assertEqualByteArrays:(ZXByteArray *)actual expected:(ZXByteArray *)expected { + XCTAssertEqual(actual.length, expected.length); + for(int i = 0; i < actual.length; i++) { + XCTAssertEqual(actual.array[i], expected.array[i], @"Failed at %d", i); + } +} + @end diff --git a/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.m b/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.m index d0e5448bb..4523d6b9d 100644 --- a/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.m +++ b/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.m @@ -38,99 +38,98 @@ - (void)testEncode1 { [self testEncode:@"This is an example Aztec symbol for Wikipedia." compact:YES layers:3 expected: @"X X X X X X X X \n" - "X X X X X X X X X X \n" - "X X X X X X X X X X X \n" - "X X X X X X X X X X X \n" - " X X X X X X X X X X X \n" - " X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X \n" - "X X X X X X X X X X \n" - " X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X \n" - " X X X X X X X X \n" - " X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X \n" - " X X X \n" - " X X X X X X X X X X \n" - " X X X X X X X X X X \n"]; + "X X X X X X X X X X \n" + "X X X X X X X X X X X \n" + "X X X X X X X X X X X \n" + " X X X X X X X X X X X \n" + " X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X \n" + "X X X X X X X X X X \n" + " X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X \n" + " X X X X X X X X \n" + " X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X \n" + " X X X \n" + " X X X X X X X X X X \n" + " X X X X X X X X X X \n"]; } - (void)testEncode2 { [self testEncode: @"Aztec Code is a public domain 2D matrix barcode symbology" - " of nominally square symbols built on a square grid with a " - "distinctive square bullseye pattern at their center." + " of nominally square symbols built on a square grid with a " + "distinctive square bullseye pattern at their center." compact:NO layers:6 expected: @" X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X X X X X X X X X \n" - " X X X X X X X X X X X X X X X X \n" - "X X X X X X X X X X X X X \n"]; + " X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X \n" + " X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X \n"]; } -- (void)testAztecWriter { - for (int i = 0; i < 1000; i++) { - NSString *sampleData = [NSString stringWithFormat:@"%c 1 sample data.", 0x20AC]; - [self testWriter:sampleData encoding:NSISOLatin1StringEncoding eccPercent:25 compact:YES layers:2]; - [self testWriter:@"\u20AC 1 sample data." encoding:(NSStringEncoding) 0x8000020F eccPercent:25 compact:YES layers:2]; - [self testWriter:sampleData encoding:NSUTF8StringEncoding eccPercent:25 compact:YES layers:2]; - [self testWriter:sampleData encoding:NSUTF8StringEncoding eccPercent:100 compact:YES layers:3]; - [self testWriter:sampleData encoding:NSUTF8StringEncoding eccPercent:300 compact:YES layers:4]; - [self testWriter:sampleData encoding:NSUTF8StringEncoding eccPercent:500 compact:NO layers:5]; - // Test AztecWriter defaults - NSString *data = @"In ut magna vel mauris malesuada"; - ZXAztecWriter *writer = [[ZXAztecWriter alloc] init]; - ZXBitMatrix *matrix = [writer encode:data format:kBarcodeFormatAztec width:0 height:0 error:nil]; - ZXAztecCode *aztec = [ZXAztecEncoder encode:[self stringToByteArray:data] - minECCPercent:ZX_AZTEC_DEFAULT_EC_PERCENT - userSpecifiedLayers:ZX_AZTEC_DEFAULT_LAYERS]; - ZXBitMatrix *expectedMatrix = aztec.matrix; - XCTAssertEqualObjects(matrix, expectedMatrix); - } -} +// Ignore: "Flaky test for unknown reasons -- disabling for now" +//- (void)testAztecWriter { +// NSString *sampleData = [NSString stringWithFormat:@"%c 1 sample data.", 0x20AC]; +// [self testWriter:sampleData encoding:NSISOLatin1StringEncoding eccPercent:25 compact:YES layers:2]; +// [self testWriter:@"\u20AC 1 sample data." encoding:(NSStringEncoding) 0x8000020F eccPercent:25 compact:YES layers:2]; +// [self testWriter:sampleData encoding:NSUTF8StringEncoding eccPercent:25 compact:YES layers:2]; +// [self testWriter:sampleData encoding:NSUTF8StringEncoding eccPercent:100 compact:YES layers:3]; +// [self testWriter:sampleData encoding:NSUTF8StringEncoding eccPercent:300 compact:YES layers:4]; +// [self testWriter:sampleData encoding:NSUTF8StringEncoding eccPercent:500 compact:NO layers:5]; +// // Test AztecWriter defaults +// NSString *data = @"In ut magna vel mauris malesuada"; +// ZXAztecWriter *writer = [[ZXAztecWriter alloc] init]; +// ZXBitMatrix *matrix = [writer encode:data format:kBarcodeFormatAztec width:0 height:0 error:nil]; +// ZXAztecCode *aztec = [ZXAztecEncoder encode:[self stringToByteArray:data] +// minECCPercent:ZX_AZTEC_DEFAULT_EC_PERCENT +// userSpecifiedLayers:ZX_AZTEC_DEFAULT_LAYERS]; +// ZXBitMatrix *expectedMatrix = aztec.matrix; +// XCTAssertEqualObjects(matrix, expectedMatrix); +//} // synthetic tests (encode-decode round-trip) @@ -152,17 +151,17 @@ - (void)testEncodeDecode4 { - (void)testEncodeDecode5 { [self testEncodeDecode:@"http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384756<>/?abc" - "Four score and seven our forefathers brought forth" compact:NO layers:5]; + "Four score and seven our forefathers brought forth" compact:NO layers:5]; } - (void)testEncodeDecode10 { [self testEncodeDecode: @"In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus quis diam" - " cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec laoreet rutrum" - " est, nec convallis mauris condimentum sit amet. Phasellus gravida, justo et congue" - " auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec lorem. Nulla" - " ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar nisi, id" - " elementum sapien dolor et diam." + " cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec laoreet rutrum" + " est, nec convallis mauris condimentum sit amet. Phasellus gravida, justo et congue" + " auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec lorem. Nulla" + " ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar nisi, id" + " elementum sapien dolor et diam." compact:NO layers:10]; } @@ -261,23 +260,23 @@ - (void)testStuffBits { - (void)testHighLevelEncode { [self testHighLevelEncodeString:@"A. b." - // 'A' P/S '. ' L/L b D/L '.' + // 'A' P/S '. ' L/L b D/L '.' expectedBits:@"...X. ..... ...XX XXX.. ...XX XXXX. XX.X"]; [self testHighLevelEncodeString:@"Lorem ipsum." - // 'L' L/L 'o' 'r' 'e' 'm' ' ' 'i' 'p' 's' 'u' 'm' D/L '.' + // 'L' L/L 'o' 'r' 'e' 'm' ' ' 'i' 'p' 's' 'u' 'm' D/L '.' expectedBits:@".XX.X XXX.. X.... X..XX ..XX. .XXX. ....X .X.X. X...X X.X.. X.XX. .XXX. XXXX. XX.X"]; [self testHighLevelEncodeString:@"Lo. Test 123." - // 'L' L/L 'o' P/S '. ' U/S 'T' 'e' 's' 't' D/L ' ' '1' '2' '3' '.' + // 'L' L/L 'o' P/S '. ' U/S 'T' 'e' 's' 't' D/L ' ' '1' '2' '3' '.' expectedBits:@".XX.X XXX.. X.... ..... ...XX XXX.. X.X.X ..XX. X.X.. X.X.X XXXX. ...X ..XX .X.. .X.X XX.X"]; [self testHighLevelEncodeString:@"Lo...x" - // 'L' L/L 'o' D/L '.' '.' '.' U/L L/L 'x' + // 'L' L/L 'o' D/L '.' '.' '.' U/L L/L 'x' expectedBits:@".XX.X XXX.. X.... XXXX. XX.X XX.X XX.X XXX. XXX.. XX..X"]; [self testHighLevelEncodeString:@". x://abc/." - //P/S '. ' L/L 'x' P/S ':' P/S '/' P/S '/' 'a' 'b' 'c' P/S '/' D/L '.' + //P/S '. ' L/L 'x' P/S ':' P/S '/' P/S '/' 'a' 'b' 'c' P/S '/' D/L '.' expectedBits:@"..... ...XX XXX.. XX..X ..... X.X.X ..... X.X.. ..... X.X.. ...X. ...XX ..X.. ..... X.X.. XXXX. XX.X"]; // Uses Binary/Shift rather than Lower/Shift to save two bits. [self testHighLevelEncodeString:@"ABCdEFG" - //'A' 'B' 'C' B/S =1 'd' 'E' 'F' 'G' + //'A' 'B' 'C' B/S =1 'd' 'E' 'F' 'G' expectedBits:@"...X. ...XX ..X.. XXXXX ....X .XX..X.. ..XX. ..XXX .X..."]; [self testHighLevelEncodeString: @@ -291,26 +290,26 @@ - (void)testHighLevelEncode { - (void)testHighLevelEncodeBinary { // binary short form single byte [self testHighLevelEncodeString:@"N\0N" - // 'N' B/S =1 '\0' N + // 'N' B/S =1 '\0' N expectedBits:@".XXXX XXXXX ....X ........ .XXXX"]; // Encode "N" in UPPER [self testHighLevelEncodeString:@"N\0n" - // 'N' B/S =2 '\0' 'n' + // 'N' B/S =2 '\0' 'n' expectedBits:@".XXXX XXXXX ...X. ........ .XX.XXX."]; // Encode "n" in BINARY // binary short form consecutive bytes [self testHighLevelEncodeString:[NSString stringWithFormat:@"N\0%C A", 0x0080] - // 'N' B/S =2 '\0' \u0080 ' ' 'A' + // 'N' B/S =2 '\0' \u0080 ' ' 'A' expectedBits:@".XXXX XXXXX ...X. ........ X....... ....X ...X."]; // binary skipping over single character [self testHighLevelEncodeString:[NSString stringWithFormat:@"\0a%C%C A", 0x00FF, 0x0080] - // B/S =4 '\0' 'a' '\3ff' '\200' ' ' 'A' + // B/S =4 '\0' 'a' '\3ff' '\200' ' ' 'A' expectedBits:@"XXXXX ..X.. ........ .XX....X XXXXXXXX X....... ....X ...X."]; // getting into binary mode from digit mode [self testHighLevelEncodeString:@"1234\0" - //D/L '1' '2' '3' '4' U/L B/S =1 \0 + //D/L '1' '2' '3' '4' U/L B/S =1 \0 expectedBits:@"XXXX. ..XX .X.. .X.X .XX. XXX. XXXXX ....X ........"]; // Create a string in which every character requires binary @@ -325,7 +324,7 @@ - (void)testHighLevelEncodeBinary { int i = [n intValue]; // This is the expected length of a binary string of length "i" int expectedLength = (8 * i) + - ( (i <= 31) ? 10 : (i <= 62) ? 20 : (i <= 2078) ? 21 : 31); + ( (i <= 31) ? 10 : (i <= 62) ? 20 : (i <= 2078) ? 21 : 31); // Verify that we are correct about the length. [self testHighLevelEncodeString:[sb substringToIndex:i] expectedReceivedBits:expectedLength]; if (i != 1 && i != 32 && i != 2079) { @@ -339,29 +338,61 @@ - (void)testHighLevelEncodeBinary { } // A lower case letter at both ends will enough to latch us into LOWER. [self testHighLevelEncodeString:[NSString stringWithFormat:@"a%@b", [sb substringToIndex:i]] - expectedReceivedBits:expectedLength + 15]; + expectedReceivedBits:expectedLength + 15]; + } + + sb = [NSMutableString string]; + for (int i = 0; i < 32; i++) { + [sb appendString:@"§"]; // § forces binary encoding + } + sb = [[sb stringByReplacingCharactersInRange:NSMakeRange(1, 1) withString:@"A"] mutableCopy]; + // expect B/S(1) A B/S(30) + [self testHighLevelEncodeString:sb expectedReceivedBits:5 + 20 + 31 * 8]; + + sb = [NSMutableString string]; + for (int i = 0; i < 31; i++) { + [sb appendString:@"§"]; + } + sb = [[sb stringByReplacingCharactersInRange:NSMakeRange(1, 1) withString:@"A"] mutableCopy]; + // expect B/S(31) + [self testHighLevelEncodeString:sb expectedReceivedBits:10 + 31 * 8]; + + sb = [NSMutableString string]; + for (int i = 0; i < 34; i++) { + [sb appendString:@"§"]; + } + sb = [[sb stringByReplacingCharactersInRange:NSMakeRange(1, 1) withString:@"A"] mutableCopy]; + // expect B/S(31) B/S(3) + [self testHighLevelEncodeString:sb expectedReceivedBits:20 + 34 * 8]; + + sb = [NSMutableString string]; + for (int i = 0; i < 64; i++) { + [sb appendString:@"§"]; } + sb = [[sb stringByReplacingCharactersInRange:NSMakeRange(30, 1) withString:@"A"] mutableCopy]; + // expect B/S(31) + [self testHighLevelEncodeString:sb expectedReceivedBits:21 + 64 * 8]; } - (void)testHighLevelEncodePairs { // Typical usage [self testHighLevelEncodeString:@"ABC. DEF\r\n" - // A B C P/S . D E F P/S \r\n + // A B C P/S . D E F P/S \r\n expectedBits:@"...X. ...XX ..X.. ..... ...XX ..X.X ..XX. ..XXX ..... ...X."]; // We should latch to PUNCT mode, rather than shift. Also check all pairs [self testHighLevelEncodeString:@"A. : , \r\n" - // 'A' M/L P/L ". " ": " ", " "\r\n" + // 'A' M/L P/L ". " ": " ", " "\r\n" expectedBits:@"...X. XXX.X XXXX. ...XX ..X.X ..X.. ...X."]; // Latch to DIGIT rather than shift to PUNCT [self testHighLevelEncodeString:@"A. 1234" - // 'A' D/L '.' ' ' '1' '2' '3' '4' + // 'A' D/L '.' ' ' '1' '2' '3' '4' expectedBits:@"...X. XXXX. XX.X ...X ..XX .X.. .X.X .X X."]; // Don't bother leaving Binary Shift. [self testHighLevelEncodeString:[NSString stringWithFormat:@"A%c. %c", '\200', '\200'] - // 'A' B/S =2 \200 "." " " \200 + // 'A' B/S =2 \200 "." " " \200 expectedBits:@"...X. XXXXX ..X.. X....... ..X.XXX. ..X..... X......."]; } @@ -452,7 +483,7 @@ - (void)testWriter:(NSString *)data encoding:(NSStringEncoding)encoding eccPerce ZXAztecWriter *writer = [[ZXAztecWriter alloc] init]; ZXBitMatrix *matrix = [writer encode:data format:kBarcodeFormatAztec width:0 height:0 hints:hints error:nil]; ZXAztecCode *aztec = [ZXAztecEncoder encode:bytes minECCPercent:eccPercent - userSpecifiedLayers:ZX_AZTEC_DEFAULT_LAYERS]; + userSpecifiedLayers:ZX_AZTEC_DEFAULT_LAYERS]; XCTAssertEqual(compact, aztec.compact, @"Unexpected symbol format (compact)"); XCTAssertEqual(layers, aztec.layers, @"Unexpected nr. of layers"); ZXBitMatrix *matrix2 = aztec.matrix; @@ -466,11 +497,11 @@ - (void)testWriter:(NSString *)data encoding:(NSStringEncoding)encoding eccPerce for (NSInteger i = 0; i < ecWords; i++) { // don't touch the core int x = rand() % 2 > 0 ? - rand() % aztec.layers * 2 - : matrix.width - 1 - (rand() % aztec.layers * 2); + rand() % aztec.layers * 2 + : matrix.width - 1 - (rand() % aztec.layers * 2); int y = rand() % 2 > 0 ? - rand() % aztec.layers * 2 - : matrix.height - 1 - (rand() % aztec.layers * 2); + rand() % aztec.layers * 2 + : matrix.height - 1 - (rand() % aztec.layers * 2); [matrix flipX:x y:y]; } r = [[ZXAztecDetectorResult alloc] initWithBits:matrix points:@[] compact:aztec.compact nbDatablocks:aztec.codeWords nbLayers:aztec.layers]; diff --git a/ZXingObjCTests/common/ZXAbstractBlackBoxTestCase.h b/ZXingObjCTests/common/ZXAbstractBlackBoxTestCase.h index 0d6a1bb4f..96350337e 100644 --- a/ZXingObjCTests/common/ZXAbstractBlackBoxTestCase.h +++ b/ZXingObjCTests/common/ZXAbstractBlackBoxTestCase.h @@ -20,6 +20,8 @@ @property (nonatomic, assign) ZXBarcodeFormat expectedFormat; @property (nonatomic, copy) NSString *testBase; @property (nonatomic, strong) NSMutableArray *testResults; +@property (nonatomic, strong) ZXCGImageLuminanceSourceInfo *luminanceSourceInfo; +@property (nonatomic, assign) BOOL shouldTruncateNewline; - (id)initWithInvocation:(NSInvocation *)invocation testBasePathSuffix:(NSString *)testBasePathSuffix barcodeReader:(id)barcodeReader expectedFormat:(ZXBarcodeFormat)expectedFormat; + (NSString *)barcodeFormatAsString:(ZXBarcodeFormat)format; diff --git a/ZXingObjCTests/common/ZXAbstractBlackBoxTestCase.m b/ZXingObjCTests/common/ZXAbstractBlackBoxTestCase.m index f4b4bb83c..188932d22 100644 --- a/ZXingObjCTests/common/ZXAbstractBlackBoxTestCase.m +++ b/ZXingObjCTests/common/ZXAbstractBlackBoxTestCase.m @@ -26,7 +26,7 @@ - (id)initWithInvocation:(NSInvocation *)invocation testBasePathSuffix:(NSString _expectedFormat = expectedFormat; _testResults = [NSMutableArray array]; } - + return self; } @@ -51,7 +51,7 @@ - (NSArray *)imageFiles { [imageFiles addObject:[NSURL fileURLWithPath:file]]; } } - + return imageFiles; } @@ -113,7 +113,7 @@ + (NSString *)barcodeFormatAsString:(ZXBarcodeFormat)format { return @"UPC/EAN extension"; break; } - + return nil; } @@ -130,25 +130,25 @@ - (void)testBlackBoxCountingResults:(BOOL)assertOnFailure { if (self.testResults.count == 0) { XCTFail(@"No test results"); } - + NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray *imageFiles = [self imageFiles]; int testCount = (int)[self.testResults count]; - + ZXIntArray *passedCounts = [[ZXIntArray alloc] initWithLength:testCount]; ZXIntArray *misreadCounts = [[ZXIntArray alloc] initWithLength:testCount]; ZXIntArray *tryHarderCounts = [[ZXIntArray alloc] initWithLength:testCount]; ZXIntArray *tryHarderMisreadCounts = [[ZXIntArray alloc] initWithLength:testCount]; - + for (NSURL *testImage in imageFiles) { NSLog(@"Starting %@", [self pathInBundle:testImage]); - + ZXImage *image = [[ZXImage alloc] initWithURL:testImage]; - + NSString *testImageFileName = [[[testImage path] componentsSeparatedByString:@"/"] lastObject]; NSString *fileBaseName = [testImageFileName substringToIndex:[testImageFileName rangeOfString:@"."].location]; NSString *expectedTextFile = [[NSBundle bundleForClass:[self class]] pathForResource:fileBaseName ofType:@"txt" inDirectory:self.testBase]; - + NSString *expectedText; if (expectedTextFile) { expectedText = [self readFileAsString:expectedTextFile encoding:NSUTF8StringEncoding]; @@ -157,17 +157,18 @@ - (void)testBlackBoxCountingResults:(BOOL)assertOnFailure { XCTAssertNotNil(expectedTextFile, @"Expected text does not exist"); expectedText = [self readFileAsString:expectedTextFile encoding:NSISOLatin1StringEncoding]; } - + NSURL *expectedMetadataFile = [NSURL URLWithString:[[NSBundle bundleForClass:[self class]] pathForResource:fileBaseName ofType:@".metadata.txt" inDirectory:self.testBase]]; NSMutableDictionary *expectedMetadata = [NSMutableDictionary dictionary]; if ([fileManager fileExistsAtPath:[expectedMetadataFile path]]) { expectedMetadata = [NSMutableDictionary dictionaryWithContentsOfFile:[expectedMetadataFile path]]; } - + for (int x = 0; x < testCount; x++) { float rotation = [(ZXTestResult *)self.testResults[x] rotation]; ZXImage *rotatedImage = [self rotateImage:image degrees:rotation]; - ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage.cgimage]; + ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage: rotatedImage.cgimage + sourceInfo: _luminanceSourceInfo]; ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXHybridBinarizer alloc] initWithSource:source]]; BOOL misread; if ([self decode:bitmap rotation:rotation expectedText:expectedText expectedMetadata:expectedMetadata tryHarder:NO misread:&misread]) { @@ -177,7 +178,7 @@ - (void)testBlackBoxCountingResults:(BOOL)assertOnFailure { } else { NSLog(@"could not read at rotation %f", rotation); } - + if ([self decode:bitmap rotation:rotation expectedText:expectedText expectedMetadata:expectedMetadata tryHarder:YES misread:&misread]) { tryHarderCounts.array[x]++; } else if (misread) { @@ -187,13 +188,13 @@ - (void)testBlackBoxCountingResults:(BOOL)assertOnFailure { } } } - + // Print the results of all tests first int totalFound = 0; int totalMustPass = 0; int totalMisread = 0; int totalMaxMisread = 0; - + for (int x = 0; x < testCount; x++) { ZXTestResult *testResult = self.testResults[x]; NSLog(@"Rotation %d degrees:", (int) testResult.rotation); @@ -212,22 +213,23 @@ - (void)testBlackBoxCountingResults:(BOOL)assertOnFailure { totalMisread += misreadCounts.array[x] + tryHarderMisreadCounts.array[x]; totalMaxMisread += testResult.maxMisreads + testResult.maxTryHarderMisreads; } - + int totalTests = (int)imageFiles.count * testCount * 2; NSLog(@"TOTALS:\nDecoded %d images out of %d (%d%%, %d required)", totalFound, totalTests, totalFound * 100 / totalTests, totalMustPass); if (totalFound > totalMustPass) { NSLog(@" +++ Test too lax by %d images", totalFound - totalMustPass); } else if (totalFound < totalMustPass) { + NSLog(@"total must pass %d - total found %d", totalMustPass, totalFound); NSLog(@" --- Test failed by %d images", totalMustPass - totalFound); } - + if (totalMisread < totalMaxMisread) { NSLog(@" +++ Test expects too many misreads by %d images", totalMaxMisread - totalMisread); } else if (totalMisread > totalMaxMisread) { NSLog(@" --- Test had too many misreads by %d images", totalMisread - totalMaxMisread); } - + // Then run through again and assert if any failed if (assertOnFailure) { for (int x = 0; x < testCount; x++) { @@ -245,31 +247,44 @@ - (void)testBlackBoxCountingResults:(BOOL)assertOnFailure { - (BOOL)decode:(ZXBinaryBitmap *)source rotation:(float)rotation expectedText:(NSString *)expectedText expectedMetadata:(NSMutableDictionary *)expectedMetadata tryHarder:(BOOL)tryHarder misread:(BOOL *)misread { NSString *suffix = [NSString stringWithFormat:@" (%@rotation: %d)", tryHarder ? @"try harder, " : @"", (int) rotation]; *misread = NO; - + + if (_shouldTruncateNewline) { + if ([expectedText length] > 0 && [[expectedText substringFromIndex: [expectedText length] - 1] isEqualToString: @"\n"]) { + NSString *temp = [expectedText substringToIndex: [expectedText length] - 1]; + expectedText = temp; + } + } + ZXDecodeHints *hints = [ZXDecodeHints hints]; + ZXDecodeHints *pureHints = [ZXDecodeHints hints]; + pureHints.pureBarcode = YES; if (tryHarder) { hints.tryHarder = YES; + pureHints.tryHarder = YES; + } + + ZXResult *result = [self.barcodeReader decode:source hints:pureHints error:nil]; + if (!result) { + result = [self.barcodeReader decode:source hints:hints error:nil]; } - - ZXResult *result = [self.barcodeReader decode:source hints:hints error:nil]; if (!result) { return NO; } - + if (self.expectedFormat != result.barcodeFormat) { NSLog(@"Format mismatch: expected '%@' but got '%@'%@", [[self class] barcodeFormatAsString:self.expectedFormat], [[self class] barcodeFormatAsString:result.barcodeFormat], suffix); *misread = YES; return NO; } - + NSString *resultText = result.text; if (![expectedText isEqualToString:resultText]) { NSLog(@"Content mismatch: expected '%@' but got '%@'%@", expectedText, resultText, suffix); *misread = YES; return NO; } - + NSMutableDictionary *resultMetadata = result.resultMetadata; for (id keyObj in [expectedMetadata allKeys]) { ZXResultMetadataType key = [keyObj intValue]; @@ -281,12 +296,12 @@ - (BOOL)decode:(ZXBinaryBitmap *)source rotation:(float)rotation expectedText:(N return NO; } } - + return YES; } - (NSString *)readFileAsString:(NSString *)file encoding:(NSStringEncoding)encoding { - NSString *stringContents = [NSString stringWithContentsOfFile:file encoding:encoding error:nil]; + NSString *stringContents = [NSString stringWithContentsOfFile:file encoding:encoding error:nil]; if ([stringContents hasSuffix:@"\n"]) { NSLog(@"String contents of file %@ end with a newline. This may not be intended and cause a test failure", file); } @@ -299,11 +314,11 @@ - (ZXImage *)rotateImage:(ZXImage *)original degrees:(float)degrees { return original; } double radians = -1 * degrees * (M_PI / 180); - + CGRect imgRect = CGRectMake(0, 0, original.width, original.height); CGAffineTransform transform = CGAffineTransformMakeRotation(radians); CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform); - + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, rotatedRect.size.width, @@ -315,22 +330,22 @@ - (ZXImage *)rotateImage:(ZXImage *)original degrees:(float)degrees { CGContextSetAllowsAntialiasing(context, FALSE); CGContextSetInterpolationQuality(context, kCGInterpolationNone); CGColorSpaceRelease(colorSpace); - + CGContextTranslateCTM(context, +(rotatedRect.size.width/2), +(rotatedRect.size.height/2)); CGContextRotateCTM(context, radians); - + CGContextDrawImage(context, CGRectMake(-imgRect.size.width / 2, -imgRect.size.height / 2, imgRect.size.width, imgRect.size.height), original.cgimage); - + CGImageRef rotatedImage = CGBitmapContextCreateImage(context); - + CFRelease(context); - + return [[ZXImage alloc] initWithCGImageRef:rotatedImage]; } diff --git a/ZXingObjCTests/common/ZXBitArrayTestCase.h b/ZXingObjCTests/common/ZXBitArrayTestCase.h index bc7f86c68..5324ee162 100644 --- a/ZXingObjCTests/common/ZXBitArrayTestCase.h +++ b/ZXingObjCTests/common/ZXBitArrayTestCase.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#import "ZXBitArray.h" + @interface ZXBitArrayTestCase : XCTestCase @end diff --git a/ZXingObjCTests/common/ZXBitArrayTestCase.m b/ZXingObjCTests/common/ZXBitArrayTestCase.m index cbce4bfd3..5ab71a492 100644 --- a/ZXingObjCTests/common/ZXBitArrayTestCase.m +++ b/ZXingObjCTests/common/ZXBitArrayTestCase.m @@ -127,6 +127,16 @@ - (void)testSetBulk { } } +- (void)testSetRange { + ZXBitArray *array = [[ZXBitArray alloc] initWithSize:64]; + [array setRange:28 end:36]; + XCTAssertFalse([array get:27]); + for (int i = 28; i < 36; i++) { + XCTAssertTrue([array get:i]); + } + XCTAssertFalse([array get:36]); +} + - (void)testClear { ZXBitArray *array = [[ZXBitArray alloc] initWithSize:32]; for (int i = 0; i < 32; i++) { @@ -138,6 +148,15 @@ - (void)testClear { } } +- (void)testFlip { + ZXBitArray *array = [[ZXBitArray alloc] initWithSize:32]; + XCTAssertFalse([array get:5]); + [array flip:5]; + XCTAssertTrue([array get:5]); + [array flip:5]; + XCTAssertFalse([array get:5]); +} + - (void)testGetArray { ZXBitArray *array = [[ZXBitArray alloc] initWithSize:64]; [array set:0]; @@ -179,6 +198,23 @@ - (void)testReverseAlgorithm { } } +- (void)testEquals { + ZXBitArray *a = [[ZXBitArray alloc] initWithSize:32]; + ZXBitArray *b = [[ZXBitArray alloc] initWithSize:32]; + XCTAssertEqualObjects(a, b); + XCTAssertEqual(a.hash, b.hash); + + XCTAssertNotEqualObjects(a, [[ZXBitArray alloc] initWithSize:31]); + + [a set:16]; + XCTAssertNotEqualObjects(a, b); + XCTAssertNotEqual(a.hash, b.hash); + + [b set:16]; + XCTAssertEqualObjects(a, b); + XCTAssertEqual(a.hash, b.hash); +} + - (ZXIntArray *)reverseOriginal:(ZXIntArray *)oldBits size:(int)size { ZXIntArray *newBits = [[ZXIntArray alloc] initWithLength:oldBits.length]; for (int i = 0; i < size; i++) { diff --git a/ZXingObjCTests/common/ZXBitMatrixTestCase.m b/ZXingObjCTests/common/ZXBitMatrixTestCase.m index 63277011a..5f119da52 100644 --- a/ZXingObjCTests/common/ZXBitMatrixTestCase.m +++ b/ZXingObjCTests/common/ZXBitMatrixTestCase.m @@ -51,6 +51,50 @@ - (void)testSetRegion { } } +- (void)testEnclosing { + ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithDimension:5]; + XCTAssertNil([matrix enclosingRectangle]); + [matrix setRegionAtLeft:1 top:1 width:1 height:1]; + ZXIntArray *actual = [matrix enclosingRectangle]; + ZXIntArray *expected = [[ZXIntArray alloc] initWithInts:1, 1, 1, 1, -1]; + XCTAssertEqualObjects(expected, actual); + [matrix setRegionAtLeft:1 top:1 width:3 height:2]; + actual = [matrix enclosingRectangle]; + expected = [[ZXIntArray alloc] initWithInts:1, 1, 3, 2, -1]; + XCTAssertEqualObjects(expected, actual); + [matrix setRegionAtLeft:0 top:0 width:5 height:5]; + actual = [matrix enclosingRectangle]; + expected = [[ZXIntArray alloc] initWithInts:0, 0, 5, 5, -1]; + XCTAssertEqualObjects(expected, actual); +} + +- (void)testOnBit { + ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithDimension:5]; + XCTAssertNil([matrix topLeftOnBit]); + XCTAssertNil([matrix bottomRightOnBit]); + [matrix setRegionAtLeft:1 top:1 width:1 height:1]; + ZXIntArray *actual = [matrix topLeftOnBit]; + ZXIntArray *expected = [[ZXIntArray alloc] initWithInts:1, 1, -1]; + XCTAssertEqualObjects(expected, actual); + actual = [matrix bottomRightOnBit]; + expected = [[ZXIntArray alloc] initWithInts:1, 1, -1]; + XCTAssertEqualObjects(expected, actual); + [matrix setRegionAtLeft:1 top:1 width:3 height:2]; + actual = [matrix topLeftOnBit]; + expected = [[ZXIntArray alloc] initWithInts:1, 1, -1]; + XCTAssertEqualObjects(expected, actual); + actual = [matrix bottomRightOnBit]; + expected = [[ZXIntArray alloc] initWithInts:3, 2, -1]; + XCTAssertEqualObjects(expected, actual); + [matrix setRegionAtLeft:0 top:0 width:5 height:5]; + actual = [matrix topLeftOnBit]; + expected = [[ZXIntArray alloc] initWithInts:0, 0, -1]; + XCTAssertEqualObjects(expected, actual); + actual = [matrix bottomRightOnBit]; + expected = [[ZXIntArray alloc] initWithInts:4, 4, -1]; + XCTAssertEqualObjects(expected, actual); +} + - (void)testRectangularMatrix { ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithWidth:75 height:20]; XCTAssertEqual(75, matrix.width); diff --git a/ZXingObjCTests/common/ZXDecimalTestCase.h b/ZXingObjCTests/common/ZXDecimalTestCase.h new file mode 100644 index 000000000..4fd911e8f --- /dev/null +++ b/ZXingObjCTests/common/ZXDecimalTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXDecimalTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/common/ZXDecimalTestCase.m b/ZXingObjCTests/common/ZXDecimalTestCase.m new file mode 100644 index 000000000..51c9b0a07 --- /dev/null +++ b/ZXingObjCTests/common/ZXDecimalTestCase.m @@ -0,0 +1,107 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXDecimalTestCase.h" +#import "ZXDecimal.h" + +@implementation ZXDecimalTestCase + +- (void)testInitializer { + ZXDecimal *decimal = [ZXDecimal decimalWithString:@"10"]; + XCTAssertEqual(10, [decimal.value intValue]); + + decimal = [ZXDecimal decimalWithInt:10]; + XCTAssertEqual(10, [decimal.value intValue]); + + decimal = [ZXDecimal decimalWithDecimalNumber:[[NSDecimalNumber alloc] initWithInt:10]]; + XCTAssertEqual(10, [decimal.value intValue]); +} + +- (void)testZero { + ZXDecimal *decimal = [ZXDecimal decimalWithInt:0]; + XCTAssertEqualObjects(decimal,[ZXDecimal decimalWithInt:0]); + XCTAssertEqualObjects([decimal decimalByMultiplyingBy:decimal], [ZXDecimal decimalWithInt:0]); + XCTAssertEqualObjects([decimal decimalByAdding:decimal], [ZXDecimal decimalWithInt:0]); + + + decimal = [ZXDecimal decimalWithString:@""]; + XCTAssertEqualObjects(decimal, [ZXDecimal decimalWithInt:0]); + XCTAssertEqualObjects([ZXDecimal zero], [ZXDecimal decimalWithInt:0]); +} + +- (void)testSimpleAddition { + ZXDecimal *decimal1 = [ZXDecimal decimalWithString:@"10"]; + ZXDecimal *decimal2 = [ZXDecimal decimalWithString:@"10"]; + XCTAssertEqual(20, [[decimal1 decimalByAdding:decimal2].value intValue]); + + decimal1 = [ZXDecimal decimalWithString:@"4"]; + decimal2 = [ZXDecimal decimalWithString:@"4"]; + XCTAssertEqual(8, [[decimal1 decimalByAdding:decimal2].value intValue]); + + decimal1 = [ZXDecimal decimalWithString:@"4000"]; + decimal2 = [ZXDecimal decimalWithString:@"44"]; + XCTAssertEqual(4044, [[decimal1 decimalByAdding:decimal2].value intValue]); + + decimal1 = [ZXDecimal decimalWithString:@"231"]; + decimal2 = [ZXDecimal decimalWithString:@"999999876"]; + XCTAssertEqual(1000000107, [[decimal1 decimalByAdding:decimal2].value intValue]); +} + +- (void)testAdditionWithLarge { + ZXDecimal *decimal1 = [ZXDecimal decimalWithString:@"231"]; + ZXDecimal *decimal2 = [ZXDecimal decimalWithString:@"999999876"]; + XCTAssertEqual(1000000107, [[decimal1 decimalByAdding:decimal2].value intValue]); +} + +- (void)testSimpleMultiply { + ZXDecimal *decimal1 = [ZXDecimal decimalWithString:@"10"]; + ZXDecimal *decimal2 = [ZXDecimal decimalWithString:@"10"]; + XCTAssertEqual(100, [[decimal1 decimalByMultiplyingBy:decimal2].value intValue]); + + decimal1 = [ZXDecimal decimalWithString:@"4"]; + decimal2 = [ZXDecimal decimalWithString:@"4"]; + XCTAssertEqual(16, [[decimal1 decimalByMultiplyingBy:decimal2].value intValue]); +} + +- (void)testEnhancedMultiply { + ZXDecimal *decimal1 = [ZXDecimal decimalWithString:@"10"]; + ZXDecimal *decimal2 = [ZXDecimal decimalWithString:@"20"]; + XCTAssertEqual(200, [[decimal1 decimalByMultiplyingBy:decimal2].value intValue]); + + decimal1 = [ZXDecimal decimalWithString:@"12"]; + decimal2 = [ZXDecimal decimalWithString:@"22"]; + XCTAssertEqual(264, [[decimal1 decimalByMultiplyingBy:decimal2].value intValue]); + + decimal1 = [ZXDecimal decimalWithString:@"10"]; + decimal2 = [ZXDecimal decimalWithString:@"100"]; + XCTAssertEqual(1000, [[decimal1 decimalByMultiplyingBy:decimal2].value intValue]); +} + +- (void)testEnhancedMultiplyWithLargeNumber { + ZXDecimal *decimal1 = [ZXDecimal decimalWithString:@"521"]; + ZXDecimal *decimal2 = [ZXDecimal decimalWithString:@"321"]; + XCTAssertEqual(167241, [[decimal1 decimalByMultiplyingBy:decimal2].value intValue]); + + decimal1 = [ZXDecimal decimalWithString:@"5589723"]; + decimal2 = [ZXDecimal decimalWithString:@"99987652"]; + XCTAssertEqualObjects(@"558903278100396", [decimal1 decimalByMultiplyingBy:decimal2].value); + + decimal1 = [ZXDecimal decimalWithString:@"989898989898981"]; + decimal2 = [ZXDecimal decimalWithString:@"999988885555533"]; + XCTAssertEqualObjects(@"989887987721629828381735611873", [decimal1 decimalByMultiplyingBy:decimal2].value); +} + +@end diff --git a/ZXingObjCTests/common/reedsolomon/ZXGenericGFPolyTestCase.h b/ZXingObjCTests/common/reedsolomon/ZXGenericGFPolyTestCase.h new file mode 100644 index 000000000..6c401865a --- /dev/null +++ b/ZXingObjCTests/common/reedsolomon/ZXGenericGFPolyTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXGenericGFPolyTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/common/reedsolomon/ZXGenericGFPolyTestCase.m b/ZXingObjCTests/common/reedsolomon/ZXGenericGFPolyTestCase.m new file mode 100644 index 000000000..80961cd1f --- /dev/null +++ b/ZXingObjCTests/common/reedsolomon/ZXGenericGFPolyTestCase.m @@ -0,0 +1,47 @@ +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXGenericGFPolyTestCase.h" +#import "ZXGenericGFPoly.h" +#import "ZXGenericGF.h" + +@implementation ZXGenericGFPolyTestCase + +static ZXGenericGF *FIELD = nil; + ++ (void)initialize { + FIELD = [ZXGenericGF QrCodeField256]; +} + +- (void)testPolynomialString { + XCTAssertEqualObjects(@"0", [FIELD.zero description]); + XCTAssertEqualObjects(@"-1", [[FIELD buildMonomial:0 coefficient:-1] description]); + ZXGenericGFPoly *p = [[ZXGenericGFPoly alloc] initWithField:FIELD coefficients:[[ZXIntArray alloc] initWithInts:3, 0, -2, 1, 1, -1]]; + XCTAssertEqualObjects(@"a^25x^4 - ax^2 + x + 1", [p description]); + p = [[ZXGenericGFPoly alloc] initWithField:FIELD coefficients:[[ZXIntArray alloc] initWithInts:3, -1]]; + XCTAssertEqualObjects(@"a^25", [p description]); +} + +- (void)testZero { + XCTAssertEqualObjects(FIELD.zero, [FIELD buildMonomial:1 coefficient:0]); + XCTAssertEqualObjects(FIELD.zero, [[FIELD buildMonomial:1 coefficient:2] multiplyScalar:0]); +} + +- (void)testEvaluate { + XCTAssertEqual(3, [[FIELD buildMonomial:0 coefficient:3] evaluateAt:0]); +} + +@end diff --git a/ZXingObjCTests/common/reedsolomon/ZXReedSolomonTestCase.m b/ZXingObjCTests/common/reedsolomon/ZXReedSolomonTestCase.m index 6cc2b8d85..ee6639aa2 100644 --- a/ZXingObjCTests/common/reedsolomon/ZXReedSolomonTestCase.m +++ b/ZXingObjCTests/common/reedsolomon/ZXReedSolomonTestCase.m @@ -15,6 +15,8 @@ */ #import "ZXReedSolomonTestCase.h" +#import "ZXGenericGFPoly.h" +#import "ZXGenericGF.h" const int DECODER_RANDOM_TEST_ITERATIONS = 3; const int DECODER_TEST_ITERATIONS = 10; diff --git a/ZXingObjCTests/datamatrix/ZXDataMatrixBlackBox1TestCase.m b/ZXingObjCTests/datamatrix/ZXDataMatrixBlackBox1TestCase.m index b3ffb9a87..e8ce80904 100644 --- a/ZXingObjCTests/datamatrix/ZXDataMatrixBlackBox1TestCase.m +++ b/ZXingObjCTests/datamatrix/ZXDataMatrixBlackBox1TestCase.m @@ -25,10 +25,10 @@ - (id)initWithInvocation:(NSInvocation *)invocation { expectedFormat:kBarcodeFormatDataMatrix]; if (self) { - [self addTest:18 tryHarderCount:18 rotation:0.0f]; - [self addTest:18 tryHarderCount:18 rotation:90.0f]; - [self addTest:18 tryHarderCount:18 rotation:180.0f]; - [self addTest:18 tryHarderCount:18 rotation:270.0f]; + [self addTest:21 tryHarderCount:21 rotation:0.0f]; + [self addTest:21 tryHarderCount:21 rotation:90.0f]; + [self addTest:21 tryHarderCount:21 rotation:180.0f]; + [self addTest:21 tryHarderCount:21 rotation:270.0f]; } return self; diff --git a/ZXingObjCTests/datamatrix/ZXDataMatrixBlackBox2TestCase.m b/ZXingObjCTests/datamatrix/ZXDataMatrixBlackBox2TestCase.m index f2f963f8e..17b52c511 100644 --- a/ZXingObjCTests/datamatrix/ZXDataMatrixBlackBox2TestCase.m +++ b/ZXingObjCTests/datamatrix/ZXDataMatrixBlackBox2TestCase.m @@ -25,10 +25,10 @@ - (id)initWithInvocation:(NSInvocation *)invocation { expectedFormat:kBarcodeFormatDataMatrix]; if (self) { - [self addTest:8 tryHarderCount:8 maxMisreads:0 maxTryHarderMisreads:1 rotation:0.0f]; - [self addTest:14 tryHarderCount:14 maxMisreads:0 maxTryHarderMisreads:1 rotation:90.0f]; - [self addTest:14 tryHarderCount:14 maxMisreads:0 maxTryHarderMisreads:1 rotation:180.0f]; - [self addTest:13 tryHarderCount:13 maxMisreads:0 maxTryHarderMisreads:1 rotation:270.0f]; + [self addTest:13 tryHarderCount:13 maxMisreads:0 maxTryHarderMisreads:1 rotation:0.0f]; + [self addTest:15 tryHarderCount:15 maxMisreads:0 maxTryHarderMisreads:1 rotation:90.0f]; + [self addTest:17 tryHarderCount:16 maxMisreads:0 maxTryHarderMisreads:1 rotation:180.0f]; + [self addTest:15 tryHarderCount:15 maxMisreads:0 maxTryHarderMisreads:1 rotation:270.0f]; } return self; diff --git a/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.m b/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.m index 1c37d2e10..f9d5aa10a 100644 --- a/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.m +++ b/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.m @@ -18,6 +18,23 @@ @implementation ZXDataMatrixWriterTestCase +- (void)testDataMatrixWriterIssue { + NSString *hugeString = @"

"; + ZXDataMatrixWriter *writer = [[ZXDataMatrixWriter alloc] init]; + ZXBitMatrix *matrix = [writer encode:hugeString format:kBarcodeFormatDataMatrix width:0 height:0 hints:nil error:nil]; + ZXImage *image = [ZXImage imageWithMatrix:matrix]; + XCTAssertNotNil(image); + + ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:image.cgimage]; + ZXBinaryBitmap *bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]]; + + ZXDataMatrixReader *reader = [[ZXDataMatrixReader alloc] init]; + ZXDecodeHints *hints = [ZXDecodeHints hints]; + hints.pureBarcode = YES; + ZXResult *result = [reader decode:bitmap hints:hints error:nil]; + XCTAssertNotNil(result); +} + - (void)testDataMatrixImageWriter { ZXEncodeHints *hints = [ZXEncodeHints hints]; hints.dataMatrixShape = ZXDataMatrixSymbolShapeHintForceSquare; diff --git a/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixHighLevelEncodeTestCase.m b/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixHighLevelEncodeTestCase.m index ed267e5ec..41ad33ed6 100644 --- a/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixHighLevelEncodeTestCase.m +++ b/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixHighLevelEncodeTestCase.m @@ -303,6 +303,11 @@ - (NSString *)encodeHighLevel:(NSString *)msg { return [[self class] visualize:encoded]; } +- (void)testEncodingWithStartAsX12AndLatchToEDIFACTInTheMiddle { + NSString *visualized = [self encodeHighLevel:@"*MEMANT-1F-MESTECH"]; + XCTAssertEqualObjects(@"238 10 99 164 204 254 240 82 220 70 180 209 83 80 80 200", visualized); +} + + (NSString *)visualize:(NSString *)codewords { NSMutableString *sb = [NSMutableString string]; for (int i = 0; i < codewords.length; i++) { diff --git a/ZXingObjCTests/maxicode/ZXMaxicodeBlackBox1TestCase.h b/ZXingObjCTests/maxicode/ZXMaxicodeBlackBox1TestCase.h new file mode 100644 index 000000000..83ffb869b --- /dev/null +++ b/ZXingObjCTests/maxicode/ZXMaxicodeBlackBox1TestCase.h @@ -0,0 +1,21 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXAbstractBlackBoxTestCase.h" + +@interface ZXMaxicodeBlackBox1TestCase : ZXAbstractBlackBoxTestCase + +@end diff --git a/ZXingObjCTests/maxicode/ZXMaxicodeBlackBox1TestCase.m b/ZXingObjCTests/maxicode/ZXMaxicodeBlackBox1TestCase.m new file mode 100644 index 000000000..4cfaf74f6 --- /dev/null +++ b/ZXingObjCTests/maxicode/ZXMaxicodeBlackBox1TestCase.m @@ -0,0 +1,41 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXMaxicodeBlackBox1TestCase.h" + +@implementation ZXMaxicodeBlackBox1TestCase + +- (id)initWithInvocation:(NSInvocation *)invocation { + self = [super initWithInvocation:invocation + testBasePathSuffix:@"Resources/blackbox/maxicode-1" + barcodeReader:[[ZXMultiFormatReader alloc] init] + expectedFormat:kBarcodeFormatMaxiCode]; + + if (self) { + [self addTest:5 tryHarderCount:5 rotation:0.0f]; +// [self addTest:5 tryHarderCount:5 rotation:90.0f]; +// [self addTest:5 tryHarderCount:5 rotation:180.0f]; +// [self addTest:5 tryHarderCount:5 rotation:270.0f]; + } + + return self; +} + +- (void)testBlackBox { + [super runTests]; +} + +@end diff --git a/ZXingObjCTests/multi/ZXMultiTestCase.h b/ZXingObjCTests/multi/ZXMultiTestCase.h new file mode 100644 index 000000000..6e2501524 --- /dev/null +++ b/ZXingObjCTests/multi/ZXMultiTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXMultiTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/multi/ZXMultiTestCase.m b/ZXingObjCTests/multi/ZXMultiTestCase.m new file mode 100644 index 000000000..e6a3cdd3a --- /dev/null +++ b/ZXingObjCTests/multi/ZXMultiTestCase.m @@ -0,0 +1,69 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXMultiTestCase.h" + +@implementation ZXMultiTestCase + +- (void)testMulti { + NSString *testBase = @"Resources/blackbox/multi-1"; + NSBundle *classBundle = [NSBundle bundleForClass:[self class]]; + NSString *pathForResource = [classBundle pathForResource:@"1" ofType:@"png" inDirectory:testBase]; + NSURL *testImageURL = [NSURL fileURLWithPath:pathForResource]; + + ZXImage *testImage = [[ZXImage alloc] initWithURL:testImageURL]; + ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:testImage.cgimage]; + ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXHybridBinarizer alloc] initWithSource:source]]; + + ZXGenericMultipleBarcodeReader *multiReader = [[ZXGenericMultipleBarcodeReader alloc] initWithDelegate:[ZXMultiFormatReader reader]]; + NSArray *results = [multiReader decodeMultiple:bitmap error:nil]; + XCTAssertNotNil(results); + XCTAssertEqual(2, results.count); + + XCTAssertEqualObjects(@"031415926531", results[0].text); + XCTAssertEqual(kBarcodeFormatUPCA, results[0].barcodeFormat); + + XCTAssertEqualObjects(@"www.airtable.com/jobs", results[1].text); + XCTAssertEqual(kBarcodeFormatQRCode, results[1].barcodeFormat); +} + +- (void)testMultiTryHarder { + NSString *testBase = @"Resources/blackbox/multi-1"; + NSBundle *classBundle = [NSBundle bundleForClass:[self class]]; + NSString *pathForResource = [classBundle pathForResource:@"1" ofType:@"png" inDirectory:testBase]; + NSURL *testImageURL = [NSURL fileURLWithPath:pathForResource]; + + ZXImage *testImage = [[ZXImage alloc] initWithURL:testImageURL]; + ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:testImage.cgimage]; + ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXHybridBinarizer alloc] initWithSource:source]]; + + ZXGenericMultipleBarcodeReader *multiReader = [[ZXGenericMultipleBarcodeReader alloc] initWithDelegate:[ZXMultiFormatReader reader]]; + + ZXDecodeHints *hints = [ZXDecodeHints hints]; + hints.tryHarder = YES; + + NSArray *results = [multiReader decodeMultiple:bitmap hints:hints error:nil]; + XCTAssertNotNil(results); + XCTAssertEqual(2, results.count); + + XCTAssertEqualObjects(@"www.airtable.com/jobs", results[0].text); + XCTAssertEqual(kBarcodeFormatQRCode, results[0].barcodeFormat); + + XCTAssertEqualObjects(@"031415926531", results[1].text); + XCTAssertEqual(kBarcodeFormatUPCA, results[1].barcodeFormat); +} + +@end diff --git a/ZXingObjCTests/oned/ZXCode128WriterTestCase.m b/ZXingObjCTests/oned/ZXCode128WriterTestCase.m index 9501ca8c4..eda2fcc57 100644 --- a/ZXingObjCTests/oned/ZXCode128WriterTestCase.m +++ b/ZXingObjCTests/oned/ZXCode128WriterTestCase.m @@ -15,18 +15,26 @@ */ #import "ZXCode128WriterTestCase.h" +#import "ZXCode128Reader.h" const NSString *ZX_FNC1 = @"11110101110"; const NSString *ZX_FNC2 = @"11110101000"; const NSString *ZX_FNC3 = @"10111100010"; -const NSString *ZX_FNC4 = @"10111101110"; +const NSString *ZX_FNC4A = @"11101011110"; +const NSString *ZX_FNC4B = @"10111101110"; +const NSString *ZX_START_CODE_A = @"11010000100"; const NSString *ZX_START_CODE_B = @"11010010000"; +const NSString *ZX_START_CODE_C = @"11010011100"; +const NSString *ZX_SWITCH_CODE_A = @"11101011110"; +const NSString *ZX_SWITCH_CODE_B = @"10111101110"; const NSString *ZX_QUIET_SPACE = @"00000"; const NSString *ZX_STOP = @"1100011101011"; +const NSString *ZX_LF = @"10000110010"; @interface ZXCode128WriterTestCase () @property (nonatomic, strong) id writer; +@property (nonatomic, strong) ZXCode128Reader *reader; @end @@ -34,6 +42,7 @@ @implementation ZXCode128WriterTestCase - (void)setUp { self.writer = [[ZXCode128Writer alloc] init]; + self.reader = [[ZXCode128Reader alloc] init]; } - (void)testEncodeWithFunc3 { @@ -60,8 +69,8 @@ - (void)testEncodeWithFunc2 { - (void)testEncodeWithFunc1 { NSString *toEncode = [NSString stringWithFormat:@"%C123", (unichar)L'\u00f1']; - // "1" "2" "3" check digit 61 - NSString *expected = [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@", ZX_QUIET_SPACE, ZX_START_CODE_B, ZX_FNC1, @"10011100110", @"11001110010", @"11001011100", @"11001000010", ZX_STOP, ZX_QUIET_SPACE]; + // "12" "3" check digit 92 + NSString *expected = [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@", ZX_QUIET_SPACE, ZX_START_CODE_C, ZX_FNC1, @"10110011100", ZX_SWITCH_CODE_B, @"11001011100", @"10101111000", ZX_STOP, ZX_QUIET_SPACE]; ZXBitMatrix *result = [self.writer encode:toEncode format:kBarcodeFormatCode128 width:0 height:0 error:nil]; @@ -72,7 +81,7 @@ - (void)testEncodeWithFunc1 { - (void)testEncodeWithFunc4 { NSString *toEncode = [NSString stringWithFormat:@"%C123", (unichar)L'\u00f4']; // "1" "2" "3" check digit 59 - NSString *expected = [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@", ZX_QUIET_SPACE, ZX_START_CODE_B, ZX_FNC4, @"10011100110", @"11001110010", @"11001011100", @"11100011010", ZX_STOP, ZX_QUIET_SPACE]; + NSString *expected = [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@", ZX_QUIET_SPACE, ZX_START_CODE_B, ZX_FNC4B, @"10011100110", @"11001110010", @"11001011100", @"11100011010", ZX_STOP, ZX_QUIET_SPACE]; ZXBitMatrix *result = [self.writer encode:toEncode format:kBarcodeFormatCode128 width:0 height:0 error:nil]; @@ -80,6 +89,52 @@ - (void)testEncodeWithFunc4 { XCTAssertEqualObjects(actual, expected); } +- (void)testEncodeWithFncsAndNumberInCodesetA { + NSString *toEncode = [NSString stringWithFormat:@"\n%C%C1\n", (unichar) 0x00f1, 0x00f4]; + // start with A switch to B and back to A + // "\0" "A" "B" Switch to B "a" "b" Switch to A "\u0010" check digit + NSString *expected = [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@%@", ZX_QUIET_SPACE, ZX_START_CODE_A, ZX_LF, ZX_FNC1, ZX_FNC4A, @"10011100110", ZX_LF, @"10101111000", ZX_STOP, ZX_QUIET_SPACE]; + + ZXBitMatrix *result = [self.writer encode:toEncode format:kBarcodeFormatCode128 width:0 height:0 error:nil]; + + NSString *actual = [self matrixToString:result]; + XCTAssertEqualObjects(actual, expected); +} + +- (void)testEncodeSwitchBetweenCodesetsAAndBStartsWithA { + NSString *toEncode = [NSString stringWithFormat:@"\0ABab%C", (unichar) 0x0010]; + // start with A switch to B and back to A + // "\0" "A" "B" Switch to B "a" "b" Switch to A "\u0010" check digit + NSString *expected = [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@%@%@%@%@", ZX_QUIET_SPACE, ZX_START_CODE_A, @"10100001100", @"10100011000", @"10001011000", ZX_SWITCH_CODE_B, @"10010110000", @"10010000110", ZX_SWITCH_CODE_A, @"10100111100", @"11001110100", ZX_STOP, ZX_QUIET_SPACE]; + + ZXBitMatrix *result = [self.writer encode:toEncode format:kBarcodeFormatCode128 width:0 height:0 error:nil]; + + NSString *actual = [self matrixToString:result]; + XCTAssertEqualObjects(actual, expected); +} + +- (void)testEncodeSwitchBetweenCodesetsAAndBStartsWithB { + NSString *toEncode = [NSString stringWithFormat:@"ab\0ab", (unichar) 0x0010]; + // start with B switch to A and back to B + // "a" "b" Switch to A "\0 "Switch to B" "a" "b" check digit + NSString *expected = [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@%@%@%@", ZX_QUIET_SPACE, ZX_START_CODE_B, @"10010110000", @"10010000110", ZX_SWITCH_CODE_A, @"10100001100", ZX_SWITCH_CODE_B, @"10010110000", @"10010000110", @"11010001110", ZX_STOP, ZX_QUIET_SPACE]; + + ZXBitMatrix *result = [self.writer encode:toEncode format:kBarcodeFormatCode128 width:0 height:0 error:nil]; + + NSString *actual = [self matrixToString:result]; + XCTAssertEqualObjects(actual, expected); +} + +- (void)testRoundtrip { + NSString *toEncode = [NSString stringWithFormat:@"%C10958%C17160526", (unichar)L'\u00f1', (unichar)L'\u00f1']; + NSString *expected = @"1095817160526"; + ZXBitMatrix *encResult = [self.writer encode:toEncode format:kBarcodeFormatCode128 width:0 height:0 error:nil]; + ZXBitArray *row = [encResult rowAtY:0 row:nil]; + ZXResult *decResult = [self.reader decodeRow:0 row:row hints:nil error:nil]; + NSString *actual = decResult.text; + XCTAssertEqualObjects(expected, actual); +} + - (NSString *)matrixToString:(ZXBitMatrix *)matrix { NSMutableString *builder = [NSMutableString stringWithCapacity:matrix.width]; for (int i = 0; i < matrix.width; i++) { diff --git a/ZXingObjCTests/oned/ZXCode39ExtendedModeTestCase.h b/ZXingObjCTests/oned/ZXCode39ExtendedModeTestCase.h new file mode 100644 index 000000000..da43d7a0e --- /dev/null +++ b/ZXingObjCTests/oned/ZXCode39ExtendedModeTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXCode39ExtendedModeTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/oned/ZXCode39ExtendedModeTestCase.m b/ZXingObjCTests/oned/ZXCode39ExtendedModeTestCase.m new file mode 100644 index 000000000..cbf4467e0 --- /dev/null +++ b/ZXingObjCTests/oned/ZXCode39ExtendedModeTestCase.m @@ -0,0 +1,37 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXCode39ExtendedModeTestCase.h" +#import "ZXCode39Reader.h" + +@implementation ZXCode39ExtendedModeTestCase + +- (void)testDecodeExtendedMode { + [self doTestExpectedResult:[NSString stringWithFormat:@"%C%C%C%C%C%C%C%C\b\t\n%C\f\r%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C", 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x000b, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f] encodedResult:@"000001001011011010101001001001011001010101101001001001010110101001011010010010010101011010010110100100100101011011010010101001001001010101011001011010010010010101101011001010100100100101010110110010101001001001010101010011011010010010010101101010011010100100100101010110100110101001001001010101011001101010010010010101101010100110100100100101010110101001101001001001010110110101001010010010010101010110100110100100100101011010110100101001001001010101101101001010010010010101010101100110100100100101011010101100101001001001010101101011001010010010010101010110110010100100100101011001010101101001001001010100110101011010010010010101100110101010100100100101010010110101101001001001010110010110101010010010010101001101101010101001001001011010100101101010010010010101101001011010100100100101101101001010101001001001010101100101101010010010010110101100101010010110110100000"]; + [self doTestExpectedResult:@" !\"#$%&'()*+,-./0123456789:;<=>?" encodedResult:@"00000100101101101010011010110101001001010010110101001011010010010100101011010010110100100101001011011010010101001001010010101011001011010010010100101101011001010100100101001010110110010101001001010010101010011011010010010100101101010011010100100101001010110100110101001001010010101011001101010010010100101101010100110100100101001010110101001101001010110110110010101101010010010100101101011010010101001101101011010010101101011001010110110110010101010100110101101101001101010101100110101010100101101101101001011010101100101101010010010100101001101101010101001001001010110110010101010010010010101010011011010100100100101101010011010101001001001010110100110101010010010010101011001101010010110110100000"]; + [self doTestExpectedResult:@"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" encodedResult:@"000010010110110101010010010010100110101011011010100101101011010010110110110100101010101100101101101011001010101101100101010101001101101101010011010101101001101010101100110101101010100110101101010011011011010100101010110100110110101101001010110110100101010101100110110101011001010110101100101010110110010110010101011010011010101101100110101010100101101011011001011010101001101101010101001001001011010101001101010010010010101101010011010100100100101101101010010101001001001010101101001101010010010010110101101001010010110110100000"]; + [self doTestExpectedResult:@"`abcdefghijklmnopqrstuvwxyz{|}~" encodedResult:@"000001001011011010101001001001011001101010101001010010010110101001011010010100100101011010010110100101001001011011010010101001010010010101011001011010010100100101101011001010100101001001010110110010101001010010010101010011011010010100100101101010011010100101001001010110100110101001010010010101011001101010010100100101101010100110100101001001010110101001101001010010010110110101001010010100100101010110100110100101001001011010110100101001010010010101101101001010010100100101010101100110100101001001011010101100101001010010010101101011001010010100100101010110110010100101001001011001010101101001010010010100110101011010010100100101100110101010100101001001010010110101101001010010010110010110101010010100100101001101101010101001001001010110110100101010010010010101010110011010100100100101101010110010101001001001010110101100101010010010010101011011001010010110110100000"]; +} + +- (void)doTestExpectedResult:(NSString *)expectedResult encodedResult:(NSString *)encodedResult { + ZXCode39Reader *reader = [[ZXCode39Reader alloc] initUsingCheckDigit:NO extendedMode:YES]; + ZXBitMatrix *matrix = [ZXBitMatrix parse:encodedResult setString:@"1" unsetString:@"0"]; + ZXBitArray *row = [matrix rowAtY:0 row:nil]; + ZXResult *result = [reader decodeRow:0 row:row hints:nil error:nil]; + XCTAssertEqualObjects(expectedResult, result.text); +} + +@end diff --git a/ZXingObjCTests/oned/ZXCode39WriterTestCase.h b/ZXingObjCTests/oned/ZXCode39WriterTestCase.h new file mode 100644 index 000000000..c6e50b360 --- /dev/null +++ b/ZXingObjCTests/oned/ZXCode39WriterTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXCode39WriterTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/oned/ZXCode39WriterTestCase.m b/ZXingObjCTests/oned/ZXCode39WriterTestCase.m new file mode 100644 index 000000000..56f48566b --- /dev/null +++ b/ZXingObjCTests/oned/ZXCode39WriterTestCase.m @@ -0,0 +1,47 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXCode39WriterTestCase.h" +#import "ZXCode39Writer.h" + +@implementation ZXCode39WriterTestCase + +- (void)testEncode { + NSString *testStr = @"000001001011011010110101001011010110100101101101101001010101011001011011010110010101" + "011011001010101010011011011010100110101011010011010101011001101011010101001101011010" + "100110110110101001010101101001101101011010010101101101001010101011001101101010110010" + "101101011001010101101100101100101010110100110101011011001101010101001011010110110010" + "110101010011011010101010011011010110100101011010110010101101101100101010101001101011" + "01101001101010101100110101010100101101101101001011010101100101101010010110110100000\n"; + [self doTest:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" expected:testStr]; + + // extended mode blocks + [self doTest:[NSString stringWithFormat:@"%C%C%C%C%C%C%C%C\b\t\n%C\f\r%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C", 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x000b, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f] expected:@"000001001011011010101001001001011001010101101001001001010110101001011010010010010101011010010110100100100101011011010010101001001001010101011001011010010010010101101011001010100100100101010110110010101001001001010101010011011010010010010101101010011010100100100101010110100110101001001001010101011001101010010010010101101010100110100100100101010110101001101001001001010110110101001010010010010101010110100110100100100101011010110100101001001001010101101101001010010010010101010101100110100100100101011010101100101001001001010101101011001010010010010101010110110010100100100101011001010101101001001001010100110101011010010010010101100110101010100100100101010010110101101001001001010110010110101010010010010101001101101010101001001001011010100101101010010010010101101001011010100100100101101101001010101001001001010101100101101010010010010110101100101010010110110100000\n"]; + [self doTest:@" !\"#$%&'()*+,-./0123456789:;<=>?" expected:@"00000100101101101010011010110101001001010010110101001011010010010100101011010010110100100101001011011010010101001001010010101011001011010010010100101101011001010100100101001010110110010101001001010010101010011011010010010100101101010011010100100101001010110100110101001001010010101011001101010010010100101101010100110100100101001010110101001101001010110110110010101101010010010100101101011010010101001101101011010010101101011001010110110110010101010100110101101101001101010101100110101010100101101101101001011010101100101101010010010100101001101101010101001001001010110110010101010010010010101010011011010100100100101101010011010101001001001010110100110101010010010010101011001101010010110110100000\n"]; + [self doTest:@"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" expected:@"0000010010110110101010010010010100110101011011010100101101011010010110110110100101010101100101101101011001010101101100101010101001101101101010011010101101001101010101100110101101010100110101101010011011011010100101010110100110110101101001010110110100101010101100110110101011001010110101100101010110110010110010101011010011010101101100110101010100101101011011001011010101001101101010101001001001011010101001101010010010010101101010011010100100100101101101010010101001001001010101101001101010010010010110101101001010010110110100000\n"]; + [self doTest:@"`abcdefghijklmnopqrstuvwxyz{|}~" expected:@"000001001011011010101001001001011001101010101001010010010110101001011010010100100101011010010110100101001001011011010010101001010010010101011001011010010100100101101011001010100101001001010110110010101001010010010101010011011010010100100101101010011010100101001001010110100110101001010010010101011001101010010100100101101010100110100101001001010110101001101001010010010110110101001010010100100101010110100110100101001001011010110100101001010010010101101101001010010100100101010101100110100101001001011010101100101001010010010101101011001010010100100101010110110010100101001001011001010101101001010010010100110101011010010100100101100110101010100101001001010010110101101001010010010110010110101010010100100101001101101010101001001001010110110100101010010010010101010110011010100100100101101010110010101001001001010110101100101010010010010101011011001010010110110100000\n"]; +} + +- (void)doTest:(NSString *)input expected:(NSString *)expected { + ZXBitMatrix *matrix = [[[ZXCode39Writer alloc] init] encode:input + format:kBarcodeFormatCode39 + width:0 + height:0 + error:nil]; + XCTAssertEqualObjects(expected, [matrix descriptionWithSetString:@"1" unsetString:@"0"]); +} + +@end diff --git a/ZXingObjCTests/oned/ZXCode93ReaderTestCase.h b/ZXingObjCTests/oned/ZXCode93ReaderTestCase.h new file mode 100644 index 000000000..22c19415f --- /dev/null +++ b/ZXingObjCTests/oned/ZXCode93ReaderTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXCode93ReaderTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/oned/ZXCode93ReaderTestCase.m b/ZXingObjCTests/oned/ZXCode93ReaderTestCase.m new file mode 100644 index 000000000..c7d4d9e67 --- /dev/null +++ b/ZXingObjCTests/oned/ZXCode93ReaderTestCase.m @@ -0,0 +1,34 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXCode93ReaderTestCase.h" +#import "ZXCode93Reader.h" + +@implementation ZXCode93ReaderTestCase + +- (void)testEncode { + NSString *expectedResult = [NSString stringWithFormat:@"Code93!\n$%%/+ :%C;[{%C%C@`%C%C%C", 0x001b, 0x007f, 0x0000, 0x007f, 0x007f, 0x007f]; + NSString *encodedResult = @"0000001010111101101000101001100101001011001001100101100101001001100101100100101000010101010000101110101101101010001001001101001101001110010101101011101011011101011101101110100101110101101001110101110110101101010001110110101100010101110110101000110101110110101000101101110110101101001101110110101100101101110110101100110101110110101011011001110110101011001101110110101001101101110110101001110101001100101101010001010111101111"; + + ZXCode93Reader *reader = [[ZXCode93Reader alloc] init]; + ZXBitMatrix *matrix = [ZXBitMatrix parse:encodedResult setString:@"1" unsetString:@"0"]; + ZXBitArray *row = [[ZXBitArray alloc] initWithSize:matrix.width]; + [matrix rowAtY:0 row:row]; + ZXResult *result = [reader decodeRow:0 row:row hints:nil error:nil]; + XCTAssertEqualObjects(expectedResult, [result text]); +} + +@end diff --git a/ZXingObjCTests/oned/ZXCode93WriterTestCase.h b/ZXingObjCTests/oned/ZXCode93WriterTestCase.h new file mode 100644 index 000000000..13673aa9a --- /dev/null +++ b/ZXingObjCTests/oned/ZXCode93WriterTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXCode93WriterTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/oned/ZXCode93WriterTestCase.m b/ZXingObjCTests/oned/ZXCode93WriterTestCase.m new file mode 100644 index 000000000..f0dce5444 --- /dev/null +++ b/ZXingObjCTests/oned/ZXCode93WriterTestCase.m @@ -0,0 +1,56 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXCode93WriterTestCase.h" +#import "ZXCode93Writer.h" + +@implementation ZXCode93WriterTestCase + +- (void)testEncode { + [self doTest:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + expected:@"000001010111101101010001101001001101000101100101001100100101100010101011010001011001" + "001011000101001101001000110101010110001010011001010001101001011001000101101101101001" + "101100101101011001101001101100101101100110101011011001011001101001101101001110101000" + "101001010010001010001001010000101001010001001001001001000101010100001000100101000010" + "10100111010101000010101011110100000\n"]; + + [self doTest:[NSString stringWithFormat:@"%C%C%C%C%C $%%+!,09:;@AZ[_`az{%C", 0x0000, 0x0001, 0x001a, 0x001b, 0x001f, 0x007f] + expected:@"00000" @"101011110" + @"111011010" @"110010110" @"100100110" @"110101000" @ // bU aA + "100100110" @"100111010" @"111011010" @"110101000" @ // aZ bA + "111011010" @"110010010" @"111010010" @"111001010" @ // bE space $ + "110101110" @"101110110" @"111010110" @"110101000" @ // % + cA + "111010110" @"101011000" @"100010100" @"100001010" @ // cL 0 9 + "111010110" @"100111010" @"111011010" @"110001010" @ // cZ bF + "111011010" @"110011010" @"110101000" @"100111010" @ // bV A Z + "111011010" @"100011010" @"111011010" @"100101100" @ // bK bO + "111011010" @"101101100" @"100110010" @"110101000" @ // bW dA + "100110010" @"100111010" @"111011010" @"100010110" @ // dZ bP + "111011010" @"110100110" @ // bT + "110100010" @"110101100" @ // checksum: 12 28 + "101011110" @"100000\n"]; +} + +- (void)doTest:(NSString *)input expected:(NSString *)expected { + ZXBitMatrix *matrix = [[[ZXCode93Writer alloc] init] encode:input + format:kBarcodeFormatCode93 + width:0 + height:0 + error:nil]; + XCTAssertEqualObjects(expected, [matrix descriptionWithSetString:@"1" unsetString:@"0"]); +} + +@end diff --git a/ZXingObjCTests/oned/ZXEAN13WriterTestCase.m b/ZXingObjCTests/oned/ZXEAN13WriterTestCase.m index 804583c24..eeb3f8713 100644 --- a/ZXingObjCTests/oned/ZXEAN13WriterTestCase.m +++ b/ZXingObjCTests/oned/ZXEAN13WriterTestCase.m @@ -19,7 +19,7 @@ @implementation ZXEAN13WriterTestCase - (void)testEncode { - NSString *testStr = @"00010100010110100111011001100100110111101001110101010110011011011001000010101110010011101000100101000"; + NSString *testStr = @"00001010001011010011101100110010011011110100111010101011001101101100100001010111001001110100010010100000"; ZXBitMatrix *result = [[[ZXEAN13Writer alloc] init] encode:@"5901234123457" format:kBarcodeFormatEan13 width:(int)testStr.length @@ -30,4 +30,24 @@ - (void)testEncode { } } +- (void)testAddChecksumAndEncode { + NSString *testStr = @"00001010001011010011101100110010011011110100111010101011001101101100100001010111001001110100010010100000"; + ZXBitMatrix *result = [[[ZXEAN13Writer alloc] init] encode:@"590123412345" + format:kBarcodeFormatEan13 + width:(int)testStr.length + height:0 + error:nil]; + for (int i = 0; i < testStr.length; i++) { + XCTAssertEqual([result getX:i y:0], [testStr characterAtIndex:i] == '1', @"Element %d", i); + } +} + +- (void)testEncodeIllegalCharacters { + XCTAssertThrows([[[ZXEAN13Writer alloc] init] encode:@"5901234123abc" + format:kBarcodeFormatEan13 + width:0 + height:0 + error:nil]); +} + @end diff --git a/ZXingObjCTests/oned/ZXEAN8WriterTestCase.m b/ZXingObjCTests/oned/ZXEAN8WriterTestCase.m index 30023fc28..1cd359dad 100644 --- a/ZXingObjCTests/oned/ZXEAN8WriterTestCase.m +++ b/ZXingObjCTests/oned/ZXEAN8WriterTestCase.m @@ -19,7 +19,7 @@ @implementation ZXEAN8WriterTestCase - (void)testEncode { - NSString *testStr = @"0001010001011010111101111010110111010101001110111001010001001011100101000"; + NSString *testStr = @"0000001010001011010111101111010110111010101001110111001010001001011100101000000"; ZXBitMatrix *result = [[[ZXEAN8Writer alloc] init] encode:@"96385074" format:kBarcodeFormatEan8 width:(int)testStr.length @@ -30,4 +30,24 @@ - (void)testEncode { } } +- (void)testAddChecksumAndEncode { + NSString *testStr = @"0000001010001011010111101111010110111010101001110111001010001001011100101000000"; + ZXBitMatrix *result = [[[ZXEAN8Writer alloc] init] encode:@"9638507" + format:kBarcodeFormatEan8 + width:(int)testStr.length + height:0 + error:nil]; + for (int i = 0; i < testStr.length; i++) { + XCTAssertEqual([testStr characterAtIndex:i] == '1', [result getX:i y:0], @"Element %d", i); + } +} + +- (void)testEncodeIllegalCharacters { + XCTAssertThrows([[[ZXEAN8Writer alloc] init] encode:@"96385abc" + format:kBarcodeFormatEan8 + width:0 + height:0 + error:nil]); +} + @end diff --git a/ZXingObjCTests/oned/ZXITFBlackBox1TestCase.m b/ZXingObjCTests/oned/ZXITFBlackBox1TestCase.m index 3c5a795e4..3ba8df807 100644 --- a/ZXingObjCTests/oned/ZXITFBlackBox1TestCase.m +++ b/ZXingObjCTests/oned/ZXITFBlackBox1TestCase.m @@ -25,8 +25,8 @@ - (id)initWithInvocation:(NSInvocation *)invocation { expectedFormat:kBarcodeFormatITF]; if (self) { - [self addTest:9 tryHarderCount:13 rotation:0.0f]; - [self addTest:12 tryHarderCount:13 rotation:180.0f]; + [self addTest:14 tryHarderCount:14 rotation:0.0f]; + [self addTest:14 tryHarderCount:14 rotation:180.0f]; } return self; diff --git a/ZXingObjCTests/oned/ZXITFWriterTestCase.h b/ZXingObjCTests/oned/ZXITFWriterTestCase.h new file mode 100644 index 000000000..da3232782 --- /dev/null +++ b/ZXingObjCTests/oned/ZXITFWriterTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXITFWriterTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/oned/ZXITFWriterTestCase.m b/ZXingObjCTests/oned/ZXITFWriterTestCase.m new file mode 100644 index 000000000..518fcc3d4 --- /dev/null +++ b/ZXingObjCTests/oned/ZXITFWriterTestCase.m @@ -0,0 +1,43 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXITFWriterTestCase.h" + +@implementation ZXITFWriterTestCase + +- (void)testEncode { + NSString *testStr = @"0000010101010111000111000101110100010101110001110111010001010001110100011" + "100010101000101011100011101011101000111000101110100010101110001110100000"; + ZXBitMatrix *result = [[[ZXITFWriter alloc] init] encode:@"00123456789012" + format:kBarcodeFormatITF + width:0 + height:0 + error:nil]; + for (int i = 0; i < testStr.length; i++) { + XCTAssertEqual([result getX:i y:0], [testStr characterAtIndex:i] == '1', @"Element %d", i); + } +} + +- (void)testEncodeIllegalCharacters { + XCTAssertThrows([[[ZXITFWriter alloc] init] encode:@"00123456789abc" + format:kBarcodeFormatITF + width:0 + height:0 + error:nil]); +} + +@end + diff --git a/ZXingObjCTests/oned/ZXUPCAWriterTestCase.m b/ZXingObjCTests/oned/ZXUPCAWriterTestCase.m index 697c5a62d..3b750bcd6 100644 --- a/ZXingObjCTests/oned/ZXUPCAWriterTestCase.m +++ b/ZXingObjCTests/oned/ZXUPCAWriterTestCase.m @@ -19,7 +19,7 @@ @implementation ZXUPCAWriterTestCase - (void)testEncode { - NSString *testStr = @"00010101000110110111011000100010110101111011110101010111001011101001001110110011011011001011100101000"; + NSString *testStr = @"00001010100011011011101100010001011010111101111010101011100101110100100111011001101101100101110010100000"; ZXBitMatrix *result = [[[ZXUPCAWriter alloc] init] encode:@"485963095124" format:kBarcodeFormatUPCA width:(int)testStr.length @@ -31,7 +31,7 @@ - (void)testEncode { } - (void)testAddChecksumAndEncode { - NSString *testStr = @"00010100110010010011011110101000110110001010111101010100010010010001110100111001011001101101100101000"; + NSString *testStr = @"00001010011001001001101111010100011011000101011110101010001001001000111010011100101100110110110010100000"; ZXBitMatrix *result = [[[ZXUPCAWriter alloc] init] encode:@"12345678901" format:kBarcodeFormatUPCA width:(int)testStr.length diff --git a/ZXingObjCTests/oned/ZXUPCEWriterTestCase.h b/ZXingObjCTests/oned/ZXUPCEWriterTestCase.h new file mode 100644 index 000000000..8bbab44ed --- /dev/null +++ b/ZXingObjCTests/oned/ZXUPCEWriterTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXUPCEWriterTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/oned/ZXUPCEWriterTestCase.m b/ZXingObjCTests/oned/ZXUPCEWriterTestCase.m new file mode 100644 index 000000000..89bedd512 --- /dev/null +++ b/ZXingObjCTests/oned/ZXUPCEWriterTestCase.m @@ -0,0 +1,65 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXUPCEWriterTestCase.h" + +@implementation ZXUPCEWriterTestCase + +- (void)testEncode { + NSString *testStr = @"0000000000010101110010100111000101101011110110111001011101010100000000000"; + ZXBitMatrix *result = [[[ZXUPCEWriter alloc] init] encode:@"05096893" + format:kBarcodeFormatUPCE + width:(int)testStr.length + height:0 + error:nil]; + for (int i = 0; i < testStr.length; i++) { + XCTAssertEqual([result getX:i y:0], [testStr characterAtIndex:i] == '1', @"Element %d", i); + } +} + +- (void)testAddChecksumAndEncode { + NSString *testStr = @"0000000000010101110010100111000101101011110110111001011101010100000000000"; + ZXBitMatrix *result = [[[ZXUPCEWriter alloc] init] encode:@"0509689" + format:kBarcodeFormatUPCE + width:(int)testStr.length + height:0 + error:nil]; + for (int i = 0; i < testStr.length; i++) { + XCTAssertEqual([result getX:i y:0], [testStr characterAtIndex:i] == '1', @"Element %d", i); + } +} + +- (void)testAddChecksumAndEncodeWithChecksum { + NSString *testStr = @"0000000000010100111010001101001110101011110001101010011101010100000000000"; + ZXBitMatrix *result = [[[ZXUPCEWriter alloc] init] encode:@"04046008" + format:kBarcodeFormatUPCE + width:(int)testStr.length + height:0 + error:nil]; + for (int i = 0; i < testStr.length; i++) { + XCTAssertEqual([result getX:i y:0], [testStr characterAtIndex:i] == '1', @"Element %d", i); + } +} + +- (void)testEncodeIllegalCharacters { + XCTAssertThrows([[[ZXUPCEWriter alloc] init] encode:@"05096abc" + format:kBarcodeFormatUPCE + width:0 + height:0 + error:nil]); +} + +@end diff --git a/ZXingObjCTests/pdf417/ZXPDF417BlackBox1TestCase.m b/ZXingObjCTests/pdf417/ZXPDF417BlackBox1TestCase.m index e9aed3365..54e291ddd 100644 --- a/ZXingObjCTests/pdf417/ZXPDF417BlackBox1TestCase.m +++ b/ZXingObjCTests/pdf417/ZXPDF417BlackBox1TestCase.m @@ -25,8 +25,8 @@ - (id)initWithInvocation:(NSInvocation *)invocation { expectedFormat:kBarcodeFormatPDF417]; if (self) { - [self addTest:9 tryHarderCount:9 rotation:0.0f]; - [self addTest:9 tryHarderCount:9 rotation:180.0f]; + [self addTest:10 tryHarderCount:10 rotation:0.0f]; + [self addTest:10 tryHarderCount:10 rotation:180.0f]; } return self; diff --git a/ZXingObjCTests/pdf417/ZXPDF417BlackBox3TestCase.m b/ZXingObjCTests/pdf417/ZXPDF417BlackBox3TestCase.m index b99c23b45..b6f9c3b46 100644 --- a/ZXingObjCTests/pdf417/ZXPDF417BlackBox3TestCase.m +++ b/ZXingObjCTests/pdf417/ZXPDF417BlackBox3TestCase.m @@ -25,8 +25,8 @@ - (id)initWithInvocation:(NSInvocation *)invocation { expectedFormat:kBarcodeFormatPDF417]; if (self) { - [self addTest:18 tryHarderCount:18 rotation:0.0f]; - [self addTest:18 tryHarderCount:18 rotation:180.0f]; + [self addTest:19 tryHarderCount:19 rotation:0.0f]; + [self addTest:19 tryHarderCount:19 rotation:180.0f]; } return self; diff --git a/ZXingObjCTests/pdf417/ZXPDF417BlackBox4TestCase.m b/ZXingObjCTests/pdf417/ZXPDF417BlackBox4TestCase.m index b462ff2ef..6ea4e6e94 100644 --- a/ZXingObjCTests/pdf417/ZXPDF417BlackBox4TestCase.m +++ b/ZXingObjCTests/pdf417/ZXPDF417BlackBox4TestCase.m @@ -26,7 +26,7 @@ - (id)initWithInvocation:(NSInvocation *)invocation { expectedFormat:kBarcodeFormatPDF417]; if (self) { - [self.testResults addObject:[[ZXTestResult alloc] initWithMustPassCount:2 tryHarderCount:2 maxMisreads:0 maxTryHarderMisreads:0 rotation:0.0f]]; + [self.testResults addObject:[[ZXTestResult alloc] initWithMustPassCount:3 tryHarderCount:3 maxMisreads:0 maxTryHarderMisreads:0 rotation:0.0f]]; } return self; diff --git a/ZXingObjCTests/pdf417/ZXPDF417WriterTestCase.h b/ZXingObjCTests/pdf417/ZXPDF417WriterTestCase.h new file mode 100644 index 000000000..256ddff47 --- /dev/null +++ b/ZXingObjCTests/pdf417/ZXPDF417WriterTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXPDF417WriterTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/pdf417/ZXPDF417WriterTestCase.m b/ZXingObjCTests/pdf417/ZXPDF417WriterTestCase.m new file mode 100644 index 000000000..cfc105eae --- /dev/null +++ b/ZXingObjCTests/pdf417/ZXPDF417WriterTestCase.m @@ -0,0 +1,56 @@ +/* + * Copyright 2013 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXPDF417WriterTestCase.h" +#import "ZXPDF417Writer.h" + +@implementation ZXPDF417WriterTestCase + +- (void)testDataMatrixImageWriter { + ZXEncodeHints *hints = [ZXEncodeHints hints]; + hints.margin = [NSNumber numberWithInt:0]; + int size = 64; + ZXPDF417Writer *writer = [[ZXPDF417Writer alloc] init]; + ZXBitMatrix *matrix = [writer encode:@"Hello Google" format:kBarcodeFormatPDF417 width:size height:size hints:hints error:nil]; + XCTAssertNotNil(matrix); + NSString *expected = @"X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n" + "X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X \n"; + XCTAssertEqualObjects(expected, [matrix description]); +} + +@end diff --git a/ZXingObjCTests/pdf417/decoder/ZXPDF417DecoderTestCase.h b/ZXingObjCTests/pdf417/decoder/ZXPDF417DecoderTestCase.h new file mode 100644 index 000000000..c67a0be3a --- /dev/null +++ b/ZXingObjCTests/pdf417/decoder/ZXPDF417DecoderTestCase.h @@ -0,0 +1,19 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@interface ZXPDF417DecoderTestCase : XCTestCase + +@end diff --git a/ZXingObjCTests/pdf417/decoder/ZXPDF417DecoderTestCase.m b/ZXingObjCTests/pdf417/decoder/ZXPDF417DecoderTestCase.m new file mode 100644 index 000000000..a470c4a54 --- /dev/null +++ b/ZXingObjCTests/pdf417/decoder/ZXPDF417DecoderTestCase.m @@ -0,0 +1,98 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXPDF417DecoderTestCase.h" +#import "ZXPDF417DecodedBitStreamParser.h" +#import "ZXPDF417ResultMetadata.h" + +@implementation ZXPDF417DecoderTestCase + +// Tests the first sample given in ISO/IEC 15438:2015(E) - Annex H.4 +- (void)testStandardSample1 { + ZXPDF417ResultMetadata *resultMetadata = [[ZXPDF417ResultMetadata alloc] init]; + ZXIntArray *sampleCodes = [[ZXIntArray alloc] initWithInts: 20, 928, 111, 100, 17, 53, 923, 1, 111, 104, + 923, 3, 64, 416, 34, 923, 4, 258, 446, 67, + // we should never reach these + 1000, 1000, 1000, -1]; + [ZXPDF417DecodedBitStreamParser decodeMacroBlock:sampleCodes codeIndex:2 resultMetadata:resultMetadata]; + + XCTAssertEqual(0, resultMetadata.segmentIndex); + XCTAssertEqualObjects(@"ARBX", resultMetadata.fileId); + XCTAssertFalse(resultMetadata.lastSegment); + XCTAssertEqual(4, resultMetadata.segmentCount); + XCTAssertEqualObjects(@"CEN BE", resultMetadata.sender); + XCTAssertEqualObjects(@"ISO CH", resultMetadata.addressee); + + NSArray *optionalData = resultMetadata.optionalData; + XCTAssertEqual(1, [optionalData[0] intValue], @"first element of optional array should be the first field identifier"); + XCTAssertEqual(67, [optionalData[optionalData.count - 1] intValue], @"last element of optional array should be the last codeword of the last field"); +} + +// Tests the second given in ISO/IEC 15438:2015(E) - Annex H.4 +- (void)testStandardSample2 { + ZXPDF417ResultMetadata *resultMetadata = [[ZXPDF417ResultMetadata alloc] init]; + ZXIntArray *sampleCodes = [[ZXIntArray alloc] initWithInts: 11, 928, 111, 103, 17, 53, 923, 1, 111, 104, 922, + // we should never reach these + 1000, 1000, 1000, -1]; + [ZXPDF417DecodedBitStreamParser decodeMacroBlock:sampleCodes codeIndex:2 resultMetadata:resultMetadata]; + + XCTAssertEqual(3, resultMetadata.segmentIndex); + XCTAssertEqualObjects(@"ARBX", resultMetadata.fileId); + XCTAssertTrue(resultMetadata.lastSegment); + XCTAssertEqual(4, resultMetadata.segmentCount); + XCTAssertNil(resultMetadata.sender); + XCTAssertNil(resultMetadata.addressee); + + NSArray *optionalData = resultMetadata.optionalData; + XCTAssertEqual(1, [optionalData[0] intValue], @"first element of optional array should be the first field identifier"); + XCTAssertEqual(104, [optionalData[optionalData.count - 1] intValue], @"last element of optional array should be the last codeword of the last field"); +} + +- (void)testSampleWithFilename { + ZXPDF417ResultMetadata *resultMetadata = [[ZXPDF417ResultMetadata alloc] init]; + ZXIntArray *sampleCodes = [[ZXIntArray alloc] initWithInts: 23, 477, 928, 111, 100, 0, 252, 21, 86, 923, + 0, 815, 251, 133, 12, 148, 537, 593, 599, 923, + 1, 111, 102, 98, 311, 355, 522, 920, 779, 40, + 628, 33, 749, 267, 506, 213, 928, 465, 248, 493, + 72, 780, 699, 780, 493, 755, 84, 198, 628, 368, + 156, 198, 809, 19, 113, -1]; + [ZXPDF417DecodedBitStreamParser decodeMacroBlock:sampleCodes codeIndex:3 resultMetadata:resultMetadata]; + + XCTAssertEqual(0, resultMetadata.segmentIndex); + XCTAssertEqualObjects(@"AAIMAVC ", resultMetadata.fileId); + XCTAssertFalse(resultMetadata.lastSegment); + XCTAssertEqual(2, resultMetadata.segmentCount); + XCTAssertNil(resultMetadata.sender); + XCTAssertNil(resultMetadata.addressee); + XCTAssertEqualObjects(@"filename.txt", resultMetadata.fileName); +} + +- (void)testSampleWithNumericValues { + ZXPDF417ResultMetadata *resultMetadata = [[ZXPDF417ResultMetadata alloc] init]; + ZXIntArray *sampleCodes = [[ZXIntArray alloc] initWithInts: 25, 477, 928, 111, 100, 0, 252, 21, 86, 923, + 2, 2, 0, 1, 0, 0, 0, 923, 5, 130, + 923, 6, 1, 500, 13, 0, -1]; + [ZXPDF417DecodedBitStreamParser decodeMacroBlock:sampleCodes codeIndex:3 resultMetadata:resultMetadata]; + + XCTAssertEqual(0, resultMetadata.segmentIndex); + XCTAssertEqualObjects(@"AAIMAVC ", resultMetadata.fileId); + XCTAssertFalse(resultMetadata.lastSegment); + XCTAssertEqual(180980729000000, resultMetadata.timestamp); + XCTAssertEqual(30, resultMetadata.fileSize); + XCTAssertEqual(260013, resultMetadata.checksum); +} + +@end diff --git a/ZXingObjCTests/pdf417/encoder/ZXPDF417EncoderTestCase.m b/ZXingObjCTests/pdf417/encoder/ZXPDF417EncoderTestCase.m index ad84209ec..3f3df3ca6 100644 --- a/ZXingObjCTests/pdf417/encoder/ZXPDF417EncoderTestCase.m +++ b/ZXingObjCTests/pdf417/encoder/ZXPDF417EncoderTestCase.m @@ -55,4 +55,18 @@ - (void)testEncodeByte { XCTAssertEqualObjects(expected, encoded); } +- (void)testEncodeAutoWithSpecialChars { + // just check if this does not throw an error + NSError *error; + [ZXPDF417HighLevelEncoder encodeHighLevel:@"1%§s ?aG$" compaction:ZXPDF417CompactionAuto encoding:NSUTF8StringEncoding error:&error]; + XCTAssertNil(error); +} + +- (void)testEncodeIso88591WithSpecialChars { + // just check if this does not throw an error + NSError *error; + [ZXPDF417HighLevelEncoder encodeHighLevel:@"asdfg§asd" compaction:ZXPDF417CompactionAuto encoding:NSISOLatin1StringEncoding error:&error]; + XCTAssertNil(error); +} + @end diff --git a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox2TestCase.m b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox2TestCase.m index 297240351..3ac63f585 100644 --- a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox2TestCase.m +++ b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox2TestCase.m @@ -25,10 +25,10 @@ - (id)initWithInvocation:(NSInvocation *)invocation { expectedFormat:kBarcodeFormatQRCode]; if (self) { - [self addTest:30 tryHarderCount:30 rotation:0.0f]; + [self addTest:31 tryHarderCount:31 rotation:0.0f]; [self addTest:29 tryHarderCount:29 rotation:90.0f]; [self addTest:30 tryHarderCount:30 rotation:180.0f]; - [self addTest:29 tryHarderCount:29 rotation:270.0f]; + [self addTest:30 tryHarderCount:30 rotation:270.0f]; } return self; diff --git a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox3TestCase.m b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox3TestCase.m index 39f1e3128..910b7fa55 100644 --- a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox3TestCase.m +++ b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox3TestCase.m @@ -26,7 +26,7 @@ - (id)initWithInvocation:(NSInvocation *)invocation { if (self) { [self addTest:38 tryHarderCount:38 rotation:0.0f]; - [self addTest:38 tryHarderCount:38 rotation:90.0f]; + [self addTest:39 tryHarderCount:39 rotation:90.0f]; [self addTest:36 tryHarderCount:36 rotation:180.0f]; [self addTest:39 tryHarderCount:39 rotation:270.0f]; } diff --git a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox5TestCase.m b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox5TestCase.m index c08dc7b3a..a6525eff4 100644 --- a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox5TestCase.m +++ b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox5TestCase.m @@ -28,7 +28,7 @@ - (id)initWithInvocation:(NSInvocation *)invocation { [self addTest:19 tryHarderCount:19 rotation:0.0f]; [self addTest:19 tryHarderCount:19 rotation:90.0f]; [self addTest:19 tryHarderCount:19 rotation:180.0f]; - [self addTest:18 tryHarderCount:18 rotation:270.0f]; + [self addTest:19 tryHarderCount:19 rotation:270.0f]; } return self; diff --git a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox6TestCase.m b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox6TestCase.m index 641746ccf..9d0c585b3 100644 --- a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox6TestCase.m +++ b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox6TestCase.m @@ -31,7 +31,7 @@ - (id)initWithInvocation:(NSInvocation *)invocation { if (self) { [self addTest:15 tryHarderCount:15 rotation:0.0f]; [self addTest:14 tryHarderCount:14 rotation:90.0f]; - [self addTest:12 tryHarderCount:13 rotation:180.0f]; + [self addTest:13 tryHarderCount:13 rotation:180.0f]; [self addTest:14 tryHarderCount:14 rotation:270.0f]; } @@ -42,4 +42,12 @@ - (void)testBlackBox { [super runTests]; } +- (void)testBlackBox2 { + ZXCGImageLuminanceSourceInfo *info = [[ZXCGImageLuminanceSourceInfo alloc] initWithShades:16]; + [self setLuminanceSourceInfo:info]; + [self setShouldTruncateNewline:TRUE]; + + [super runTests]; +} + @end diff --git a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox7TestCase.h b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox7TestCase.h new file mode 100644 index 000000000..42762046b --- /dev/null +++ b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox7TestCase.h @@ -0,0 +1,21 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXAbstractBlackBoxTestCase.h" + +@interface ZXQRCodeBlackBox7TestCase : ZXAbstractBlackBoxTestCase + +@end diff --git a/ZXingObjCTests/qrcode/ZXQRCodeBlackBox7TestCase.m b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox7TestCase.m new file mode 100644 index 000000000..5773b0137 --- /dev/null +++ b/ZXingObjCTests/qrcode/ZXQRCodeBlackBox7TestCase.m @@ -0,0 +1,46 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ZXQRCodeBlackBox7TestCase.h" +#import + +@implementation ZXQRCodeBlackBox7TestCase + +- (id)initWithInvocation:(NSInvocation *)invocation { + self = [super initWithInvocation:invocation + testBasePathSuffix:@"Resources/blackbox/qrcode-7" + barcodeReader:[[ZXMultiFormatReader alloc] init] + expectedFormat:kBarcodeFormatQRCode]; + + if (self) { + [self addTest:1 tryHarderCount:1 rotation:0.0f]; + [self addTest:1 tryHarderCount:1 rotation:90.0f]; + [self addTest:1 tryHarderCount:1 rotation:180.0f]; + [self addTest:1 tryHarderCount:1 rotation:270.0f]; + } + + return self; +} + +- (void)testBlackBox { + ZXCGImageLuminanceSourceInfo *info = [[ZXCGImageLuminanceSourceInfo alloc] initWithDecomposingMin]; + [self setLuminanceSourceInfo:info]; + [self setShouldTruncateNewline:YES]; + + [super runTests]; +} + +@end diff --git a/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.m b/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.m index a70073e10..32e988e98 100644 --- a/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.m +++ b/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.m @@ -74,4 +74,17 @@ - (void)testHanzi { XCTAssertEqualObjects(@"\u963f", result); } +- (void)testHanziLevel1 { + ZXBitSourceBuilder *builder = [[ZXBitSourceBuilder alloc] init]; + [builder write:0x0D numBits:4]; // Hanzi mode + [builder write:0x01 numBits:4]; // Subset 1 = GB2312 encoding + [builder write:0x01 numBits:8]; // 1 characters + // A5A2 (U+30A2) => A5A2 - A1A1 = 401, 4*60 + 01 = 0181 + [builder write:0x0181 numBits:13]; + NSString *result = [[ZXQRCodeDecodedBitStreamParser decode:[builder toByteArray] + version:[ZXQRCodeVersion versionForNumber:1] + ecLevel:nil hints:nil error:nil] text]; + XCTAssertEqualObjects(@"\u30a2", result); +} + @end diff --git a/ZXingObjCTests/qrcode/encoder/ZXQRCodeEncoderTestCase.m b/ZXingObjCTests/qrcode/encoder/ZXQRCodeEncoderTestCase.m index d88bec9be..b082f680e 100644 --- a/ZXingObjCTests/qrcode/encoder/ZXQRCodeEncoderTestCase.m +++ b/ZXingObjCTests/qrcode/encoder/ZXQRCodeEncoderTestCase.m @@ -116,6 +116,93 @@ - (void)testEncode { XCTAssertEqualObjects(expected, [qrCode description]); } +- (void)testEncodeKanjiMode { + ZXEncodeHints *hints = [ZXEncodeHints hints]; + hints.encoding = NSShiftJISStringEncoding; + // Nihon in Kanji + ZXQRCode *qrCode = [ZXQRCodeEncoder encode:@"\u65e5\u672c" ecLevel:[ZXQRCodeErrorCorrectionLevel errorCorrectionLevelM] hints:hints error:nil]; + NSString *expected = + @"<<\n" + " mode: KANJI\n" + " ecLevel: M\n" + " version: 1\n" + " maskPattern: 0\n" + " matrix:\n" + " 1 1 1 1 1 1 1 0 0 1 0 1 0 0 1 1 1 1 1 1 1\n" + " 1 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0 0 1\n" + " 1 0 1 1 1 0 1 0 0 1 1 1 1 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 0 0 0 0 1 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 1 1 1 1 1 0 1 0 1 1 1 0 1\n" + " 1 0 0 0 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 0 1\n" + " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + " 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0\n" + " 1 0 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 1 0\n" + " 1 1 0 1 0 0 0 1 0 1 1 1 0 1 0 1 0 1 0 0 0\n" + " 0 1 0 0 0 0 1 1 1 1 1 1 0 1 1 1 0 1 0 1 0\n" + " 1 1 1 0 0 1 0 1 0 0 0 1 1 1 0 1 1 0 1 0 0\n" + " 0 1 1 0 0 1 1 0 1 1 0 1 0 1 1 1 0 1 0 0 1\n" + " 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 1\n" + " 1 1 1 1 1 1 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1\n" + " 1 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 1 1\n" + " 1 0 1 1 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1\n" + " 1 0 1 1 1 0 1 0 0 0 0 1 0 1 0 1 0 1 0 1 0\n" + " 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 1 0 0 1 0 1\n" + " 1 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1 1 1 0 1 0\n" + " 1 1 1 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 0 0\n" + ">>\n"; + XCTAssertEqualObjects(expected, [qrCode description]); +} + +- (void)testEncodeShiftjisNumeric { + ZXEncodeHints *hints = [ZXEncodeHints hints]; + hints.encoding = NSShiftJISStringEncoding; + ZXQRCode *qrCode = [ZXQRCodeEncoder encode:@"0123" ecLevel:[ZXQRCodeErrorCorrectionLevel errorCorrectionLevelM] hints:hints error:nil]; + NSString *expected = + @"<<\n" + " mode: NUMERIC\n" + " ecLevel: M\n" + " version: 1\n" + " maskPattern: 2\n" + " matrix:\n" + " 1 1 1 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1 1 1\n" + " 1 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 1\n" + " 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 1 1 0 1 1 0 1 0 1 1 1 0 1\n" + " 1 0 0 0 0 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0 1\n" + " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + " 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0\n" + " 1 0 1 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1 0 0\n" + " 1 1 0 0 0 1 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0\n" + " 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 1 0 1 1\n" + " 1 0 1 1 0 1 0 1 0 0 1 0 0 0 0 1 1 0 1 0 0\n" + " 0 0 1 0 0 1 1 1 0 0 0 1 0 1 0 0 1 0 1 0 0\n" + " 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 0 0 1 0 0 0\n" + " 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1 1 0 0 0 0 0\n" + " 1 0 0 0 0 0 1 0 1 1 0 1 1 1 1 0 0 1 0 1 0\n" + " 1 0 1 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 1 0 0\n" + " 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 1 0 0 1 0 0\n" + " 1 0 1 1 1 0 1 0 1 1 0 1 0 1 0 0 1 1 1 0 0\n" + " 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 0 1 1 0\n" + " 1 1 1 1 1 1 1 0 1 1 0 1 0 1 0 0 1 1 1 0 0\n" + ">>\n"; + XCTAssertEqualObjects(expected, [qrCode description]); +} + +- (void)testEncodeWithVersion { + ZXEncodeHints *hints = [ZXEncodeHints hints]; + hints.qrVersion = @7; + ZXQRCode *qrCode = [ZXQRCodeEncoder encode:@"ABCDEF" ecLevel:[ZXQRCodeErrorCorrectionLevel errorCorrectionLevelH] hints:hints error:nil]; + XCTAssertTrue([qrCode.description containsString:@" version: 7\n"]); +} + +- (void)testEncodeWithVersionTooSmall { + ZXEncodeHints *hints = [ZXEncodeHints hints]; + hints.qrVersion = @3; + ZXQRCode *qrCode = [ZXQRCodeEncoder encode:@"THISMESSAGEISTOOLONGFORAQRCODEVERSION3" ecLevel:[ZXQRCodeErrorCorrectionLevel errorCorrectionLevelH] hints:hints error:nil]; + XCTAssertNil(qrCode); +} + - (void)testSimpleUTF8ECI { ZXEncodeHints *hints = [ZXEncodeHints hints]; hints.encoding = NSUTF8StringEncoding; @@ -152,6 +239,120 @@ - (void)testSimpleUTF8ECI { XCTAssertEqualObjects(expected, [qrCode description]); } +- (void)testGS1ModeHeaderWithECI { + ZXEncodeHints *hints = [ZXEncodeHints hints]; + hints.encoding = NSUTF8StringEncoding; + hints.gs1Format = YES; + ZXQRCode *qrCode = [ZXQRCodeEncoder encode:@"hello" ecLevel:[ZXQRCodeErrorCorrectionLevel errorCorrectionLevelH] hints:hints error:nil]; + NSString *expected = + @"<<\n" + " mode: BYTE\n" + " ecLevel: H\n" + " version: 1\n" + " maskPattern: 5\n" + " matrix:\n" + " 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 1 1 1 1 1 1\n" + " 1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 0 0 1\n" + " 1 0 1 1 1 0 1 0 1 1 1 0 0 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 1 0 1 0 0 0 1 0 1 1 1 0 1\n" + " 1 0 0 0 0 0 1 0 0 1 1 1 1 0 1 0 0 0 0 0 1\n" + " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + " 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0\n" + " 0 0 0 0 0 1 1 0 0 1 1 0 0 0 1 0 1 0 1 0 1\n" + " 0 1 0 1 1 0 0 1 0 1 1 1 1 1 1 0 1 1 1 0 1\n" + " 0 1 0 1 1 1 1 0 1 1 0 0 0 1 0 1 0 1 1 0 0\n" + " 1 1 1 1 0 1 0 1 0 0 1 0 1 0 0 1 1 1 1 0 0\n" + " 1 0 0 1 0 0 1 1 0 1 1 0 1 0 1 0 0 1 0 0 1\n" + " 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 0 1 0 0 1 0\n" + " 1 1 1 1 1 1 1 0 0 0 1 1 0 0 1 0 0 0 1 1 0\n" + " 1 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0 1 1 1 0 0\n" + " 1 0 1 1 1 0 1 0 0 1 0 0 1 0 1 0 1 0 0 0 1\n" + " 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1 0 1 1 1 1 0\n" + " 1 0 1 1 1 0 1 0 0 0 1 0 0 1 0 0 1 0 1 1 1\n" + " 1 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 0 1 1 1 1\n" + " 1 1 1 1 1 1 1 0 0 1 1 1 0 1 1 0 1 0 0 1 0\n" + ">>\n"; + XCTAssertEqualObjects(expected, [qrCode description]); +} + +- (void)testEncodeGS1 { + ZXEncodeHints *hints = [ZXEncodeHints hints]; + hints.encoding = NSUTF8StringEncoding; + hints.gs1Format = YES; + ZXQRCode *qrCode = [ZXQRCodeEncoder encode:@"100001%11171218" ecLevel:[ZXQRCodeErrorCorrectionLevel errorCorrectionLevelH] hints:hints error:nil]; + NSString *expected = + @"<<\n" + " mode: ALPHANUMERIC\n" + " ecLevel: H\n" + " version: 2\n" + " maskPattern: 4\n" + " matrix:\n" + " 1 1 1 1 1 1 1 0 0 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + " 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1\n" + " 1 0 1 1 1 0 1 0 0 0 0 0 1 1 1 0 1 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 1 0 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 0 0 1 1 1 0 0 0 1 0 1 0 1 1 1 0 1\n" + " 1 0 0 0 0 0 1 0 1 1 0 1 1 0 1 1 0 0 1 0 0 0 0 0 1\n" + " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + " 0 0 0 0 0 0 0 0 1 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0\n" + " 0 0 0 0 1 1 1 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 0 1 0\n" + " 0 1 1 0 1 1 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1\n" + " 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0\n" + " 1 0 1 1 1 0 0 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 0 0\n" + " 0 1 0 1 0 0 1 1 1 1 1 1 0 0 1 1 0 1 0 0 0 0 0 1 0\n" + " 1 0 0 1 1 1 0 0 1 1 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0\n" + " 0 0 1 0 0 1 1 1 0 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 0\n" + " 0 0 0 1 1 0 0 1 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 1 0\n" + " 1 1 0 1 0 1 1 0 1 0 1 0 0 0 1 1 1 1 1 1 1 0 0 0 0\n" + " 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 1 0 0 0 1 1 0 1 0\n" + " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0\n" + " 1 0 0 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1 0 1 1 0\n" + " 1 0 1 1 1 0 1 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 0 0 1\n" + " 1 0 1 1 1 0 1 0 0 0 0 0 0 1 1 1 0 0 1 1 0 1 0 0 0\n" + " 1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 1 1 1 0 1 1 0 0 1 0\n" + " 1 0 0 0 0 0 1 0 0 1 1 0 1 1 1 1 1 0 1 0 1 1 0 0 0\n" + " 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 1 1 0 0 1 1 0 0 1 1\n" + ">>\n"; + XCTAssertEqualObjects(expected, [qrCode description]); +} + +- (void)testEncodeGS1WhenHintIsFalse { + ZXEncodeHints *hints = [ZXEncodeHints hints]; + hints.encoding = NSUTF8StringEncoding; + ZXQRCode *qrCode = [ZXQRCodeEncoder encode:@"ABCDEF" ecLevel:[ZXQRCodeErrorCorrectionLevel errorCorrectionLevelH] hints:hints error:nil]; + NSString *expected = + @"<<\n" + " mode: ALPHANUMERIC\n" + " ecLevel: H\n" + " version: 1\n" + " maskPattern: 4\n" + " matrix:\n" + " 1 1 1 1 1 1 1 0 0 1 0 1 0 0 1 1 1 1 1 1 1\n" + " 1 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 1\n" + " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 0 1 0 0 1 0 1 0 1 1 1 0 1\n" + " 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 0 1\n" + " 1 0 0 0 0 0 1 0 1 0 0 1 1 0 1 0 0 0 0 0 1\n" + " 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" + " 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0\n" + " 0 0 0 0 1 1 1 1 0 1 1 0 1 0 1 1 0 0 0 1 0\n" + " 0 0 0 0 1 1 0 1 1 1 0 0 1 1 1 1 0 1 1 0 1\n" + " 1 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 1 1 0 1 1\n" + " 1 0 0 1 1 1 0 0 1 1 1 1 0 0 0 0 1 0 0 0 0\n" + " 0 1 1 1 1 1 1 0 1 0 1 0 1 1 1 0 0 1 1 0 0\n" + " 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 1\n" + " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 0 0\n" + " 1 0 0 0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 1 1\n" + " 1 0 1 1 1 0 1 0 1 0 0 1 0 0 0 1 1 0 0 1 1\n" + " 1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 0 0 0 1 1 1\n" + " 1 0 1 1 1 0 1 0 0 1 0 1 0 0 0 1 1 0 0 0 0\n" + " 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 0 1\n" + " 1 1 1 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0 1 1 1\n" + ">>\n"; + XCTAssertEqualObjects(expected, [qrCode description]); +} + - (void)testAppendModeInfo { ZXBitArray *bits = [[ZXBitArray alloc] init]; [ZXQRCodeEncoder appendModeInfo:[ZXQRCodeMode numericMode] bits:bits]; diff --git a/examples/BarcodeScanner/AppDelegate.m b/examples/BarcodeScanner/AppDelegate.m index e17d53afd..498c7f127 100644 --- a/examples/BarcodeScanner/AppDelegate.m +++ b/examples/BarcodeScanner/AppDelegate.m @@ -20,9 +20,6 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - self.window.rootViewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; - [self.window makeKeyAndVisible]; return YES; } diff --git a/examples/BarcodeScanner/BarcodeScanner-Info.plist b/examples/BarcodeScanner/BarcodeScanner-Info.plist index 7f1244807..9022ce328 100644 --- a/examples/BarcodeScanner/BarcodeScanner-Info.plist +++ b/examples/BarcodeScanner/BarcodeScanner-Info.plist @@ -2,6 +2,10 @@ + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main CFBundleDevelopmentRegion en CFBundleDisplayName @@ -9,7 +13,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.zxing.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -24,6 +28,8 @@ 1.0 LSRequiresIPhoneOS + NSCameraUsageDescription + Barcode Scanner must have access to your camera to scan barcodes. UIRequiredDeviceCapabilities armv7 @@ -31,6 +37,9 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight diff --git a/examples/BarcodeScanner/BarcodeScanner.xcodeproj/project.pbxproj b/examples/BarcodeScanner/BarcodeScanner.xcodeproj/project.pbxproj index 072557f8c..83446540e 100644 --- a/examples/BarcodeScanner/BarcodeScanner.xcodeproj/project.pbxproj +++ b/examples/BarcodeScanner/BarcodeScanner.xcodeproj/project.pbxproj @@ -18,11 +18,11 @@ 02C6AFD7156FCB330052B145 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 02C6AFD6156FCB330052B145 /* main.m */; }; 02C6AFDA156FCB4F0052B145 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 02C6AFD9156FCB4F0052B145 /* ViewController.m */; }; 02C6AFDD156FCB660052B145 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 02C6AFDC156FCB660052B145 /* AppDelegate.m */; }; - 02C6AFE0156FCBA00052B145 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 02C6AFDE156FCBA00052B145 /* ViewController.xib */; }; 02C6AFE3156FCBA80052B145 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 02C6AFE1156FCBA80052B145 /* InfoPlist.strings */; }; - 25404718166AC1D200E13304 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 25404717166AC1D200E13304 /* Default-568h@2x.png */; }; 25404737166AC2EA00E13304 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404736166AC2EA00E13304 /* AVFoundation.framework */; }; 25FFF6A61839839400C2E985 /* libZXingObjC-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 25FFF69B1839837F00C2E985 /* libZXingObjC-iOS.a */; }; + 52D7D9D52657C33700EBEE2A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 52D7D9D42657C33700EBEE2A /* Main.storyboard */; }; + 52D7D9D72657C4A200EBEE2A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 52D7D9D62657C4A200EBEE2A /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -94,11 +94,11 @@ 02C6AFD9156FCB4F0052B145 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = SOURCE_ROOT; }; 02C6AFDB156FCB660052B145 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; 02C6AFDC156FCB660052B145 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; - 02C6AFDF156FCBA00052B145 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = SOURCE_ROOT; }; 02C6AFE2156FCBA80052B145 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; }; - 25404717166AC1D200E13304 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = SOURCE_ROOT; }; 25404736166AC2EA00E13304 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; 25FFF6921839837E00C2E985 /* ZXingObjC.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ZXingObjC.xcodeproj; path = ../../ZXingObjC.xcodeproj; sourceTree = ""; }; + 52D7D9D42657C33700EBEE2A /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = SOURCE_ROOT; }; + 52D7D9D62657C4A200EBEE2A /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -163,8 +163,8 @@ 02C6AFDC156FCB660052B145 /* AppDelegate.m */, 02C6AFD8156FCB4F0052B145 /* ViewController.h */, 02C6AFD9156FCB4F0052B145 /* ViewController.m */, - 02C6AFDE156FCBA00052B145 /* ViewController.xib */, - 25404717166AC1D200E13304 /* Default-568h@2x.png */, + 52D7D9D42657C33700EBEE2A /* Main.storyboard */, + 52D7D9D62657C4A200EBEE2A /* LaunchScreen.storyboard */, 024D10E6156EAB6F00FE6872 /* Supporting Files */, ); path = BarcodeScanner; @@ -221,7 +221,7 @@ 024D10D2156EAB6E00FE6872 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0620; + LastUpgradeCheck = 1000; ORGANIZATIONNAME = "Draconis Software"; }; buildConfigurationList = 024D10D5156EAB6E00FE6872 /* Build configuration list for PBXProject "BarcodeScanner" */; @@ -297,9 +297,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 02C6AFE0156FCBA00052B145 /* ViewController.xib in Resources */, 02C6AFE3156FCBA80052B145 /* InfoPlist.strings in Resources */, - 25404718166AC1D200E13304 /* Default-568h@2x.png in Resources */, + 52D7D9D72657C4A200EBEE2A /* LaunchScreen.storyboard in Resources */, + 52D7D9D52657C33700EBEE2A /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -327,14 +327,6 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - 02C6AFDE156FCBA00052B145 /* ViewController.xib */ = { - isa = PBXVariantGroup; - children = ( - 02C6AFDF156FCBA00052B145 /* en */, - ); - name = ViewController.xib; - sourceTree = ""; - }; 02C6AFE1156FCBA80052B145 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -350,18 +342,30 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -375,7 +379,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; @@ -387,17 +391,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; @@ -405,7 +420,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; OTHER_LDFLAGS = "-ObjC"; SDKROOT = iphoneos; @@ -418,6 +433,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; + ENABLE_BITCODE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "BarcodeScanner-Prefix.pch"; HEADER_SEARCH_PATHS = ( @@ -425,7 +441,9 @@ "$(SRCROOT)/../../**", ); INFOPLIST_FILE = "BarcodeScanner-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LIBRARY_SEARCH_PATHS = ""; + PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -435,6 +453,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; + ENABLE_BITCODE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "BarcodeScanner-Prefix.pch"; HEADER_SEARCH_PATHS = ( @@ -442,7 +461,9 @@ "$(SRCROOT)/../../**", ); INFOPLIST_FILE = "BarcodeScanner-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LIBRARY_SEARCH_PATHS = ""; + PRODUCT_BUNDLE_IDENTIFIER = "com.zxing.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/examples/BarcodeScanner/BarcodeScanner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/BarcodeScanner/BarcodeScanner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/examples/BarcodeScanner/BarcodeScanner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/BarcodeScanner/BarcodeScanner.xcodeproj/xcshareddata/xcschemes/BarcodeScanner.xcscheme b/examples/BarcodeScanner/BarcodeScanner.xcodeproj/xcshareddata/xcschemes/BarcodeScanner.xcscheme index bd2416a74..f3cb322a0 100644 --- a/examples/BarcodeScanner/BarcodeScanner.xcodeproj/xcshareddata/xcschemes/BarcodeScanner.xcscheme +++ b/examples/BarcodeScanner/BarcodeScanner.xcodeproj/xcshareddata/xcschemes/BarcodeScanner.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -38,15 +38,18 @@ ReferencedContainer = "container:BarcodeScanner.xcodeproj"> + + @@ -62,10 +65,10 @@ diff --git a/examples/BarcodeScanner/Default-568h@2x.png b/examples/BarcodeScanner/Default-568h@2x.png deleted file mode 100644 index 0891b7aab..000000000 Binary files a/examples/BarcodeScanner/Default-568h@2x.png and /dev/null differ diff --git a/examples/BarcodeScanner/LaunchScreen.storyboard b/examples/BarcodeScanner/LaunchScreen.storyboard new file mode 100644 index 000000000..0b905fb5a --- /dev/null +++ b/examples/BarcodeScanner/LaunchScreen.storyboard @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/BarcodeScanner/Main.storyboard b/examples/BarcodeScanner/Main.storyboard new file mode 100644 index 000000000..75e29c499 --- /dev/null +++ b/examples/BarcodeScanner/Main.storyboard @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/BarcodeScanner/ViewController.m b/examples/BarcodeScanner/ViewController.m index 0a3bcf99e..de3b067e2 100644 --- a/examples/BarcodeScanner/ViewController.m +++ b/examples/BarcodeScanner/ViewController.m @@ -20,123 +20,221 @@ @interface ViewController () @property (nonatomic, strong) ZXCapture *capture; -@property (nonatomic, weak) IBOutlet UIView *scanRectView; -@property (nonatomic, weak) IBOutlet UILabel *decodedLabel; +@property (nonatomic, weak) IBOutlet UIView *scanView; +@property (nonatomic, weak) IBOutlet UILabel *resultLabel; +@property (nonatomic) BOOL isScanning; +@property (nonatomic) BOOL isFirstApplyOrientation; @end -@implementation ViewController +@implementation ViewController { + CGAffineTransform _captureSizeTransform; +} #pragma mark - View Controller Methods - (void)dealloc { - [self.capture.layer removeFromSuperlayer]; + [self.capture.layer removeFromSuperlayer]; } - (void)viewDidLoad { - [super viewDidLoad]; - - self.capture = [[ZXCapture alloc] init]; - self.capture.camera = self.capture.back; - self.capture.focusMode = AVCaptureFocusModeContinuousAutoFocus; - self.capture.rotation = 90.0f; + [super viewDidLoad]; + [self setup]; +} - self.capture.layer.frame = self.view.bounds; - [self.view.layer addSublayer:self.capture.layer]; +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} - [self.view bringSubviewToFront:self.scanRectView]; - [self.view bringSubviewToFront:self.decodedLabel]; +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + + if (_isFirstApplyOrientation) return; + _isFirstApplyOrientation = TRUE; + [self applyOrientation]; } -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; +- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id )coordinator { + [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; + [coordinator animateAlongsideTransition:^(id context) { + } completion:^(id context) + { + [self applyOrientation]; + }]; +} - self.capture.delegate = self; - self.capture.layer.frame = self.view.bounds; +#pragma mark - Private +- (void)setup { + self.capture = [[ZXCapture alloc] init]; + self.capture.sessionPreset = AVCaptureSessionPreset1920x1080; + self.capture.camera = self.capture.back; + self.capture.focusMode = AVCaptureFocusModeContinuousAutoFocus; + self.capture.delegate = self; + + self.isScanning = NO; + + [self.view.layer addSublayer:self.capture.layer]; + + [self.view bringSubviewToFront:self.scanView]; + [self.view bringSubviewToFront:self.resultLabel]; + + // [self.capture setLuminance: TRUE]; + // [self.capture.luminance setFrame: CGRectMake(150, 30, 100, 100)]; + // [self.view.layer addSublayer: self.capture.luminance]; + + // [self.capture enableHeuristic]; +} - CGAffineTransform captureSizeTransform = CGAffineTransformMakeScale(320 / self.view.frame.size.width, 480 / self.view.frame.size.height); - self.capture.scanRect = CGRectApplyAffineTransform(self.scanRectView.frame, captureSizeTransform); +- (void)applyOrientation { + UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; + float scanRectRotation; + float captureRotation; + + switch (orientation) { + case UIInterfaceOrientationPortrait: + captureRotation = 0; + scanRectRotation = 90; + break; + case UIInterfaceOrientationLandscapeLeft: + captureRotation = 90; + scanRectRotation = 180; + break; + case UIInterfaceOrientationLandscapeRight: + captureRotation = 270; + scanRectRotation = 0; + break; + case UIInterfaceOrientationPortraitUpsideDown: + captureRotation = 180; + scanRectRotation = 270; + break; + default: + captureRotation = 0; + scanRectRotation = 90; + break; + } + + [self applyRectOfInterest:orientation]; + + CGFloat angleRadius = captureRotation / 180 * M_PI; + CGAffineTransform transform = CGAffineTransformMakeRotation(angleRadius); + + [self.capture setTransform:transform]; + [self.capture setRotation:scanRectRotation]; + self.capture.layer.frame = self.view.frame; } -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { - return toInterfaceOrientation == UIInterfaceOrientationPortrait; +- (void)applyRectOfInterest:(UIInterfaceOrientation)orientation { + CGRect transformedScanRect; + if (UIInterfaceOrientationIsLandscape(orientation)) { + transformedScanRect = CGRectMake(_scanView.frame.origin.y, + _scanView.frame.origin.x, + _scanView.frame.size.height, + _scanView.frame.size.width); + } else { + transformedScanRect = _scanView.frame; + } + + CGRect metadataOutputRect = [(AVCaptureVideoPreviewLayer *) _capture.layer metadataOutputRectOfInterestForRect:transformedScanRect]; + CGRect rectOfInterest = [_capture.output rectForMetadataOutputRectOfInterest:metadataOutputRect]; + _capture.scanRect = rectOfInterest; } #pragma mark - Private Methods - (NSString *)barcodeFormatToString:(ZXBarcodeFormat)format { - switch (format) { - case kBarcodeFormatAztec: - return @"Aztec"; - - case kBarcodeFormatCodabar: - return @"CODABAR"; - - case kBarcodeFormatCode39: - return @"Code 39"; - - case kBarcodeFormatCode93: - return @"Code 93"; - - case kBarcodeFormatCode128: - return @"Code 128"; - - case kBarcodeFormatDataMatrix: - return @"Data Matrix"; - - case kBarcodeFormatEan8: - return @"EAN-8"; - - case kBarcodeFormatEan13: - return @"EAN-13"; - - case kBarcodeFormatITF: - return @"ITF"; - - case kBarcodeFormatPDF417: - return @"PDF417"; - - case kBarcodeFormatQRCode: - return @"QR Code"; - - case kBarcodeFormatRSS14: - return @"RSS 14"; - - case kBarcodeFormatRSSExpanded: - return @"RSS Expanded"; - - case kBarcodeFormatUPCA: - return @"UPCA"; - - case kBarcodeFormatUPCE: - return @"UPCE"; - - case kBarcodeFormatUPCEANExtension: - return @"UPC/EAN extension"; - - default: - return @"Unknown"; - } + switch (format) { + case kBarcodeFormatAztec: + return @"Aztec"; + + case kBarcodeFormatCodabar: + return @"CODABAR"; + + case kBarcodeFormatCode39: + return @"Code 39"; + + case kBarcodeFormatCode93: + return @"Code 93"; + + case kBarcodeFormatCode128: + return @"Code 128"; + + case kBarcodeFormatDataMatrix: + return @"Data Matrix"; + + case kBarcodeFormatEan8: + return @"EAN-8"; + + case kBarcodeFormatEan13: + return @"EAN-13"; + + case kBarcodeFormatITF: + return @"ITF"; + + case kBarcodeFormatPDF417: + return @"PDF417"; + + case kBarcodeFormatQRCode: + return @"QR Code"; + + case kBarcodeFormatRSS14: + return @"RSS 14"; + + case kBarcodeFormatRSSExpanded: + return @"RSS Expanded"; + + case kBarcodeFormatUPCA: + return @"UPCA"; + + case kBarcodeFormatUPCE: + return @"UPCE"; + + case kBarcodeFormatUPCEANExtension: + return @"UPC/EAN extension"; + + default: + return @"Unknown"; + } } #pragma mark - ZXCaptureDelegate Methods -- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result { - if (!result) return; - - // We got a result. Display information about the result onscreen. - NSString *formatString = [self barcodeFormatToString:result.barcodeFormat]; - NSString *display = [NSString stringWithFormat:@"Scanned!\n\nFormat: %@\n\nContents:\n%@", formatString, result.text]; - [self.decodedLabel performSelectorOnMainThread:@selector(setText:) withObject:display waitUntilDone:YES]; - - // Vibrate - AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); - - [self.capture stop]; +- (void)captureCameraIsReady:(ZXCapture *)capture { + self.isScanning = YES; +} - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - [self.capture start]; - }); +- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result { + if (!self.isScanning) return; + if (!result) return; + + // We got a result. + [self.capture stop]; + self.isScanning = NO; + + // Display found barcode location + CGAffineTransform inverse = CGAffineTransformInvert(_captureSizeTransform); + NSMutableArray *points = [[NSMutableArray alloc] init]; + NSString *location = @""; + for (ZXResultPoint *resultPoint in result.resultPoints) { + CGPoint cgPoint = CGPointMake(resultPoint.x, resultPoint.y); + CGPoint transformedPoint = CGPointApplyAffineTransform(cgPoint, inverse); + transformedPoint = [self.scanView convertPoint:transformedPoint toView:self.scanView.window]; + NSValue* windowPointValue = [NSValue valueWithCGPoint:transformedPoint]; + location = [NSString stringWithFormat:@"%@ (%f, %f)", location, transformedPoint.x, transformedPoint.y]; + [points addObject:windowPointValue]; + } + + // Display information about the result onscreen. + NSString *formatString = [self barcodeFormatToString:result.barcodeFormat]; + NSString *display = [NSString stringWithFormat:@"Scanned!\n\nFormat: %@\n\nContents:\n%@\nLocation: %@", formatString, result.text, location]; + [self.resultLabel performSelectorOnMainThread:@selector(setText:) withObject:display waitUntilDone:YES]; + + // Vibrate + AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + self.isScanning = YES; + [self.capture start]; + }); } @end diff --git a/examples/BarcodeScanner/en.lproj/ViewController.xib b/examples/BarcodeScanner/en.lproj/ViewController.xib deleted file mode 100644 index 6f0d73c35..000000000 --- a/examples/BarcodeScanner/en.lproj/ViewController.xib +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX.xcodeproj/project.pbxproj b/examples/BarcodeScannerOSX/BarcodeScannerOSX.xcodeproj/project.pbxproj deleted file mode 100644 index 312c99d0f..000000000 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX.xcodeproj/project.pbxproj +++ /dev/null @@ -1,458 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 0228E6FB18E351CA004EF5D6 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FC93020139D875D00DA0D4F /* CoreMedia.framework */; }; - 026A32EC18C128C8002C3566 /* libZXingObjC-osx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 026A32E518C128B0002C3566 /* libZXingObjC-osx.a */; }; - 026A32F118C12A8C002C3566 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 026A32F018C12A8C002C3566 /* QuartzCore.framework */; }; - E9C967D3137B516200C6D18B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9C967D2137B516200C6D18B /* Cocoa.framework */; }; - E9C967DD137B516200C6D18B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E9C967DB137B516200C6D18B /* InfoPlist.strings */; }; - E9C967DF137B516200C6D18B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E9C967DE137B516200C6D18B /* main.m */; }; - E9C967E6137B516200C6D18B /* BarcodeScannerDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = E9C967E5137B516200C6D18B /* BarcodeScannerDocument.m */; }; - E9C967E9137B516200C6D18B /* BarcodeScannerDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9C967E7137B516200C6D18B /* BarcodeScannerDocument.xib */; }; - E9C967EC137B516200C6D18B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9C967EA137B516200C6D18B /* MainMenu.xib */; }; - E9C967F8137B51A700C6D18B /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9C967F7137B51A700C6D18B /* AVFoundation.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 026A32E018C128B0002C3566 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 25403CB3166A96FA00E13304; - remoteInfo = "ZXingObjC-iOS"; - }; - 026A32E218C128B0002C3566 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 25403CC4166A96FA00E13304; - remoteInfo = "Unit Tests iOS"; - }; - 026A32E418C128B0002C3566 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 25404166166AADAC00E13304; - remoteInfo = "ZXingObjC-osx"; - }; - 026A32E618C128B0002C3566 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 25404178166AADAC00E13304; - remoteInfo = "Unit Tests OS X"; - }; - 026A32E818C128B0002C3566 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2540439E166ABA0A00E13304; - remoteInfo = "OS X Framework"; - }; - 026A32EA18C128C3002C3566 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 25404165166AADAC00E13304; - remoteInfo = "ZXingObjC-osx"; - }; - 027E58821ABC5D1E00C334CA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = DB72547F1A523C9200EFF81B; - remoteInfo = "iOS Framework"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ZXingObjC.xcodeproj; path = ../../ZXingObjC.xcodeproj; sourceTree = ""; }; - 026A32EE18C12A7B002C3566 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; - 026A32F018C12A8C002C3566 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 2FC93020139D875D00DA0D4F /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; - 2FC93024139D8CC500DA0D4F /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; - E9C967CE137B516200C6D18B /* BarcodeScannerOSX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BarcodeScannerOSX.app; sourceTree = BUILT_PRODUCTS_DIR; }; - E9C967D2137B516200C6D18B /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - E9C967DA137B516200C6D18B /* BarcodeScannerOSX-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "BarcodeScannerOSX-Info.plist"; sourceTree = ""; }; - E9C967DC137B516200C6D18B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - E9C967DE137B516200C6D18B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - E9C967E0137B516200C6D18B /* BarcodeScannerOSX-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BarcodeScannerOSX-Prefix.pch"; sourceTree = ""; }; - E9C967E4137B516200C6D18B /* BarcodeScannerDocument.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BarcodeScannerDocument.h; sourceTree = ""; }; - E9C967E5137B516200C6D18B /* BarcodeScannerDocument.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BarcodeScannerDocument.m; sourceTree = ""; }; - E9C967E8137B516200C6D18B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/BarcodeScannerDocument.xib; sourceTree = ""; }; - E9C967EB137B516200C6D18B /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; - E9C967F7137B51A700C6D18B /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - E9C967CB137B516200C6D18B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 0228E6FB18E351CA004EF5D6 /* CoreMedia.framework in Frameworks */, - 026A32F118C12A8C002C3566 /* QuartzCore.framework in Frameworks */, - 026A32EC18C128C8002C3566 /* libZXingObjC-osx.a in Frameworks */, - E9C967F8137B51A700C6D18B /* AVFoundation.framework in Frameworks */, - E9C967D3137B516200C6D18B /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 026A32D918C128AE002C3566 /* Products */ = { - isa = PBXGroup; - children = ( - 026A32E118C128B0002C3566 /* libZXingObjC-iOS.a */, - 026A32E318C128B0002C3566 /* Unit Tests iOS.xctest */, - 026A32E518C128B0002C3566 /* libZXingObjC-osx.a */, - 026A32E718C128B0002C3566 /* Unit Tests OS X.xctest */, - 026A32E918C128B0002C3566 /* ZXingObjC.framework */, - 027E58831ABC5D1E00C334CA /* ZXingObjC.framework */, - ); - name = Products; - sourceTree = ""; - }; - E9C967C3137B516100C6D18B = { - isa = PBXGroup; - children = ( - E9C967D8137B516200C6D18B /* BarcodeScannerOSX */, - E9C967D1137B516200C6D18B /* Frameworks */, - E9C967CF137B516200C6D18B /* Products */, - 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */, - ); - sourceTree = ""; - }; - E9C967CF137B516200C6D18B /* Products */ = { - isa = PBXGroup; - children = ( - E9C967CE137B516200C6D18B /* BarcodeScannerOSX.app */, - ); - name = Products; - sourceTree = ""; - }; - E9C967D1137B516200C6D18B /* Frameworks */ = { - isa = PBXGroup; - children = ( - 026A32F018C12A8C002C3566 /* QuartzCore.framework */, - 026A32EE18C12A7B002C3566 /* CoreVideo.framework */, - 2FC93024139D8CC500DA0D4F /* AudioToolbox.framework */, - E9C967F7137B51A700C6D18B /* AVFoundation.framework */, - E9C967D2137B516200C6D18B /* Cocoa.framework */, - 2FC93020139D875D00DA0D4F /* CoreMedia.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - E9C967D8137B516200C6D18B /* BarcodeScannerOSX */ = { - isa = PBXGroup; - children = ( - E9C967E4137B516200C6D18B /* BarcodeScannerDocument.h */, - E9C967E5137B516200C6D18B /* BarcodeScannerDocument.m */, - E9C967E7137B516200C6D18B /* BarcodeScannerDocument.xib */, - E9C967EA137B516200C6D18B /* MainMenu.xib */, - E9C967D9137B516200C6D18B /* Supporting Files */, - ); - path = BarcodeScannerOSX; - sourceTree = ""; - }; - E9C967D9137B516200C6D18B /* Supporting Files */ = { - isa = PBXGroup; - children = ( - E9C967DA137B516200C6D18B /* BarcodeScannerOSX-Info.plist */, - E9C967DB137B516200C6D18B /* InfoPlist.strings */, - E9C967DE137B516200C6D18B /* main.m */, - E9C967E0137B516200C6D18B /* BarcodeScannerOSX-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - E9C967CD137B516200C6D18B /* BarcodeScannerOSX */ = { - isa = PBXNativeTarget; - buildConfigurationList = E9C967EF137B516200C6D18B /* Build configuration list for PBXNativeTarget "BarcodeScannerOSX" */; - buildPhases = ( - E9C967CA137B516200C6D18B /* Sources */, - E9C967CB137B516200C6D18B /* Frameworks */, - E9C967CC137B516200C6D18B /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 026A32EB18C128C3002C3566 /* PBXTargetDependency */, - ); - name = BarcodeScannerOSX; - productName = BarcodeScannerOSX; - productReference = E9C967CE137B516200C6D18B /* BarcodeScannerOSX.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - E9C967C5137B516100C6D18B /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0620; - }; - buildConfigurationList = E9C967C8137B516100C6D18B /* Build configuration list for PBXProject "BarcodeScannerOSX" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = E9C967C3137B516100C6D18B; - productRefGroup = E9C967CF137B516200C6D18B /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 026A32D918C128AE002C3566 /* Products */; - ProjectRef = 026A32D818C128AE002C3566 /* ZXingObjC.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - E9C967CD137B516200C6D18B /* BarcodeScannerOSX */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 026A32E118C128B0002C3566 /* libZXingObjC-iOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libZXingObjC-iOS.a"; - remoteRef = 026A32E018C128B0002C3566 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 026A32E318C128B0002C3566 /* Unit Tests iOS.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = "Unit Tests iOS.xctest"; - remoteRef = 026A32E218C128B0002C3566 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 026A32E518C128B0002C3566 /* libZXingObjC-osx.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libZXingObjC-osx.a"; - remoteRef = 026A32E418C128B0002C3566 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 026A32E718C128B0002C3566 /* Unit Tests OS X.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = "Unit Tests OS X.xctest"; - remoteRef = 026A32E618C128B0002C3566 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 026A32E918C128B0002C3566 /* ZXingObjC.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = ZXingObjC.framework; - remoteRef = 026A32E818C128B0002C3566 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 027E58831ABC5D1E00C334CA /* ZXingObjC.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = ZXingObjC.framework; - remoteRef = 027E58821ABC5D1E00C334CA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - E9C967CC137B516200C6D18B /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - E9C967DD137B516200C6D18B /* InfoPlist.strings in Resources */, - E9C967E9137B516200C6D18B /* BarcodeScannerDocument.xib in Resources */, - E9C967EC137B516200C6D18B /* MainMenu.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - E9C967CA137B516200C6D18B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - E9C967DF137B516200C6D18B /* main.m in Sources */, - E9C967E6137B516200C6D18B /* BarcodeScannerDocument.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 026A32EB18C128C3002C3566 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "ZXingObjC-osx"; - targetProxy = 026A32EA18C128C3002C3566 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - E9C967DB137B516200C6D18B /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - E9C967DC137B516200C6D18B /* en */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - E9C967E7137B516200C6D18B /* BarcodeScannerDocument.xib */ = { - isa = PBXVariantGroup; - children = ( - E9C967E8137B516200C6D18B /* en */, - ); - name = BarcodeScannerDocument.xib; - sourceTree = ""; - }; - E9C967EA137B516200C6D18B /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - E9C967EB137B516200C6D18B /* en */, - ); - name = MainMenu.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - E9C967ED137B516200C6D18B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - ONLY_ACTIVE_ARCH = YES; - }; - name = Debug; - }; - E9C967EE137B516200C6D18B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - }; - name = Release; - }; - E9C967F0137B516200C6D18B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "BarcodeScannerOSX/BarcodeScannerOSX-Prefix.pch"; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../../**", - ); - INFOPLIST_FILE = "BarcodeScannerOSX/BarcodeScannerOSX-Info.plist"; - PRODUCT_NAME = BarcodeScannerOSX; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - E9C967F1137B516200C6D18B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "BarcodeScannerOSX/BarcodeScannerOSX-Prefix.pch"; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../../**", - ); - INFOPLIST_FILE = "BarcodeScannerOSX/BarcodeScannerOSX-Info.plist"; - PRODUCT_NAME = BarcodeScannerOSX; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - E9C967C8137B516100C6D18B /* Build configuration list for PBXProject "BarcodeScannerOSX" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - E9C967ED137B516200C6D18B /* Debug */, - E9C967EE137B516200C6D18B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - E9C967EF137B516200C6D18B /* Build configuration list for PBXNativeTarget "BarcodeScannerOSX" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - E9C967F0137B516200C6D18B /* Debug */, - E9C967F1137B516200C6D18B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = E9C967C5137B516100C6D18B /* Project object */; -} diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/BarcodeScannerOSX/BarcodeScannerOSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1ca5c549b..000000000 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX.xcodeproj/xcshareddata/xcschemes/BarcodeScannerOSX.xcscheme b/examples/BarcodeScannerOSX/BarcodeScannerOSX.xcodeproj/xcshareddata/xcschemes/BarcodeScannerOSX.xcscheme deleted file mode 100644 index ab8d4f254..000000000 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX.xcodeproj/xcshareddata/xcschemes/BarcodeScannerOSX.xcscheme +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerDocument.m b/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerDocument.m deleted file mode 100644 index b215f86e0..000000000 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerDocument.m +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2014 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "BarcodeScannerDocument.h" - -@interface BarcodeScannerDocument () - -@property (nonatomic, strong) ZXCapture *capture; - -@end - -@implementation BarcodeScannerDocument - -#pragma mark - NSDocument Methods - -- (void)dealloc { - [self.capture.layer removeFromSuperlayer]; -} - -- (NSString *)windowNibName { - return @"BarcodeScannerDocument"; -} - -- (void)windowControllerDidLoadNib:(NSWindowController *)controller { - [super windowControllerDidLoadNib:controller]; - - self.capture = [[ZXCapture alloc] init]; - self.capture.rotation = 90.0f; - - self.capture.layer.frame = self.previewView.bounds; - [self.previewView.layer addSublayer:self.capture.layer]; - - self.capture.delegate = self; -} - -#pragma mark - ZXCaptureDelegate Methods - -- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result { - if (result) { - NSString *formatString = [self barcodeFormatToString:result.barcodeFormat]; - NSLog(@"Scanned!\n\nFormat: %@\n\nContents:\n%@", formatString, result.text); - } -} - -#pragma mark - Private Methods - -- (NSString *)barcodeFormatToString:(ZXBarcodeFormat)format { - switch (format) { - case kBarcodeFormatAztec: - return @"Aztec"; - - case kBarcodeFormatCodabar: - return @"CODABAR"; - - case kBarcodeFormatCode39: - return @"Code 39"; - - case kBarcodeFormatCode93: - return @"Code 93"; - - case kBarcodeFormatCode128: - return @"Code 128"; - - case kBarcodeFormatDataMatrix: - return @"Data Matrix"; - - case kBarcodeFormatEan8: - return @"EAN-8"; - - case kBarcodeFormatEan13: - return @"EAN-13"; - - case kBarcodeFormatITF: - return @"ITF"; - - case kBarcodeFormatPDF417: - return @"PDF417"; - - case kBarcodeFormatQRCode: - return @"QR Code"; - - case kBarcodeFormatRSS14: - return @"RSS 14"; - - case kBarcodeFormatRSSExpanded: - return @"RSS Expanded"; - - case kBarcodeFormatUPCA: - return @"UPCA"; - - case kBarcodeFormatUPCE: - return @"UPCE"; - - case kBarcodeFormatUPCEANExtension: - return @"UPC/EAN extension"; - - default: - return @"Unknown"; - } -} - -@end diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerOSX-Info.plist b/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerOSX-Info.plist deleted file mode 100644 index 30287ba4a..000000000 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX/BarcodeScannerOSX-Info.plist +++ /dev/null @@ -1,53 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - mov - - CFBundleTypeIconFile - - CFBundleTypeName - Movie - CFBundleTypeOSTypes - - MooV - - CFBundleTypeRole - Editor - NSDocumentClass - BarcodeScannerDocument - - - CFBundleExecutable - BarcodeScannerOSX - CFBundleIconFile - - CFBundleIdentifier - BarcodeScannerOSX - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSMinimumSystemVersion - 10.7 - NSHumanReadableCopyright - - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - - diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX/en.lproj/BarcodeScannerDocument.xib b/examples/BarcodeScannerOSX/BarcodeScannerOSX/en.lproj/BarcodeScannerDocument.xib deleted file mode 100644 index 4c681cd63..000000000 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX/en.lproj/BarcodeScannerDocument.xib +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX/en.lproj/InfoPlist.strings b/examples/BarcodeScannerOSX/BarcodeScannerOSX/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28ff8..000000000 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/examples/BarcodeScannerOSX/BarcodeScannerOSX/en.lproj/MainMenu.xib b/examples/BarcodeScannerOSX/BarcodeScannerOSX/en.lproj/MainMenu.xib deleted file mode 100644 index a3b96d3e5..000000000 --- a/examples/BarcodeScannerOSX/BarcodeScannerOSX/en.lproj/MainMenu.xib +++ /dev/null @@ -1,591 +0,0 @@ - - - - 1060 - 13B42 - 4514 - 1265 - 696.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 4514 - - - NSCustomObject - NSMenu - NSMenuItem - - - com.apple.InterfaceBuilder.CocoaPlugin - - - PluginDependencyRecalculationVersion - - - - - - NSApplication - - - - FirstResponder - - - NSApplication - - - MainMenu - - - - BarcodeScannerOSX - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - - BarcodeScannerOSX - - - - About BarcodeScannerOSX - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - - - Services - - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide BarcodeScannerOSX - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit BarcodeScannerOSX - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - File - - 1048576 - 2147483647 - - - submenuAction: - - - - File - - - - - New Recording - n - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Close - w - 1048576 - 2147483647 - - - - - - - - - Window - - 1048576 - 2147483647 - - - submenuAction: - - - - Window - - - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Bring All to Front - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - _NSMainMenu - - - - - - - terminate: - - - - 139 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - hideOtherApplications: - - - - 146 - - - - hide: - - - - 152 - - - - unhideAllApplications: - - - - 153 - - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - performClose: - - - - 193 - - - - newDocument: - - - - 194 - - - - performZoom: - - - - 204 - - - - - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - 29 - - - - - - - - MainMenu - - - 19 - - - - - - - - 24 - - - - - - - - - - - 5 - - - - - 23 - - - - - 92 - - - - - 203 - - - - - 56 - - - - - - - - 57 - - - - - - - - - - - - - - - - 58 - - - - - 131 - - - - - - - - 130 - - - - - 134 - - - - - 136 - - - - - 144 - - - - - 145 - - - - - 149 - - - - - 150 - - - - - 202 - - - - - 83 - - - - - - - - 81 - - - - - - - - - - 73 - - - - - 79 - - - - - 82 - - - - - -3 - - - Application - - - - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - - - - - 212 - - - 0 - IBCocoaFramework - NO - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - 3 - - {11, 11} - {10, 3} - - - diff --git a/examples/BarcodeScannerSwift/BarcodeScannerSwift.xcodeproj/project.pbxproj b/examples/BarcodeScannerSwift/BarcodeScannerSwift.xcodeproj/project.pbxproj new file mode 100644 index 000000000..18685b7ac --- /dev/null +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift.xcodeproj/project.pbxproj @@ -0,0 +1,480 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 9014C55F2160FF5300B063E6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9014C55E2160FF5300B063E6 /* AppDelegate.swift */; }; + 9014C5612160FF5300B063E6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9014C5602160FF5300B063E6 /* ViewController.swift */; }; + 9014C5662160FF5400B063E6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9014C5652160FF5400B063E6 /* Assets.xcassets */; }; + 9014C5692160FF5400B063E6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9014C5672160FF5400B063E6 /* LaunchScreen.storyboard */; }; + 9014C5A8216100DE00B063E6 /* ZXingObjC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9014C5A02160FFE100B063E6 /* ZXingObjC.framework */; }; + 9014C5A9216100DE00B063E6 /* ZXingObjC.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9014C5A02160FFE100B063E6 /* ZXingObjC.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9014C5AE2161137F00B063E6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9014C5AD2161137F00B063E6 /* Main.storyboard */; }; + 9014C5B5216116AB00B063E6 /* BarcodeScannerSwift.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9014C5B4216116AB00B063E6 /* BarcodeScannerSwift.plist */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 9014C5952160FFE100B063E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 25403CB3166A96FA00E13304; + remoteInfo = "ZXingObjC-iOS"; + }; + 9014C5972160FFE100B063E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 25403CC4166A96FA00E13304; + remoteInfo = "Unit Tests iOS"; + }; + 9014C5992160FFE100B063E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 25404166166AADAC00E13304; + remoteInfo = "ZXingObjC-osx"; + }; + 9014C59B2160FFE100B063E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 25404178166AADAC00E13304; + remoteInfo = "Unit Tests OS X"; + }; + 9014C59D2160FFE100B063E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 2540439E166ABA0A00E13304; + remoteInfo = "OS X Framework"; + }; + 9014C59F2160FFE100B063E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = DB72547F1A523C9200EFF81B; + remoteInfo = "iOS Framework"; + }; + 9014C5AA216100DF00B063E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = DB72547E1A523C9200EFF81B; + remoteInfo = "iOS Framework"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9014C5AC216100DF00B063E6 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 9014C5A9216100DE00B063E6 /* ZXingObjC.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 9014C55B2160FF5300B063E6 /* BarcodeScannerSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BarcodeScannerSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9014C55E2160FF5300B063E6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 9014C5602160FF5300B063E6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 9014C5652160FF5400B063E6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 9014C5682160FF5400B063E6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ZXingObjC.xcodeproj; path = ../../ZXingObjC.xcodeproj; sourceTree = ""; }; + 9014C5AD2161137F00B063E6 /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; + 9014C5B4216116AB00B063E6 /* BarcodeScannerSwift.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = BarcodeScannerSwift.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 9014C5582160FF5300B063E6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9014C5A8216100DE00B063E6 /* ZXingObjC.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9014C5522160FF5300B063E6 = { + isa = PBXGroup; + children = ( + 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */, + 9014C55D2160FF5300B063E6 /* BarcodeScannerSwift */, + 9014C55C2160FF5300B063E6 /* Products */, + ); + sourceTree = ""; + }; + 9014C55C2160FF5300B063E6 /* Products */ = { + isa = PBXGroup; + children = ( + 9014C55B2160FF5300B063E6 /* BarcodeScannerSwift.app */, + ); + name = Products; + sourceTree = ""; + }; + 9014C55D2160FF5300B063E6 /* BarcodeScannerSwift */ = { + isa = PBXGroup; + children = ( + 9014C5B4216116AB00B063E6 /* BarcodeScannerSwift.plist */, + 9014C55E2160FF5300B063E6 /* AppDelegate.swift */, + 9014C5602160FF5300B063E6 /* ViewController.swift */, + 9014C5652160FF5400B063E6 /* Assets.xcassets */, + 9014C5AD2161137F00B063E6 /* Main.storyboard */, + 9014C5672160FF5400B063E6 /* LaunchScreen.storyboard */, + ); + path = BarcodeScannerSwift; + sourceTree = ""; + }; + 9014C58D2160FFE100B063E6 /* Products */ = { + isa = PBXGroup; + children = ( + 9014C5962160FFE100B063E6 /* libZXingObjC-iOS.a */, + 9014C5982160FFE100B063E6 /* Unit Tests iOS.xctest */, + 9014C59A2160FFE100B063E6 /* libZXingObjC-osx.a */, + 9014C59C2160FFE100B063E6 /* Unit Tests OS X.xctest */, + 9014C59E2160FFE100B063E6 /* ZXingObjC.framework */, + 9014C5A02160FFE100B063E6 /* ZXingObjC.framework */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 9014C55A2160FF5300B063E6 /* BarcodeScannerSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9014C5832160FF5400B063E6 /* Build configuration list for PBXNativeTarget "BarcodeScannerSwift" */; + buildPhases = ( + 9014C5572160FF5300B063E6 /* Sources */, + 9014C5582160FF5300B063E6 /* Frameworks */, + 9014C5592160FF5300B063E6 /* Resources */, + 9014C5AC216100DF00B063E6 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 9014C5AB216100DF00B063E6 /* PBXTargetDependency */, + ); + name = BarcodeScannerSwift; + productName = BarcodeScannerSwift; + productReference = 9014C55B2160FF5300B063E6 /* BarcodeScannerSwift.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 9014C5532160FF5300B063E6 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0930; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = neacao; + TargetAttributes = { + 9014C55A2160FF5300B063E6 = { + CreatedOnToolsVersion = 9.3.1; + }; + }; + }; + buildConfigurationList = 9014C5562160FF5300B063E6 /* Build configuration list for PBXProject "BarcodeScannerSwift" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 9014C5522160FF5300B063E6; + productRefGroup = 9014C55C2160FF5300B063E6 /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 9014C58D2160FFE100B063E6 /* Products */; + ProjectRef = 9014C58C2160FFE100B063E6 /* ZXingObjC.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 9014C55A2160FF5300B063E6 /* BarcodeScannerSwift */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 9014C5962160FFE100B063E6 /* libZXingObjC-iOS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libZXingObjC-iOS.a"; + remoteRef = 9014C5952160FFE100B063E6 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9014C5982160FFE100B063E6 /* Unit Tests iOS.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "Unit Tests iOS.xctest"; + remoteRef = 9014C5972160FFE100B063E6 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9014C59A2160FFE100B063E6 /* libZXingObjC-osx.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libZXingObjC-osx.a"; + remoteRef = 9014C5992160FFE100B063E6 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9014C59C2160FFE100B063E6 /* Unit Tests OS X.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "Unit Tests OS X.xctest"; + remoteRef = 9014C59B2160FFE100B063E6 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9014C59E2160FFE100B063E6 /* ZXingObjC.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = ZXingObjC.framework; + remoteRef = 9014C59D2160FFE100B063E6 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9014C5A02160FFE100B063E6 /* ZXingObjC.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = ZXingObjC.framework; + remoteRef = 9014C59F2160FFE100B063E6 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 9014C5592160FF5300B063E6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9014C5AE2161137F00B063E6 /* Main.storyboard in Resources */, + 9014C5692160FF5400B063E6 /* LaunchScreen.storyboard in Resources */, + 9014C5B5216116AB00B063E6 /* BarcodeScannerSwift.plist in Resources */, + 9014C5662160FF5400B063E6 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 9014C5572160FF5300B063E6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9014C5612160FF5300B063E6 /* ViewController.swift in Sources */, + 9014C55F2160FF5300B063E6 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 9014C5AB216100DF00B063E6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "iOS Framework"; + targetProxy = 9014C5AA216100DF00B063E6 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 9014C5672160FF5400B063E6 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 9014C5682160FF5400B063E6 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 9014C5812160FF5400B063E6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 9014C5822160FF5400B063E6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 9014C5842160FF5400B063E6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = BarcodeScannerSwift/BarcodeScannerSwift.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.neacao.BarcodeScannerSwift; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 9014C5852160FF5400B063E6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = BarcodeScannerSwift/BarcodeScannerSwift.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.neacao.BarcodeScannerSwift; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 9014C5562160FF5300B063E6 /* Build configuration list for PBXProject "BarcodeScannerSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9014C5812160FF5400B063E6 /* Debug */, + 9014C5822160FF5400B063E6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9014C5832160FF5400B063E6 /* Build configuration list for PBXNativeTarget "BarcodeScannerSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9014C5842160FF5400B063E6 /* Debug */, + 9014C5852160FF5400B063E6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 9014C5532160FF5300B063E6 /* Project object */; +} diff --git a/examples/QrCodeTest/QrCodeTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/BarcodeScannerSwift/BarcodeScannerSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 66% rename from examples/QrCodeTest/QrCodeTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to examples/BarcodeScannerSwift/BarcodeScannerSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 552c69ae2..5346960c4 100644 --- a/examples/QrCodeTest/QrCodeTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:BarcodeScannerSwift.xcodeproj"> diff --git a/examples/BarcodeScannerSwift/BarcodeScannerSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/BarcodeScannerSwift/BarcodeScannerSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/QrCodeTest/ViewController.h b/examples/BarcodeScannerSwift/BarcodeScannerSwift/AppDelegate.swift similarity index 67% rename from examples/QrCodeTest/ViewController.h rename to examples/BarcodeScannerSwift/BarcodeScannerSwift/AppDelegate.swift index 425d07297..d4ee8dee0 100644 --- a/examples/QrCodeTest/ViewController.h +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift/AppDelegate.swift @@ -14,13 +14,16 @@ * limitations under the License. */ -#import +import UIKit -@interface ViewController : UIViewController +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { -@property (nonatomic, strong) IBOutlet UITextView *textView; -@property (nonatomic, strong) IBOutlet UIImageView *imageView; + var window: UIWindow? -- (IBAction)updatePressed:(id)sender; + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + return true + } + +} -@end diff --git a/examples/BarcodeScannerSwift/BarcodeScannerSwift/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/BarcodeScannerSwift/BarcodeScannerSwift/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..d8db8d65f --- /dev/null +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/BarcodeScannerSwift/BarcodeScannerSwift/Assets.xcassets/Contents.json b/examples/BarcodeScannerSwift/BarcodeScannerSwift/Assets.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/QrCodeTest/QrCodeTest-Info.plist b/examples/BarcodeScannerSwift/BarcodeScannerSwift/BarcodeScannerSwift.plist similarity index 52% rename from examples/QrCodeTest/QrCodeTest-Info.plist rename to examples/BarcodeScannerSwift/BarcodeScannerSwift/BarcodeScannerSwift.plist index c854d3ab4..b3d5f7f12 100644 --- a/examples/QrCodeTest/QrCodeTest-Info.plist +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift/BarcodeScannerSwift.plist @@ -3,29 +3,29 @@ CFBundleDevelopmentRegion - en - CFBundleDisplayName - ${PRODUCT_NAME} + $(DEVELOPMENT_LANGUAGE) CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFiles - + $(EXECUTABLE_NAME) CFBundleIdentifier - com.zxing.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName - ${PRODUCT_NAME} + $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 - CFBundleSignature - ???? CFBundleVersion - 1.0 + 1 LSRequiresIPhoneOS + NSCameraUsageDescription + Barcode Scanner must have access to your camera to scan barcodes. + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main UIRequiredDeviceCapabilities armv7 @@ -35,6 +35,14 @@ UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight diff --git a/examples/BarcodeScannerSwift/BarcodeScannerSwift/Base.lproj/LaunchScreen.storyboard b/examples/BarcodeScannerSwift/BarcodeScannerSwift/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..0b905fb5a --- /dev/null +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/BarcodeScannerSwift/BarcodeScannerSwift/Main.storyboard b/examples/BarcodeScannerSwift/BarcodeScannerSwift/Main.storyboard new file mode 100644 index 000000000..480c43391 --- /dev/null +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift/Main.storyboard @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/BarcodeScannerSwift/BarcodeScannerSwift/ViewController.swift b/examples/BarcodeScannerSwift/BarcodeScannerSwift/ViewController.swift new file mode 100644 index 000000000..a1a385b0d --- /dev/null +++ b/examples/BarcodeScannerSwift/BarcodeScannerSwift/ViewController.swift @@ -0,0 +1,228 @@ +/* + * Copyright 2012 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import UIKit +import ZXingObjC + +class ViewController: UIViewController { + + // MARK: Properties + + @IBOutlet weak var scanView: UIView? + @IBOutlet weak var resultLabel: UILabel? + + fileprivate var capture: ZXCapture? + + fileprivate var isScanning: Bool? + fileprivate var isFirstApplyOrientation: Bool? + + + // MARK: Life Circles + + override func viewDidLoad() { + super.viewDidLoad() + setup() + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + if isFirstApplyOrientation == true { return } + isFirstApplyOrientation = true + applyOrientation() + } + + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + + coordinator.animate(alongsideTransition: { (context) in + // do nothing + }) { [weak self] (context) in + guard let weakSelf = self else { return } + weakSelf.applyOrientation() + } + } +} + +// MARK: Helpers +extension ViewController { + func setup() { + isScanning = false + isFirstApplyOrientation = false + + capture = ZXCapture() + guard let _capture = capture else { return } + _capture.camera = _capture.back() + _capture.focusMode = .continuousAutoFocus + _capture.delegate = self + + self.view.layer.addSublayer(_capture.layer) + guard let _scanView = scanView, let _resultLabel = resultLabel else { return } + self.view.bringSubview(toFront: _scanView) + self.view.bringSubview(toFront: _resultLabel) + } + + func applyOrientation() { + let orientation = UIApplication.shared.statusBarOrientation + var captureRotation: Double + var scanRectRotation: Double + + switch orientation { + case .portrait: + captureRotation = 0 + scanRectRotation = 90 + break + + case .landscapeLeft: + captureRotation = 90 + scanRectRotation = 180 + break + + case .landscapeRight: + captureRotation = 270 + scanRectRotation = 0 + break + + case .portraitUpsideDown: + captureRotation = 180 + scanRectRotation = 270 + break + + default: + captureRotation = 0 + scanRectRotation = 90 + break + } + + applyRectOfInterest(orientation: orientation) + + let angleRadius = captureRotation / 180.0 * Double.pi + let captureTranform = CGAffineTransform(rotationAngle: CGFloat(angleRadius)) + + capture?.transform = captureTranform + capture?.rotation = CGFloat(scanRectRotation) + capture?.layer.frame = view.frame + } + + func applyRectOfInterest(orientation: UIInterfaceOrientation) { + guard + let capture = capture, + let captureLayer = capture.layer as? AVCaptureVideoPreviewLayer, + let scanRect = scanView?.frame + else { return } + + let transformedScanRect: CGRect + if orientation.isLandscape { + transformedScanRect = CGRect( + x: scanRect.origin.y, + y: scanRect.origin.x, + width: scanRect.size.height, + height: scanRect.size.width + ) + } else { + transformedScanRect = scanRect + } + + let metadataOutputRect = captureLayer.metadataOutputRectConverted(fromLayerRect: transformedScanRect) + let rectOfInterest = capture.output.outputRectConverted(fromMetadataOutputRect: metadataOutputRect) + capture.scanRect = rectOfInterest + } + + func barcodeFormatToString(format: ZXBarcodeFormat) -> String { + switch (format) { + case kBarcodeFormatAztec: + return "Aztec" + + case kBarcodeFormatCodabar: + return "CODABAR" + + case kBarcodeFormatCode39: + return "Code 39" + + case kBarcodeFormatCode93: + return "Code 93" + + case kBarcodeFormatCode128: + return "Code 128" + + case kBarcodeFormatDataMatrix: + return "Data Matrix" + + case kBarcodeFormatEan8: + return "EAN-8" + + case kBarcodeFormatEan13: + return "EAN-13" + + case kBarcodeFormatITF: + return "ITF" + + case kBarcodeFormatPDF417: + return "PDF417" + + case kBarcodeFormatQRCode: + return "QR Code" + + case kBarcodeFormatRSS14: + return "RSS 14" + + case kBarcodeFormatRSSExpanded: + return "RSS Expanded" + + case kBarcodeFormatUPCA: + return "UPCA" + + case kBarcodeFormatUPCE: + return "UPCE" + + case kBarcodeFormatUPCEANExtension: + return "UPC/EAN extension" + + default: + return "Unknown" + } + } +} + +// MARK: ZXCaptureDelegate +extension ViewController: ZXCaptureDelegate { + func captureCameraIsReady(_ capture: ZXCapture!) { + isScanning = true + } + + func captureResult(_ capture: ZXCapture!, result: ZXResult!) { + guard let _result = result, isScanning == true else { return } + + capture?.stop() + isScanning = false + + let text = _result.text ?? "Unknow" + let format = barcodeFormatToString(format: _result.barcodeFormat) + + let displayStr = "Scanned !\nFormat: \(format)\nContents: \(text)" + resultLabel?.text = displayStr + + AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) + + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { [weak self] in + guard let weakSelf = self else { return } + weakSelf.isScanning = true + weakSelf.capture?.start() + } + } + +} + diff --git a/examples/QrCodeTest/AppDelegate.m b/examples/QrCodeTest/AppDelegate.m deleted file mode 100644 index 02cc8ee15..000000000 --- a/examples/QrCodeTest/AppDelegate.m +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "AppDelegate.h" -#import "ViewController.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; - self.window.rootViewController = self.viewController; - [self.window makeKeyAndVisible]; - return YES; -} - -@end diff --git a/examples/QrCodeTest/Default-568h@2x.png b/examples/QrCodeTest/Default-568h@2x.png deleted file mode 100644 index 0891b7aab..000000000 Binary files a/examples/QrCodeTest/Default-568h@2x.png and /dev/null differ diff --git a/examples/QrCodeTest/QrCodeTest-Prefix.pch b/examples/QrCodeTest/QrCodeTest-Prefix.pch deleted file mode 100644 index a9ba32244..000000000 --- a/examples/QrCodeTest/QrCodeTest-Prefix.pch +++ /dev/null @@ -1,16 +0,0 @@ -// -// Prefix header for all source files of the 'QrCodeTest' target in the 'QrCodeTest' project -// - -#import - -#ifndef __IPHONE_4_0 -#warning "This project uses features only available in iOS SDK 4.0 and later." -#endif - -#ifdef __OBJC__ - #import - #import - - #import -#endif diff --git a/examples/QrCodeTest/QrCodeTest.xcodeproj/project.pbxproj b/examples/QrCodeTest/QrCodeTest.xcodeproj/project.pbxproj deleted file mode 100644 index a20caf8f0..000000000 --- a/examples/QrCodeTest/QrCodeTest.xcodeproj/project.pbxproj +++ /dev/null @@ -1,470 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 022B185F14D1B5FE000503E2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 022B185E14D1B5FE000503E2 /* UIKit.framework */; }; - 022B186114D1B5FE000503E2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 022B186014D1B5FE000503E2 /* Foundation.framework */; }; - 022B186914D1B5FE000503E2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 022B186714D1B5FE000503E2 /* InfoPlist.strings */; }; - 0248363016CC14F8001E03E4 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0248362F16CC14F8001E03E4 /* CoreMedia.framework */; }; - 0248363216CC14FF001E03E4 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0248363116CC14FF001E03E4 /* QuartzCore.framework */; }; - 026851F8151383A200394C7B /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 026851F7151383A200394C7B /* ViewController.xib */; }; - 029BCCF715128A90009E6549 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 022B186A14D1B5FE000503E2 /* main.m */; }; - 029BCCF815128A92009E6549 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 022B187114D1B5FE000503E2 /* ViewController.m */; }; - 029BCCF915128A94009E6549 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 022B186E14D1B5FE000503E2 /* AppDelegate.m */; }; - 2540479B166AFC5900E13304 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2540479A166AFC5900E13304 /* Default-568h@2x.png */; }; - 2540479D166AFCD800E13304 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540479C166AFCD800E13304 /* AVFoundation.framework */; }; - 2540479F166AFCDC00E13304 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540479E166AFCDC00E13304 /* CoreGraphics.framework */; }; - 254047A4166AFCF600E13304 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 254047A2166AFCE400E13304 /* ImageIO.framework */; }; - 254047A5166AFD0200E13304 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 254047A0166AFCE100E13304 /* CoreVideo.framework */; }; - 25FFF6BB183983E900C2E985 /* libZXingObjC-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 25FFF6B0183983D400C2E985 /* libZXingObjC-iOS.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 027E588A1ABC5D4200C334CA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = DB72547F1A523C9200EFF81B; - remoteInfo = "iOS Framework"; - }; - 25FFF6AF183983D400C2E985 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 25403CB3166A96FA00E13304; - remoteInfo = "ZXingObjC-iOS"; - }; - 25FFF6B1183983D400C2E985 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 25403CC4166A96FA00E13304; - remoteInfo = "ZXingObjCTests-iOS"; - }; - 25FFF6B3183983D400C2E985 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 25404166166AADAC00E13304; - remoteInfo = "ZXingObjC-osx"; - }; - 25FFF6B5183983D400C2E985 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 25404178166AADAC00E13304; - remoteInfo = "ZXingObjCTests-osx"; - }; - 25FFF6B7183983D400C2E985 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2540439E166ABA0A00E13304; - remoteInfo = "OS X Framework"; - }; - 25FFF6B9183983E500C2E985 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 25403CB2166A96FA00E13304; - remoteInfo = "ZXingObjC-iOS"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 022B185A14D1B5FE000503E2 /* QrCodeTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QrCodeTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 022B185E14D1B5FE000503E2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 022B186014D1B5FE000503E2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 022B186614D1B5FE000503E2 /* QrCodeTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "QrCodeTest-Info.plist"; sourceTree = SOURCE_ROOT; }; - 022B186814D1B5FE000503E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 022B186A14D1B5FE000503E2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; - 022B186C14D1B5FE000503E2 /* QrCodeTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QrCodeTest-Prefix.pch"; sourceTree = ""; }; - 022B186D14D1B5FE000503E2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; }; - 022B186E14D1B5FE000503E2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; }; - 022B187014D1B5FE000503E2 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = SOURCE_ROOT; }; - 022B187114D1B5FE000503E2 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = SOURCE_ROOT; }; - 0248362F16CC14F8001E03E4 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; - 0248363116CC14FF001E03E4 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 026851F7151383A200394C7B /* ViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ViewController.xib; sourceTree = SOURCE_ROOT; }; - 2540479A166AFC5900E13304 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = SOURCE_ROOT; }; - 2540479C166AFCD800E13304 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; - 2540479E166AFCDC00E13304 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 254047A0166AFCE100E13304 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; - 254047A2166AFCE400E13304 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; }; - 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ZXingObjC.xcodeproj; path = ../../ZXingObjC.xcodeproj; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 022B185714D1B5FE000503E2 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 25FFF6BB183983E900C2E985 /* libZXingObjC-iOS.a in Frameworks */, - 0248363216CC14FF001E03E4 /* QuartzCore.framework in Frameworks */, - 0248363016CC14F8001E03E4 /* CoreMedia.framework in Frameworks */, - 2540479D166AFCD800E13304 /* AVFoundation.framework in Frameworks */, - 2540479F166AFCDC00E13304 /* CoreGraphics.framework in Frameworks */, - 254047A5166AFD0200E13304 /* CoreVideo.framework in Frameworks */, - 022B186114D1B5FE000503E2 /* Foundation.framework in Frameworks */, - 254047A4166AFCF600E13304 /* ImageIO.framework in Frameworks */, - 022B185F14D1B5FE000503E2 /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 022B184F14D1B5FE000503E2 = { - isa = PBXGroup; - children = ( - 022B186414D1B5FE000503E2 /* QrCodeTest */, - 022B185D14D1B5FE000503E2 /* Frameworks */, - 022B185B14D1B5FE000503E2 /* Products */, - 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */, - ); - sourceTree = ""; - }; - 022B185B14D1B5FE000503E2 /* Products */ = { - isa = PBXGroup; - children = ( - 022B185A14D1B5FE000503E2 /* QrCodeTest.app */, - ); - name = Products; - sourceTree = ""; - }; - 022B185D14D1B5FE000503E2 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 022B185E14D1B5FE000503E2 /* UIKit.framework */, - 022B186014D1B5FE000503E2 /* Foundation.framework */, - 254047A2166AFCE400E13304 /* ImageIO.framework */, - 0248363116CC14FF001E03E4 /* QuartzCore.framework */, - 0248362F16CC14F8001E03E4 /* CoreMedia.framework */, - 254047A0166AFCE100E13304 /* CoreVideo.framework */, - 2540479E166AFCDC00E13304 /* CoreGraphics.framework */, - 2540479C166AFCD800E13304 /* AVFoundation.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 022B186414D1B5FE000503E2 /* QrCodeTest */ = { - isa = PBXGroup; - children = ( - 2540479A166AFC5900E13304 /* Default-568h@2x.png */, - 022B186D14D1B5FE000503E2 /* AppDelegate.h */, - 022B186E14D1B5FE000503E2 /* AppDelegate.m */, - 022B187014D1B5FE000503E2 /* ViewController.h */, - 022B187114D1B5FE000503E2 /* ViewController.m */, - 026851F7151383A200394C7B /* ViewController.xib */, - 022B186514D1B5FE000503E2 /* Supporting Files */, - ); - path = QrCodeTest; - sourceTree = ""; - }; - 022B186514D1B5FE000503E2 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 022B186614D1B5FE000503E2 /* QrCodeTest-Info.plist */, - 022B186714D1B5FE000503E2 /* InfoPlist.strings */, - 022B186A14D1B5FE000503E2 /* main.m */, - 022B186C14D1B5FE000503E2 /* QrCodeTest-Prefix.pch */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 25FFF6A8183983D400C2E985 /* Products */ = { - isa = PBXGroup; - children = ( - 25FFF6B0183983D400C2E985 /* libZXingObjC-iOS.a */, - 25FFF6B2183983D400C2E985 /* Unit Tests iOS.xctest */, - 25FFF6B4183983D400C2E985 /* libZXingObjC-osx.a */, - 25FFF6B6183983D400C2E985 /* Unit Tests OS X.xctest */, - 25FFF6B8183983D400C2E985 /* ZXingObjC.framework */, - 027E588B1ABC5D4200C334CA /* ZXingObjC.framework */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 022B185914D1B5FE000503E2 /* QrCodeTest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 022B187814D1B5FE000503E2 /* Build configuration list for PBXNativeTarget "QrCodeTest" */; - buildPhases = ( - 022B185614D1B5FE000503E2 /* Sources */, - 022B185714D1B5FE000503E2 /* Frameworks */, - 022B185814D1B5FE000503E2 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 25FFF6BA183983E500C2E985 /* PBXTargetDependency */, - ); - name = QrCodeTest; - productName = QrCodeTest; - productReference = 022B185A14D1B5FE000503E2 /* QrCodeTest.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 022B185114D1B5FE000503E2 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0620; - ORGANIZATIONNAME = "Draconis Software"; - TargetAttributes = { - 022B185914D1B5FE000503E2 = { - DevelopmentTeam = 6N6S8VZUT9; - }; - }; - }; - buildConfigurationList = 022B185414D1B5FE000503E2 /* Build configuration list for PBXProject "QrCodeTest" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 022B184F14D1B5FE000503E2; - productRefGroup = 022B185B14D1B5FE000503E2 /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 25FFF6A8183983D400C2E985 /* Products */; - ProjectRef = 25FFF6A7183983D400C2E985 /* ZXingObjC.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 022B185914D1B5FE000503E2 /* QrCodeTest */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 027E588B1ABC5D4200C334CA /* ZXingObjC.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = ZXingObjC.framework; - remoteRef = 027E588A1ABC5D4200C334CA /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 25FFF6B0183983D400C2E985 /* libZXingObjC-iOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libZXingObjC-iOS.a"; - remoteRef = 25FFF6AF183983D400C2E985 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 25FFF6B2183983D400C2E985 /* Unit Tests iOS.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = "Unit Tests iOS.xctest"; - remoteRef = 25FFF6B1183983D400C2E985 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 25FFF6B4183983D400C2E985 /* libZXingObjC-osx.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libZXingObjC-osx.a"; - remoteRef = 25FFF6B3183983D400C2E985 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 25FFF6B6183983D400C2E985 /* Unit Tests OS X.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = "Unit Tests OS X.xctest"; - remoteRef = 25FFF6B5183983D400C2E985 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 25FFF6B8183983D400C2E985 /* ZXingObjC.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = ZXingObjC.framework; - remoteRef = 25FFF6B7183983D400C2E985 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 022B185814D1B5FE000503E2 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 022B186914D1B5FE000503E2 /* InfoPlist.strings in Resources */, - 026851F8151383A200394C7B /* ViewController.xib in Resources */, - 2540479B166AFC5900E13304 /* Default-568h@2x.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 022B185614D1B5FE000503E2 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 029BCCF715128A90009E6549 /* main.m in Sources */, - 029BCCF815128A92009E6549 /* ViewController.m in Sources */, - 029BCCF915128A94009E6549 /* AppDelegate.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 25FFF6BA183983E500C2E985 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "ZXingObjC-iOS"; - targetProxy = 25FFF6B9183983E500C2E985 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 022B186714D1B5FE000503E2 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 022B186814D1B5FE000503E2 /* en */, - ); - name = InfoPlist.strings; - sourceTree = SOURCE_ROOT; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 022B187614D1B5FE000503E2 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 022B187714D1B5FE000503E2 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; - OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 022B187914D1B5FE000503E2 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "QrCodeTest-Prefix.pch"; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../../**", - ); - INFOPLIST_FILE = "QrCodeTest-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - WRAPPER_EXTENSION = app; - }; - name = Debug; - }; - 022B187A14D1B5FE000503E2 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "QrCodeTest-Prefix.pch"; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(SRCROOT)/../../**", - ); - INFOPLIST_FILE = "QrCodeTest-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - WRAPPER_EXTENSION = app; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 022B185414D1B5FE000503E2 /* Build configuration list for PBXProject "QrCodeTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 022B187614D1B5FE000503E2 /* Debug */, - 022B187714D1B5FE000503E2 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 022B187814D1B5FE000503E2 /* Build configuration list for PBXNativeTarget "QrCodeTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 022B187914D1B5FE000503E2 /* Debug */, - 022B187A14D1B5FE000503E2 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 022B185114D1B5FE000503E2 /* Project object */; -} diff --git a/examples/QrCodeTest/QrCodeTest.xcodeproj/xcshareddata/xcschemes/QrCodeTest.xcscheme b/examples/QrCodeTest/QrCodeTest.xcodeproj/xcshareddata/xcschemes/QrCodeTest.xcscheme deleted file mode 100644 index 873ab47c1..000000000 --- a/examples/QrCodeTest/QrCodeTest.xcodeproj/xcshareddata/xcschemes/QrCodeTest.xcscheme +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/QrCodeTest/ViewController.m b/examples/QrCodeTest/ViewController.m deleted file mode 100644 index 4ccac6728..000000000 --- a/examples/QrCodeTest/ViewController.m +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import "ViewController.h" - -@implementation ViewController - -#pragma mark - View lifecycle - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - self.textView.text = @"http://github.com/TheLevelUp/ZXingObjC"; - [self updatePressed:nil]; -} - -#pragma mark - Events - -- (IBAction)updatePressed:(id)sender { - [self.textView resignFirstResponder]; - - NSString *data = self.textView.text; - if (data == 0) return; - - ZXMultiFormatWriter *writer = [[ZXMultiFormatWriter alloc] init]; - ZXBitMatrix *result = [writer encode:data - format:kBarcodeFormatQRCode - width:self.imageView.frame.size.width - height:self.imageView.frame.size.width - error:nil]; - - if (result) { - ZXImage *image = [ZXImage imageWithMatrix:result]; - self.imageView.image = [UIImage imageWithCGImage:image.cgimage]; - } else { - self.imageView.image = nil; - } -} - -@end diff --git a/examples/QrCodeTest/ViewController.xib b/examples/QrCodeTest/ViewController.xib deleted file mode 100644 index fa482333a..000000000 --- a/examples/QrCodeTest/ViewController.xib +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. - - - - - - - - - - - \ No newline at end of file diff --git a/examples/QrCodeTest/en.lproj/InfoPlist.strings b/examples/QrCodeTest/en.lproj/InfoPlist.strings deleted file mode 100644 index 477b28ff8..000000000 --- a/examples/QrCodeTest/en.lproj/InfoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -/* Localized versions of Info.plist keys */ - diff --git a/mac-Info.plist b/mac-Info.plist new file mode 100644 index 000000000..7add7c8e2 --- /dev/null +++ b/mac-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 3.2.1 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + +