Project import
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..fd5fa15
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,110 @@
+This project consists of contributions from several people, recognized here for convenience,
+in alphabetical order.
+
+Agustín Delgado (Servinform S.A.)
+Aitor Almeida (University of Deusto)
+Alasdair Mackintosh (Google)
+Alex Dupre
+Alexander Martin (Haase & Martin GmbH)
+Alexander Schmidt
+Anders Borg
+Andreas Pillath
+Andrew Walbran (Google)
+Andrey Sitnik
+Androida.hu / http://www.androida.hu/
+Antonio Manuel Benjumea (Servinform S.A.)
+Asier Iturralde
+Asmuri Anwar
+Betaminos
+Brian Brown (Google)
+Bruce Allen
+Chang Hyun Park
+Christian Brunschen (Google)
+Christoph Schulz (creatale GmbH)
+Costa Walcott (SCVNGR)
+crowdin.net
+Daniel Switkin (Google)
+Dave MacLachlan (Google)
+David Phillip Oster (Google)
+David Albert (Bug Labs)
+David Olivier
+David Walker (Google)
+Diego Pierotto
+Dion Hardy
+drejc83
+Eduardo Castillejo (University of Deusto)
+Emanuele Aina
+Eric Kobrin (Velocitude)
+evansepdx
+Erik Barbara
+Francois B. (Google)
+Fred Lin (Anobiit)
+gcstang
+Guenther Grau
+Guillaume Le Biller
+Hannes Erven
+Hartmut Neubauer (Schweers Informationstechnologie GmbH)
+hosigumayuugi
+hypest (Barcorama project)
+Ian W. Davis
+Isaac Potoczny-Jones
+Jacob Haynes (Google)
+Jeff Breidenbach (Google)
+Joan Montané (Softcatalà.cat)
+John Connolly (Bug Labs)
+Jonas Petersson (Prisjakt)
+Joseph Wain (Google)
+Juha Kuitunen
+Juho Mikkonen
+jwicks
+Kamil Kaczmarczyk
+Kazuki Nishiura
+Kevin O'Sullivan (SITA)
+Kevin Xue (NetDragon Websoft Inc., China)
+Lachezar Dobrev
+Luiz Silva
+Luka Finžgar
+Łukasz Stefaniak
+Malte Starostik
+Manuel Kasten
+Marcelo
+Mateusz Jędrasik
+Matrix44
+Matthew Schulkind (Google)
+Matt York (LifeMarks)
+mike32767
+mikej06
+Mohamad Fairol
+Morgan Courbet
+Nikolaos Ftylitakis
+Nikolaus Huber
+Olli
+Pablo Orduña (University of Deusto)
+Paul Hackenberger
+perennialmind
+Ralf Kistner
+Randy Shen (Acer)
+Rasmus Schrøder Sørensen
+Richard Hřivňák
+Romain Pechayre
+Roman Nurik (Google)
+Rustam Abdullaev
+Ryan Alford
+Sanford Squires
+Satoshi Kametaya
+Shachar Shemesh
+Sean Owen (Google)
+Shiyuan Guo / 郭世元
+ShumovichY
+Simon Flannery (Ericsson)
+Steven Parkes
+stoty74
+Suraj Supekar
+Sven Klinkhamer
+techinstantdx
+Thomas Gerbet
+Tim Gernat
+v.anestis
+Vince Francis (LifeMarks)
+Wolfgang Jung
+Yakov Okshtein (Google)
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..f9d4708
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,11 @@
+--------------------------------------------------------------------------------
+NOTICES FOR BARCODE4J
+--------------------------------------------------------------------------------
+
+Barcode4J
+Copyright 2002-2010 Jeremias Märki
+Copyright 2005-2006 Dietmar Bürkle
+
+Portions of this software were contributed under section 5 of the
+Apache License. Contributors are listed under:
+http://barcode4j.sourceforge.net/contributors.html
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..98912fd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,118 @@
+ZXingObjC
+=========
+
+ZXingObjC is a full Objective-C port of [ZXing](http://code.google.com/p/zxing/) ("Zebra Crossing"), a Java barcode image processing library. It is designed to be used on both iOS devices and in Mac applications.
+
+The following barcodes are currently supported for both encoding and decoding:
+
+* UPC-A and UPC-E
+* EAN-8 and EAN-13
+* Code 39
+* Code 93
+* Code 128
+* ITF
+* Codabar
+* RSS-14 (all variants)
+* QR Code
+* Data Matrix
+* Aztec ('beta' quality)
+* PDF 417 ('alpha' quality)
+
+ZXingObjC currently has feature parity with ZXing version 2.0.
+
+Usage
+----
+
+Encoding:
+
+```objc
+NSError* error = nil;
+ZXMultiFormatWriter* writer = [ZXMultiFormatWriter writer];
+ZXBitMatrix* result = [writer encode:@"A string to encode"
+ format:kBarcodeFormatQRCode
+ width:500
+ height:500
+ error:&error];
+if (result) {
+ CGImageRef image = [[ZXImage imageWithMatrix:result] cgimage];
+
+ // This CGImageRef image can be placed in a UIImage, NSImage, or written to a file.
+} else {
+ NSString* errorMessage = [error localizedDescription];
+}
+```
+
+Decoding:
+
+```objc
+CGImageRef imageToDecode; // Given a CGImage in which we are looking for barcodes
+
+ZXLuminanceSource* source = [[[ZXCGImageLuminanceSource alloc] initWithCGImage:imageToDecode] autorelease];
+ZXBinaryBitmap* bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]];
+
+NSError* error = nil;
+
+// There are a number of hints we can give to the reader, including
+// possible formats, allowed lengths, and the string encoding.
+ZXDecodeHints* hints = [ZXDecodeHints hints];
+
+ZXMultiFormatReader* reader = [ZXMultiFormatReader reader];
+ZXResult* result = [reader decode:bitmap
+ hints:hints
+ error:&error];
+if (result) {
+ // The coded result as a string. The raw data can be accessed with
+ // result.rawBytes and result.length.
+ NSString* contents = result.text;
+
+ // The barcode format, such as a QR code or UPC-A
+ ZXBarcodeFormat format = result.barcodeFormat;
+} else {
+ // Use error to determine why we didn't get a result, such as a barcode
+ // not being found, an invalid checksum, or a format inconsistency.
+}
+```
+
+Examples
+--------
+
+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.
+* QrCodeTest - A basic QR code generator that accepts input, encodes it as a QR code, and displays it on screen.
+
+Getting Started
+---------------
+> As a simpler alternative to adding files directly, you can consider using [CocoaPods](http://cocoapods.org) to add ZXingObjC as a dependency.
+
+1. [Download ZXingObjC](https://github.com/TheLevelUp/ZXingObjC/tarball/master) or clone it from git: `git clone git://github.com/TheLevelUp/ZXingObjC.git`.
+
+2. Drag the ZXingObjC folder onto Xcode. Make sure "Copy items" is checked before clicking "Add".
+
+3. Selecting your project in the left sidebar, select your target, and choose the "Build Phases" tab. Under "Link Binary With Libraries", add the appropriate frameworks for your architecture:
+
+ For an iOS app:
+ * AVFoundation.framework
+ * CoreGraphics.framework
+ * CoreMedia.framework
+ * CoreVideo.framework
+ * ImageIO.framework
+ * QuartzCore.framework
+
+ For a Mac app:
+ * ApplicationServices.framework
+ * CoreMedia.framework
+ * CoreVideo.framework
+ * QuartzCore.framework
+ * QTKit.framework
+
+4. Import the ZXingObjC framework header:
+
+```obj-c
+#import "ZXingObjC.h"
+```
+
+License
+-------
+
+ZXingObjC is available under the [Apache 2.0 license](http://www.apache.org/licenses/LICENSE-2.0.html).
diff --git a/ZXingObjC.podspec b/ZXingObjC.podspec
new file mode 100644
index 0000000..cdfe1d2
--- /dev/null
+++ b/ZXingObjC.podspec
@@ -0,0 +1,18 @@
+Pod::Spec.new do |s|
+ s.name = "ZXingObjC"
+ s.version = "2.2.3"
+ s.summary = "An Objective-C Port of ZXing."
+ s.homepage = "https://github.com/TheLevelUp/ZXingObjC"
+ s.author = "ZXing team (http://code.google.com/p/zxing/people/list) and TheLevelUp"
+
+ s.license = { :type => 'Apache License 2.0', :file => 'COPYING' }
+
+ s.source = { :git => "https://github.com/TheLevelUp/ZXingObjC.git", :tag => "2.2.3" }
+ s.ios.deployment_target = '5.0'
+ s.osx.deployment_target = '10.7'
+
+ s.source_files = 'ZXingObjC/**/*.{h,m}'
+ s.requires_arc = true
+
+ s.frameworks = 'ImageIO', 'CoreGraphics', 'CoreVideo', 'CoreMedia', 'QuartzCore', 'AVFoundation', 'AudioToolbox'
+end
diff --git a/ZXingObjC.xcodeproj/project.pbxproj b/ZXingObjC.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..46d3b38
--- /dev/null
+++ b/ZXingObjC.xcodeproj/project.pbxproj
@@ -0,0 +1,6085 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 024957F31898641B003D4E6A /* AztecBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FEF166AA0F100E13304 /* AztecBlackBox1TestCase.m */; };
+ 024957F41898641B003D4E6A /* AztecBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FF1166AA0F100E13304 /* AztecBlackBox2TestCase.m */; };
+ 024957FB1898641B003D4E6A /* PDF417BlackBox4TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B582981816F7B00013634A /* PDF417BlackBox4TestCase.m */; };
+ 024958021898641B003D4E6A /* AbstractBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540400E166AA0F100E13304 /* AbstractBlackBoxTestCase.m */; };
+ 024958031898641B003D4E6A /* AbstractNegativeBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404010166AA0F100E13304 /* AbstractNegativeBlackBoxTestCase.m */; };
+ 024958041898641B003D4E6A /* TestResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540401B166AA0F100E13304 /* TestResult.m */; };
+ 0249580B1898641B003D4E6A /* DataMatrixBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540402A166AA0F100E13304 /* DataMatrixBlackBox1TestCase.m */; };
+ 0249580C1898641B003D4E6A /* DataMatrixBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540402C166AA0F100E13304 /* DataMatrixBlackBox2TestCase.m */; };
+ 0249580E1898641B003D4E6A /* FalsePositives2BlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404032166AA0F100E13304 /* FalsePositives2BlackBoxTestCase.m */; };
+ 0249580F1898641B003D4E6A /* FalsePositivesBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404034166AA0F100E13304 /* FalsePositivesBlackBoxTestCase.m */; };
+ 024958101898641B003D4E6A /* PartialBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404036166AA0F100E13304 /* PartialBlackBoxTestCase.m */; };
+ 024958111898641B003D4E6A /* UnsupportedBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404038166AA0F100E13304 /* UnsupportedBlackBoxTestCase.m */; };
+ 024958121898641B003D4E6A /* CodabarBlackbox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540403B166AA0F100E13304 /* CodabarBlackbox1TestCase.m */; };
+ 024958131898641B003D4E6A /* PDF417BlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E9E91817FA555400364861 /* PDF417BlackBox3TestCase.m */; };
+ 024958141898641B003D4E6A /* Code128BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540403D166AA0F100E13304 /* Code128BlackBox1TestCase.m */; };
+ 024958151898641B003D4E6A /* Code128BlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540403F166AA0F100E13304 /* Code128BlackBox2TestCase.m */; };
+ 024958161898641B003D4E6A /* Code128BlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404041166AA0F100E13304 /* Code128BlackBox3TestCase.m */; };
+ 024958171898641B003D4E6A /* Code39BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404043166AA0F100E13304 /* Code39BlackBox1TestCase.m */; };
+ 024958181898641B003D4E6A /* Code39BlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404045166AA0F100E13304 /* Code39BlackBox3TestCase.m */; };
+ 024958191898641B003D4E6A /* Code39ExtendedBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404047166AA0F100E13304 /* Code39ExtendedBlackBox2TestCase.m */; };
+ 0249581A1898641B003D4E6A /* Code93BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404049166AA0F100E13304 /* Code93BlackBox1TestCase.m */; };
+ 0249581B1898641B003D4E6A /* EAN13BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540404B166AA0F100E13304 /* EAN13BlackBox1TestCase.m */; };
+ 0249581C1898641B003D4E6A /* EAN13BlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540404D166AA0F100E13304 /* EAN13BlackBox2TestCase.m */; };
+ 0249581D1898641B003D4E6A /* EAN13BlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540404F166AA0F100E13304 /* EAN13BlackBox3TestCase.m */; };
+ 0249581E1898641B003D4E6A /* EAN13BlackBox4TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404051166AA0F100E13304 /* EAN13BlackBox4TestCase.m */; };
+ 0249581F1898641B003D4E6A /* EAN13BlackBox5BlurryTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404053166AA0F100E13304 /* EAN13BlackBox5BlurryTestCase.m */; };
+ 024958201898641B003D4E6A /* EAN8BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404055166AA0F100E13304 /* EAN8BlackBox1TestCase.m */; };
+ 024958211898641B003D4E6A /* ITFBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404057166AA0F100E13304 /* ITFBlackBox1TestCase.m */; };
+ 024958221898641B003D4E6A /* ITFBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404059166AA0F100E13304 /* ITFBlackBox2TestCase.m */; };
+ 024958291898641B003D4E6A /* RSSExpandedBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540406A166AA0F100E13304 /* RSSExpandedBlackBox1TestCase.m */; };
+ 0249582A1898641B003D4E6A /* RSSExpandedBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540406C166AA0F100E13304 /* RSSExpandedBlackBox2TestCase.m */; };
+ 0249582B1898641B003D4E6A /* RSSExpandedBlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540406E166AA0F100E13304 /* RSSExpandedBlackBox3TestCase.m */; };
+ 0249582C1898641B003D4E6A /* RSSExpandedImage2binaryTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404070166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.m */; };
+ 0249582D1898641B003D4E6A /* RSSExpandedImage2resultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404072166AA0F100E13304 /* RSSExpandedImage2resultTestCase.m */; };
+ 0249582E1898641B003D4E6A /* RSSExpandedImage2stringTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404074166AA0F100E13304 /* RSSExpandedImage2stringTestCase.m */; };
+ 0249582F1898641B003D4E6A /* RSSExpandedInternalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404076166AA0F100E13304 /* RSSExpandedInternalTestCase.m */; };
+ 024958341898641B003D4E6A /* RSS14BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404080166AA0F100E13304 /* RSS14BlackBox1TestCase.m */; };
+ 024958351898641B003D4E6A /* RSS14BlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404082166AA0F100E13304 /* RSS14BlackBox2TestCase.m */; };
+ 024958361898641B003D4E6A /* UPCABlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404084166AA0F100E13304 /* UPCABlackBox1TestCase.m */; };
+ 024958371898641B003D4E6A /* UPCABlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404086166AA0F100E13304 /* UPCABlackBox2TestCase.m */; };
+ 024958381898641B003D4E6A /* UPCABlackBox3ReflectiveTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404088166AA0F100E13304 /* UPCABlackBox3ReflectiveTestCase.m */; };
+ 024958391898641B003D4E6A /* UPCABlackBox4TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540408A166AA0F100E13304 /* UPCABlackBox4TestCase.m */; };
+ 0249583A1898641B003D4E6A /* UPCABlackBox5TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540408C166AA0F100E13304 /* UPCABlackBox5TestCase.m */; };
+ 0249583B1898641B003D4E6A /* UPCABlackBox6BlurryTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540408E166AA0F100E13304 /* UPCABlackBox6BlurryTestCase.m */; };
+ 0249583C1898641B003D4E6A /* UPCEANExtensionBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404090166AA0F100E13304 /* UPCEANExtensionBlackBox1TestCase.m */; };
+ 0249583D1898641B003D4E6A /* UPCEBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404092166AA0F100E13304 /* UPCEBlackBox1TestCase.m */; };
+ 0249583E1898641B003D4E6A /* UPCEBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404094166AA0F100E13304 /* UPCEBlackBox2TestCase.m */; };
+ 0249583F1898641B003D4E6A /* UPCEBlackBox3ReflectiveTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404096166AA0F100E13304 /* UPCEBlackBox3ReflectiveTestCase.m */; };
+ 024958451898641B003D4E6A /* AbstractErrorCorrectionTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040A9166AA0F100E13304 /* AbstractErrorCorrectionTestCase.m */; };
+ 024958471898641B003D4E6A /* PDF417BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040AD166AA0F100E13304 /* PDF417BlackBox1TestCase.m */; };
+ 024958481898641B003D4E6A /* PDF417BlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040AF166AA0F100E13304 /* PDF417BlackBox2TestCase.m */; };
+ 024958541898641B003D4E6A /* QRCodeBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040CA166AA0F100E13304 /* QRCodeBlackBox1TestCase.m */; };
+ 024958551898641B003D4E6A /* QRCodeBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040CC166AA0F100E13304 /* QRCodeBlackBox2TestCase.m */; };
+ 024958561898641B003D4E6A /* QRCodeBlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040CE166AA0F100E13304 /* QRCodeBlackBox3TestCase.m */; };
+ 024958581898641B003D4E6A /* QRCodeBlackBox4TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040D0166AA0F100E13304 /* QRCodeBlackBox4TestCase.m */; };
+ 024958591898641B003D4E6A /* QRCodeBlackBox5TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040D2166AA0F100E13304 /* QRCodeBlackBox5TestCase.m */; };
+ 0249585A1898641B003D4E6A /* QRCodeBlackBox6TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040D4166AA0F100E13304 /* QRCodeBlackBox6TestCase.m */; };
+ 0249585C1898641B003D4E6A /* RSSExpandedStackedBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3916D0B82F00826CDB /* RSSExpandedStackedBlackBox1TestCase.m */; };
+ 0249585D1898641B003D4E6A /* RSSExpandedStackedBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3B16D0B83000826CDB /* RSSExpandedStackedBlackBox2TestCase.m */; };
+ 024958691898641B003D4E6A /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540471A166AC21000E13304 /* AVFoundation.framework */; };
+ 0249586A1898641B003D4E6A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540414E166AA33700E13304 /* CoreGraphics.framework */; };
+ 0249586B1898641B003D4E6A /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540415E166AAA2F00E13304 /* CoreVideo.framework */; };
+ 0249586C1898641B003D4E6A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25403CB6166A96FA00E13304 /* Foundation.framework */; };
+ 0249586D1898641B003D4E6A /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540415B166AA86900E13304 /* ImageIO.framework */; };
+ 0249586E1898641B003D4E6A /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25403CC5166A96FA00E13304 /* SenTestingKit.framework */; };
+ 0249586F1898641B003D4E6A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404145166AA16200E13304 /* UIKit.framework */; };
+ 024958701898641B003D4E6A /* libZXingObjC-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 25403CB3166A96FA00E13304 /* libZXingObjC-iOS.a */; };
+ 024958721898641B003D4E6A /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 25FE5D4416D1997C00826CDB /* Resources */; };
+ 02B4884A17F5F10000E6285D /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 25FE5D4416D1997C00826CDB /* Resources */; };
+ 02D81373189864C70081721D /* RSSExpandedStackedBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3916D0B82F00826CDB /* RSSExpandedStackedBlackBox1TestCase.m */; };
+ 02D81374189864C70081721D /* RSSExpandedStackedBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3B16D0B83000826CDB /* RSSExpandedStackedBlackBox2TestCase.m */; };
+ 02D81375189864C70081721D /* RSSExpandedStackedInternalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3F16D0B84C00826CDB /* RSSExpandedStackedInternalTestCase.m */; };
+ 02D81377189864C70081721D /* AztecBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FEF166AA0F100E13304 /* AztecBlackBox1TestCase.m */; };
+ 02D81378189864C70081721D /* AztecBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FF1166AA0F100E13304 /* AztecBlackBox2TestCase.m */; };
+ 02D8137B189864C70081721D /* PDF417BlackBox4TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25B582981816F7B00013634A /* PDF417BlackBox4TestCase.m */; };
+ 02D81386189864C70081721D /* AbstractBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540400E166AA0F100E13304 /* AbstractBlackBoxTestCase.m */; };
+ 02D81387189864C70081721D /* PDF417BlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25E9E91817FA555400364861 /* PDF417BlackBox3TestCase.m */; };
+ 02D81388189864C70081721D /* AbstractNegativeBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404010166AA0F100E13304 /* AbstractNegativeBlackBoxTestCase.m */; };
+ 02D81389189864C70081721D /* TestResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540401B166AA0F100E13304 /* TestResult.m */; };
+ 02D81390189864C70081721D /* DataMatrixBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540402A166AA0F100E13304 /* DataMatrixBlackBox1TestCase.m */; };
+ 02D81391189864C70081721D /* DataMatrixBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540402C166AA0F100E13304 /* DataMatrixBlackBox2TestCase.m */; };
+ 02D81393189864C70081721D /* FalsePositives2BlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404032166AA0F100E13304 /* FalsePositives2BlackBoxTestCase.m */; };
+ 02D81394189864C70081721D /* FalsePositivesBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404034166AA0F100E13304 /* FalsePositivesBlackBoxTestCase.m */; };
+ 02D81395189864C70081721D /* PartialBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404036166AA0F100E13304 /* PartialBlackBoxTestCase.m */; };
+ 02D81396189864C70081721D /* UnsupportedBlackBoxTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404038166AA0F100E13304 /* UnsupportedBlackBoxTestCase.m */; };
+ 02D81397189864C70081721D /* CodabarBlackbox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540403B166AA0F100E13304 /* CodabarBlackbox1TestCase.m */; };
+ 02D81398189864C70081721D /* Code128BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540403D166AA0F100E13304 /* Code128BlackBox1TestCase.m */; };
+ 02D81399189864C70081721D /* Code128BlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540403F166AA0F100E13304 /* Code128BlackBox2TestCase.m */; };
+ 02D8139A189864C70081721D /* Code128BlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404041166AA0F100E13304 /* Code128BlackBox3TestCase.m */; };
+ 02D8139B189864C70081721D /* Code39BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404043166AA0F100E13304 /* Code39BlackBox1TestCase.m */; };
+ 02D8139C189864C70081721D /* Code39BlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404045166AA0F100E13304 /* Code39BlackBox3TestCase.m */; };
+ 02D8139D189864C70081721D /* Code39ExtendedBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404047166AA0F100E13304 /* Code39ExtendedBlackBox2TestCase.m */; };
+ 02D8139E189864C70081721D /* Code93BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404049166AA0F100E13304 /* Code93BlackBox1TestCase.m */; };
+ 02D8139F189864C70081721D /* EAN13BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540404B166AA0F100E13304 /* EAN13BlackBox1TestCase.m */; };
+ 02D813A0189864C70081721D /* EAN13BlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540404D166AA0F100E13304 /* EAN13BlackBox2TestCase.m */; };
+ 02D813A1189864C70081721D /* EAN13BlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540404F166AA0F100E13304 /* EAN13BlackBox3TestCase.m */; };
+ 02D813A2189864C70081721D /* EAN13BlackBox4TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404051166AA0F100E13304 /* EAN13BlackBox4TestCase.m */; };
+ 02D813A3189864C70081721D /* EAN13BlackBox5BlurryTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404053166AA0F100E13304 /* EAN13BlackBox5BlurryTestCase.m */; };
+ 02D813A4189864C70081721D /* EAN8BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404055166AA0F100E13304 /* EAN8BlackBox1TestCase.m */; };
+ 02D813A5189864C70081721D /* ITFBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404057166AA0F100E13304 /* ITFBlackBox1TestCase.m */; };
+ 02D813A6189864C70081721D /* ITFBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404059166AA0F100E13304 /* ITFBlackBox2TestCase.m */; };
+ 02D813AD189864C70081721D /* RSSExpandedBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540406A166AA0F100E13304 /* RSSExpandedBlackBox1TestCase.m */; };
+ 02D813AE189864C70081721D /* RSSExpandedBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540406C166AA0F100E13304 /* RSSExpandedBlackBox2TestCase.m */; };
+ 02D813AF189864C70081721D /* RSSExpandedBlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540406E166AA0F100E13304 /* RSSExpandedBlackBox3TestCase.m */; };
+ 02D813B0189864C70081721D /* RSSExpandedImage2binaryTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404070166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.m */; };
+ 02D813B1189864C70081721D /* RSSExpandedImage2resultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404072166AA0F100E13304 /* RSSExpandedImage2resultTestCase.m */; };
+ 02D813B2189864C70081721D /* RSSExpandedImage2stringTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404074166AA0F100E13304 /* RSSExpandedImage2stringTestCase.m */; };
+ 02D813B3189864C70081721D /* RSSExpandedInternalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404076166AA0F100E13304 /* RSSExpandedInternalTestCase.m */; };
+ 02D813B8189864C70081721D /* RSS14BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404080166AA0F100E13304 /* RSS14BlackBox1TestCase.m */; };
+ 02D813B9189864C70081721D /* RSS14BlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404082166AA0F100E13304 /* RSS14BlackBox2TestCase.m */; };
+ 02D813BA189864C70081721D /* UPCABlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404084166AA0F100E13304 /* UPCABlackBox1TestCase.m */; };
+ 02D813BB189864C70081721D /* UPCABlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404086166AA0F100E13304 /* UPCABlackBox2TestCase.m */; };
+ 02D813BC189864C70081721D /* UPCABlackBox3ReflectiveTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404088166AA0F100E13304 /* UPCABlackBox3ReflectiveTestCase.m */; };
+ 02D813BD189864C70081721D /* UPCABlackBox4TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540408A166AA0F100E13304 /* UPCABlackBox4TestCase.m */; };
+ 02D813BE189864C70081721D /* UPCABlackBox5TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540408C166AA0F100E13304 /* UPCABlackBox5TestCase.m */; };
+ 02D813BF189864C70081721D /* UPCABlackBox6BlurryTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540408E166AA0F100E13304 /* UPCABlackBox6BlurryTestCase.m */; };
+ 02D813C0189864C70081721D /* UPCEANExtensionBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404090166AA0F100E13304 /* UPCEANExtensionBlackBox1TestCase.m */; };
+ 02D813C1189864C70081721D /* UPCEBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404092166AA0F100E13304 /* UPCEBlackBox1TestCase.m */; };
+ 02D813C2189864C70081721D /* UPCEBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404094166AA0F100E13304 /* UPCEBlackBox2TestCase.m */; };
+ 02D813C3189864C70081721D /* UPCEBlackBox3ReflectiveTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404096166AA0F100E13304 /* UPCEBlackBox3ReflectiveTestCase.m */; };
+ 02D813CB189864C70081721D /* PDF417BlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040AD166AA0F100E13304 /* PDF417BlackBox1TestCase.m */; };
+ 02D813CC189864C70081721D /* PDF417BlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040AF166AA0F100E13304 /* PDF417BlackBox2TestCase.m */; };
+ 02D813D8189864C70081721D /* QRCodeBlackBox1TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040CA166AA0F100E13304 /* QRCodeBlackBox1TestCase.m */; };
+ 02D813D9189864C70081721D /* QRCodeBlackBox2TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040CC166AA0F100E13304 /* QRCodeBlackBox2TestCase.m */; };
+ 02D813DA189864C70081721D /* QRCodeBlackBox3TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040CE166AA0F100E13304 /* QRCodeBlackBox3TestCase.m */; };
+ 02D813DC189864C70081721D /* QRCodeBlackBox4TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040D0166AA0F100E13304 /* QRCodeBlackBox4TestCase.m */; };
+ 02D813DD189864C70081721D /* QRCodeBlackBox5TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040D2166AA0F100E13304 /* QRCodeBlackBox5TestCase.m */; };
+ 02D813DE189864C70081721D /* QRCodeBlackBox6TestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040D4166AA0F100E13304 /* QRCodeBlackBox6TestCase.m */; };
+ 02D813E9189864C70081721D /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404700166ABC3F00E13304 /* QTKit.framework */; };
+ 02D813EA189864C70081721D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 254046FC166ABC1600E13304 /* QuartzCore.framework */; };
+ 02D813EB189864C70081721D /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404394166AB95700E13304 /* ApplicationServices.framework */; };
+ 02D813EC189864C70081721D /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404387166AB8CF00E13304 /* CoreVideo.framework */; };
+ 02D813ED189864C70081721D /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25403CC5166A96FA00E13304 /* SenTestingKit.framework */; };
+ 02D813EE189864C70081721D /* libZXingObjC-osx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404166166AADAC00E13304 /* libZXingObjC-osx.a */; };
+ 02D813F0189864C70081721D /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 25FE5D4416D1997C00826CDB /* Resources */; };
+ 2504D4C616F698AA00DF8882 /* ZXInvertedLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504D4C416F698AA00DF8882 /* ZXInvertedLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2504D4C716F698AA00DF8882 /* ZXInvertedLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D4C516F698AA00DF8882 /* ZXInvertedLuminanceSource.m */; };
+ 2504D4C816F698BE00DF8882 /* ZXInvertedLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504D4C416F698AA00DF8882 /* ZXInvertedLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2504D4CA16F698C900DF8882 /* ZXInvertedLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D4C516F698AA00DF8882 /* ZXInvertedLuminanceSource.m */; };
+ 2504D4CB16F698C900DF8882 /* ZXInvertedLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D4C516F698AA00DF8882 /* ZXInvertedLuminanceSource.m */; };
+ 2504D9CF16FFD2E200DF8882 /* ZXAztecCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504D9CD16FFD2E200DF8882 /* ZXAztecCode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 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 */; };
+ 2504D9D416FFD3B300DF8882 /* ZXAztecCode.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9CE16FFD2E200DF8882 /* ZXAztecCode.m */; };
+ 2504D9DC16FFD4CD00DF8882 /* ZXAztecEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504D9DA16FFD4CD00DF8882 /* ZXAztecEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2504D9DD16FFD4CD00DF8882 /* ZXAztecEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9DB16FFD4CD00DF8882 /* ZXAztecEncoder.m */; };
+ 2504D9DF16FFEB7A00DF8882 /* ZXAztecEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9DB16FFD4CD00DF8882 /* ZXAztecEncoder.m */; };
+ 2504D9E016FFEB7B00DF8882 /* ZXAztecEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9DB16FFD4CD00DF8882 /* ZXAztecEncoder.m */; };
+ 2504D9E216FFEB8100DF8882 /* ZXAztecEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504D9DA16FFD4CD00DF8882 /* ZXAztecEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2504D9E816FFF27C00DF8882 /* ZXAztecEncoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9E516FFF27C00DF8882 /* ZXAztecEncoderTest.m */; };
+ 2504D9E916FFF2A900DF8882 /* ZXAztecEncoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9E516FFF27C00DF8882 /* ZXAztecEncoderTest.m */; };
+ 2504D9EC170005FE00DF8882 /* ReedSolomonTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9EB170005FE00DF8882 /* ReedSolomonTestCase.m */; };
+ 2504D9ED170005FE00DF8882 /* ReedSolomonTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2504D9EB170005FE00DF8882 /* ReedSolomonTestCase.m */; };
+ 2519AB3417FD1EC000A71C45 /* ZXAztecWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB3217FD1EC000A71C45 /* ZXAztecWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB3517FD1EC000A71C45 /* ZXAztecWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB3217FD1EC000A71C45 /* ZXAztecWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB3717FD1EC000A71C45 /* ZXAztecWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB3317FD1EC000A71C45 /* ZXAztecWriter.m */; };
+ 2519AB3817FD1EC000A71C45 /* ZXAztecWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB3317FD1EC000A71C45 /* ZXAztecWriter.m */; };
+ 2519AB3917FD1EC000A71C45 /* ZXAztecWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB3317FD1EC000A71C45 /* ZXAztecWriter.m */; };
+ 2519AB3C17FD1EE400A71C45 /* ZXPDF417Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB3A17FD1EE400A71C45 /* ZXPDF417Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB3D17FD1EE400A71C45 /* ZXPDF417Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB3A17FD1EE400A71C45 /* ZXPDF417Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB3F17FD1EE400A71C45 /* ZXPDF417Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB3B17FD1EE400A71C45 /* ZXPDF417Writer.m */; };
+ 2519AB4017FD1EE400A71C45 /* ZXPDF417Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB3B17FD1EE400A71C45 /* ZXPDF417Writer.m */; };
+ 2519AB4117FD1EE400A71C45 /* ZXPDF417Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB3B17FD1EE400A71C45 /* ZXPDF417Writer.m */; };
+ 2519AB4417FE554D00A71C45 /* ZXPDF417Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB4217FE554D00A71C45 /* ZXPDF417Common.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB4517FE554D00A71C45 /* ZXPDF417Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB4317FE554D00A71C45 /* ZXPDF417Common.m */; };
+ 2519AB4817FE5C1F00A71C45 /* ZXPDF417ResultMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB4617FE5C1F00A71C45 /* ZXPDF417ResultMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB4917FE5C1F00A71C45 /* ZXPDF417ResultMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB4717FE5C1F00A71C45 /* ZXPDF417ResultMetadata.m */; };
+ 2519AB4A17FE5C2E00A71C45 /* ZXPDF417ResultMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB4717FE5C1F00A71C45 /* ZXPDF417ResultMetadata.m */; };
+ 2519AB4B17FE5C2E00A71C45 /* ZXPDF417ResultMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB4717FE5C1F00A71C45 /* ZXPDF417ResultMetadata.m */; };
+ 2519AB4C17FE5C3100A71C45 /* ZXPDF417Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB4317FE554D00A71C45 /* ZXPDF417Common.m */; };
+ 2519AB4D17FE5C3100A71C45 /* ZXPDF417Common.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB4317FE554D00A71C45 /* ZXPDF417Common.m */; };
+ 2519AB5017FE5C4500A71C45 /* ZXPDF417Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB4217FE554D00A71C45 /* ZXPDF417Common.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB5217FE5C5400A71C45 /* ZXPDF417ResultMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB4617FE5C1F00A71C45 /* ZXPDF417ResultMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB5E17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB5C17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB5F17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB5C17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB6117FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB5D17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m */; };
+ 2519AB6217FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB5D17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m */; };
+ 2519AB6317FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB5D17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m */; };
+ 2519AB6617FE5F2E00A71C45 /* ZXPDF417BarcodeValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB6417FE5F2E00A71C45 /* ZXPDF417BarcodeValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB6717FE5F2E00A71C45 /* ZXPDF417BarcodeValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB6417FE5F2E00A71C45 /* ZXPDF417BarcodeValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB6917FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB6517FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m */; };
+ 2519AB6A17FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB6517FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m */; };
+ 2519AB6B17FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB6517FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m */; };
+ 2519AB6E17FE60E700A71C45 /* ZXPDF417BoundingBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB6C17FE60E700A71C45 /* ZXPDF417BoundingBox.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB6F17FE60E700A71C45 /* ZXPDF417BoundingBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB6C17FE60E700A71C45 /* ZXPDF417BoundingBox.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB7117FE60E700A71C45 /* ZXPDF417BoundingBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB6D17FE60E700A71C45 /* ZXPDF417BoundingBox.m */; };
+ 2519AB7217FE60E700A71C45 /* ZXPDF417BoundingBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB6D17FE60E700A71C45 /* ZXPDF417BoundingBox.m */; };
+ 2519AB7317FE60E700A71C45 /* ZXPDF417BoundingBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB6D17FE60E700A71C45 /* ZXPDF417BoundingBox.m */; };
+ 2519AB7617FE649000A71C45 /* ZXPDF417Codeword.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB7417FE649000A71C45 /* ZXPDF417Codeword.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB7717FE649000A71C45 /* ZXPDF417Codeword.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB7417FE649000A71C45 /* ZXPDF417Codeword.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2519AB7917FE649000A71C45 /* ZXPDF417Codeword.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB7517FE649000A71C45 /* ZXPDF417Codeword.m */; };
+ 2519AB7A17FE649000A71C45 /* ZXPDF417Codeword.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB7517FE649000A71C45 /* ZXPDF417Codeword.m */; };
+ 2519AB7B17FE649000A71C45 /* ZXPDF417Codeword.m in Sources */ = {isa = PBXBuildFile; fileRef = 2519AB7517FE649000A71C45 /* ZXPDF417Codeword.m */; };
+ 251FCDEB16CC8F53000C27E5 /* ZXRGBLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 251FCDE916CC8F53000C27E5 /* ZXRGBLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 251FCDEC16CC8F53000C27E5 /* ZXRGBLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 251FCDE916CC8F53000C27E5 /* ZXRGBLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 251FCDED16CC8F53000C27E5 /* ZXRGBLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 251FCDEA16CC8F53000C27E5 /* ZXRGBLuminanceSource.m */; };
+ 251FCDEE16CC8F53000C27E5 /* ZXRGBLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 251FCDEA16CC8F53000C27E5 /* ZXRGBLuminanceSource.m */; };
+ 251FCDF016CC8F7C000C27E5 /* ZXRGBLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 251FCDEA16CC8F53000C27E5 /* ZXRGBLuminanceSource.m */; };
+ 25389B6017FFC84300772392 /* ZXPDF417DetectionResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B5E17FFC84300772392 /* ZXPDF417DetectionResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B6117FFC84300772392 /* ZXPDF417DetectionResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B5E17FFC84300772392 /* ZXPDF417DetectionResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B6217FFC84300772392 /* ZXPDF417DetectionResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B5F17FFC84300772392 /* ZXPDF417DetectionResult.m */; };
+ 25389B6317FFC84300772392 /* ZXPDF417DetectionResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B5F17FFC84300772392 /* ZXPDF417DetectionResult.m */; };
+ 25389B6417FFC84800772392 /* ZXPDF417DetectionResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B5F17FFC84300772392 /* ZXPDF417DetectionResult.m */; };
+ 25389B6517FFC84F00772392 /* ZXPDF417DecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F23166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B6917FFC98100772392 /* ZXPDF417DetectionResultColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B6717FFC98100772392 /* ZXPDF417DetectionResultColumn.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B6A17FFC98100772392 /* ZXPDF417DetectionResultColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B6717FFC98100772392 /* ZXPDF417DetectionResultColumn.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B6C17FFC98100772392 /* ZXPDF417DetectionResultColumn.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B6817FFC98100772392 /* ZXPDF417DetectionResultColumn.m */; };
+ 25389B6D17FFC98100772392 /* ZXPDF417DetectionResultColumn.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B6817FFC98100772392 /* ZXPDF417DetectionResultColumn.m */; };
+ 25389B6E17FFC98100772392 /* ZXPDF417DetectionResultColumn.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B6817FFC98100772392 /* ZXPDF417DetectionResultColumn.m */; };
+ 25389B7117FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B6F17FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B7217FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B6F17FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B7417FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B7017FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m */; };
+ 25389B7517FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B7017FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m */; };
+ 25389B7617FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B7017FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m */; };
+ 25389B791800DEC300772392 /* ZXPDF417CodewordDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B771800DEC300772392 /* ZXPDF417CodewordDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B7A1800DEC300772392 /* ZXPDF417CodewordDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B771800DEC300772392 /* ZXPDF417CodewordDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B7C1800DEC300772392 /* ZXPDF417CodewordDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B781800DEC300772392 /* ZXPDF417CodewordDecoder.m */; };
+ 25389B7D1800DEC300772392 /* ZXPDF417CodewordDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B781800DEC300772392 /* ZXPDF417CodewordDecoder.m */; };
+ 25389B7E1800DEC300772392 /* ZXPDF417CodewordDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B781800DEC300772392 /* ZXPDF417CodewordDecoder.m */; };
+ 25389B811800E35B00772392 /* ZXPDF417ScanningDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B7F1800E35B00772392 /* ZXPDF417ScanningDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B821800E35B00772392 /* ZXPDF417ScanningDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B7F1800E35B00772392 /* ZXPDF417ScanningDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B841800E35B00772392 /* ZXPDF417ScanningDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B801800E35B00772392 /* ZXPDF417ScanningDecoder.m */; };
+ 25389B851800E35B00772392 /* ZXPDF417ScanningDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B801800E35B00772392 /* ZXPDF417ScanningDecoder.m */; };
+ 25389B861800E35B00772392 /* ZXPDF417ScanningDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B801800E35B00772392 /* ZXPDF417ScanningDecoder.m */; };
+ 25389B8918010B9A00772392 /* ZXPDF417DetectorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B8718010B9A00772392 /* ZXPDF417DetectorResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B8A18010B9A00772392 /* ZXPDF417DetectorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B8718010B9A00772392 /* ZXPDF417DetectorResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25389B8C18010B9A00772392 /* ZXPDF417DetectorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B8818010B9A00772392 /* ZXPDF417DetectorResult.m */; };
+ 25389B8D18010B9A00772392 /* ZXPDF417DetectorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B8818010B9A00772392 /* ZXPDF417DetectorResult.m */; };
+ 25389B8E18010B9A00772392 /* ZXPDF417DetectorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B8818010B9A00772392 /* ZXPDF417DetectorResult.m */; };
+ 25389B9818010DCB00772392 /* ZXPDF417DetectorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B9118010D9B00772392 /* ZXPDF417DetectorTest.m */; };
+ 25389B9918010DCB00772392 /* ZXPDF417DetectorTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25389B9118010D9B00772392 /* ZXPDF417DetectorTest.m */; };
+ 25403CB7166A96FA00E13304 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25403CB6166A96FA00E13304 /* Foundation.framework */; };
+ 25403CC6166A96FA00E13304 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25403CC5166A96FA00E13304 /* SenTestingKit.framework */; };
+ 25403CC9166A96FA00E13304 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25403CB6166A96FA00E13304 /* Foundation.framework */; };
+ 25403CCC166A96FA00E13304 /* libZXingObjC-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 25403CB3166A96FA00E13304 /* libZXingObjC-iOS.a */; };
+ 25403CE3166A98C700E13304 /* ZXingObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CBB166A96FA00E13304 /* ZXingObjC.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403CF7166A999D00E13304 /* ZXAztecDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CEE166A999D00E13304 /* ZXAztecDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403CF8166A999D00E13304 /* ZXAztecDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CEF166A999D00E13304 /* ZXAztecDecoder.m */; };
+ 25403CF9166A999D00E13304 /* ZXAztecDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CF1166A999D00E13304 /* ZXAztecDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403CFA166A999D00E13304 /* ZXAztecDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF2166A999D00E13304 /* ZXAztecDetector.m */; };
+ 25403CFB166A999D00E13304 /* ZXAztecDetectorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CF3166A999D00E13304 /* ZXAztecDetectorResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403CFC166A999D00E13304 /* ZXAztecDetectorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF4166A999D00E13304 /* ZXAztecDetectorResult.m */; };
+ 25403CFD166A999D00E13304 /* ZXAztecReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CF5166A999D00E13304 /* ZXAztecReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403CFE166A999D00E13304 /* ZXAztecReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF6166A999D00E13304 /* ZXAztecReader.m */; };
+ 25403D50166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D01166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D51166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D02166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.m */; };
+ 25403D52166A9A0800E13304 /* ZXAddressBookAUResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D03166A9A0800E13304 /* ZXAddressBookAUResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D53166A9A0800E13304 /* ZXAddressBookAUResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D04166A9A0800E13304 /* ZXAddressBookAUResultParser.m */; };
+ 25403D54166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D05166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D55166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D06166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.m */; };
+ 25403D56166A9A0800E13304 /* ZXAddressBookParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D07166A9A0800E13304 /* ZXAddressBookParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D57166A9A0800E13304 /* ZXAddressBookParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D08166A9A0800E13304 /* ZXAddressBookParsedResult.m */; };
+ 25403D58166A9A0800E13304 /* ZXBizcardResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D09166A9A0800E13304 /* ZXBizcardResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D59166A9A0800E13304 /* ZXBizcardResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D0A166A9A0800E13304 /* ZXBizcardResultParser.m */; };
+ 25403D5A166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D0B166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D5B166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D0C166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.m */; };
+ 25403D5C166A9A0800E13304 /* ZXCalendarParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D0D166A9A0800E13304 /* ZXCalendarParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D5D166A9A0800E13304 /* ZXCalendarParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D0E166A9A0800E13304 /* ZXCalendarParsedResult.m */; };
+ 25403D5E166A9A0800E13304 /* ZXEmailAddressParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D0F166A9A0800E13304 /* ZXEmailAddressParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D5F166A9A0800E13304 /* ZXEmailAddressParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D10166A9A0800E13304 /* ZXEmailAddressParsedResult.m */; };
+ 25403D60166A9A0800E13304 /* ZXEmailAddressResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D11166A9A0800E13304 /* ZXEmailAddressResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D61166A9A0800E13304 /* ZXEmailAddressResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D12166A9A0800E13304 /* ZXEmailAddressResultParser.m */; };
+ 25403D62166A9A0800E13304 /* ZXEmailDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D13166A9A0800E13304 /* ZXEmailDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D63166A9A0800E13304 /* ZXEmailDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D14166A9A0800E13304 /* ZXEmailDoCoMoResultParser.m */; };
+ 25403D64166A9A0800E13304 /* ZXExpandedProductParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D15166A9A0800E13304 /* ZXExpandedProductParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D65166A9A0800E13304 /* ZXExpandedProductParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D16166A9A0800E13304 /* ZXExpandedProductParsedResult.m */; };
+ 25403D66166A9A0800E13304 /* ZXExpandedProductResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D17166A9A0800E13304 /* ZXExpandedProductResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D67166A9A0800E13304 /* ZXExpandedProductResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D18166A9A0800E13304 /* ZXExpandedProductResultParser.m */; };
+ 25403D68166A9A0800E13304 /* ZXGeoParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D19166A9A0800E13304 /* ZXGeoParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D69166A9A0800E13304 /* ZXGeoParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D1A166A9A0800E13304 /* ZXGeoParsedResult.m */; };
+ 25403D6A166A9A0800E13304 /* ZXGeoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D1B166A9A0800E13304 /* ZXGeoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D6B166A9A0800E13304 /* ZXGeoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D1C166A9A0800E13304 /* ZXGeoResultParser.m */; };
+ 25403D6C166A9A0800E13304 /* ZXISBNParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D1D166A9A0800E13304 /* ZXISBNParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D6D166A9A0800E13304 /* ZXISBNParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D1E166A9A0800E13304 /* ZXISBNParsedResult.m */; };
+ 25403D6E166A9A0800E13304 /* ZXISBNResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D1F166A9A0800E13304 /* ZXISBNResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D6F166A9A0800E13304 /* ZXISBNResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D20166A9A0800E13304 /* ZXISBNResultParser.m */; };
+ 25403D70166A9A0800E13304 /* ZXParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D21166A9A0800E13304 /* ZXParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D71166A9A0800E13304 /* ZXParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D22166A9A0800E13304 /* ZXParsedResult.m */; };
+ 25403D72166A9A0800E13304 /* ZXParsedResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D23166A9A0800E13304 /* ZXParsedResultType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D73166A9A0800E13304 /* ZXProductParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D24166A9A0800E13304 /* ZXProductParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D74166A9A0800E13304 /* ZXProductParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D25166A9A0800E13304 /* ZXProductParsedResult.m */; };
+ 25403D75166A9A0800E13304 /* ZXProductResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D26166A9A0800E13304 /* ZXProductResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D76166A9A0800E13304 /* ZXProductResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D27166A9A0800E13304 /* ZXProductResultParser.m */; };
+ 25403D77166A9A0800E13304 /* ZXResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D28166A9A0800E13304 /* ZXResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D78166A9A0800E13304 /* ZXResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D29166A9A0800E13304 /* ZXResultParser.m */; };
+ 25403D79166A9A0800E13304 /* ZXSMSMMSResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D2A166A9A0800E13304 /* ZXSMSMMSResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D7A166A9A0800E13304 /* ZXSMSMMSResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D2B166A9A0800E13304 /* ZXSMSMMSResultParser.m */; };
+ 25403D7B166A9A0800E13304 /* ZXSMSParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D2C166A9A0800E13304 /* ZXSMSParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D7C166A9A0800E13304 /* ZXSMSParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D2D166A9A0800E13304 /* ZXSMSParsedResult.m */; };
+ 25403D7D166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D2E166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D7E166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D2F166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.m */; };
+ 25403D7F166A9A0800E13304 /* ZXSMTPResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D30166A9A0800E13304 /* ZXSMTPResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D80166A9A0800E13304 /* ZXSMTPResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D31166A9A0800E13304 /* ZXSMTPResultParser.m */; };
+ 25403D81166A9A0800E13304 /* ZXTelParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D32166A9A0800E13304 /* ZXTelParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D82166A9A0800E13304 /* ZXTelParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D33166A9A0800E13304 /* ZXTelParsedResult.m */; };
+ 25403D83166A9A0800E13304 /* ZXTelResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D34166A9A0800E13304 /* ZXTelResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D84166A9A0800E13304 /* ZXTelResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D35166A9A0800E13304 /* ZXTelResultParser.m */; };
+ 25403D85166A9A0800E13304 /* ZXTextParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D36166A9A0800E13304 /* ZXTextParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D86166A9A0800E13304 /* ZXTextParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D37166A9A0800E13304 /* ZXTextParsedResult.m */; };
+ 25403D87166A9A0800E13304 /* ZXURIParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D38166A9A0800E13304 /* ZXURIParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D88166A9A0800E13304 /* ZXURIParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D39166A9A0800E13304 /* ZXURIParsedResult.m */; };
+ 25403D89166A9A0800E13304 /* ZXURIResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D3A166A9A0800E13304 /* ZXURIResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D8A166A9A0800E13304 /* ZXURIResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D3B166A9A0800E13304 /* ZXURIResultParser.m */; };
+ 25403D8B166A9A0800E13304 /* ZXURLTOResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D3C166A9A0800E13304 /* ZXURLTOResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D8C166A9A0800E13304 /* ZXURLTOResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D3D166A9A0800E13304 /* ZXURLTOResultParser.m */; };
+ 25403D8D166A9A0800E13304 /* ZXVCardResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D3E166A9A0800E13304 /* ZXVCardResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D8E166A9A0800E13304 /* ZXVCardResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D3F166A9A0800E13304 /* ZXVCardResultParser.m */; };
+ 25403D8F166A9A0800E13304 /* ZXVEventResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D40166A9A0800E13304 /* ZXVEventResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D90166A9A0800E13304 /* ZXVEventResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D41166A9A0800E13304 /* ZXVEventResultParser.m */; };
+ 25403D91166A9A0800E13304 /* ZXWifiParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D42166A9A0800E13304 /* ZXWifiParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D92166A9A0800E13304 /* ZXWifiParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D43166A9A0800E13304 /* ZXWifiParsedResult.m */; };
+ 25403D93166A9A0800E13304 /* ZXWifiResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D44166A9A0800E13304 /* ZXWifiResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D94166A9A0800E13304 /* ZXWifiResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D45166A9A0800E13304 /* ZXWifiResultParser.m */; };
+ 25403D95166A9A0800E13304 /* ZXCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D46166A9A0800E13304 /* ZXCapture.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D96166A9A0800E13304 /* ZXCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D47166A9A0800E13304 /* ZXCapture.m */; };
+ 25403D97166A9A0800E13304 /* ZXCaptureDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D48166A9A0800E13304 /* ZXCaptureDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D98166A9A0800E13304 /* ZXCaptureView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D49166A9A0800E13304 /* ZXCaptureView.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D99166A9A0800E13304 /* ZXCaptureView.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D4A166A9A0800E13304 /* ZXCaptureView.m */; };
+ 25403D9A166A9A0800E13304 /* ZXCGImageLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D4B166A9A0800E13304 /* ZXCGImageLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D9B166A9A0800E13304 /* ZXCGImageLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D4C166A9A0800E13304 /* ZXCGImageLuminanceSource.m */; };
+ 25403D9C166A9A0800E13304 /* ZXImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D4D166A9A0800E13304 /* ZXImage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403D9D166A9A0800E13304 /* ZXImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D4E166A9A0800E13304 /* ZXImage.m */; };
+ 25403D9E166A9A0800E13304 /* ZXView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D4F166A9A0800E13304 /* ZXView.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DCA166A9C0E00E13304 /* ZXMathUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA1166A9C0E00E13304 /* ZXMathUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DCB166A9C0E00E13304 /* ZXMathUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA2166A9C0E00E13304 /* ZXMathUtils.m */; };
+ 25403DCC166A9C0E00E13304 /* ZXMonochromeRectangleDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA3166A9C0E00E13304 /* ZXMonochromeRectangleDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DCD166A9C0E00E13304 /* ZXMonochromeRectangleDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA4166A9C0E00E13304 /* ZXMonochromeRectangleDetector.m */; };
+ 25403DCE166A9C0E00E13304 /* ZXWhiteRectangleDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA5166A9C0E00E13304 /* ZXWhiteRectangleDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DCF166A9C0E00E13304 /* ZXWhiteRectangleDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA6166A9C0E00E13304 /* ZXWhiteRectangleDetector.m */; };
+ 25403DD0166A9C0E00E13304 /* ZXGenericGF.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA8166A9C0E00E13304 /* ZXGenericGF.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DD1166A9C0E00E13304 /* ZXGenericGF.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA9166A9C0E00E13304 /* ZXGenericGF.m */; };
+ 25403DD2166A9C0E00E13304 /* ZXGenericGFPoly.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DAA166A9C0E00E13304 /* ZXGenericGFPoly.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DD3166A9C0E00E13304 /* ZXGenericGFPoly.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DAB166A9C0E00E13304 /* ZXGenericGFPoly.m */; };
+ 25403DD4166A9C0E00E13304 /* ZXReedSolomonDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DAC166A9C0E00E13304 /* ZXReedSolomonDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DD5166A9C0E00E13304 /* ZXReedSolomonDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DAD166A9C0E00E13304 /* ZXReedSolomonDecoder.m */; };
+ 25403DD6166A9C0E00E13304 /* ZXReedSolomonEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DAE166A9C0E00E13304 /* ZXReedSolomonEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DD7166A9C0E00E13304 /* ZXReedSolomonEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DAF166A9C0E00E13304 /* ZXReedSolomonEncoder.m */; };
+ 25403DD8166A9C0E00E13304 /* ZXBitArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB0166A9C0E00E13304 /* ZXBitArray.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DD9166A9C0E00E13304 /* ZXBitArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB1166A9C0E00E13304 /* ZXBitArray.m */; };
+ 25403DDA166A9C0E00E13304 /* ZXBitMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB2166A9C0E00E13304 /* ZXBitMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DDB166A9C0E00E13304 /* ZXBitMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB3166A9C0E00E13304 /* ZXBitMatrix.m */; };
+ 25403DDC166A9C0E00E13304 /* ZXBitSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB4166A9C0E00E13304 /* ZXBitSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DDD166A9C0E00E13304 /* ZXBitSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB5166A9C0E00E13304 /* ZXBitSource.m */; };
+ 25403DDE166A9C0E00E13304 /* ZXCharacterSetECI.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB6166A9C0E00E13304 /* ZXCharacterSetECI.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DDF166A9C0E00E13304 /* ZXCharacterSetECI.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB7166A9C0E00E13304 /* ZXCharacterSetECI.m */; };
+ 25403DE0166A9C0E00E13304 /* ZXDecoderResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB8166A9C0E00E13304 /* ZXDecoderResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DE1166A9C0E00E13304 /* ZXDecoderResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB9166A9C0E00E13304 /* ZXDecoderResult.m */; };
+ 25403DE2166A9C0E00E13304 /* ZXDefaultGridSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DBA166A9C0E00E13304 /* ZXDefaultGridSampler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DE3166A9C0E00E13304 /* ZXDefaultGridSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DBB166A9C0E00E13304 /* ZXDefaultGridSampler.m */; };
+ 25403DE4166A9C0E00E13304 /* ZXDetectorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DBC166A9C0E00E13304 /* ZXDetectorResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DE5166A9C0E00E13304 /* ZXDetectorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DBD166A9C0E00E13304 /* ZXDetectorResult.m */; };
+ 25403DE6166A9C0E00E13304 /* ZXECI.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DBE166A9C0E00E13304 /* ZXECI.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DE7166A9C0E00E13304 /* ZXECI.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DBF166A9C0E00E13304 /* ZXECI.m */; };
+ 25403DE8166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC0166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DE9166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC1166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.m */; };
+ 25403DEA166A9C0E00E13304 /* ZXGridSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC2166A9C0E00E13304 /* ZXGridSampler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DEB166A9C0E00E13304 /* ZXGridSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC3166A9C0E00E13304 /* ZXGridSampler.m */; };
+ 25403DEC166A9C0E00E13304 /* ZXHybridBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC4166A9C0E00E13304 /* ZXHybridBinarizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DED166A9C0E00E13304 /* ZXHybridBinarizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC5166A9C0E00E13304 /* ZXHybridBinarizer.m */; };
+ 25403DEE166A9C0E00E13304 /* ZXPerspectiveTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC6166A9C0E00E13304 /* ZXPerspectiveTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DEF166A9C0E00E13304 /* ZXPerspectiveTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC7166A9C0E00E13304 /* ZXPerspectiveTransform.m */; };
+ 25403DF0166A9C0E00E13304 /* ZXStringUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC8166A9C0E00E13304 /* ZXStringUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403DF1166A9C0E00E13304 /* ZXStringUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC9166A9C0E00E13304 /* ZXStringUtils.m */; };
+ 25403E03166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DF4166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E04166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DF5166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.m */; };
+ 25403E05166A9CCB00E13304 /* ZXDataMatrixDataBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DF6166A9CCB00E13304 /* ZXDataMatrixDataBlock.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E06166A9CCB00E13304 /* ZXDataMatrixDataBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DF7166A9CCB00E13304 /* ZXDataMatrixDataBlock.m */; };
+ 25403E07166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DF8166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E08166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DF9166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.m */; };
+ 25403E09166A9CCB00E13304 /* ZXDataMatrixDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DFA166A9CCB00E13304 /* ZXDataMatrixDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E0A166A9CCB00E13304 /* ZXDataMatrixDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DFB166A9CCB00E13304 /* ZXDataMatrixDecoder.m */; };
+ 25403E0B166A9CCB00E13304 /* ZXDataMatrixVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DFC166A9CCB00E13304 /* ZXDataMatrixVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E0C166A9CCB00E13304 /* ZXDataMatrixVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DFD166A9CCB00E13304 /* ZXDataMatrixVersion.m */; };
+ 25403E0D166A9CCB00E13304 /* ZXDataMatrixDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DFF166A9CCB00E13304 /* ZXDataMatrixDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E0E166A9CCB00E13304 /* ZXDataMatrixDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E00166A9CCB00E13304 /* ZXDataMatrixDetector.m */; };
+ 25403E0F166A9CCB00E13304 /* ZXDataMatrixReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E01166A9CCB00E13304 /* ZXDataMatrixReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E10166A9CCB00E13304 /* ZXDataMatrixReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E02166A9CCB00E13304 /* ZXDataMatrixReader.m */; };
+ 25403E1B166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E13166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E1C166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E14166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.m */; };
+ 25403E1D166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E15166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E1E166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E16166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.m */; };
+ 25403E1F166A9D4B00E13304 /* ZXMaxiCodeDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E17166A9D4B00E13304 /* ZXMaxiCodeDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E20166A9D4B00E13304 /* ZXMaxiCodeDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E18166A9D4B00E13304 /* ZXMaxiCodeDecoder.m */; };
+ 25403E21166A9D4B00E13304 /* ZXMaxiCodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E19166A9D4B00E13304 /* ZXMaxiCodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E22166A9D4B00E13304 /* ZXMaxiCodeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E1A166A9D4B00E13304 /* ZXMaxiCodeReader.m */; };
+ 25403E31166A9D8B00E13304 /* ZXMultiDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E26166A9D8B00E13304 /* ZXMultiDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E32166A9D8B00E13304 /* ZXMultiDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E27166A9D8B00E13304 /* ZXMultiDetector.m */; };
+ 25403E33166A9D8B00E13304 /* ZXMultiFinderPatternFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E28166A9D8B00E13304 /* ZXMultiFinderPatternFinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E34166A9D8B00E13304 /* ZXMultiFinderPatternFinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E29166A9D8B00E13304 /* ZXMultiFinderPatternFinder.m */; };
+ 25403E35166A9D8B00E13304 /* ZXQRCodeMultiReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E2A166A9D8B00E13304 /* ZXQRCodeMultiReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E36166A9D8B00E13304 /* ZXQRCodeMultiReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E2B166A9D8B00E13304 /* ZXQRCodeMultiReader.m */; };
+ 25403E37166A9D8B00E13304 /* ZXByQuadrantReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E2C166A9D8B00E13304 /* ZXByQuadrantReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E38166A9D8B00E13304 /* ZXByQuadrantReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E2D166A9D8B00E13304 /* ZXByQuadrantReader.m */; };
+ 25403E39166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E2E166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403E3A166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E2F166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.m */; };
+ 25403E3B166A9D8B00E13304 /* ZXMultipleBarcodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E30166A9D8B00E13304 /* ZXMultipleBarcodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EAC166A9DF400E13304 /* ZXAbstractExpandedDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E40166A9DF300E13304 /* ZXAbstractExpandedDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EAD166A9DF400E13304 /* ZXAbstractExpandedDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E41166A9DF300E13304 /* ZXAbstractExpandedDecoder.m */; };
+ 25403EAE166A9DF400E13304 /* ZXAI013103decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E42166A9DF300E13304 /* ZXAI013103decoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EAF166A9DF400E13304 /* ZXAI013103decoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E43166A9DF300E13304 /* ZXAI013103decoder.m */; };
+ 25403EB0166A9DF400E13304 /* ZXAI01320xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E44166A9DF300E13304 /* ZXAI01320xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EB1166A9DF400E13304 /* ZXAI01320xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E45166A9DF300E13304 /* ZXAI01320xDecoder.m */; };
+ 25403EB2166A9DF400E13304 /* ZXAI01392xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E46166A9DF300E13304 /* ZXAI01392xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EB3166A9DF400E13304 /* ZXAI01392xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E47166A9DF300E13304 /* ZXAI01392xDecoder.m */; };
+ 25403EB4166A9DF400E13304 /* ZXAI01393xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E48166A9DF300E13304 /* ZXAI01393xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EB5166A9DF400E13304 /* ZXAI01393xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E49166A9DF300E13304 /* ZXAI01393xDecoder.m */; };
+ 25403EB6166A9DF400E13304 /* ZXAI013x0x1xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E4A166A9DF300E13304 /* ZXAI013x0x1xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EB7166A9DF400E13304 /* ZXAI013x0x1xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E4B166A9DF300E13304 /* ZXAI013x0x1xDecoder.m */; };
+ 25403EB8166A9DF400E13304 /* ZXAI013x0xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E4C166A9DF300E13304 /* ZXAI013x0xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EB9166A9DF400E13304 /* ZXAI013x0xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E4D166A9DF300E13304 /* ZXAI013x0xDecoder.m */; };
+ 25403EBA166A9DF400E13304 /* ZXAI01AndOtherAIs.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E4E166A9DF300E13304 /* ZXAI01AndOtherAIs.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EBB166A9DF400E13304 /* ZXAI01AndOtherAIs.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E4F166A9DF300E13304 /* ZXAI01AndOtherAIs.m */; };
+ 25403EBC166A9DF400E13304 /* ZXAI01decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E50166A9DF300E13304 /* ZXAI01decoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EBD166A9DF400E13304 /* ZXAI01decoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E51166A9DF300E13304 /* ZXAI01decoder.m */; };
+ 25403EBE166A9DF400E13304 /* ZXAI01weightDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E52166A9DF300E13304 /* ZXAI01weightDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EBF166A9DF400E13304 /* ZXAI01weightDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E53166A9DF300E13304 /* ZXAI01weightDecoder.m */; };
+ 25403EC0166A9DF400E13304 /* ZXAnyAIDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E54166A9DF300E13304 /* ZXAnyAIDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EC1166A9DF400E13304 /* ZXAnyAIDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E55166A9DF300E13304 /* ZXAnyAIDecoder.m */; };
+ 25403EC2166A9DF400E13304 /* ZXBlockParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E56166A9DF300E13304 /* ZXBlockParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EC3166A9DF400E13304 /* ZXBlockParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E57166A9DF300E13304 /* ZXBlockParsedResult.m */; };
+ 25403EC4166A9DF400E13304 /* ZXCurrentParsingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E58166A9DF300E13304 /* ZXCurrentParsingState.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EC5166A9DF400E13304 /* ZXCurrentParsingState.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E59166A9DF300E13304 /* ZXCurrentParsingState.m */; };
+ 25403EC6166A9DF400E13304 /* ZXDecodedChar.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E5A166A9DF300E13304 /* ZXDecodedChar.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EC7166A9DF400E13304 /* ZXDecodedChar.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E5B166A9DF300E13304 /* ZXDecodedChar.m */; };
+ 25403EC8166A9DF400E13304 /* ZXDecodedInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E5C166A9DF300E13304 /* ZXDecodedInformation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EC9166A9DF400E13304 /* ZXDecodedInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E5D166A9DF300E13304 /* ZXDecodedInformation.m */; };
+ 25403ECA166A9DF400E13304 /* ZXDecodedNumeric.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E5E166A9DF300E13304 /* ZXDecodedNumeric.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403ECB166A9DF400E13304 /* ZXDecodedNumeric.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E5F166A9DF300E13304 /* ZXDecodedNumeric.m */; };
+ 25403ECC166A9DF400E13304 /* ZXDecodedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E60166A9DF300E13304 /* ZXDecodedObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403ECD166A9DF400E13304 /* ZXDecodedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E61166A9DF300E13304 /* ZXDecodedObject.m */; };
+ 25403ECE166A9DF400E13304 /* ZXFieldParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E62166A9DF300E13304 /* ZXFieldParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403ECF166A9DF400E13304 /* ZXFieldParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E63166A9DF300E13304 /* ZXFieldParser.m */; };
+ 25403ED0166A9DF400E13304 /* ZXGeneralAppIdDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E64166A9DF300E13304 /* ZXGeneralAppIdDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403ED1166A9DF400E13304 /* ZXGeneralAppIdDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E65166A9DF300E13304 /* ZXGeneralAppIdDecoder.m */; };
+ 25403ED2166A9DF400E13304 /* ZXBitArrayBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E66166A9DF300E13304 /* ZXBitArrayBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403ED3166A9DF400E13304 /* ZXBitArrayBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E67166A9DF300E13304 /* ZXBitArrayBuilder.m */; };
+ 25403ED4166A9DF400E13304 /* ZXExpandedPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E68166A9DF300E13304 /* ZXExpandedPair.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403ED5166A9DF400E13304 /* ZXExpandedPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E69166A9DF300E13304 /* ZXExpandedPair.m */; };
+ 25403ED6166A9DF400E13304 /* ZXRSSExpandedReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E6A166A9DF300E13304 /* ZXRSSExpandedReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403ED7166A9DF400E13304 /* ZXRSSExpandedReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E6B166A9DF300E13304 /* ZXRSSExpandedReader.m */; };
+ 25403ED8166A9DF400E13304 /* ZXAbstractRSSReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E6C166A9DF300E13304 /* ZXAbstractRSSReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403ED9166A9DF400E13304 /* ZXAbstractRSSReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E6D166A9DF300E13304 /* ZXAbstractRSSReader.m */; };
+ 25403EDA166A9DF400E13304 /* ZXDataCharacter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E6E166A9DF300E13304 /* ZXDataCharacter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EDB166A9DF400E13304 /* ZXDataCharacter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E6F166A9DF300E13304 /* ZXDataCharacter.m */; };
+ 25403EDC166A9DF400E13304 /* ZXPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E70166A9DF300E13304 /* ZXPair.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EDD166A9DF400E13304 /* ZXPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E71166A9DF300E13304 /* ZXPair.m */; };
+ 25403EDE166A9DF400E13304 /* ZXRSS14Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E72166A9DF300E13304 /* ZXRSS14Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EDF166A9DF400E13304 /* ZXRSS14Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E73166A9DF300E13304 /* ZXRSS14Reader.m */; };
+ 25403EE0166A9DF400E13304 /* ZXRSSFinderPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E74166A9DF300E13304 /* ZXRSSFinderPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EE1166A9DF400E13304 /* ZXRSSFinderPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E75166A9DF300E13304 /* ZXRSSFinderPattern.m */; };
+ 25403EE2166A9DF400E13304 /* ZXRSSUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E76166A9DF300E13304 /* ZXRSSUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EE3166A9DF400E13304 /* ZXRSSUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E77166A9DF300E13304 /* ZXRSSUtils.m */; };
+ 25403EE4166A9DF400E13304 /* ZXCodaBarReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E78166A9DF300E13304 /* ZXCodaBarReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EE5166A9DF400E13304 /* ZXCodaBarReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E79166A9DF300E13304 /* ZXCodaBarReader.m */; };
+ 25403EE6166A9DF400E13304 /* ZXCodaBarWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E7A166A9DF300E13304 /* ZXCodaBarWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EE7166A9DF400E13304 /* ZXCodaBarWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E7B166A9DF300E13304 /* ZXCodaBarWriter.m */; };
+ 25403EE8166A9DF400E13304 /* ZXCode128Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E7C166A9DF300E13304 /* ZXCode128Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EE9166A9DF400E13304 /* ZXCode128Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E7D166A9DF300E13304 /* ZXCode128Reader.m */; };
+ 25403EEA166A9DF400E13304 /* ZXCode128Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E7E166A9DF300E13304 /* ZXCode128Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EEB166A9DF400E13304 /* ZXCode128Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E7F166A9DF300E13304 /* ZXCode128Writer.m */; };
+ 25403EEC166A9DF400E13304 /* ZXCode39Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E80166A9DF300E13304 /* ZXCode39Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EED166A9DF400E13304 /* ZXCode39Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E81166A9DF300E13304 /* ZXCode39Reader.m */; };
+ 25403EEE166A9DF400E13304 /* ZXCode39Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E82166A9DF300E13304 /* ZXCode39Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EEF166A9DF400E13304 /* ZXCode39Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E83166A9DF300E13304 /* ZXCode39Writer.m */; };
+ 25403EF0166A9DF400E13304 /* ZXCode93Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E84166A9DF300E13304 /* ZXCode93Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EF1166A9DF400E13304 /* ZXCode93Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E85166A9DF300E13304 /* ZXCode93Reader.m */; };
+ 25403EF2166A9DF400E13304 /* ZXEAN13Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E86166A9DF300E13304 /* ZXEAN13Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EF3166A9DF400E13304 /* ZXEAN13Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E87166A9DF300E13304 /* ZXEAN13Reader.m */; };
+ 25403EF4166A9DF400E13304 /* ZXEAN13Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E88166A9DF300E13304 /* ZXEAN13Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EF5166A9DF400E13304 /* ZXEAN13Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E89166A9DF300E13304 /* ZXEAN13Writer.m */; };
+ 25403EF6166A9DF400E13304 /* ZXEAN8Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E8A166A9DF300E13304 /* ZXEAN8Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EF7166A9DF400E13304 /* ZXEAN8Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E8B166A9DF300E13304 /* ZXEAN8Reader.m */; };
+ 25403EF8166A9DF400E13304 /* ZXEAN8Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E8C166A9DF300E13304 /* ZXEAN8Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EF9166A9DF400E13304 /* ZXEAN8Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E8D166A9DF300E13304 /* ZXEAN8Writer.m */; };
+ 25403EFA166A9DF400E13304 /* ZXEANManufacturerOrgSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E8E166A9DF300E13304 /* ZXEANManufacturerOrgSupport.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EFB166A9DF400E13304 /* ZXEANManufacturerOrgSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E8F166A9DF300E13304 /* ZXEANManufacturerOrgSupport.m */; };
+ 25403EFC166A9DF400E13304 /* ZXITFReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E90166A9DF300E13304 /* ZXITFReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EFD166A9DF400E13304 /* ZXITFReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E91166A9DF300E13304 /* ZXITFReader.m */; };
+ 25403EFE166A9DF400E13304 /* ZXITFWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E92166A9DF300E13304 /* ZXITFWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403EFF166A9DF400E13304 /* ZXITFWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E93166A9DF300E13304 /* ZXITFWriter.m */; };
+ 25403F00166A9DF400E13304 /* ZXMultiFormatOneDReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E94166A9DF300E13304 /* ZXMultiFormatOneDReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F01166A9DF400E13304 /* ZXMultiFormatOneDReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E95166A9DF300E13304 /* ZXMultiFormatOneDReader.m */; };
+ 25403F02166A9DF400E13304 /* ZXMultiFormatUPCEANReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E96166A9DF300E13304 /* ZXMultiFormatUPCEANReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F03166A9DF400E13304 /* ZXMultiFormatUPCEANReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E97166A9DF300E13304 /* ZXMultiFormatUPCEANReader.m */; };
+ 25403F04166A9DF400E13304 /* ZXOneDimensionalCodeWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E98166A9DF300E13304 /* ZXOneDimensionalCodeWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F05166A9DF400E13304 /* ZXOneDimensionalCodeWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E99166A9DF300E13304 /* ZXOneDimensionalCodeWriter.m */; };
+ 25403F06166A9DF400E13304 /* ZXOneDReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E9A166A9DF300E13304 /* ZXOneDReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F07166A9DF400E13304 /* ZXOneDReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E9B166A9DF300E13304 /* ZXOneDReader.m */; };
+ 25403F08166A9DF400E13304 /* ZXUPCAReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E9C166A9DF300E13304 /* ZXUPCAReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F09166A9DF400E13304 /* ZXUPCAReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E9D166A9DF300E13304 /* ZXUPCAReader.m */; };
+ 25403F0A166A9DF400E13304 /* ZXUPCAWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E9E166A9DF300E13304 /* ZXUPCAWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F0B166A9DF400E13304 /* ZXUPCAWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E9F166A9DF300E13304 /* ZXUPCAWriter.m */; };
+ 25403F0C166A9DF400E13304 /* ZXUPCEANExtension2Support.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA0166A9DF300E13304 /* ZXUPCEANExtension2Support.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F0D166A9DF400E13304 /* ZXUPCEANExtension2Support.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA1166A9DF300E13304 /* ZXUPCEANExtension2Support.m */; };
+ 25403F0E166A9DF400E13304 /* ZXUPCEANExtension5Support.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA2166A9DF300E13304 /* ZXUPCEANExtension5Support.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F0F166A9DF400E13304 /* ZXUPCEANExtension5Support.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA3166A9DF300E13304 /* ZXUPCEANExtension5Support.m */; };
+ 25403F10166A9DF400E13304 /* ZXUPCEANExtensionSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA4166A9DF300E13304 /* ZXUPCEANExtensionSupport.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F11166A9DF400E13304 /* ZXUPCEANExtensionSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA5166A9DF300E13304 /* ZXUPCEANExtensionSupport.m */; };
+ 25403F12166A9DF400E13304 /* ZXUPCEANReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA6166A9DF300E13304 /* ZXUPCEANReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F13166A9DF400E13304 /* ZXUPCEANReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA7166A9DF300E13304 /* ZXUPCEANReader.m */; };
+ 25403F14166A9DF400E13304 /* ZXUPCEANWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA8166A9DF300E13304 /* ZXUPCEANWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F15166A9DF400E13304 /* ZXUPCEANWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA9166A9DF300E13304 /* ZXUPCEANWriter.m */; };
+ 25403F16166A9DF400E13304 /* ZXUPCEReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EAA166A9DF300E13304 /* ZXUPCEReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F17166A9DF400E13304 /* ZXUPCEReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EAB166A9DF300E13304 /* ZXUPCEReader.m */; };
+ 25403F3C166A9EB500E13304 /* ZXModulusGF.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F1B166A9EB500E13304 /* ZXModulusGF.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F3D166A9EB500E13304 /* ZXModulusGF.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F1C166A9EB500E13304 /* ZXModulusGF.m */; };
+ 25403F3E166A9EB500E13304 /* ZXModulusPoly.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F1D166A9EB500E13304 /* ZXModulusPoly.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F3F166A9EB500E13304 /* ZXModulusPoly.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F1E166A9EB500E13304 /* ZXModulusPoly.m */; };
+ 25403F40166A9EB500E13304 /* ZXPDF417ECErrorCorrection.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F1F166A9EB500E13304 /* ZXPDF417ECErrorCorrection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F41166A9EB500E13304 /* ZXPDF417ECErrorCorrection.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F20166A9EB500E13304 /* ZXPDF417ECErrorCorrection.m */; };
+ 25403F44166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F23166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F45166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F24166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.m */; };
+ 25403F48166A9EB500E13304 /* ZXPDF417Detector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F28166A9EB500E13304 /* ZXPDF417Detector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F49166A9EB500E13304 /* ZXPDF417Detector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F29166A9EB500E13304 /* ZXPDF417Detector.m */; };
+ 25403F4A166A9EB500E13304 /* ZXBarcodeMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F2B166A9EB500E13304 /* ZXBarcodeMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F4B166A9EB500E13304 /* ZXBarcodeMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F2C166A9EB500E13304 /* ZXBarcodeMatrix.m */; };
+ 25403F4C166A9EB500E13304 /* ZXBarcodeRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F2D166A9EB500E13304 /* ZXBarcodeRow.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F4D166A9EB500E13304 /* ZXBarcodeRow.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F2E166A9EB500E13304 /* ZXBarcodeRow.m */; };
+ 25403F4E166A9EB500E13304 /* ZXCompaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F2F166A9EB500E13304 /* ZXCompaction.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F4F166A9EB500E13304 /* ZXDimensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F30166A9EB500E13304 /* ZXDimensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F50166A9EB500E13304 /* ZXDimensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F31166A9EB500E13304 /* ZXDimensions.m */; };
+ 25403F51166A9EB500E13304 /* ZXPDF417.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F32166A9EB500E13304 /* ZXPDF417.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F52166A9EB500E13304 /* ZXPDF417.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F33166A9EB500E13304 /* ZXPDF417.m */; };
+ 25403F53166A9EB500E13304 /* ZXPDF417ErrorCorrection.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F34166A9EB500E13304 /* ZXPDF417ErrorCorrection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F54166A9EB500E13304 /* ZXPDF417ErrorCorrection.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F35166A9EB500E13304 /* ZXPDF417ErrorCorrection.m */; };
+ 25403F55166A9EB500E13304 /* ZXPDF417HighLevelEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F36166A9EB500E13304 /* ZXPDF417HighLevelEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F56166A9EB500E13304 /* ZXPDF417HighLevelEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F37166A9EB500E13304 /* ZXPDF417HighLevelEncoder.m */; };
+ 25403F59166A9EB500E13304 /* ZXPDF417Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F3A166A9EB500E13304 /* ZXPDF417Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F5A166A9EB500E13304 /* ZXPDF417Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F3B166A9EB500E13304 /* ZXPDF417Reader.m */; };
+ 25403F8D166A9F2D00E13304 /* ZXDataMask.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F5D166A9F2D00E13304 /* ZXDataMask.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F8E166A9F2D00E13304 /* ZXDataMask.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F5E166A9F2D00E13304 /* ZXDataMask.m */; };
+ 25403F8F166A9F2D00E13304 /* ZXErrorCorrectionLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F5F166A9F2D00E13304 /* ZXErrorCorrectionLevel.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F90166A9F2D00E13304 /* ZXErrorCorrectionLevel.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F60166A9F2D00E13304 /* ZXErrorCorrectionLevel.m */; };
+ 25403F91166A9F2D00E13304 /* ZXFormatInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F61166A9F2D00E13304 /* ZXFormatInformation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F92166A9F2D00E13304 /* ZXFormatInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F62166A9F2D00E13304 /* ZXFormatInformation.m */; };
+ 25403F93166A9F2D00E13304 /* ZXMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F63166A9F2D00E13304 /* ZXMode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F94166A9F2D00E13304 /* ZXMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F64166A9F2D00E13304 /* ZXMode.m */; };
+ 25403F95166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F65166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F96166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F66166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.m */; };
+ 25403F97166A9F2D00E13304 /* ZXQRCodeDataBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F67166A9F2D00E13304 /* ZXQRCodeDataBlock.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F98166A9F2D00E13304 /* ZXQRCodeDataBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F68166A9F2D00E13304 /* ZXQRCodeDataBlock.m */; };
+ 25403F99166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F69166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F9A166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F6A166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.m */; };
+ 25403F9B166A9F2D00E13304 /* ZXQRCodeDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F6B166A9F2D00E13304 /* ZXQRCodeDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F9C166A9F2D00E13304 /* ZXQRCodeDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F6C166A9F2D00E13304 /* ZXQRCodeDecoder.m */; };
+ 25403F9D166A9F2D00E13304 /* ZXQRCodeVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F6D166A9F2D00E13304 /* ZXQRCodeVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403F9E166A9F2D00E13304 /* ZXQRCodeVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F6E166A9F2D00E13304 /* ZXQRCodeVersion.m */; };
+ 25403F9F166A9F2D00E13304 /* ZXAlignmentPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F70166A9F2D00E13304 /* ZXAlignmentPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FA0166A9F2D00E13304 /* ZXAlignmentPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F71166A9F2D00E13304 /* ZXAlignmentPattern.m */; };
+ 25403FA1166A9F2D00E13304 /* ZXAlignmentPatternFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F72166A9F2D00E13304 /* ZXAlignmentPatternFinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FA2166A9F2D00E13304 /* ZXAlignmentPatternFinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F73166A9F2D00E13304 /* ZXAlignmentPatternFinder.m */; };
+ 25403FA3166A9F2D00E13304 /* ZXFinderPatternFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F74166A9F2D00E13304 /* ZXFinderPatternFinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FA4166A9F2D00E13304 /* ZXFinderPatternFinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F75166A9F2D00E13304 /* ZXFinderPatternFinder.m */; };
+ 25403FA5166A9F2D00E13304 /* ZXFinderPatternInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F76166A9F2D00E13304 /* ZXFinderPatternInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FA6166A9F2D00E13304 /* ZXFinderPatternInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F77166A9F2D00E13304 /* ZXFinderPatternInfo.m */; };
+ 25403FA7166A9F2D00E13304 /* ZXQRCodeDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F78166A9F2D00E13304 /* ZXQRCodeDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FA8166A9F2D00E13304 /* ZXQRCodeDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F79166A9F2D00E13304 /* ZXQRCodeDetector.m */; };
+ 25403FA9166A9F2D00E13304 /* ZXQRCodeFinderPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F7A166A9F2D00E13304 /* ZXQRCodeFinderPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FAA166A9F2D00E13304 /* ZXQRCodeFinderPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F7B166A9F2D00E13304 /* ZXQRCodeFinderPattern.m */; };
+ 25403FAB166A9F2D00E13304 /* ZXBlockPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F7D166A9F2D00E13304 /* ZXBlockPair.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FAC166A9F2D00E13304 /* ZXBlockPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F7E166A9F2D00E13304 /* ZXBlockPair.m */; };
+ 25403FAD166A9F2D00E13304 /* ZXByteMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F7F166A9F2D00E13304 /* ZXByteMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FAE166A9F2D00E13304 /* ZXByteMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F80166A9F2D00E13304 /* ZXByteMatrix.m */; };
+ 25403FAF166A9F2D00E13304 /* ZXEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F81166A9F2D00E13304 /* ZXEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FB0166A9F2D00E13304 /* ZXEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F82166A9F2D00E13304 /* ZXEncoder.m */; };
+ 25403FB1166A9F2D00E13304 /* ZXMaskUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F83166A9F2D00E13304 /* ZXMaskUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FB2166A9F2D00E13304 /* ZXMaskUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F84166A9F2D00E13304 /* ZXMaskUtil.m */; };
+ 25403FB3166A9F2D00E13304 /* ZXMatrixUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F85166A9F2D00E13304 /* ZXMatrixUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FB4166A9F2D00E13304 /* ZXMatrixUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F86166A9F2D00E13304 /* ZXMatrixUtil.m */; };
+ 25403FB5166A9F2D00E13304 /* ZXQRCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F87166A9F2D00E13304 /* ZXQRCode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FB6166A9F2D00E13304 /* ZXQRCode.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F88166A9F2D00E13304 /* ZXQRCode.m */; };
+ 25403FB7166A9F2D00E13304 /* ZXQRCodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F89166A9F2D00E13304 /* ZXQRCodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FB8166A9F2D00E13304 /* ZXQRCodeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F8A166A9F2D00E13304 /* ZXQRCodeReader.m */; };
+ 25403FB9166A9F2D00E13304 /* ZXQRCodeWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F8B166A9F2D00E13304 /* ZXQRCodeWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FBA166A9F2D00E13304 /* ZXQRCodeWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F8C166A9F2D00E13304 /* ZXQRCodeWriter.m */; };
+ 25403FC6166A9FFC00E13304 /* ZXBarcodeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FBB166A9FFC00E13304 /* ZXBarcodeFormat.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FC7166A9FFC00E13304 /* ZXBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FBC166A9FFC00E13304 /* ZXBinarizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FC8166A9FFC00E13304 /* ZXBinarizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FBD166A9FFC00E13304 /* ZXBinarizer.m */; };
+ 25403FC9166A9FFC00E13304 /* ZXBinaryBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FBE166A9FFC00E13304 /* ZXBinaryBitmap.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FCA166A9FFC00E13304 /* ZXBinaryBitmap.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FBF166A9FFC00E13304 /* ZXBinaryBitmap.m */; };
+ 25403FCB166A9FFC00E13304 /* ZXDecodeHints.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FC0166A9FFC00E13304 /* ZXDecodeHints.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FCC166A9FFC00E13304 /* ZXDecodeHints.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FC1166A9FFC00E13304 /* ZXDecodeHints.m */; };
+ 25403FCD166A9FFC00E13304 /* ZXEncodeHints.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FC2166A9FFC00E13304 /* ZXEncodeHints.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FCE166A9FFC00E13304 /* ZXEncodeHints.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FC3166A9FFC00E13304 /* ZXEncodeHints.m */; };
+ 25403FCF166A9FFC00E13304 /* ZXErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FC4166A9FFC00E13304 /* ZXErrors.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FD0166A9FFC00E13304 /* ZXErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FC5166A9FFC00E13304 /* ZXErrors.m */; };
+ 25403FDF166AA00800E13304 /* ZXLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD1166AA00700E13304 /* ZXLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FE0166AA00800E13304 /* ZXLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD2166AA00700E13304 /* ZXLuminanceSource.m */; };
+ 25403FE1166AA00800E13304 /* ZXMultiFormatReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD3166AA00700E13304 /* ZXMultiFormatReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FE2166AA00800E13304 /* ZXMultiFormatReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD4166AA00700E13304 /* ZXMultiFormatReader.m */; };
+ 25403FE3166AA00800E13304 /* ZXMultiFormatWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD5166AA00700E13304 /* ZXMultiFormatWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FE4166AA00800E13304 /* ZXMultiFormatWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD6166AA00700E13304 /* ZXMultiFormatWriter.m */; };
+ 25403FE5166AA00800E13304 /* ZXReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD7166AA00700E13304 /* ZXReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FE6166AA00800E13304 /* ZXResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD8166AA00700E13304 /* ZXResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FE7166AA00800E13304 /* ZXResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD9166AA00700E13304 /* ZXResult.m */; };
+ 25403FE8166AA00800E13304 /* ZXResultMetadataType.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDA166AA00700E13304 /* ZXResultMetadataType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FE9166AA00800E13304 /* ZXResultPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDB166AA00700E13304 /* ZXResultPoint.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FEA166AA00800E13304 /* ZXResultPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FDC166AA00700E13304 /* ZXResultPoint.m */; };
+ 25403FEB166AA00800E13304 /* ZXResultPointCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDD166AA00700E13304 /* ZXResultPointCallback.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25403FEC166AA00800E13304 /* ZXWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDE166AA00700E13304 /* ZXWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254040D9166AA0F100E13304 /* ZXAddressBookParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FF5166AA0F100E13304 /* ZXAddressBookParsedResultTestCase.m */; };
+ 254040DA166AA0F100E13304 /* ZXCalendarParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FF7166AA0F100E13304 /* ZXCalendarParsedResultTestCase.m */; };
+ 254040DB166AA0F100E13304 /* ZXEmailAddressParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FF9166AA0F100E13304 /* ZXEmailAddressParsedResultTestCase.m */; };
+ 254040DC166AA0F100E13304 /* ZXExpandedProductParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FFB166AA0F100E13304 /* ZXExpandedProductParsedResultTestCase.m */; };
+ 254040DD166AA0F100E13304 /* ZXGeoParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FFD166AA0F100E13304 /* ZXGeoParsedResultTestCase.m */; };
+ 254040DE166AA0F100E13304 /* ZXISBNParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FFF166AA0F100E13304 /* ZXISBNParsedResultTestCase.m */; };
+ 254040DF166AA0F100E13304 /* ZXParsedReaderResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404001166AA0F100E13304 /* ZXParsedReaderResultTestCase.m */; };
+ 254040E0166AA0F100E13304 /* ZXProductParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404003166AA0F100E13304 /* ZXProductParsedResultTestCase.m */; };
+ 254040E1166AA0F100E13304 /* ZXSMSMMSParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404005166AA0F100E13304 /* ZXSMSMMSParsedResultTestCase.m */; };
+ 254040E2166AA0F100E13304 /* ZXTelParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404007166AA0F100E13304 /* ZXTelParsedResultTestCase.m */; };
+ 254040E3166AA0F100E13304 /* ZXURIParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404009166AA0F100E13304 /* ZXURIParsedResultTestCase.m */; };
+ 254040E4166AA0F100E13304 /* ZXWifiParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540400B166AA0F100E13304 /* ZXWifiParsedResultTestCase.m */; };
+ 254040EC166AA0F100E13304 /* ZXBitArrayTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540401D166AA0F100E13304 /* ZXBitArrayTestCase.m */; };
+ 254040ED166AA0F100E13304 /* ZXBitMatrixTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540401F166AA0F100E13304 /* ZXBitMatrixTestCase.m */; };
+ 254040EE166AA0F100E13304 /* ZXBitSourceBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404021166AA0F100E13304 /* ZXBitSourceBuilder.m */; };
+ 254040EF166AA0F100E13304 /* ZXBitSourceTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404023166AA0F100E13304 /* ZXBitSourceTestCase.m */; };
+ 254040F0166AA0F100E13304 /* ZXPerspectiveTransformTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404025166AA0F100E13304 /* ZXPerspectiveTransformTestCase.m */; };
+ 254040F1166AA0F100E13304 /* ZXStringUtilsTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404027166AA0F100E13304 /* ZXStringUtilsTestCase.m */; };
+ 254040F4166AA0F100E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540402F166AA0F100E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.m */; };
+ 25404109166AA0F100E13304 /* AbstractDecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540405E166AA0F100E13304 /* AbstractDecoderTest.m */; };
+ 2540410A166AA0F100E13304 /* AI01_3103_DecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404060166AA0F100E13304 /* AI01_3103_DecoderTest.m */; };
+ 2540410B166AA0F100E13304 /* AI01_3202_3203_DecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404062166AA0F100E13304 /* AI01_3202_3203_DecoderTest.m */; };
+ 2540410C166AA0F100E13304 /* AI01_3X0X_1X_DecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404064166AA0F100E13304 /* AI01_3X0X_1X_DecoderTest.m */; };
+ 2540410D166AA0F100E13304 /* AnyAIDecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404066166AA0F100E13304 /* AnyAIDecoderTest.m */; };
+ 2540410E166AA0F100E13304 /* ZXFieldParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404068166AA0F100E13304 /* ZXFieldParserTest.m */; };
+ 25404112166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404070166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.m */; };
+ 25404113166AA0F100E13304 /* RSSExpandedImage2resultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404072166AA0F100E13304 /* RSSExpandedImage2resultTestCase.m */; };
+ 25404114166AA0F100E13304 /* RSSExpandedImage2stringTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404074166AA0F100E13304 /* RSSExpandedImage2stringTestCase.m */; };
+ 25404115166AA0F100E13304 /* RSSExpandedInternalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404076166AA0F100E13304 /* RSSExpandedInternalTestCase.m */; };
+ 25404116166AA0F100E13304 /* ZXBinaryUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404078166AA0F100E13304 /* ZXBinaryUtil.m */; };
+ 25404117166AA0F100E13304 /* ZXBinaryUtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540407A166AA0F100E13304 /* ZXBinaryUtilTest.m */; };
+ 25404118166AA0F100E13304 /* ZXBitArrayBuilderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540407C166AA0F100E13304 /* ZXBitArrayBuilderTest.m */; };
+ 25404119166AA0F100E13304 /* ZXExpandedInformationDecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540407E166AA0F100E13304 /* ZXExpandedInformationDecoderTest.m */; };
+ 25404126166AA0F100E13304 /* ZXCodaBarWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404098166AA0F100E13304 /* ZXCodaBarWriterTestCase.m */; };
+ 25404128166AA0F100E13304 /* ZXEAN13WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540409C166AA0F100E13304 /* ZXEAN13WriterTestCase.m */; };
+ 25404129166AA0F100E13304 /* ZXEAN8WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540409E166AA0F100E13304 /* ZXEAN8WriterTestCase.m */; };
+ 2540412A166AA0F100E13304 /* ZXEANManufacturerOrgSupportTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040A0166AA0F100E13304 /* ZXEANManufacturerOrgSupportTest.m */; };
+ 2540412C166AA0F100E13304 /* ZXUPCAWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040A4166AA0F100E13304 /* ZXUPCAWriterTestCase.m */; };
+ 2540412D166AA0F100E13304 /* AbstractErrorCorrectionTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040A9166AA0F100E13304 /* AbstractErrorCorrectionTestCase.m */; };
+ 2540412E166AA0F100E13304 /* ZXPDF417ECErrorCorrectionTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040AB166AA0F100E13304 /* ZXPDF417ECErrorCorrectionTestCase.m */; };
+ 25404131166AA0F100E13304 /* ZXDataMaskTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040B3166AA0F100E13304 /* ZXDataMaskTestCase.m */; };
+ 25404132166AA0F100E13304 /* ZXErrorCorrectionLevelTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040B5166AA0F100E13304 /* ZXErrorCorrectionLevelTestCase.m */; };
+ 25404133166AA0F100E13304 /* ZXFormatInformationTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040B7166AA0F100E13304 /* ZXFormatInformationTestCase.m */; };
+ 25404134166AA0F100E13304 /* ZXModeTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040B9166AA0F100E13304 /* ZXModeTestCase.m */; };
+ 25404135166AA0F100E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040BB166AA0F100E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.m */; };
+ 25404136166AA0F100E13304 /* ZXQRCodeVersionTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040BD166AA0F100E13304 /* ZXQRCodeVersionTestCase.m */; };
+ 25404137166AA0F100E13304 /* BitVectorTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C0166AA0F100E13304 /* BitVectorTestCase.m */; };
+ 25404138166AA0F100E13304 /* ZXEncoderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C2166AA0F100E13304 /* ZXEncoderTestCase.m */; };
+ 25404139166AA0F100E13304 /* ZXMaskUtilTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C4166AA0F100E13304 /* ZXMaskUtilTestCase.m */; };
+ 2540413A166AA0F100E13304 /* ZXMatrixUtilTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C6166AA0F100E13304 /* ZXMatrixUtilTestCase.m */; };
+ 2540413B166AA0F100E13304 /* ZXQRCodeTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C8166AA0F100E13304 /* ZXQRCodeTestCase.m */; };
+ 25404142166AA0F100E13304 /* ZXQRCodeWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040D6166AA0F100E13304 /* ZXQRCodeWriterTestCase.m */; };
+ 25404146166AA16200E13304 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404145166AA16200E13304 /* UIKit.framework */; };
+ 2540414F166AA33700E13304 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540414E166AA33700E13304 /* CoreGraphics.framework */; };
+ 25404150166AA33E00E13304 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540414E166AA33700E13304 /* CoreGraphics.framework */; };
+ 2540415C166AA86900E13304 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540415B166AA86900E13304 /* ImageIO.framework */; };
+ 2540415D166AA87000E13304 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540415B166AA86900E13304 /* ImageIO.framework */; };
+ 2540415F166AAA2F00E13304 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540415E166AAA2F00E13304 /* CoreVideo.framework */; };
+ 25404160166AAAAB00E13304 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404145166AA16200E13304 /* UIKit.framework */; };
+ 25404161166AAAD900E13304 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540415E166AAA2F00E13304 /* CoreVideo.framework */; };
+ 25404179166AADAC00E13304 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25403CC5166A96FA00E13304 /* SenTestingKit.framework */; };
+ 2540417D166AADAC00E13304 /* libZXingObjC-osx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404166166AADAC00E13304 /* libZXingObjC-osx.a */; };
+ 2540418F166AAE6000E13304 /* ZXAztecDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CEF166A999D00E13304 /* ZXAztecDecoder.m */; };
+ 25404190166AAE6000E13304 /* ZXAztecDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF2166A999D00E13304 /* ZXAztecDetector.m */; };
+ 25404191166AAE6000E13304 /* ZXAztecDetectorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF4166A999D00E13304 /* ZXAztecDetectorResult.m */; };
+ 25404192166AAE6000E13304 /* ZXAztecReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF6166A999D00E13304 /* ZXAztecReader.m */; };
+ 25404193166AAE6000E13304 /* ZXAbstractDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D02166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.m */; };
+ 25404194166AAE6000E13304 /* ZXAddressBookAUResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D04166A9A0800E13304 /* ZXAddressBookAUResultParser.m */; };
+ 25404195166AAE6000E13304 /* ZXAddressBookDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D06166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.m */; };
+ 25404196166AAE6000E13304 /* ZXAddressBookParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D08166A9A0800E13304 /* ZXAddressBookParsedResult.m */; };
+ 25404197166AAE6000E13304 /* ZXBizcardResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D0A166A9A0800E13304 /* ZXBizcardResultParser.m */; };
+ 25404198166AAE6000E13304 /* ZXBookmarkDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D0C166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.m */; };
+ 25404199166AAE6000E13304 /* ZXCalendarParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D0E166A9A0800E13304 /* ZXCalendarParsedResult.m */; };
+ 2540419A166AAE6000E13304 /* ZXEmailAddressParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D10166A9A0800E13304 /* ZXEmailAddressParsedResult.m */; };
+ 2540419B166AAE6000E13304 /* ZXEmailAddressResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D12166A9A0800E13304 /* ZXEmailAddressResultParser.m */; };
+ 2540419C166AAE6000E13304 /* ZXEmailDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D14166A9A0800E13304 /* ZXEmailDoCoMoResultParser.m */; };
+ 2540419D166AAE6000E13304 /* ZXExpandedProductParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D16166A9A0800E13304 /* ZXExpandedProductParsedResult.m */; };
+ 2540419E166AAE6000E13304 /* ZXExpandedProductResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D18166A9A0800E13304 /* ZXExpandedProductResultParser.m */; };
+ 2540419F166AAE6000E13304 /* ZXGeoParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D1A166A9A0800E13304 /* ZXGeoParsedResult.m */; };
+ 254041A0166AAE6000E13304 /* ZXGeoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D1C166A9A0800E13304 /* ZXGeoResultParser.m */; };
+ 254041A1166AAE6000E13304 /* ZXISBNParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D1E166A9A0800E13304 /* ZXISBNParsedResult.m */; };
+ 254041A2166AAE6000E13304 /* ZXISBNResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D20166A9A0800E13304 /* ZXISBNResultParser.m */; };
+ 254041A3166AAE6000E13304 /* ZXParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D22166A9A0800E13304 /* ZXParsedResult.m */; };
+ 254041A4166AAE6000E13304 /* ZXProductParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D25166A9A0800E13304 /* ZXProductParsedResult.m */; };
+ 254041A5166AAE6000E13304 /* ZXProductResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D27166A9A0800E13304 /* ZXProductResultParser.m */; };
+ 254041A6166AAE6000E13304 /* ZXResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D29166A9A0800E13304 /* ZXResultParser.m */; };
+ 254041A7166AAE6000E13304 /* ZXSMSMMSResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D2B166A9A0800E13304 /* ZXSMSMMSResultParser.m */; };
+ 254041A8166AAE6000E13304 /* ZXSMSParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D2D166A9A0800E13304 /* ZXSMSParsedResult.m */; };
+ 254041A9166AAE6000E13304 /* ZXSMSTOMMSTOResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D2F166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.m */; };
+ 254041AA166AAE6000E13304 /* ZXSMTPResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D31166A9A0800E13304 /* ZXSMTPResultParser.m */; };
+ 254041AB166AAE6000E13304 /* ZXTelParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D33166A9A0800E13304 /* ZXTelParsedResult.m */; };
+ 254041AC166AAE6000E13304 /* ZXTelResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D35166A9A0800E13304 /* ZXTelResultParser.m */; };
+ 254041AD166AAE6000E13304 /* ZXTextParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D37166A9A0800E13304 /* ZXTextParsedResult.m */; };
+ 254041AE166AAE6000E13304 /* ZXURIParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D39166A9A0800E13304 /* ZXURIParsedResult.m */; };
+ 254041AF166AAE6000E13304 /* ZXURIResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D3B166A9A0800E13304 /* ZXURIResultParser.m */; };
+ 254041B0166AAE6000E13304 /* ZXURLTOResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D3D166A9A0800E13304 /* ZXURLTOResultParser.m */; };
+ 254041B1166AAE6000E13304 /* ZXVCardResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D3F166A9A0800E13304 /* ZXVCardResultParser.m */; };
+ 254041B2166AAE6000E13304 /* ZXVEventResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D41166A9A0800E13304 /* ZXVEventResultParser.m */; };
+ 254041B3166AAE6000E13304 /* ZXWifiParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D43166A9A0800E13304 /* ZXWifiParsedResult.m */; };
+ 254041B4166AAE6000E13304 /* ZXWifiResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D45166A9A0800E13304 /* ZXWifiResultParser.m */; };
+ 254041B5166AAE6000E13304 /* ZXCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D47166A9A0800E13304 /* ZXCapture.m */; };
+ 254041B6166AAE6000E13304 /* ZXCaptureView.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D4A166A9A0800E13304 /* ZXCaptureView.m */; };
+ 254041B7166AAE6000E13304 /* ZXCGImageLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D4C166A9A0800E13304 /* ZXCGImageLuminanceSource.m */; };
+ 254041B8166AAE6000E13304 /* ZXImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D4E166A9A0800E13304 /* ZXImage.m */; };
+ 254041B9166AAE6000E13304 /* ZXMathUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA2166A9C0E00E13304 /* ZXMathUtils.m */; };
+ 254041BA166AAE6000E13304 /* ZXMonochromeRectangleDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA4166A9C0E00E13304 /* ZXMonochromeRectangleDetector.m */; };
+ 254041BB166AAE6000E13304 /* ZXWhiteRectangleDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA6166A9C0E00E13304 /* ZXWhiteRectangleDetector.m */; };
+ 254041BC166AAE6000E13304 /* ZXGenericGF.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA9166A9C0E00E13304 /* ZXGenericGF.m */; };
+ 254041BD166AAE6000E13304 /* ZXGenericGFPoly.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DAB166A9C0E00E13304 /* ZXGenericGFPoly.m */; };
+ 254041BE166AAE6000E13304 /* ZXReedSolomonDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DAD166A9C0E00E13304 /* ZXReedSolomonDecoder.m */; };
+ 254041BF166AAE6000E13304 /* ZXReedSolomonEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DAF166A9C0E00E13304 /* ZXReedSolomonEncoder.m */; };
+ 254041C0166AAE6000E13304 /* ZXBitArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB1166A9C0E00E13304 /* ZXBitArray.m */; };
+ 254041C1166AAE6000E13304 /* ZXBitMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB3166A9C0E00E13304 /* ZXBitMatrix.m */; };
+ 254041C2166AAE6000E13304 /* ZXBitSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB5166A9C0E00E13304 /* ZXBitSource.m */; };
+ 254041C3166AAE6000E13304 /* ZXCharacterSetECI.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB7166A9C0E00E13304 /* ZXCharacterSetECI.m */; };
+ 254041C4166AAE6000E13304 /* ZXDecoderResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB9166A9C0E00E13304 /* ZXDecoderResult.m */; };
+ 254041C5166AAE6000E13304 /* ZXDefaultGridSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DBB166A9C0E00E13304 /* ZXDefaultGridSampler.m */; };
+ 254041C6166AAE6000E13304 /* ZXDetectorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DBD166A9C0E00E13304 /* ZXDetectorResult.m */; };
+ 254041C7166AAE6000E13304 /* ZXECI.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DBF166A9C0E00E13304 /* ZXECI.m */; };
+ 254041C8166AAE6000E13304 /* ZXGlobalHistogramBinarizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC1166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.m */; };
+ 254041C9166AAE6000E13304 /* ZXGridSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC3166A9C0E00E13304 /* ZXGridSampler.m */; };
+ 254041CA166AAE6000E13304 /* ZXHybridBinarizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC5166A9C0E00E13304 /* ZXHybridBinarizer.m */; };
+ 254041CB166AAE6000E13304 /* ZXPerspectiveTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC7166A9C0E00E13304 /* ZXPerspectiveTransform.m */; };
+ 254041CC166AAE6000E13304 /* ZXStringUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC9166A9C0E00E13304 /* ZXStringUtils.m */; };
+ 254041CD166AAE6000E13304 /* ZXDataMatrixBitMatrixParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DF5166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.m */; };
+ 254041CE166AAE6000E13304 /* ZXDataMatrixDataBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DF7166A9CCB00E13304 /* ZXDataMatrixDataBlock.m */; };
+ 254041CF166AAE6000E13304 /* ZXDataMatrixDecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DF9166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.m */; };
+ 254041D0166AAE6000E13304 /* ZXDataMatrixDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DFB166A9CCB00E13304 /* ZXDataMatrixDecoder.m */; };
+ 254041D1166AAE6000E13304 /* ZXDataMatrixVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DFD166A9CCB00E13304 /* ZXDataMatrixVersion.m */; };
+ 254041D2166AAE6000E13304 /* ZXDataMatrixDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E00166A9CCB00E13304 /* ZXDataMatrixDetector.m */; };
+ 254041D3166AAE6000E13304 /* ZXDataMatrixReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E02166A9CCB00E13304 /* ZXDataMatrixReader.m */; };
+ 254041D4166AAE6000E13304 /* ZXMaxiCodeBitMatrixParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E14166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.m */; };
+ 254041D5166AAE6000E13304 /* ZXMaxiCodeDecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E16166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.m */; };
+ 254041D6166AAE6000E13304 /* ZXMaxiCodeDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E18166A9D4B00E13304 /* ZXMaxiCodeDecoder.m */; };
+ 254041D7166AAE6000E13304 /* ZXMaxiCodeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E1A166A9D4B00E13304 /* ZXMaxiCodeReader.m */; };
+ 254041D8166AAE6000E13304 /* ZXMultiDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E27166A9D8B00E13304 /* ZXMultiDetector.m */; };
+ 254041D9166AAE6000E13304 /* ZXMultiFinderPatternFinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E29166A9D8B00E13304 /* ZXMultiFinderPatternFinder.m */; };
+ 254041DA166AAE6000E13304 /* ZXQRCodeMultiReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E2B166A9D8B00E13304 /* ZXQRCodeMultiReader.m */; };
+ 254041DB166AAE6000E13304 /* ZXByQuadrantReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E2D166A9D8B00E13304 /* ZXByQuadrantReader.m */; };
+ 254041DC166AAE6000E13304 /* ZXGenericMultipleBarcodeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E2F166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.m */; };
+ 254041DD166AAE6000E13304 /* ZXAbstractExpandedDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E41166A9DF300E13304 /* ZXAbstractExpandedDecoder.m */; };
+ 254041DE166AAE6000E13304 /* ZXAI013103decoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E43166A9DF300E13304 /* ZXAI013103decoder.m */; };
+ 254041DF166AAE6000E13304 /* ZXAI01320xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E45166A9DF300E13304 /* ZXAI01320xDecoder.m */; };
+ 254041E0166AAE6000E13304 /* ZXAI01392xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E47166A9DF300E13304 /* ZXAI01392xDecoder.m */; };
+ 254041E1166AAE6000E13304 /* ZXAI01393xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E49166A9DF300E13304 /* ZXAI01393xDecoder.m */; };
+ 254041E2166AAE6000E13304 /* ZXAI013x0x1xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E4B166A9DF300E13304 /* ZXAI013x0x1xDecoder.m */; };
+ 254041E3166AAE6000E13304 /* ZXAI013x0xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E4D166A9DF300E13304 /* ZXAI013x0xDecoder.m */; };
+ 254041E4166AAE6000E13304 /* ZXAI01AndOtherAIs.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E4F166A9DF300E13304 /* ZXAI01AndOtherAIs.m */; };
+ 254041E5166AAE6000E13304 /* ZXAI01decoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E51166A9DF300E13304 /* ZXAI01decoder.m */; };
+ 254041E6166AAE6000E13304 /* ZXAI01weightDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E53166A9DF300E13304 /* ZXAI01weightDecoder.m */; };
+ 254041E7166AAE6000E13304 /* ZXAnyAIDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E55166A9DF300E13304 /* ZXAnyAIDecoder.m */; };
+ 254041E8166AAE6000E13304 /* ZXBlockParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E57166A9DF300E13304 /* ZXBlockParsedResult.m */; };
+ 254041E9166AAE6000E13304 /* ZXCurrentParsingState.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E59166A9DF300E13304 /* ZXCurrentParsingState.m */; };
+ 254041EA166AAE6000E13304 /* ZXDecodedChar.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E5B166A9DF300E13304 /* ZXDecodedChar.m */; };
+ 254041EB166AAE6000E13304 /* ZXDecodedInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E5D166A9DF300E13304 /* ZXDecodedInformation.m */; };
+ 254041EC166AAE6000E13304 /* ZXDecodedNumeric.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E5F166A9DF300E13304 /* ZXDecodedNumeric.m */; };
+ 254041ED166AAE6000E13304 /* ZXDecodedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E61166A9DF300E13304 /* ZXDecodedObject.m */; };
+ 254041EE166AAE6000E13304 /* ZXFieldParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E63166A9DF300E13304 /* ZXFieldParser.m */; };
+ 254041EF166AAE6000E13304 /* ZXGeneralAppIdDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E65166A9DF300E13304 /* ZXGeneralAppIdDecoder.m */; };
+ 254041F0166AAE6000E13304 /* ZXBitArrayBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E67166A9DF300E13304 /* ZXBitArrayBuilder.m */; };
+ 254041F1166AAE6000E13304 /* ZXExpandedPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E69166A9DF300E13304 /* ZXExpandedPair.m */; };
+ 254041F2166AAE6000E13304 /* ZXRSSExpandedReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E6B166A9DF300E13304 /* ZXRSSExpandedReader.m */; };
+ 254041F3166AAE6000E13304 /* ZXAbstractRSSReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E6D166A9DF300E13304 /* ZXAbstractRSSReader.m */; };
+ 254041F4166AAE6000E13304 /* ZXDataCharacter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E6F166A9DF300E13304 /* ZXDataCharacter.m */; };
+ 254041F5166AAE6000E13304 /* ZXPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E71166A9DF300E13304 /* ZXPair.m */; };
+ 254041F6166AAE6000E13304 /* ZXRSS14Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E73166A9DF300E13304 /* ZXRSS14Reader.m */; };
+ 254041F7166AAE6000E13304 /* ZXRSSFinderPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E75166A9DF300E13304 /* ZXRSSFinderPattern.m */; };
+ 254041F8166AAE6000E13304 /* ZXRSSUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E77166A9DF300E13304 /* ZXRSSUtils.m */; };
+ 254041F9166AAE6000E13304 /* ZXCodaBarReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E79166A9DF300E13304 /* ZXCodaBarReader.m */; };
+ 254041FA166AAE6000E13304 /* ZXCodaBarWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E7B166A9DF300E13304 /* ZXCodaBarWriter.m */; };
+ 254041FB166AAE6000E13304 /* ZXCode128Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E7D166A9DF300E13304 /* ZXCode128Reader.m */; };
+ 254041FC166AAE6000E13304 /* ZXCode128Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E7F166A9DF300E13304 /* ZXCode128Writer.m */; };
+ 254041FD166AAE6000E13304 /* ZXCode39Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E81166A9DF300E13304 /* ZXCode39Reader.m */; };
+ 254041FE166AAE6000E13304 /* ZXCode39Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E83166A9DF300E13304 /* ZXCode39Writer.m */; };
+ 254041FF166AAE6000E13304 /* ZXCode93Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E85166A9DF300E13304 /* ZXCode93Reader.m */; };
+ 25404200166AAE6000E13304 /* ZXEAN13Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E87166A9DF300E13304 /* ZXEAN13Reader.m */; };
+ 25404201166AAE6000E13304 /* ZXEAN13Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E89166A9DF300E13304 /* ZXEAN13Writer.m */; };
+ 25404202166AAE6000E13304 /* ZXEAN8Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E8B166A9DF300E13304 /* ZXEAN8Reader.m */; };
+ 25404203166AAE6000E13304 /* ZXEAN8Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E8D166A9DF300E13304 /* ZXEAN8Writer.m */; };
+ 25404204166AAE6000E13304 /* ZXEANManufacturerOrgSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E8F166A9DF300E13304 /* ZXEANManufacturerOrgSupport.m */; };
+ 25404205166AAE6000E13304 /* ZXITFReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E91166A9DF300E13304 /* ZXITFReader.m */; };
+ 25404206166AAE6000E13304 /* ZXITFWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E93166A9DF300E13304 /* ZXITFWriter.m */; };
+ 25404207166AAE6000E13304 /* ZXMultiFormatOneDReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E95166A9DF300E13304 /* ZXMultiFormatOneDReader.m */; };
+ 25404208166AAE6000E13304 /* ZXMultiFormatUPCEANReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E97166A9DF300E13304 /* ZXMultiFormatUPCEANReader.m */; };
+ 25404209166AAE6000E13304 /* ZXOneDimensionalCodeWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E99166A9DF300E13304 /* ZXOneDimensionalCodeWriter.m */; };
+ 2540420A166AAE6000E13304 /* ZXOneDReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E9B166A9DF300E13304 /* ZXOneDReader.m */; };
+ 2540420B166AAE6000E13304 /* ZXUPCAReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E9D166A9DF300E13304 /* ZXUPCAReader.m */; };
+ 2540420C166AAE6000E13304 /* ZXUPCAWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E9F166A9DF300E13304 /* ZXUPCAWriter.m */; };
+ 2540420D166AAE6000E13304 /* ZXUPCEANExtension2Support.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA1166A9DF300E13304 /* ZXUPCEANExtension2Support.m */; };
+ 2540420E166AAE6000E13304 /* ZXUPCEANExtension5Support.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA3166A9DF300E13304 /* ZXUPCEANExtension5Support.m */; };
+ 2540420F166AAE6000E13304 /* ZXUPCEANExtensionSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA5166A9DF300E13304 /* ZXUPCEANExtensionSupport.m */; };
+ 25404210166AAE6000E13304 /* ZXUPCEANReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA7166A9DF300E13304 /* ZXUPCEANReader.m */; };
+ 25404211166AAE6000E13304 /* ZXUPCEANWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA9166A9DF300E13304 /* ZXUPCEANWriter.m */; };
+ 25404212166AAE6000E13304 /* ZXUPCEReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EAB166A9DF300E13304 /* ZXUPCEReader.m */; };
+ 25404213166AAE6000E13304 /* ZXModulusGF.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F1C166A9EB500E13304 /* ZXModulusGF.m */; };
+ 25404214166AAE6000E13304 /* ZXModulusPoly.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F1E166A9EB500E13304 /* ZXModulusPoly.m */; };
+ 25404215166AAE6000E13304 /* ZXPDF417ECErrorCorrection.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F20166A9EB500E13304 /* ZXPDF417ECErrorCorrection.m */; };
+ 25404217166AAE6000E13304 /* ZXPDF417DecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F24166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.m */; };
+ 25404219166AAE6000E13304 /* ZXPDF417Detector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F29166A9EB500E13304 /* ZXPDF417Detector.m */; };
+ 2540421A166AAE6000E13304 /* ZXBarcodeMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F2C166A9EB500E13304 /* ZXBarcodeMatrix.m */; };
+ 2540421B166AAE6000E13304 /* ZXBarcodeRow.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F2E166A9EB500E13304 /* ZXBarcodeRow.m */; };
+ 2540421C166AAE6000E13304 /* ZXDimensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F31166A9EB500E13304 /* ZXDimensions.m */; };
+ 2540421D166AAE6000E13304 /* ZXPDF417.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F33166A9EB500E13304 /* ZXPDF417.m */; };
+ 2540421E166AAE6000E13304 /* ZXPDF417ErrorCorrection.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F35166A9EB500E13304 /* ZXPDF417ErrorCorrection.m */; };
+ 2540421F166AAE6000E13304 /* ZXPDF417HighLevelEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F37166A9EB500E13304 /* ZXPDF417HighLevelEncoder.m */; };
+ 25404221166AAE6000E13304 /* ZXPDF417Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F3B166A9EB500E13304 /* ZXPDF417Reader.m */; };
+ 25404222166AAE6000E13304 /* ZXDataMask.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F5E166A9F2D00E13304 /* ZXDataMask.m */; };
+ 25404223166AAE6000E13304 /* ZXErrorCorrectionLevel.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F60166A9F2D00E13304 /* ZXErrorCorrectionLevel.m */; };
+ 25404224166AAE6000E13304 /* ZXFormatInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F62166A9F2D00E13304 /* ZXFormatInformation.m */; };
+ 25404225166AAE6000E13304 /* ZXMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F64166A9F2D00E13304 /* ZXMode.m */; };
+ 25404226166AAE6000E13304 /* ZXQRCodeBitMatrixParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F66166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.m */; };
+ 25404227166AAE6000E13304 /* ZXQRCodeDataBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F68166A9F2D00E13304 /* ZXQRCodeDataBlock.m */; };
+ 25404228166AAE6000E13304 /* ZXQRCodeDecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F6A166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.m */; };
+ 25404229166AAE6000E13304 /* ZXQRCodeDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F6C166A9F2D00E13304 /* ZXQRCodeDecoder.m */; };
+ 2540422A166AAE6000E13304 /* ZXQRCodeVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F6E166A9F2D00E13304 /* ZXQRCodeVersion.m */; };
+ 2540422B166AAE6000E13304 /* ZXAlignmentPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F71166A9F2D00E13304 /* ZXAlignmentPattern.m */; };
+ 2540422C166AAE6000E13304 /* ZXAlignmentPatternFinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F73166A9F2D00E13304 /* ZXAlignmentPatternFinder.m */; };
+ 2540422D166AAE6000E13304 /* ZXFinderPatternFinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F75166A9F2D00E13304 /* ZXFinderPatternFinder.m */; };
+ 2540422E166AAE6000E13304 /* ZXFinderPatternInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F77166A9F2D00E13304 /* ZXFinderPatternInfo.m */; };
+ 2540422F166AAE6000E13304 /* ZXQRCodeDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F79166A9F2D00E13304 /* ZXQRCodeDetector.m */; };
+ 25404230166AAE6000E13304 /* ZXQRCodeFinderPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F7B166A9F2D00E13304 /* ZXQRCodeFinderPattern.m */; };
+ 25404231166AAE6000E13304 /* ZXBlockPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F7E166A9F2D00E13304 /* ZXBlockPair.m */; };
+ 25404232166AAE6000E13304 /* ZXByteMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F80166A9F2D00E13304 /* ZXByteMatrix.m */; };
+ 25404233166AAE6000E13304 /* ZXEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F82166A9F2D00E13304 /* ZXEncoder.m */; };
+ 25404234166AAE6000E13304 /* ZXMaskUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F84166A9F2D00E13304 /* ZXMaskUtil.m */; };
+ 25404235166AAE6000E13304 /* ZXMatrixUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F86166A9F2D00E13304 /* ZXMatrixUtil.m */; };
+ 25404236166AAE6000E13304 /* ZXQRCode.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F88166A9F2D00E13304 /* ZXQRCode.m */; };
+ 25404237166AAE6000E13304 /* ZXQRCodeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F8A166A9F2D00E13304 /* ZXQRCodeReader.m */; };
+ 25404238166AAE6000E13304 /* ZXQRCodeWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F8C166A9F2D00E13304 /* ZXQRCodeWriter.m */; };
+ 25404239166AAE6000E13304 /* ZXBinarizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FBD166A9FFC00E13304 /* ZXBinarizer.m */; };
+ 2540423A166AAE6000E13304 /* ZXBinaryBitmap.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FBF166A9FFC00E13304 /* ZXBinaryBitmap.m */; };
+ 2540423B166AAE6000E13304 /* ZXDecodeHints.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FC1166A9FFC00E13304 /* ZXDecodeHints.m */; };
+ 2540423C166AAE6000E13304 /* ZXEncodeHints.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FC3166A9FFC00E13304 /* ZXEncodeHints.m */; };
+ 2540423D166AAE6000E13304 /* ZXErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FC5166A9FFC00E13304 /* ZXErrors.m */; };
+ 2540423E166AAE6000E13304 /* ZXLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD2166AA00700E13304 /* ZXLuminanceSource.m */; };
+ 2540423F166AAE6000E13304 /* ZXMultiFormatReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD4166AA00700E13304 /* ZXMultiFormatReader.m */; };
+ 25404240166AAE6000E13304 /* ZXMultiFormatWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD6166AA00700E13304 /* ZXMultiFormatWriter.m */; };
+ 25404241166AAE6000E13304 /* ZXResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD9166AA00700E13304 /* ZXResult.m */; };
+ 25404242166AAE6000E13304 /* ZXResultPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FDC166AA00700E13304 /* ZXResultPoint.m */; };
+ 2540431D166AB8B800E13304 /* ZXAddressBookParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FF5166AA0F100E13304 /* ZXAddressBookParsedResultTestCase.m */; };
+ 2540431E166AB8B800E13304 /* ZXCalendarParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FF7166AA0F100E13304 /* ZXCalendarParsedResultTestCase.m */; };
+ 2540431F166AB8B800E13304 /* ZXEmailAddressParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FF9166AA0F100E13304 /* ZXEmailAddressParsedResultTestCase.m */; };
+ 25404320166AB8B800E13304 /* ZXExpandedProductParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FFB166AA0F100E13304 /* ZXExpandedProductParsedResultTestCase.m */; };
+ 25404321166AB8B800E13304 /* ZXGeoParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FFD166AA0F100E13304 /* ZXGeoParsedResultTestCase.m */; };
+ 25404322166AB8B800E13304 /* ZXISBNParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FFF166AA0F100E13304 /* ZXISBNParsedResultTestCase.m */; };
+ 25404323166AB8B800E13304 /* ZXParsedReaderResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404001166AA0F100E13304 /* ZXParsedReaderResultTestCase.m */; };
+ 25404324166AB8B800E13304 /* ZXProductParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404003166AA0F100E13304 /* ZXProductParsedResultTestCase.m */; };
+ 25404325166AB8B800E13304 /* ZXSMSMMSParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404005166AA0F100E13304 /* ZXSMSMMSParsedResultTestCase.m */; };
+ 25404326166AB8B800E13304 /* ZXTelParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404007166AA0F100E13304 /* ZXTelParsedResultTestCase.m */; };
+ 25404327166AB8B800E13304 /* ZXURIParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404009166AA0F100E13304 /* ZXURIParsedResultTestCase.m */; };
+ 25404328166AB8B800E13304 /* ZXWifiParsedResultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540400B166AA0F100E13304 /* ZXWifiParsedResultTestCase.m */; };
+ 25404330166AB8B800E13304 /* ZXBitArrayTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540401D166AA0F100E13304 /* ZXBitArrayTestCase.m */; };
+ 25404331166AB8B800E13304 /* ZXBitMatrixTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540401F166AA0F100E13304 /* ZXBitMatrixTestCase.m */; };
+ 25404332166AB8B800E13304 /* ZXBitSourceBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404021166AA0F100E13304 /* ZXBitSourceBuilder.m */; };
+ 25404333166AB8B800E13304 /* ZXBitSourceTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404023166AA0F100E13304 /* ZXBitSourceTestCase.m */; };
+ 25404334166AB8B800E13304 /* ZXPerspectiveTransformTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404025166AA0F100E13304 /* ZXPerspectiveTransformTestCase.m */; };
+ 25404335166AB8B800E13304 /* ZXStringUtilsTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404027166AA0F100E13304 /* ZXStringUtilsTestCase.m */; };
+ 25404338166AB8B800E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540402F166AA0F100E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.m */; };
+ 2540434D166AB8B800E13304 /* AbstractDecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540405E166AA0F100E13304 /* AbstractDecoderTest.m */; };
+ 2540434E166AB8B800E13304 /* AI01_3103_DecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404060166AA0F100E13304 /* AI01_3103_DecoderTest.m */; };
+ 2540434F166AB8B800E13304 /* AI01_3202_3203_DecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404062166AA0F100E13304 /* AI01_3202_3203_DecoderTest.m */; };
+ 25404350166AB8B800E13304 /* AI01_3X0X_1X_DecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404064166AA0F100E13304 /* AI01_3X0X_1X_DecoderTest.m */; };
+ 25404351166AB8B800E13304 /* AnyAIDecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404066166AA0F100E13304 /* AnyAIDecoderTest.m */; };
+ 25404352166AB8B800E13304 /* ZXFieldParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404068166AA0F100E13304 /* ZXFieldParserTest.m */; };
+ 25404356166AB8B800E13304 /* RSSExpandedImage2binaryTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404070166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.m */; };
+ 25404357166AB8B800E13304 /* RSSExpandedImage2resultTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404072166AA0F100E13304 /* RSSExpandedImage2resultTestCase.m */; };
+ 25404358166AB8B800E13304 /* RSSExpandedImage2stringTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404074166AA0F100E13304 /* RSSExpandedImage2stringTestCase.m */; };
+ 25404359166AB8B800E13304 /* RSSExpandedInternalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404076166AA0F100E13304 /* RSSExpandedInternalTestCase.m */; };
+ 2540435A166AB8B800E13304 /* ZXBinaryUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404078166AA0F100E13304 /* ZXBinaryUtil.m */; };
+ 2540435B166AB8B800E13304 /* ZXBinaryUtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540407A166AA0F100E13304 /* ZXBinaryUtilTest.m */; };
+ 2540435C166AB8B800E13304 /* ZXBitArrayBuilderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540407C166AA0F100E13304 /* ZXBitArrayBuilderTest.m */; };
+ 2540435D166AB8B800E13304 /* ZXExpandedInformationDecoderTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540407E166AA0F100E13304 /* ZXExpandedInformationDecoderTest.m */; };
+ 2540436A166AB8B800E13304 /* ZXCodaBarWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25404098166AA0F100E13304 /* ZXCodaBarWriterTestCase.m */; };
+ 2540436C166AB8B800E13304 /* ZXEAN13WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540409C166AA0F100E13304 /* ZXEAN13WriterTestCase.m */; };
+ 2540436D166AB8B800E13304 /* ZXEAN8WriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2540409E166AA0F100E13304 /* ZXEAN8WriterTestCase.m */; };
+ 2540436E166AB8B800E13304 /* ZXEANManufacturerOrgSupportTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040A0166AA0F100E13304 /* ZXEANManufacturerOrgSupportTest.m */; };
+ 25404370166AB8B800E13304 /* ZXUPCAWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040A4166AA0F100E13304 /* ZXUPCAWriterTestCase.m */; };
+ 25404371166AB8B800E13304 /* AbstractErrorCorrectionTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040A9166AA0F100E13304 /* AbstractErrorCorrectionTestCase.m */; };
+ 25404372166AB8B800E13304 /* ZXPDF417ECErrorCorrectionTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040AB166AA0F100E13304 /* ZXPDF417ECErrorCorrectionTestCase.m */; };
+ 25404375166AB8B800E13304 /* ZXDataMaskTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040B3166AA0F100E13304 /* ZXDataMaskTestCase.m */; };
+ 25404376166AB8B800E13304 /* ZXErrorCorrectionLevelTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040B5166AA0F100E13304 /* ZXErrorCorrectionLevelTestCase.m */; };
+ 25404377166AB8B800E13304 /* ZXFormatInformationTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040B7166AA0F100E13304 /* ZXFormatInformationTestCase.m */; };
+ 25404378166AB8B800E13304 /* ZXModeTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040B9166AA0F100E13304 /* ZXModeTestCase.m */; };
+ 25404379166AB8B800E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040BB166AA0F100E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.m */; };
+ 2540437A166AB8B800E13304 /* ZXQRCodeVersionTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040BD166AA0F100E13304 /* ZXQRCodeVersionTestCase.m */; };
+ 2540437B166AB8B800E13304 /* BitVectorTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C0166AA0F100E13304 /* BitVectorTestCase.m */; };
+ 2540437C166AB8B800E13304 /* ZXEncoderTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C2166AA0F100E13304 /* ZXEncoderTestCase.m */; };
+ 2540437D166AB8B800E13304 /* ZXMaskUtilTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C4166AA0F100E13304 /* ZXMaskUtilTestCase.m */; };
+ 2540437E166AB8B800E13304 /* ZXMatrixUtilTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C6166AA0F100E13304 /* ZXMatrixUtilTestCase.m */; };
+ 2540437F166AB8B800E13304 /* ZXQRCodeTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040C8166AA0F100E13304 /* ZXQRCodeTestCase.m */; };
+ 25404386166AB8B800E13304 /* ZXQRCodeWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254040D6166AA0F100E13304 /* ZXQRCodeWriterTestCase.m */; };
+ 25404388166AB8CF00E13304 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404387166AB8CF00E13304 /* CoreVideo.framework */; };
+ 25404389166AB8D600E13304 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404387166AB8CF00E13304 /* CoreVideo.framework */; };
+ 25404390166AB91700E13304 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540438F166AB91700E13304 /* Cocoa.framework */; };
+ 25404395166AB95700E13304 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404394166AB95700E13304 /* ApplicationServices.framework */; };
+ 25404397166AB96000E13304 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404394166AB95700E13304 /* ApplicationServices.framework */; };
+ 254043B5166ABA6B00E13304 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540438F166AB91700E13304 /* Cocoa.framework */; };
+ 254043B6166ABA7500E13304 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404394166AB95700E13304 /* ApplicationServices.framework */; };
+ 254043B7166ABA7800E13304 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404387166AB8CF00E13304 /* CoreVideo.framework */; };
+ 2540452B166ABAF000E13304 /* ZXAztecDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CEE166A999D00E13304 /* ZXAztecDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540452C166ABAF000E13304 /* ZXAztecDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CF1166A999D00E13304 /* ZXAztecDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540452D166ABAF000E13304 /* ZXAztecDetectorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CF3166A999D00E13304 /* ZXAztecDetectorResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540452E166ABAF000E13304 /* ZXAztecReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CF5166A999D00E13304 /* ZXAztecReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540452F166ABAF000E13304 /* ZXAbstractDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D01166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404530166ABAF000E13304 /* ZXAddressBookAUResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D03166A9A0800E13304 /* ZXAddressBookAUResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404531166ABAF000E13304 /* ZXAddressBookDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D05166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404532166ABAF000E13304 /* ZXAddressBookParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D07166A9A0800E13304 /* ZXAddressBookParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404533166ABAF000E13304 /* ZXBizcardResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D09166A9A0800E13304 /* ZXBizcardResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404534166ABAF000E13304 /* ZXBookmarkDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D0B166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404535166ABAF000E13304 /* ZXCalendarParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D0D166A9A0800E13304 /* ZXCalendarParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404536166ABAF000E13304 /* ZXEmailAddressParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D0F166A9A0800E13304 /* ZXEmailAddressParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404537166ABAF000E13304 /* ZXEmailAddressResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D11166A9A0800E13304 /* ZXEmailAddressResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404538166ABAF000E13304 /* ZXEmailDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D13166A9A0800E13304 /* ZXEmailDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404539166ABAF000E13304 /* ZXExpandedProductParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D15166A9A0800E13304 /* ZXExpandedProductParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540453A166ABAF000E13304 /* ZXExpandedProductResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D17166A9A0800E13304 /* ZXExpandedProductResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540453B166ABAF000E13304 /* ZXGeoParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D19166A9A0800E13304 /* ZXGeoParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540453C166ABAF000E13304 /* ZXGeoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D1B166A9A0800E13304 /* ZXGeoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540453D166ABAF000E13304 /* ZXISBNParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D1D166A9A0800E13304 /* ZXISBNParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540453E166ABAF000E13304 /* ZXISBNResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D1F166A9A0800E13304 /* ZXISBNResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540453F166ABAF000E13304 /* ZXParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D21166A9A0800E13304 /* ZXParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404540166ABAF000E13304 /* ZXParsedResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D23166A9A0800E13304 /* ZXParsedResultType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404541166ABAF000E13304 /* ZXProductParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D24166A9A0800E13304 /* ZXProductParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404542166ABAF000E13304 /* ZXProductResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D26166A9A0800E13304 /* ZXProductResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404543166ABAF000E13304 /* ZXResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D28166A9A0800E13304 /* ZXResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404544166ABAF000E13304 /* ZXSMSMMSResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D2A166A9A0800E13304 /* ZXSMSMMSResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404545166ABAF000E13304 /* ZXSMSParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D2C166A9A0800E13304 /* ZXSMSParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404546166ABAF000E13304 /* ZXSMSTOMMSTOResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D2E166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404547166ABAF000E13304 /* ZXSMTPResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D30166A9A0800E13304 /* ZXSMTPResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404548166ABAF000E13304 /* ZXTelParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D32166A9A0800E13304 /* ZXTelParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404549166ABAF000E13304 /* ZXTelResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D34166A9A0800E13304 /* ZXTelResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540454A166ABAF000E13304 /* ZXTextParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D36166A9A0800E13304 /* ZXTextParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540454B166ABAF000E13304 /* ZXURIParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D38166A9A0800E13304 /* ZXURIParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540454C166ABAF000E13304 /* ZXURIResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D3A166A9A0800E13304 /* ZXURIResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540454D166ABAF000E13304 /* ZXURLTOResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D3C166A9A0800E13304 /* ZXURLTOResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540454E166ABAF000E13304 /* ZXVCardResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D3E166A9A0800E13304 /* ZXVCardResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540454F166ABAF000E13304 /* ZXVEventResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D40166A9A0800E13304 /* ZXVEventResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404550166ABAF000E13304 /* ZXWifiParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D42166A9A0800E13304 /* ZXWifiParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404551166ABAF000E13304 /* ZXWifiResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D44166A9A0800E13304 /* ZXWifiResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404552166ABAF000E13304 /* ZXCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D46166A9A0800E13304 /* ZXCapture.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404553166ABAF000E13304 /* ZXCaptureDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D48166A9A0800E13304 /* ZXCaptureDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404554166ABAF000E13304 /* ZXCaptureView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D49166A9A0800E13304 /* ZXCaptureView.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404555166ABAF000E13304 /* ZXCGImageLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D4B166A9A0800E13304 /* ZXCGImageLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404556166ABAF000E13304 /* ZXImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D4D166A9A0800E13304 /* ZXImage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404557166ABAF000E13304 /* ZXView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D4F166A9A0800E13304 /* ZXView.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404558166ABAF000E13304 /* ZXMathUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA1166A9C0E00E13304 /* ZXMathUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404559166ABAF000E13304 /* ZXMonochromeRectangleDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA3166A9C0E00E13304 /* ZXMonochromeRectangleDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540455A166ABAF000E13304 /* ZXWhiteRectangleDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA5166A9C0E00E13304 /* ZXWhiteRectangleDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540455B166ABAF000E13304 /* ZXGenericGF.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA8166A9C0E00E13304 /* ZXGenericGF.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540455C166ABAF000E13304 /* ZXGenericGFPoly.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DAA166A9C0E00E13304 /* ZXGenericGFPoly.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540455D166ABAF000E13304 /* ZXReedSolomonDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DAC166A9C0E00E13304 /* ZXReedSolomonDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540455E166ABAF000E13304 /* ZXReedSolomonEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DAE166A9C0E00E13304 /* ZXReedSolomonEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540455F166ABAF000E13304 /* ZXBitArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB0166A9C0E00E13304 /* ZXBitArray.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404560166ABAF000E13304 /* ZXBitMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB2166A9C0E00E13304 /* ZXBitMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404561166ABAF000E13304 /* ZXBitSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB4166A9C0E00E13304 /* ZXBitSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404562166ABAF000E13304 /* ZXCharacterSetECI.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB6166A9C0E00E13304 /* ZXCharacterSetECI.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404563166ABAF000E13304 /* ZXDecoderResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB8166A9C0E00E13304 /* ZXDecoderResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404564166ABAF000E13304 /* ZXDefaultGridSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DBA166A9C0E00E13304 /* ZXDefaultGridSampler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404565166ABAF000E13304 /* ZXDetectorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DBC166A9C0E00E13304 /* ZXDetectorResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404566166ABAF000E13304 /* ZXECI.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DBE166A9C0E00E13304 /* ZXECI.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404567166ABAF000E13304 /* ZXGlobalHistogramBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC0166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404568166ABAF000E13304 /* ZXGridSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC2166A9C0E00E13304 /* ZXGridSampler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404569166ABAF000E13304 /* ZXHybridBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC4166A9C0E00E13304 /* ZXHybridBinarizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540456A166ABAF000E13304 /* ZXPerspectiveTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC6166A9C0E00E13304 /* ZXPerspectiveTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540456B166ABAF000E13304 /* ZXStringUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC8166A9C0E00E13304 /* ZXStringUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540456C166ABAF000E13304 /* ZXDataMatrixBitMatrixParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DF4166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540456D166ABAF000E13304 /* ZXDataMatrixDataBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DF6166A9CCB00E13304 /* ZXDataMatrixDataBlock.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540456E166ABAF000E13304 /* ZXDataMatrixDecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DF8166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540456F166ABAF000E13304 /* ZXDataMatrixDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DFA166A9CCB00E13304 /* ZXDataMatrixDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404570166ABAF000E13304 /* ZXDataMatrixVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DFC166A9CCB00E13304 /* ZXDataMatrixVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404571166ABAF000E13304 /* ZXDataMatrixDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DFF166A9CCB00E13304 /* ZXDataMatrixDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404572166ABAF000E13304 /* ZXDataMatrixReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E01166A9CCB00E13304 /* ZXDataMatrixReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404573166ABAF000E13304 /* ZXMaxiCodeBitMatrixParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E13166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404574166ABAF000E13304 /* ZXMaxiCodeDecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E15166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404575166ABAF000E13304 /* ZXMaxiCodeDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E17166A9D4B00E13304 /* ZXMaxiCodeDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404576166ABAF000E13304 /* ZXMaxiCodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E19166A9D4B00E13304 /* ZXMaxiCodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404577166ABAF000E13304 /* ZXMultiDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E26166A9D8B00E13304 /* ZXMultiDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404578166ABAF000E13304 /* ZXMultiFinderPatternFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E28166A9D8B00E13304 /* ZXMultiFinderPatternFinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404579166ABAF000E13304 /* ZXQRCodeMultiReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E2A166A9D8B00E13304 /* ZXQRCodeMultiReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540457A166ABAF000E13304 /* ZXByQuadrantReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E2C166A9D8B00E13304 /* ZXByQuadrantReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540457B166ABAF000E13304 /* ZXGenericMultipleBarcodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E2E166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540457C166ABAF000E13304 /* ZXMultipleBarcodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E30166A9D8B00E13304 /* ZXMultipleBarcodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540457D166ABAF000E13304 /* ZXPDF417Detector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F28166A9EB500E13304 /* ZXPDF417Detector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540457E166ABAF000E13304 /* ZXBarcodeMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F2B166A9EB500E13304 /* ZXBarcodeMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540457F166ABAF000E13304 /* ZXBarcodeRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F2D166A9EB500E13304 /* ZXBarcodeRow.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404580166ABAF000E13304 /* ZXCompaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F2F166A9EB500E13304 /* ZXCompaction.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404581166ABAF000E13304 /* ZXDimensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F30166A9EB500E13304 /* ZXDimensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404582166ABAF000E13304 /* ZXPDF417.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F32166A9EB500E13304 /* ZXPDF417.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404583166ABAF000E13304 /* ZXPDF417ErrorCorrection.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F34166A9EB500E13304 /* ZXPDF417ErrorCorrection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404584166ABAF000E13304 /* ZXPDF417HighLevelEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F36166A9EB500E13304 /* ZXPDF417HighLevelEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404586166ABAF000E13304 /* ZXPDF417Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F3A166A9EB500E13304 /* ZXPDF417Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404587166ABAF000E13304 /* ZXDataMask.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F5D166A9F2D00E13304 /* ZXDataMask.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404588166ABAF000E13304 /* ZXErrorCorrectionLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F5F166A9F2D00E13304 /* ZXErrorCorrectionLevel.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404589166ABAF000E13304 /* ZXFormatInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F61166A9F2D00E13304 /* ZXFormatInformation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540458A166ABAF000E13304 /* ZXMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F63166A9F2D00E13304 /* ZXMode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540458B166ABAF000E13304 /* ZXQRCodeBitMatrixParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F65166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540458C166ABAF000E13304 /* ZXQRCodeDataBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F67166A9F2D00E13304 /* ZXQRCodeDataBlock.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540458D166ABAF000E13304 /* ZXQRCodeDecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F69166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540458E166ABAF000E13304 /* ZXQRCodeDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F6B166A9F2D00E13304 /* ZXQRCodeDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540458F166ABAF000E13304 /* ZXQRCodeVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F6D166A9F2D00E13304 /* ZXQRCodeVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404590166ABAF000E13304 /* ZXAlignmentPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F70166A9F2D00E13304 /* ZXAlignmentPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404591166ABAF000E13304 /* ZXAlignmentPatternFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F72166A9F2D00E13304 /* ZXAlignmentPatternFinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404592166ABAF000E13304 /* ZXFinderPatternFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F74166A9F2D00E13304 /* ZXFinderPatternFinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404593166ABAF000E13304 /* ZXFinderPatternInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F76166A9F2D00E13304 /* ZXFinderPatternInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404594166ABAF000E13304 /* ZXQRCodeDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F78166A9F2D00E13304 /* ZXQRCodeDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404595166ABAF000E13304 /* ZXQRCodeFinderPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F7A166A9F2D00E13304 /* ZXQRCodeFinderPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404596166ABAF000E13304 /* ZXBlockPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F7D166A9F2D00E13304 /* ZXBlockPair.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404597166ABAF000E13304 /* ZXByteMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F7F166A9F2D00E13304 /* ZXByteMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404598166ABAF000E13304 /* ZXEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F81166A9F2D00E13304 /* ZXEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404599166ABAF000E13304 /* ZXMaskUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F83166A9F2D00E13304 /* ZXMaskUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540459A166ABAF000E13304 /* ZXMatrixUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F85166A9F2D00E13304 /* ZXMatrixUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540459B166ABAF000E13304 /* ZXQRCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F87166A9F2D00E13304 /* ZXQRCode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540459C166ABAF000E13304 /* ZXQRCodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F89166A9F2D00E13304 /* ZXQRCodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540459D166ABAF000E13304 /* ZXQRCodeWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F8B166A9F2D00E13304 /* ZXQRCodeWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540459E166ABAF000E13304 /* ZXBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FBC166A9FFC00E13304 /* ZXBinarizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2540459F166ABAF000E13304 /* ZXBinaryBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FBE166A9FFC00E13304 /* ZXBinaryBitmap.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A0166ABAF000E13304 /* ZXDecodeHints.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FC0166A9FFC00E13304 /* ZXDecodeHints.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A1166ABAF000E13304 /* ZXEncodeHints.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FC2166A9FFC00E13304 /* ZXEncodeHints.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A2166ABAF000E13304 /* ZXErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FC4166A9FFC00E13304 /* ZXErrors.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A3166ABAF000E13304 /* ZXingObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CBB166A96FA00E13304 /* ZXingObjC.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A4166ABAF000E13304 /* ZXLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD1166AA00700E13304 /* ZXLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A5166ABAF000E13304 /* ZXMultiFormatReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD3166AA00700E13304 /* ZXMultiFormatReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A6166ABAF000E13304 /* ZXMultiFormatWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD5166AA00700E13304 /* ZXMultiFormatWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A7166ABAF000E13304 /* ZXReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD7166AA00700E13304 /* ZXReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A8166ABAF000E13304 /* ZXResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD8166AA00700E13304 /* ZXResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045A9166ABAF000E13304 /* ZXResultMetadataType.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDA166AA00700E13304 /* ZXResultMetadataType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045AA166ABAF000E13304 /* ZXResultPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDB166AA00700E13304 /* ZXResultPoint.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045AB166ABAF000E13304 /* ZXResultPointCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDD166AA00700E13304 /* ZXResultPointCallback.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254045AC166ABAF000E13304 /* ZXWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDE166AA00700E13304 /* ZXWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25404648166ABBED00E13304 /* ZXAztecDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CEF166A999D00E13304 /* ZXAztecDecoder.m */; };
+ 25404649166ABBED00E13304 /* ZXAztecDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF2166A999D00E13304 /* ZXAztecDetector.m */; };
+ 2540464A166ABBED00E13304 /* ZXAztecDetectorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF4166A999D00E13304 /* ZXAztecDetectorResult.m */; };
+ 2540464B166ABBED00E13304 /* ZXAztecReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403CF6166A999D00E13304 /* ZXAztecReader.m */; };
+ 2540464C166ABBED00E13304 /* ZXAbstractDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D02166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.m */; };
+ 2540464D166ABBED00E13304 /* ZXAddressBookAUResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D04166A9A0800E13304 /* ZXAddressBookAUResultParser.m */; };
+ 2540464E166ABBED00E13304 /* ZXAddressBookDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D06166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.m */; };
+ 2540464F166ABBED00E13304 /* ZXAddressBookParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D08166A9A0800E13304 /* ZXAddressBookParsedResult.m */; };
+ 25404650166ABBED00E13304 /* ZXBizcardResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D0A166A9A0800E13304 /* ZXBizcardResultParser.m */; };
+ 25404651166ABBED00E13304 /* ZXBookmarkDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D0C166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.m */; };
+ 25404652166ABBED00E13304 /* ZXCalendarParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D0E166A9A0800E13304 /* ZXCalendarParsedResult.m */; };
+ 25404653166ABBED00E13304 /* ZXEmailAddressParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D10166A9A0800E13304 /* ZXEmailAddressParsedResult.m */; };
+ 25404654166ABBED00E13304 /* ZXEmailAddressResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D12166A9A0800E13304 /* ZXEmailAddressResultParser.m */; };
+ 25404655166ABBED00E13304 /* ZXEmailDoCoMoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D14166A9A0800E13304 /* ZXEmailDoCoMoResultParser.m */; };
+ 25404656166ABBED00E13304 /* ZXExpandedProductParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D16166A9A0800E13304 /* ZXExpandedProductParsedResult.m */; };
+ 25404657166ABBED00E13304 /* ZXExpandedProductResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D18166A9A0800E13304 /* ZXExpandedProductResultParser.m */; };
+ 25404658166ABBED00E13304 /* ZXGeoParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D1A166A9A0800E13304 /* ZXGeoParsedResult.m */; };
+ 25404659166ABBED00E13304 /* ZXGeoResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D1C166A9A0800E13304 /* ZXGeoResultParser.m */; };
+ 2540465A166ABBED00E13304 /* ZXISBNParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D1E166A9A0800E13304 /* ZXISBNParsedResult.m */; };
+ 2540465B166ABBED00E13304 /* ZXISBNResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D20166A9A0800E13304 /* ZXISBNResultParser.m */; };
+ 2540465C166ABBED00E13304 /* ZXParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D22166A9A0800E13304 /* ZXParsedResult.m */; };
+ 2540465D166ABBED00E13304 /* ZXProductParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D25166A9A0800E13304 /* ZXProductParsedResult.m */; };
+ 2540465E166ABBED00E13304 /* ZXProductResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D27166A9A0800E13304 /* ZXProductResultParser.m */; };
+ 2540465F166ABBED00E13304 /* ZXResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D29166A9A0800E13304 /* ZXResultParser.m */; };
+ 25404660166ABBED00E13304 /* ZXSMSMMSResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D2B166A9A0800E13304 /* ZXSMSMMSResultParser.m */; };
+ 25404661166ABBED00E13304 /* ZXSMSParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D2D166A9A0800E13304 /* ZXSMSParsedResult.m */; };
+ 25404662166ABBED00E13304 /* ZXSMSTOMMSTOResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D2F166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.m */; };
+ 25404663166ABBED00E13304 /* ZXSMTPResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D31166A9A0800E13304 /* ZXSMTPResultParser.m */; };
+ 25404664166ABBED00E13304 /* ZXTelParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D33166A9A0800E13304 /* ZXTelParsedResult.m */; };
+ 25404665166ABBED00E13304 /* ZXTelResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D35166A9A0800E13304 /* ZXTelResultParser.m */; };
+ 25404666166ABBED00E13304 /* ZXTextParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D37166A9A0800E13304 /* ZXTextParsedResult.m */; };
+ 25404667166ABBED00E13304 /* ZXURIParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D39166A9A0800E13304 /* ZXURIParsedResult.m */; };
+ 25404668166ABBED00E13304 /* ZXURIResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D3B166A9A0800E13304 /* ZXURIResultParser.m */; };
+ 25404669166ABBED00E13304 /* ZXURLTOResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D3D166A9A0800E13304 /* ZXURLTOResultParser.m */; };
+ 2540466A166ABBED00E13304 /* ZXVCardResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D3F166A9A0800E13304 /* ZXVCardResultParser.m */; };
+ 2540466B166ABBED00E13304 /* ZXVEventResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D41166A9A0800E13304 /* ZXVEventResultParser.m */; };
+ 2540466C166ABBED00E13304 /* ZXWifiParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D43166A9A0800E13304 /* ZXWifiParsedResult.m */; };
+ 2540466D166ABBED00E13304 /* ZXWifiResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D45166A9A0800E13304 /* ZXWifiResultParser.m */; };
+ 2540466E166ABBED00E13304 /* ZXCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D47166A9A0800E13304 /* ZXCapture.m */; };
+ 2540466F166ABBED00E13304 /* ZXCaptureView.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D4A166A9A0800E13304 /* ZXCaptureView.m */; };
+ 25404670166ABBED00E13304 /* ZXCGImageLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D4C166A9A0800E13304 /* ZXCGImageLuminanceSource.m */; };
+ 25404671166ABBED00E13304 /* ZXImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403D4E166A9A0800E13304 /* ZXImage.m */; };
+ 25404672166ABBED00E13304 /* ZXMathUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA2166A9C0E00E13304 /* ZXMathUtils.m */; };
+ 25404673166ABBED00E13304 /* ZXMonochromeRectangleDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA4166A9C0E00E13304 /* ZXMonochromeRectangleDetector.m */; };
+ 25404674166ABBED00E13304 /* ZXWhiteRectangleDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA6166A9C0E00E13304 /* ZXWhiteRectangleDetector.m */; };
+ 25404675166ABBED00E13304 /* ZXGenericGF.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DA9166A9C0E00E13304 /* ZXGenericGF.m */; };
+ 25404676166ABBED00E13304 /* ZXGenericGFPoly.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DAB166A9C0E00E13304 /* ZXGenericGFPoly.m */; };
+ 25404677166ABBED00E13304 /* ZXReedSolomonDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DAD166A9C0E00E13304 /* ZXReedSolomonDecoder.m */; };
+ 25404678166ABBED00E13304 /* ZXReedSolomonEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DAF166A9C0E00E13304 /* ZXReedSolomonEncoder.m */; };
+ 25404679166ABBED00E13304 /* ZXBitArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB1166A9C0E00E13304 /* ZXBitArray.m */; };
+ 2540467A166ABBED00E13304 /* ZXBitMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB3166A9C0E00E13304 /* ZXBitMatrix.m */; };
+ 2540467B166ABBED00E13304 /* ZXBitSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB5166A9C0E00E13304 /* ZXBitSource.m */; };
+ 2540467C166ABBED00E13304 /* ZXCharacterSetECI.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB7166A9C0E00E13304 /* ZXCharacterSetECI.m */; };
+ 2540467D166ABBED00E13304 /* ZXDecoderResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DB9166A9C0E00E13304 /* ZXDecoderResult.m */; };
+ 2540467E166ABBED00E13304 /* ZXDefaultGridSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DBB166A9C0E00E13304 /* ZXDefaultGridSampler.m */; };
+ 2540467F166ABBED00E13304 /* ZXDetectorResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DBD166A9C0E00E13304 /* ZXDetectorResult.m */; };
+ 25404680166ABBED00E13304 /* ZXECI.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DBF166A9C0E00E13304 /* ZXECI.m */; };
+ 25404681166ABBED00E13304 /* ZXGlobalHistogramBinarizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC1166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.m */; };
+ 25404682166ABBED00E13304 /* ZXGridSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC3166A9C0E00E13304 /* ZXGridSampler.m */; };
+ 25404683166ABBED00E13304 /* ZXHybridBinarizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC5166A9C0E00E13304 /* ZXHybridBinarizer.m */; };
+ 25404684166ABBED00E13304 /* ZXPerspectiveTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC7166A9C0E00E13304 /* ZXPerspectiveTransform.m */; };
+ 25404685166ABBED00E13304 /* ZXStringUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DC9166A9C0E00E13304 /* ZXStringUtils.m */; };
+ 25404686166ABBED00E13304 /* ZXDataMatrixBitMatrixParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DF5166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.m */; };
+ 25404687166ABBED00E13304 /* ZXDataMatrixDataBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DF7166A9CCB00E13304 /* ZXDataMatrixDataBlock.m */; };
+ 25404688166ABBED00E13304 /* ZXDataMatrixDecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DF9166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.m */; };
+ 25404689166ABBED00E13304 /* ZXDataMatrixDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DFB166A9CCB00E13304 /* ZXDataMatrixDecoder.m */; };
+ 2540468A166ABBED00E13304 /* ZXDataMatrixVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403DFD166A9CCB00E13304 /* ZXDataMatrixVersion.m */; };
+ 2540468B166ABBED00E13304 /* ZXDataMatrixDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E00166A9CCB00E13304 /* ZXDataMatrixDetector.m */; };
+ 2540468C166ABBED00E13304 /* ZXDataMatrixReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E02166A9CCB00E13304 /* ZXDataMatrixReader.m */; };
+ 2540468D166ABBED00E13304 /* ZXMaxiCodeBitMatrixParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E14166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.m */; };
+ 2540468E166ABBED00E13304 /* ZXMaxiCodeDecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E16166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.m */; };
+ 2540468F166ABBED00E13304 /* ZXMaxiCodeDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E18166A9D4B00E13304 /* ZXMaxiCodeDecoder.m */; };
+ 25404690166ABBED00E13304 /* ZXMaxiCodeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E1A166A9D4B00E13304 /* ZXMaxiCodeReader.m */; };
+ 25404691166ABBED00E13304 /* ZXMultiDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E27166A9D8B00E13304 /* ZXMultiDetector.m */; };
+ 25404692166ABBED00E13304 /* ZXMultiFinderPatternFinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E29166A9D8B00E13304 /* ZXMultiFinderPatternFinder.m */; };
+ 25404693166ABBED00E13304 /* ZXQRCodeMultiReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E2B166A9D8B00E13304 /* ZXQRCodeMultiReader.m */; };
+ 25404694166ABBED00E13304 /* ZXByQuadrantReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E2D166A9D8B00E13304 /* ZXByQuadrantReader.m */; };
+ 25404695166ABBED00E13304 /* ZXGenericMultipleBarcodeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E2F166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.m */; };
+ 25404696166ABBED00E13304 /* ZXAbstractExpandedDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E41166A9DF300E13304 /* ZXAbstractExpandedDecoder.m */; };
+ 25404697166ABBED00E13304 /* ZXAI013103decoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E43166A9DF300E13304 /* ZXAI013103decoder.m */; };
+ 25404698166ABBED00E13304 /* ZXAI01320xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E45166A9DF300E13304 /* ZXAI01320xDecoder.m */; };
+ 25404699166ABBED00E13304 /* ZXAI01392xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E47166A9DF300E13304 /* ZXAI01392xDecoder.m */; };
+ 2540469A166ABBED00E13304 /* ZXAI01393xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E49166A9DF300E13304 /* ZXAI01393xDecoder.m */; };
+ 2540469B166ABBED00E13304 /* ZXAI013x0x1xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E4B166A9DF300E13304 /* ZXAI013x0x1xDecoder.m */; };
+ 2540469C166ABBED00E13304 /* ZXAI013x0xDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E4D166A9DF300E13304 /* ZXAI013x0xDecoder.m */; };
+ 2540469D166ABBED00E13304 /* ZXAI01AndOtherAIs.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E4F166A9DF300E13304 /* ZXAI01AndOtherAIs.m */; };
+ 2540469E166ABBED00E13304 /* ZXAI01decoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E51166A9DF300E13304 /* ZXAI01decoder.m */; };
+ 2540469F166ABBED00E13304 /* ZXAI01weightDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E53166A9DF300E13304 /* ZXAI01weightDecoder.m */; };
+ 254046A0166ABBED00E13304 /* ZXAnyAIDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E55166A9DF300E13304 /* ZXAnyAIDecoder.m */; };
+ 254046A1166ABBED00E13304 /* ZXBlockParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E57166A9DF300E13304 /* ZXBlockParsedResult.m */; };
+ 254046A2166ABBED00E13304 /* ZXCurrentParsingState.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E59166A9DF300E13304 /* ZXCurrentParsingState.m */; };
+ 254046A3166ABBED00E13304 /* ZXDecodedChar.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E5B166A9DF300E13304 /* ZXDecodedChar.m */; };
+ 254046A4166ABBED00E13304 /* ZXDecodedInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E5D166A9DF300E13304 /* ZXDecodedInformation.m */; };
+ 254046A5166ABBED00E13304 /* ZXDecodedNumeric.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E5F166A9DF300E13304 /* ZXDecodedNumeric.m */; };
+ 254046A6166ABBED00E13304 /* ZXDecodedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E61166A9DF300E13304 /* ZXDecodedObject.m */; };
+ 254046A7166ABBED00E13304 /* ZXFieldParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E63166A9DF300E13304 /* ZXFieldParser.m */; };
+ 254046A8166ABBED00E13304 /* ZXGeneralAppIdDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E65166A9DF300E13304 /* ZXGeneralAppIdDecoder.m */; };
+ 254046A9166ABBED00E13304 /* ZXBitArrayBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E67166A9DF300E13304 /* ZXBitArrayBuilder.m */; };
+ 254046AA166ABBED00E13304 /* ZXExpandedPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E69166A9DF300E13304 /* ZXExpandedPair.m */; };
+ 254046AB166ABBED00E13304 /* ZXRSSExpandedReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E6B166A9DF300E13304 /* ZXRSSExpandedReader.m */; };
+ 254046AC166ABBED00E13304 /* ZXAbstractRSSReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E6D166A9DF300E13304 /* ZXAbstractRSSReader.m */; };
+ 254046AD166ABBED00E13304 /* ZXDataCharacter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E6F166A9DF300E13304 /* ZXDataCharacter.m */; };
+ 254046AE166ABBED00E13304 /* ZXPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E71166A9DF300E13304 /* ZXPair.m */; };
+ 254046AF166ABBED00E13304 /* ZXRSS14Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E73166A9DF300E13304 /* ZXRSS14Reader.m */; };
+ 254046B0166ABBED00E13304 /* ZXRSSFinderPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E75166A9DF300E13304 /* ZXRSSFinderPattern.m */; };
+ 254046B1166ABBED00E13304 /* ZXRSSUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E77166A9DF300E13304 /* ZXRSSUtils.m */; };
+ 254046B2166ABBED00E13304 /* ZXCodaBarReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E79166A9DF300E13304 /* ZXCodaBarReader.m */; };
+ 254046B3166ABBED00E13304 /* ZXCodaBarWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E7B166A9DF300E13304 /* ZXCodaBarWriter.m */; };
+ 254046B4166ABBED00E13304 /* ZXCode128Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E7D166A9DF300E13304 /* ZXCode128Reader.m */; };
+ 254046B5166ABBED00E13304 /* ZXCode128Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E7F166A9DF300E13304 /* ZXCode128Writer.m */; };
+ 254046B6166ABBED00E13304 /* ZXCode39Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E81166A9DF300E13304 /* ZXCode39Reader.m */; };
+ 254046B7166ABBED00E13304 /* ZXCode39Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E83166A9DF300E13304 /* ZXCode39Writer.m */; };
+ 254046B8166ABBED00E13304 /* ZXCode93Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E85166A9DF300E13304 /* ZXCode93Reader.m */; };
+ 254046B9166ABBED00E13304 /* ZXEAN13Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E87166A9DF300E13304 /* ZXEAN13Reader.m */; };
+ 254046BA166ABBED00E13304 /* ZXEAN13Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E89166A9DF300E13304 /* ZXEAN13Writer.m */; };
+ 254046BB166ABBED00E13304 /* ZXEAN8Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E8B166A9DF300E13304 /* ZXEAN8Reader.m */; };
+ 254046BC166ABBED00E13304 /* ZXEAN8Writer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E8D166A9DF300E13304 /* ZXEAN8Writer.m */; };
+ 254046BD166ABBED00E13304 /* ZXEANManufacturerOrgSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E8F166A9DF300E13304 /* ZXEANManufacturerOrgSupport.m */; };
+ 254046BE166ABBED00E13304 /* ZXITFReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E91166A9DF300E13304 /* ZXITFReader.m */; };
+ 254046BF166ABBED00E13304 /* ZXITFWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E93166A9DF300E13304 /* ZXITFWriter.m */; };
+ 254046C0166ABBED00E13304 /* ZXMultiFormatOneDReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E95166A9DF300E13304 /* ZXMultiFormatOneDReader.m */; };
+ 254046C1166ABBED00E13304 /* ZXMultiFormatUPCEANReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E97166A9DF300E13304 /* ZXMultiFormatUPCEANReader.m */; };
+ 254046C2166ABBED00E13304 /* ZXOneDimensionalCodeWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E99166A9DF300E13304 /* ZXOneDimensionalCodeWriter.m */; };
+ 254046C3166ABBED00E13304 /* ZXOneDReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E9B166A9DF300E13304 /* ZXOneDReader.m */; };
+ 254046C4166ABBED00E13304 /* ZXUPCAReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E9D166A9DF300E13304 /* ZXUPCAReader.m */; };
+ 254046C5166ABBED00E13304 /* ZXUPCAWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403E9F166A9DF300E13304 /* ZXUPCAWriter.m */; };
+ 254046C6166ABBED00E13304 /* ZXUPCEANExtension2Support.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA1166A9DF300E13304 /* ZXUPCEANExtension2Support.m */; };
+ 254046C7166ABBED00E13304 /* ZXUPCEANExtension5Support.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA3166A9DF300E13304 /* ZXUPCEANExtension5Support.m */; };
+ 254046C8166ABBED00E13304 /* ZXUPCEANExtensionSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA5166A9DF300E13304 /* ZXUPCEANExtensionSupport.m */; };
+ 254046C9166ABBED00E13304 /* ZXUPCEANReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA7166A9DF300E13304 /* ZXUPCEANReader.m */; };
+ 254046CA166ABBED00E13304 /* ZXUPCEANWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EA9166A9DF300E13304 /* ZXUPCEANWriter.m */; };
+ 254046CB166ABBED00E13304 /* ZXUPCEReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403EAB166A9DF300E13304 /* ZXUPCEReader.m */; };
+ 254046CC166ABBED00E13304 /* ZXModulusGF.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F1C166A9EB500E13304 /* ZXModulusGF.m */; };
+ 254046CD166ABBED00E13304 /* ZXModulusPoly.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F1E166A9EB500E13304 /* ZXModulusPoly.m */; };
+ 254046CE166ABBED00E13304 /* ZXPDF417ECErrorCorrection.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F20166A9EB500E13304 /* ZXPDF417ECErrorCorrection.m */; };
+ 254046D0166ABBED00E13304 /* ZXPDF417DecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F24166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.m */; };
+ 254046D2166ABBED00E13304 /* ZXPDF417Detector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F29166A9EB500E13304 /* ZXPDF417Detector.m */; };
+ 254046D3166ABBED00E13304 /* ZXBarcodeMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F2C166A9EB500E13304 /* ZXBarcodeMatrix.m */; };
+ 254046D4166ABBED00E13304 /* ZXBarcodeRow.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F2E166A9EB500E13304 /* ZXBarcodeRow.m */; };
+ 254046D5166ABBED00E13304 /* ZXDimensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F31166A9EB500E13304 /* ZXDimensions.m */; };
+ 254046D6166ABBED00E13304 /* ZXPDF417.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F33166A9EB500E13304 /* ZXPDF417.m */; };
+ 254046D7166ABBED00E13304 /* ZXPDF417ErrorCorrection.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F35166A9EB500E13304 /* ZXPDF417ErrorCorrection.m */; };
+ 254046D8166ABBED00E13304 /* ZXPDF417HighLevelEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F37166A9EB500E13304 /* ZXPDF417HighLevelEncoder.m */; };
+ 254046DA166ABBED00E13304 /* ZXPDF417Reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F3B166A9EB500E13304 /* ZXPDF417Reader.m */; };
+ 254046DB166ABBED00E13304 /* ZXDataMask.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F5E166A9F2D00E13304 /* ZXDataMask.m */; };
+ 254046DC166ABBED00E13304 /* ZXErrorCorrectionLevel.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F60166A9F2D00E13304 /* ZXErrorCorrectionLevel.m */; };
+ 254046DD166ABBED00E13304 /* ZXFormatInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F62166A9F2D00E13304 /* ZXFormatInformation.m */; };
+ 254046DE166ABBED00E13304 /* ZXMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F64166A9F2D00E13304 /* ZXMode.m */; };
+ 254046DF166ABBED00E13304 /* ZXQRCodeBitMatrixParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F66166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.m */; };
+ 254046E0166ABBED00E13304 /* ZXQRCodeDataBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F68166A9F2D00E13304 /* ZXQRCodeDataBlock.m */; };
+ 254046E1166ABBED00E13304 /* ZXQRCodeDecodedBitStreamParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F6A166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.m */; };
+ 254046E2166ABBED00E13304 /* ZXQRCodeDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F6C166A9F2D00E13304 /* ZXQRCodeDecoder.m */; };
+ 254046E3166ABBED00E13304 /* ZXQRCodeVersion.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F6E166A9F2D00E13304 /* ZXQRCodeVersion.m */; };
+ 254046E4166ABBED00E13304 /* ZXAlignmentPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F71166A9F2D00E13304 /* ZXAlignmentPattern.m */; };
+ 254046E5166ABBED00E13304 /* ZXAlignmentPatternFinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F73166A9F2D00E13304 /* ZXAlignmentPatternFinder.m */; };
+ 254046E6166ABBED00E13304 /* ZXFinderPatternFinder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F75166A9F2D00E13304 /* ZXFinderPatternFinder.m */; };
+ 254046E7166ABBED00E13304 /* ZXFinderPatternInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F77166A9F2D00E13304 /* ZXFinderPatternInfo.m */; };
+ 254046E8166ABBED00E13304 /* ZXQRCodeDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F79166A9F2D00E13304 /* ZXQRCodeDetector.m */; };
+ 254046E9166ABBED00E13304 /* ZXQRCodeFinderPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F7B166A9F2D00E13304 /* ZXQRCodeFinderPattern.m */; };
+ 254046EA166ABBED00E13304 /* ZXBlockPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F7E166A9F2D00E13304 /* ZXBlockPair.m */; };
+ 254046EB166ABBED00E13304 /* ZXByteMatrix.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F80166A9F2D00E13304 /* ZXByteMatrix.m */; };
+ 254046EC166ABBED00E13304 /* ZXEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F82166A9F2D00E13304 /* ZXEncoder.m */; };
+ 254046ED166ABBED00E13304 /* ZXMaskUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F84166A9F2D00E13304 /* ZXMaskUtil.m */; };
+ 254046EE166ABBED00E13304 /* ZXMatrixUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F86166A9F2D00E13304 /* ZXMatrixUtil.m */; };
+ 254046EF166ABBED00E13304 /* ZXQRCode.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F88166A9F2D00E13304 /* ZXQRCode.m */; };
+ 254046F0166ABBED00E13304 /* ZXQRCodeReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F8A166A9F2D00E13304 /* ZXQRCodeReader.m */; };
+ 254046F1166ABBED00E13304 /* ZXQRCodeWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403F8C166A9F2D00E13304 /* ZXQRCodeWriter.m */; };
+ 254046F2166ABBED00E13304 /* ZXBinarizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FBD166A9FFC00E13304 /* ZXBinarizer.m */; };
+ 254046F3166ABBED00E13304 /* ZXBinaryBitmap.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FBF166A9FFC00E13304 /* ZXBinaryBitmap.m */; };
+ 254046F4166ABBED00E13304 /* ZXDecodeHints.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FC1166A9FFC00E13304 /* ZXDecodeHints.m */; };
+ 254046F5166ABBED00E13304 /* ZXEncodeHints.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FC3166A9FFC00E13304 /* ZXEncodeHints.m */; };
+ 254046F6166ABBED00E13304 /* ZXErrors.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FC5166A9FFC00E13304 /* ZXErrors.m */; };
+ 254046F7166ABBED00E13304 /* ZXLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD2166AA00700E13304 /* ZXLuminanceSource.m */; };
+ 254046F8166ABBED00E13304 /* ZXMultiFormatReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD4166AA00700E13304 /* ZXMultiFormatReader.m */; };
+ 254046F9166ABBED00E13304 /* ZXMultiFormatWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD6166AA00700E13304 /* ZXMultiFormatWriter.m */; };
+ 254046FA166ABBED00E13304 /* ZXResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FD9166AA00700E13304 /* ZXResult.m */; };
+ 254046FB166ABBED00E13304 /* ZXResultPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 25403FDC166AA00700E13304 /* ZXResultPoint.m */; };
+ 254046FD166ABC1600E13304 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 254046FC166ABC1600E13304 /* QuartzCore.framework */; };
+ 254046FE166ABC2100E13304 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 254046FC166ABC1600E13304 /* QuartzCore.framework */; };
+ 254046FF166ABC2600E13304 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 254046FC166ABC1600E13304 /* QuartzCore.framework */; };
+ 25404701166ABC3F00E13304 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404700166ABC3F00E13304 /* QTKit.framework */; };
+ 25404702166ABC4600E13304 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404700166ABC3F00E13304 /* QTKit.framework */; };
+ 25404703166ABC4B00E13304 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25404700166ABC3F00E13304 /* QTKit.framework */; };
+ 2540471B166AC21000E13304 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540471A166AC21000E13304 /* AVFoundation.framework */; };
+ 2540471C166AC21D00E13304 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2540471A166AC21000E13304 /* AVFoundation.framework */; };
+ 2542996D16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542996B16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542996E16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542996C16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.m */; };
+ 2542996F16D3334100D4C045 /* ZXPlanarYUVLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542996B16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542997116D3336000D4C045 /* ZXPlanarYUVLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542996C16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.m */; };
+ 2542997216D3336100D4C045 /* ZXPlanarYUVLuminanceSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542996C16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.m */; };
+ 2542997516D46E8500D4C045 /* ZXDimension.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542997316D46E8400D4C045 /* ZXDimension.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542997616D46E8500D4C045 /* ZXDimension.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542997416D46E8400D4C045 /* ZXDimension.m */; };
+ 2542997716D46FE900D4C045 /* ZXDimension.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542997316D46E8400D4C045 /* ZXDimension.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542997916D46FF100D4C045 /* ZXDimension.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542997416D46E8400D4C045 /* ZXDimension.m */; };
+ 2542997A16D46FF200D4C045 /* ZXDimension.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542997416D46E8400D4C045 /* ZXDimension.m */; };
+ 2542997D16D470D600D4C045 /* ZXDataMatrixWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542997B16D470D600D4C045 /* ZXDataMatrixWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542997E16D470D600D4C045 /* ZXDataMatrixWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542997C16D470D600D4C045 /* ZXDataMatrixWriter.m */; };
+ 2542997F16D470E600D4C045 /* ZXDataMatrixWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542997B16D470D600D4C045 /* ZXDataMatrixWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542998116D470F300D4C045 /* ZXDataMatrixWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542997C16D470D600D4C045 /* ZXDataMatrixWriter.m */; };
+ 2542998216D470F400D4C045 /* ZXDataMatrixWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542997C16D470D600D4C045 /* ZXDataMatrixWriter.m */; };
+ 2542998616D478A000D4C045 /* ZXASCIIEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542998416D478A000D4C045 /* ZXASCIIEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542998716D478A000D4C045 /* ZXASCIIEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542998416D478A000D4C045 /* ZXASCIIEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542998916D478A000D4C045 /* ZXASCIIEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542998516D478A000D4C045 /* ZXASCIIEncoder.m */; };
+ 2542998A16D478A000D4C045 /* ZXASCIIEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542998516D478A000D4C045 /* ZXASCIIEncoder.m */; };
+ 2542998B16D478A000D4C045 /* ZXASCIIEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542998516D478A000D4C045 /* ZXASCIIEncoder.m */; };
+ 2542998F16D47BC000D4C045 /* ZXBase256Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542998D16D47BBF00D4C045 /* ZXBase256Encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542999016D47BC000D4C045 /* ZXBase256Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542998D16D47BBF00D4C045 /* ZXBase256Encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542999216D47BC000D4C045 /* ZXBase256Encoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542998E16D47BBF00D4C045 /* ZXBase256Encoder.m */; };
+ 2542999316D47BC000D4C045 /* ZXBase256Encoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542998E16D47BBF00D4C045 /* ZXBase256Encoder.m */; };
+ 2542999416D47BC000D4C045 /* ZXBase256Encoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542998E16D47BBF00D4C045 /* ZXBase256Encoder.m */; };
+ 2542999916D482F900D4C045 /* ZXC40Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542999716D482F800D4C045 /* ZXC40Encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542999A16D482F900D4C045 /* ZXC40Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542999716D482F800D4C045 /* ZXC40Encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2542999C16D482F900D4C045 /* ZXC40Encoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542999816D482F800D4C045 /* ZXC40Encoder.m */; };
+ 2542999D16D482F900D4C045 /* ZXC40Encoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542999816D482F800D4C045 /* ZXC40Encoder.m */; };
+ 254299A116D4879800D4C045 /* ZXDataMatrixSymbolInfo144.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542999F16D4879800D4C045 /* ZXDataMatrixSymbolInfo144.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299A216D4879800D4C045 /* ZXDataMatrixSymbolInfo144.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542999F16D4879800D4C045 /* ZXDataMatrixSymbolInfo144.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299A416D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299A016D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m */; };
+ 254299A516D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299A016D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m */; };
+ 254299A616D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299A016D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m */; };
+ 254299A916D4886100D4C045 /* ZXDefaultPlacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299A716D4886000D4C045 /* ZXDefaultPlacement.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299AA16D4886100D4C045 /* ZXDefaultPlacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299A716D4886000D4C045 /* ZXDefaultPlacement.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299AC16D4886100D4C045 /* ZXDefaultPlacement.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299A816D4886000D4C045 /* ZXDefaultPlacement.m */; };
+ 254299AD16D4886100D4C045 /* ZXDefaultPlacement.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299A816D4886000D4C045 /* ZXDefaultPlacement.m */; };
+ 254299AE16D4886100D4C045 /* ZXDefaultPlacement.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299A816D4886000D4C045 /* ZXDefaultPlacement.m */; };
+ 254299B116D4A36700D4C045 /* ZXEdifactEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299AF16D4A36700D4C045 /* ZXEdifactEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299B216D4A36700D4C045 /* ZXEdifactEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299AF16D4A36700D4C045 /* ZXEdifactEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299B416D4A36700D4C045 /* ZXEdifactEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299B016D4A36700D4C045 /* ZXEdifactEncoder.m */; };
+ 254299B516D4A36700D4C045 /* ZXEdifactEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299B016D4A36700D4C045 /* ZXEdifactEncoder.m */; };
+ 254299B616D4A36700D4C045 /* ZXEdifactEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299B016D4A36700D4C045 /* ZXEdifactEncoder.m */; };
+ 254299B916D4A5AA00D4C045 /* ZXEncoderContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299B716D4A5A900D4C045 /* ZXEncoderContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299BA16D4A5AA00D4C045 /* ZXEncoderContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299B716D4A5A900D4C045 /* ZXEncoderContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299BC16D4A5AA00D4C045 /* ZXEncoderContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299B816D4A5A900D4C045 /* ZXEncoderContext.m */; };
+ 254299BD16D4A5AA00D4C045 /* ZXEncoderContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299B816D4A5A900D4C045 /* ZXEncoderContext.m */; };
+ 254299BE16D4A5AA00D4C045 /* ZXEncoderContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299B816D4A5A900D4C045 /* ZXEncoderContext.m */; };
+ 254299C116D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299BF16D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299C216D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299BF16D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299C416D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299C016D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.m */; };
+ 254299C516D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299C016D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.m */; };
+ 254299C616D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299C016D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.m */; };
+ 254299C916D5BD5400D4C045 /* ZXHighLevelEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299C716D5BD5300D4C045 /* ZXHighLevelEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299CA16D5BD5400D4C045 /* ZXHighLevelEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299C716D5BD5300D4C045 /* ZXHighLevelEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299CC16D5BD5400D4C045 /* ZXHighLevelEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299C816D5BD5300D4C045 /* ZXHighLevelEncoder.m */; };
+ 254299CD16D5BD5400D4C045 /* ZXHighLevelEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299C816D5BD5300D4C045 /* ZXHighLevelEncoder.m */; };
+ 254299CE16D5BD5400D4C045 /* ZXHighLevelEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299C816D5BD5300D4C045 /* ZXHighLevelEncoder.m */; };
+ 254299D116D5C96100D4C045 /* ZXSymbolInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299CF16D5C96000D4C045 /* ZXSymbolInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299D216D5C96100D4C045 /* ZXSymbolInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299CF16D5C96000D4C045 /* ZXSymbolInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299D416D5C96100D4C045 /* ZXSymbolInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299D016D5C96000D4C045 /* ZXSymbolInfo.m */; };
+ 254299D516D5C96100D4C045 /* ZXSymbolInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299D016D5C96000D4C045 /* ZXSymbolInfo.m */; };
+ 254299D616D5C96100D4C045 /* ZXSymbolInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299D016D5C96000D4C045 /* ZXSymbolInfo.m */; };
+ 254299D916D5D12000D4C045 /* ZXSymbolShapeHint.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299D716D5D11E00D4C045 /* ZXSymbolShapeHint.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299DA16D5D12000D4C045 /* ZXSymbolShapeHint.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299D716D5D11E00D4C045 /* ZXSymbolShapeHint.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299E016D5D24E00D4C045 /* ZXSymbolShapeHint.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299DF16D5D24D00D4C045 /* ZXSymbolShapeHint.m */; };
+ 254299E116D5D24E00D4C045 /* ZXSymbolShapeHint.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299DF16D5D24D00D4C045 /* ZXSymbolShapeHint.m */; };
+ 254299E216D5D24E00D4C045 /* ZXSymbolShapeHint.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299DF16D5D24D00D4C045 /* ZXSymbolShapeHint.m */; };
+ 254299E516D5D81A00D4C045 /* ZXTextEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299E316D5D81800D4C045 /* ZXTextEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299E616D5D81A00D4C045 /* ZXTextEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299E316D5D81800D4C045 /* ZXTextEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299E816D5D81A00D4C045 /* ZXTextEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299E416D5D81900D4C045 /* ZXTextEncoder.m */; };
+ 254299E916D5D81A00D4C045 /* ZXTextEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299E416D5D81900D4C045 /* ZXTextEncoder.m */; };
+ 254299EA16D5D81A00D4C045 /* ZXTextEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299E416D5D81900D4C045 /* ZXTextEncoder.m */; };
+ 254299ED16D5D94B00D4C045 /* ZXX12Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299EB16D5D94900D4C045 /* ZXX12Encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299EE16D5D94B00D4C045 /* ZXX12Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299EB16D5D94900D4C045 /* ZXX12Encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 254299F016D5D94B00D4C045 /* ZXX12Encoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299EC16D5D94A00D4C045 /* ZXX12Encoder.m */; };
+ 254299F116D5D94B00D4C045 /* ZXX12Encoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299EC16D5D94A00D4C045 /* ZXX12Encoder.m */; };
+ 254299F216D5D94B00D4C045 /* ZXX12Encoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299EC16D5D94A00D4C045 /* ZXX12Encoder.m */; };
+ 254299FB16D5DCC000D4C045 /* ZXDataMatrixWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299F416D5DC8E00D4C045 /* ZXDataMatrixWriterTestCase.m */; };
+ 254299FC16D5DCC300D4C045 /* ZXDataMatrixWriterTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299F416D5DC8E00D4C045 /* ZXDataMatrixWriterTestCase.m */; };
+ 25429A0016D5DFD800D4C045 /* ZXDebugPlacement.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299FF16D5DFD800D4C045 /* ZXDebugPlacement.m */; };
+ 25429A0116D5DFD800D4C045 /* ZXDebugPlacement.m in Sources */ = {isa = PBXBuildFile; fileRef = 254299FF16D5DFD800D4C045 /* ZXDebugPlacement.m */; };
+ 25429A0416D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25429A0316D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m */; };
+ 25429A0516D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25429A0316D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m */; };
+ 25429A0816D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25429A0716D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.m */; };
+ 25429A0916D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25429A0716D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.m */; };
+ 25429A0C16D5F4E000D4C045 /* ZXPlacementTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25429A0B16D5F4E000D4C045 /* ZXPlacementTestCase.m */; };
+ 25429A0D16D5F4E000D4C045 /* ZXPlacementTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25429A0B16D5F4E000D4C045 /* ZXPlacementTestCase.m */; };
+ 25429A1016D5F66D00D4C045 /* ZXSymbolInfoTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25429A0F16D5F66D00D4C045 /* ZXSymbolInfoTestCase.m */; };
+ 25429A1116D5F66D00D4C045 /* ZXSymbolInfoTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25429A0F16D5F66D00D4C045 /* ZXSymbolInfoTestCase.m */; };
+ 255B9DB116FFCDE000EEEE61 /* ZXDataMatrixEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542998C16D478F800D4C045 /* ZXDataMatrixEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255B9DB216FFCDE100EEEE61 /* ZXDataMatrixEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542998C16D478F800D4C045 /* ZXDataMatrixEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E481E18143A3900A03A28 /* RSSExpandedStackedInternalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3F16D0B84C00826CDB /* RSSExpandedStackedInternalTestCase.m */; };
+ 255E481F18143A3900A03A28 /* TestCaseUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D4216D0B8B200826CDB /* TestCaseUtil.m */; };
+ 255E482018143A4A00A03A28 /* ZXC40Encoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 2542999816D482F800D4C045 /* ZXC40Encoder.m */; };
+ 255E482118143A8800A03A28 /* ZXAztecDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CEE166A999D00E13304 /* ZXAztecDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482218143A8800A03A28 /* ZXAztecDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CF1166A999D00E13304 /* ZXAztecDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482318143A8800A03A28 /* ZXAztecCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504D9CD16FFD2E200DF8882 /* ZXAztecCode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482418143A8800A03A28 /* ZXAztecEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504D9DA16FFD4CD00DF8882 /* ZXAztecEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482518143A8800A03A28 /* ZXAztecDetectorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CF3166A999D00E13304 /* ZXAztecDetectorResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482618143A8800A03A28 /* ZXAztecReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CF5166A999D00E13304 /* ZXAztecReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482718143A8800A03A28 /* ZXAztecWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB3217FD1EC000A71C45 /* ZXAztecWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482818143A8800A03A28 /* ZXAbstractDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D01166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482918143A8800A03A28 /* ZXAddressBookAUResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D03166A9A0800E13304 /* ZXAddressBookAUResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482A18143A8800A03A28 /* ZXAddressBookDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D05166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482B18143A8800A03A28 /* ZXAddressBookParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D07166A9A0800E13304 /* ZXAddressBookParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482C18143A8800A03A28 /* ZXBizcardResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D09166A9A0800E13304 /* ZXBizcardResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482D18143A8800A03A28 /* ZXBookmarkDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D0B166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482E18143A8800A03A28 /* ZXCalendarParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D0D166A9A0800E13304 /* ZXCalendarParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E482F18143A8800A03A28 /* ZXEmailAddressParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D0F166A9A0800E13304 /* ZXEmailAddressParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483018143A8800A03A28 /* ZXEmailAddressResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D11166A9A0800E13304 /* ZXEmailAddressResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483118143A8800A03A28 /* ZXEmailDoCoMoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D13166A9A0800E13304 /* ZXEmailDoCoMoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483218143A8800A03A28 /* ZXExpandedProductParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D15166A9A0800E13304 /* ZXExpandedProductParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483318143A8800A03A28 /* ZXExpandedProductResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D17166A9A0800E13304 /* ZXExpandedProductResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483418143A8800A03A28 /* ZXGeoParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D19166A9A0800E13304 /* ZXGeoParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483518143A8800A03A28 /* ZXGeoResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D1B166A9A0800E13304 /* ZXGeoResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483618143A8800A03A28 /* ZXISBNParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D1D166A9A0800E13304 /* ZXISBNParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483718143A8800A03A28 /* ZXISBNResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D1F166A9A0800E13304 /* ZXISBNResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483818143A8800A03A28 /* ZXParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D21166A9A0800E13304 /* ZXParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483918143A8800A03A28 /* ZXParsedResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D23166A9A0800E13304 /* ZXParsedResultType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483A18143A8800A03A28 /* ZXProductParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D24166A9A0800E13304 /* ZXProductParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483B18143A8800A03A28 /* ZXProductResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D26166A9A0800E13304 /* ZXProductResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483C18143A8800A03A28 /* ZXResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D28166A9A0800E13304 /* ZXResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483D18143A8800A03A28 /* ZXSMSMMSResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D2A166A9A0800E13304 /* ZXSMSMMSResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483E18143A8800A03A28 /* ZXSMSParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D2C166A9A0800E13304 /* ZXSMSParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E483F18143A8800A03A28 /* ZXSMSTOMMSTOResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D2E166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484018143A8800A03A28 /* ZXSMTPResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D30166A9A0800E13304 /* ZXSMTPResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484118143A8800A03A28 /* ZXTelParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D32166A9A0800E13304 /* ZXTelParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484218143A8800A03A28 /* ZXTelResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D34166A9A0800E13304 /* ZXTelResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484318143A8800A03A28 /* ZXTextParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D36166A9A0800E13304 /* ZXTextParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484418143A8800A03A28 /* ZXURIParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D38166A9A0800E13304 /* ZXURIParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484518143A8800A03A28 /* ZXURIResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D3A166A9A0800E13304 /* ZXURIResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484618143A8800A03A28 /* ZXURLTOResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D3C166A9A0800E13304 /* ZXURLTOResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484718143A8800A03A28 /* ZXVCardResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D3E166A9A0800E13304 /* ZXVCardResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484818143A8800A03A28 /* ZXVEventResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D40166A9A0800E13304 /* ZXVEventResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484918143A8800A03A28 /* ZXWifiParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D42166A9A0800E13304 /* ZXWifiParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484A18143A8800A03A28 /* ZXWifiResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D44166A9A0800E13304 /* ZXWifiResultParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484B18143A8800A03A28 /* ZXCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D46166A9A0800E13304 /* ZXCapture.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484C18143A8800A03A28 /* ZXCaptureDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D48166A9A0800E13304 /* ZXCaptureDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484D18143A8800A03A28 /* ZXCaptureView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D49166A9A0800E13304 /* ZXCaptureView.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484E18143A8800A03A28 /* ZXCGImageLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D4B166A9A0800E13304 /* ZXCGImageLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E484F18143A8800A03A28 /* ZXImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D4D166A9A0800E13304 /* ZXImage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485018143A8800A03A28 /* ZXView.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403D4F166A9A0800E13304 /* ZXView.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485118143A8800A03A28 /* ZXMathUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA1166A9C0E00E13304 /* ZXMathUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485218143A8800A03A28 /* ZXMonochromeRectangleDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA3166A9C0E00E13304 /* ZXMonochromeRectangleDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485318143A8800A03A28 /* ZXWhiteRectangleDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA5166A9C0E00E13304 /* ZXWhiteRectangleDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485418143A8800A03A28 /* ZXGenericGF.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DA8166A9C0E00E13304 /* ZXGenericGF.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485518143A8800A03A28 /* ZXGenericGFPoly.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DAA166A9C0E00E13304 /* ZXGenericGFPoly.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485618143A8800A03A28 /* ZXReedSolomonDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DAC166A9C0E00E13304 /* ZXReedSolomonDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485718143A8800A03A28 /* ZXReedSolomonEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DAE166A9C0E00E13304 /* ZXReedSolomonEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485818143A8800A03A28 /* ZXBitArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB0166A9C0E00E13304 /* ZXBitArray.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485918143A8800A03A28 /* ZXBitMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB2166A9C0E00E13304 /* ZXBitMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485A18143A8800A03A28 /* ZXBitSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB4166A9C0E00E13304 /* ZXBitSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485B18143A8800A03A28 /* ZXCharacterSetECI.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB6166A9C0E00E13304 /* ZXCharacterSetECI.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485C18143A8800A03A28 /* ZXDecoderResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DB8166A9C0E00E13304 /* ZXDecoderResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485D18143A8800A03A28 /* ZXDefaultGridSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DBA166A9C0E00E13304 /* ZXDefaultGridSampler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485E18143A8800A03A28 /* ZXDetectorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DBC166A9C0E00E13304 /* ZXDetectorResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E485F18143A8800A03A28 /* ZXECI.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DBE166A9C0E00E13304 /* ZXECI.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486018143A8800A03A28 /* ZXGlobalHistogramBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC0166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486118143A8800A03A28 /* ZXGridSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC2166A9C0E00E13304 /* ZXGridSampler.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486218143A8800A03A28 /* ZXHybridBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC4166A9C0E00E13304 /* ZXHybridBinarizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486318143A8800A03A28 /* ZXPerspectiveTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC6166A9C0E00E13304 /* ZXPerspectiveTransform.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486418143A8800A03A28 /* ZXStringUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DC8166A9C0E00E13304 /* ZXStringUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486518143A8800A03A28 /* ZXDataMatrixBitMatrixParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DF4166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486618143A8800A03A28 /* ZXDataMatrixDataBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DF6166A9CCB00E13304 /* ZXDataMatrixDataBlock.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486718143A8800A03A28 /* ZXDataMatrixDecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DF8166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486818143A8800A03A28 /* ZXDataMatrixDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DFA166A9CCB00E13304 /* ZXDataMatrixDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486918143A8800A03A28 /* ZXDataMatrixVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DFC166A9CCB00E13304 /* ZXDataMatrixVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486A18143A8800A03A28 /* ZXDataMatrixDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403DFF166A9CCB00E13304 /* ZXDataMatrixDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486B18143A8800A03A28 /* ZXASCIIEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542998416D478A000D4C045 /* ZXASCIIEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486C18143A8800A03A28 /* ZXBase256Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542998D16D47BBF00D4C045 /* ZXBase256Encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486D18143A8800A03A28 /* ZXC40Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542999716D482F800D4C045 /* ZXC40Encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486E18143A8800A03A28 /* ZXDataMatrixEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542998C16D478F800D4C045 /* ZXDataMatrixEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E486F18143A8800A03A28 /* ZXDataMatrixErrorCorrection.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299BF16D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487018143A8800A03A28 /* ZXDataMatrixSymbolInfo144.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542999F16D4879800D4C045 /* ZXDataMatrixSymbolInfo144.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487118143A8800A03A28 /* ZXDefaultPlacement.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299A716D4886000D4C045 /* ZXDefaultPlacement.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487218143A8800A03A28 /* ZXEdifactEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299AF16D4A36700D4C045 /* ZXEdifactEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487318143A8800A03A28 /* ZXEncoderContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299B716D4A5A900D4C045 /* ZXEncoderContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487418143A8800A03A28 /* ZXHighLevelEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299C716D5BD5300D4C045 /* ZXHighLevelEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487518143A8800A03A28 /* ZXSymbolInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299CF16D5C96000D4C045 /* ZXSymbolInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487618143A8800A03A28 /* ZXSymbolShapeHint.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299D716D5D11E00D4C045 /* ZXSymbolShapeHint.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487718143A8800A03A28 /* ZXTextEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299E316D5D81800D4C045 /* ZXTextEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487818143A8800A03A28 /* ZXX12Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 254299EB16D5D94900D4C045 /* ZXX12Encoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487918143A8800A03A28 /* ZXDataMatrixReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E01166A9CCB00E13304 /* ZXDataMatrixReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487A18143A8800A03A28 /* ZXDataMatrixWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542997B16D470D600D4C045 /* ZXDataMatrixWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487B18143A8800A03A28 /* ZXMaxiCodeBitMatrixParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E13166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487C18143A8800A03A28 /* ZXMaxiCodeDecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E15166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487D18143A8800A03A28 /* ZXMaxiCodeDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E17166A9D4B00E13304 /* ZXMaxiCodeDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487E18143A8800A03A28 /* ZXMaxiCodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E19166A9D4B00E13304 /* ZXMaxiCodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E487F18143A8800A03A28 /* ZXMultiDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E26166A9D8B00E13304 /* ZXMultiDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488018143A8800A03A28 /* ZXMultiFinderPatternFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E28166A9D8B00E13304 /* ZXMultiFinderPatternFinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488118143A8800A03A28 /* ZXQRCodeMultiReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E2A166A9D8B00E13304 /* ZXQRCodeMultiReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488218143A8800A03A28 /* ZXByQuadrantReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E2C166A9D8B00E13304 /* ZXByQuadrantReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488318143A8800A03A28 /* ZXGenericMultipleBarcodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E2E166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488418143A8800A03A28 /* ZXMultipleBarcodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E30166A9D8B00E13304 /* ZXMultipleBarcodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488518143A8800A03A28 /* ZXAbstractExpandedDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E40166A9DF300E13304 /* ZXAbstractExpandedDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488618143A8800A03A28 /* ZXAI013103decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E42166A9DF300E13304 /* ZXAI013103decoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488718143A8800A03A28 /* ZXAI01320xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E44166A9DF300E13304 /* ZXAI01320xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488818143A8800A03A28 /* ZXAI01392xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E46166A9DF300E13304 /* ZXAI01392xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488918143A8800A03A28 /* ZXAI01393xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E48166A9DF300E13304 /* ZXAI01393xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488A18143A8800A03A28 /* ZXAI013x0x1xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E4A166A9DF300E13304 /* ZXAI013x0x1xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488B18143A8800A03A28 /* ZXAI013x0xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E4C166A9DF300E13304 /* ZXAI013x0xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488C18143A8800A03A28 /* ZXAI01AndOtherAIs.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E4E166A9DF300E13304 /* ZXAI01AndOtherAIs.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488D18143A8800A03A28 /* ZXAI01decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E50166A9DF300E13304 /* ZXAI01decoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488E18143A8800A03A28 /* ZXAI01weightDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E52166A9DF300E13304 /* ZXAI01weightDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E488F18143A8800A03A28 /* ZXAnyAIDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E54166A9DF300E13304 /* ZXAnyAIDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489018143A8800A03A28 /* ZXBlockParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E56166A9DF300E13304 /* ZXBlockParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489118143A8800A03A28 /* ZXCurrentParsingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E58166A9DF300E13304 /* ZXCurrentParsingState.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489218143A8800A03A28 /* ZXDecodedChar.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E5A166A9DF300E13304 /* ZXDecodedChar.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489318143A8800A03A28 /* ZXDecodedInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E5C166A9DF300E13304 /* ZXDecodedInformation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489418143A8800A03A28 /* ZXDecodedNumeric.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E5E166A9DF300E13304 /* ZXDecodedNumeric.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489518143A8800A03A28 /* ZXDecodedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E60166A9DF300E13304 /* ZXDecodedObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489618143A8800A03A28 /* ZXFieldParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E62166A9DF300E13304 /* ZXFieldParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489718143A8800A03A28 /* ZXGeneralAppIdDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E64166A9DF300E13304 /* ZXGeneralAppIdDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489818143A8800A03A28 /* ZXBitArrayBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E66166A9DF300E13304 /* ZXBitArrayBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489918143A8800A03A28 /* ZXExpandedPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E68166A9DF300E13304 /* ZXExpandedPair.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489A18143A8800A03A28 /* ZXExpandedRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FE5D3116D0AFED00826CDB /* ZXExpandedRow.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489B18143A8800A03A28 /* ZXRSSExpandedReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E6A166A9DF300E13304 /* ZXRSSExpandedReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489C18143A8800A03A28 /* ZXAbstractRSSReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E6C166A9DF300E13304 /* ZXAbstractRSSReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489D18143A8800A03A28 /* ZXDataCharacter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E6E166A9DF300E13304 /* ZXDataCharacter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489E18143A8800A03A28 /* ZXPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E70166A9DF300E13304 /* ZXPair.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E489F18143A8800A03A28 /* ZXRSS14Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E72166A9DF300E13304 /* ZXRSS14Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A018143A8800A03A28 /* ZXRSSFinderPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E74166A9DF300E13304 /* ZXRSSFinderPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A118143A8800A03A28 /* ZXRSSUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E76166A9DF300E13304 /* ZXRSSUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A218143A8800A03A28 /* ZXCodaBarReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E78166A9DF300E13304 /* ZXCodaBarReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A318143A8800A03A28 /* ZXCodaBarWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E7A166A9DF300E13304 /* ZXCodaBarWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A418143A8800A03A28 /* ZXCode128Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E7C166A9DF300E13304 /* ZXCode128Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A518143A8800A03A28 /* ZXCode128Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E7E166A9DF300E13304 /* ZXCode128Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A618143A8800A03A28 /* ZXCode39Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E80166A9DF300E13304 /* ZXCode39Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A718143A8800A03A28 /* ZXCode39Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E82166A9DF300E13304 /* ZXCode39Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A818143A8800A03A28 /* ZXCode93Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E84166A9DF300E13304 /* ZXCode93Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48A918143A8800A03A28 /* ZXEAN13Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E86166A9DF300E13304 /* ZXEAN13Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48AA18143A8800A03A28 /* ZXEAN13Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E88166A9DF300E13304 /* ZXEAN13Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48AB18143A8800A03A28 /* ZXEAN8Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E8A166A9DF300E13304 /* ZXEAN8Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48AC18143A8800A03A28 /* ZXEAN8Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E8C166A9DF300E13304 /* ZXEAN8Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48AD18143A8800A03A28 /* ZXEANManufacturerOrgSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E8E166A9DF300E13304 /* ZXEANManufacturerOrgSupport.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48AE18143A8800A03A28 /* ZXITFReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E90166A9DF300E13304 /* ZXITFReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48AF18143A8800A03A28 /* ZXITFWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E92166A9DF300E13304 /* ZXITFWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B018143A8800A03A28 /* ZXMultiFormatOneDReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E94166A9DF300E13304 /* ZXMultiFormatOneDReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B118143A8800A03A28 /* ZXMultiFormatUPCEANReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E96166A9DF300E13304 /* ZXMultiFormatUPCEANReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B218143A8800A03A28 /* ZXOneDimensionalCodeWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E98166A9DF300E13304 /* ZXOneDimensionalCodeWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B318143A8800A03A28 /* ZXOneDReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E9A166A9DF300E13304 /* ZXOneDReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B418143A8800A03A28 /* ZXUPCAReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E9C166A9DF300E13304 /* ZXUPCAReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B518143A8800A03A28 /* ZXUPCAWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E9E166A9DF300E13304 /* ZXUPCAWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B618143A8800A03A28 /* ZXUPCEANExtension2Support.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA0166A9DF300E13304 /* ZXUPCEANExtension2Support.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B718143A8800A03A28 /* ZXUPCEANExtension5Support.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA2166A9DF300E13304 /* ZXUPCEANExtension5Support.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B818143A8800A03A28 /* ZXUPCEANExtensionSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA4166A9DF300E13304 /* ZXUPCEANExtensionSupport.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48B918143A8800A03A28 /* ZXUPCEANReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA6166A9DF300E13304 /* ZXUPCEANReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48BA18143A8800A03A28 /* ZXUPCEANWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA8166A9DF300E13304 /* ZXUPCEANWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48BB18143A8800A03A28 /* ZXUPCEReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EAA166A9DF300E13304 /* ZXUPCEReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48BC18143A8800A03A28 /* ZXModulusGF.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F1B166A9EB500E13304 /* ZXModulusGF.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48BD18143A8800A03A28 /* ZXModulusPoly.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F1D166A9EB500E13304 /* ZXModulusPoly.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48BE18143A8800A03A28 /* ZXPDF417ECErrorCorrection.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F1F166A9EB500E13304 /* ZXPDF417ECErrorCorrection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C018143A8800A03A28 /* ZXPDF417BarcodeMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB5C17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C118143A8800A03A28 /* ZXPDF417BarcodeValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB6417FE5F2E00A71C45 /* ZXPDF417BarcodeValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C218143A8800A03A28 /* ZXPDF417BoundingBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB6C17FE60E700A71C45 /* ZXPDF417BoundingBox.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C318143A8800A03A28 /* ZXPDF417Codeword.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB7417FE649000A71C45 /* ZXPDF417Codeword.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C418143A8800A03A28 /* ZXPDF417CodewordDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B771800DEC300772392 /* ZXPDF417CodewordDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C518143A8800A03A28 /* ZXPDF417DecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F23166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C618143A8800A03A28 /* ZXPDF417DetectionResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B5E17FFC84300772392 /* ZXPDF417DetectionResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C718143A8800A03A28 /* ZXPDF417DetectionResultColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B6717FFC98100772392 /* ZXPDF417DetectionResultColumn.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C818143A8800A03A28 /* ZXPDF417DetectionResultRowIndicatorColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B6F17FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48C918143A8800A03A28 /* ZXPDF417ScanningDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B7F1800E35B00772392 /* ZXPDF417ScanningDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48CA18143A8800A03A28 /* ZXPDF417Detector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F28166A9EB500E13304 /* ZXPDF417Detector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48CB18143A8800A03A28 /* ZXPDF417DetectorResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25389B8718010B9A00772392 /* ZXPDF417DetectorResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48CC18143A8800A03A28 /* ZXBarcodeMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F2B166A9EB500E13304 /* ZXBarcodeMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48CD18143A8800A03A28 /* ZXBarcodeRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F2D166A9EB500E13304 /* ZXBarcodeRow.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48CE18143A8800A03A28 /* ZXCompaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F2F166A9EB500E13304 /* ZXCompaction.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48CF18143A8800A03A28 /* ZXDimensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F30166A9EB500E13304 /* ZXDimensions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D018143A8800A03A28 /* ZXPDF417.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F32166A9EB500E13304 /* ZXPDF417.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D118143A8800A03A28 /* ZXPDF417ErrorCorrection.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F34166A9EB500E13304 /* ZXPDF417ErrorCorrection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D218143A8800A03A28 /* ZXPDF417HighLevelEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F36166A9EB500E13304 /* ZXPDF417HighLevelEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D318143A8800A03A28 /* ZXPDF417Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB4217FE554D00A71C45 /* ZXPDF417Common.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D418143A8800A03A28 /* ZXPDF417Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F3A166A9EB500E13304 /* ZXPDF417Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D518143A8800A03A28 /* ZXPDF417ResultMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB4617FE5C1F00A71C45 /* ZXPDF417ResultMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D618143A8800A03A28 /* ZXPDF417Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2519AB3A17FD1EE400A71C45 /* ZXPDF417Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D718143A8800A03A28 /* ZXDataMask.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F5D166A9F2D00E13304 /* ZXDataMask.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D818143A8800A03A28 /* ZXErrorCorrectionLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F5F166A9F2D00E13304 /* ZXErrorCorrectionLevel.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48D918143A8800A03A28 /* ZXFormatInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F61166A9F2D00E13304 /* ZXFormatInformation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48DA18143A8800A03A28 /* ZXMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F63166A9F2D00E13304 /* ZXMode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48DB18143A8800A03A28 /* ZXQRCodeBitMatrixParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F65166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48DC18143A8800A03A28 /* ZXQRCodeDataBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F67166A9F2D00E13304 /* ZXQRCodeDataBlock.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48DD18143A8800A03A28 /* ZXQRCodeDecodedBitStreamParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F69166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48DE18143A8800A03A28 /* ZXQRCodeDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F6B166A9F2D00E13304 /* ZXQRCodeDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48DF18143A8800A03A28 /* ZXQRCodeVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F6D166A9F2D00E13304 /* ZXQRCodeVersion.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E018143A8800A03A28 /* ZXAlignmentPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F70166A9F2D00E13304 /* ZXAlignmentPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E118143A8800A03A28 /* ZXAlignmentPatternFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F72166A9F2D00E13304 /* ZXAlignmentPatternFinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E218143A8800A03A28 /* ZXFinderPatternFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F74166A9F2D00E13304 /* ZXFinderPatternFinder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E318143A8800A03A28 /* ZXFinderPatternInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F76166A9F2D00E13304 /* ZXFinderPatternInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E418143A8800A03A28 /* ZXQRCodeDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F78166A9F2D00E13304 /* ZXQRCodeDetector.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E518143A8800A03A28 /* ZXQRCodeFinderPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F7A166A9F2D00E13304 /* ZXQRCodeFinderPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E618143A8800A03A28 /* ZXBlockPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F7D166A9F2D00E13304 /* ZXBlockPair.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E718143A8800A03A28 /* ZXByteMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F7F166A9F2D00E13304 /* ZXByteMatrix.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E818143A8800A03A28 /* ZXEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F81166A9F2D00E13304 /* ZXEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48E918143A8800A03A28 /* ZXMaskUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F83166A9F2D00E13304 /* ZXMaskUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48EA18143A8800A03A28 /* ZXMatrixUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F85166A9F2D00E13304 /* ZXMatrixUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48EB18143A8800A03A28 /* ZXQRCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F87166A9F2D00E13304 /* ZXQRCode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48EC18143A8800A03A28 /* ZXQRCodeReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F89166A9F2D00E13304 /* ZXQRCodeReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48ED18143A8800A03A28 /* ZXQRCodeWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F8B166A9F2D00E13304 /* ZXQRCodeWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48EE18143A8800A03A28 /* ZXBarcodeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FBB166A9FFC00E13304 /* ZXBarcodeFormat.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48EF18143A8800A03A28 /* ZXBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FBC166A9FFC00E13304 /* ZXBinarizer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F018143A8800A03A28 /* ZXBinaryBitmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FBE166A9FFC00E13304 /* ZXBinaryBitmap.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F118143A8800A03A28 /* ZXDecodeHints.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FC0166A9FFC00E13304 /* ZXDecodeHints.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F218143A8800A03A28 /* ZXDimension.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542997316D46E8400D4C045 /* ZXDimension.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F318143A8800A03A28 /* ZXEncodeHints.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FC2166A9FFC00E13304 /* ZXEncodeHints.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F418143A8800A03A28 /* ZXErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FC4166A9FFC00E13304 /* ZXErrors.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F518143A8800A03A28 /* ZXingObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403CBB166A96FA00E13304 /* ZXingObjC.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F618143A8800A03A28 /* ZXInvertedLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2504D4C416F698AA00DF8882 /* ZXInvertedLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F718143A8800A03A28 /* ZXLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD1166AA00700E13304 /* ZXLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F818143A8800A03A28 /* ZXMultiFormatReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD3166AA00700E13304 /* ZXMultiFormatReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48F918143A8800A03A28 /* ZXMultiFormatWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD5166AA00700E13304 /* ZXMultiFormatWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48FA18143A8800A03A28 /* ZXPlanarYUVLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542996B16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48FB18143A8800A03A28 /* ZXReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD7166AA00700E13304 /* ZXReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48FC18143A8800A03A28 /* ZXResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FD8166AA00700E13304 /* ZXResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48FD18143A8800A03A28 /* ZXResultMetadataType.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDA166AA00700E13304 /* ZXResultMetadataType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48FE18143A8800A03A28 /* ZXResultPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDB166AA00700E13304 /* ZXResultPoint.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E48FF18143A8800A03A28 /* ZXResultPointCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDD166AA00700E13304 /* ZXResultPointCallback.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490018143A8800A03A28 /* ZXRGBLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 251FCDE916CC8F53000C27E5 /* ZXRGBLuminanceSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490118143A8800A03A28 /* ZXWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FDE166AA00700E13304 /* ZXWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490218143AC600A03A28 /* ZXAbstractExpandedDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E40166A9DF300E13304 /* ZXAbstractExpandedDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490318143AC600A03A28 /* ZXAI013103decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E42166A9DF300E13304 /* ZXAI013103decoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490418143AC600A03A28 /* ZXAI01320xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E44166A9DF300E13304 /* ZXAI01320xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490518143AC600A03A28 /* ZXAI01392xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E46166A9DF300E13304 /* ZXAI01392xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490618143AC600A03A28 /* ZXAI01393xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E48166A9DF300E13304 /* ZXAI01393xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490718143AC600A03A28 /* ZXAI013x0x1xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E4A166A9DF300E13304 /* ZXAI013x0x1xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490818143AC600A03A28 /* ZXAI013x0xDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E4C166A9DF300E13304 /* ZXAI013x0xDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490918143AC600A03A28 /* ZXAI01AndOtherAIs.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E4E166A9DF300E13304 /* ZXAI01AndOtherAIs.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490A18143AC600A03A28 /* ZXAI01decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E50166A9DF300E13304 /* ZXAI01decoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490B18143AC600A03A28 /* ZXAI01weightDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E52166A9DF300E13304 /* ZXAI01weightDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490C18143AC600A03A28 /* ZXAnyAIDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E54166A9DF300E13304 /* ZXAnyAIDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490D18143AC600A03A28 /* ZXBlockParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E56166A9DF300E13304 /* ZXBlockParsedResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490E18143AC600A03A28 /* ZXCurrentParsingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E58166A9DF300E13304 /* ZXCurrentParsingState.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E490F18143AC600A03A28 /* ZXDecodedChar.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E5A166A9DF300E13304 /* ZXDecodedChar.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491018143AC600A03A28 /* ZXDecodedInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E5C166A9DF300E13304 /* ZXDecodedInformation.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491118143AC600A03A28 /* ZXDecodedNumeric.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E5E166A9DF300E13304 /* ZXDecodedNumeric.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491218143AC600A03A28 /* ZXDecodedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E60166A9DF300E13304 /* ZXDecodedObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491318143AC600A03A28 /* ZXFieldParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E62166A9DF300E13304 /* ZXFieldParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491418143AC600A03A28 /* ZXGeneralAppIdDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E64166A9DF300E13304 /* ZXGeneralAppIdDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491518143AC600A03A28 /* ZXBitArrayBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E66166A9DF300E13304 /* ZXBitArrayBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491618143AC600A03A28 /* ZXExpandedPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E68166A9DF300E13304 /* ZXExpandedPair.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491718143AC600A03A28 /* ZXExpandedRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FE5D3116D0AFED00826CDB /* ZXExpandedRow.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491818143AC600A03A28 /* ZXRSSExpandedReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E6A166A9DF300E13304 /* ZXRSSExpandedReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491918143AC600A03A28 /* ZXAbstractRSSReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E6C166A9DF300E13304 /* ZXAbstractRSSReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491A18143AC600A03A28 /* ZXDataCharacter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E6E166A9DF300E13304 /* ZXDataCharacter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491B18143AC600A03A28 /* ZXPair.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E70166A9DF300E13304 /* ZXPair.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491C18143AC600A03A28 /* ZXRSS14Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E72166A9DF300E13304 /* ZXRSS14Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491D18143AC600A03A28 /* ZXRSSFinderPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E74166A9DF300E13304 /* ZXRSSFinderPattern.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491E18143AC600A03A28 /* ZXRSSUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E76166A9DF300E13304 /* ZXRSSUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E491F18143AC600A03A28 /* ZXCodaBarReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E78166A9DF300E13304 /* ZXCodaBarReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492018143AC600A03A28 /* ZXCodaBarWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E7A166A9DF300E13304 /* ZXCodaBarWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492118143AC600A03A28 /* ZXCode128Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E7C166A9DF300E13304 /* ZXCode128Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492218143AC600A03A28 /* ZXCode128Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E7E166A9DF300E13304 /* ZXCode128Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492318143AC600A03A28 /* ZXCode39Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E80166A9DF300E13304 /* ZXCode39Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492418143AC600A03A28 /* ZXCode39Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E82166A9DF300E13304 /* ZXCode39Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492518143AC600A03A28 /* ZXCode93Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E84166A9DF300E13304 /* ZXCode93Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492618143AC600A03A28 /* ZXEAN13Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E86166A9DF300E13304 /* ZXEAN13Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492718143AC600A03A28 /* ZXEAN13Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E88166A9DF300E13304 /* ZXEAN13Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492818143AC600A03A28 /* ZXEAN8Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E8A166A9DF300E13304 /* ZXEAN8Reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492918143AC600A03A28 /* ZXEAN8Writer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E8C166A9DF300E13304 /* ZXEAN8Writer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492A18143AC600A03A28 /* ZXEANManufacturerOrgSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E8E166A9DF300E13304 /* ZXEANManufacturerOrgSupport.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492B18143AC600A03A28 /* ZXITFReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E90166A9DF300E13304 /* ZXITFReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492C18143AC600A03A28 /* ZXITFWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E92166A9DF300E13304 /* ZXITFWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492D18143AC600A03A28 /* ZXMultiFormatOneDReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E94166A9DF300E13304 /* ZXMultiFormatOneDReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492E18143AC600A03A28 /* ZXMultiFormatUPCEANReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E96166A9DF300E13304 /* ZXMultiFormatUPCEANReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E492F18143AC600A03A28 /* ZXOneDimensionalCodeWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E98166A9DF300E13304 /* ZXOneDimensionalCodeWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493018143AC600A03A28 /* ZXOneDReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E9A166A9DF300E13304 /* ZXOneDReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493118143AC600A03A28 /* ZXUPCAReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E9C166A9DF300E13304 /* ZXUPCAReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493218143AC600A03A28 /* ZXUPCAWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403E9E166A9DF300E13304 /* ZXUPCAWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493318143AC600A03A28 /* ZXUPCEANExtension2Support.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA0166A9DF300E13304 /* ZXUPCEANExtension2Support.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493418143AC600A03A28 /* ZXUPCEANExtension5Support.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA2166A9DF300E13304 /* ZXUPCEANExtension5Support.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493518143AC600A03A28 /* ZXUPCEANExtensionSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA4166A9DF300E13304 /* ZXUPCEANExtensionSupport.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493618143AC600A03A28 /* ZXUPCEANReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA6166A9DF300E13304 /* ZXUPCEANReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493718143AC600A03A28 /* ZXUPCEANWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EA8166A9DF300E13304 /* ZXUPCEANWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493818143AC600A03A28 /* ZXUPCEReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403EAA166A9DF300E13304 /* ZXUPCEReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493918143AC600A03A28 /* ZXModulusGF.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F1B166A9EB500E13304 /* ZXModulusGF.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493A18143AC600A03A28 /* ZXModulusPoly.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F1D166A9EB500E13304 /* ZXModulusPoly.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493B18143AC600A03A28 /* ZXPDF417ECErrorCorrection.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403F1F166A9EB500E13304 /* ZXPDF417ECErrorCorrection.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 255E493C18143AC600A03A28 /* ZXBarcodeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 25403FBB166A9FFC00E13304 /* ZXBarcodeFormat.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25FE5D3316D0AFED00826CDB /* ZXExpandedRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 25FE5D3116D0AFED00826CDB /* ZXExpandedRow.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 25FE5D3416D0AFED00826CDB /* ZXExpandedRow.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3216D0AFED00826CDB /* ZXExpandedRow.m */; };
+ 25FE5D3616D0B00600826CDB /* ZXExpandedRow.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3216D0AFED00826CDB /* ZXExpandedRow.m */; };
+ 25FE5D3716D0B00700826CDB /* ZXExpandedRow.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3216D0AFED00826CDB /* ZXExpandedRow.m */; };
+ 25FE5D4016D0B84C00826CDB /* RSSExpandedStackedInternalTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D3F16D0B84C00826CDB /* RSSExpandedStackedInternalTestCase.m */; };
+ 25FE5D4316D0B8B200826CDB /* TestCaseUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 25FE5D4216D0B8B200826CDB /* TestCaseUtil.m */; };
+ 25FE5D4516D1997C00826CDB /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 25FE5D4416D1997C00826CDB /* Resources */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 024957F11898641B003D4E6A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 25403CAA166A96F900E13304 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 25403CB2166A96FA00E13304;
+ remoteInfo = ZXingObjC;
+ };
+ 02D81371189864C70081721D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 25403CAA166A96F900E13304 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 25404165166AADAC00E13304;
+ remoteInfo = ZXingObjC;
+ };
+ 25403CCA166A96FA00E13304 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 25403CAA166A96F900E13304 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 25403CB2166A96FA00E13304;
+ remoteInfo = ZXingObjC;
+ };
+ 2540417B166AADAC00E13304 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 25403CAA166A96F900E13304 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 25404165166AADAC00E13304;
+ remoteInfo = ZXingObjC;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 024958781898641B003D4E6A /* ZXingObjCTests-iOS copy.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ZXingObjCTests-iOS copy.octest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 02BDA2EE1803109E0039B326 /* Tests-iOS-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Tests-iOS-Prefix.pch"; sourceTree = "<group>"; };
+ 02BDA2EF1803109E0039B326 /* Tests-OSX-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Tests-OSX-Prefix.pch"; sourceTree = "<group>"; };
+ 02BDA2F01803109E0039B326 /* ZXingObjCTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ZXingObjCTests-Info.plist"; sourceTree = "<group>"; };
+ 02D813F6189864C70081721D /* ZXingObjCTests-osx copy.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ZXingObjCTests-osx copy.octest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2504D4C416F698AA00DF8882 /* ZXInvertedLuminanceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXInvertedLuminanceSource.h; sourceTree = "<group>"; };
+ 2504D4C516F698AA00DF8882 /* ZXInvertedLuminanceSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXInvertedLuminanceSource.m; sourceTree = "<group>"; };
+ 2504D9CD16FFD2E200DF8882 /* ZXAztecCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXAztecCode.h; path = encoder/ZXAztecCode.h; sourceTree = "<group>"; };
+ 2504D9CE16FFD2E200DF8882 /* ZXAztecCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXAztecCode.m; path = encoder/ZXAztecCode.m; sourceTree = "<group>"; };
+ 2504D9DA16FFD4CD00DF8882 /* ZXAztecEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXAztecEncoder.h; path = encoder/ZXAztecEncoder.h; sourceTree = "<group>"; };
+ 2504D9DB16FFD4CD00DF8882 /* ZXAztecEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXAztecEncoder.m; path = encoder/ZXAztecEncoder.m; sourceTree = "<group>"; };
+ 2504D9E416FFF27C00DF8882 /* ZXAztecEncoderTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXAztecEncoderTest.h; path = encoder/ZXAztecEncoderTest.h; sourceTree = "<group>"; };
+ 2504D9E516FFF27C00DF8882 /* ZXAztecEncoderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXAztecEncoderTest.m; path = encoder/ZXAztecEncoderTest.m; sourceTree = "<group>"; };
+ 2504D9EA170005FE00DF8882 /* ReedSolomonTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReedSolomonTestCase.h; sourceTree = "<group>"; };
+ 2504D9EB170005FE00DF8882 /* ReedSolomonTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReedSolomonTestCase.m; sourceTree = "<group>"; };
+ 2519AB3217FD1EC000A71C45 /* ZXAztecWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAztecWriter.h; sourceTree = "<group>"; };
+ 2519AB3317FD1EC000A71C45 /* ZXAztecWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAztecWriter.m; sourceTree = "<group>"; };
+ 2519AB3A17FD1EE400A71C45 /* ZXPDF417Writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417Writer.h; sourceTree = "<group>"; };
+ 2519AB3B17FD1EE400A71C45 /* ZXPDF417Writer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417Writer.m; sourceTree = "<group>"; };
+ 2519AB4217FE554D00A71C45 /* ZXPDF417Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417Common.h; sourceTree = "<group>"; };
+ 2519AB4317FE554D00A71C45 /* ZXPDF417Common.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417Common.m; sourceTree = "<group>"; };
+ 2519AB4617FE5C1F00A71C45 /* ZXPDF417ResultMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417ResultMetadata.h; sourceTree = "<group>"; };
+ 2519AB4717FE5C1F00A71C45 /* ZXPDF417ResultMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417ResultMetadata.m; sourceTree = "<group>"; };
+ 2519AB5C17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417BarcodeMetadata.h; sourceTree = "<group>"; };
+ 2519AB5D17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417BarcodeMetadata.m; sourceTree = "<group>"; };
+ 2519AB6417FE5F2E00A71C45 /* ZXPDF417BarcodeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417BarcodeValue.h; sourceTree = "<group>"; };
+ 2519AB6517FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417BarcodeValue.m; sourceTree = "<group>"; };
+ 2519AB6C17FE60E700A71C45 /* ZXPDF417BoundingBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417BoundingBox.h; sourceTree = "<group>"; };
+ 2519AB6D17FE60E700A71C45 /* ZXPDF417BoundingBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417BoundingBox.m; sourceTree = "<group>"; };
+ 2519AB7417FE649000A71C45 /* ZXPDF417Codeword.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417Codeword.h; sourceTree = "<group>"; };
+ 2519AB7517FE649000A71C45 /* ZXPDF417Codeword.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417Codeword.m; sourceTree = "<group>"; };
+ 251FCDE916CC8F53000C27E5 /* ZXRGBLuminanceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXRGBLuminanceSource.h; sourceTree = "<group>"; };
+ 251FCDEA16CC8F53000C27E5 /* ZXRGBLuminanceSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXRGBLuminanceSource.m; sourceTree = "<group>"; };
+ 25389B5E17FFC84300772392 /* ZXPDF417DetectionResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417DetectionResult.h; sourceTree = "<group>"; };
+ 25389B5F17FFC84300772392 /* ZXPDF417DetectionResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417DetectionResult.m; sourceTree = "<group>"; };
+ 25389B6717FFC98100772392 /* ZXPDF417DetectionResultColumn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417DetectionResultColumn.h; sourceTree = "<group>"; };
+ 25389B6817FFC98100772392 /* ZXPDF417DetectionResultColumn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417DetectionResultColumn.m; sourceTree = "<group>"; };
+ 25389B6F17FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417DetectionResultRowIndicatorColumn.h; sourceTree = "<group>"; };
+ 25389B7017FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417DetectionResultRowIndicatorColumn.m; sourceTree = "<group>"; };
+ 25389B771800DEC300772392 /* ZXPDF417CodewordDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417CodewordDecoder.h; sourceTree = "<group>"; };
+ 25389B781800DEC300772392 /* ZXPDF417CodewordDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417CodewordDecoder.m; sourceTree = "<group>"; };
+ 25389B7F1800E35B00772392 /* ZXPDF417ScanningDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417ScanningDecoder.h; sourceTree = "<group>"; };
+ 25389B801800E35B00772392 /* ZXPDF417ScanningDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417ScanningDecoder.m; sourceTree = "<group>"; };
+ 25389B8718010B9A00772392 /* ZXPDF417DetectorResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417DetectorResult.h; sourceTree = "<group>"; };
+ 25389B8818010B9A00772392 /* ZXPDF417DetectorResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417DetectorResult.m; sourceTree = "<group>"; };
+ 25389B9018010D9B00772392 /* ZXPDF417DetectorTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417DetectorTest.h; sourceTree = "<group>"; };
+ 25389B9118010D9B00772392 /* ZXPDF417DetectorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417DetectorTest.m; sourceTree = "<group>"; };
+ 25403CB3166A96FA00E13304 /* libZXingObjC-iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libZXingObjC-iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 25403CB6166A96FA00E13304 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 25403CBB166A96FA00E13304 /* ZXingObjC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZXingObjC.h; sourceTree = "<group>"; };
+ 25403CC4166A96FA00E13304 /* Unit Tests iOS.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Unit Tests iOS.octest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 25403CC5166A96FA00E13304 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
+ 25403CE1166A979700E13304 /* ios-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ios-Prefix.pch"; sourceTree = SOURCE_ROOT; };
+ 25403CEE166A999D00E13304 /* ZXAztecDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAztecDecoder.h; sourceTree = "<group>"; };
+ 25403CEF166A999D00E13304 /* ZXAztecDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAztecDecoder.m; sourceTree = "<group>"; };
+ 25403CF1166A999D00E13304 /* ZXAztecDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAztecDetector.h; sourceTree = "<group>"; };
+ 25403CF2166A999D00E13304 /* ZXAztecDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAztecDetector.m; sourceTree = "<group>"; };
+ 25403CF3166A999D00E13304 /* ZXAztecDetectorResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAztecDetectorResult.h; sourceTree = "<group>"; };
+ 25403CF4166A999D00E13304 /* ZXAztecDetectorResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAztecDetectorResult.m; sourceTree = "<group>"; };
+ 25403CF5166A999D00E13304 /* ZXAztecReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAztecReader.h; sourceTree = "<group>"; };
+ 25403CF6166A999D00E13304 /* ZXAztecReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAztecReader.m; sourceTree = "<group>"; };
+ 25403D01166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAbstractDoCoMoResultParser.h; sourceTree = "<group>"; };
+ 25403D02166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAbstractDoCoMoResultParser.m; sourceTree = "<group>"; };
+ 25403D03166A9A0800E13304 /* ZXAddressBookAUResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAddressBookAUResultParser.h; sourceTree = "<group>"; };
+ 25403D04166A9A0800E13304 /* ZXAddressBookAUResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAddressBookAUResultParser.m; sourceTree = "<group>"; };
+ 25403D05166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAddressBookDoCoMoResultParser.h; sourceTree = "<group>"; };
+ 25403D06166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAddressBookDoCoMoResultParser.m; sourceTree = "<group>"; };
+ 25403D07166A9A0800E13304 /* ZXAddressBookParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAddressBookParsedResult.h; sourceTree = "<group>"; };
+ 25403D08166A9A0800E13304 /* ZXAddressBookParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAddressBookParsedResult.m; sourceTree = "<group>"; };
+ 25403D09166A9A0800E13304 /* ZXBizcardResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBizcardResultParser.h; sourceTree = "<group>"; };
+ 25403D0A166A9A0800E13304 /* ZXBizcardResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBizcardResultParser.m; sourceTree = "<group>"; };
+ 25403D0B166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBookmarkDoCoMoResultParser.h; sourceTree = "<group>"; };
+ 25403D0C166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBookmarkDoCoMoResultParser.m; sourceTree = "<group>"; };
+ 25403D0D166A9A0800E13304 /* ZXCalendarParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCalendarParsedResult.h; sourceTree = "<group>"; };
+ 25403D0E166A9A0800E13304 /* ZXCalendarParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCalendarParsedResult.m; sourceTree = "<group>"; };
+ 25403D0F166A9A0800E13304 /* ZXEmailAddressParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEmailAddressParsedResult.h; sourceTree = "<group>"; };
+ 25403D10166A9A0800E13304 /* ZXEmailAddressParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEmailAddressParsedResult.m; sourceTree = "<group>"; };
+ 25403D11166A9A0800E13304 /* ZXEmailAddressResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEmailAddressResultParser.h; sourceTree = "<group>"; };
+ 25403D12166A9A0800E13304 /* ZXEmailAddressResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEmailAddressResultParser.m; sourceTree = "<group>"; };
+ 25403D13166A9A0800E13304 /* ZXEmailDoCoMoResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEmailDoCoMoResultParser.h; sourceTree = "<group>"; };
+ 25403D14166A9A0800E13304 /* ZXEmailDoCoMoResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEmailDoCoMoResultParser.m; sourceTree = "<group>"; };
+ 25403D15166A9A0800E13304 /* ZXExpandedProductParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXExpandedProductParsedResult.h; sourceTree = "<group>"; };
+ 25403D16166A9A0800E13304 /* ZXExpandedProductParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXExpandedProductParsedResult.m; sourceTree = "<group>"; };
+ 25403D17166A9A0800E13304 /* ZXExpandedProductResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXExpandedProductResultParser.h; sourceTree = "<group>"; };
+ 25403D18166A9A0800E13304 /* ZXExpandedProductResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXExpandedProductResultParser.m; sourceTree = "<group>"; };
+ 25403D19166A9A0800E13304 /* ZXGeoParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXGeoParsedResult.h; sourceTree = "<group>"; };
+ 25403D1A166A9A0800E13304 /* ZXGeoParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGeoParsedResult.m; sourceTree = "<group>"; };
+ 25403D1B166A9A0800E13304 /* ZXGeoResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXGeoResultParser.h; sourceTree = "<group>"; };
+ 25403D1C166A9A0800E13304 /* ZXGeoResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGeoResultParser.m; sourceTree = "<group>"; };
+ 25403D1D166A9A0800E13304 /* ZXISBNParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXISBNParsedResult.h; sourceTree = "<group>"; };
+ 25403D1E166A9A0800E13304 /* ZXISBNParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXISBNParsedResult.m; sourceTree = "<group>"; };
+ 25403D1F166A9A0800E13304 /* ZXISBNResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXISBNResultParser.h; sourceTree = "<group>"; };
+ 25403D20166A9A0800E13304 /* ZXISBNResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXISBNResultParser.m; sourceTree = "<group>"; };
+ 25403D21166A9A0800E13304 /* ZXParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXParsedResult.h; sourceTree = "<group>"; };
+ 25403D22166A9A0800E13304 /* ZXParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXParsedResult.m; sourceTree = "<group>"; };
+ 25403D23166A9A0800E13304 /* ZXParsedResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXParsedResultType.h; sourceTree = "<group>"; };
+ 25403D24166A9A0800E13304 /* ZXProductParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXProductParsedResult.h; sourceTree = "<group>"; };
+ 25403D25166A9A0800E13304 /* ZXProductParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXProductParsedResult.m; sourceTree = "<group>"; };
+ 25403D26166A9A0800E13304 /* ZXProductResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXProductResultParser.h; sourceTree = "<group>"; };
+ 25403D27166A9A0800E13304 /* ZXProductResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXProductResultParser.m; sourceTree = "<group>"; };
+ 25403D28166A9A0800E13304 /* ZXResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXResultParser.h; sourceTree = "<group>"; };
+ 25403D29166A9A0800E13304 /* ZXResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXResultParser.m; sourceTree = "<group>"; };
+ 25403D2A166A9A0800E13304 /* ZXSMSMMSResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXSMSMMSResultParser.h; sourceTree = "<group>"; };
+ 25403D2B166A9A0800E13304 /* ZXSMSMMSResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXSMSMMSResultParser.m; sourceTree = "<group>"; };
+ 25403D2C166A9A0800E13304 /* ZXSMSParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXSMSParsedResult.h; sourceTree = "<group>"; };
+ 25403D2D166A9A0800E13304 /* ZXSMSParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXSMSParsedResult.m; sourceTree = "<group>"; };
+ 25403D2E166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXSMSTOMMSTOResultParser.h; sourceTree = "<group>"; };
+ 25403D2F166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXSMSTOMMSTOResultParser.m; sourceTree = "<group>"; };
+ 25403D30166A9A0800E13304 /* ZXSMTPResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXSMTPResultParser.h; sourceTree = "<group>"; };
+ 25403D31166A9A0800E13304 /* ZXSMTPResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXSMTPResultParser.m; sourceTree = "<group>"; };
+ 25403D32166A9A0800E13304 /* ZXTelParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXTelParsedResult.h; sourceTree = "<group>"; };
+ 25403D33166A9A0800E13304 /* ZXTelParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXTelParsedResult.m; sourceTree = "<group>"; };
+ 25403D34166A9A0800E13304 /* ZXTelResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXTelResultParser.h; sourceTree = "<group>"; };
+ 25403D35166A9A0800E13304 /* ZXTelResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXTelResultParser.m; sourceTree = "<group>"; };
+ 25403D36166A9A0800E13304 /* ZXTextParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXTextParsedResult.h; sourceTree = "<group>"; };
+ 25403D37166A9A0800E13304 /* ZXTextParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXTextParsedResult.m; sourceTree = "<group>"; };
+ 25403D38166A9A0800E13304 /* ZXURIParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXURIParsedResult.h; sourceTree = "<group>"; };
+ 25403D39166A9A0800E13304 /* ZXURIParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXURIParsedResult.m; sourceTree = "<group>"; };
+ 25403D3A166A9A0800E13304 /* ZXURIResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXURIResultParser.h; sourceTree = "<group>"; };
+ 25403D3B166A9A0800E13304 /* ZXURIResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXURIResultParser.m; sourceTree = "<group>"; };
+ 25403D3C166A9A0800E13304 /* ZXURLTOResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXURLTOResultParser.h; sourceTree = "<group>"; };
+ 25403D3D166A9A0800E13304 /* ZXURLTOResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXURLTOResultParser.m; sourceTree = "<group>"; };
+ 25403D3E166A9A0800E13304 /* ZXVCardResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXVCardResultParser.h; sourceTree = "<group>"; };
+ 25403D3F166A9A0800E13304 /* ZXVCardResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXVCardResultParser.m; sourceTree = "<group>"; };
+ 25403D40166A9A0800E13304 /* ZXVEventResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXVEventResultParser.h; sourceTree = "<group>"; };
+ 25403D41166A9A0800E13304 /* ZXVEventResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXVEventResultParser.m; sourceTree = "<group>"; };
+ 25403D42166A9A0800E13304 /* ZXWifiParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXWifiParsedResult.h; sourceTree = "<group>"; };
+ 25403D43166A9A0800E13304 /* ZXWifiParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXWifiParsedResult.m; sourceTree = "<group>"; };
+ 25403D44166A9A0800E13304 /* ZXWifiResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXWifiResultParser.h; sourceTree = "<group>"; };
+ 25403D45166A9A0800E13304 /* ZXWifiResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXWifiResultParser.m; sourceTree = "<group>"; };
+ 25403D46166A9A0800E13304 /* ZXCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCapture.h; sourceTree = "<group>"; };
+ 25403D47166A9A0800E13304 /* ZXCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCapture.m; sourceTree = "<group>"; };
+ 25403D48166A9A0800E13304 /* ZXCaptureDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCaptureDelegate.h; sourceTree = "<group>"; };
+ 25403D49166A9A0800E13304 /* ZXCaptureView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCaptureView.h; sourceTree = "<group>"; };
+ 25403D4A166A9A0800E13304 /* ZXCaptureView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCaptureView.m; sourceTree = "<group>"; };
+ 25403D4B166A9A0800E13304 /* ZXCGImageLuminanceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCGImageLuminanceSource.h; sourceTree = "<group>"; };
+ 25403D4C166A9A0800E13304 /* ZXCGImageLuminanceSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCGImageLuminanceSource.m; sourceTree = "<group>"; };
+ 25403D4D166A9A0800E13304 /* ZXImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXImage.h; sourceTree = "<group>"; };
+ 25403D4E166A9A0800E13304 /* ZXImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXImage.m; sourceTree = "<group>"; };
+ 25403D4F166A9A0800E13304 /* ZXView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXView.h; sourceTree = "<group>"; };
+ 25403DA1166A9C0E00E13304 /* ZXMathUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMathUtils.h; sourceTree = "<group>"; };
+ 25403DA2166A9C0E00E13304 /* ZXMathUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMathUtils.m; sourceTree = "<group>"; };
+ 25403DA3166A9C0E00E13304 /* ZXMonochromeRectangleDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMonochromeRectangleDetector.h; sourceTree = "<group>"; };
+ 25403DA4166A9C0E00E13304 /* ZXMonochromeRectangleDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMonochromeRectangleDetector.m; sourceTree = "<group>"; };
+ 25403DA5166A9C0E00E13304 /* ZXWhiteRectangleDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXWhiteRectangleDetector.h; sourceTree = "<group>"; };
+ 25403DA6166A9C0E00E13304 /* ZXWhiteRectangleDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXWhiteRectangleDetector.m; sourceTree = "<group>"; };
+ 25403DA8166A9C0E00E13304 /* ZXGenericGF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXGenericGF.h; sourceTree = "<group>"; };
+ 25403DA9166A9C0E00E13304 /* ZXGenericGF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGenericGF.m; sourceTree = "<group>"; };
+ 25403DAA166A9C0E00E13304 /* ZXGenericGFPoly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXGenericGFPoly.h; sourceTree = "<group>"; };
+ 25403DAB166A9C0E00E13304 /* ZXGenericGFPoly.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGenericGFPoly.m; sourceTree = "<group>"; };
+ 25403DAC166A9C0E00E13304 /* ZXReedSolomonDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXReedSolomonDecoder.h; sourceTree = "<group>"; };
+ 25403DAD166A9C0E00E13304 /* ZXReedSolomonDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXReedSolomonDecoder.m; sourceTree = "<group>"; };
+ 25403DAE166A9C0E00E13304 /* ZXReedSolomonEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXReedSolomonEncoder.h; sourceTree = "<group>"; };
+ 25403DAF166A9C0E00E13304 /* ZXReedSolomonEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXReedSolomonEncoder.m; sourceTree = "<group>"; };
+ 25403DB0166A9C0E00E13304 /* ZXBitArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBitArray.h; sourceTree = "<group>"; };
+ 25403DB1166A9C0E00E13304 /* ZXBitArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBitArray.m; sourceTree = "<group>"; };
+ 25403DB2166A9C0E00E13304 /* ZXBitMatrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBitMatrix.h; sourceTree = "<group>"; };
+ 25403DB3166A9C0E00E13304 /* ZXBitMatrix.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBitMatrix.m; sourceTree = "<group>"; };
+ 25403DB4166A9C0E00E13304 /* ZXBitSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBitSource.h; sourceTree = "<group>"; };
+ 25403DB5166A9C0E00E13304 /* ZXBitSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBitSource.m; sourceTree = "<group>"; };
+ 25403DB6166A9C0E00E13304 /* ZXCharacterSetECI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCharacterSetECI.h; sourceTree = "<group>"; };
+ 25403DB7166A9C0E00E13304 /* ZXCharacterSetECI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCharacterSetECI.m; sourceTree = "<group>"; };
+ 25403DB8166A9C0E00E13304 /* ZXDecoderResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDecoderResult.h; sourceTree = "<group>"; };
+ 25403DB9166A9C0E00E13304 /* ZXDecoderResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDecoderResult.m; sourceTree = "<group>"; };
+ 25403DBA166A9C0E00E13304 /* ZXDefaultGridSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDefaultGridSampler.h; sourceTree = "<group>"; };
+ 25403DBB166A9C0E00E13304 /* ZXDefaultGridSampler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDefaultGridSampler.m; sourceTree = "<group>"; };
+ 25403DBC166A9C0E00E13304 /* ZXDetectorResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDetectorResult.h; sourceTree = "<group>"; };
+ 25403DBD166A9C0E00E13304 /* ZXDetectorResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDetectorResult.m; sourceTree = "<group>"; };
+ 25403DBE166A9C0E00E13304 /* ZXECI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXECI.h; sourceTree = "<group>"; };
+ 25403DBF166A9C0E00E13304 /* ZXECI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXECI.m; sourceTree = "<group>"; };
+ 25403DC0166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXGlobalHistogramBinarizer.h; sourceTree = "<group>"; };
+ 25403DC1166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGlobalHistogramBinarizer.m; sourceTree = "<group>"; };
+ 25403DC2166A9C0E00E13304 /* ZXGridSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXGridSampler.h; sourceTree = "<group>"; };
+ 25403DC3166A9C0E00E13304 /* ZXGridSampler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGridSampler.m; sourceTree = "<group>"; };
+ 25403DC4166A9C0E00E13304 /* ZXHybridBinarizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXHybridBinarizer.h; sourceTree = "<group>"; };
+ 25403DC5166A9C0E00E13304 /* ZXHybridBinarizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXHybridBinarizer.m; sourceTree = "<group>"; };
+ 25403DC6166A9C0E00E13304 /* ZXPerspectiveTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPerspectiveTransform.h; sourceTree = "<group>"; };
+ 25403DC7166A9C0E00E13304 /* ZXPerspectiveTransform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPerspectiveTransform.m; sourceTree = "<group>"; };
+ 25403DC8166A9C0E00E13304 /* ZXStringUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXStringUtils.h; sourceTree = "<group>"; };
+ 25403DC9166A9C0E00E13304 /* ZXStringUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXStringUtils.m; sourceTree = "<group>"; };
+ 25403DF4166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixBitMatrixParser.h; sourceTree = "<group>"; };
+ 25403DF5166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixBitMatrixParser.m; sourceTree = "<group>"; };
+ 25403DF6166A9CCB00E13304 /* ZXDataMatrixDataBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixDataBlock.h; sourceTree = "<group>"; };
+ 25403DF7166A9CCB00E13304 /* ZXDataMatrixDataBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixDataBlock.m; sourceTree = "<group>"; };
+ 25403DF8166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixDecodedBitStreamParser.h; sourceTree = "<group>"; };
+ 25403DF9166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixDecodedBitStreamParser.m; sourceTree = "<group>"; };
+ 25403DFA166A9CCB00E13304 /* ZXDataMatrixDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixDecoder.h; sourceTree = "<group>"; };
+ 25403DFB166A9CCB00E13304 /* ZXDataMatrixDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixDecoder.m; sourceTree = "<group>"; };
+ 25403DFC166A9CCB00E13304 /* ZXDataMatrixVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixVersion.h; sourceTree = "<group>"; };
+ 25403DFD166A9CCB00E13304 /* ZXDataMatrixVersion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixVersion.m; sourceTree = "<group>"; };
+ 25403DFF166A9CCB00E13304 /* ZXDataMatrixDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixDetector.h; sourceTree = "<group>"; };
+ 25403E00166A9CCB00E13304 /* ZXDataMatrixDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixDetector.m; sourceTree = "<group>"; };
+ 25403E01166A9CCB00E13304 /* ZXDataMatrixReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixReader.h; sourceTree = "<group>"; };
+ 25403E02166A9CCB00E13304 /* ZXDataMatrixReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixReader.m; sourceTree = "<group>"; };
+ 25403E13166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMaxiCodeBitMatrixParser.h; sourceTree = "<group>"; };
+ 25403E14166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMaxiCodeBitMatrixParser.m; sourceTree = "<group>"; };
+ 25403E15166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMaxiCodeDecodedBitStreamParser.h; sourceTree = "<group>"; };
+ 25403E16166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMaxiCodeDecodedBitStreamParser.m; sourceTree = "<group>"; };
+ 25403E17166A9D4B00E13304 /* ZXMaxiCodeDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMaxiCodeDecoder.h; sourceTree = "<group>"; };
+ 25403E18166A9D4B00E13304 /* ZXMaxiCodeDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMaxiCodeDecoder.m; sourceTree = "<group>"; };
+ 25403E19166A9D4B00E13304 /* ZXMaxiCodeReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMaxiCodeReader.h; sourceTree = "<group>"; };
+ 25403E1A166A9D4B00E13304 /* ZXMaxiCodeReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMaxiCodeReader.m; sourceTree = "<group>"; };
+ 25403E26166A9D8B00E13304 /* ZXMultiDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMultiDetector.h; sourceTree = "<group>"; };
+ 25403E27166A9D8B00E13304 /* ZXMultiDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMultiDetector.m; sourceTree = "<group>"; };
+ 25403E28166A9D8B00E13304 /* ZXMultiFinderPatternFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMultiFinderPatternFinder.h; sourceTree = "<group>"; };
+ 25403E29166A9D8B00E13304 /* ZXMultiFinderPatternFinder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMultiFinderPatternFinder.m; sourceTree = "<group>"; };
+ 25403E2A166A9D8B00E13304 /* ZXQRCodeMultiReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeMultiReader.h; sourceTree = "<group>"; };
+ 25403E2B166A9D8B00E13304 /* ZXQRCodeMultiReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeMultiReader.m; sourceTree = "<group>"; };
+ 25403E2C166A9D8B00E13304 /* ZXByQuadrantReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXByQuadrantReader.h; sourceTree = "<group>"; };
+ 25403E2D166A9D8B00E13304 /* ZXByQuadrantReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXByQuadrantReader.m; sourceTree = "<group>"; };
+ 25403E2E166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXGenericMultipleBarcodeReader.h; sourceTree = "<group>"; };
+ 25403E2F166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGenericMultipleBarcodeReader.m; sourceTree = "<group>"; };
+ 25403E30166A9D8B00E13304 /* ZXMultipleBarcodeReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMultipleBarcodeReader.h; sourceTree = "<group>"; };
+ 25403E40166A9DF300E13304 /* ZXAbstractExpandedDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAbstractExpandedDecoder.h; sourceTree = "<group>"; };
+ 25403E41166A9DF300E13304 /* ZXAbstractExpandedDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAbstractExpandedDecoder.m; sourceTree = "<group>"; };
+ 25403E42166A9DF300E13304 /* ZXAI013103decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAI013103decoder.h; sourceTree = "<group>"; };
+ 25403E43166A9DF300E13304 /* ZXAI013103decoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAI013103decoder.m; sourceTree = "<group>"; };
+ 25403E44166A9DF300E13304 /* ZXAI01320xDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAI01320xDecoder.h; sourceTree = "<group>"; };
+ 25403E45166A9DF300E13304 /* ZXAI01320xDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAI01320xDecoder.m; sourceTree = "<group>"; };
+ 25403E46166A9DF300E13304 /* ZXAI01392xDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAI01392xDecoder.h; sourceTree = "<group>"; };
+ 25403E47166A9DF300E13304 /* ZXAI01392xDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAI01392xDecoder.m; sourceTree = "<group>"; };
+ 25403E48166A9DF300E13304 /* ZXAI01393xDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAI01393xDecoder.h; sourceTree = "<group>"; };
+ 25403E49166A9DF300E13304 /* ZXAI01393xDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAI01393xDecoder.m; sourceTree = "<group>"; };
+ 25403E4A166A9DF300E13304 /* ZXAI013x0x1xDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAI013x0x1xDecoder.h; sourceTree = "<group>"; };
+ 25403E4B166A9DF300E13304 /* ZXAI013x0x1xDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAI013x0x1xDecoder.m; sourceTree = "<group>"; };
+ 25403E4C166A9DF300E13304 /* ZXAI013x0xDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAI013x0xDecoder.h; sourceTree = "<group>"; };
+ 25403E4D166A9DF300E13304 /* ZXAI013x0xDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAI013x0xDecoder.m; sourceTree = "<group>"; };
+ 25403E4E166A9DF300E13304 /* ZXAI01AndOtherAIs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAI01AndOtherAIs.h; sourceTree = "<group>"; };
+ 25403E4F166A9DF300E13304 /* ZXAI01AndOtherAIs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAI01AndOtherAIs.m; sourceTree = "<group>"; };
+ 25403E50166A9DF300E13304 /* ZXAI01decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAI01decoder.h; sourceTree = "<group>"; };
+ 25403E51166A9DF300E13304 /* ZXAI01decoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAI01decoder.m; sourceTree = "<group>"; };
+ 25403E52166A9DF300E13304 /* ZXAI01weightDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAI01weightDecoder.h; sourceTree = "<group>"; };
+ 25403E53166A9DF300E13304 /* ZXAI01weightDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAI01weightDecoder.m; sourceTree = "<group>"; };
+ 25403E54166A9DF300E13304 /* ZXAnyAIDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAnyAIDecoder.h; sourceTree = "<group>"; };
+ 25403E55166A9DF300E13304 /* ZXAnyAIDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAnyAIDecoder.m; sourceTree = "<group>"; };
+ 25403E56166A9DF300E13304 /* ZXBlockParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBlockParsedResult.h; sourceTree = "<group>"; };
+ 25403E57166A9DF300E13304 /* ZXBlockParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBlockParsedResult.m; sourceTree = "<group>"; };
+ 25403E58166A9DF300E13304 /* ZXCurrentParsingState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCurrentParsingState.h; sourceTree = "<group>"; };
+ 25403E59166A9DF300E13304 /* ZXCurrentParsingState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCurrentParsingState.m; sourceTree = "<group>"; };
+ 25403E5A166A9DF300E13304 /* ZXDecodedChar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDecodedChar.h; sourceTree = "<group>"; };
+ 25403E5B166A9DF300E13304 /* ZXDecodedChar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDecodedChar.m; sourceTree = "<group>"; };
+ 25403E5C166A9DF300E13304 /* ZXDecodedInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDecodedInformation.h; sourceTree = "<group>"; };
+ 25403E5D166A9DF300E13304 /* ZXDecodedInformation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDecodedInformation.m; sourceTree = "<group>"; };
+ 25403E5E166A9DF300E13304 /* ZXDecodedNumeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDecodedNumeric.h; sourceTree = "<group>"; };
+ 25403E5F166A9DF300E13304 /* ZXDecodedNumeric.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDecodedNumeric.m; sourceTree = "<group>"; };
+ 25403E60166A9DF300E13304 /* ZXDecodedObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDecodedObject.h; sourceTree = "<group>"; };
+ 25403E61166A9DF300E13304 /* ZXDecodedObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDecodedObject.m; sourceTree = "<group>"; };
+ 25403E62166A9DF300E13304 /* ZXFieldParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXFieldParser.h; sourceTree = "<group>"; };
+ 25403E63166A9DF300E13304 /* ZXFieldParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXFieldParser.m; sourceTree = "<group>"; };
+ 25403E64166A9DF300E13304 /* ZXGeneralAppIdDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXGeneralAppIdDecoder.h; sourceTree = "<group>"; };
+ 25403E65166A9DF300E13304 /* ZXGeneralAppIdDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGeneralAppIdDecoder.m; sourceTree = "<group>"; };
+ 25403E66166A9DF300E13304 /* ZXBitArrayBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBitArrayBuilder.h; sourceTree = "<group>"; };
+ 25403E67166A9DF300E13304 /* ZXBitArrayBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBitArrayBuilder.m; sourceTree = "<group>"; };
+ 25403E68166A9DF300E13304 /* ZXExpandedPair.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXExpandedPair.h; sourceTree = "<group>"; };
+ 25403E69166A9DF300E13304 /* ZXExpandedPair.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXExpandedPair.m; sourceTree = "<group>"; };
+ 25403E6A166A9DF300E13304 /* ZXRSSExpandedReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXRSSExpandedReader.h; sourceTree = "<group>"; };
+ 25403E6B166A9DF300E13304 /* ZXRSSExpandedReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXRSSExpandedReader.m; sourceTree = "<group>"; };
+ 25403E6C166A9DF300E13304 /* ZXAbstractRSSReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAbstractRSSReader.h; sourceTree = "<group>"; };
+ 25403E6D166A9DF300E13304 /* ZXAbstractRSSReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAbstractRSSReader.m; sourceTree = "<group>"; };
+ 25403E6E166A9DF300E13304 /* ZXDataCharacter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataCharacter.h; sourceTree = "<group>"; };
+ 25403E6F166A9DF300E13304 /* ZXDataCharacter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataCharacter.m; sourceTree = "<group>"; };
+ 25403E70166A9DF300E13304 /* ZXPair.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPair.h; sourceTree = "<group>"; };
+ 25403E71166A9DF300E13304 /* ZXPair.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPair.m; sourceTree = "<group>"; };
+ 25403E72166A9DF300E13304 /* ZXRSS14Reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXRSS14Reader.h; sourceTree = "<group>"; };
+ 25403E73166A9DF300E13304 /* ZXRSS14Reader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXRSS14Reader.m; sourceTree = "<group>"; };
+ 25403E74166A9DF300E13304 /* ZXRSSFinderPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXRSSFinderPattern.h; sourceTree = "<group>"; };
+ 25403E75166A9DF300E13304 /* ZXRSSFinderPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXRSSFinderPattern.m; sourceTree = "<group>"; };
+ 25403E76166A9DF300E13304 /* ZXRSSUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXRSSUtils.h; sourceTree = "<group>"; };
+ 25403E77166A9DF300E13304 /* ZXRSSUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXRSSUtils.m; sourceTree = "<group>"; };
+ 25403E78166A9DF300E13304 /* ZXCodaBarReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCodaBarReader.h; sourceTree = "<group>"; };
+ 25403E79166A9DF300E13304 /* ZXCodaBarReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCodaBarReader.m; sourceTree = "<group>"; };
+ 25403E7A166A9DF300E13304 /* ZXCodaBarWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCodaBarWriter.h; sourceTree = "<group>"; };
+ 25403E7B166A9DF300E13304 /* ZXCodaBarWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCodaBarWriter.m; sourceTree = "<group>"; };
+ 25403E7C166A9DF300E13304 /* ZXCode128Reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCode128Reader.h; sourceTree = "<group>"; };
+ 25403E7D166A9DF300E13304 /* ZXCode128Reader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode128Reader.m; sourceTree = "<group>"; };
+ 25403E7E166A9DF300E13304 /* ZXCode128Writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCode128Writer.h; sourceTree = "<group>"; };
+ 25403E7F166A9DF300E13304 /* ZXCode128Writer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode128Writer.m; sourceTree = "<group>"; };
+ 25403E80166A9DF300E13304 /* ZXCode39Reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCode39Reader.h; sourceTree = "<group>"; };
+ 25403E81166A9DF300E13304 /* ZXCode39Reader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode39Reader.m; sourceTree = "<group>"; };
+ 25403E82166A9DF300E13304 /* ZXCode39Writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCode39Writer.h; sourceTree = "<group>"; };
+ 25403E83166A9DF300E13304 /* ZXCode39Writer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode39Writer.m; sourceTree = "<group>"; };
+ 25403E84166A9DF300E13304 /* ZXCode93Reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCode93Reader.h; sourceTree = "<group>"; };
+ 25403E85166A9DF300E13304 /* ZXCode93Reader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCode93Reader.m; sourceTree = "<group>"; };
+ 25403E86166A9DF300E13304 /* ZXEAN13Reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEAN13Reader.h; sourceTree = "<group>"; };
+ 25403E87166A9DF300E13304 /* ZXEAN13Reader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEAN13Reader.m; sourceTree = "<group>"; };
+ 25403E88166A9DF300E13304 /* ZXEAN13Writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEAN13Writer.h; sourceTree = "<group>"; };
+ 25403E89166A9DF300E13304 /* ZXEAN13Writer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEAN13Writer.m; sourceTree = "<group>"; };
+ 25403E8A166A9DF300E13304 /* ZXEAN8Reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEAN8Reader.h; sourceTree = "<group>"; };
+ 25403E8B166A9DF300E13304 /* ZXEAN8Reader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEAN8Reader.m; sourceTree = "<group>"; };
+ 25403E8C166A9DF300E13304 /* ZXEAN8Writer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEAN8Writer.h; sourceTree = "<group>"; };
+ 25403E8D166A9DF300E13304 /* ZXEAN8Writer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEAN8Writer.m; sourceTree = "<group>"; };
+ 25403E8E166A9DF300E13304 /* ZXEANManufacturerOrgSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEANManufacturerOrgSupport.h; sourceTree = "<group>"; };
+ 25403E8F166A9DF300E13304 /* ZXEANManufacturerOrgSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEANManufacturerOrgSupport.m; sourceTree = "<group>"; };
+ 25403E90166A9DF300E13304 /* ZXITFReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXITFReader.h; sourceTree = "<group>"; };
+ 25403E91166A9DF300E13304 /* ZXITFReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXITFReader.m; sourceTree = "<group>"; };
+ 25403E92166A9DF300E13304 /* ZXITFWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXITFWriter.h; sourceTree = "<group>"; };
+ 25403E93166A9DF300E13304 /* ZXITFWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXITFWriter.m; sourceTree = "<group>"; };
+ 25403E94166A9DF300E13304 /* ZXMultiFormatOneDReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMultiFormatOneDReader.h; sourceTree = "<group>"; };
+ 25403E95166A9DF300E13304 /* ZXMultiFormatOneDReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMultiFormatOneDReader.m; sourceTree = "<group>"; };
+ 25403E96166A9DF300E13304 /* ZXMultiFormatUPCEANReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMultiFormatUPCEANReader.h; sourceTree = "<group>"; };
+ 25403E97166A9DF300E13304 /* ZXMultiFormatUPCEANReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMultiFormatUPCEANReader.m; sourceTree = "<group>"; };
+ 25403E98166A9DF300E13304 /* ZXOneDimensionalCodeWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXOneDimensionalCodeWriter.h; sourceTree = "<group>"; };
+ 25403E99166A9DF300E13304 /* ZXOneDimensionalCodeWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXOneDimensionalCodeWriter.m; sourceTree = "<group>"; };
+ 25403E9A166A9DF300E13304 /* ZXOneDReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXOneDReader.h; sourceTree = "<group>"; };
+ 25403E9B166A9DF300E13304 /* ZXOneDReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXOneDReader.m; sourceTree = "<group>"; };
+ 25403E9C166A9DF300E13304 /* ZXUPCAReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCAReader.h; sourceTree = "<group>"; };
+ 25403E9D166A9DF300E13304 /* ZXUPCAReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCAReader.m; sourceTree = "<group>"; };
+ 25403E9E166A9DF300E13304 /* ZXUPCAWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCAWriter.h; sourceTree = "<group>"; };
+ 25403E9F166A9DF300E13304 /* ZXUPCAWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCAWriter.m; sourceTree = "<group>"; };
+ 25403EA0166A9DF300E13304 /* ZXUPCEANExtension2Support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCEANExtension2Support.h; sourceTree = "<group>"; };
+ 25403EA1166A9DF300E13304 /* ZXUPCEANExtension2Support.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCEANExtension2Support.m; sourceTree = "<group>"; };
+ 25403EA2166A9DF300E13304 /* ZXUPCEANExtension5Support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCEANExtension5Support.h; sourceTree = "<group>"; };
+ 25403EA3166A9DF300E13304 /* ZXUPCEANExtension5Support.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCEANExtension5Support.m; sourceTree = "<group>"; };
+ 25403EA4166A9DF300E13304 /* ZXUPCEANExtensionSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCEANExtensionSupport.h; sourceTree = "<group>"; };
+ 25403EA5166A9DF300E13304 /* ZXUPCEANExtensionSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCEANExtensionSupport.m; sourceTree = "<group>"; };
+ 25403EA6166A9DF300E13304 /* ZXUPCEANReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCEANReader.h; sourceTree = "<group>"; };
+ 25403EA7166A9DF300E13304 /* ZXUPCEANReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCEANReader.m; sourceTree = "<group>"; };
+ 25403EA8166A9DF300E13304 /* ZXUPCEANWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCEANWriter.h; sourceTree = "<group>"; };
+ 25403EA9166A9DF300E13304 /* ZXUPCEANWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCEANWriter.m; sourceTree = "<group>"; };
+ 25403EAA166A9DF300E13304 /* ZXUPCEReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCEReader.h; sourceTree = "<group>"; };
+ 25403EAB166A9DF300E13304 /* ZXUPCEReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCEReader.m; sourceTree = "<group>"; };
+ 25403F1B166A9EB500E13304 /* ZXModulusGF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXModulusGF.h; sourceTree = "<group>"; };
+ 25403F1C166A9EB500E13304 /* ZXModulusGF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXModulusGF.m; sourceTree = "<group>"; };
+ 25403F1D166A9EB500E13304 /* ZXModulusPoly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXModulusPoly.h; sourceTree = "<group>"; };
+ 25403F1E166A9EB500E13304 /* ZXModulusPoly.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXModulusPoly.m; sourceTree = "<group>"; };
+ 25403F1F166A9EB500E13304 /* ZXPDF417ECErrorCorrection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417ECErrorCorrection.h; sourceTree = "<group>"; };
+ 25403F20166A9EB500E13304 /* ZXPDF417ECErrorCorrection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417ECErrorCorrection.m; sourceTree = "<group>"; };
+ 25403F23166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417DecodedBitStreamParser.h; sourceTree = "<group>"; };
+ 25403F24166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417DecodedBitStreamParser.m; sourceTree = "<group>"; };
+ 25403F28166A9EB500E13304 /* ZXPDF417Detector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417Detector.h; sourceTree = "<group>"; };
+ 25403F29166A9EB500E13304 /* ZXPDF417Detector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417Detector.m; sourceTree = "<group>"; };
+ 25403F2B166A9EB500E13304 /* ZXBarcodeMatrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBarcodeMatrix.h; sourceTree = "<group>"; };
+ 25403F2C166A9EB500E13304 /* ZXBarcodeMatrix.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBarcodeMatrix.m; sourceTree = "<group>"; };
+ 25403F2D166A9EB500E13304 /* ZXBarcodeRow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBarcodeRow.h; sourceTree = "<group>"; };
+ 25403F2E166A9EB500E13304 /* ZXBarcodeRow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBarcodeRow.m; sourceTree = "<group>"; };
+ 25403F2F166A9EB500E13304 /* ZXCompaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCompaction.h; sourceTree = "<group>"; };
+ 25403F30166A9EB500E13304 /* ZXDimensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDimensions.h; sourceTree = "<group>"; };
+ 25403F31166A9EB500E13304 /* ZXDimensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDimensions.m; sourceTree = "<group>"; };
+ 25403F32166A9EB500E13304 /* ZXPDF417.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417.h; sourceTree = "<group>"; };
+ 25403F33166A9EB500E13304 /* ZXPDF417.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417.m; sourceTree = "<group>"; };
+ 25403F34166A9EB500E13304 /* ZXPDF417ErrorCorrection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417ErrorCorrection.h; sourceTree = "<group>"; };
+ 25403F35166A9EB500E13304 /* ZXPDF417ErrorCorrection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417ErrorCorrection.m; sourceTree = "<group>"; };
+ 25403F36166A9EB500E13304 /* ZXPDF417HighLevelEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417HighLevelEncoder.h; sourceTree = "<group>"; };
+ 25403F37166A9EB500E13304 /* ZXPDF417HighLevelEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417HighLevelEncoder.m; sourceTree = "<group>"; };
+ 25403F3A166A9EB500E13304 /* ZXPDF417Reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417Reader.h; sourceTree = "<group>"; };
+ 25403F3B166A9EB500E13304 /* ZXPDF417Reader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417Reader.m; sourceTree = "<group>"; };
+ 25403F5D166A9F2D00E13304 /* ZXDataMask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMask.h; sourceTree = "<group>"; };
+ 25403F5E166A9F2D00E13304 /* ZXDataMask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMask.m; sourceTree = "<group>"; };
+ 25403F5F166A9F2D00E13304 /* ZXErrorCorrectionLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXErrorCorrectionLevel.h; sourceTree = "<group>"; };
+ 25403F60166A9F2D00E13304 /* ZXErrorCorrectionLevel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXErrorCorrectionLevel.m; sourceTree = "<group>"; };
+ 25403F61166A9F2D00E13304 /* ZXFormatInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXFormatInformation.h; sourceTree = "<group>"; };
+ 25403F62166A9F2D00E13304 /* ZXFormatInformation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXFormatInformation.m; sourceTree = "<group>"; };
+ 25403F63166A9F2D00E13304 /* ZXMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMode.h; sourceTree = "<group>"; };
+ 25403F64166A9F2D00E13304 /* ZXMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMode.m; sourceTree = "<group>"; };
+ 25403F65166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeBitMatrixParser.h; sourceTree = "<group>"; };
+ 25403F66166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeBitMatrixParser.m; sourceTree = "<group>"; };
+ 25403F67166A9F2D00E13304 /* ZXQRCodeDataBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeDataBlock.h; sourceTree = "<group>"; };
+ 25403F68166A9F2D00E13304 /* ZXQRCodeDataBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeDataBlock.m; sourceTree = "<group>"; };
+ 25403F69166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeDecodedBitStreamParser.h; sourceTree = "<group>"; };
+ 25403F6A166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeDecodedBitStreamParser.m; sourceTree = "<group>"; };
+ 25403F6B166A9F2D00E13304 /* ZXQRCodeDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeDecoder.h; sourceTree = "<group>"; };
+ 25403F6C166A9F2D00E13304 /* ZXQRCodeDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeDecoder.m; sourceTree = "<group>"; };
+ 25403F6D166A9F2D00E13304 /* ZXQRCodeVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeVersion.h; sourceTree = "<group>"; };
+ 25403F6E166A9F2D00E13304 /* ZXQRCodeVersion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeVersion.m; sourceTree = "<group>"; };
+ 25403F70166A9F2D00E13304 /* ZXAlignmentPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAlignmentPattern.h; sourceTree = "<group>"; };
+ 25403F71166A9F2D00E13304 /* ZXAlignmentPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAlignmentPattern.m; sourceTree = "<group>"; };
+ 25403F72166A9F2D00E13304 /* ZXAlignmentPatternFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAlignmentPatternFinder.h; sourceTree = "<group>"; };
+ 25403F73166A9F2D00E13304 /* ZXAlignmentPatternFinder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAlignmentPatternFinder.m; sourceTree = "<group>"; };
+ 25403F74166A9F2D00E13304 /* ZXFinderPatternFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXFinderPatternFinder.h; sourceTree = "<group>"; };
+ 25403F75166A9F2D00E13304 /* ZXFinderPatternFinder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXFinderPatternFinder.m; sourceTree = "<group>"; };
+ 25403F76166A9F2D00E13304 /* ZXFinderPatternInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXFinderPatternInfo.h; sourceTree = "<group>"; };
+ 25403F77166A9F2D00E13304 /* ZXFinderPatternInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXFinderPatternInfo.m; sourceTree = "<group>"; };
+ 25403F78166A9F2D00E13304 /* ZXQRCodeDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeDetector.h; sourceTree = "<group>"; };
+ 25403F79166A9F2D00E13304 /* ZXQRCodeDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeDetector.m; sourceTree = "<group>"; };
+ 25403F7A166A9F2D00E13304 /* ZXQRCodeFinderPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeFinderPattern.h; sourceTree = "<group>"; };
+ 25403F7B166A9F2D00E13304 /* ZXQRCodeFinderPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeFinderPattern.m; sourceTree = "<group>"; };
+ 25403F7D166A9F2D00E13304 /* ZXBlockPair.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBlockPair.h; sourceTree = "<group>"; };
+ 25403F7E166A9F2D00E13304 /* ZXBlockPair.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBlockPair.m; sourceTree = "<group>"; };
+ 25403F7F166A9F2D00E13304 /* ZXByteMatrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXByteMatrix.h; sourceTree = "<group>"; };
+ 25403F80166A9F2D00E13304 /* ZXByteMatrix.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXByteMatrix.m; sourceTree = "<group>"; };
+ 25403F81166A9F2D00E13304 /* ZXEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEncoder.h; sourceTree = "<group>"; };
+ 25403F82166A9F2D00E13304 /* ZXEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEncoder.m; sourceTree = "<group>"; };
+ 25403F83166A9F2D00E13304 /* ZXMaskUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMaskUtil.h; sourceTree = "<group>"; };
+ 25403F84166A9F2D00E13304 /* ZXMaskUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMaskUtil.m; sourceTree = "<group>"; };
+ 25403F85166A9F2D00E13304 /* ZXMatrixUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMatrixUtil.h; sourceTree = "<group>"; };
+ 25403F86166A9F2D00E13304 /* ZXMatrixUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMatrixUtil.m; sourceTree = "<group>"; };
+ 25403F87166A9F2D00E13304 /* ZXQRCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCode.h; sourceTree = "<group>"; };
+ 25403F88166A9F2D00E13304 /* ZXQRCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCode.m; sourceTree = "<group>"; };
+ 25403F89166A9F2D00E13304 /* ZXQRCodeReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeReader.h; sourceTree = "<group>"; };
+ 25403F8A166A9F2D00E13304 /* ZXQRCodeReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeReader.m; sourceTree = "<group>"; };
+ 25403F8B166A9F2D00E13304 /* ZXQRCodeWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeWriter.h; sourceTree = "<group>"; };
+ 25403F8C166A9F2D00E13304 /* ZXQRCodeWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeWriter.m; sourceTree = "<group>"; };
+ 25403FBB166A9FFC00E13304 /* ZXBarcodeFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBarcodeFormat.h; sourceTree = "<group>"; };
+ 25403FBC166A9FFC00E13304 /* ZXBinarizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBinarizer.h; sourceTree = "<group>"; };
+ 25403FBD166A9FFC00E13304 /* ZXBinarizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBinarizer.m; sourceTree = "<group>"; };
+ 25403FBE166A9FFC00E13304 /* ZXBinaryBitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBinaryBitmap.h; sourceTree = "<group>"; };
+ 25403FBF166A9FFC00E13304 /* ZXBinaryBitmap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBinaryBitmap.m; sourceTree = "<group>"; };
+ 25403FC0166A9FFC00E13304 /* ZXDecodeHints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDecodeHints.h; sourceTree = "<group>"; };
+ 25403FC1166A9FFC00E13304 /* ZXDecodeHints.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDecodeHints.m; sourceTree = "<group>"; };
+ 25403FC2166A9FFC00E13304 /* ZXEncodeHints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEncodeHints.h; sourceTree = "<group>"; };
+ 25403FC3166A9FFC00E13304 /* ZXEncodeHints.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEncodeHints.m; sourceTree = "<group>"; };
+ 25403FC4166A9FFC00E13304 /* ZXErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXErrors.h; sourceTree = "<group>"; };
+ 25403FC5166A9FFC00E13304 /* ZXErrors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXErrors.m; sourceTree = "<group>"; };
+ 25403FD1166AA00700E13304 /* ZXLuminanceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXLuminanceSource.h; sourceTree = "<group>"; };
+ 25403FD2166AA00700E13304 /* ZXLuminanceSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXLuminanceSource.m; sourceTree = "<group>"; };
+ 25403FD3166AA00700E13304 /* ZXMultiFormatReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMultiFormatReader.h; sourceTree = "<group>"; };
+ 25403FD4166AA00700E13304 /* ZXMultiFormatReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMultiFormatReader.m; sourceTree = "<group>"; };
+ 25403FD5166AA00700E13304 /* ZXMultiFormatWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMultiFormatWriter.h; sourceTree = "<group>"; };
+ 25403FD6166AA00700E13304 /* ZXMultiFormatWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMultiFormatWriter.m; sourceTree = "<group>"; };
+ 25403FD7166AA00700E13304 /* ZXReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXReader.h; sourceTree = "<group>"; };
+ 25403FD8166AA00700E13304 /* ZXResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXResult.h; sourceTree = "<group>"; };
+ 25403FD9166AA00700E13304 /* ZXResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXResult.m; sourceTree = "<group>"; };
+ 25403FDA166AA00700E13304 /* ZXResultMetadataType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXResultMetadataType.h; sourceTree = "<group>"; };
+ 25403FDB166AA00700E13304 /* ZXResultPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXResultPoint.h; sourceTree = "<group>"; };
+ 25403FDC166AA00700E13304 /* ZXResultPoint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXResultPoint.m; sourceTree = "<group>"; };
+ 25403FDD166AA00700E13304 /* ZXResultPointCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXResultPointCallback.h; sourceTree = "<group>"; };
+ 25403FDE166AA00700E13304 /* ZXWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXWriter.h; sourceTree = "<group>"; };
+ 25403FEE166AA0F100E13304 /* AztecBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AztecBlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25403FEF166AA0F100E13304 /* AztecBlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AztecBlackBox1TestCase.m; sourceTree = "<group>"; };
+ 25403FF0166AA0F100E13304 /* AztecBlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AztecBlackBox2TestCase.h; sourceTree = "<group>"; };
+ 25403FF1166AA0F100E13304 /* AztecBlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AztecBlackBox2TestCase.m; sourceTree = "<group>"; };
+ 25403FF4166AA0F100E13304 /* ZXAddressBookParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXAddressBookParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25403FF5166AA0F100E13304 /* ZXAddressBookParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXAddressBookParsedResultTestCase.m; sourceTree = "<group>"; };
+ 25403FF6166AA0F100E13304 /* ZXCalendarParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCalendarParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25403FF7166AA0F100E13304 /* ZXCalendarParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCalendarParsedResultTestCase.m; sourceTree = "<group>"; };
+ 25403FF8166AA0F100E13304 /* ZXEmailAddressParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEmailAddressParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25403FF9166AA0F100E13304 /* ZXEmailAddressParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEmailAddressParsedResultTestCase.m; sourceTree = "<group>"; };
+ 25403FFA166AA0F100E13304 /* ZXExpandedProductParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXExpandedProductParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25403FFB166AA0F100E13304 /* ZXExpandedProductParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXExpandedProductParsedResultTestCase.m; sourceTree = "<group>"; };
+ 25403FFC166AA0F100E13304 /* ZXGeoParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXGeoParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25403FFD166AA0F100E13304 /* ZXGeoParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXGeoParsedResultTestCase.m; sourceTree = "<group>"; };
+ 25403FFE166AA0F100E13304 /* ZXISBNParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXISBNParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25403FFF166AA0F100E13304 /* ZXISBNParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXISBNParsedResultTestCase.m; sourceTree = "<group>"; };
+ 25404000166AA0F100E13304 /* ZXParsedReaderResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXParsedReaderResultTestCase.h; sourceTree = "<group>"; };
+ 25404001166AA0F100E13304 /* ZXParsedReaderResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXParsedReaderResultTestCase.m; sourceTree = "<group>"; };
+ 25404002166AA0F100E13304 /* ZXProductParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXProductParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25404003166AA0F100E13304 /* ZXProductParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXProductParsedResultTestCase.m; sourceTree = "<group>"; };
+ 25404004166AA0F100E13304 /* ZXSMSMMSParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXSMSMMSParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25404005166AA0F100E13304 /* ZXSMSMMSParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXSMSMMSParsedResultTestCase.m; sourceTree = "<group>"; };
+ 25404006166AA0F100E13304 /* ZXTelParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXTelParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25404007166AA0F100E13304 /* ZXTelParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXTelParsedResultTestCase.m; sourceTree = "<group>"; };
+ 25404008166AA0F100E13304 /* ZXURIParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXURIParsedResultTestCase.h; sourceTree = "<group>"; };
+ 25404009166AA0F100E13304 /* ZXURIParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXURIParsedResultTestCase.m; sourceTree = "<group>"; };
+ 2540400A166AA0F100E13304 /* ZXWifiParsedResultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXWifiParsedResultTestCase.h; sourceTree = "<group>"; };
+ 2540400B166AA0F100E13304 /* ZXWifiParsedResultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXWifiParsedResultTestCase.m; sourceTree = "<group>"; };
+ 2540400D166AA0F100E13304 /* AbstractBlackBoxTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractBlackBoxTestCase.h; sourceTree = "<group>"; };
+ 2540400E166AA0F100E13304 /* AbstractBlackBoxTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AbstractBlackBoxTestCase.m; sourceTree = "<group>"; };
+ 2540400F166AA0F100E13304 /* AbstractNegativeBlackBoxTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractNegativeBlackBoxTestCase.h; sourceTree = "<group>"; };
+ 25404010166AA0F100E13304 /* AbstractNegativeBlackBoxTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AbstractNegativeBlackBoxTestCase.m; sourceTree = "<group>"; };
+ 2540401A166AA0F100E13304 /* TestResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestResult.h; sourceTree = "<group>"; };
+ 2540401B166AA0F100E13304 /* TestResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestResult.m; sourceTree = "<group>"; };
+ 2540401C166AA0F100E13304 /* ZXBitArrayTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBitArrayTestCase.h; sourceTree = "<group>"; };
+ 2540401D166AA0F100E13304 /* ZXBitArrayTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBitArrayTestCase.m; sourceTree = "<group>"; };
+ 2540401E166AA0F100E13304 /* ZXBitMatrixTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBitMatrixTestCase.h; sourceTree = "<group>"; };
+ 2540401F166AA0F100E13304 /* ZXBitMatrixTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBitMatrixTestCase.m; sourceTree = "<group>"; };
+ 25404020166AA0F100E13304 /* ZXBitSourceBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBitSourceBuilder.h; sourceTree = "<group>"; };
+ 25404021166AA0F100E13304 /* ZXBitSourceBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBitSourceBuilder.m; sourceTree = "<group>"; };
+ 25404022166AA0F100E13304 /* ZXBitSourceTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBitSourceTestCase.h; sourceTree = "<group>"; };
+ 25404023166AA0F100E13304 /* ZXBitSourceTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBitSourceTestCase.m; sourceTree = "<group>"; };
+ 25404024166AA0F100E13304 /* ZXPerspectiveTransformTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPerspectiveTransformTestCase.h; sourceTree = "<group>"; };
+ 25404025166AA0F100E13304 /* ZXPerspectiveTransformTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPerspectiveTransformTestCase.m; sourceTree = "<group>"; };
+ 25404026166AA0F100E13304 /* ZXStringUtilsTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXStringUtilsTestCase.h; sourceTree = "<group>"; };
+ 25404027166AA0F100E13304 /* ZXStringUtilsTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXStringUtilsTestCase.m; sourceTree = "<group>"; };
+ 25404029166AA0F100E13304 /* DataMatrixBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataMatrixBlackBox1TestCase.h; sourceTree = "<group>"; };
+ 2540402A166AA0F100E13304 /* DataMatrixBlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataMatrixBlackBox1TestCase.m; sourceTree = "<group>"; };
+ 2540402B166AA0F100E13304 /* DataMatrixBlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataMatrixBlackBox2TestCase.h; sourceTree = "<group>"; };
+ 2540402C166AA0F100E13304 /* DataMatrixBlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataMatrixBlackBox2TestCase.m; sourceTree = "<group>"; };
+ 2540402E166AA0F100E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixDecodedBitStreamParserTestCase.h; sourceTree = "<group>"; };
+ 2540402F166AA0F100E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixDecodedBitStreamParserTestCase.m; sourceTree = "<group>"; };
+ 25404031166AA0F100E13304 /* FalsePositives2BlackBoxTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FalsePositives2BlackBoxTestCase.h; sourceTree = "<group>"; };
+ 25404032166AA0F100E13304 /* FalsePositives2BlackBoxTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FalsePositives2BlackBoxTestCase.m; sourceTree = "<group>"; };
+ 25404033166AA0F100E13304 /* FalsePositivesBlackBoxTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FalsePositivesBlackBoxTestCase.h; sourceTree = "<group>"; };
+ 25404034166AA0F100E13304 /* FalsePositivesBlackBoxTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FalsePositivesBlackBoxTestCase.m; sourceTree = "<group>"; };
+ 25404035166AA0F100E13304 /* PartialBlackBoxTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PartialBlackBoxTestCase.h; sourceTree = "<group>"; };
+ 25404036166AA0F100E13304 /* PartialBlackBoxTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PartialBlackBoxTestCase.m; sourceTree = "<group>"; };
+ 25404037166AA0F100E13304 /* UnsupportedBlackBoxTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnsupportedBlackBoxTestCase.h; sourceTree = "<group>"; };
+ 25404038166AA0F100E13304 /* UnsupportedBlackBoxTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UnsupportedBlackBoxTestCase.m; sourceTree = "<group>"; };
+ 2540403A166AA0F100E13304 /* CodabarBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodabarBlackBox1TestCase.h; sourceTree = "<group>"; };
+ 2540403B166AA0F100E13304 /* CodabarBlackbox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodabarBlackbox1TestCase.m; sourceTree = "<group>"; };
+ 2540403C166AA0F100E13304 /* Code128BlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Code128BlackBox1TestCase.h; sourceTree = "<group>"; };
+ 2540403D166AA0F100E13304 /* Code128BlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Code128BlackBox1TestCase.m; sourceTree = "<group>"; };
+ 2540403E166AA0F100E13304 /* Code128BlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Code128BlackBox2TestCase.h; sourceTree = "<group>"; };
+ 2540403F166AA0F100E13304 /* Code128BlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Code128BlackBox2TestCase.m; sourceTree = "<group>"; };
+ 25404040166AA0F100E13304 /* Code128BlackBox3TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Code128BlackBox3TestCase.h; sourceTree = "<group>"; };
+ 25404041166AA0F100E13304 /* Code128BlackBox3TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Code128BlackBox3TestCase.m; sourceTree = "<group>"; };
+ 25404042166AA0F100E13304 /* Code39BlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Code39BlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25404043166AA0F100E13304 /* Code39BlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Code39BlackBox1TestCase.m; sourceTree = "<group>"; };
+ 25404044166AA0F100E13304 /* Code39BlackBox3TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Code39BlackBox3TestCase.h; sourceTree = "<group>"; };
+ 25404045166AA0F100E13304 /* Code39BlackBox3TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Code39BlackBox3TestCase.m; sourceTree = "<group>"; };
+ 25404046166AA0F100E13304 /* Code39ExtendedBlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Code39ExtendedBlackBox2TestCase.h; sourceTree = "<group>"; };
+ 25404047166AA0F100E13304 /* Code39ExtendedBlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Code39ExtendedBlackBox2TestCase.m; sourceTree = "<group>"; };
+ 25404048166AA0F100E13304 /* Code93BlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Code93BlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25404049166AA0F100E13304 /* Code93BlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Code93BlackBox1TestCase.m; sourceTree = "<group>"; };
+ 2540404A166AA0F100E13304 /* EAN13BlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAN13BlackBox1TestCase.h; sourceTree = "<group>"; };
+ 2540404B166AA0F100E13304 /* EAN13BlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAN13BlackBox1TestCase.m; sourceTree = "<group>"; };
+ 2540404C166AA0F100E13304 /* EAN13BlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAN13BlackBox2TestCase.h; sourceTree = "<group>"; };
+ 2540404D166AA0F100E13304 /* EAN13BlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAN13BlackBox2TestCase.m; sourceTree = "<group>"; };
+ 2540404E166AA0F100E13304 /* EAN13BlackBox3TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAN13BlackBox3TestCase.h; sourceTree = "<group>"; };
+ 2540404F166AA0F100E13304 /* EAN13BlackBox3TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAN13BlackBox3TestCase.m; sourceTree = "<group>"; };
+ 25404050166AA0F100E13304 /* EAN13BlackBox4TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAN13BlackBox4TestCase.h; sourceTree = "<group>"; };
+ 25404051166AA0F100E13304 /* EAN13BlackBox4TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAN13BlackBox4TestCase.m; sourceTree = "<group>"; };
+ 25404052166AA0F100E13304 /* EAN13BlackBox5BlurryTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAN13BlackBox5BlurryTestCase.h; sourceTree = "<group>"; };
+ 25404053166AA0F100E13304 /* EAN13BlackBox5BlurryTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAN13BlackBox5BlurryTestCase.m; sourceTree = "<group>"; };
+ 25404054166AA0F100E13304 /* EAN8BlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EAN8BlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25404055166AA0F100E13304 /* EAN8BlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EAN8BlackBox1TestCase.m; sourceTree = "<group>"; };
+ 25404056166AA0F100E13304 /* ITFBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITFBlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25404057166AA0F100E13304 /* ITFBlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITFBlackBox1TestCase.m; sourceTree = "<group>"; };
+ 25404058166AA0F100E13304 /* ITFBlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ITFBlackBox2TestCase.h; sourceTree = "<group>"; };
+ 25404059166AA0F100E13304 /* ITFBlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ITFBlackBox2TestCase.m; sourceTree = "<group>"; };
+ 2540405D166AA0F100E13304 /* AbstractDecoderTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractDecoderTest.h; sourceTree = "<group>"; };
+ 2540405E166AA0F100E13304 /* AbstractDecoderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AbstractDecoderTest.m; sourceTree = "<group>"; };
+ 2540405F166AA0F100E13304 /* AI01_3103_DecoderTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AI01_3103_DecoderTest.h; sourceTree = "<group>"; };
+ 25404060166AA0F100E13304 /* AI01_3103_DecoderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AI01_3103_DecoderTest.m; sourceTree = "<group>"; };
+ 25404061166AA0F100E13304 /* AI01_3202_3203_DecoderTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AI01_3202_3203_DecoderTest.h; sourceTree = "<group>"; };
+ 25404062166AA0F100E13304 /* AI01_3202_3203_DecoderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AI01_3202_3203_DecoderTest.m; sourceTree = "<group>"; };
+ 25404063166AA0F100E13304 /* AI01_3X0X_1X_DecoderTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AI01_3X0X_1X_DecoderTest.h; sourceTree = "<group>"; };
+ 25404064166AA0F100E13304 /* AI01_3X0X_1X_DecoderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AI01_3X0X_1X_DecoderTest.m; sourceTree = "<group>"; };
+ 25404065166AA0F100E13304 /* AnyAIDecoderTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnyAIDecoderTest.h; sourceTree = "<group>"; };
+ 25404066166AA0F100E13304 /* AnyAIDecoderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnyAIDecoderTest.m; sourceTree = "<group>"; };
+ 25404067166AA0F100E13304 /* ZXFieldParserTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXFieldParserTest.h; sourceTree = "<group>"; };
+ 25404068166AA0F100E13304 /* ZXFieldParserTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXFieldParserTest.m; sourceTree = "<group>"; };
+ 25404069166AA0F100E13304 /* RSSExpandedBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedBlackBox1TestCase.h; sourceTree = "<group>"; };
+ 2540406A166AA0F100E13304 /* RSSExpandedBlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedBlackBox1TestCase.m; sourceTree = "<group>"; };
+ 2540406B166AA0F100E13304 /* RSSExpandedBlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedBlackBox2TestCase.h; sourceTree = "<group>"; };
+ 2540406C166AA0F100E13304 /* RSSExpandedBlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedBlackBox2TestCase.m; sourceTree = "<group>"; };
+ 2540406D166AA0F100E13304 /* RSSExpandedBlackBox3TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedBlackBox3TestCase.h; sourceTree = "<group>"; };
+ 2540406E166AA0F100E13304 /* RSSExpandedBlackBox3TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedBlackBox3TestCase.m; sourceTree = "<group>"; };
+ 2540406F166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedImage2binaryTestCase.h; sourceTree = "<group>"; };
+ 25404070166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedImage2binaryTestCase.m; sourceTree = "<group>"; };
+ 25404071166AA0F100E13304 /* RSSExpandedImage2resultTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedImage2resultTestCase.h; sourceTree = "<group>"; };
+ 25404072166AA0F100E13304 /* RSSExpandedImage2resultTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedImage2resultTestCase.m; sourceTree = "<group>"; };
+ 25404073166AA0F100E13304 /* RSSExpandedImage2stringTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedImage2stringTestCase.h; sourceTree = "<group>"; };
+ 25404074166AA0F100E13304 /* RSSExpandedImage2stringTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedImage2stringTestCase.m; sourceTree = "<group>"; };
+ 25404075166AA0F100E13304 /* RSSExpandedInternalTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedInternalTestCase.h; sourceTree = "<group>"; };
+ 25404076166AA0F100E13304 /* RSSExpandedInternalTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedInternalTestCase.m; sourceTree = "<group>"; };
+ 25404077166AA0F100E13304 /* ZXBinaryUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBinaryUtil.h; sourceTree = "<group>"; };
+ 25404078166AA0F100E13304 /* ZXBinaryUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBinaryUtil.m; sourceTree = "<group>"; };
+ 25404079166AA0F100E13304 /* ZXBinaryUtilTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBinaryUtilTest.h; sourceTree = "<group>"; };
+ 2540407A166AA0F100E13304 /* ZXBinaryUtilTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBinaryUtilTest.m; sourceTree = "<group>"; };
+ 2540407B166AA0F100E13304 /* ZXBitArrayBuilderTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXBitArrayBuilderTest.h; sourceTree = "<group>"; };
+ 2540407C166AA0F100E13304 /* ZXBitArrayBuilderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXBitArrayBuilderTest.m; sourceTree = "<group>"; };
+ 2540407D166AA0F100E13304 /* ZXExpandedInformationDecoderTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXExpandedInformationDecoderTest.h; sourceTree = "<group>"; };
+ 2540407E166AA0F100E13304 /* ZXExpandedInformationDecoderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXExpandedInformationDecoderTest.m; sourceTree = "<group>"; };
+ 2540407F166AA0F100E13304 /* RSS14BlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSS14BlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25404080166AA0F100E13304 /* RSS14BlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSS14BlackBox1TestCase.m; sourceTree = "<group>"; };
+ 25404081166AA0F100E13304 /* RSS14BlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSS14BlackBox2TestCase.h; sourceTree = "<group>"; };
+ 25404082166AA0F100E13304 /* RSS14BlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSS14BlackBox2TestCase.m; sourceTree = "<group>"; };
+ 25404083166AA0F100E13304 /* UPCABlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCABlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25404084166AA0F100E13304 /* UPCABlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCABlackBox1TestCase.m; sourceTree = "<group>"; };
+ 25404085166AA0F100E13304 /* UPCABlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCABlackBox2TestCase.h; sourceTree = "<group>"; };
+ 25404086166AA0F100E13304 /* UPCABlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCABlackBox2TestCase.m; sourceTree = "<group>"; };
+ 25404087166AA0F100E13304 /* UPCABlackBox3ReflectiveTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCABlackBox3ReflectiveTestCase.h; sourceTree = "<group>"; };
+ 25404088166AA0F100E13304 /* UPCABlackBox3ReflectiveTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCABlackBox3ReflectiveTestCase.m; sourceTree = "<group>"; };
+ 25404089166AA0F100E13304 /* UPCABlackBox4TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCABlackBox4TestCase.h; sourceTree = "<group>"; };
+ 2540408A166AA0F100E13304 /* UPCABlackBox4TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCABlackBox4TestCase.m; sourceTree = "<group>"; };
+ 2540408B166AA0F100E13304 /* UPCABlackBox5TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCABlackBox5TestCase.h; sourceTree = "<group>"; };
+ 2540408C166AA0F100E13304 /* UPCABlackBox5TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCABlackBox5TestCase.m; sourceTree = "<group>"; };
+ 2540408D166AA0F100E13304 /* UPCABlackBox6BlurryTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCABlackBox6BlurryTestCase.h; sourceTree = "<group>"; };
+ 2540408E166AA0F100E13304 /* UPCABlackBox6BlurryTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCABlackBox6BlurryTestCase.m; sourceTree = "<group>"; };
+ 2540408F166AA0F100E13304 /* UPCEANExtensionBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCEANExtensionBlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25404090166AA0F100E13304 /* UPCEANExtensionBlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCEANExtensionBlackBox1TestCase.m; sourceTree = "<group>"; };
+ 25404091166AA0F100E13304 /* UPCEBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCEBlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25404092166AA0F100E13304 /* UPCEBlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCEBlackBox1TestCase.m; sourceTree = "<group>"; };
+ 25404093166AA0F100E13304 /* UPCEBlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCEBlackBox2TestCase.h; sourceTree = "<group>"; };
+ 25404094166AA0F100E13304 /* UPCEBlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCEBlackBox2TestCase.m; sourceTree = "<group>"; };
+ 25404095166AA0F100E13304 /* UPCEBlackBox3ReflectiveTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UPCEBlackBox3ReflectiveTestCase.h; sourceTree = "<group>"; };
+ 25404096166AA0F100E13304 /* UPCEBlackBox3ReflectiveTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UPCEBlackBox3ReflectiveTestCase.m; sourceTree = "<group>"; };
+ 25404097166AA0F100E13304 /* ZXCodaBarWriterTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXCodaBarWriterTestCase.h; sourceTree = "<group>"; };
+ 25404098166AA0F100E13304 /* ZXCodaBarWriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXCodaBarWriterTestCase.m; sourceTree = "<group>"; };
+ 2540409B166AA0F100E13304 /* ZXEAN13WriterTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEAN13WriterTestCase.h; sourceTree = "<group>"; };
+ 2540409C166AA0F100E13304 /* ZXEAN13WriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEAN13WriterTestCase.m; sourceTree = "<group>"; };
+ 2540409D166AA0F100E13304 /* ZXEAN8WriterTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEAN8WriterTestCase.h; sourceTree = "<group>"; };
+ 2540409E166AA0F100E13304 /* ZXEAN8WriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEAN8WriterTestCase.m; sourceTree = "<group>"; };
+ 2540409F166AA0F100E13304 /* ZXEANManufacturerOrgSupportTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEANManufacturerOrgSupportTest.h; sourceTree = "<group>"; };
+ 254040A0166AA0F100E13304 /* ZXEANManufacturerOrgSupportTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEANManufacturerOrgSupportTest.m; sourceTree = "<group>"; };
+ 254040A3166AA0F100E13304 /* ZXUPCAWriterTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXUPCAWriterTestCase.h; sourceTree = "<group>"; };
+ 254040A4166AA0F100E13304 /* ZXUPCAWriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXUPCAWriterTestCase.m; sourceTree = "<group>"; };
+ 254040A8166AA0F100E13304 /* AbstractErrorCorrectionTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractErrorCorrectionTestCase.h; sourceTree = "<group>"; };
+ 254040A9166AA0F100E13304 /* AbstractErrorCorrectionTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AbstractErrorCorrectionTestCase.m; sourceTree = "<group>"; };
+ 254040AA166AA0F100E13304 /* ZXPDF417ECErrorCorrectionTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPDF417ECErrorCorrectionTestCase.h; sourceTree = "<group>"; };
+ 254040AB166AA0F100E13304 /* ZXPDF417ECErrorCorrectionTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPDF417ECErrorCorrectionTestCase.m; sourceTree = "<group>"; };
+ 254040AC166AA0F100E13304 /* PDF417BlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDF417BlackBox1TestCase.h; sourceTree = "<group>"; };
+ 254040AD166AA0F100E13304 /* PDF417BlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDF417BlackBox1TestCase.m; sourceTree = "<group>"; };
+ 254040AE166AA0F100E13304 /* PDF417BlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDF417BlackBox2TestCase.h; sourceTree = "<group>"; };
+ 254040AF166AA0F100E13304 /* PDF417BlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDF417BlackBox2TestCase.m; sourceTree = "<group>"; };
+ 254040B2166AA0F100E13304 /* ZXDataMaskTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMaskTestCase.h; sourceTree = "<group>"; };
+ 254040B3166AA0F100E13304 /* ZXDataMaskTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMaskTestCase.m; sourceTree = "<group>"; };
+ 254040B4166AA0F100E13304 /* ZXErrorCorrectionLevelTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXErrorCorrectionLevelTestCase.h; sourceTree = "<group>"; };
+ 254040B5166AA0F100E13304 /* ZXErrorCorrectionLevelTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXErrorCorrectionLevelTestCase.m; sourceTree = "<group>"; };
+ 254040B6166AA0F100E13304 /* ZXFormatInformationTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXFormatInformationTestCase.h; sourceTree = "<group>"; };
+ 254040B7166AA0F100E13304 /* ZXFormatInformationTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXFormatInformationTestCase.m; sourceTree = "<group>"; };
+ 254040B8166AA0F100E13304 /* ZXModeTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXModeTestCase.h; sourceTree = "<group>"; };
+ 254040B9166AA0F100E13304 /* ZXModeTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXModeTestCase.m; sourceTree = "<group>"; };
+ 254040BA166AA0F100E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeDecodedBitStreamParserTestCase.h; sourceTree = "<group>"; };
+ 254040BB166AA0F100E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeDecodedBitStreamParserTestCase.m; sourceTree = "<group>"; };
+ 254040BC166AA0F100E13304 /* ZXQRCodeVersionTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeVersionTestCase.h; sourceTree = "<group>"; };
+ 254040BD166AA0F100E13304 /* ZXQRCodeVersionTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeVersionTestCase.m; sourceTree = "<group>"; };
+ 254040BF166AA0F100E13304 /* BitVectorTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitVectorTestCase.h; sourceTree = "<group>"; };
+ 254040C0166AA0F100E13304 /* BitVectorTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitVectorTestCase.m; sourceTree = "<group>"; };
+ 254040C1166AA0F100E13304 /* ZXEncoderTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXEncoderTestCase.h; sourceTree = "<group>"; };
+ 254040C2166AA0F100E13304 /* ZXEncoderTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXEncoderTestCase.m; sourceTree = "<group>"; };
+ 254040C3166AA0F100E13304 /* ZXMaskUtilTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMaskUtilTestCase.h; sourceTree = "<group>"; };
+ 254040C4166AA0F100E13304 /* ZXMaskUtilTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMaskUtilTestCase.m; sourceTree = "<group>"; };
+ 254040C5166AA0F100E13304 /* ZXMatrixUtilTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXMatrixUtilTestCase.h; sourceTree = "<group>"; };
+ 254040C6166AA0F100E13304 /* ZXMatrixUtilTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXMatrixUtilTestCase.m; sourceTree = "<group>"; };
+ 254040C7166AA0F100E13304 /* ZXQRCodeTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeTestCase.h; sourceTree = "<group>"; };
+ 254040C8166AA0F100E13304 /* ZXQRCodeTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeTestCase.m; sourceTree = "<group>"; };
+ 254040C9166AA0F100E13304 /* QRCodeBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeBlackBox1TestCase.h; sourceTree = "<group>"; };
+ 254040CA166AA0F100E13304 /* QRCodeBlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRCodeBlackBox1TestCase.m; sourceTree = "<group>"; };
+ 254040CB166AA0F100E13304 /* QRCodeBlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeBlackBox2TestCase.h; sourceTree = "<group>"; };
+ 254040CC166AA0F100E13304 /* QRCodeBlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRCodeBlackBox2TestCase.m; sourceTree = "<group>"; };
+ 254040CD166AA0F100E13304 /* QRCodeBlackBox3TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeBlackBox3TestCase.h; sourceTree = "<group>"; };
+ 254040CE166AA0F100E13304 /* QRCodeBlackBox3TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRCodeBlackBox3TestCase.m; sourceTree = "<group>"; };
+ 254040CF166AA0F100E13304 /* QRCodeBlackBox4TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeBlackBox4TestCase.h; sourceTree = "<group>"; };
+ 254040D0166AA0F100E13304 /* QRCodeBlackBox4TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRCodeBlackBox4TestCase.m; sourceTree = "<group>"; };
+ 254040D1166AA0F100E13304 /* QRCodeBlackBox5TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeBlackBox5TestCase.h; sourceTree = "<group>"; };
+ 254040D2166AA0F100E13304 /* QRCodeBlackBox5TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRCodeBlackBox5TestCase.m; sourceTree = "<group>"; };
+ 254040D3166AA0F100E13304 /* QRCodeBlackBox6TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeBlackBox6TestCase.h; sourceTree = "<group>"; };
+ 254040D4166AA0F100E13304 /* QRCodeBlackBox6TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRCodeBlackBox6TestCase.m; sourceTree = "<group>"; };
+ 254040D5166AA0F100E13304 /* ZXQRCodeWriterTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXQRCodeWriterTestCase.h; sourceTree = "<group>"; };
+ 254040D6166AA0F100E13304 /* ZXQRCodeWriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXQRCodeWriterTestCase.m; sourceTree = "<group>"; };
+ 25404145166AA16200E13304 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 2540414E166AA33700E13304 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 2540415B166AA86900E13304 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
+ 2540415E166AAA2F00E13304 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
+ 25404166166AADAC00E13304 /* libZXingObjC-osx.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libZXingObjC-osx.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 25404178166AADAC00E13304 /* Unit Tests OS X.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Unit Tests OS X.octest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2540418D166AADEF00E13304 /* osx-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "osx-Prefix.pch"; sourceTree = SOURCE_ROOT; };
+ 25404387166AB8CF00E13304 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/CoreVideo.framework; sourceTree = DEVELOPER_DIR; };
+ 2540438F166AB91700E13304 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; };
+ 25404394166AB95700E13304 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/ApplicationServices.framework; sourceTree = DEVELOPER_DIR; };
+ 2540439E166ABA0A00E13304 /* ZXingObjC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ZXingObjC.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 254046FC166ABC1600E13304 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+ 25404700166ABC3F00E13304 /* QTKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/QTKit.framework; sourceTree = DEVELOPER_DIR; };
+ 2540471A166AC21000E13304 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
+ 2542996B16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXPlanarYUVLuminanceSource.h; sourceTree = "<group>"; };
+ 2542996C16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXPlanarYUVLuminanceSource.m; sourceTree = "<group>"; };
+ 2542997316D46E8400D4C045 /* ZXDimension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDimension.h; sourceTree = "<group>"; };
+ 2542997416D46E8400D4C045 /* ZXDimension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDimension.m; sourceTree = "<group>"; };
+ 2542997B16D470D600D4C045 /* ZXDataMatrixWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixWriter.h; sourceTree = "<group>"; };
+ 2542997C16D470D600D4C045 /* ZXDataMatrixWriter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixWriter.m; sourceTree = "<group>"; };
+ 2542998416D478A000D4C045 /* ZXASCIIEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXASCIIEncoder.h; path = encoder/ZXASCIIEncoder.h; sourceTree = "<group>"; };
+ 2542998516D478A000D4C045 /* ZXASCIIEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXASCIIEncoder.m; path = encoder/ZXASCIIEncoder.m; sourceTree = "<group>"; };
+ 2542998C16D478F800D4C045 /* ZXDataMatrixEncoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ZXDataMatrixEncoder.h; path = encoder/ZXDataMatrixEncoder.h; sourceTree = "<group>"; };
+ 2542998D16D47BBF00D4C045 /* ZXBase256Encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXBase256Encoder.h; path = encoder/ZXBase256Encoder.h; sourceTree = "<group>"; };
+ 2542998E16D47BBF00D4C045 /* ZXBase256Encoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXBase256Encoder.m; path = encoder/ZXBase256Encoder.m; sourceTree = "<group>"; };
+ 2542999716D482F800D4C045 /* ZXC40Encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXC40Encoder.h; path = encoder/ZXC40Encoder.h; sourceTree = "<group>"; };
+ 2542999816D482F800D4C045 /* ZXC40Encoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXC40Encoder.m; path = encoder/ZXC40Encoder.m; sourceTree = "<group>"; };
+ 2542999F16D4879800D4C045 /* ZXDataMatrixSymbolInfo144.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXDataMatrixSymbolInfo144.h; path = encoder/ZXDataMatrixSymbolInfo144.h; sourceTree = "<group>"; };
+ 254299A016D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXDataMatrixSymbolInfo144.m; path = encoder/ZXDataMatrixSymbolInfo144.m; sourceTree = "<group>"; };
+ 254299A716D4886000D4C045 /* ZXDefaultPlacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXDefaultPlacement.h; path = encoder/ZXDefaultPlacement.h; sourceTree = "<group>"; };
+ 254299A816D4886000D4C045 /* ZXDefaultPlacement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXDefaultPlacement.m; path = encoder/ZXDefaultPlacement.m; sourceTree = "<group>"; };
+ 254299AF16D4A36700D4C045 /* ZXEdifactEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXEdifactEncoder.h; path = encoder/ZXEdifactEncoder.h; sourceTree = "<group>"; };
+ 254299B016D4A36700D4C045 /* ZXEdifactEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXEdifactEncoder.m; path = encoder/ZXEdifactEncoder.m; sourceTree = "<group>"; };
+ 254299B716D4A5A900D4C045 /* ZXEncoderContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXEncoderContext.h; path = encoder/ZXEncoderContext.h; sourceTree = "<group>"; };
+ 254299B816D4A5A900D4C045 /* ZXEncoderContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXEncoderContext.m; path = encoder/ZXEncoderContext.m; sourceTree = "<group>"; };
+ 254299BF16D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXDataMatrixErrorCorrection.h; path = encoder/ZXDataMatrixErrorCorrection.h; sourceTree = "<group>"; };
+ 254299C016D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXDataMatrixErrorCorrection.m; path = encoder/ZXDataMatrixErrorCorrection.m; sourceTree = "<group>"; };
+ 254299C716D5BD5300D4C045 /* ZXHighLevelEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXHighLevelEncoder.h; path = encoder/ZXHighLevelEncoder.h; sourceTree = "<group>"; };
+ 254299C816D5BD5300D4C045 /* ZXHighLevelEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXHighLevelEncoder.m; path = encoder/ZXHighLevelEncoder.m; sourceTree = "<group>"; };
+ 254299CF16D5C96000D4C045 /* ZXSymbolInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXSymbolInfo.h; path = encoder/ZXSymbolInfo.h; sourceTree = "<group>"; };
+ 254299D016D5C96000D4C045 /* ZXSymbolInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXSymbolInfo.m; path = encoder/ZXSymbolInfo.m; sourceTree = "<group>"; };
+ 254299D716D5D11E00D4C045 /* ZXSymbolShapeHint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXSymbolShapeHint.h; path = encoder/ZXSymbolShapeHint.h; sourceTree = "<group>"; };
+ 254299DF16D5D24D00D4C045 /* ZXSymbolShapeHint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXSymbolShapeHint.m; path = encoder/ZXSymbolShapeHint.m; sourceTree = "<group>"; };
+ 254299E316D5D81800D4C045 /* ZXTextEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXTextEncoder.h; path = encoder/ZXTextEncoder.h; sourceTree = "<group>"; };
+ 254299E416D5D81900D4C045 /* ZXTextEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXTextEncoder.m; path = encoder/ZXTextEncoder.m; sourceTree = "<group>"; };
+ 254299EB16D5D94900D4C045 /* ZXX12Encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXX12Encoder.h; path = encoder/ZXX12Encoder.h; sourceTree = "<group>"; };
+ 254299EC16D5D94A00D4C045 /* ZXX12Encoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXX12Encoder.m; path = encoder/ZXX12Encoder.m; sourceTree = "<group>"; };
+ 254299F316D5DC8E00D4C045 /* ZXDataMatrixWriterTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXDataMatrixWriterTestCase.h; sourceTree = "<group>"; };
+ 254299F416D5DC8E00D4C045 /* ZXDataMatrixWriterTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXDataMatrixWriterTestCase.m; sourceTree = "<group>"; };
+ 254299FE16D5DFD800D4C045 /* ZXDebugPlacement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXDebugPlacement.h; path = encoder/ZXDebugPlacement.h; sourceTree = "<group>"; };
+ 254299FF16D5DFD800D4C045 /* ZXDebugPlacement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXDebugPlacement.m; path = encoder/ZXDebugPlacement.m; sourceTree = "<group>"; };
+ 25429A0216D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXDataMatrixErrorCorrectionTestCase.h; path = encoder/ZXDataMatrixErrorCorrectionTestCase.h; sourceTree = "<group>"; };
+ 25429A0316D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXDataMatrixErrorCorrectionTestCase.m; path = encoder/ZXDataMatrixErrorCorrectionTestCase.m; sourceTree = "<group>"; };
+ 25429A0616D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXHighLevelEncodeTestCase.h; path = encoder/ZXHighLevelEncodeTestCase.h; sourceTree = "<group>"; };
+ 25429A0716D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXHighLevelEncodeTestCase.m; path = encoder/ZXHighLevelEncodeTestCase.m; sourceTree = "<group>"; };
+ 25429A0A16D5F4E000D4C045 /* ZXPlacementTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXPlacementTestCase.h; path = encoder/ZXPlacementTestCase.h; sourceTree = "<group>"; };
+ 25429A0B16D5F4E000D4C045 /* ZXPlacementTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXPlacementTestCase.m; path = encoder/ZXPlacementTestCase.m; sourceTree = "<group>"; };
+ 25429A0E16D5F66D00D4C045 /* ZXSymbolInfoTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ZXSymbolInfoTestCase.h; path = encoder/ZXSymbolInfoTestCase.h; sourceTree = "<group>"; };
+ 25429A0F16D5F66D00D4C045 /* ZXSymbolInfoTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ZXSymbolInfoTestCase.m; path = encoder/ZXSymbolInfoTestCase.m; sourceTree = "<group>"; };
+ 25B582971816F7B00013634A /* PDF417BlackBox4TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDF417BlackBox4TestCase.h; sourceTree = "<group>"; };
+ 25B582981816F7B00013634A /* PDF417BlackBox4TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDF417BlackBox4TestCase.m; sourceTree = "<group>"; };
+ 25E9E91717FA555400364861 /* PDF417BlackBox3TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDF417BlackBox3TestCase.h; sourceTree = "<group>"; };
+ 25E9E91817FA555400364861 /* PDF417BlackBox3TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PDF417BlackBox3TestCase.m; sourceTree = "<group>"; };
+ 25FE5D3116D0AFED00826CDB /* ZXExpandedRow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXExpandedRow.h; sourceTree = "<group>"; };
+ 25FE5D3216D0AFED00826CDB /* ZXExpandedRow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZXExpandedRow.m; sourceTree = "<group>"; };
+ 25FE5D3816D0B82F00826CDB /* RSSExpandedStackedBlackBox1TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedStackedBlackBox1TestCase.h; sourceTree = "<group>"; };
+ 25FE5D3916D0B82F00826CDB /* RSSExpandedStackedBlackBox1TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedStackedBlackBox1TestCase.m; sourceTree = "<group>"; };
+ 25FE5D3A16D0B83000826CDB /* RSSExpandedStackedBlackBox2TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedStackedBlackBox2TestCase.h; sourceTree = "<group>"; };
+ 25FE5D3B16D0B83000826CDB /* RSSExpandedStackedBlackBox2TestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedStackedBlackBox2TestCase.m; sourceTree = "<group>"; };
+ 25FE5D3E16D0B84C00826CDB /* RSSExpandedStackedInternalTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSSExpandedStackedInternalTestCase.h; sourceTree = "<group>"; };
+ 25FE5D3F16D0B84C00826CDB /* RSSExpandedStackedInternalTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RSSExpandedStackedInternalTestCase.m; sourceTree = "<group>"; };
+ 25FE5D4116D0B8B100826CDB /* TestCaseUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestCaseUtil.h; sourceTree = "<group>"; };
+ 25FE5D4216D0B8B200826CDB /* TestCaseUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestCaseUtil.m; sourceTree = "<group>"; };
+ 25FE5D4416D1997C00826CDB /* Resources */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Resources; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 024958681898641B003D4E6A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 024958691898641B003D4E6A /* AVFoundation.framework in Frameworks */,
+ 0249586A1898641B003D4E6A /* CoreGraphics.framework in Frameworks */,
+ 0249586B1898641B003D4E6A /* CoreVideo.framework in Frameworks */,
+ 0249586C1898641B003D4E6A /* Foundation.framework in Frameworks */,
+ 0249586D1898641B003D4E6A /* ImageIO.framework in Frameworks */,
+ 0249586E1898641B003D4E6A /* SenTestingKit.framework in Frameworks */,
+ 0249586F1898641B003D4E6A /* UIKit.framework in Frameworks */,
+ 024958701898641B003D4E6A /* libZXingObjC-iOS.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 02D813E8189864C70081721D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 02D813E9189864C70081721D /* QTKit.framework in Frameworks */,
+ 02D813EA189864C70081721D /* QuartzCore.framework in Frameworks */,
+ 02D813EB189864C70081721D /* ApplicationServices.framework in Frameworks */,
+ 02D813EC189864C70081721D /* CoreVideo.framework in Frameworks */,
+ 02D813ED189864C70081721D /* SenTestingKit.framework in Frameworks */,
+ 02D813EE189864C70081721D /* libZXingObjC-osx.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25403CB0166A96FA00E13304 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2540471B166AC21000E13304 /* AVFoundation.framework in Frameworks */,
+ 2540414F166AA33700E13304 /* CoreGraphics.framework in Frameworks */,
+ 25404161166AAAD900E13304 /* CoreVideo.framework in Frameworks */,
+ 25403CB7166A96FA00E13304 /* Foundation.framework in Frameworks */,
+ 2540415C166AA86900E13304 /* ImageIO.framework in Frameworks */,
+ 25404146166AA16200E13304 /* UIKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25403CC0166A96FA00E13304 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2540471C166AC21D00E13304 /* AVFoundation.framework in Frameworks */,
+ 25404150166AA33E00E13304 /* CoreGraphics.framework in Frameworks */,
+ 2540415F166AAA2F00E13304 /* CoreVideo.framework in Frameworks */,
+ 25403CC9166A96FA00E13304 /* Foundation.framework in Frameworks */,
+ 2540415D166AA87000E13304 /* ImageIO.framework in Frameworks */,
+ 25403CC6166A96FA00E13304 /* SenTestingKit.framework in Frameworks */,
+ 25404160166AAAAB00E13304 /* UIKit.framework in Frameworks */,
+ 25403CCC166A96FA00E13304 /* libZXingObjC-iOS.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25404163166AADAC00E13304 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 25404395166AB95700E13304 /* ApplicationServices.framework in Frameworks */,
+ 25404390166AB91700E13304 /* Cocoa.framework in Frameworks */,
+ 25404701166ABC3F00E13304 /* QTKit.framework in Frameworks */,
+ 254046FF166ABC2600E13304 /* QuartzCore.framework in Frameworks */,
+ 25404388166AB8CF00E13304 /* CoreVideo.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25404174166AADAC00E13304 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 25404702166ABC4600E13304 /* QTKit.framework in Frameworks */,
+ 254046FE166ABC2100E13304 /* QuartzCore.framework in Frameworks */,
+ 25404397166AB96000E13304 /* ApplicationServices.framework in Frameworks */,
+ 25404389166AB8D600E13304 /* CoreVideo.framework in Frameworks */,
+ 25404179166AADAC00E13304 /* SenTestingKit.framework in Frameworks */,
+ 2540417D166AADAC00E13304 /* libZXingObjC-osx.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 2540439A166ABA0A00E13304 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 25404703166ABC4B00E13304 /* QTKit.framework in Frameworks */,
+ 254046FD166ABC1600E13304 /* QuartzCore.framework in Frameworks */,
+ 254043B7166ABA7800E13304 /* CoreVideo.framework in Frameworks */,
+ 254043B6166ABA7500E13304 /* ApplicationServices.framework in Frameworks */,
+ 254043B5166ABA6B00E13304 /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 02BDA2ED1803109E0039B326 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 02BDA2EE1803109E0039B326 /* Tests-iOS-Prefix.pch */,
+ 02BDA2EF1803109E0039B326 /* Tests-OSX-Prefix.pch */,
+ 02BDA2F01803109E0039B326 /* ZXingObjCTests-Info.plist */,
+ );
+ path = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ 2504D9CC16FFD2CC00DF8882 /* encoder */ = {
+ isa = PBXGroup;
+ children = (
+ 2504D9CD16FFD2E200DF8882 /* ZXAztecCode.h */,
+ 2504D9CE16FFD2E200DF8882 /* ZXAztecCode.m */,
+ 2504D9DA16FFD4CD00DF8882 /* ZXAztecEncoder.h */,
+ 2504D9DB16FFD4CD00DF8882 /* ZXAztecEncoder.m */,
+ );
+ name = encoder;
+ sourceTree = "<group>";
+ };
+ 2504D9E316FFF25E00DF8882 /* encoder */ = {
+ isa = PBXGroup;
+ children = (
+ 2504D9E416FFF27C00DF8882 /* ZXAztecEncoderTest.h */,
+ 2504D9E516FFF27C00DF8882 /* ZXAztecEncoderTest.m */,
+ );
+ name = encoder;
+ sourceTree = "<group>";
+ };
+ 25389B8F18010D7A00772392 /* detector */ = {
+ isa = PBXGroup;
+ children = (
+ 25389B9018010D9B00772392 /* ZXPDF417DetectorTest.h */,
+ 25389B9118010D9B00772392 /* ZXPDF417DetectorTest.m */,
+ );
+ name = detector;
+ sourceTree = "<group>";
+ };
+ 25403CA8166A96F900E13304 = {
+ isa = PBXGroup;
+ children = (
+ 25403CB8166A96FA00E13304 /* ZXingObjC */,
+ 25403CCD166A96FA00E13304 /* ZXingObjCTests */,
+ 25403CB9166A96FA00E13304 /* Supporting Files */,
+ 25403CB5166A96FA00E13304 /* iOS Frameworks */,
+ 2540438A166AB8EA00E13304 /* OS X Frameworks */,
+ 25403CB4166A96FA00E13304 /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ 25403CB4166A96FA00E13304 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 25403CB3166A96FA00E13304 /* libZXingObjC-iOS.a */,
+ 25403CC4166A96FA00E13304 /* Unit Tests iOS.octest */,
+ 25404166166AADAC00E13304 /* libZXingObjC-osx.a */,
+ 25404178166AADAC00E13304 /* Unit Tests OS X.octest */,
+ 2540439E166ABA0A00E13304 /* ZXingObjC.framework */,
+ 024958781898641B003D4E6A /* ZXingObjCTests-iOS copy.octest */,
+ 02D813F6189864C70081721D /* ZXingObjCTests-osx copy.octest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 25403CB5166A96FA00E13304 /* iOS Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 2540471A166AC21000E13304 /* AVFoundation.framework */,
+ 2540414E166AA33700E13304 /* CoreGraphics.framework */,
+ 2540415E166AAA2F00E13304 /* CoreVideo.framework */,
+ 25403CB6166A96FA00E13304 /* Foundation.framework */,
+ 2540415B166AA86900E13304 /* ImageIO.framework */,
+ 25403CC5166A96FA00E13304 /* SenTestingKit.framework */,
+ 25404145166AA16200E13304 /* UIKit.framework */,
+ );
+ name = "iOS Frameworks";
+ sourceTree = "<group>";
+ };
+ 25403CB8166A96FA00E13304 /* ZXingObjC */ = {
+ isa = PBXGroup;
+ children = (
+ 25403CEC166A999D00E13304 /* aztec */,
+ 25403CFF166A9A0800E13304 /* client */,
+ 25403D9F166A9C0E00E13304 /* common */,
+ 25403DF2166A9CCB00E13304 /* datamatrix */,
+ 25403E11166A9D4B00E13304 /* maxicode */,
+ 25403E23166A9D8B00E13304 /* multi */,
+ 25403E3C166A9DF300E13304 /* oned */,
+ 25403F18166A9EB500E13304 /* pdf417 */,
+ 25403F5B166A9F2D00E13304 /* qrcode */,
+ 25403FBB166A9FFC00E13304 /* ZXBarcodeFormat.h */,
+ 25403FBC166A9FFC00E13304 /* ZXBinarizer.h */,
+ 25403FBD166A9FFC00E13304 /* ZXBinarizer.m */,
+ 25403FBE166A9FFC00E13304 /* ZXBinaryBitmap.h */,
+ 25403FBF166A9FFC00E13304 /* ZXBinaryBitmap.m */,
+ 25403FC0166A9FFC00E13304 /* ZXDecodeHints.h */,
+ 25403FC1166A9FFC00E13304 /* ZXDecodeHints.m */,
+ 2542997316D46E8400D4C045 /* ZXDimension.h */,
+ 2542997416D46E8400D4C045 /* ZXDimension.m */,
+ 25403FC2166A9FFC00E13304 /* ZXEncodeHints.h */,
+ 25403FC3166A9FFC00E13304 /* ZXEncodeHints.m */,
+ 25403FC4166A9FFC00E13304 /* ZXErrors.h */,
+ 25403FC5166A9FFC00E13304 /* ZXErrors.m */,
+ 25403CBB166A96FA00E13304 /* ZXingObjC.h */,
+ 2504D4C416F698AA00DF8882 /* ZXInvertedLuminanceSource.h */,
+ 2504D4C516F698AA00DF8882 /* ZXInvertedLuminanceSource.m */,
+ 25403FD1166AA00700E13304 /* ZXLuminanceSource.h */,
+ 25403FD2166AA00700E13304 /* ZXLuminanceSource.m */,
+ 25403FD3166AA00700E13304 /* ZXMultiFormatReader.h */,
+ 25403FD4166AA00700E13304 /* ZXMultiFormatReader.m */,
+ 25403FD5166AA00700E13304 /* ZXMultiFormatWriter.h */,
+ 25403FD6166AA00700E13304 /* ZXMultiFormatWriter.m */,
+ 2542996B16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.h */,
+ 2542996C16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.m */,
+ 25403FD7166AA00700E13304 /* ZXReader.h */,
+ 25403FD8166AA00700E13304 /* ZXResult.h */,
+ 25403FD9166AA00700E13304 /* ZXResult.m */,
+ 25403FDA166AA00700E13304 /* ZXResultMetadataType.h */,
+ 25403FDB166AA00700E13304 /* ZXResultPoint.h */,
+ 25403FDC166AA00700E13304 /* ZXResultPoint.m */,
+ 25403FDD166AA00700E13304 /* ZXResultPointCallback.h */,
+ 251FCDE916CC8F53000C27E5 /* ZXRGBLuminanceSource.h */,
+ 251FCDEA16CC8F53000C27E5 /* ZXRGBLuminanceSource.m */,
+ 25403FDE166AA00700E13304 /* ZXWriter.h */,
+ );
+ path = ZXingObjC;
+ sourceTree = "<group>";
+ };
+ 25403CB9166A96FA00E13304 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 25403CE1166A979700E13304 /* ios-Prefix.pch */,
+ 2540418D166AADEF00E13304 /* osx-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ path = ZXingObjC;
+ sourceTree = "<group>";
+ };
+ 25403CCD166A96FA00E13304 /* ZXingObjCTests */ = {
+ isa = PBXGroup;
+ children = (
+ 25403FED166AA0F100E13304 /* aztec */,
+ 25403FF2166AA0F100E13304 /* client */,
+ 2540400C166AA0F100E13304 /* common */,
+ 25404028166AA0F100E13304 /* datamatrix */,
+ 25404030166AA0F100E13304 /* negative */,
+ 25404039166AA0F100E13304 /* oned */,
+ 254040A5166AA0F100E13304 /* pdf417 */,
+ 254040B0166AA0F100E13304 /* qrcode */,
+ 25FE5D4416D1997C00826CDB /* Resources */,
+ 02BDA2ED1803109E0039B326 /* Supporting Files */,
+ );
+ path = ZXingObjCTests;
+ sourceTree = "<group>";
+ };
+ 25403CEC166A999D00E13304 /* aztec */ = {
+ isa = PBXGroup;
+ children = (
+ 25403CED166A999D00E13304 /* decoder */,
+ 25403CF0166A999D00E13304 /* detector */,
+ 2504D9CC16FFD2CC00DF8882 /* encoder */,
+ 25403CF3166A999D00E13304 /* ZXAztecDetectorResult.h */,
+ 25403CF4166A999D00E13304 /* ZXAztecDetectorResult.m */,
+ 25403CF5166A999D00E13304 /* ZXAztecReader.h */,
+ 25403CF6166A999D00E13304 /* ZXAztecReader.m */,
+ 2519AB3217FD1EC000A71C45 /* ZXAztecWriter.h */,
+ 2519AB3317FD1EC000A71C45 /* ZXAztecWriter.m */,
+ );
+ path = aztec;
+ sourceTree = "<group>";
+ };
+ 25403CED166A999D00E13304 /* decoder */ = {
+ isa = PBXGroup;
+ children = (
+ 25403CEE166A999D00E13304 /* ZXAztecDecoder.h */,
+ 25403CEF166A999D00E13304 /* ZXAztecDecoder.m */,
+ );
+ path = decoder;
+ sourceTree = "<group>";
+ };
+ 25403CF0166A999D00E13304 /* detector */ = {
+ isa = PBXGroup;
+ children = (
+ 25403CF1166A999D00E13304 /* ZXAztecDetector.h */,
+ 25403CF2166A999D00E13304 /* ZXAztecDetector.m */,
+ );
+ path = detector;
+ sourceTree = "<group>";
+ };
+ 25403CFF166A9A0800E13304 /* client */ = {
+ isa = PBXGroup;
+ children = (
+ 25403D00166A9A0800E13304 /* result */,
+ 25403D46166A9A0800E13304 /* ZXCapture.h */,
+ 25403D47166A9A0800E13304 /* ZXCapture.m */,
+ 25403D48166A9A0800E13304 /* ZXCaptureDelegate.h */,
+ 25403D49166A9A0800E13304 /* ZXCaptureView.h */,
+ 25403D4A166A9A0800E13304 /* ZXCaptureView.m */,
+ 25403D4B166A9A0800E13304 /* ZXCGImageLuminanceSource.h */,
+ 25403D4C166A9A0800E13304 /* ZXCGImageLuminanceSource.m */,
+ 25403D4D166A9A0800E13304 /* ZXImage.h */,
+ 25403D4E166A9A0800E13304 /* ZXImage.m */,
+ 25403D4F166A9A0800E13304 /* ZXView.h */,
+ );
+ name = client;
+ path = ZXingObjC/client;
+ sourceTree = SOURCE_ROOT;
+ };
+ 25403D00166A9A0800E13304 /* result */ = {
+ isa = PBXGroup;
+ children = (
+ 25403D01166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.h */,
+ 25403D02166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.m */,
+ 25403D03166A9A0800E13304 /* ZXAddressBookAUResultParser.h */,
+ 25403D04166A9A0800E13304 /* ZXAddressBookAUResultParser.m */,
+ 25403D05166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.h */,
+ 25403D06166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.m */,
+ 25403D07166A9A0800E13304 /* ZXAddressBookParsedResult.h */,
+ 25403D08166A9A0800E13304 /* ZXAddressBookParsedResult.m */,
+ 25403D09166A9A0800E13304 /* ZXBizcardResultParser.h */,
+ 25403D0A166A9A0800E13304 /* ZXBizcardResultParser.m */,
+ 25403D0B166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.h */,
+ 25403D0C166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.m */,
+ 25403D0D166A9A0800E13304 /* ZXCalendarParsedResult.h */,
+ 25403D0E166A9A0800E13304 /* ZXCalendarParsedResult.m */,
+ 25403D0F166A9A0800E13304 /* ZXEmailAddressParsedResult.h */,
+ 25403D10166A9A0800E13304 /* ZXEmailAddressParsedResult.m */,
+ 25403D11166A9A0800E13304 /* ZXEmailAddressResultParser.h */,
+ 25403D12166A9A0800E13304 /* ZXEmailAddressResultParser.m */,
+ 25403D13166A9A0800E13304 /* ZXEmailDoCoMoResultParser.h */,
+ 25403D14166A9A0800E13304 /* ZXEmailDoCoMoResultParser.m */,
+ 25403D15166A9A0800E13304 /* ZXExpandedProductParsedResult.h */,
+ 25403D16166A9A0800E13304 /* ZXExpandedProductParsedResult.m */,
+ 25403D17166A9A0800E13304 /* ZXExpandedProductResultParser.h */,
+ 25403D18166A9A0800E13304 /* ZXExpandedProductResultParser.m */,
+ 25403D19166A9A0800E13304 /* ZXGeoParsedResult.h */,
+ 25403D1A166A9A0800E13304 /* ZXGeoParsedResult.m */,
+ 25403D1B166A9A0800E13304 /* ZXGeoResultParser.h */,
+ 25403D1C166A9A0800E13304 /* ZXGeoResultParser.m */,
+ 25403D1D166A9A0800E13304 /* ZXISBNParsedResult.h */,
+ 25403D1E166A9A0800E13304 /* ZXISBNParsedResult.m */,
+ 25403D1F166A9A0800E13304 /* ZXISBNResultParser.h */,
+ 25403D20166A9A0800E13304 /* ZXISBNResultParser.m */,
+ 25403D21166A9A0800E13304 /* ZXParsedResult.h */,
+ 25403D22166A9A0800E13304 /* ZXParsedResult.m */,
+ 25403D23166A9A0800E13304 /* ZXParsedResultType.h */,
+ 25403D24166A9A0800E13304 /* ZXProductParsedResult.h */,
+ 25403D25166A9A0800E13304 /* ZXProductParsedResult.m */,
+ 25403D26166A9A0800E13304 /* ZXProductResultParser.h */,
+ 25403D27166A9A0800E13304 /* ZXProductResultParser.m */,
+ 25403D28166A9A0800E13304 /* ZXResultParser.h */,
+ 25403D29166A9A0800E13304 /* ZXResultParser.m */,
+ 25403D2A166A9A0800E13304 /* ZXSMSMMSResultParser.h */,
+ 25403D2B166A9A0800E13304 /* ZXSMSMMSResultParser.m */,
+ 25403D2C166A9A0800E13304 /* ZXSMSParsedResult.h */,
+ 25403D2D166A9A0800E13304 /* ZXSMSParsedResult.m */,
+ 25403D2E166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.h */,
+ 25403D2F166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.m */,
+ 25403D30166A9A0800E13304 /* ZXSMTPResultParser.h */,
+ 25403D31166A9A0800E13304 /* ZXSMTPResultParser.m */,
+ 25403D32166A9A0800E13304 /* ZXTelParsedResult.h */,
+ 25403D33166A9A0800E13304 /* ZXTelParsedResult.m */,
+ 25403D34166A9A0800E13304 /* ZXTelResultParser.h */,
+ 25403D35166A9A0800E13304 /* ZXTelResultParser.m */,
+ 25403D36166A9A0800E13304 /* ZXTextParsedResult.h */,
+ 25403D37166A9A0800E13304 /* ZXTextParsedResult.m */,
+ 25403D38166A9A0800E13304 /* ZXURIParsedResult.h */,
+ 25403D39166A9A0800E13304 /* ZXURIParsedResult.m */,
+ 25403D3A166A9A0800E13304 /* ZXURIResultParser.h */,
+ 25403D3B166A9A0800E13304 /* ZXURIResultParser.m */,
+ 25403D3C166A9A0800E13304 /* ZXURLTOResultParser.h */,
+ 25403D3D166A9A0800E13304 /* ZXURLTOResultParser.m */,
+ 25403D3E166A9A0800E13304 /* ZXVCardResultParser.h */,
+ 25403D3F166A9A0800E13304 /* ZXVCardResultParser.m */,
+ 25403D40166A9A0800E13304 /* ZXVEventResultParser.h */,
+ 25403D41166A9A0800E13304 /* ZXVEventResultParser.m */,
+ 25403D42166A9A0800E13304 /* ZXWifiParsedResult.h */,
+ 25403D43166A9A0800E13304 /* ZXWifiParsedResult.m */,
+ 25403D44166A9A0800E13304 /* ZXWifiResultParser.h */,
+ 25403D45166A9A0800E13304 /* ZXWifiResultParser.m */,
+ );
+ path = result;
+ sourceTree = "<group>";
+ };
+ 25403D9F166A9C0E00E13304 /* common */ = {
+ isa = PBXGroup;
+ children = (
+ 25403DA0166A9C0E00E13304 /* detector */,
+ 25403DA7166A9C0E00E13304 /* reedsolomon */,
+ 25403DB0166A9C0E00E13304 /* ZXBitArray.h */,
+ 25403DB1166A9C0E00E13304 /* ZXBitArray.m */,
+ 25403DB2166A9C0E00E13304 /* ZXBitMatrix.h */,
+ 25403DB3166A9C0E00E13304 /* ZXBitMatrix.m */,
+ 25403DB4166A9C0E00E13304 /* ZXBitSource.h */,
+ 25403DB5166A9C0E00E13304 /* ZXBitSource.m */,
+ 25403DB6166A9C0E00E13304 /* ZXCharacterSetECI.h */,
+ 25403DB7166A9C0E00E13304 /* ZXCharacterSetECI.m */,
+ 25403DB8166A9C0E00E13304 /* ZXDecoderResult.h */,
+ 25403DB9166A9C0E00E13304 /* ZXDecoderResult.m */,
+ 25403DBA166A9C0E00E13304 /* ZXDefaultGridSampler.h */,
+ 25403DBB166A9C0E00E13304 /* ZXDefaultGridSampler.m */,
+ 25403DBC166A9C0E00E13304 /* ZXDetectorResult.h */,
+ 25403DBD166A9C0E00E13304 /* ZXDetectorResult.m */,
+ 25403DBE166A9C0E00E13304 /* ZXECI.h */,
+ 25403DBF166A9C0E00E13304 /* ZXECI.m */,
+ 25403DC0166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.h */,
+ 25403DC1166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.m */,
+ 25403DC2166A9C0E00E13304 /* ZXGridSampler.h */,
+ 25403DC3166A9C0E00E13304 /* ZXGridSampler.m */,
+ 25403DC4166A9C0E00E13304 /* ZXHybridBinarizer.h */,
+ 25403DC5166A9C0E00E13304 /* ZXHybridBinarizer.m */,
+ 25403DC6166A9C0E00E13304 /* ZXPerspectiveTransform.h */,
+ 25403DC7166A9C0E00E13304 /* ZXPerspectiveTransform.m */,
+ 25403DC8166A9C0E00E13304 /* ZXStringUtils.h */,
+ 25403DC9166A9C0E00E13304 /* ZXStringUtils.m */,
+ );
+ path = common;
+ sourceTree = "<group>";
+ };
+ 25403DA0166A9C0E00E13304 /* detector */ = {
+ isa = PBXGroup;
+ children = (
+ 25403DA1166A9C0E00E13304 /* ZXMathUtils.h */,
+ 25403DA2166A9C0E00E13304 /* ZXMathUtils.m */,
+ 25403DA3166A9C0E00E13304 /* ZXMonochromeRectangleDetector.h */,
+ 25403DA4166A9C0E00E13304 /* ZXMonochromeRectangleDetector.m */,
+ 25403DA5166A9C0E00E13304 /* ZXWhiteRectangleDetector.h */,
+ 25403DA6166A9C0E00E13304 /* ZXWhiteRectangleDetector.m */,
+ );
+ path = detector;
+ sourceTree = "<group>";
+ };
+ 25403DA7166A9C0E00E13304 /* reedsolomon */ = {
+ isa = PBXGroup;
+ children = (
+ 25403DA8166A9C0E00E13304 /* ZXGenericGF.h */,
+ 25403DA9166A9C0E00E13304 /* ZXGenericGF.m */,
+ 25403DAA166A9C0E00E13304 /* ZXGenericGFPoly.h */,
+ 25403DAB166A9C0E00E13304 /* ZXGenericGFPoly.m */,
+ 25403DAC166A9C0E00E13304 /* ZXReedSolomonDecoder.h */,
+ 25403DAD166A9C0E00E13304 /* ZXReedSolomonDecoder.m */,
+ 25403DAE166A9C0E00E13304 /* ZXReedSolomonEncoder.h */,
+ 25403DAF166A9C0E00E13304 /* ZXReedSolomonEncoder.m */,
+ );
+ path = reedsolomon;
+ sourceTree = "<group>";
+ };
+ 25403DF2166A9CCB00E13304 /* datamatrix */ = {
+ isa = PBXGroup;
+ children = (
+ 25403DF3166A9CCB00E13304 /* decoder */,
+ 25403DFE166A9CCB00E13304 /* detector */,
+ 2542998316D4788100D4C045 /* encoder */,
+ 25403E01166A9CCB00E13304 /* ZXDataMatrixReader.h */,
+ 25403E02166A9CCB00E13304 /* ZXDataMatrixReader.m */,
+ 2542997B16D470D600D4C045 /* ZXDataMatrixWriter.h */,
+ 2542997C16D470D600D4C045 /* ZXDataMatrixWriter.m */,
+ );
+ path = datamatrix;
+ sourceTree = "<group>";
+ };
+ 25403DF3166A9CCB00E13304 /* decoder */ = {
+ isa = PBXGroup;
+ children = (
+ 25403DF4166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.h */,
+ 25403DF5166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.m */,
+ 25403DF6166A9CCB00E13304 /* ZXDataMatrixDataBlock.h */,
+ 25403DF7166A9CCB00E13304 /* ZXDataMatrixDataBlock.m */,
+ 25403DF8166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.h */,
+ 25403DF9166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.m */,
+ 25403DFA166A9CCB00E13304 /* ZXDataMatrixDecoder.h */,
+ 25403DFB166A9CCB00E13304 /* ZXDataMatrixDecoder.m */,
+ 25403DFC166A9CCB00E13304 /* ZXDataMatrixVersion.h */,
+ 25403DFD166A9CCB00E13304 /* ZXDataMatrixVersion.m */,
+ );
+ path = decoder;
+ sourceTree = "<group>";
+ };
+ 25403DFE166A9CCB00E13304 /* detector */ = {
+ isa = PBXGroup;
+ children = (
+ 25403DFF166A9CCB00E13304 /* ZXDataMatrixDetector.h */,
+ 25403E00166A9CCB00E13304 /* ZXDataMatrixDetector.m */,
+ );
+ path = detector;
+ sourceTree = "<group>";
+ };
+ 25403E11166A9D4B00E13304 /* maxicode */ = {
+ isa = PBXGroup;
+ children = (
+ 25403E12166A9D4B00E13304 /* decoder */,
+ 25403E19166A9D4B00E13304 /* ZXMaxiCodeReader.h */,
+ 25403E1A166A9D4B00E13304 /* ZXMaxiCodeReader.m */,
+ );
+ path = maxicode;
+ sourceTree = "<group>";
+ };
+ 25403E12166A9D4B00E13304 /* decoder */ = {
+ isa = PBXGroup;
+ children = (
+ 25403E13166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.h */,
+ 25403E14166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.m */,
+ 25403E15166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.h */,
+ 25403E16166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.m */,
+ 25403E17166A9D4B00E13304 /* ZXMaxiCodeDecoder.h */,
+ 25403E18166A9D4B00E13304 /* ZXMaxiCodeDecoder.m */,
+ );
+ path = decoder;
+ sourceTree = "<group>";
+ };
+ 25403E23166A9D8B00E13304 /* multi */ = {
+ isa = PBXGroup;
+ children = (
+ 25403E24166A9D8B00E13304 /* qrcode */,
+ 25403E2C166A9D8B00E13304 /* ZXByQuadrantReader.h */,
+ 25403E2D166A9D8B00E13304 /* ZXByQuadrantReader.m */,
+ 25403E2E166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.h */,
+ 25403E2F166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.m */,
+ 25403E30166A9D8B00E13304 /* ZXMultipleBarcodeReader.h */,
+ );
+ path = multi;
+ sourceTree = "<group>";
+ };
+ 25403E24166A9D8B00E13304 /* qrcode */ = {
+ isa = PBXGroup;
+ children = (
+ 25403E25166A9D8B00E13304 /* detector */,
+ 25403E2A166A9D8B00E13304 /* ZXQRCodeMultiReader.h */,
+ 25403E2B166A9D8B00E13304 /* ZXQRCodeMultiReader.m */,
+ );
+ path = qrcode;
+ sourceTree = "<group>";
+ };
+ 25403E25166A9D8B00E13304 /* detector */ = {
+ isa = PBXGroup;
+ children = (
+ 25403E26166A9D8B00E13304 /* ZXMultiDetector.h */,
+ 25403E27166A9D8B00E13304 /* ZXMultiDetector.m */,
+ 25403E28166A9D8B00E13304 /* ZXMultiFinderPatternFinder.h */,
+ 25403E29166A9D8B00E13304 /* ZXMultiFinderPatternFinder.m */,
+ );
+ path = detector;
+ sourceTree = "<group>";
+ };
+ 25403E3C166A9DF300E13304 /* oned */ = {
+ isa = PBXGroup;
+ children = (
+ 25403E3D166A9DF300E13304 /* rss */,
+ 25403E78166A9DF300E13304 /* ZXCodaBarReader.h */,
+ 25403E79166A9DF300E13304 /* ZXCodaBarReader.m */,
+ 25403E7A166A9DF300E13304 /* ZXCodaBarWriter.h */,
+ 25403E7B166A9DF300E13304 /* ZXCodaBarWriter.m */,
+ 25403E7C166A9DF300E13304 /* ZXCode128Reader.h */,
+ 25403E7D166A9DF300E13304 /* ZXCode128Reader.m */,
+ 25403E7E166A9DF300E13304 /* ZXCode128Writer.h */,
+ 25403E7F166A9DF300E13304 /* ZXCode128Writer.m */,
+ 25403E80166A9DF300E13304 /* ZXCode39Reader.h */,
+ 25403E81166A9DF300E13304 /* ZXCode39Reader.m */,
+ 25403E82166A9DF300E13304 /* ZXCode39Writer.h */,
+ 25403E83166A9DF300E13304 /* ZXCode39Writer.m */,
+ 25403E84166A9DF300E13304 /* ZXCode93Reader.h */,
+ 25403E85166A9DF300E13304 /* ZXCode93Reader.m */,
+ 25403E86166A9DF300E13304 /* ZXEAN13Reader.h */,
+ 25403E87166A9DF300E13304 /* ZXEAN13Reader.m */,
+ 25403E88166A9DF300E13304 /* ZXEAN13Writer.h */,
+ 25403E89166A9DF300E13304 /* ZXEAN13Writer.m */,
+ 25403E8A166A9DF300E13304 /* ZXEAN8Reader.h */,
+ 25403E8B166A9DF300E13304 /* ZXEAN8Reader.m */,
+ 25403E8C166A9DF300E13304 /* ZXEAN8Writer.h */,
+ 25403E8D166A9DF300E13304 /* ZXEAN8Writer.m */,
+ 25403E8E166A9DF300E13304 /* ZXEANManufacturerOrgSupport.h */,
+ 25403E8F166A9DF300E13304 /* ZXEANManufacturerOrgSupport.m */,
+ 25403E90166A9DF300E13304 /* ZXITFReader.h */,
+ 25403E91166A9DF300E13304 /* ZXITFReader.m */,
+ 25403E92166A9DF300E13304 /* ZXITFWriter.h */,
+ 25403E93166A9DF300E13304 /* ZXITFWriter.m */,
+ 25403E94166A9DF300E13304 /* ZXMultiFormatOneDReader.h */,
+ 25403E95166A9DF300E13304 /* ZXMultiFormatOneDReader.m */,
+ 25403E96166A9DF300E13304 /* ZXMultiFormatUPCEANReader.h */,
+ 25403E97166A9DF300E13304 /* ZXMultiFormatUPCEANReader.m */,
+ 25403E98166A9DF300E13304 /* ZXOneDimensionalCodeWriter.h */,
+ 25403E99166A9DF300E13304 /* ZXOneDimensionalCodeWriter.m */,
+ 25403E9A166A9DF300E13304 /* ZXOneDReader.h */,
+ 25403E9B166A9DF300E13304 /* ZXOneDReader.m */,
+ 25403E9C166A9DF300E13304 /* ZXUPCAReader.h */,
+ 25403E9D166A9DF300E13304 /* ZXUPCAReader.m */,
+ 25403E9E166A9DF300E13304 /* ZXUPCAWriter.h */,
+ 25403E9F166A9DF300E13304 /* ZXUPCAWriter.m */,
+ 25403EA0166A9DF300E13304 /* ZXUPCEANExtension2Support.h */,
+ 25403EA1166A9DF300E13304 /* ZXUPCEANExtension2Support.m */,
+ 25403EA2166A9DF300E13304 /* ZXUPCEANExtension5Support.h */,
+ 25403EA3166A9DF300E13304 /* ZXUPCEANExtension5Support.m */,
+ 25403EA4166A9DF300E13304 /* ZXUPCEANExtensionSupport.h */,
+ 25403EA5166A9DF300E13304 /* ZXUPCEANExtensionSupport.m */,
+ 25403EA6166A9DF300E13304 /* ZXUPCEANReader.h */,
+ 25403EA7166A9DF300E13304 /* ZXUPCEANReader.m */,
+ 25403EA8166A9DF300E13304 /* ZXUPCEANWriter.h */,
+ 25403EA9166A9DF300E13304 /* ZXUPCEANWriter.m */,
+ 25403EAA166A9DF300E13304 /* ZXUPCEReader.h */,
+ 25403EAB166A9DF300E13304 /* ZXUPCEReader.m */,
+ );
+ path = oned;
+ sourceTree = "<group>";
+ };
+ 25403E3D166A9DF300E13304 /* rss */ = {
+ isa = PBXGroup;
+ children = (
+ 25403E3E166A9DF300E13304 /* expanded */,
+ 25403E6C166A9DF300E13304 /* ZXAbstractRSSReader.h */,
+ 25403E6D166A9DF300E13304 /* ZXAbstractRSSReader.m */,
+ 25403E6E166A9DF300E13304 /* ZXDataCharacter.h */,
+ 25403E6F166A9DF300E13304 /* ZXDataCharacter.m */,
+ 25403E70166A9DF300E13304 /* ZXPair.h */,
+ 25403E71166A9DF300E13304 /* ZXPair.m */,
+ 25403E72166A9DF300E13304 /* ZXRSS14Reader.h */,
+ 25403E73166A9DF300E13304 /* ZXRSS14Reader.m */,
+ 25403E74166A9DF300E13304 /* ZXRSSFinderPattern.h */,
+ 25403E75166A9DF300E13304 /* ZXRSSFinderPattern.m */,
+ 25403E76166A9DF300E13304 /* ZXRSSUtils.h */,
+ 25403E77166A9DF300E13304 /* ZXRSSUtils.m */,
+ );
+ path = rss;
+ sourceTree = "<group>";
+ };
+ 25403E3E166A9DF300E13304 /* expanded */ = {
+ isa = PBXGroup;
+ children = (
+ 25403E3F166A9DF300E13304 /* decoders */,
+ 25403E66166A9DF300E13304 /* ZXBitArrayBuilder.h */,
+ 25403E67166A9DF300E13304 /* ZXBitArrayBuilder.m */,
+ 25403E68166A9DF300E13304 /* ZXExpandedPair.h */,
+ 25403E69166A9DF300E13304 /* ZXExpandedPair.m */,
+ 25FE5D3116D0AFED00826CDB /* ZXExpandedRow.h */,
+ 25FE5D3216D0AFED00826CDB /* ZXExpandedRow.m */,
+ 25403E6A166A9DF300E13304 /* ZXRSSExpandedReader.h */,
+ 25403E6B166A9DF300E13304 /* ZXRSSExpandedReader.m */,
+ );
+ path = expanded;
+ sourceTree = "<group>";
+ };
+ 25403E3F166A9DF300E13304 /* decoders */ = {
+ isa = PBXGroup;
+ children = (
+ 25403E40166A9DF300E13304 /* ZXAbstractExpandedDecoder.h */,
+ 25403E41166A9DF300E13304 /* ZXAbstractExpandedDecoder.m */,
+ 25403E42166A9DF300E13304 /* ZXAI013103decoder.h */,
+ 25403E43166A9DF300E13304 /* ZXAI013103decoder.m */,
+ 25403E44166A9DF300E13304 /* ZXAI01320xDecoder.h */,
+ 25403E45166A9DF300E13304 /* ZXAI01320xDecoder.m */,
+ 25403E46166A9DF300E13304 /* ZXAI01392xDecoder.h */,
+ 25403E47166A9DF300E13304 /* ZXAI01392xDecoder.m */,
+ 25403E48166A9DF300E13304 /* ZXAI01393xDecoder.h */,
+ 25403E49166A9DF300E13304 /* ZXAI01393xDecoder.m */,
+ 25403E4A166A9DF300E13304 /* ZXAI013x0x1xDecoder.h */,
+ 25403E4B166A9DF300E13304 /* ZXAI013x0x1xDecoder.m */,
+ 25403E4C166A9DF300E13304 /* ZXAI013x0xDecoder.h */,
+ 25403E4D166A9DF300E13304 /* ZXAI013x0xDecoder.m */,
+ 25403E4E166A9DF300E13304 /* ZXAI01AndOtherAIs.h */,
+ 25403E4F166A9DF300E13304 /* ZXAI01AndOtherAIs.m */,
+ 25403E50166A9DF300E13304 /* ZXAI01decoder.h */,
+ 25403E51166A9DF300E13304 /* ZXAI01decoder.m */,
+ 25403E52166A9DF300E13304 /* ZXAI01weightDecoder.h */,
+ 25403E53166A9DF300E13304 /* ZXAI01weightDecoder.m */,
+ 25403E54166A9DF300E13304 /* ZXAnyAIDecoder.h */,
+ 25403E55166A9DF300E13304 /* ZXAnyAIDecoder.m */,
+ 25403E56166A9DF300E13304 /* ZXBlockParsedResult.h */,
+ 25403E57166A9DF300E13304 /* ZXBlockParsedResult.m */,
+ 25403E58166A9DF300E13304 /* ZXCurrentParsingState.h */,
+ 25403E59166A9DF300E13304 /* ZXCurrentParsingState.m */,
+ 25403E5A166A9DF300E13304 /* ZXDecodedChar.h */,
+ 25403E5B166A9DF300E13304 /* ZXDecodedChar.m */,
+ 25403E5C166A9DF300E13304 /* ZXDecodedInformation.h */,
+ 25403E5D166A9DF300E13304 /* ZXDecodedInformation.m */,
+ 25403E5E166A9DF300E13304 /* ZXDecodedNumeric.h */,
+ 25403E5F166A9DF300E13304 /* ZXDecodedNumeric.m */,
+ 25403E60166A9DF300E13304 /* ZXDecodedObject.h */,
+ 25403E61166A9DF300E13304 /* ZXDecodedObject.m */,
+ 25403E62166A9DF300E13304 /* ZXFieldParser.h */,
+ 25403E63166A9DF300E13304 /* ZXFieldParser.m */,
+ 25403E64166A9DF300E13304 /* ZXGeneralAppIdDecoder.h */,
+ 25403E65166A9DF300E13304 /* ZXGeneralAppIdDecoder.m */,
+ );
+ path = decoders;
+ sourceTree = "<group>";
+ };
+ 25403F18166A9EB500E13304 /* pdf417 */ = {
+ isa = PBXGroup;
+ children = (
+ 25403F19166A9EB500E13304 /* decoder */,
+ 25403F27166A9EB500E13304 /* detector */,
+ 25403F2A166A9EB500E13304 /* encoder */,
+ 2519AB4217FE554D00A71C45 /* ZXPDF417Common.h */,
+ 2519AB4317FE554D00A71C45 /* ZXPDF417Common.m */,
+ 25403F3A166A9EB500E13304 /* ZXPDF417Reader.h */,
+ 25403F3B166A9EB500E13304 /* ZXPDF417Reader.m */,
+ 2519AB4617FE5C1F00A71C45 /* ZXPDF417ResultMetadata.h */,
+ 2519AB4717FE5C1F00A71C45 /* ZXPDF417ResultMetadata.m */,
+ 2519AB3A17FD1EE400A71C45 /* ZXPDF417Writer.h */,
+ 2519AB3B17FD1EE400A71C45 /* ZXPDF417Writer.m */,
+ );
+ path = pdf417;
+ sourceTree = "<group>";
+ };
+ 25403F19166A9EB500E13304 /* decoder */ = {
+ isa = PBXGroup;
+ children = (
+ 25403F1A166A9EB500E13304 /* ec */,
+ 2519AB5C17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.h */,
+ 2519AB5D17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m */,
+ 2519AB6417FE5F2E00A71C45 /* ZXPDF417BarcodeValue.h */,
+ 2519AB6517FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m */,
+ 2519AB6C17FE60E700A71C45 /* ZXPDF417BoundingBox.h */,
+ 2519AB6D17FE60E700A71C45 /* ZXPDF417BoundingBox.m */,
+ 2519AB7417FE649000A71C45 /* ZXPDF417Codeword.h */,
+ 2519AB7517FE649000A71C45 /* ZXPDF417Codeword.m */,
+ 25389B771800DEC300772392 /* ZXPDF417CodewordDecoder.h */,
+ 25389B781800DEC300772392 /* ZXPDF417CodewordDecoder.m */,
+ 25403F23166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.h */,
+ 25403F24166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.m */,
+ 25389B5E17FFC84300772392 /* ZXPDF417DetectionResult.h */,
+ 25389B5F17FFC84300772392 /* ZXPDF417DetectionResult.m */,
+ 25389B6717FFC98100772392 /* ZXPDF417DetectionResultColumn.h */,
+ 25389B6817FFC98100772392 /* ZXPDF417DetectionResultColumn.m */,
+ 25389B6F17FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.h */,
+ 25389B7017FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m */,
+ 25389B7F1800E35B00772392 /* ZXPDF417ScanningDecoder.h */,
+ 25389B801800E35B00772392 /* ZXPDF417ScanningDecoder.m */,
+ );
+ path = decoder;
+ sourceTree = "<group>";
+ };
+ 25403F1A166A9EB500E13304 /* ec */ = {
+ isa = PBXGroup;
+ children = (
+ 25403F1B166A9EB500E13304 /* ZXModulusGF.h */,
+ 25403F1C166A9EB500E13304 /* ZXModulusGF.m */,
+ 25403F1D166A9EB500E13304 /* ZXModulusPoly.h */,
+ 25403F1E166A9EB500E13304 /* ZXModulusPoly.m */,
+ 25403F1F166A9EB500E13304 /* ZXPDF417ECErrorCorrection.h */,
+ 25403F20166A9EB500E13304 /* ZXPDF417ECErrorCorrection.m */,
+ );
+ path = ec;
+ sourceTree = "<group>";
+ };
+ 25403F27166A9EB500E13304 /* detector */ = {
+ isa = PBXGroup;
+ children = (
+ 25403F28166A9EB500E13304 /* ZXPDF417Detector.h */,
+ 25403F29166A9EB500E13304 /* ZXPDF417Detector.m */,
+ 25389B8718010B9A00772392 /* ZXPDF417DetectorResult.h */,
+ 25389B8818010B9A00772392 /* ZXPDF417DetectorResult.m */,
+ );
+ path = detector;
+ sourceTree = "<group>";
+ };
+ 25403F2A166A9EB500E13304 /* encoder */ = {
+ isa = PBXGroup;
+ children = (
+ 25403F2B166A9EB500E13304 /* ZXBarcodeMatrix.h */,
+ 25403F2C166A9EB500E13304 /* ZXBarcodeMatrix.m */,
+ 25403F2D166A9EB500E13304 /* ZXBarcodeRow.h */,
+ 25403F2E166A9EB500E13304 /* ZXBarcodeRow.m */,
+ 25403F2F166A9EB500E13304 /* ZXCompaction.h */,
+ 25403F30166A9EB500E13304 /* ZXDimensions.h */,
+ 25403F31166A9EB500E13304 /* ZXDimensions.m */,
+ 25403F32166A9EB500E13304 /* ZXPDF417.h */,
+ 25403F33166A9EB500E13304 /* ZXPDF417.m */,
+ 25403F34166A9EB500E13304 /* ZXPDF417ErrorCorrection.h */,
+ 25403F35166A9EB500E13304 /* ZXPDF417ErrorCorrection.m */,
+ 25403F36166A9EB500E13304 /* ZXPDF417HighLevelEncoder.h */,
+ 25403F37166A9EB500E13304 /* ZXPDF417HighLevelEncoder.m */,
+ );
+ path = encoder;
+ sourceTree = "<group>";
+ };
+ 25403F5B166A9F2D00E13304 /* qrcode */ = {
+ isa = PBXGroup;
+ children = (
+ 25403F5C166A9F2D00E13304 /* decoder */,
+ 25403F6F166A9F2D00E13304 /* detector */,
+ 25403F7C166A9F2D00E13304 /* encoder */,
+ 25403F89166A9F2D00E13304 /* ZXQRCodeReader.h */,
+ 25403F8A166A9F2D00E13304 /* ZXQRCodeReader.m */,
+ 25403F8B166A9F2D00E13304 /* ZXQRCodeWriter.h */,
+ 25403F8C166A9F2D00E13304 /* ZXQRCodeWriter.m */,
+ );
+ path = qrcode;
+ sourceTree = "<group>";
+ };
+ 25403F5C166A9F2D00E13304 /* decoder */ = {
+ isa = PBXGroup;
+ children = (
+ 25403F5D166A9F2D00E13304 /* ZXDataMask.h */,
+ 25403F5E166A9F2D00E13304 /* ZXDataMask.m */,
+ 25403F5F166A9F2D00E13304 /* ZXErrorCorrectionLevel.h */,
+ 25403F60166A9F2D00E13304 /* ZXErrorCorrectionLevel.m */,
+ 25403F61166A9F2D00E13304 /* ZXFormatInformation.h */,
+ 25403F62166A9F2D00E13304 /* ZXFormatInformation.m */,
+ 25403F63166A9F2D00E13304 /* ZXMode.h */,
+ 25403F64166A9F2D00E13304 /* ZXMode.m */,
+ 25403F65166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.h */,
+ 25403F66166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.m */,
+ 25403F67166A9F2D00E13304 /* ZXQRCodeDataBlock.h */,
+ 25403F68166A9F2D00E13304 /* ZXQRCodeDataBlock.m */,
+ 25403F69166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.h */,
+ 25403F6A166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.m */,
+ 25403F6B166A9F2D00E13304 /* ZXQRCodeDecoder.h */,
+ 25403F6C166A9F2D00E13304 /* ZXQRCodeDecoder.m */,
+ 25403F6D166A9F2D00E13304 /* ZXQRCodeVersion.h */,
+ 25403F6E166A9F2D00E13304 /* ZXQRCodeVersion.m */,
+ );
+ path = decoder;
+ sourceTree = "<group>";
+ };
+ 25403F6F166A9F2D00E13304 /* detector */ = {
+ isa = PBXGroup;
+ children = (
+ 25403F70166A9F2D00E13304 /* ZXAlignmentPattern.h */,
+ 25403F71166A9F2D00E13304 /* ZXAlignmentPattern.m */,
+ 25403F72166A9F2D00E13304 /* ZXAlignmentPatternFinder.h */,
+ 25403F73166A9F2D00E13304 /* ZXAlignmentPatternFinder.m */,
+ 25403F74166A9F2D00E13304 /* ZXFinderPatternFinder.h */,
+ 25403F75166A9F2D00E13304 /* ZXFinderPatternFinder.m */,
+ 25403F76166A9F2D00E13304 /* ZXFinderPatternInfo.h */,
+ 25403F77166A9F2D00E13304 /* ZXFinderPatternInfo.m */,
+ 25403F78166A9F2D00E13304 /* ZXQRCodeDetector.h */,
+ 25403F79166A9F2D00E13304 /* ZXQRCodeDetector.m */,
+ 25403F7A166A9F2D00E13304 /* ZXQRCodeFinderPattern.h */,
+ 25403F7B166A9F2D00E13304 /* ZXQRCodeFinderPattern.m */,
+ );
+ path = detector;
+ sourceTree = "<group>";
+ };
+ 25403F7C166A9F2D00E13304 /* encoder */ = {
+ isa = PBXGroup;
+ children = (
+ 25403F7D166A9F2D00E13304 /* ZXBlockPair.h */,
+ 25403F7E166A9F2D00E13304 /* ZXBlockPair.m */,
+ 25403F7F166A9F2D00E13304 /* ZXByteMatrix.h */,
+ 25403F80166A9F2D00E13304 /* ZXByteMatrix.m */,
+ 25403F81166A9F2D00E13304 /* ZXEncoder.h */,
+ 25403F82166A9F2D00E13304 /* ZXEncoder.m */,
+ 25403F83166A9F2D00E13304 /* ZXMaskUtil.h */,
+ 25403F84166A9F2D00E13304 /* ZXMaskUtil.m */,
+ 25403F85166A9F2D00E13304 /* ZXMatrixUtil.h */,
+ 25403F86166A9F2D00E13304 /* ZXMatrixUtil.m */,
+ 25403F87166A9F2D00E13304 /* ZXQRCode.h */,
+ 25403F88166A9F2D00E13304 /* ZXQRCode.m */,
+ );
+ path = encoder;
+ sourceTree = "<group>";
+ };
+ 25403FED166AA0F100E13304 /* aztec */ = {
+ isa = PBXGroup;
+ children = (
+ 2504D9E316FFF25E00DF8882 /* encoder */,
+ 25403FEE166AA0F100E13304 /* AztecBlackBox1TestCase.h */,
+ 25403FEF166AA0F100E13304 /* AztecBlackBox1TestCase.m */,
+ 25403FF0166AA0F100E13304 /* AztecBlackBox2TestCase.h */,
+ 25403FF1166AA0F100E13304 /* AztecBlackBox2TestCase.m */,
+ );
+ path = aztec;
+ sourceTree = "<group>";
+ };
+ 25403FF2166AA0F100E13304 /* client */ = {
+ isa = PBXGroup;
+ children = (
+ 25403FF3166AA0F100E13304 /* result */,
+ );
+ path = client;
+ sourceTree = "<group>";
+ };
+ 25403FF3166AA0F100E13304 /* result */ = {
+ isa = PBXGroup;
+ children = (
+ 25403FF4166AA0F100E13304 /* ZXAddressBookParsedResultTestCase.h */,
+ 25403FF5166AA0F100E13304 /* ZXAddressBookParsedResultTestCase.m */,
+ 25403FF6166AA0F100E13304 /* ZXCalendarParsedResultTestCase.h */,
+ 25403FF7166AA0F100E13304 /* ZXCalendarParsedResultTestCase.m */,
+ 25403FF8166AA0F100E13304 /* ZXEmailAddressParsedResultTestCase.h */,
+ 25403FF9166AA0F100E13304 /* ZXEmailAddressParsedResultTestCase.m */,
+ 25403FFA166AA0F100E13304 /* ZXExpandedProductParsedResultTestCase.h */,
+ 25403FFB166AA0F100E13304 /* ZXExpandedProductParsedResultTestCase.m */,
+ 25403FFC166AA0F100E13304 /* ZXGeoParsedResultTestCase.h */,
+ 25403FFD166AA0F100E13304 /* ZXGeoParsedResultTestCase.m */,
+ 25403FFE166AA0F100E13304 /* ZXISBNParsedResultTestCase.h */,
+ 25403FFF166AA0F100E13304 /* ZXISBNParsedResultTestCase.m */,
+ 25404000166AA0F100E13304 /* ZXParsedReaderResultTestCase.h */,
+ 25404001166AA0F100E13304 /* ZXParsedReaderResultTestCase.m */,
+ 25404002166AA0F100E13304 /* ZXProductParsedResultTestCase.h */,
+ 25404003166AA0F100E13304 /* ZXProductParsedResultTestCase.m */,
+ 25404004166AA0F100E13304 /* ZXSMSMMSParsedResultTestCase.h */,
+ 25404005166AA0F100E13304 /* ZXSMSMMSParsedResultTestCase.m */,
+ 25404006166AA0F100E13304 /* ZXTelParsedResultTestCase.h */,
+ 25404007166AA0F100E13304 /* ZXTelParsedResultTestCase.m */,
+ 25404008166AA0F100E13304 /* ZXURIParsedResultTestCase.h */,
+ 25404009166AA0F100E13304 /* ZXURIParsedResultTestCase.m */,
+ 2540400A166AA0F100E13304 /* ZXWifiParsedResultTestCase.h */,
+ 2540400B166AA0F100E13304 /* ZXWifiParsedResultTestCase.m */,
+ );
+ path = result;
+ sourceTree = "<group>";
+ };
+ 2540400C166AA0F100E13304 /* common */ = {
+ isa = PBXGroup;
+ children = (
+ 2540400D166AA0F100E13304 /* AbstractBlackBoxTestCase.h */,
+ 2540400E166AA0F100E13304 /* AbstractBlackBoxTestCase.m */,
+ 2540400F166AA0F100E13304 /* AbstractNegativeBlackBoxTestCase.h */,
+ 25404010166AA0F100E13304 /* AbstractNegativeBlackBoxTestCase.m */,
+ 25404011166AA0F100E13304 /* reedsolomon */,
+ 2540401A166AA0F100E13304 /* TestResult.h */,
+ 2540401B166AA0F100E13304 /* TestResult.m */,
+ 2540401C166AA0F100E13304 /* ZXBitArrayTestCase.h */,
+ 2540401D166AA0F100E13304 /* ZXBitArrayTestCase.m */,
+ 2540401E166AA0F100E13304 /* ZXBitMatrixTestCase.h */,
+ 2540401F166AA0F100E13304 /* ZXBitMatrixTestCase.m */,
+ 25404020166AA0F100E13304 /* ZXBitSourceBuilder.h */,
+ 25404021166AA0F100E13304 /* ZXBitSourceBuilder.m */,
+ 25404022166AA0F100E13304 /* ZXBitSourceTestCase.h */,
+ 25404023166AA0F100E13304 /* ZXBitSourceTestCase.m */,
+ 25404024166AA0F100E13304 /* ZXPerspectiveTransformTestCase.h */,
+ 25404025166AA0F100E13304 /* ZXPerspectiveTransformTestCase.m */,
+ 25404026166AA0F100E13304 /* ZXStringUtilsTestCase.h */,
+ 25404027166AA0F100E13304 /* ZXStringUtilsTestCase.m */,
+ );
+ path = common;
+ sourceTree = "<group>";
+ };
+ 25404011166AA0F100E13304 /* reedsolomon */ = {
+ isa = PBXGroup;
+ children = (
+ 2504D9EA170005FE00DF8882 /* ReedSolomonTestCase.h */,
+ 2504D9EB170005FE00DF8882 /* ReedSolomonTestCase.m */,
+ );
+ path = reedsolomon;
+ sourceTree = "<group>";
+ };
+ 25404028166AA0F100E13304 /* datamatrix */ = {
+ isa = PBXGroup;
+ children = (
+ 25404029166AA0F100E13304 /* DataMatrixBlackBox1TestCase.h */,
+ 2540402A166AA0F100E13304 /* DataMatrixBlackBox1TestCase.m */,
+ 2540402B166AA0F100E13304 /* DataMatrixBlackBox2TestCase.h */,
+ 2540402C166AA0F100E13304 /* DataMatrixBlackBox2TestCase.m */,
+ 2540402D166AA0F100E13304 /* decoder */,
+ 254299FD16D5DFBB00D4C045 /* encoder */,
+ 254299F316D5DC8E00D4C045 /* ZXDataMatrixWriterTestCase.h */,
+ 254299F416D5DC8E00D4C045 /* ZXDataMatrixWriterTestCase.m */,
+ );
+ path = datamatrix;
+ sourceTree = "<group>";
+ };
+ 2540402D166AA0F100E13304 /* decoder */ = {
+ isa = PBXGroup;
+ children = (
+ 2540402E166AA0F100E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.h */,
+ 2540402F166AA0F100E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.m */,
+ );
+ path = decoder;
+ sourceTree = "<group>";
+ };
+ 25404030166AA0F100E13304 /* negative */ = {
+ isa = PBXGroup;
+ children = (
+ 25404031166AA0F100E13304 /* FalsePositives2BlackBoxTestCase.h */,
+ 25404032166AA0F100E13304 /* FalsePositives2BlackBoxTestCase.m */,
+ 25404033166AA0F100E13304 /* FalsePositivesBlackBoxTestCase.h */,
+ 25404034166AA0F100E13304 /* FalsePositivesBlackBoxTestCase.m */,
+ 25404035166AA0F100E13304 /* PartialBlackBoxTestCase.h */,
+ 25404036166AA0F100E13304 /* PartialBlackBoxTestCase.m */,
+ 25404037166AA0F100E13304 /* UnsupportedBlackBoxTestCase.h */,
+ 25404038166AA0F100E13304 /* UnsupportedBlackBoxTestCase.m */,
+ );
+ path = negative;
+ sourceTree = "<group>";
+ };
+ 25404039166AA0F100E13304 /* oned */ = {
+ isa = PBXGroup;
+ children = (
+ 2540403A166AA0F100E13304 /* CodabarBlackBox1TestCase.h */,
+ 2540403B166AA0F100E13304 /* CodabarBlackbox1TestCase.m */,
+ 2540403C166AA0F100E13304 /* Code128BlackBox1TestCase.h */,
+ 2540403D166AA0F100E13304 /* Code128BlackBox1TestCase.m */,
+ 2540403E166AA0F100E13304 /* Code128BlackBox2TestCase.h */,
+ 2540403F166AA0F100E13304 /* Code128BlackBox2TestCase.m */,
+ 25404040166AA0F100E13304 /* Code128BlackBox3TestCase.h */,
+ 25404041166AA0F100E13304 /* Code128BlackBox3TestCase.m */,
+ 25404042166AA0F100E13304 /* Code39BlackBox1TestCase.h */,
+ 25404043166AA0F100E13304 /* Code39BlackBox1TestCase.m */,
+ 25404044166AA0F100E13304 /* Code39BlackBox3TestCase.h */,
+ 25404045166AA0F100E13304 /* Code39BlackBox3TestCase.m */,
+ 25404046166AA0F100E13304 /* Code39ExtendedBlackBox2TestCase.h */,
+ 25404047166AA0F100E13304 /* Code39ExtendedBlackBox2TestCase.m */,
+ 25404048166AA0F100E13304 /* Code93BlackBox1TestCase.h */,
+ 25404049166AA0F100E13304 /* Code93BlackBox1TestCase.m */,
+ 2540404A166AA0F100E13304 /* EAN13BlackBox1TestCase.h */,
+ 2540404B166AA0F100E13304 /* EAN13BlackBox1TestCase.m */,
+ 2540404C166AA0F100E13304 /* EAN13BlackBox2TestCase.h */,
+ 2540404D166AA0F100E13304 /* EAN13BlackBox2TestCase.m */,
+ 2540404E166AA0F100E13304 /* EAN13BlackBox3TestCase.h */,
+ 2540404F166AA0F100E13304 /* EAN13BlackBox3TestCase.m */,
+ 25404050166AA0F100E13304 /* EAN13BlackBox4TestCase.h */,
+ 25404051166AA0F100E13304 /* EAN13BlackBox4TestCase.m */,
+ 25404052166AA0F100E13304 /* EAN13BlackBox5BlurryTestCase.h */,
+ 25404053166AA0F100E13304 /* EAN13BlackBox5BlurryTestCase.m */,
+ 25404054166AA0F100E13304 /* EAN8BlackBox1TestCase.h */,
+ 25404055166AA0F100E13304 /* EAN8BlackBox1TestCase.m */,
+ 25404056166AA0F100E13304 /* ITFBlackBox1TestCase.h */,
+ 25404057166AA0F100E13304 /* ITFBlackBox1TestCase.m */,
+ 25404058166AA0F100E13304 /* ITFBlackBox2TestCase.h */,
+ 25404059166AA0F100E13304 /* ITFBlackBox2TestCase.m */,
+ 2540405A166AA0F100E13304 /* rss */,
+ 25404083166AA0F100E13304 /* UPCABlackBox1TestCase.h */,
+ 25404084166AA0F100E13304 /* UPCABlackBox1TestCase.m */,
+ 25404085166AA0F100E13304 /* UPCABlackBox2TestCase.h */,
+ 25404086166AA0F100E13304 /* UPCABlackBox2TestCase.m */,
+ 25404087166AA0F100E13304 /* UPCABlackBox3ReflectiveTestCase.h */,
+ 25404088166AA0F100E13304 /* UPCABlackBox3ReflectiveTestCase.m */,
+ 25404089166AA0F100E13304 /* UPCABlackBox4TestCase.h */,
+ 2540408A166AA0F100E13304 /* UPCABlackBox4TestCase.m */,
+ 2540408B166AA0F100E13304 /* UPCABlackBox5TestCase.h */,
+ 2540408C166AA0F100E13304 /* UPCABlackBox5TestCase.m */,
+ 2540408D166AA0F100E13304 /* UPCABlackBox6BlurryTestCase.h */,
+ 2540408E166AA0F100E13304 /* UPCABlackBox6BlurryTestCase.m */,
+ 2540408F166AA0F100E13304 /* UPCEANExtensionBlackBox1TestCase.h */,
+ 25404090166AA0F100E13304 /* UPCEANExtensionBlackBox1TestCase.m */,
+ 25404091166AA0F100E13304 /* UPCEBlackBox1TestCase.h */,
+ 25404092166AA0F100E13304 /* UPCEBlackBox1TestCase.m */,
+ 25404093166AA0F100E13304 /* UPCEBlackBox2TestCase.h */,
+ 25404094166AA0F100E13304 /* UPCEBlackBox2TestCase.m */,
+ 25404095166AA0F100E13304 /* UPCEBlackBox3ReflectiveTestCase.h */,
+ 25404096166AA0F100E13304 /* UPCEBlackBox3ReflectiveTestCase.m */,
+ 25404097166AA0F100E13304 /* ZXCodaBarWriterTestCase.h */,
+ 25404098166AA0F100E13304 /* ZXCodaBarWriterTestCase.m */,
+ 2540409B166AA0F100E13304 /* ZXEAN13WriterTestCase.h */,
+ 2540409C166AA0F100E13304 /* ZXEAN13WriterTestCase.m */,
+ 2540409D166AA0F100E13304 /* ZXEAN8WriterTestCase.h */,
+ 2540409E166AA0F100E13304 /* ZXEAN8WriterTestCase.m */,
+ 2540409F166AA0F100E13304 /* ZXEANManufacturerOrgSupportTest.h */,
+ 254040A0166AA0F100E13304 /* ZXEANManufacturerOrgSupportTest.m */,
+ 254040A3166AA0F100E13304 /* ZXUPCAWriterTestCase.h */,
+ 254040A4166AA0F100E13304 /* ZXUPCAWriterTestCase.m */,
+ );
+ path = oned;
+ sourceTree = "<group>";
+ };
+ 2540405A166AA0F100E13304 /* rss */ = {
+ isa = PBXGroup;
+ children = (
+ 2540405B166AA0F100E13304 /* expanded */,
+ 2540407F166AA0F100E13304 /* RSS14BlackBox1TestCase.h */,
+ 25404080166AA0F100E13304 /* RSS14BlackBox1TestCase.m */,
+ 25404081166AA0F100E13304 /* RSS14BlackBox2TestCase.h */,
+ 25404082166AA0F100E13304 /* RSS14BlackBox2TestCase.m */,
+ );
+ path = rss;
+ sourceTree = "<group>";
+ };
+ 2540405B166AA0F100E13304 /* expanded */ = {
+ isa = PBXGroup;
+ children = (
+ 2540405C166AA0F100E13304 /* decoders */,
+ 25404069166AA0F100E13304 /* RSSExpandedBlackBox1TestCase.h */,
+ 2540406A166AA0F100E13304 /* RSSExpandedBlackBox1TestCase.m */,
+ 2540406B166AA0F100E13304 /* RSSExpandedBlackBox2TestCase.h */,
+ 2540406C166AA0F100E13304 /* RSSExpandedBlackBox2TestCase.m */,
+ 2540406D166AA0F100E13304 /* RSSExpandedBlackBox3TestCase.h */,
+ 2540406E166AA0F100E13304 /* RSSExpandedBlackBox3TestCase.m */,
+ 2540406F166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.h */,
+ 25404070166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.m */,
+ 25404071166AA0F100E13304 /* RSSExpandedImage2resultTestCase.h */,
+ 25404072166AA0F100E13304 /* RSSExpandedImage2resultTestCase.m */,
+ 25404073166AA0F100E13304 /* RSSExpandedImage2stringTestCase.h */,
+ 25404074166AA0F100E13304 /* RSSExpandedImage2stringTestCase.m */,
+ 25404075166AA0F100E13304 /* RSSExpandedInternalTestCase.h */,
+ 25404076166AA0F100E13304 /* RSSExpandedInternalTestCase.m */,
+ 25FE5D3816D0B82F00826CDB /* RSSExpandedStackedBlackBox1TestCase.h */,
+ 25FE5D3916D0B82F00826CDB /* RSSExpandedStackedBlackBox1TestCase.m */,
+ 25FE5D3A16D0B83000826CDB /* RSSExpandedStackedBlackBox2TestCase.h */,
+ 25FE5D3B16D0B83000826CDB /* RSSExpandedStackedBlackBox2TestCase.m */,
+ 25FE5D3E16D0B84C00826CDB /* RSSExpandedStackedInternalTestCase.h */,
+ 25FE5D3F16D0B84C00826CDB /* RSSExpandedStackedInternalTestCase.m */,
+ 25FE5D4116D0B8B100826CDB /* TestCaseUtil.h */,
+ 25FE5D4216D0B8B200826CDB /* TestCaseUtil.m */,
+ 25404077166AA0F100E13304 /* ZXBinaryUtil.h */,
+ 25404078166AA0F100E13304 /* ZXBinaryUtil.m */,
+ 25404079166AA0F100E13304 /* ZXBinaryUtilTest.h */,
+ 2540407A166AA0F100E13304 /* ZXBinaryUtilTest.m */,
+ 2540407B166AA0F100E13304 /* ZXBitArrayBuilderTest.h */,
+ 2540407C166AA0F100E13304 /* ZXBitArrayBuilderTest.m */,
+ 2540407D166AA0F100E13304 /* ZXExpandedInformationDecoderTest.h */,
+ 2540407E166AA0F100E13304 /* ZXExpandedInformationDecoderTest.m */,
+ );
+ path = expanded;
+ sourceTree = "<group>";
+ };
+ 2540405C166AA0F100E13304 /* decoders */ = {
+ isa = PBXGroup;
+ children = (
+ 2540405D166AA0F100E13304 /* AbstractDecoderTest.h */,
+ 2540405E166AA0F100E13304 /* AbstractDecoderTest.m */,
+ 2540405F166AA0F100E13304 /* AI01_3103_DecoderTest.h */,
+ 25404060166AA0F100E13304 /* AI01_3103_DecoderTest.m */,
+ 25404061166AA0F100E13304 /* AI01_3202_3203_DecoderTest.h */,
+ 25404062166AA0F100E13304 /* AI01_3202_3203_DecoderTest.m */,
+ 25404063166AA0F100E13304 /* AI01_3X0X_1X_DecoderTest.h */,
+ 25404064166AA0F100E13304 /* AI01_3X0X_1X_DecoderTest.m */,
+ 25404065166AA0F100E13304 /* AnyAIDecoderTest.h */,
+ 25404066166AA0F100E13304 /* AnyAIDecoderTest.m */,
+ 25404067166AA0F100E13304 /* ZXFieldParserTest.h */,
+ 25404068166AA0F100E13304 /* ZXFieldParserTest.m */,
+ );
+ path = decoders;
+ sourceTree = "<group>";
+ };
+ 254040A5166AA0F100E13304 /* pdf417 */ = {
+ isa = PBXGroup;
+ children = (
+ 254040A6166AA0F100E13304 /* decoder */,
+ 25389B8F18010D7A00772392 /* detector */,
+ 254040AC166AA0F100E13304 /* PDF417BlackBox1TestCase.h */,
+ 254040AD166AA0F100E13304 /* PDF417BlackBox1TestCase.m */,
+ 254040AE166AA0F100E13304 /* PDF417BlackBox2TestCase.h */,
+ 254040AF166AA0F100E13304 /* PDF417BlackBox2TestCase.m */,
+ 25E9E91717FA555400364861 /* PDF417BlackBox3TestCase.h */,
+ 25E9E91817FA555400364861 /* PDF417BlackBox3TestCase.m */,
+ 25B582971816F7B00013634A /* PDF417BlackBox4TestCase.h */,
+ 25B582981816F7B00013634A /* PDF417BlackBox4TestCase.m */,
+ );
+ path = pdf417;
+ sourceTree = "<group>";
+ };
+ 254040A6166AA0F100E13304 /* decoder */ = {
+ isa = PBXGroup;
+ children = (
+ 254040A7166AA0F100E13304 /* ec */,
+ );
+ path = decoder;
+ sourceTree = "<group>";
+ };
+ 254040A7166AA0F100E13304 /* ec */ = {
+ isa = PBXGroup;
+ children = (
+ 254040A8166AA0F100E13304 /* AbstractErrorCorrectionTestCase.h */,
+ 254040A9166AA0F100E13304 /* AbstractErrorCorrectionTestCase.m */,
+ 254040AA166AA0F100E13304 /* ZXPDF417ECErrorCorrectionTestCase.h */,
+ 254040AB166AA0F100E13304 /* ZXPDF417ECErrorCorrectionTestCase.m */,
+ );
+ path = ec;
+ sourceTree = "<group>";
+ };
+ 254040B0166AA0F100E13304 /* qrcode */ = {
+ isa = PBXGroup;
+ children = (
+ 254040B1166AA0F100E13304 /* decoder */,
+ 254040BE166AA0F100E13304 /* encoder */,
+ 254040C9166AA0F100E13304 /* QRCodeBlackBox1TestCase.h */,
+ 254040CA166AA0F100E13304 /* QRCodeBlackBox1TestCase.m */,
+ 254040CB166AA0F100E13304 /* QRCodeBlackBox2TestCase.h */,
+ 254040CC166AA0F100E13304 /* QRCodeBlackBox2TestCase.m */,
+ 254040CD166AA0F100E13304 /* QRCodeBlackBox3TestCase.h */,
+ 254040CE166AA0F100E13304 /* QRCodeBlackBox3TestCase.m */,
+ 254040CF166AA0F100E13304 /* QRCodeBlackBox4TestCase.h */,
+ 254040D0166AA0F100E13304 /* QRCodeBlackBox4TestCase.m */,
+ 254040D1166AA0F100E13304 /* QRCodeBlackBox5TestCase.h */,
+ 254040D2166AA0F100E13304 /* QRCodeBlackBox5TestCase.m */,
+ 254040D3166AA0F100E13304 /* QRCodeBlackBox6TestCase.h */,
+ 254040D4166AA0F100E13304 /* QRCodeBlackBox6TestCase.m */,
+ 254040D5166AA0F100E13304 /* ZXQRCodeWriterTestCase.h */,
+ 254040D6166AA0F100E13304 /* ZXQRCodeWriterTestCase.m */,
+ );
+ path = qrcode;
+ sourceTree = "<group>";
+ };
+ 254040B1166AA0F100E13304 /* decoder */ = {
+ isa = PBXGroup;
+ children = (
+ 254040B2166AA0F100E13304 /* ZXDataMaskTestCase.h */,
+ 254040B3166AA0F100E13304 /* ZXDataMaskTestCase.m */,
+ 254040B4166AA0F100E13304 /* ZXErrorCorrectionLevelTestCase.h */,
+ 254040B5166AA0F100E13304 /* ZXErrorCorrectionLevelTestCase.m */,
+ 254040B6166AA0F100E13304 /* ZXFormatInformationTestCase.h */,
+ 254040B7166AA0F100E13304 /* ZXFormatInformationTestCase.m */,
+ 254040B8166AA0F100E13304 /* ZXModeTestCase.h */,
+ 254040B9166AA0F100E13304 /* ZXModeTestCase.m */,
+ 254040BA166AA0F100E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.h */,
+ 254040BB166AA0F100E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.m */,
+ 254040BC166AA0F100E13304 /* ZXQRCodeVersionTestCase.h */,
+ 254040BD166AA0F100E13304 /* ZXQRCodeVersionTestCase.m */,
+ );
+ path = decoder;
+ sourceTree = "<group>";
+ };
+ 254040BE166AA0F100E13304 /* encoder */ = {
+ isa = PBXGroup;
+ children = (
+ 254040BF166AA0F100E13304 /* BitVectorTestCase.h */,
+ 254040C0166AA0F100E13304 /* BitVectorTestCase.m */,
+ 254040C1166AA0F100E13304 /* ZXEncoderTestCase.h */,
+ 254040C2166AA0F100E13304 /* ZXEncoderTestCase.m */,
+ 254040C3166AA0F100E13304 /* ZXMaskUtilTestCase.h */,
+ 254040C4166AA0F100E13304 /* ZXMaskUtilTestCase.m */,
+ 254040C5166AA0F100E13304 /* ZXMatrixUtilTestCase.h */,
+ 254040C6166AA0F100E13304 /* ZXMatrixUtilTestCase.m */,
+ 254040C7166AA0F100E13304 /* ZXQRCodeTestCase.h */,
+ 254040C8166AA0F100E13304 /* ZXQRCodeTestCase.m */,
+ );
+ path = encoder;
+ sourceTree = "<group>";
+ };
+ 2540438A166AB8EA00E13304 /* OS X Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 25404394166AB95700E13304 /* ApplicationServices.framework */,
+ 2540438F166AB91700E13304 /* Cocoa.framework */,
+ 25404387166AB8CF00E13304 /* CoreVideo.framework */,
+ 25404700166ABC3F00E13304 /* QTKit.framework */,
+ 254046FC166ABC1600E13304 /* QuartzCore.framework */,
+ );
+ name = "OS X Frameworks";
+ sourceTree = "<group>";
+ };
+ 2542998316D4788100D4C045 /* encoder */ = {
+ isa = PBXGroup;
+ children = (
+ 2542998416D478A000D4C045 /* ZXASCIIEncoder.h */,
+ 2542998516D478A000D4C045 /* ZXASCIIEncoder.m */,
+ 2542998D16D47BBF00D4C045 /* ZXBase256Encoder.h */,
+ 2542998E16D47BBF00D4C045 /* ZXBase256Encoder.m */,
+ 2542999716D482F800D4C045 /* ZXC40Encoder.h */,
+ 2542999816D482F800D4C045 /* ZXC40Encoder.m */,
+ 2542998C16D478F800D4C045 /* ZXDataMatrixEncoder.h */,
+ 254299BF16D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.h */,
+ 254299C016D5B8E400D4C045 /* ZXDataMatrixErrorCorrection.m */,
+ 2542999F16D4879800D4C045 /* ZXDataMatrixSymbolInfo144.h */,
+ 254299A016D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m */,
+ 254299A716D4886000D4C045 /* ZXDefaultPlacement.h */,
+ 254299A816D4886000D4C045 /* ZXDefaultPlacement.m */,
+ 254299AF16D4A36700D4C045 /* ZXEdifactEncoder.h */,
+ 254299B016D4A36700D4C045 /* ZXEdifactEncoder.m */,
+ 254299B716D4A5A900D4C045 /* ZXEncoderContext.h */,
+ 254299B816D4A5A900D4C045 /* ZXEncoderContext.m */,
+ 254299C716D5BD5300D4C045 /* ZXHighLevelEncoder.h */,
+ 254299C816D5BD5300D4C045 /* ZXHighLevelEncoder.m */,
+ 254299CF16D5C96000D4C045 /* ZXSymbolInfo.h */,
+ 254299D016D5C96000D4C045 /* ZXSymbolInfo.m */,
+ 254299D716D5D11E00D4C045 /* ZXSymbolShapeHint.h */,
+ 254299DF16D5D24D00D4C045 /* ZXSymbolShapeHint.m */,
+ 254299E316D5D81800D4C045 /* ZXTextEncoder.h */,
+ 254299E416D5D81900D4C045 /* ZXTextEncoder.m */,
+ 254299EB16D5D94900D4C045 /* ZXX12Encoder.h */,
+ 254299EC16D5D94A00D4C045 /* ZXX12Encoder.m */,
+ );
+ name = encoder;
+ sourceTree = "<group>";
+ };
+ 254299FD16D5DFBB00D4C045 /* encoder */ = {
+ isa = PBXGroup;
+ children = (
+ 25429A0216D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.h */,
+ 25429A0316D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m */,
+ 254299FE16D5DFD800D4C045 /* ZXDebugPlacement.h */,
+ 254299FF16D5DFD800D4C045 /* ZXDebugPlacement.m */,
+ 25429A0616D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.h */,
+ 25429A0716D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.m */,
+ 25429A0A16D5F4E000D4C045 /* ZXPlacementTestCase.h */,
+ 25429A0B16D5F4E000D4C045 /* ZXPlacementTestCase.m */,
+ 25429A0E16D5F66D00D4C045 /* ZXSymbolInfoTestCase.h */,
+ 25429A0F16D5F66D00D4C045 /* ZXSymbolInfoTestCase.m */,
+ );
+ name = encoder;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 25403CE2166A98B600E13304 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 25403CE3166A98C700E13304 /* ZXingObjC.h in Headers */,
+ 25403CF7166A999D00E13304 /* ZXAztecDecoder.h in Headers */,
+ 25403CF9166A999D00E13304 /* ZXAztecDetector.h in Headers */,
+ 25403CFB166A999D00E13304 /* ZXAztecDetectorResult.h in Headers */,
+ 25403CFD166A999D00E13304 /* ZXAztecReader.h in Headers */,
+ 25403D50166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.h in Headers */,
+ 25403D52166A9A0800E13304 /* ZXAddressBookAUResultParser.h in Headers */,
+ 25403D54166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.h in Headers */,
+ 25403D56166A9A0800E13304 /* ZXAddressBookParsedResult.h in Headers */,
+ 25403D58166A9A0800E13304 /* ZXBizcardResultParser.h in Headers */,
+ 25403D5A166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.h in Headers */,
+ 25403D5C166A9A0800E13304 /* ZXCalendarParsedResult.h in Headers */,
+ 2519AB7617FE649000A71C45 /* ZXPDF417Codeword.h in Headers */,
+ 25403D5E166A9A0800E13304 /* ZXEmailAddressParsedResult.h in Headers */,
+ 25403D60166A9A0800E13304 /* ZXEmailAddressResultParser.h in Headers */,
+ 25403D62166A9A0800E13304 /* ZXEmailDoCoMoResultParser.h in Headers */,
+ 25403D64166A9A0800E13304 /* ZXExpandedProductParsedResult.h in Headers */,
+ 25403D66166A9A0800E13304 /* ZXExpandedProductResultParser.h in Headers */,
+ 2519AB6617FE5F2E00A71C45 /* ZXPDF417BarcodeValue.h in Headers */,
+ 25403D68166A9A0800E13304 /* ZXGeoParsedResult.h in Headers */,
+ 25403D6A166A9A0800E13304 /* ZXGeoResultParser.h in Headers */,
+ 25403D6C166A9A0800E13304 /* ZXISBNParsedResult.h in Headers */,
+ 25403D6E166A9A0800E13304 /* ZXISBNResultParser.h in Headers */,
+ 25403D70166A9A0800E13304 /* ZXParsedResult.h in Headers */,
+ 25403D72166A9A0800E13304 /* ZXParsedResultType.h in Headers */,
+ 25403D73166A9A0800E13304 /* ZXProductParsedResult.h in Headers */,
+ 25403D75166A9A0800E13304 /* ZXProductResultParser.h in Headers */,
+ 25403D77166A9A0800E13304 /* ZXResultParser.h in Headers */,
+ 25403D79166A9A0800E13304 /* ZXSMSMMSResultParser.h in Headers */,
+ 25403D7B166A9A0800E13304 /* ZXSMSParsedResult.h in Headers */,
+ 25403D7D166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.h in Headers */,
+ 25403D7F166A9A0800E13304 /* ZXSMTPResultParser.h in Headers */,
+ 25403D81166A9A0800E13304 /* ZXTelParsedResult.h in Headers */,
+ 25403D83166A9A0800E13304 /* ZXTelResultParser.h in Headers */,
+ 25403D85166A9A0800E13304 /* ZXTextParsedResult.h in Headers */,
+ 25403D87166A9A0800E13304 /* ZXURIParsedResult.h in Headers */,
+ 25403D89166A9A0800E13304 /* ZXURIResultParser.h in Headers */,
+ 25403D8B166A9A0800E13304 /* ZXURLTOResultParser.h in Headers */,
+ 25403D8D166A9A0800E13304 /* ZXVCardResultParser.h in Headers */,
+ 25403D8F166A9A0800E13304 /* ZXVEventResultParser.h in Headers */,
+ 25403D91166A9A0800E13304 /* ZXWifiParsedResult.h in Headers */,
+ 25403D93166A9A0800E13304 /* ZXWifiResultParser.h in Headers */,
+ 25403D95166A9A0800E13304 /* ZXCapture.h in Headers */,
+ 25403D97166A9A0800E13304 /* ZXCaptureDelegate.h in Headers */,
+ 25403D98166A9A0800E13304 /* ZXCaptureView.h in Headers */,
+ 25403D9A166A9A0800E13304 /* ZXCGImageLuminanceSource.h in Headers */,
+ 25403D9C166A9A0800E13304 /* ZXImage.h in Headers */,
+ 25403D9E166A9A0800E13304 /* ZXView.h in Headers */,
+ 25403DCA166A9C0E00E13304 /* ZXMathUtils.h in Headers */,
+ 2519AB4417FE554D00A71C45 /* ZXPDF417Common.h in Headers */,
+ 25403DCC166A9C0E00E13304 /* ZXMonochromeRectangleDetector.h in Headers */,
+ 25403DCE166A9C0E00E13304 /* ZXWhiteRectangleDetector.h in Headers */,
+ 25403DD0166A9C0E00E13304 /* ZXGenericGF.h in Headers */,
+ 25403DD2166A9C0E00E13304 /* ZXGenericGFPoly.h in Headers */,
+ 25403DD4166A9C0E00E13304 /* ZXReedSolomonDecoder.h in Headers */,
+ 25403DD6166A9C0E00E13304 /* ZXReedSolomonEncoder.h in Headers */,
+ 25403DD8166A9C0E00E13304 /* ZXBitArray.h in Headers */,
+ 25403DDA166A9C0E00E13304 /* ZXBitMatrix.h in Headers */,
+ 25403DDC166A9C0E00E13304 /* ZXBitSource.h in Headers */,
+ 25403DDE166A9C0E00E13304 /* ZXCharacterSetECI.h in Headers */,
+ 2519AB4817FE5C1F00A71C45 /* ZXPDF417ResultMetadata.h in Headers */,
+ 25403DE0166A9C0E00E13304 /* ZXDecoderResult.h in Headers */,
+ 25403DE2166A9C0E00E13304 /* ZXDefaultGridSampler.h in Headers */,
+ 25403DE4166A9C0E00E13304 /* ZXDetectorResult.h in Headers */,
+ 25403DE6166A9C0E00E13304 /* ZXECI.h in Headers */,
+ 25403DE8166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.h in Headers */,
+ 25403DEA166A9C0E00E13304 /* ZXGridSampler.h in Headers */,
+ 25403DEC166A9C0E00E13304 /* ZXHybridBinarizer.h in Headers */,
+ 25403DEE166A9C0E00E13304 /* ZXPerspectiveTransform.h in Headers */,
+ 25403DF0166A9C0E00E13304 /* ZXStringUtils.h in Headers */,
+ 25403E03166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.h in Headers */,
+ 25403E05166A9CCB00E13304 /* ZXDataMatrixDataBlock.h in Headers */,
+ 25403E07166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.h in Headers */,
+ 25403E09166A9CCB00E13304 /* ZXDataMatrixDecoder.h in Headers */,
+ 25403E0B166A9CCB00E13304 /* ZXDataMatrixVersion.h in Headers */,
+ 25403E0D166A9CCB00E13304 /* ZXDataMatrixDetector.h in Headers */,
+ 25403E0F166A9CCB00E13304 /* ZXDataMatrixReader.h in Headers */,
+ 25403E1B166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.h in Headers */,
+ 25403E1D166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.h in Headers */,
+ 25403E1F166A9D4B00E13304 /* ZXMaxiCodeDecoder.h in Headers */,
+ 25403E21166A9D4B00E13304 /* ZXMaxiCodeReader.h in Headers */,
+ 25403E31166A9D8B00E13304 /* ZXMultiDetector.h in Headers */,
+ 25403E33166A9D8B00E13304 /* ZXMultiFinderPatternFinder.h in Headers */,
+ 25403E35166A9D8B00E13304 /* ZXQRCodeMultiReader.h in Headers */,
+ 25403E37166A9D8B00E13304 /* ZXByQuadrantReader.h in Headers */,
+ 25403E39166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.h in Headers */,
+ 25403E3B166A9D8B00E13304 /* ZXMultipleBarcodeReader.h in Headers */,
+ 25403EAC166A9DF400E13304 /* ZXAbstractExpandedDecoder.h in Headers */,
+ 25403EAE166A9DF400E13304 /* ZXAI013103decoder.h in Headers */,
+ 25403EB0166A9DF400E13304 /* ZXAI01320xDecoder.h in Headers */,
+ 25403EB2166A9DF400E13304 /* ZXAI01392xDecoder.h in Headers */,
+ 25403EB4166A9DF400E13304 /* ZXAI01393xDecoder.h in Headers */,
+ 25403EB6166A9DF400E13304 /* ZXAI013x0x1xDecoder.h in Headers */,
+ 25403EB8166A9DF400E13304 /* ZXAI013x0xDecoder.h in Headers */,
+ 25403EBA166A9DF400E13304 /* ZXAI01AndOtherAIs.h in Headers */,
+ 25403EBC166A9DF400E13304 /* ZXAI01decoder.h in Headers */,
+ 25403EBE166A9DF400E13304 /* ZXAI01weightDecoder.h in Headers */,
+ 25403EC0166A9DF400E13304 /* ZXAnyAIDecoder.h in Headers */,
+ 25403EC2166A9DF400E13304 /* ZXBlockParsedResult.h in Headers */,
+ 2519AB5E17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.h in Headers */,
+ 25403EC4166A9DF400E13304 /* ZXCurrentParsingState.h in Headers */,
+ 25403EC6166A9DF400E13304 /* ZXDecodedChar.h in Headers */,
+ 25403EC8166A9DF400E13304 /* ZXDecodedInformation.h in Headers */,
+ 25403ECA166A9DF400E13304 /* ZXDecodedNumeric.h in Headers */,
+ 25403ECC166A9DF400E13304 /* ZXDecodedObject.h in Headers */,
+ 25403ECE166A9DF400E13304 /* ZXFieldParser.h in Headers */,
+ 25403ED0166A9DF400E13304 /* ZXGeneralAppIdDecoder.h in Headers */,
+ 25403ED2166A9DF400E13304 /* ZXBitArrayBuilder.h in Headers */,
+ 25403ED4166A9DF400E13304 /* ZXExpandedPair.h in Headers */,
+ 25403ED6166A9DF400E13304 /* ZXRSSExpandedReader.h in Headers */,
+ 25403ED8166A9DF400E13304 /* ZXAbstractRSSReader.h in Headers */,
+ 25403EDA166A9DF400E13304 /* ZXDataCharacter.h in Headers */,
+ 25403EDC166A9DF400E13304 /* ZXPair.h in Headers */,
+ 25403EDE166A9DF400E13304 /* ZXRSS14Reader.h in Headers */,
+ 25403EE0166A9DF400E13304 /* ZXRSSFinderPattern.h in Headers */,
+ 25403EE2166A9DF400E13304 /* ZXRSSUtils.h in Headers */,
+ 2519AB3C17FD1EE400A71C45 /* ZXPDF417Writer.h in Headers */,
+ 25403EE4166A9DF400E13304 /* ZXCodaBarReader.h in Headers */,
+ 25403EE6166A9DF400E13304 /* ZXCodaBarWriter.h in Headers */,
+ 25403EE8166A9DF400E13304 /* ZXCode128Reader.h in Headers */,
+ 25403EEA166A9DF400E13304 /* ZXCode128Writer.h in Headers */,
+ 25403EEC166A9DF400E13304 /* ZXCode39Reader.h in Headers */,
+ 25403EEE166A9DF400E13304 /* ZXCode39Writer.h in Headers */,
+ 25403EF0166A9DF400E13304 /* ZXCode93Reader.h in Headers */,
+ 25403EF2166A9DF400E13304 /* ZXEAN13Reader.h in Headers */,
+ 25403EF4166A9DF400E13304 /* ZXEAN13Writer.h in Headers */,
+ 25403EF6166A9DF400E13304 /* ZXEAN8Reader.h in Headers */,
+ 25403EF8166A9DF400E13304 /* ZXEAN8Writer.h in Headers */,
+ 25403EFA166A9DF400E13304 /* ZXEANManufacturerOrgSupport.h in Headers */,
+ 25403EFC166A9DF400E13304 /* ZXITFReader.h in Headers */,
+ 25403EFE166A9DF400E13304 /* ZXITFWriter.h in Headers */,
+ 25403F00166A9DF400E13304 /* ZXMultiFormatOneDReader.h in Headers */,
+ 25403F02166A9DF400E13304 /* ZXMultiFormatUPCEANReader.h in Headers */,
+ 25403F04166A9DF400E13304 /* ZXOneDimensionalCodeWriter.h in Headers */,
+ 25403F06166A9DF400E13304 /* ZXOneDReader.h in Headers */,
+ 25403F08166A9DF400E13304 /* ZXUPCAReader.h in Headers */,
+ 25403F0A166A9DF400E13304 /* ZXUPCAWriter.h in Headers */,
+ 25403F0C166A9DF400E13304 /* ZXUPCEANExtension2Support.h in Headers */,
+ 25403F0E166A9DF400E13304 /* ZXUPCEANExtension5Support.h in Headers */,
+ 25403F10166A9DF400E13304 /* ZXUPCEANExtensionSupport.h in Headers */,
+ 25403F12166A9DF400E13304 /* ZXUPCEANReader.h in Headers */,
+ 25403F14166A9DF400E13304 /* ZXUPCEANWriter.h in Headers */,
+ 25403F16166A9DF400E13304 /* ZXUPCEReader.h in Headers */,
+ 25403F3C166A9EB500E13304 /* ZXModulusGF.h in Headers */,
+ 25403F3E166A9EB500E13304 /* ZXModulusPoly.h in Headers */,
+ 25403F40166A9EB500E13304 /* ZXPDF417ECErrorCorrection.h in Headers */,
+ 25403F44166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.h in Headers */,
+ 25403F48166A9EB500E13304 /* ZXPDF417Detector.h in Headers */,
+ 25403F4A166A9EB500E13304 /* ZXBarcodeMatrix.h in Headers */,
+ 25403F4C166A9EB500E13304 /* ZXBarcodeRow.h in Headers */,
+ 25403F4E166A9EB500E13304 /* ZXCompaction.h in Headers */,
+ 25403F4F166A9EB500E13304 /* ZXDimensions.h in Headers */,
+ 25403F51166A9EB500E13304 /* ZXPDF417.h in Headers */,
+ 25403F53166A9EB500E13304 /* ZXPDF417ErrorCorrection.h in Headers */,
+ 25403F55166A9EB500E13304 /* ZXPDF417HighLevelEncoder.h in Headers */,
+ 25403F59166A9EB500E13304 /* ZXPDF417Reader.h in Headers */,
+ 25403F8D166A9F2D00E13304 /* ZXDataMask.h in Headers */,
+ 25403F8F166A9F2D00E13304 /* ZXErrorCorrectionLevel.h in Headers */,
+ 25403F91166A9F2D00E13304 /* ZXFormatInformation.h in Headers */,
+ 25403F93166A9F2D00E13304 /* ZXMode.h in Headers */,
+ 25403F95166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.h in Headers */,
+ 25403F97166A9F2D00E13304 /* ZXQRCodeDataBlock.h in Headers */,
+ 25403F99166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.h in Headers */,
+ 25403F9B166A9F2D00E13304 /* ZXQRCodeDecoder.h in Headers */,
+ 25403F9D166A9F2D00E13304 /* ZXQRCodeVersion.h in Headers */,
+ 25403F9F166A9F2D00E13304 /* ZXAlignmentPattern.h in Headers */,
+ 25403FA1166A9F2D00E13304 /* ZXAlignmentPatternFinder.h in Headers */,
+ 25403FA3166A9F2D00E13304 /* ZXFinderPatternFinder.h in Headers */,
+ 25403FA5166A9F2D00E13304 /* ZXFinderPatternInfo.h in Headers */,
+ 25403FA7166A9F2D00E13304 /* ZXQRCodeDetector.h in Headers */,
+ 25403FA9166A9F2D00E13304 /* ZXQRCodeFinderPattern.h in Headers */,
+ 25403FAB166A9F2D00E13304 /* ZXBlockPair.h in Headers */,
+ 25403FAD166A9F2D00E13304 /* ZXByteMatrix.h in Headers */,
+ 25403FAF166A9F2D00E13304 /* ZXEncoder.h in Headers */,
+ 25403FB1166A9F2D00E13304 /* ZXMaskUtil.h in Headers */,
+ 25403FB3166A9F2D00E13304 /* ZXMatrixUtil.h in Headers */,
+ 25403FB5166A9F2D00E13304 /* ZXQRCode.h in Headers */,
+ 25403FB7166A9F2D00E13304 /* ZXQRCodeReader.h in Headers */,
+ 25403FB9166A9F2D00E13304 /* ZXQRCodeWriter.h in Headers */,
+ 25403FC6166A9FFC00E13304 /* ZXBarcodeFormat.h in Headers */,
+ 25403FC7166A9FFC00E13304 /* ZXBinarizer.h in Headers */,
+ 25403FC9166A9FFC00E13304 /* ZXBinaryBitmap.h in Headers */,
+ 25403FCB166A9FFC00E13304 /* ZXDecodeHints.h in Headers */,
+ 25403FCD166A9FFC00E13304 /* ZXEncodeHints.h in Headers */,
+ 25403FCF166A9FFC00E13304 /* ZXErrors.h in Headers */,
+ 25403FDF166AA00800E13304 /* ZXLuminanceSource.h in Headers */,
+ 25403FE1166AA00800E13304 /* ZXMultiFormatReader.h in Headers */,
+ 25403FE3166AA00800E13304 /* ZXMultiFormatWriter.h in Headers */,
+ 25403FE5166AA00800E13304 /* ZXReader.h in Headers */,
+ 25403FE6166AA00800E13304 /* ZXResult.h in Headers */,
+ 25403FE8166AA00800E13304 /* ZXResultMetadataType.h in Headers */,
+ 25403FE9166AA00800E13304 /* ZXResultPoint.h in Headers */,
+ 25403FEB166AA00800E13304 /* ZXResultPointCallback.h in Headers */,
+ 25403FEC166AA00800E13304 /* ZXWriter.h in Headers */,
+ 251FCDEB16CC8F53000C27E5 /* ZXRGBLuminanceSource.h in Headers */,
+ 25FE5D3316D0AFED00826CDB /* ZXExpandedRow.h in Headers */,
+ 2542996D16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.h in Headers */,
+ 2542997D16D470D600D4C045 /* ZXDataMatrixWriter.h in Headers */,
+ 2542998616D478A000D4C045 /* ZXASCIIEncoder.h in Headers */,
+ 25389B791800DEC300772392 /* ZXPDF417CodewordDecoder.h in Headers */,
+ 25389B8918010B9A00772392 /* ZXPDF417DetectorResult.h in Headers */,
+ 2519AB3417FD1EC000A71C45 /* ZXAztecWriter.h in Headers */,
+ 25389B6917FFC98100772392 /* ZXPDF417DetectionResultColumn.h in Headers */,
+ 25389B7117FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.h in Headers */,
+ 2542997516D46E8500D4C045 /* ZXDimension.h in Headers */,
+ 2542999916D482F900D4C045 /* ZXC40Encoder.h in Headers */,
+ 254299A116D4879800D4C045 /* ZXDataMatrixSymbolInfo144.h in Headers */,
+ 254299A916D4886100D4C045 /* ZXDefaultPlacement.h in Headers */,
+ 254299B116D4A36700D4C045 /* ZXEdifactEncoder.h in Headers */,
+ 25389B811800E35B00772392 /* ZXPDF417ScanningDecoder.h in Headers */,
+ 254299B916D4A5AA00D4C045 /* ZXEncoderContext.h in Headers */,
+ 254299C116D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.h in Headers */,
+ 254299C916D5BD5400D4C045 /* ZXHighLevelEncoder.h in Headers */,
+ 254299D116D5C96100D4C045 /* ZXSymbolInfo.h in Headers */,
+ 254299D916D5D12000D4C045 /* ZXSymbolShapeHint.h in Headers */,
+ 254299E516D5D81A00D4C045 /* ZXTextEncoder.h in Headers */,
+ 254299ED16D5D94B00D4C045 /* ZXX12Encoder.h in Headers */,
+ 255B9DB116FFCDE000EEEE61 /* ZXDataMatrixEncoder.h in Headers */,
+ 2542998F16D47BC000D4C045 /* ZXBase256Encoder.h in Headers */,
+ 25389B6017FFC84300772392 /* ZXPDF417DetectionResult.h in Headers */,
+ 2504D4C616F698AA00DF8882 /* ZXInvertedLuminanceSource.h in Headers */,
+ 2504D9CF16FFD2E200DF8882 /* ZXAztecCode.h in Headers */,
+ 2519AB6E17FE60E700A71C45 /* ZXPDF417BoundingBox.h in Headers */,
+ 2504D9DC16FFD4CD00DF8882 /* ZXAztecEncoder.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25404164166AADAC00E13304 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2540452B166ABAF000E13304 /* ZXAztecDecoder.h in Headers */,
+ 2540452C166ABAF000E13304 /* ZXAztecDetector.h in Headers */,
+ 2540452D166ABAF000E13304 /* ZXAztecDetectorResult.h in Headers */,
+ 2540452E166ABAF000E13304 /* ZXAztecReader.h in Headers */,
+ 2540452F166ABAF000E13304 /* ZXAbstractDoCoMoResultParser.h in Headers */,
+ 25404530166ABAF000E13304 /* ZXAddressBookAUResultParser.h in Headers */,
+ 25404531166ABAF000E13304 /* ZXAddressBookDoCoMoResultParser.h in Headers */,
+ 25404532166ABAF000E13304 /* ZXAddressBookParsedResult.h in Headers */,
+ 25404533166ABAF000E13304 /* ZXBizcardResultParser.h in Headers */,
+ 25404534166ABAF000E13304 /* ZXBookmarkDoCoMoResultParser.h in Headers */,
+ 25404535166ABAF000E13304 /* ZXCalendarParsedResult.h in Headers */,
+ 25404536166ABAF000E13304 /* ZXEmailAddressParsedResult.h in Headers */,
+ 25404537166ABAF000E13304 /* ZXEmailAddressResultParser.h in Headers */,
+ 25404538166ABAF000E13304 /* ZXEmailDoCoMoResultParser.h in Headers */,
+ 25404539166ABAF000E13304 /* ZXExpandedProductParsedResult.h in Headers */,
+ 2540453A166ABAF000E13304 /* ZXExpandedProductResultParser.h in Headers */,
+ 2540453B166ABAF000E13304 /* ZXGeoParsedResult.h in Headers */,
+ 2540453C166ABAF000E13304 /* ZXGeoResultParser.h in Headers */,
+ 2540453D166ABAF000E13304 /* ZXISBNParsedResult.h in Headers */,
+ 2540453E166ABAF000E13304 /* ZXISBNResultParser.h in Headers */,
+ 2540453F166ABAF000E13304 /* ZXParsedResult.h in Headers */,
+ 25404540166ABAF000E13304 /* ZXParsedResultType.h in Headers */,
+ 25404541166ABAF000E13304 /* ZXProductParsedResult.h in Headers */,
+ 25404542166ABAF000E13304 /* ZXProductResultParser.h in Headers */,
+ 25404543166ABAF000E13304 /* ZXResultParser.h in Headers */,
+ 25404544166ABAF000E13304 /* ZXSMSMMSResultParser.h in Headers */,
+ 25404545166ABAF000E13304 /* ZXSMSParsedResult.h in Headers */,
+ 25404546166ABAF000E13304 /* ZXSMSTOMMSTOResultParser.h in Headers */,
+ 25404547166ABAF000E13304 /* ZXSMTPResultParser.h in Headers */,
+ 25404548166ABAF000E13304 /* ZXTelParsedResult.h in Headers */,
+ 25404549166ABAF000E13304 /* ZXTelResultParser.h in Headers */,
+ 2540454A166ABAF000E13304 /* ZXTextParsedResult.h in Headers */,
+ 2540454B166ABAF000E13304 /* ZXURIParsedResult.h in Headers */,
+ 2540454C166ABAF000E13304 /* ZXURIResultParser.h in Headers */,
+ 2540454D166ABAF000E13304 /* ZXURLTOResultParser.h in Headers */,
+ 2540454E166ABAF000E13304 /* ZXVCardResultParser.h in Headers */,
+ 2540454F166ABAF000E13304 /* ZXVEventResultParser.h in Headers */,
+ 25404550166ABAF000E13304 /* ZXWifiParsedResult.h in Headers */,
+ 25404551166ABAF000E13304 /* ZXWifiResultParser.h in Headers */,
+ 25404552166ABAF000E13304 /* ZXCapture.h in Headers */,
+ 25404553166ABAF000E13304 /* ZXCaptureDelegate.h in Headers */,
+ 25404554166ABAF000E13304 /* ZXCaptureView.h in Headers */,
+ 25404555166ABAF000E13304 /* ZXCGImageLuminanceSource.h in Headers */,
+ 25404556166ABAF000E13304 /* ZXImage.h in Headers */,
+ 25404557166ABAF000E13304 /* ZXView.h in Headers */,
+ 25404558166ABAF000E13304 /* ZXMathUtils.h in Headers */,
+ 25404559166ABAF000E13304 /* ZXMonochromeRectangleDetector.h in Headers */,
+ 2540455A166ABAF000E13304 /* ZXWhiteRectangleDetector.h in Headers */,
+ 2540455B166ABAF000E13304 /* ZXGenericGF.h in Headers */,
+ 2540455C166ABAF000E13304 /* ZXGenericGFPoly.h in Headers */,
+ 2540455D166ABAF000E13304 /* ZXReedSolomonDecoder.h in Headers */,
+ 2519AB5F17FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.h in Headers */,
+ 2540455E166ABAF000E13304 /* ZXReedSolomonEncoder.h in Headers */,
+ 2540455F166ABAF000E13304 /* ZXBitArray.h in Headers */,
+ 25404560166ABAF000E13304 /* ZXBitMatrix.h in Headers */,
+ 25404561166ABAF000E13304 /* ZXBitSource.h in Headers */,
+ 25404562166ABAF000E13304 /* ZXCharacterSetECI.h in Headers */,
+ 25404563166ABAF000E13304 /* ZXDecoderResult.h in Headers */,
+ 25404564166ABAF000E13304 /* ZXDefaultGridSampler.h in Headers */,
+ 25404565166ABAF000E13304 /* ZXDetectorResult.h in Headers */,
+ 25404566166ABAF000E13304 /* ZXECI.h in Headers */,
+ 25389B6517FFC84F00772392 /* ZXPDF417DecodedBitStreamParser.h in Headers */,
+ 2519AB6F17FE60E700A71C45 /* ZXPDF417BoundingBox.h in Headers */,
+ 25404567166ABAF000E13304 /* ZXGlobalHistogramBinarizer.h in Headers */,
+ 25404568166ABAF000E13304 /* ZXGridSampler.h in Headers */,
+ 25404569166ABAF000E13304 /* ZXHybridBinarizer.h in Headers */,
+ 2540456A166ABAF000E13304 /* ZXPerspectiveTransform.h in Headers */,
+ 2540456B166ABAF000E13304 /* ZXStringUtils.h in Headers */,
+ 2540456C166ABAF000E13304 /* ZXDataMatrixBitMatrixParser.h in Headers */,
+ 2540456D166ABAF000E13304 /* ZXDataMatrixDataBlock.h in Headers */,
+ 2540456E166ABAF000E13304 /* ZXDataMatrixDecodedBitStreamParser.h in Headers */,
+ 2519AB7717FE649000A71C45 /* ZXPDF417Codeword.h in Headers */,
+ 2540456F166ABAF000E13304 /* ZXDataMatrixDecoder.h in Headers */,
+ 25404570166ABAF000E13304 /* ZXDataMatrixVersion.h in Headers */,
+ 25404571166ABAF000E13304 /* ZXDataMatrixDetector.h in Headers */,
+ 25404572166ABAF000E13304 /* ZXDataMatrixReader.h in Headers */,
+ 25404573166ABAF000E13304 /* ZXMaxiCodeBitMatrixParser.h in Headers */,
+ 25404574166ABAF000E13304 /* ZXMaxiCodeDecodedBitStreamParser.h in Headers */,
+ 25404575166ABAF000E13304 /* ZXMaxiCodeDecoder.h in Headers */,
+ 2519AB3D17FD1EE400A71C45 /* ZXPDF417Writer.h in Headers */,
+ 25404576166ABAF000E13304 /* ZXMaxiCodeReader.h in Headers */,
+ 25404577166ABAF000E13304 /* ZXMultiDetector.h in Headers */,
+ 25404578166ABAF000E13304 /* ZXMultiFinderPatternFinder.h in Headers */,
+ 25404579166ABAF000E13304 /* ZXQRCodeMultiReader.h in Headers */,
+ 2540457A166ABAF000E13304 /* ZXByQuadrantReader.h in Headers */,
+ 2540457B166ABAF000E13304 /* ZXGenericMultipleBarcodeReader.h in Headers */,
+ 2540457C166ABAF000E13304 /* ZXMultipleBarcodeReader.h in Headers */,
+ 2540457D166ABAF000E13304 /* ZXPDF417Detector.h in Headers */,
+ 2540457E166ABAF000E13304 /* ZXBarcodeMatrix.h in Headers */,
+ 2540457F166ABAF000E13304 /* ZXBarcodeRow.h in Headers */,
+ 25404580166ABAF000E13304 /* ZXCompaction.h in Headers */,
+ 25404581166ABAF000E13304 /* ZXDimensions.h in Headers */,
+ 25404582166ABAF000E13304 /* ZXPDF417.h in Headers */,
+ 25404583166ABAF000E13304 /* ZXPDF417ErrorCorrection.h in Headers */,
+ 25404584166ABAF000E13304 /* ZXPDF417HighLevelEncoder.h in Headers */,
+ 25404586166ABAF000E13304 /* ZXPDF417Reader.h in Headers */,
+ 25404587166ABAF000E13304 /* ZXDataMask.h in Headers */,
+ 25404588166ABAF000E13304 /* ZXErrorCorrectionLevel.h in Headers */,
+ 25404589166ABAF000E13304 /* ZXFormatInformation.h in Headers */,
+ 2540458A166ABAF000E13304 /* ZXMode.h in Headers */,
+ 2540458B166ABAF000E13304 /* ZXQRCodeBitMatrixParser.h in Headers */,
+ 2540458C166ABAF000E13304 /* ZXQRCodeDataBlock.h in Headers */,
+ 2540458D166ABAF000E13304 /* ZXQRCodeDecodedBitStreamParser.h in Headers */,
+ 2540458E166ABAF000E13304 /* ZXQRCodeDecoder.h in Headers */,
+ 2540458F166ABAF000E13304 /* ZXQRCodeVersion.h in Headers */,
+ 25404590166ABAF000E13304 /* ZXAlignmentPattern.h in Headers */,
+ 25404591166ABAF000E13304 /* ZXAlignmentPatternFinder.h in Headers */,
+ 25404592166ABAF000E13304 /* ZXFinderPatternFinder.h in Headers */,
+ 25404593166ABAF000E13304 /* ZXFinderPatternInfo.h in Headers */,
+ 25404594166ABAF000E13304 /* ZXQRCodeDetector.h in Headers */,
+ 25404595166ABAF000E13304 /* ZXQRCodeFinderPattern.h in Headers */,
+ 25404596166ABAF000E13304 /* ZXBlockPair.h in Headers */,
+ 25404597166ABAF000E13304 /* ZXByteMatrix.h in Headers */,
+ 25404598166ABAF000E13304 /* ZXEncoder.h in Headers */,
+ 25404599166ABAF000E13304 /* ZXMaskUtil.h in Headers */,
+ 2540459A166ABAF000E13304 /* ZXMatrixUtil.h in Headers */,
+ 2540459B166ABAF000E13304 /* ZXQRCode.h in Headers */,
+ 2519AB5017FE5C4500A71C45 /* ZXPDF417Common.h in Headers */,
+ 2540459C166ABAF000E13304 /* ZXQRCodeReader.h in Headers */,
+ 2540459D166ABAF000E13304 /* ZXQRCodeWriter.h in Headers */,
+ 2540459E166ABAF000E13304 /* ZXBinarizer.h in Headers */,
+ 2519AB6717FE5F2E00A71C45 /* ZXPDF417BarcodeValue.h in Headers */,
+ 2540459F166ABAF000E13304 /* ZXBinaryBitmap.h in Headers */,
+ 254045A0166ABAF000E13304 /* ZXDecodeHints.h in Headers */,
+ 2519AB5217FE5C5400A71C45 /* ZXPDF417ResultMetadata.h in Headers */,
+ 25389B6117FFC84300772392 /* ZXPDF417DetectionResult.h in Headers */,
+ 254045A1166ABAF000E13304 /* ZXEncodeHints.h in Headers */,
+ 254045A2166ABAF000E13304 /* ZXErrors.h in Headers */,
+ 254045A3166ABAF000E13304 /* ZXingObjC.h in Headers */,
+ 254045A4166ABAF000E13304 /* ZXLuminanceSource.h in Headers */,
+ 254045A5166ABAF000E13304 /* ZXMultiFormatReader.h in Headers */,
+ 254045A6166ABAF000E13304 /* ZXMultiFormatWriter.h in Headers */,
+ 254045A7166ABAF000E13304 /* ZXReader.h in Headers */,
+ 254045A8166ABAF000E13304 /* ZXResult.h in Headers */,
+ 254045A9166ABAF000E13304 /* ZXResultMetadataType.h in Headers */,
+ 254045AA166ABAF000E13304 /* ZXResultPoint.h in Headers */,
+ 254045AB166ABAF000E13304 /* ZXResultPointCallback.h in Headers */,
+ 254045AC166ABAF000E13304 /* ZXWriter.h in Headers */,
+ 251FCDEC16CC8F53000C27E5 /* ZXRGBLuminanceSource.h in Headers */,
+ 2542996F16D3334100D4C045 /* ZXPlanarYUVLuminanceSource.h in Headers */,
+ 2542997716D46FE900D4C045 /* ZXDimension.h in Headers */,
+ 25389B6A17FFC98100772392 /* ZXPDF417DetectionResultColumn.h in Headers */,
+ 25389B7217FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.h in Headers */,
+ 25389B821800E35B00772392 /* ZXPDF417ScanningDecoder.h in Headers */,
+ 2519AB3517FD1EC000A71C45 /* ZXAztecWriter.h in Headers */,
+ 25389B8A18010B9A00772392 /* ZXPDF417DetectorResult.h in Headers */,
+ 25389B7A1800DEC300772392 /* ZXPDF417CodewordDecoder.h in Headers */,
+ 2542999A16D482F900D4C045 /* ZXC40Encoder.h in Headers */,
+ 254299A216D4879800D4C045 /* ZXDataMatrixSymbolInfo144.h in Headers */,
+ 254299AA16D4886100D4C045 /* ZXDefaultPlacement.h in Headers */,
+ 254299B216D4A36700D4C045 /* ZXEdifactEncoder.h in Headers */,
+ 254299BA16D4A5AA00D4C045 /* ZXEncoderContext.h in Headers */,
+ 254299C216D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.h in Headers */,
+ 254299CA16D5BD5400D4C045 /* ZXHighLevelEncoder.h in Headers */,
+ 254299D216D5C96100D4C045 /* ZXSymbolInfo.h in Headers */,
+ 254299DA16D5D12000D4C045 /* ZXSymbolShapeHint.h in Headers */,
+ 254299E616D5D81A00D4C045 /* ZXTextEncoder.h in Headers */,
+ 254299EE16D5D94B00D4C045 /* ZXX12Encoder.h in Headers */,
+ 255B9DB216FFCDE100EEEE61 /* ZXDataMatrixEncoder.h in Headers */,
+ 2504D9E216FFEB8100DF8882 /* ZXAztecEncoder.h in Headers */,
+ 2542997F16D470E600D4C045 /* ZXDataMatrixWriter.h in Headers */,
+ 2542998716D478A000D4C045 /* ZXASCIIEncoder.h in Headers */,
+ 2542999016D47BC000D4C045 /* ZXBase256Encoder.h in Headers */,
+ 2504D4C816F698BE00DF8882 /* ZXInvertedLuminanceSource.h in Headers */,
+ 2504D9D116FFD3A100DF8882 /* ZXAztecCode.h in Headers */,
+ 255E490218143AC600A03A28 /* ZXAbstractExpandedDecoder.h in Headers */,
+ 255E490318143AC600A03A28 /* ZXAI013103decoder.h in Headers */,
+ 255E490418143AC600A03A28 /* ZXAI01320xDecoder.h in Headers */,
+ 255E490518143AC600A03A28 /* ZXAI01392xDecoder.h in Headers */,
+ 255E490618143AC600A03A28 /* ZXAI01393xDecoder.h in Headers */,
+ 255E490718143AC600A03A28 /* ZXAI013x0x1xDecoder.h in Headers */,
+ 255E490818143AC600A03A28 /* ZXAI013x0xDecoder.h in Headers */,
+ 255E490918143AC600A03A28 /* ZXAI01AndOtherAIs.h in Headers */,
+ 255E490A18143AC600A03A28 /* ZXAI01decoder.h in Headers */,
+ 255E490B18143AC600A03A28 /* ZXAI01weightDecoder.h in Headers */,
+ 255E490C18143AC600A03A28 /* ZXAnyAIDecoder.h in Headers */,
+ 255E490D18143AC600A03A28 /* ZXBlockParsedResult.h in Headers */,
+ 255E490E18143AC600A03A28 /* ZXCurrentParsingState.h in Headers */,
+ 255E490F18143AC600A03A28 /* ZXDecodedChar.h in Headers */,
+ 255E491018143AC600A03A28 /* ZXDecodedInformation.h in Headers */,
+ 255E491118143AC600A03A28 /* ZXDecodedNumeric.h in Headers */,
+ 255E491218143AC600A03A28 /* ZXDecodedObject.h in Headers */,
+ 255E491318143AC600A03A28 /* ZXFieldParser.h in Headers */,
+ 255E491418143AC600A03A28 /* ZXGeneralAppIdDecoder.h in Headers */,
+ 255E491518143AC600A03A28 /* ZXBitArrayBuilder.h in Headers */,
+ 255E491618143AC600A03A28 /* ZXExpandedPair.h in Headers */,
+ 255E491718143AC600A03A28 /* ZXExpandedRow.h in Headers */,
+ 255E491818143AC600A03A28 /* ZXRSSExpandedReader.h in Headers */,
+ 255E491918143AC600A03A28 /* ZXAbstractRSSReader.h in Headers */,
+ 255E491A18143AC600A03A28 /* ZXDataCharacter.h in Headers */,
+ 255E491B18143AC600A03A28 /* ZXPair.h in Headers */,
+ 255E491C18143AC600A03A28 /* ZXRSS14Reader.h in Headers */,
+ 255E491D18143AC600A03A28 /* ZXRSSFinderPattern.h in Headers */,
+ 255E491E18143AC600A03A28 /* ZXRSSUtils.h in Headers */,
+ 255E491F18143AC600A03A28 /* ZXCodaBarReader.h in Headers */,
+ 255E492018143AC600A03A28 /* ZXCodaBarWriter.h in Headers */,
+ 255E492118143AC600A03A28 /* ZXCode128Reader.h in Headers */,
+ 255E492218143AC600A03A28 /* ZXCode128Writer.h in Headers */,
+ 255E492318143AC600A03A28 /* ZXCode39Reader.h in Headers */,
+ 255E492418143AC600A03A28 /* ZXCode39Writer.h in Headers */,
+ 255E492518143AC600A03A28 /* ZXCode93Reader.h in Headers */,
+ 255E492618143AC600A03A28 /* ZXEAN13Reader.h in Headers */,
+ 255E492718143AC600A03A28 /* ZXEAN13Writer.h in Headers */,
+ 255E492818143AC600A03A28 /* ZXEAN8Reader.h in Headers */,
+ 255E492918143AC600A03A28 /* ZXEAN8Writer.h in Headers */,
+ 255E492A18143AC600A03A28 /* ZXEANManufacturerOrgSupport.h in Headers */,
+ 255E492B18143AC600A03A28 /* ZXITFReader.h in Headers */,
+ 255E492C18143AC600A03A28 /* ZXITFWriter.h in Headers */,
+ 255E492D18143AC600A03A28 /* ZXMultiFormatOneDReader.h in Headers */,
+ 255E492E18143AC600A03A28 /* ZXMultiFormatUPCEANReader.h in Headers */,
+ 255E492F18143AC600A03A28 /* ZXOneDimensionalCodeWriter.h in Headers */,
+ 255E493018143AC600A03A28 /* ZXOneDReader.h in Headers */,
+ 255E493118143AC600A03A28 /* ZXUPCAReader.h in Headers */,
+ 255E493218143AC600A03A28 /* ZXUPCAWriter.h in Headers */,
+ 255E493318143AC600A03A28 /* ZXUPCEANExtension2Support.h in Headers */,
+ 255E493418143AC600A03A28 /* ZXUPCEANExtension5Support.h in Headers */,
+ 255E493518143AC600A03A28 /* ZXUPCEANExtensionSupport.h in Headers */,
+ 255E493618143AC600A03A28 /* ZXUPCEANReader.h in Headers */,
+ 255E493718143AC600A03A28 /* ZXUPCEANWriter.h in Headers */,
+ 255E493818143AC600A03A28 /* ZXUPCEReader.h in Headers */,
+ 255E493918143AC600A03A28 /* ZXModulusGF.h in Headers */,
+ 255E493A18143AC600A03A28 /* ZXModulusPoly.h in Headers */,
+ 255E493B18143AC600A03A28 /* ZXPDF417ECErrorCorrection.h in Headers */,
+ 255E493C18143AC600A03A28 /* ZXBarcodeFormat.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 2540439B166ABA0A00E13304 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 255E482118143A8800A03A28 /* ZXAztecDecoder.h in Headers */,
+ 255E482218143A8800A03A28 /* ZXAztecDetector.h in Headers */,
+ 255E482318143A8800A03A28 /* ZXAztecCode.h in Headers */,
+ 255E482418143A8800A03A28 /* ZXAztecEncoder.h in Headers */,
+ 255E482518143A8800A03A28 /* ZXAztecDetectorResult.h in Headers */,
+ 255E482618143A8800A03A28 /* ZXAztecReader.h in Headers */,
+ 255E482718143A8800A03A28 /* ZXAztecWriter.h in Headers */,
+ 255E482818143A8800A03A28 /* ZXAbstractDoCoMoResultParser.h in Headers */,
+ 255E482918143A8800A03A28 /* ZXAddressBookAUResultParser.h in Headers */,
+ 255E482A18143A8800A03A28 /* ZXAddressBookDoCoMoResultParser.h in Headers */,
+ 255E482B18143A8800A03A28 /* ZXAddressBookParsedResult.h in Headers */,
+ 255E482C18143A8800A03A28 /* ZXBizcardResultParser.h in Headers */,
+ 255E482D18143A8800A03A28 /* ZXBookmarkDoCoMoResultParser.h in Headers */,
+ 255E482E18143A8800A03A28 /* ZXCalendarParsedResult.h in Headers */,
+ 255E482F18143A8800A03A28 /* ZXEmailAddressParsedResult.h in Headers */,
+ 255E483018143A8800A03A28 /* ZXEmailAddressResultParser.h in Headers */,
+ 255E483118143A8800A03A28 /* ZXEmailDoCoMoResultParser.h in Headers */,
+ 255E483218143A8800A03A28 /* ZXExpandedProductParsedResult.h in Headers */,
+ 255E483318143A8800A03A28 /* ZXExpandedProductResultParser.h in Headers */,
+ 255E483418143A8800A03A28 /* ZXGeoParsedResult.h in Headers */,
+ 255E483518143A8800A03A28 /* ZXGeoResultParser.h in Headers */,
+ 255E483618143A8800A03A28 /* ZXISBNParsedResult.h in Headers */,
+ 255E483718143A8800A03A28 /* ZXISBNResultParser.h in Headers */,
+ 255E483818143A8800A03A28 /* ZXParsedResult.h in Headers */,
+ 255E483918143A8800A03A28 /* ZXParsedResultType.h in Headers */,
+ 255E483A18143A8800A03A28 /* ZXProductParsedResult.h in Headers */,
+ 255E483B18143A8800A03A28 /* ZXProductResultParser.h in Headers */,
+ 255E483C18143A8800A03A28 /* ZXResultParser.h in Headers */,
+ 255E483D18143A8800A03A28 /* ZXSMSMMSResultParser.h in Headers */,
+ 255E483E18143A8800A03A28 /* ZXSMSParsedResult.h in Headers */,
+ 255E483F18143A8800A03A28 /* ZXSMSTOMMSTOResultParser.h in Headers */,
+ 255E484018143A8800A03A28 /* ZXSMTPResultParser.h in Headers */,
+ 255E484118143A8800A03A28 /* ZXTelParsedResult.h in Headers */,
+ 255E484218143A8800A03A28 /* ZXTelResultParser.h in Headers */,
+ 255E484318143A8800A03A28 /* ZXTextParsedResult.h in Headers */,
+ 255E484418143A8800A03A28 /* ZXURIParsedResult.h in Headers */,
+ 255E484518143A8800A03A28 /* ZXURIResultParser.h in Headers */,
+ 255E484618143A8800A03A28 /* ZXURLTOResultParser.h in Headers */,
+ 255E484718143A8800A03A28 /* ZXVCardResultParser.h in Headers */,
+ 255E484818143A8800A03A28 /* ZXVEventResultParser.h in Headers */,
+ 255E484918143A8800A03A28 /* ZXWifiParsedResult.h in Headers */,
+ 255E484A18143A8800A03A28 /* ZXWifiResultParser.h in Headers */,
+ 255E484B18143A8800A03A28 /* ZXCapture.h in Headers */,
+ 255E484C18143A8800A03A28 /* ZXCaptureDelegate.h in Headers */,
+ 255E484D18143A8800A03A28 /* ZXCaptureView.h in Headers */,
+ 255E484E18143A8800A03A28 /* ZXCGImageLuminanceSource.h in Headers */,
+ 255E484F18143A8800A03A28 /* ZXImage.h in Headers */,
+ 255E485018143A8800A03A28 /* ZXView.h in Headers */,
+ 255E485118143A8800A03A28 /* ZXMathUtils.h in Headers */,
+ 255E485218143A8800A03A28 /* ZXMonochromeRectangleDetector.h in Headers */,
+ 255E485318143A8800A03A28 /* ZXWhiteRectangleDetector.h in Headers */,
+ 255E485418143A8800A03A28 /* ZXGenericGF.h in Headers */,
+ 255E485518143A8800A03A28 /* ZXGenericGFPoly.h in Headers */,
+ 255E485618143A8800A03A28 /* ZXReedSolomonDecoder.h in Headers */,
+ 255E485718143A8800A03A28 /* ZXReedSolomonEncoder.h in Headers */,
+ 255E485818143A8800A03A28 /* ZXBitArray.h in Headers */,
+ 255E485918143A8800A03A28 /* ZXBitMatrix.h in Headers */,
+ 255E485A18143A8800A03A28 /* ZXBitSource.h in Headers */,
+ 255E485B18143A8800A03A28 /* ZXCharacterSetECI.h in Headers */,
+ 255E485C18143A8800A03A28 /* ZXDecoderResult.h in Headers */,
+ 255E485D18143A8800A03A28 /* ZXDefaultGridSampler.h in Headers */,
+ 255E485E18143A8800A03A28 /* ZXDetectorResult.h in Headers */,
+ 255E485F18143A8800A03A28 /* ZXECI.h in Headers */,
+ 255E486018143A8800A03A28 /* ZXGlobalHistogramBinarizer.h in Headers */,
+ 255E486118143A8800A03A28 /* ZXGridSampler.h in Headers */,
+ 255E486218143A8800A03A28 /* ZXHybridBinarizer.h in Headers */,
+ 255E486318143A8800A03A28 /* ZXPerspectiveTransform.h in Headers */,
+ 255E486418143A8800A03A28 /* ZXStringUtils.h in Headers */,
+ 255E486518143A8800A03A28 /* ZXDataMatrixBitMatrixParser.h in Headers */,
+ 255E486618143A8800A03A28 /* ZXDataMatrixDataBlock.h in Headers */,
+ 255E486718143A8800A03A28 /* ZXDataMatrixDecodedBitStreamParser.h in Headers */,
+ 255E486818143A8800A03A28 /* ZXDataMatrixDecoder.h in Headers */,
+ 255E486918143A8800A03A28 /* ZXDataMatrixVersion.h in Headers */,
+ 255E486A18143A8800A03A28 /* ZXDataMatrixDetector.h in Headers */,
+ 255E486B18143A8800A03A28 /* ZXASCIIEncoder.h in Headers */,
+ 255E486C18143A8800A03A28 /* ZXBase256Encoder.h in Headers */,
+ 255E486D18143A8800A03A28 /* ZXC40Encoder.h in Headers */,
+ 255E486E18143A8800A03A28 /* ZXDataMatrixEncoder.h in Headers */,
+ 255E486F18143A8800A03A28 /* ZXDataMatrixErrorCorrection.h in Headers */,
+ 255E487018143A8800A03A28 /* ZXDataMatrixSymbolInfo144.h in Headers */,
+ 255E487118143A8800A03A28 /* ZXDefaultPlacement.h in Headers */,
+ 255E487218143A8800A03A28 /* ZXEdifactEncoder.h in Headers */,
+ 255E487318143A8800A03A28 /* ZXEncoderContext.h in Headers */,
+ 255E487418143A8800A03A28 /* ZXHighLevelEncoder.h in Headers */,
+ 255E487518143A8800A03A28 /* ZXSymbolInfo.h in Headers */,
+ 255E487618143A8800A03A28 /* ZXSymbolShapeHint.h in Headers */,
+ 255E487718143A8800A03A28 /* ZXTextEncoder.h in Headers */,
+ 255E487818143A8800A03A28 /* ZXX12Encoder.h in Headers */,
+ 255E487918143A8800A03A28 /* ZXDataMatrixReader.h in Headers */,
+ 255E487A18143A8800A03A28 /* ZXDataMatrixWriter.h in Headers */,
+ 255E487B18143A8800A03A28 /* ZXMaxiCodeBitMatrixParser.h in Headers */,
+ 255E487C18143A8800A03A28 /* ZXMaxiCodeDecodedBitStreamParser.h in Headers */,
+ 255E487D18143A8800A03A28 /* ZXMaxiCodeDecoder.h in Headers */,
+ 255E487E18143A8800A03A28 /* ZXMaxiCodeReader.h in Headers */,
+ 255E487F18143A8800A03A28 /* ZXMultiDetector.h in Headers */,
+ 255E488018143A8800A03A28 /* ZXMultiFinderPatternFinder.h in Headers */,
+ 255E488118143A8800A03A28 /* ZXQRCodeMultiReader.h in Headers */,
+ 255E488218143A8800A03A28 /* ZXByQuadrantReader.h in Headers */,
+ 255E488318143A8800A03A28 /* ZXGenericMultipleBarcodeReader.h in Headers */,
+ 255E488418143A8800A03A28 /* ZXMultipleBarcodeReader.h in Headers */,
+ 255E488518143A8800A03A28 /* ZXAbstractExpandedDecoder.h in Headers */,
+ 255E488618143A8800A03A28 /* ZXAI013103decoder.h in Headers */,
+ 255E488718143A8800A03A28 /* ZXAI01320xDecoder.h in Headers */,
+ 255E488818143A8800A03A28 /* ZXAI01392xDecoder.h in Headers */,
+ 255E488918143A8800A03A28 /* ZXAI01393xDecoder.h in Headers */,
+ 255E488A18143A8800A03A28 /* ZXAI013x0x1xDecoder.h in Headers */,
+ 255E488B18143A8800A03A28 /* ZXAI013x0xDecoder.h in Headers */,
+ 255E488C18143A8800A03A28 /* ZXAI01AndOtherAIs.h in Headers */,
+ 255E488D18143A8800A03A28 /* ZXAI01decoder.h in Headers */,
+ 255E488E18143A8800A03A28 /* ZXAI01weightDecoder.h in Headers */,
+ 255E488F18143A8800A03A28 /* ZXAnyAIDecoder.h in Headers */,
+ 255E489018143A8800A03A28 /* ZXBlockParsedResult.h in Headers */,
+ 255E489118143A8800A03A28 /* ZXCurrentParsingState.h in Headers */,
+ 255E489218143A8800A03A28 /* ZXDecodedChar.h in Headers */,
+ 255E489318143A8800A03A28 /* ZXDecodedInformation.h in Headers */,
+ 255E489418143A8800A03A28 /* ZXDecodedNumeric.h in Headers */,
+ 255E489518143A8800A03A28 /* ZXDecodedObject.h in Headers */,
+ 255E489618143A8800A03A28 /* ZXFieldParser.h in Headers */,
+ 255E489718143A8800A03A28 /* ZXGeneralAppIdDecoder.h in Headers */,
+ 255E489818143A8800A03A28 /* ZXBitArrayBuilder.h in Headers */,
+ 255E489918143A8800A03A28 /* ZXExpandedPair.h in Headers */,
+ 255E489A18143A8800A03A28 /* ZXExpandedRow.h in Headers */,
+ 255E489B18143A8800A03A28 /* ZXRSSExpandedReader.h in Headers */,
+ 255E489C18143A8800A03A28 /* ZXAbstractRSSReader.h in Headers */,
+ 255E489D18143A8800A03A28 /* ZXDataCharacter.h in Headers */,
+ 255E489E18143A8800A03A28 /* ZXPair.h in Headers */,
+ 255E489F18143A8800A03A28 /* ZXRSS14Reader.h in Headers */,
+ 255E48A018143A8800A03A28 /* ZXRSSFinderPattern.h in Headers */,
+ 255E48A118143A8800A03A28 /* ZXRSSUtils.h in Headers */,
+ 255E48A218143A8800A03A28 /* ZXCodaBarReader.h in Headers */,
+ 255E48A318143A8800A03A28 /* ZXCodaBarWriter.h in Headers */,
+ 255E48A418143A8800A03A28 /* ZXCode128Reader.h in Headers */,
+ 255E48A518143A8800A03A28 /* ZXCode128Writer.h in Headers */,
+ 255E48A618143A8800A03A28 /* ZXCode39Reader.h in Headers */,
+ 255E48A718143A8800A03A28 /* ZXCode39Writer.h in Headers */,
+ 255E48A818143A8800A03A28 /* ZXCode93Reader.h in Headers */,
+ 255E48A918143A8800A03A28 /* ZXEAN13Reader.h in Headers */,
+ 255E48AA18143A8800A03A28 /* ZXEAN13Writer.h in Headers */,
+ 255E48AB18143A8800A03A28 /* ZXEAN8Reader.h in Headers */,
+ 255E48AC18143A8800A03A28 /* ZXEAN8Writer.h in Headers */,
+ 255E48AD18143A8800A03A28 /* ZXEANManufacturerOrgSupport.h in Headers */,
+ 255E48AE18143A8800A03A28 /* ZXITFReader.h in Headers */,
+ 255E48AF18143A8800A03A28 /* ZXITFWriter.h in Headers */,
+ 255E48B018143A8800A03A28 /* ZXMultiFormatOneDReader.h in Headers */,
+ 255E48B118143A8800A03A28 /* ZXMultiFormatUPCEANReader.h in Headers */,
+ 255E48B218143A8800A03A28 /* ZXOneDimensionalCodeWriter.h in Headers */,
+ 255E48B318143A8800A03A28 /* ZXOneDReader.h in Headers */,
+ 255E48B418143A8800A03A28 /* ZXUPCAReader.h in Headers */,
+ 255E48B518143A8800A03A28 /* ZXUPCAWriter.h in Headers */,
+ 255E48B618143A8800A03A28 /* ZXUPCEANExtension2Support.h in Headers */,
+ 255E48B718143A8800A03A28 /* ZXUPCEANExtension5Support.h in Headers */,
+ 255E48B818143A8800A03A28 /* ZXUPCEANExtensionSupport.h in Headers */,
+ 255E48B918143A8800A03A28 /* ZXUPCEANReader.h in Headers */,
+ 255E48BA18143A8800A03A28 /* ZXUPCEANWriter.h in Headers */,
+ 255E48BB18143A8800A03A28 /* ZXUPCEReader.h in Headers */,
+ 255E48BC18143A8800A03A28 /* ZXModulusGF.h in Headers */,
+ 255E48BD18143A8800A03A28 /* ZXModulusPoly.h in Headers */,
+ 255E48BE18143A8800A03A28 /* ZXPDF417ECErrorCorrection.h in Headers */,
+ 255E48C018143A8800A03A28 /* ZXPDF417BarcodeMetadata.h in Headers */,
+ 255E48C118143A8800A03A28 /* ZXPDF417BarcodeValue.h in Headers */,
+ 255E48C218143A8800A03A28 /* ZXPDF417BoundingBox.h in Headers */,
+ 255E48C318143A8800A03A28 /* ZXPDF417Codeword.h in Headers */,
+ 255E48C418143A8800A03A28 /* ZXPDF417CodewordDecoder.h in Headers */,
+ 255E48C518143A8800A03A28 /* ZXPDF417DecodedBitStreamParser.h in Headers */,
+ 255E48C618143A8800A03A28 /* ZXPDF417DetectionResult.h in Headers */,
+ 255E48C718143A8800A03A28 /* ZXPDF417DetectionResultColumn.h in Headers */,
+ 255E48C818143A8800A03A28 /* ZXPDF417DetectionResultRowIndicatorColumn.h in Headers */,
+ 255E48C918143A8800A03A28 /* ZXPDF417ScanningDecoder.h in Headers */,
+ 255E48CA18143A8800A03A28 /* ZXPDF417Detector.h in Headers */,
+ 255E48CB18143A8800A03A28 /* ZXPDF417DetectorResult.h in Headers */,
+ 255E48CC18143A8800A03A28 /* ZXBarcodeMatrix.h in Headers */,
+ 255E48CD18143A8800A03A28 /* ZXBarcodeRow.h in Headers */,
+ 255E48CE18143A8800A03A28 /* ZXCompaction.h in Headers */,
+ 255E48CF18143A8800A03A28 /* ZXDimensions.h in Headers */,
+ 255E48D018143A8800A03A28 /* ZXPDF417.h in Headers */,
+ 255E48D118143A8800A03A28 /* ZXPDF417ErrorCorrection.h in Headers */,
+ 255E48D218143A8800A03A28 /* ZXPDF417HighLevelEncoder.h in Headers */,
+ 255E48D318143A8800A03A28 /* ZXPDF417Common.h in Headers */,
+ 255E48D418143A8800A03A28 /* ZXPDF417Reader.h in Headers */,
+ 255E48D518143A8800A03A28 /* ZXPDF417ResultMetadata.h in Headers */,
+ 255E48D618143A8800A03A28 /* ZXPDF417Writer.h in Headers */,
+ 255E48D718143A8800A03A28 /* ZXDataMask.h in Headers */,
+ 255E48D818143A8800A03A28 /* ZXErrorCorrectionLevel.h in Headers */,
+ 255E48D918143A8800A03A28 /* ZXFormatInformation.h in Headers */,
+ 255E48DA18143A8800A03A28 /* ZXMode.h in Headers */,
+ 255E48DB18143A8800A03A28 /* ZXQRCodeBitMatrixParser.h in Headers */,
+ 255E48DC18143A8800A03A28 /* ZXQRCodeDataBlock.h in Headers */,
+ 255E48DD18143A8800A03A28 /* ZXQRCodeDecodedBitStreamParser.h in Headers */,
+ 255E48DE18143A8800A03A28 /* ZXQRCodeDecoder.h in Headers */,
+ 255E48DF18143A8800A03A28 /* ZXQRCodeVersion.h in Headers */,
+ 255E48E018143A8800A03A28 /* ZXAlignmentPattern.h in Headers */,
+ 255E48E118143A8800A03A28 /* ZXAlignmentPatternFinder.h in Headers */,
+ 255E48E218143A8800A03A28 /* ZXFinderPatternFinder.h in Headers */,
+ 255E48E318143A8800A03A28 /* ZXFinderPatternInfo.h in Headers */,
+ 255E48E418143A8800A03A28 /* ZXQRCodeDetector.h in Headers */,
+ 255E48E518143A8800A03A28 /* ZXQRCodeFinderPattern.h in Headers */,
+ 255E48E618143A8800A03A28 /* ZXBlockPair.h in Headers */,
+ 255E48E718143A8800A03A28 /* ZXByteMatrix.h in Headers */,
+ 255E48E818143A8800A03A28 /* ZXEncoder.h in Headers */,
+ 255E48E918143A8800A03A28 /* ZXMaskUtil.h in Headers */,
+ 255E48EA18143A8800A03A28 /* ZXMatrixUtil.h in Headers */,
+ 255E48EB18143A8800A03A28 /* ZXQRCode.h in Headers */,
+ 255E48EC18143A8800A03A28 /* ZXQRCodeReader.h in Headers */,
+ 255E48ED18143A8800A03A28 /* ZXQRCodeWriter.h in Headers */,
+ 255E48EE18143A8800A03A28 /* ZXBarcodeFormat.h in Headers */,
+ 255E48EF18143A8800A03A28 /* ZXBinarizer.h in Headers */,
+ 255E48F018143A8800A03A28 /* ZXBinaryBitmap.h in Headers */,
+ 255E48F118143A8800A03A28 /* ZXDecodeHints.h in Headers */,
+ 255E48F218143A8800A03A28 /* ZXDimension.h in Headers */,
+ 255E48F318143A8800A03A28 /* ZXEncodeHints.h in Headers */,
+ 255E48F418143A8800A03A28 /* ZXErrors.h in Headers */,
+ 255E48F518143A8800A03A28 /* ZXingObjC.h in Headers */,
+ 255E48F618143A8800A03A28 /* ZXInvertedLuminanceSource.h in Headers */,
+ 255E48F718143A8800A03A28 /* ZXLuminanceSource.h in Headers */,
+ 255E48F818143A8800A03A28 /* ZXMultiFormatReader.h in Headers */,
+ 255E48F918143A8800A03A28 /* ZXMultiFormatWriter.h in Headers */,
+ 255E48FA18143A8800A03A28 /* ZXPlanarYUVLuminanceSource.h in Headers */,
+ 255E48FB18143A8800A03A28 /* ZXReader.h in Headers */,
+ 255E48FC18143A8800A03A28 /* ZXResult.h in Headers */,
+ 255E48FD18143A8800A03A28 /* ZXResultMetadataType.h in Headers */,
+ 255E48FE18143A8800A03A28 /* ZXResultPoint.h in Headers */,
+ 255E48FF18143A8800A03A28 /* ZXResultPointCallback.h in Headers */,
+ 255E490018143A8800A03A28 /* ZXRGBLuminanceSource.h in Headers */,
+ 255E490118143A8800A03A28 /* ZXWriter.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 024957EF1898641B003D4E6A /* Blackbox Tests iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 024958741898641B003D4E6A /* Build configuration list for PBXNativeTarget "Blackbox Tests iOS" */;
+ buildPhases = (
+ 024957F21898641B003D4E6A /* Sources */,
+ 024958681898641B003D4E6A /* Frameworks */,
+ 024958711898641B003D4E6A /* Resources */,
+ 024958731898641B003D4E6A /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 024957F01898641B003D4E6A /* PBXTargetDependency */,
+ );
+ name = "Blackbox Tests iOS";
+ productName = ZXingObjCTests;
+ productReference = 024958781898641B003D4E6A /* ZXingObjCTests-iOS copy.octest */;
+ productType = "com.apple.product-type.bundle.ocunit-test";
+ };
+ 02D8136F189864C70081721D /* Blackbox Tests OS X */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 02D813F2189864C70081721D /* Build configuration list for PBXNativeTarget "Blackbox Tests OS X" */;
+ buildPhases = (
+ 02D81372189864C70081721D /* Sources */,
+ 02D813E8189864C70081721D /* Frameworks */,
+ 02D813EF189864C70081721D /* Resources */,
+ 02D813F1189864C70081721D /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 02D81370189864C70081721D /* PBXTargetDependency */,
+ );
+ name = "Blackbox Tests OS X";
+ productName = ZXingObjCTests;
+ productReference = 02D813F6189864C70081721D /* ZXingObjCTests-osx copy.octest */;
+ productType = "com.apple.product-type.bundle.ocunit-test";
+ };
+ 25403CB2166A96FA00E13304 /* ZXingObjC-iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 25403CD8166A96FA00E13304 /* Build configuration list for PBXNativeTarget "ZXingObjC-iOS" */;
+ buildPhases = (
+ 25403CAF166A96FA00E13304 /* Sources */,
+ 25403CB0166A96FA00E13304 /* Frameworks */,
+ 25403CE2166A98B600E13304 /* Headers */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "ZXingObjC-iOS";
+ productName = ZXingObjC;
+ productReference = 25403CB3166A96FA00E13304 /* libZXingObjC-iOS.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ 25403CC3166A96FA00E13304 /* Unit Tests iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 25403CDB166A96FA00E13304 /* Build configuration list for PBXNativeTarget "Unit Tests iOS" */;
+ buildPhases = (
+ 25403CBF166A96FA00E13304 /* Sources */,
+ 25403CC0166A96FA00E13304 /* Frameworks */,
+ 25403CC1166A96FA00E13304 /* Resources */,
+ 25403CC2166A96FA00E13304 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 25403CCB166A96FA00E13304 /* PBXTargetDependency */,
+ );
+ name = "Unit Tests iOS";
+ productName = ZXingObjCTests;
+ productReference = 25403CC4166A96FA00E13304 /* Unit Tests iOS.octest */;
+ productType = "com.apple.product-type.bundle.ocunit-test";
+ };
+ 25404165166AADAC00E13304 /* ZXingObjC-osx */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 25404187166AADAD00E13304 /* Build configuration list for PBXNativeTarget "ZXingObjC-osx" */;
+ buildPhases = (
+ 25404162166AADAC00E13304 /* Sources */,
+ 25404163166AADAC00E13304 /* Frameworks */,
+ 25404164166AADAC00E13304 /* Headers */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "ZXingObjC-osx";
+ productName = ZXingObjC;
+ productReference = 25404166166AADAC00E13304 /* libZXingObjC-osx.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ 25404177166AADAC00E13304 /* Unit Tests OS X */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 2540418A166AADAD00E13304 /* Build configuration list for PBXNativeTarget "Unit Tests OS X" */;
+ buildPhases = (
+ 25404173166AADAC00E13304 /* Sources */,
+ 25404174166AADAC00E13304 /* Frameworks */,
+ 25404175166AADAC00E13304 /* Resources */,
+ 25404176166AADAC00E13304 /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 2540417C166AADAC00E13304 /* PBXTargetDependency */,
+ );
+ name = "Unit Tests OS X";
+ productName = ZXingObjCTests;
+ productReference = 25404178166AADAC00E13304 /* Unit Tests OS X.octest */;
+ productType = "com.apple.product-type.bundle.ocunit-test";
+ };
+ 2540439D166ABA0A00E13304 /* OS X Framework */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 254043B0166ABA0A00E13304 /* Build configuration list for PBXNativeTarget "OS X Framework" */;
+ buildPhases = (
+ 25404399166ABA0A00E13304 /* Sources */,
+ 2540439A166ABA0A00E13304 /* Frameworks */,
+ 2540439B166ABA0A00E13304 /* Headers */,
+ 2540439C166ABA0A00E13304 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "OS X Framework";
+ productName = ZXingObjC;
+ productReference = 2540439E166ABA0A00E13304 /* ZXingObjC.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 25403CAA166A96F900E13304 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastTestingUpgradeCheck = 0510;
+ LastUpgradeCheck = 0510;
+ ORGANIZATIONNAME = zxing;
+ };
+ buildConfigurationList = 25403CAD166A96F900E13304 /* Build configuration list for PBXProject "ZXingObjC" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 25403CA8166A96F900E13304;
+ productRefGroup = 25403CB4166A96FA00E13304 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 25403CB2166A96FA00E13304 /* ZXingObjC-iOS */,
+ 25403CC3166A96FA00E13304 /* Unit Tests iOS */,
+ 024957EF1898641B003D4E6A /* Blackbox Tests iOS */,
+ 25404165166AADAC00E13304 /* ZXingObjC-osx */,
+ 25404177166AADAC00E13304 /* Unit Tests OS X */,
+ 02D8136F189864C70081721D /* Blackbox Tests OS X */,
+ 2540439D166ABA0A00E13304 /* OS X Framework */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 024958711898641B003D4E6A /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 024958721898641B003D4E6A /* Resources in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 02D813EF189864C70081721D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 02D813F0189864C70081721D /* Resources in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25403CC1166A96FA00E13304 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 25FE5D4516D1997C00826CDB /* Resources in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25404175166AADAC00E13304 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 02B4884A17F5F10000E6285D /* Resources in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 2540439C166ABA0A00E13304 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 024958731898641B003D4E6A /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+ };
+ 02D813F1189864C70081721D /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+ };
+ 25403CC2166A96FA00E13304 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+ };
+ 25404176166AADAC00E13304 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 024957F21898641B003D4E6A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 024957F31898641B003D4E6A /* AztecBlackBox1TestCase.m in Sources */,
+ 024957F41898641B003D4E6A /* AztecBlackBox2TestCase.m in Sources */,
+ 024957FB1898641B003D4E6A /* PDF417BlackBox4TestCase.m in Sources */,
+ 024958021898641B003D4E6A /* AbstractBlackBoxTestCase.m in Sources */,
+ 024958031898641B003D4E6A /* AbstractNegativeBlackBoxTestCase.m in Sources */,
+ 024958041898641B003D4E6A /* TestResult.m in Sources */,
+ 0249580B1898641B003D4E6A /* DataMatrixBlackBox1TestCase.m in Sources */,
+ 0249580C1898641B003D4E6A /* DataMatrixBlackBox2TestCase.m in Sources */,
+ 0249580E1898641B003D4E6A /* FalsePositives2BlackBoxTestCase.m in Sources */,
+ 0249580F1898641B003D4E6A /* FalsePositivesBlackBoxTestCase.m in Sources */,
+ 024958101898641B003D4E6A /* PartialBlackBoxTestCase.m in Sources */,
+ 024958111898641B003D4E6A /* UnsupportedBlackBoxTestCase.m in Sources */,
+ 024958121898641B003D4E6A /* CodabarBlackbox1TestCase.m in Sources */,
+ 024958131898641B003D4E6A /* PDF417BlackBox3TestCase.m in Sources */,
+ 024958141898641B003D4E6A /* Code128BlackBox1TestCase.m in Sources */,
+ 024958151898641B003D4E6A /* Code128BlackBox2TestCase.m in Sources */,
+ 024958161898641B003D4E6A /* Code128BlackBox3TestCase.m in Sources */,
+ 024958171898641B003D4E6A /* Code39BlackBox1TestCase.m in Sources */,
+ 024958181898641B003D4E6A /* Code39BlackBox3TestCase.m in Sources */,
+ 024958191898641B003D4E6A /* Code39ExtendedBlackBox2TestCase.m in Sources */,
+ 0249581A1898641B003D4E6A /* Code93BlackBox1TestCase.m in Sources */,
+ 0249581B1898641B003D4E6A /* EAN13BlackBox1TestCase.m in Sources */,
+ 0249581C1898641B003D4E6A /* EAN13BlackBox2TestCase.m in Sources */,
+ 0249581D1898641B003D4E6A /* EAN13BlackBox3TestCase.m in Sources */,
+ 0249581E1898641B003D4E6A /* EAN13BlackBox4TestCase.m in Sources */,
+ 0249581F1898641B003D4E6A /* EAN13BlackBox5BlurryTestCase.m in Sources */,
+ 024958201898641B003D4E6A /* EAN8BlackBox1TestCase.m in Sources */,
+ 024958211898641B003D4E6A /* ITFBlackBox1TestCase.m in Sources */,
+ 024958221898641B003D4E6A /* ITFBlackBox2TestCase.m in Sources */,
+ 024958291898641B003D4E6A /* RSSExpandedBlackBox1TestCase.m in Sources */,
+ 0249582A1898641B003D4E6A /* RSSExpandedBlackBox2TestCase.m in Sources */,
+ 0249582B1898641B003D4E6A /* RSSExpandedBlackBox3TestCase.m in Sources */,
+ 0249582C1898641B003D4E6A /* RSSExpandedImage2binaryTestCase.m in Sources */,
+ 0249582D1898641B003D4E6A /* RSSExpandedImage2resultTestCase.m in Sources */,
+ 0249582E1898641B003D4E6A /* RSSExpandedImage2stringTestCase.m in Sources */,
+ 0249582F1898641B003D4E6A /* RSSExpandedInternalTestCase.m in Sources */,
+ 024958341898641B003D4E6A /* RSS14BlackBox1TestCase.m in Sources */,
+ 024958351898641B003D4E6A /* RSS14BlackBox2TestCase.m in Sources */,
+ 024958361898641B003D4E6A /* UPCABlackBox1TestCase.m in Sources */,
+ 024958371898641B003D4E6A /* UPCABlackBox2TestCase.m in Sources */,
+ 024958381898641B003D4E6A /* UPCABlackBox3ReflectiveTestCase.m in Sources */,
+ 024958391898641B003D4E6A /* UPCABlackBox4TestCase.m in Sources */,
+ 0249583A1898641B003D4E6A /* UPCABlackBox5TestCase.m in Sources */,
+ 0249583B1898641B003D4E6A /* UPCABlackBox6BlurryTestCase.m in Sources */,
+ 0249583C1898641B003D4E6A /* UPCEANExtensionBlackBox1TestCase.m in Sources */,
+ 0249583D1898641B003D4E6A /* UPCEBlackBox1TestCase.m in Sources */,
+ 0249583E1898641B003D4E6A /* UPCEBlackBox2TestCase.m in Sources */,
+ 0249583F1898641B003D4E6A /* UPCEBlackBox3ReflectiveTestCase.m in Sources */,
+ 024958451898641B003D4E6A /* AbstractErrorCorrectionTestCase.m in Sources */,
+ 024958471898641B003D4E6A /* PDF417BlackBox1TestCase.m in Sources */,
+ 024958481898641B003D4E6A /* PDF417BlackBox2TestCase.m in Sources */,
+ 024958541898641B003D4E6A /* QRCodeBlackBox1TestCase.m in Sources */,
+ 024958551898641B003D4E6A /* QRCodeBlackBox2TestCase.m in Sources */,
+ 024958561898641B003D4E6A /* QRCodeBlackBox3TestCase.m in Sources */,
+ 024958581898641B003D4E6A /* QRCodeBlackBox4TestCase.m in Sources */,
+ 024958591898641B003D4E6A /* QRCodeBlackBox5TestCase.m in Sources */,
+ 0249585A1898641B003D4E6A /* QRCodeBlackBox6TestCase.m in Sources */,
+ 0249585C1898641B003D4E6A /* RSSExpandedStackedBlackBox1TestCase.m in Sources */,
+ 0249585D1898641B003D4E6A /* RSSExpandedStackedBlackBox2TestCase.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 02D81372189864C70081721D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 02D81373189864C70081721D /* RSSExpandedStackedBlackBox1TestCase.m in Sources */,
+ 02D81374189864C70081721D /* RSSExpandedStackedBlackBox2TestCase.m in Sources */,
+ 02D81375189864C70081721D /* RSSExpandedStackedInternalTestCase.m in Sources */,
+ 02D81377189864C70081721D /* AztecBlackBox1TestCase.m in Sources */,
+ 02D81378189864C70081721D /* AztecBlackBox2TestCase.m in Sources */,
+ 02D8137B189864C70081721D /* PDF417BlackBox4TestCase.m in Sources */,
+ 02D81386189864C70081721D /* AbstractBlackBoxTestCase.m in Sources */,
+ 02D81387189864C70081721D /* PDF417BlackBox3TestCase.m in Sources */,
+ 02D81388189864C70081721D /* AbstractNegativeBlackBoxTestCase.m in Sources */,
+ 02D81389189864C70081721D /* TestResult.m in Sources */,
+ 02D81390189864C70081721D /* DataMatrixBlackBox1TestCase.m in Sources */,
+ 02D81391189864C70081721D /* DataMatrixBlackBox2TestCase.m in Sources */,
+ 02D81393189864C70081721D /* FalsePositives2BlackBoxTestCase.m in Sources */,
+ 02D81394189864C70081721D /* FalsePositivesBlackBoxTestCase.m in Sources */,
+ 02D81395189864C70081721D /* PartialBlackBoxTestCase.m in Sources */,
+ 02D81396189864C70081721D /* UnsupportedBlackBoxTestCase.m in Sources */,
+ 02D81397189864C70081721D /* CodabarBlackbox1TestCase.m in Sources */,
+ 02D81398189864C70081721D /* Code128BlackBox1TestCase.m in Sources */,
+ 02D81399189864C70081721D /* Code128BlackBox2TestCase.m in Sources */,
+ 02D8139A189864C70081721D /* Code128BlackBox3TestCase.m in Sources */,
+ 02D8139B189864C70081721D /* Code39BlackBox1TestCase.m in Sources */,
+ 02D8139C189864C70081721D /* Code39BlackBox3TestCase.m in Sources */,
+ 02D8139D189864C70081721D /* Code39ExtendedBlackBox2TestCase.m in Sources */,
+ 02D8139E189864C70081721D /* Code93BlackBox1TestCase.m in Sources */,
+ 02D8139F189864C70081721D /* EAN13BlackBox1TestCase.m in Sources */,
+ 02D813A0189864C70081721D /* EAN13BlackBox2TestCase.m in Sources */,
+ 02D813A1189864C70081721D /* EAN13BlackBox3TestCase.m in Sources */,
+ 02D813A2189864C70081721D /* EAN13BlackBox4TestCase.m in Sources */,
+ 02D813A3189864C70081721D /* EAN13BlackBox5BlurryTestCase.m in Sources */,
+ 02D813A4189864C70081721D /* EAN8BlackBox1TestCase.m in Sources */,
+ 02D813A5189864C70081721D /* ITFBlackBox1TestCase.m in Sources */,
+ 02D813A6189864C70081721D /* ITFBlackBox2TestCase.m in Sources */,
+ 02D813AD189864C70081721D /* RSSExpandedBlackBox1TestCase.m in Sources */,
+ 02D813AE189864C70081721D /* RSSExpandedBlackBox2TestCase.m in Sources */,
+ 02D813AF189864C70081721D /* RSSExpandedBlackBox3TestCase.m in Sources */,
+ 02D813B0189864C70081721D /* RSSExpandedImage2binaryTestCase.m in Sources */,
+ 02D813B1189864C70081721D /* RSSExpandedImage2resultTestCase.m in Sources */,
+ 02D813B2189864C70081721D /* RSSExpandedImage2stringTestCase.m in Sources */,
+ 02D813B3189864C70081721D /* RSSExpandedInternalTestCase.m in Sources */,
+ 02D813B8189864C70081721D /* RSS14BlackBox1TestCase.m in Sources */,
+ 02D813B9189864C70081721D /* RSS14BlackBox2TestCase.m in Sources */,
+ 02D813BA189864C70081721D /* UPCABlackBox1TestCase.m in Sources */,
+ 02D813BB189864C70081721D /* UPCABlackBox2TestCase.m in Sources */,
+ 02D813BC189864C70081721D /* UPCABlackBox3ReflectiveTestCase.m in Sources */,
+ 02D813BD189864C70081721D /* UPCABlackBox4TestCase.m in Sources */,
+ 02D813BE189864C70081721D /* UPCABlackBox5TestCase.m in Sources */,
+ 02D813BF189864C70081721D /* UPCABlackBox6BlurryTestCase.m in Sources */,
+ 02D813C0189864C70081721D /* UPCEANExtensionBlackBox1TestCase.m in Sources */,
+ 02D813C1189864C70081721D /* UPCEBlackBox1TestCase.m in Sources */,
+ 02D813C2189864C70081721D /* UPCEBlackBox2TestCase.m in Sources */,
+ 02D813C3189864C70081721D /* UPCEBlackBox3ReflectiveTestCase.m in Sources */,
+ 02D813CB189864C70081721D /* PDF417BlackBox1TestCase.m in Sources */,
+ 02D813CC189864C70081721D /* PDF417BlackBox2TestCase.m in Sources */,
+ 02D813D8189864C70081721D /* QRCodeBlackBox1TestCase.m in Sources */,
+ 02D813D9189864C70081721D /* QRCodeBlackBox2TestCase.m in Sources */,
+ 02D813DA189864C70081721D /* QRCodeBlackBox3TestCase.m in Sources */,
+ 02D813DC189864C70081721D /* QRCodeBlackBox4TestCase.m in Sources */,
+ 02D813DD189864C70081721D /* QRCodeBlackBox5TestCase.m in Sources */,
+ 02D813DE189864C70081721D /* QRCodeBlackBox6TestCase.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25403CAF166A96FA00E13304 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 25403CF8166A999D00E13304 /* ZXAztecDecoder.m in Sources */,
+ 2519AB3717FD1EC000A71C45 /* ZXAztecWriter.m in Sources */,
+ 25403CFA166A999D00E13304 /* ZXAztecDetector.m in Sources */,
+ 25403CFC166A999D00E13304 /* ZXAztecDetectorResult.m in Sources */,
+ 25403CFE166A999D00E13304 /* ZXAztecReader.m in Sources */,
+ 25403D51166A9A0800E13304 /* ZXAbstractDoCoMoResultParser.m in Sources */,
+ 25403D53166A9A0800E13304 /* ZXAddressBookAUResultParser.m in Sources */,
+ 25403D55166A9A0800E13304 /* ZXAddressBookDoCoMoResultParser.m in Sources */,
+ 25403D57166A9A0800E13304 /* ZXAddressBookParsedResult.m in Sources */,
+ 25403D59166A9A0800E13304 /* ZXBizcardResultParser.m in Sources */,
+ 25403D5B166A9A0800E13304 /* ZXBookmarkDoCoMoResultParser.m in Sources */,
+ 25403D5D166A9A0800E13304 /* ZXCalendarParsedResult.m in Sources */,
+ 25403D5F166A9A0800E13304 /* ZXEmailAddressParsedResult.m in Sources */,
+ 25403D61166A9A0800E13304 /* ZXEmailAddressResultParser.m in Sources */,
+ 25403D63166A9A0800E13304 /* ZXEmailDoCoMoResultParser.m in Sources */,
+ 25403D65166A9A0800E13304 /* ZXExpandedProductParsedResult.m in Sources */,
+ 25403D67166A9A0800E13304 /* ZXExpandedProductResultParser.m in Sources */,
+ 25403D69166A9A0800E13304 /* ZXGeoParsedResult.m in Sources */,
+ 25403D6B166A9A0800E13304 /* ZXGeoResultParser.m in Sources */,
+ 25403D6D166A9A0800E13304 /* ZXISBNParsedResult.m in Sources */,
+ 25403D6F166A9A0800E13304 /* ZXISBNResultParser.m in Sources */,
+ 25403D71166A9A0800E13304 /* ZXParsedResult.m in Sources */,
+ 25403D74166A9A0800E13304 /* ZXProductParsedResult.m in Sources */,
+ 25403D76166A9A0800E13304 /* ZXProductResultParser.m in Sources */,
+ 25403D78166A9A0800E13304 /* ZXResultParser.m in Sources */,
+ 25403D7A166A9A0800E13304 /* ZXSMSMMSResultParser.m in Sources */,
+ 25403D7C166A9A0800E13304 /* ZXSMSParsedResult.m in Sources */,
+ 25403D7E166A9A0800E13304 /* ZXSMSTOMMSTOResultParser.m in Sources */,
+ 25403D80166A9A0800E13304 /* ZXSMTPResultParser.m in Sources */,
+ 25403D82166A9A0800E13304 /* ZXTelParsedResult.m in Sources */,
+ 25403D84166A9A0800E13304 /* ZXTelResultParser.m in Sources */,
+ 25403D86166A9A0800E13304 /* ZXTextParsedResult.m in Sources */,
+ 25403D88166A9A0800E13304 /* ZXURIParsedResult.m in Sources */,
+ 25403D8A166A9A0800E13304 /* ZXURIResultParser.m in Sources */,
+ 25403D8C166A9A0800E13304 /* ZXURLTOResultParser.m in Sources */,
+ 25403D8E166A9A0800E13304 /* ZXVCardResultParser.m in Sources */,
+ 25403D90166A9A0800E13304 /* ZXVEventResultParser.m in Sources */,
+ 25403D92166A9A0800E13304 /* ZXWifiParsedResult.m in Sources */,
+ 25403D94166A9A0800E13304 /* ZXWifiResultParser.m in Sources */,
+ 25403D96166A9A0800E13304 /* ZXCapture.m in Sources */,
+ 25403D99166A9A0800E13304 /* ZXCaptureView.m in Sources */,
+ 25403D9B166A9A0800E13304 /* ZXCGImageLuminanceSource.m in Sources */,
+ 25403D9D166A9A0800E13304 /* ZXImage.m in Sources */,
+ 25403DCB166A9C0E00E13304 /* ZXMathUtils.m in Sources */,
+ 25403DCD166A9C0E00E13304 /* ZXMonochromeRectangleDetector.m in Sources */,
+ 25403DCF166A9C0E00E13304 /* ZXWhiteRectangleDetector.m in Sources */,
+ 25403DD1166A9C0E00E13304 /* ZXGenericGF.m in Sources */,
+ 25403DD3166A9C0E00E13304 /* ZXGenericGFPoly.m in Sources */,
+ 25403DD5166A9C0E00E13304 /* ZXReedSolomonDecoder.m in Sources */,
+ 25403DD7166A9C0E00E13304 /* ZXReedSolomonEncoder.m in Sources */,
+ 25403DD9166A9C0E00E13304 /* ZXBitArray.m in Sources */,
+ 25403DDB166A9C0E00E13304 /* ZXBitMatrix.m in Sources */,
+ 25403DDD166A9C0E00E13304 /* ZXBitSource.m in Sources */,
+ 25403DDF166A9C0E00E13304 /* ZXCharacterSetECI.m in Sources */,
+ 25403DE1166A9C0E00E13304 /* ZXDecoderResult.m in Sources */,
+ 25403DE3166A9C0E00E13304 /* ZXDefaultGridSampler.m in Sources */,
+ 25403DE5166A9C0E00E13304 /* ZXDetectorResult.m in Sources */,
+ 25403DE7166A9C0E00E13304 /* ZXECI.m in Sources */,
+ 25403DE9166A9C0E00E13304 /* ZXGlobalHistogramBinarizer.m in Sources */,
+ 25403DEB166A9C0E00E13304 /* ZXGridSampler.m in Sources */,
+ 25403DED166A9C0E00E13304 /* ZXHybridBinarizer.m in Sources */,
+ 25403DEF166A9C0E00E13304 /* ZXPerspectiveTransform.m in Sources */,
+ 25403DF1166A9C0E00E13304 /* ZXStringUtils.m in Sources */,
+ 25403E04166A9CCB00E13304 /* ZXDataMatrixBitMatrixParser.m in Sources */,
+ 25389B841800E35B00772392 /* ZXPDF417ScanningDecoder.m in Sources */,
+ 25403E06166A9CCB00E13304 /* ZXDataMatrixDataBlock.m in Sources */,
+ 25403E08166A9CCB00E13304 /* ZXDataMatrixDecodedBitStreamParser.m in Sources */,
+ 25403E0A166A9CCB00E13304 /* ZXDataMatrixDecoder.m in Sources */,
+ 25403E0C166A9CCB00E13304 /* ZXDataMatrixVersion.m in Sources */,
+ 25403E0E166A9CCB00E13304 /* ZXDataMatrixDetector.m in Sources */,
+ 25403E10166A9CCB00E13304 /* ZXDataMatrixReader.m in Sources */,
+ 25403E1C166A9D4B00E13304 /* ZXMaxiCodeBitMatrixParser.m in Sources */,
+ 25403E1E166A9D4B00E13304 /* ZXMaxiCodeDecodedBitStreamParser.m in Sources */,
+ 25403E20166A9D4B00E13304 /* ZXMaxiCodeDecoder.m in Sources */,
+ 25403E22166A9D4B00E13304 /* ZXMaxiCodeReader.m in Sources */,
+ 25403E32166A9D8B00E13304 /* ZXMultiDetector.m in Sources */,
+ 25403E34166A9D8B00E13304 /* ZXMultiFinderPatternFinder.m in Sources */,
+ 25389B6C17FFC98100772392 /* ZXPDF417DetectionResultColumn.m in Sources */,
+ 25403E36166A9D8B00E13304 /* ZXQRCodeMultiReader.m in Sources */,
+ 25403E38166A9D8B00E13304 /* ZXByQuadrantReader.m in Sources */,
+ 25403E3A166A9D8B00E13304 /* ZXGenericMultipleBarcodeReader.m in Sources */,
+ 25403EAD166A9DF400E13304 /* ZXAbstractExpandedDecoder.m in Sources */,
+ 25403EAF166A9DF400E13304 /* ZXAI013103decoder.m in Sources */,
+ 25403EB1166A9DF400E13304 /* ZXAI01320xDecoder.m in Sources */,
+ 25403EB3166A9DF400E13304 /* ZXAI01392xDecoder.m in Sources */,
+ 25403EB5166A9DF400E13304 /* ZXAI01393xDecoder.m in Sources */,
+ 2519AB4517FE554D00A71C45 /* ZXPDF417Common.m in Sources */,
+ 25403EB7166A9DF400E13304 /* ZXAI013x0x1xDecoder.m in Sources */,
+ 2519AB6917FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m in Sources */,
+ 25403EB9166A9DF400E13304 /* ZXAI013x0xDecoder.m in Sources */,
+ 25403EBB166A9DF400E13304 /* ZXAI01AndOtherAIs.m in Sources */,
+ 25403EBD166A9DF400E13304 /* ZXAI01decoder.m in Sources */,
+ 25403EBF166A9DF400E13304 /* ZXAI01weightDecoder.m in Sources */,
+ 25403EC1166A9DF400E13304 /* ZXAnyAIDecoder.m in Sources */,
+ 25403EC3166A9DF400E13304 /* ZXBlockParsedResult.m in Sources */,
+ 25403EC5166A9DF400E13304 /* ZXCurrentParsingState.m in Sources */,
+ 25403EC7166A9DF400E13304 /* ZXDecodedChar.m in Sources */,
+ 25403EC9166A9DF400E13304 /* ZXDecodedInformation.m in Sources */,
+ 2519AB7917FE649000A71C45 /* ZXPDF417Codeword.m in Sources */,
+ 25403ECB166A9DF400E13304 /* ZXDecodedNumeric.m in Sources */,
+ 25403ECD166A9DF400E13304 /* ZXDecodedObject.m in Sources */,
+ 25389B6217FFC84300772392 /* ZXPDF417DetectionResult.m in Sources */,
+ 25403ECF166A9DF400E13304 /* ZXFieldParser.m in Sources */,
+ 25403ED1166A9DF400E13304 /* ZXGeneralAppIdDecoder.m in Sources */,
+ 25403ED3166A9DF400E13304 /* ZXBitArrayBuilder.m in Sources */,
+ 25403ED5166A9DF400E13304 /* ZXExpandedPair.m in Sources */,
+ 25403ED7166A9DF400E13304 /* ZXRSSExpandedReader.m in Sources */,
+ 2519AB7117FE60E700A71C45 /* ZXPDF417BoundingBox.m in Sources */,
+ 25403ED9166A9DF400E13304 /* ZXAbstractRSSReader.m in Sources */,
+ 25403EDB166A9DF400E13304 /* ZXDataCharacter.m in Sources */,
+ 25403EDD166A9DF400E13304 /* ZXPair.m in Sources */,
+ 25403EDF166A9DF400E13304 /* ZXRSS14Reader.m in Sources */,
+ 25403EE1166A9DF400E13304 /* ZXRSSFinderPattern.m in Sources */,
+ 25403EE3166A9DF400E13304 /* ZXRSSUtils.m in Sources */,
+ 25403EE5166A9DF400E13304 /* ZXCodaBarReader.m in Sources */,
+ 25403EE7166A9DF400E13304 /* ZXCodaBarWriter.m in Sources */,
+ 25403EE9166A9DF400E13304 /* ZXCode128Reader.m in Sources */,
+ 25403EEB166A9DF400E13304 /* ZXCode128Writer.m in Sources */,
+ 25403EED166A9DF400E13304 /* ZXCode39Reader.m in Sources */,
+ 25403EEF166A9DF400E13304 /* ZXCode39Writer.m in Sources */,
+ 25403EF1166A9DF400E13304 /* ZXCode93Reader.m in Sources */,
+ 25403EF3166A9DF400E13304 /* ZXEAN13Reader.m in Sources */,
+ 25403EF5166A9DF400E13304 /* ZXEAN13Writer.m in Sources */,
+ 25403EF7166A9DF400E13304 /* ZXEAN8Reader.m in Sources */,
+ 25403EF9166A9DF400E13304 /* ZXEAN8Writer.m in Sources */,
+ 25389B8C18010B9A00772392 /* ZXPDF417DetectorResult.m in Sources */,
+ 25403EFB166A9DF400E13304 /* ZXEANManufacturerOrgSupport.m in Sources */,
+ 25403EFD166A9DF400E13304 /* ZXITFReader.m in Sources */,
+ 25403EFF166A9DF400E13304 /* ZXITFWriter.m in Sources */,
+ 25403F01166A9DF400E13304 /* ZXMultiFormatOneDReader.m in Sources */,
+ 25403F03166A9DF400E13304 /* ZXMultiFormatUPCEANReader.m in Sources */,
+ 25403F05166A9DF400E13304 /* ZXOneDimensionalCodeWriter.m in Sources */,
+ 25403F07166A9DF400E13304 /* ZXOneDReader.m in Sources */,
+ 25403F09166A9DF400E13304 /* ZXUPCAReader.m in Sources */,
+ 25403F0B166A9DF400E13304 /* ZXUPCAWriter.m in Sources */,
+ 25403F0D166A9DF400E13304 /* ZXUPCEANExtension2Support.m in Sources */,
+ 25403F0F166A9DF400E13304 /* ZXUPCEANExtension5Support.m in Sources */,
+ 25403F11166A9DF400E13304 /* ZXUPCEANExtensionSupport.m in Sources */,
+ 25403F13166A9DF400E13304 /* ZXUPCEANReader.m in Sources */,
+ 25403F15166A9DF400E13304 /* ZXUPCEANWriter.m in Sources */,
+ 25403F17166A9DF400E13304 /* ZXUPCEReader.m in Sources */,
+ 25403F3D166A9EB500E13304 /* ZXModulusGF.m in Sources */,
+ 25403F3F166A9EB500E13304 /* ZXModulusPoly.m in Sources */,
+ 25403F41166A9EB500E13304 /* ZXPDF417ECErrorCorrection.m in Sources */,
+ 25403F45166A9EB500E13304 /* ZXPDF417DecodedBitStreamParser.m in Sources */,
+ 25403F49166A9EB500E13304 /* ZXPDF417Detector.m in Sources */,
+ 25403F4B166A9EB500E13304 /* ZXBarcodeMatrix.m in Sources */,
+ 25403F4D166A9EB500E13304 /* ZXBarcodeRow.m in Sources */,
+ 2519AB6117FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m in Sources */,
+ 25403F50166A9EB500E13304 /* ZXDimensions.m in Sources */,
+ 25403F52166A9EB500E13304 /* ZXPDF417.m in Sources */,
+ 25403F54166A9EB500E13304 /* ZXPDF417ErrorCorrection.m in Sources */,
+ 25403F56166A9EB500E13304 /* ZXPDF417HighLevelEncoder.m in Sources */,
+ 25403F5A166A9EB500E13304 /* ZXPDF417Reader.m in Sources */,
+ 25403F8E166A9F2D00E13304 /* ZXDataMask.m in Sources */,
+ 25403F90166A9F2D00E13304 /* ZXErrorCorrectionLevel.m in Sources */,
+ 25403F92166A9F2D00E13304 /* ZXFormatInformation.m in Sources */,
+ 25403F94166A9F2D00E13304 /* ZXMode.m in Sources */,
+ 25403F96166A9F2D00E13304 /* ZXQRCodeBitMatrixParser.m in Sources */,
+ 25403F98166A9F2D00E13304 /* ZXQRCodeDataBlock.m in Sources */,
+ 25403F9A166A9F2D00E13304 /* ZXQRCodeDecodedBitStreamParser.m in Sources */,
+ 25403F9C166A9F2D00E13304 /* ZXQRCodeDecoder.m in Sources */,
+ 25403F9E166A9F2D00E13304 /* ZXQRCodeVersion.m in Sources */,
+ 25403FA0166A9F2D00E13304 /* ZXAlignmentPattern.m in Sources */,
+ 25403FA2166A9F2D00E13304 /* ZXAlignmentPatternFinder.m in Sources */,
+ 25403FA4166A9F2D00E13304 /* ZXFinderPatternFinder.m in Sources */,
+ 25403FA6166A9F2D00E13304 /* ZXFinderPatternInfo.m in Sources */,
+ 25403FA8166A9F2D00E13304 /* ZXQRCodeDetector.m in Sources */,
+ 25403FAA166A9F2D00E13304 /* ZXQRCodeFinderPattern.m in Sources */,
+ 25403FAC166A9F2D00E13304 /* ZXBlockPair.m in Sources */,
+ 25403FAE166A9F2D00E13304 /* ZXByteMatrix.m in Sources */,
+ 25403FB0166A9F2D00E13304 /* ZXEncoder.m in Sources */,
+ 25403FB2166A9F2D00E13304 /* ZXMaskUtil.m in Sources */,
+ 25403FB4166A9F2D00E13304 /* ZXMatrixUtil.m in Sources */,
+ 25403FB6166A9F2D00E13304 /* ZXQRCode.m in Sources */,
+ 25403FB8166A9F2D00E13304 /* ZXQRCodeReader.m in Sources */,
+ 25389B7417FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m in Sources */,
+ 25403FBA166A9F2D00E13304 /* ZXQRCodeWriter.m in Sources */,
+ 25403FC8166A9FFC00E13304 /* ZXBinarizer.m in Sources */,
+ 25403FCA166A9FFC00E13304 /* ZXBinaryBitmap.m in Sources */,
+ 25403FCC166A9FFC00E13304 /* ZXDecodeHints.m in Sources */,
+ 25403FCE166A9FFC00E13304 /* ZXEncodeHints.m in Sources */,
+ 25403FD0166A9FFC00E13304 /* ZXErrors.m in Sources */,
+ 25403FE0166AA00800E13304 /* ZXLuminanceSource.m in Sources */,
+ 25403FE2166AA00800E13304 /* ZXMultiFormatReader.m in Sources */,
+ 25403FE4166AA00800E13304 /* ZXMultiFormatWriter.m in Sources */,
+ 25403FE7166AA00800E13304 /* ZXResult.m in Sources */,
+ 25403FEA166AA00800E13304 /* ZXResultPoint.m in Sources */,
+ 251FCDED16CC8F53000C27E5 /* ZXRGBLuminanceSource.m in Sources */,
+ 25FE5D3416D0AFED00826CDB /* ZXExpandedRow.m in Sources */,
+ 2542996E16D3331F00D4C045 /* ZXPlanarYUVLuminanceSource.m in Sources */,
+ 2519AB3F17FD1EE400A71C45 /* ZXPDF417Writer.m in Sources */,
+ 2519AB4917FE5C1F00A71C45 /* ZXPDF417ResultMetadata.m in Sources */,
+ 25389B7C1800DEC300772392 /* ZXPDF417CodewordDecoder.m in Sources */,
+ 2542997616D46E8500D4C045 /* ZXDimension.m in Sources */,
+ 2542997E16D470D600D4C045 /* ZXDataMatrixWriter.m in Sources */,
+ 2542998916D478A000D4C045 /* ZXASCIIEncoder.m in Sources */,
+ 2542999216D47BC000D4C045 /* ZXBase256Encoder.m in Sources */,
+ 2542999C16D482F900D4C045 /* ZXC40Encoder.m in Sources */,
+ 254299A416D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m in Sources */,
+ 254299AC16D4886100D4C045 /* ZXDefaultPlacement.m in Sources */,
+ 254299B416D4A36700D4C045 /* ZXEdifactEncoder.m in Sources */,
+ 254299BC16D4A5AA00D4C045 /* ZXEncoderContext.m in Sources */,
+ 254299C416D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.m in Sources */,
+ 254299CC16D5BD5400D4C045 /* ZXHighLevelEncoder.m in Sources */,
+ 254299D416D5C96100D4C045 /* ZXSymbolInfo.m in Sources */,
+ 254299E016D5D24E00D4C045 /* ZXSymbolShapeHint.m in Sources */,
+ 254299E816D5D81A00D4C045 /* ZXTextEncoder.m in Sources */,
+ 254299F016D5D94B00D4C045 /* ZXX12Encoder.m in Sources */,
+ 2504D4C716F698AA00DF8882 /* ZXInvertedLuminanceSource.m in Sources */,
+ 2504D9D016FFD2E200DF8882 /* ZXAztecCode.m in Sources */,
+ 2504D9DD16FFD4CD00DF8882 /* ZXAztecEncoder.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25403CBF166A96FA00E13304 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 254040D9166AA0F100E13304 /* ZXAddressBookParsedResultTestCase.m in Sources */,
+ 254040DA166AA0F100E13304 /* ZXCalendarParsedResultTestCase.m in Sources */,
+ 254040DB166AA0F100E13304 /* ZXEmailAddressParsedResultTestCase.m in Sources */,
+ 254040DC166AA0F100E13304 /* ZXExpandedProductParsedResultTestCase.m in Sources */,
+ 254040DD166AA0F100E13304 /* ZXGeoParsedResultTestCase.m in Sources */,
+ 254040DE166AA0F100E13304 /* ZXISBNParsedResultTestCase.m in Sources */,
+ 254040DF166AA0F100E13304 /* ZXParsedReaderResultTestCase.m in Sources */,
+ 254040E0166AA0F100E13304 /* ZXProductParsedResultTestCase.m in Sources */,
+ 254040E1166AA0F100E13304 /* ZXSMSMMSParsedResultTestCase.m in Sources */,
+ 254040E2166AA0F100E13304 /* ZXTelParsedResultTestCase.m in Sources */,
+ 254040E3166AA0F100E13304 /* ZXURIParsedResultTestCase.m in Sources */,
+ 254040E4166AA0F100E13304 /* ZXWifiParsedResultTestCase.m in Sources */,
+ 254040EC166AA0F100E13304 /* ZXBitArrayTestCase.m in Sources */,
+ 254040ED166AA0F100E13304 /* ZXBitMatrixTestCase.m in Sources */,
+ 254040EE166AA0F100E13304 /* ZXBitSourceBuilder.m in Sources */,
+ 254040EF166AA0F100E13304 /* ZXBitSourceTestCase.m in Sources */,
+ 254040F0166AA0F100E13304 /* ZXPerspectiveTransformTestCase.m in Sources */,
+ 254040F1166AA0F100E13304 /* ZXStringUtilsTestCase.m in Sources */,
+ 254040F4166AA0F100E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.m in Sources */,
+ 25404109166AA0F100E13304 /* AbstractDecoderTest.m in Sources */,
+ 2540410A166AA0F100E13304 /* AI01_3103_DecoderTest.m in Sources */,
+ 2540410B166AA0F100E13304 /* AI01_3202_3203_DecoderTest.m in Sources */,
+ 2540410C166AA0F100E13304 /* AI01_3X0X_1X_DecoderTest.m in Sources */,
+ 2540410D166AA0F100E13304 /* AnyAIDecoderTest.m in Sources */,
+ 2540410E166AA0F100E13304 /* ZXFieldParserTest.m in Sources */,
+ 25404112166AA0F100E13304 /* RSSExpandedImage2binaryTestCase.m in Sources */,
+ 25404113166AA0F100E13304 /* RSSExpandedImage2resultTestCase.m in Sources */,
+ 25404114166AA0F100E13304 /* RSSExpandedImage2stringTestCase.m in Sources */,
+ 25404115166AA0F100E13304 /* RSSExpandedInternalTestCase.m in Sources */,
+ 25404116166AA0F100E13304 /* ZXBinaryUtil.m in Sources */,
+ 25404117166AA0F100E13304 /* ZXBinaryUtilTest.m in Sources */,
+ 25404118166AA0F100E13304 /* ZXBitArrayBuilderTest.m in Sources */,
+ 25404119166AA0F100E13304 /* ZXExpandedInformationDecoderTest.m in Sources */,
+ 25404126166AA0F100E13304 /* ZXCodaBarWriterTestCase.m in Sources */,
+ 25404128166AA0F100E13304 /* ZXEAN13WriterTestCase.m in Sources */,
+ 25404129166AA0F100E13304 /* ZXEAN8WriterTestCase.m in Sources */,
+ 2540412A166AA0F100E13304 /* ZXEANManufacturerOrgSupportTest.m in Sources */,
+ 2540412C166AA0F100E13304 /* ZXUPCAWriterTestCase.m in Sources */,
+ 2540412D166AA0F100E13304 /* AbstractErrorCorrectionTestCase.m in Sources */,
+ 2540412E166AA0F100E13304 /* ZXPDF417ECErrorCorrectionTestCase.m in Sources */,
+ 25404131166AA0F100E13304 /* ZXDataMaskTestCase.m in Sources */,
+ 25404132166AA0F100E13304 /* ZXErrorCorrectionLevelTestCase.m in Sources */,
+ 25404133166AA0F100E13304 /* ZXFormatInformationTestCase.m in Sources */,
+ 25404134166AA0F100E13304 /* ZXModeTestCase.m in Sources */,
+ 25404135166AA0F100E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.m in Sources */,
+ 25404136166AA0F100E13304 /* ZXQRCodeVersionTestCase.m in Sources */,
+ 25404137166AA0F100E13304 /* BitVectorTestCase.m in Sources */,
+ 25404138166AA0F100E13304 /* ZXEncoderTestCase.m in Sources */,
+ 25404139166AA0F100E13304 /* ZXMaskUtilTestCase.m in Sources */,
+ 2540413A166AA0F100E13304 /* ZXMatrixUtilTestCase.m in Sources */,
+ 2540413B166AA0F100E13304 /* ZXQRCodeTestCase.m in Sources */,
+ 25389B9918010DCB00772392 /* ZXPDF417DetectorTest.m in Sources */,
+ 25404142166AA0F100E13304 /* ZXQRCodeWriterTestCase.m in Sources */,
+ 25FE5D4016D0B84C00826CDB /* RSSExpandedStackedInternalTestCase.m in Sources */,
+ 25FE5D4316D0B8B200826CDB /* TestCaseUtil.m in Sources */,
+ 254299FB16D5DCC000D4C045 /* ZXDataMatrixWriterTestCase.m in Sources */,
+ 25429A0016D5DFD800D4C045 /* ZXDebugPlacement.m in Sources */,
+ 25429A0416D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m in Sources */,
+ 25429A0816D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.m in Sources */,
+ 25429A0C16D5F4E000D4C045 /* ZXPlacementTestCase.m in Sources */,
+ 25429A1016D5F66D00D4C045 /* ZXSymbolInfoTestCase.m in Sources */,
+ 2504D9E916FFF2A900DF8882 /* ZXAztecEncoderTest.m in Sources */,
+ 2504D9EC170005FE00DF8882 /* ReedSolomonTestCase.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25404162166AADAC00E13304 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2540418F166AAE6000E13304 /* ZXAztecDecoder.m in Sources */,
+ 2519AB3817FD1EC000A71C45 /* ZXAztecWriter.m in Sources */,
+ 25404190166AAE6000E13304 /* ZXAztecDetector.m in Sources */,
+ 25404191166AAE6000E13304 /* ZXAztecDetectorResult.m in Sources */,
+ 25404192166AAE6000E13304 /* ZXAztecReader.m in Sources */,
+ 25404193166AAE6000E13304 /* ZXAbstractDoCoMoResultParser.m in Sources */,
+ 25404194166AAE6000E13304 /* ZXAddressBookAUResultParser.m in Sources */,
+ 25404195166AAE6000E13304 /* ZXAddressBookDoCoMoResultParser.m in Sources */,
+ 25404196166AAE6000E13304 /* ZXAddressBookParsedResult.m in Sources */,
+ 25404197166AAE6000E13304 /* ZXBizcardResultParser.m in Sources */,
+ 25404198166AAE6000E13304 /* ZXBookmarkDoCoMoResultParser.m in Sources */,
+ 25404199166AAE6000E13304 /* ZXCalendarParsedResult.m in Sources */,
+ 2540419A166AAE6000E13304 /* ZXEmailAddressParsedResult.m in Sources */,
+ 2540419B166AAE6000E13304 /* ZXEmailAddressResultParser.m in Sources */,
+ 2540419C166AAE6000E13304 /* ZXEmailDoCoMoResultParser.m in Sources */,
+ 2540419D166AAE6000E13304 /* ZXExpandedProductParsedResult.m in Sources */,
+ 2540419E166AAE6000E13304 /* ZXExpandedProductResultParser.m in Sources */,
+ 2540419F166AAE6000E13304 /* ZXGeoParsedResult.m in Sources */,
+ 254041A0166AAE6000E13304 /* ZXGeoResultParser.m in Sources */,
+ 254041A1166AAE6000E13304 /* ZXISBNParsedResult.m in Sources */,
+ 254041A2166AAE6000E13304 /* ZXISBNResultParser.m in Sources */,
+ 254041A3166AAE6000E13304 /* ZXParsedResult.m in Sources */,
+ 254041A4166AAE6000E13304 /* ZXProductParsedResult.m in Sources */,
+ 254041A5166AAE6000E13304 /* ZXProductResultParser.m in Sources */,
+ 254041A6166AAE6000E13304 /* ZXResultParser.m in Sources */,
+ 254041A7166AAE6000E13304 /* ZXSMSMMSResultParser.m in Sources */,
+ 254041A8166AAE6000E13304 /* ZXSMSParsedResult.m in Sources */,
+ 254041A9166AAE6000E13304 /* ZXSMSTOMMSTOResultParser.m in Sources */,
+ 254041AA166AAE6000E13304 /* ZXSMTPResultParser.m in Sources */,
+ 254041AB166AAE6000E13304 /* ZXTelParsedResult.m in Sources */,
+ 254041AC166AAE6000E13304 /* ZXTelResultParser.m in Sources */,
+ 254041AD166AAE6000E13304 /* ZXTextParsedResult.m in Sources */,
+ 254041AE166AAE6000E13304 /* ZXURIParsedResult.m in Sources */,
+ 2519AB4C17FE5C3100A71C45 /* ZXPDF417Common.m in Sources */,
+ 254041AF166AAE6000E13304 /* ZXURIResultParser.m in Sources */,
+ 254041B0166AAE6000E13304 /* ZXURLTOResultParser.m in Sources */,
+ 254041B1166AAE6000E13304 /* ZXVCardResultParser.m in Sources */,
+ 254041B2166AAE6000E13304 /* ZXVEventResultParser.m in Sources */,
+ 254041B3166AAE6000E13304 /* ZXWifiParsedResult.m in Sources */,
+ 254041B4166AAE6000E13304 /* ZXWifiResultParser.m in Sources */,
+ 254041B5166AAE6000E13304 /* ZXCapture.m in Sources */,
+ 254041B6166AAE6000E13304 /* ZXCaptureView.m in Sources */,
+ 254041B7166AAE6000E13304 /* ZXCGImageLuminanceSource.m in Sources */,
+ 254041B8166AAE6000E13304 /* ZXImage.m in Sources */,
+ 254041B9166AAE6000E13304 /* ZXMathUtils.m in Sources */,
+ 254041BA166AAE6000E13304 /* ZXMonochromeRectangleDetector.m in Sources */,
+ 254041BB166AAE6000E13304 /* ZXWhiteRectangleDetector.m in Sources */,
+ 254041BC166AAE6000E13304 /* ZXGenericGF.m in Sources */,
+ 254041BD166AAE6000E13304 /* ZXGenericGFPoly.m in Sources */,
+ 254041BE166AAE6000E13304 /* ZXReedSolomonDecoder.m in Sources */,
+ 254041BF166AAE6000E13304 /* ZXReedSolomonEncoder.m in Sources */,
+ 254041C0166AAE6000E13304 /* ZXBitArray.m in Sources */,
+ 254041C1166AAE6000E13304 /* ZXBitMatrix.m in Sources */,
+ 254041C2166AAE6000E13304 /* ZXBitSource.m in Sources */,
+ 254041C3166AAE6000E13304 /* ZXCharacterSetECI.m in Sources */,
+ 254041C4166AAE6000E13304 /* ZXDecoderResult.m in Sources */,
+ 254041C5166AAE6000E13304 /* ZXDefaultGridSampler.m in Sources */,
+ 254041C6166AAE6000E13304 /* ZXDetectorResult.m in Sources */,
+ 254041C7166AAE6000E13304 /* ZXECI.m in Sources */,
+ 254041C8166AAE6000E13304 /* ZXGlobalHistogramBinarizer.m in Sources */,
+ 254041C9166AAE6000E13304 /* ZXGridSampler.m in Sources */,
+ 254041CA166AAE6000E13304 /* ZXHybridBinarizer.m in Sources */,
+ 254041CB166AAE6000E13304 /* ZXPerspectiveTransform.m in Sources */,
+ 25389B851800E35B00772392 /* ZXPDF417ScanningDecoder.m in Sources */,
+ 254041CC166AAE6000E13304 /* ZXStringUtils.m in Sources */,
+ 254041CD166AAE6000E13304 /* ZXDataMatrixBitMatrixParser.m in Sources */,
+ 254041CE166AAE6000E13304 /* ZXDataMatrixDataBlock.m in Sources */,
+ 254041CF166AAE6000E13304 /* ZXDataMatrixDecodedBitStreamParser.m in Sources */,
+ 254041D0166AAE6000E13304 /* ZXDataMatrixDecoder.m in Sources */,
+ 254041D1166AAE6000E13304 /* ZXDataMatrixVersion.m in Sources */,
+ 254041D2166AAE6000E13304 /* ZXDataMatrixDetector.m in Sources */,
+ 254041D3166AAE6000E13304 /* ZXDataMatrixReader.m in Sources */,
+ 254041D4166AAE6000E13304 /* ZXMaxiCodeBitMatrixParser.m in Sources */,
+ 254041D5166AAE6000E13304 /* ZXMaxiCodeDecodedBitStreamParser.m in Sources */,
+ 254041D6166AAE6000E13304 /* ZXMaxiCodeDecoder.m in Sources */,
+ 254041D7166AAE6000E13304 /* ZXMaxiCodeReader.m in Sources */,
+ 25389B6D17FFC98100772392 /* ZXPDF417DetectionResultColumn.m in Sources */,
+ 254041D8166AAE6000E13304 /* ZXMultiDetector.m in Sources */,
+ 254041D9166AAE6000E13304 /* ZXMultiFinderPatternFinder.m in Sources */,
+ 254041DA166AAE6000E13304 /* ZXQRCodeMultiReader.m in Sources */,
+ 254041DB166AAE6000E13304 /* ZXByQuadrantReader.m in Sources */,
+ 254041DC166AAE6000E13304 /* ZXGenericMultipleBarcodeReader.m in Sources */,
+ 254041DD166AAE6000E13304 /* ZXAbstractExpandedDecoder.m in Sources */,
+ 254041DE166AAE6000E13304 /* ZXAI013103decoder.m in Sources */,
+ 254041DF166AAE6000E13304 /* ZXAI01320xDecoder.m in Sources */,
+ 254041E0166AAE6000E13304 /* ZXAI01392xDecoder.m in Sources */,
+ 254041E1166AAE6000E13304 /* ZXAI01393xDecoder.m in Sources */,
+ 2519AB6A17FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m in Sources */,
+ 254041E2166AAE6000E13304 /* ZXAI013x0x1xDecoder.m in Sources */,
+ 254041E3166AAE6000E13304 /* ZXAI013x0xDecoder.m in Sources */,
+ 254041E4166AAE6000E13304 /* ZXAI01AndOtherAIs.m in Sources */,
+ 254041E5166AAE6000E13304 /* ZXAI01decoder.m in Sources */,
+ 254041E6166AAE6000E13304 /* ZXAI01weightDecoder.m in Sources */,
+ 254041E7166AAE6000E13304 /* ZXAnyAIDecoder.m in Sources */,
+ 254041E8166AAE6000E13304 /* ZXBlockParsedResult.m in Sources */,
+ 254041E9166AAE6000E13304 /* ZXCurrentParsingState.m in Sources */,
+ 254041EA166AAE6000E13304 /* ZXDecodedChar.m in Sources */,
+ 2519AB7A17FE649000A71C45 /* ZXPDF417Codeword.m in Sources */,
+ 254041EB166AAE6000E13304 /* ZXDecodedInformation.m in Sources */,
+ 254041EC166AAE6000E13304 /* ZXDecodedNumeric.m in Sources */,
+ 25389B6317FFC84300772392 /* ZXPDF417DetectionResult.m in Sources */,
+ 254041ED166AAE6000E13304 /* ZXDecodedObject.m in Sources */,
+ 254041EE166AAE6000E13304 /* ZXFieldParser.m in Sources */,
+ 254041EF166AAE6000E13304 /* ZXGeneralAppIdDecoder.m in Sources */,
+ 254041F0166AAE6000E13304 /* ZXBitArrayBuilder.m in Sources */,
+ 254041F1166AAE6000E13304 /* ZXExpandedPair.m in Sources */,
+ 2519AB7217FE60E700A71C45 /* ZXPDF417BoundingBox.m in Sources */,
+ 254041F2166AAE6000E13304 /* ZXRSSExpandedReader.m in Sources */,
+ 254041F3166AAE6000E13304 /* ZXAbstractRSSReader.m in Sources */,
+ 254041F4166AAE6000E13304 /* ZXDataCharacter.m in Sources */,
+ 254041F5166AAE6000E13304 /* ZXPair.m in Sources */,
+ 254041F6166AAE6000E13304 /* ZXRSS14Reader.m in Sources */,
+ 254041F7166AAE6000E13304 /* ZXRSSFinderPattern.m in Sources */,
+ 254041F8166AAE6000E13304 /* ZXRSSUtils.m in Sources */,
+ 254041F9166AAE6000E13304 /* ZXCodaBarReader.m in Sources */,
+ 254041FA166AAE6000E13304 /* ZXCodaBarWriter.m in Sources */,
+ 254041FB166AAE6000E13304 /* ZXCode128Reader.m in Sources */,
+ 254041FC166AAE6000E13304 /* ZXCode128Writer.m in Sources */,
+ 254041FD166AAE6000E13304 /* ZXCode39Reader.m in Sources */,
+ 254041FE166AAE6000E13304 /* ZXCode39Writer.m in Sources */,
+ 254041FF166AAE6000E13304 /* ZXCode93Reader.m in Sources */,
+ 25404200166AAE6000E13304 /* ZXEAN13Reader.m in Sources */,
+ 25404201166AAE6000E13304 /* ZXEAN13Writer.m in Sources */,
+ 25404202166AAE6000E13304 /* ZXEAN8Reader.m in Sources */,
+ 25404203166AAE6000E13304 /* ZXEAN8Writer.m in Sources */,
+ 25389B8D18010B9A00772392 /* ZXPDF417DetectorResult.m in Sources */,
+ 25404204166AAE6000E13304 /* ZXEANManufacturerOrgSupport.m in Sources */,
+ 25404205166AAE6000E13304 /* ZXITFReader.m in Sources */,
+ 25404206166AAE6000E13304 /* ZXITFWriter.m in Sources */,
+ 25404207166AAE6000E13304 /* ZXMultiFormatOneDReader.m in Sources */,
+ 25404208166AAE6000E13304 /* ZXMultiFormatUPCEANReader.m in Sources */,
+ 25404209166AAE6000E13304 /* ZXOneDimensionalCodeWriter.m in Sources */,
+ 2540420A166AAE6000E13304 /* ZXOneDReader.m in Sources */,
+ 2540420B166AAE6000E13304 /* ZXUPCAReader.m in Sources */,
+ 2540420C166AAE6000E13304 /* ZXUPCAWriter.m in Sources */,
+ 2540420D166AAE6000E13304 /* ZXUPCEANExtension2Support.m in Sources */,
+ 2540420E166AAE6000E13304 /* ZXUPCEANExtension5Support.m in Sources */,
+ 2540420F166AAE6000E13304 /* ZXUPCEANExtensionSupport.m in Sources */,
+ 25404210166AAE6000E13304 /* ZXUPCEANReader.m in Sources */,
+ 25404211166AAE6000E13304 /* ZXUPCEANWriter.m in Sources */,
+ 25404212166AAE6000E13304 /* ZXUPCEReader.m in Sources */,
+ 25404213166AAE6000E13304 /* ZXModulusGF.m in Sources */,
+ 2519AB4B17FE5C2E00A71C45 /* ZXPDF417ResultMetadata.m in Sources */,
+ 25404214166AAE6000E13304 /* ZXModulusPoly.m in Sources */,
+ 25404215166AAE6000E13304 /* ZXPDF417ECErrorCorrection.m in Sources */,
+ 25404217166AAE6000E13304 /* ZXPDF417DecodedBitStreamParser.m in Sources */,
+ 25404219166AAE6000E13304 /* ZXPDF417Detector.m in Sources */,
+ 2540421A166AAE6000E13304 /* ZXBarcodeMatrix.m in Sources */,
+ 2519AB6217FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m in Sources */,
+ 2540421B166AAE6000E13304 /* ZXBarcodeRow.m in Sources */,
+ 2540421C166AAE6000E13304 /* ZXDimensions.m in Sources */,
+ 2540421D166AAE6000E13304 /* ZXPDF417.m in Sources */,
+ 2540421E166AAE6000E13304 /* ZXPDF417ErrorCorrection.m in Sources */,
+ 2540421F166AAE6000E13304 /* ZXPDF417HighLevelEncoder.m in Sources */,
+ 25404221166AAE6000E13304 /* ZXPDF417Reader.m in Sources */,
+ 25404222166AAE6000E13304 /* ZXDataMask.m in Sources */,
+ 25404223166AAE6000E13304 /* ZXErrorCorrectionLevel.m in Sources */,
+ 25404224166AAE6000E13304 /* ZXFormatInformation.m in Sources */,
+ 25404225166AAE6000E13304 /* ZXMode.m in Sources */,
+ 25404226166AAE6000E13304 /* ZXQRCodeBitMatrixParser.m in Sources */,
+ 25404227166AAE6000E13304 /* ZXQRCodeDataBlock.m in Sources */,
+ 25404228166AAE6000E13304 /* ZXQRCodeDecodedBitStreamParser.m in Sources */,
+ 25404229166AAE6000E13304 /* ZXQRCodeDecoder.m in Sources */,
+ 2540422A166AAE6000E13304 /* ZXQRCodeVersion.m in Sources */,
+ 2540422B166AAE6000E13304 /* ZXAlignmentPattern.m in Sources */,
+ 2540422C166AAE6000E13304 /* ZXAlignmentPatternFinder.m in Sources */,
+ 2540422D166AAE6000E13304 /* ZXFinderPatternFinder.m in Sources */,
+ 2540422E166AAE6000E13304 /* ZXFinderPatternInfo.m in Sources */,
+ 2540422F166AAE6000E13304 /* ZXQRCodeDetector.m in Sources */,
+ 25404230166AAE6000E13304 /* ZXQRCodeFinderPattern.m in Sources */,
+ 25404231166AAE6000E13304 /* ZXBlockPair.m in Sources */,
+ 25404232166AAE6000E13304 /* ZXByteMatrix.m in Sources */,
+ 25404233166AAE6000E13304 /* ZXEncoder.m in Sources */,
+ 25404234166AAE6000E13304 /* ZXMaskUtil.m in Sources */,
+ 25404235166AAE6000E13304 /* ZXMatrixUtil.m in Sources */,
+ 25404236166AAE6000E13304 /* ZXQRCode.m in Sources */,
+ 25389B7517FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m in Sources */,
+ 25404237166AAE6000E13304 /* ZXQRCodeReader.m in Sources */,
+ 25404238166AAE6000E13304 /* ZXQRCodeWriter.m in Sources */,
+ 25404239166AAE6000E13304 /* ZXBinarizer.m in Sources */,
+ 2540423A166AAE6000E13304 /* ZXBinaryBitmap.m in Sources */,
+ 2540423B166AAE6000E13304 /* ZXDecodeHints.m in Sources */,
+ 2540423C166AAE6000E13304 /* ZXEncodeHints.m in Sources */,
+ 2540423D166AAE6000E13304 /* ZXErrors.m in Sources */,
+ 2540423E166AAE6000E13304 /* ZXLuminanceSource.m in Sources */,
+ 2540423F166AAE6000E13304 /* ZXMultiFormatReader.m in Sources */,
+ 25404240166AAE6000E13304 /* ZXMultiFormatWriter.m in Sources */,
+ 25404241166AAE6000E13304 /* ZXResult.m in Sources */,
+ 25404242166AAE6000E13304 /* ZXResultPoint.m in Sources */,
+ 251FCDEE16CC8F53000C27E5 /* ZXRGBLuminanceSource.m in Sources */,
+ 25FE5D3616D0B00600826CDB /* ZXExpandedRow.m in Sources */,
+ 2542997116D3336000D4C045 /* ZXPlanarYUVLuminanceSource.m in Sources */,
+ 2519AB4017FD1EE400A71C45 /* ZXPDF417Writer.m in Sources */,
+ 25389B7D1800DEC300772392 /* ZXPDF417CodewordDecoder.m in Sources */,
+ 2542997A16D46FF200D4C045 /* ZXDimension.m in Sources */,
+ 2542998216D470F400D4C045 /* ZXDataMatrixWriter.m in Sources */,
+ 2542998A16D478A000D4C045 /* ZXASCIIEncoder.m in Sources */,
+ 2542999316D47BC000D4C045 /* ZXBase256Encoder.m in Sources */,
+ 2542999D16D482F900D4C045 /* ZXC40Encoder.m in Sources */,
+ 254299A516D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m in Sources */,
+ 254299AD16D4886100D4C045 /* ZXDefaultPlacement.m in Sources */,
+ 254299B516D4A36700D4C045 /* ZXEdifactEncoder.m in Sources */,
+ 254299BD16D4A5AA00D4C045 /* ZXEncoderContext.m in Sources */,
+ 254299C516D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.m in Sources */,
+ 254299CD16D5BD5400D4C045 /* ZXHighLevelEncoder.m in Sources */,
+ 254299D516D5C96100D4C045 /* ZXSymbolInfo.m in Sources */,
+ 254299E116D5D24E00D4C045 /* ZXSymbolShapeHint.m in Sources */,
+ 254299E916D5D81A00D4C045 /* ZXTextEncoder.m in Sources */,
+ 254299F116D5D94B00D4C045 /* ZXX12Encoder.m in Sources */,
+ 2504D4CA16F698C900DF8882 /* ZXInvertedLuminanceSource.m in Sources */,
+ 2504D9D316FFD3B300DF8882 /* ZXAztecCode.m in Sources */,
+ 2504D9E016FFEB7B00DF8882 /* ZXAztecEncoder.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25404173166AADAC00E13304 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 255E481E18143A3900A03A28 /* RSSExpandedStackedInternalTestCase.m in Sources */,
+ 255E481F18143A3900A03A28 /* TestCaseUtil.m in Sources */,
+ 2540431D166AB8B800E13304 /* ZXAddressBookParsedResultTestCase.m in Sources */,
+ 2540431E166AB8B800E13304 /* ZXCalendarParsedResultTestCase.m in Sources */,
+ 2540431F166AB8B800E13304 /* ZXEmailAddressParsedResultTestCase.m in Sources */,
+ 25404320166AB8B800E13304 /* ZXExpandedProductParsedResultTestCase.m in Sources */,
+ 25404321166AB8B800E13304 /* ZXGeoParsedResultTestCase.m in Sources */,
+ 25404322166AB8B800E13304 /* ZXISBNParsedResultTestCase.m in Sources */,
+ 25404323166AB8B800E13304 /* ZXParsedReaderResultTestCase.m in Sources */,
+ 25404324166AB8B800E13304 /* ZXProductParsedResultTestCase.m in Sources */,
+ 25404325166AB8B800E13304 /* ZXSMSMMSParsedResultTestCase.m in Sources */,
+ 25404326166AB8B800E13304 /* ZXTelParsedResultTestCase.m in Sources */,
+ 25404327166AB8B800E13304 /* ZXURIParsedResultTestCase.m in Sources */,
+ 25404328166AB8B800E13304 /* ZXWifiParsedResultTestCase.m in Sources */,
+ 25404330166AB8B800E13304 /* ZXBitArrayTestCase.m in Sources */,
+ 25404331166AB8B800E13304 /* ZXBitMatrixTestCase.m in Sources */,
+ 25404332166AB8B800E13304 /* ZXBitSourceBuilder.m in Sources */,
+ 25404333166AB8B800E13304 /* ZXBitSourceTestCase.m in Sources */,
+ 25404334166AB8B800E13304 /* ZXPerspectiveTransformTestCase.m in Sources */,
+ 25404335166AB8B800E13304 /* ZXStringUtilsTestCase.m in Sources */,
+ 25404338166AB8B800E13304 /* ZXDataMatrixDecodedBitStreamParserTestCase.m in Sources */,
+ 2540434D166AB8B800E13304 /* AbstractDecoderTest.m in Sources */,
+ 2540434E166AB8B800E13304 /* AI01_3103_DecoderTest.m in Sources */,
+ 2540434F166AB8B800E13304 /* AI01_3202_3203_DecoderTest.m in Sources */,
+ 25404350166AB8B800E13304 /* AI01_3X0X_1X_DecoderTest.m in Sources */,
+ 25404351166AB8B800E13304 /* AnyAIDecoderTest.m in Sources */,
+ 25404352166AB8B800E13304 /* ZXFieldParserTest.m in Sources */,
+ 25404356166AB8B800E13304 /* RSSExpandedImage2binaryTestCase.m in Sources */,
+ 25404357166AB8B800E13304 /* RSSExpandedImage2resultTestCase.m in Sources */,
+ 25404358166AB8B800E13304 /* RSSExpandedImage2stringTestCase.m in Sources */,
+ 25404359166AB8B800E13304 /* RSSExpandedInternalTestCase.m in Sources */,
+ 2540435A166AB8B800E13304 /* ZXBinaryUtil.m in Sources */,
+ 2540435B166AB8B800E13304 /* ZXBinaryUtilTest.m in Sources */,
+ 2540435C166AB8B800E13304 /* ZXBitArrayBuilderTest.m in Sources */,
+ 2540435D166AB8B800E13304 /* ZXExpandedInformationDecoderTest.m in Sources */,
+ 2540436A166AB8B800E13304 /* ZXCodaBarWriterTestCase.m in Sources */,
+ 2540436C166AB8B800E13304 /* ZXEAN13WriterTestCase.m in Sources */,
+ 2540436D166AB8B800E13304 /* ZXEAN8WriterTestCase.m in Sources */,
+ 2540436E166AB8B800E13304 /* ZXEANManufacturerOrgSupportTest.m in Sources */,
+ 25404370166AB8B800E13304 /* ZXUPCAWriterTestCase.m in Sources */,
+ 25404371166AB8B800E13304 /* AbstractErrorCorrectionTestCase.m in Sources */,
+ 25404372166AB8B800E13304 /* ZXPDF417ECErrorCorrectionTestCase.m in Sources */,
+ 25404375166AB8B800E13304 /* ZXDataMaskTestCase.m in Sources */,
+ 25404376166AB8B800E13304 /* ZXErrorCorrectionLevelTestCase.m in Sources */,
+ 25404377166AB8B800E13304 /* ZXFormatInformationTestCase.m in Sources */,
+ 25404378166AB8B800E13304 /* ZXModeTestCase.m in Sources */,
+ 25404379166AB8B800E13304 /* ZXQRCodeDecodedBitStreamParserTestCase.m in Sources */,
+ 2540437A166AB8B800E13304 /* ZXQRCodeVersionTestCase.m in Sources */,
+ 2540437B166AB8B800E13304 /* BitVectorTestCase.m in Sources */,
+ 2540437C166AB8B800E13304 /* ZXEncoderTestCase.m in Sources */,
+ 2540437D166AB8B800E13304 /* ZXMaskUtilTestCase.m in Sources */,
+ 2540437E166AB8B800E13304 /* ZXMatrixUtilTestCase.m in Sources */,
+ 2540437F166AB8B800E13304 /* ZXQRCodeTestCase.m in Sources */,
+ 25389B9818010DCB00772392 /* ZXPDF417DetectorTest.m in Sources */,
+ 25404386166AB8B800E13304 /* ZXQRCodeWriterTestCase.m in Sources */,
+ 254299FC16D5DCC300D4C045 /* ZXDataMatrixWriterTestCase.m in Sources */,
+ 25429A0116D5DFD800D4C045 /* ZXDebugPlacement.m in Sources */,
+ 25429A0516D5E0ED00D4C045 /* ZXDataMatrixErrorCorrectionTestCase.m in Sources */,
+ 25429A0916D5E21C00D4C045 /* ZXHighLevelEncodeTestCase.m in Sources */,
+ 25429A0D16D5F4E000D4C045 /* ZXPlacementTestCase.m in Sources */,
+ 25429A1116D5F66D00D4C045 /* ZXSymbolInfoTestCase.m in Sources */,
+ 2504D9E816FFF27C00DF8882 /* ZXAztecEncoderTest.m in Sources */,
+ 2504D9ED170005FE00DF8882 /* ReedSolomonTestCase.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 25404399166ABA0A00E13304 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 255E482018143A4A00A03A28 /* ZXC40Encoder.m in Sources */,
+ 25404648166ABBED00E13304 /* ZXAztecDecoder.m in Sources */,
+ 25404649166ABBED00E13304 /* ZXAztecDetector.m in Sources */,
+ 2540464A166ABBED00E13304 /* ZXAztecDetectorResult.m in Sources */,
+ 2540464B166ABBED00E13304 /* ZXAztecReader.m in Sources */,
+ 2540464C166ABBED00E13304 /* ZXAbstractDoCoMoResultParser.m in Sources */,
+ 2540464D166ABBED00E13304 /* ZXAddressBookAUResultParser.m in Sources */,
+ 2540464E166ABBED00E13304 /* ZXAddressBookDoCoMoResultParser.m in Sources */,
+ 2540464F166ABBED00E13304 /* ZXAddressBookParsedResult.m in Sources */,
+ 25404650166ABBED00E13304 /* ZXBizcardResultParser.m in Sources */,
+ 25404651166ABBED00E13304 /* ZXBookmarkDoCoMoResultParser.m in Sources */,
+ 25404652166ABBED00E13304 /* ZXCalendarParsedResult.m in Sources */,
+ 25404653166ABBED00E13304 /* ZXEmailAddressParsedResult.m in Sources */,
+ 25404654166ABBED00E13304 /* ZXEmailAddressResultParser.m in Sources */,
+ 25404655166ABBED00E13304 /* ZXEmailDoCoMoResultParser.m in Sources */,
+ 25404656166ABBED00E13304 /* ZXExpandedProductParsedResult.m in Sources */,
+ 25404657166ABBED00E13304 /* ZXExpandedProductResultParser.m in Sources */,
+ 25404658166ABBED00E13304 /* ZXGeoParsedResult.m in Sources */,
+ 25404659166ABBED00E13304 /* ZXGeoResultParser.m in Sources */,
+ 2540465A166ABBED00E13304 /* ZXISBNParsedResult.m in Sources */,
+ 2540465B166ABBED00E13304 /* ZXISBNResultParser.m in Sources */,
+ 2540465C166ABBED00E13304 /* ZXParsedResult.m in Sources */,
+ 2540465D166ABBED00E13304 /* ZXProductParsedResult.m in Sources */,
+ 2540465E166ABBED00E13304 /* ZXProductResultParser.m in Sources */,
+ 2540465F166ABBED00E13304 /* ZXResultParser.m in Sources */,
+ 25404660166ABBED00E13304 /* ZXSMSMMSResultParser.m in Sources */,
+ 25404661166ABBED00E13304 /* ZXSMSParsedResult.m in Sources */,
+ 25404662166ABBED00E13304 /* ZXSMSTOMMSTOResultParser.m in Sources */,
+ 25404663166ABBED00E13304 /* ZXSMTPResultParser.m in Sources */,
+ 25404664166ABBED00E13304 /* ZXTelParsedResult.m in Sources */,
+ 25404665166ABBED00E13304 /* ZXTelResultParser.m in Sources */,
+ 25404666166ABBED00E13304 /* ZXTextParsedResult.m in Sources */,
+ 25404667166ABBED00E13304 /* ZXURIParsedResult.m in Sources */,
+ 25404668166ABBED00E13304 /* ZXURIResultParser.m in Sources */,
+ 25389B6417FFC84800772392 /* ZXPDF417DetectionResult.m in Sources */,
+ 25404669166ABBED00E13304 /* ZXURLTOResultParser.m in Sources */,
+ 2540466A166ABBED00E13304 /* ZXVCardResultParser.m in Sources */,
+ 2540466B166ABBED00E13304 /* ZXVEventResultParser.m in Sources */,
+ 2540466C166ABBED00E13304 /* ZXWifiParsedResult.m in Sources */,
+ 2540466D166ABBED00E13304 /* ZXWifiResultParser.m in Sources */,
+ 2540466E166ABBED00E13304 /* ZXCapture.m in Sources */,
+ 2540466F166ABBED00E13304 /* ZXCaptureView.m in Sources */,
+ 25404670166ABBED00E13304 /* ZXCGImageLuminanceSource.m in Sources */,
+ 25404671166ABBED00E13304 /* ZXImage.m in Sources */,
+ 25404672166ABBED00E13304 /* ZXMathUtils.m in Sources */,
+ 25404673166ABBED00E13304 /* ZXMonochromeRectangleDetector.m in Sources */,
+ 25404674166ABBED00E13304 /* ZXWhiteRectangleDetector.m in Sources */,
+ 25404675166ABBED00E13304 /* ZXGenericGF.m in Sources */,
+ 25404676166ABBED00E13304 /* ZXGenericGFPoly.m in Sources */,
+ 25404677166ABBED00E13304 /* ZXReedSolomonDecoder.m in Sources */,
+ 25404678166ABBED00E13304 /* ZXReedSolomonEncoder.m in Sources */,
+ 25404679166ABBED00E13304 /* ZXBitArray.m in Sources */,
+ 2540467A166ABBED00E13304 /* ZXBitMatrix.m in Sources */,
+ 2540467B166ABBED00E13304 /* ZXBitSource.m in Sources */,
+ 2540467C166ABBED00E13304 /* ZXCharacterSetECI.m in Sources */,
+ 2540467D166ABBED00E13304 /* ZXDecoderResult.m in Sources */,
+ 2540467E166ABBED00E13304 /* ZXDefaultGridSampler.m in Sources */,
+ 2540467F166ABBED00E13304 /* ZXDetectorResult.m in Sources */,
+ 25404680166ABBED00E13304 /* ZXECI.m in Sources */,
+ 25404681166ABBED00E13304 /* ZXGlobalHistogramBinarizer.m in Sources */,
+ 25404682166ABBED00E13304 /* ZXGridSampler.m in Sources */,
+ 25404683166ABBED00E13304 /* ZXHybridBinarizer.m in Sources */,
+ 25404684166ABBED00E13304 /* ZXPerspectiveTransform.m in Sources */,
+ 25404685166ABBED00E13304 /* ZXStringUtils.m in Sources */,
+ 25404686166ABBED00E13304 /* ZXDataMatrixBitMatrixParser.m in Sources */,
+ 25404687166ABBED00E13304 /* ZXDataMatrixDataBlock.m in Sources */,
+ 25404688166ABBED00E13304 /* ZXDataMatrixDecodedBitStreamParser.m in Sources */,
+ 25404689166ABBED00E13304 /* ZXDataMatrixDecoder.m in Sources */,
+ 2540468A166ABBED00E13304 /* ZXDataMatrixVersion.m in Sources */,
+ 2540468B166ABBED00E13304 /* ZXDataMatrixDetector.m in Sources */,
+ 2540468C166ABBED00E13304 /* ZXDataMatrixReader.m in Sources */,
+ 2540468D166ABBED00E13304 /* ZXMaxiCodeBitMatrixParser.m in Sources */,
+ 2540468E166ABBED00E13304 /* ZXMaxiCodeDecodedBitStreamParser.m in Sources */,
+ 2540468F166ABBED00E13304 /* ZXMaxiCodeDecoder.m in Sources */,
+ 2519AB7317FE60E700A71C45 /* ZXPDF417BoundingBox.m in Sources */,
+ 25404690166ABBED00E13304 /* ZXMaxiCodeReader.m in Sources */,
+ 25404691166ABBED00E13304 /* ZXMultiDetector.m in Sources */,
+ 25404692166ABBED00E13304 /* ZXMultiFinderPatternFinder.m in Sources */,
+ 25404693166ABBED00E13304 /* ZXQRCodeMultiReader.m in Sources */,
+ 25404694166ABBED00E13304 /* ZXByQuadrantReader.m in Sources */,
+ 25404695166ABBED00E13304 /* ZXGenericMultipleBarcodeReader.m in Sources */,
+ 25404696166ABBED00E13304 /* ZXAbstractExpandedDecoder.m in Sources */,
+ 25404697166ABBED00E13304 /* ZXAI013103decoder.m in Sources */,
+ 25404698166ABBED00E13304 /* ZXAI01320xDecoder.m in Sources */,
+ 25404699166ABBED00E13304 /* ZXAI01392xDecoder.m in Sources */,
+ 2540469A166ABBED00E13304 /* ZXAI01393xDecoder.m in Sources */,
+ 2540469B166ABBED00E13304 /* ZXAI013x0x1xDecoder.m in Sources */,
+ 2540469C166ABBED00E13304 /* ZXAI013x0xDecoder.m in Sources */,
+ 2519AB6B17FE5F2E00A71C45 /* ZXPDF417BarcodeValue.m in Sources */,
+ 2540469D166ABBED00E13304 /* ZXAI01AndOtherAIs.m in Sources */,
+ 2540469E166ABBED00E13304 /* ZXAI01decoder.m in Sources */,
+ 2540469F166ABBED00E13304 /* ZXAI01weightDecoder.m in Sources */,
+ 254046A0166ABBED00E13304 /* ZXAnyAIDecoder.m in Sources */,
+ 254046A1166ABBED00E13304 /* ZXBlockParsedResult.m in Sources */,
+ 254046A2166ABBED00E13304 /* ZXCurrentParsingState.m in Sources */,
+ 254046A3166ABBED00E13304 /* ZXDecodedChar.m in Sources */,
+ 254046A4166ABBED00E13304 /* ZXDecodedInformation.m in Sources */,
+ 2519AB4117FD1EE400A71C45 /* ZXPDF417Writer.m in Sources */,
+ 254046A5166ABBED00E13304 /* ZXDecodedNumeric.m in Sources */,
+ 254046A6166ABBED00E13304 /* ZXDecodedObject.m in Sources */,
+ 254046A7166ABBED00E13304 /* ZXFieldParser.m in Sources */,
+ 254046A8166ABBED00E13304 /* ZXGeneralAppIdDecoder.m in Sources */,
+ 254046A9166ABBED00E13304 /* ZXBitArrayBuilder.m in Sources */,
+ 254046AA166ABBED00E13304 /* ZXExpandedPair.m in Sources */,
+ 254046AB166ABBED00E13304 /* ZXRSSExpandedReader.m in Sources */,
+ 254046AC166ABBED00E13304 /* ZXAbstractRSSReader.m in Sources */,
+ 254046AD166ABBED00E13304 /* ZXDataCharacter.m in Sources */,
+ 254046AE166ABBED00E13304 /* ZXPair.m in Sources */,
+ 25389B8E18010B9A00772392 /* ZXPDF417DetectorResult.m in Sources */,
+ 254046AF166ABBED00E13304 /* ZXRSS14Reader.m in Sources */,
+ 254046B0166ABBED00E13304 /* ZXRSSFinderPattern.m in Sources */,
+ 254046B1166ABBED00E13304 /* ZXRSSUtils.m in Sources */,
+ 254046B2166ABBED00E13304 /* ZXCodaBarReader.m in Sources */,
+ 254046B3166ABBED00E13304 /* ZXCodaBarWriter.m in Sources */,
+ 254046B4166ABBED00E13304 /* ZXCode128Reader.m in Sources */,
+ 254046B5166ABBED00E13304 /* ZXCode128Writer.m in Sources */,
+ 254046B6166ABBED00E13304 /* ZXCode39Reader.m in Sources */,
+ 254046B7166ABBED00E13304 /* ZXCode39Writer.m in Sources */,
+ 254046B8166ABBED00E13304 /* ZXCode93Reader.m in Sources */,
+ 254046B9166ABBED00E13304 /* ZXEAN13Reader.m in Sources */,
+ 254046BA166ABBED00E13304 /* ZXEAN13Writer.m in Sources */,
+ 254046BB166ABBED00E13304 /* ZXEAN8Reader.m in Sources */,
+ 254046BC166ABBED00E13304 /* ZXEAN8Writer.m in Sources */,
+ 254046BD166ABBED00E13304 /* ZXEANManufacturerOrgSupport.m in Sources */,
+ 254046BE166ABBED00E13304 /* ZXITFReader.m in Sources */,
+ 254046BF166ABBED00E13304 /* ZXITFWriter.m in Sources */,
+ 25389B7617FFCA2700772392 /* ZXPDF417DetectionResultRowIndicatorColumn.m in Sources */,
+ 254046C0166ABBED00E13304 /* ZXMultiFormatOneDReader.m in Sources */,
+ 254046C1166ABBED00E13304 /* ZXMultiFormatUPCEANReader.m in Sources */,
+ 254046C2166ABBED00E13304 /* ZXOneDimensionalCodeWriter.m in Sources */,
+ 254046C3166ABBED00E13304 /* ZXOneDReader.m in Sources */,
+ 254046C4166ABBED00E13304 /* ZXUPCAReader.m in Sources */,
+ 254046C5166ABBED00E13304 /* ZXUPCAWriter.m in Sources */,
+ 254046C6166ABBED00E13304 /* ZXUPCEANExtension2Support.m in Sources */,
+ 254046C7166ABBED00E13304 /* ZXUPCEANExtension5Support.m in Sources */,
+ 254046C8166ABBED00E13304 /* ZXUPCEANExtensionSupport.m in Sources */,
+ 2519AB4D17FE5C3100A71C45 /* ZXPDF417Common.m in Sources */,
+ 254046C9166ABBED00E13304 /* ZXUPCEANReader.m in Sources */,
+ 254046CA166ABBED00E13304 /* ZXUPCEANWriter.m in Sources */,
+ 254046CB166ABBED00E13304 /* ZXUPCEReader.m in Sources */,
+ 254046CC166ABBED00E13304 /* ZXModulusGF.m in Sources */,
+ 254046CD166ABBED00E13304 /* ZXModulusPoly.m in Sources */,
+ 254046CE166ABBED00E13304 /* ZXPDF417ECErrorCorrection.m in Sources */,
+ 254046D0166ABBED00E13304 /* ZXPDF417DecodedBitStreamParser.m in Sources */,
+ 254046D2166ABBED00E13304 /* ZXPDF417Detector.m in Sources */,
+ 254046D3166ABBED00E13304 /* ZXBarcodeMatrix.m in Sources */,
+ 25389B7E1800DEC300772392 /* ZXPDF417CodewordDecoder.m in Sources */,
+ 2519AB7B17FE649000A71C45 /* ZXPDF417Codeword.m in Sources */,
+ 254046D4166ABBED00E13304 /* ZXBarcodeRow.m in Sources */,
+ 2519AB3917FD1EC000A71C45 /* ZXAztecWriter.m in Sources */,
+ 254046D5166ABBED00E13304 /* ZXDimensions.m in Sources */,
+ 254046D6166ABBED00E13304 /* ZXPDF417.m in Sources */,
+ 2519AB4A17FE5C2E00A71C45 /* ZXPDF417ResultMetadata.m in Sources */,
+ 254046D7166ABBED00E13304 /* ZXPDF417ErrorCorrection.m in Sources */,
+ 254046D8166ABBED00E13304 /* ZXPDF417HighLevelEncoder.m in Sources */,
+ 254046DA166ABBED00E13304 /* ZXPDF417Reader.m in Sources */,
+ 254046DB166ABBED00E13304 /* ZXDataMask.m in Sources */,
+ 254046DC166ABBED00E13304 /* ZXErrorCorrectionLevel.m in Sources */,
+ 254046DD166ABBED00E13304 /* ZXFormatInformation.m in Sources */,
+ 254046DE166ABBED00E13304 /* ZXMode.m in Sources */,
+ 254046DF166ABBED00E13304 /* ZXQRCodeBitMatrixParser.m in Sources */,
+ 254046E0166ABBED00E13304 /* ZXQRCodeDataBlock.m in Sources */,
+ 254046E1166ABBED00E13304 /* ZXQRCodeDecodedBitStreamParser.m in Sources */,
+ 254046E2166ABBED00E13304 /* ZXQRCodeDecoder.m in Sources */,
+ 254046E3166ABBED00E13304 /* ZXQRCodeVersion.m in Sources */,
+ 254046E4166ABBED00E13304 /* ZXAlignmentPattern.m in Sources */,
+ 254046E5166ABBED00E13304 /* ZXAlignmentPatternFinder.m in Sources */,
+ 254046E6166ABBED00E13304 /* ZXFinderPatternFinder.m in Sources */,
+ 254046E7166ABBED00E13304 /* ZXFinderPatternInfo.m in Sources */,
+ 254046E8166ABBED00E13304 /* ZXQRCodeDetector.m in Sources */,
+ 254046E9166ABBED00E13304 /* ZXQRCodeFinderPattern.m in Sources */,
+ 254046EA166ABBED00E13304 /* ZXBlockPair.m in Sources */,
+ 254046EB166ABBED00E13304 /* ZXByteMatrix.m in Sources */,
+ 254046EC166ABBED00E13304 /* ZXEncoder.m in Sources */,
+ 254046ED166ABBED00E13304 /* ZXMaskUtil.m in Sources */,
+ 254046EE166ABBED00E13304 /* ZXMatrixUtil.m in Sources */,
+ 254046EF166ABBED00E13304 /* ZXQRCode.m in Sources */,
+ 254046F0166ABBED00E13304 /* ZXQRCodeReader.m in Sources */,
+ 254046F1166ABBED00E13304 /* ZXQRCodeWriter.m in Sources */,
+ 254046F2166ABBED00E13304 /* ZXBinarizer.m in Sources */,
+ 254046F3166ABBED00E13304 /* ZXBinaryBitmap.m in Sources */,
+ 254046F4166ABBED00E13304 /* ZXDecodeHints.m in Sources */,
+ 254046F5166ABBED00E13304 /* ZXEncodeHints.m in Sources */,
+ 254046F6166ABBED00E13304 /* ZXErrors.m in Sources */,
+ 254046F7166ABBED00E13304 /* ZXLuminanceSource.m in Sources */,
+ 25389B861800E35B00772392 /* ZXPDF417ScanningDecoder.m in Sources */,
+ 254046F8166ABBED00E13304 /* ZXMultiFormatReader.m in Sources */,
+ 254046F9166ABBED00E13304 /* ZXMultiFormatWriter.m in Sources */,
+ 254046FA166ABBED00E13304 /* ZXResult.m in Sources */,
+ 254046FB166ABBED00E13304 /* ZXResultPoint.m in Sources */,
+ 251FCDF016CC8F7C000C27E5 /* ZXRGBLuminanceSource.m in Sources */,
+ 25FE5D3716D0B00700826CDB /* ZXExpandedRow.m in Sources */,
+ 2542997216D3336100D4C045 /* ZXPlanarYUVLuminanceSource.m in Sources */,
+ 2542997916D46FF100D4C045 /* ZXDimension.m in Sources */,
+ 2542998116D470F300D4C045 /* ZXDataMatrixWriter.m in Sources */,
+ 2542998B16D478A000D4C045 /* ZXASCIIEncoder.m in Sources */,
+ 2542999416D47BC000D4C045 /* ZXBase256Encoder.m in Sources */,
+ 254299A616D4879800D4C045 /* ZXDataMatrixSymbolInfo144.m in Sources */,
+ 2519AB6317FE5E4F00A71C45 /* ZXPDF417BarcodeMetadata.m in Sources */,
+ 254299AE16D4886100D4C045 /* ZXDefaultPlacement.m in Sources */,
+ 254299B616D4A36700D4C045 /* ZXEdifactEncoder.m in Sources */,
+ 254299BE16D4A5AA00D4C045 /* ZXEncoderContext.m in Sources */,
+ 254299C616D5B8E500D4C045 /* ZXDataMatrixErrorCorrection.m in Sources */,
+ 254299CE16D5BD5400D4C045 /* ZXHighLevelEncoder.m in Sources */,
+ 254299D616D5C96100D4C045 /* ZXSymbolInfo.m in Sources */,
+ 254299E216D5D24E00D4C045 /* ZXSymbolShapeHint.m in Sources */,
+ 254299EA16D5D81A00D4C045 /* ZXTextEncoder.m in Sources */,
+ 254299F216D5D94B00D4C045 /* ZXX12Encoder.m in Sources */,
+ 2504D4CB16F698C900DF8882 /* ZXInvertedLuminanceSource.m in Sources */,
+ 2504D9D416FFD3B300DF8882 /* ZXAztecCode.m in Sources */,
+ 25389B6E17FFC98100772392 /* ZXPDF417DetectionResultColumn.m in Sources */,
+ 2504D9DF16FFEB7A00DF8882 /* ZXAztecEncoder.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 024957F01898641B003D4E6A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 25403CB2166A96FA00E13304 /* ZXingObjC-iOS */;
+ targetProxy = 024957F11898641B003D4E6A /* PBXContainerItemProxy */;
+ };
+ 02D81370189864C70081721D /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 25404165166AADAC00E13304 /* ZXingObjC-osx */;
+ targetProxy = 02D81371189864C70081721D /* PBXContainerItemProxy */;
+ };
+ 25403CCB166A96FA00E13304 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 25403CB2166A96FA00E13304 /* ZXingObjC-iOS */;
+ targetProxy = 25403CCA166A96FA00E13304 /* PBXContainerItemProxy */;
+ };
+ 2540417C166AADAC00E13304 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 25404165166AADAC00E13304 /* ZXingObjC-osx */;
+ targetProxy = 2540417B166AADAC00E13304 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 024958751898641B003D4E6A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMPRESS_PNG_FILES = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "\"$(SDKROOT)/Developer/Library/Frameworks\"",
+ "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "ZXingObjCTests/Supporting Files/Tests-iOS-Prefix.pch";
+ INFOPLIST_FILE = "ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ PRODUCT_NAME = "ZXingObjCTests-iOS copy";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Debug;
+ };
+ 024958761898641B003D4E6A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMPRESS_PNG_FILES = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "\"$(SDKROOT)/Developer/Library/Frameworks\"",
+ "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "ZXingObjCTests/Supporting Files/Tests-iOS-Prefix.pch";
+ INFOPLIST_FILE = "ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ PRODUCT_NAME = "ZXingObjCTests-iOS copy";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Release;
+ };
+ 024958771898641B003D4E6A /* Distribution */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMPRESS_PNG_FILES = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "\"$(SDKROOT)/Developer/Library/Frameworks\"",
+ "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "ZXingObjCTests/Supporting Files/Tests-iOS-Prefix.pch";
+ INFOPLIST_FILE = "ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ PRODUCT_NAME = "ZXingObjCTests-iOS copy";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Distribution;
+ };
+ 02AF346E1672527F003B9255 /* Distribution */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ FRAMEWORK_VERSION = 2.2.3;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Distribution;
+ };
+ 02AF346F1672527F003B9255 /* Distribution */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COPY_PHASE_STRIP = NO;
+ DEAD_CODE_STRIPPING = NO;
+ DSTROOT = /tmp/ZXingObjC.dst;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "ios-Prefix.pch";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ ONLY_ACTIVE_ARCH = NO;
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = "ZXingObjC-iOS";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)Headers";
+ SKIP_INSTALL = YES;
+ STRIP_STYLE = "non-global";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Distribution;
+ };
+ 02AF34701672527F003B9255 /* Distribution */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMPRESS_PNG_FILES = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "\"$(SDKROOT)/Developer/Library/Frameworks\"",
+ "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "ZXingObjCTests/Supporting Files/Tests-iOS-Prefix.pch";
+ INFOPLIST_FILE = "ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Distribution;
+ };
+ 02AF34721672527F003B9255 /* Distribution */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
+ );
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "osx-Prefix.pch";
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ };
+ name = Distribution;
+ };
+ 02AF34731672527F003B9255 /* Distribution */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"";
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ 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.7;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Distribution;
+ };
+ 02AF34741672527F003B9255 /* Distribution */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
+ );
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "osx-Prefix.pch";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ PRODUCT_NAME = ZXingObjC;
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = framework;
+ };
+ name = Distribution;
+ };
+ 02D813F3189864C70081721D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ FRAMEWORK_SEARCH_PATHS = "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"";
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ 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.7;
+ PRODUCT_NAME = "ZXingObjCTests-osx copy";
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Debug;
+ };
+ 02D813F4189864C70081721D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"";
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ 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.7;
+ PRODUCT_NAME = "ZXingObjCTests-osx copy";
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Release;
+ };
+ 02D813F5189864C70081721D /* Distribution */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"";
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ 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.7;
+ PRODUCT_NAME = "ZXingObjCTests-osx copy";
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Distribution;
+ };
+ 25403CD6166A96FA00E13304 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_VERSION = 2.2.3;
+ 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_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 25403CD7166A96FA00E13304 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ FRAMEWORK_VERSION = 2.2.3;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 25403CD9166A96FA00E13304 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COPY_PHASE_STRIP = NO;
+ DEAD_CODE_STRIPPING = NO;
+ DSTROOT = /tmp/ZXingObjC.dst;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "ios-Prefix.pch";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ ONLY_ACTIVE_ARCH = NO;
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = "ZXingObjC-iOS";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)Headers";
+ SKIP_INSTALL = YES;
+ STRIP_STYLE = "non-global";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 25403CDA166A96FA00E13304 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COPY_PHASE_STRIP = NO;
+ DEAD_CODE_STRIPPING = NO;
+ DSTROOT = /tmp/ZXingObjC.dst;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "ios-Prefix.pch";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ ONLY_ACTIVE_ARCH = NO;
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = "ZXingObjC-iOS";
+ PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)Headers";
+ SKIP_INSTALL = YES;
+ STRIP_STYLE = "non-global";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ 25403CDC166A96FA00E13304 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMPRESS_PNG_FILES = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "\"$(SDKROOT)/Developer/Library/Frameworks\"",
+ "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "ZXingObjCTests/Supporting Files/Tests-iOS-Prefix.pch";
+ INFOPLIST_FILE = "ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Debug;
+ };
+ 25403CDD166A96FA00E13304 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMPRESS_PNG_FILES = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "\"$(SDKROOT)/Developer/Library/Frameworks\"",
+ "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
+ );
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "ZXingObjCTests/Supporting Files/Tests-iOS-Prefix.pch";
+ INFOPLIST_FILE = "ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Release;
+ };
+ 25404188166AADAD00E13304 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
+ );
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "osx-Prefix.pch";
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 25404189166AADAD00E13304 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
+ );
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "osx-Prefix.pch";
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ 2540418B166AADAD00E13304 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ FRAMEWORK_SEARCH_PATHS = "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"";
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ 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.7;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Debug;
+ };
+ 2540418C166AADAD00E13304 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"";
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ 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.7;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Release;
+ };
+ 254043B1166ABA0A00E13304 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
+ );
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "osx-Prefix.pch";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ PRODUCT_NAME = ZXingObjC;
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = framework;
+ };
+ name = Debug;
+ };
+ 254043B2166ABA0A00E13304 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"",
+ );
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "osx-Prefix.pch";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ PRODUCT_NAME = ZXingObjC;
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = framework;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 024958741898641B003D4E6A /* Build configuration list for PBXNativeTarget "Blackbox Tests iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 024958751898641B003D4E6A /* Debug */,
+ 024958761898641B003D4E6A /* Release */,
+ 024958771898641B003D4E6A /* Distribution */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 02D813F2189864C70081721D /* Build configuration list for PBXNativeTarget "Blackbox Tests OS X" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 02D813F3189864C70081721D /* Debug */,
+ 02D813F4189864C70081721D /* Release */,
+ 02D813F5189864C70081721D /* Distribution */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 25403CAD166A96F900E13304 /* Build configuration list for PBXProject "ZXingObjC" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 25403CD6166A96FA00E13304 /* Debug */,
+ 25403CD7166A96FA00E13304 /* Release */,
+ 02AF346E1672527F003B9255 /* Distribution */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 25403CD8166A96FA00E13304 /* Build configuration list for PBXNativeTarget "ZXingObjC-iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 25403CD9166A96FA00E13304 /* Debug */,
+ 25403CDA166A96FA00E13304 /* Release */,
+ 02AF346F1672527F003B9255 /* Distribution */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 25403CDB166A96FA00E13304 /* Build configuration list for PBXNativeTarget "Unit Tests iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 25403CDC166A96FA00E13304 /* Debug */,
+ 25403CDD166A96FA00E13304 /* Release */,
+ 02AF34701672527F003B9255 /* Distribution */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 25404187166AADAD00E13304 /* Build configuration list for PBXNativeTarget "ZXingObjC-osx" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 25404188166AADAD00E13304 /* Debug */,
+ 25404189166AADAD00E13304 /* Release */,
+ 02AF34721672527F003B9255 /* Distribution */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 2540418A166AADAD00E13304 /* Build configuration list for PBXNativeTarget "Unit Tests OS X" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 2540418B166AADAD00E13304 /* Debug */,
+ 2540418C166AADAD00E13304 /* Release */,
+ 02AF34731672527F003B9255 /* Distribution */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 254043B0166ABA0A00E13304 /* Build configuration list for PBXNativeTarget "OS X Framework" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 254043B1166ABA0A00E13304 /* Debug */,
+ 254043B2166ABA0A00E13304 /* Release */,
+ 02AF34741672527F003B9255 /* Distribution */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 25403CAA166A96F900E13304 /* Project object */;
+}
diff --git a/ZXingObjC.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ZXingObjC.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..9e3b1a8
--- /dev/null
+++ b/ZXingObjC.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:ZXingObjC.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/ZXingObjC.xcodeproj/xcshareddata/xcschemes/ZXingObjC-iOS.xcscheme b/ZXingObjC.xcodeproj/xcshareddata/xcschemes/ZXingObjC-iOS.xcscheme
new file mode 100644
index 0000000..68dc9b8
--- /dev/null
+++ b/ZXingObjC.xcodeproj/xcshareddata/xcschemes/ZXingObjC-iOS.xcscheme
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0510"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "25403CB2166A96FA00E13304"
+ BuildableName = "libZXingObjC-iOS.a"
+ BlueprintName = "ZXingObjC-iOS"
+ ReferencedContainer = "container:ZXingObjC.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ buildConfiguration = "Debug">
+ <Testables>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "25403CC3166A96FA00E13304"
+ BuildableName = "Unit Tests iOS.octest"
+ BlueprintName = "Unit Tests iOS"
+ ReferencedContainer = "container:ZXingObjC.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ <TestableReference
+ skipped = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "024957EF1898641B003D4E6A"
+ BuildableName = "ZXingObjCTests-iOS copy.octest"
+ BlueprintName = "Blackbox Tests iOS"
+ ReferencedContainer = "container:ZXingObjC.xcodeproj">
+ </BuildableReference>
+ </TestableReference>
+ </Testables>
+ </TestAction>
+ <LaunchAction
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ buildConfiguration = "Debug"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ allowLocationSimulation = "YES">
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "25403CB2166A96FA00E13304"
+ BuildableName = "libZXingObjC-iOS.a"
+ BlueprintName = "ZXingObjC-iOS"
+ ReferencedContainer = "container:ZXingObjC.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ buildConfiguration = "Release"
+ debugDocumentVersioning = "YES">
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/ZXingObjC/ZXBarcodeFormat.h b/ZXingObjC/ZXBarcodeFormat.h
new file mode 100644
index 0000000..4f74599
--- /dev/null
+++ b/ZXingObjC/ZXBarcodeFormat.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/**
+ * Enumerates barcode formats known to this package. Please keep alphabetized.
+ */
+typedef enum {
+ /** Aztec 2D barcode format. */
+ kBarcodeFormatAztec,
+
+ /** CODABAR 1D format. */
+ kBarcodeFormatCodabar,
+
+ /** Code 39 1D format. */
+ kBarcodeFormatCode39,
+
+ /** Code 93 1D format. */
+ kBarcodeFormatCode93,
+
+ /** Code 128 1D format. */
+ kBarcodeFormatCode128,
+
+ /** Data Matrix 2D barcode format. */
+ kBarcodeFormatDataMatrix,
+
+ /** EAN-8 1D format. */
+ kBarcodeFormatEan8,
+
+ /** EAN-13 1D format. */
+ kBarcodeFormatEan13,
+
+ /** ITF (Interleaved Two of Five) 1D format. */
+ kBarcodeFormatITF,
+
+ /** MaxiCode 2D barcode format. */
+ kBarcodeFormatMaxiCode,
+
+ /** PDF417 format. */
+ kBarcodeFormatPDF417,
+
+ /** QR Code 2D barcode format. */
+ kBarcodeFormatQRCode,
+
+ /** RSS 14 */
+ kBarcodeFormatRSS14,
+
+ /** RSS EXPANDED */
+ kBarcodeFormatRSSExpanded,
+
+ /** UPC-A 1D format. */
+ kBarcodeFormatUPCA,
+
+ /** UPC-E 1D format. */
+ kBarcodeFormatUPCE,
+
+ /** UPC/EAN extension format. Not a stand-alone format. */
+ kBarcodeFormatUPCEANExtension
+} ZXBarcodeFormat;
diff --git a/ZXingObjC/ZXBinarizer.h b/ZXingObjC/ZXBinarizer.h
new file mode 100644
index 0000000..6862e2f
--- /dev/null
+++ b/ZXingObjC/ZXBinarizer.h
@@ -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.
+ */
+
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+#include <ImageIO/ImageIO.h>
+#else
+#import <QuartzCore/QuartzCore.h>
+#endif
+
+#import "ZXBitArray.h"
+#import "ZXBitMatrix.h"
+#import "ZXLuminanceSource.h"
+
+/**
+ * This class hierarchy provides a set of methods to convert luminance data to 1 bit data.
+ * It allows the algorithm to vary polymorphically, for example allowing a very expensive
+ * thresholding technique for servers and a fast one for mobile. It also permits the implementation
+ * to vary, e.g. a JNI version for Android and a Java fallback version for other platforms.
+ */
+
+@interface ZXBinarizer : NSObject
+
+@property (nonatomic, strong, readonly) ZXLuminanceSource *luminanceSource;
+@property (nonatomic, assign, readonly) int width;
+@property (nonatomic, assign, readonly) int height;
+
+- (id)initWithSource:(ZXLuminanceSource *)source;
++ (id)binarizerWithSource:(ZXLuminanceSource *)source;
+- (ZXBitMatrix *)blackMatrixWithError:(NSError **)error;
+- (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error;
+- (ZXBinarizer *)createBinarizer:(ZXLuminanceSource *)source;
+- (CGImageRef)createImage CF_RETURNS_RETAINED;
+
+@end
diff --git a/ZXingObjC/ZXBinarizer.m b/ZXingObjC/ZXBinarizer.m
new file mode 100644
index 0000000..4dbe746
--- /dev/null
+++ b/ZXingObjC/ZXBinarizer.m
@@ -0,0 +1,143 @@
+/*
+ * 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 "ZXBinarizer.h"
+
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+#import <UIKit/UIKit.h>
+#define ZXBlack [[UIColor blackColor] CGColor]
+#define ZXWhite [[UIColor whiteColor] CGColor]
+#else
+#define ZXBlack CGColorGetConstantColor(kCGColorBlack)
+#define ZXWhite CGColorGetConstantColor(kCGColorWhite)
+#endif
+
+@implementation ZXBinarizer
+
+- (id)initWithSource:(ZXLuminanceSource *)source {
+ if (self = [super init]) {
+ _luminanceSource = source;
+ }
+
+ return self;
+}
+
+- (id)initWithLuminanceSource:(ZXLuminanceSource *)source {
+ return [self initWithSource:source];
+}
+
++ (id)binarizerWithSource:(ZXLuminanceSource *)source {
+ return [[self alloc] initWithLuminanceSource:source];
+}
+
+/**
+ * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
+ * 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.
+ * For callers which only examine one row of pixels at a time, the same BitArray should be reused
+ * and passed in with each call for performance. However it is legal to keep more than one row
+ * at a time if needed.
+ */
+- (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+
+/**
+ * Converts a 2D array of luminance data to 1 bit data. As above, assume this method is expensive
+ * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
+ * may not apply sharpening. Therefore, a row from this matrix may not be identical to one
+ * fetched using blackRow(), so don't mix and match between them.
+ */
+- (ZXBitMatrix *)blackMatrixWithError:(NSError **)error {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+
+/**
+ * Creates a new object with the same type as this Binarizer implementation, but with pristine
+ * state. This is needed because Binarizer implementations may be stateful, e.g. keeping a cache
+ * of 1 bit data. See Effective Java for why we can't use Java's clone() method.
+ */
+- (ZXBinarizer *)createBinarizer:(ZXLuminanceSource *)source {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+- (CGImageRef)createImage CF_RETURNS_RETAINED {
+ ZXBitMatrix *matrix = [self blackMatrixWithError:nil];
+ if (!matrix) {
+ return nil;
+ }
+ ZXLuminanceSource *source = [self luminanceSource];
+
+ int width = source.width;
+ int height = source.height;
+
+ int bytesPerRow = ((width&0xf)>>4)<<4;
+
+ CGColorSpaceRef gray = CGColorSpaceCreateDeviceGray();
+ CGContextRef context = CGBitmapContextCreate (
+ 0,
+ width,
+ height,
+ 8, // bits per component
+ bytesPerRow,
+ gray,
+ kCGBitmapAlphaInfoMask & kCGImageAlphaNone);
+ CGColorSpaceRelease(gray);
+
+ CGRect r = CGRectZero;
+ r.size.width = width;
+ r.size.height = height;
+ CGContextSetFillColorWithColor(context, ZXBlack);
+ CGContextFillRect(context, r);
+
+ r.size.width = 1;
+ r.size.height = 1;
+
+ CGContextSetFillColorWithColor(context, ZXWhite);
+ for(int y=0; y<height; y++) {
+ r.origin.y = height-1-y;
+ for(int x=0; x<width; x++) {
+ if (![matrix getX:x y:y]) {
+ r.origin.x = x;
+ CGContextFillRect(context, r);
+ }
+ }
+ }
+
+ CGImageRef binary = CGBitmapContextCreateImage(context);
+
+ CGContextRelease(context);
+
+ return binary;
+}
+
+- (int)width {
+ return self.luminanceSource.width;
+}
+
+- (int)height {
+ return self.luminanceSource.height;
+}
+
+@end
diff --git a/ZXingObjC/ZXBinaryBitmap.h b/ZXingObjC/ZXBinaryBitmap.h
new file mode 100644
index 0000000..43ef35f
--- /dev/null
+++ b/ZXingObjC/ZXBinaryBitmap.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/**
+ * This class is the core bitmap class used by ZXing to represent 1 bit data. Reader objects
+ * accept a BinaryBitmap and attempt to decode it.
+ */
+
+@class ZXBinarizer, ZXBitArray, ZXBitMatrix;
+
+@interface ZXBinaryBitmap : NSObject
+
+@property (nonatomic, readonly) int width;
+@property (nonatomic, readonly) int height;
+@property (nonatomic, readonly) BOOL cropSupported;
+@property (nonatomic, readonly) BOOL rotateSupported;
+
+- (id)initWithBinarizer:(ZXBinarizer *)binarizer;
++ (id)binaryBitmapWithBinarizer:(ZXBinarizer *)binarizer;
+- (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error;
+- (ZXBitMatrix *)blackMatrixWithError:(NSError **)error;
+- (ZXBinaryBitmap *)crop:(int)left top:(int)top width:(int)width height:(int)height;
+- (ZXBinaryBitmap *)rotateCounterClockwise;
+- (ZXBinaryBitmap *)rotateCounterClockwise45;
+
+@end
diff --git a/ZXingObjC/ZXBinaryBitmap.m b/ZXingObjC/ZXBinaryBitmap.m
new file mode 100644
index 0000000..0bb4cee
--- /dev/null
+++ b/ZXingObjC/ZXBinaryBitmap.m
@@ -0,0 +1,108 @@
+/*
+ * 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 "ZXBinarizer.h"
+#import "ZXBinaryBitmap.h"
+#import "ZXBitArray.h"
+#import "ZXBitMatrix.h"
+
+@interface ZXBinaryBitmap ()
+
+@property (nonatomic, strong) ZXBinarizer *binarizer;
+@property (nonatomic, strong) ZXBitMatrix *matrix;
+
+@end
+
+@implementation ZXBinaryBitmap
+
+- (id)initWithBinarizer:(ZXBinarizer *)binarizer {
+ if (self = [super init]) {
+ if (binarizer == nil) {
+ [NSException raise:NSInvalidArgumentException format:@"Binarizer must be non-null."];
+ }
+
+ self.binarizer = binarizer;
+ }
+
+ return self;
+}
+
++ (id)binaryBitmapWithBinarizer:(ZXBinarizer *)binarizer {
+ return [[self alloc] initWithBinarizer:binarizer];
+}
+
+- (int)width {
+ return self.binarizer.width;
+}
+
+- (int)height {
+ return self.binarizer.height;
+}
+
+/**
+ * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
+ * 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.
+ */
+- (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error {
+ return [self.binarizer blackRow:y row:row error:error];
+}
+
+/**
+ * Converts a 2D array of luminance data to 1 bit. As above, assume this method is expensive
+ * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
+ * may not apply sharpening. Therefore, a row from this matrix may not be identical to one
+ * fetched using blackRow(), so don't mix and match between them.
+ */
+- (ZXBitMatrix *)blackMatrixWithError:(NSError **)error {
+ if (self.matrix == nil) {
+ self.matrix = [self.binarizer blackMatrixWithError:error];
+ }
+ return self.matrix;
+}
+
+- (BOOL)cropSupported {
+ return [[self.binarizer luminanceSource] cropSupported];
+}
+
+/**
+ * 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.
+ */
+- (ZXBinaryBitmap *)crop:(int)left top:(int)top width:(int)aWidth height:(int)aHeight {
+ ZXLuminanceSource *newSource = [[self.binarizer luminanceSource] crop:left top:top width:aWidth height:aHeight];
+ return [[ZXBinaryBitmap alloc] initWithBinarizer:[self.binarizer createBinarizer:newSource]];
+}
+
+- (BOOL)rotateSupported {
+ return [[self.binarizer luminanceSource] rotateSupported];
+}
+
+/**
+ * Returns a new object with rotated image data by 90 degrees counterclockwise.
+ * Only callable if isRotateSupported() is true.
+ */
+- (ZXBinaryBitmap *)rotateCounterClockwise {
+ ZXLuminanceSource *newSource = [[self.binarizer luminanceSource] rotateCounterClockwise];
+ return [[ZXBinaryBitmap alloc] initWithBinarizer:[self.binarizer createBinarizer:newSource]];
+}
+
+- (ZXBinaryBitmap *)rotateCounterClockwise45 {
+ ZXLuminanceSource *newSource = [[self.binarizer luminanceSource] rotateCounterClockwise45];
+ return [[ZXBinaryBitmap alloc] initWithBinarizer:[self.binarizer createBinarizer:newSource]];
+}
+
+@end
diff --git a/ZXingObjC/ZXDecodeHints.h b/ZXingObjC/ZXDecodeHints.h
new file mode 100644
index 0000000..4a07418
--- /dev/null
+++ b/ZXingObjC/ZXDecodeHints.h
@@ -0,0 +1,80 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+
+@protocol ZXResultPointCallback;
+
+/**
+ * Encapsulates hints that a caller may pass to a barcode reader to help it
+ * more quickly or accurately decode it. It is up to implementations to decide what,
+ * if anything, to do with the information that is supplied.
+ */
+@interface ZXDecodeHints : NSObject <NSCopying>
+
++ (id)hints;
+
+/**
+ * Assume Code 39 codes employ a check digit. Maps to {@link Boolean}.
+ */
+@property (nonatomic, assign) BOOL assumeCode39CheckDigit;
+
+/**
+ * Assume the barcode is being processed as a GS1 barcode, and modify behavior as needed.
+ * For example this affects FNC1 handling for Code 128 (aka GS1-128).
+ */
+@property (nonatomic, assign) BOOL assumeGS1;
+
+/**
+ * Allowed lengths of encoded data -- reject anything else. Maps to an int[].
+ */
+@property (nonatomic, strong) NSArray *allowedLengths;
+
+/**
+ * Specifies what character encoding to use when decoding, where applicable (type String)
+ */
+@property (nonatomic, assign) NSStringEncoding encoding;
+
+/**
+ * Unspecified, application-specific hint.
+ */
+@property (nonatomic, strong) id other;
+
+/**
+ * Image is a pure monochrome image of a barcode.
+ */
+@property (nonatomic, assign) BOOL pureBarcode;
+
+/**
+ * The caller needs to be notified via callback when a possible {@link ResultPoint}
+ * is found. Maps to a {@link ResultPointCallback}.
+ */
+@property (nonatomic, strong) id <ZXResultPointCallback> resultPointCallback;
+
+/**
+ * Spend more time to try to find a barcode; optimize for accuracy, not speed.
+ */
+@property (nonatomic, assign) BOOL tryHarder;
+
+/**
+ * Image is known to be of one of a few possible formats.
+ */
+- (void)addPossibleFormat:(ZXBarcodeFormat)format;
+- (BOOL)containsFormat:(ZXBarcodeFormat)format;
+- (int)numberOfPossibleFormats;
+- (void)removePossibleFormat:(ZXBarcodeFormat)format;
+
+@end
\ No newline at end of file
diff --git a/ZXingObjC/ZXDecodeHints.m b/ZXingObjC/ZXDecodeHints.m
new file mode 100644
index 0000000..19e065c
--- /dev/null
+++ b/ZXingObjC/ZXDecodeHints.m
@@ -0,0 +1,76 @@
+/*
+ * 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 "ZXDecodeHints.h"
+#import "ZXResultPointCallback.h"
+
+@interface ZXDecodeHints ()
+
+@property (nonatomic, strong) NSMutableArray *barcodeFormats;
+
+@end
+
+@implementation ZXDecodeHints
+
+- (id)init {
+ if (self = [super init]) {
+ _barcodeFormats = [NSMutableArray array];
+ }
+
+ return self;
+}
+
++ (id)hints {
+ return [[self alloc] init];
+}
+
+- (id)copyWithZone:(NSZone *)zone {
+ ZXDecodeHints *result = [[[self class] allocWithZone:zone] init];
+ if (result) {
+ result.assumeCode39CheckDigit = self.assumeCode39CheckDigit;
+ result.allowedLengths = [self.allowedLengths copy];
+
+ for (NSNumber *formatNumber in self.barcodeFormats) {
+ [result addPossibleFormat:[formatNumber intValue]];
+ }
+
+ result.encoding = self.encoding;
+ result.other = self.other;
+ result.pureBarcode = self.pureBarcode;
+ result.resultPointCallback = self.resultPointCallback;
+ result.tryHarder = self.tryHarder;
+ }
+
+ return result;
+}
+
+- (void)addPossibleFormat:(ZXBarcodeFormat)format {
+ [self.barcodeFormats addObject:[NSNumber numberWithInt:format]];
+}
+
+- (BOOL)containsFormat:(ZXBarcodeFormat)format {
+ return [self.barcodeFormats containsObject:[NSNumber numberWithInt:format]];
+}
+
+- (int)numberOfPossibleFormats {
+ return (int)self.barcodeFormats.count;
+}
+
+- (void)removePossibleFormat:(ZXBarcodeFormat)format {
+ [self.barcodeFormats removeObject:[NSNumber numberWithInt:format]];
+}
+
+@end
\ No newline at end of file
diff --git a/ZXingObjC/ZXDimension.h b/ZXingObjC/ZXDimension.h
new file mode 100644
index 0000000..21eaf1a
--- /dev/null
+++ b/ZXingObjC/ZXDimension.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * Simply encapsulates a width and height.
+ */
+
+@interface ZXDimension : NSObject
+
+@property (nonatomic, assign, readonly) int height;
+@property (nonatomic, assign, readonly) int width;
+
+- (id)initWithWidth:(int)width height:(int)height;
+
+@end
diff --git a/ZXingObjC/ZXDimension.m b/ZXingObjC/ZXDimension.m
new file mode 100644
index 0000000..3eed89a
--- /dev/null
+++ b/ZXingObjC/ZXDimension.m
@@ -0,0 +1,50 @@
+/*
+ * 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 "ZXDimension.h"
+
+@implementation ZXDimension
+
+- (id)initWithWidth:(int)width height:(int)height {
+ if (width < 0 || height < 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Width and height must not be negative"];
+ }
+
+ if (self = [super init]) {
+ _width = width;
+ _height = height;
+ }
+
+ return self;
+}
+
+- (BOOL)isEqual:(id)other {
+ if ([other isKindOfClass:[ZXDimension class]]) {
+ ZXDimension *d = (ZXDimension *)other;
+ return self.width == d.width && self.height == d.height;
+ }
+ return NO;
+}
+
+- (NSUInteger)hash {
+ return self.width * 32713 + self.height;
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%dx%d", self.width, self.height];
+}
+
+@end
diff --git a/ZXingObjC/ZXEncodeHints.h b/ZXingObjC/ZXEncodeHints.h
new file mode 100644
index 0000000..01534a0
--- /dev/null
+++ b/ZXingObjC/ZXEncodeHints.h
@@ -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 "ZXCompaction.h"
+#import "ZXDimensions.h"
+#import "ZXErrorCorrectionLevel.h"
+#import "ZXSymbolShapeHint.h"
+
+/**
+ * These are a set of hints that you may pass to Writers to specify their behavior.
+ */
+
+@class ZXDimension, ZXSymbolShapeHint;
+
+@interface ZXEncodeHints : NSObject
+
++ (id)hints;
+
+/**
+ * Specifies what character encoding to use where applicable.
+ */
+@property (nonatomic, assign) NSStringEncoding encoding;
+
+/**
+ * Specifies the matrix shape for Data Matrix .
+ */
+@property (nonatomic, strong) ZXSymbolShapeHint *dataMatrixShape;
+
+/**
+ * Specifies a minimum barcode size. Only applicable to Data Matrix now.
+ */
+@property (nonatomic, strong) ZXDimension *minSize;
+
+/**
+ * Specifies a maximum barcode size. Only applicable to Data Matrix now.
+ */
+@property (nonatomic, strong) ZXDimension *maxSize;
+
+/**
+ * Specifies what degree of error correction to use, for example in QR Codes.
+ * For Aztec it represents the minimal percentage of error correction words.
+ * Note: an Aztec symbol should have a minimum of 25% EC words.
+ */
+@property (nonatomic, strong) ZXErrorCorrectionLevel *errorCorrectionLevel;
+
+/**
+ * Specifies what percent of error correction to use.
+ * For Aztec it represents the minimal percentage of error correction words.
+ * Note: an Aztec symbol should have a minimum of 25% EC words.
+ */
+@property (nonatomic, strong) NSNumber *errorCorrectionPercent;
+
+/**
+ * Specifies margin, in pixels, to use when generating the barcode. The meaning can vary
+ * by format; for example it controls margin before and after the barcode horizontally for
+ * most 1D formats.
+ */
+@property (nonatomic, strong) NSNumber *margin;
+
+/**
+ * Specifies whether to use compact mode for PDF417.
+ */
+@property (nonatomic, assign) BOOL pdf417Compact;
+
+/**
+ * Specifies what compaction mode to use for PDF417.
+ */
+@property (nonatomic, assign) ZXCompaction pdf417Compaction;
+
+/**
+ * Specifies the minimum and maximum number of rows and columns for PDF417.
+ */
+@property (nonatomic, strong) ZXDimensions *pdf417Dimensions;
+
+@end
diff --git a/ZXingObjC/ZXEncodeHints.m b/ZXingObjC/ZXEncodeHints.m
new file mode 100644
index 0000000..539a3ce
--- /dev/null
+++ b/ZXingObjC/ZXEncodeHints.m
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXEncodeHints.h"
+
+@implementation ZXEncodeHints
+
++ (id)hints {
+ return [[self alloc] init];
+}
+
+@end
diff --git a/ZXingObjC/ZXErrors.h b/ZXingObjC/ZXErrors.h
new file mode 100644
index 0000000..2f090c2
--- /dev/null
+++ b/ZXingObjC/ZXErrors.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#define ZXErrorDomain @"ZXErrorDomain"
+
+enum {
+ /**
+ * Thrown when a barcode was successfully detected and decoded, but
+ * was not returned because its checksum feature failed.
+ */
+ ZXChecksumError = 1000,
+
+ /**
+ * Thrown when a barcode was successfully detected, but some aspect of
+ * the content did not conform to the barcode's format rules. This could have
+ * been due to a mis-detection.
+ */
+ ZXFormatError = 1001,
+
+ /**
+ * Thrown when a barcode was not found in the image. It might have been
+ * partially detected but could not be confirmed.
+ */
+ ZXNotFoundError = 1002,
+
+ /**
+ * Thrown when an exception occurs during Reed-Solomon decoding, such as when
+ * there are too many errors to correct.
+ */
+ ZXReedSolomonError = 1003,
+
+ /**
+ * This general error is thrown when something goes wrong during decoding of a barcode.
+ * This includes, but is not limited to, failing checksums / error correction algorithms, being
+ * unable to locate finder timing patterns, and so on.
+ */
+ ZXReaderError = 1004,
+
+ /**
+ * Covers the range of error which may occur when encoding a barcode using the Writer framework.
+ */
+ ZXWriterError = 1005
+};
+
+// Helper methods for error instances
+NSError *ChecksumErrorInstance(void);
+NSError *FormatErrorInstance(void);
+NSError *NotFoundErrorInstance(void);
diff --git a/ZXingObjC/ZXErrors.m b/ZXingObjC/ZXErrors.m
new file mode 100644
index 0000000..a0040f9
--- /dev/null
+++ b/ZXingObjC/ZXErrors.m
@@ -0,0 +1,35 @@
+/*
+ * 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 "ZXErrors.h"
+
+NSError *ChecksumErrorInstance() {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"This barcode failed its checksum"};
+
+ return [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXChecksumError userInfo:userInfo];
+}
+
+NSError *FormatErrorInstance() {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"This barcode does not confirm to the format's rules"};
+
+ return [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXFormatError userInfo:userInfo];
+}
+
+NSError *NotFoundErrorInstance() {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"A barcode was not found in this image"};
+
+ return [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:userInfo];
+}
diff --git a/ZXingObjC/ZXInvertedLuminanceSource.h b/ZXingObjC/ZXInvertedLuminanceSource.h
new file mode 100644
index 0000000..7db6f2d
--- /dev/null
+++ b/ZXingObjC/ZXInvertedLuminanceSource.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXLuminanceSource.h"
+
+/**
+ * A wrapper implementation of ZXLuminanceSource which inverts the luminances it returns -- black becomes
+ * white and vice versa, and each value becomes (255-value).
+ */
+@interface ZXInvertedLuminanceSource : ZXLuminanceSource
+
+- (id)initWithDelegate:(ZXLuminanceSource *)delegate;
+
+@end
diff --git a/ZXingObjC/ZXInvertedLuminanceSource.m b/ZXingObjC/ZXInvertedLuminanceSource.m
new file mode 100644
index 0000000..c3c9b28
--- /dev/null
+++ b/ZXingObjC/ZXInvertedLuminanceSource.m
@@ -0,0 +1,82 @@
+/*
+ * 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 "ZXInvertedLuminanceSource.h"
+
+@interface ZXInvertedLuminanceSource ()
+
+@property (nonatomic, weak) ZXLuminanceSource *delegate;
+
+@end
+
+@implementation ZXInvertedLuminanceSource
+
+- (id)initWithDelegate:(ZXLuminanceSource *)delegate {
+ self = [super initWithWidth:delegate.width height:delegate.height];
+ if (self) {
+ _delegate = delegate;
+ }
+
+ return self;
+}
+
+- (int8_t *)row:(int)y {
+ int8_t *row = [self.delegate row:y];
+ for (int i = 0; i < self.width; i++) {
+ row[i] = (int8_t) (255 - (row[i] & 0xFF));
+ }
+ return row;
+}
+
+- (int8_t *)matrix {
+ int8_t *matrix = [self.delegate matrix];
+ int length = self.width * self.height;
+ int8_t *invertedMatrix = (int8_t *)malloc(length * sizeof(int8_t));
+ for (int i = 0; i < length; i++) {
+ invertedMatrix[i] = (int8_t) (255 - (matrix[i] & 0xFF));
+ }
+ free(matrix);
+ return invertedMatrix;
+}
+
+- (BOOL)cropSupported {
+ return self.delegate.cropSupported;
+}
+
+- (ZXLuminanceSource *)crop:(int)left top:(int)top width:(int)aWidth height:(int)aHeight {
+ return [[ZXInvertedLuminanceSource alloc] initWithDelegate:[self.delegate crop:left top:top width:aWidth height:aHeight]];
+}
+
+- (BOOL)rotateSupported {
+ return self.delegate.rotateSupported;
+}
+
+/**
+ * Returns original delegate ZXLuminanceSource since invert undoes itself
+ */
+- (ZXLuminanceSource *)invert {
+ return self.delegate;
+}
+
+- (ZXLuminanceSource *)rotateCounterClockwise {
+ return [[ZXInvertedLuminanceSource alloc] initWithDelegate:[self.delegate rotateCounterClockwise]];
+}
+
+- (ZXLuminanceSource *)rotateCounterClockwise45 {
+ return [[ZXInvertedLuminanceSource alloc] initWithDelegate:[self.delegate rotateCounterClockwise45]];
+}
+
+@end
diff --git a/ZXingObjC/ZXLuminanceSource.h b/ZXingObjC/ZXLuminanceSource.h
new file mode 100644
index 0000000..54a6913
--- /dev/null
+++ b/ZXingObjC/ZXLuminanceSource.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/**
+ * The purpose of this class hierarchy is to abstract different bitmap implementations across
+ * platforms into a standard interface for requesting greyscale luminance values. The interface
+ * only provides immutable methods; therefore crop and rotation create copies. This is to ensure
+ * that one Reader does not modify the original luminance source and leave it in an unknown state
+ * for other Readers in the chain.
+ */
+
+@interface ZXLuminanceSource : NSObject
+
+@property (nonatomic, assign, readonly) int width;
+@property (nonatomic, assign, readonly) int height;
+@property (nonatomic, assign, readonly) BOOL cropSupported;
+@property (nonatomic, assign, readonly) BOOL rotateSupported;
+
+- (id)initWithWidth:(int)width height:(int)height;
+- (int8_t *)row:(int)y;
+- (int8_t *)matrix;
+- (ZXLuminanceSource *)crop:(int)left top:(int)top width:(int)width height:(int)height;
+- (ZXLuminanceSource *)invert;
+- (ZXLuminanceSource *)rotateCounterClockwise;
+- (ZXLuminanceSource *)rotateCounterClockwise45;
+
+@end
diff --git a/ZXingObjC/ZXLuminanceSource.m b/ZXingObjC/ZXLuminanceSource.m
new file mode 100644
index 0000000..c36954c
--- /dev/null
+++ b/ZXingObjC/ZXLuminanceSource.m
@@ -0,0 +1,122 @@
+/*
+ * 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 "ZXInvertedLuminanceSource.h"
+#import "ZXLuminanceSource.h"
+
+@implementation ZXLuminanceSource
+
+- (id)initWithWidth:(int)width height:(int)height {
+ if (self = [super init]) {
+ _width = width;
+ _height = height;
+ }
+
+ return self;
+}
+
+/**
+ * Fetches one row of luminance data from the underlying platform's bitmap. Values range from
+ * 0 (black) to 255 (white). Because Java does not have an unsigned byte type, callers will have
+ * to bitwise and with 0xff for each value. It is preferable for implementations of this method
+ * to only fetch this row rather than the whole image, since no 2D Readers may be installed and
+ * getMatrix() may never be called.
+ */
+- (int8_t *)row:(int)y {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+/**
+ * Fetches luminance data for the underlying bitmap. Values should be fetched using:
+ * int luminance = array[y * width + x] & 0xff;
+ *
+ * Returns A row-major 2D array of luminance values. Do not use result.length as it may be
+ * larger than width * height bytes on some platforms. Do not modify the contents
+ * of the result.
+ */
+- (int8_t *)matrix {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+/**
+ * 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.
+ */
+- (ZXLuminanceSource *)crop:(int)left top:(int)top width:(int)width height:(int)height {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:@"This luminance source does not support cropping."
+ userInfo:nil];
+}
+
+/**
+ * Returns a wrapper of this ZXLuminanceSource which inverts the luminances it returns -- black becomes
+ * white and vice versa, and each value becomes (255-value).
+ */
+- (ZXLuminanceSource *)invert {
+ return [[ZXInvertedLuminanceSource alloc] initWithDelegate:self];
+}
+
+/**
+ * Returns a new object with rotated image data by 90 degrees counterclockwise.
+ * Only callable if isRotateSupported() is true.
+ */
+- (ZXLuminanceSource *)rotateCounterClockwise {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:@"This luminance source does not support rotation by 90 degrees."
+ userInfo:nil];
+}
+
+/**
+ * Returns a new object with rotated image data by 45 degrees counterclockwise.
+ * Only callable if isRotateSupported() is true.
+ */
+- (ZXLuminanceSource *)rotateCounterClockwise45 {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:@"This luminance source does not support rotation by 45 degrees."
+ userInfo:nil];
+}
+
+- (NSString *)description {
+ int8_t *row = NULL;
+ NSMutableString *result = [NSMutableString stringWithCapacity:self.height * (self.width + 1)];
+ for (int y = 0; y < self.height; y++) {
+ row = [self row:y];
+ for (int x = 0; x < self.width; x++) {
+ int luminance = row[x] & 0xFF;
+ unichar c;
+ if (luminance < 0x40) {
+ c = '#';
+ } else if (luminance < 0x80) {
+ c = '+';
+ } else if (luminance < 0xC0) {
+ c = '.';
+ } else {
+ c = ' ';
+ }
+ [result appendFormat:@"%C", c];
+ }
+ [result appendString:@"\n"];
+ free(row);
+ row = NULL;
+ }
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/ZXMultiFormatReader.h b/ZXingObjC/ZXMultiFormatReader.h
new file mode 100644
index 0000000..adca3ea
--- /dev/null
+++ b/ZXingObjC/ZXMultiFormatReader.h
@@ -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 "ZXReader.h"
+
+/**
+ * ZXMultiFormatReader is a convenience class and the main entry point into the library for most uses.
+ * By default it attempts to decode all barcode formats that the library supports. Optionally, you
+ * can provide a hints object to request different behavior, for example only decoding QR codes.
+ */
+
+@class ZXDecodeHints;
+
+@interface ZXMultiFormatReader : NSObject <ZXReader>
+
+@property (nonatomic, strong) ZXDecodeHints *hints;
+
++ (id)reader;
+- (ZXResult *)decodeWithState:(ZXBinaryBitmap *)image error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/ZXMultiFormatReader.m b/ZXingObjC/ZXMultiFormatReader.m
new file mode 100644
index 0000000..bb9a44a
--- /dev/null
+++ b/ZXingObjC/ZXMultiFormatReader.m
@@ -0,0 +1,160 @@
+/*
+ * 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 "ZXAztecReader.h"
+#import "ZXBinaryBitmap.h"
+#import "ZXDataMatrixReader.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXMaxiCodeReader.h"
+#import "ZXMultiFormatOneDReader.h"
+#import "ZXMultiFormatReader.h"
+#import "ZXPDF417Reader.h"
+#import "ZXQRCodeReader.h"
+#import "ZXResult.h"
+
+@interface ZXMultiFormatReader ()
+
+@property (nonatomic, strong) NSMutableArray *readers;
+
+@end
+
+@implementation ZXMultiFormatReader
+
+- (id)init {
+ if (self = [super init]) {
+ _readers = [NSMutableArray array];
+ }
+
+ return self;
+}
+
++ (id)reader {
+ return [[ZXMultiFormatReader alloc] init];
+}
+
+/**
+ * This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it
+ * passes null as a hint to the decoders. However, that makes it inefficient to call repeatedly.
+ * Use setHints() followed by decodeWithState() for continuous scan applications.
+ */
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
+ self.hints = nil;
+ return [self decodeInternal:image error:error];
+}
+
+
+/**
+ * Decode an image using the hints provided. Does not honor existing state.
+ */
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ self.hints = hints;
+ return [self decodeInternal:image error:error];
+}
+
+/**
+ * Decode an image using the state set up by calling setHints() previously. Continuous scan
+ * clients will get a <b>large</b> speed increase by using this instead of decode().
+ */
+- (ZXResult *)decodeWithState:(ZXBinaryBitmap *)image error:(NSError **)error {
+ if (self.readers == nil) {
+ self.hints = nil;
+ }
+ return [self decodeInternal:image error:error];
+}
+
+/**
+ * This method adds state to the ZXMultiFormatReader. By setting the hints once, subsequent calls
+ * to decodeWithState(image) can reuse the same set of readers without reallocating memory. This
+ * is important for performance in continuous scan clients.
+ */
+- (void)setHints:(ZXDecodeHints *)hints {
+ _hints = hints;
+
+ BOOL tryHarder = hints != nil && hints.tryHarder;
+ [self.readers removeAllObjects];
+ if (hints != nil) {
+ BOOL addZXOneDReader = [hints containsFormat:kBarcodeFormatUPCA] ||
+ [hints containsFormat:kBarcodeFormatUPCE] ||
+ [hints containsFormat:kBarcodeFormatEan13] ||
+ [hints containsFormat:kBarcodeFormatEan8] ||
+ [hints containsFormat:kBarcodeFormatCodabar] ||
+ [hints containsFormat:kBarcodeFormatCode39] ||
+ [hints containsFormat:kBarcodeFormatCode93] ||
+ [hints containsFormat:kBarcodeFormatCode128] ||
+ [hints containsFormat:kBarcodeFormatITF] ||
+ [hints containsFormat:kBarcodeFormatRSS14] ||
+ [hints containsFormat:kBarcodeFormatRSSExpanded];
+ if (addZXOneDReader && !tryHarder) {
+ [self.readers addObject:[[ZXMultiFormatOneDReader alloc] initWithHints:hints]];
+ }
+ if ([hints containsFormat:kBarcodeFormatQRCode]) {
+ [self.readers addObject:[[ZXQRCodeReader alloc] init]];
+ }
+ if ([hints containsFormat:kBarcodeFormatDataMatrix]) {
+ [self.readers addObject:[[ZXDataMatrixReader alloc] init]];
+ }
+ if ([hints containsFormat:kBarcodeFormatAztec]) {
+ [self.readers addObject:[[ZXAztecReader alloc] init]];
+ }
+ if ([hints containsFormat:kBarcodeFormatPDF417]) {
+ [self.readers addObject:[[ZXPDF417Reader alloc] init]];
+ }
+ if ([hints containsFormat:kBarcodeFormatMaxiCode]) {
+ [self.readers addObject:[[ZXMaxiCodeReader alloc] init]];
+ }
+ if (addZXOneDReader && tryHarder) {
+ [self.readers addObject:[[ZXMultiFormatOneDReader alloc] initWithHints:hints]];
+ }
+ }
+ if ([self.readers count] == 0) {
+ if (!tryHarder) {
+ [self.readers addObject:[[ZXMultiFormatOneDReader alloc] initWithHints:hints]];
+ }
+ [self.readers addObject:[[ZXQRCodeReader alloc] init]];
+ [self.readers addObject:[[ZXDataMatrixReader alloc] init]];
+ [self.readers addObject:[[ZXAztecReader alloc] init]];
+ [self.readers addObject:[[ZXPDF417Reader alloc] init]];
+ [self.readers addObject:[[ZXMaxiCodeReader alloc] init]];
+ if (tryHarder) {
+ [self.readers addObject:[[ZXMultiFormatOneDReader alloc] initWithHints:hints]];
+ }
+ }
+}
+
+- (void)reset {
+ if (self.readers != nil) {
+ for (id<ZXReader> reader in self.readers) {
+ [reader reset];
+ }
+ }
+}
+
+- (ZXResult *)decodeInternal:(ZXBinaryBitmap *)image error:(NSError **)error {
+ if (self.readers != nil) {
+ for (id<ZXReader> reader in self.readers) {
+ ZXResult *result = [reader decode:image hints:self.hints error:nil];
+ if (result) {
+ return result;
+ }
+ }
+ }
+
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+}
+
+@end
diff --git a/ZXingObjC/ZXMultiFormatWriter.h b/ZXingObjC/ZXMultiFormatWriter.h
new file mode 100644
index 0000000..f83f732
--- /dev/null
+++ b/ZXingObjC/ZXMultiFormatWriter.h
@@ -0,0 +1,28 @@
+/*
+ * 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 "ZXWriter.h"
+
+/**
+ * This is a factory class which finds the appropriate Writer subclass for the BarcodeFormat
+ * requested and encodes the barcode with the supplied contents.
+ */
+
+@interface ZXMultiFormatWriter : NSObject <ZXWriter>
+
++ (id)writer;
+
+@end
diff --git a/ZXingObjC/ZXMultiFormatWriter.m b/ZXingObjC/ZXMultiFormatWriter.m
new file mode 100644
index 0000000..6a9f056
--- /dev/null
+++ b/ZXingObjC/ZXMultiFormatWriter.m
@@ -0,0 +1,96 @@
+/*
+ * 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 "ZXAztecWriter.h"
+#import "ZXBitMatrix.h"
+#import "ZXCodaBarWriter.h"
+#import "ZXCode39Writer.h"
+#import "ZXCode128Writer.h"
+#import "ZXDataMatrixWriter.h"
+#import "ZXEAN8Writer.h"
+#import "ZXEAN13Writer.h"
+#import "ZXErrors.h"
+#import "ZXITFWriter.h"
+#import "ZXMultiFormatWriter.h"
+#import "ZXPDF417Writer.h"
+#import "ZXQRCodeWriter.h"
+#import "ZXUPCAWriter.h"
+
+@implementation ZXMultiFormatWriter
+
++ (id)writer {
+ return [[ZXMultiFormatWriter alloc] init];
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error {
+ return [self encode:contents format:format width:width height:height hints:nil error:error];
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ id<ZXWriter> writer;
+ switch (format) {
+ case kBarcodeFormatEan8:
+ writer = [[ZXEAN8Writer alloc] init];
+ break;
+
+ case kBarcodeFormatEan13:
+ writer = [[ZXEAN13Writer alloc] init];
+ break;
+
+ case kBarcodeFormatUPCA:
+ writer = [[ZXUPCAWriter alloc] init];
+ break;
+
+ case kBarcodeFormatQRCode:
+ writer = [[ZXQRCodeWriter alloc] init];
+ break;
+
+ case kBarcodeFormatCode39:
+ writer = [[ZXCode39Writer alloc] init];
+ break;
+
+ case kBarcodeFormatCode128:
+ writer = [[ZXCode128Writer alloc] init];
+ break;
+
+ case kBarcodeFormatITF:
+ writer = [[ZXITFWriter alloc] init];
+ break;
+
+ case kBarcodeFormatPDF417:
+ writer = [[ZXPDF417Writer alloc] init];
+ break;
+
+ case kBarcodeFormatCodabar:
+ writer = [[ZXCodaBarWriter alloc] init];
+ break;
+
+ case kBarcodeFormatDataMatrix:
+ writer = [[ZXDataMatrixWriter alloc] init];
+ break;
+
+ case kBarcodeFormatAztec:
+ writer = [[ZXAztecWriter alloc] init];
+ break;
+
+ default:
+ 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];
+}
+
+@end
diff --git a/ZXingObjC/ZXPlanarYUVLuminanceSource.h b/ZXingObjC/ZXPlanarYUVLuminanceSource.h
new file mode 100644
index 0000000..850bbcf
--- /dev/null
+++ b/ZXingObjC/ZXPlanarYUVLuminanceSource.h
@@ -0,0 +1,38 @@
+/*
+ * 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 "ZXLuminanceSource.h"
+
+/**
+ * This object extends LuminanceSource around an array of YUV data returned from the camera driver,
+ * with the option to crop to a rectangle within the full data. This can be used to exclude
+ * superfluous pixels around the perimeter and speed up decoding.
+ *
+ * It works for any pixel format where the Y channel is planar and appears first, including
+ * YCbCr_420_SP and YCbCr_422_SP.
+ */
+
+@interface ZXPlanarYUVLuminanceSource : ZXLuminanceSource
+
+@property (nonatomic, assign, readonly) int thumbnailWidth;
+@property (nonatomic, assign, readonly) int thumbnailHeight;
+
+- (id)initWithYuvData:(int8_t *)yuvData yuvDataLen:(int)yuvDataLen dataWidth:(int)dataWidth
+ dataHeight:(int)dataHeight left:(int)left top:(int)top width:(int)width height:(int)height
+ reverseHorizontal:(BOOL)reverseHorizontal;
+- (int *)renderThumbnail;
+
+@end
diff --git a/ZXingObjC/ZXPlanarYUVLuminanceSource.m b/ZXingObjC/ZXPlanarYUVLuminanceSource.m
new file mode 100644
index 0000000..f5085b3
--- /dev/null
+++ b/ZXingObjC/ZXPlanarYUVLuminanceSource.m
@@ -0,0 +1,141 @@
+/*
+ * 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 "ZXPlanarYUVLuminanceSource.h"
+
+const int THUMBNAIL_SCALE_FACTOR = 2;
+
+@interface ZXPlanarYUVLuminanceSource ()
+
+@property (nonatomic, assign) int8_t *yuvData;
+@property (nonatomic, assign) int yuvDataLen;
+@property (nonatomic, assign) int dataWidth;
+@property (nonatomic, assign) int dataHeight;
+@property (nonatomic, assign) int left;
+@property (nonatomic, assign) int top;
+
+@end
+
+@implementation ZXPlanarYUVLuminanceSource
+
+- (id)initWithYuvData:(int8_t *)yuvData yuvDataLen:(int)yuvDataLen dataWidth:(int)dataWidth
+ dataHeight:(int)dataHeight left:(int)left top:(int)top width:(int)width height:(int)height
+ reverseHorizontal:(BOOL)reverseHorizontal {
+ if (self = [super initWithWidth:width height:height]) {
+ if (left + width > dataWidth || top + height > dataHeight) {
+ [NSException raise:NSInvalidArgumentException format:@"Crop rectangle does not fit within image data."];
+ }
+
+ _yuvDataLen = yuvDataLen;
+ _yuvData = (int8_t *)malloc(yuvDataLen * sizeof(int8_t));
+ memcpy(_yuvData, yuvData, yuvDataLen);
+ _dataWidth = dataWidth;
+ _dataHeight = dataHeight;
+ _left = left;
+ _top = top;
+ if (reverseHorizontal) {
+ [self reverseHorizontal:width height:height];
+ }
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_yuvData != NULL) {
+ free(_yuvData);
+ _yuvData = NULL;
+ }
+}
+
+- (int8_t *)row:(int)y {
+ if (y < 0 || y >= self.height) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Requested row is outside the image: %d", y];
+ }
+ int8_t *row = (int8_t *)malloc(self.width * sizeof(int8_t));
+ int offset = (y + self.top) * self.dataWidth + self.left;
+ memcpy(row, self.yuvData + offset, self.width);
+ return row;
+}
+
+- (int8_t *)matrix {
+ int area = self.width * self.height;
+ int8_t *matrix = malloc(area * sizeof(int8_t));
+ int inputOffset = self.top * self.dataWidth + self.left;
+
+ // If the width matches the full width of the underlying data, perform a single copy.
+ if (self.width == self.dataWidth) {
+ memcpy(matrix, self.yuvData + inputOffset, area - inputOffset);
+ return matrix;
+ }
+
+ // Otherwise copy one cropped row at a time.
+ for (int y = 0; y < self.height; y++) {
+ int outputOffset = y * self.width;
+ memcpy(matrix + outputOffset, self.yuvData + inputOffset, self.width);
+ inputOffset += self.dataWidth;
+ }
+ return matrix;
+}
+
+- (BOOL)cropSupported {
+ return YES;
+}
+
+- (ZXLuminanceSource *)crop:(int)left top:(int)top width:(int)width height:(int)height {
+ return [[[self class] alloc] initWithYuvData:self.yuvData yuvDataLen:self.yuvDataLen dataWidth:self.dataWidth
+ dataHeight:self.dataHeight left:self.left + left top:self.top + top
+ width:width height:height reverseHorizontal:NO];
+}
+
+- (int *)renderThumbnail {
+ int thumbWidth = self.width / THUMBNAIL_SCALE_FACTOR;
+ int thumbHeight = self.height / THUMBNAIL_SCALE_FACTOR;
+ int *pixels = (int *)malloc(thumbWidth * thumbHeight * sizeof(int));
+ int inputOffset = self.top * self.dataWidth + self.left;
+
+ for (int y = 0; y < self.height; y++) {
+ int outputOffset = y * self.width;
+ for (int x = 0; x < self.width; x++) {
+ int grey = self.yuvData[inputOffset + x * THUMBNAIL_SCALE_FACTOR] & 0xff;
+ pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
+ }
+ inputOffset += self.dataWidth * THUMBNAIL_SCALE_FACTOR;
+ }
+ return pixels;
+}
+
+- (int)thumbnailWidth {
+ return self.width / THUMBNAIL_SCALE_FACTOR;
+}
+
+- (int)thumbnailHeight {
+ return self.height / THUMBNAIL_SCALE_FACTOR;
+}
+
+- (void)reverseHorizontal:(int)_width height:(int)_height {
+ for (int y = 0, rowStart = self.top * self.dataWidth + self.left; y < _height; y++, rowStart += self.dataWidth) {
+ int middle = rowStart + _width / 2;
+ for (int x1 = rowStart, x2 = rowStart + _width - 1; x1 < middle; x1++, x2--) {
+ int8_t temp = self.yuvData[x1];
+ self.yuvData[x1] = self.yuvData[x2];
+ self.yuvData[x2] = temp;
+ }
+ }
+}
+
+@end
diff --git a/ZXingObjC/ZXRGBLuminanceSource.h b/ZXingObjC/ZXRGBLuminanceSource.h
new file mode 100644
index 0000000..07a2cb9
--- /dev/null
+++ b/ZXingObjC/ZXRGBLuminanceSource.h
@@ -0,0 +1,28 @@
+/*
+ * 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 "ZXLuminanceSource.h"
+
+/**
+ * This class is used to help decode images from files which arrive as RGB data from
+ * an ARGB pixel array. It does not support rotation.
+ */
+
+@interface ZXRGBLuminanceSource : ZXLuminanceSource
+
+- (id)initWithWidth:(int)width height:(int)height pixels:(int *)pixels pixelsLen:(int)pixelsLen;
+
+@end
diff --git a/ZXingObjC/ZXRGBLuminanceSource.m b/ZXingObjC/ZXRGBLuminanceSource.m
new file mode 100644
index 0000000..96dc198
--- /dev/null
+++ b/ZXingObjC/ZXRGBLuminanceSource.m
@@ -0,0 +1,130 @@
+/*
+ * 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"
+
+@interface ZXRGBLuminanceSource ()
+
+@property (nonatomic, assign) int8_t *luminances;
+@property (nonatomic, assign) int luminancesCount;
+@property (nonatomic, assign) int dataWidth;
+@property (nonatomic, assign) int dataHeight;
+@property (nonatomic, assign) int left;
+@property (nonatomic, assign) int top;
+
+@end
+
+@implementation ZXRGBLuminanceSource
+
+- (id)initWithWidth:(int)width height:(int)height pixels:(int *)pixels pixelsLen:(int)pixelsLen {
+ if (self = [super initWithWidth:width height:height]) {
+ _dataWidth = width;
+ _dataHeight = height;
+ _left = 0;
+ _top = 0;
+
+ // 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.
+ _luminancesCount = width * height;
+ _luminances = (int8_t *)malloc(_luminancesCount * sizeof(int8_t));
+ 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[offset + x] = (char) r;
+ } else {
+ // Calculate luminance cheaply, favoring green.
+ _luminances[offset + x] = (char) ((r + g + g + b) >> 2);
+ }
+ }
+ }
+ }
+
+ return self;
+}
+
+- (id)initWithPixels:(int8_t *)pixels pixelsLen:(int)pixelsLen 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."];
+ }
+
+ _luminancesCount = pixelsLen;
+ _luminances = (int8_t *)malloc(pixelsLen * sizeof(int8_t));
+ memcpy(_luminances, pixels, pixelsLen * sizeof(int8_t));
+
+ _dataWidth = dataWidth;
+ _dataHeight = dataHeight;
+ _left = left;
+ _top = top;
+ }
+
+ return self;
+}
+
+- (int8_t *)row:(int)y {
+ if (y < 0 || y >= self.height) {
+ [NSException raise:NSInvalidArgumentException format:@"Requested row is outside the image: %d", y];
+ }
+ int8_t *row = (int8_t *)malloc(self.width * sizeof(int8_t));
+
+ int offset = (y + self.top) * self.dataWidth + self.left;
+ memcpy(row, self.luminances + offset, self.width);
+ return row;
+}
+
+- (int8_t *)matrix {
+ int area = self.width * self.height;
+ int8_t *matrix = (int8_t *)malloc(area * sizeof(int8_t));
+ int inputOffset = self.top * self.dataWidth + self.left;
+
+ // If the width matches the full width of the underlying data, perform a single copy.
+ if (self.width == self.dataWidth) {
+ memcpy(matrix, self.luminances + inputOffset, area - inputOffset);
+ return matrix;
+ }
+
+ // Otherwise copy one cropped row at a time.
+ for (int y = 0; y < self.height; y++) {
+ int outputOffset = y * self.width;
+ memcpy(matrix + outputOffset, self.luminances + inputOffset, self.width);
+ inputOffset += self.dataWidth;
+ }
+ return matrix;
+}
+
+- (BOOL)cropSupported {
+ return YES;
+}
+
+- (ZXLuminanceSource *)crop:(int)left top:(int)top width:(int)width height:(int)height {
+ return [[[self class] alloc] initWithPixels:self.luminances
+ pixelsLen:self.luminancesCount
+ dataWidth:self.dataWidth
+ dataHeight:self.dataHeight
+ left:self.left + left
+ top:self.top + top
+ width:width
+ height:height];
+}
+
+@end
diff --git a/ZXingObjC/ZXReader.h b/ZXingObjC/ZXReader.h
new file mode 100644
index 0000000..9020725
--- /dev/null
+++ b/ZXingObjC/ZXReader.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementations of this interface can decode an image of a barcode in some format into
+ * the String it encodes. For example, ZXQRCodeReader can
+ * decode a QR code. The decoder may optionally receive hints from the caller which may help
+ * it decode more quickly or accurately.
+ *
+ * See ZXMultiFormatReader, which attempts to determine what barcode
+ * format is present within the image as well, and then decodes it accordingly.
+ */
+
+@class ZXBinaryBitmap, ZXDecodeHints, ZXResult;
+
+@protocol ZXReader <NSObject>
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error;
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error;
+- (void)reset;
+
+@end
diff --git a/ZXingObjC/ZXResult.h b/ZXingObjC/ZXResult.h
new file mode 100644
index 0000000..b71d2bc
--- /dev/null
+++ b/ZXingObjC/ZXResult.h
@@ -0,0 +1,42 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXResultMetadataType.h"
+
+/**
+ * Encapsulates the result of decoding a barcode within an image.
+ */
+
+@interface ZXResult : NSObject
+
+@property (nonatomic, copy, readonly) NSString *text;
+@property (nonatomic, assign, readonly) int8_t *rawBytes;
+@property (nonatomic, assign, readonly) int length;
+@property (nonatomic, strong, readonly) NSMutableArray *resultPoints;
+@property (nonatomic, assign, readonly) ZXBarcodeFormat barcodeFormat;
+@property (nonatomic, strong, readonly) NSMutableDictionary *resultMetadata;
+@property (nonatomic, assign, readonly) long timestamp;
+
+- (id)initWithText:(NSString *)text rawBytes:(int8_t *)rawBytes length:(unsigned int)length resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format;
+- (id)initWithText:(NSString *)text rawBytes:(int8_t *)rawBytes length:(unsigned int)length resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp;
++ (id)resultWithText:(NSString *)text rawBytes:(int8_t *)rawBytes length:(unsigned int)length resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format;
++ (id)resultWithText:(NSString *)text rawBytes:(int8_t *)rawBytes length:(unsigned int)length resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp;
+- (void)putMetadata:(ZXResultMetadataType)type value:(id)value;
+- (void)putAllMetadata:(NSMutableDictionary *)metadata;
+- (void)addResultPoints:(NSArray *)newPoints;
+
+@end
diff --git a/ZXingObjC/ZXResult.m b/ZXingObjC/ZXResult.m
new file mode 100644
index 0000000..16e9ac5
--- /dev/null
+++ b/ZXingObjC/ZXResult.m
@@ -0,0 +1,96 @@
+/*
+ * 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 "ZXResult.h"
+
+@interface ZXResult ()
+
+@property (nonatomic, strong) NSMutableDictionary *resultMetadata;
+@property (nonatomic, strong) NSMutableArray *resultPoints;
+
+@end
+
+@implementation ZXResult
+
+- (id)initWithText:(NSString *)text rawBytes:(int8_t *)rawBytes length:(unsigned int)length resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format {
+ return [self initWithText:text rawBytes:rawBytes length:length resultPoints:resultPoints format:format timestamp:CFAbsoluteTimeGetCurrent()];
+}
+
+- (id)initWithText:(NSString *)text rawBytes:(int8_t *)rawBytes length:(unsigned int)length resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp {
+ if (self = [super init]) {
+ _text = text;
+ if (rawBytes != NULL && length > 0) {
+ _rawBytes = (int8_t *)malloc(length * sizeof(int8_t));
+ memcpy(_rawBytes, rawBytes, length);
+ _length = length;
+ } else {
+ _rawBytes = NULL;
+ _length = 0;
+ }
+ _resultPoints = [resultPoints mutableCopy];
+ _barcodeFormat = format;
+ _resultMetadata = nil;
+ _timestamp = timestamp;
+ }
+
+ return self;
+}
+
++ (id)resultWithText:(NSString *)text rawBytes:(int8_t *)rawBytes length:(unsigned int)length resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format {
+ return [[self alloc] initWithText:text rawBytes:rawBytes length:length resultPoints:resultPoints format:format];
+}
+
++ (id)resultWithText:(NSString *)text rawBytes:(int8_t *)rawBytes length:(unsigned int)length resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp {
+ return [[self alloc] initWithText:text rawBytes:rawBytes length:length resultPoints:resultPoints format:format timestamp:timestamp];
+}
+
+- (void)dealloc {
+ if (_rawBytes != NULL) {
+ free(_rawBytes);
+ _rawBytes = NULL;
+ }
+}
+
+- (void)putMetadata:(ZXResultMetadataType)type value:(id)value {
+ if (self.resultMetadata == nil) {
+ self.resultMetadata = [NSMutableDictionary dictionary];
+ }
+ self.resultMetadata[@(type)] = value;
+}
+
+- (void)putAllMetadata:(NSMutableDictionary *)metadata {
+ if (metadata != nil) {
+ if (self.resultMetadata == nil) {
+ self.resultMetadata = metadata;
+ } else {
+ [self.resultMetadata addEntriesFromDictionary:metadata];
+ }
+ }
+}
+
+- (void)addResultPoints:(NSArray *)newPoints {
+ if (self.resultPoints == nil) {
+ self.resultPoints = [newPoints mutableCopy];
+ } else if (newPoints != nil && [newPoints count] > 0) {
+ [self.resultPoints addObjectsFromArray:newPoints];
+ }
+}
+
+- (NSString *)description {
+ return self.text;
+}
+
+@end
diff --git a/ZXingObjC/ZXResultMetadataType.h b/ZXingObjC/ZXResultMetadataType.h
new file mode 100644
index 0000000..64031e3
--- /dev/null
+++ b/ZXingObjC/ZXResultMetadataType.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+/**
+ * Represents some type of metadata about the result of the decoding that the decoder
+ * wishes to communicate back to the caller.
+ */
+
+typedef enum {
+ /**
+ * Unspecified, application-specific metadata. Maps to an unspecified NSObject.
+ */
+ kResultMetadataTypeOther,
+
+ /**
+ * Denotes the likely approximate orientation of the barcode in the image. This value
+ * is given as degrees rotated clockwise from the normal, upright orientation.
+ * For example a 1D barcode which was found by reading top-to-bottom would be
+ * said to have orientation "90". This key maps to an integer whose
+ * value is in the range [0,360).
+ */
+ kResultMetadataTypeOrientation,
+
+ /**
+ * 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
+ * the complete raw bytes in the barcode for these formats, it does not offer the bytes
+ * from the byte segments alone.
+ *
+ * This maps to an array of byte arrays corresponding to the
+ * raw bytes in the byte segments in the barcode, in order.
+ */
+ kResultMetadataTypeByteSegments,
+
+ /**
+ * Error correction level used, if applicable. The value type depends on the
+ * format, but is typically a String.
+ */
+ kResultMetadataTypeErrorCorrectionLevel,
+
+ /**
+ * For some periodicals, indicates the issue number as an integer.
+ */
+ kResultMetadataTypeIssueNumber,
+
+ /**
+ * For some products, indicates the suggested retail price in the barcode as a
+ * formatted NSString.
+ */
+ kResultMetadataTypeSuggestedPrice,
+
+ /**
+ * For some products, the possible country of manufacture as NSString denoting the
+ * ISO country code. Some map to multiple possible countries, like "US/CA".
+ */
+ kResultMetadataTypePossibleCountry,
+
+ /**
+ * For some products, the extension text
+ */
+ kResultMetadataTypeUPCEANExtension,
+
+ /**
+ * PDF417-specific metadata
+ */
+ kResultMetadataTypePDF417ExtraMetadata
+} ZXResultMetadataType;
diff --git a/ZXingObjC/ZXResultPoint.h b/ZXingObjC/ZXResultPoint.h
new file mode 100644
index 0000000..9b25046
--- /dev/null
+++ b/ZXingObjC/ZXResultPoint.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * 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.
+ */
+
+@interface ZXResultPoint : NSObject<NSCopying>
+
+@property (nonatomic, assign, readonly) float x;
+@property (nonatomic, assign, readonly) float y;
+
+- (id)initWithX:(float)x y:(float)y;
++ (id)resultPointWithX:(float)x y:(float)y;
++ (void)orderBestPatterns:(NSMutableArray *)patterns;
++ (float)distance:(ZXResultPoint *)pattern1 pattern2:(ZXResultPoint *)pattern2;
+
+@end
diff --git a/ZXingObjC/ZXResultPoint.m b/ZXingObjC/ZXResultPoint.m
new file mode 100644
index 0000000..d6a88c1
--- /dev/null
+++ b/ZXingObjC/ZXResultPoint.m
@@ -0,0 +1,106 @@
+/*
+ * 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 "ZXMathUtils.h"
+#import "ZXResultPoint.h"
+
+@implementation ZXResultPoint
+
+- (id)initWithX:(float)x y:(float)y {
+ if (self = [super init]) {
+ _x = x;
+ _y = y;
+ }
+
+ return self;
+}
+
++ (id)resultPointWithX:(float)x y:(float)y {
+ return [[self alloc] initWithX:x y:y];
+}
+
+- (id)copyWithZone:(NSZone *)zone {
+ return [[ZXResultPoint allocWithZone:zone] initWithX:self.x y:self.y];
+}
+
+- (BOOL)isEqual:(id)other {
+ if ([other isKindOfClass:[ZXResultPoint class]]) {
+ ZXResultPoint *otherPoint = (ZXResultPoint *)other;
+ return self.x == otherPoint.x && self.y == otherPoint.y;
+ }
+ return NO;
+}
+
+- (NSUInteger)hash {
+ return 31 * *((int *)(&_x)) + *((int *)(&_y));
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"(%f,%f)", self.x, self.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.
+ */
++ (void)orderBestPatterns:(NSMutableArray *)patterns {
+ float zeroOneDistance = [self distance:patterns[0] pattern2:patterns[1]];
+ float oneTwoDistance = [self distance:patterns[1] pattern2:patterns[2]];
+ float zeroTwoDistance = [self distance:patterns[0] pattern2:patterns[2]];
+ ZXResultPoint *pointA;
+ ZXResultPoint *pointB;
+ ZXResultPoint *pointC;
+ if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
+ pointB = patterns[0];
+ pointA = patterns[1];
+ pointC = patterns[2];
+ } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
+ pointB = patterns[1];
+ pointA = patterns[0];
+ pointC = patterns[2];
+ } else {
+ pointB = patterns[2];
+ pointA = patterns[0];
+ pointC = patterns[1];
+ }
+
+ if ([self crossProductZ:pointA pointB:pointB pointC:pointC] < 0.0f) {
+ ZXResultPoint *temp = pointA;
+ pointA = pointC;
+ pointC = temp;
+ }
+ patterns[0] = pointA;
+ patterns[1] = pointB;
+ patterns[2] = pointC;
+}
+
+/**
+ * Returns distance between two points
+ */
++ (float)distance:(ZXResultPoint *)pattern1 pattern2:(ZXResultPoint *)pattern2 {
+ return [ZXMathUtils distance:pattern1.x aY:pattern1.y bX:pattern2.x bY:pattern2.y];
+}
+
+/**
+ * Returns the z component of the cross product between vectors BC and BA.
+ */
++ (float) crossProductZ:(ZXResultPoint *)pointA pointB:(ZXResultPoint *)pointB pointC:(ZXResultPoint *)pointC {
+ float bX = pointB.x;
+ float bY = pointB.y;
+ return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));
+}
+
+@end
diff --git a/ZXingObjC/ZXResultPointCallback.h b/ZXingObjC/ZXResultPointCallback.h
new file mode 100644
index 0000000..f3fa450
--- /dev/null
+++ b/ZXingObjC/ZXResultPointCallback.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * Callback which is invoked when a possible result point (significant
+ * point in the barcode image such as a corner) is found.
+ */
+
+@class ZXResultPoint;
+
+@protocol ZXResultPointCallback <NSObject>
+
+- (void)foundPossibleResultPoint:(ZXResultPoint *)point;
+
+@end
diff --git a/ZXingObjC/ZXWriter.h b/ZXingObjC/ZXWriter.h
new file mode 100644
index 0000000..6cc9902
--- /dev/null
+++ b/ZXingObjC/ZXWriter.h
@@ -0,0 +1,30 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+
+/**
+ * The base class for all objects which encode/generate a barcode image.
+ */
+
+@class ZXBitMatrix, ZXEncodeHints;
+
+@protocol ZXWriter <NSObject>
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error;
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/ZXingObjC.h b/ZXingObjC/ZXingObjC.h
new file mode 100644
index 0000000..e943c6d
--- /dev/null
+++ b/ZXingObjC/ZXingObjC.h
@@ -0,0 +1,305 @@
+/*
+ * 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 <Foundation/Foundation.h>
+
+// ZXingObjC/aztec/decoder
+#import "ZXAztecDecoder.h"
+
+// ZXingObjC/aztec/detector
+#import "ZXAztecDetector.h"
+
+// ZXingObjC/aztec/encoder
+#import "ZXAztecCode.h"
+#import "ZXAztecEncoder.h"
+#import "ZXAztecWriter.h"
+
+// ZXingObjC/aztec
+#import "ZXAztecDetectorResult.h"
+#import "ZXAztecReader.h"
+
+// ZXingObjC/client/result
+#import "ZXAbstractDoCoMoResultParser.h"
+#import "ZXAddressBookAUResultParser.h"
+#import "ZXAddressBookDoCoMoResultParser.h"
+#import "ZXAddressBookParsedResult.h"
+#import "ZXBizcardResultParser.h"
+#import "ZXBookmarkDoCoMoResultParser.h"
+#import "ZXCalendarParsedResult.h"
+#import "ZXEmailAddressParsedResult.h"
+#import "ZXEmailAddressResultParser.h"
+#import "ZXEmailDoCoMoResultParser.h"
+#import "ZXExpandedProductParsedResult.h"
+#import "ZXExpandedProductResultParser.h"
+#import "ZXGeoParsedResult.h"
+#import "ZXGeoResultParser.h"
+#import "ZXISBNParsedResult.h"
+#import "ZXISBNResultParser.h"
+#import "ZXParsedResult.h"
+#import "ZXParsedResultType.h"
+#import "ZXProductParsedResult.h"
+#import "ZXProductResultParser.h"
+#import "ZXResultParser.h"
+#import "ZXSMSMMSResultParser.h"
+#import "ZXSMSParsedResult.h"
+#import "ZXSMSTOMMSTOResultParser.h"
+#import "ZXSMTPResultParser.h"
+#import "ZXTelParsedResult.h"
+#import "ZXTelResultParser.h"
+#import "ZXTextParsedResult.h"
+#import "ZXURIParsedResult.h"
+#import "ZXURIResultParser.h"
+#import "ZXURLTOResultParser.h"
+#import "ZXVCardResultParser.h"
+#import "ZXVEventResultParser.h"
+#import "ZXWifiParsedResult.h"
+#import "ZXWifiResultParser.h"
+
+// ZXingObjC/client
+#import "ZXCapture.h"
+#import "ZXCaptureDelegate.h"
+#import "ZXCaptureView.h"
+#import "ZXCGImageLuminanceSource.h"
+#import "ZXImage.h"
+#import "ZXView.h"
+
+// ZXingObjC/common/detector
+#import "ZXMathUtils.h"
+#import "ZXMonochromeRectangleDetector.h"
+#import "ZXWhiteRectangleDetector.h"
+
+// ZXingObjC/common/reedsolomon
+#import "ZXGenericGF.h"
+#import "ZXGenericGFPoly.h"
+#import "ZXReedSolomonDecoder.h"
+#import "ZXReedSolomonEncoder.h"
+
+// ZXingObjC/common
+#import "ZXBitArray.h"
+#import "ZXBitMatrix.h"
+#import "ZXBitSource.h"
+#import "ZXCharacterSetECI.h"
+#import "ZXDecoderResult.h"
+#import "ZXDefaultGridSampler.h"
+#import "ZXDetectorResult.h"
+#import "ZXECI.h"
+#import "ZXGlobalHistogramBinarizer.h"
+#import "ZXGridSampler.h"
+#import "ZXHybridBinarizer.h"
+#import "ZXPerspectiveTransform.h"
+#import "ZXStringUtils.h"
+
+// ZXingObjC/datamatrix/decoder
+#import "ZXDataMatrixBitMatrixParser.h"
+#import "ZXDataMatrixDataBlock.h"
+#import "ZXDataMatrixDecodedBitStreamParser.h"
+#import "ZXDataMatrixDecoder.h"
+#import "ZXDataMatrixVersion.h"
+
+// ZXingObjC/datamatrix/detector
+#import "ZXDataMatrixDetector.h"
+
+// ZXingObjC/datamatrix/encoder
+#import "ZXASCIIEncoder.h"
+#import "ZXBase256Encoder.h"
+#import "ZXC40Encoder.h"
+#import "ZXDataMatrixEncoder.h"
+#import "ZXDataMatrixErrorCorrection.h"
+#import "ZXDataMatrixSymbolInfo144.h"
+#import "ZXDefaultPlacement.h"
+#import "ZXEdifactEncoder.h"
+#import "ZXEncoderContext.h"
+#import "ZXHighLevelEncoder.h"
+#import "ZXSymbolInfo.h"
+#import "ZXSymbolShapeHint.h"
+#import "ZXTextEncoder.h"
+#import "ZXX12Encoder.h"
+
+// ZXingObjC/datamatrix
+#import "ZXDataMatrixReader.h"
+#import "ZXDataMatrixWriter.h"
+
+// ZXingObjC/maxicode/decoder
+#import "ZXMaxiCodeBitMatrixParser.h"
+#import "ZXMaxiCodeDecodedBitStreamParser.h"
+#import "ZXMaxiCodeDecoder.h"
+
+// ZXingObjC/maxicode
+#import "ZXMaxiCodeReader.h"
+
+// ZXingObjC/multi/qrcode/detector
+#import "ZXMultiDetector.h"
+#import "ZXMultiFinderPatternFinder.h"
+
+// ZXingObjC/multi/qrcode
+#import "ZXQRCodeMultiReader.h"
+
+// ZXingObjC/multi
+#import "ZXByQuadrantReader.h"
+#import "ZXGenericMultipleBarcodeReader.h"
+#import "ZXMultipleBarcodeReader.h"
+
+// ZXingObjC/oned/rss/expanded/decoders
+#import "ZXAbstractExpandedDecoder.h"
+#import "ZXAI013103decoder.h"
+#import "ZXAI01320xDecoder.h"
+#import "ZXAI01392xDecoder.h"
+#import "ZXAI01393xDecoder.h"
+#import "ZXAI013x0x1xDecoder.h"
+#import "ZXAI013x0xDecoder.h"
+#import "ZXAI01AndOtherAIs.h"
+#import "ZXAI01decoder.h"
+#import "ZXAI01weightDecoder.h"
+#import "ZXAnyAIDecoder.h"
+#import "ZXBlockParsedResult.h"
+#import "ZXCurrentParsingState.h"
+#import "ZXDecodedChar.h"
+#import "ZXDecodedInformation.h"
+#import "ZXDecodedNumeric.h"
+#import "ZXDecodedObject.h"
+#import "ZXFieldParser.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+// ZXingObjC/oned/rss/expanded
+#import "ZXBitArrayBuilder.h"
+#import "ZXExpandedPair.h"
+#import "ZXExpandedRow.h"
+#import "ZXRSSExpandedReader.h"
+
+// ZXingObjC/oned/rss
+#import "ZXAbstractRSSReader.h"
+#import "ZXDataCharacter.h"
+#import "ZXPair.h"
+#import "ZXRSS14Reader.h"
+#import "ZXRSSFinderPattern.h"
+#import "ZXRSSUtils.h"
+
+// ZXingObjC/oned
+#import "ZXCodaBarReader.h"
+#import "ZXCodaBarWriter.h"
+#import "ZXCode128Reader.h"
+#import "ZXCode128Writer.h"
+#import "ZXCode39Reader.h"
+#import "ZXCode39Writer.h"
+#import "ZXCode93Reader.h"
+#import "ZXEAN13Reader.h"
+#import "ZXEAN13Writer.h"
+#import "ZXEAN8Reader.h"
+#import "ZXEAN8Writer.h"
+#import "ZXEANManufacturerOrgSupport.h"
+#import "ZXITFReader.h"
+#import "ZXITFWriter.h"
+#import "ZXMultiFormatOneDReader.h"
+#import "ZXMultiFormatUPCEANReader.h"
+#import "ZXOneDimensionalCodeWriter.h"
+#import "ZXOneDReader.h"
+#import "ZXUPCAReader.h"
+#import "ZXUPCAWriter.h"
+#import "ZXUPCEANExtension2Support.h"
+#import "ZXUPCEANExtension5Support.h"
+#import "ZXUPCEANExtensionSupport.h"
+#import "ZXUPCEANReader.h"
+#import "ZXUPCEANWriter.h"
+#import "ZXUPCEReader.h"
+
+// ZXingObjC/pdf417/decoder/ec
+#import "ZXModulusGF.h"
+#import "ZXModulusPoly.h"
+#import "ZXPDF417ECErrorCorrection.h"
+
+// ZXingObjC/pdf417/decoder
+#import "ZXPDF417BarcodeMetadata.h"
+#import "ZXPDF417BarcodeValue.h"
+#import "ZXPDF417BoundingBox.h"
+#import "ZXPDF417Codeword.h"
+#import "ZXPDF417CodewordDecoder.h"
+#import "ZXPDF417DecodedBitStreamParser.h"
+#import "ZXPDF417DetectionResult.h"
+#import "ZXPDF417DetectionResultColumn.h"
+#import "ZXPDF417DetectionResultRowIndicatorColumn.h"
+#import "ZXPDF417ScanningDecoder.h"
+
+// ZXingObjC/pdf417/detector
+#import "ZXPDF417Detector.h"
+#import "ZXPDF417DetectorResult.h"
+
+// ZXingObjC/pdf417/encoder
+#import "ZXBarcodeMatrix.h"
+#import "ZXBarcodeRow.h"
+#import "ZXCompaction.h"
+#import "ZXDimensions.h"
+#import "ZXPDF417.h"
+#import "ZXPDF417ErrorCorrection.h"
+#import "ZXPDF417HighLevelEncoder.h"
+#import "ZXPDF417Writer.h"
+
+// ZXingObjC/pdf417
+#import "ZXPDF417Common.h"
+#import "ZXPDF417Reader.h"
+#import "ZXPDF417ResultMetadata.h"
+#import "ZXPDF417Writer.h"
+
+// ZXingObjC/qrcode/decoder
+#import "ZXDataMask.h"
+#import "ZXErrorCorrectionLevel.h"
+#import "ZXFormatInformation.h"
+#import "ZXMode.h"
+#import "ZXQRCodeBitMatrixParser.h"
+#import "ZXQRCodeDataBlock.h"
+#import "ZXQRCodeDecodedBitStreamParser.h"
+#import "ZXQRCodeDecoder.h"
+#import "ZXQRCodeVersion.h"
+
+// ZXingObjC/qrcode/detector
+#import "ZXAlignmentPattern.h"
+#import "ZXAlignmentPatternFinder.h"
+#import "ZXFinderPatternFinder.h"
+#import "ZXFinderPatternInfo.h"
+#import "ZXQRCodeDetector.h"
+#import "ZXQRCodeFinderPattern.h"
+
+// ZXingObjC/qrcode/encoder
+#import "ZXBlockPair.h"
+#import "ZXByteMatrix.h"
+#import "ZXEncoder.h"
+#import "ZXMaskUtil.h"
+#import "ZXMatrixUtil.h"
+#import "ZXQRCode.h"
+
+// ZXingObjC/qrcode
+#import "ZXQRCodeReader.h"
+#import "ZXQRCodeWriter.h"
+
+// ZXingObjC
+#import "ZXBarcodeFormat.h"
+#import "ZXBinarizer.h"
+#import "ZXBinaryBitmap.h"
+#import "ZXDecodeHints.h"
+#import "ZXDimension.h"
+#import "ZXEncodeHints.h"
+#import "ZXErrors.h"
+#import "ZXInvertedLuminanceSource.h"
+#import "ZXLuminanceSource.h"
+#import "ZXMultiFormatReader.h"
+#import "ZXMultiFormatWriter.h"
+#import "ZXPlanarYUVLuminanceSource.h"
+#import "ZXReader.h"
+#import "ZXResult.h"
+#import "ZXResultMetadataType.h"
+#import "ZXResultPoint.h"
+#import "ZXResultPointCallback.h"
+#import "ZXRGBLuminanceSource.h"
+#import "ZXWriter.h"
diff --git a/ZXingObjC/aztec/ZXAztecDetectorResult.h b/ZXingObjC/aztec/ZXAztecDetectorResult.h
new file mode 100644
index 0000000..f1c7a15
--- /dev/null
+++ b/ZXingObjC/aztec/ZXAztecDetectorResult.h
@@ -0,0 +1,33 @@
+/*
+ * 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 "ZXResultPoint.h"
+#import "ZXBitMatrix.h"
+#import "ZXDetectorResult.h"
+
+@interface ZXAztecDetectorResult : ZXDetectorResult
+
+@property (nonatomic, readonly) BOOL compact;
+@property (nonatomic, readonly) int nbDatablocks;
+@property (nonatomic, readonly) int nbLayers;
+
+- (id)initWithBits:(ZXBitMatrix *)bits
+ points:(NSArray *)points
+ compact:(BOOL)compact
+ nbDatablocks:(int)nbDatablocks
+ nbLayers:(int)nbLayers;
+
+@end
diff --git a/ZXingObjC/aztec/ZXAztecDetectorResult.m b/ZXingObjC/aztec/ZXAztecDetectorResult.m
new file mode 100644
index 0000000..9dd270e
--- /dev/null
+++ b/ZXingObjC/aztec/ZXAztecDetectorResult.m
@@ -0,0 +1,35 @@
+/*
+ * 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 "ZXAztecDetectorResult.h"
+
+@implementation ZXAztecDetectorResult
+
+- (id)initWithBits:(ZXBitMatrix *)bits
+ points:(NSArray *)points
+ compact:(BOOL)compact
+ nbDatablocks:(int)nbDatablocks
+ nbLayers:(int)nbLayers {
+ if (self = [super initWithBits:bits points:points]) {
+ _compact = compact;
+ _nbDatablocks = nbDatablocks;
+ _nbLayers = nbLayers;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/aztec/ZXAztecReader.h b/ZXingObjC/aztec/ZXAztecReader.h
new file mode 100644
index 0000000..55a95d2
--- /dev/null
+++ b/ZXingObjC/aztec/ZXAztecReader.h
@@ -0,0 +1,26 @@
+/*
+ * 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 "ZXReader.h"
+
+@class ZXBinaryBitmap, ZXDecodeHints, ZXResult;
+
+/**
+ * This implementation can detect and decode Aztec codes in an image.
+ */
+@interface ZXAztecReader : NSObject <ZXReader>
+
+@end
diff --git a/ZXingObjC/aztec/ZXAztecReader.m b/ZXingObjC/aztec/ZXAztecReader.m
new file mode 100644
index 0000000..1c62ef5
--- /dev/null
+++ b/ZXingObjC/aztec/ZXAztecReader.m
@@ -0,0 +1,80 @@
+/*
+ * 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 "ZXAztecDecoder.h"
+#import "ZXAztecDetector.h"
+#import "ZXAztecDetectorResult.h"
+#import "ZXAztecReader.h"
+#import "ZXBinaryBitmap.h"
+#import "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXReader.h"
+#import "ZXResult.h"
+#import "ZXResultPointCallback.h"
+
+@implementation ZXAztecReader
+
+/**
+ * Locates and decodes a Data Matrix code in an image.
+ */
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decode:image hints:nil error:error];
+}
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXBitMatrix *matrix = [image blackMatrixWithError:error];
+ if (!matrix) {
+ return nil;
+ }
+
+ ZXAztecDetectorResult *detectorResult = [[[ZXAztecDetector alloc] initWithImage:matrix] detectWithError:error];
+ if (!detectorResult) {
+ return nil;
+ }
+ NSArray *points = [detectorResult points];
+
+ if (hints != nil) {
+ id <ZXResultPointCallback> rpcb = hints.resultPointCallback;
+ if (rpcb != nil) {
+ for (ZXResultPoint *p in points) {
+ [rpcb foundPossibleResultPoint:p];
+ }
+ }
+ }
+
+ ZXDecoderResult *decoderResult = [[[ZXAztecDecoder alloc] init] decode:detectorResult error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ ZXResult *result = [ZXResult resultWithText:decoderResult.text rawBytes:decoderResult.rawBytes length:decoderResult.length resultPoints:points format:kBarcodeFormatAztec];
+
+ NSMutableArray *byteSegments = decoderResult.byteSegments;
+ if (byteSegments != nil) {
+ [result putMetadata:kResultMetadataTypeByteSegments value:byteSegments];
+ }
+ NSString *ecLevel = decoderResult.ecLevel;
+ if (ecLevel != nil) {
+ [result putMetadata:kResultMetadataTypeErrorCorrectionLevel value:ecLevel];
+ }
+
+ return result;
+}
+
+- (void)reset {
+ // do nothing
+}
+
+@end
diff --git a/ZXingObjC/aztec/ZXAztecWriter.h b/ZXingObjC/aztec/ZXAztecWriter.h
new file mode 100644
index 0000000..cd032e2
--- /dev/null
+++ b/ZXingObjC/aztec/ZXAztecWriter.h
@@ -0,0 +1,21 @@
+/*
+ * 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 "ZXWriter.h"
+
+@interface ZXAztecWriter : NSObject <ZXWriter>
+
+@end
diff --git a/ZXingObjC/aztec/ZXAztecWriter.m b/ZXingObjC/aztec/ZXAztecWriter.m
new file mode 100644
index 0000000..eb1ba34
--- /dev/null
+++ b/ZXingObjC/aztec/ZXAztecWriter.m
@@ -0,0 +1,86 @@
+/*
+ * 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 "ZXAztecCode.h"
+#import "ZXAztecEncoder.h"
+#import "ZXAztecWriter.h"
+#import "ZXBitMatrix.h"
+#import "ZXEncodeHints.h"
+
+const NSStringEncoding ZX_DEFAULT_AZTEC_ENCODING = NSISOLatin1StringEncoding;
+
+@implementation ZXAztecWriter
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error {
+ return [self encode:contents format:format width:width height:height encoding:ZX_DEFAULT_AZTEC_ENCODING eccPercent:ZX_DEFAULT_AZTEC_EC_PERCENT];
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ NSStringEncoding encoding = hints.encoding;
+ NSNumber *eccPercent = hints.errorCorrectionPercent;
+
+ return [self encode:contents
+ format:format
+ width:width
+ height:height
+ encoding:encoding == 0 ? ZX_DEFAULT_AZTEC_ENCODING : encoding
+ eccPercent:eccPercent == nil ? ZX_DEFAULT_AZTEC_EC_PERCENT : [eccPercent intValue]];
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height encoding:(NSStringEncoding)encoding eccPercent:(int)eccPercent {
+ if (format != kBarcodeFormatAztec) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Can only encode kBarcodeFormatAztec (%d), but got %d", kBarcodeFormatAztec, format]
+ userInfo:nil];
+ }
+ NSData *contentsData = [contents dataUsingEncoding:encoding];
+ int8_t *bytes = (int8_t *)[contentsData bytes];
+ NSUInteger bytesLen = [contentsData length];
+
+ ZXAztecCode *aztec = [ZXAztecEncoder encode:bytes len:(int)bytesLen minECCPercent:eccPercent];
+ return [self renderResult:aztec width:width height:height];
+}
+
+- (ZXBitMatrix *)renderResult:(ZXAztecCode *)aztec width:(int)width height:(int)height {
+ ZXBitMatrix *input = aztec.matrix;
+ if (!input) {
+ return nil;
+ }
+
+ 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];
+
+ for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
+ // Write the contents of this row of the barcode
+ for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
+ if ([input getX:inputX y:inputY]) {
+ [output setRegionAtLeft:outputX top:outputY width:multiple height:multiple];
+ }
+ }
+ }
+
+ return output;
+}
+
+@end
diff --git a/ZXingObjC/aztec/decoder/ZXAztecDecoder.h b/ZXingObjC/aztec/decoder/ZXAztecDecoder.h
new file mode 100644
index 0000000..3b550ac
--- /dev/null
+++ b/ZXingObjC/aztec/decoder/ZXAztecDecoder.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * The main class which implements Aztec Code decoding -- as opposed to locating and extracting
+ * the Aztec Code from an image.
+ */
+
+@class ZXAztecDetectorResult, ZXDecoderResult;
+
+@interface ZXAztecDecoder : NSObject
+
+- (ZXDecoderResult *)decode:(ZXAztecDetectorResult *)detectorResult error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/aztec/decoder/ZXAztecDecoder.m b/ZXingObjC/aztec/decoder/ZXAztecDecoder.m
new file mode 100644
index 0000000..1a1a155
--- /dev/null
+++ b/ZXingObjC/aztec/decoder/ZXAztecDecoder.m
@@ -0,0 +1,483 @@
+/*
+ * 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 "ZXAztecDecoder.h"
+#import "ZXAztecDetectorResult.h"
+#import "ZXBitMatrix.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXGenericGF.h"
+#import "ZXReedSolomonDecoder.h"
+
+enum {
+ UPPER = 0,
+ LOWER,
+ MIXED,
+ DIGIT,
+ PUNCT,
+ BINARY
+};
+
+static int NB_BITS_COMPACT[] = {
+ 0, 104, 240, 408, 608
+};
+
+static int NB_BITS[] = {
+ 0, 128, 288, 480, 704, 960, 1248, 1568, 1920, 2304, 2720, 3168, 3648, 4160, 4704, 5280, 5888, 6528,
+ 7200, 7904, 8640, 9408, 10208, 11040, 11904, 12800, 13728, 14688, 15680, 16704, 17760, 18848, 19968
+};
+
+static int NB_DATABLOCK_COMPACT[] = {
+ 0, 17, 40, 51, 76
+};
+
+static int NB_DATABLOCK[] = {
+ 0, 21, 48, 60, 88, 120, 156, 196, 240, 230, 272, 316, 364, 416, 470, 528, 588, 652, 720, 790, 864,
+ 940, 1020, 920, 992, 1066, 1144, 1224, 1306, 1392, 1480, 1570, 1664
+};
+
+static NSString *UPPER_TABLE[] = {
+ @"CTRL_PS", @" ", @"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", @"CTRL_LL", @"CTRL_ML", @"CTRL_DL", @"CTRL_BS"
+};
+
+static NSString *LOWER_TABLE[] = {
+ @"CTRL_PS", @" ", @"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", @"CTRL_US", @"CTRL_ML", @"CTRL_DL", @"CTRL_BS"
+};
+
+static NSString *MIXED_TABLE[] = {
+ @"CTRL_PS", @" ", @"\1", @"\2", @"\3", @"\4", @"\5", @"\6", @"\7", @"\b", @"\t", @"\n",
+ @"\13", @"\f", @"\r", @"\33", @"\34", @"\35", @"\36", @"\37", @"@", @"\\", @"^", @"_",
+ @"`", @"|", @"~", @"\177", @"CTRL_LL", @"CTRL_UL", @"CTRL_PL", @"CTRL_BS"
+};
+
+static NSString *PUNCT_TABLE[] = {
+ @"", @"\r", @"\r\n", @". ", @", ", @": ", @"!", @"\"", @"#", @"$", @"%", @"&", @"'", @"(", @")",
+ @"*", @"+", @",", @"-", @".", @"/", @":", @";", @"<", @"=", @">", @"?", @"[", @"]", @"{", @"}", @"CTRL_UL"
+};
+
+static NSString *DIGIT_TABLE[] = {
+ @"CTRL_PS", @" ", @"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @",", @".", @"CTRL_UL", @"CTRL_US"
+};
+
+@interface ZXAztecDecoder ()
+
+@property (nonatomic, assign) int codewordSize;
+@property (nonatomic, strong) ZXAztecDetectorResult *ddata;
+@property (nonatomic, assign) int invertedBitCount;
+@property (nonatomic, assign) int numCodewords;
+
+@end
+
+@implementation ZXAztecDecoder
+
+- (ZXDecoderResult *)decode:(ZXAztecDetectorResult *)detectorResult error:(NSError **)error {
+ self.ddata = detectorResult;
+ ZXBitMatrix *matrix = [detectorResult bits];
+ if (![self.ddata compact]) {
+ matrix = [self removeDashedLines:[self.ddata bits]];
+ }
+
+ BOOL *rawbits;
+ NSUInteger rawbitsLength = [self extractBits:matrix pBits:&rawbits];
+ if (rawbitsLength == 0) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+
+ BOOL *correctedBits;
+ NSUInteger correctedBitsLength = [self correctBits:rawbits bitsLength:rawbitsLength pBits:&correctedBits error:error];
+ free(rawbits);
+ rawbits = NULL;
+ if (correctedBitsLength == 0) {
+ return nil;
+ }
+
+ NSString *result = [self encodedData:correctedBits length:correctedBitsLength error:error];
+
+ free(correctedBits);
+ correctedBits = NULL;
+
+ if (!result) {
+ return nil;
+ }
+ return [[ZXDecoderResult alloc] initWithRawBytes:NULL length:0 text:result byteSegments:nil ecLevel:nil];
+}
+
+
+/**
+ *
+ * Gets the string encoded in the aztec code bits
+ */
+- (NSString *)encodedData:(BOOL *)correctedBits length:(NSUInteger)correctedBitsLength error:(NSError **)error {
+ int endIndex = self.codewordSize * [self.ddata nbDatablocks] - self.invertedBitCount;
+ if (endIndex > correctedBitsLength) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ int lastTable = UPPER;
+ int table = UPPER;
+ int startIndex = 0;
+ NSMutableString *result = [NSMutableString stringWithCapacity:20];
+ BOOL end = NO;
+ BOOL shift = NO;
+ BOOL switchShift = NO;
+ BOOL binaryShift = NO;
+
+ while (!end) {
+ if (shift) {
+ switchShift = YES;
+ } else {
+ lastTable = table;
+ }
+
+ int code;
+ if (binaryShift) {
+ if (endIndex - startIndex < 5) {
+ break;
+ }
+
+ int length = [self readCode:correctedBits startIndex:startIndex length:5];
+ startIndex += 5;
+ if (length == 0) {
+ if (endIndex - startIndex < 11) {
+ break;
+ }
+
+ length = [self readCode:correctedBits startIndex:startIndex length:11] + 31;
+ startIndex += 11;
+ }
+ for (int charCount = 0; charCount < length; charCount++) {
+ if (endIndex - startIndex < 8) {
+ end = true;
+ break;
+ }
+
+ code = [self readCode:correctedBits startIndex:startIndex length:8];
+ unichar uCode = (unichar)code;
+ [result appendString:[NSString stringWithCharacters:&uCode length:1]];
+ startIndex += 8;
+ }
+ binaryShift = false;
+ } else {
+ if (table == BINARY) {
+ if (endIndex - startIndex < 8) {
+ break;
+ }
+ code = [self readCode:correctedBits startIndex:startIndex length:8];
+ startIndex += 8;
+
+ unichar uCode = (unichar)code;
+ [result appendString:[NSString stringWithCharacters:&uCode length:1]];
+ } else {
+ int size = 5;
+
+ if (table == DIGIT) {
+ size = 4;
+ }
+
+ if (endIndex - startIndex < size) {
+ break;
+ }
+
+ code = [self readCode:correctedBits startIndex:startIndex length:size];
+ startIndex += size;
+
+ NSString *str = [self character:table code:code];
+ if ([str hasPrefix:@"CTRL_"]) {
+ // Table changes
+ table = [self table:[str characterAtIndex:5]];
+
+ if ([str characterAtIndex:6] == 'S') {
+ shift = YES;
+ if ([str characterAtIndex:5] == 'B') {
+ binaryShift = YES;
+ }
+ }
+ } else {
+ [result appendString:str];
+ }
+ }
+ }
+
+ if (switchShift) {
+ table = lastTable;
+ shift = NO;
+ switchShift = NO;
+ }
+ }
+
+ return result;
+}
+
+
+/**
+ * gets the table corresponding to the char passed
+ */
+- (int)table:(unichar)t {
+ int table = UPPER;
+
+ switch (t) {
+ case 'U':
+ table = UPPER;
+ break;
+ case 'L':
+ table = LOWER;
+ break;
+ case 'P':
+ table = PUNCT;
+ break;
+ case 'M':
+ table = MIXED;
+ break;
+ case 'D':
+ table = DIGIT;
+ break;
+ case 'B':
+ table = BINARY;
+ break;
+ }
+ return table;
+}
+
+
+/**
+ * Gets the character (or string) corresponding to the passed code in the given table
+ */
+- (NSString *)character:(int)table code:(int)code {
+ switch (table) {
+ case UPPER:
+ return UPPER_TABLE[code];
+ case LOWER:
+ return LOWER_TABLE[code];
+ case MIXED:
+ return MIXED_TABLE[code];
+ case PUNCT:
+ return PUNCT_TABLE[code];
+ case DIGIT:
+ return DIGIT_TABLE[code];
+ default:
+ return @"";
+ }
+}
+
+
+/**
+ * Performs RS error correction on an array of bits
+ */
+- (NSUInteger)correctBits:(BOOL *)rawbits bitsLength:(NSUInteger)rawbitsLength pBits:(BOOL **)pBits error:(NSError **)error {
+ ZXGenericGF *gf;
+ if ([self.ddata nbLayers] <= 2) {
+ self.codewordSize = 6;
+ gf = [ZXGenericGF AztecData6];
+ } else if ([self.ddata nbLayers] <= 8) {
+ self.codewordSize = 8;
+ gf = [ZXGenericGF AztecData8];
+ } else if ([self.ddata nbLayers] <= 22) {
+ self.codewordSize = 10;
+ gf = [ZXGenericGF AztecData10];
+ } else {
+ self.codewordSize = 12;
+ gf = [ZXGenericGF AztecData12];
+ }
+
+ int numDataCodewords = [self.ddata nbDatablocks];
+ int numECCodewords;
+ int offset;
+
+ if ([self.ddata compact]) {
+ offset = NB_BITS_COMPACT[[self.ddata nbLayers]] - self.numCodewords * self.codewordSize;
+ numECCodewords = NB_DATABLOCK_COMPACT[[self.ddata nbLayers]] - numDataCodewords;
+ } else {
+ offset = NB_BITS[[self.ddata nbLayers]] - self.numCodewords * self.codewordSize;
+ numECCodewords = NB_DATABLOCK[[self.ddata nbLayers]] - numDataCodewords;
+ }
+
+ int dataWordsLen = self.numCodewords;
+ int dataWords[dataWordsLen];
+ for (int i = 0; i < dataWordsLen; i++) {
+ dataWords[i] = 0;
+ int flag = 1;
+ for (int j = 1; j <= self.codewordSize; j++) {
+ if (rawbits[self.codewordSize * i + self.codewordSize - j + offset]) {
+ dataWords[i] += flag;
+ }
+ flag <<= 1;
+ }
+ }
+
+ ZXReedSolomonDecoder *rsDecoder = [[ZXReedSolomonDecoder alloc] initWithField:gf];
+ NSError *decodeError = nil;
+ if (![rsDecoder decode:dataWords receivedLen:dataWordsLen twoS:numECCodewords error:&decodeError]) {
+ if (decodeError.code == ZXReedSolomonError) {
+ if (error) *error = FormatErrorInstance();
+ } else {
+ if (error) *error = decodeError;
+ }
+ return 0;
+ }
+
+ offset = 0;
+ self.invertedBitCount = 0;
+
+ NSUInteger correctedBitsLength = numDataCodewords * self.codewordSize;
+ BOOL *correctedBits = (BOOL *)malloc(correctedBitsLength * sizeof(BOOL));
+ memset(correctedBits, NO, correctedBitsLength * sizeof(BOOL));
+
+ for (int i = 0; i < numDataCodewords; i++) {
+ BOOL seriesColor = NO;
+ int seriesCount = 0;
+ int flag = 1 << (self.codewordSize - 1);
+
+ for (int j = 0; j < self.codewordSize; j++) {
+ BOOL color = (dataWords[i] & flag) == flag;
+
+ if (seriesCount == self.codewordSize - 1) {
+ if (color == seriesColor) {
+ if (error) *error = FormatErrorInstance();
+ return 0;
+ }
+ seriesColor = NO;
+ seriesCount = 0;
+ offset++;
+ self.invertedBitCount++;
+ } else {
+ if (seriesColor == color) {
+ seriesCount++;
+ } else {
+ seriesCount = 1;
+ seriesColor = color;
+ }
+
+ correctedBits[i * self.codewordSize + j - offset] = color;
+ }
+
+ flag = (int)(((NSUInteger)flag) >> 1);
+ }
+ }
+
+ *pBits = correctedBits;
+ return correctedBitsLength;
+}
+
+
+/**
+ * Gets the array of bits from an Aztec Code matrix
+ */
+- (NSUInteger)extractBits:(ZXBitMatrix *)matrix pBits:(BOOL **)pBits {
+ NSUInteger rawBitsLength;
+ if ([self.ddata compact]) {
+ if ([self.ddata nbLayers] > (sizeof(NB_BITS_COMPACT) / sizeof(int))) {
+ return 0;
+ }
+ rawBitsLength = NB_BITS_COMPACT[[self.ddata nbLayers]];
+ self.numCodewords = NB_DATABLOCK_COMPACT[[self.ddata nbLayers]];
+ } else {
+ if ([self.ddata nbLayers] > (sizeof(NB_BITS) / sizeof(int))) {
+ return 0;
+ }
+ rawBitsLength = NB_BITS[[self.ddata nbLayers]];
+ self.numCodewords = NB_DATABLOCK[[self.ddata nbLayers]];
+ }
+
+ BOOL *rawbits = (BOOL *)malloc(rawBitsLength * sizeof(BOOL));
+ memset(rawbits, NO, rawBitsLength * sizeof(BOOL));
+
+ int layer = [self.ddata nbLayers];
+ int size = matrix.height;
+ int rawbitsOffset = 0;
+ int matrixOffset = 0;
+
+ while (layer != 0) {
+ int flip = 0;
+
+ for (int i = 0; i < 2 * size - 4; i++) {
+ rawbits[rawbitsOffset + i] = [matrix getX:matrixOffset + flip y:matrixOffset + i / 2];
+
+ rawbits[rawbitsOffset + 2 * size - 4 + i] = [matrix getX:matrixOffset + i / 2 y:matrixOffset + size - 1 - flip];
+
+ flip = (flip + 1) % 2;
+ }
+
+ flip = 0;
+ for (int i = 2 * size + 1; i > 5; i--) {
+ rawbits[rawbitsOffset + 4 * size - 8 + (2 * size - i) + 1] =
+ [matrix getX:matrixOffset + size - 1 - flip y:matrixOffset + i / 2 - 1];
+ rawbits[rawbitsOffset + 6 * size - 12 + (2 * size - i) + 1] =
+ [matrix getX:matrixOffset + i / 2 - 1 y:matrixOffset + flip];
+ flip = (flip + 1) % 2;
+ }
+
+ matrixOffset += 2;
+ rawbitsOffset += 8 * size - 16;
+ layer--;
+ size -= 4;
+ }
+
+ *pBits = rawbits;
+ return rawBitsLength;
+}
+
+
+/**
+ * Transforms an Aztec code matrix by removing the control dashed lines
+ */
+- (ZXBitMatrix *)removeDashedLines:(ZXBitMatrix *)matrix {
+ int nbDashed = 1 + 2 * ((matrix.width - 1) / 2 / 16);
+ ZXBitMatrix *newMatrix = [[ZXBitMatrix alloc] initWithWidth:matrix.width - nbDashed height:matrix.height - nbDashed];
+ int nx = 0;
+
+ for (int x = 0; x < matrix.width; x++) {
+ if ((matrix.width / 2 - x) % 16 == 0) {
+ continue;
+ }
+ int ny = 0;
+
+ for (int y = 0; y < matrix.height; y++) {
+ if ((matrix.width / 2 - y) % 16 == 0) {
+ continue;
+ }
+ if ([matrix getX:x y:y]) {
+ [newMatrix setX:nx y:ny];
+ }
+ ny++;
+ }
+
+ nx++;
+ }
+
+ return newMatrix;
+}
+
+
+/**
+ * Reads a code of given length and at given index in an array of bits
+ */
+- (int)readCode:(BOOL *)rawbits startIndex:(int)startIndex length:(int)length {
+ int res = 0;
+
+ for (int i = startIndex; i < startIndex + length; i++) {
+ res <<= 1;
+ if (rawbits[i]) {
+ res++;
+ }
+ }
+
+ return res;
+}
+
+@end
diff --git a/ZXingObjC/aztec/detector/ZXAztecDetector.h b/ZXingObjC/aztec/detector/ZXAztecDetector.h
new file mode 100644
index 0000000..440495d
--- /dev/null
+++ b/ZXingObjC/aztec/detector/ZXAztecDetector.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates logic that can detect an Aztec Code in an image, even if the Aztec Code
+ * is rotated or skewed, or partially obscured.
+ */
+
+@class ZXAztecDetectorResult, ZXBitMatrix;
+
+@interface ZXAztecDetector : NSObject
+
+- (id)initWithImage:(ZXBitMatrix *)image;
+- (ZXAztecDetectorResult *)detectWithError:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/aztec/detector/ZXAztecDetector.m b/ZXingObjC/aztec/detector/ZXAztecDetector.m
new file mode 100644
index 0000000..8902bc3
--- /dev/null
+++ b/ZXingObjC/aztec/detector/ZXAztecDetector.m
@@ -0,0 +1,641 @@
+/*
+ * 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 "ZXAztecDetector.h"
+#import "ZXAztecDetectorResult.h"
+#import "ZXErrors.h"
+#import "ZXGenericGF.h"
+#import "ZXGridSampler.h"
+#import "ZXMathUtils.h"
+#import "ZXReedSolomonDecoder.h"
+#import "ZXResultPoint.h"
+#import "ZXWhiteRectangleDetector.h"
+
+@interface ZXAztecPoint : NSObject
+
+@property (nonatomic, assign) int x;
+@property (nonatomic, assign) int y;
+
+@end
+
+@implementation ZXAztecPoint
+
+- (id)initWithX:(int)x y:(int)y {
+ if (self = [super init]) {
+ _x = x;
+ _y = y;
+ }
+ return self;
+}
+
+- (ZXResultPoint *)toResultPoint {
+ return [[ZXResultPoint alloc] initWithX:self.x y:self.y];
+}
+
+@end
+
+@interface ZXAztecDetector ()
+
+@property (nonatomic, assign) BOOL compact;
+@property (nonatomic, strong) ZXBitMatrix *image;
+@property (nonatomic, assign) int nbCenterLayers;
+@property (nonatomic, assign) int nbDataBlocks;
+@property (nonatomic, assign) int nbLayers;
+@property (nonatomic, assign) int shift;
+
+@end
+
+@implementation ZXAztecDetector
+
+- (id)initWithImage:(ZXBitMatrix *)image {
+ if (self = [super init]) {
+ _image = image;
+ }
+ return self;
+}
+
+/**
+ * Detects an Aztec Code in an image.
+ */
+- (ZXAztecDetectorResult *)detectWithError:(NSError **)error {
+ // 1. Get the center of the aztec matrix
+ ZXAztecPoint *pCenter = [self matrixCenterWithError:error];
+ if (!pCenter) {
+ return nil;
+ }
+
+ // 2. Get the corners of the center bull's eye
+ NSArray *bullEyeCornerPoints = [self bullEyeCornerPoints:pCenter];
+ if (!bullEyeCornerPoints) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ // 3. Get the size of the matrix from the bull's eye
+ if (![self extractParameters:bullEyeCornerPoints error:error]) {
+ return nil;
+ }
+
+ // 4. Get the corners of the matrix
+ NSArray *corners = [self matrixCornerPoints:bullEyeCornerPoints];
+ if (!corners) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ // 5. Sample the grid
+ ZXBitMatrix *bits = [self sampleGrid:self.image
+ topLeft:corners[self.shift % 4]
+ bottomLeft:corners[(self.shift + 3) % 4]
+ bottomRight:corners[(self.shift + 2) % 4]
+ topRight:corners[(self.shift + 1) % 4]
+ error:error];
+ if (!bits) {
+ return nil;
+ }
+
+ return [[ZXAztecDetectorResult alloc] initWithBits:bits
+ points:corners
+ compact:self.compact
+ nbDatablocks:self.nbDataBlocks
+ nbLayers:self.nbLayers];
+}
+
+
+/**
+ * Extracts the number of data layers and data blocks from the layer around the bull's eye
+ */
+- (BOOL)extractParameters:(NSArray *)bullEyeCornerPoints error:(NSError **)error {
+ ZXAztecPoint *p0 = bullEyeCornerPoints[0];
+ ZXAztecPoint *p1 = bullEyeCornerPoints[1];
+ ZXAztecPoint *p2 = bullEyeCornerPoints[2];
+ ZXAztecPoint *p3 = bullEyeCornerPoints[3];
+
+ int twoCenterLayers = 2 * self.nbCenterLayers;
+
+ // Get the bits around the bull's eye
+ NSArray *resab = [self sampleLine:p0 p2:p1 size:twoCenterLayers + 1];
+ NSArray *resbc = [self sampleLine:p1 p2:p2 size:twoCenterLayers + 1];
+ NSArray *rescd = [self sampleLine:p2 p2:p3 size:twoCenterLayers + 1];
+ NSArray *resda = [self sampleLine:p3 p2:p0 size:twoCenterLayers + 1];
+
+ // Determine the orientation of the matrix
+ if ([resab[0] boolValue] && [resab[twoCenterLayers] boolValue]) {
+ self.shift = 0;
+ } else if ([resbc[0] boolValue] && [resbc[twoCenterLayers] boolValue]) {
+ self.shift = 1;
+ } else if ([rescd[0] boolValue] && [rescd[twoCenterLayers] boolValue]) {
+ self.shift = 2;
+ } else if ([resda[0] boolValue] && [resda[twoCenterLayers] boolValue]) {
+ self.shift = 3;
+ } else {
+ if (error) *error = NotFoundErrorInstance();
+ return NO;
+ }
+
+ NSMutableArray *parameterData = [NSMutableArray array];
+ NSMutableArray *shiftedParameterData = [NSMutableArray array];
+ if (self.compact) {
+ for (int i = 0; i < 28; i++) {
+ [shiftedParameterData addObject:@NO];
+ }
+
+ for (int i = 0; i < 7; i++) {
+ shiftedParameterData[i] = resab[2+i];
+ shiftedParameterData[i + 7] = resbc[2+i];
+ shiftedParameterData[i + 14] = rescd[2+i];
+ shiftedParameterData[i + 21] = resda[2+i];
+ }
+
+ for (int i = 0; i < 28; i++) {
+ [parameterData addObject:shiftedParameterData[(i + self.shift * 7) % 28]];
+ }
+ } else {
+ for (int i = 0; i < 40; i++) {
+ [shiftedParameterData addObject:@NO];
+ }
+
+ for (int i = 0; i < 11; i++) {
+ if (i < 5) {
+ shiftedParameterData[i] = resab[2 + i];
+ shiftedParameterData[i + 10] = resbc[2 + i];
+ shiftedParameterData[i + 20] = rescd[2 + i];
+ shiftedParameterData[i + 30] = resda[2 + i];
+ }
+ if (i > 5) {
+ shiftedParameterData[i - 1] = resab[2 + i];
+ shiftedParameterData[i + 9] = resbc[2 + i];
+ shiftedParameterData[i + 19] = rescd[2 + i];
+ shiftedParameterData[i + 29] = resda[2 + i];
+ }
+ }
+
+ for (int i = 0; i < 40; i++) {
+ [parameterData addObject:shiftedParameterData[(i + self.shift * 10) % 40]];
+ }
+ }
+
+ if (![self correctParameterData:parameterData compact:self.compact error:error]) {
+ return NO;
+ }
+ [self parameters:parameterData];
+ return YES;
+}
+
+
+/**
+ * Gets the Aztec code corners from the bull's eye corners and the parameters
+ */
+- (NSArray *)matrixCornerPoints:(NSArray *)bullEyeCornerPoints {
+ ZXAztecPoint *p0 = bullEyeCornerPoints[0];
+ ZXAztecPoint *p1 = bullEyeCornerPoints[1];
+ ZXAztecPoint *p2 = bullEyeCornerPoints[2];
+ ZXAztecPoint *p3 = bullEyeCornerPoints[3];
+
+ float ratio = (2 * self.nbLayers + (self.nbLayers > 4 ? 1 : 0) + (self.nbLayers - 4) / 8) / (2.0f * self.nbCenterLayers);
+
+ int dx = p0.x - p2.x;
+ dx += dx > 0 ? 1 : -1;
+ int dy = p0.y - p2.y;
+ dy += dy > 0 ? 1 : -1;
+
+ int targetcx = [ZXMathUtils round:p2.x - ratio * dx];
+ int targetcy = [ZXMathUtils round:p2.y - ratio * dy];
+
+ int targetax = [ZXMathUtils round:p0.x + ratio * dx];
+ int targetay = [ZXMathUtils round:p0.y + ratio * dy];
+
+ dx = p1.x - p3.x;
+ dx += dx > 0 ? 1 : -1;
+ dy = p1.y - p3.y;
+ dy += dy > 0 ? 1 : -1;
+
+ int targetdx = [ZXMathUtils round:p3.x - ratio * dx];
+ int targetdy = [ZXMathUtils round:p3.y - ratio * dy];
+ int targetbx = [ZXMathUtils round:p1.x + ratio * dx];
+ int targetby = [ZXMathUtils round:p1.y + ratio * dy];
+
+ if (![self isValidX:targetax y:targetay] ||
+ ![self isValidX:targetbx y:targetby] ||
+ ![self isValidX:targetcx y:targetcy] ||
+ ![self isValidX:targetdx y:targetdy]) {
+ return nil;
+ }
+
+ return @[[[ZXResultPoint alloc] initWithX:targetax y:targetay],
+ [[ZXResultPoint alloc] initWithX:targetbx y:targetby],
+ [[ZXResultPoint alloc] initWithX:targetcx y:targetcy],
+ [[ZXResultPoint alloc] initWithX:targetdx y:targetdy]];
+}
+
+
+/**
+ * Corrects the parameter bits using Reed-Solomon algorithm
+ */
+- (BOOL)correctParameterData:(NSMutableArray *)parameterData compact:(BOOL)isCompact error:(NSError **)error {
+ int numCodewords;
+ int numDataCodewords;
+
+ if (isCompact) {
+ numCodewords = 7;
+ numDataCodewords = 2;
+ } else {
+ numCodewords = 10;
+ numDataCodewords = 4;
+ }
+
+ int numECCodewords = numCodewords - numDataCodewords;
+ int parameterWordsLen = numCodewords;
+ int parameterWords[parameterWordsLen];
+
+ int codewordSize = 4;
+ for (int i = 0; i < parameterWordsLen; i++) {
+ parameterWords[i] = 0;
+ int flag = 1;
+ for (int j = 1; j <= codewordSize; j++) {
+ if ([parameterData[codewordSize * i + codewordSize - j] boolValue]) {
+ parameterWords[i] += flag;
+ }
+ flag <<= 1;
+ }
+ }
+
+ ZXReedSolomonDecoder *rsDecoder = [[ZXReedSolomonDecoder alloc] initWithField:[ZXGenericGF AztecParam]];
+ NSError *decodeError = nil;
+ if (![rsDecoder decode:parameterWords receivedLen:parameterWordsLen twoS:numECCodewords error:error]) {
+ if (decodeError.code == ZXReedSolomonError) {
+ if (error) *error = NotFoundErrorInstance();
+ return NO;
+ } else {
+ return NO;
+ }
+ }
+
+ for (int i = 0; i < numDataCodewords; i++) {
+ int flag = 1;
+ for (int j = 1; j <= codewordSize; j++) {
+ parameterData[i * codewordSize + codewordSize - j] = [NSNumber numberWithBool:(parameterWords[i] & flag) == flag];
+ flag <<= 1;
+ }
+ }
+ return YES;
+}
+
+
+/**
+ * Finds the corners of a bull-eye centered on the passed point
+ */
+- (NSArray *)bullEyeCornerPoints:(ZXAztecPoint *)pCenter {
+ ZXAztecPoint *pina = pCenter;
+ ZXAztecPoint *pinb = pCenter;
+ ZXAztecPoint *pinc = pCenter;
+ ZXAztecPoint *pind = pCenter;
+
+ BOOL color = YES;
+
+ for (self.nbCenterLayers = 1; self.nbCenterLayers < 9; self.nbCenterLayers++) {
+ ZXAztecPoint *pouta = [self firstDifferent:pina color:color dx:1 dy:-1];
+ ZXAztecPoint *poutb = [self firstDifferent:pinb color:color dx:1 dy:1];
+ ZXAztecPoint *poutc = [self firstDifferent:pinc color:color dx:-1 dy:1];
+ ZXAztecPoint *poutd = [self firstDifferent:pind color:color dx:-1 dy:-1];
+
+ if (self.nbCenterLayers > 2) {
+ float q = [self distance:poutd b:pouta] * self.nbCenterLayers / ([self distance:pind b:pina] * (self.nbCenterLayers + 2));
+ if (q < 0.75 || q > 1.25 || ![self isWhiteOrBlackRectangle:pouta p2:poutb p3:poutc p4:poutd]) {
+ break;
+ }
+ }
+
+ pina = pouta;
+ pinb = poutb;
+ pinc = poutc;
+ pind = poutd;
+
+ color = !color;
+ }
+
+ if (self.nbCenterLayers != 5 && self.nbCenterLayers != 7) {
+ return nil;
+ }
+
+ self.compact = self.nbCenterLayers == 5;
+
+ float ratio = 0.75f * 2 / (2 * self.nbCenterLayers - 3);
+
+ int dx = pina.x - pinc.x;
+ int dy = pina.y - pinc.y;
+ int targetcx = [ZXMathUtils round:pinc.x - ratio * dx];
+ int targetcy = [ZXMathUtils round:pinc.y - ratio * dy];
+ int targetax = [ZXMathUtils round:pina.x + ratio * dx];
+ int targetay = [ZXMathUtils round:pina.y + ratio * dy];
+
+ dx = pinb.x - pind.x;
+ dy = pinb.y - pind.y;
+
+ int targetdx = [ZXMathUtils round:pind.x - ratio * dx];
+ int targetdy = [ZXMathUtils round:pind.y - ratio * dy];
+ int targetbx = [ZXMathUtils round:pinb.x + ratio * dx];
+ int targetby = [ZXMathUtils round:pinb.y + ratio * dy];
+
+ if (![self isValidX:targetax y:targetay] ||
+ ![self isValidX:targetbx y:targetby] ||
+ ![self isValidX:targetcx y:targetcy] ||
+ ![self isValidX:targetdx y:targetdy]) {
+ return nil;
+ }
+
+ ZXAztecPoint *pa = [[ZXAztecPoint alloc] initWithX:targetax y:targetay];
+ ZXAztecPoint *pb = [[ZXAztecPoint alloc] initWithX:targetbx y:targetby];
+ ZXAztecPoint *pc = [[ZXAztecPoint alloc] initWithX:targetcx y:targetcy];
+ ZXAztecPoint *pd = [[ZXAztecPoint alloc] initWithX:targetdx y:targetdy];
+
+ return @[pa, pb, pc, pd];
+}
+
+
+/**
+ * Finds a candidate center point of an Aztec code from an image
+ */
+- (ZXAztecPoint *)matrixCenterWithError:(NSError **)error {
+ ZXResultPoint *pointA;
+ ZXResultPoint *pointB;
+ ZXResultPoint *pointC;
+ ZXResultPoint *pointD;
+
+ NSError *detectorError = nil;
+ ZXWhiteRectangleDetector *detector = [[ZXWhiteRectangleDetector alloc] initWithImage:self.image error:&detectorError];
+ NSArray *cornerPoints = nil;
+ if (detector) {
+ cornerPoints = [detector detectWithError:&detectorError];
+ }
+
+ if (detectorError && detectorError.code == ZXNotFoundError) {
+ int cx = self.image.width / 2;
+ int cy = self.image.height / 2;
+ pointA = [[self firstDifferent:[[ZXAztecPoint alloc] initWithX:cx + 7 y:cy - 7] color:NO dx:1 dy:-1] toResultPoint];
+ pointB = [[self firstDifferent:[[ZXAztecPoint alloc] initWithX:cx + 7 y:cy + 7] color:NO dx:1 dy:1] toResultPoint];
+ pointC = [[self firstDifferent:[[ZXAztecPoint alloc] initWithX:cx - 7 y:cy + 7] color:NO dx:-1 dy:1] toResultPoint];
+ pointD = [[self firstDifferent:[[ZXAztecPoint alloc] initWithX:cx - 7 y:cy - 7] color:NO dx:-1 dy:-1] toResultPoint];
+ } else if (detectorError) {
+ if (error) *error = detectorError;
+ return nil;
+ } else {
+ pointA = cornerPoints[0];
+ pointB = cornerPoints[1];
+ pointC = cornerPoints[2];
+ pointD = cornerPoints[3];
+ }
+
+ int cx = [ZXMathUtils round:([pointA x] + [pointD x] + [pointB x] + [pointC x]) / 4.0f];
+ int cy = [ZXMathUtils round:([pointA y] + [pointD y] + [pointB y] + [pointC y]) / 4.0f];
+
+ detectorError = nil;
+ detector = [[ZXWhiteRectangleDetector alloc] initWithImage:self.image initSize:15 x:cx y:cy error:&detectorError];
+ if (detector) {
+ cornerPoints = [detector detectWithError:&detectorError];
+ }
+
+ if (detectorError && detectorError.code == ZXNotFoundError) {
+ pointA = [[self firstDifferent:[[ZXAztecPoint alloc] initWithX:cx + 7 y:cy - 7] color:NO dx:1 dy:-1] toResultPoint];
+ pointB = [[self firstDifferent:[[ZXAztecPoint alloc] initWithX:cx + 7 y:cy + 7] color:NO dx:1 dy:1] toResultPoint];
+ pointC = [[self firstDifferent:[[ZXAztecPoint alloc] initWithX:cx - 7 y:cy + 7] color:NO dx:-1 dy:1] toResultPoint];
+ pointD = [[self firstDifferent:[[ZXAztecPoint alloc] initWithX:cx - 7 y:cy - 7] color:NO dx:-1 dy:-1] toResultPoint];
+ } else if (detectorError) {
+ if (error) *error = detectorError;
+ return nil;
+ } else {
+ pointA = cornerPoints[0];
+ pointB = cornerPoints[1];
+ pointC = cornerPoints[2];
+ pointD = cornerPoints[3];
+ }
+
+ cx = [ZXMathUtils round:([pointA x] + [pointD x] + [pointB x] + [pointC x]) / 4];
+ cy = [ZXMathUtils round:([pointA y] + [pointD y] + [pointB y] + [pointC y]) / 4];
+
+ return [[ZXAztecPoint alloc] initWithX:cx y:cy];
+}
+
+
+/**
+ * Samples an Aztec matrix from an image
+ */
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)anImage
+ topLeft:(ZXResultPoint *)topLeft
+ bottomLeft:(ZXResultPoint *)bottomLeft
+ bottomRight:(ZXResultPoint *)bottomRight
+ topRight:(ZXResultPoint *)topRight
+ error:(NSError **)error {
+ int dimension;
+ if (self.compact) {
+ dimension = 4 * self.nbLayers + 11;
+ } else {
+ if (self.nbLayers <= 4) {
+ dimension = 4 * self.nbLayers + 15;
+ } else {
+ dimension = 4 * self.nbLayers + 2 * ((self.nbLayers - 4) / 8 + 1) + 15;
+ }
+ }
+
+ ZXGridSampler *sampler = [ZXGridSampler instance];
+
+ return [sampler sampleGrid:anImage
+ dimensionX:dimension
+ dimensionY:dimension
+ p1ToX:0.5f
+ p1ToY:0.5f
+ p2ToX:dimension - 0.5f
+ p2ToY:0.5f
+ p3ToX:dimension - 0.5f
+ p3ToY:dimension - 0.5f
+ p4ToX:0.5f
+ p4ToY:dimension - 0.5f
+ p1FromX:topLeft.x
+ p1FromY:topLeft.y
+ p2FromX:topRight.x
+ p2FromY:topRight.y
+ p3FromX:bottomRight.x
+ p3FromY:bottomRight.y
+ p4FromX:bottomLeft.x
+ p4FromY:bottomLeft.y
+ error:error];
+}
+
+
+/**
+ * Sets number of layers and number of data blocks from parameter bits
+ */
+- (void)parameters:(NSArray *)parameterData {
+ int nbBitsForNbLayers;
+ int nbBitsForNbDatablocks;
+
+ if (self.compact) {
+ nbBitsForNbLayers = 2;
+ nbBitsForNbDatablocks = 6;
+ } else {
+ nbBitsForNbLayers = 5;
+ nbBitsForNbDatablocks = 11;
+ }
+
+ for (int i = 0; i < nbBitsForNbLayers; i++) {
+ self.nbLayers <<= 1;
+ if ([parameterData[i] boolValue]) {
+ self.nbLayers++;
+ }
+ }
+
+ for (int i = nbBitsForNbLayers; i < nbBitsForNbLayers + nbBitsForNbDatablocks; i++) {
+ self.nbDataBlocks <<= 1;
+ if ([parameterData[i] boolValue]) {
+ self.nbDataBlocks++;
+ }
+ }
+
+ self.nbLayers++;
+ self.nbDataBlocks++;
+}
+
+
+/**
+ * Samples a line
+ */
+- (NSArray *)sampleLine:(ZXAztecPoint *)p1 p2:(ZXAztecPoint *)p2 size:(int)size {
+ NSMutableArray *res = [NSMutableArray arrayWithCapacity:size];
+ float d = [self distance:p1 b:p2];
+ float moduleSize = d / (size - 1);
+ float dx = moduleSize * (p2.x - p1.x) / d;
+ float dy = moduleSize * (p2.y - p1.y) / d;
+
+ float px = p1.x;
+ float py = p1.y;
+
+ for (int i = 0; i < size; i++) {
+ [res addObject:@([self.image getX:[ZXMathUtils round:px] y:[ZXMathUtils round:py]])];
+ px += dx;
+ py += dy;
+ }
+
+ return res;
+}
+
+
+/**
+ * return true if the border of the rectangle passed in parameter is compound of white points only
+ * or black points only
+ */
+- (BOOL)isWhiteOrBlackRectangle:(ZXAztecPoint *)p1 p2:(ZXAztecPoint *)p2 p3:(ZXAztecPoint *)p3 p4:(ZXAztecPoint *)p4 {
+ int corr = 3;
+
+ p1 = [[ZXAztecPoint alloc] initWithX:p1.x - corr y:p1.y + corr];
+ p2 = [[ZXAztecPoint alloc] initWithX:p2.x - corr y:p2.y - corr];
+ p3 = [[ZXAztecPoint alloc] initWithX:p3.x + corr y:p3.y - corr];
+ p4 = [[ZXAztecPoint alloc] initWithX:p4.x + corr y:p4.y + corr];
+
+ int cInit = [self color:p4 p2:p1];
+
+ if (cInit == 0) {
+ return NO;
+ }
+
+ int c = [self color:p1 p2:p2];
+
+ if (c != cInit) {
+ return NO;
+ }
+
+ c = [self color:p2 p2:p3];
+
+ if (c != cInit) {
+ return NO;
+ }
+
+ c = [self color:p3 p2:p4];
+
+ return c == cInit;
+}
+
+
+/**
+ * Gets the color of a segment
+ * return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else
+ */
+- (int)color:(ZXAztecPoint *)p1 p2:(ZXAztecPoint *)p2 {
+ float d = [self distance:p1 b:p2];
+ float dx = (p2.x - p1.x) / d;
+ float dy = (p2.y - p1.y) / d;
+ int error = 0;
+
+ float px = p1.x;
+ float py = p1.y;
+
+ BOOL colorModel = [self.image getX:p1.x y:p1.y];
+
+ for (int i = 0; i < d; i++) {
+ px += dx;
+ py += dy;
+ if ([self.image getX:[ZXMathUtils round:px] y:[ZXMathUtils round:py]] != colorModel) {
+ error++;
+ }
+ }
+
+ float errRatio = (float)error / d;
+
+ if (errRatio > 0.1f && errRatio < 0.9f) {
+ return 0;
+ }
+
+ return (errRatio <= 0.1f) == colorModel ? 1 : -1;
+}
+
+
+/**
+ * Gets the coordinate of the first point with a different color in the given direction
+ */
+- (ZXAztecPoint *)firstDifferent:(ZXAztecPoint *)init color:(BOOL)color dx:(int)dx dy:(int)dy {
+ int x = init.x + dx;
+ int y = init.y + dy;
+
+ while ([self isValidX:x y:y] && [self.image getX:x y:y] == color) {
+ x += dx;
+ y += dy;
+ }
+
+ x -= dx;
+ y -= dy;
+
+ while ([self isValidX:x y:y] && [self.image getX:x y:y] == color) {
+ x += dx;
+ }
+ x -= dx;
+
+ while ([self isValidX:x y:y] && [self.image getX:x y:y] == color) {
+ y += dy;
+ }
+ y -= dy;
+
+ return [[ZXAztecPoint alloc] initWithX:x y:y];
+}
+
+- (BOOL) isValidX:(int)x y:(int)y {
+ return x >= 0 && x < self.image.width && y > 0 && y < self.image.height;
+}
+
+
+- (float)distance:(ZXAztecPoint *)a b:(ZXAztecPoint *)b {
+ return [ZXMathUtils distance:a.x aY:a.y bX:b.x bY:b.y];
+}
+
+@end
diff --git a/ZXingObjC/aztec/encoder/ZXAztecCode.h b/ZXingObjC/aztec/encoder/ZXAztecCode.h
new file mode 100644
index 0000000..dcb681f
--- /dev/null
+++ b/ZXingObjC/aztec/encoder/ZXAztecCode.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+@class ZXBitMatrix;
+
+/**
+ * Aztec 2D code representation
+ */
+@interface ZXAztecCode : NSObject
+
+/**
+ * Number of data codewords
+ */
+@property (nonatomic, assign) int codeWords;
+
+/**
+ * Compact or full symbol indicator
+ */
+@property (nonatomic, assign) BOOL compact;
+
+/**
+ * Number of levels
+ */
+@property (nonatomic, assign) int layers;
+
+/**
+ * The symbol image
+ */
+@property (nonatomic, strong) ZXBitMatrix *matrix;
+
+/**
+ * Size in pixels (width and height)
+ */
+@property (nonatomic, assign) int size;
+
+@end
diff --git a/ZXingObjC/aztec/encoder/ZXAztecCode.m b/ZXingObjC/aztec/encoder/ZXAztecCode.m
new file mode 100644
index 0000000..c7054d5
--- /dev/null
+++ b/ZXingObjC/aztec/encoder/ZXAztecCode.m
@@ -0,0 +1,21 @@
+/*
+ * 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 "ZXAztecCode.h"
+
+@implementation ZXAztecCode
+
+@end
diff --git a/ZXingObjC/aztec/encoder/ZXAztecEncoder.h b/ZXingObjC/aztec/encoder/ZXAztecEncoder.h
new file mode 100644
index 0000000..9825d88
--- /dev/null
+++ b/ZXingObjC/aztec/encoder/ZXAztecEncoder.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+extern int ZX_DEFAULT_AZTEC_EC_PERCENT;
+
+@class ZXAztecCode, ZXBitArray, ZXGenericGF;
+
+@interface ZXAztecEncoder : NSObject
+
++ (ZXAztecCode *)encode:(int8_t *)data len:(int)len;
++ (ZXAztecCode *)encode:(int8_t *)data len:(int)len minECCPercent:(int)minECCPercent;
++ (void)drawBullsEye:(ZXBitMatrix *)matrix center:(int)center size:(int)size;
++ (ZXBitArray *)generateModeMessageCompact:(BOOL)compact layers:(int)layers messageSizeInWords:(int)messageSizeInWords;
++ (void)drawModeMessage:(ZXBitMatrix *)matrix compact:(BOOL)compact matrixSize:(int)matrixSize modeMessage:(ZXBitArray *)modeMessage;
++ (ZXBitArray *)generateCheckWords:(ZXBitArray *)stuffedBits totalSymbolBits:(int)totalSymbolBits wordSize:(int)wordSize;
++ (void)bitsToWords:(ZXBitArray *)stuffedBits wordSize:(int)wordSize totalWords:(int)totalWords message:(int *)message;
++ (ZXGenericGF *)getGF:(int)wordSize;
++ (ZXBitArray *)stuffBits:(ZXBitArray *)bits wordSize:(int)wordSize;
++ (ZXBitArray *)highLevelEncode:(int8_t *)data len:(int)len;
++ (void)outputWord:(ZXBitArray *)bits mode:(int)mode value:(int)value;
+
+@end
diff --git a/ZXingObjC/aztec/encoder/ZXAztecEncoder.m b/ZXingObjC/aztec/encoder/ZXAztecEncoder.m
new file mode 100644
index 0000000..cb248df
--- /dev/null
+++ b/ZXingObjC/aztec/encoder/ZXAztecEncoder.m
@@ -0,0 +1,595 @@
+/*
+ * 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 "ZXAztecCode.h"
+#import "ZXAztecEncoder.h"
+#import "ZXBitArray.h"
+#import "ZXBitMatrix.h"
+#import "ZXGenericGF.h"
+#import "ZXReedSolomonEncoder.h"
+
+int ZX_DEFAULT_AZTEC_EC_PERCENT = 33;
+
+const int TABLE_UPPER = 0; // 5 bits
+const int TABLE_LOWER = 1; // 5 bits
+const int TABLE_DIGIT = 2; // 4 bits
+const int TABLE_MIXED = 3; // 5 bits
+const int TABLE_PUNCT = 4; // 5 bits
+const int TABLE_BINARY = 5; // 8 bits
+
+static int CHAR_MAP[5][256]; // reverse mapping ASCII -> table offset, per table
+static int SHIFT_TABLE[6][6]; // mode shift codes, per table
+static int LATCH_TABLE[6][6]; // mode latch codes, per table
+
+const int NB_BITS_LEN = 33;
+static int NB_BITS[NB_BITS_LEN]; // total bits per compact symbol for a given number of layers
+
+const int NB_BITS_COMPACT_LEN = 5;
+static int NB_BITS_COMPACT[NB_BITS_COMPACT_LEN]; // total bits per full symbol for a given number of layers
+
+static int WORD_SIZE[33] = {
+ 4, 6, 6, 8, 8, 8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
+};
+
+@implementation ZXAztecEncoder
+
++ (void)initialize {
+ CHAR_MAP[TABLE_UPPER][' '] = 1;
+ for (int c = 'A'; c <= 'Z'; c++) {
+ CHAR_MAP[TABLE_UPPER][c] = c - 'A' + 2;
+ }
+ CHAR_MAP[TABLE_LOWER][' '] = 1;
+ for (int c = 'a'; c <= 'z'; c++) {
+ CHAR_MAP[TABLE_LOWER][c] = c - 'a' + 2;
+ }
+ CHAR_MAP[TABLE_DIGIT][' '] = 1;
+ for (int c = '0'; c <= '9'; c++) {
+ CHAR_MAP[TABLE_DIGIT][c] = c - '0' + 2;
+ }
+ CHAR_MAP[TABLE_DIGIT][','] = 12;
+ CHAR_MAP[TABLE_DIGIT]['.'] = 13;
+
+ const int mixedTableLen = 28;
+ int mixedTable[mixedTableLen] = {
+ '\0', ' ', '\1', '\2', '\3', '\4', '\5', '\6', '\7', '\b', '\t', '\n', '\13', '\f', '\r',
+ '\33', '\34', '\35', '\36', '\37', '@', '\\', '^', '_', '`', '|', '~', '\177'
+ };
+ for (int i = 0; i < 28; i++) {
+ CHAR_MAP[TABLE_MIXED][mixedTable[i]] = i;
+ }
+ const int punctTableLen = 31;
+ int punctTable[punctTableLen] = {
+ '\0', '\r', '\0', '\0', '\0', '\0', '!', '\'', '#', '$', '%', '&', '\'', '(', ')', '*', '+',
+ ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '[', ']', '{', '}'
+ };
+ for (int i = 0; i < punctTableLen; i++) {
+ if (punctTable[i] > 0) {
+ CHAR_MAP[TABLE_PUNCT][punctTable[i]] = i;
+ }
+ }
+ for (int i = 0; i < 6; i++) {
+ for (int j = 0; j < 6; j++) {
+ SHIFT_TABLE[i][j] = -1;
+ LATCH_TABLE[i][j] = -1;
+ }
+ }
+ SHIFT_TABLE[TABLE_UPPER][TABLE_PUNCT] = 0;
+ LATCH_TABLE[TABLE_UPPER][TABLE_LOWER] = 28;
+ LATCH_TABLE[TABLE_UPPER][TABLE_MIXED] = 29;
+ LATCH_TABLE[TABLE_UPPER][TABLE_DIGIT] = 30;
+ SHIFT_TABLE[TABLE_UPPER][TABLE_BINARY] = 31;
+ SHIFT_TABLE[TABLE_LOWER][TABLE_PUNCT] = 0;
+ SHIFT_TABLE[TABLE_LOWER][TABLE_UPPER] = 28;
+ LATCH_TABLE[TABLE_LOWER][TABLE_MIXED] = 29;
+ LATCH_TABLE[TABLE_LOWER][TABLE_DIGIT] = 30;
+ SHIFT_TABLE[TABLE_LOWER][TABLE_BINARY] = 31;
+ SHIFT_TABLE[TABLE_MIXED][TABLE_PUNCT] = 0;
+ LATCH_TABLE[TABLE_MIXED][TABLE_LOWER] = 28;
+ LATCH_TABLE[TABLE_MIXED][TABLE_UPPER] = 29;
+ LATCH_TABLE[TABLE_MIXED][TABLE_PUNCT] = 30;
+ SHIFT_TABLE[TABLE_MIXED][TABLE_BINARY] = 31;
+ LATCH_TABLE[TABLE_PUNCT][TABLE_UPPER] = 31;
+ SHIFT_TABLE[TABLE_DIGIT][TABLE_PUNCT] = 0;
+ LATCH_TABLE[TABLE_DIGIT][TABLE_UPPER] = 30;
+ SHIFT_TABLE[TABLE_DIGIT][TABLE_UPPER] = 31;
+ for (int i = 1; i < NB_BITS_COMPACT_LEN; i++) {
+ NB_BITS_COMPACT[i] = (88 + 16 * i) * i;
+ }
+ for (int i = 1; i < NB_BITS_LEN; i++) {
+ NB_BITS[i] = (112 + 16 * i) * i;
+ }
+}
+
+/**
+ * Encodes the given binary content as an Aztec symbol
+ */
++ (ZXAztecCode *)encode:(int8_t *)data len:(int)len {
+ return [self encode:data len:len minECCPercent:ZX_DEFAULT_AZTEC_EC_PERCENT];
+}
+
+/**
+ * Encodes the given binary content as an Aztec symbol
+ */
++ (ZXAztecCode *)encode:(int8_t *)data len:(int)len minECCPercent:(int)minECCPercent {
+ // High-level encode
+ ZXBitArray *bits = [self highLevelEncode:data len:len];
+
+ // stuff bits and choose symbol size
+ int eccBits = bits.size * minECCPercent / 100 + 11;
+ int totalSizeBits = bits.size + eccBits;
+ int layers;
+ int wordSize = 0;
+ int totalSymbolBits = 0;
+ ZXBitArray *stuffedBits = nil;
+ for (layers = 1; layers < NB_BITS_COMPACT_LEN; layers++) {
+ if (NB_BITS_COMPACT[layers] >= totalSizeBits) {
+ if (wordSize != WORD_SIZE[layers]) {
+ wordSize = WORD_SIZE[layers];
+ stuffedBits = [self stuffBits:bits wordSize:wordSize];
+ }
+ totalSymbolBits = NB_BITS_COMPACT[layers];
+ if (stuffedBits.size + eccBits <= NB_BITS_COMPACT[layers]) {
+ break;
+ }
+ }
+ }
+ BOOL compact = YES;
+ if (layers == NB_BITS_COMPACT_LEN) {
+ compact = false;
+ for (layers = 1; layers < NB_BITS_LEN; layers++) {
+ if (NB_BITS[layers] >= totalSizeBits) {
+ if (wordSize != WORD_SIZE[layers]) {
+ wordSize = WORD_SIZE[layers];
+ stuffedBits = [self stuffBits:bits wordSize:wordSize];
+ }
+ totalSymbolBits = NB_BITS[layers];
+ if (stuffedBits.size + eccBits <= NB_BITS[layers]) {
+ break;
+ }
+ }
+ }
+ }
+ if (layers == NB_BITS_LEN || wordSize == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Data too large for an Aztec code"];
+ }
+
+ // pad the end
+ int messageSizeInWords = (stuffedBits.size + wordSize - 1) / wordSize;
+ // This seems to be redundant?
+ /*
+ for (int i = messageSizeInWords * wordSize - stuffedBits.size; i > 0; i--) {
+ [stuffedBits appendBit:YES];
+ }
+ */
+
+ // generate check words
+ ZXReedSolomonEncoder *rs = [[ZXReedSolomonEncoder alloc] initWithField:[self getGF:wordSize]];
+ int totalSizeInFullWords = totalSymbolBits / wordSize;
+
+ int messageWords[totalSizeInFullWords];
+ [self bitsToWords:stuffedBits wordSize:wordSize totalWords:totalSizeInFullWords message:messageWords];
+ [rs encode:messageWords toEncodeLen:totalSizeInFullWords ecBytes:totalSizeInFullWords - messageSizeInWords];
+
+ // convert to bit array and pad in the beginning
+ int startPad = totalSymbolBits % wordSize;
+ ZXBitArray *messageBits = [[ZXBitArray alloc] init];
+ [messageBits appendBits:0 numBits:startPad];
+ for (int i = 0; i < totalSizeInFullWords; i++) {
+ [messageBits appendBits:messageWords[i] numBits:wordSize];
+ }
+
+ // generate mode message
+ ZXBitArray *modeMessage = [self generateModeMessageCompact:compact layers:layers messageSizeInWords:messageSizeInWords];
+
+ // allocate symbol
+ int baseMatrixSize = compact ? 11 + layers * 4 : 14 + layers * 4; // not including alignment lines
+ int alignmentMap[baseMatrixSize];
+ int matrixSize;
+ if (compact) {
+ // no alignment marks in compact mode, alignmentMap is a no-op
+ matrixSize = baseMatrixSize;
+ for (int i = 0; i < baseMatrixSize; i++) {
+ alignmentMap[i] = i;
+ }
+ } else {
+ matrixSize = baseMatrixSize + 1 + 2 * ((baseMatrixSize / 2 - 1) / 15);
+ int origCenter = baseMatrixSize / 2;
+ int center = matrixSize / 2;
+ for (int i = 0; i < origCenter; i++) {
+ int newOffset = i + i / 15;
+ alignmentMap[origCenter - i - 1] = center - newOffset - 1;
+ alignmentMap[origCenter + i] = center + newOffset + 1;
+ }
+ }
+ ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithDimension:matrixSize];
+
+ // draw mode and data bits
+ for (int i = 0, rowOffset = 0; i < layers; i++) {
+ int rowSize = compact ? (layers - i) * 4 + 9 : (layers - i) * 4 + 12;
+ for (int j = 0; j < rowSize; j++) {
+ int columnOffset = j * 2;
+ for (int k = 0; k < 2; k++) {
+ if ([messageBits get:rowOffset + columnOffset + k]) {
+ [matrix setX:alignmentMap[i * 2 + k] y:alignmentMap[i * 2 + j]];
+ }
+ if ([messageBits get:rowOffset + rowSize * 2 + columnOffset + k]) {
+ [matrix setX:alignmentMap[i * 2 + j] y:alignmentMap[baseMatrixSize - 1 - i * 2 - k]];
+ }
+ if ([messageBits get:rowOffset + rowSize * 4 + columnOffset + k]) {
+ [matrix setX:alignmentMap[baseMatrixSize - 1 - i * 2 - k] y:alignmentMap[baseMatrixSize - 1 - i * 2 - j]];
+ }
+ if ([messageBits get:rowOffset + rowSize * 6 + columnOffset + k]) {
+ [matrix setX:alignmentMap[baseMatrixSize - 1 - i * 2 - j] y:alignmentMap[i * 2 + k]];
+ }
+ }
+ }
+ rowOffset += rowSize * 8;
+ }
+ [self drawModeMessage:matrix compact:compact matrixSize:matrixSize modeMessage:modeMessage];
+
+ // draw alignment marks
+ if (compact) {
+ [self drawBullsEye:matrix center:matrixSize / 2 size:5];
+ } else {
+ [self drawBullsEye:matrix center:matrixSize / 2 size:7];
+ for (int i = 0, j = 0; i < baseMatrixSize / 2 - 1; i += 15, j += 16) {
+ for (int k = (matrixSize / 2) & 1; k < matrixSize; k += 2) {
+ [matrix setX:matrixSize / 2 - j y:k];
+ [matrix setX:matrixSize / 2 + j y:k];
+ [matrix setX:k y:matrixSize / 2 - j];
+ [matrix setX:k y:matrixSize / 2 + j];
+ }
+ }
+ }
+
+ ZXAztecCode *aztec = [[ZXAztecCode alloc] init];
+ aztec.compact = compact;
+ aztec.size = matrixSize;
+ aztec.layers = layers;
+ aztec.codeWords = messageSizeInWords;
+ aztec.matrix = matrix;
+ return aztec;
+}
+
++ (void)drawBullsEye:(ZXBitMatrix *)matrix center:(int)center size:(int)size {
+ for (int i = 0; i < size; i += 2) {
+ for (int j = center - i; j <= center + i; j++) {
+ [matrix setX:j y:center - i];
+ [matrix setX:j y:center + i];
+ [matrix setX:center - i y:j];
+ [matrix setX:center + i y:j];
+ }
+ }
+ [matrix setX:center - size y:center - size];
+ [matrix setX:center - size + 1 y:center - size];
+ [matrix setX:center - size y:center - size + 1];
+ [matrix setX:center + size y:center - size];
+ [matrix setX:center + size y:center - size + 1];
+ [matrix setX:center + size y:center + size - 1];
+}
+
++ (ZXBitArray *)generateModeMessageCompact:(BOOL)compact layers:(int)layers messageSizeInWords:(int)messageSizeInWords {
+ ZXBitArray *modeMessage = [[ZXBitArray alloc] init];
+ if (compact) {
+ [modeMessage appendBits:layers - 1 numBits:2];
+ [modeMessage appendBits:messageSizeInWords - 1 numBits:6];
+ modeMessage = [self generateCheckWords:modeMessage totalSymbolBits:28 wordSize:4];
+ } else {
+ [modeMessage appendBits:layers - 1 numBits:5];
+ [modeMessage appendBits:messageSizeInWords - 1 numBits:11];
+ modeMessage = [self generateCheckWords:modeMessage totalSymbolBits:40 wordSize:4];
+ }
+ return modeMessage;
+}
+
++ (void)drawModeMessage:(ZXBitMatrix *)matrix compact:(BOOL)compact matrixSize:(int)matrixSize modeMessage:(ZXBitArray *)modeMessage {
+ if (compact) {
+ for (int i = 0; i < 7; i++) {
+ if ([modeMessage get:i]) {
+ [matrix setX:matrixSize / 2 - 3 + i y:matrixSize / 2 - 5];
+ }
+ if ([modeMessage get:i + 7]) {
+ [matrix setX:matrixSize / 2 + 5 y:matrixSize / 2 - 3 + i];
+ }
+ if ([modeMessage get:20 - i]) {
+ [matrix setX:matrixSize / 2 - 3 + i y:matrixSize / 2 + 5];
+ }
+ if ([modeMessage get:27 - i]) {
+ [matrix setX:matrixSize / 2 - 5 y:matrixSize / 2 - 3 + i];
+ }
+ }
+ } else {
+ for (int i = 0; i < 10; i++) {
+ if ([modeMessage get:i]) {
+ [matrix setX:matrixSize / 2 - 5 + i + i / 5 y:matrixSize / 2 - 7];
+ }
+ if ([modeMessage get:i + 10]) {
+ [matrix setX:matrixSize / 2 + 7 y:matrixSize / 2 - 5 + i + i / 5];
+ }
+ if ([modeMessage get:29 - i]) {
+ [matrix setX:matrixSize / 2 - 5 + i + i / 5 y:matrixSize / 2 + 7];
+ }
+ if ([modeMessage get:39 - i]) {
+ [matrix setX:matrixSize / 2 - 7 y:matrixSize / 2 - 5 + i + i / 5];
+ }
+ }
+ }
+}
+
++ (ZXBitArray *)generateCheckWords:(ZXBitArray *)stuffedBits totalSymbolBits:(int)totalSymbolBits wordSize:(int)wordSize {
+ int messageSizeInWords = (stuffedBits.size + wordSize - 1) / wordSize;
+ for (int i = messageSizeInWords * wordSize - stuffedBits.size; i > 0; i--) {
+ [stuffedBits appendBit:YES];
+ }
+ ZXReedSolomonEncoder *rs = [[ZXReedSolomonEncoder alloc] initWithField:[self getGF:wordSize]];
+ int totalSizeInFullWords = totalSymbolBits / wordSize;
+
+ int messageWords[totalSizeInFullWords];
+ [self bitsToWords:stuffedBits wordSize:wordSize totalWords:totalSizeInFullWords message:messageWords];
+
+ [rs encode:messageWords toEncodeLen:totalSizeInFullWords ecBytes:totalSizeInFullWords - messageSizeInWords];
+ int startPad = totalSymbolBits % wordSize;
+ ZXBitArray *messageBits = [[ZXBitArray alloc] init];
+ [messageBits appendBits:0 numBits:startPad];
+ for (int i = 0; i < totalSizeInFullWords; i++) {
+ [messageBits appendBits:messageWords[i] numBits:wordSize];
+ }
+ return messageBits;
+}
+
++ (void)bitsToWords:(ZXBitArray *)stuffedBits wordSize:(int)wordSize totalWords:(int)totalWords message:(int *)message {
+ int i;
+ int n;
+ for (i = 0, n = stuffedBits.size / wordSize; i < n; i++) {
+ int value = 0;
+ for (int j = 0; j < wordSize; j++) {
+ value |= [stuffedBits get:i * wordSize + j] ? (1 << (wordSize - j - 1)) : 0;
+ }
+ message[i] = value;
+ }
+}
+
++ (ZXGenericGF *)getGF:(int)wordSize {
+ switch (wordSize) {
+ case 4:
+ return [ZXGenericGF AztecParam];
+ case 6:
+ return [ZXGenericGF AztecData6];
+ case 8:
+ return [ZXGenericGF AztecData8];
+ case 10:
+ return [ZXGenericGF AztecData10];
+ case 12:
+ return [ZXGenericGF AztecData12];
+ default:
+ return nil;
+ }
+}
+
++ (ZXBitArray *)stuffBits:(ZXBitArray *)bits wordSize:(int)wordSize {
+ ZXBitArray *arrayOut = [[ZXBitArray alloc] init];
+
+ // 1. stuff the bits
+ int n = bits.size;
+ int mask = (1 << wordSize) - 2;
+ for (int i = 0; i < n; i += wordSize) {
+ int word = 0;
+ for (int j = 0; j < wordSize; j++) {
+ if (i + j >= n || [bits get:i + j]) {
+ word |= 1 << (wordSize - 1 - j);
+ }
+ }
+ if ((word & mask) == mask) {
+ [arrayOut appendBits:word & mask numBits:wordSize];
+ i--;
+ } else if ((word & mask) == 0) {
+ [arrayOut appendBits:word | 1 numBits:wordSize];
+ i--;
+ } else {
+ [arrayOut appendBits:word numBits:wordSize];
+ }
+ }
+
+ // 2. pad last word to wordSize
+ // This seems to be redundant?
+ /*
+ n = arrayOut.size;
+ int remainder = n % wordSize;
+ if (remainder != 0) {
+ int j = 1;
+ for (int i = 0; i < remainder; i++) {
+ if (![arrayOut get:n - 1 - i]) {
+ j = 0;
+ }
+ }
+ for (int i = remainder; i < wordSize - 1; i++) {
+ [arrayOut appendBit:YES];
+ }
+ [arrayOut appendBit:j == 0];
+ }
+ */
+ return arrayOut;
+}
+
++ (ZXBitArray *)highLevelEncode:(int8_t *)data len:(int)len {
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ int mode = TABLE_UPPER;
+ int idx[5] = {0, 0, 0, 0, 0};
+ int idxnext[5] = {0, 0, 0, 0, 0};
+
+ for (int i = 0; i < len; i++) {
+ int c = data[i] & 0xFF;
+ int next = i < len - 1 ? data[i + 1] & 0xFF : 0;
+ int punctWord = 0;
+ // special case: double-character codes
+ if (c == '\r' && next == '\n') {
+ punctWord = 2;
+ } else if (c == '.' && next == ' ') {
+ punctWord = 3;
+ } else if (c == ',' && next == ' ') {
+ punctWord = 4;
+ } else if (c == ':' && next == ' ') {
+ punctWord = 5;
+ }
+ if (punctWord > 0) {
+ if (mode == TABLE_PUNCT) {
+ [self outputWord:bits mode:TABLE_PUNCT value:punctWord];
+ i++;
+ continue;
+ } else if (SHIFT_TABLE[mode][TABLE_PUNCT] >= 0) {
+ [self outputWord:bits mode:mode value:SHIFT_TABLE[mode][TABLE_PUNCT]];
+ [self outputWord:bits mode:TABLE_PUNCT value:punctWord];
+ i++;
+ continue;
+ } else if (LATCH_TABLE[mode][TABLE_PUNCT] >= 0) {
+ [self outputWord:bits mode:mode value:LATCH_TABLE[mode][TABLE_PUNCT]];
+ [self outputWord:bits mode:TABLE_PUNCT value:punctWord];
+ mode = TABLE_PUNCT;
+ i++;
+ continue;
+ }
+ }
+ // find the best matching table, taking current mode and next character into account
+ int firstMatch = -1;
+ int shiftMode = -1;
+ int latchMode = -1;
+ int j;
+ for (j = 0; j < TABLE_BINARY; j++) {
+ idx[j] = CHAR_MAP[j][c];
+ if (idx[j] > 0 && firstMatch < 0) {
+ firstMatch = j;
+ }
+ if (shiftMode < 0 && idx[j] > 0 && SHIFT_TABLE[mode][j] >= 0) {
+ shiftMode = j;
+ }
+ idxnext[j] = CHAR_MAP[j][next];
+ if (latchMode < 0 && idx[j] > 0 && (next == 0 || idxnext[j] > 0) && LATCH_TABLE[mode][j] >= 0) {
+ latchMode = j;
+ }
+ }
+ if (shiftMode < 0 && latchMode < 0) {
+ for (j = 0; j < TABLE_BINARY; j++) {
+ if (idx[j] > 0 && LATCH_TABLE[mode][j] >= 0) {
+ latchMode = j;
+ break;
+ }
+ }
+ }
+ if (idx[mode] > 0) {
+ // found character in current table - stay in current table
+ [self outputWord:bits mode:mode value:idx[mode]];
+ } else {
+ if (latchMode >= 0) {
+ // latch into mode latchMode
+ [self outputWord:bits mode:mode value:LATCH_TABLE[mode][latchMode]];
+ [self outputWord:bits mode:latchMode value:idx[latchMode]];
+ mode = latchMode;
+ } else if (shiftMode >= 0) {
+ // shift into shiftMode
+ [self outputWord:bits mode:mode value:SHIFT_TABLE[mode][shiftMode]];
+ [self outputWord:bits mode:shiftMode value:idx[shiftMode]];
+ } else {
+ if (firstMatch >= 0) {
+ // can't switch into this mode from current mode - switch in two steps
+ if (mode == TABLE_PUNCT) {
+ [self outputWord:bits mode:TABLE_PUNCT value:LATCH_TABLE[TABLE_PUNCT][TABLE_UPPER]];
+ mode = TABLE_UPPER;
+ i--;
+ continue;
+ } else if (mode == TABLE_DIGIT) {
+ [self outputWord:bits mode:TABLE_DIGIT value:LATCH_TABLE[TABLE_DIGIT][TABLE_UPPER]];
+ mode = TABLE_UPPER;
+ i--;
+ continue;
+ }
+ }
+ // use binary table
+ // find the binary string length
+ int k;
+ int lookahead;
+ for (k = i + 1, lookahead = 0; k < len; k++) {
+ next = data[k] & 0xFF;
+ BOOL binary = YES;
+ for (j = 0; j < TABLE_BINARY; j++) {
+ if (CHAR_MAP[j][next] > 0) {
+ binary = NO;
+ break;
+ }
+ }
+ if (binary) {
+ lookahead = 0;
+ } else {
+ // skip over single character in between binary bytes
+ if (lookahead >= 1) {
+ k -= lookahead;
+ break;
+ }
+ lookahead++;
+ }
+ }
+ k -= i;
+ // switch into binary table
+ switch (mode) {
+ case TABLE_UPPER:
+ case TABLE_LOWER:
+ case TABLE_MIXED:
+ [self outputWord:bits mode:mode value:SHIFT_TABLE[mode][TABLE_BINARY]];
+ break;
+ case TABLE_DIGIT:
+ [self outputWord:bits mode:mode value:LATCH_TABLE[mode][TABLE_UPPER]];
+ mode = TABLE_UPPER;
+ [self outputWord:bits mode:mode value:SHIFT_TABLE[mode][TABLE_BINARY]];
+ break;
+ case TABLE_PUNCT:
+ [self outputWord:bits mode:mode value:LATCH_TABLE[mode][TABLE_UPPER]];
+ mode = TABLE_UPPER;
+ [self outputWord:bits mode:mode value:SHIFT_TABLE[mode][TABLE_BINARY]];
+ break;
+ }
+ if (k >= 32 && k < 63) { // optimization: split one long form into two short forms, saves 1 bit
+ k = 31;
+ }
+ if (k > 542) { // maximum encodable binary length in long form is 511 + 31
+ k = 542;
+ }
+ if (k < 32) {
+ [bits appendBits:k numBits:5];
+ } else {
+ [bits appendBits:k - 31 numBits:16];
+ }
+ for (; k > 0; k--, i++) {
+ [bits appendBits:data[i] numBits:8];
+ }
+ i--;
+ }
+ }
+ }
+ return bits;
+
+}
+
++ (void)outputWord:(ZXBitArray *)bits mode:(int)mode value:(int)value {
+ if (mode == TABLE_DIGIT) {
+ [bits appendBits:value numBits:4];
+ } else if (mode < TABLE_BINARY) {
+ [bits appendBits:value numBits:5];
+ } else {
+ [bits appendBits:value numBits:8];
+ }
+}
+
+@end
diff --git a/ZXingObjC/client/ZXCGImageLuminanceSource.h b/ZXingObjC/client/ZXCGImageLuminanceSource.h
new file mode 100644
index 0000000..7627431
--- /dev/null
+++ b/ZXingObjC/client/ZXCGImageLuminanceSource.h
@@ -0,0 +1,62 @@
+/*
+ * 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 <CoreVideo/CoreVideo.h>
+#import "ZXLuminanceSource.h"
+
+@class ZXImage;
+
+@interface ZXCGImageLuminanceSource : ZXLuminanceSource {
+ CGImageRef _image;
+ int8_t *_data;
+ size_t _left;
+ size_t _top;
+}
+
++ (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer CF_RETURNS_RETAINED;
++ (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer
+ left:(size_t)left
+ top:(size_t)top
+ width:(size_t)width
+ height:(size_t)height CF_RETURNS_RETAINED;
+
+- (id)initWithZXImage:(ZXImage *)image
+ left:(size_t)left
+ top:(size_t)top
+ width:(size_t)width
+ height:(size_t)height;
+
+- (id)initWithZXImage:(ZXImage *)image;
+
+- (id)initWithCGImage:(CGImageRef)image
+ left:(size_t)left
+ top:(size_t)top
+ width:(size_t)width
+ height:(size_t)height;
+
+- (id)initWithCGImage:(CGImageRef)image;
+
+- (id)initWithBuffer:(CVPixelBufferRef)buffer
+ left:(size_t)left
+ top:(size_t)top
+ width:(size_t)width
+ height:(size_t)height;
+
+- (id)initWithBuffer:(CVPixelBufferRef)buffer;
+
+- (CGImageRef)image;
+
+@end
diff --git a/ZXingObjC/client/ZXCGImageLuminanceSource.m b/ZXingObjC/client/ZXCGImageLuminanceSource.m
new file mode 100644
index 0000000..5980325
--- /dev/null
+++ b/ZXingObjC/client/ZXCGImageLuminanceSource.m
@@ -0,0 +1,283 @@
+/*
+ * 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 <CoreVideo/CoreVideo.h>
+#import "ZXCGImageLuminanceSource.h"
+#import "ZXImage.h"
+
+@implementation ZXCGImageLuminanceSource
+
++ (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer CF_RETURNS_RETAINED {
+ return [self createImageFromBuffer:buffer
+ left:0
+ top:0
+ width:CVPixelBufferGetWidth(buffer)
+ height:CVPixelBufferGetHeight(buffer)];
+}
+
++ (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer
+ left:(size_t)left
+ top:(size_t)top
+ width:(size_t)width
+ height:(size_t)height CF_RETURNS_RETAINED {
+ 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) {
+ memcpy(bytes, baseAddress+top*bytesPerRow, size * sizeof(int8_t));
+ } else {
+ for(int y=0; y<height; y++) {
+ memcpy(bytes+y*newBytesPerRow,
+ baseAddress+left*4+(top+y)*bytesPerRow,
+ newBytesPerRow * sizeof(int8_t));
+ }
+ }
+ CVPixelBufferUnlockBaseAddress(buffer, 0);
+
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef newContext = CGBitmapContextCreate(bytes,
+ width,
+ height,
+ 8,
+ newBytesPerRow,
+ colorSpace,
+ kCGBitmapByteOrder32Little|
+ kCGImageAlphaNoneSkipFirst);
+ CGColorSpaceRelease(colorSpace);
+
+ CGImageRef result = CGBitmapContextCreateImage(newContext);
+
+ CGContextRelease(newContext);
+
+ free(bytes);
+
+ return result;
+}
+
+- (id)initWithZXImage:(ZXImage *)image
+ left:(size_t)left
+ top:(size_t)top
+ width:(size_t)width
+ height:(size_t)height {
+ return [self initWithCGImage:image.cgimage left:left top:top width:width height:height];
+}
+
+- (id)initWithZXImage:(ZXImage *)image {
+ return [self initWithCGImage:image.cgimage];
+}
+
+- (id)initWithCGImage:(CGImageRef)image
+ left:(size_t)left
+ top:(size_t)top
+ width:(size_t)width
+ height:(size_t)height {
+ if (self = [super initWithWidth:(int)width height:(int)height]) {
+ [self initializeWithImage:image left:left top:top width:width height:height];
+ }
+
+ return self;
+}
+
+- (id)initWithCGImage:(CGImageRef)image {
+ return [self initWithCGImage:image left:0 top:0 width:CGImageGetWidth(image) height:CGImageGetHeight(image)];
+}
+
+- (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;
+}
+
+- (CGImageRef)image {
+ return _image;
+}
+
+- (void)dealloc {
+ if (_image) {
+ CGImageRelease(_image);
+ }
+ if (_data) {
+ free(_data);
+ }
+}
+
+- (int8_t *)row:(int)y {
+ if (y < 0 || y >= self.height) {
+ [NSException raise:NSInvalidArgumentException format:@"Requested row is outside the image: %d", y];
+ }
+
+ int8_t *row = (int8_t *)malloc(self.width * sizeof(int8_t));
+
+ int offset = y * self.width;
+ memcpy(row, _data + offset, self.width);
+ return row;
+}
+
+- (int8_t *)matrix {
+ int area = self.width * self.height;
+
+ int8_t *result = (int8_t *)malloc(area * sizeof(int8_t));
+ memcpy(result, _data, area * sizeof(int8_t));
+ return result;
+}
+
+- (void)initializeWithImage:(CGImageRef)cgimage left:(size_t)left top:(size_t)top width:(size_t)width height:(size_t)height {
+ _data = 0;
+ _image = CGImageRetain(cgimage);
+ _left = left;
+ _top = top;
+ size_t sourceWidth = CGImageGetWidth(cgimage);
+ size_t sourceHeight = CGImageGetHeight(cgimage);
+
+ if (left + self.width > sourceWidth ||
+ top + self.height > sourceHeight) {
+ [NSException raise:NSInvalidArgumentException format:@"Crop rectangle does not fit within image data."];
+ }
+
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(0, self.width, self.height, 8, self.width * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
+ CGContextSetAllowsAntialiasing(context, FALSE);
+ CGContextSetInterpolationQuality(context, kCGInterpolationNone);
+
+ if (top || left) {
+ CGContextClipToRect(context, CGRectMake(0, 0, self.width, self.height));
+ }
+
+ CGContextDrawImage(context, CGRectMake(-left, -top, self.width, self.height), self.image);
+
+ uint32_t *pixelData = (uint32_t *) malloc(self.width * self.height * sizeof(uint32_t));
+ memcpy(pixelData, CGBitmapContextGetData(context), self.width * self.height * sizeof(uint32_t));
+ CGContextRelease(context);
+ CGColorSpaceRelease(colorSpace);
+
+ _data = (int8_t *)malloc(self.width * self.height * sizeof(int8_t));
+
+ for (int i = 0; i < self.height * self.width; i++) {
+ uint32_t rgbPixel=pixelData[i];
+
+ float red = (rgbPixel>>24)&0xFF;
+ float green = (rgbPixel>>16)&0xFF;
+ float blue = (rgbPixel>>8)&0xFF;
+ float alpha = (float)(rgbPixel & 0xFF) / 255.0f;
+
+ // ImageIO premultiplies all PNGs, so we have to "un-premultiply them":
+ // http://code.google.com/p/cocos2d-iphone/issues/detail?id=697#c26
+ red = round((red / alpha) - 0.001f);
+ green = round((green / alpha) - 0.001f);
+ blue = round((blue / alpha) - 0.001f);
+
+ if (red == green && green == blue) {
+ _data[i] = red;
+ } else {
+ _data[i] = (306 * (int)red +
+ 601 * (int)green +
+ 117 * (int)blue +
+ (0x200)) >> 10; // 0x200 = 1<<9, half an lsb of the result to force rounding
+ }
+ }
+
+ free(pixelData);
+
+ _top = top;
+ _left = left;
+}
+
+- (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,
+ rotatedRect.size.height,
+ CGImageGetBitsPerComponent(self.image),
+ 0,
+ colorSpace,
+ kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedFirst);
+ 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:_top top:sourceWidth - (_left + self.width) width:self.height height:self.width];
+
+ CGImageRelease(rotatedImage);
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/client/ZXCapture.h b/ZXingObjC/client/ZXCapture.h
new file mode 100644
index 0000000..d950941
--- /dev/null
+++ b/ZXingObjC/client/ZXCapture.h
@@ -0,0 +1,166 @@
+/*
+ * 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 <QuartzCore/QuartzCore.h>
+#import "ZXCaptureDelegate.h"
+
+@protocol ZXReader;
+@class ZXDecodeHints;
+
+#if !TARGET_IPHONE_SIMULATOR
+#if TARGET_OS_EMBEDDED
+#include <AVFoundation/AVFoundation.h>
+#define ZX(x) x
+#define ZXAV(x) x
+#define ZXAVC(x) ,x
+#define ZXQT(x)
+#define ZXCaptureSession AVCaptureSession
+#define ZXCaptureVideoPreviewLayer AVCaptureVideoPreviewLayer
+#define ZXCaptureDevice AVCaptureDevice
+#define ZXCaptureDeviceInput AVCaptureDeviceInput
+#define ZXCaptureVideoOutput AVCaptureVideoDataOutput
+#else
+#import <QTKit/QTKit.h>
+#define ZX(x) x
+#define ZXAV(x)
+#define ZXAVC(x)
+#define ZXQT(x) x
+#define ZXCaptureSession QTCaptureSession
+#define ZXCaptureVideoPreviewLayer QTCaptureLayer
+#define ZXCaptureDevice QTCaptureDevice
+#define ZXCaptureDeviceInput QTCaptureDeviceInput
+#define ZXCaptureVideoOutput QTCaptureDecompressedVideoOutput
+#endif
+
+@interface ZXCapture
+ : NSObject
+ZX(<CAAction ZXAVC(AVCaptureVideoDataOutputSampleBufferDelegate)>) {
+ ZX(
+ ZXCaptureSession *session;
+ ZXCaptureVideoPreviewLayer *layer;
+ ZXCaptureDevice *capture_device;
+ ZXCaptureDeviceInput *input;
+ ZXCaptureVideoOutput *output;
+ )
+
+ int order_in_skip;
+ int order_out_skip;
+ BOOL running;
+ BOOL on_screen;
+ CALayer *luminance;
+ CALayer *binary;
+ size_t width;
+ size_t height;
+ size_t reported_width;
+ size_t reported_height;
+ NSString *captureToFilename;
+ BOOL hard_stop;
+ int camera;
+ BOOL torch;
+ BOOL mirror;
+ int capture_device_index;
+ CGAffineTransform transform;
+ BOOL cameraIsReady;
+}
+
+@property (nonatomic, weak) id<ZXCaptureDelegate> delegate;
+@property (nonatomic, copy) NSString *captureToFilename;
+@property (nonatomic) CGAffineTransform transform;
+@property (nonatomic, readonly) ZXCaptureVideoOutput *output;
+@property (nonatomic, readonly) CALayer *layer;
+@property (nonatomic, retain) ZXCaptureDevice *captureDevice;
+@property (nonatomic, assign) BOOL mirror;
+@property (nonatomic, readonly) BOOL running;
+@property (nonatomic, retain) id<ZXReader> reader;
+@property (nonatomic, retain) ZXDecodeHints *hints;
+@property (nonatomic, assign) CGFloat rotation;
+
+- (id)init;
+- (CALayer *)luminance;
+- (void)setLuminance:(BOOL)on_off;
+- (CALayer *)binary;
+- (void)setBinary:(BOOL)on_off;
+- (void)start;
+
+// Nest Labs addition:
+- (void)stopAndFreezeOutput:(BOOL)freezeOutput;
+
+- (void)stop;
+- (void)hard_stop;
+- (void)order_skip;
+
+@property (nonatomic, readonly) BOOL hasFront;
+@property (nonatomic, readonly) BOOL hasBack;
+@property (nonatomic, readonly) BOOL hasTorch;
+
+@property (nonatomic, readonly) int front;
+@property (nonatomic, readonly) int back;
+
+@property (nonatomic) int camera;
+@property (nonatomic) BOOL torch;
+
+@end
+
+#else
+
+@interface ZXCapture : NSObject {
+ // Nest Labs addition:
+ // Prevents compilation errors on simulator
+ BOOL running;
+}
+
+@property (nonatomic,weak) id<ZXCaptureDelegate> delegate;
+@property (nonatomic,copy) NSString *captureToFilename;
+@property (nonatomic) CGAffineTransform transform;
+@property (nonatomic, readonly) void *output;
+@property (weak, nonatomic, readonly) CALayer *layer;
+@property (nonatomic, strong) id<ZXReader> reader;
+@property (nonatomic, strong) ZXDecodeHints *hints;
+@property (nonatomic, assign) CGFloat rotation;
+
+- (id)init;
+- (CALayer *)luminance;
+- (void)setLuminance:(BOOL)on_off;
+- (CALayer *)binary;
+- (void)setBinary:(BOOL)on_off;
+- (void)start;
+- (void)stop;
+
+// Nest Labs addition:
+- (void)stopAndFreezeOutput:(BOOL)freezeOutput;
+
+- (void)hard_stop;
+- (void)order_skip;
+
+@property (nonatomic,readonly) BOOL hasFront;
+@property (nonatomic,readonly) BOOL hasBack;
+@property (nonatomic,readonly) BOOL hasTorch;
+
+@property (nonatomic,readonly) int front;
+@property (nonatomic,readonly) int back;
+
+@property (nonatomic) int camera;
+@property (nonatomic) BOOL torch;
+
+@property (nonatomic, assign) BOOL mirror;
+
+// Nest Labs addition:
+// Prevents compilation errors on simulator
+@property (nonatomic, readonly) BOOL running;
+
+@end
+
+#endif
diff --git a/ZXingObjC/client/ZXCapture.m b/ZXingObjC/client/ZXCapture.m
new file mode 100644
index 0000000..c8b4d93
--- /dev/null
+++ b/ZXingObjC/client/ZXCapture.m
@@ -0,0 +1,778 @@
+/*
+ * 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 "ZXCapture.h"
+
+#if !TARGET_IPHONE_SIMULATOR
+#include "ZXCGImageLuminanceSource.h"
+#include "ZXBinaryBitmap.h"
+#include "ZXDecodeHints.h"
+#include "ZXHybridBinarizer.h"
+#include "ZXMultiFormatReader.h"
+#include "ZXReader.h"
+#include "ZXResult.h"
+
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+#import <UIKit/UIKit.h>
+#define ZXCaptureOutput AVCaptureOutput
+#define ZXMediaTypeVideo AVMediaTypeVideo
+#define ZXCaptureConnection AVCaptureConnection
+#else
+#define ZXCaptureOutput QTCaptureOutput
+#define ZXCaptureConnection QTCaptureConnection
+#define ZXMediaTypeVideo QTMediaTypeVideo
+#endif
+
+#if ZXAV(1)+0
+static bool isIPad();
+#endif
+
+#if TARGET_OS_IPHONE
+# if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
+# define KS_DISPATCH_RELEASE(q) (dispatch_release(q))
+# endif
+#else
+# if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
+# define KS_DISPATCH_RELEASE(q) (dispatch_release(q))
+# endif
+#endif
+#ifndef KS_DISPATCH_RELEASE
+# define KS_DISPATCH_RELEASE(q)
+#endif
+
+@interface ZXCapture ()
+
+@property (nonatomic, strong) __attribute__((NSObject)) dispatch_queue_t captureQueue;
+
+@end
+
+@implementation ZXCapture
+
+@synthesize delegate;
+@synthesize captureToFilename;
+@synthesize transform;
+@synthesize rotation;
+@synthesize hints;
+
+// Adapted from http://blog.coriolis.ch/2009/09/04/arbitrary-rotation-of-a-cgimage/ and https://github.com/JanX2/CreateRotateWriteCGImage
+- (CGImageRef)createRotatedImage:(CGImageRef)original degrees:(float)degrees CF_RETURNS_RETAINED {
+ if (degrees == 0.0f) {
+ CGImageRetain(original);
+ 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,
+ rotatedRect.size.height,
+ CGImageGetBitsPerComponent(original),
+ 0,
+ colorSpace,
+ kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedFirst);
+ 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;
+ }
+}
+
+- (ZXCapture *)init {
+ if ((self = [super init])) {
+ on_screen = running = NO;
+ reported_width = 0;
+ reported_height = 0;
+ width = 1920;
+ height = 1080;
+ hard_stop = false;
+ capture_device = 0;
+ capture_device_index = -1;
+ order_in_skip = 0;
+ order_out_skip = 0;
+ transform = CGAffineTransformIdentity;
+ rotation = 0.0f;
+ ZXQT({
+ transform.a = -1;
+ });
+ self.reader = [ZXMultiFormatReader reader];
+ self.hints = [ZXDecodeHints hints];
+ _captureQueue = dispatch_queue_create("com.zxing.captureQueue", NULL);
+ }
+ return self;
+}
+
+- (BOOL)running {return running;}
+
+- (BOOL)mirror {
+ return mirror;
+}
+
+- (void)setMirror:(BOOL)mirror_ {
+ if (mirror != mirror_) {
+ mirror = mirror_;
+ if (layer) {
+ transform.a = -transform.a;
+ [layer setAffineTransform:transform];
+ }
+ }
+}
+
+- (void)order_skip {
+ order_out_skip = order_in_skip = 1;
+}
+
+- (ZXCaptureDevice *)device {
+ if (capture_device) {
+ return capture_device;
+ }
+
+ ZXCaptureDevice *zxd = nil;
+
+#if ZXAV(1)+0
+ NSArray *devices =
+ [ZXCaptureDevice
+ ZXAV(devicesWithMediaType:)
+ ZXQT(inputDevicesWithMediaType:) ZXMediaTypeVideo];
+
+ if ([devices count] > 0) {
+ if (capture_device_index == -1) {
+ AVCaptureDevicePosition position = AVCaptureDevicePositionBack;
+ if (camera == self.front) {
+ position = AVCaptureDevicePositionFront;
+ }
+
+ for(unsigned int i=0; i < [devices count]; ++i) {
+ ZXCaptureDevice *dev = [devices objectAtIndex:i];
+ if (dev.position == position) {
+ capture_device_index = i;
+ zxd = dev;
+ break;
+ }
+ }
+ }
+
+ if (!zxd && capture_device_index != -1) {
+ zxd = [devices objectAtIndex:capture_device_index];
+ }
+ }
+#endif
+
+ if (!zxd) {
+ zxd =
+ [ZXCaptureDevice
+ ZXAV(defaultDeviceWithMediaType:)
+ ZXQT(defaultInputDeviceWithMediaType:) ZXMediaTypeVideo];
+ }
+
+ capture_device = zxd;
+
+ return zxd;
+}
+
+- (ZXCaptureDevice *)captureDevice {
+ return capture_device;
+}
+
+- (void)setCaptureDevice:(ZXCaptureDevice *)device {
+ if (device == capture_device) {
+ return;
+ }
+
+ if(capture_device) {
+ ZXQT({
+ if ([capture_device isOpen]) {
+ [capture_device close];
+ }});
+ }
+
+ capture_device = device;
+}
+
+- (void)replaceInput {
+ if ([session respondsToSelector:@selector(beginConfiguration)]) {
+ [session performSelector:@selector(beginConfiguration)];
+ }
+
+ if (session && input) {
+ [session removeInput:input];
+ input = nil;
+ }
+
+ ZXCaptureDevice *zxd = [self device];
+ ZXQT([zxd open:nil]);
+
+ if (zxd) {
+ input =
+ [ZXCaptureDeviceInput deviceInputWithDevice:zxd
+ ZXAV(error:nil)];
+ }
+
+ if (input) {
+ ZXAV({
+ NSString *preset = 0;
+ if (!preset &&
+ NSClassFromString(@"NSOrderedSet") && // Proxy for "is this iOS 5" ...
+ [UIScreen mainScreen].scale > 1 &&
+ isIPad() &&
+ &AVCaptureSessionPresetiFrame960x540 != nil &&
+ [zxd supportsAVCaptureSessionPreset:AVCaptureSessionPresetiFrame960x540]) {
+ // NSLog(@"960");
+ preset = AVCaptureSessionPresetiFrame960x540;
+ }
+ if (!preset) {
+ // NSLog(@"MED");
+ preset = AVCaptureSessionPresetMedium;
+ }
+ session.sessionPreset = preset;
+ });
+ [session addInput:input ZXQT(error:nil)];
+ }
+
+ if ([session respondsToSelector:@selector(commitConfiguration)]) {
+ [session performSelector:@selector(commitConfiguration)];
+ }
+}
+
+- (ZXCaptureSession *)session {
+ if (session == 0) {
+ session = [[ZXCaptureSession alloc] init];
+ [self replaceInput];
+ }
+ return session;
+}
+
+- (void)stopAndFreezeOutput:(BOOL)freezeOutput {
+ // NSLog(@"stop");
+
+ if (!running) {
+ return;
+ }
+
+ if (true ZXAV(&& self.session.running)) {
+ // NSLog(@"stop running");
+ if (!freezeOutput)
+ [self.layer removeFromSuperlayer];
+
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ [self.session stopRunning];
+ });
+ } else {
+ // NSLog(@"already stopped");
+ }
+ running = false;
+}
+
+- (void)stop {
+ [self stopAndFreezeOutput:NO];
+}
+
+- (void)setOutputAttributes {
+ NSString *key = (NSString *)kCVPixelBufferPixelFormatTypeKey;
+ NSNumber *value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
+ NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObject:value forKey:key];
+ ZXQT({
+ key = (NSString *)kCVPixelBufferWidthKey;
+ value = [NSNumber numberWithUnsignedLong:width];
+ [attributes setObject:value forKey:key];
+ key = (NSString *)kCVPixelBufferHeightKey;
+ value = [NSNumber numberWithUnsignedLong:height];
+ [attributes setObject:value forKey:key];
+ });
+ [output ZXQT(setPixelBufferAttributes:)ZXAV(setVideoSettings:)attributes];
+}
+
+- (ZXCaptureVideoOutput *)output {
+ if (!output) {
+ output = [[ZXCaptureVideoOutput alloc] init];
+ [self setOutputAttributes];
+ [output ZXQT(setAutomaticallyDropsLateVideoFrames:)
+ ZXAV(setAlwaysDiscardsLateVideoFrames:)YES];
+
+ [output ZXQT(setDelegate:)ZXAV(setSampleBufferDelegate:)self
+ ZXAV(queue:_captureQueue)];
+
+ [self.session addOutput:output ZXQT(error:nil)];
+ }
+ return output;
+}
+
+- (void)start {
+ // NSLog(@"start %@ %d %@ %@", self.session, running, output, delegate);
+
+ if (hard_stop) {
+ return;
+ }
+
+ if (delegate || luminance || binary) {
+ // for side effects
+ [self output];
+ }
+
+ if (false ZXAV(|| self.session.running)) {
+ // NSLog(@"already running");
+ } else {
+
+ static int i = 0;
+ if (++i == -2) {
+ abort();
+ }
+
+ // NSLog(@"start running");
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ [self.session startRunning];
+ });
+ }
+ running = true;
+}
+
+- (void)start_stop {
+ // NSLog(@"ss %d %@ %d %@ %@ %@", running, delegate, on_screen, output, luminanceLayer, binary);
+ if ((!running && (delegate || on_screen)) ||
+ (!output &&
+ (delegate ||
+ (on_screen && (luminance || binary))))) {
+ [self start];
+ }
+ if (running && !delegate && !on_screen) {
+ [self stop];
+ }
+}
+
+- (void)setDelegate:(id<ZXCaptureDelegate>)_delegate {
+ delegate = _delegate;
+ if (delegate) {
+ hard_stop = false;
+ }
+ [self start_stop];
+}
+
+- (void)hard_stop {
+ hard_stop = true;
+ if (running) {
+ [self stop];
+ }
+}
+
+- (void)setLuminance:(BOOL)on {
+ if (on && !luminance) {
+ luminance = [CALayer layer];
+ } else if (!on && luminance) {
+ luminance = nil;
+ }
+}
+
+- (CALayer *)luminance {
+ return luminance;
+}
+
+- (void)setBinary:(BOOL)on {
+ if (on && !binary) {
+ binary = [CALayer layer];
+ } else if (!on && binary) {
+ binary = nil;
+ }
+}
+
+- (CALayer *)binary {
+ return binary;
+}
+
+- (CALayer *)layer {
+ if (!layer) {
+ layer = [[ZXCaptureVideoPreviewLayer alloc] initWithSession:self.session];
+
+ ZXAV(layer.videoGravity = AVLayerVideoGravityResizeAspect);
+ ZXAV(layer.videoGravity = AVLayerVideoGravityResizeAspectFill);
+
+ [layer setAffineTransform:transform];
+ layer.delegate = self;
+
+ ZXQT({
+ ProcessSerialNumber psn;
+ GetCurrentProcess(&psn);
+ TransformProcessType(&psn, 1);
+ });
+ }
+ return layer;
+}
+
+- (void)runActionForKey:(NSString *)key
+ object:(id)anObject
+ arguments:(NSDictionary *)dict {
+ // NSLog(@" rAFK %@ %@ %@", key, anObject, dict);
+ (void)anObject;
+ (void)dict;
+ if ([key isEqualToString:kCAOnOrderIn]) {
+
+ if (order_in_skip) {
+ --order_in_skip;
+ // NSLog(@"order in skip");
+ return;
+ }
+
+ // NSLog(@"order in");
+
+ on_screen = true;
+ if (luminance && luminance.superlayer != layer) {
+ // [layer addSublayer:luminance];
+ }
+ if (binary && binary.superlayer != layer) {
+ // [layer addSublayer:binary];
+ }
+ [self start_stop];
+ } else if ([key isEqualToString:kCAOnOrderOut]) {
+ if (order_out_skip) {
+ --order_out_skip;
+ // NSLog(@"order out skip");
+ return;
+ }
+
+ on_screen = false;
+ // NSLog(@"order out");
+ [self start_stop];
+ }
+}
+
+- (id<CAAction>)actionForLayer:(CALayer *)_layer forKey:(NSString *)event {
+ (void)_layer;
+
+ // NSLog(@"layer event %@", event);
+
+ // never animate
+ [CATransaction setValue:[NSNumber numberWithFloat:0.0f]
+ forKey:kCATransactionAnimationDuration];
+
+ // NSLog(@"afl %@ %@", _layer, event);
+ if ([event isEqualToString:kCAOnOrderIn]
+ || [event isEqualToString:kCAOnOrderOut]
+ // || ([event isEqualToString:@"bounds"] && (binary || luminance))
+ // || ([event isEqualToString:@"onLayout"] && (binary || luminance))
+ ) {
+ return self;
+ } else if ([event isEqualToString:@"contents"] ) {
+ } else if ([event isEqualToString:@"sublayers"] ) {
+ } else if ([event isEqualToString:@"onLayout"] ) {
+ } else if ([event isEqualToString:@"position"] ) {
+ } else if ([event isEqualToString:@"bounds"] ) {
+ } else if ([event isEqualToString:@"layoutManager"] ) {
+ } else if ([event isEqualToString:@"transform"] ) {
+ } else {
+ NSLog(@"afl %@ %@", _layer, event);
+ }
+ return nil;
+}
+
+- (void)captureOutput:(ZXCaptureOutput *)captureOutput
+ZXQT(didOutputVideoFrame:(CVImageBufferRef)videoFrame
+ withSampleBuffer:(QTSampleBuffer *)sampleBuffer)
+ZXAV(didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer)
+ fromConnection:(ZXCaptureConnection *)connection {
+ @autoreleasepool {
+ if (!cameraIsReady)
+ {
+ cameraIsReady = YES;
+ if ([self.delegate respondsToSelector:@selector(captureCameraIsReady:)])
+ {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.delegate captureCameraIsReady:self];
+ });
+ }
+ }
+
+ if (!captureToFilename && !luminance && !binary && !delegate) {
+ // NSLog(@"skipping capture");
+ return;
+ }
+
+ // NSLog(@"received frame");
+
+ ZXAV(CVImageBufferRef videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer));
+
+ // NSLog(@"%ld %ld", CVPixelBufferGetWidth(videoFrame), CVPixelBufferGetHeight(videoFrame));
+ // NSLog(@"delegate %@", delegate);
+
+ ZXQT({
+ if (!reported_width || !reported_height) {
+ NSSize size =
+ [[[[input.device.formatDescriptions objectAtIndex:0]
+ formatDescriptionAttributes] objectForKey:@"videoEncodedPixelsSize"] sizeValue];
+ width = size.width;
+ height = size.height;
+ // NSLog(@"reported: %f x %f", size.width, size.height);
+ [self performSelectorOnMainThread:@selector(setOutputAttributes) withObject:nil waitUntilDone:NO];
+ reported_width = size.width;
+ reported_height = size.height;
+ if ([delegate respondsToSelector:@selector(captureSize:width:height:)]) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [delegate captureSize:self
+ width:[NSNumber numberWithFloat:size.width]
+ height:[NSNumber numberWithFloat:size.height]];
+ });
+ }
+ }});
+
+ (void)sampleBuffer;
+ (void)captureOutput;
+ (void)connection;
+
+#if !TARGET_OS_EMBEDDED
+ // The routines don't exist in iOS. There are alternatives, but a good
+ // solution would have to figure out a reasonable path and might be
+ // better as a post to url
+
+ if (captureToFilename) {
+ CGImageRef image =
+ [ZXCGImageLuminanceSource createImageFromBuffer:videoFrame];
+ NSURL *url = [NSURL fileURLWithPath:captureToFilename];
+ CGImageDestinationRef dest =
+ CGImageDestinationCreateWithURL((__bridge CFURLRef)url, kUTTypePNG, 1, nil);
+ CGImageDestinationAddImage(dest, image, nil);
+ CGImageDestinationFinalize(dest);
+ CGImageRelease(image);
+ CFRelease(dest);
+ self.captureToFilename = nil;
+ }
+#endif
+
+ CGImageRef videoFrameImage = [ZXCGImageLuminanceSource createImageFromBuffer:videoFrame];
+ CGImageRef rotatedImage = [self createRotatedImage:videoFrameImage degrees:rotation];
+ CGImageRelease(videoFrameImage);
+
+ ZXCGImageLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage];
+ CGImageRelease(rotatedImage);
+
+ if (luminance) {
+ CGImageRef image = source.image;
+ CGImageRetain(image);
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{
+ luminance.contents = (__bridge id)image;
+ CGImageRelease(image);
+ });
+ }
+
+ if (binary || delegate) {
+ ZXHybridBinarizer *binarizer = [[ZXHybridBinarizer alloc] initWithSource:source];
+
+ if (binary) {
+ CGImageRef image = [binarizer createImage];
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{
+ binary.contents = (__bridge id)image;
+ CGImageRelease(image);
+ });
+ }
+
+ if (delegate) {
+ ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:binarizer];
+
+ NSError *error;
+ ZXResult *result = [self.reader decode:bitmap hints:hints error:&error];
+ if (result) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [delegate captureResult:self result:result];
+ });
+ }
+ }
+ }
+ }
+}
+
+- (BOOL)hasFront {
+ NSArray *devices =
+ [ZXCaptureDevice
+ ZXAV(devicesWithMediaType:)
+ ZXQT(inputDevicesWithMediaType:) ZXMediaTypeVideo];
+ return [devices count] > 1;
+}
+
+- (BOOL)hasBack {
+ NSArray *devices =
+ [ZXCaptureDevice
+ ZXAV(devicesWithMediaType:)
+ ZXQT(inputDevicesWithMediaType:) ZXMediaTypeVideo];
+ return [devices count] > 0;
+}
+
+- (BOOL)hasTorch {
+ if ([self device]) {
+ return false ZXAV(|| [self device].hasTorch);
+ } else {
+ return NO;
+ }
+}
+
+- (int)front {
+ return 0;
+}
+
+- (int)back {
+ return 1;
+}
+
+- (int)camera {
+ return camera;
+}
+
+- (BOOL)torch {
+ return torch;
+}
+
+- (void)setCamera:(int)camera_ {
+ if (camera != camera_) {
+ camera = camera_;
+ capture_device_index = -1;
+ capture_device = 0;
+ [self replaceInput];
+ }
+}
+
+- (void)setTorch:(BOOL)torch_ {
+ torch = torch_;
+ ZXAV({
+ [input.device lockForConfiguration:nil];
+ if (torch) {
+ input.device.torchMode = AVCaptureTorchModeOn;
+ } else {
+ input.device.torchMode = AVCaptureTorchModeOff;
+ }
+ [input.device unlockForConfiguration];
+ });
+}
+
+- (void)setTransform:(CGAffineTransform)transform_ {
+ transform = transform_;
+ [layer setAffineTransform:transform];
+}
+
+@end
+
+// If you try to define this higher, there (seem to be) clashes with something(s) defined
+// in the includes ...
+
+#if ZXAV(1)+0
+#include <sys/types.h>
+#include <sys/sysctl.h>
+// Gross, I know, but ...
+static bool isIPad() {
+ static int is_ipad = -1;
+ if (is_ipad < 0) {
+ size_t size;
+ sysctlbyname("hw.machine", NULL, &size, NULL, 0); // Get size of data to be returned.
+ char *name = (char *)malloc(size);
+ sysctlbyname("hw.machine", name, &size, NULL, 0);
+ NSString *machine = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
+ free(name);
+ is_ipad = [machine hasPrefix:@"iPad"];
+ }
+ return !!is_ipad;
+}
+#endif
+
+#else
+
+@implementation ZXCapture
+
+- (id)init {
+ if ((self = [super init])) {
+
+ }
+ return 0;
+}
+
+- (BOOL)running {return NO;}
+
+- (CALayer *)layer {
+ return 0;
+}
+
+- (CALayer *)luminance {
+ return 0;
+}
+
+- (CALayer *)binary {
+ return 0;
+}
+
+- (void)setLuminance:(BOOL)on {}
+- (void)setBinary:(BOOL)on {}
+
+- (void)hard_stop {
+}
+
+- (BOOL)hasFront {
+ return YES;
+}
+
+- (BOOL)hasBack {
+ return NO;
+}
+
+- (BOOL)hasTorch {
+ return NO;
+}
+
+- (int)front {
+ return 0;
+}
+
+- (int)back {
+ return 1;
+}
+
+- (int)camera {
+ return self.front;
+}
+
+- (BOOL)torch {
+ return NO;
+}
+
+- (void)setCamera:(int)camera_ {}
+- (void)setTorch:(BOOL)torch {}
+- (void)order_skip {}
+- (void)start {}
+- (void)stop {}
+- (void)stopAndFreezeOutput:(BOOL)freezeOutput {}
+- (void *)output {return 0;}
+
+@end
+
+#endif
diff --git a/ZXingObjC/client/ZXCaptureDelegate.h b/ZXingObjC/client/ZXCaptureDelegate.h
new file mode 100644
index 0000000..33a7f48
--- /dev/null
+++ b/ZXingObjC/client/ZXCaptureDelegate.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+@class ZXCapture;
+@class ZXResult;
+
+@protocol ZXCaptureDelegate <NSObject>
+
+- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result;
+
+@optional
+- (void)captureSize:(ZXCapture *)capture
+ width:(NSNumber *)width
+ height:(NSNumber *)height;
+
+- (void)captureCameraIsReady:(ZXCapture *)capture;
+
+@end
diff --git a/ZXingObjC/client/ZXCaptureView.h b/ZXingObjC/client/ZXCaptureView.h
new file mode 100644
index 0000000..23f9946
--- /dev/null
+++ b/ZXingObjC/client/ZXCaptureView.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.
+ */
+
+#include "ZXView.h"
+
+@interface ZXCaptureView : ZXView
+
+@end
diff --git a/ZXingObjC/client/ZXCaptureView.m b/ZXingObjC/client/ZXCaptureView.m
new file mode 100644
index 0000000..17fc3aa
--- /dev/null
+++ b/ZXingObjC/client/ZXCaptureView.m
@@ -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.
+ */
+
+#include "ZXCaptureView.h"
+
+@implementation ZXCaptureView
+
+@end
diff --git a/ZXingObjC/client/ZXImage.h b/ZXingObjC/client/ZXImage.h
new file mode 100644
index 0000000..2470dbe
--- /dev/null
+++ b/ZXingObjC/client/ZXImage.h
@@ -0,0 +1,31 @@
+/*
+ * 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 <QuartzCore/QuartzCore.h>
+
+@class ZXBitMatrix;
+
+@interface ZXImage : NSObject
+
+@property (nonatomic, assign, readonly) CGImageRef cgimage;
+
+- (ZXImage *)initWithCGImageRef:(CGImageRef)image;
+- (ZXImage *)initWithURL:(NSURL const *)url;
+- (size_t)width;
+- (size_t)height;
++ (ZXImage *)imageWithMatrix:(ZXBitMatrix *)matrix;
+
+@end
diff --git a/ZXingObjC/client/ZXImage.m b/ZXingObjC/client/ZXImage.m
new file mode 100644
index 0000000..80afe7f
--- /dev/null
+++ b/ZXingObjC/client/ZXImage.m
@@ -0,0 +1,101 @@
+/*
+ * 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 "ZXImage.h"
+
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+#import <ImageIO/ImageIO.h>
+#endif
+
+@interface ZXImage ()
+
+@property (nonatomic, assign) CGImageRef cgimage;
+
+@end
+
+@implementation ZXImage
+
+- (ZXImage *)initWithCGImageRef:(CGImageRef)image {
+ if (self = [super init]) {
+ _cgimage = CGImageRetain(image);
+ }
+
+ return self;
+}
+
+- (ZXImage *)initWithURL:(NSURL const *)url {
+ if (self = [super init]) {
+ CGDataProviderRef provider = CGDataProviderCreateWithURL((__bridge CFURLRef)url);
+
+ if (provider) {
+ CGImageSourceRef source = CGImageSourceCreateWithDataProvider(provider, 0);
+
+ if (source) {
+ _cgimage = CGImageSourceCreateImageAtIndex(source, 0, 0);
+ CFRelease(source);
+ }
+
+ CGDataProviderRelease(provider);
+ }
+ }
+
+ return self;
+}
+
+- (size_t)width {
+ return CGImageGetWidth(self.cgimage);
+}
+
+- (size_t)height {
+ return CGImageGetHeight(self.cgimage);
+}
+
+- (void)dealloc {
+ if (_cgimage) {
+ CGImageRelease(_cgimage);
+ }
+}
+
++ (ZXImage *)imageWithMatrix:(ZXBitMatrix *)matrix {
+ 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];
+ int8_t intensity = bit ? 0 : 255;
+ for(int i = 0; i < 3; i++) {
+ bytes[y * width * 4 + x * 4 + i] = intensity;
+ }
+ bytes[y * width * 4 + x * 4 + 3] = 255;
+ }
+ }
+
+ 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;
+}
+
+@end
diff --git a/ZXingObjC/client/ZXView.h b/ZXingObjC/client/ZXView.h
new file mode 100644
index 0000000..88a093f
--- /dev/null
+++ b/ZXingObjC/client/ZXView.h
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+#import <UIKit/UIKit.h>
+#define ZXView UIView
+#else
+#import <Cocoa/Cocoa.h>
+#define ZXView NSView
+#endif
diff --git a/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.h b/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.h
new file mode 100644
index 0000000..30f3503
--- /dev/null
+++ b/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.h
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * See DoCoMo's documentation http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/about/s2.html
+ * about the result types represented by subclasses of this class.
+ */
+
+@interface ZXAbstractDoCoMoResultParser : ZXResultParser
+
++ (NSArray *)matchDoCoMoPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim;
++ (NSString *)matchSingleDoCoMoPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim;
+
+@end
diff --git a/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.m b/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.m
new file mode 100644
index 0000000..3fdcd36
--- /dev/null
+++ b/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.m
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXAbstractDoCoMoResultParser.h"
+
+@implementation ZXAbstractDoCoMoResultParser
+
++ (NSArray *) matchDoCoMoPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim {
+ return [self matchPrefixedField:prefix rawText:rawText endChar:';' trim:trim];
+}
+
++ (NSString *) matchSingleDoCoMoPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim {
+ return [self matchSinglePrefixedField:prefix rawText:rawText endChar:';' trim:trim];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXAddressBookAUResultParser.h b/ZXingObjC/client/result/ZXAddressBookAUResultParser.h
new file mode 100644
index 0000000..461f9d1
--- /dev/null
+++ b/ZXingObjC/client/result/ZXAddressBookAUResultParser.h
@@ -0,0 +1,26 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Implements KDDI AU's address book format. See http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html.
+ * (Thanks to Yuzo for translating!)
+ */
+
+@interface ZXAddressBookAUResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXAddressBookAUResultParser.m b/ZXingObjC/client/result/ZXAddressBookAUResultParser.m
new file mode 100644
index 0000000..4c9f7d8
--- /dev/null
+++ b/ZXingObjC/client/result/ZXAddressBookAUResultParser.m
@@ -0,0 +1,80 @@
+/*
+ * 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 "ZXAddressBookAUResultParser.h"
+#import "ZXAddressBookParsedResult.h"
+#import "ZXResult.h"
+
+@implementation ZXAddressBookAUResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+
+ if ([rawText rangeOfString:@"MEMORY"].location == NSNotFound ||
+ [rawText rangeOfString:@"\r\n"].location == NSNotFound) {
+ return nil;
+ }
+
+ NSString *name = [[self class] matchSinglePrefixedField:@"NAME1:" rawText:rawText endChar:'\r' trim:YES];
+ NSString *pronunciation = [[self class] matchSinglePrefixedField:@"NAME2:" rawText:rawText endChar:'\r' trim:YES];
+ NSArray *phoneNumbers = [self matchMultipleValuePrefix:@"TEL" max:3 rawText:rawText trim:YES];
+ NSArray *emails = [self matchMultipleValuePrefix:@"MAIL" max:3 rawText:rawText trim:YES];
+ NSString *note = [[self class] matchSinglePrefixedField:@"MEMORY:" rawText:rawText endChar:'\r' trim:NO];
+ NSString *address = [[self class] matchSinglePrefixedField:@"ADD:" rawText:rawText endChar:'\r' trim:YES];
+ NSArray *addresses = address == nil ? nil : @[address];
+
+ return [ZXAddressBookParsedResult addressBookParsedResultWithNames:[self maybeWrap:name]
+ nicknames:nil
+ pronunciation:pronunciation
+ phoneNumbers:phoneNumbers
+ phoneTypes:nil
+ emails:emails
+ emailTypes:nil
+ instantMessenger:nil
+ note:note
+ addresses:addresses
+ addressTypes:nil
+ org:nil
+ birthday:nil
+ title:nil
+ urls:nil
+ geo:nil];
+}
+
+- (NSArray *)matchMultipleValuePrefix:(NSString *)prefix max:(int)max rawText:(NSString *)rawText trim:(BOOL)trim {
+ NSMutableArray *values = nil;
+
+ for (int i = 1; i <= max; i++) {
+ NSString *value = [[self class] matchSinglePrefixedField:[NSString stringWithFormat:@"%@%d:", prefix, i]
+ rawText:rawText
+ endChar:'\r'
+ trim:trim];
+ if (value == nil) {
+ break;
+ }
+ if (values == nil) {
+ values = [[NSMutableArray alloc] initWithCapacity:max];
+ }
+ [values addObject:value];
+ }
+
+ if (values == nil) {
+ return nil;
+ }
+ return values;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.h b/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.h
new file mode 100644
index 0000000..d6a4b20
--- /dev/null
+++ b/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.h
@@ -0,0 +1,36 @@
+/*
+ * 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 "ZXAbstractDoCoMoResultParser.h"
+#import "ZXResult.h"
+
+/**
+ * Implements the "MECARD" address book entry format.
+ *
+ * Supported keys: N, SOUND, TEL, EMAIL, NOTE, ADR, BDAY, URL, plus ORG
+ * Unsupported keys: TEL-AV, NICKNAME
+ *
+ * Except for TEL, multiple values for keys are also not supported;
+ * the first one found takes precedence.
+ *
+ * Our understanding of the MECARD format is based on this document:
+ *
+ * http://www.mobicode.org.tw/files/OMIA%20Mobile%20Bar%20Code%20Standard%20v3.2.1.doc
+ */
+
+@interface ZXAddressBookDoCoMoResultParser : ZXAbstractDoCoMoResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.m b/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.m
new file mode 100644
index 0000000..6c78f90
--- /dev/null
+++ b/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.m
@@ -0,0 +1,71 @@
+/*
+ * 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 "ZXAddressBookDoCoMoResultParser.h"
+#import "ZXAddressBookParsedResult.h"
+#import "ZXResult.h"
+
+@implementation ZXAddressBookDoCoMoResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (![rawText hasPrefix:@"MECARD:"]) {
+ return nil;
+ }
+ NSArray *rawName = [[self class] matchDoCoMoPrefixedField:@"N:" rawText:rawText trim:YES];
+ if (rawName == nil) {
+ return nil;
+ }
+ NSString *name = [self parseName:rawName[0]];
+ NSString *pronunciation = [[self class] matchSingleDoCoMoPrefixedField:@"SOUND:" rawText:rawText trim:YES];
+ NSArray *phoneNumbers = [[self class] matchDoCoMoPrefixedField:@"TEL:" rawText:rawText trim:YES];
+ NSArray *emails = [[self class] matchDoCoMoPrefixedField:@"EMAIL:" rawText:rawText trim:YES];
+ NSString *note = [[self class] matchSingleDoCoMoPrefixedField:@"NOTE:" rawText:rawText trim:NO];
+ NSArray *addresses = [[self class] matchDoCoMoPrefixedField:@"ADR:" rawText:rawText trim:YES];
+ NSString *birthday = [[self class] matchSingleDoCoMoPrefixedField:@"BDAY:" rawText:rawText trim:YES];
+ if (birthday != nil && ![[self class] isStringOfDigits:birthday length:8]) {
+ birthday = nil;
+ }
+ NSArray *urls = [[self class] matchDoCoMoPrefixedField:@"URL:" rawText:rawText trim:YES];
+ NSString *org = [[self class] matchSingleDoCoMoPrefixedField:@"ORG:" rawText:rawText trim:YES];
+
+ return [ZXAddressBookParsedResult addressBookParsedResultWithNames:[self maybeWrap:name]
+ nicknames:nil
+ pronunciation:pronunciation
+ phoneNumbers:phoneNumbers
+ phoneTypes:nil
+ emails:emails
+ emailTypes:nil
+ instantMessenger:nil
+ note:note
+ addresses:addresses
+ addressTypes:nil
+ org:org
+ birthday:birthday
+ title:nil
+ urls:urls
+ geo:nil];
+}
+
+- (NSString *)parseName:(NSString *)name {
+ NSUInteger comma = [name rangeOfString:@","].location;
+ if (comma != NSNotFound) {
+ return [NSString stringWithFormat:@"%@ %@", [name substringFromIndex:comma + 1], [name substringToIndex:comma]];
+ }
+ return name;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXAddressBookParsedResult.h b/ZXingObjC/client/result/ZXAddressBookParsedResult.h
new file mode 100644
index 0000000..33a94e8
--- /dev/null
+++ b/ZXingObjC/client/result/ZXAddressBookParsedResult.h
@@ -0,0 +1,59 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@interface ZXAddressBookParsedResult : ZXParsedResult
+
+@property (nonatomic, readonly, strong) NSArray *names;
+@property (nonatomic, readonly, strong) NSArray *nicknames;
+@property (nonatomic, readonly, copy) NSString *pronunciation;
+@property (nonatomic, readonly, strong) NSArray *phoneNumbers;
+@property (nonatomic, readonly, strong) NSArray *phoneTypes;
+@property (nonatomic, readonly, strong) NSArray *emails;
+@property (nonatomic, readonly, strong) NSArray *emailTypes;
+@property (nonatomic, readonly, copy) NSString *instantMessenger;
+@property (nonatomic, readonly, copy) NSString *note;
+@property (nonatomic, readonly, strong) NSArray *addresses;
+@property (nonatomic, readonly, strong) NSArray *addressTypes;
+@property (nonatomic, readonly, copy) NSString *title;
+@property (nonatomic, readonly, copy) NSString *org;
+@property (nonatomic, readonly, strong) NSArray *urls;
+@property (nonatomic, readonly, copy) NSString *birthday;
+@property (nonatomic, readonly, strong) NSArray *geo;
+
+- (id)initWithNames:(NSArray *)names phoneNumbers:(NSArray *)phoneNumbers
+ phoneTypes:(NSArray *)phoneTypes emails:(NSArray *)emails emailTypes:(NSArray *)emailTypes
+ addresses:(NSArray *)addresses addressTypes:(NSArray *)addressTypes;
+
+- (id)initWithNames:(NSArray *)names nicknames:(NSArray *)nicknames pronunciation:(NSString *)pronunciation
+ phoneNumbers:(NSArray *)phoneNumbers phoneTypes:(NSArray *)phoneTypes emails:(NSArray *)emails
+ emailTypes:(NSArray *)emailTypes instantMessenger:(NSString *)instantMessenger note:(NSString *)note
+ addresses:(NSArray *)addresses addressTypes:(NSArray *)addressTypes org:(NSString *)org
+ birthday:(NSString *)birthday title:(NSString *)title urls:(NSArray *)urls geo:(NSArray *)geo;
+
++ (id)addressBookParsedResultWithNames:(NSArray *)names phoneNumbers:(NSArray *)phoneNumbers
+ phoneTypes:(NSArray *)phoneTypes emails:(NSArray *)emails emailTypes:(NSArray *)emailTypes
+ addresses:(NSArray *)addresses addressTypes:(NSArray *)addressTypes;
+
++ (id)addressBookParsedResultWithNames:(NSArray *)names nicknames:(NSArray *)nicknames
+ pronunciation:(NSString *)pronunciation phoneNumbers:(NSArray *)phoneNumbers
+ phoneTypes:(NSArray *)phoneTypes emails:(NSArray *)emails emailTypes:(NSArray *)emailTypes
+ instantMessenger:(NSString *)instantMessenger note:(NSString *)note addresses:(NSArray *)addresses
+ addressTypes:(NSArray *)addressTypes org:(NSString *)org birthday:(NSString *)birthday
+ title:(NSString *)title urls:(NSArray *)urls geo:(NSArray *)geo;
+
+@end
diff --git a/ZXingObjC/client/result/ZXAddressBookParsedResult.m b/ZXingObjC/client/result/ZXAddressBookParsedResult.m
new file mode 100644
index 0000000..13a5e24
--- /dev/null
+++ b/ZXingObjC/client/result/ZXAddressBookParsedResult.m
@@ -0,0 +1,94 @@
+/*
+ * 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 "ZXAddressBookParsedResult.h"
+#import "ZXParsedResultType.h"
+
+@implementation ZXAddressBookParsedResult
+
+- (id)initWithNames:(NSArray *)names phoneNumbers:(NSArray *)phoneNumbers
+ phoneTypes:(NSArray *)phoneTypes emails:(NSArray *)emails emailTypes:(NSArray *)emailTypes
+ addresses:(NSArray *)addresses addressTypes:(NSArray *)addressTypes {
+ return [self initWithNames:names nicknames:nil pronunciation:nil phoneNumbers:phoneNumbers phoneTypes:phoneNumbers
+ emails:emails emailTypes:_emailTypes instantMessenger:nil note:nil addresses:addresses
+ addressTypes:addressTypes org:nil birthday:nil title:nil urls:nil geo:nil];
+}
+
+- (id)initWithNames:(NSArray *)names nicknames:(NSArray *)nicknames pronunciation:(NSString *)pronunciation
+ phoneNumbers:(NSArray *)phoneNumbers phoneTypes:(NSArray *)phoneTypes emails:(NSArray *)emails
+ emailTypes:(NSArray *)emailTypes instantMessenger:(NSString *)instantMessenger note:(NSString *)note
+ addresses:(NSArray *)addresses addressTypes:(NSArray *)addressTypes org:(NSString *)org
+ birthday:(NSString *)birthday title:(NSString *)title urls:(NSArray *)urls geo:(NSArray *)geo {
+ if (self = [super initWithType:kParsedResultTypeAddressBook]) {
+ _names = names;
+ _nicknames = nicknames;
+ _pronunciation = pronunciation;
+ _phoneNumbers = phoneNumbers;
+ _phoneTypes = phoneTypes;
+ _emails = emails;
+ _emailTypes = emailTypes;
+ _instantMessenger = instantMessenger;
+ _note = note;
+ _addresses = addresses;
+ _addressTypes = addressTypes;
+ _org = org;
+ _birthday = birthday;
+ _title = title;
+ _urls = urls;
+ _geo = geo;
+ }
+
+ return self;
+}
+
++ (id)addressBookParsedResultWithNames:(NSArray *)names phoneNumbers:(NSArray *)phoneNumbers
+ phoneTypes:(NSArray *)phoneTypes emails:(NSArray *)emails emailTypes:(NSArray *)emailTypes
+ addresses:(NSArray *)addresses addressTypes:(NSArray *)addressTypes {
+ return [[self alloc] initWithNames:names phoneNumbers:phoneNumbers phoneTypes:phoneTypes emails:emails
+ emailTypes:emailTypes addresses:addresses addressTypes:addressTypes];
+}
+
++ (id)addressBookParsedResultWithNames:(NSArray *)names nicknames:(NSArray *)nicknames
+ pronunciation:(NSString *)pronunciation phoneNumbers:(NSArray *)phoneNumbers
+ phoneTypes:(NSArray *)phoneTypes emails:(NSArray *)emails emailTypes:(NSArray *)emailTypes
+ instantMessenger:(NSString *)instantMessenger note:(NSString *)note addresses:(NSArray *)addresses
+ addressTypes:(NSArray *)addressTypes org:(NSString *)org birthday:(NSString *)birthday
+ title:(NSString *)title urls:(NSArray *)urls geo:(NSArray *)geo {
+ return [[self alloc] initWithNames:names nicknames:nicknames pronunciation:pronunciation phoneNumbers:phoneNumbers
+ phoneTypes:phoneTypes emails:emails emailTypes:emailTypes instantMessenger:instantMessenger
+ note:note addresses:addresses addressTypes:addressTypes org:org birthday:birthday
+ title:title urls:urls geo:geo];
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString string];
+ [ZXParsedResult maybeAppendArray:self.names result:result];
+ [ZXParsedResult maybeAppendArray:self.nicknames result:result];
+ [ZXParsedResult maybeAppend:self.pronunciation result:result];
+ [ZXParsedResult maybeAppend:self.title result:result];
+ [ZXParsedResult maybeAppend:self.org result:result];
+ [ZXParsedResult maybeAppendArray:self.addresses result:result];
+ [ZXParsedResult maybeAppendArray:self.phoneNumbers result:result];
+ [ZXParsedResult maybeAppendArray:self.emails result:result];
+ [ZXParsedResult maybeAppend:self.instantMessenger result:result];
+ [ZXParsedResult maybeAppendArray:self.urls result:result];
+ [ZXParsedResult maybeAppend:self.birthday result:result];
+ [ZXParsedResult maybeAppendArray:self.geo result:result];
+ [ZXParsedResult maybeAppend:self.note result:result];
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXBizcardResultParser.h b/ZXingObjC/client/result/ZXBizcardResultParser.h
new file mode 100644
index 0000000..42d7f0a
--- /dev/null
+++ b/ZXingObjC/client/result/ZXBizcardResultParser.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXAbstractDoCoMoResultParser.h"
+
+/**
+ * Implements the "BIZCARD" address book entry format, though this has been
+ * largely reverse-engineered from examples observed in the wild -- still
+ * looking for a definitive reference.
+ */
+
+@interface ZXBizcardResultParser : ZXAbstractDoCoMoResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXBizcardResultParser.m b/ZXingObjC/client/result/ZXBizcardResultParser.m
new file mode 100644
index 0000000..f6a297c
--- /dev/null
+++ b/ZXingObjC/client/result/ZXBizcardResultParser.m
@@ -0,0 +1,87 @@
+/*
+ * 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 "ZXAddressBookParsedResult.h"
+#import "ZXBizcardResultParser.h"
+#import "ZXResult.h"
+
+@implementation ZXBizcardResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (![rawText hasPrefix:@"BIZCARD:"]) {
+ return nil;
+ }
+ NSString *firstName = [[self class] matchSingleDoCoMoPrefixedField:@"N:" rawText:rawText trim:YES];
+ NSString *lastName = [[self class] matchSingleDoCoMoPrefixedField:@"X:" rawText:rawText trim:YES];
+ NSString *fullName = [self buildName:firstName lastName:lastName];
+ NSString *title = [[self class] matchSingleDoCoMoPrefixedField:@"T:" rawText:rawText trim:YES];
+ NSString *org = [[self class] matchSingleDoCoMoPrefixedField:@"C:" rawText:rawText trim:YES];
+ NSArray *addresses = [[self class] matchDoCoMoPrefixedField:@"A:" rawText:rawText trim:YES];
+ NSString *phoneNumber1 = [[self class] matchSingleDoCoMoPrefixedField:@"B:" rawText:rawText trim:YES];
+ NSString *phoneNumber2 = [[self class] matchSingleDoCoMoPrefixedField:@"M:" rawText:rawText trim:YES];
+ NSString *phoneNumber3 = [[self class] matchSingleDoCoMoPrefixedField:@"F:" rawText:rawText trim:YES];
+ NSString *email = [[self class] matchSingleDoCoMoPrefixedField:@"E:" rawText:rawText trim:YES];
+
+ return [ZXAddressBookParsedResult addressBookParsedResultWithNames:[self maybeWrap:fullName]
+ nicknames:nil
+ pronunciation:nil
+ phoneNumbers:[self buildPhoneNumbers:phoneNumber1 number2:phoneNumber2 number3:phoneNumber3]
+ phoneTypes:nil
+ emails:[self maybeWrap:email]
+ emailTypes:nil
+ instantMessenger:nil
+ note:nil
+ addresses:addresses
+ addressTypes:nil
+ org:org
+ birthday:nil
+ title:title
+ urls:nil
+ geo:nil];
+}
+
+- (NSArray *)buildPhoneNumbers:(NSString *)number1 number2:(NSString *)number2 number3:(NSString *)number3 {
+ NSMutableArray *numbers = [NSMutableArray arrayWithCapacity:3];
+ if (number1 != nil) {
+ [numbers addObject:number1];
+ }
+ if (number2 != nil) {
+ [numbers addObject:number2];
+ }
+ if (number3 != nil) {
+ [numbers addObject:number3];
+ }
+ NSUInteger size = [numbers count];
+ if (size == 0) {
+ return nil;
+ }
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:size];
+ for (int i = 0; i < size; i++) {
+ [result addObject:numbers[i]];
+ }
+ return result;
+}
+
+- (NSString *)buildName:(NSString *)firstName lastName:(NSString *)lastName {
+ if (firstName == nil) {
+ return lastName;
+ } else {
+ return lastName == nil ? firstName : [[firstName stringByAppendingString:@" "] stringByAppendingString:lastName];
+ }
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.h b/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.h
new file mode 100644
index 0000000..bb9ca2d
--- /dev/null
+++ b/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.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 "ZXAbstractDoCoMoResultParser.h"
+
+@interface ZXBookmarkDoCoMoResultParser : ZXAbstractDoCoMoResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.m b/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.m
new file mode 100644
index 0000000..50f50a5
--- /dev/null
+++ b/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.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 "ZXBookmarkDoCoMoResultParser.h"
+#import "ZXResult.h"
+#import "ZXURIParsedResult.h"
+#import "ZXURIResultParser.h"
+
+@implementation ZXBookmarkDoCoMoResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [result text];
+ if (![rawText hasPrefix:@"MEBKM:"]) {
+ return nil;
+ }
+ NSString *title = [[self class] matchSingleDoCoMoPrefixedField:@"TITLE:" rawText:rawText trim:YES];
+ NSArray *rawUri = [[self class] matchDoCoMoPrefixedField:@"URL:" rawText:rawText trim:YES];
+ if (rawUri == nil) {
+ return nil;
+ }
+ NSString *uri = rawUri[0];
+ if (![ZXURIResultParser isBasicallyValidURI:uri]) {
+ return nil;
+ }
+ return [ZXURIParsedResult uriParsedResultWithUri:uri title:title];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXCalendarParsedResult.h b/ZXingObjC/client/result/ZXCalendarParsedResult.h
new file mode 100644
index 0000000..78fa38b
--- /dev/null
+++ b/ZXingObjC/client/result/ZXCalendarParsedResult.h
@@ -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 "ZXParsedResult.h"
+
+@interface ZXCalendarParsedResult : ZXParsedResult
+
+@property (nonatomic, strong, readonly) NSString *summary;
+@property (nonatomic, strong, readonly) NSDate *start;
+@property (nonatomic, readonly) BOOL startAllDay;
+@property (nonatomic, strong, readonly) NSDate *end;
+@property (nonatomic, readonly) BOOL endAllDay;
+@property (nonatomic, strong, readonly) NSString *location;
+@property (nonatomic, strong, readonly) NSString *organizer;
+@property (nonatomic, strong, readonly) NSArray *attendees;
+@property (nonatomic, strong, readonly) NSString *zxDescription;
+@property (nonatomic, readonly) double latitude;
+@property (nonatomic, readonly) double longitude;
+
+- (id)initWithSummary:(NSString *)summary startString:(NSString *)startString endString:(NSString *)endString
+ durationString:(NSString *)durationString location:(NSString *)location organizer:(NSString *)organizer
+ attendees:(NSArray *)attendees description:(NSString *)description latitude:(double)latitude
+ longitude:(double)longitude;
++ (id)calendarParsedResultWithSummary:(NSString *)summary startString:(NSString *)startString
+ endString:(NSString *)endString durationString:(NSString *)durationString
+ location:(NSString *)location organizer:(NSString *)organizer
+ attendees:(NSArray *)attendees description:(NSString *)description latitude:(double)latitude
+ longitude:(double)longitude;
+
+@end
diff --git a/ZXingObjC/client/result/ZXCalendarParsedResult.m b/ZXingObjC/client/result/ZXCalendarParsedResult.m
new file mode 100644
index 0000000..f679384
--- /dev/null
+++ b/ZXingObjC/client/result/ZXCalendarParsedResult.m
@@ -0,0 +1,155 @@
+/*
+ * 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 "ZXCalendarParsedResult.h"
+
+static NSRegularExpression *DATE_TIME = nil;
+static NSRegularExpression *RFC2445_DURATION = nil;
+static NSDateFormatter *DATE_FORMAT = nil;
+static NSDateFormatter *DATE_TIME_FORMAT = nil;
+
+const int RFC2445_DURATION_FIELD_UNITS_LEN = 5;
+const long RFC2445_DURATION_FIELD_UNITS[RFC2445_DURATION_FIELD_UNITS_LEN] = {
+ 7 * 24 * 60 * 60 * 1000, // 1 week
+ 24 * 60 * 60 * 1000, // 1 day
+ 60 * 60 * 1000, // 1 hour
+ 60 * 1000, // 1 minute
+ 1000, // 1 second
+};
+
+@implementation ZXCalendarParsedResult
+
++ (void)initialize {
+ DATE_TIME = [[NSRegularExpression alloc] initWithPattern:@"[0-9]{8}(T[0-9]{6}Z?)?"
+ options:0
+ error:nil];
+
+ RFC2445_DURATION = [[NSRegularExpression alloc] initWithPattern:@"P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?"
+ options:NSRegularExpressionCaseInsensitive
+ error:nil];
+
+ DATE_FORMAT = [[NSDateFormatter alloc] init];
+ DATE_FORMAT.dateFormat = @"yyyyMMdd";
+
+ DATE_TIME_FORMAT = [[NSDateFormatter alloc] init];
+ DATE_TIME_FORMAT.dateFormat = @"yyyyMMdd'T'HHmmss";
+}
+
+- (id)initWithSummary:(NSString *)summary startString:(NSString *)startString endString:(NSString *)endString
+ durationString:(NSString *)durationString location:(NSString *)location organizer:(NSString *)organizer
+ attendees:(NSArray *)attendees description:(NSString *)description latitude:(double)latitude
+ longitude:(double)longitude {
+ if (self = [super initWithType:kParsedResultTypeCalendar]) {
+ _summary = summary;
+ _start = [self parseDate:startString];
+
+ if (endString == nil) {
+ long durationMS = [self parseDurationMS:durationString];
+ _end = durationMS < 0 ? nil : [NSDate dateWithTimeIntervalSince1970:[_start timeIntervalSince1970] + durationMS / 1000];
+ } else {
+ _end = [self parseDate:endString];
+ }
+
+ _startAllDay = startString.length == 8;
+ _endAllDay = endString != nil && endString.length == 8;
+
+ _location = location;
+ _organizer = organizer;
+ _attendees = attendees;
+ _zxDescription = description;
+ _latitude = latitude;
+ _longitude = longitude;
+ }
+ return self;
+}
+
++ (id)calendarParsedResultWithSummary:(NSString *)summary startString:(NSString *)startString
+ endString:(NSString *)endString durationString:(NSString *)durationString
+ location:(NSString *)location organizer:(NSString *)organizer
+ attendees:(NSArray *)attendees description:(NSString *)description latitude:(double)latitude
+ longitude:(double)longitude {
+ return [[self alloc] initWithSummary:summary startString:startString endString:endString durationString:durationString
+ location:location organizer:organizer attendees:attendees description:description
+ latitude:latitude longitude:longitude];
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString stringWithCapacity:100];
+ [ZXParsedResult maybeAppend:self.summary result:result];
+ [ZXParsedResult maybeAppend:[self format:self.startAllDay date:self.start] result:result];
+ [ZXParsedResult maybeAppend:[self format:self.endAllDay date:self.end] result:result];
+ [ZXParsedResult maybeAppend:self.location result:result];
+ [ZXParsedResult maybeAppend:self.organizer result:result];
+ [ZXParsedResult maybeAppendArray:self.attendees result:result];
+ [ZXParsedResult maybeAppend:self.zxDescription result:result];
+ return result;
+}
+
+
+/**
+ * Parses a string as a date. RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021)
+ * or DATE-TIME (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC).
+ */
+- (NSDate *)parseDate:(NSString *)when {
+ NSArray *matches = [DATE_TIME matchesInString:when options:0 range:NSMakeRange(0, when.length)];
+ if (matches.count == 0) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Invalid date"];
+ }
+ if (when.length == 8) {
+ // Show only year/month/day
+ return [DATE_FORMAT dateFromString:when];
+ } else {
+ // The when string can be local time, or UTC if it ends with a Z
+ if (when.length == 16 && [when characterAtIndex:15] == 'Z') {
+ return [DATE_TIME_FORMAT dateFromString:[when substringToIndex:15]];
+ } else {
+ return [DATE_TIME_FORMAT dateFromString:when];
+ }
+ }
+}
+
+- (NSString *)format:(BOOL)allDay date:(NSDate *)date {
+ if (date == nil) {
+ return nil;
+ }
+ NSDateFormatter *format = [[NSDateFormatter alloc] init];
+ format.dateFormat = allDay ? @"MMM d, yyyy" : @"MMM d, yyyy hh:mm:ss a";
+ return [format stringFromDate:date];
+}
+
+- (long)parseDurationMS:(NSString *)durationString {
+ if (durationString == nil) {
+ return -1;
+ }
+ NSArray *m = [RFC2445_DURATION matchesInString:durationString options:0 range:NSMakeRange(0, durationString.length)];
+ if (m.count == 0) {
+ return -1;
+ }
+ long durationMS = 0;
+ NSTextCheckingResult *match = m[0];
+ for (int i = 0; i < RFC2445_DURATION_FIELD_UNITS_LEN; i++) {
+ if ([match rangeAtIndex:i + 1].location != NSNotFound) {
+ NSString *fieldValue = [durationString substringWithRange:[match rangeAtIndex:i + 1]];
+ if (fieldValue != nil) {
+ durationMS += RFC2445_DURATION_FIELD_UNITS[i] * [fieldValue intValue];
+ }
+ }
+ }
+ return durationMS;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXEmailAddressParsedResult.h b/ZXingObjC/client/result/ZXEmailAddressParsedResult.h
new file mode 100644
index 0000000..b55010b
--- /dev/null
+++ b/ZXingObjC/client/result/ZXEmailAddressParsedResult.h
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@interface ZXEmailAddressParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *body;
+@property (nonatomic, copy, readonly) NSString *emailAddress;
+@property (nonatomic, copy, readonly) NSString *mailtoURI;
+@property (nonatomic, copy, readonly) NSString *subject;
+
+- (id)initWithEmailAddress:(NSString *)emailAddress subject:(NSString *)subject body:(NSString *)body
+ mailtoURI:(NSString *)mailtoURI;
++ (id)emailAddressParsedResultWithEmailAddress:(NSString *)emailAddress subject:(NSString *)subject
+ body:(NSString *)body mailtoURI:(NSString *)mailtoURI;
+
+@end
diff --git a/ZXingObjC/client/result/ZXEmailAddressParsedResult.m b/ZXingObjC/client/result/ZXEmailAddressParsedResult.m
new file mode 100644
index 0000000..4cfc001
--- /dev/null
+++ b/ZXingObjC/client/result/ZXEmailAddressParsedResult.m
@@ -0,0 +1,45 @@
+/*
+ * 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 "ZXEmailAddressParsedResult.h"
+#import "ZXParsedResultType.h"
+
+@implementation ZXEmailAddressParsedResult
+
+- (id)initWithEmailAddress:(NSString *)emailAddress subject:(NSString *)subject body:(NSString *)body mailtoURI:(NSString *)mailtoURI {
+ if (self = [super initWithType:kParsedResultTypeEmailAddress]) {
+ _emailAddress = emailAddress;
+ _subject = subject;
+ _body = body;
+ _mailtoURI = mailtoURI;
+ }
+
+ return self;
+}
+
++ (id)emailAddressParsedResultWithEmailAddress:(NSString *)emailAddress subject:(NSString *)subject body:(NSString *)body mailtoURI:(NSString *)mailtoURI {
+ return [[self alloc] initWithEmailAddress:emailAddress subject:subject body:body mailtoURI:mailtoURI];
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString stringWithCapacity:30];
+ [ZXParsedResult maybeAppend:self.emailAddress result:result];
+ [ZXParsedResult maybeAppend:self.subject result:result];
+ [ZXParsedResult maybeAppend:self.body result:result];
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXEmailAddressResultParser.h b/ZXingObjC/client/result/ZXEmailAddressResultParser.h
new file mode 100644
index 0000000..827673f
--- /dev/null
+++ b/ZXingObjC/client/result/ZXEmailAddressResultParser.h
@@ -0,0 +1,26 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Represents a result that encodes an e-mail address, either as a plain address
+ * like "joe@example.org" or a mailto: URL like "mailto:joe@example.org".
+ */
+
+@interface ZXEmailAddressResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXEmailAddressResultParser.m b/ZXingObjC/client/result/ZXEmailAddressResultParser.m
new file mode 100644
index 0000000..1db5c83
--- /dev/null
+++ b/ZXingObjC/client/result/ZXEmailAddressResultParser.m
@@ -0,0 +1,60 @@
+/*
+ * 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 "ZXEmailAddressParsedResult.h"
+#import "ZXEmailAddressResultParser.h"
+#import "ZXEmailDoCoMoResultParser.h"
+#import "ZXResult.h"
+
+@implementation ZXEmailAddressResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ NSString *emailAddress;
+ if ([rawText hasPrefix:@"mailto:"] || [rawText hasPrefix:@"MAILTO:"]) {
+ emailAddress = [rawText substringFromIndex:7];
+ NSUInteger queryStart = [emailAddress rangeOfString:@"?"].location;
+ if (queryStart != NSNotFound) {
+ emailAddress = [emailAddress substringToIndex:queryStart];
+ }
+ emailAddress = [[self class] urlDecode:emailAddress];
+ NSMutableDictionary *nameValues = [self parseNameValuePairs:rawText];
+ NSString *subject = nil;
+ NSString *body = nil;
+ if (nameValues != nil) {
+ if ([emailAddress length] == 0) {
+ emailAddress = nameValues[@"to"];
+ }
+ subject = nameValues[@"subject"];
+ body = nameValues[@"body"];
+ }
+ return [ZXEmailAddressParsedResult emailAddressParsedResultWithEmailAddress:emailAddress
+ subject:subject
+ body:body
+ mailtoURI:rawText];
+ } else {
+ if (![ZXEmailDoCoMoResultParser isBasicallyValidEmailAddress:rawText]) {
+ return nil;
+ }
+ emailAddress = rawText;
+ return [ZXEmailAddressParsedResult emailAddressParsedResultWithEmailAddress:emailAddress
+ subject:nil
+ body:nil
+ mailtoURI:[@"mailto:" stringByAppendingString:emailAddress]];
+ }
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.h b/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.h
new file mode 100644
index 0000000..838b558
--- /dev/null
+++ b/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.h
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXAbstractDoCoMoResultParser.h"
+
+/**
+ * Implements the "MATMSG" email message entry format.
+ *
+ * Supported keys: TO, SUB, BODY
+ */
+
+@interface ZXEmailDoCoMoResultParser : ZXAbstractDoCoMoResultParser
+
++ (BOOL)isBasicallyValidEmailAddress:(NSString *)email;
+
+@end
diff --git a/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.m b/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.m
new file mode 100644
index 0000000..cb5e07f
--- /dev/null
+++ b/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.m
@@ -0,0 +1,63 @@
+/*
+ * 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 "ZXEmailAddressParsedResult.h"
+#import "ZXEmailDoCoMoResultParser.h"
+#import "ZXResult.h"
+
+static NSRegularExpression *ATEXT_ALPHANUMERIC = nil;
+
+@implementation ZXEmailDoCoMoResultParser
+
++ (void)initialize {
+ ATEXT_ALPHANUMERIC = [[NSRegularExpression alloc] initWithPattern:@"^[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+$"
+ options:0 error:nil];
+}
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (![rawText hasPrefix:@"MATMSG:"]) {
+ return nil;
+ }
+ NSArray *rawTo = [[self class] matchDoCoMoPrefixedField:@"TO:" rawText:rawText trim:YES];
+ if (rawTo == nil) {
+ return nil;
+ }
+ NSString *to = rawTo[0];
+ if (![[self class] isBasicallyValidEmailAddress:to]) {
+ return nil;
+ }
+ NSString *subject = [[self class] matchSingleDoCoMoPrefixedField:@"SUB:" rawText:rawText trim:NO];
+ NSString *body = [[self class] matchSingleDoCoMoPrefixedField:@"BODY:" rawText:rawText trim:NO];
+
+ return [ZXEmailAddressParsedResult emailAddressParsedResultWithEmailAddress:to
+ subject:subject
+ body:body
+ mailtoURI:[@"mailto:" stringByAppendingString:to]];
+}
+
+
+/**
+ * This implements only the most basic checking for an email address's validity -- that it contains
+ * an '@' and contains no characters disallowed by RFC 2822. This is an overly lenient definition of
+ * validity. We want to generally be lenient here since this class is only intended to encapsulate what's
+ * in a barcode, not "judge" it.
+ */
++ (BOOL)isBasicallyValidEmailAddress:(NSString *)email {
+ return email != nil && [ATEXT_ALPHANUMERIC numberOfMatchesInString:email options:0 range:NSMakeRange(0, email.length)] > 0 && [email rangeOfString:@"@"].location != NSNotFound;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXExpandedProductParsedResult.h b/ZXingObjC/client/result/ZXExpandedProductParsedResult.h
new file mode 100644
index 0000000..3341d6d
--- /dev/null
+++ b/ZXingObjC/client/result/ZXExpandedProductParsedResult.h
@@ -0,0 +1,54 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+extern NSString * const ZX_KILOGRAM;
+extern NSString * const ZX_POUND;
+
+@interface ZXExpandedProductParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *rawText;
+@property (nonatomic, copy, readonly) NSString *productID;
+@property (nonatomic, copy, readonly) NSString *sscc;
+@property (nonatomic, copy, readonly) NSString *lotNumber;
+@property (nonatomic, copy, readonly) NSString *productionDate;
+@property (nonatomic, copy, readonly) NSString *packagingDate;
+@property (nonatomic, copy, readonly) NSString *bestBeforeDate;
+@property (nonatomic, copy, readonly) NSString *expirationDate;
+@property (nonatomic, copy, readonly) NSString *weight;
+@property (nonatomic, copy, readonly) NSString *weightType;
+@property (nonatomic, copy, readonly) NSString *weightIncrement;
+@property (nonatomic, copy, readonly) NSString *price;
+@property (nonatomic, copy, readonly) NSString *priceIncrement;
+@property (nonatomic, copy, readonly) NSString *priceCurrency;
+@property (nonatomic, strong, readonly) NSMutableDictionary *uncommonAIs;
+
+- (id)initWithRawText:(NSString *)rawText productID:(NSString *)productID sscc:(NSString *)sscc
+ lotNumber:(NSString *)lotNumber productionDate:(NSString *)productionDate
+ packagingDate:(NSString *)packagingDate bestBeforeDate:(NSString *)bestBeforeDate
+ expirationDate:(NSString *)expirationDate weight:(NSString *)weight weightType:(NSString *)weightType
+ weightIncrement:(NSString *)weightIncrement price:(NSString *)price priceIncrement:(NSString *)priceIncrement
+ priceCurrency:(NSString *)priceCurrency uncommonAIs:(NSMutableDictionary *)uncommonAIs;
++ (id)expandedProductParsedResultWithRawText:(NSString *)rawText productID:(NSString *)productID sscc:(NSString *)sscc
+ lotNumber:(NSString *)lotNumber productionDate:(NSString *)productionDate
+ packagingDate:(NSString *)packagingDate bestBeforeDate:(NSString *)bestBeforeDate
+ expirationDate:(NSString *)expirationDate weight:(NSString *)weight
+ weightType:(NSString *)weightType weightIncrement:(NSString *)weightIncrement
+ price:(NSString *)price priceIncrement:(NSString *)priceIncrement
+ priceCurrency:(NSString *)priceCurrency uncommonAIs:(NSMutableDictionary *)uncommonAIs;
+
+@end
diff --git a/ZXingObjC/client/result/ZXExpandedProductParsedResult.m b/ZXingObjC/client/result/ZXExpandedProductParsedResult.m
new file mode 100644
index 0000000..f217dc8
--- /dev/null
+++ b/ZXingObjC/client/result/ZXExpandedProductParsedResult.m
@@ -0,0 +1,119 @@
+/*
+ * 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 "ZXExpandedProductParsedResult.h"
+
+NSString * const ZX_KILOGRAM = @"KG";
+NSString * const ZX_POUND = @"LB";
+
+@implementation ZXExpandedProductParsedResult
+
+- (id)init {
+ return [self initWithRawText:@"" productID:@"" sscc:@"" lotNumber:@"" productionDate:@"" packagingDate:@""
+ bestBeforeDate:@"" expirationDate:@"" weight:@"" weightType:@"" weightIncrement:@"" price:@""
+ priceIncrement:@"" priceCurrency:@"" uncommonAIs:[NSMutableDictionary dictionary]];
+}
+
+- (id)initWithRawText:(NSString *)rawText productID:(NSString *)productID sscc:(NSString *)sscc
+ lotNumber:(NSString *)lotNumber productionDate:(NSString *)productionDate
+ packagingDate:(NSString *)packagingDate bestBeforeDate:(NSString *)bestBeforeDate
+ expirationDate:(NSString *)expirationDate weight:(NSString *)weight weightType:(NSString *)weightType
+ weightIncrement:(NSString *)weightIncrement price:(NSString *)price priceIncrement:(NSString *)priceIncrement
+ priceCurrency:(NSString *)priceCurrency uncommonAIs:(NSMutableDictionary *)uncommonAIs {
+ if (self = [super initWithType:kParsedResultTypeProduct]) {
+ _rawText = rawText;
+ _productID = productID;
+ _sscc = sscc;
+ _lotNumber = lotNumber;
+ _productionDate = productionDate;
+ _packagingDate = packagingDate;
+ _bestBeforeDate = bestBeforeDate;
+ _expirationDate = expirationDate;
+ _weight = weight;
+ _weightType = weightType;
+ _weightIncrement = weightIncrement;
+ _price = price;
+ _priceIncrement = priceIncrement;
+ _priceCurrency = priceCurrency;
+ _uncommonAIs = uncommonAIs;
+ }
+
+ return self;
+}
+
++ (id)expandedProductParsedResultWithRawText:(NSString *)rawText productID:(NSString *)productID sscc:(NSString *)sscc
+ lotNumber:(NSString *)lotNumber productionDate:(NSString *)productionDate
+ packagingDate:(NSString *)packagingDate bestBeforeDate:(NSString *)bestBeforeDate
+ expirationDate:(NSString *)expirationDate weight:(NSString *)weight
+ weightType:(NSString *)weightType weightIncrement:(NSString *)weightIncrement
+ price:(NSString *)price priceIncrement:(NSString *)priceIncrement
+ priceCurrency:(NSString *)priceCurrency uncommonAIs:(NSMutableDictionary *)uncommonAIs {
+ return [[self alloc] initWithRawText:rawText productID:productID sscc:sscc lotNumber:lotNumber
+ productionDate:productionDate packagingDate:packagingDate bestBeforeDate:bestBeforeDate
+ expirationDate:expirationDate weight:weight weightType:weightType
+ weightIncrement:weightIncrement price:price priceIncrement:priceIncrement
+ priceCurrency:priceCurrency uncommonAIs:uncommonAIs];
+}
+
+- (BOOL)isEqual:(id)o {
+ if (![o isKindOfClass:[self class]]) {
+ return NO;
+ }
+
+ ZXExpandedProductParsedResult *other = (ZXExpandedProductParsedResult *)o;
+
+ return [self equalsOrNil:self.productID o2:other.productID]
+ && [self equalsOrNil:self.sscc o2:other.sscc]
+ && [self equalsOrNil:self.lotNumber o2:other.lotNumber]
+ && [self equalsOrNil:self.productionDate o2:other.productionDate]
+ && [self equalsOrNil:self.bestBeforeDate o2:other.bestBeforeDate]
+ && [self equalsOrNil:self.expirationDate o2:other.expirationDate]
+ && [self equalsOrNil:self.weight o2:other.weight]
+ && [self equalsOrNil:self.weightType o2:other.weightType]
+ && [self equalsOrNil:self.weightIncrement o2:other.weightIncrement]
+ && [self equalsOrNil:self.price o2:other.price]
+ && [self equalsOrNil:self.priceIncrement o2:other.priceIncrement]
+ && [self equalsOrNil:self.priceCurrency o2:other.priceCurrency]
+ && [self equalsOrNil:self.uncommonAIs o2:other.uncommonAIs];
+}
+
+- (BOOL)equalsOrNil:(id)o1 o2:(id)o2 {
+ return o1 == nil ? o2 == nil : [o1 isEqual:o2];
+}
+
+- (NSUInteger)hash {
+ int hash = 0;
+ hash ^= [self.productID hash];
+ hash ^= [self.sscc hash];
+ hash ^= [self.lotNumber hash];
+ hash ^= [self.productionDate hash];
+ hash ^= [self.bestBeforeDate hash];
+ hash ^= [self.expirationDate hash];
+ hash ^= [self.weight hash];
+ hash ^= [self.weightType hash];
+ hash ^= [self.weightIncrement hash];
+ hash ^= [self.price hash];
+ hash ^= [self.priceIncrement hash];
+ hash ^= [self.priceCurrency hash];
+ hash ^= [self.uncommonAIs hash];
+ return hash;
+}
+
+- (NSString *)displayResult {
+ return self.rawText;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXExpandedProductResultParser.h b/ZXingObjC/client/result/ZXExpandedProductResultParser.h
new file mode 100644
index 0000000..b7049c8
--- /dev/null
+++ b/ZXingObjC/client/result/ZXExpandedProductResultParser.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses strings of digits that represent a RSS Extended code.
+ */
+
+@interface ZXExpandedProductResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXExpandedProductResultParser.m b/ZXingObjC/client/result/ZXExpandedProductResultParser.m
new file mode 100644
index 0000000..1722c7f
--- /dev/null
+++ b/ZXingObjC/client/result/ZXExpandedProductResultParser.m
@@ -0,0 +1,157 @@
+/*
+ * 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 "ZXExpandedProductResultParser.h"
+#import "ZXExpandedProductParsedResult.h"
+#import "ZXResult.h"
+
+@implementation ZXExpandedProductResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ ZXBarcodeFormat format = [result barcodeFormat];
+ if (kBarcodeFormatRSSExpanded != format) {
+ return nil;
+ }
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (rawText == nil) {
+ return nil;
+ }
+
+ NSString *productID = nil;
+ NSString *sscc = nil;
+ NSString *lotNumber = nil;
+ NSString *productionDate = nil;
+ NSString *packagingDate = nil;
+ NSString *bestBeforeDate = nil;
+ NSString *expirationDate = nil;
+ NSString *weight = nil;
+ NSString *weightType = nil;
+ NSString *weightIncrement = nil;
+ NSString *price = nil;
+ NSString *priceIncrement = nil;
+ NSString *priceCurrency = nil;
+ NSMutableDictionary *uncommonAIs = [NSMutableDictionary dictionary];
+
+ int i = 0;
+
+ while (i < [rawText length]) {
+ NSString *ai = [self findAIvalue:i rawText:rawText];
+ if (ai == nil) {
+ // Error. Code doesn't match with RSS expanded pattern
+ // ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern
+ return nil;
+ }
+ i += [ai length] + 2;
+ NSString *value = [self findValue:i rawText:rawText];
+ i += [value length];
+
+ if ([@"00" isEqualToString:ai]) {
+ sscc = value;
+ } else if ([@"01" isEqualToString:ai]) {
+ productID = value;
+ } else if ([@"10" isEqualToString:ai]) {
+ lotNumber = value;
+ } else if ([@"11" isEqualToString:ai]) {
+ productionDate = value;
+ } else if ([@"13" isEqualToString:ai]) {
+ packagingDate = value;
+ } else if ([@"15" isEqualToString:ai]) {
+ bestBeforeDate = value;
+ } else if ([@"17" isEqualToString:ai]) {
+ expirationDate = value;
+ } else if ([@"3100" isEqualToString:ai] || [@"3101" isEqualToString:ai] || [@"3102" isEqualToString:ai] || [@"3103" isEqualToString:ai] || [@"3104" isEqualToString:ai] || [@"3105" isEqualToString:ai] || [@"3106" isEqualToString:ai] || [@"3107" isEqualToString:ai] || [@"3108" isEqualToString:ai] || [@"3109" isEqualToString:ai]) {
+ weight = value;
+ weightType = ZX_KILOGRAM;
+ weightIncrement = [ai substringFromIndex:3];
+ } else if ([@"3200" isEqualToString:ai] || [@"3201" isEqualToString:ai] || [@"3202" isEqualToString:ai] || [@"3203" isEqualToString:ai] || [@"3204" isEqualToString:ai] || [@"3205" isEqualToString:ai] || [@"3206" isEqualToString:ai] || [@"3207" isEqualToString:ai] || [@"3208" isEqualToString:ai] || [@"3209" isEqualToString:ai]) {
+ weight = value;
+ weightType = ZX_POUND;
+ weightIncrement = [ai substringFromIndex:3];
+ } else if ([@"3920" isEqualToString:ai] || [@"3921" isEqualToString:ai] || [@"3922" isEqualToString:ai] || [@"3923" isEqualToString:ai]) {
+ price = value;
+ priceIncrement = [ai substringFromIndex:3];
+ } else if ([@"3930" isEqualToString:ai] || [@"3931" isEqualToString:ai] || [@"3932" isEqualToString:ai] || [@"3933" isEqualToString:ai]) {
+ if ([value length] < 4) {
+ return nil;
+ }
+ price = [value substringFromIndex:3];
+ priceCurrency = [value substringToIndex:3];
+ priceIncrement = [ai substringFromIndex:3];
+ } else {
+ uncommonAIs[ai] = value;
+ }
+ }
+
+ return [ZXExpandedProductParsedResult expandedProductParsedResultWithRawText:rawText
+ productID:productID
+ sscc:sscc
+ lotNumber:lotNumber
+ productionDate:productionDate
+ packagingDate:packagingDate
+ bestBeforeDate:bestBeforeDate
+ expirationDate:expirationDate
+ weight:weight
+ weightType:weightType
+ weightIncrement:weightIncrement
+ price:price
+ priceIncrement:priceIncrement
+ priceCurrency:priceCurrency
+ uncommonAIs:uncommonAIs];
+}
+
+- (NSString *)findAIvalue:(int)i rawText:(NSString *)rawText {
+ unichar c = [rawText characterAtIndex:i];
+ if (c != '(') {
+ return nil;
+ }
+
+ NSString *rawTextAux = [rawText substringFromIndex:i + 1];
+
+ NSMutableString *buf = [NSMutableString string];
+ for (int index = 0; index < [rawTextAux length]; index++) {
+ unichar currentChar = [rawTextAux characterAtIndex:index];
+ if (currentChar == ')') {
+ return buf;
+ } else if (currentChar >= '0' && currentChar <= '9') {
+ [buf appendFormat:@"%C", currentChar];
+ } else {
+ return nil;
+ }
+ }
+ return buf;
+}
+
+- (NSString *)findValue:(int)i rawText:(NSString *)rawText {
+ NSMutableString *buf = [NSMutableString string];
+ NSString *rawTextAux = [rawText substringFromIndex:i];
+
+ for (int index = 0; index < [rawTextAux length]; index++) {
+ unichar c = [rawTextAux characterAtIndex:index];
+ if (c == '(') {
+ if ([self findAIvalue:index rawText:rawTextAux] == nil) {
+ [buf appendString:@"("];
+ } else {
+ break;
+ }
+ } else {
+ [buf appendFormat:@"%C", c];
+ }
+ }
+
+ return buf;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXGeoParsedResult.h b/ZXingObjC/client/result/ZXGeoParsedResult.h
new file mode 100644
index 0000000..aa44a03
--- /dev/null
+++ b/ZXingObjC/client/result/ZXGeoParsedResult.h
@@ -0,0 +1,30 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@interface ZXGeoParsedResult : ZXParsedResult
+
+@property (nonatomic, readonly) double latitude;
+@property (nonatomic, readonly) double longitude;
+@property (nonatomic, readonly) double altitude;
+@property (nonatomic, copy, readonly) NSString *query;
+
+- (id)initWithLatitude:(double)latitude longitude:(double)longitude altitude:(double)altitude query:(NSString *)query;
++ (id)geoParsedResultWithLatitude:(double)latitude longitude:(double)longitude altitude:(double)altitude query:(NSString *)query;
+- (NSString *)geoURI;
+
+@end
diff --git a/ZXingObjC/client/result/ZXGeoParsedResult.m b/ZXingObjC/client/result/ZXGeoParsedResult.m
new file mode 100644
index 0000000..d2ec38b
--- /dev/null
+++ b/ZXingObjC/client/result/ZXGeoParsedResult.m
@@ -0,0 +1,62 @@
+/*
+ * 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 "ZXGeoParsedResult.h"
+#import "ZXParsedResultType.h"
+
+@implementation ZXGeoParsedResult
+
+- (id)initWithLatitude:(double)latitude longitude:(double)longitude altitude:(double)altitude query:(NSString *)query {
+ if (self = [super initWithType:kParsedResultTypeGeo]) {
+ _latitude = latitude;
+ _longitude = longitude;
+ _altitude = altitude;
+ _query = query;
+ }
+
+ return self;
+}
+
++ (id)geoParsedResultWithLatitude:(double)latitude longitude:(double)longitude altitude:(double)altitude query:(NSString *)query {
+ return [[self alloc] initWithLatitude:latitude longitude:longitude altitude:altitude query:query];
+}
+
+- (NSString *)geoURI {
+ NSMutableString *result = [NSMutableString string];
+ [result appendFormat:@"geo:%f,%f", self.latitude, self.longitude];
+ if (self.altitude > 0) {
+ [result appendFormat:@",%f", self.altitude];
+ }
+ if (self.query != nil) {
+ [result appendFormat:@"?%@", self.query];
+ }
+ return result;
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString string];
+ [result appendFormat:@"%f, %f", self.latitude, self.longitude];
+ if (self.altitude > 0.0) {
+ [result appendFormat:@", %f", self.altitude];
+ [result appendString:@"m"];
+ }
+ if (self.query != nil) {
+ [result appendFormat:@" (%@)", self.query];
+ }
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXGeoResultParser.h b/ZXingObjC/client/result/ZXGeoResultParser.h
new file mode 100644
index 0000000..751897a
--- /dev/null
+++ b/ZXingObjC/client/result/ZXGeoResultParser.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses a "geo:" URI result, which specifies a location on the surface of
+ * the Earth as well as an optional altitude above the surface. See
+ * http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00.
+ */
+
+@interface ZXGeoResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXGeoResultParser.m b/ZXingObjC/client/result/ZXGeoResultParser.m
new file mode 100644
index 0000000..7a6a2d9
--- /dev/null
+++ b/ZXingObjC/client/result/ZXGeoResultParser.m
@@ -0,0 +1,68 @@
+/*
+ * 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 "ZXGeoParsedResult.h"
+#import "ZXGeoResultParser.h"
+
+static NSRegularExpression *GEO_URL_PATTERN = nil;
+
+@implementation ZXGeoResultParser
+
++ (void)initialize {
+ GEO_URL_PATTERN = [[NSRegularExpression alloc] initWithPattern:@"geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?"
+ options:NSRegularExpressionCaseInsensitive error:nil];
+
+}
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (rawText == nil || (![rawText hasPrefix:@"geo:"] && ![rawText hasPrefix:@"GEO:"])) {
+ return nil;
+ }
+
+ NSArray *matches = [GEO_URL_PATTERN matchesInString:rawText options:0 range:NSMakeRange(0, rawText.length)];
+ if (matches.count == 0) {
+ return nil;
+ }
+
+ NSTextCheckingResult *match = matches[0];
+ NSString *query = nil;
+ if ([match rangeAtIndex:4].location != NSNotFound) {
+ query = [rawText substringWithRange:[match rangeAtIndex:4]];
+ }
+
+ double latitude = [[rawText substringWithRange:[match rangeAtIndex:1]] doubleValue];
+ if (latitude > 90.0 || latitude < -90.0) {
+ return nil;
+ }
+ double longitude = [[rawText substringWithRange:[match rangeAtIndex:2]] doubleValue];
+ if (longitude > 180.0 || longitude < -180.0) {
+ return nil;
+ }
+ double altitude;
+ if ([match rangeAtIndex:3].location == NSNotFound) {
+ altitude = 0.0;
+ } else {
+ altitude = [[rawText substringWithRange:[match rangeAtIndex:3]] doubleValue];
+ if (altitude < 0.0) {
+ return nil;
+ }
+ }
+
+ return [ZXGeoParsedResult geoParsedResultWithLatitude:latitude longitude:longitude altitude:altitude query:query];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXISBNParsedResult.h b/ZXingObjC/client/result/ZXISBNParsedResult.h
new file mode 100644
index 0000000..76adecb
--- /dev/null
+++ b/ZXingObjC/client/result/ZXISBNParsedResult.h
@@ -0,0 +1,26 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@interface ZXISBNParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *isbn;
+
+- (id)initWithIsbn:(NSString *)isbn;
++ (id)isbnParsedResultWithIsbn:(NSString *)isbn;
+
+@end
diff --git a/ZXingObjC/client/result/ZXISBNParsedResult.m b/ZXingObjC/client/result/ZXISBNParsedResult.m
new file mode 100644
index 0000000..22f2aab
--- /dev/null
+++ b/ZXingObjC/client/result/ZXISBNParsedResult.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 "ZXISBNParsedResult.h"
+
+@implementation ZXISBNParsedResult
+
+- (id)initWithIsbn:(NSString *)isbn {
+ if (self = [super initWithType:kParsedResultTypeISBN]) {
+ _isbn = isbn;
+ }
+
+ return self;
+}
+
++ (id)isbnParsedResultWithIsbn:(NSString *)isbn {
+ return [[self alloc] initWithIsbn:isbn];
+}
+
+- (NSString *)displayResult {
+ return self.isbn;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXISBNResultParser.h b/ZXingObjC/client/result/ZXISBNResultParser.h
new file mode 100644
index 0000000..84c75ed
--- /dev/null
+++ b/ZXingObjC/client/result/ZXISBNResultParser.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses strings of digits that represent a ISBN.
+ */
+
+@interface ZXISBNResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXISBNResultParser.m b/ZXingObjC/client/result/ZXISBNResultParser.m
new file mode 100644
index 0000000..ed617f4
--- /dev/null
+++ b/ZXingObjC/client/result/ZXISBNResultParser.m
@@ -0,0 +1,38 @@
+/*
+ * 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 "ZXISBNParsedResult.h"
+#import "ZXISBNResultParser.h"
+
+@implementation ZXISBNResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ ZXBarcodeFormat format = [result barcodeFormat];
+ if (format != kBarcodeFormatEan13) {
+ return nil;
+ }
+ NSString *rawText = [ZXResultParser massagedText:result];
+ NSUInteger length = [rawText length];
+ if (length != 13) {
+ return nil;
+ }
+ if (![rawText hasPrefix:@"978"] && ![rawText hasPrefix:@"979"]) {
+ return nil;
+ }
+ return [ZXISBNParsedResult isbnParsedResultWithIsbn:rawText];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXParsedResult.h b/ZXingObjC/client/result/ZXParsedResult.h
new file mode 100644
index 0000000..a460130
--- /dev/null
+++ b/ZXingObjC/client/result/ZXParsedResult.h
@@ -0,0 +1,40 @@
+/*
+ * 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 "ZXParsedResultType.h"
+#import "ZXResult.h"
+
+/**
+ * Abstract class representing the result of decoding a barcode, as more than
+ * a String -- as some type of structured data. This might be a subclass which represents
+ * a URL, or an e-mail address. parseResult() will turn a raw
+ * decoded string into the most appropriate type of structured representation.
+ *
+ * Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
+ * on exception-based mechanisms during parsing.
+ */
+
+@interface ZXParsedResult : NSObject
+
+@property (nonatomic, readonly) ZXParsedResultType type;
+
+- (id)initWithType:(ZXParsedResultType)type;
++ (id)parsedResultWithType:(ZXParsedResultType)type;
+- (NSString *)displayResult;
++ (void)maybeAppend:(NSString *)value result:(NSMutableString *)result;
++ (void)maybeAppendArray:(NSArray *)value result:(NSMutableString *)result;
+
+@end
diff --git a/ZXingObjC/client/result/ZXParsedResult.m b/ZXingObjC/client/result/ZXParsedResult.m
new file mode 100644
index 0000000..daa2883
--- /dev/null
+++ b/ZXingObjC/client/result/ZXParsedResult.m
@@ -0,0 +1,60 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@implementation ZXParsedResult
+
+- (id)initWithType:(ZXParsedResultType)type {
+ if (self = [super init]) {
+ _type = type;
+ }
+
+ return self;
+}
+
++ (id)parsedResultWithType:(ZXParsedResultType)type {
+ return [[self alloc] initWithType:type];
+}
+
+- (NSString *)displayResult {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+- (NSString *)description {
+ return [self displayResult];
+}
+
++ (void)maybeAppend:(NSString *)value result:(NSMutableString *)result {
+ if (value != nil && (id)value != [NSNull null] && [value length] > 0) {
+ if ([result length] > 0) {
+ [result appendString:@"\n"];
+ }
+ [result appendString:value];
+ }
+}
+
++ (void)maybeAppendArray:(NSArray *)values result:(NSMutableString *)result {
+ if (values != nil) {
+ for (NSString *value in values) {
+ [self maybeAppend:value result:result];
+ }
+ }
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXParsedResultType.h b/ZXingObjC/client/result/ZXParsedResultType.h
new file mode 100644
index 0000000..c097c19
--- /dev/null
+++ b/ZXingObjC/client/result/ZXParsedResultType.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Represents the type of data encoded by a barcode -- from plain text, to a
+ * URI, to an e-mail address, etc.
+ */
+typedef enum {
+ kParsedResultTypeAddressBook,
+ kParsedResultTypeEmailAddress,
+ kParsedResultTypeProduct,
+ kParsedResultTypeURI,
+ kParsedResultTypeText,
+ kParsedResultTypeAndroidIntent,
+ kParsedResultTypeGeo,
+ kParsedResultTypeTel,
+ kParsedResultTypeSMS,
+ kParsedResultTypeCalendar,
+ kParsedResultTypeWifi,
+ kParsedResultTypeNDEFSMartPoster,
+ kParsedResultTypeMobiletagRichWeb,
+ kParsedResultTypeISBN
+} ZXParsedResultType;
diff --git a/ZXingObjC/client/result/ZXProductParsedResult.h b/ZXingObjC/client/result/ZXProductParsedResult.h
new file mode 100644
index 0000000..b2039c0
--- /dev/null
+++ b/ZXingObjC/client/result/ZXProductParsedResult.h
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@interface ZXProductParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *normalizedProductID;
+@property (nonatomic, copy, readonly) NSString *productID;
+
+- (id)initWithProductID:(NSString *)productID;
+- (id)initWithProductID:(NSString *)productID normalizedProductID:(NSString *)normalizedProductID;
++ (id)productParsedResultWithProductID:(NSString *)productID;
++ (id)productParsedResultWithProductID:(NSString *)productID normalizedProductID:(NSString *)normalizedProductID;
+
+@end
diff --git a/ZXingObjC/client/result/ZXProductParsedResult.m b/ZXingObjC/client/result/ZXProductParsedResult.m
new file mode 100644
index 0000000..5fa5371
--- /dev/null
+++ b/ZXingObjC/client/result/ZXProductParsedResult.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 "ZXProductParsedResult.h"
+
+@implementation ZXProductParsedResult
+
+- (id)initWithProductID:(NSString *)productID {
+ return [self initWithProductID:productID normalizedProductID:productID];
+}
+
+- (id)initWithProductID:(NSString *)productID normalizedProductID:(NSString *)normalizedProductID {
+ if (self = [super initWithType:kParsedResultTypeProduct]) {
+ _normalizedProductID = normalizedProductID;
+ _productID = productID;
+ }
+
+ return self;
+}
+
++ (id)productParsedResultWithProductID:(NSString *)productID {
+ return [[self alloc] initWithProductID:productID];
+}
+
++ (id)productParsedResultWithProductID:(NSString *)productID normalizedProductID:(NSString *)normalizedProductID {
+ return [[self alloc] initWithProductID:productID normalizedProductID:normalizedProductID];
+}
+
+- (NSString *)displayResult {
+ return self.productID;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXProductResultParser.h b/ZXingObjC/client/result/ZXProductResultParser.h
new file mode 100644
index 0000000..b2bbf80
--- /dev/null
+++ b/ZXingObjC/client/result/ZXProductResultParser.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses strings of digits that represent a UPC code.
+ */
+
+@interface ZXProductResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXProductResultParser.m b/ZXingObjC/client/result/ZXProductResultParser.m
new file mode 100644
index 0000000..e8a8824
--- /dev/null
+++ b/ZXingObjC/client/result/ZXProductResultParser.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 "ZXBarcodeFormat.h"
+#import "ZXProductParsedResult.h"
+#import "ZXProductResultParser.h"
+#import "ZXUPCEReader.h"
+
+@implementation ZXProductResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ ZXBarcodeFormat format = [result barcodeFormat];
+ if (!(format == kBarcodeFormatUPCA || format == kBarcodeFormatUPCE || format == kBarcodeFormatEan8 || format == kBarcodeFormatEan13)) {
+ return nil;
+ }
+ NSString *rawText = [ZXResultParser massagedText:result];
+ NSUInteger length = [rawText length];
+ for (int x = 0; x < length; x++) {
+ unichar c = [rawText characterAtIndex:x];
+ if (c < '0' || c > '9') {
+ return nil;
+ }
+ }
+
+ NSString *normalizedProductID;
+ if (format == kBarcodeFormatUPCE) {
+ normalizedProductID = [ZXUPCEReader convertUPCEtoUPCA:rawText];
+ } else {
+ normalizedProductID = rawText;
+ }
+ return [ZXProductParsedResult productParsedResultWithProductID:rawText normalizedProductID:normalizedProductID];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXResultParser.h b/ZXingObjC/client/result/ZXResultParser.h
new file mode 100644
index 0000000..240153f
--- /dev/null
+++ b/ZXingObjC/client/result/ZXResultParser.h
@@ -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.
+ */
+
+/**
+ * Abstract class representing the result of decoding a barcode, as more than
+ * a String -- as some type of structured data. This might be a subclass which represents
+ * a URL, or an e-mail address. parseResult() will turn a raw
+ * decoded string into the most appropriate type of structured representation.
+ *
+ * Thanks to Jeff Griffin for proposing rewrite of these classes that relies less
+ * on exception-based mechanisms during parsing.
+ */
+
+@class ZXParsedResult, ZXResult;
+
+@interface ZXResultParser : NSObject
+
++ (NSString *)massagedText:(ZXResult *)result;
+- (ZXParsedResult *)parse:(ZXResult *)result;
++ (ZXParsedResult *)parseResult:(ZXResult *)theResult;
+- (void)maybeAppend:(NSString *)value result:(NSMutableString *)result;
+- (void)maybeAppendArray:(NSArray *)value result:(NSMutableString *)result;
+- (NSArray *)maybeWrap:(NSString *)value;
++ (BOOL)isStringOfDigits:(NSString *)value length:(unsigned int)length;
++ (BOOL)isSubstringOfDigits:(NSString *)value offset:(int)offset length:(unsigned int)length;
++ (BOOL)isSubstringOfAlphaNumeric:(NSString *)value offset:(int)offset length:(unsigned int)length;
++ (int)parseHexDigit:(unichar)c;
+- (NSMutableDictionary *)parseNameValuePairs:(NSString *)uri;
++ (NSString *)urlDecode:(NSString *)encoded;
++ (NSArray *)matchPrefixedField:(NSString *)prefix rawText:(NSString *)rawText endChar:(unichar)endChar trim:(BOOL)trim;
++ (NSString *)matchSinglePrefixedField:(NSString *)prefix rawText:(NSString *)rawText endChar:(unichar)endChar trim:(BOOL)trim;
+
+@end
diff --git a/ZXingObjC/client/result/ZXResultParser.m b/ZXingObjC/client/result/ZXResultParser.m
new file mode 100644
index 0000000..bb42b42
--- /dev/null
+++ b/ZXingObjC/client/result/ZXResultParser.m
@@ -0,0 +1,308 @@
+/*
+ * 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 "ZXAddressBookAUResultParser.h"
+#import "ZXAddressBookDoCoMoResultParser.h"
+#import "ZXAddressBookParsedResult.h"
+#import "ZXBizcardResultParser.h"
+#import "ZXBookmarkDoCoMoResultParser.h"
+#import "ZXCalendarParsedResult.h"
+#import "ZXEmailAddressParsedResult.h"
+#import "ZXEmailAddressResultParser.h"
+#import "ZXEmailDoCoMoResultParser.h"
+#import "ZXExpandedProductParsedResult.h"
+#import "ZXExpandedProductResultParser.h"
+#import "ZXGeoParsedResult.h"
+#import "ZXGeoResultParser.h"
+#import "ZXISBNParsedResult.h"
+#import "ZXISBNResultParser.h"
+#import "ZXParsedResult.h"
+#import "ZXProductParsedResult.h"
+#import "ZXProductResultParser.h"
+#import "ZXResult.h"
+#import "ZXResultParser.h"
+#import "ZXSMSMMSResultParser.h"
+#import "ZXSMSParsedResult.h"
+#import "ZXSMSTOMMSTOResultParser.h"
+#import "ZXSMTPResultParser.h"
+#import "ZXTelParsedResult.h"
+#import "ZXTelResultParser.h"
+#import "ZXTextParsedResult.h"
+#import "ZXURIParsedResult.h"
+#import "ZXURIResultParser.h"
+#import "ZXURLTOResultParser.h"
+#import "ZXVCardResultParser.h"
+#import "ZXVEventResultParser.h"
+#import "ZXWifiParsedResult.h"
+#import "ZXWifiResultParser.h"
+
+static NSArray *PARSERS = nil;
+static NSRegularExpression *DIGITS = nil;
+static NSRegularExpression *ALPHANUM = nil;
+static NSString *AMPERSAND = @"&";
+static NSString *EQUALS = @"=";
+static unichar BYTE_ORDER_MARK = L'\ufeff';
+
+@implementation ZXResultParser
+
++ (void)initialize {
+ PARSERS = @[[[ZXBookmarkDoCoMoResultParser alloc] init],
+ [[ZXAddressBookDoCoMoResultParser alloc] init],
+ [[ZXEmailDoCoMoResultParser alloc] init],
+ [[ZXAddressBookAUResultParser alloc] init],
+ [[ZXVCardResultParser alloc] init],
+ [[ZXBizcardResultParser alloc] init],
+ [[ZXVEventResultParser alloc] init],
+ [[ZXEmailAddressResultParser alloc] init],
+ [[ZXSMTPResultParser alloc] init],
+ [[ZXTelResultParser alloc] init],
+ [[ZXSMSMMSResultParser alloc] init],
+ [[ZXSMSTOMMSTOResultParser alloc] init],
+ [[ZXGeoResultParser alloc] init],
+ [[ZXWifiResultParser alloc] init],
+ [[ZXURLTOResultParser alloc] init],
+ [[ZXURIResultParser alloc] init],
+ [[ZXISBNResultParser alloc] init],
+ [[ZXProductResultParser alloc] init],
+ [[ZXExpandedProductResultParser alloc] init]];
+ DIGITS = [[NSRegularExpression alloc] initWithPattern:@"^\\d*$" options:0 error:nil];
+ ALPHANUM = [[NSRegularExpression alloc] initWithPattern:@"^[a-zA-Z0-9]*$" options:0 error:nil];
+}
+
++ (NSString *)massagedText:(ZXResult *)result {
+ NSString *text = result.text;
+ if (text.length > 0 && [text characterAtIndex:0] == BYTE_ORDER_MARK) {
+ text = [text substringFromIndex:1];
+ }
+ return text;
+}
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
++ (ZXParsedResult *)parseResult:(ZXResult *)theResult {
+ for (ZXResultParser *parser in PARSERS) {
+ ZXParsedResult *result = [parser parse:theResult];
+ if (result != nil) {
+ return result;
+ }
+ }
+ return [ZXTextParsedResult textParsedResultWithText:[theResult text] language:nil];
+}
+
+- (void)maybeAppend:(NSString *)value result:(NSMutableString *)result {
+ if (value != nil) {
+ [result appendFormat:@"\n%@", value];
+ }
+}
+
+- (void)maybeAppendArray:(NSArray *)value result:(NSMutableString *)result {
+ if (value != nil) {
+ for (NSString *s in value) {
+ [result appendFormat:@"\n%@", s];
+ }
+ }
+}
+
+- (NSArray *)maybeWrap:(NSString *)value {
+ return value == nil ? nil : @[value];
+}
+
++ (NSString *)unescapeBackslash:(NSString *)escaped {
+ NSUInteger backslash = [escaped rangeOfString:@"\\"].location;
+ if (backslash == NSNotFound) {
+ return escaped;
+ }
+ NSUInteger max = [escaped length];
+ NSMutableString *unescaped = [NSMutableString stringWithCapacity:max - 1];
+ [unescaped appendString:[escaped substringToIndex:backslash]];
+ BOOL nextIsEscaped = NO;
+ for (int i = (int)backslash; i < max; i++) {
+ unichar c = [escaped characterAtIndex:i];
+ if (nextIsEscaped || c != '\\') {
+ [unescaped appendFormat:@"%C", c];
+ nextIsEscaped = NO;
+ } else {
+ nextIsEscaped = YES;
+ }
+ }
+ return unescaped;
+}
+
++ (int)parseHexDigit:(unichar)c {
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ }
+ if (c >= 'a' && c <= 'f') {
+ return 10 + (c - 'a');
+ }
+ if (c >= 'A' && c <= 'F') {
+ return 10 + (c - 'A');
+ }
+ return -1;
+}
+
++ (BOOL)isStringOfDigits:(NSString *)value length:(unsigned int)length {
+ return value != nil && length == value.length && [DIGITS numberOfMatchesInString:value options:0 range:NSMakeRange(0, value.length)] > 0;
+}
+
+- (NSString *)urlDecode:(NSString *)escaped {
+ if (escaped == nil) {
+ return nil;
+ }
+
+ int first = [self findFirstEscape:escaped];
+ if (first == -1) {
+ return escaped;
+ }
+
+ NSUInteger max = [escaped length];
+ NSMutableString *unescaped = [NSMutableString stringWithCapacity:max - 2];
+ [unescaped appendString:[escaped substringToIndex:first]];
+
+ for (int i = first; i < max; i++) {
+ unichar c = [escaped characterAtIndex:i];
+ switch (c) {
+ case '+':
+ [unescaped appendString:@" "];
+ break;
+ case '%':
+ if (i >= max - 2) {
+ [unescaped appendString:@"%"];
+ } else {
+ int firstDigitValue = [[self class] parseHexDigit:[escaped characterAtIndex:++i]];
+ int secondDigitValue = [[self class] parseHexDigit:[escaped characterAtIndex:++i]];
+ if (firstDigitValue < 0 || secondDigitValue < 0) {
+ [unescaped appendFormat:@"%%%C%C", [escaped characterAtIndex:i - 1], [escaped characterAtIndex:i]];
+ }
+ [unescaped appendFormat:@"%C", (unichar)((firstDigitValue << 4) + secondDigitValue)];
+ }
+ break;
+ default:
+ [unescaped appendFormat:@"%C", c];
+ break;
+ }
+ }
+
+ return unescaped;
+}
+
+- (int)findFirstEscape:(NSString *)escaped {
+ NSUInteger max = [escaped length];
+ for (int i = 0; i < max; i++) {
+ unichar c = [escaped characterAtIndex:i];
+ if (c == '+' || c == '%') {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
++ (BOOL)isSubstringOfDigits:(NSString *)value offset:(int)offset length:(unsigned int)length {
+ if (value == nil) {
+ return NO;
+ }
+ int max = offset + length;
+ return value.length >= max && [DIGITS numberOfMatchesInString:value options:0 range:NSMakeRange(offset, max - offset)] > 0;
+}
+
++ (BOOL)isSubstringOfAlphaNumeric:(NSString *)value offset:(int)offset length:(unsigned int)length {
+ if (value == nil) {
+ return NO;
+ }
+ int max = offset + length;
+ return value.length >= max && [ALPHANUM numberOfMatchesInString:value options:0 range:NSMakeRange(offset, max - offset)] > 0;
+}
+
+- (NSMutableDictionary *)parseNameValuePairs:(NSString *)uri {
+ NSUInteger paramStart = [uri rangeOfString:@"?"].location;
+ if (paramStart == NSNotFound) {
+ return nil;
+ }
+ NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:3];
+ for (NSString *keyValue in [[uri substringFromIndex:paramStart + 1] componentsSeparatedByString:AMPERSAND]) {
+ [self appendKeyValue:keyValue result:result];
+ }
+ return result;
+}
+
+- (void)appendKeyValue:(NSString *)keyValue result:(NSMutableDictionary *)result {
+ NSRange equalsRange = [keyValue rangeOfString:EQUALS];
+ if (equalsRange.location != NSNotFound) {
+ NSString *key = [keyValue substringToIndex:equalsRange.location];
+ NSString *value = [keyValue substringFromIndex:equalsRange.location + 1];
+ value = [self urlDecode:value];
+ result[key] = value;
+ }
+}
+
++ (NSString *)urlDecode:(NSString *)encoded {
+ NSString *result = [encoded stringByReplacingOccurrencesOfString:@"+" withString:@" "];
+ result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+ return result;
+}
+
++ (NSArray *)matchPrefixedField:(NSString *)prefix rawText:(NSString *)rawText endChar:(unichar)endChar trim:(BOOL)trim {
+ NSMutableArray *matches = nil;
+ NSUInteger i = 0;
+ NSUInteger max = [rawText length];
+ while (i < max) {
+ i = [rawText rangeOfString:prefix options:NSLiteralSearch range:NSMakeRange(i, [rawText length] - i - 1)].location;
+ if (i == NSNotFound) {
+ break;
+ }
+ i += [prefix length];
+ NSUInteger start = i;
+ BOOL more = YES;
+ while (more) {
+ i = [rawText rangeOfString:[NSString stringWithFormat:@"%C", endChar] options:NSLiteralSearch range:NSMakeRange(i, [rawText length] - i)].location;
+ if (i == NSNotFound) {
+ i = [rawText length];
+ more = NO;
+ } else if ([rawText characterAtIndex:i - 1] == '\\') {
+ i++;
+ } else {
+ if (matches == nil) {
+ matches = [NSMutableArray arrayWithCapacity:3];
+ }
+ NSString *element = [self unescapeBackslash:[rawText substringWithRange:NSMakeRange(start, i - start)]];
+ if (trim) {
+ element = [element stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ }
+ if (element.length > 0) {
+ [matches addObject:element];
+ }
+ i++;
+ more = NO;
+ }
+ }
+ }
+ if (matches == nil || [matches count] == 0) {
+ return nil;
+ }
+ return matches;
+}
+
++ (NSString *)matchSinglePrefixedField:(NSString *)prefix rawText:(NSString *)rawText endChar:(unichar)endChar trim:(BOOL)trim {
+ NSArray *matches = [self matchPrefixedField:prefix rawText:rawText endChar:endChar trim:trim];
+ return matches == nil ? nil : matches[0];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXSMSMMSResultParser.h b/ZXingObjC/client/result/ZXSMSMMSResultParser.h
new file mode 100644
index 0000000..99b3fac
--- /dev/null
+++ b/ZXingObjC/client/result/ZXSMSMMSResultParser.h
@@ -0,0 +1,35 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses an "sms:" URI result, which specifies a number to SMS.
+ * See http://tools.ietf.org/html/rfc5724 on this.
+ *
+ * This class supports "via" syntax for numbers, which is not part of the spec.
+ * For example "+12125551212;via=+12124440101" may appear as a number.
+ * It also supports a "subject" query parameter, which is not mentioned in the spec.
+ * These are included since they were mentioned in earlier IETF drafts and might be
+ * used.
+ *
+ * This actually also parses URIs starting with "mms:" and treats them all the same way,
+ * and effectively converts them to an "sms:" URI for purposes of forwarding to the platform.
+ */
+
+@interface ZXSMSMMSResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXSMSMMSResultParser.m b/ZXingObjC/client/result/ZXSMSMMSResultParser.m
new file mode 100644
index 0000000..e0dba74
--- /dev/null
+++ b/ZXingObjC/client/result/ZXSMSMMSResultParser.m
@@ -0,0 +1,80 @@
+/*
+ * 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 "ZXResult.h"
+#import "ZXSMSMMSResultParser.h"
+#import "ZXSMSParsedResult.h"
+
+@implementation ZXSMSMMSResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (!([rawText hasPrefix:@"sms:"] || [rawText hasPrefix:@"SMS:"] || [rawText hasPrefix:@"mms:"] || [rawText hasPrefix:@"MMS:"])) {
+ return nil;
+ }
+
+ NSMutableDictionary *nameValuePairs = [self parseNameValuePairs:rawText];
+ NSString *subject = nil;
+ NSString *body = nil;
+ BOOL querySyntax = NO;
+ if (nameValuePairs != nil && [nameValuePairs count] > 0) {
+ subject = nameValuePairs[@"subject"];
+ body = nameValuePairs[@"body"];
+ querySyntax = YES;
+ }
+
+ NSUInteger queryStart = [rawText rangeOfString:@"?" options:NSLiteralSearch range:NSMakeRange(4, [rawText length] - 4)].location;
+ NSString *smsURIWithoutQuery;
+ if (queryStart == NSNotFound || !querySyntax) {
+ smsURIWithoutQuery = [rawText substringFromIndex:4];
+ } else {
+ smsURIWithoutQuery = [rawText substringWithRange:NSMakeRange(4, queryStart - 4)];
+ }
+
+ int lastComma = -1;
+ NSInteger comma;
+ NSMutableArray *numbers = [NSMutableArray arrayWithCapacity:1];
+ NSMutableArray *vias = [NSMutableArray arrayWithCapacity:1];
+ while ((comma = [smsURIWithoutQuery rangeOfString:@"," options:NSLiteralSearch range:NSMakeRange(lastComma + 1, (int)[smsURIWithoutQuery length] - lastComma - 1)].location) > lastComma && comma != NSNotFound) {
+ NSString *numberPart = [smsURIWithoutQuery substringWithRange:NSMakeRange(lastComma + 1, comma - lastComma - 1)];
+ [self addNumberVia:numbers vias:vias numberPart:numberPart];
+ lastComma = (int)comma;
+ }
+ [self addNumberVia:numbers vias:vias numberPart:[smsURIWithoutQuery substringFromIndex:lastComma + 1]];
+
+ return [ZXSMSParsedResult smsParsedResultWithNumbers:numbers
+ vias:vias
+ subject:subject
+ body:body];
+}
+
+- (void)addNumberVia:(NSMutableArray *)numbers vias:(NSMutableArray *)vias numberPart:(NSString *)numberPart {
+ NSUInteger numberEnd = [numberPart rangeOfString:@";"].location;
+ if (numberEnd == NSNotFound) {
+ [numbers addObject:numberPart];
+ [vias addObject:[NSNull null]];
+ } else {
+ [numbers addObject:[numberPart substringToIndex:numberEnd]];
+ NSString *maybeVia = [numberPart substringFromIndex:numberEnd + 1];
+ if ([maybeVia hasPrefix:@"via="]) {
+ [vias addObject:[maybeVia substringFromIndex:4]];
+ } else {
+ [vias addObject:[NSNull null]];
+ }
+ }
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXSMSParsedResult.h b/ZXingObjC/client/result/ZXSMSParsedResult.h
new file mode 100644
index 0000000..0f594ff
--- /dev/null
+++ b/ZXingObjC/client/result/ZXSMSParsedResult.h
@@ -0,0 +1,32 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@interface ZXSMSParsedResult : ZXParsedResult
+
+@property (nonatomic, strong, readonly) NSArray *numbers;
+@property (nonatomic, strong, readonly) NSArray *vias;
+@property (nonatomic, copy, readonly) NSString *subject;
+@property (nonatomic, copy, readonly) NSString *body;
+
+- (id)initWithNumber:(NSString *)number via:(NSString *)via subject:(NSString *)subject body:(NSString *)body;
+- (id)initWithNumbers:(NSArray *)numbers vias:(NSArray *)vias subject:(NSString *)subject body:(NSString *)body;
++ (id)smsParsedResultWithNumber:(NSString *)number via:(NSString *)via subject:(NSString *)subject body:(NSString *)body;
++ (id)smsParsedResultWithNumbers:(NSArray *)numbers vias:(NSArray *)vias subject:(NSString *)subject body:(NSString *)body;
+- (NSString *)sMSURI;
+
+@end
diff --git a/ZXingObjC/client/result/ZXSMSParsedResult.m b/ZXingObjC/client/result/ZXSMSParsedResult.m
new file mode 100644
index 0000000..52ef064
--- /dev/null
+++ b/ZXingObjC/client/result/ZXSMSParsedResult.m
@@ -0,0 +1,97 @@
+/*
+ * 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 "ZXSMSParsedResult.h"
+
+@implementation ZXSMSParsedResult
+
+- (id)initWithNumber:(NSString *)number via:(NSString *)via subject:(NSString *)subject body:(NSString *)body {
+ NSArray *numbers;
+ if (number) {
+ numbers = @[number];
+ }
+
+ NSArray *vias;
+ if (via) {
+ vias = @[via];
+ }
+
+ return [self initWithNumbers:numbers vias:vias subject:subject body:body];
+}
+
+- (id)initWithNumbers:(NSArray *)numbers vias:(NSArray *)vias subject:(NSString *)subject body:(NSString *)body {
+ if (self = [super initWithType:kParsedResultTypeSMS]) {
+ _numbers = numbers;
+ _vias = vias;
+ _subject = subject;
+ _body = body;
+ }
+
+ return self;
+}
+
++ (id)smsParsedResultWithNumber:(NSString *)number via:(NSString *)via subject:(NSString *)subject body:(NSString *)body {
+ return [[self alloc] initWithNumber:number via:via subject:subject body:body];
+}
+
++ (id)smsParsedResultWithNumbers:(NSArray *)numbers vias:(NSArray *)vias subject:(NSString *)subject body:(NSString *)body {
+ return [[self alloc] initWithNumbers:numbers vias:vias subject:subject body:body];
+}
+
+- (NSString *)sMSURI {
+ NSMutableString *result = [NSMutableString stringWithString:@"sms:"];
+ BOOL first = YES;
+ for (int i = 0; i < self.numbers.count; i++) {
+ if (first) {
+ first = NO;
+ } else {
+ [result appendString:@","];
+ }
+ [result appendString:self.numbers[i]];
+ if (self.vias != nil && self.vias[i] != [NSNull null]) {
+ [result appendString:@";via="];
+ [result appendString:self.vias[i]];
+ }
+ }
+
+ BOOL hasBody = self.body != nil;
+ BOOL hasSubject = self.subject != nil;
+ if (hasBody || hasSubject) {
+ [result appendString:@"?"];
+ if (hasBody) {
+ [result appendString:@"body="];
+ [result appendString:self.body];
+ }
+ if (hasSubject) {
+ if (hasBody) {
+ [result appendString:@"&"];
+ }
+ [result appendString:@"subject="];
+ [result appendString:self.subject];
+ }
+ }
+ return result;
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString stringWithCapacity:100];
+ [ZXParsedResult maybeAppendArray:self.numbers result:result];
+ [ZXParsedResult maybeAppend:self.subject result:result];
+ [ZXParsedResult maybeAppend:self.body result:result];
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.h b/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.h
new file mode 100644
index 0000000..2a1bcd6
--- /dev/null
+++ b/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.h
@@ -0,0 +1,30 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses an "smsto:" URI result, whose format is not standardized but appears to be like:
+ * smsto:number(:body).
+ *
+ * This actually also parses URIs starting with "smsto:", "mmsto:", "SMSTO:", and
+ * "MMSTO:", and treats them all the same way, and effectively converts them to an "sms:" URI
+ * for purposes of forwarding to the platform.
+ */
+
+@interface ZXSMSTOMMSTOResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.m b/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.m
new file mode 100644
index 0000000..024b807
--- /dev/null
+++ b/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.m
@@ -0,0 +1,38 @@
+/*
+ * 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 "ZXResult.h"
+#import "ZXSMSTOMMSTOResultParser.h"
+#import "ZXSMSParsedResult.h"
+
+@implementation ZXSMSTOMMSTOResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (!([rawText hasPrefix:@"smsto:"] || [rawText hasPrefix:@"SMSTO:"] || [rawText hasPrefix:@"mmsto:"] || [rawText hasPrefix:@"MMSTO:"])) {
+ return nil;
+ }
+ NSString *number = [rawText substringFromIndex:6];
+ NSString *body = nil;
+ NSUInteger bodyStart = [number rangeOfString:@":"].location;
+ if (bodyStart != NSNotFound) {
+ body = [number substringFromIndex:bodyStart + 1];
+ number = [number substringToIndex:bodyStart];
+ }
+ return [ZXSMSParsedResult smsParsedResultWithNumber:number via:nil subject:nil body:body];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXSMTPResultParser.h b/ZXingObjC/client/result/ZXSMTPResultParser.h
new file mode 100644
index 0000000..0c3b5f7
--- /dev/null
+++ b/ZXingObjC/client/result/ZXSMTPResultParser.h
@@ -0,0 +1,28 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses an "smtp:" URI result, whose format is not standardized but appears to be like:
+ * smtp(:subject(:body)).
+ *
+ * See http://code.google.com/p/zxing/issues/detail?id=536
+ */
+
+@interface ZXSMTPResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXSMTPResultParser.m b/ZXingObjC/client/result/ZXSMTPResultParser.m
new file mode 100644
index 0000000..4c7566f
--- /dev/null
+++ b/ZXingObjC/client/result/ZXSMTPResultParser.m
@@ -0,0 +1,48 @@
+/*
+ * 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 "ZXEmailAddressParsedResult.h"
+#import "ZXResult.h"
+#import "ZXSMTPResultParser.h"
+
+@implementation ZXSMTPResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (!([rawText hasPrefix:@"smtp:"] || [rawText hasPrefix:@"SMTP:"])) {
+ return nil;
+ }
+ NSString *emailAddress = [rawText substringFromIndex:5];
+ NSString *subject = nil;
+ NSString *body = nil;
+ NSUInteger colon = [emailAddress rangeOfString:@":"].location;
+ if (colon != NSNotFound) {
+ subject = [emailAddress substringFromIndex:colon + 1];
+ emailAddress = [emailAddress substringToIndex:colon];
+ colon = [subject rangeOfString:@":"].location;
+ if (colon != NSNotFound) {
+ body = [subject substringFromIndex:colon + 1];
+ subject = [subject substringToIndex:colon];
+ }
+ }
+ NSString *mailtoURI = [@"mailto:" stringByAppendingString:emailAddress];
+ return [ZXEmailAddressParsedResult emailAddressParsedResultWithEmailAddress:emailAddress
+ subject:subject
+ body:body
+ mailtoURI:mailtoURI];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXTelParsedResult.h b/ZXingObjC/client/result/ZXTelParsedResult.h
new file mode 100644
index 0000000..7c5d2d1
--- /dev/null
+++ b/ZXingObjC/client/result/ZXTelParsedResult.h
@@ -0,0 +1,28 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@interface ZXTelParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *number;
+@property (nonatomic, copy, readonly) NSString *telURI;
+@property (nonatomic, copy, readonly) NSString *title;
+
+- (id)initWithNumber:(NSString *)number telURI:(NSString *)telURI title:(NSString *)title;
++ (id)telParsedResultWithNumber:(NSString *)number telURI:(NSString *)telURI title:(NSString *)title;
+
+@end
diff --git a/ZXingObjC/client/result/ZXTelParsedResult.m b/ZXingObjC/client/result/ZXTelParsedResult.m
new file mode 100644
index 0000000..aed1b28
--- /dev/null
+++ b/ZXingObjC/client/result/ZXTelParsedResult.m
@@ -0,0 +1,42 @@
+/*
+ * 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 "ZXTelParsedResult.h"
+
+@implementation ZXTelParsedResult
+
+- (id)initWithNumber:(NSString *)number telURI:(NSString *)telURI title:(NSString *)title {
+ if (self = [super initWithType:kParsedResultTypeTel]) {
+ _number = number;
+ _telURI = telURI;
+ _title = title;
+ }
+
+ return self;
+}
+
++ (id)telParsedResultWithNumber:(NSString *)number telURI:(NSString *)telURI title:(NSString *)title {
+ return [[self alloc] initWithNumber:number telURI:telURI title:title];
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString stringWithCapacity:20];
+ [ZXParsedResult maybeAppend:self.number result:result];
+ [ZXParsedResult maybeAppend:self.title result:result];
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXTelResultParser.h b/ZXingObjC/client/result/ZXTelResultParser.h
new file mode 100644
index 0000000..cb4175b
--- /dev/null
+++ b/ZXingObjC/client/result/ZXTelResultParser.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses a "tel:" URI result, which specifies a phone number.
+ */
+
+@interface ZXTelResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXTelResultParser.m b/ZXingObjC/client/result/ZXTelResultParser.m
new file mode 100644
index 0000000..92de3c4
--- /dev/null
+++ b/ZXingObjC/client/result/ZXTelResultParser.m
@@ -0,0 +1,33 @@
+/*
+ * 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 "ZXTelParsedResult.h"
+#import "ZXTelResultParser.h"
+
+@implementation ZXTelResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (![rawText hasPrefix:@"tel:"] && ![rawText hasPrefix:@"TEL:"]) {
+ return nil;
+ }
+ NSString *telURI = [rawText hasPrefix:@"TEL:"] ? [@"tel:" stringByAppendingString:[rawText substringFromIndex:4]] : rawText;
+ NSUInteger queryStart = [rawText rangeOfString:@"?" options:NSLiteralSearch range:NSMakeRange(4, [rawText length] - 4)].location;
+ NSString *number = queryStart == NSNotFound ? [rawText substringFromIndex:4] : [rawText substringWithRange:NSMakeRange(4, [rawText length] - queryStart)];
+ return [ZXTelParsedResult telParsedResultWithNumber:number telURI:telURI title:nil];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXTextParsedResult.h b/ZXingObjC/client/result/ZXTextParsedResult.h
new file mode 100644
index 0000000..f01b21c
--- /dev/null
+++ b/ZXingObjC/client/result/ZXTextParsedResult.h
@@ -0,0 +1,32 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+/**
+ * A simple result type encapsulating a string that has no further
+ * interpretation.
+ */
+
+@interface ZXTextParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *text;
+@property (nonatomic, copy, readonly) NSString *language;
+
+- (id)initWithText:(NSString *)text language:(NSString *)language;
++ (id)textParsedResultWithText:(NSString *)text language:(NSString *)language;
+
+@end
diff --git a/ZXingObjC/client/result/ZXTextParsedResult.m b/ZXingObjC/client/result/ZXTextParsedResult.m
new file mode 100644
index 0000000..059fae0
--- /dev/null
+++ b/ZXingObjC/client/result/ZXTextParsedResult.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "ZXParsedResultType.h"
+#import "ZXTextParsedResult.h"
+
+@implementation ZXTextParsedResult
+
+- (id)initWithText:(NSString *)text language:(NSString *)language {
+ if (self = [super initWithType:kParsedResultTypeText]) {
+ _text = text;
+ _language = language;
+ }
+
+ return self;
+}
+
++ (id)textParsedResultWithText:(NSString *)text language:(NSString *)language {
+ return [[self alloc] initWithText:text language:language];
+}
+
+- (NSString *)displayResult {
+ return self.text;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXURIParsedResult.h b/ZXingObjC/client/result/ZXURIParsedResult.h
new file mode 100644
index 0000000..bb7a69c
--- /dev/null
+++ b/ZXingObjC/client/result/ZXURIParsedResult.h
@@ -0,0 +1,28 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@interface ZXURIParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *uri;
+@property (nonatomic, copy, readonly) NSString *title;
+
+- (id)initWithUri:(NSString *)uri title:(NSString *)title;
++ (id)uriParsedResultWithUri:(NSString *)uri title:(NSString *)title;
+- (BOOL)possiblyMaliciousURI;
+
+@end
diff --git a/ZXingObjC/client/result/ZXURIParsedResult.m b/ZXingObjC/client/result/ZXURIParsedResult.m
new file mode 100644
index 0000000..421233a
--- /dev/null
+++ b/ZXingObjC/client/result/ZXURIParsedResult.m
@@ -0,0 +1,94 @@
+/*
+ * 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 "ZXURIParsedResult.h"
+
+static NSRegularExpression *USER_IN_HOST = nil;
+
+@implementation ZXURIParsedResult
+
++ (void)initialize {
+ USER_IN_HOST = [[NSRegularExpression alloc] initWithPattern:@":/*([^/@]+)@[^/]+" options:0 error:nil];
+}
+
+- (id)initWithUri:(NSString *)uri title:(NSString *)title {
+ if (self = [super initWithType:kParsedResultTypeURI]) {
+ _uri = [self massageURI:uri];
+ _title = title;
+ }
+
+ return self;
+}
+
++ (id)uriParsedResultWithUri:(NSString *)uri title:(NSString *)title {
+ return [[self alloc] initWithUri:uri title:title];
+}
+
+/**
+ * Returns true if the URI contains suspicious patterns that may suggest it intends to
+ * mislead the user about its true nature. At the moment this looks for the presence
+ * of user/password syntax in the host/authority portion of a URI which may be used
+ * in attempts to make the URI's host appear to be other than it is. Example:
+ * http://yourbank.com@phisher.com This URI connects to phisher.com but may appear
+ * to connect to yourbank.com at first glance.
+ */
+- (BOOL)possiblyMaliciousURI {
+ return [USER_IN_HOST numberOfMatchesInString:self.uri options:0 range:NSMakeRange(0, self.uri.length)] > 0;
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString stringWithCapacity:30];
+ [ZXParsedResult maybeAppend:self.title result:result];
+ [ZXParsedResult maybeAppend:self.uri result:result];
+ return result;
+}
+
+/**
+ * Transforms a string that represents a URI into something more proper, by adding or canonicalizing
+ * the protocol.
+ */
+- (NSString *)massageURI:(NSString *)uri {
+ NSString *massagedUri = [uri stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ NSUInteger protocolEnd = [massagedUri rangeOfString:@":"].location;
+ if (protocolEnd == NSNotFound) {
+ // No protocol, assume http
+ massagedUri = [NSString stringWithFormat:@"http://%@", massagedUri];
+ } else if ([self isColonFollowedByPortNumber:massagedUri protocolEnd:(int)protocolEnd]) {
+ // Found a colon, but it looks like it is after the host, so the protocol is still missing
+ massagedUri = [NSString stringWithFormat:@"http://%@", massagedUri];
+ }
+ return massagedUri;
+}
+
+- (BOOL)isColonFollowedByPortNumber:(NSString *)aUri protocolEnd:(int)protocolEnd {
+ NSUInteger nextSlash = [aUri rangeOfString:@"/" options:0 range:NSMakeRange(protocolEnd + 1, [aUri length] - protocolEnd - 1)].location;
+ if (nextSlash == NSNotFound) {
+ nextSlash = [aUri length];
+ }
+ if (nextSlash <= protocolEnd + 1) {
+ return NO;
+ }
+
+ for (int x = protocolEnd + 1; x < nextSlash; x++) {
+ if ([aUri characterAtIndex:x] < '0' || [aUri characterAtIndex:x] > '9') {
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXURIResultParser.h b/ZXingObjC/client/result/ZXURIResultParser.h
new file mode 100644
index 0000000..c2dda20
--- /dev/null
+++ b/ZXingObjC/client/result/ZXURIResultParser.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Tries to parse results that are a URI of some kind.
+ */
+
+@interface ZXURIResultParser : ZXResultParser
+
++ (BOOL)isBasicallyValidURI:(NSString *)uri;
+
+@end
diff --git a/ZXingObjC/client/result/ZXURIResultParser.m b/ZXingObjC/client/result/ZXURIResultParser.m
new file mode 100644
index 0000000..a4dc432
--- /dev/null
+++ b/ZXingObjC/client/result/ZXURIResultParser.m
@@ -0,0 +1,64 @@
+/*
+ * 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 "ZXURIResultParser.h"
+#import "ZXResult.h"
+#import "ZXURIParsedResult.h"
+
+static NSString *ALPHANUM_PART = @"[a-zA-Z0-9\\-]";
+static NSRegularExpression *URL_WITH_PROTOCOL_PATTERN = nil;
+static NSRegularExpression *URL_WITHOUT_PROTOCOL_PATTERN = nil;
+
+@implementation ZXURIResultParser
+
++ (void)initialize {
+ URL_WITH_PROTOCOL_PATTERN = [[NSRegularExpression alloc] initWithPattern:@"^[a-zA-Z0-9]{2,}:"
+ options:0
+ error:nil];
+ URL_WITHOUT_PROTOCOL_PATTERN = [[NSRegularExpression alloc] initWithPattern:
+ [[[NSString stringWithFormat:@"(%@+\\.)+%@{2,}", ALPHANUM_PART, ALPHANUM_PART] // host name elements
+ stringByAppendingString:@"(:\\d{1,5})?"] // maybe port
+ stringByAppendingString:@"(/|\\?|$)"] // query, path or nothing
+ options:0
+ error:nil];
+}
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ // We specifically handle the odd "URL" scheme here for simplicity and add "URI" for fun
+ // Assume anything starting this way really means to be a URI
+ if ([rawText hasPrefix:@"URL:"] || [rawText hasPrefix:@"URI:"]) {
+ return [[ZXURIParsedResult alloc] initWithUri:[[rawText substringFromIndex:4] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]
+ title:nil];
+ }
+ rawText = [rawText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ return [[self class] isBasicallyValidURI:rawText] ? [ZXURIParsedResult uriParsedResultWithUri:rawText title:nil] : nil;
+}
+
+
++ (BOOL)isBasicallyValidURI:(NSString *)uri {
+ if ([uri rangeOfString:@" "].location != NSNotFound) {
+ // Quick hack check for a common case
+ return NO;
+ }
+
+ if ([URL_WITH_PROTOCOL_PATTERN numberOfMatchesInString:uri options:NSMatchingWithoutAnchoringBounds range:NSMakeRange(0, uri.length)] > 0) { // match at start only
+ return YES;
+ }
+ return [URL_WITHOUT_PROTOCOL_PATTERN numberOfMatchesInString:uri options:NSMatchingWithoutAnchoringBounds range:NSMakeRange(0, uri.length)] > 0;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXURLTOResultParser.h b/ZXingObjC/client/result/ZXURLTOResultParser.h
new file mode 100644
index 0000000..9f78f91
--- /dev/null
+++ b/ZXingObjC/client/result/ZXURLTOResultParser.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses the "URLTO" result format, which is of the form "URLTO:[title]:[url]".
+ * This seems to be used sometimes, but I am not able to find documentation
+ * on its origin or official format?
+ */
+
+@interface ZXURLTOResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXURLTOResultParser.m b/ZXingObjC/client/result/ZXURLTOResultParser.m
new file mode 100644
index 0000000..b95b884
--- /dev/null
+++ b/ZXingObjC/client/result/ZXURLTOResultParser.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 "ZXResult.h"
+#import "ZXURIParsedResult.h"
+#import "ZXURLTOResultParser.h"
+
+@implementation ZXURLTOResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (![rawText hasPrefix:@"urlto:"] && ![rawText hasPrefix:@"URLTO:"]) {
+ return nil;
+ }
+ NSUInteger titleEnd = [rawText rangeOfString:@":" options:NSLiteralSearch range:NSMakeRange(6, [rawText length] - 6)].location;
+ if (titleEnd == NSNotFound) {
+ return nil;
+ }
+ NSString *title = titleEnd <= 6 ? nil : [rawText substringWithRange:NSMakeRange(6, titleEnd - 6)];
+ NSString *uri = [rawText substringFromIndex:titleEnd + 1];
+ return [ZXURIParsedResult uriParsedResultWithUri:uri title:title];
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXVCardResultParser.h b/ZXingObjC/client/result/ZXVCardResultParser.h
new file mode 100644
index 0000000..5df6b84
--- /dev/null
+++ b/ZXingObjC/client/result/ZXVCardResultParser.h
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses contact information formatted according to the VCard (2.1) format. This is not a complete
+ * implementation but should parse information as commonly encoded in 2D barcodes.
+ */
+
+@interface ZXVCardResultParser : ZXResultParser
+
++ (NSArray *)matchSingleVCardPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim parseFieldDivider:(BOOL)parseFieldDivider;
++ (NSMutableArray *)matchVCardPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim parseFieldDivider:(BOOL)parseFieldDivider;
+
+@end
diff --git a/ZXingObjC/client/result/ZXVCardResultParser.m b/ZXingObjC/client/result/ZXVCardResultParser.m
new file mode 100644
index 0000000..2130702
--- /dev/null
+++ b/ZXingObjC/client/result/ZXVCardResultParser.m
@@ -0,0 +1,347 @@
+/*
+ * 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 "ZXAddressBookParsedResult.h"
+#import "ZXResult.h"
+#import "ZXVCardResultParser.h"
+
+static NSRegularExpression *BEGIN_VCARD = nil;
+static NSRegularExpression *VCARD_LIKE_DATE = nil;
+static NSRegularExpression *CR_LF_SPACE_TAB = nil;
+static NSRegularExpression *NEWLINE_ESCAPE = nil;
+static NSRegularExpression *VCARD_ESCAPES = nil;
+static NSString *EQUALS = @"=";
+static NSString *SEMICOLON = @";";
+static NSRegularExpression *UNESCAPED_SEMICOLONS = nil;
+static NSCharacterSet *COMMA = nil;
+static NSCharacterSet *SEMICOLON_OR_COMMA = nil;
+
+@implementation ZXVCardResultParser
+
++ (void)initialize {
+ BEGIN_VCARD = [[NSRegularExpression alloc] initWithPattern:@"BEGIN:VCARD" options:NSRegularExpressionCaseInsensitive error:nil];
+ VCARD_LIKE_DATE = [[NSRegularExpression alloc] initWithPattern:@"\\d{4}-?\\d{2}-?\\d{2}" options:0 error:nil];
+ CR_LF_SPACE_TAB = [[NSRegularExpression alloc] initWithPattern:@"\r\n[ \t]" options:0 error:nil];
+ NEWLINE_ESCAPE = [[NSRegularExpression alloc] initWithPattern:@"\\\\[nN]" options:0 error:nil];
+ VCARD_ESCAPES = [[NSRegularExpression alloc] initWithPattern:@"\\\\([,;\\\\])" options:0 error:nil];
+ UNESCAPED_SEMICOLONS = [[NSRegularExpression alloc] initWithPattern:@"(?<!\\\\);+" options:0 error:nil];
+ COMMA = [NSCharacterSet characterSetWithCharactersInString:@","];
+ SEMICOLON_OR_COMMA = [NSCharacterSet characterSetWithCharactersInString:@";,"];
+}
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ // Although we should insist on the raw text ending with "END:VCARD", there's no reason
+ // to throw out everything else we parsed just because this was omitted. In fact, Eclair
+ // is doing just that, and we can't parse its contacts without this leniency.
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if ([BEGIN_VCARD numberOfMatchesInString:rawText options:0 range:NSMakeRange(0, rawText.length)] == 0) {
+ return nil;
+ }
+ NSMutableArray *names = [[self class] matchVCardPrefixedField:@"FN" rawText:rawText trim:YES parseFieldDivider:NO];
+ if (names == nil) {
+ // If no display names found, look for regular name fields and format them
+ names = [[self class] matchVCardPrefixedField:@"N" rawText:rawText trim:YES parseFieldDivider:NO];
+ [self formatNames:names];
+ }
+ NSArray *nicknameString = [[self class] matchSingleVCardPrefixedField:@"NICKNAME" rawText:rawText trim:YES parseFieldDivider:NO];
+ NSArray *nicknames = nicknameString == nil ? nil : [nicknameString[0] componentsSeparatedByCharactersInSet:COMMA];
+ NSArray *phoneNumbers = [[self class] matchVCardPrefixedField:@"TEL" rawText:rawText trim:YES parseFieldDivider:NO];
+ NSArray *emails = [[self class] matchVCardPrefixedField:@"EMAIL" rawText:rawText trim:YES parseFieldDivider:NO];
+ NSArray *note = [[self class] matchSingleVCardPrefixedField:@"NOTE" rawText:rawText trim:NO parseFieldDivider:NO];
+ NSMutableArray *addresses = [[self class] matchVCardPrefixedField:@"ADR" rawText:rawText trim:YES parseFieldDivider:YES];
+ NSArray *org = [[self class] matchSingleVCardPrefixedField:@"ORG" rawText:rawText trim:YES parseFieldDivider:YES];
+ NSArray *birthday = [[self class] matchSingleVCardPrefixedField:@"BDAY" rawText:rawText trim:YES parseFieldDivider:NO];
+ if (birthday != nil && ![self isLikeVCardDate:birthday[0]]) {
+ birthday = nil;
+ }
+ NSArray *title = [[self class] matchSingleVCardPrefixedField:@"TITLE" rawText:rawText trim:YES parseFieldDivider:NO];
+ NSArray *urls = [[self class] matchVCardPrefixedField:@"URL" rawText:rawText trim:YES parseFieldDivider:NO];
+ NSArray *instantMessenger = [[self class] matchSingleVCardPrefixedField:@"IMPP" rawText:rawText trim:YES parseFieldDivider:NO];
+ NSArray *geoString = [[self class] matchSingleVCardPrefixedField:@"GEO" rawText:rawText trim:YES parseFieldDivider:NO];
+ NSArray *geo = geoString == nil ? nil : [geoString[0] componentsSeparatedByCharactersInSet:SEMICOLON_OR_COMMA];
+ if (geo != nil && geo.count != 2) {
+ geo = nil;
+ }
+ return [ZXAddressBookParsedResult addressBookParsedResultWithNames:[self toPrimaryValues:names]
+ nicknames:nicknames
+ pronunciation:nil
+ phoneNumbers:[self toPrimaryValues:phoneNumbers]
+ phoneTypes:[self toTypes:phoneNumbers]
+ emails:[self toPrimaryValues:emails]
+ emailTypes:[self toTypes:emails]
+ instantMessenger:[self toPrimaryValue:instantMessenger]
+ note:[self toPrimaryValue:note]
+ addresses:[self toPrimaryValues:addresses]
+ addressTypes:[self toTypes:addresses]
+ org:[self toPrimaryValue:org]
+ birthday:[self toPrimaryValue:birthday]
+ title:[self toPrimaryValue:title]
+ urls:[self toPrimaryValues:urls]
+ geo:geo];
+}
+
++ (NSMutableArray *)matchVCardPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim parseFieldDivider:(BOOL)parseFieldDivider {
+ NSMutableArray *matches = nil;
+ NSUInteger i = 0;
+ NSUInteger max = [rawText length];
+
+ while (i < max) {
+ // At start or after newling, match prefix, followed by optional metadata
+ // (led by ;) ultimately ending in colon
+ NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"(?:^|\n)%@(?:;([^:]*))?:", prefix]
+ options:NSRegularExpressionCaseInsensitive error:nil];
+ if (i > 0) {
+ i--; // Find from i-1 not i since looking at the preceding character
+ }
+ NSArray *regexMatches = [regex matchesInString:rawText options:0 range:NSMakeRange(i, rawText.length - i)];
+ if (regexMatches.count == 0) {
+ break;
+ }
+ NSRange matchRange = [regexMatches[0] range];
+ i = matchRange.location + matchRange.length;
+
+ NSString *metadataString = nil;
+ if ([regexMatches[0] rangeAtIndex:1].location != NSNotFound) {
+ metadataString = [rawText substringWithRange:[regexMatches[0] rangeAtIndex:1]];
+ }
+ NSMutableArray *metadata = nil;
+ BOOL quotedPrintable = NO;
+ NSString *quotedPrintableCharset = nil;
+ if (metadataString != nil) {
+ for (NSString *metadatum in [metadataString componentsSeparatedByString:SEMICOLON]) {
+ if (metadata == nil) {
+ metadata = [NSMutableArray array];
+ }
+ [metadata addObject:metadatum];
+ NSUInteger equals = [metadatum rangeOfString:EQUALS].location;
+ if (equals != NSNotFound) {
+ NSString *key = [metadatum substringToIndex:equals];
+ NSString *value = [metadatum substringFromIndex:equals + 1];
+ if ([@"ENCODING" caseInsensitiveCompare:key] == NSOrderedSame &&
+ [@"QUOTED-PRINTABLE" caseInsensitiveCompare:value] == NSOrderedSame) {
+ quotedPrintable = YES;
+ } else if ([@"CHARSET" caseInsensitiveCompare:key] == NSOrderedSame) {
+ quotedPrintableCharset = value;
+ }
+ }
+ }
+ }
+
+ NSUInteger matchStart = i; // Found the start of a match here
+
+ while ((NSUInteger)(i = [rawText rangeOfString:@"\n" options:NSLiteralSearch range:NSMakeRange(i, [rawText length] - i)].location) != NSNotFound) { // Really, end in \r\n
+ if (i < [rawText length] - 1 && // But if followed by tab or space,
+ ([rawText characterAtIndex:i + 1] == ' ' || // this is only a continuation
+ [rawText characterAtIndex:i + 1] == '\t')) {
+ i += 2; // Skip \n and continutation whitespace
+ } else if (quotedPrintable && // If preceded by = in quoted printable
+ ((i >= 1 && [rawText characterAtIndex:i - 1] == '=') || // this is a continuation
+ (i >= 2 && [rawText characterAtIndex:i - 2] == '='))) {
+ i++; // Skip \n
+ } else {
+ break;
+ }
+ }
+
+ if (i == NSNotFound) {
+ // No terminating end character? uh, done. Set i such that loop terminates and break
+ i = max;
+ } else if (i > matchStart) {
+ // found a match
+ if (matches == nil) {
+ matches = [NSMutableArray arrayWithCapacity:1];
+ }
+ if (i >= 1 && [rawText characterAtIndex:i-1] == '\r') {
+ i--; // Back up over \r, which really should be there
+ }
+ NSString *element = [rawText substringWithRange:NSMakeRange(matchStart, i - matchStart)];
+ if (trim) {
+ element = [element stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ }
+ if (quotedPrintable) {
+ element = [self decodeQuotedPrintable:element charset:quotedPrintableCharset];
+ if (parseFieldDivider) {
+ element = [[UNESCAPED_SEMICOLONS stringByReplacingMatchesInString:element options:0 range:NSMakeRange(0, element.length) withTemplate:@"\n"]
+ stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ }
+ } else {
+ if (parseFieldDivider) {
+ element = [[UNESCAPED_SEMICOLONS stringByReplacingMatchesInString:element options:0 range:NSMakeRange(0, element.length) withTemplate:@"\n"]
+ stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ }
+ element = [CR_LF_SPACE_TAB stringByReplacingMatchesInString:element options:0 range:NSMakeRange(0, element.length) withTemplate:@""];
+ element = [NEWLINE_ESCAPE stringByReplacingMatchesInString:element options:0 range:NSMakeRange(0, element.length) withTemplate:@"\n"];
+ element = [VCARD_ESCAPES stringByReplacingMatchesInString:element options:0 range:NSMakeRange(0, element.length) withTemplate:@"$1"];
+ }
+ if (metadata == nil) {
+ NSMutableArray *match = [NSMutableArray arrayWithObject:element];
+ [match addObject:element];
+ [matches addObject:match];
+ } else {
+ [metadata insertObject:element atIndex:0];
+ [matches addObject:metadata];
+ }
+ i++;
+ } else {
+ i++;
+ }
+ }
+
+ return matches;
+}
+
++ (NSString *)decodeQuotedPrintable:(NSString *)value charset:(NSString *)charset {
+ NSUInteger length = [value length];
+ NSMutableString *result = [NSMutableString stringWithCapacity:length];
+ NSMutableData *fragmentBuffer = [NSMutableData data];
+
+ for (int i = 0; i < length; i++) {
+ unichar c = [value characterAtIndex:i];
+
+ switch (c) {
+ case '\r':
+ case '\n':
+ break;
+ case '=':
+ if (i < length - 2) {
+ unichar nextChar = [value characterAtIndex:i + 1];
+ if (nextChar != '\r' && nextChar != '\n') {
+ unichar nextNextChar = [value characterAtIndex:i + 2];
+ int firstDigit = [self parseHexDigit:nextChar];
+ int secondDigit = [self parseHexDigit:nextNextChar];
+ if (firstDigit >= 0 && secondDigit >= 0) {
+ int encodedByte = (firstDigit << 4) + secondDigit;
+ [fragmentBuffer appendBytes:&encodedByte length:1];
+ } // else ignore it, assume it was incorrectly encoded
+ i += 2;
+ }
+ }
+ break;
+ default:
+ [self maybeAppendFragment:fragmentBuffer charset:charset result:result];
+ [result appendFormat:@"%C", c];
+ }
+ }
+
+ [self maybeAppendFragment:fragmentBuffer charset:charset result:result];
+ return result;
+}
+
++ (void)maybeAppendFragment:(NSMutableData *)fragmentBuffer charset:(NSString *)charset result:(NSMutableString *)result {
+ if ([fragmentBuffer length] > 0) {
+ NSString *fragment;
+ if (charset == nil || CFStringConvertIANACharSetNameToEncoding((CFStringRef)charset) == kCFStringEncodingInvalidId) {
+ fragment = [[NSString alloc] initWithData:fragmentBuffer encoding:NSUTF8StringEncoding];
+ } else {
+ fragment = [[NSString alloc] initWithData:fragmentBuffer encoding:CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef)charset))];
+ }
+ [fragmentBuffer setLength:0];
+ [result appendString:fragment];
+ }
+}
+
++ (NSArray *)matchSingleVCardPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim parseFieldDivider:(BOOL)parseFieldDivider {
+ NSArray *values = [self matchVCardPrefixedField:prefix rawText:rawText trim:trim parseFieldDivider:parseFieldDivider];
+ return values == nil ? nil : values[0];
+}
+
+- (NSString *)toPrimaryValue:(NSArray *)list {
+ return list == nil || list.count == 0 ? nil : list[0];
+}
+
+- (NSArray *)toPrimaryValues:(NSArray *)lists {
+ if (lists == nil || lists.count == 0) {
+ return nil;
+ }
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:lists.count];
+ for (NSArray *list in lists) {
+ NSString *value = list[0];
+ if (value != nil && value.length > 0) {
+ [result addObject:value];
+ }
+ }
+ return result;
+}
+
+- (NSArray *)toTypes:(NSArray *)lists {
+ if (lists == nil || lists.count == 0) {
+ return nil;
+ }
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:lists.count];
+ for (NSArray *list in lists) {
+ NSString *type = nil;
+ for (int i = 1; i < list.count; i++) {
+ NSString *metadatum = list[i];
+ NSUInteger equals = [metadatum rangeOfString:@"=" options:NSCaseInsensitiveSearch].location;
+ if (equals == NSNotFound) {
+ // take the whole thing as a usable label
+ type = metadatum;
+ break;
+ }
+ if ([@"TYPE" isEqualToString:[[metadatum substringToIndex:equals] uppercaseString]]) {
+ type = [metadatum substringFromIndex:equals + 1];
+ break;
+ }
+ }
+
+ if (type) {
+ [result addObject:type];
+ } else {
+ [result addObject:[NSNull null]];
+ }
+ }
+ return result;
+}
+
+- (BOOL)isLikeVCardDate:(NSString *)value {
+ return value == nil || [VCARD_LIKE_DATE numberOfMatchesInString:value options:0 range:NSMakeRange(0, value.length)] > 0;
+}
+
+/**
+ * Formats name fields of the form "Public;John;Q.;Reverend;III" into a form like
+ * "Reverend John Q. Public III".
+ */
+- (void)formatNames:(NSMutableArray *)names {
+ if (names != nil) {
+ for (NSMutableArray *list in names) {
+ NSString *name = list[0];
+ NSMutableArray *components = [NSMutableArray arrayWithCapacity:5];
+ NSUInteger start = 0;
+ NSUInteger end;
+ while ((end = [name rangeOfString:@";" options:NSLiteralSearch range:NSMakeRange(start, [name length] - start)].location) != NSNotFound && end > 0) {
+ [components addObject:[name substringWithRange:NSMakeRange(start, [name length] - end - 1)]];
+ start = end + 1;
+ }
+
+ [components addObject:[name substringFromIndex:start]];
+ NSMutableString *newName = [NSMutableString stringWithCapacity:100];
+ [self maybeAppendComponent:components i:3 newName:newName];
+ [self maybeAppendComponent:components i:1 newName:newName];
+ [self maybeAppendComponent:components i:2 newName:newName];
+ [self maybeAppendComponent:components i:0 newName:newName];
+ [self maybeAppendComponent:components i:4 newName:newName];
+ list[0] = [newName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ }
+ }
+}
+
+- (void)maybeAppendComponent:(NSArray *)components i:(int)i newName:(NSMutableString *)newName {
+ if ([components count] > i && components[i]) {
+ [newName appendFormat:@" %@", components[i]];
+ }
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXVEventResultParser.h b/ZXingObjC/client/result/ZXVEventResultParser.h
new file mode 100644
index 0000000..839f72f
--- /dev/null
+++ b/ZXingObjC/client/result/ZXVEventResultParser.h
@@ -0,0 +1,26 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Partially implements the iCalendar format's "VEVENT" format for specifying a
+ * calendar event. See RFC 2445. This supports SUMMARY, LOCATION, GEO, DTSTART and DTEND fields.
+ */
+
+@interface ZXVEventResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXVEventResultParser.m b/ZXingObjC/client/result/ZXVEventResultParser.m
new file mode 100644
index 0000000..7beac8d
--- /dev/null
+++ b/ZXingObjC/client/result/ZXVEventResultParser.m
@@ -0,0 +1,105 @@
+/*
+ * 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 "ZXCalendarParsedResult.h"
+#import "ZXResult.h"
+#import "ZXVCardResultParser.h"
+#import "ZXVEventResultParser.h"
+
+@implementation ZXVEventResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (rawText == nil) {
+ return nil;
+ }
+ NSUInteger vEventStart = [rawText rangeOfString:@"BEGIN:VEVENT"].location;
+ if (vEventStart == NSNotFound) {
+ return nil;
+ }
+
+ NSString *summary = [self matchSingleVCardPrefixedField:@"SUMMARY" rawText:rawText trim:YES];
+ NSString *start = [self matchSingleVCardPrefixedField:@"DTSTART" rawText:rawText trim:YES];
+ if (start == nil) {
+ return nil;
+ }
+ NSString *end = [self matchSingleVCardPrefixedField:@"DTEND" rawText:rawText trim:YES];
+ NSString *duration = [self matchSingleVCardPrefixedField:@"DURATION" rawText:rawText trim:YES];
+ NSString *location = [self matchSingleVCardPrefixedField:@"LOCATION" rawText:rawText trim:YES];
+ NSString *organizer = [self stripMailto:[self matchSingleVCardPrefixedField:@"ORGANIZER" rawText:rawText trim:YES]];
+
+ NSMutableArray *attendees = [self matchVCardPrefixedField:@"ATTENDEE" rawText:rawText trim:YES];
+ if (attendees != nil) {
+ for (int i = 0; i < attendees.count; i++) {
+ attendees[i] = [self stripMailto:attendees[i]];
+ }
+ }
+ NSString *description = [self matchSingleVCardPrefixedField:@"DESCRIPTION" rawText:rawText trim:YES];
+
+ NSString *geoString = [self matchSingleVCardPrefixedField:@"GEO" rawText:rawText trim:YES];
+ double latitude;
+ double longitude;
+ if (geoString == nil) {
+ latitude = NAN;
+ longitude = NAN;
+ } else {
+ NSUInteger semicolon = [geoString rangeOfString:@";"].location;
+ latitude = [[geoString substringToIndex:semicolon] doubleValue];
+ longitude = [[geoString substringFromIndex:semicolon + 1] doubleValue];
+ }
+
+ @try {
+ return [ZXCalendarParsedResult calendarParsedResultWithSummary:summary
+ startString:start
+ endString:end
+ durationString:duration
+ location:location
+ organizer:organizer
+ attendees:attendees
+ description:description
+ latitude:latitude
+ longitude:longitude];
+ } @catch (NSException *iae) {
+ return nil;
+ }
+}
+
+- (NSString *)matchSingleVCardPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim {
+ NSArray *values = [ZXVCardResultParser matchSingleVCardPrefixedField:prefix rawText:rawText trim:trim parseFieldDivider:NO];
+ return values == nil || values.count == 0 ? nil : values[0];
+}
+
+- (NSMutableArray *)matchVCardPrefixedField:(NSString *)prefix rawText:(NSString *)rawText trim:(BOOL)trim {
+ NSMutableArray *values = [ZXVCardResultParser matchVCardPrefixedField:prefix rawText:rawText trim:trim parseFieldDivider:NO];
+ if (values == nil || values.count == 0) {
+ return nil;
+ }
+ NSUInteger size = values.count;
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:size];
+ for (int i = 0; i < size; i++) {
+ [result addObject:values[i][0]];
+ }
+ return result;
+}
+
+- (NSString *)stripMailto:(NSString *)s {
+ if (s != nil && ([s hasPrefix:@"mailto:"] || [s hasPrefix:@"MAILTO:"])) {
+ s = [s substringFromIndex:7];
+ }
+ return s;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXWifiParsedResult.h b/ZXingObjC/client/result/ZXWifiParsedResult.h
new file mode 100644
index 0000000..708a1df
--- /dev/null
+++ b/ZXingObjC/client/result/ZXWifiParsedResult.h
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXParsedResult.h"
+
+@interface ZXWifiParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *ssid;
+@property (nonatomic, copy, readonly) NSString *networkEncryption;
+@property (nonatomic, copy, readonly) NSString *password;
+@property (nonatomic, assign, readonly) BOOL hidden;
+
+- (id)initWithNetworkEncryption:(NSString *)networkEncryption ssid:(NSString *)ssid password:(NSString *)password;
+- (id)initWithNetworkEncryption:(NSString *)networkEncryption ssid:(NSString *)ssid password:(NSString *)password hidden:(BOOL)hidden;
++ (id)wifiParsedResultWithNetworkEncryption:(NSString *)networkEncryption ssid:(NSString *)ssid password:(NSString *)password;
++ (id)wifiParsedResultWithNetworkEncryption:(NSString *)networkEncryption ssid:(NSString *)ssid password:(NSString *)password hidden:(BOOL)hidden;
+
+@end
diff --git a/ZXingObjC/client/result/ZXWifiParsedResult.m b/ZXingObjC/client/result/ZXWifiParsedResult.m
new file mode 100644
index 0000000..cc6e655
--- /dev/null
+++ b/ZXingObjC/client/result/ZXWifiParsedResult.m
@@ -0,0 +1,54 @@
+/*
+ * 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 "ZXParsedResultType.h"
+#import "ZXWifiParsedResult.h"
+
+@implementation ZXWifiParsedResult
+
+- (id)initWithNetworkEncryption:(NSString *)networkEncryption ssid:(NSString *)ssid password:(NSString *)password {
+ return [self initWithNetworkEncryption:networkEncryption ssid:ssid password:password];
+}
+
+- (id)initWithNetworkEncryption:(NSString *)networkEncryption ssid:(NSString *)ssid password:(NSString *)password hidden:(BOOL)hidden {
+ if (self = [super initWithType:kParsedResultTypeWifi]) {
+ _ssid = ssid;
+ _networkEncryption = networkEncryption;
+ _password = password;
+ _hidden = hidden;
+ }
+
+ return self;
+}
+
++ (id)wifiParsedResultWithNetworkEncryption:(NSString *)networkEncryption ssid:(NSString *)ssid password:(NSString *)password {
+ return [[self alloc] initWithNetworkEncryption:networkEncryption ssid:ssid password:password];
+}
+
++ (id)wifiParsedResultWithNetworkEncryption:(NSString *)networkEncryption ssid:(NSString *)ssid password:(NSString *)password hidden:(BOOL)hidden {
+ return [[self alloc] initWithNetworkEncryption:networkEncryption ssid:ssid password:password hidden:hidden];
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString stringWithCapacity:80];
+ [ZXParsedResult maybeAppend:self.ssid result:result];
+ [ZXParsedResult maybeAppend:self.networkEncryption result:result];
+ [ZXParsedResult maybeAppend:self.password result:result];
+ [ZXParsedResult maybeAppend:[@(self.hidden) stringValue] result:result];
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/client/result/ZXWifiResultParser.h b/ZXingObjC/client/result/ZXWifiResultParser.h
new file mode 100644
index 0000000..39293f7
--- /dev/null
+++ b/ZXingObjC/client/result/ZXWifiResultParser.h
@@ -0,0 +1,28 @@
+/*
+ * 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 "ZXResultParser.h"
+
+/**
+ * Parses a WIFI configuration string. Strings will be of the form:
+ * WIFI:T:[network type];S:[SSID];P:[network password];H:[hidden?];;
+ *
+ * The fields can appear in any order. Only "S:" is required.
+ */
+
+@interface ZXWifiResultParser : ZXResultParser
+
+@end
diff --git a/ZXingObjC/client/result/ZXWifiResultParser.m b/ZXingObjC/client/result/ZXWifiResultParser.m
new file mode 100644
index 0000000..3b70ed2
--- /dev/null
+++ b/ZXingObjC/client/result/ZXWifiResultParser.m
@@ -0,0 +1,42 @@
+/*
+ * 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 "ZXResult.h"
+#import "ZXWifiResultParser.h"
+#import "ZXWifiParsedResult.h"
+
+@implementation ZXWifiResultParser
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (![rawText hasPrefix:@"WIFI:"]) {
+ return nil;
+ }
+ NSString *ssid = [[self class] matchSinglePrefixedField:@"S:" rawText:rawText endChar:';' trim:NO];
+ if (ssid == nil || ssid.length == 0) {
+ return nil;
+ }
+ NSString *pass = [[self class] matchSinglePrefixedField:@"P:" rawText:rawText endChar:';' trim:NO];
+ NSString *type = [[self class] matchSinglePrefixedField:@"T:" rawText:rawText endChar:';' trim:NO];
+ if (type == nil) {
+ type = @"nopass";
+ }
+
+ BOOL hidden = [[[self class] matchSinglePrefixedField:@"H:" rawText:rawText endChar:';' trim:NO] boolValue];
+ return [ZXWifiParsedResult wifiParsedResultWithNetworkEncryption:type ssid:ssid password:pass hidden:hidden];
+}
+
+@end
diff --git a/ZXingObjC/common/ZXBitArray.h b/ZXingObjC/common/ZXBitArray.h
new file mode 100644
index 0000000..bcc21c8
--- /dev/null
+++ b/ZXingObjC/common/ZXBitArray.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+/**
+ * A simple, fast array of bits, represented compactly by an array of ints internally.
+ */
+
+@interface ZXBitArray : NSObject
+
+@property (nonatomic, readonly) int32_t *bits;
+@property (nonatomic, readonly) int size;
+
+- (id)initWithSize:(int)size;
+- (int)sizeInBytes;
+- (BOOL)get:(int)i;
+- (void)set:(int)i;
+- (void)flip:(int)i;
+- (int)nextSet:(int)from;
+- (int)nextUnset:(int)from;
+- (void)setBulk:(int)i newBits:(int32_t)newBits;
+- (void)setRange:(int)start end:(int)end;
+- (void)clear;
+- (BOOL)isRange:(int)start end:(int)end value:(BOOL)value;
+- (void)appendBit:(BOOL)bit;
+- (void)appendBits:(int32_t)value numBits:(int)numBits;
+- (void)appendBitArray:(ZXBitArray *)other;
+- (void)xor:(ZXBitArray *)other;
+- (void)toBytes:(int)bitOffset array:(int8_t *)array offset:(int)offset numBytes:(int)numBytes;
+- (void)reverse;
+
+@end
diff --git a/ZXingObjC/common/ZXBitArray.m b/ZXingObjC/common/ZXBitArray.m
new file mode 100644
index 0000000..fec6270
--- /dev/null
+++ b/ZXingObjC/common/ZXBitArray.m
@@ -0,0 +1,311 @@
+/*
+ * 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 "ZXBitArray.h"
+
+@interface ZXBitArray ()
+
+@property (nonatomic, assign) int32_t *bits;
+@property (nonatomic, assign) int bitsLength;
+@property (nonatomic, assign) int size;
+
+@end
+
+@implementation ZXBitArray
+
+- (id)init {
+ if (self = [super init]) {
+ _size = 0;
+ _bits = (int32_t *)malloc(1 * sizeof(int32_t));
+ _bitsLength = 1;
+ _bits[0] = 0;
+ }
+
+ return self;
+}
+
+- (id)initWithSize:(int)size {
+ if (self = [super init]) {
+ _size = size;
+ _bitsLength = (size + 31) >> 5;
+
+ _bits = (int32_t *)malloc(_bitsLength * sizeof(int32_t));
+ memset(_bits, 0, _bitsLength * sizeof(int32_t));
+ }
+
+ return self;
+}
+
+
+- (void)dealloc {
+ if (_bits != NULL) {
+ free(_bits);
+ _bits = NULL;
+ }
+}
+
+- (int)sizeInBytes {
+ return (self.size + 7) >> 3;
+}
+
+- (void)ensureCapacity:(int)size {
+ if (size > self.bitsLength << 5) {
+ int newBitsLength = (size + 31) >> 5;
+ self.bits = realloc(self.bits, newBitsLength * sizeof(int32_t));
+ memset(self.bits + self.bitsLength, 0, (newBitsLength - self.bitsLength) * sizeof(int32_t));
+
+ self.bitsLength = newBitsLength;
+ }
+}
+
+
+- (BOOL)get:(int)i {
+ return (self.bits[i >> 5] & (1 << (i & 0x1F))) != 0;
+}
+
+
+- (void)set:(int)i {
+ self.bits[i >> 5] |= 1 << (i & 0x1F);
+}
+
+/**
+ * Flips bit i.
+ */
+- (void)flip:(int)i {
+ self.bits[i >> 5] ^= 1 << (i & 0x1F);
+}
+
+- (int)nextSet:(int)from {
+ if (from >= self.size) {
+ return self.size;
+ }
+ int bitsOffset = from >> 5;
+ int32_t currentBits = self.bits[bitsOffset];
+ // mask off lesser bits first
+ currentBits &= ~((1 << (from & 0x1F)) - 1);
+ while (currentBits == 0) {
+ if (++bitsOffset == self.bitsLength) {
+ return self.size;
+ }
+ currentBits = self.bits[bitsOffset];
+ }
+ int result = (bitsOffset << 5) + [self numberOfTrailingZeros:currentBits];
+ return result > self.size ? self.size : result;
+}
+
+- (int)nextUnset:(int)from {
+ if (from >= self.size) {
+ return self.size;
+ }
+ int bitsOffset = from >> 5;
+ int32_t currentBits = ~self.bits[bitsOffset];
+ // mask off lesser bits first
+ currentBits &= ~((1 << (from & 0x1F)) - 1);
+ while (currentBits == 0) {
+ if (++bitsOffset == self.bitsLength) {
+ return self.size;
+ }
+ currentBits = ~self.bits[bitsOffset];
+ }
+ int result = (bitsOffset << 5) + [self numberOfTrailingZeros:currentBits];
+ return result > self.size ? self.size : result;
+}
+
+/**
+ * Sets a block of 32 bits, starting at bit i.
+ *
+ * newBits is the new value of the next 32 bits. Note again that the least-significant bit
+ * corresponds to bit i, the next-least-significant to i+1, and so on.
+ */
+- (void)setBulk:(int)i newBits:(int32_t)newBits {
+ self.bits[i >> 5] = newBits;
+}
+
+/**
+ * Sets a range of bits.
+ */
+- (void)setRange:(int)start end:(int)end {
+ if (end < start) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Start greater than end" userInfo:nil];
+ }
+ if (end == start) {
+ return;
+ }
+ end--; // will be easier to treat this as the last actually set bit -- inclusive
+ int firstInt = start >> 5;
+ int lastInt = end >> 5;
+ 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 (firstBit == 0 && lastBit == 31) {
+ mask = -1;
+ } else {
+ mask = 0;
+ for (int j = firstBit; j <= lastBit; j++) {
+ mask |= 1 << j;
+ }
+ }
+ self.bits[i] |= mask;
+ }
+}
+
+/**
+ * Clears all bits (sets to false).
+ */
+- (void)clear {
+ memset(self.bits, 0, self.bitsLength * sizeof(int32_t));
+}
+
+/**
+ * Efficient method to check if a range of bits is set, or not set.
+ */
+- (BOOL)isRange:(int)start end:(int)end value:(BOOL)value {
+ if (end < start) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Start greater than end" userInfo:nil];
+ }
+ if (end == start) {
+ return YES;
+ }
+ end--;
+ int firstInt = start >> 5;
+ int lastInt = end >> 5;
+
+ 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 (firstBit == 0 && lastBit == 31) {
+ mask = -1;
+ } else {
+ mask = 0;
+
+ for (int j = firstBit; j <= lastBit; j++) {
+ mask |= 1 << j;
+ }
+ }
+ if ((self.bits[i] & mask) != (value ? mask : 0)) {
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+- (void)appendBit:(BOOL)bit {
+ [self ensureCapacity:self.size + 1];
+ if (bit) {
+ self.bits[self.size >> 5] |= 1 << (self.size & 0x1F);
+ }
+ self.size++;
+}
+
+/**
+ * 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.
+ */
+- (void)appendBits:(int32_t)value numBits:(int)numBits {
+ if (numBits < 0 || numBits > 32) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"Num bits must be between 0 and 32"
+ userInfo:nil];
+ }
+ [self ensureCapacity:self.size + numBits];
+ for (int numBitsLeft = numBits; numBitsLeft > 0; numBitsLeft--) {
+ [self appendBit:((value >> (numBitsLeft - 1)) & 0x01) == 1];
+ }
+}
+
+- (void)appendBitArray:(ZXBitArray *)other {
+ int otherSize = [other size];
+ [self ensureCapacity:self.size + otherSize];
+
+ for (int i = 0; i < otherSize; i++) {
+ [self appendBit:[other get:i]];
+ }
+}
+
+- (void)xor:(ZXBitArray *)other {
+ if (self.bitsLength != other.bitsLength) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"Sizes don't match"
+ userInfo:nil];
+ }
+
+ for (int i = 0; i < self.bitsLength; i++) {
+ self.bits[i] ^= other.bits[i];
+ }
+}
+
+
+- (void)toBytes:(int)bitOffset array:(int8_t *)array offset:(int)offset numBytes:(int)numBytes {
+ for (int i = 0; i < numBytes; i++) {
+ int32_t theByte = 0;
+ for (int j = 0; j < 8; j++) {
+ if ([self get:bitOffset]) {
+ theByte |= 1 << (7 - j);
+ }
+ bitOffset++;
+ }
+ array[offset + i] = (int8_t)theByte;
+ }
+}
+
+/**
+ * Reverses all bits in the array.
+ */
+- (void)reverse {
+ int32_t *newBits = (int32_t *)malloc(self.size * sizeof(int32_t));
+ memset(newBits, 0, self.size * sizeof(int32_t));
+ for (int i = 0; i < self.size; i++) {
+ if ([self get:self.size - i - 1]) {
+ newBits[i >> 5] |= 1 << (i & 0x1F);
+ }
+ }
+
+ if (self.bits != NULL) {
+ free(self.bits);
+ }
+ self.bits = newBits;
+}
+
+- (NSString *)description {
+ NSMutableString *result = [NSMutableString string];
+
+ for (int i = 0; i < self.size; i++) {
+ if ((i & 0x07) == 0) {
+ [result appendString:@" "];
+ }
+ [result appendString:[self get:i] ? @"X" : @"."];
+ }
+
+ return result;
+}
+
+// Ported from OpenJDK Integer.numberOfTrailingZeros implementation
+- (int32_t)numberOfTrailingZeros:(int32_t)i {
+ int32_t y;
+ if (i == 0) return 32;
+ int32_t n = 31;
+ y = i <<16; if (y != 0) { n = n -16; i = y; }
+ y = i << 8; if (y != 0) { n = n - 8; i = y; }
+ y = i << 4; if (y != 0) { n = n - 4; i = y; }
+ y = i << 2; if (y != 0) { n = n - 2; i = y; }
+ return n - (int32_t)((uint32_t)(i << 1) >> 31);
+}
+
+@end
diff --git a/ZXingObjC/common/ZXBitMatrix.h b/ZXingObjC/common/ZXBitMatrix.h
new file mode 100644
index 0000000..a4c05d3
--- /dev/null
+++ b/ZXingObjC/common/ZXBitMatrix.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * Represents a 2D matrix of bits. In function arguments below, and throughout the common
+ * module, x is the column position, and y is the row position. The ordering is always x, y.
+ * The origin is at the top-left.
+ *
+ * Internally the bits are represented in a 1-D array of 32-bit ints. However, each row begins
+ * with a new NSInteger. This is done intentionally so that we can copy out a row into a BitArray very
+ * efficiently.
+ *
+ * The ordering of bits is row-major. Within each NSInteger, the least significant bits are used first,
+ * meaning they represent lower x values. This is compatible with BitArray's implementation.
+ */
+
+@class ZXBitArray;
+
+@interface ZXBitMatrix : NSObject
+
+@property (nonatomic, readonly) int width;
+@property (nonatomic, readonly) int height;
+@property (nonatomic, readonly) int32_t *bits;
+
++ (ZXBitMatrix *)bitMatrixWithDimension:(int)dimension;
++ (ZXBitMatrix *)bitMatrixWithWidth:(int)width height:(int)height;
+
+- (id)initWithDimension:(int)dimension;
+- (id)initWithWidth:(int)width height:(int)height;
+
+- (BOOL)getX:(int)x y:(int)y;
+- (void)setX:(int)x y:(int)y;
+- (void)flipX:(int)x y:(int)y;
+- (void)clear;
+- (void)setRegionAtLeft:(int)left top:(int)top width:(int)width height:(int)height;
+- (ZXBitArray *)rowAtY:(int)y row:(ZXBitArray *)row;
+- (void)setRowAtY:(int)y row:(ZXBitArray *)row;
+- (NSArray *)enclosingRectangle;
+- (NSArray *)topLeftOnBit;
+- (NSArray *)bottomRightOnBit;
+
+@end
diff --git a/ZXingObjC/common/ZXBitMatrix.m b/ZXingObjC/common/ZXBitMatrix.m
new file mode 100644
index 0000000..d502ed6
--- /dev/null
+++ b/ZXingObjC/common/ZXBitMatrix.m
@@ -0,0 +1,281 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXBitMatrix.h"
+
+@interface ZXBitMatrix ()
+
+@property (nonatomic, assign) int rowSize;
+@property (nonatomic, assign) int bitsSize;
+
+@end
+
+@implementation ZXBitMatrix
+
++ (ZXBitMatrix *)bitMatrixWithDimension:(int)dimension {
+ return [[self alloc] initWithDimension:dimension];
+}
+
++ (ZXBitMatrix *)bitMatrixWithWidth:(int)width height:(int)height {
+ return [[self alloc] initWithWidth:width height:height];
+}
+
+- (id)initWithDimension:(int)dimension {
+ return [self initWithWidth:dimension height:dimension];
+}
+
+- (id)initWithWidth:(int)width height:(int)height {
+ if (self = [super init]) {
+ if (width < 1 || height < 1) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"Both dimensions must be greater than 0"
+ userInfo:nil];
+ }
+ _width = width;
+ _height = height;
+ _rowSize = (_width + 31) >> 5;
+ _bitsSize = _rowSize * _height;
+ _bits = (int32_t *)malloc(_bitsSize * sizeof(int32_t));
+ [self clear];
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_bits != NULL) {
+ free(_bits);
+ _bits = NULL;
+ }
+}
+
+/**
+ * Gets the requested bit, where true means black.
+ */
+- (BOOL)getX:(int)x y:(int)y {
+ NSInteger offset = y * self.rowSize + (x >> 5);
+ return ((self.bits[offset] >> (x & 0x1f)) & 1) != 0;
+}
+
+/**
+ * Sets the given bit to true.
+ */
+- (void)setX:(int)x y:(int)y {
+ NSInteger offset = y * self.rowSize + (x >> 5);
+ self.bits[offset] |= 1 << (x & 0x1f);
+}
+
+/**
+ * Flips the given bit.
+ */
+- (void)flipX:(int)x y:(int)y {
+ NSUInteger offset = y * self.rowSize + (x >> 5);
+ self.bits[offset] ^= 1 << (x & 0x1f);
+}
+
+/**
+ * Clears all bits (sets to false).
+ */
+- (void)clear {
+ NSInteger max = self.bitsSize;
+ memset(self.bits, 0, max * sizeof(int32_t));
+}
+
+/**
+ * Sets a square region of the bit matrix to true.
+ */
+- (void)setRegionAtLeft:(int)left top:(int)top width:(int)aWidth height:(int)aHeight {
+ if (aHeight < 1 || aWidth < 1) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"Height and width must be at least 1"
+ userInfo:nil];
+ }
+ NSUInteger right = left + aWidth;
+ NSUInteger bottom = top + aHeight;
+ if (bottom > self.height || right > self.width) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"The region must fit inside the matrix"
+ userInfo:nil];
+ }
+ for (NSUInteger y = top; y < bottom; y++) {
+ NSUInteger offset = y * self.rowSize;
+ for (NSInteger x = left; x < right; x++) {
+ self.bits[offset + (x >> 5)] |= 1 << (x & 0x1f);
+ }
+ }
+}
+
+/**
+ * A fast method to retrieve one row of data from the matrix as a BitArray.
+ */
+- (ZXBitArray *)rowAtY:(int)y row:(ZXBitArray *)row {
+ if (row == nil || [row size] < self.width) {
+ row = [[ZXBitArray alloc] initWithSize:self.width];
+ }
+ int offset = y * self.rowSize;
+ for (int x = 0; x < self.rowSize; x++) {
+ [row setBulk:x << 5 newBits:self.bits[offset + x]];
+ }
+
+ return row;
+}
+
+- (void)setRowAtY:(int)y row:(ZXBitArray *)row {
+ for (NSUInteger i = 0; i < self.rowSize; i++) {
+ self.bits[(y * self.rowSize) + i] = row.bits[i];
+ }
+}
+
+/**
+ * This is useful in detecting the enclosing rectangle of a 'pure' barcode.
+ *
+ * Returns {left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white
+ */
+- (NSArray *)enclosingRectangle {
+ int left = self.width;
+ int top = self.height;
+ int right = -1;
+ int bottom = -1;
+
+ for (int y = 0; y < self.height; y++) {
+ for (int x32 = 0; x32 < self.rowSize; x32++) {
+ int32_t theBits = self.bits[y * self.rowSize + x32];
+ if (theBits != 0) {
+ if (y < top) {
+ top = y;
+ }
+ if (y > bottom) {
+ bottom = y;
+ }
+ if (x32 * 32 < left) {
+ int32_t bit = 0;
+ while ((theBits << (31 - bit)) == 0) {
+ bit++;
+ }
+ if ((x32 * 32 + bit) < left) {
+ left = x32 * 32 + bit;
+ }
+ }
+ if (x32 * 32 + 31 > right) {
+ int bit = 31;
+ while ((theBits >> bit) == 0) {
+ bit--;
+ }
+ if ((x32 * 32 + bit) > right) {
+ right = x32 * 32 + bit;
+ }
+ }
+ }
+ }
+ }
+
+ NSInteger width = right - left;
+ NSInteger height = bottom - top;
+
+ if (width < 0 || height < 0) {
+ return nil;
+ }
+
+ return @[@(left), @(top), @(_width), @(_height)];
+}
+
+/**
+ * This is useful in detecting a corner of a 'pure' barcode.
+ *
+ * Returns {x,y} coordinate of top-left-most 1 bit, or null if it is all white
+ */
+- (NSArray *)topLeftOnBit {
+ int bitsOffset = 0;
+ while (bitsOffset < self.bitsSize && self.bits[bitsOffset] == 0) {
+ bitsOffset++;
+ }
+ if (bitsOffset == self.bitsSize) {
+ return nil;
+ }
+ int y = bitsOffset / self.rowSize;
+ int x = (bitsOffset % self.rowSize) << 5;
+
+ int32_t theBits = self.bits[bitsOffset];
+ int32_t bit = 0;
+ while ((theBits << (31 - bit)) == 0) {
+ bit++;
+ }
+ x += bit;
+ return @[@(x), @(y)];
+}
+
+- (NSArray *)bottomRightOnBit {
+ int bitsOffset = self.bitsSize - 1;
+ while (bitsOffset >= 0 && self.bits[bitsOffset] == 0) {
+ bitsOffset--;
+ }
+ if (bitsOffset < 0) {
+ return nil;
+ }
+
+ int y = bitsOffset / self.rowSize;
+ int x = (bitsOffset % self.rowSize) << 5;
+
+ int32_t theBits = self.bits[bitsOffset];
+ int32_t bit = 31;
+ while ((theBits >> bit) == 0) {
+ bit--;
+ }
+ x += bit;
+
+ return @[@(x), @(y)];
+}
+
+- (BOOL)isEqual:(NSObject *)o {
+ if (!([o isKindOfClass:[ZXBitMatrix class]])) {
+ return NO;
+ }
+ ZXBitMatrix *other = (ZXBitMatrix *)o;
+ if (self.width != other.width || self.height != other.height || self.rowSize != other.rowSize || self.bitsSize != other.bitsSize) {
+ return NO;
+ }
+ for (int i = 0; i < self.bitsSize; i++) {
+ if (self.bits[i] != other.bits[i]) {
+ return NO;
+ }
+ }
+ return YES;
+}
+
+- (NSUInteger)hash {
+ NSInteger hash = self.width;
+ hash = 31 * hash + self.width;
+ hash = 31 * hash + self.height;
+ hash = 31 * hash + self.rowSize;
+ for (NSUInteger i = 0; i < self.bitsSize; i++) {
+ hash = 31 * hash + self.bits[i];
+ }
+ return hash;
+}
+
+- (NSString *)description {
+ NSMutableString *result = [NSMutableString stringWithCapacity:self.height * (self.width + 1)];
+ for (int y = 0; y < self.height; y++) {
+ for (int x = 0; x < self.width; x++) {
+ [result appendString:[self getX:x y:y] ? @"X " : @" "];
+ }
+ [result appendString:@"\n"];
+ }
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/common/ZXBitSource.h b/ZXingObjC/common/ZXBitSource.h
new file mode 100644
index 0000000..9e95589
--- /dev/null
+++ b/ZXingObjC/common/ZXBitSource.h
@@ -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.
+ */
+
+/**
+ * This provides an easy abstraction to read bits at a time from a sequence of bytes, where the
+ * number of bits read is not often a multiple of 8.
+ *
+ * This class is thread-safe but not reentrant -- unless the caller modifies the bytes array
+ * it passed in, in which case all bets are off.
+ */
+
+@interface ZXBitSource : NSObject
+
+@property (nonatomic, assign, readonly) int bitOffset;
+@property (nonatomic, assign, readonly) int byteOffset;
+
+- (id)initWithBytes:(int8_t *)bytes length:(unsigned int)length;
+- (int)readBits:(int)numBits;
+- (int)available;
+
+@end
diff --git a/ZXingObjC/common/ZXBitSource.m b/ZXingObjC/common/ZXBitSource.m
new file mode 100644
index 0000000..b10fbb1
--- /dev/null
+++ b/ZXingObjC/common/ZXBitSource.m
@@ -0,0 +1,84 @@
+/*
+ * 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 "ZXBitSource.h"
+
+@interface ZXBitSource ()
+
+@property (nonatomic, assign) int8_t *bytes;
+@property (nonatomic, assign) int byteOffset;
+@property (nonatomic, assign) int bitOffset;
+@property (nonatomic, assign) int length;
+
+@end
+
+@implementation ZXBitSource
+
+/**
+ * bytes is the bytes from which this will read bits. Bits will be read from the first byte first.
+ * Bits are read within a byte from most-significant to least-significant bit.
+ */
+- (id)initWithBytes:(int8_t *)bytes length:(unsigned int)length {
+ if (self = [super init]) {
+ _bytes = bytes;
+ _length = length;
+ }
+ return self;
+}
+
+
+- (int)readBits:(int)numBits {
+ if (numBits < 1 || numBits > 32 || numBits > self.available) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Invalid number of bits: %d", numBits];
+ }
+ int result = 0;
+ if (self.bitOffset > 0) {
+ int bitsLeft = 8 - self.bitOffset;
+ int toRead = numBits < bitsLeft ? numBits : bitsLeft;
+ int bitsToNotRead = bitsLeft - toRead;
+ int mask = (0xFF >> (8 - toRead)) << bitsToNotRead;
+ result = (self.bytes[self.byteOffset] & mask) >> bitsToNotRead;
+ numBits -= toRead;
+ self.bitOffset += toRead;
+ if (self.bitOffset == 8) {
+ self.bitOffset = 0;
+ self.byteOffset++;
+ }
+ }
+
+ if (numBits > 0) {
+ while (numBits >= 8) {
+ result = (result << 8) | (self.bytes[self.byteOffset] & 0xFF);
+ self.byteOffset++;
+ numBits -= 8;
+ }
+
+ if (numBits > 0) {
+ int bitsToNotRead = 8 - numBits;
+ int mask = (0xFF >> bitsToNotRead) << bitsToNotRead;
+ result = (result << numBits) | ((self.bytes[self.byteOffset] & mask) >> bitsToNotRead);
+ self.bitOffset += numBits;
+ }
+ }
+ return result;
+}
+
+- (int)available {
+ return 8 * (self.length - self.byteOffset) - self.bitOffset;
+}
+
+@end
diff --git a/ZXingObjC/common/ZXCharacterSetECI.h b/ZXingObjC/common/ZXCharacterSetECI.h
new file mode 100644
index 0000000..b5a1f8e
--- /dev/null
+++ b/ZXingObjC/common/ZXCharacterSetECI.h
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXECI.h"
+
+/**
+ * Encapsulates a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1
+ * of ISO 18004.
+ */
+
+@interface ZXCharacterSetECI : ZXECI
+
+@property (nonatomic, readonly) NSStringEncoding encoding;
+
++ (ZXCharacterSetECI *)characterSetECIByValue:(int)value;
++ (ZXCharacterSetECI *)characterSetECIByEncoding:(NSStringEncoding)encoding;
+
+@end
diff --git a/ZXingObjC/common/ZXCharacterSetECI.m b/ZXingObjC/common/ZXCharacterSetECI.m
new file mode 100644
index 0000000..4d016b3
--- /dev/null
+++ b/ZXingObjC/common/ZXCharacterSetECI.m
@@ -0,0 +1,92 @@
+/*
+ * 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 "ZXCharacterSetECI.h"
+#import "ZXErrors.h"
+
+static NSMutableDictionary *VALUE_TO_ECI = nil;
+static NSMutableDictionary *ENCODING_TO_ECI = nil;
+
+@implementation ZXCharacterSetECI
+
++ (void)initialize {
+ VALUE_TO_ECI = [[NSMutableDictionary alloc] initWithCapacity:29];
+ ENCODING_TO_ECI = [[NSMutableDictionary alloc] initWithCapacity:29];
+ [self addCharacterSet:0 encoding:(NSStringEncoding) 0x80000400];
+ [self addCharacterSet:1 encoding:NSISOLatin1StringEncoding];
+ [self addCharacterSet:2 encoding:(NSStringEncoding) 0x80000400];
+ [self addCharacterSet:3 encoding:NSISOLatin1StringEncoding];
+ [self addCharacterSet:4 encoding:NSISOLatin2StringEncoding];
+ [self addCharacterSet:5 encoding:(NSStringEncoding) 0x80000203];
+ [self addCharacterSet:6 encoding:(NSStringEncoding) 0x80000204];
+ [self addCharacterSet:7 encoding:(NSStringEncoding) 0x80000205];
+ [self addCharacterSet:8 encoding:(NSStringEncoding) 0x80000206];
+ [self addCharacterSet:9 encoding:(NSStringEncoding) 0x80000207];
+ [self addCharacterSet:10 encoding:(NSStringEncoding) 0x80000208];
+ [self addCharacterSet:11 encoding:(NSStringEncoding) 0x80000209];
+ [self addCharacterSet:12 encoding:(NSStringEncoding) 0x8000020A];
+ [self addCharacterSet:13 encoding:(NSStringEncoding) 0x8000020B];
+ [self addCharacterSet:15 encoding:(NSStringEncoding) 0x8000020D];
+ [self addCharacterSet:16 encoding:(NSStringEncoding) 0x8000020E];
+ [self addCharacterSet:17 encoding:(NSStringEncoding) 0x8000020F];
+ [self addCharacterSet:18 encoding:(NSStringEncoding) 0x80000210];
+ [self addCharacterSet:20 encoding:NSShiftJISStringEncoding];
+ [self addCharacterSet:21 encoding:NSWindowsCP1250StringEncoding];
+ [self addCharacterSet:22 encoding:NSWindowsCP1251StringEncoding];
+ [self addCharacterSet:23 encoding:NSWindowsCP1252StringEncoding];
+ [self addCharacterSet:24 encoding:(NSStringEncoding) 0x80000505];
+ [self addCharacterSet:25 encoding:NSUTF16BigEndianStringEncoding];
+ [self addCharacterSet:26 encoding:NSUTF8StringEncoding];
+ [self addCharacterSet:27 encoding:NSASCIIStringEncoding];
+ [self addCharacterSet:28 encoding:(NSStringEncoding) 0x80000A03];
+ [self addCharacterSet:29 encoding:(NSStringEncoding) 0x80000632];
+ [self addCharacterSet:30 encoding:(NSStringEncoding) 0x80000940];
+ [self addCharacterSet:170 encoding:NSASCIIStringEncoding];
+}
+
+- (id)initWithValue:(int)value encoding:(NSStringEncoding)encoding {
+ if (self = [super initWithValue:value]) {
+ _encoding = encoding;
+ }
+
+ return self;
+}
+
++ (void)addCharacterSet:(int)value encoding:(NSStringEncoding)encoding {
+ ZXCharacterSetECI *eci = [[ZXCharacterSetECI alloc] initWithValue:value encoding:encoding];
+ VALUE_TO_ECI[@(value)] = eci;
+ ENCODING_TO_ECI[@(encoding)] = eci;
+}
+
++ (ZXCharacterSetECI *)characterSetECIByValue:(int)value {
+ if (VALUE_TO_ECI == nil) {
+ [self initialize];
+ }
+ if (value < 0 || value >= 900) {
+ return nil;
+ }
+ return VALUE_TO_ECI[@(value)];
+}
+
+
++ (ZXCharacterSetECI *)characterSetECIByEncoding:(NSStringEncoding)encoding {
+ if (ENCODING_TO_ECI == nil) {
+ [self initialize];
+ }
+ return ENCODING_TO_ECI[@(encoding)];
+}
+
+@end
diff --git a/ZXingObjC/common/ZXDecoderResult.h b/ZXingObjC/common/ZXDecoderResult.h
new file mode 100644
index 0000000..774e81e
--- /dev/null
+++ b/ZXingObjC/common/ZXDecoderResult.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates the result of decoding a matrix of bits. This typically
+ * applies to 2D barcode formats. For now it contains the raw bytes obtained,
+ * as well as a String interpretation of those bytes, if applicable.
+ */
+
+@interface ZXDecoderResult : NSObject
+
+@property (nonatomic, assign, readonly) int8_t *rawBytes;
+@property (nonatomic, assign, readonly) int length;
+@property (nonatomic, copy, readonly) NSString *text;
+@property (nonatomic, strong, readonly) NSMutableArray *byteSegments;
+@property (nonatomic, copy, readonly) NSString *ecLevel;
+@property (nonatomic, copy) NSNumber *errorsCorrected;
+@property (nonatomic, copy) NSNumber *erasures;
+@property (nonatomic, strong) id other;
+
+- (id)initWithRawBytes:(int8_t *)rawBytes
+ length:(unsigned int)length
+ text:(NSString *)text
+ byteSegments:(NSMutableArray *)byteSegments
+ ecLevel:(NSString *)ecLevel;
+
+@end
diff --git a/ZXingObjC/common/ZXDecoderResult.m b/ZXingObjC/common/ZXDecoderResult.m
new file mode 100644
index 0000000..65b994f
--- /dev/null
+++ b/ZXingObjC/common/ZXDecoderResult.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 "ZXDecoderResult.h"
+
+@implementation ZXDecoderResult
+
+- (id)initWithRawBytes:(int8_t *)rawBytes
+ length:(unsigned int)length
+ text:(NSString *)text
+ byteSegments:(NSMutableArray *)byteSegments
+ ecLevel:(NSString *)ecLevel {
+ if (self = [super init]) {
+ _rawBytes = rawBytes;
+ _length = length;
+ _text = text;
+ _byteSegments = byteSegments;
+ _ecLevel = ecLevel;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/common/ZXDefaultGridSampler.h b/ZXingObjC/common/ZXDefaultGridSampler.h
new file mode 100644
index 0000000..b7776cc
--- /dev/null
+++ b/ZXingObjC/common/ZXDefaultGridSampler.h
@@ -0,0 +1,23 @@
+/*
+ * 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 "ZXGridSampler.h"
+
+@class ZXBitMatrix, ZXPerspectiveTransform;
+
+@interface ZXDefaultGridSampler : ZXGridSampler
+
+@end
diff --git a/ZXingObjC/common/ZXDefaultGridSampler.m b/ZXingObjC/common/ZXDefaultGridSampler.m
new file mode 100644
index 0000000..23b4bbf
--- /dev/null
+++ b/ZXingObjC/common/ZXDefaultGridSampler.m
@@ -0,0 +1,91 @@
+/*
+ * 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 "ZXDefaultGridSampler.h"
+#import "ZXErrors.h"
+#import "ZXPerspectiveTransform.h"
+
+@implementation ZXDefaultGridSampler
+
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image
+ dimensionX:(int)dimensionX
+ dimensionY:(int)dimensionY
+ p1ToX:(float)p1ToX p1ToY:(float)p1ToY
+ p2ToX:(float)p2ToX p2ToY:(float)p2ToY
+ p3ToX:(float)p3ToX p3ToY:(float)p3ToY
+ p4ToX:(float)p4ToX p4ToY:(float)p4ToY
+ p1FromX:(float)p1FromX p1FromY:(float)p1FromY
+ p2FromX:(float)p2FromX p2FromY:(float)p2FromY
+ p3FromX:(float)p3FromX p3FromY:(float)p3FromY
+ p4FromX:(float)p4FromX p4FromY:(float)p4FromY
+ error:(NSError **)error {
+ ZXPerspectiveTransform *transform =
+ [ZXPerspectiveTransform quadrilateralToQuadrilateral:p1ToX y0:p1ToY
+ x1:p2ToX y1:p2ToY
+ x2:p3ToX y2:p3ToY
+ x3:p4ToX y3:p4ToY
+ x0p:p1FromX y0p:p1FromY
+ x1p:p2FromX y1p:p2FromY
+ x2p:p3FromX y2p:p3FromY
+ x3p:p4FromX y3p:p4FromY];
+ return [self sampleGrid:image dimensionX:dimensionX dimensionY:dimensionY transform:transform error:error];
+}
+
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image
+ dimensionX:(int)dimensionX
+ dimensionY:(int)dimensionY
+ transform:(ZXPerspectiveTransform *)transform
+ error:(NSError **)error {
+ if (dimensionX <= 0 || dimensionY <= 0) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithWidth:dimensionX height:dimensionY];
+ int pointsLen = dimensionX << 1;
+ float pointsf[pointsLen];
+ memset(pointsf, 0, pointsLen * sizeof(float));
+
+ for (int y = 0; y < dimensionY; y++) {
+ int max = dimensionX << 1;
+ float iValue = (float)y + 0.5f;
+ for (int x = 0; x < max; x += 2) {
+ pointsf[x] = (float) (x >> 1) + 0.5f;
+ pointsf[x + 1] = iValue;
+ }
+ [transform transformPoints:pointsf pointsLen:pointsLen];
+
+ if (![ZXGridSampler checkAndNudgePoints:image points:pointsf pointsLen:pointsLen error:error]) {
+ return nil;
+ }
+ for (int x = 0; x < max; x += 2) {
+ int xx = (int)pointsf[x];
+ int yy = (int)pointsf[x + 1];
+ if (xx < 0 || yy < 0 || xx >= image.width || yy >= image.height) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ if ([image getX:xx y:yy]) {
+ [bits setX:x >> 1 y:y];
+ }
+ }
+ }
+
+ return bits;
+}
+
+@end
diff --git a/ZXingObjC/common/ZXDetectorResult.h b/ZXingObjC/common/ZXDetectorResult.h
new file mode 100644
index 0000000..6ba3633
--- /dev/null
+++ b/ZXingObjC/common/ZXDetectorResult.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates the result of detecting a barcode in an image. This includes the raw
+ * matrix of black/white pixels corresponding to the barcode, and possibly points of interest
+ * in the image, like the location of finder patterns or corners of the barcode in the image.
+ */
+
+@class ZXBitMatrix;
+
+@interface ZXDetectorResult : NSObject
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *bits;
+@property (nonatomic, strong, readonly) NSArray *points;
+
+- (id)initWithBits:(ZXBitMatrix *)bits points:(NSArray *)points;
+
+@end
diff --git a/ZXingObjC/common/ZXDetectorResult.m b/ZXingObjC/common/ZXDetectorResult.m
new file mode 100644
index 0000000..edd9d25
--- /dev/null
+++ b/ZXingObjC/common/ZXDetectorResult.m
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXDetectorResult.h"
+
+@implementation ZXDetectorResult
+
+- (id)initWithBits:(ZXBitMatrix *)bits points:(NSArray *)points {
+ if (self = [super init]) {
+ _bits = bits;
+ _points = points;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/common/ZXECI.h b/ZXingObjC/common/ZXECI.h
new file mode 100644
index 0000000..2dd563b
--- /dev/null
+++ b/ZXingObjC/common/ZXECI.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * Superclass of classes encapsulating types ECIs, according to "Extended Channel Interpretations"
+ * 5.3 of ISO 18004.
+ */
+
+@interface ZXECI : NSObject
+
+@property (nonatomic, readonly) int value;
+
+- (id)initWithValue:(int)value;
++ (ZXECI *)eciByValue:(int)value;
+
+@end
diff --git a/ZXingObjC/common/ZXECI.m b/ZXingObjC/common/ZXECI.m
new file mode 100644
index 0000000..a44c618
--- /dev/null
+++ b/ZXingObjC/common/ZXECI.m
@@ -0,0 +1,42 @@
+/*
+ * 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 "ZXCharacterSetECI.h"
+#import "ZXECI.h"
+
+@implementation ZXECI
+
+- (id)initWithValue:(int)value {
+ if (self = [super init]) {
+ _value = value;
+ }
+
+ return self;
+}
+
++ (ZXECI *)eciByValue:(int)value {
+ if (value < 0 || value > 999999) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Bad ECI value: %d", value]
+ userInfo:nil];
+ }
+ if (value < 900) {
+ return [ZXCharacterSetECI characterSetECIByValue:value];
+ }
+ return nil;
+}
+
+@end
diff --git a/ZXingObjC/common/ZXGlobalHistogramBinarizer.h b/ZXingObjC/common/ZXGlobalHistogramBinarizer.h
new file mode 100644
index 0000000..d7b54ed
--- /dev/null
+++ b/ZXingObjC/common/ZXGlobalHistogramBinarizer.h
@@ -0,0 +1,35 @@
+/*
+ * 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 "ZXBinarizer.h"
+
+/**
+ * This Binarizer implementation uses the old ZXing global histogram approach. It is suitable
+ * for low-end mobile devices which don't have enough CPU or memory to use a local thresholding
+ * algorithm. However, because it picks a global black point, it cannot handle difficult shadows
+ * and gradients.
+ *
+ * Faster mobile devices and all desktop applications should probably use ZXHybridBinarizer instead.
+ */
+
+@class ZXBitArray, ZXBitMatrix, ZXLuminanceSource;
+
+@interface ZXGlobalHistogramBinarizer : ZXBinarizer
+
+- (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error;
+- (ZXBinarizer *)createBinarizer:(ZXLuminanceSource *)source;
+
+@end
diff --git a/ZXingObjC/common/ZXGlobalHistogramBinarizer.m b/ZXingObjC/common/ZXGlobalHistogramBinarizer.m
new file mode 100644
index 0000000..f16e377
--- /dev/null
+++ b/ZXingObjC/common/ZXGlobalHistogramBinarizer.m
@@ -0,0 +1,212 @@
+/*
+ * 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 "ZXGlobalHistogramBinarizer.h"
+#import "ZXBitArray.h"
+#import "ZXBitMatrix.h"
+#import "ZXErrors.h"
+#import "ZXLuminanceSource.h"
+
+int const LUMINANCE_BITS = 5;
+int const LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
+int const LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
+
+@interface ZXGlobalHistogramBinarizer ()
+
+@property (nonatomic, assign) int8_t *luminances;
+@property (nonatomic, assign) int luminancesCount;
+@property (nonatomic, assign) int *buckets;
+
+@end
+
+@implementation ZXGlobalHistogramBinarizer
+
+- (id)initWithSource:(ZXLuminanceSource *)source {
+ if (self = [super initWithSource:source]) {
+ _luminances = NULL;
+ _luminancesCount = 0;
+ _buckets = (int *)malloc(LUMINANCE_BUCKETS * sizeof(int));
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_luminances != NULL) {
+ free(_luminances);
+ _luminances = NULL;
+ }
+
+ if (_buckets != NULL) {
+ free(_buckets);
+ _buckets = NULL;
+ }
+}
+
+- (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error {
+ ZXLuminanceSource *source = self.luminanceSource;
+ int width = source.width;
+ if (row == nil || row.size < width) {
+ row = [[ZXBitArray alloc] initWithSize:width];
+ } else {
+ [row clear];
+ }
+
+ [self initArrays:width];
+ int8_t *localLuminances = [source row:y];
+ int *localBuckets = (int *)malloc(LUMINANCE_BUCKETS * sizeof(int));
+ memset(localBuckets, 0, LUMINANCE_BUCKETS * sizeof(int));
+ for (int x = 0; x < width; x++) {
+ int pixel = localLuminances[x] & 0xff;
+ localBuckets[pixel >> LUMINANCE_SHIFT]++;
+ }
+ int blackPoint = [self estimateBlackPoint:localBuckets];
+ free(localBuckets);
+ localBuckets = NULL;
+ if (blackPoint == -1) {
+ free(localLuminances);
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ int left = localLuminances[0] & 0xff;
+ int center = localLuminances[1] & 0xff;
+ for (int x = 1; x < width - 1; x++) {
+ int right = localLuminances[x + 1] & 0xff;
+ int luminance = ((center << 2) - left - right) >> 1;
+ if (luminance < blackPoint) {
+ [row set:x];
+ }
+ left = center;
+ center = right;
+ }
+
+ free(localLuminances);
+ return row;
+}
+
+- (ZXBitMatrix *)blackMatrixWithError:(NSError **)error {
+ ZXLuminanceSource *source = self.luminanceSource;
+ int width = source.width;
+ int height = source.height;
+ ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithWidth:width height:height];
+
+ [self initArrays:width];
+
+ int *localBuckets = (int *)malloc(LUMINANCE_BUCKETS * sizeof(int));
+ memset(localBuckets, 0, LUMINANCE_BUCKETS * sizeof(int));
+ for (int y = 1; y < 5; y++) {
+ int row = height * y / 5;
+ int8_t *localLuminances = [source row:row];
+ int right = (width << 2) / 5;
+ for (int x = width / 5; x < right; x++) {
+ int pixel = localLuminances[x] & 0xff;
+ localBuckets[pixel >> LUMINANCE_SHIFT]++;
+ }
+ }
+ int blackPoint = [self estimateBlackPoint:localBuckets];
+ free(localBuckets);
+ localBuckets = NULL;
+
+ if (blackPoint == -1) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ int8_t *localLuminances = source.matrix;
+ for (int y = 0; y < height; y++) {
+ int offset = y * width;
+ for (int x = 0; x < width; x++) {
+ int pixel = localLuminances[offset + x] & 0xff;
+ if (pixel < blackPoint) {
+ [matrix setX:x y:y];
+ }
+ }
+ }
+
+ return matrix;
+}
+
+- (ZXBinarizer *)createBinarizer:(ZXLuminanceSource *)source {
+ return [[ZXGlobalHistogramBinarizer alloc] initWithSource:source];
+}
+
+- (void)initArrays:(int)luminanceSize {
+ if (self.luminances == NULL || self.luminancesCount < luminanceSize) {
+ if (self.luminances != NULL) {
+ free(self.luminances);
+ }
+ self.luminances = (int8_t *)malloc(luminanceSize * sizeof(int8_t));
+ self.luminancesCount = luminanceSize;
+ }
+
+ for (int x = 0; x < LUMINANCE_BUCKETS; x++) {
+ self.buckets[x] = 0;
+ }
+}
+
+- (int)estimateBlackPoint:(int *)otherBuckets {
+ int numBuckets = LUMINANCE_BUCKETS;
+ int maxBucketCount = 0;
+ int firstPeak = 0;
+ int firstPeakSize = 0;
+
+ for (int x = 0; x < numBuckets; x++) {
+ if (otherBuckets[x] > firstPeakSize) {
+ firstPeak = x;
+ firstPeakSize = otherBuckets[x];
+ }
+ if (otherBuckets[x] > maxBucketCount) {
+ maxBucketCount = otherBuckets[x];
+ }
+ }
+
+ int secondPeak = 0;
+ int secondPeakScore = 0;
+ for (int x = 0; x < numBuckets; x++) {
+ int distanceToBiggest = x - firstPeak;
+ int score = otherBuckets[x] * distanceToBiggest * distanceToBiggest;
+ if (score > secondPeakScore) {
+ secondPeak = x;
+ secondPeakScore = score;
+ }
+ }
+
+ if (firstPeak > secondPeak) {
+ int temp = firstPeak;
+ firstPeak = secondPeak;
+ secondPeak = temp;
+ }
+
+ if (secondPeak - firstPeak <= numBuckets >> 4) {
+ return -1;
+ }
+
+ int bestValley = secondPeak - 1;
+ int bestValleyScore = -1;
+ for (int x = secondPeak - 1; x > firstPeak; x--) {
+ int fromFirst = x - firstPeak;
+ int score = fromFirst * fromFirst * (secondPeak - x) * (maxBucketCount - otherBuckets[x]);
+ if (score > bestValleyScore) {
+ bestValley = x;
+ bestValleyScore = score;
+ }
+ }
+
+ return bestValley << LUMINANCE_SHIFT;
+}
+
+@end
diff --git a/ZXingObjC/common/ZXGridSampler.h b/ZXingObjC/common/ZXGridSampler.h
new file mode 100644
index 0000000..3d331a1
--- /dev/null
+++ b/ZXingObjC/common/ZXGridSampler.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementations of this class can, given locations of finder patterns for a QR code in an
+ * image, sample the right points in the image to reconstruct the QR code, accounting for
+ * perspective distortion. It is abstracted since it is relatively expensive and should be allowed
+ * to take advantage of platform-specific optimized implementations, like Sun's Java Advanced
+ * 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)}
+ * with an instance of a class which implements this interface.
+ */
+
+@class ZXBitMatrix, ZXPerspectiveTransform;
+
+@interface ZXGridSampler : NSObject
+
++ (ZXGridSampler *)instance;
++ (void)setGridSampler:(ZXGridSampler *)newGridSampler;
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image
+ dimensionX:(int)dimensionX
+ dimensionY:(int)dimensionY
+ p1ToX:(float)p1ToX p1ToY:(float)p1ToY
+ p2ToX:(float)p2ToX p2ToY:(float)p2ToY
+ p3ToX:(float)p3ToX p3ToY:(float)p3ToY
+ p4ToX:(float)p4ToX p4ToY:(float)p4ToY
+ p1FromX:(float)p1FromX p1FromY:(float)p1FromY
+ p2FromX:(float)p2FromX p2FromY:(float)p2FromY
+ p3FromX:(float)p3FromX p3FromY:(float)p3FromY
+ p4FromX:(float)p4FromX p4FromY:(float)p4FromY
+ error:(NSError **)error;
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image
+ dimensionX:(int)dimensionX
+ dimensionY:(int)dimensionY
+ transform:(ZXPerspectiveTransform *)transform
+ error:(NSError **)error;
++ (BOOL)checkAndNudgePoints:(ZXBitMatrix *)image points:(float *)points pointsLen:(int)pointsLen error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/common/ZXGridSampler.m b/ZXingObjC/common/ZXGridSampler.m
new file mode 100644
index 0000000..455dbba
--- /dev/null
+++ b/ZXingObjC/common/ZXGridSampler.m
@@ -0,0 +1,144 @@
+/*
+ * 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 "ZXDefaultGridSampler.h"
+#import "ZXErrors.h"
+#import "ZXGridSampler.h"
+#import "ZXPerspectiveTransform.h"
+
+static ZXGridSampler *gridSampler = nil;
+
+@implementation ZXGridSampler
+
+/**
+ * Sets the implementation of GridSampler used by the library. One global
+ * instance is stored, which may sound problematic. But, the implementation provided
+ * ought to be appropriate for the entire platform, and all uses of this library
+ * in the whole lifetime of the JVM. For instance, an Android activity can swap in
+ * an implementation that takes advantage of native platform libraries.
+ */
++ (void)setGridSampler:(ZXGridSampler *)newGridSampler {
+ gridSampler = newGridSampler;
+}
+
++ (ZXGridSampler *)instance {
+ if (!gridSampler) {
+ gridSampler = [[ZXDefaultGridSampler alloc] init];
+ }
+
+ return gridSampler;
+}
+
+/**
+ * Samples an image for a rectangular matrix of bits of the given dimension.
+ */
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image
+ dimensionX:(int)dimensionX
+ dimensionY:(int)dimensionY
+ p1ToX:(float)p1ToX p1ToY:(float)p1ToY
+ p2ToX:(float)p2ToX p2ToY:(float)p2ToY
+ p3ToX:(float)p3ToX p3ToY:(float)p3ToY
+ p4ToX:(float)p4ToX p4ToY:(float)p4ToY
+ p1FromX:(float)p1FromX p1FromY:(float)p1FromY
+ p2FromX:(float)p2FromX p2FromY:(float)p2FromY
+ p3FromX:(float)p3FromX p3FromY:(float)p3FromY
+ p4FromX:(float)p4FromX p4FromY:(float)p4FromY
+ error:(NSError **)error {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image
+ dimensionX:(int)dimensionX
+ dimensionY:(int)dimensionY
+ transform:(ZXPerspectiveTransform *)transform
+ error:(NSError **)error {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+
+/**
+ * Checks a set of points that have been transformed to sample points on an image against
+ * the image's dimensions to see if the point are even within the image.
+ *
+ * This method will actually "nudge" the endpoints back onto the image if they are found to be
+ * barely (less than 1 pixel) off the image. This accounts for imperfect detection of finder
+ * patterns in an image where the QR Code runs all the way to the image border.
+ *
+ * For efficiency, the method will check points from either end of the line until one is found
+ * to be within the image. Because the set of points are assumed to be linear, this is valid.
+ */
++ (BOOL)checkAndNudgePoints:(ZXBitMatrix *)image points:(float *)points pointsLen:(int)pointsLen error:(NSError **)error {
+ int width = image.width;
+ int height = image.height;
+
+ BOOL nudged = YES;
+ for (int offset = 0; offset < pointsLen && nudged; offset += 2) {
+ int x = (int) points[offset];
+ int y = (int) points[offset + 1];
+ if (x < -1 || x > width || y < -1 || y > height) {
+ if (error) *error = NotFoundErrorInstance();
+ return NO;
+ }
+ nudged = NO;
+ if (x == -1) {
+ points[offset] = 0.0f;
+ nudged = YES;
+ } else if (x == width) {
+ points[offset] = width - 1;
+ nudged = YES;
+ }
+ if (y == -1) {
+ points[offset + 1] = 0.0f;
+ nudged = YES;
+ } else if (y == height) {
+ points[offset + 1] = height - 1;
+ nudged = YES;
+ }
+ }
+
+ nudged = YES;
+ for (int offset = pointsLen - 2; offset >= 0 && nudged; offset -= 2) {
+ int x = (int) points[offset];
+ int y = (int) points[offset + 1];
+ if (x < -1 || x > width || y < -1 || y > height) {
+ if (error) *error = NotFoundErrorInstance();
+ return NO;
+ }
+ nudged = NO;
+ if (x == -1) {
+ points[offset] = 0.0f;
+ nudged = YES;
+ } else if (x == width) {
+ points[offset] = width - 1;
+ nudged = YES;
+ }
+ if (y == -1) {
+ points[offset + 1] = 0.0f;
+ nudged = YES;
+ } else if (y == height) {
+ points[offset + 1] = height - 1;
+ nudged = YES;
+ }
+ }
+ return YES;
+}
+
+@end
diff --git a/ZXingObjC/common/ZXHybridBinarizer.h b/ZXingObjC/common/ZXHybridBinarizer.h
new file mode 100644
index 0000000..0d723a3
--- /dev/null
+++ b/ZXingObjC/common/ZXHybridBinarizer.h
@@ -0,0 +1,39 @@
+/*
+ * 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 "ZXGlobalHistogramBinarizer.h"
+
+/**
+ * This class implements a local thresholding algorithm, which while slower than the
+ * ZXGlobalHistogramBinarizer, is fairly efficient for what it does. It is designed for
+ * high frequency images of barcodes with black data on white backgrounds. For this application,
+ * it does a much better job than a global blackpoint with severe shadows and gradients.
+ * However it tends to produce artifacts on lower frequency images and is therefore not
+ * a good general purpose binarizer for uses outside ZXing.
+ *
+ * This class extends ZXGlobalHistogramBinarizer, using the older histogram approach for 1D readers,
+ * and the newer local approach for 2D readers. 1D decoding using a per-row histogram is already
+ * inherently local, and only fails for horizontal gradients. We can revisit that problem later,
+ * but for now it was not a win to use local blocks for 1D.
+ *
+ * This Binarizer is the default for the unit tests and the recommended class for library users.
+ */
+
+@class ZXBinarizer, ZXBitMatrix, ZXLuminanceSource;
+
+@interface ZXHybridBinarizer : ZXGlobalHistogramBinarizer
+
+@end
diff --git a/ZXingObjC/common/ZXHybridBinarizer.m b/ZXingObjC/common/ZXHybridBinarizer.m
new file mode 100644
index 0000000..ee90d5e
--- /dev/null
+++ b/ZXingObjC/common/ZXHybridBinarizer.m
@@ -0,0 +1,223 @@
+/*
+ * 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 "ZXHybridBinarizer.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.
+const int BLOCK_SIZE_POWER = 3;
+const int BLOCK_SIZE = 1 << BLOCK_SIZE_POWER; // ...0100...00
+const int BLOCK_SIZE_MASK = BLOCK_SIZE - 1; // ...0011...11
+const int MINIMUM_DIMENSION = BLOCK_SIZE * 5;
+const int MIN_DYNAMIC_RANGE = 24;
+
+@interface ZXHybridBinarizer ()
+
+@property (nonatomic, strong) ZXBitMatrix *matrix;
+
+@end
+
+@implementation ZXHybridBinarizer
+
+/**
+ * Calculates the final BitMatrix once for all requests. This could be called once from the
+ * constructor instead, but there are some advantages to doing it lazily, such as making
+ * profiling easier, and not doing heavy lifting when callers don't expect it.
+ */
+- (ZXBitMatrix *)blackMatrixWithError:(NSError **)error {
+ if (self.matrix != nil) {
+ return self.matrix;
+ }
+ ZXLuminanceSource *source = [self luminanceSource];
+ int width = source.width;
+ int height = source.height;
+ if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {
+ int8_t *_luminances = source.matrix;
+ int subWidth = width >> BLOCK_SIZE_POWER;
+ if ((width & BLOCK_SIZE_MASK) != 0) {
+ subWidth++;
+ }
+ int subHeight = height >> BLOCK_SIZE_POWER;
+ if ((height & BLOCK_SIZE_MASK) != 0) {
+ subHeight++;
+ }
+ int **blackPoints = [self calculateBlackPoints:_luminances subWidth:subWidth subHeight:subHeight width:width height:height];
+
+ ZXBitMatrix *newMatrix = [[ZXBitMatrix alloc] initWithWidth:width height:height];
+ [self calculateThresholdForBlock:_luminances subWidth:subWidth subHeight:subHeight width:width height:height blackPoints:blackPoints matrix:newMatrix];
+ self.matrix = newMatrix;
+
+ free(_luminances);
+
+ for (int i = 0; i < subHeight; i++) {
+ free(blackPoints[i]);
+ }
+ free(blackPoints);
+ } else {
+ // If the image is too small, fall back to the global histogram approach.
+ self.matrix = [super blackMatrixWithError:error];
+ }
+ return self.matrix;
+}
+
+- (ZXBinarizer *)createBinarizer:(ZXLuminanceSource *)source {
+ return [[ZXHybridBinarizer alloc] initWithSource:source];
+}
+
+/**
+ * For each block in the image, calculate the average black point using a 5x5 grid
+ * of the blocks around it. Also handles the corner cases (fractional blocks are computed based
+ * on the last pixels in the row/column which are also used in the previous block).
+ */
+- (void)calculateThresholdForBlock:(int8_t *)luminances
+ subWidth:(int)subWidth
+ subHeight:(int)subHeight
+ width:(int)width
+ height:(int)height
+ blackPoints:(int **)blackPoints
+ matrix:(ZXBitMatrix *)matrix {
+ for (int y = 0; y < subHeight; y++) {
+ int yoffset = y << BLOCK_SIZE_POWER;
+ int maxYOffset = height - BLOCK_SIZE;
+ if (yoffset > maxYOffset) {
+ yoffset = maxYOffset;
+ }
+ for (int x = 0; x < subWidth; x++) {
+ int xoffset = x << BLOCK_SIZE_POWER;
+ int maxXOffset = width - 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];
+ sum += blackRow[left - 2] + blackRow[left - 1] + blackRow[left] + blackRow[left + 1] + blackRow[left + 2];
+ }
+ int average = sum / 25;
+ [self thresholdBlock:luminances xoffset:xoffset yoffset:yoffset threshold:average stride:width matrix:matrix];
+ }
+ }
+}
+
+- (int)cap:(int)value min:(int)min max:(int)max {
+ return value < min ? min : value > max ? max : value;
+}
+
+/**
+ * Applies a single threshold to a block of pixels.
+ */
+- (void)thresholdBlock:(int8_t *)luminances
+ xoffset:(int)xoffset
+ yoffset:(int)yoffset
+ threshold:(int)threshold
+ stride:(int)stride
+ matrix:(ZXBitMatrix *)matrix {
+ for (int y = 0, offset = yoffset * stride + xoffset; y < BLOCK_SIZE; y++, offset += stride) {
+ for (int x = 0; x < BLOCK_SIZE; x++) {
+ // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0
+ if ((luminances[offset + x] & 0xFF) <= threshold) {
+ [matrix setX:xoffset + x y:yoffset + y];
+ }
+ }
+ }
+}
+
+/**
+ * Calculates a single black point for each block of pixels and saves it away.
+ * See the following thread for a discussion of this algorithm:
+ * http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0
+ */
+- (int **)calculateBlackPoints:(int8_t *)_luminances
+ subWidth:(int)subWidth
+ subHeight:(int)subHeight
+ width:(int)width
+ height:(int)height {
+ int **blackPoints = (int **)malloc(subHeight * sizeof(int *));
+ for (int y = 0; y < subHeight; y++) {
+ blackPoints[y] = (int *)malloc(subWidth * sizeof(int));
+
+ int yoffset = y << BLOCK_SIZE_POWER;
+ int maxYOffset = height - BLOCK_SIZE;
+ if (yoffset > maxYOffset) {
+ yoffset = maxYOffset;
+ }
+ for (int x = 0; x < subWidth; x++) {
+ int xoffset = x << BLOCK_SIZE_POWER;
+ int maxXOffset = width - BLOCK_SIZE;
+ if (xoffset > maxXOffset) {
+ xoffset = maxXOffset;
+ }
+ int sum = 0;
+ int min = 0xFF;
+ int max = 0;
+ for (int yy = 0, offset = yoffset * width + xoffset; yy < BLOCK_SIZE; yy++, offset += width) {
+ for (int xx = 0; xx < BLOCK_SIZE; xx++) {
+ int pixel = _luminances[offset + xx] & 0xFF;
+ sum += pixel;
+ // still looking for good contrast
+ if (pixel < min) {
+ min = pixel;
+ }
+ if (pixel > max) {
+ max = pixel;
+ }
+ }
+ // short-circuit min/max tests once dynamic range is met
+ if (max - min > MIN_DYNAMIC_RANGE) {
+ // finish the rest of the rows quickly
+ for (yy++, offset += width; yy < BLOCK_SIZE; yy++, offset += width) {
+ for (int xx = 0; xx < BLOCK_SIZE; xx++) {
+ sum += _luminances[offset + xx] & 0xFF;
+ }
+ }
+ }
+ }
+
+ // The default estimate is the average of the values in the block.
+ int average = sum >> (BLOCK_SIZE_POWER * 2);
+ if (max - min <= MIN_DYNAMIC_RANGE) {
+ // If variation within the block is low, assume this is a block with only light or only
+ // dark pixels. In that case we do not want to use the average, as it would divide this
+ // low contrast area into black and white pixels, essentially creating data out of noise.
+ //
+ // The default assumption is that the block is light/background. Since no estimate for
+ // the level of dark pixels exists locally, use half the min for the block.
+ average = min >> 1;
+
+ if (y > 0 && x > 0) {
+ // Correct the "white background" assumption for blocks that have neighbors by comparing
+ // the pixels in this block to the previously calculated black points. This is based on
+ // the fact that dark barcode symbology is always surrounded by some amount of light
+ // background for which reasonable black point estimates were made. The bp estimated at
+ // the boundaries is used for the interior.
+
+ // The (min < bp) is arbitrary but works better than other heuristics that were tried.
+ int averageNeighborBlackPoint = (blackPoints[y - 1][x] + (2 * blackPoints[y][x - 1]) +
+ blackPoints[y - 1][x - 1]) >> 2;
+ if (min < averageNeighborBlackPoint) {
+ average = averageNeighborBlackPoint;
+ }
+ }
+ }
+ blackPoints[y][x] = average;
+ }
+ }
+ return blackPoints;
+}
+
+@end
diff --git a/ZXingObjC/common/ZXPerspectiveTransform.h b/ZXingObjC/common/ZXPerspectiveTransform.h
new file mode 100644
index 0000000..c0f12c3
--- /dev/null
+++ b/ZXingObjC/common/ZXPerspectiveTransform.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * 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
+ * directly upon section 3.4.2 of George Wolberg's "Digital Image Warping"; see pages 54-56.
+ */
+
+@interface ZXPerspectiveTransform : NSObject
+
++ (ZXPerspectiveTransform *)quadrilateralToQuadrilateral:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3 x0p:(float)x0p y0p:(float)y0p x1p:(float)x1p y1p:(float)y1p x2p:(float)x2p y2p:(float)y2p x3p:(float)x3p y3p:(float)y3p;
+- (void)transformPoints:(float *)points pointsLen:(int)pointsLen;
+- (void)transformPoints:(float *)xValues yValues:(float *)yValues pointsLen:(int)pointsLen;
++ (ZXPerspectiveTransform *)squareToQuadrilateral:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3;
++ (ZXPerspectiveTransform *)quadrilateralToSquare:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3;
+- (ZXPerspectiveTransform *)buildAdjoint;
+- (ZXPerspectiveTransform *)times:(ZXPerspectiveTransform *)other;
+
+@end
diff --git a/ZXingObjC/common/ZXPerspectiveTransform.m b/ZXingObjC/common/ZXPerspectiveTransform.m
new file mode 100644
index 0000000..86ed899
--- /dev/null
+++ b/ZXingObjC/common/ZXPerspectiveTransform.m
@@ -0,0 +1,128 @@
+/*
+ * 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 "ZXPerspectiveTransform.h"
+
+@interface ZXPerspectiveTransform ()
+
+@property (nonatomic, assign) float a11;
+@property (nonatomic, assign) float a12;
+@property (nonatomic, assign) float a13;
+@property (nonatomic, assign) float a21;
+@property (nonatomic, assign) float a22;
+@property (nonatomic, assign) float a23;
+@property (nonatomic, assign) float a31;
+@property (nonatomic, assign) float a32;
+@property (nonatomic, assign) float a33;
+
+@end
+
+@implementation ZXPerspectiveTransform
+
+- (id)initWithA11:(float)a11 a21:(float)a21 a31:(float)a31 a12:(float)a12 a22:(float)a22 a32:(float)a32 a13:(float)a13 a23:(float)a23 a33:(float)a33 {
+ if (self = [super init]) {
+ _a11 = a11;
+ _a12 = a12;
+ _a13 = a13;
+ _a21 = a21;
+ _a22 = a22;
+ _a23 = a23;
+ _a31 = a31;
+ _a32 = a32;
+ _a33 = a33;
+ }
+
+ return self;
+}
+
++ (ZXPerspectiveTransform *)quadrilateralToQuadrilateral:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3 x0p:(float)x0p y0p:(float)y0p x1p:(float)x1p y1p:(float)y1p x2p:(float)x2p y2p:(float)y2p x3p:(float)x3p y3p:(float)y3p {
+ ZXPerspectiveTransform *qToS = [self quadrilateralToSquare:x0 y0:y0 x1:x1 y1:y1 x2:x2 y2:y2 x3:x3 y3:y3];
+ ZXPerspectiveTransform *sToQ = [self squareToQuadrilateral:x0p y0:y0p x1:x1p y1:y1p x2:x2p y2:y2p x3:x3p y3:y3p];
+ return [sToQ times:qToS];
+}
+
+- (void)transformPoints:(float *)points pointsLen:(int)pointsLen {
+ int max = pointsLen;
+ for (int i = 0; i < max; i += 2) {
+ float x = points[i];
+ float y = points[i + 1];
+ float denominator = self.a13 * x + self.a23 * y + self.a33;
+ points[i] = (self.a11 * x + self.a21 * y + self.a31) / denominator;
+ points[i + 1] = (self.a12 * x + self.a22 * y + self.a32) / denominator;
+ }
+}
+
+/**
+ * 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 ++) {
+ float x = xValues[i];
+ float y = yValues[i];
+ float denominator = self.a13 * x + self.a23 * y + self.a33;
+ xValues[i] = (self.a11 * x + self.a21 * y + self.a31) / denominator;
+ yValues[i] = (self.a12 * x + self.a22 * y + self.a32) / denominator;
+ }
+}
+
++ (ZXPerspectiveTransform *)squareToQuadrilateral:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3 {
+ float dx3 = x0 - x1 + x2 - x3;
+ float dy3 = y0 - y1 + y2 - y3;
+ if (dx3 == 0.0f && dy3 == 0.0f) {
+ // Affine
+ return [[ZXPerspectiveTransform alloc] initWithA11:x1 - x0 a21:x2 - x1 a31:x0 a12:y1 - y0 a22:y2 - y1 a32:y0 a13:0.0f a23:0.0f a33:1.0f];
+ } else {
+ float dx1 = x1 - x2;
+ float dx2 = x3 - x2;
+ float dy1 = y1 - y2;
+ float dy2 = y3 - y2;
+ float denominator = dx1 * dy2 - dx2 * dy1;
+ float a13 = (dx3 * dy2 - dx2 * dy3) / denominator;
+ float a23 = (dx1 * dy3 - dx3 * dy1) / denominator;
+ return [[ZXPerspectiveTransform alloc] initWithA11:x1 - x0 + a13 * x1 a21:x3 - x0 + a23 * x3 a31:x0 a12:y1 - y0 + a13 * y1 a22:y3 - y0 + a23 * y3 a32:y0 a13:a13 a23:a23 a33:1.0f];
+ }
+}
+
++ (ZXPerspectiveTransform *)quadrilateralToSquare:(float)x0 y0:(float)y0 x1:(float)x1 y1:(float)y1 x2:(float)x2 y2:(float)y2 x3:(float)x3 y3:(float)y3 {
+ return [[self squareToQuadrilateral:x0 y0:y0 x1:x1 y1:y1 x2:x2 y2:y2 x3:x3 y3:y3] buildAdjoint];
+}
+
+- (ZXPerspectiveTransform *)buildAdjoint {
+ return [[ZXPerspectiveTransform alloc] initWithA11:self.a22 * self.a33 - self.a23 * self.a32
+ a21:self.a23 * self.a31 - self.a21 * self.a33
+ a31:self.a21 * self.a32 - self.a22 * self.a31
+ a12:self.a13 * self.a32 - self.a12 * self.a33
+ a22:self.a11 * self.a33 - self.a13 * self.a31
+ a32:self.a12 * self.a31 - self.a11 * self.a32
+ a13:self.a12 * self.a23 - self.a13 * self.a22
+ a23:self.a13 * self.a21 - self.a11 * self.a23
+ a33:self.a11 * self.a22 - self.a12 * self.a21];
+}
+
+- (ZXPerspectiveTransform *)times:(ZXPerspectiveTransform *)other {
+ return [[ZXPerspectiveTransform alloc] initWithA11:self.a11 * other.a11 + self.a21 * other.a12 + self.a31 * other.a13
+ a21:self.a11 * other.a21 + self.a21 * other.a22 + self.a31 * other.a23
+ a31:self.a11 * other.a31 + self.a21 * other.a32 + self.a31 * other.a33
+ a12:self.a12 * other.a11 + self.a22 * other.a12 + self.a32 * other.a13
+ a22:self.a12 * other.a21 + self.a22 * other.a22 + self.a32 * other.a23
+ a32:self.a12 * other.a31 + self.a22 * other.a32 + self.a32 * other.a33
+ a13:self.a13 * other.a11 + self.a23 * other.a12 + self.a33 * other.a13
+ a23:self.a13 * other.a21 + self.a23 * other.a22 + self.a33 * other.a23
+ a33:self.a13 * other.a31 + self.a23 * other.a32 + self.a33 * other.a33];
+}
+
+@end
diff --git a/ZXingObjC/common/ZXStringUtils.h b/ZXingObjC/common/ZXStringUtils.h
new file mode 100644
index 0000000..afb0e81
--- /dev/null
+++ b/ZXingObjC/common/ZXStringUtils.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/**
+ * Common string-related functions.
+ */
+
+@class ZXDecodeHints;
+
+@interface ZXStringUtils : NSObject
+
++ (NSStringEncoding)guessEncoding:(int8_t *)bytes length:(unsigned int)length hints:(ZXDecodeHints *)hints;
+
+@end
diff --git a/ZXingObjC/common/ZXStringUtils.m b/ZXingObjC/common/ZXStringUtils.m
new file mode 100644
index 0000000..79e1553
--- /dev/null
+++ b/ZXingObjC/common/ZXStringUtils.m
@@ -0,0 +1,185 @@
+/*
+ * 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 "ZXDecodeHints.h"
+#import "ZXStringUtils.h"
+
+@implementation ZXStringUtils
+
++ (NSStringEncoding)guessEncoding:(int8_t *)bytes length:(unsigned int)length hints:(ZXDecodeHints *)hints {
+ BOOL assumeShiftJIS = CFStringGetSystemEncoding() == NSShiftJISStringEncoding || CFStringGetSystemEncoding() == NSJapaneseEUCStringEncoding;
+
+ if (hints != nil) {
+ NSStringEncoding encoding = hints.encoding;
+ if (encoding > 0) {
+ return encoding;
+ }
+ }
+ // For now, merely tries to distinguish ISO-8859-1, UTF-8 and Shift_JIS,
+ // which should be by far the most common encodings.
+ BOOL canBeISO88591 = YES;
+ BOOL canBeShiftJIS = YES;
+ BOOL canBeUTF8 = YES;
+ int utf8BytesLeft = 0;
+ //int utf8LowChars = 0;
+ int utf2BytesChars = 0;
+ int utf3BytesChars = 0;
+ int utf4BytesChars = 0;
+ int sjisBytesLeft = 0;
+ //int sjisLowChars = 0;
+ int sjisKatakanaChars = 0;
+ //int sjisDoubleBytesChars = 0;
+ int sjisCurKatakanaWordLength = 0;
+ int sjisCurDoubleBytesWordLength = 0;
+ int sjisMaxKatakanaWordLength = 0;
+ int sjisMaxDoubleBytesWordLength = 0;
+ //int isoLowChars = 0;
+ //int isoHighChars = 0;
+ int isoHighOther = 0;
+
+ BOOL utf8bom = length > 3 &&
+ bytes[0] == (int8_t) 0xEF &&
+ bytes[1] == (int8_t) 0xBB &&
+ bytes[2] == (int8_t) 0xBF;
+
+ for (int i = 0;
+ i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8);
+ i++) {
+
+ int value = bytes[i] & 0xFF;
+
+ // UTF-8 stuff
+ if (canBeUTF8) {
+ if (utf8BytesLeft > 0) {
+ if ((value & 0x80) == 0) {
+ canBeUTF8 = NO;
+ } else {
+ utf8BytesLeft--;
+ }
+ } else if ((value & 0x80) != 0) {
+ if ((value & 0x40) == 0) {
+ canBeUTF8 = NO;
+ } else {
+ utf8BytesLeft++;
+ if ((value & 0x20) == 0) {
+ utf2BytesChars++;
+ } else {
+ utf8BytesLeft++;
+ if ((value & 0x10) == 0) {
+ utf3BytesChars++;
+ } else {
+ utf8BytesLeft++;
+ if ((value & 0x08) == 0) {
+ utf4BytesChars++;
+ } else {
+ canBeUTF8 = NO;
+ }
+ }
+ }
+ }
+ } //else {
+ //utf8LowChars++;
+ //}
+ }
+
+ // ISO-8859-1 stuff
+ if (canBeISO88591) {
+ if (value > 0x7F && value < 0xA0) {
+ canBeISO88591 = NO;
+ } else if (value > 0x9F) {
+ if (value < 0xC0 || value == 0xD7 || value == 0xF7) {
+ isoHighOther++;
+ } //else {
+ //isoHighChars++;
+ //}
+ } //else {
+ //isoLowChars++;
+ //}
+ }
+
+ // Shift_JIS stuff
+ if (canBeShiftJIS) {
+ if (sjisBytesLeft > 0) {
+ if (value < 0x40 || value == 0x7F || value > 0xFC) {
+ canBeShiftJIS = NO;
+ } else {
+ sjisBytesLeft--;
+ }
+ } else if (value == 0x80 || value == 0xA0 || value > 0xEF) {
+ canBeShiftJIS = NO;
+ } else if (value > 0xA0 && value < 0xE0) {
+ sjisKatakanaChars++;
+ sjisCurDoubleBytesWordLength = 0;
+ sjisCurKatakanaWordLength++;
+ if (sjisCurKatakanaWordLength > sjisMaxKatakanaWordLength) {
+ sjisMaxKatakanaWordLength = sjisCurKatakanaWordLength;
+ }
+ } else if (value > 0x7F) {
+ sjisBytesLeft++;
+ //sjisDoubleBytesChars++;
+ sjisCurKatakanaWordLength = 0;
+ sjisCurDoubleBytesWordLength++;
+ if (sjisCurDoubleBytesWordLength > sjisMaxDoubleBytesWordLength) {
+ sjisMaxDoubleBytesWordLength = sjisCurDoubleBytesWordLength;
+ }
+ } else {
+ //sjisLowChars++;
+ sjisCurKatakanaWordLength = 0;
+ sjisCurDoubleBytesWordLength = 0;
+ }
+ }
+ }
+
+ if (canBeUTF8 && utf8BytesLeft > 0) {
+ canBeUTF8 = NO;
+ }
+ if (canBeShiftJIS && sjisBytesLeft > 0) {
+ canBeShiftJIS = NO;
+ }
+
+ // Easy -- if there is BOM or at least 1 valid not-single byte character (and no evidence it can't be UTF-8), done
+ if (canBeUTF8 && (utf8bom || utf2BytesChars + utf3BytesChars + utf4BytesChars > 0)) {
+ return NSUTF8StringEncoding;
+ }
+ // Easy -- if assuming Shift_JIS or at least 3 valid consecutive not-ascii characters (and no evidence it can't be), done
+ if (canBeShiftJIS && (assumeShiftJIS || sjisMaxKatakanaWordLength >= 3 || sjisMaxDoubleBytesWordLength >= 3)) {
+ return NSShiftJISStringEncoding;
+ }
+ // Distinguishing Shift_JIS and ISO-8859-1 can be a little tough for short words. The crude heuristic is:
+ // - If we saw
+ // - only two consecutive katakana chars in the whole text, or
+ // - at least 10% of bytes that could be "upper" not-alphanumeric Latin1,
+ // - then we conclude Shift_JIS, else ISO-8859-1
+ if (canBeISO88591 && canBeShiftJIS) {
+ return (sjisMaxKatakanaWordLength == 2 && sjisKatakanaChars == 2) || isoHighOther * 10 >= length
+ ? NSShiftJISStringEncoding : NSISOLatin1StringEncoding;
+ }
+
+ // Otherwise, try in order ISO-8859-1, Shift JIS, UTF-8 and fall back to default platform encoding
+ if (canBeISO88591) {
+ return NSISOLatin1StringEncoding;
+ }
+ if (canBeShiftJIS) {
+ return NSShiftJISStringEncoding;
+ }
+ if (canBeUTF8) {
+ return NSUTF8StringEncoding;
+ }
+ // Otherwise, we take a wild guess with platform encoding
+ return CFStringGetSystemEncoding();
+}
+
+@end
diff --git a/ZXingObjC/common/detector/ZXMathUtils.h b/ZXingObjC/common/detector/ZXMathUtils.h
new file mode 100644
index 0000000..cd38da4
--- /dev/null
+++ b/ZXingObjC/common/detector/ZXMathUtils.h
@@ -0,0 +1,23 @@
+/*
+ * 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 ZXMathUtils : NSObject
+
++ (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/ZXMathUtils.m b/ZXingObjC/common/detector/ZXMathUtils.m
new file mode 100644
index 0000000..6cadbc7
--- /dev/null
+++ b/ZXingObjC/common/detector/ZXMathUtils.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 "ZXMathUtils.h"
+
+@implementation ZXMathUtils
+
++ (int)round:(float)d {
+ return (int)(d + 0.5f);
+}
+
++ (float)distance:(float)aX aY:(float)aY bX:(float)bX bY:(float)bY {
+ float xDiff = aX - bX;
+ float yDiff = aY - bY;
+ return sqrtf(xDiff * xDiff + yDiff * yDiff);
+}
+
++ (float)distanceInt:(int)aX aY:(int)aY bX:(int)bX bY:(int)bY {
+ int xDiff = aX - bX;
+ int yDiff = aY - bY;
+ return sqrtf(xDiff * xDiff + yDiff * yDiff);
+}
+
+@end
diff --git a/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.h b/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.h
new file mode 100644
index 0000000..700218a
--- /dev/null
+++ b/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * A somewhat generic detector that looks for a barcode-like rectangular region within an image.
+ * It looks within a mostly white region of an image for a region of black and white, but mostly
+ * black. It returns the four corners of the region, as best it can determine.
+ */
+
+@class ZXBitMatrix;
+
+@interface ZXMonochromeRectangleDetector : NSObject
+
+- (id)initWithImage:(ZXBitMatrix *)image;
+- (NSArray *)detectWithError:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m b/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m
new file mode 100644
index 0000000..98dd305
--- /dev/null
+++ b/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m
@@ -0,0 +1,218 @@
+/*
+ * 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 "ZXErrors.h"
+#import "ZXMonochromeRectangleDetector.h"
+#import "ZXResultPoint.h"
+
+int const MONOCHROME_MAX_MODULES = 32;
+
+@interface ZXMonochromeRectangleDetector ()
+
+@property (nonatomic, strong) ZXBitMatrix *image;
+
+@end
+
+@implementation ZXMonochromeRectangleDetector
+
+- (id)initWithImage:(ZXBitMatrix *)image {
+ if (self = [super init]) {
+ _image = image;
+ }
+
+ return self;
+}
+
+/**
+ * Detects a rectangular region of black and white -- mostly black -- with a region of mostly
+ * white, in an image.
+ *
+ * Returns a ResultPoint NSArray 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 leftmost and the
+ * third, the rightmost
+ */
+- (NSArray *)detectWithError:(NSError **)error {
+ int height = [self.image height];
+ int width = [self.image width];
+ int halfHeight = height >> 1;
+ int halfWidth = width >> 1;
+ int deltaY = MAX(1, height / (MONOCHROME_MAX_MODULES << 3) > 1);
+ int deltaX = MAX(1, width / (MONOCHROME_MAX_MODULES << 3) > 1);
+
+ int top = 0;
+ int bottom = height;
+ int left = 0;
+ int right = width;
+ ZXResultPoint *pointA = [self findCornerFromCenter:halfWidth deltaX:0 left:left right:right
+ centerY:halfHeight deltaY:-deltaY top:top bottom:bottom maxWhiteRun:halfWidth >> 1];
+ if (!pointA) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ top = (int)[pointA y] - 1;
+ ZXResultPoint *pointB = [self findCornerFromCenter:halfWidth deltaX:-deltaX left:left right:right
+ centerY:halfHeight deltaY:0 top:top bottom:bottom maxWhiteRun:halfHeight >> 1];
+ if (!pointB) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ left = (int)[pointB x] - 1;
+ ZXResultPoint *pointC = [self findCornerFromCenter:halfWidth deltaX:deltaX left:left right:right
+ centerY:halfHeight deltaY:0 top:top bottom:bottom maxWhiteRun:halfHeight >> 1];
+ if (!pointC) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ right = (int)[pointC x] + 1;
+ ZXResultPoint *pointD = [self findCornerFromCenter:halfWidth deltaX:0 left:left right:right
+ centerY:halfHeight deltaY:deltaY top:top bottom:bottom maxWhiteRun:halfWidth >> 1];
+ if (!pointD) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ bottom = (int)[pointD y] + 1;
+
+ pointA = [self findCornerFromCenter:halfWidth deltaX:0 left:left right:right
+ centerY:halfHeight deltaY:-deltaY top:top bottom:bottom maxWhiteRun:halfWidth >> 2];
+ if (!pointA) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ return @[pointA, pointB, pointC, pointD];
+}
+
+
+/**
+ * Attempts to locate a corner of the barcode by scanning up, down, left or right from a center
+ * point which should be within the barcode.
+ *
+ * Params:
+ * centerX center's x component (horizontal)
+ * deltaX same as deltaY but change in x per step instead
+ * left minimum value of x
+ * right maximum value of x
+ * centerY center's y component (vertical)
+ * deltaY change in y per step. If scanning up this is negative; down, positive;
+ * left or right, 0
+ * top minimum value of y to search through (meaningless when di == 0)
+ * bottom maximum value of y
+ * maxWhiteRun maximum run of white pixels that can still be considered to be within
+ * the barcode
+ */
+- (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 {
+ NSArray *lastRange = nil;
+ for (int y = centerY, x = centerX; y < bottom && y >= top && x < right && x >= left; y += deltaY, x += deltaX) {
+ NSArray *range;
+ if (deltaX == 0) {
+ range = [self blackWhiteRange:y maxWhiteRun:maxWhiteRun minDim:left maxDim:right horizontal:YES];
+ } else {
+ range = [self blackWhiteRange:x maxWhiteRun:maxWhiteRun minDim:top maxDim:bottom horizontal:NO];
+ }
+ if (range == nil) {
+ if (lastRange == nil) {
+ return nil;
+ }
+ if (deltaX == 0) {
+ int lastY = y - deltaY;
+ if ([lastRange[0] intValue] < centerX) {
+ if ([lastRange[0] intValue] > centerX) {
+ return [[ZXResultPoint alloc] initWithX:deltaY > 0 ? [lastRange[0] intValue] : [lastRange[1] intValue] y:lastY];
+ }
+ return [[ZXResultPoint alloc] initWithX:[lastRange[0] intValue] y:lastY];
+ } else {
+ return [[ZXResultPoint alloc] initWithX:[lastRange[1] intValue] y:lastY];
+ }
+ } else {
+ int lastX = x - deltaX;
+ if ([lastRange[0] intValue] < centerY) {
+ if ([lastRange[1] intValue] > centerY) {
+ return [[ZXResultPoint alloc] initWithX:lastX y:deltaX < 0 ? [lastRange[0] intValue] : [lastRange[1] intValue]];
+ }
+ return [[ZXResultPoint alloc] initWithX:lastX y:[lastRange[0] intValue]];
+ } else {
+ return [[ZXResultPoint alloc] initWithX:lastX y:[lastRange[1] intValue]];
+ }
+ }
+ }
+ lastRange = range;
+ }
+
+ return nil;
+}
+
+
+/**
+ * Computes the start and end of a region of pixels, either horizontally or vertically, that could
+ * be part of a Data Matrix barcode.
+ *
+ * Params:
+ * fixedDimension if scanning horizontally, this is the row (the fixed vertical location)
+ * where we are scanning. If scanning vertically it's the column, the fixed horizontal location
+ * maxWhiteRun largest run of white pixels that can still be considered part of the
+ * barcode region
+ * minDim minimum pixel location, horizontally or vertically, to consider
+ * maxDim maximum pixel location, horizontally or vertically, to consider
+ * horizontal if true, we're scanning left-right, instead of up-down
+ */
+- (NSArray *)blackWhiteRange:(int)fixedDimension maxWhiteRun:(int)maxWhiteRun minDim:(int)minDim maxDim:(int)maxDim horizontal:(BOOL)horizontal {
+ int center = (minDim + maxDim) >> 1;
+
+ int start = center;
+ while (start >= minDim) {
+ if (horizontal ? [self.image getX:start y:fixedDimension] : [self.image getX:fixedDimension y:start]) {
+ start--;
+ } else {
+ int whiteRunStart = start;
+
+ do {
+ start--;
+ } while (start >= minDim && !(horizontal ? [self.image getX:start y:fixedDimension] : [self.image getX:fixedDimension y:start]));
+ int whiteRunSize = whiteRunStart - start;
+ if (start < minDim || whiteRunSize > maxWhiteRun) {
+ start = whiteRunStart;
+ break;
+ }
+ }
+ }
+
+ start++;
+ int end = center;
+
+ while (end < maxDim) {
+ if (horizontal ? [self.image getX:end y:fixedDimension] : [self.image getX:fixedDimension y:end]) {
+ end++;
+ } else {
+ int whiteRunStart = end;
+
+ do {
+ end++;
+ } while (end < maxDim && !(horizontal ? [self.image getX:end y:fixedDimension] : [self.image getX:fixedDimension y:end]));
+ int whiteRunSize = end - whiteRunStart;
+ if (end >= maxDim || whiteRunSize > maxWhiteRun) {
+ end = whiteRunStart;
+ break;
+ }
+ }
+ }
+
+ end--;
+ return end > start ? @[@(start), @(end)] : nil;
+}
+
+@end
diff --git a/ZXingObjC/common/detector/ZXWhiteRectangleDetector.h b/ZXingObjC/common/detector/ZXWhiteRectangleDetector.h
new file mode 100644
index 0000000..08c5adf
--- /dev/null
+++ b/ZXingObjC/common/detector/ZXWhiteRectangleDetector.h
@@ -0,0 +1,33 @@
+/*
+ * 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 "ZXResultPoint.h"
+#import "ZXBitMatrix.h"
+
+/**
+ * Detects a candidate barcode-like rectangular region within an image. It
+ * starts around the center of the image, increases the size of the candidate
+ * region until it finds a white rectangular region. By keeping track of the
+ * last black points it encountered, it determines the corners of the barcode.
+ */
+
+@interface ZXWhiteRectangleDetector : NSObject
+
+- (id)initWithImage:(ZXBitMatrix *)image error:(NSError **)error;
+- (id)initWithImage:(ZXBitMatrix *)image initSize:(int)initSize x:(int)x y:(int)y error:(NSError **)error;
+- (NSArray *)detectWithError:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/common/detector/ZXWhiteRectangleDetector.m b/ZXingObjC/common/detector/ZXWhiteRectangleDetector.m
new file mode 100644
index 0000000..5aad24b
--- /dev/null
+++ b/ZXingObjC/common/detector/ZXWhiteRectangleDetector.m
@@ -0,0 +1,310 @@
+/*
+ * 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 "ZXErrors.h"
+#import "ZXMathUtils.h"
+#import "ZXWhiteRectangleDetector.h"
+
+@interface ZXWhiteRectangleDetector ()
+
+@property (nonatomic, strong) ZXBitMatrix *image;
+@property (nonatomic, assign) int height;
+@property (nonatomic, assign) int width;
+@property (nonatomic, assign) int leftInit;
+@property (nonatomic, assign) int rightInit;
+@property (nonatomic, assign) int downInit;
+@property (nonatomic, assign) int upInit;
+
+@end
+
+int const INIT_SIZE = 30;
+int const CORR = 1;
+
+@implementation ZXWhiteRectangleDetector
+
+- (id)initWithImage:(ZXBitMatrix *)image error:(NSError **)error {
+ if (self = [super init]) {
+ _image = image;
+ _height = image.height;
+ _width = image.width;
+ _leftInit = (_width - INIT_SIZE) >> 1;
+ _rightInit = (_width + INIT_SIZE) >> 1;
+ _upInit = (_height - INIT_SIZE) >> 1;
+ _downInit = (_height + INIT_SIZE) >> 1;
+ if (_upInit < 0 || _leftInit < 0 || _downInit >= _height || _rightInit >= _width) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ }
+
+ return self;
+}
+
+- (id)initWithImage:(ZXBitMatrix *)image initSize:(int)initSize x:(int)x y:(int)y error:(NSError **)error {
+ if (self = [super init]) {
+ _image = image;
+ _height = image.height;
+ _width = image.width;
+ int halfsize = initSize >> 1;
+ _leftInit = x - halfsize;
+ _rightInit = x + halfsize;
+ _upInit = y - halfsize;
+ _downInit = y + halfsize;
+ if (_upInit < 0 || _leftInit < 0 || _downInit >= _height || _rightInit >= _width) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ }
+
+ return self;
+}
+
+/**
+ * Detects a candidate barcode-like rectangular region within an image. It
+ * starts around the center of the image, increases the size of the candidate
+ * region until it finds a white rectangular region.
+ *
+ * Returns a ResultPoint NSArray 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
+ * leftmost and the third, the rightmost
+ */
+- (NSArray *)detectWithError:(NSError **)error {
+ int left = self.leftInit;
+ int right = self.rightInit;
+ int up = self.upInit;
+ int down = self.downInit;
+ BOOL sizeExceeded = NO;
+ BOOL aBlackPointFoundOnBorder = YES;
+ BOOL atLeastOneBlackPointFoundOnBorder = NO;
+
+ while (aBlackPointFoundOnBorder) {
+ aBlackPointFoundOnBorder = NO;
+
+ // .....
+ // . |
+ // .....
+ BOOL rightBorderNotWhite = YES;
+ while (rightBorderNotWhite && right < self.width) {
+ rightBorderNotWhite = [self containsBlackPoint:up b:down fixed:right horizontal:NO];
+ if (rightBorderNotWhite) {
+ right++;
+ aBlackPointFoundOnBorder = YES;
+ }
+ }
+
+ if (right >= self.width) {
+ sizeExceeded = YES;
+ break;
+ }
+
+ // .....
+ // . .
+ // .___.
+ BOOL bottomBorderNotWhite = YES;
+ while (bottomBorderNotWhite && down < self.height) {
+ bottomBorderNotWhite = [self containsBlackPoint:left b:right fixed:down horizontal:YES];
+ if (bottomBorderNotWhite) {
+ down++;
+ aBlackPointFoundOnBorder = YES;
+ }
+ }
+
+ if (down >= self.height) {
+ sizeExceeded = YES;
+ break;
+ }
+
+ // .....
+ // | .
+ // .....
+ BOOL leftBorderNotWhite = YES;
+ while (leftBorderNotWhite && left >= 0) {
+ leftBorderNotWhite = [self containsBlackPoint:up b:down fixed:left horizontal:NO];
+ if (leftBorderNotWhite) {
+ left--;
+ aBlackPointFoundOnBorder = YES;
+ }
+ }
+
+ if (left < 0) {
+ sizeExceeded = YES;
+ break;
+ }
+
+ // .___.
+ // . .
+ // .....
+ BOOL topBorderNotWhite = YES;
+ while (topBorderNotWhite && up >= 0) {
+ topBorderNotWhite = [self containsBlackPoint:left b:right fixed:up horizontal:YES];
+ if (topBorderNotWhite) {
+ up--;
+ aBlackPointFoundOnBorder = YES;
+ }
+ }
+
+ if (up < 0) {
+ sizeExceeded = YES;
+ break;
+ }
+
+ if (aBlackPointFoundOnBorder) {
+ atLeastOneBlackPointFoundOnBorder = YES;
+ }
+ }
+
+ if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
+ int maxSize = right - left;
+
+ ZXResultPoint *z = nil;
+ for (int i = 1; i < maxSize; i++) {
+ z = [self blackPointOnSegment:left aY:down - i bX:left + i bY:down];
+ if (z != nil) {
+ break;
+ }
+ }
+
+ if (z == nil) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ ZXResultPoint *t = nil;
+ for (int i = 1; i < maxSize; i++) {
+ t = [self blackPointOnSegment:left aY:up + i bX:left + i bY:up];
+ if (t != nil) {
+ break;
+ }
+ }
+
+ if (t == nil) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ ZXResultPoint *x = nil;
+ for (int i = 1; i < maxSize; i++) {
+ x = [self blackPointOnSegment:right aY:up + i bX:right - i bY:up];
+ if (x != nil) {
+ break;
+ }
+ }
+
+ if (x == nil) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ ZXResultPoint *y = nil;
+ for (int i = 1; i < maxSize; i++) {
+ y = [self blackPointOnSegment:right aY:down - i bX:right - i bY:down];
+ if (y != nil) {
+ break;
+ }
+ }
+
+ if (y == nil) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ return [self centerEdges:y z:z x:x t:t];
+ } else {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+}
+
+
+- (ZXResultPoint *)blackPointOnSegment:(float)aX aY:(float)aY bX:(float)bX bY:(float)bY {
+ int dist = [ZXMathUtils round:[ZXMathUtils distance:aX aY:aY bX:bX bY:bY]];
+ float xStep = (bX - aX) / dist;
+ float yStep = (bY - aY) / dist;
+
+ for (int i = 0; i < dist; i++) {
+ int x = [ZXMathUtils round:aX + i * xStep];
+ int y = [ZXMathUtils round:aY + i * yStep];
+ if ([self.image getX:x y:y]) {
+ return [[ZXResultPoint alloc] initWithX:x y:y];
+ }
+ }
+
+ return nil;
+}
+
+/**
+ * recenters the points of a constant distance towards the center
+ *
+ * returns a ResultPoint NSArray 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
+ * leftmost and the third, the rightmost
+ */
+- (NSArray *)centerEdges:(ZXResultPoint *)y z:(ZXResultPoint *)z x:(ZXResultPoint *)x t:(ZXResultPoint *)t {
+ //
+ // t t
+ // z x
+ // x OR z
+ // y y
+ //
+
+ float yi = y.x;
+ float yj = y.y;
+ float zi = z.x;
+ float zj = z.y;
+ float xi = x.x;
+ float xj = x.y;
+ float ti = t.x;
+ float tj = t.y;
+
+ if (yi < self.width / 2.0f) {
+ return @[[[ZXResultPoint alloc] initWithX:ti - CORR y:tj + CORR],
+ [[ZXResultPoint alloc] initWithX:zi + CORR y:zj + CORR],
+ [[ZXResultPoint alloc] initWithX:xi - CORR y:xj - CORR],
+ [[ZXResultPoint alloc] initWithX:yi + CORR y:yj - CORR]];
+ } else {
+ return @[[[ZXResultPoint alloc] initWithX:ti + CORR y:tj + CORR],
+ [[ZXResultPoint alloc] initWithX:zi + CORR y:zj - CORR],
+ [[ZXResultPoint alloc] initWithX:xi - CORR y:xj + CORR],
+ [[ZXResultPoint alloc] initWithX:yi - CORR y:yj - CORR]];
+ }
+}
+
+
+/**
+ * Determines whether a segment contains a black point
+ */
+- (BOOL)containsBlackPoint:(int)a b:(int)b fixed:(int)fixed horizontal:(BOOL)horizontal {
+ if (horizontal) {
+ for (int x = a; x <= b; x++) {
+ if ([self.image getX:x y:fixed]) {
+ return YES;
+ }
+ }
+ } else {
+ for (int y = a; y <= b; y++) {
+ if ([self.image getX:fixed y:y]) {
+ return YES;
+ }
+ }
+ }
+
+ return NO;
+}
+
+@end
diff --git a/ZXingObjC/common/reedsolomon/ZXGenericGF.h b/ZXingObjC/common/reedsolomon/ZXGenericGF.h
new file mode 100644
index 0000000..5706f76
--- /dev/null
+++ b/ZXingObjC/common/reedsolomon/ZXGenericGF.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * This class contains utility methods for performing mathematical operations over
+ * the Galois Fields. Operations use a given primitive polynomial in calculations.
+ *
+ * Throughout this package, elements of the GF are represented as an int
+ * for convenience and speed (but at the cost of memory).
+ */
+
+@class ZXGenericGFPoly;
+
+@interface ZXGenericGF : NSObject
+
+@property (nonatomic, strong, readonly) ZXGenericGFPoly *zero;
+@property (nonatomic, strong, readonly) ZXGenericGFPoly *one;
+@property (nonatomic, assign, readonly) int size;
+@property (nonatomic, assign, readonly) int generatorBase;
+
++ (ZXGenericGF *)AztecData12;
++ (ZXGenericGF *)AztecData10;
++ (ZXGenericGF *)AztecData6;
++ (ZXGenericGF *)AztecParam;
++ (ZXGenericGF *)QrCodeField256;
++ (ZXGenericGF *)DataMatrixField256;
++ (ZXGenericGF *)AztecData8;
++ (ZXGenericGF *)MaxiCodeField64;
+
+- (id)initWithPrimitive:(int)primitive size:(int)size b:(int)b;
+- (ZXGenericGFPoly *)buildMonomial:(int)degree coefficient:(int)coefficient;
++ (int)addOrSubtract:(int)a b:(int)b;
+- (int)exp:(int)a;
+- (int)log:(int)a;
+- (int)inverse:(int)a;
+- (int)multiply:(int)a b:(int)b;
+
+@end
diff --git a/ZXingObjC/common/reedsolomon/ZXGenericGF.m b/ZXingObjC/common/reedsolomon/ZXGenericGF.m
new file mode 100644
index 0000000..852e598
--- /dev/null
+++ b/ZXingObjC/common/reedsolomon/ZXGenericGF.m
@@ -0,0 +1,212 @@
+/*
+ * 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 "ZXGenericGF.h"
+#import "ZXGenericGFPoly.h"
+
+@interface ZXGenericGF ()
+
+@property (nonatomic, assign) int *expTable;
+@property (nonatomic, assign) int *logTable;
+@property (nonatomic, assign) int primitive;
+@property (nonatomic, assign) BOOL initialized;
+
+@end
+
+@implementation ZXGenericGF {
+ ZXGenericGFPoly *_one;
+ ZXGenericGFPoly *_zero;
+}
+
+/**
+ * Create a representation of GF(size) using the given primitive polynomial.
+ */
+- (id)initWithPrimitive:(int)primitive size:(int)size b:(int)b {
+ if (self = [super init]) {
+ _primitive = primitive;
+ _size = size;
+ _generatorBase = b;
+ }
+
+ return self;
+}
+
+- (void)initialize {
+ _expTable = (int *)malloc(self.size * sizeof(int));
+ _logTable = (int *)malloc(self.size * sizeof(int));
+ int x = 1;
+ for (int i = 0; i < self.size; i++) {
+ _expTable[i] = x;
+ x <<= 1; // x = x * 2; we're assuming the generator alpha is 2
+ if (x >= self.size) {
+ x ^= self.primitive;
+ x &= self.size - 1;
+ }
+ }
+
+ for (int i = 0; i < self.size-1; i++) {
+ _logTable[_expTable[i]] = i;
+ }
+ // logTable[0] == 0 but this should never be used
+ _zero = [[ZXGenericGFPoly alloc] initWithField:self coefficients:NULL coefficientsLen:0];
+ int oneInt = 1;
+ _one = [[ZXGenericGFPoly alloc] initWithField:self coefficients:&oneInt coefficientsLen:1];
+ self.initialized = YES;
+}
+
+- (void)checkInit {
+ if (!self.initialized) {
+ [self initialize];
+ }
+}
+
+- (ZXGenericGFPoly *)zero {
+ [self checkInit];
+
+ return _zero;
+}
+
+- (ZXGenericGFPoly *)one {
+ [self checkInit];
+
+ return _one;
+}
+
++ (ZXGenericGF *)AztecData12 {
+ static ZXGenericGF *AztecData12 = nil;
+ if (!AztecData12) {
+ AztecData12 = [[ZXGenericGF alloc] initWithPrimitive:0x1069 size:4096 b:1]; // x^12 + x^6 + x^5 + x^3 + 1
+ }
+ return AztecData12;
+}
+
++ (ZXGenericGF *)AztecData10 {
+ static ZXGenericGF *AztecData10 = nil;
+ if (!AztecData10) {
+ AztecData10 = [[ZXGenericGF alloc] initWithPrimitive:0x409 size:1024 b:1]; // x^10 + x^3 + 1
+ }
+ return AztecData10;
+}
+
++ (ZXGenericGF *)AztecData6 {
+ static ZXGenericGF *AztecData6 = nil;
+ if (!AztecData6) {
+ AztecData6 = [[ZXGenericGF alloc] initWithPrimitive:0x43 size:64 b:1]; // x^6 + x + 1
+ }
+ return AztecData6;
+}
+
++ (ZXGenericGF *)AztecParam {
+ static ZXGenericGF *AztecParam = nil;
+ if (!AztecParam) {
+ AztecParam = [[ZXGenericGF alloc] initWithPrimitive:0x13 size:16 b:1]; // x^4 + x + 1
+ }
+ return AztecParam;
+}
+
++ (ZXGenericGF *)QrCodeField256 {
+ static ZXGenericGF *QrCodeField256 = nil;
+ if (!QrCodeField256) {
+ QrCodeField256 = [[ZXGenericGF alloc] initWithPrimitive:0x011D size:256 b:0]; // x^8 + x^4 + x^3 + x^2 + 1
+ }
+ return QrCodeField256;
+}
+
++ (ZXGenericGF *)DataMatrixField256 {
+ static ZXGenericGF *DataMatrixField256 = nil;
+ if (!DataMatrixField256) {
+ DataMatrixField256 = [[ZXGenericGF alloc] initWithPrimitive:0x012D size:256 b:1]; // x^8 + x^5 + x^3 + x^2 + 1
+ }
+ return DataMatrixField256;
+}
+
++ (ZXGenericGF *)AztecData8 {
+ return [self DataMatrixField256];
+}
+
++ (ZXGenericGF *)MaxiCodeField64 {
+ return [self AztecData6];
+}
+
+- (ZXGenericGFPoly *)buildMonomial:(int)degree coefficient:(int)coefficient {
+ [self checkInit];
+
+ if (degree < 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Degree must be greater than 0."];
+ }
+ if (coefficient == 0) {
+ return self.zero;
+ }
+
+ int coefficientsLen = degree + 1;
+ int coefficients[coefficientsLen];
+ coefficients[0] = coefficient;
+ for (int i = 1; i < coefficientsLen; i++) {
+ coefficients[i] = 0;
+ }
+ return [[ZXGenericGFPoly alloc] initWithField:self coefficients:coefficients coefficientsLen:coefficientsLen];
+}
+
+/**
+ * Implements both addition and subtraction -- they are the same in GF(size).
+ */
++ (int)addOrSubtract:(int)a b:(int)b {
+ return a ^ b;
+}
+
+- (int)exp:(int)a {
+ [self checkInit];
+
+ return self.expTable[a];
+}
+
+- (int)log:(int)a {
+ [self checkInit];
+
+ if (a == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Argument must be non-zero."];
+ }
+ return self.logTable[a];
+}
+
+- (int)inverse:(int)a {
+ [self checkInit];
+
+ if (a == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Argument must be non-zero."];
+ }
+ return self.expTable[self.size - self.logTable[a] - 1];
+}
+
+- (int)multiply:(int)a b:(int)b {
+ [self checkInit];
+
+ if (a == 0 || b == 0) {
+ return 0;
+ }
+
+ return self.expTable[(self.logTable[a] + self.logTable[b]) % (self.size - 1)];
+}
+
+- (BOOL)isEqual:(ZXGenericGF *)object {
+ return self.primitive == object.primitive && self.size == object.size;
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"GF(0x%X,%d)", self.primitive, self.size];
+}
+
+@end
diff --git a/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h b/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h
new file mode 100644
index 0000000..faca70b
--- /dev/null
+++ b/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h
@@ -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.
+ */
+
+/**
+ * Represents a polynomial whose coefficients are elements of a GF.
+ * Instances of this class are immutable.
+ *
+ * Much credit is due to William Rucklidge since portions of this code are an indirect
+ * port of his C++ Reed-Solomon implementation.
+ */
+
+@class ZXGenericGF;
+
+@interface ZXGenericGFPoly : NSObject
+
+@property (nonatomic, assign, readonly) int *coefficients;
+@property (nonatomic, assign, readonly) int coefficientsLen;
+
+- (id)initWithField:(ZXGenericGF *)field coefficients:(int *)coefficients coefficientsLen:(int)coefficientsLen;
+- (int)degree;
+- (BOOL)zero;
+- (int)coefficient:(int)degree;
+- (int)evaluateAt:(int)a;
+- (ZXGenericGFPoly *)addOrSubtract:(ZXGenericGFPoly *)other;
+- (ZXGenericGFPoly *)multiply:(ZXGenericGFPoly *)other;
+- (ZXGenericGFPoly *)multiplyScalar:(int)scalar;
+- (ZXGenericGFPoly *)multiplyByMonomial:(int)degree coefficient:(int)coefficient;
+- (NSArray *)divide:(ZXGenericGFPoly *)other;
+
+@end
diff --git a/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m b/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m
new file mode 100644
index 0000000..478dd78
--- /dev/null
+++ b/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m
@@ -0,0 +1,256 @@
+/*
+ * 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 "ZXGenericGF.h"
+#import "ZXGenericGFPoly.h"
+
+@interface ZXGenericGFPoly ()
+
+@property (nonatomic, strong) ZXGenericGF *field;
+
+@end
+
+@implementation ZXGenericGFPoly
+
+- (id)initWithField:(ZXGenericGF *)field coefficients:(int *)coefficients coefficientsLen:(int)coefficientsLen {
+ if (self = [super init]) {
+ _field = field;
+ if (coefficientsLen > 1 && coefficients[0] == 0) {
+ int firstNonZero = 1;
+ while (firstNonZero < coefficientsLen && coefficients[firstNonZero] == 0) {
+ firstNonZero++;
+ }
+ if (firstNonZero == coefficientsLen) {
+ ZXGenericGFPoly *zero = [field zero];
+ _coefficients = (int *)malloc(zero.coefficientsLen * sizeof(int));
+ memcpy(_coefficients, zero.coefficients, zero.coefficientsLen * sizeof(int));
+ _coefficientsLen = zero.coefficientsLen;
+ } else {
+ _coefficientsLen = (coefficientsLen - firstNonZero);
+ _coefficients = (int *)malloc(_coefficientsLen * sizeof(int));
+ for (int i = 0; i < _coefficientsLen; i++) {
+ _coefficients[i] = coefficients[firstNonZero + i];
+ }
+ }
+ } else {
+ _coefficients = (int *)malloc(coefficientsLen * sizeof(int));
+ memcpy(_coefficients, coefficients, coefficientsLen * sizeof(int));
+ _coefficientsLen = coefficientsLen;
+ }
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_coefficients != NULL) {
+ free(_coefficients);
+ _coefficients = NULL;
+ }
+}
+
+- (int)degree {
+ return self.coefficientsLen - 1;
+}
+
+- (BOOL)zero {
+ return self.coefficients[0] == 0;
+}
+
+- (int)coefficient:(int)degree {
+ return self.coefficients[self.coefficientsLen - 1 - degree];
+}
+
+- (int)evaluateAt:(int)a {
+ if (a == 0) {
+ return [self coefficient:0];
+ }
+ int size = self.coefficientsLen;
+ if (a == 1) {
+ int result = 0;
+ for (int i = 0; i < size; i++) {
+ result = [ZXGenericGF addOrSubtract:result b:self.coefficients[i]];
+ }
+ return result;
+ }
+ int result = self.coefficients[0];
+ for (int i = 1; i < size; i++) {
+ result = [ZXGenericGF addOrSubtract:[self.field multiply:a b:result] b:self.coefficients[i]];
+ }
+ return result;
+}
+
+- (ZXGenericGFPoly *)addOrSubtract:(ZXGenericGFPoly *)other {
+ if (![self.field isEqual:other.field]) {
+ [NSException raise:NSInvalidArgumentException format:@"ZXGenericGFPolys do not have same ZXGenericGF field"];
+ }
+ if (self.zero) {
+ return other;
+ }
+ if (other.zero) {
+ return self;
+ }
+
+ int *smallerCoefficients = self.coefficients;
+ int smallerCoefficientsLen = self.coefficientsLen;
+ int *largerCoefficients = other.coefficients;
+ int largerCoefficientsLen = other.coefficientsLen;
+ if (smallerCoefficientsLen > largerCoefficientsLen) {
+ int *temp = smallerCoefficients;
+ int tempLen = smallerCoefficientsLen;
+ smallerCoefficients = largerCoefficients;
+ smallerCoefficientsLen = largerCoefficientsLen;
+ largerCoefficients = temp;
+ largerCoefficientsLen = tempLen;
+ }
+ int sumDiff[largerCoefficientsLen];
+ memset(sumDiff, 0, largerCoefficientsLen * sizeof(int));
+ int lengthDiff = largerCoefficientsLen - smallerCoefficientsLen;
+ for (int i = 0; i < lengthDiff; i++) {
+ sumDiff[i] = largerCoefficients[i];
+ }
+ for (int i = lengthDiff; i < largerCoefficientsLen; i++) {
+ sumDiff[i] = [ZXGenericGF addOrSubtract:smallerCoefficients[i - lengthDiff] b:largerCoefficients[i]];
+ }
+
+ return [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:sumDiff coefficientsLen:largerCoefficientsLen];
+}
+
+- (ZXGenericGFPoly *) multiply:(ZXGenericGFPoly *)other {
+ if (![self.field isEqual:other.field]) {
+ [NSException raise:NSInvalidArgumentException format:@"ZXGenericGFPolys do not have same GenericGF field"];
+ }
+ if (self.zero || other.zero) {
+ return self.field.zero;
+ }
+ int *aCoefficients = self.coefficients;
+ int aLength = self.coefficientsLen;
+ int *bCoefficients = other.coefficients;
+ int bLength = other.coefficientsLen;
+ int productLen = aLength + bLength - 1;
+ int product[productLen];
+ memset(product, 0, productLen * sizeof(int));
+
+ for (int i = 0; i < aLength; i++) {
+ int aCoeff = aCoefficients[i];
+ for (int j = 0; j < bLength; j++) {
+ product[i + j] = [ZXGenericGF addOrSubtract:product[i + j]
+ b:[self.field multiply:aCoeff b:bCoefficients[j]]];
+ }
+ }
+ return [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:product coefficientsLen:productLen];
+}
+
+- (ZXGenericGFPoly *)multiplyScalar:(int)scalar {
+ if (scalar == 0) {
+ return self.field.zero;
+ }
+ if (scalar == 1) {
+ return self;
+ }
+ int size = self.coefficientsLen;
+ int product[size];
+ for (int i = 0; i < size; i++) {
+ product[i] = [self.field multiply:self.coefficients[i] b:scalar];
+ }
+ return [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:product coefficientsLen:size];
+}
+
+- (ZXGenericGFPoly *)multiplyByMonomial:(int)degree coefficient:(int)coefficient {
+ if (degree < 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Degree must be greater than 0."];
+ }
+ if (coefficient == 0) {
+ return self.field.zero;
+ }
+ int size = self.coefficientsLen;
+ int product[size + degree];
+ for (int i = 0; i < size + degree; i++) {
+ if (i < size) {
+ product[i] = [self.field multiply:self.coefficients[i] b:coefficient];
+ } else {
+ product[i] = 0;
+ }
+ }
+
+ return [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:product coefficientsLen:size + degree];
+}
+
+- (NSArray *)divide:(ZXGenericGFPoly *)other {
+ if (![self.field isEqual:other.field]) {
+ [NSException raise:NSInvalidArgumentException format:@"ZXGenericGFPolys do not have same ZXGenericGF field"];
+ }
+ if (other.zero) {
+ [NSException raise:NSInvalidArgumentException format:@"Divide by 0"];
+ }
+
+ ZXGenericGFPoly *quotient = self.field.zero;
+ ZXGenericGFPoly *remainder = self;
+
+ int denominatorLeadingTerm = [other coefficient:other.degree];
+ int inverseDenominatorLeadingTerm = [self.field inverse:denominatorLeadingTerm];
+
+ while ([remainder degree] >= other.degree && !remainder.zero) {
+ int degreeDifference = remainder.degree - other.degree;
+ int scale = [self.field multiply:[remainder coefficient:remainder.degree] b:inverseDenominatorLeadingTerm];
+ ZXGenericGFPoly *term = [other multiplyByMonomial:degreeDifference coefficient:scale];
+ ZXGenericGFPoly *iterationQuotient = [self.field buildMonomial:degreeDifference coefficient:scale];
+ quotient = [quotient addOrSubtract:iterationQuotient];
+ remainder = [remainder addOrSubtract:term];
+ }
+
+ return @[quotient, remainder];
+}
+
+- (NSString *) description {
+ 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:@" - "];
+ coefficient = -coefficient;
+ } else {
+ if ([result length] > 0) {
+ [result appendString:@" + "];
+ }
+ }
+ if (degree == 0 || coefficient != 1) {
+ int alphaPower = [self.field log:coefficient];
+ if (alphaPower == 0) {
+ [result appendString:@"1"];
+ } else if (alphaPower == 1) {
+ [result appendString:@"a"];
+ } else {
+ [result appendString:@"a^"];
+ [result appendFormat:@"%d", alphaPower];
+ }
+ }
+ if (degree != 0) {
+ if (degree == 1) {
+ [result appendString:@"x"];
+ } else {
+ [result appendString:@"x^"];
+ [result appendFormat:@"%d", degree];
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.h b/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.h
new file mode 100644
index 0000000..d256a4b
--- /dev/null
+++ b/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implements Reed-Solomon decoding, as the name implies.
+ *
+ * The algorithm will not be explained here, but the following references were helpful
+ * in creating this implementation:
+ *
+ * Bruce Maggs.
+ * http://www.cs.cmu.edu/afs/cs.cmu.edu/project/pscico-guyb/realworld/www/rs_decode.ps
+ * "Decoding Reed-Solomon Codes" (see discussion of Forney's Formula)
+ *
+ * J.I. Hall. www.mth.msu.edu/~jhall/classes/codenotes/GRS.pdf
+ * "Chapter 5. Generalized Reed-Solomon Codes"
+ * (see discussion of Euclidean algorithm)
+ *
+ * Much credit is due to William Rucklidge since portions of this code are an indirect
+ * port of his C++ Reed-Solomon implementation.
+ */
+
+@class ZXGenericGF;
+
+@interface ZXReedSolomonDecoder : NSObject
+
+- (id)initWithField:(ZXGenericGF *)field;
+- (BOOL)decode:(int *)received receivedLen:(int)receivedLen twoS:(int)twoS error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.m b/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.m
new file mode 100644
index 0000000..6a9bdbb
--- /dev/null
+++ b/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.m
@@ -0,0 +1,189 @@
+/*
+ * 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 "ZXErrors.h"
+#import "ZXGenericGF.h"
+#import "ZXGenericGFPoly.h"
+#import "ZXReedSolomonDecoder.h"
+
+@interface ZXReedSolomonDecoder ()
+
+@property (nonatomic, strong) ZXGenericGF *field;
+
+@end
+
+@implementation ZXReedSolomonDecoder
+
+- (id)initWithField:(ZXGenericGF *)field {
+ if (self = [super init]) {
+ _field = field;
+ }
+
+ return self;
+}
+
+/**
+ * Decodes given set of received codewords, which include both data and error-correction
+ * codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,
+ * in the input.
+ */
+- (BOOL)decode:(int *)received receivedLen:(int)receivedLen twoS:(int)twoS error:(NSError **)error {
+ ZXGenericGFPoly *poly = [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:received coefficientsLen:receivedLen];
+ int syndromeCoefficientsLen = twoS;
+ int syndromeCoefficients[syndromeCoefficientsLen];
+ BOOL noError = YES;
+
+ for (int i = 0; i < twoS; i++) {
+ int eval = [poly evaluateAt:[self.field exp:i + self.field.generatorBase]];
+ syndromeCoefficients[syndromeCoefficientsLen - 1 - i] = eval;
+ if (eval != 0) {
+ noError = NO;
+ }
+ }
+ if (noError) {
+ return YES;
+ }
+ ZXGenericGFPoly *syndrome = [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:syndromeCoefficients coefficientsLen:syndromeCoefficientsLen];
+ NSArray *sigmaOmega = [self runEuclideanAlgorithm:[self.field buildMonomial:twoS coefficient:1] b:syndrome R:twoS error:error];
+ if (!sigmaOmega) {
+ return NO;
+ }
+ ZXGenericGFPoly *sigma = sigmaOmega[0];
+ ZXGenericGFPoly *omega = sigmaOmega[1];
+ NSArray *errorLocations = [self findErrorLocations:sigma error:error];
+ if (!errorLocations) {
+ return NO;
+ }
+ NSArray *errorMagnitudes = [self findErrorMagnitudes:omega errorLocations:errorLocations];
+ for (int i = 0; i < [errorLocations count]; i++) {
+ int position = receivedLen - 1 - [self.field log:[errorLocations[i] intValue]];
+ if (position < 0) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Bad error location"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXReedSolomonError userInfo:userInfo];
+ return NO;
+ }
+ received[position] = [ZXGenericGF addOrSubtract:received[position] b:[errorMagnitudes[i] intValue]];
+ }
+ return YES;
+}
+
+- (NSArray *)runEuclideanAlgorithm:(ZXGenericGFPoly *)a b:(ZXGenericGFPoly *)b R:(int)R error:(NSError **)error {
+ if (a.degree < b.degree) {
+ ZXGenericGFPoly *temp = a;
+ a = b;
+ b = temp;
+ }
+
+ ZXGenericGFPoly *rLast = a;
+ ZXGenericGFPoly *r = b;
+ ZXGenericGFPoly *tLast = self.field.zero;
+ ZXGenericGFPoly *t = self.field.one;
+
+ while ([r degree] >= R / 2) {
+ ZXGenericGFPoly *rLastLast = rLast;
+ ZXGenericGFPoly *tLastLast = tLast;
+ rLast = r;
+ tLast = t;
+
+ if ([rLast zero]) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"r_{i-1} was zero"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXReedSolomonError userInfo:userInfo];
+ return NO;
+ }
+ r = rLastLast;
+ ZXGenericGFPoly *q = [self.field zero];
+ int denominatorLeadingTerm = [rLast coefficient:[rLast degree]];
+ int dltInverse = [self.field inverse:denominatorLeadingTerm];
+
+ while ([r degree] >= [rLast degree] && ![r zero]) {
+ int degreeDiff = [r degree] - [rLast degree];
+ int scale = [self.field multiply:[r coefficient:[r degree]] b:dltInverse];
+ q = [q addOrSubtract:[self.field buildMonomial:degreeDiff coefficient:scale]];
+ r = [r addOrSubtract:[rLast multiplyByMonomial:degreeDiff coefficient:scale]];
+ }
+
+ t = [[q multiply:tLast] addOrSubtract:tLastLast];
+
+ if (r.degree >= rLast.degree) {
+ @throw [NSException exceptionWithName:@"IllegalStateException"
+ reason:@"Division algorithm failed to reduce polynomial?"
+ userInfo:nil];
+ }
+ }
+
+ int sigmaTildeAtZero = [t coefficient:0];
+ if (sigmaTildeAtZero == 0) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"sigmaTilde(0) was zero"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXReedSolomonError userInfo:userInfo];
+ return NO;
+ }
+
+ int inverse = [self.field inverse:sigmaTildeAtZero];
+ ZXGenericGFPoly *sigma = [t multiplyScalar:inverse];
+ ZXGenericGFPoly *omega = [r multiplyScalar:inverse];
+ return @[sigma, omega];
+}
+
+- (NSArray *)findErrorLocations:(ZXGenericGFPoly *)errorLocator error:(NSError **)error {
+ int numErrors = [errorLocator degree];
+ if (numErrors == 1) {
+ return @[@([errorLocator coefficient:1])];
+ }
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:numErrors];
+ int e = 0;
+ for (int i = 1; i < [self.field size] && e < numErrors; i++) {
+ if ([errorLocator evaluateAt:i] == 0) {
+ [result addObject:@([self.field inverse:i])];
+ e++;
+ }
+ }
+
+ if (e != numErrors) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Error locator degree does not match number of roots"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXReedSolomonError userInfo:userInfo];
+ return nil;
+ }
+ return result;
+}
+
+- (NSArray *)findErrorMagnitudes:(ZXGenericGFPoly *)errorEvaluator errorLocations:(NSArray *)errorLocations {
+ NSUInteger s = [errorLocations count];
+ NSMutableArray *result = [NSMutableArray array];
+ for (int i = 0; i < s; i++) {
+ int xiInverse = [self.field inverse:[errorLocations[i] intValue]];
+ int denominator = 1;
+ for (int j = 0; j < s; j++) {
+ if (i != j) {
+ int term = [self.field multiply:[errorLocations[j] intValue] b:xiInverse];
+ int termPlus1 = (term & 0x1) == 0 ? term | 1 : term & ~1;
+ denominator = [self.field multiply:denominator b:termPlus1];
+ }
+ }
+
+ [result addObject:@([self.field multiply:[errorEvaluator evaluateAt:xiInverse] b:[self.field inverse:denominator]])];
+ if (self.field.generatorBase != 0) {
+ result[i] = @([self.field multiply:[result[i] intValue] b:xiInverse]);
+ }
+ }
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.h b/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.h
new file mode 100644
index 0000000..a073722
--- /dev/null
+++ b/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implements Reed-Solomon enbcoding, as the name implies.
+ */
+
+@class ZXGenericGF;
+
+@interface ZXReedSolomonEncoder : NSObject
+
+- (id)initWithField:(ZXGenericGF *)field;
+- (void)encode:(int *)toEncode toEncodeLen:(int)toEncodeLen ecBytes:(int)ecBytes;
+
+@end
diff --git a/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.m b/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.m
new file mode 100644
index 0000000..d2fac8f
--- /dev/null
+++ b/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.m
@@ -0,0 +1,85 @@
+/*
+ * 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 "ZXGenericGF.h"
+#import "ZXGenericGFPoly.h"
+#import "ZXReedSolomonEncoder.h"
+
+@interface ZXReedSolomonEncoder ()
+
+@property (nonatomic, strong) NSMutableArray *cachedGenerators;
+@property (nonatomic, strong) ZXGenericGF *field;
+
+@end
+
+@implementation ZXReedSolomonEncoder
+
+- (id)initWithField:(ZXGenericGF *)field {
+ if (self = [super init]) {
+ _field = field;
+ int one = 1;
+ _cachedGenerators = [NSMutableArray arrayWithObject:[[ZXGenericGFPoly alloc] initWithField:field coefficients:&one coefficientsLen:1]];
+ }
+
+ return self;
+}
+
+- (ZXGenericGFPoly *)buildGenerator:(int)degree {
+ if (degree >= self.cachedGenerators.count) {
+ ZXGenericGFPoly *lastGenerator = self.cachedGenerators[[self.cachedGenerators count] - 1];
+ for (NSUInteger d = [self.cachedGenerators count]; d <= degree; d++) {
+ int next[2] = { 1, [self.field exp:(int)d - 1 + self.field.generatorBase] };
+ ZXGenericGFPoly *nextGenerator = [lastGenerator multiply:[[ZXGenericGFPoly alloc] initWithField:self.field coefficients:next coefficientsLen:2]];
+ [self.cachedGenerators addObject:nextGenerator];
+ lastGenerator = nextGenerator;
+ }
+ }
+
+ return (ZXGenericGFPoly *)self.cachedGenerators[degree];
+}
+
+- (void)encode:(int *)toEncode toEncodeLen:(int)toEncodeLen ecBytes:(int)ecBytes {
+ if (ecBytes == 0) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"No error correction bytes"
+ userInfo:nil];
+ }
+ int dataBytes = toEncodeLen - ecBytes;
+ if (dataBytes <= 0) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"No data bytes provided"
+ userInfo:nil];
+ }
+ ZXGenericGFPoly *generator = [self buildGenerator:ecBytes];
+ int infoCoefficients[dataBytes];
+ for (int i = 0; i < dataBytes; i++) {
+ infoCoefficients[i] = toEncode[i];
+ }
+ ZXGenericGFPoly *info = [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:infoCoefficients coefficientsLen:dataBytes];
+ info = [info multiplyByMonomial:ecBytes coefficient:1];
+ ZXGenericGFPoly *remainder = [info divide:generator][1];
+ int *coefficients = remainder.coefficients;
+ int coefficientsLen = remainder.coefficientsLen;
+ int numZeroCoefficients = ecBytes - coefficientsLen;
+ for (int i = 0; i < numZeroCoefficients; i++) {
+ toEncode[dataBytes + i] = 0;
+ }
+ for (int i = 0; i < coefficientsLen; i++) {
+ toEncode[dataBytes + numZeroCoefficients + i] = coefficients[i];
+ }
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/ZXDataMatrixReader.h b/ZXingObjC/datamatrix/ZXDataMatrixReader.h
new file mode 100644
index 0000000..17d7359
--- /dev/null
+++ b/ZXingObjC/datamatrix/ZXDataMatrixReader.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXReader.h"
+
+/**
+ * This implementation can detect and decode Data Matrix codes in an image.
+ */
+
+@class ZXBinaryBitmap, ZXDecodeHints, ZXResult;
+
+@interface ZXDataMatrixReader : NSObject <ZXReader>
+
+@end
diff --git a/ZXingObjC/datamatrix/ZXDataMatrixReader.m b/ZXingObjC/datamatrix/ZXDataMatrixReader.m
new file mode 100644
index 0000000..6ed3df7
--- /dev/null
+++ b/ZXingObjC/datamatrix/ZXDataMatrixReader.m
@@ -0,0 +1,171 @@
+/*
+ * 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 "ZXBinaryBitmap.h"
+#import "ZXBitMatrix.h"
+#import "ZXDataMatrixDecoder.h"
+#import "ZXDataMatrixReader.h"
+#import "ZXDataMatrixDetector.h"
+#import "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXDetectorResult.h"
+#import "ZXErrors.h"
+#import "ZXResult.h"
+
+@interface ZXDataMatrixReader ()
+
+@property (nonatomic, strong) ZXDataMatrixDecoder *decoder;
+
+@end
+
+@implementation ZXDataMatrixReader
+
+- (id)init {
+ if (self = [super init]) {
+ _decoder = [[ZXDataMatrixDecoder alloc] init];
+ }
+
+ return self;
+}
+
+/**
+ * Locates and decodes a Data Matrix code in an image.
+ */
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decode:image hints:nil error:error];
+}
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXDecoderResult *decoderResult;
+ NSArray *points;
+ if (hints != nil && hints.pureBarcode) {
+ ZXBitMatrix *matrix = [image blackMatrixWithError:error];
+ if (!matrix) {
+ return nil;
+ }
+ ZXBitMatrix *bits = [self extractPureBits:matrix];
+ if (!bits) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ decoderResult = [self.decoder decodeMatrix:bits error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ points = @[];
+ } else {
+ ZXBitMatrix *matrix = [image blackMatrixWithError:error];
+ if (!matrix) {
+ return nil;
+ }
+ ZXDataMatrixDetector *detector = [[ZXDataMatrixDetector alloc] initWithImage:matrix error:error];
+ if (!detector) {
+ return nil;
+ }
+ ZXDetectorResult *detectorResult = [detector detectWithError:error];
+ if (!detectorResult) {
+ return nil;
+ }
+ decoderResult = [self.decoder decodeMatrix:detectorResult.bits error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ points = detectorResult.points;
+ }
+ ZXResult *result = [ZXResult resultWithText:decoderResult.text
+ rawBytes:decoderResult.rawBytes
+ length:decoderResult.length
+ resultPoints:points
+ format:kBarcodeFormatDataMatrix];
+ if (decoderResult.byteSegments != nil) {
+ [result putMetadata:kResultMetadataTypeByteSegments value:decoderResult.byteSegments];
+ }
+ if (decoderResult.ecLevel != nil) {
+ [result putMetadata:kResultMetadataTypeErrorCorrectionLevel value:decoderResult.ecLevel];
+ }
+ return result;
+}
+
+- (void) reset {
+ // do nothing
+}
+
+
+/**
+ * This method detects a code in a "pure" image -- that is, pure monochrome image
+ * which contains only an unrotated, unskewed, image of a code, with some white border
+ * around it. This is a specialized method that works exceptionally fast in this special
+ * case.
+ */
+- (ZXBitMatrix *)extractPureBits:(ZXBitMatrix *)image {
+ NSArray *leftTopBlack = image.topLeftOnBit;
+ NSArray *rightBottomBlack = image.bottomRightOnBit;
+ if (leftTopBlack == nil || rightBottomBlack == nil) {
+ return nil;
+ }
+
+ int moduleSize = [self moduleSize:leftTopBlack image:image];
+ if (moduleSize == -1) {
+ return nil;
+ }
+
+ int top = [leftTopBlack[1] intValue];
+ int bottom = [rightBottomBlack[1] intValue];
+ int left = [leftTopBlack[0] intValue];
+ int right = [rightBottomBlack[0] intValue];
+
+ int matrixWidth = (right - left + 1) / moduleSize;
+ int matrixHeight = (bottom - top + 1) / moduleSize;
+ if (matrixWidth <= 0 || matrixHeight <= 0) {
+ return nil;
+ }
+
+ int nudge = moduleSize >> 1;
+ top += nudge;
+ left += nudge;
+
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithWidth:matrixWidth height:matrixHeight];
+ for (int y = 0; y < matrixHeight; y++) {
+ int iOffset = top + y * moduleSize;
+ for (int x = 0; x < matrixWidth; x++) {
+ if ([image getX:left + x * moduleSize y:iOffset]) {
+ [bits setX:x y:y];
+ }
+ }
+ }
+
+ return bits;
+}
+
+- (int)moduleSize:(NSArray *)leftTopBlack image:(ZXBitMatrix *)image {
+ int width = image.width;
+ int x = [leftTopBlack[0] intValue];
+ int y = [leftTopBlack[1] intValue];
+ while (x < width && [image getX:x y:y]) {
+ x++;
+ }
+ if (x == width) {
+ return -1;
+ }
+
+ int moduleSize = x - [leftTopBlack[0] intValue];
+ if (moduleSize == 0) {
+ return -1;
+ }
+ return moduleSize;
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/ZXDataMatrixWriter.h b/ZXingObjC/datamatrix/ZXDataMatrixWriter.h
new file mode 100644
index 0000000..3762cd7
--- /dev/null
+++ b/ZXingObjC/datamatrix/ZXDataMatrixWriter.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXWriter.h"
+
+/**
+ * This object renders a Data Matrix code as a BitMatrix 2D array of greyscale values.
+ */
+
+@interface ZXDataMatrixWriter : NSObject <ZXWriter>
+
+@end
diff --git a/ZXingObjC/datamatrix/ZXDataMatrixWriter.m b/ZXingObjC/datamatrix/ZXDataMatrixWriter.m
new file mode 100644
index 0000000..9caae9c
--- /dev/null
+++ b/ZXingObjC/datamatrix/ZXDataMatrixWriter.m
@@ -0,0 +1,156 @@
+/*
+ * 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 "ZXBitMatrix.h"
+#import "ZXByteMatrix.h"
+#import "ZXDataMatrixErrorCorrection.h"
+#import "ZXDataMatrixWriter.h"
+#import "ZXDefaultPlacement.h"
+#import "ZXDimension.h"
+#import "ZXEncodeHints.h"
+#import "ZXHighLevelEncoder.h"
+#import "ZXSymbolInfo.h"
+#import "ZXSymbolShapeHint.h"
+
+@implementation ZXDataMatrixWriter
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error {
+ return [self encode:contents format:format width:width height:height hints:nil error:error];
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if (contents.length == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Found empty contents"];
+ }
+
+ if (format != kBarcodeFormatDataMatrix) {
+ [NSException raise:NSInvalidArgumentException format:@"Can only encode kBarcodeFormatDataMatrix"];
+ }
+
+ if (width < 0 || height < 0) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Requested dimensions are too small: %dx%d", width, height];
+ }
+
+ // Try to get force shape & min / max size
+ ZXSymbolShapeHint *shape = [ZXSymbolShapeHint forceNone];
+ ZXDimension *minSize = nil;
+ ZXDimension *maxSize = nil;
+ if (hints != nil) {
+ ZXSymbolShapeHint *requestedShape = hints.dataMatrixShape;
+ if (requestedShape != nil) {
+ shape = requestedShape;
+ }
+ ZXDimension *requestedMinSize = hints.minSize;
+ if (requestedMinSize != nil) {
+ minSize = requestedMinSize;
+ }
+ ZXDimension *requestedMaxSize = hints.maxSize;
+ if (requestedMaxSize != nil) {
+ maxSize = requestedMaxSize;
+ }
+ }
+
+ //1. step: Data encodation
+ NSString *encoded = [ZXHighLevelEncoder encodeHighLevel:contents shape:shape minSize:minSize maxSize:maxSize];
+
+ ZXSymbolInfo *symbolInfo = [ZXSymbolInfo lookup:(int)encoded.length shape:shape minSize:minSize maxSize:maxSize fail:YES];
+
+ //2. step: ECC generation
+ NSString *codewords = [ZXDataMatrixErrorCorrection encodeECC200:encoded symbolInfo:symbolInfo];
+
+ //3. step: Module placement in Matrix
+ ZXDefaultPlacement *placement = [[ZXDefaultPlacement alloc] initWithCodewords:codewords numcols:symbolInfo.symbolDataWidth numrows:symbolInfo.symbolDataHeight];
+ [placement place];
+
+ //4. step: low-level encoding
+ return [self encodeLowLevel:placement symbolInfo:symbolInfo];
+}
+
+/**
+ * Encode the given symbol info to a bit matrix.
+ */
+- (ZXBitMatrix *)encodeLowLevel:(ZXDefaultPlacement *)placement symbolInfo:(ZXSymbolInfo *)symbolInfo {
+ int symbolWidth = symbolInfo.symbolDataWidth;
+ int symbolHeight = symbolInfo.symbolDataHeight;
+
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:symbolInfo.symbolWidth height:symbolInfo.symbolHeight];
+
+ int matrixY = 0;
+
+ for (int y = 0; y < symbolHeight; y++) {
+ // Fill the top edge with alternate 0 / 1
+ int matrixX;
+ if ((y % symbolInfo.matrixHeight) == 0) {
+ matrixX = 0;
+ for (int x = 0; x < symbolInfo.symbolWidth; x++) {
+ [matrix setX:matrixX y:matrixY boolValue:(x % 2) == 0];
+ matrixX++;
+ }
+ matrixY++;
+ }
+ matrixX = 0;
+ for (int x = 0; x < symbolWidth; x++) {
+ // Fill the right edge with full 1
+ if ((x % symbolInfo.matrixWidth) == 0) {
+ [matrix setX:matrixX y:matrixY boolValue:YES];
+ matrixX++;
+ }
+ [matrix setX:matrixX y:matrixY boolValue:[placement bitAtCol:x row:y]];
+ matrixX++;
+ // Fill the right edge with alternate 0 / 1
+ if ((x % symbolInfo.matrixWidth) == symbolInfo.matrixWidth - 1) {
+ [matrix setX:matrixX y:matrixY boolValue:(y % 2) == 0];
+ matrixX++;
+ }
+ }
+ matrixY++;
+ // Fill the bottom edge with full 1
+ if ((y % symbolInfo.matrixHeight) == symbolInfo.matrixHeight - 1) {
+ matrixX = 0;
+ for (int x = 0; x < symbolInfo.symbolWidth; x++) {
+ [matrix setX:matrixX y:matrixY boolValue:YES];
+ matrixX++;
+ }
+ matrixY++;
+ }
+ }
+
+ return [self convertByteMatrixToBitMatrix:matrix];
+}
+
+/**
+ * Convert the ByteMatrix to BitMatrix.
+ */
+- (ZXBitMatrix *)convertByteMatrixToBitMatrix:(ZXByteMatrix *)matrix {
+ int matrixWidgth = matrix.width;
+ int matrixHeight = matrix.height;
+
+ ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:matrixWidgth height:matrixHeight];
+ [output clear];
+ for (int i = 0; i < matrixWidgth; i++) {
+ for (int j = 0; j < matrixHeight; j++) {
+ // Zero is white in the bytematrix
+ if ([matrix getX:i y:j] == 1) {
+ [output setX:i y:j];
+ }
+ }
+ }
+
+ return output;
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.h b/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.h
new file mode 100644
index 0000000..30d0b09
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+@class ZXBitMatrix, ZXDataMatrixVersion;
+
+@interface ZXDataMatrixBitMatrixParser : NSObject
+
+@property (nonatomic, strong, readonly) ZXDataMatrixVersion *version;
+
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error;
+- (NSArray *)readCodewords;
+- (BOOL)readModule:(int)row column:(int)column numRows:(int)numRows numColumns:(int)numColumns;
+- (int)readUtah:(int)row column:(int)column numRows:(int)numRows numColumns:(int)numColumns;
+- (int)readCorner1:(int)numRows numColumns:(int)numColumns;
+- (int)readCorner2:(int)numRows numColumns:(int)numColumns;
+- (int)readCorner3:(int)numRows numColumns:(int)numColumns;
+- (int)readCorner4:(int)numRows numColumns:(int)numColumns;
+- (ZXBitMatrix *)extractDataRegion:(ZXBitMatrix *)bitMatrix;
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.m b/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.m
new file mode 100644
index 0000000..6c9d6c1
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.m
@@ -0,0 +1,404 @@
+/*
+ * 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 "ZXDataMatrixBitMatrixParser.h"
+#import "ZXDataMatrixVersion.h"
+#import "ZXErrors.h"
+
+@interface ZXDataMatrixBitMatrixParser ()
+
+@property (nonatomic, strong) ZXBitMatrix *mappingBitMatrix;
+@property (nonatomic, strong) ZXBitMatrix *readMappingMatrix;
+
+@end
+
+@implementation ZXDataMatrixBitMatrixParser
+
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error {
+ if (self = [super init]) {
+ int dimension = bitMatrix.height;
+ if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ _version = [self readVersion:bitMatrix];
+ if (!_version) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ _mappingBitMatrix = [self extractDataRegion:bitMatrix];
+ _readMappingMatrix = [[ZXBitMatrix alloc] initWithWidth:_mappingBitMatrix.width
+ height:_mappingBitMatrix.height];
+ }
+
+ return self;
+}
+
+/**
+ * Creates the version object based on the dimension of the original bit matrix from
+ * the datamatrix code.
+ *
+ * See ISO 16022:2006 Table 7 - ECC 200 symbol attributes
+ */
+- (ZXDataMatrixVersion *)readVersion:(ZXBitMatrix *)bitMatrix {
+ int numRows = bitMatrix.height;
+ int numColumns = bitMatrix.width;
+ return [ZXDataMatrixVersion versionForDimensions:numRows numColumns:numColumns];
+}
+
+
+/**
+ * Reads the bits in the {@link BitMatrix} representing the mapping matrix (No alignment patterns)
+ * in the correct order in order to reconstitute the codewords bytes contained within the
+ * Data Matrix Code.
+ */
+- (NSArray *)readCodewords {
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:self.version.totalCodewords];
+
+ int row = 4;
+ int column = 0;
+
+ int numRows = self.mappingBitMatrix.height;
+ int numColumns = self.mappingBitMatrix.width;
+
+ BOOL corner1Read = NO;
+ BOOL corner2Read = NO;
+ BOOL corner3Read = NO;
+ BOOL corner4Read = NO;
+
+ do {
+ if ((row == numRows) && (column == 0) && !corner1Read) {
+ [result addObject:@([self readCorner1:numRows numColumns:numColumns])];
+ row -= 2;
+ column += 2;
+ corner1Read = YES;
+ } else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x03) != 0) && !corner2Read) {
+ [result addObject:@([self readCorner2:numRows numColumns:numColumns])];
+ row -= 2;
+ column += 2;
+ corner2Read = YES;
+ } else if ((row == numRows + 4) && (column == 2) && ((numColumns & 0x07) == 0) && !corner3Read) {
+ [result addObject:@([self readCorner3:numRows numColumns:numColumns])];
+ row -= 2;
+ column += 2;
+ corner3Read = YES;
+ } else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x07) == 4) && !corner4Read) {
+ [result addObject:@([self readCorner4:numRows numColumns:numColumns])];
+ row -= 2;
+ column += 2;
+ corner4Read = YES;
+ } else {
+ do {
+ if ((row < numRows) && (column >= 0) && ![self.readMappingMatrix getX:column y:row]) {
+ [result addObject:@([self readUtah:row column:column numRows:numRows numColumns:numColumns])];
+ }
+ row -= 2;
+ column += 2;
+ } while ((row >= 0) && (column < numColumns));
+ row += 1;
+ column += 3;
+
+ do {
+ if ((row >= 0) && (column < numColumns) && ![self.readMappingMatrix getX:column y:row]) {
+ [result addObject:@([self readUtah:row column:column numRows:numRows numColumns:numColumns])];
+ }
+ row += 2;
+ column -= 2;
+ } while ((row < numRows) && (column >= 0));
+ row += 3;
+ column += 1;
+ }
+ } while ((row < numRows) || (column < numColumns));
+
+ if ([result count] != self.version.totalCodewords) {
+ return nil;
+ }
+ return result;
+}
+
+
+/**
+ * Reads a bit of the mapping matrix accounting for boundary wrapping.
+ */
+- (BOOL)readModule:(int)row column:(int)column numRows:(int)numRows numColumns:(int)numColumns {
+ if (row < 0) {
+ row += numRows;
+ column += 4 - ((numRows + 4) & 0x07);
+ }
+ if (column < 0) {
+ column += numColumns;
+ row += 4 - ((numColumns + 4) & 0x07);
+ }
+ [self.readMappingMatrix setX:column y:row];
+ return [self.mappingBitMatrix getX:column y:row];
+}
+
+
+/**
+ * Reads the 8 bits of the standard Utah-shaped pattern.
+ *
+ * See ISO 16022:2006, 5.8.1 Figure 6
+ */
+- (int)readUtah:(int)row column:(int)column numRows:(int)numRows numColumns:(int)numColumns {
+ int currentByte = 0;
+ if ([self readModule:row - 2 column:column - 2 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:row - 2 column:column - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:row - 1 column:column - 2 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:row - 1 column:column - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:row - 1 column:column numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:row column:column - 2 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:row column:column - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:row column:column numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+
+
+/**
+ * Reads the 8 bits of the special corner condition 1.
+ *
+ * See ISO 16022:2006, Figure F.3
+ */
+- (int)readCorner1:(int)numRows numColumns:(int)numColumns {
+ int currentByte = 0;
+ if ([self readModule:numRows - 1 column:0 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:numRows - 1 column:1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:numRows - 1 column:2 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 2 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:1 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:2 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:3 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+
+
+/**
+ * Reads the 8 bits of the special corner condition 2.
+ *
+ * See ISO 16022:2006, Figure F.4
+ */
+- (int)readCorner2:(int)numRows numColumns:(int)numColumns {
+ int currentByte = 0;
+ if ([self readModule:numRows - 3 column:0 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:numRows - 2 column:0 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:numRows - 1 column:0 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 4 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 3 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 2 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:1 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+
+
+/**
+ * Reads the 8 bits of the special corner condition 3.
+ *
+ * See ISO 16022:2006, Figure F.5
+ */
+- (int)readCorner3:(int)numRows numColumns:(int)numColumns {
+ int currentByte = 0;
+ if ([self readModule:numRows - 1 column:0 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:numRows - 1 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 3 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 2 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:1 column:numColumns - 3 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:1 column:numColumns - 2 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:1 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+
+
+/**
+ * Reads the 8 bits of the special corner condition 4.
+ *
+ * See ISO 16022:2006, Figure F.6
+ */
+- (int)readCorner4:(int)numRows numColumns:(int)numColumns {
+ int currentByte = 0;
+ if ([self readModule:numRows - 3 column:0 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:numRows - 2 column:0 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:numRows - 1 column:0 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 2 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:0 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:1 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:2 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if ([self readModule:3 column:numColumns - 1 numRows:numRows numColumns:numColumns]) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+
+
+/**
+ * Extracts the data region from a {@link BitMatrix} that contains
+ * alignment patterns.
+ */
+- (ZXBitMatrix *)extractDataRegion:(ZXBitMatrix *)bitMatrix {
+ int symbolSizeRows = self.version.symbolSizeRows;
+ int symbolSizeColumns = self.version.symbolSizeColumns;
+
+ if (bitMatrix.height != symbolSizeRows) {
+ [NSException raise:NSInvalidArgumentException format:@"Dimension of bitMatrix must match the version size"];
+ }
+
+ int dataRegionSizeRows = self.version.dataRegionSizeRows;
+ int dataRegionSizeColumns = self.version.dataRegionSizeColumns;
+
+ int numDataRegionsRow = symbolSizeRows / dataRegionSizeRows;
+ int numDataRegionsColumn = symbolSizeColumns / dataRegionSizeColumns;
+
+ int sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows;
+ int sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns;
+
+ ZXBitMatrix *bitMatrixWithoutAlignment = [[ZXBitMatrix alloc] initWithWidth:sizeDataRegionColumn height:sizeDataRegionRow];
+ for (int dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow) {
+ int dataRegionRowOffset = dataRegionRow * dataRegionSizeRows;
+ for (int dataRegionColumn = 0; dataRegionColumn < numDataRegionsColumn; ++dataRegionColumn) {
+ int dataRegionColumnOffset = dataRegionColumn * dataRegionSizeColumns;
+ for (int i = 0; i < dataRegionSizeRows; ++i) {
+ int readRowOffset = dataRegionRow * (dataRegionSizeRows + 2) + 1 + i;
+ int writeRowOffset = dataRegionRowOffset + i;
+ for (int j = 0; j < dataRegionSizeColumns; ++j) {
+ int readColumnOffset = dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j;
+ if ([bitMatrix getX:readColumnOffset y:readRowOffset]) {
+ int writeColumnOffset = dataRegionColumnOffset + j;
+ [bitMatrixWithoutAlignment setX:writeColumnOffset y:writeRowOffset];
+ }
+ }
+ }
+ }
+ }
+
+ return bitMatrixWithoutAlignment;
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.h b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.h
new file mode 100644
index 0000000..ef091e2
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates a block of data within a Data Matrix Code. Data Matrix Codes may split their data into
+ * multiple blocks, each of which is a unit of data and error-correction codewords. Each
+ * is represented by an instance of this class.
+ */
+
+@class ZXDataMatrixVersion;
+
+@interface ZXDataMatrixDataBlock : NSObject
+
+@property (nonatomic, assign, readonly) int numDataCodewords;
+@property (nonatomic, strong, readonly) NSMutableArray *codewords;
+
++ (NSArray *)dataBlocks:(NSArray *)rawCodewords version:(ZXDataMatrixVersion *)version;
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.m b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.m
new file mode 100644
index 0000000..9a4499e
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.m
@@ -0,0 +1,91 @@
+/*
+ * 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 "ZXDataMatrixDataBlock.h"
+#import "ZXDataMatrixVersion.h"
+#import "ZXQRCodeVersion.h"
+
+@implementation ZXDataMatrixDataBlock
+
+- (id)initWithNumDataCodewords:(int)numDataCodewords codewords:(NSMutableArray *)codewords {
+ if (self = [super init]) {
+ _numDataCodewords = numDataCodewords;
+ _codewords = codewords;
+ }
+
+ return self;
+}
+
+/**
+ * When Data Matrix Codes use multiple data blocks, they actually interleave the bytes of each of them.
+ * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
+ * method will separate the data into original blocks.
+ */
++ (NSArray *)dataBlocks:(NSArray *)rawCodewords version:(ZXDataMatrixVersion *)version {
+ ZXDataMatrixECBlocks *ecBlocks = version.ecBlocks;
+
+ int totalBlocks = 0;
+ NSArray *ecBlockArray = ecBlocks.ecBlocks;
+ for (ZXDataMatrixECB *ecBlock in ecBlockArray) {
+ totalBlocks += ecBlock.count;
+ }
+
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:totalBlocks];
+ int numResultBlocks = 0;
+ for (ZXDataMatrixECB *ecBlock in ecBlockArray) {
+ for (int i = 0; i < ecBlock.count; i++) {
+ int numDataCodewords = ecBlock.dataCodewords;
+ int numBlockCodewords = ecBlocks.ecCodewords + numDataCodewords;
+ NSMutableArray *tempCodewords = [NSMutableArray arrayWithCapacity:numBlockCodewords];
+ for (int j = 0; j < numBlockCodewords; j++) {
+ [tempCodewords addObject:@0];
+ }
+ [result addObject:[[ZXDataMatrixDataBlock alloc] initWithNumDataCodewords:numDataCodewords codewords:tempCodewords]];
+ numResultBlocks++;
+ }
+ }
+
+ int longerBlocksTotalCodewords = (int)[[result[0] codewords] count];
+ int longerBlocksNumDataCodewords = longerBlocksTotalCodewords - ecBlocks.ecCodewords;
+ int shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1;
+ int rawCodewordsOffset = 0;
+ for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {
+ for (int j = 0; j < numResultBlocks; j++) {
+ [result[j] codewords][i] = rawCodewords[rawCodewordsOffset++];
+ }
+ }
+
+ BOOL specialVersion = version.versionNumber == 24;
+ int numLongerBlocks = specialVersion ? 8 : numResultBlocks;
+ for (int j = 0; j < numLongerBlocks; j++) {
+ [result[j] codewords][longerBlocksNumDataCodewords - 1] = rawCodewords[rawCodewordsOffset++];
+ }
+
+ NSUInteger max = [[result[0] codewords] count];
+ for (int i = longerBlocksNumDataCodewords; i < max; i++) {
+ for (int j = 0; j < numResultBlocks; j++) {
+ int iOffset = specialVersion && j > 7 ? i - 1 : i;
+ [result[j] codewords][iOffset] = rawCodewords[rawCodewordsOffset++];
+ }
+ }
+
+ if (rawCodewordsOffset != [rawCodewords count]) {
+ [NSException raise:NSInvalidArgumentException format:@"Codewords size mismatch"];
+ }
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.h b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.h
new file mode 100644
index 0000000..410cb5e
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * Data Matrix Codes can encode text as bits in one of several modes, and can use multiple modes
+ * in one Data Matrix Code. This class decodes the bits back into text.
+ *
+ * See ISO 16022:2006, 5.2.1 - 5.2.9.2
+ */
+
+@class ZXDecoderResult;
+
+@interface ZXDataMatrixDecodedBitStreamParser : NSObject
+
++ (ZXDecoderResult *)decode:(int8_t *)bytes length:(unsigned int)length error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.m b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.m
new file mode 100644
index 0000000..5bc21d9
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.m
@@ -0,0 +1,497 @@
+/*
+ * 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 "ZXBitSource.h"
+#import "ZXDataMatrixDecodedBitStreamParser.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+
+/**
+ * See ISO 16022:2006, Annex C Table C.1
+ * The C40 Basic Character Set (*'s used for placeholders for the shift values)
+ */
+const char C40_BASIC_SET_CHARS[40] = {
+ '*', '*', '*', ' ', '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'
+};
+
+const char C40_SHIFT2_SET_CHARS[40] = {
+ '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
+ '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
+};
+
+/**
+ * See ISO 16022:2006, Annex C Table C.2
+ * The Text Basic Character Set (*'s used for placeholders for the shift values)
+ */
+const char TEXT_BASIC_SET_CHARS[40] = {
+ '*', '*', '*', ' ', '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'
+};
+
+const char TEXT_SHIFT3_SET_CHARS[32] = {
+ '\'', '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', '{', '|', '}', '~', (char) 127
+};
+
+enum {
+ PAD_ENCODE = 0, // Not really a mode
+ ASCII_ENCODE,
+ C40_ENCODE,
+ TEXT_ENCODE,
+ ANSIX12_ENCODE,
+ EDIFACT_ENCODE,
+ BASE256_ENCODE
+};
+
+@implementation ZXDataMatrixDecodedBitStreamParser
+
++ (ZXDecoderResult *)decode:(int8_t *)bytes length:(unsigned int)length error:(NSError **)error {
+ ZXBitSource *bits = [[ZXBitSource alloc] initWithBytes:bytes length:length];
+ NSMutableString *result = [NSMutableString stringWithCapacity:100];
+ NSMutableString *resultTrailer = [NSMutableString string];
+ NSMutableArray *byteSegments = [NSMutableArray arrayWithCapacity:1];
+ int mode = ASCII_ENCODE;
+ do {
+ if (mode == ASCII_ENCODE) {
+ mode = [self decodeAsciiSegment:bits result:result resultTrailer:resultTrailer];
+ if (mode == -1) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ } else {
+ switch (mode) {
+ case C40_ENCODE:
+ if (![self decodeC40Segment:bits result:result]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ break;
+ case TEXT_ENCODE:
+ if (![self decodeTextSegment:bits result:result]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ break;
+ case ANSIX12_ENCODE:
+ if (![self decodeAnsiX12Segment:bits result:result]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ break;
+ case EDIFACT_ENCODE:
+ [self decodeEdifactSegment:bits result:result];
+ break;
+ case BASE256_ENCODE:
+ if (![self decodeBase256Segment:bits result:result byteSegments:byteSegments]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ break;
+ default:
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ mode = ASCII_ENCODE;
+ }
+ } while (mode != PAD_ENCODE && bits.available > 0);
+ if ([resultTrailer length] > 0) {
+ [result appendString:resultTrailer];
+ }
+ return [[ZXDecoderResult alloc] initWithRawBytes:bytes
+ length:length
+ text:result
+ byteSegments:[byteSegments count] == 0 ? nil : byteSegments
+ ecLevel:nil];
+}
+
+/**
+ * See ISO 16022:2006, 5.2.3 and Annex C, Table C.2
+ */
++ (int)decodeAsciiSegment:(ZXBitSource *)bits result:(NSMutableString *)result resultTrailer:(NSMutableString *)resultTrailer {
+ BOOL upperShift = NO;
+ do {
+ int oneByte = [bits readBits:8];
+ if (oneByte == 0) {
+ return -1;
+ } else if (oneByte <= 128) { // ASCII data (ASCII value + 1)
+ if (upperShift) {
+ oneByte += 128;
+ //upperShift = NO;
+ }
+ [result appendFormat:@"%C", (unichar)(oneByte - 1)];
+ return ASCII_ENCODE;
+ } else if (oneByte == 129) { // Pad
+ return PAD_ENCODE;
+ } else if (oneByte <= 229) { // 2-digit data 00-99 (Numeric Value + 130)
+ int value = oneByte - 130;
+ if (value < 10) { // padd with '0' for single digit values
+ [result appendString:@"0"];
+ }
+ [result appendFormat:@"%d", value];
+ } else if (oneByte == 230) { // Latch to C40 encodation
+ return C40_ENCODE;
+ } else if (oneByte == 231) { // Latch to Base 256 encodation
+ return BASE256_ENCODE;
+ } else if (oneByte == 232) {
+ // FNC1
+ [result appendFormat:@"%C", (unichar)29]; // translate as ASCII 29
+ } else if (oneByte == 233 || oneByte == 234) {
+ // Structured Append, Reader Programming
+ // Ignore these symbols for now
+ //return -1;
+ } 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];
+ [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];
+ [resultTrailer insertString:[NSString stringWithFormat:@"%C%C", (unichar)0x001E, (unichar)0x0004] atIndex:0];
+ } else if (oneByte == 238) { // Latch to ANSI X12 encodation
+ return ANSIX12_ENCODE;
+ } else if (oneByte == 239) { // Latch to Text encodation
+ return TEXT_ENCODE;
+ } else if (oneByte == 240) { // Latch to EDIFACT encodation
+ return EDIFACT_ENCODE;
+ } else if (oneByte == 241) { // ECI Character
+ // TODO(bbrown): I think we need to support ECI
+ // Ignore this symbol for now
+ } else if (oneByte >= 242) { // Not to be used in ASCII encodation
+ // ... but work around encoders that end with 254, latch back to ASCII
+ if (oneByte != 254 || bits.available != 0) {
+ return -1;
+ }
+ }
+ } while (bits.available > 0);
+ return ASCII_ENCODE;
+}
+
+
+/**
+ * See ISO 16022:2006, 5.2.5 and Annex C, Table C.1
+ */
++ (BOOL)decodeC40Segment:(ZXBitSource *)bits result:(NSMutableString *)result {
+ // Three C40 values are encoded in a 16-bit value as
+ // (1600 * C1) + (40 * C2) + C3 + 1
+ // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time
+ BOOL upperShift = NO;
+
+ int cValues[3] = {0};
+ int shift = 0;
+
+ do {
+ // If there is only one byte left then it will be encoded as ASCII
+ if ([bits available] == 8) {
+ return YES;
+ }
+ int firstByte = [bits readBits:8];
+ if (firstByte == 254) { // Unlatch codeword
+ return YES;
+ }
+
+ [self parseTwoBytes:firstByte secondByte:[bits readBits:8] result:cValues];
+
+ for (int i = 0; i < 3; i++) {
+ int cValue = cValues[i];
+ switch (shift) {
+ case 0:
+ if (cValue < 3) {
+ shift = cValue + 1;
+ } else if (cValue < sizeof(C40_BASIC_SET_CHARS) / sizeof(char)) {
+ unichar c40char = C40_BASIC_SET_CHARS[cValue];
+ if (upperShift) {
+ [result appendFormat:@"%C", (unichar)(c40char + 128)];
+ upperShift = NO;
+ } else {
+ [result appendFormat:@"%C", c40char];
+ }
+ } else {
+ return NO;
+ }
+ break;
+ case 1:
+ if (upperShift) {
+ [result appendFormat:@"%C", (unichar)(cValue + 128)];
+ upperShift = NO;
+ } else {
+ [result appendFormat:@"%C", (unichar)cValue];
+ }
+ shift = 0;
+ break;
+ case 2:
+ if (cValue < sizeof(C40_SHIFT2_SET_CHARS) / sizeof(char)) {
+ unichar c40char = C40_SHIFT2_SET_CHARS[cValue];
+ if (upperShift) {
+ [result appendFormat:@"%C", (unichar)(c40char + 128)];
+ upperShift = NO;
+ } else {
+ [result appendFormat:@"%C", c40char];
+ }
+ } else if (cValue == 27) { // FNC1
+ [result appendFormat:@"%C", (unichar)29]; // translate as ASCII 29
+ } else if (cValue == 30) { // Upper Shift
+ upperShift = YES;
+ } else {
+ return NO;
+ }
+ shift = 0;
+ break;
+ case 3:
+ if (upperShift) {
+ [result appendFormat:@"%C", (unichar)(cValue + 224)];
+ upperShift = NO;
+ } else {
+ [result appendFormat:@"%C", (unichar)(cValue + 96)];
+ }
+ shift = 0;
+ break;
+ default:
+ return NO;
+ }
+ }
+ } while (bits.available > 0);
+
+ return YES;
+}
+
+
+/**
+ * See ISO 16022:2006, 5.2.6 and Annex C, Table C.2
+ */
++ (BOOL)decodeTextSegment:(ZXBitSource *)bits result:(NSMutableString *)result {
+ // Three Text values are encoded in a 16-bit value as
+ // (1600 * C1) + (40 * C2) + C3 + 1
+ // TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time
+ BOOL upperShift = NO;
+
+ int cValues[3] = {0};
+
+ int shift = 0;
+ do {
+ // If there is only one byte left then it will be encoded as ASCII
+ if (bits.available == 8) {
+ return YES;
+ }
+ int firstByte = [bits readBits:8];
+ if (firstByte == 254) { // Unlatch codeword
+ return YES;
+ }
+
+ [self parseTwoBytes:firstByte secondByte:[bits readBits:8] result:cValues];
+
+ for (int i = 0; i < 3; i++) {
+ int cValue = cValues[i];
+ switch (shift) {
+ case 0:
+ if (cValue < 3) {
+ shift = cValue + 1;
+ } else if (cValue < sizeof(TEXT_BASIC_SET_CHARS) / sizeof(char)) {
+ unichar textChar = TEXT_BASIC_SET_CHARS[cValue];
+ if (upperShift) {
+ [result appendFormat:@"%C", (unichar)(textChar + 128)];
+ upperShift = NO;
+ } else {
+ [result appendFormat:@"%C", textChar];
+ }
+ } else {
+ return NO;
+ }
+ break;
+ case 1:
+ if (upperShift) {
+ [result appendFormat:@"%C", (unichar)(cValue + 128)];
+ upperShift = NO;
+ } else {
+ [result appendFormat:@"%C", (unichar)cValue];
+ }
+ shift = 0;
+ break;
+ case 2:
+ // Shift 2 for Text is the same encoding as C40
+ if (cValue < sizeof(C40_SHIFT2_SET_CHARS) / sizeof(char)) {
+ unichar c40char = C40_SHIFT2_SET_CHARS[cValue];
+ if (upperShift) {
+ [result appendFormat:@"%C", (unichar)(c40char + 128)];
+ upperShift = NO;
+ } else {
+ [result appendFormat:@"%C", c40char];
+ }
+ } else if (cValue == 27) {
+ [result appendFormat:@"%C", (unichar)29]; // translate as ASCII 29
+ } else if (cValue == 30) { // Upper Shift
+ upperShift = YES;
+ } else {
+ return NO;
+ }
+ shift = 0;
+ break;
+ case 3:
+ if (cValue < sizeof(TEXT_SHIFT3_SET_CHARS) / sizeof(char)) {
+ unichar textChar = TEXT_SHIFT3_SET_CHARS[cValue];
+ if (upperShift) {
+ [result appendFormat:@"%C", (unichar)(textChar + 128)];
+ upperShift = NO;
+ } else {
+ [result appendFormat:@"%C", textChar];
+ }
+ shift = 0;
+ } else {
+ return NO;
+ }
+ break;
+ default:
+ return NO;
+ }
+ }
+ } while (bits.available > 0);
+ return YES;
+}
+
+
+/**
+ * See ISO 16022:2006, 5.2.7
+ */
++ (BOOL)decodeAnsiX12Segment:(ZXBitSource *)bits result:(NSMutableString *)result {
+ // Three ANSI X12 values are encoded in a 16-bit value as
+ // (1600 * C1) + (40 * C2) + C3 + 1
+
+ int cValues[3] = {0};
+ do {
+ // If there is only one byte left then it will be encoded as ASCII
+ if (bits.available == 8) {
+ return YES;
+ }
+ int firstByte = [bits readBits:8];
+ if (firstByte == 254) { // Unlatch codeword
+ return YES;
+ }
+
+ [self parseTwoBytes:firstByte secondByte:[bits readBits:8] result:cValues];
+
+ for (int i = 0; i < 3; i++) {
+ int cValue = cValues[i];
+ if (cValue == 0) { // X12 segment terminator <CR>
+ [result appendString:@"\r"];
+ } else if (cValue == 1) { // X12 segment separator *
+ [result appendString:@"*"];
+ } else if (cValue == 2) { // X12 sub-element separator >
+ [result appendString:@">"];
+ } else if (cValue == 3) { // space
+ [result appendString:@" "];
+ } else if (cValue < 14) { // 0 - 9
+ [result appendFormat:@"%C", (unichar)(cValue + 44)];
+ } else if (cValue < 40) { // A - Z
+ [result appendFormat:@"%C", (unichar)(cValue + 51)];
+ } else {
+ return NO;
+ }
+ }
+ } while (bits.available > 0);
+ return YES;
+}
+
++ (void)parseTwoBytes:(int)firstByte secondByte:(int)secondByte result:(int[])result {
+ int fullBitValue = (firstByte << 8) + secondByte - 1;
+ int temp = fullBitValue / 1600;
+ result[0] = temp;
+ fullBitValue -= temp * 1600;
+ temp = fullBitValue / 40;
+ result[1] = temp;
+ result[2] = fullBitValue - temp * 40;
+}
+
+
+/**
+ * See ISO 16022:2006, 5.2.8 and Annex C Table C.3
+ */
++ (void)decodeEdifactSegment:(ZXBitSource *)bits result:(NSMutableString *)result {
+ do {
+ // If there is only two or less bytes left then it will be encoded as ASCII
+ if (bits.available <= 16) {
+ return;
+ }
+
+ for (int i = 0; i < 4; i++) {
+ int edifactValue = [bits readBits:6];
+
+ // Check for the unlatch character
+ if (edifactValue == 0x1F) { // 011111
+ // Read rest of byte, which should be 0, and stop
+ int bitsLeft = 8 - bits.bitOffset;
+ if (bitsLeft != 8) {
+ [bits readBits:bitsLeft];
+ }
+ return;
+ }
+
+ if ((edifactValue & 0x20) == 0) { // no 1 in the leading (6th) bit
+ edifactValue |= 0x40; // Add a leading 01 to the 6 bit binary value
+ }
+ [result appendFormat:@"%c", (char)edifactValue];
+ }
+ } while (bits.available > 0);
+}
+
+
+/**
+ * See ISO 16022:2006, 5.2.9 and Annex B, B.2
+ */
++ (BOOL)decodeBase256Segment:(ZXBitSource *)bits result:(NSMutableString *)result byteSegments:(NSMutableArray *)byteSegments {
+ int codewordPosition = 1 + bits.byteOffset; // position is 1-indexed
+ int d1 = [self unrandomize255State:[bits readBits:8] base256CodewordPosition:codewordPosition++];
+ int count;
+ if (d1 == 0) {
+ count = [bits available] / 8;
+ } else if (d1 < 250) {
+ count = d1;
+ } else {
+ count = 250 * (d1 - 249) + [self unrandomize255State:[bits readBits:8] base256CodewordPosition:codewordPosition++];
+ }
+
+ if (count < 0) {
+ return NO;
+ }
+
+ NSMutableArray *bytesArray = [NSMutableArray arrayWithCapacity:count];
+ int8_t bytes[count];
+ for (int i = 0; i < count; i++) {
+ if ([bits available] < 8) {
+ return NO;
+ }
+ int8_t byte = (int8_t)[self unrandomize255State:[bits readBits:8] base256CodewordPosition:codewordPosition++];
+ bytes[i] = byte;
+ [bytesArray addObject:[NSNumber numberWithChar:byte]];
+ }
+ [byteSegments addObject:bytesArray];
+
+ [result appendString:[[NSString alloc] initWithBytes:bytes length:count encoding:NSISOLatin1StringEncoding]];
+ return YES;
+}
+
+
+/**
+ * See ISO 16022:2006, Annex B, B.2
+ */
++ (int)unrandomize255State:(int)randomizedBase256Codeword base256CodewordPosition:(int)base256CodewordPosition {
+ int pseudoRandomNumber = ((149 * base256CodewordPosition) % 255) + 1;
+ int tempVariable = randomizedBase256Codeword - pseudoRandomNumber;
+ return tempVariable >= 0 ? tempVariable : tempVariable + 256;
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.h b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.h
new file mode 100644
index 0000000..03506ae
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * The main class which implements Data Matrix Code decoding -- as opposed to locating and extracting
+ * the Data Matrix Code from an image.
+ */
+
+@class ZXBitMatrix, ZXDecoderResult, ZXReedSolomonDecoder;
+
+@interface ZXDataMatrixDecoder : NSObject
+
+- (ZXDecoderResult *)decode:(BOOL **)image length:(unsigned int)length error:(NSError **)error;
+- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.m b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.m
new file mode 100644
index 0000000..093d6c9
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.m
@@ -0,0 +1,135 @@
+/*
+ * 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 "ZXDataMatrixBitMatrixParser.h"
+#import "ZXDataMatrixDataBlock.h"
+#import "ZXDataMatrixDecodedBitStreamParser.h"
+#import "ZXDataMatrixDecoder.h"
+#import "ZXDataMatrixVersion.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXGenericGF.h"
+#import "ZXReedSolomonDecoder.h"
+
+@interface ZXDataMatrixDecoder ()
+
+@property (nonatomic, strong) ZXReedSolomonDecoder *rsDecoder;
+
+@end
+
+@implementation ZXDataMatrixDecoder
+
+- (id)init {
+ if (self = [super init]) {
+ _rsDecoder = [[ZXReedSolomonDecoder alloc] initWithField:[ZXGenericGF DataMatrixField256]];
+ }
+
+ return self;
+}
+
+/**
+ * Convenience method that can decode a Data Matrix Code represented as a 2D array of booleans.
+ * "true" is taken to mean a black module.
+ */
+- (ZXDecoderResult *)decode:(BOOL **)image length:(unsigned int)length error:(NSError **)error {
+ int dimension = length;
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithDimension:dimension];
+ for (int i = 0; i < dimension; i++) {
+ for (int j = 0; j < dimension; j++) {
+ if (image[i][j]) {
+ [bits setX:j y:i];
+ }
+ }
+ }
+
+ return [self decodeMatrix:bits error:error];
+}
+
+
+/**
+ * Decodes a Data Matrix Code represented as a BitMatrix. A 1 or "true" is taken
+ * to mean a black module.
+ */
+- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits error:(NSError **)error {
+ ZXDataMatrixBitMatrixParser *parser = [[ZXDataMatrixBitMatrixParser alloc] initWithBitMatrix:bits error:error];
+ if (!parser) {
+ return nil;
+ }
+ ZXDataMatrixVersion *version = [parser version];
+
+ NSArray *codewords = [parser readCodewords];
+ NSArray *dataBlocks = [ZXDataMatrixDataBlock dataBlocks:codewords version:version];
+
+ NSUInteger dataBlocksCount = [dataBlocks count];
+
+ int totalBytes = 0;
+ for (int i = 0; i < dataBlocksCount; i++) {
+ totalBytes += [dataBlocks[i] numDataCodewords];
+ }
+
+ if (totalBytes == 0) {
+ return nil;
+ }
+
+ int8_t resultBytes[totalBytes];
+
+ for (int j = 0; j < dataBlocksCount; j++) {
+ ZXDataMatrixDataBlock *dataBlock = dataBlocks[j];
+ NSMutableArray *codewordBytes = dataBlock.codewords;
+ int numDataCodewords = [dataBlock numDataCodewords];
+ if (![self correctErrors:codewordBytes numDataCodewords:numDataCodewords error:error]) {
+ return nil;
+ }
+ for (int i = 0; i < numDataCodewords; i++) {
+ resultBytes[i * dataBlocksCount + j] = [codewordBytes[i] charValue];
+ }
+ }
+
+ return [ZXDataMatrixDecodedBitStreamParser decode:resultBytes length:totalBytes error:error];
+}
+
+
+/**
+ * Given data and error-correction codewords received, possibly corrupted by errors, attempts to
+ * correct the errors in-place using Reed-Solomon error correction.
+ */
+- (BOOL)correctErrors:(NSMutableArray *)codewordBytes numDataCodewords:(int)numDataCodewords error:(NSError **)error {
+ int numCodewords = (int)[codewordBytes count];
+ int codewordsInts[numCodewords];
+ for (int i = 0; i < numCodewords; i++) {
+ codewordsInts[i] = [codewordBytes[i] charValue] & 0xFF;
+ }
+ int numECCodewords = (int)[codewordBytes count] - numDataCodewords;
+
+ NSError *decodeError = nil;
+ if (![self.rsDecoder decode:codewordsInts receivedLen:numCodewords twoS:numECCodewords error:&decodeError]) {
+ if (decodeError.code == ZXReedSolomonError) {
+ if (error) *error = ChecksumErrorInstance();
+ return NO;
+ } else {
+ if (error) *error = decodeError;
+ return NO;
+ }
+ }
+
+ for (int i = 0; i < numDataCodewords; i++) {
+ codewordBytes[i] = [NSNumber numberWithChar:codewordsInts[i]];
+ }
+ return YES;
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h b/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h
new file mode 100644
index 0000000..c7b4df5
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+/**
+ * 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
+ * each set of blocks. It also holds the number of error-correction codewords per block since it
+ * will be the same across all blocks within one version.
+ */
+
+@interface ZXDataMatrixECBlocks : NSObject
+
+@property (nonatomic, strong, readonly) NSArray *ecBlocks;
+@property (nonatomic, assign, readonly) int ecCodewords;
+
+@end
+
+/**
+ * Encapsualtes the parameters for one error-correction block in one symbol version.
+ * This includes the number of data codewords, and the number of times a block with these
+ * parameters is used consecutively in the Data Matrix code version's format.
+ */
+
+@interface ZXDataMatrixECB : NSObject
+
+@property (nonatomic, assign, readonly) int count;
+@property (nonatomic, assign, readonly) int dataCodewords;
+
+@end
+
+/**
+ * The Version object encapsulates attributes about a particular
+ * size Data Matrix Code.
+ */
+
+@interface ZXDataMatrixVersion : NSObject
+
+@property (nonatomic, strong, readonly) ZXDataMatrixECBlocks *ecBlocks;
+@property (nonatomic, assign, readonly) int dataRegionSizeColumns;
+@property (nonatomic, assign, readonly) int dataRegionSizeRows;
+@property (nonatomic, assign, readonly) int symbolSizeColumns;
+@property (nonatomic, assign, readonly) int symbolSizeRows;
+@property (nonatomic, assign, readonly) int totalCodewords;
+@property (nonatomic, assign, readonly) int versionNumber;
+
++ (ZXDataMatrixVersion *)versionForDimensions:(int)numRows numColumns:(int)numColumns;
+
+@end
diff --git a/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.m b/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.m
new file mode 100644
index 0000000..4d5fef8
--- /dev/null
+++ b/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.m
@@ -0,0 +1,350 @@
+/*
+ * 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 "ZXDataMatrixVersion.h"
+
+@implementation ZXDataMatrixECBlocks
+
+- (id)initWithCodewords:(int)ecCodewords ecBlocks:(ZXDataMatrixECB *)ecBlocks {
+ if (self = [super init]) {
+ _ecCodewords = ecCodewords;
+ _ecBlocks = @[ecBlocks];
+ }
+
+ return self;
+}
+
+- (id)initWithCodewords:(int)ecCodewords ecBlocks1:(ZXDataMatrixECB *)ecBlocks1 ecBlocks2:(ZXDataMatrixECB *)ecBlocks2 {
+ if (self = [super init]) {
+ _ecCodewords = ecCodewords;
+ _ecBlocks = @[ecBlocks1, ecBlocks2];
+ }
+
+ return self;
+}
+
+@end
+
+
+@implementation ZXDataMatrixECB
+
+- (id)initWithCount:(int)count dataCodewords:(int)dataCodewords {
+ if (self = [super init]) {
+ _count = count;
+ _dataCodewords = dataCodewords;
+ }
+
+ return self;
+}
+
+@end
+
+
+static NSArray *VERSIONS = nil;
+
+@implementation ZXDataMatrixVersion
+
+- (id)initWithVersionNumber:(int)versionNumber symbolSizeRows:(int)symbolSizeRows symbolSizeColumns:(int)symbolSizeColumns
+ dataRegionSizeRows:(int)dataRegionSizeRows dataRegionSizeColumns:(int)dataRegionSizeColumns ecBlocks:(ZXDataMatrixECBlocks *)ecBlocks {
+ if (self = [super init]) {
+ _versionNumber = versionNumber;
+ _symbolSizeRows = symbolSizeRows;
+ _symbolSizeColumns = symbolSizeColumns;
+ _dataRegionSizeRows = dataRegionSizeRows;
+ _dataRegionSizeColumns = dataRegionSizeColumns;
+ _ecBlocks = ecBlocks;
+
+ int total = 0;
+ int ecCodewords = ecBlocks.ecCodewords;
+ NSArray *ecbArray = ecBlocks.ecBlocks;
+ for (ZXDataMatrixECB *ecBlock in ecbArray) {
+ total += ecBlock.count * (ecBlock.dataCodewords + ecCodewords);
+ }
+ _totalCodewords = total;
+ }
+
+ return self;
+}
+
+/**
+ * Deduces version information from Data Matrix dimensions.
+ */
++ (ZXDataMatrixVersion *)versionForDimensions:(int)numRows numColumns:(int)numColumns {
+ if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {
+ return nil;
+ }
+
+ for (ZXDataMatrixVersion *version in VERSIONS) {
+ if (version.symbolSizeRows == numRows && version.symbolSizeColumns == numColumns) {
+ return version;
+ }
+ }
+
+ return nil;
+}
+
+- (NSString *)description {
+ return [@(self.versionNumber) stringValue];
+}
+
+
+/**
+ * See ISO 16022:2006 5.5.1 Table 7
+ */
++ (void)initialize {
+ VERSIONS = @[[[ZXDataMatrixVersion alloc] initWithVersionNumber:1
+ symbolSizeRows:10
+ symbolSizeColumns:10
+ dataRegionSizeRows:8
+ dataRegionSizeColumns:8
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:5
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:3]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:2
+ symbolSizeRows:12
+ symbolSizeColumns:12
+ dataRegionSizeRows:10
+ dataRegionSizeColumns:10
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:7
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:5]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:3
+ symbolSizeRows:14
+ symbolSizeColumns:14
+ dataRegionSizeRows:12
+ dataRegionSizeColumns:12
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:10
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:8]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:4
+ symbolSizeRows:16
+ symbolSizeColumns:16
+ dataRegionSizeRows:14
+ dataRegionSizeColumns:14
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:12
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:12]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:5
+ symbolSizeRows:18
+ symbolSizeColumns:18
+ dataRegionSizeRows:16
+ dataRegionSizeColumns:16
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:14
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:18]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:6
+ symbolSizeRows:20
+ symbolSizeColumns:20
+ dataRegionSizeRows:18
+ dataRegionSizeColumns:18
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:18
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:22]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:7
+ symbolSizeRows:22
+ symbolSizeColumns:22
+ dataRegionSizeRows:20
+ dataRegionSizeColumns:20
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:20
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:30]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:8
+ symbolSizeRows:24
+ symbolSizeColumns:24
+ dataRegionSizeRows:22
+ dataRegionSizeColumns:22
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:24
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:36]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:9
+ symbolSizeRows:26
+ symbolSizeColumns:26
+ dataRegionSizeRows:24
+ dataRegionSizeColumns:24
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:28
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:44]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:10
+ symbolSizeRows:32
+ symbolSizeColumns:32
+ dataRegionSizeRows:14
+ dataRegionSizeColumns:14
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:36
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:62]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:11
+ symbolSizeRows:36
+ symbolSizeColumns:36
+ dataRegionSizeRows:16
+ dataRegionSizeColumns:16
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:42
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:86]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:12
+ symbolSizeRows:40
+ symbolSizeColumns:40
+ dataRegionSizeRows:18
+ dataRegionSizeColumns:18
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:48
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:114]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:13
+ symbolSizeRows:44
+ symbolSizeColumns:44
+ dataRegionSizeRows:20
+ dataRegionSizeColumns:20
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:56
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:144]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:14
+ symbolSizeRows:48
+ symbolSizeColumns:48
+ dataRegionSizeRows:22
+ dataRegionSizeColumns:22
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:68
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:174]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:15
+ symbolSizeRows:52
+ symbolSizeColumns:52
+ dataRegionSizeRows:24
+ dataRegionSizeColumns:24
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:42
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:2 dataCodewords:102]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:16
+ symbolSizeRows:64
+ symbolSizeColumns:64
+ dataRegionSizeRows:14
+ dataRegionSizeColumns:14
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:56
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:2 dataCodewords:140]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:17
+ symbolSizeRows:72
+ symbolSizeColumns:72
+ dataRegionSizeRows:16
+ dataRegionSizeColumns:16
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:36
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:4 dataCodewords:92]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:18
+ symbolSizeRows:80
+ symbolSizeColumns:80
+ dataRegionSizeRows:18
+ dataRegionSizeColumns:18
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:48
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:4 dataCodewords:114]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:19
+ symbolSizeRows:88
+ symbolSizeColumns:88
+ dataRegionSizeRows:20
+ dataRegionSizeColumns:20
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:56
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:4 dataCodewords:144]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:20
+ symbolSizeRows:96
+ symbolSizeColumns:96
+ dataRegionSizeRows:22
+ dataRegionSizeColumns:22
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:68
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:4 dataCodewords:174]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:21
+ symbolSizeRows:104
+ symbolSizeColumns:104
+ dataRegionSizeRows:24
+ dataRegionSizeColumns:24
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:56
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:6 dataCodewords:136]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:22
+ symbolSizeRows:120
+ symbolSizeColumns:120
+ dataRegionSizeRows:18
+ dataRegionSizeColumns:18
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:68
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:6 dataCodewords:175]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:23
+ symbolSizeRows:132
+ symbolSizeColumns:132
+ dataRegionSizeRows:20
+ dataRegionSizeColumns:20
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:62
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:8 dataCodewords:163]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:24
+ symbolSizeRows:144
+ symbolSizeColumns:144
+ dataRegionSizeRows:22
+ dataRegionSizeColumns:22
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:62
+ ecBlocks1:[[ZXDataMatrixECB alloc] initWithCount:8 dataCodewords:156]
+ ecBlocks2:[[ZXDataMatrixECB alloc] initWithCount:2 dataCodewords:155]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:25
+ symbolSizeRows:8
+ symbolSizeColumns:18
+ dataRegionSizeRows:6
+ dataRegionSizeColumns:16
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:7
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:5]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:26
+ symbolSizeRows:8
+ symbolSizeColumns:32
+ dataRegionSizeRows:6
+ dataRegionSizeColumns:14
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:11
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:10]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:27
+ symbolSizeRows:12
+ symbolSizeColumns:26
+ dataRegionSizeRows:10
+ dataRegionSizeColumns:24
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:14
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:16]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:28
+ symbolSizeRows:12
+ symbolSizeColumns:36
+ dataRegionSizeRows:10
+ dataRegionSizeColumns:16
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:18
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:22]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:29
+ symbolSizeRows:16
+ symbolSizeColumns:36
+ dataRegionSizeRows:14
+ dataRegionSizeColumns:16
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:24
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:32]]],
+
+ [[ZXDataMatrixVersion alloc] initWithVersionNumber:30
+ symbolSizeRows:16
+ symbolSizeColumns:48
+ dataRegionSizeRows:14
+ dataRegionSizeColumns:22
+ ecBlocks:[[ZXDataMatrixECBlocks alloc] initWithCodewords:28
+ ecBlocks:[[ZXDataMatrixECB alloc] initWithCount:1 dataCodewords:49]]]];
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.h b/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.h
new file mode 100644
index 0000000..de5f4a2
--- /dev/null
+++ b/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates logic that can detect a Data Matrix Code in an image, even if the Data Matrix Code
+ * is rotated or skewed, or partially obscured.
+ */
+
+@class ZXBitMatrix, ZXDetectorResult, ZXWhiteRectangleDetector;
+
+@interface ZXDataMatrixDetector : NSObject
+
+- (id)initWithImage:(ZXBitMatrix *)image error:(NSError **)error;
+- (ZXDetectorResult *)detectWithError:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m b/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m
new file mode 100644
index 0000000..3db1725
--- /dev/null
+++ b/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m
@@ -0,0 +1,367 @@
+/*
+ * 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 "ZXDataMatrixDetector.h"
+#import "ZXDetectorResult.h"
+#import "ZXErrors.h"
+#import "ZXGridSampler.h"
+#import "ZXMathUtils.h"
+#import "ZXResultPoint.h"
+#import "ZXWhiteRectangleDetector.h"
+
+/**
+ * Simply encapsulates two points and a number of transitions between them.
+ */
+
+@interface ResultPointsAndTransitions : NSObject
+
+@property (nonatomic, strong) ZXResultPoint *from;
+@property (nonatomic, strong) ZXResultPoint *to;
+@property (nonatomic, assign) int transitions;
+
+@end
+
+@implementation ResultPointsAndTransitions
+
+- (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:(ResultPointsAndTransitions *)otherObject {
+ return [@(self.transitions) compare:@(otherObject.transitions)];
+}
+
+@end
+
+
+@interface ZXDataMatrixDetector ()
+
+@property (nonatomic, strong) ZXBitMatrix *image;
+@property (nonatomic, strong) ZXWhiteRectangleDetector *rectangleDetector;
+
+@end
+
+@implementation ZXDataMatrixDetector
+
+- (id)initWithImage:(ZXBitMatrix *)image error:(NSError **)error {
+ if (self = [super init]) {
+ _image = image;
+ _rectangleDetector = [[ZXWhiteRectangleDetector alloc] initWithImage:_image error:error];
+ if (!_rectangleDetector) {
+ return nil;
+ }
+ }
+
+ return self;
+}
+
+/**
+ * Detects a Data Matrix Code in an image.
+ */
+- (ZXDetectorResult *)detectWithError:(NSError **)error {
+ NSArray *cornerPoints = [self.rectangleDetector detectWithError: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:)];
+
+ ResultPointsAndTransitions *lSideOne = (ResultPointsAndTransitions *)transitions[0];
+ ResultPointsAndTransitions *lSideTwo = (ResultPointsAndTransitions *)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 = NotFoundErrorInstance();
+ return nil;
+ }
+
+ NSMutableArray *corners = [NSMutableArray arrayWithObjects:maybeTopLeft, bottomLeft, maybeBottomRight, nil];
+ [ZXResultPoint orderBestPatterns:corners];
+
+ 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];
+
+ if ((dimensionTop & 0x01) == 1) {
+ dimensionTop++;
+ }
+ dimensionTop += 2;
+
+ if ((dimensionRight & 0x01) == 1) {
+ dimensionRight++;
+ }
+ dimensionRight += 2;
+
+ ZXBitMatrix *bits;
+ ZXResultPoint *correctedTopRight;
+
+ 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;
+ }
+
+ dimensionTop = [[self transitionsBetween:topLeft to:correctedTopRight] transitions];
+ dimensionRight = [[self transitionsBetween:bottomRight to:correctedTopRight] transitions];
+
+ if ((dimensionTop & 0x01) == 1) {
+ dimensionTop++;
+ }
+
+ if ((dimensionRight & 0x01) == 1) {
+ dimensionRight++;
+ }
+
+ bits = [self sampleGrid:self.image topLeft:topLeft bottomLeft:bottomLeft bottomRight:bottomRight topRight:correctedTopRight dimensionX:dimensionTop dimensionY:dimensionRight error:error];
+ if (!bits) {
+ return nil;
+ }
+ } 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++;
+ }
+
+ bits = [self sampleGrid:self.image topLeft:topLeft bottomLeft:bottomLeft bottomRight:bottomRight topRight:correctedTopRight dimensionX:dimensionCorrected dimensionY:dimensionCorrected error:error];
+ if (!bits) {
+ return nil;
+ }
+ }
+ return [[ZXDetectorResult alloc] initWithBits:bits points:@[topLeft, bottomLeft, bottomRight, correctedTopRight]];
+}
+
+
+/**
+ * Calculates the position of the white top right module using the output of the rectangle detector
+ * for a rectangular matrix
+ */
+- (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;
+ }
+
+ 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;
+ }
+
+ return c2;
+}
+
+
+/**
+ * Calculates the position of the white top right module using the output of the rectangle detector
+ * for a square matrix
+ */
+- (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;
+
+ 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;
+ }
+
+ 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]);
+
+ return l1 <= l2 ? c1 : c2;
+}
+
+- (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.
+ */
+- (void)increment:(NSMutableDictionary *)table key:(ZXResultPoint *)key {
+ NSNumber *value = table[key];
+ table[key] = value == nil ? @1 : @([value intValue] + 1);
+}
+
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)image
+ topLeft:(ZXResultPoint *)topLeft
+ bottomLeft:(ZXResultPoint *)bottomLeft
+ bottomRight:(ZXResultPoint *)bottomRight
+ topRight:(ZXResultPoint *)topRight
+ dimensionX:(int)dimensionX
+ dimensionY:(int)dimensionY
+ error:(NSError **)error {
+ ZXGridSampler *sampler = [ZXGridSampler instance];
+ return [sampler sampleGrid:image
+ dimensionX:dimensionX dimensionY:dimensionY
+ p1ToX:0.5f p1ToY:0.5f
+ p2ToX:dimensionX - 0.5f p2ToY:0.5f
+ p3ToX:dimensionX - 0.5f p3ToY:dimensionY - 0.5f
+ p4ToX:0.5f p4ToY:dimensionY - 0.5f
+ p1FromX:[topLeft x] p1FromY:[topLeft y]
+ p2FromX:[topRight x] p2FromY:[topRight y]
+ p3FromX:[bottomRight x] p3FromY:[bottomRight y]
+ p4FromX:[bottomLeft x] p4FromY:[bottomLeft y]
+ error:error];
+}
+
+
+/**
+ * Counts the number of black/white transitions between two points, using something like Bresenham's algorithm.
+ */
+- (ResultPointsAndTransitions *)transitionsBetween:(ZXResultPoint *)from to:(ZXResultPoint *)to {
+ int fromX = (int)[from x];
+ int fromY = (int)[from y];
+ int toX = (int)[to x];
+ int toY = (int)[to y];
+ BOOL steep = abs(toY - fromY) > abs(toX - fromX);
+ if (steep) {
+ int temp = fromX;
+ fromX = fromY;
+ fromY = temp;
+ temp = toX;
+ toX = toY;
+ toY = temp;
+ }
+
+ int dx = abs(toX - fromX);
+ int dy = abs(toY - fromY);
+ int error = -dx >> 1;
+ int ystep = fromY < toY ? 1 : -1;
+ int xstep = fromX < toX ? 1 : -1;
+ int transitions = 0;
+ BOOL inBlack = [self.image getX:steep ? fromY : fromX y:steep ? fromX : fromY];
+ for (int x = fromX, y = fromY; x != toX; x += xstep) {
+ BOOL isBlack = [self.image getX:steep ? y : x y:steep ? x : y];
+ if (isBlack != inBlack) {
+ transitions++;
+ inBlack = isBlack;
+ }
+ error += dy;
+ if (error > 0) {
+ if (y == toY) {
+ break;
+ }
+ y += ystep;
+ error -= dx;
+ }
+ }
+ return [[ResultPointsAndTransitions alloc] initWithFrom:from to:to transitions:transitions];
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXASCIIEncoder.h b/ZXingObjC/datamatrix/encoder/ZXASCIIEncoder.h
new file mode 100644
index 0000000..c8e2b12
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXASCIIEncoder.h
@@ -0,0 +1,21 @@
+/*
+ * 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 "ZXDataMatrixEncoder.h"
+
+@interface ZXASCIIEncoder : NSObject <ZXDataMatrixEncoder>
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXASCIIEncoder.m b/ZXingObjC/datamatrix/encoder/ZXASCIIEncoder.m
new file mode 100644
index 0000000..2f82d68
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXASCIIEncoder.m
@@ -0,0 +1,79 @@
+/*
+ * 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 "ZXASCIIEncoder.h"
+#import "ZXEncoderContext.h"
+#import "ZXHighLevelEncoder.h"
+
+@implementation ZXASCIIEncoder
+
+- (int)encodingMode {
+ return [ZXHighLevelEncoder asciiEncodation];
+}
+
+- (void)encode:(ZXEncoderContext *)context {
+ //step B
+ int n = [ZXHighLevelEncoder determineConsecutiveDigitCount:context.message startpos:context.pos];
+ if (n >= 2) {
+ [context writeCodeword:[self encodeASCIIDigits:[context.message characterAtIndex:context.pos]
+ digit2:[context.message characterAtIndex:context.pos + 1]]];
+ context.pos += 2;
+ } else {
+ unichar c = [context currentChar];
+ int newMode = [ZXHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]];
+ if (newMode != [self encodingMode]) {
+ if (newMode == [ZXHighLevelEncoder base256Encodation]) {
+ [context writeCodeword:[ZXHighLevelEncoder latchToBase256]];
+ [context signalEncoderChange:[ZXHighLevelEncoder base256Encodation]];
+ return;
+ } else if (newMode == [ZXHighLevelEncoder c40Encodation]) {
+ [context writeCodeword:[ZXHighLevelEncoder latchToC40]];
+ [context signalEncoderChange:[ZXHighLevelEncoder c40Encodation]];
+ return;
+ } else if (newMode == [ZXHighLevelEncoder x12Encodation]) {
+ [context writeCodeword:[ZXHighLevelEncoder latchToAnsiX12]];
+ [context signalEncoderChange:[ZXHighLevelEncoder x12Encodation]];
+ } else if (newMode == [ZXHighLevelEncoder textEncodation]) {
+ [context writeCodeword:[ZXHighLevelEncoder latchToText]];
+ [context signalEncoderChange:[ZXHighLevelEncoder textEncodation]];
+ } else if (newMode == [ZXHighLevelEncoder edifactEncodation]) {
+ [context writeCodeword:[ZXHighLevelEncoder latchToEdifact]];
+ [context signalEncoderChange:[ZXHighLevelEncoder edifactEncodation]];
+ } else {
+ @throw [NSException exceptionWithName:@"IllegalStateException" reason:@"Illegal mode" userInfo:nil];
+ }
+ } else if ([ZXHighLevelEncoder isExtendedASCII:c]) {
+ [context writeCodeword:[ZXHighLevelEncoder upperShift]];
+ [context writeCodeword:(unichar)(c - 128 + 1)];
+ context.pos++;
+ } else {
+ [context writeCodeword:(unichar)(c + 1)];
+ context.pos++;
+ }
+ }
+}
+
+- (unichar)encodeASCIIDigits:(unichar)digit1 digit2:(unichar)digit2 {
+ if ([ZXHighLevelEncoder isDigit:digit1] && [ZXHighLevelEncoder isDigit:digit2]) {
+ int num = (digit1 - 48) * 10 + (digit2 - 48);
+ return (unichar) (num + 130);
+ }
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"not digits: %C %C", digit1, digit2]
+ userInfo:nil];
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXBase256Encoder.h b/ZXingObjC/datamatrix/encoder/ZXBase256Encoder.h
new file mode 100644
index 0000000..7142266
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXBase256Encoder.h
@@ -0,0 +1,21 @@
+/*
+ * 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 "ZXDataMatrixEncoder.h"
+
+@interface ZXBase256Encoder : NSObject <ZXDataMatrixEncoder>
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXBase256Encoder.m b/ZXingObjC/datamatrix/encoder/ZXBase256Encoder.m
new file mode 100644
index 0000000..8d2c4c8
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXBase256Encoder.m
@@ -0,0 +1,78 @@
+/*
+ * 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 "ZXBase256Encoder.h"
+#import "ZXEncoderContext.h"
+#import "ZXHighLevelEncoder.h"
+#import "ZXSymbolInfo.h"
+
+@implementation ZXBase256Encoder
+
+- (int)encodingMode {
+ return [ZXHighLevelEncoder base256Encodation];
+}
+
+- (void)encode:(ZXEncoderContext *)context {
+ NSMutableString *buffer = [NSMutableString string];
+ [buffer appendString:@"\0"]; //Initialize length field
+ while ([context hasMoreCharacters]) {
+ unichar c = [context currentChar];
+ [buffer appendFormat:@"%C", c];
+
+ context.pos++;
+
+ int newMode = [ZXHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]];
+ if (newMode != [self encodingMode]) {
+ [context signalEncoderChange:newMode];
+ break;
+ }
+ }
+ int dataCount = (int)buffer.length - 1;
+ int lengthFieldSize = 1;
+ int currentSize = [context codewordCount] + dataCount + lengthFieldSize;
+ [context updateSymbolInfoWithLength:currentSize];
+ BOOL mustPad = (context.symbolInfo.dataCapacity - currentSize) > 0;
+ if ([context hasMoreCharacters] || mustPad) {
+ if (dataCount <= 249) {
+ [buffer replaceCharactersInRange:NSMakeRange(0, 1)
+ withString:[NSString stringWithFormat:@"%C", (unichar) dataCount]];
+ } else if (dataCount > 249 && dataCount <= 1555) {
+ [buffer replaceCharactersInRange:NSMakeRange(0, 1)
+ withString:[NSString stringWithFormat:@"%C", (unichar) ((dataCount / 250) + 249)]];
+ [buffer insertString:[NSString stringWithFormat:@"%C", (unichar) (dataCount % 250)]
+ atIndex:1];
+ } else {
+ @throw [NSException exceptionWithName:@"IllegalStateException"
+ reason:[NSString stringWithFormat:@"Message length not in valid ranges: %d", dataCount]
+ userInfo:nil];
+ }
+ }
+ for (int i = 0, c = (int)buffer.length; i < c; i++) {
+ [context writeCodeword:[self randomize255State:[buffer characterAtIndex:i] codewordPosition:context.codewordCount + 1]];
+ }
+}
+
+- (unichar)randomize255State:(unichar)ch codewordPosition:(int)codewordPosition {
+ int pseudoRandom = ((149 * codewordPosition) % 255) + 1;
+ int tempVariable = ch + pseudoRandom;
+ if (tempVariable <= 255) {
+ return (unichar) tempVariable;
+ } else {
+ return (unichar) (tempVariable - 256);
+ }
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXC40Encoder.h b/ZXingObjC/datamatrix/encoder/ZXC40Encoder.h
new file mode 100644
index 0000000..40cca60
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXC40Encoder.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXDataMatrixEncoder.h"
+
+@interface ZXC40Encoder : NSObject <ZXDataMatrixEncoder>
+
+- (int)encodeChar:(unichar)c buffer:(NSMutableString *)sb;
+- (void)writeNextTriplet:(ZXEncoderContext *)context buffer:(NSMutableString *)buffer;
+- (void)handleEOD:(ZXEncoderContext *)context buffer:(NSMutableString *)buffer;
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXC40Encoder.m b/ZXingObjC/datamatrix/encoder/ZXC40Encoder.m
new file mode 100644
index 0000000..818bfe8
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXC40Encoder.m
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2013 9 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 "ZXC40Encoder.h"
+#import "ZXEncoderContext.h"
+#import "ZXHighLevelEncoder.h"
+#import "ZXSymbolInfo.h"
+
+@implementation ZXC40Encoder
+
+- (int)encodingMode {
+ return [ZXHighLevelEncoder c40Encodation];
+}
+
+- (void)encode:(ZXEncoderContext *)context {
+ //step C
+ NSMutableString *buffer = [NSMutableString string];
+ while ([context hasMoreCharacters]) {
+ unichar c = [context currentChar];
+ context.pos++;
+
+ int lastCharSize = [self encodeChar:c buffer:buffer];
+
+ int unwritten = ((int)buffer.length / 3) * 2;
+
+ int curCodewordCount = context.codewordCount + unwritten;
+ [context updateSymbolInfoWithLength:curCodewordCount];
+ int available = context.symbolInfo.dataCapacity - curCodewordCount;
+
+ if (![context hasMoreCharacters]) {
+ //Avoid having a single C40 value in the last triplet
+ NSMutableString *removed = [NSMutableString string];
+ if ((buffer.length % 3) == 2) {
+ if (available < 2 || available > 2) {
+ lastCharSize = [self backtrackOneCharacter:context buffer:buffer removed:removed lastCharSize:lastCharSize];
+ }
+ }
+ while ((buffer.length % 3) == 1
+ && ((lastCharSize <= 3 && available != 1) || lastCharSize > 3)) {
+ lastCharSize = [self backtrackOneCharacter:context buffer:buffer removed:removed lastCharSize:lastCharSize];
+ }
+ break;
+ }
+
+ NSUInteger count = buffer.length;
+ if ((count % 3) == 0) {
+ int newMode = [ZXHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]];
+ if (newMode != [self encodingMode]) {
+ [context signalEncoderChange:newMode];
+ break;
+ }
+ }
+ }
+ [self handleEOD:context buffer:buffer];
+}
+
+- (int)backtrackOneCharacter:(ZXEncoderContext *)context buffer:(NSMutableString *)buffer
+ removed:(NSMutableString *)removed lastCharSize:(int)lastCharSize {
+ NSUInteger count = buffer.length;
+ [buffer deleteCharactersInRange:NSMakeRange(count - lastCharSize, lastCharSize)];
+ context.pos--;
+ unichar c = context.currentChar;
+ lastCharSize = [self encodeChar:c buffer:removed];
+ [context resetSymbolInfo]; //Deal with possible reduction in symbol size
+ return lastCharSize;
+}
+
+- (void)writeNextTriplet:(ZXEncoderContext *)context buffer:(NSMutableString *)buffer {
+ [context writeCodewords:[self encodeToCodewords:buffer startpos:0]];
+ [buffer deleteCharactersInRange:NSMakeRange(0, 3)];
+}
+
+/**
+ * Handle "end of data" situations
+ */
+- (void)handleEOD:(ZXEncoderContext *)context buffer:(NSMutableString *)buffer {
+ int unwritten = ((int)buffer.length / 3) * 2;
+ int rest = buffer.length % 3;
+
+ int curCodewordCount = context.codewordCount + unwritten;
+ [context updateSymbolInfoWithLength:curCodewordCount];
+ int available = context.symbolInfo.dataCapacity - curCodewordCount;
+
+ if (rest == 2) {
+ [buffer appendString:@"\0"]; //Shift 1
+ while (buffer.length >= 3) {
+ [self writeNextTriplet:context buffer:buffer];
+ }
+ if ([context hasMoreCharacters]) {
+ [context writeCodeword:[ZXHighLevelEncoder c40Unlatch]];
+ }
+ } else if (available == 1 && rest == 1) {
+ while (buffer.length >= 3) {
+ [self writeNextTriplet:context buffer:buffer];
+ }
+ if ([context hasMoreCharacters]) {
+ [context writeCodeword:[ZXHighLevelEncoder c40Unlatch]];
+ }
+ // else no latch
+ context.pos--;
+ } else if (rest == 0) {
+ while (buffer.length >= 3) {
+ [self writeNextTriplet:context buffer:buffer];
+ }
+ if (available > 0 || [context hasMoreCharacters]) {
+ [context writeCodeword:[ZXHighLevelEncoder c40Unlatch]];
+ }
+ } else {
+ @throw [NSException exceptionWithName:@"IllegalStateException"
+ reason:@"Unexpected case. Please report!"
+ userInfo:nil];
+ }
+ [context signalEncoderChange:[ZXHighLevelEncoder asciiEncodation]];
+}
+
+- (int)encodeChar:(unichar)c buffer:(NSMutableString *)sb {
+ if (c == ' ') {
+ [sb appendString:@"\3"];
+ return 1;
+ } else if (c >= '0' && c <= '9') {
+ [sb appendFormat:@"%C", (unichar) (c - 48 + 4)];
+ return 1;
+ } else if (c >= 'A' && c <= 'Z') {
+ [sb appendFormat:@"%C", (unichar) (c - 65 + 14)];
+ return 1;
+ } else if (c >= '\0' && c <= (unichar)0x001f) {
+ [sb appendString:@"\0"]; //Shift 1 Set
+ [sb appendFormat:@"%C", c];
+ return 2;
+ } else if (c >= '!' && c <= '/') {
+ [sb appendString:@"\1"]; //Shift 2 Set
+ [sb appendFormat:@"%C", (unichar) (c - 33)];
+ return 2;
+ } else if (c >= ':' && c <= '@') {
+ [sb appendString:@"\1"]; //Shift 2 Set
+ [sb appendFormat:@"%C", (unichar) (c - 58 + 15)];
+ return 2;
+ } else if (c >= '[' && c <= '_') {
+ [sb appendString:@"\1"]; //Shift 2 Set
+ [sb appendFormat:@"%C", (unichar) (c - 91 + 22)];
+ return 2;
+ } else if (c >= '\u0060' && c <= (char)0x007f) {
+ [sb appendString:@"\2"]; //Shift 3 Set
+ [sb appendFormat:@"%C", (unichar) (c - 96)];
+ return 2;
+ } else if (c >= (unichar)0x0080) {
+ [sb appendFormat:@"\1%C", (unichar)0x001e]; //Shift 2, Upper Shift
+ int len = 2;
+ len += [self encodeChar:(unichar) (c - 128) buffer:sb];
+ return len;
+ } else {
+ @throw [NSException exceptionWithName:@"IllegalStateException"
+ reason:[NSString stringWithFormat:@"Illegal character: %C", c]
+ userInfo:nil];
+ }
+}
+
+- (NSString *)encodeToCodewords:(NSString *)sb startpos:(int)startPos {
+ unichar c1 = [sb characterAtIndex:startPos];
+ unichar c2 = [sb characterAtIndex:startPos + 1];
+ unichar c3 = [sb characterAtIndex:startPos + 2];
+ int v = (1600 * c1) + (40 * c2) + c3 + 1;
+ unichar cw1 = (unichar) (v / 256);
+ unichar cw2 = (unichar) (v % 256);
+ return [NSString stringWithFormat:@"%C%C", cw1, cw2];
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoder.h b/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoder.h
new file mode 100644
index 0000000..bab9e59
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoder.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@class ZXEncoderContext;
+
+@protocol ZXDataMatrixEncoder <NSObject>
+
+- (int)encodingMode;
+- (void)encode:(ZXEncoderContext *)context;
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h b/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h
new file mode 100644
index 0000000..fe7c530
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/**
+ * Error Correction Code for ECC200.
+ */
+
+@class ZXSymbolInfo;
+
+@interface ZXDataMatrixErrorCorrection : NSObject
+
++ (NSString *)encodeECC200:(NSString *)codewords symbolInfo:(ZXSymbolInfo *)symbolInfo;
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m b/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m
new file mode 100644
index 0000000..73b9bcc
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m
@@ -0,0 +1,166 @@
+/*
+ * 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 "ZXDataMatrixErrorCorrection.h"
+#import "ZXSymbolInfo.h"
+
+/**
+ * Lookup table which factors to use for which number of error correction codewords.
+ * See FACTORS.
+ */
+const int FACTOR_SETS_LEN = 16;
+const int FACTOR_SETS[FACTOR_SETS_LEN] = {5, 7, 10, 11, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 62, 68};
+
+/**
+ * Precomputed polynomial factors for ECC 200.
+ */
+const int FACTORS[16][68] = {
+ {228, 48, 15, 111, 62},
+ {23, 68, 144, 134, 240, 92, 254},
+ {28, 24, 185, 166, 223, 248, 116, 255, 110, 61},
+ {175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120},
+ {41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242},
+ {156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185},
+ {83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254, 225, 48, 90, 188},
+ {15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79, 108, 82, 27, 174, 186, 172},
+ {52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21, 5, 172,
+ 254, 124, 12, 181, 184, 96, 50, 193},
+ {211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34, 249, 121,
+ 17, 138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255},
+ {245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220, 251, 80, 182,
+ 229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59, 25,
+ 225, 98, 81, 112},
+ {77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133, 242, 8,
+ 175, 95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57, 54, 101,
+ 248, 202, 69, 50, 150, 177, 226, 5, 9, 5},
+ {245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205, 188, 237, 87,
+ 191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100, 66, 138,
+ 186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253, 225, 19},
+ {175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192, 215, 235,
+ 150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117, 203, 29, 232,
+ 144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127, 67, 247, 28,
+ 155, 43, 203, 107, 233, 53, 143, 46},
+ {242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143, 108, 196, 37,
+ 185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175, 64, 114, 71,
+ 161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163, 31,
+ 176, 170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204},
+ {220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36, 73, 127,
+ 213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15, 160, 227, 236,
+ 66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231, 136, 223, 239,
+ 181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153, 132, 63,
+ 96, 103, 82, 186}};
+
+const int MODULO_VALUE = 0x12D;
+
+static int LOG[256], ALOG[256];
+
+@implementation ZXDataMatrixErrorCorrection
+
++ (void)initialize {
+ //Create log and antilog table
+ int p = 1;
+ for (int i = 0; i < 255; i++) {
+ ALOG[i] = p;
+ LOG[p] = i;
+ p <<= 1;
+ if (p >= 256) {
+ p ^= MODULO_VALUE;
+ }
+ }
+}
+
++ (NSString *)encodeECC200:(NSString *)codewords symbolInfo:(ZXSymbolInfo *)symbolInfo {
+ if (codewords.length != symbolInfo.dataCapacity) {
+ [NSException raise:NSInvalidArgumentException format:@"The number of codewords does not match the selected symbol"];
+ }
+ NSUInteger capacity = symbolInfo.dataCapacity + symbolInfo.errorCodewords;
+ NSMutableString *sb = [NSMutableString stringWithCapacity:capacity];
+ [sb appendString:codewords];
+ int blockCount = symbolInfo.interleavedBlockCount;
+ if (blockCount == 1) {
+ NSString *ecc = [self createECCBlock:codewords numECWords:symbolInfo.errorCodewords];
+ [sb appendString:ecc];
+ } else {
+ if (sb.length > capacity) {
+ [sb deleteCharactersInRange:NSMakeRange(capacity, sb.length - capacity)];
+ }
+ int dataSizes[blockCount];
+ int errorSizes[blockCount];
+ int startPos[blockCount];
+ for (int i = 0; i < blockCount; i++) {
+ dataSizes[i] = [symbolInfo dataLengthForInterleavedBlock:i + 1];
+ errorSizes[i] = [symbolInfo errorLengthForInterleavedBlock:i + 1];
+ startPos[i] = 0;
+ if (i > 0) {
+ startPos[i] = startPos[i - 1] + dataSizes[i];
+ }
+ }
+ 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]];
+ }
+ NSString *ecc = [self createECCBlock:temp numECWords:errorSizes[block]];
+ int pos = 0;
+ for (int e = block; e < errorSizes[block] * blockCount; e += blockCount) {
+ [sb replaceCharactersInRange:NSMakeRange(symbolInfo.dataCapacity + e, 1) withString:[ecc substringWithRange:NSMakeRange(pos++, 1)]];
+ }
+ }
+ }
+ return [NSString stringWithString:sb];
+}
+
++ (NSString *)createECCBlock:(NSString *)codewords numECWords:(int)numECWords {
+ return [self createECCBlock:codewords start:0 len:(int)codewords.length numECWords:numECWords];
+}
+
++ (NSString *)createECCBlock:(NSString *)codewords start:(int)start len:(int)len numECWords:(int)numECWords {
+ int table = -1;
+ for (int i = 0; i < FACTOR_SETS_LEN; i++) {
+ if (FACTOR_SETS[i] == numECWords) {
+ table = i;
+ break;
+ }
+ }
+ if (table < 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Illegal number of error correction codewords specified: %d", numECWords];
+ }
+ int *poly = (int *)FACTORS[table];
+ unichar ecc[numECWords];
+ memset(ecc, 0, numECWords * sizeof(unichar));
+ for (int i = start; i < start + len; i++) {
+ int m = ecc[numECWords - 1] ^ [codewords characterAtIndex:i];
+ for (int k = numECWords - 1; k > 0; k--) {
+ if (m != 0 && poly[k] != 0) {
+ ecc[k] = (unichar) (ecc[k - 1] ^ ALOG[(LOG[m] + LOG[poly[k]]) % 255]);
+ } else {
+ ecc[k] = ecc[k - 1];
+ }
+ }
+ if (m != 0 && poly[0] != 0) {
+ ecc[0] = (unichar) ALOG[(LOG[m] + LOG[poly[0]]) % 255];
+ } else {
+ ecc[0] = 0;
+ }
+ }
+ unichar eccReversed[numECWords];
+ for (int i = 0; i < numECWords; i++) {
+ eccReversed[i] = ecc[numECWords - i - 1];
+ }
+ return [NSString stringWithCharacters:eccReversed length:numECWords];
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.h b/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.h
new file mode 100644
index 0000000..28e3a9f
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.h
@@ -0,0 +1,21 @@
+/*
+ * 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 "ZXSymbolInfo.h"
+
+@interface ZXDataMatrixSymbolInfo144 : ZXSymbolInfo
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.m b/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.m
new file mode 100644
index 0000000..83a8dcc
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.m
@@ -0,0 +1,38 @@
+/*
+ * 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 "ZXDataMatrixSymbolInfo144.h"
+
+@implementation ZXDataMatrixSymbolInfo144
+
+- (id)init {
+ if (self = [super initWithRectangular:NO dataCapacity:1558 errorCodewords:620 matrixWidth:22 matrixHeight:22 dataRegions:36]) {
+ self.rsBlockData = -1; //special! see below
+ self.rsBlockError = 62;
+ }
+
+ return self;
+}
+
+- (int)interleavedBlockCount {
+ return 10;
+}
+
+- (int)dataLengthForInterleavedBlock:(int)index {
+ return (index <= 8) ? 156 : 155;
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXDefaultPlacement.h b/ZXingObjC/datamatrix/encoder/ZXDefaultPlacement.h
new file mode 100644
index 0000000..e6d2697
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXDefaultPlacement.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/**
+ * Symbol Character Placement Program. Adapted from Annex M.1 in ISO/IEC 16022:2000(E).
+ */
+
+@interface ZXDefaultPlacement : NSObject
+
+@property (nonatomic, copy, readonly) NSString *codewords;
+@property (nonatomic, assign, readonly) int numrows;
+@property (nonatomic, assign, readonly) int numcols;
+@property (nonatomic, assign, readonly) int8_t *bits;
+@property (nonatomic, assign, readonly) int bitsLen;
+
+- (id)initWithCodewords:(NSString *)codewords numcols:(int)numcols numrows:(int)numrows;
+- (BOOL)bitAtCol:(int)col row:(int)row;
+- (void)setBitAtCol:(int)col row:(int)row bit:(BOOL)bit;
+- (BOOL)hasBitAtCol:(int)col row:(int)row;
+- (void)place;
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXDefaultPlacement.m b/ZXingObjC/datamatrix/encoder/ZXDefaultPlacement.m
new file mode 100644
index 0000000..718ec65
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXDefaultPlacement.m
@@ -0,0 +1,177 @@
+/*
+ * 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 "ZXDefaultPlacement.h"
+
+@implementation ZXDefaultPlacement
+
+- (id)initWithCodewords:(NSString *)codewords numcols:(int)numcols numrows:(int)numrows {
+ if (self = [super init]) {
+ _codewords = [codewords copy];
+ _numcols = numcols;
+ _numrows = numrows;
+ _bitsLen = numcols * numrows;
+ _bits = (int8_t *)malloc(_bitsLen * sizeof(int8_t));
+ memset(_bits, -1, _bitsLen); //Initialize with "not set" value
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_bits != NULL) {
+ free(_bits);
+ _bits = NULL;
+ }
+}
+
+- (BOOL)bitAtCol:(int)col row:(int)row {
+ return self.bits[row * self.numcols + col] == 1;
+}
+
+- (void)setBitAtCol:(int)col row:(int)row bit:(BOOL)bit {
+ self.bits[row * self.numcols + col] = bit ? (int8_t) 1 : (int8_t) 0;
+}
+
+- (BOOL)hasBitAtCol:(int)col row:(int)row {
+ return self.bits[row * self.numcols + col] >= 0;
+}
+
+- (void)place {
+ int pos = 0;
+ int row = 4;
+ int col = 0;
+
+ do {
+ /* repeatedly first check for one of the special corner cases, then... */
+ if ((row == self.numrows) && (col == 0)) {
+ [self corner1:pos++];
+ }
+ if ((row == self.numrows - 2) && (col == 0) && ((self.numcols % 4) != 0)) {
+ [self corner2:pos++];
+ }
+ if ((row == self.numrows - 2) && (col == 0) && (self.numcols % 8 == 4)) {
+ [self corner3:pos++];
+ }
+ if ((row == self.numrows + 4) && (col == 2) && ((self.numcols % 8) == 0)) {
+ [self corner4:pos++];
+ }
+ /* sweep upward diagonally, inserting successive characters... */
+ do {
+ if ((row < self.numrows) && (col >= 0) && ![self hasBitAtCol:col row:row]) {
+ [self utahAtRow:row col:col pos:pos++];
+ }
+ row -= 2;
+ col += 2;
+ } while (row >= 0 && (col < self.numcols));
+ row++;
+ col += 3;
+
+ /* and then sweep downward diagonally, inserting successive characters, ... */
+ do {
+ if ((row >= 0) && (col < self.numcols) && ![self hasBitAtCol:col row:row]) {
+ [self utahAtRow:row col:col pos:pos++];
+ }
+ row += 2;
+ col -= 2;
+ } while ((row < self.numrows) && (col >= 0));
+ row += 3;
+ col++;
+
+ /* ...until the entire array is scanned */
+ } while ((row < self.numrows) || (col < self.numcols));
+
+ /* Lastly, if the lower righthand corner is untouched, fill in fixed pattern */
+ if (![self hasBitAtCol:self.numcols - 1 row:self.numrows - 1]) {
+ [self setBitAtCol:self.numcols - 1 row:self.numrows - 1 bit:YES];
+ [self setBitAtCol:self.numcols - 2 row:self.numrows - 2 bit:YES];
+ }
+}
+
+- (void)moduleAtRow:(int)row col:(int)col pos:(int)pos bit:(int)bit {
+ if (row < 0) {
+ row += self.numrows;
+ col += 4 - ((self.numrows + 4) % 8);
+ }
+ if (col < 0) {
+ col += self.numcols;
+ row += 4 - ((self.numcols + 4) % 8);
+ }
+ // Note the conversion:
+ int v = [self.codewords characterAtIndex:pos];
+ v &= 1 << (8 - bit);
+ [self setBitAtCol:col row:row bit:v != 0];
+}
+
+/**
+ * Places the 8 bits of a utah-shaped symbol character in ECC200.
+ */
+- (void)utahAtRow:(int)row col:(int)col pos:(int)pos {
+ [self moduleAtRow:row - 2 col:col - 2 pos:pos bit:1];
+ [self moduleAtRow:row - 2 col:col - 1 pos:pos bit:2];
+ [self moduleAtRow:row - 1 col:col - 2 pos:pos bit:3];
+ [self moduleAtRow:row - 1 col:col - 1 pos:pos bit:4];
+ [self moduleAtRow:row - 1 col:col pos:pos bit:5];
+ [self moduleAtRow:row col:col - 2 pos:pos bit:6];
+ [self moduleAtRow:row col:col - 1 pos:pos bit:7];
+ [self moduleAtRow:row col:col pos:pos bit:8];
+}
+
+- (void)corner1:(int)pos {
+ [self moduleAtRow:self.numrows - 1 col:0 pos:pos bit:1];
+ [self moduleAtRow:self.numrows - 1 col:1 pos:pos bit:2];
+ [self moduleAtRow:self.numrows - 1 col:2 pos:pos bit:3];
+ [self moduleAtRow:0 col:self.numcols - 2 pos:pos bit:4];
+ [self moduleAtRow:0 col:self.numcols - 1 pos:pos bit:5];
+ [self moduleAtRow:1 col:self.numcols - 1 pos:pos bit:6];
+ [self moduleAtRow:2 col:self.numcols - 1 pos:pos bit:7];
+ [self moduleAtRow:3 col:self.numcols - 1 pos:pos bit:8];
+}
+
+- (void)corner2:(int)pos {
+ [self moduleAtRow:self.numrows - 3 col:0 pos:pos bit:1];
+ [self moduleAtRow:self.numrows - 2 col:0 pos:pos bit:2];
+ [self moduleAtRow:self.numrows - 1 col:0 pos:pos bit:3];
+ [self moduleAtRow:0 col:self.numcols - 4 pos:pos bit:4];
+ [self moduleAtRow:0 col:self.numcols - 3 pos:pos bit:5];
+ [self moduleAtRow:0 col:self.numcols - 2 pos:pos bit:6];
+ [self moduleAtRow:0 col:self.numcols - 1 pos:pos bit:7];
+ [self moduleAtRow:1 col:self.numcols - 1 pos:pos bit:8];
+}
+
+- (void)corner3:(int)pos {
+ [self moduleAtRow:self.numrows - 3 col:0 pos:pos bit:1];
+ [self moduleAtRow:self.numrows - 2 col:0 pos:pos bit:2];
+ [self moduleAtRow:self.numrows - 1 col:0 pos:pos bit:3];
+ [self moduleAtRow:0 col:self.numcols - 2 pos:pos bit:4];
+ [self moduleAtRow:0 col:self.numcols - 1 pos:pos bit:5];
+ [self moduleAtRow:1 col:self.numcols - 1 pos:pos bit:6];
+ [self moduleAtRow:2 col:self.numcols - 1 pos:pos bit:7];
+ [self moduleAtRow:3 col:self.numcols - 1 pos:pos bit:8];
+}
+
+- (void)corner4:(int)pos {
+ [self moduleAtRow:self.numrows - 1 col:0 pos:pos bit:1];
+ [self moduleAtRow:self.numrows - 1 col:self.numcols - 1 pos:pos bit:2];
+ [self moduleAtRow:0 col:self.numcols - 3 pos:pos bit:3];
+ [self moduleAtRow:0 col:self.numcols - 2 pos:pos bit:4];
+ [self moduleAtRow:0 col:self.numcols - 1 pos:pos bit:5];
+ [self moduleAtRow:1 col:self.numcols - 3 pos:pos bit:6];
+ [self moduleAtRow:1 col:self.numcols - 2 pos:pos bit:7];
+ [self moduleAtRow:1 col:self.numcols - 1 pos:pos bit:8];
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXEdifactEncoder.h b/ZXingObjC/datamatrix/encoder/ZXEdifactEncoder.h
new file mode 100644
index 0000000..de9ceb9
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXEdifactEncoder.h
@@ -0,0 +1,21 @@
+/*
+ * 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 "ZXDataMatrixEncoder.h"
+
+@interface ZXEdifactEncoder : NSObject <ZXDataMatrixEncoder>
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXEdifactEncoder.m b/ZXingObjC/datamatrix/encoder/ZXEdifactEncoder.m
new file mode 100644
index 0000000..4802771
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXEdifactEncoder.m
@@ -0,0 +1,139 @@
+/*
+ * 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 "ZXEdifactEncoder.h"
+#import "ZXEncoderContext.h"
+#import "ZXHighLevelEncoder.h"
+#import "ZXSymbolInfo.h"
+
+@implementation ZXEdifactEncoder
+
+- (int)encodingMode {
+ return [ZXHighLevelEncoder edifactEncodation];
+}
+
+- (void)encode:(ZXEncoderContext *)context {
+ //step F
+ NSMutableString *buffer = [NSMutableString string];
+ while ([context hasMoreCharacters]) {
+ unichar c = [context currentChar];
+ [self encodeChar:c buffer:buffer];
+ context.pos++;
+
+ NSUInteger count = buffer.length;
+ if (count >= 4) {
+ [context writeCodewords:[self encodeToCodewords:buffer startpos:0]];
+ [buffer deleteCharactersInRange:NSMakeRange(0, 4)];
+
+ int newMode = [ZXHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]];
+ if (newMode != [self encodingMode]) {
+ [context signalEncoderChange:[ZXHighLevelEncoder asciiEncodation]];
+ break;
+ }
+ }
+ }
+ [buffer appendFormat:@"%C", (unichar) 31]; //Unlatch
+ [self handleEOD:context buffer:buffer];
+}
+
+/**
+ * Handle "end of data" situations
+ */
+- (void)handleEOD:(ZXEncoderContext *)context buffer:(NSMutableString *)buffer {
+ @try {
+ NSUInteger count = buffer.length;
+ if (count == 0) {
+ return; //Already finished
+ }
+ if (count == 1) {
+ //Only an unlatch at the end
+ [context updateSymbolInfo];
+ int available = context.symbolInfo.dataCapacity - context.codewordCount;
+ int remaining = [context remainingCharacters];
+ if (remaining == 0 && available <= 2) {
+ return; //No unlatch
+ }
+ }
+
+ if (count > 4) {
+ @throw [NSException exceptionWithName:@"IllegalStateException"
+ reason:@"Count must not exceed 4"
+ userInfo:nil];
+ }
+ int restChars = (int)count - 1;
+ NSString *encoded = [self encodeToCodewords:buffer startpos:0];
+ BOOL endOfSymbolReached = ![context hasMoreCharacters];
+ BOOL restInAscii = endOfSymbolReached && restChars <= 2;
+
+ if (restChars <= 2) {
+ [context updateSymbolInfoWithLength:context.codewordCount + restChars];
+ int available = context.symbolInfo.dataCapacity - context.codewordCount;
+ if (available >= 3) {
+ restInAscii = NO;
+ [context updateSymbolInfoWithLength:context.codewordCount + (int)encoded.length];
+ //available = context.symbolInfo.dataCapacity - context.codewordCount;
+ }
+ }
+
+ if (restInAscii) {
+ [context resetSymbolInfo];
+ context.pos -= restChars;
+ } else {
+ [context writeCodewords:encoded];
+ }
+ } @finally {
+ [context signalEncoderChange:[ZXHighLevelEncoder asciiEncodation]];
+ }
+}
+
+- (void)encodeChar:(unichar)c buffer:(NSMutableString *)sb {
+ if (c >= ' ' && c <= '?') {
+ [sb appendFormat:@"%C", c];
+ } else if (c >= '@' && c <= '^') {
+ [sb appendFormat:@"%C", (unichar) (c - 64)];
+ } else {
+ [ZXHighLevelEncoder illegalCharacter:c];
+ }
+}
+
+- (NSString *)encodeToCodewords:(NSMutableString *)sb startpos:(int)startPos {
+ int len = (int)sb.length - startPos;
+ if (len == 0) {
+ @throw [NSException exceptionWithName:@"IllegalStateException"
+ reason:@"Buffer must not be empty"
+ userInfo:nil];
+ }
+ unichar c1 = [sb characterAtIndex:startPos];
+ unichar c2 = len >= 2 ? [sb characterAtIndex:startPos + 1] : 0;
+ unichar c3 = len >= 3 ? [sb characterAtIndex:startPos + 2] : 0;
+ unichar c4 = len >= 4 ? [sb characterAtIndex:startPos + 3] : 0;
+
+ int v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4;
+ unichar cw1 = (unichar) ((v >> 16) & 255);
+ unichar cw2 = (unichar) ((v >> 8) & 255);
+ unichar cw3 = (unichar) (v & 255);
+ NSMutableString *res = [NSMutableString stringWithCapacity:3];
+ [res appendFormat:@"%C", cw1];
+ if (len >= 2) {
+ [res appendFormat:@"%C", cw2];
+ }
+ if (len >= 3) {
+ [res appendFormat:@"%C", cw3];
+ }
+ return [NSString stringWithString:res];
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXEncoderContext.h b/ZXingObjC/datamatrix/encoder/ZXEncoderContext.h
new file mode 100644
index 0000000..c839839
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXEncoderContext.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+@class ZXDimension, ZXSymbolInfo, ZXSymbolShapeHint;
+
+@interface ZXEncoderContext : NSObject
+
+@property (nonatomic, copy) NSMutableString *codewords;
+@property (nonatomic, copy) NSString *message;
+@property (nonatomic, assign) int newEncoding;
+@property (nonatomic, assign) int pos;
+@property (nonatomic, assign) int skipAtEnd;
+@property (nonatomic, strong) ZXSymbolShapeHint *symbolShape;
+@property (nonatomic, strong) ZXSymbolInfo *symbolInfo;
+
+- (id)initWithMessage:(NSString *)msg;
+- (void)setSizeConstraints:(ZXDimension *)minSize maxSize:(ZXDimension *)maxSize;
+- (void)setSkipAtEnd:(int)count;
+- (unichar)currentChar;
+- (unichar)current;
+- (void)writeCodewords:(NSString *)codewords;
+- (void)writeCodeword:(unichar)codeword;
+- (int)codewordCount;
+- (void)signalEncoderChange:(int)encoding;
+- (void)resetEncoderSignal;
+- (BOOL)hasMoreCharacters;
+- (int)totalMessageCharCount;
+- (int)remainingCharacters;
+- (void)updateSymbolInfo;
+- (void)updateSymbolInfoWithLength:(int)len;
+- (void)resetSymbolInfo;
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXEncoderContext.m b/ZXingObjC/datamatrix/encoder/ZXEncoderContext.m
new file mode 100644
index 0000000..fbbac69
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXEncoderContext.m
@@ -0,0 +1,112 @@
+/*
+ * 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 "ZXEncoderContext.h"
+#import "ZXSymbolInfo.h"
+#import "ZXSymbolShapeHint.h"
+
+@interface ZXEncoderContext ()
+
+@property (nonatomic, strong) ZXDimension *maxSize;
+@property (nonatomic, strong) ZXDimension *minSize;
+
+@end
+
+@implementation ZXEncoderContext
+
+- (id)initWithMessage:(NSString *)msg {
+ if (self = [super init]) {
+ //From this point on Strings are not Unicode anymore!
+ NSData *msgData = [msg dataUsingEncoding:NSISOLatin1StringEncoding];
+ if (!msgData) {
+ [NSException raise:NSInvalidArgumentException format:@"Message contains characters outside ISO-8859-1 encoding."];
+ }
+ const char *msgBinary = [msgData bytes];
+ NSMutableString *sb = [NSMutableString string];
+ for (int i = 0, c = (int)msg.length; i < c; i++) {
+ unichar ch = (unichar) (msgBinary[i] & 0xff);
+ [sb appendFormat:@"%C", ch];
+ }
+
+ _message = [[NSString alloc] initWithString:sb];
+ _symbolShape = [ZXSymbolShapeHint forceNone];
+ _codewords = [[NSMutableString alloc] initWithCapacity:msg.length];
+ _newEncoding = -1;
+ }
+
+ return self;
+}
+
+- (void)setSizeConstraints:(ZXDimension *)minSize maxSize:(ZXDimension *)maxSize {
+ self.minSize = minSize;
+ self.maxSize = maxSize;
+}
+
+- (unichar)currentChar {
+ return [self.message characterAtIndex:self.pos];
+}
+
+- (unichar)current {
+ return [self.message characterAtIndex:self.pos];
+}
+
+- (void)writeCodewords:(NSString *)codewords {
+ [self.codewords appendString:codewords];
+}
+
+- (void)writeCodeword:(unichar)codeword {
+ [self.codewords appendFormat:@"%C", codeword];
+}
+
+- (int)codewordCount {
+ return (int)self.codewords.length;
+}
+
+- (void)signalEncoderChange:(int)encoding {
+ self.newEncoding = encoding;
+}
+
+- (void)resetEncoderSignal {
+ self.newEncoding = -1;
+}
+
+- (BOOL)hasMoreCharacters {
+ return self.pos < [self totalMessageCharCount];
+}
+
+- (int)totalMessageCharCount {
+ return (int)self.message.length - self.skipAtEnd;
+}
+
+- (int)remainingCharacters {
+ return [self totalMessageCharCount] - self.pos;
+}
+
+- (void)updateSymbolInfo {
+ [self updateSymbolInfoWithLength:[self codewordCount]];
+}
+
+- (void)updateSymbolInfoWithLength:(int)len {
+ if (self.symbolInfo == nil || len > self.symbolInfo.dataCapacity) {
+ self.symbolInfo = [ZXSymbolInfo lookup:len shape:self.symbolShape minSize:self.minSize maxSize:self.maxSize fail:YES];
+ }
+}
+
+- (void)resetSymbolInfo {
+ self.symbolInfo = nil;
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXHighLevelEncoder.h b/ZXingObjC/datamatrix/encoder/ZXHighLevelEncoder.h
new file mode 100644
index 0000000..b2c33e0
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXHighLevelEncoder.h
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+/**
+ * DataMatrix ECC 200 data encoder following the algorithm described in ISO/IEC 16022:200(E) in
+ * annex S.
+ */
+
+@class ZXDimension, ZXSymbolShapeHint;
+
+@interface ZXHighLevelEncoder : NSObject
+
+/**
+ * mode latch to C40 encodation mode
+ */
++ (unichar)latchToC40;
+
+/**
+ * mode latch to Base 256 encodation mode
+ */
++ (unichar)latchToBase256;
+
+/**
+ * Upper Shift
+ */
++ (unichar)upperShift;
+
+/**
+ * 05 Macro
+ */
++ (unichar)macro05;
+
+/**
+ * 06 Macro
+ */
++ (unichar)macro06;
+
+/**
+ * mode latch to ANSI X.12 encodation mode
+ */
++ (unichar)latchToAnsiX12;
+
+/**
+ * mode latch to Text encodation mode
+ */
+
++ (unichar)latchToText;
+
+/**
+ * mode latch to EDIFACT encodation mode
+ */
++ (unichar)latchToEdifact;
+
+/**
+ * Unlatch from C40 encodation
+ */
++ (unichar)c40Unlatch;
+
+/**
+ * Unlatch from X12 encodation
+ */
++ (unichar)x12Unlatch;
+
++ (int)asciiEncodation;
++ (int)c40Encodation;
++ (int)textEncodation;
++ (int)x12Encodation;
++ (int)edifactEncodation;
++ (int)base256Encodation;
+
+/**
+ * Converts the message to a byte array using the default encoding (cp437) as defined by the
+ * specification
+ */
++ (int8_t *)bytesForMessage:(NSString *)msg;
+
+/**
+ * Performs message encoding of a DataMatrix message using the algorithm described in annex P
+ * of ISO/IEC 16022:2000(E).
+ */
++ (NSString *)encodeHighLevel:(NSString *)msg;
+
+/**
+ * Performs message encoding of a DataMatrix message using the algorithm described in annex P
+ * of ISO/IEC 16022:2000(E).
+ */
++ (NSString *)encodeHighLevel:(NSString *)msg shape:(ZXSymbolShapeHint *)shape
+ minSize:(ZXDimension *)minSize maxSize:(ZXDimension *)maxSize;
+
++ (int)lookAheadTest:(NSString *)msg startpos:(int)startpos currentMode:(int)currentMode;
+
+/**
+ * Determines the number of consecutive characters that are encodable using numeric compaction.
+ */
++ (int)determineConsecutiveDigitCount:(NSString *)msg startpos:(int)startpos;
+
++ (BOOL)isDigit:(unichar)ch;
++ (BOOL)isExtendedASCII:(unichar)ch;
+
++ (void)illegalCharacter:(unichar)c;
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXHighLevelEncoder.m b/ZXingObjC/datamatrix/encoder/ZXHighLevelEncoder.m
new file mode 100644
index 0000000..b69183d
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXHighLevelEncoder.m
@@ -0,0 +1,428 @@
+/*
+ * 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 "ZXASCIIEncoder.h"
+#import "ZXBase256Encoder.h"
+#import "ZXC40Encoder.h"
+#import "ZXEdifactEncoder.h"
+#import "ZXEncoderContext.h"
+#import "ZXHighLevelEncoder.h"
+#import "ZXSymbolInfo.h"
+#import "ZXSymbolShapeHint.h"
+#import "ZXTextEncoder.h"
+#import "ZXX12Encoder.h"
+
+/**
+ * Padding character
+ */
+const unichar PAD_CHAR = 129;
+
+/**
+ * 05 Macro header
+ */
+static NSString *MACRO_05_HEADER = nil;
+
+/**
+ * 06 Macro header
+ */
+static NSString *MACRO_06_HEADER = nil;
+
+/**
+ * Macro trailer
+ */
+static NSString *MACRO_TRAILER = nil;
+
+@implementation ZXHighLevelEncoder
+
++ (void)initialize {
+ MACRO_05_HEADER = [[NSString alloc] initWithFormat:@"[)>%C05%C", (unichar)0x001E, (unichar)0x001D];
+ MACRO_06_HEADER = [[NSString alloc] initWithFormat:@"[)>%C06%C", (unichar)0x001E, (unichar)0x001D];
+ MACRO_TRAILER = [[NSString alloc] initWithFormat:@"%C%C", (unichar)0x001E, (unichar)0x0004];
+}
+
++ (unichar)latchToC40 {
+ return 230;
+}
+
++ (unichar)latchToBase256 {
+ return 231;
+}
+
++ (unichar)upperShift {
+ return 235;
+}
+
++ (unichar)macro05 {
+ return 236;
+}
+
++ (unichar)macro06 {
+ return 237;
+}
+
++ (unichar)latchToAnsiX12 {
+ return 238;
+}
+
++ (unichar)latchToText {
+ return 239;
+}
+
++ (unichar)latchToEdifact {
+ return 240;
+}
+
++ (unichar)c40Unlatch {
+ return 254;
+}
+
++ (unichar)x12Unlatch {
+ return 254;
+}
+
++ (int)asciiEncodation {
+ return 0;
+}
+
++ (int)c40Encodation {
+ return 1;
+}
+
++ (int)textEncodation {
+ return 2;
+}
+
++ (int)x12Encodation {
+ return 3;
+}
+
++ (int)edifactEncodation {
+ return 4;
+}
+
++ (int)base256Encodation {
+ return 5;
+}
+
++ (int8_t *)bytesForMessage:(NSString *)msg {
+ return (int8_t *)[[msg dataUsingEncoding:(NSStringEncoding) 0x80000400] bytes]; //See 4.4.3 and annex B of ISO/IEC 15438:2001(E)
+}
+
++ (unichar)randomize253State:(unichar)ch codewordPosition:(int)codewordPosition {
+ int pseudoRandom = ((149 * codewordPosition) % 253) + 1;
+ int tempVariable = ch + pseudoRandom;
+ return tempVariable <= 254 ? (unichar) tempVariable : (unichar) (tempVariable - 254);
+}
+
++ (NSString *)encodeHighLevel:(NSString *)msg {
+ return [self encodeHighLevel:msg shape:[ZXSymbolShapeHint forceNone] minSize:nil maxSize:nil];
+}
+
++ (NSString *)encodeHighLevel:(NSString *)msg shape:(ZXSymbolShapeHint *)shape
+ minSize:(ZXDimension *)minSize maxSize:(ZXDimension *)maxSize {
+ //the codewords 0..255 are encoded as Unicode characters
+ NSArray *encoders = @[[[ZXASCIIEncoder alloc] init],
+ [[ZXC40Encoder alloc] init],
+ [[ZXTextEncoder alloc] init],
+ [[ZXX12Encoder alloc] init],
+ [[ZXEdifactEncoder alloc] init],
+ [[ZXBase256Encoder alloc] init]];
+
+ ZXEncoderContext *context = [[ZXEncoderContext alloc] initWithMessage:msg];
+ context.symbolShape = shape;
+ [context setSizeConstraints:minSize maxSize:maxSize];
+
+ if ([msg hasPrefix:MACRO_05_HEADER] && [msg hasSuffix:MACRO_TRAILER]) {
+ [context writeCodeword:[self macro05]];
+ [context setSkipAtEnd:2];
+ context.pos += MACRO_05_HEADER.length;
+ } else if ([msg hasPrefix:MACRO_06_HEADER] && [msg hasSuffix:MACRO_TRAILER]) {
+ [context writeCodeword:[self macro06]];
+ [context setSkipAtEnd:2];
+ context.pos += MACRO_06_HEADER.length;
+ }
+
+ int encodingMode = [self asciiEncodation]; //Default mode
+ while ([context hasMoreCharacters]) {
+ [encoders[encodingMode] encode:context];
+ if (context.newEncoding >= 0) {
+ encodingMode = context.newEncoding;
+ [context resetEncoderSignal];
+ }
+ }
+ NSUInteger len = context.codewords.length;
+ [context updateSymbolInfo];
+ int capacity = context.symbolInfo.dataCapacity;
+ if (len < capacity) {
+ if (encodingMode != [self asciiEncodation] && encodingMode != [self base256Encodation]) {
+ [context writeCodeword:(unichar)0x00fe]; //Unlatch (254)
+ }
+ }
+ //Padding
+ NSMutableString *codewords = context.codewords;
+ if (codewords.length < capacity) {
+ [codewords appendFormat:@"%C", PAD_CHAR];
+ }
+ while (codewords.length < capacity) {
+ [codewords appendFormat:@"%C", [self randomize253State:PAD_CHAR codewordPosition:(int)codewords.length + 1]];
+ }
+
+ return [NSString stringWithString:context.codewords];
+}
+
++ (int)lookAheadTest:(NSString *)msg startpos:(int)startpos currentMode:(int)currentMode {
+ if (startpos >= msg.length) {
+ return currentMode;
+ }
+ float charCounts[6];
+ //step J
+ if (currentMode == [self asciiEncodation]) {
+ charCounts[0] = 0;
+ charCounts[1] = 1;
+ charCounts[2] = 1;
+ charCounts[3] = 1;
+ charCounts[4] = 1;
+ charCounts[5] = 1.25f;
+ } else {
+ charCounts[0] = 1;
+ charCounts[1] = 2;
+ charCounts[2] = 2;
+ charCounts[3] = 2;
+ charCounts[4] = 2;
+ charCounts[5] = 2.25f;
+ charCounts[currentMode] = 0;
+ }
+
+ int charsProcessed = 0;
+ while (YES) {
+ //step K
+ if ((startpos + charsProcessed) == msg.length) {
+ int min = INT_MAX;
+ int8_t mins[6];
+ int intCharCounts[6];
+ min = [self findMinimums:charCounts intCharCounts:intCharCounts min:min mins:mins];
+ int minCount = [self minimumCount:mins];
+
+ if (intCharCounts[[self asciiEncodation]] == min) {
+ return [self asciiEncodation];
+ }
+ if (minCount == 1 && mins[[self base256Encodation]] > 0) {
+ return [self base256Encodation];
+ }
+ if (minCount == 1 && mins[[self edifactEncodation]] > 0) {
+ return [self edifactEncodation];
+ }
+ if (minCount == 1 && mins[[self textEncodation]] > 0) {
+ return [self textEncodation];
+ }
+ if (minCount == 1 && mins[[self x12Encodation]] > 0) {
+ return [self x12Encodation];
+ }
+ return [self c40Encodation];
+ }
+
+ unichar c = [msg characterAtIndex:startpos + charsProcessed];
+ charsProcessed++;
+
+ //step L
+ if ([self isDigit:c]) {
+ charCounts[[self asciiEncodation]] += 0.5;
+ } else if ([self isExtendedASCII:c]) {
+ charCounts[[self asciiEncodation]] = (int) ceil(charCounts[[self asciiEncodation]]);
+ charCounts[[self asciiEncodation]] += 2;
+ } else {
+ charCounts[[self asciiEncodation]] = (int) ceil(charCounts[[self asciiEncodation]]);
+ charCounts[[self asciiEncodation]]++;
+ }
+
+ //step M
+ if ([self isNativeC40:c]) {
+ charCounts[[self c40Encodation]] += 2.0f / 3.0f;
+ } else if ([self isExtendedASCII:c]) {
+ charCounts[[self c40Encodation]] += 8.0f / 3.0f;
+ } else {
+ charCounts[[self c40Encodation]] += 4.0f / 3.0f;
+ }
+
+ //step N
+ if ([self isNativeText:c]) {
+ charCounts[[self textEncodation]] += 2.0f / 3.0f;
+ } else if ([self isExtendedASCII:c]) {
+ charCounts[[self textEncodation]] += 8.0f / 3.0f;
+ } else {
+ charCounts[[self textEncodation]] += 4.0f / 3.0f;
+ }
+
+ //step O
+ if ([self isNativeX12:c]) {
+ charCounts[[self x12Encodation]] += 2.0f / 3.0f;
+ } else if ([self isExtendedASCII:c]) {
+ charCounts[[self x12Encodation]] += 13.0f / 3.0f;
+ } else {
+ charCounts[[self x12Encodation]] += 10.0f / 3.0f;
+ }
+
+ //step P
+ if ([self isNativeEDIFACT:c]) {
+ charCounts[[self edifactEncodation]] += 3.0f / 4.0f;
+ } else if ([self isExtendedASCII:c]) {
+ charCounts[[self edifactEncodation]] += 17.0f / 4.0f;
+ } else {
+ charCounts[[self edifactEncodation]] += 13.0f / 4.0f;
+ }
+
+ // step Q
+ if ([self isSpecialB256:c]) {
+ charCounts[[self base256Encodation]] += 4;
+ } else {
+ charCounts[[self base256Encodation]]++;
+ }
+
+ //step R
+ if (charsProcessed >= 4) {
+ int intCharCounts[6];
+ int8_t mins[6];
+ [self findMinimums:charCounts intCharCounts:intCharCounts min:INT_MAX mins:mins];
+ int minCount = [self minimumCount:mins];
+
+ if (intCharCounts[[self asciiEncodation]] < intCharCounts[[self base256Encodation]]
+ && intCharCounts[[self asciiEncodation]] < intCharCounts[[self c40Encodation]]
+ && intCharCounts[[self asciiEncodation]] < intCharCounts[[self textEncodation]]
+ && intCharCounts[[self asciiEncodation]] < intCharCounts[[self x12Encodation]]
+ && intCharCounts[[self asciiEncodation]] < intCharCounts[[self edifactEncodation]]) {
+ return [self asciiEncodation];
+ }
+ if (intCharCounts[[self base256Encodation]] < intCharCounts[[self asciiEncodation]]
+ || (mins[[self c40Encodation]] + mins[[self textEncodation]] + mins[[self x12Encodation]] + mins[[self edifactEncodation]]) == 0) {
+ return [self base256Encodation];
+ }
+ if (minCount == 1 && mins[[self edifactEncodation]] > 0) {
+ return [self edifactEncodation];
+ }
+ if (minCount == 1 && mins[[self textEncodation]] > 0) {
+ return [self textEncodation];
+ }
+ if (minCount == 1 && mins[[self x12Encodation]] > 0) {
+ return [self x12Encodation];
+ }
+ if (intCharCounts[[self c40Encodation]] + 1 < intCharCounts[[self asciiEncodation]]
+ && intCharCounts[[self c40Encodation]] + 1 < intCharCounts[[self base256Encodation]]
+ && intCharCounts[[self c40Encodation]] + 1 < intCharCounts[[self edifactEncodation]]
+ && intCharCounts[[self c40Encodation]] + 1 < intCharCounts[[self textEncodation]]) {
+ if (intCharCounts[[self c40Encodation]] < intCharCounts[[self x12Encodation]]) {
+ return [self c40Encodation];
+ }
+ if (intCharCounts[[self c40Encodation]] == intCharCounts[[self x12Encodation]]) {
+ int p = startpos + charsProcessed + 1;
+ while (p < msg.length) {
+ char tc = [msg characterAtIndex:p];
+ if ([self isX12TermSep:tc]) {
+ return [self x12Encodation];
+ }
+ if (![self isNativeX12:tc]) {
+ break;
+ }
+ p++;
+ }
+ return [self c40Encodation];
+ }
+ }
+ }
+ }
+}
+
++ (int)findMinimums:(float *)charCounts intCharCounts:(int *)intCharCounts min:(int)min mins:(int8_t *)mins {
+ memset(mins, 0, 6);
+ for (int i = 0; i < 6; i++) {
+ intCharCounts[i] = (int) ceil(charCounts[i]);
+ int current = intCharCounts[i];
+ if (min > current) {
+ min = current;
+ memset(mins, 0, 6);
+ }
+ if (min == current) {
+ mins[i]++;
+ }
+ }
+ return min;
+}
+
++ (int)minimumCount:(int8_t *)mins {
+ int minCount = 0;
+ for (int i = 0; i < 6; i++) {
+ minCount += mins[i];
+ }
+ return minCount;
+}
+
++ (BOOL)isDigit:(unichar)ch {
+ return ch >= '0' && ch <= '9';
+}
+
++ (BOOL)isExtendedASCII:(unichar)ch {
+ return ch >= 128 && ch <= 255;
+}
+
++ (BOOL)isNativeC40:(unichar)ch {
+ return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z');
+}
+
++ (BOOL)isNativeText:(unichar)ch {
+ return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z');
+}
+
++ (BOOL)isNativeX12:(unichar)ch {
+ return [self isX12TermSep:ch] || (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z');
+}
+
++ (BOOL)isX12TermSep:(unichar)ch {
+ return (ch == '\r') //CR
+ || (ch == '*')
+ || (ch == '>');
+}
+
++ (BOOL)isNativeEDIFACT:(unichar)ch {
+ return ch >= ' ' && ch <= '^';
+}
+
++ (BOOL)isSpecialB256:(unichar)ch {
+ return NO; //TODO NOT IMPLEMENTED YET!!!
+}
+
++ (int)determineConsecutiveDigitCount:(NSString *)msg startpos:(int)startpos {
+ int count = 0;
+ NSUInteger len = msg.length;
+ int idx = startpos;
+ if (idx < len) {
+ unichar ch = [msg characterAtIndex:idx];
+ while ([self isDigit:ch] && idx < len) {
+ count++;
+ idx++;
+ if (idx < len) {
+ ch = [msg characterAtIndex:idx];
+ }
+ }
+ }
+ return count;
+}
+
++ (void)illegalCharacter:(unichar)c {
+ NSString *hex = [NSString stringWithFormat:@"%x", c];
+ hex = [[@"0000" substringWithRange:NSMakeRange(0, hex.length)] stringByAppendingString:hex];
+ [NSException raise:NSInvalidArgumentException format:@"Illegal character: %C (0x%@)", c, hex];
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXSymbolInfo.h b/ZXingObjC/datamatrix/encoder/ZXSymbolInfo.h
new file mode 100644
index 0000000..e77553f
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXSymbolInfo.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+/**
+ * Symbol info table for DataMatrix.
+ */
+
+@class ZXDimension, ZXSymbolShapeHint;
+
+@interface ZXSymbolInfo : NSObject
+
+@property (nonatomic, assign) BOOL rectangular;
+@property (nonatomic, assign) int errorCodewords;
+@property (nonatomic, assign) int dataCapacity;
+@property (nonatomic, assign) int dataRegions;
+@property (nonatomic, assign) int matrixWidth;
+@property (nonatomic, assign) int matrixHeight;
+@property (nonatomic, assign) int rsBlockData;
+@property (nonatomic, assign) int rsBlockError;
+
+/**
+ * Overrides the symbol info set used by this class. Used for testing purposes.
+ */
++ (void)overrideSymbolSet:(NSArray *)override;
++ (NSArray *)prodSymbols;
+- (id)initWithRectangular:(BOOL)rectangular dataCapacity:(int)dataCapacity errorCodewords:(int)errorCodewords
+ matrixWidth:(int)matrixWidth matrixHeight:(int)matrixHeight dataRegions:(int)dataRegions;
+- (id)initWithRectangular:(BOOL)rectangular dataCapacity:(int)dataCapacity errorCodewords:(int)errorCodewords
+ matrixWidth:(int)matrixWidth matrixHeight:(int)matrixHeight dataRegions:(int)dataRegions
+ rsBlockData:(int)rsBlockData rsBlockError:(int)rsBlockError;
++ (ZXSymbolInfo *)lookup:(int)dataCodewords;
++ (ZXSymbolInfo *)lookup:(int)dataCodewords shape:(ZXSymbolShapeHint *)shape;
++ (ZXSymbolInfo *)lookup:(int)dataCodewords allowRectangular:(BOOL)allowRectangular fail:(BOOL)fail;
++ (ZXSymbolInfo *)lookup:(int)dataCodewords shape:(ZXSymbolShapeHint *)shape fail:(BOOL)fail;
++ (ZXSymbolInfo *)lookup:(int)dataCodewords shape:(ZXSymbolShapeHint *)shape minSize:(ZXDimension *)minSize
+ maxSize:(ZXDimension *)maxSize fail:(BOOL)fail;
+- (int)horizontalDataRegions;
+- (int)verticalDataRegions;
+- (int)symbolDataWidth;
+- (int)symbolDataHeight;
+- (int)symbolWidth;
+- (int)symbolHeight;
+- (int)codewordCount;
+- (int)interleavedBlockCount;
+- (int)dataLengthForInterleavedBlock:(int)index;
+- (int)errorLengthForInterleavedBlock:(int)index;
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXSymbolInfo.m b/ZXingObjC/datamatrix/encoder/ZXSymbolInfo.m
new file mode 100644
index 0000000..b432def
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXSymbolInfo.m
@@ -0,0 +1,219 @@
+/*
+ * 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 "ZXDataMatrixSymbolInfo144.h"
+#import "ZXDimension.h"
+#import "ZXSymbolInfo.h"
+#import "ZXSymbolShapeHint.h"
+
+static NSArray *PROD_SYMBOLS = nil;
+static NSArray *symbols = nil;
+
+@implementation ZXSymbolInfo
+
++ (void)initialize {
+ PROD_SYMBOLS = @[[[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:3 errorCodewords:5 matrixWidth:8 matrixHeight:8 dataRegions:1],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:5 errorCodewords:7 matrixWidth:10 matrixHeight:10 dataRegions:1],
+ /*rect*/[[ZXSymbolInfo alloc] initWithRectangular:YES dataCapacity:5 errorCodewords:7 matrixWidth:16 matrixHeight:6 dataRegions:1],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:8 errorCodewords:10 matrixWidth:12 matrixHeight:12 dataRegions:1],
+ /*rect*/[[ZXSymbolInfo alloc] initWithRectangular:YES dataCapacity:10 errorCodewords:11 matrixWidth:14 matrixHeight:6 dataRegions:2],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:12 errorCodewords:12 matrixWidth:14 matrixHeight:14 dataRegions:1],
+ /*rect*/[[ZXSymbolInfo alloc] initWithRectangular:YES dataCapacity:16 errorCodewords:14 matrixWidth:24 matrixHeight:10 dataRegions:1],
+
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:18 errorCodewords:14 matrixWidth:16 matrixHeight:16 dataRegions:1],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:22 errorCodewords:18 matrixWidth:18 matrixHeight:18 dataRegions:1],
+ /*rect*/[[ZXSymbolInfo alloc] initWithRectangular:YES dataCapacity:22 errorCodewords:18 matrixWidth:16 matrixHeight:10 dataRegions:2],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:30 errorCodewords:20 matrixWidth:20 matrixHeight:20 dataRegions:1],
+ /*rect*/[[ZXSymbolInfo alloc] initWithRectangular:YES dataCapacity:32 errorCodewords:24 matrixWidth:16 matrixHeight:14 dataRegions:2],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:36 errorCodewords:24 matrixWidth:22 matrixHeight:22 dataRegions:1],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:44 errorCodewords:28 matrixWidth:24 matrixHeight:24 dataRegions:1],
+ /*rect*/[[ZXSymbolInfo alloc] initWithRectangular:YES dataCapacity:49 errorCodewords:28 matrixWidth:22 matrixHeight:14 dataRegions:2],
+
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:62 errorCodewords:36 matrixWidth:14 matrixHeight:14 dataRegions:4],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:86 errorCodewords:42 matrixWidth:16 matrixHeight:16 dataRegions:4],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:114 errorCodewords:48 matrixWidth:18 matrixHeight:18 dataRegions:4],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:144 errorCodewords:56 matrixWidth:20 matrixHeight:20 dataRegions:4],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:174 errorCodewords:68 matrixWidth:22 matrixHeight:22 dataRegions:4],
+
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:204 errorCodewords:84 matrixWidth:24 matrixHeight:24 dataRegions:4 rsBlockData:102 rsBlockError:42],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:280 errorCodewords:112 matrixWidth:14 matrixHeight:14 dataRegions:16 rsBlockData:140 rsBlockError:56],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:368 errorCodewords:144 matrixWidth:16 matrixHeight:16 dataRegions:16 rsBlockData:92 rsBlockError:36],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:456 errorCodewords:192 matrixWidth:18 matrixHeight:18 dataRegions:16 rsBlockData:114 rsBlockError:48],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:576 errorCodewords:224 matrixWidth:20 matrixHeight:20 dataRegions:16 rsBlockData:144 rsBlockError:56],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:696 errorCodewords:272 matrixWidth:22 matrixHeight:22 dataRegions:16 rsBlockData:174 rsBlockError:68],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:816 errorCodewords:336 matrixWidth:24 matrixHeight:24 dataRegions:16 rsBlockData:136 rsBlockError:56],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:1050 errorCodewords:408 matrixWidth:18 matrixHeight:18 dataRegions:36 rsBlockData:175 rsBlockError:68],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:1304 errorCodewords:496 matrixWidth:20 matrixHeight:20 dataRegions:36 rsBlockData:163 rsBlockError:62],
+ [[ZXDataMatrixSymbolInfo144 alloc] init]];
+ symbols = PROD_SYMBOLS;
+}
+
++ (NSArray *)prodSymbols {
+ return PROD_SYMBOLS;
+}
+
++ (void)overrideSymbolSet:(NSArray *)override {
+ symbols = override;
+}
+
+- (id)initWithRectangular:(BOOL)rectangular dataCapacity:(int)dataCapacity errorCodewords:(int)errorCodewords
+ matrixWidth:(int)matrixWidth matrixHeight:(int)matrixHeight dataRegions:(int)dataRegions {
+ return [self initWithRectangular:rectangular dataCapacity:dataCapacity errorCodewords:errorCodewords
+ matrixWidth:matrixWidth matrixHeight:matrixHeight dataRegions:dataRegions
+ rsBlockData:dataCapacity rsBlockError:errorCodewords];
+}
+
+- (id)initWithRectangular:(BOOL)rectangular dataCapacity:(int)dataCapacity errorCodewords:(int)errorCodewords
+ matrixWidth:(int)matrixWidth matrixHeight:(int)matrixHeight dataRegions:(int)dataRegions
+ rsBlockData:(int)rsBlockData rsBlockError:(int)rsBlockError {
+ if (self = [super init]) {
+ _rectangular = rectangular;
+ _dataCapacity = dataCapacity;
+ _errorCodewords = errorCodewords;
+ _matrixWidth = matrixWidth;
+ _matrixHeight = matrixHeight;
+ _dataRegions = dataRegions;
+ _rsBlockData = rsBlockData;
+ _rsBlockError = rsBlockError;
+ }
+
+ return self;
+}
+
++ (ZXSymbolInfo *)lookup:(int)dataCodewords {
+ return [self lookup:dataCodewords shape:[ZXSymbolShapeHint forceNone] fail:YES];
+}
+
++ (ZXSymbolInfo *)lookup:(int)dataCodewords shape:(ZXSymbolShapeHint *)shape {
+ return [self lookup:dataCodewords shape:shape fail:YES];
+}
+
++ (ZXSymbolInfo *)lookup:(int)dataCodewords allowRectangular:(BOOL)allowRectangular fail:(BOOL)fail {
+ ZXSymbolShapeHint *shape = allowRectangular
+ ? [ZXSymbolShapeHint forceNone] : [ZXSymbolShapeHint forceSquare];
+ return [self lookup:dataCodewords shape:shape fail:fail];
+}
+
++ (ZXSymbolInfo *)lookup:(int)dataCodewords shape:(ZXSymbolShapeHint *)shape fail:(BOOL)fail {
+ return [self lookup:dataCodewords shape:shape minSize:nil maxSize:nil fail:fail];
+}
+
++ (ZXSymbolInfo *)lookup:(int)dataCodewords shape:(ZXSymbolShapeHint *)shape minSize:(ZXDimension *)minSize
+ maxSize:(ZXDimension *)maxSize fail:(BOOL)fail {
+ for (ZXSymbolInfo *symbol in symbols) {
+ if (shape == [ZXSymbolShapeHint forceSquare] && symbol.rectangular) {
+ continue;
+ }
+ if (shape == [ZXSymbolShapeHint forceRectangle] && !symbol.rectangular) {
+ continue;
+ }
+ if (minSize != nil
+ && ([symbol symbolWidth] < minSize.width
+ || [symbol symbolHeight] < minSize.height)) {
+ continue;
+ }
+ if (maxSize != nil
+ && ([symbol symbolWidth] > maxSize.width
+ || [symbol symbolHeight] > maxSize.height)) {
+ continue;
+ }
+ if (dataCodewords <= symbol.dataCapacity) {
+ return symbol;
+ }
+ }
+ if (fail) {
+ [NSException raise:NSInvalidArgumentException format:@"Can't find a symbol arrangement that matches the message. Data codewords: %d", dataCodewords];
+ }
+ return nil;
+}
+
+- (int)horizontalDataRegions {
+ switch (_dataRegions) {
+ case 1:
+ return 1;
+ case 2:
+ return 2;
+ case 4:
+ return 2;
+ case 16:
+ return 4;
+ case 36:
+ return 6;
+ default:
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Cannot handle this number of data regions" userInfo:nil];
+ }
+}
+
+- (int)verticalDataRegions {
+ switch (_dataRegions) {
+ case 1:
+ return 1;
+ case 2:
+ return 1;
+ case 4:
+ return 2;
+ case 16:
+ return 4;
+ case 36:
+ return 6;
+ default:
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Cannot handle this number of data regions" userInfo:nil];
+ }
+}
+
+- (int)symbolDataWidth {
+ return [self horizontalDataRegions] * _matrixWidth;
+}
+
+- (int)symbolDataHeight {
+ return [self verticalDataRegions] * _matrixHeight;
+}
+
+- (int)symbolWidth {
+ return [self symbolDataWidth] + ([self horizontalDataRegions] * 2);
+}
+
+- (int)symbolHeight {
+ return [self symbolDataHeight] + ([self verticalDataRegions] * 2);
+}
+
+- (int)codewordCount {
+ return _dataCapacity + _errorCodewords;
+}
+
+- (int)interleavedBlockCount {
+ return _dataCapacity / _rsBlockData;
+}
+
+- (int)dataLengthForInterleavedBlock:(int)index {
+ return _rsBlockData;
+}
+
+- (int)errorLengthForInterleavedBlock:(int)index {
+ return _rsBlockError;
+}
+
+- (NSString *)description {
+ NSMutableString *sb = [NSMutableString string];
+ [sb appendString:_rectangular ? @"Rectangular Symbol:" : @"Square Symbol:"];
+ [sb appendFormat:@" data region %dx%d", _matrixWidth, _matrixHeight];
+ [sb appendFormat:@", symbol size %dx%d", [self symbolWidth], [self symbolHeight]];
+ [sb appendFormat:@", symbol data size %dx%d", [self symbolDataWidth], [self symbolDataHeight]];
+ [sb appendFormat:@", codewords %d+%d", _dataCapacity, _errorCodewords];
+ return [NSString stringWithString:sb];
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXSymbolShapeHint.h b/ZXingObjC/datamatrix/encoder/ZXSymbolShapeHint.h
new file mode 100644
index 0000000..45cf67e
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXSymbolShapeHint.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * Enumeration for DataMatrix symbol shape hint. It can be used to force square or rectangular
+ * symbols.
+ */
+
+@interface ZXSymbolShapeHint : NSObject
+
++ (ZXSymbolShapeHint *)forceNone;
++ (ZXSymbolShapeHint *)forceSquare;
++ (ZXSymbolShapeHint *)forceRectangle;
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXSymbolShapeHint.m b/ZXingObjC/datamatrix/encoder/ZXSymbolShapeHint.m
new file mode 100644
index 0000000..f9649d2
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXSymbolShapeHint.m
@@ -0,0 +1,51 @@
+/*
+ * 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 "ZXSymbolShapeHint.h"
+
+@implementation ZXSymbolShapeHint
+
++ (ZXSymbolShapeHint *)forceNone {
+ static ZXSymbolShapeHint *_forceNone = nil;
+
+ if (!_forceNone) {
+ _forceNone = [[ZXSymbolShapeHint alloc] init];
+ }
+
+ return _forceNone;
+}
+
++ (ZXSymbolShapeHint *)forceSquare {
+ static ZXSymbolShapeHint *_forceSquare = nil;
+
+ if (!_forceSquare) {
+ _forceSquare = [[ZXSymbolShapeHint alloc] init];
+ }
+
+ return _forceSquare;
+}
+
++ (ZXSymbolShapeHint *)forceRectangle {
+ static ZXSymbolShapeHint *_forceRectangle = nil;
+
+ if (!_forceRectangle) {
+ _forceRectangle = [[ZXSymbolShapeHint alloc] init];
+ }
+
+ return _forceRectangle;
+}
+
+@end
\ No newline at end of file
diff --git a/ZXingObjC/datamatrix/encoder/ZXTextEncoder.h b/ZXingObjC/datamatrix/encoder/ZXTextEncoder.h
new file mode 100644
index 0000000..f215934
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXTextEncoder.h
@@ -0,0 +1,21 @@
+/*
+ * 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 "ZXC40Encoder.h"
+
+@interface ZXTextEncoder : ZXC40Encoder
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXTextEncoder.m b/ZXingObjC/datamatrix/encoder/ZXTextEncoder.m
new file mode 100644
index 0000000..3612c7d
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXTextEncoder.m
@@ -0,0 +1,84 @@
+/*
+ * 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 "ZXHighLevelEncoder.h"
+#import "ZXTextEncoder.h"
+
+@implementation ZXTextEncoder
+
+- (int)encodingMode {
+ return [ZXHighLevelEncoder textEncodation];
+}
+
+- (int)encodeChar:(unichar)c buffer:(NSMutableString *)sb {
+ if (c == ' ') {
+ [sb appendString:@"\3"];
+ return 1;
+ }
+ if (c >= '0' && c <= '9') {
+ [sb appendFormat:@"%C", (unichar) (c - 48 + 4)];
+ return 1;
+ }
+ if (c >= 'a' && c <= 'z') {
+ [sb appendFormat:@"%C", (unichar) (c - 97 + 14)];
+ return 1;
+ }
+ if (c >= '\0' && c <= (char)0x001f) {
+ [sb appendString:@"\0"]; //Shift 1 Set
+ [sb appendFormat:@"%C", c];
+ return 2;
+ }
+ if (c >= '!' && c <= '/') {
+ [sb appendString:@"\1"]; //Shift 2 Set
+ [sb appendFormat:@"%C", (unichar) (c - 33)];
+ return 2;
+ }
+ if (c >= ':' && c <= '@') {
+ [sb appendString:@"\1"]; //Shift 2 Set
+ [sb appendFormat:@"%C", (unichar) (c - 58 + 15)];
+ return 2;
+ }
+ if (c >= '[' && c <= '_') {
+ [sb appendString:@"\1"]; //Shift 2 Set
+ [sb appendFormat:@"%C", (unichar) (c - 91 + 22)];
+ return 2;
+ }
+ if (c == '\u0060') {
+ [sb appendString:@"\2"]; //Shift 3 Set
+ [sb appendFormat:@"%C", (unichar) (c - 96)];
+ return 2;
+ }
+ if (c >= 'A' && c <= 'Z') {
+ [sb appendString:@"\2"]; //Shift 3 Set
+ [sb appendFormat:@"%C", (unichar) (c - 65 + 1)];
+ return 2;
+ }
+ if (c >= '{' && c <= (char)0x007f) {
+ [sb appendString:@"\2"]; //Shift 3 Set
+ [sb appendFormat:@"%C", (unichar) (c - 123 + 27)];
+ return 2;
+ }
+ if (c >= (unichar)0x0080) {
+ [sb appendFormat:@"\1%C", (unichar)0x001e]; //Shift 2, Upper Shift
+ int len = 2;
+ len += [self encodeChar:(unichar) (c - 128) buffer:sb];
+ return len;
+ }
+ [ZXHighLevelEncoder illegalCharacter:c];
+ return -1;
+}
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXX12Encoder.h b/ZXingObjC/datamatrix/encoder/ZXX12Encoder.h
new file mode 100644
index 0000000..1564a82
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXX12Encoder.h
@@ -0,0 +1,21 @@
+/*
+ * 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 "ZXC40Encoder.h"
+
+@interface ZXX12Encoder : ZXC40Encoder
+
+@end
diff --git a/ZXingObjC/datamatrix/encoder/ZXX12Encoder.m b/ZXingObjC/datamatrix/encoder/ZXX12Encoder.m
new file mode 100644
index 0000000..39f1735
--- /dev/null
+++ b/ZXingObjC/datamatrix/encoder/ZXX12Encoder.m
@@ -0,0 +1,88 @@
+/*
+ * 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 "ZXEncoderContext.h"
+#import "ZXHighLevelEncoder.h"
+#import "ZXSymbolInfo.h"
+#import "ZXX12Encoder.h"
+
+@implementation ZXX12Encoder
+
+- (int)encodingMode {
+ return [ZXHighLevelEncoder x12Encodation];
+}
+
+- (void)encode:(ZXEncoderContext *)context {
+ //step C
+ NSMutableString *buffer = [NSMutableString string];
+ while ([context hasMoreCharacters]) {
+ unichar c = [context currentChar];
+ context.pos++;
+
+ [self encodeChar:c buffer:buffer];
+
+ NSUInteger count = buffer.length;
+ if ((count % 3) == 0) {
+ [self writeNextTriplet:context buffer:buffer];
+
+ int newMode = [ZXHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]];
+ if (newMode != [self encodingMode]) {
+ [context signalEncoderChange:newMode];
+ break;
+ }
+ }
+ }
+ [self handleEOD:context buffer:buffer];
+}
+
+- (int)encodeChar:(unichar)c buffer:(NSMutableString *)sb {
+ if (c == '\r') {
+ [sb appendString:@"\0"];
+ } else if (c == '*') {
+ [sb appendString:@"\1"];
+ } else if (c == '>') {
+ [sb appendString:@"\2"];
+ } else if (c == ' ') {
+ [sb appendString:@"\3"];
+ } else if (c >= '0' && c <= '9') {
+ [sb appendFormat:@"%C", (unichar) (c - 48 + 4)];
+ } else if (c >= 'A' && c <= 'Z') {
+ [sb appendFormat:@"%C", (unichar) (c - 65 + 14)];
+ } else {
+ [ZXHighLevelEncoder illegalCharacter:c];
+ }
+ return 1;
+}
+
+- (void)handleEOD:(ZXEncoderContext *)context buffer:(NSMutableString *)buffer {
+ [context updateSymbolInfo];
+ int available = context.symbolInfo.dataCapacity - [context codewordCount];
+ NSUInteger count = buffer.length;
+ if (count == 2) {
+ [context writeCodeword:[ZXHighLevelEncoder x12Unlatch]];
+ context.pos -= 2;
+ [context signalEncoderChange:[ZXHighLevelEncoder asciiEncodation]];
+ } else if (count == 1) {
+ context.pos--;
+ if (available > 1) {
+ [context writeCodeword:[ZXHighLevelEncoder x12Unlatch]];
+ }
+ //NOP - No unlatch necessary
+ [context signalEncoderChange:[ZXHighLevelEncoder asciiEncodation]];
+ }
+}
+
+@end
diff --git a/ZXingObjC/maxicode/ZXMaxiCodeReader.h b/ZXingObjC/maxicode/ZXMaxiCodeReader.h
new file mode 100644
index 0000000..27f42b0
--- /dev/null
+++ b/ZXingObjC/maxicode/ZXMaxiCodeReader.h
@@ -0,0 +1,26 @@
+/*
+ * 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 "ZXReader.h"
+
+@class ZXBinaryBitmap, ZXDecodeHints, ZXResult;
+
+/**
+ * This implementation can detect and decode a MaxiCode in an image.
+ */
+@interface ZXMaxiCodeReader : NSObject <ZXReader>
+
+@end
diff --git a/ZXingObjC/maxicode/ZXMaxiCodeReader.m b/ZXingObjC/maxicode/ZXMaxiCodeReader.m
new file mode 100644
index 0000000..a4fe214
--- /dev/null
+++ b/ZXingObjC/maxicode/ZXMaxiCodeReader.m
@@ -0,0 +1,123 @@
+/*
+ * 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 "ZXBinaryBitmap.h"
+#import "ZXBitMatrix.h"
+#import "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXMaxiCodeDecoder.h"
+#import "ZXMaxiCodeReader.h"
+#import "ZXResult.h"
+
+const int MATRIX_WIDTH = 30;
+const int MATRIX_HEIGHT = 33;
+
+@interface ZXMaxiCodeReader ()
+
+@property (nonatomic, strong) ZXMaxiCodeDecoder *decoder;
+
+@end
+
+@implementation ZXMaxiCodeReader
+
+- (id)init {
+ if (self = [super init]) {
+ _decoder = [[ZXMaxiCodeDecoder alloc] init];
+ }
+
+ return self;
+}
+
+/**
+ * Locates and decodes a MaxiCode code in an image.
+ */
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decode:image hints:nil error:error];
+}
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXDecoderResult *decoderResult;
+ if (hints != nil && hints.pureBarcode) {
+ ZXBitMatrix *matrix = [image blackMatrixWithError:error];
+ if (!matrix) {
+ return nil;
+ }
+ ZXBitMatrix *bits = [self extractPureBits:matrix];
+ if (!bits) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ decoderResult = [self.decoder decode:bits hints:hints error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ } else {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ NSArray *points = @[];
+ ZXResult *result = [ZXResult resultWithText:decoderResult.text
+ rawBytes:decoderResult.rawBytes
+ length:decoderResult.length
+ resultPoints:points
+ format:kBarcodeFormatMaxiCode];
+
+ NSString *ecLevel = decoderResult.ecLevel;
+ if (ecLevel != nil) {
+ [result putMetadata:kResultMetadataTypeErrorCorrectionLevel value:ecLevel];
+ }
+ return result;
+}
+
+- (void)reset {
+ // do nothing
+}
+
+/**
+ * This method detects a code in a "pure" image -- that is, pure monochrome image
+ * which contains only an unrotated, unskewed, image of a code, with some white border
+ * around it. This is a specialized method that works exceptionally fast in this special
+ * case.
+ */
+- (ZXBitMatrix *)extractPureBits:(ZXBitMatrix *)image {
+ NSArray *enclosingRectangle = image.enclosingRectangle;
+ if (enclosingRectangle == nil) {
+ return nil;
+ }
+
+ int left = [enclosingRectangle[0] intValue];
+ int top = [enclosingRectangle[1] intValue];
+ int width = [enclosingRectangle[2] intValue];
+ int height = [enclosingRectangle[3] intValue];
+
+ // Now just read off the bits
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithWidth:MATRIX_WIDTH height:MATRIX_HEIGHT];
+ for (int y = 0; y < MATRIX_HEIGHT; y++) {
+ int iy = top + (y * height + height / 2) / MATRIX_HEIGHT;
+ for (int x = 0; x < MATRIX_WIDTH; x++) {
+ int ix = left + (x * width + width / 2 + (y & 0x01) * width / 2) / MATRIX_WIDTH;
+ if ([image getX:ix y:iy]) {
+ [bits setX:x y:y];
+ }
+ }
+ }
+
+ return bits;
+}
+
+@end
diff --git a/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.h b/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.h
new file mode 100644
index 0000000..c818a94
--- /dev/null
+++ b/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@class ZXBitMatrix;
+
+@interface ZXMaxiCodeBitMatrixParser : NSObject
+
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error;
+- (NSArray *)readCodewords;
+
+@end
diff --git a/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.m b/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.m
new file mode 100644
index 0000000..352f7ae
--- /dev/null
+++ b/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.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 "ZXBitMatrix.h"
+#import "ZXErrors.h"
+#import "ZXMaxiCodeBitMatrixParser.h"
+
+const int BITNR[33][30] = {
+ {121,120,127,126,133,132,139,138,145,144,151,150,157,156,163,162,169,168,175,174,181,180,187,186,193,192,199,198, -2, -2},
+ {123,122,129,128,135,134,141,140,147,146,153,152,159,158,165,164,171,170,177,176,183,182,189,188,195,194,201,200,816, -3},
+ {125,124,131,130,137,136,143,142,149,148,155,154,161,160,167,166,173,172,179,178,185,184,191,190,197,196,203,202,818,817},
+ {283,282,277,276,271,270,265,264,259,258,253,252,247,246,241,240,235,234,229,228,223,222,217,216,211,210,205,204,819, -3},
+ {285,284,279,278,273,272,267,266,261,260,255,254,249,248,243,242,237,236,231,230,225,224,219,218,213,212,207,206,821,820},
+ {287,286,281,280,275,274,269,268,263,262,257,256,251,250,245,244,239,238,233,232,227,226,221,220,215,214,209,208,822, -3},
+ {289,288,295,294,301,300,307,306,313,312,319,318,325,324,331,330,337,336,343,342,349,348,355,354,361,360,367,366,824,823},
+ {291,290,297,296,303,302,309,308,315,314,321,320,327,326,333,332,339,338,345,344,351,350,357,356,363,362,369,368,825, -3},
+ {293,292,299,298,305,304,311,310,317,316,323,322,329,328,335,334,341,340,347,346,353,352,359,358,365,364,371,370,827,826},
+ {409,408,403,402,397,396,391,390, 79, 78, -2, -2, 13, 12, 37, 36, 2, -1, 44, 43,109,108,385,384,379,378,373,372,828, -3},
+ {411,410,405,404,399,398,393,392, 81, 80, 40, -2, 15, 14, 39, 38, 3, -1, -1, 45,111,110,387,386,381,380,375,374,830,829},
+ {413,412,407,406,401,400,395,394, 83, 82, 41, -3, -3, -3, -3, -3, 5, 4, 47, 46,113,112,389,388,383,382,377,376,831, -3},
+ {415,414,421,420,427,426,103,102, 55, 54, 16, -3, -3, -3, -3, -3, -3, -3, 20, 19, 85, 84,433,432,439,438,445,444,833,832},
+ {417,416,423,422,429,428,105,104, 57, 56, -3, -3, -3, -3, -3, -3, -3, -3, 22, 21, 87, 86,435,434,441,440,447,446,834, -3},
+ {419,418,425,424,431,430,107,106, 59, 58, -3, -3, -3, -3, -3, -3, -3, -3, -3, 23, 89, 88,437,436,443,442,449,448,836,835},
+ {481,480,475,474,469,468, 48, -2, 30, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 0, 53, 52,463,462,457,456,451,450,837, -3},
+ {483,482,477,476,471,470, 49, -1, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -1,465,464,459,458,453,452,839,838},
+ {485,484,479,478,473,472, 51, 50, 31, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 1, -2, 42,467,466,461,460,455,454,840, -3},
+ {487,486,493,492,499,498, 97, 96, 61, 60, -3, -3, -3, -3, -3, -3, -3, -3, -3, 26, 91, 90,505,504,511,510,517,516,842,841},
+ {489,488,495,494,501,500, 99, 98, 63, 62, -3, -3, -3, -3, -3, -3, -3, -3, 28, 27, 93, 92,507,506,513,512,519,518,843, -3},
+ {491,490,497,496,503,502,101,100, 65, 64, 17, -3, -3, -3, -3, -3, -3, -3, 18, 29, 95, 94,509,508,515,514,521,520,845,844},
+ {559,558,553,552,547,546,541,540, 73, 72, 32, -3, -3, -3, -3, -3, -3, 10, 67, 66,115,114,535,534,529,528,523,522,846, -3},
+ {561,560,555,554,549,548,543,542, 75, 74, -2, -1, 7, 6, 35, 34, 11, -2, 69, 68,117,116,537,536,531,530,525,524,848,847},
+ {563,562,557,556,551,550,545,544, 77, 76, -2, 33, 9, 8, 25, 24, -1, -2, 71, 70,119,118,539,538,533,532,527,526,849, -3},
+ {565,564,571,570,577,576,583,582,589,588,595,594,601,600,607,606,613,612,619,618,625,624,631,630,637,636,643,642,851,850},
+ {567,566,573,572,579,578,585,584,591,590,597,596,603,602,609,608,615,614,621,620,627,626,633,632,639,638,645,644,852, -3},
+ {569,568,575,574,581,580,587,586,593,592,599,598,605,604,611,610,617,616,623,622,629,628,635,634,641,640,647,646,854,853},
+ {727,726,721,720,715,714,709,708,703,702,697,696,691,690,685,684,679,678,673,672,667,666,661,660,655,654,649,648,855, -3},
+ {729,728,723,722,717,716,711,710,705,704,699,698,693,692,687,686,681,680,675,674,669,668,663,662,657,656,651,650,857,856},
+ {731,730,725,724,719,718,713,712,707,706,701,700,695,694,689,688,683,682,677,676,671,670,665,664,659,658,653,652,858, -3},
+ {733,732,739,738,745,744,751,750,757,756,763,762,769,768,775,774,781,780,787,786,793,792,799,798,805,804,811,810,860,859},
+ {735,734,741,740,747,746,753,752,759,758,765,764,771,770,777,776,783,782,789,788,795,794,801,800,807,806,813,812,861, -3},
+ {737,736,743,742,749,748,755,754,761,760,767,766,773,772,779,778,785,784,791,790,797,796,803,802,809,808,815,814,863,862}
+};
+
+@interface ZXMaxiCodeBitMatrixParser ()
+
+@property (nonatomic, strong) ZXBitMatrix *bitMatrix;
+
+@end
+
+@implementation ZXMaxiCodeBitMatrixParser
+
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error {
+ if (self = [super init]) {
+ _bitMatrix = bitMatrix;
+ }
+
+ return self;
+}
+
+- (NSArray *)readCodewords {
+ const int resultLength = 144;
+ int8_t result[resultLength];
+ memset(result, 0, resultLength * sizeof(int8_t));
+
+ int height = self.bitMatrix.height;
+ int width = self.bitMatrix.width;
+ for (int y = 0; y < height; y++) {
+ int *bitnrRow = (int *)BITNR[y];
+ for (int x = 0; x < width; x++) {
+ int bit = bitnrRow[x];
+ if (bit >= 0 && [self.bitMatrix getX:x y:y]) {
+ result[bit / 6] |= (int8_t) (1 << (5 - (bit % 6)));
+ }
+ }
+ }
+
+ NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:resultLength];
+ for (int i = 0; i < resultLength; i++) {
+ [resultArray addObject:[NSNumber numberWithChar:result[i]]];
+ }
+
+ return resultArray;
+}
+
+@end
diff --git a/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.h b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.h
new file mode 100644
index 0000000..d30173e
--- /dev/null
+++ b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * MaxiCodes can encode text or structured information as bits in one of several modes,
+ * with multiple character sets in one code. This class decodes the bits back into text.
+ */
+
+@class ZXDecoderResult;
+
+@interface ZXMaxiCodeDecodedBitStreamParser : NSObject
+
++ (ZXDecoderResult *)decode:(int8_t *)bytes length:(unsigned int)length mode:(int)mode;
+
+@end
diff --git a/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m
new file mode 100644
index 0000000..5b05ed8
--- /dev/null
+++ b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m
@@ -0,0 +1,225 @@
+/*
+ * 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 "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXMaxiCodeDecodedBitStreamParser.h"
+
+const unichar SHIFTA = 0xFFF0;
+const unichar SHIFTB = 0xFFF1;
+const unichar SHIFTC = 0xFFF2;
+const unichar SHIFTD = 0xFFF3;
+const unichar SHIFTE = 0xFFF4;
+const unichar TWOSHIFTA = 0xFFF5;
+const unichar THREESHIFTA = 0xFFF6;
+const unichar LATCHA = 0xFFF7;
+const unichar LATCHB = 0xFFF8;
+const unichar LOCK = 0xFFF9;
+const unichar ECI = 0xFFFA;
+const unichar NS = 0xFFFB;
+const unichar PAD = 0xFFFC;
+const unichar FS = 0x001C;
+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
+};
+
+@implementation ZXMaxiCodeDecodedBitStreamParser
+
++ (ZXDecoderResult *)decode:(int8_t *)bytes length:(unsigned int)length mode:(int)mode {
+ NSMutableString *result = [NSMutableString stringWithCapacity:144];
+ switch (mode) {
+ case 2:
+ case 3: {
+ NSString *postcode;
+ if (mode == 2) {
+ int pc = [self postCode2:bytes length:length];
+ postcode = [NSString stringWithFormat:@"%9d", pc];
+ } else {
+ postcode = [self postCode3:bytes length:length];
+ }
+ NSString *country = [NSString stringWithFormat:@"%3d", [self country:bytes length:length]];
+ NSString *service = [NSString stringWithFormat:@"%3d", [self serviceClass:bytes length:length]];
+ [result appendString:[self message:bytes length:length start:10 len:84]];
+ if ([result hasPrefix:[NSString stringWithFormat:@"[)>%C01%C", RS, GS]]) {
+ [result insertString:[NSString stringWithFormat:@"%@%C%@%C%@%C", postcode, GS, country, GS, service, GS] atIndex:9];
+ } else {
+ [result insertString:[NSString stringWithFormat:@"%@%C%@%C%@%C", postcode, GS, country, GS, service, GS] atIndex:0];
+ }
+ break;
+ }
+ case 4:
+ [result appendString:[self message:bytes length:length start:1 len:93]];
+ break;
+ case 5:
+ [result appendString:[self message:bytes length:length start:1 len:77]];
+ break;
+ }
+ return [[ZXDecoderResult alloc] initWithRawBytes:bytes
+ length:length
+ text:result
+ byteSegments:nil
+ ecLevel:[NSString stringWithFormat:@"%d", mode]];
+}
+
++ (int)bit:(int)bit bytes:(int8_t *)bytes length:(unsigned int)length {
+ bit--;
+ return (bytes[bit / 6] & (1 << (5 - (bit % 6)))) == 0 ? 0 : 1;
+}
+
++ (int)integer:(int8_t *)bytes length:(unsigned int)length x:(int8_t *)x xLength:(unsigned int)xLength {
+ int val = 0;
+ for (int i = 0; i < xLength; i++) {
+ val += [self bit:x[i] bytes:bytes length:length] << (xLength - i - 1);
+ }
+ return val;
+}
+
+#define COUNTRY_ARRAY_LEN 10
++ (int)country:(int8_t *)bytes length:(unsigned int)length {
+ int8_t array[COUNTRY_ARRAY_LEN] = {53, 54, 43, 44, 45, 46, 47, 48, 37, 38};
+
+ return [self integer:bytes length:length x:array xLength:COUNTRY_ARRAY_LEN];
+}
+
+#define SERVICE_ARRAY_LEN 10
++ (int)serviceClass:(int8_t *)bytes length:(unsigned int)length {
+ int8_t array[SERVICE_ARRAY_LEN] = {55, 56, 57, 58, 59, 60, 49, 50, 51, 52};
+
+ return [self integer:bytes length:length x:array xLength:SERVICE_ARRAY_LEN];
+}
+
+#define POST_CODE2_LENGTH_LEN 10
++ (int)postCode2Length:(int8_t *)bytes length:(unsigned int)length {
+ int8_t array[POST_CODE2_LENGTH_LEN] = {39, 40, 41, 42, 31, 32};
+
+ return [self integer:bytes length:length x:array xLength:POST_CODE2_LENGTH_LEN];
+}
+
+#define POST_CODE2_LEN 30
++ (int)postCode2:(int8_t *)bytes length:(unsigned int)length {
+ int8_t array[POST_CODE2_LEN] = {33, 34, 35, 36, 25, 26, 27, 28, 29, 30, 19,
+ 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2};
+
+ return [self integer:bytes length:length x:array xLength:POST_CODE2_LEN];
+}
+
+#define POST_CODE3_LEN 6
++ (NSString *)postCode3:(int8_t *)bytes length:(unsigned int)length {
+ int8_t array[POST_CODE3_LEN][POST_CODE3_LEN] = {
+ {39, 40, 41, 42, 31, 32},
+ {33, 34, 35, 36, 25, 26},
+ {27, 28, 29, 30, 19, 20},
+ {21, 22, 23, 24, 13, 14},
+ {15, 16, 17, 18, 7, 8},
+ { 9, 10, 11, 12, 1, 2}
+ };
+
+ return [NSString stringWithFormat:@"%C%C%C%C%C%C",
+ SETS[0][[self integer:bytes length:length x:array[0] xLength:POST_CODE3_LEN]],
+ SETS[0][[self integer:bytes length:length x:array[1] xLength:POST_CODE3_LEN]],
+ SETS[0][[self integer:bytes length:length x:array[2] xLength:POST_CODE3_LEN]],
+ SETS[0][[self integer:bytes length:length x:array[3] xLength:POST_CODE3_LEN]],
+ SETS[0][[self integer:bytes length:length x:array[4] xLength:POST_CODE3_LEN]],
+ SETS[0][[self integer:bytes length:length x:array[5] xLength:POST_CODE3_LEN]]];
+}
+
++ (NSString *)message:(int8_t *)bytes length:(unsigned int)length start:(int)start len:(int)len {
+ NSMutableString *sb = [NSMutableString string];
+ int shift = -1;
+ int set = 0;
+ int lastset = 0;
+ for (int i = start; i < start + len; i++) {
+ unichar c = SETS[set][bytes[i]];
+ switch (c) {
+ case LATCHA:
+ set = 0;
+ shift = -1;
+ break;
+ case LATCHB:
+ set = 1;
+ shift = -1;
+ break;
+ case SHIFTA:
+ case SHIFTB:
+ case SHIFTC:
+ case SHIFTD:
+ case SHIFTE:
+ lastset = set;
+ set = c - SHIFTA;
+ shift = 1;
+ break;
+ case TWOSHIFTA:
+ lastset = set;
+ set = 0;
+ shift = 2;
+ break;
+ case THREESHIFTA:
+ lastset = set;
+ set = 0;
+ shift = 3;
+ break;
+ case NS: {
+ int nsval1 = bytes[++i] << 24;
+ int nsval2 = bytes[++i] << 18;
+ int nsval3 = bytes[++i] << 12;
+ int nsval4 = bytes[++i] << 6;
+ int nsval5 = bytes[++i];
+ int nsval = nsval1 + nsval2 + nsval3 + nsval4 + nsval5;
+ [sb appendFormat:@"%9d", nsval];
+ break;
+ }
+ case LOCK:
+ shift = -1;
+ break;
+ default:
+ [sb appendFormat:@"%C", c];
+ }
+ if (shift-- == 0) {
+ set = lastset;
+ }
+ }
+ while (sb.length > 0 && [sb characterAtIndex:sb.length - 1] == PAD) {
+ [sb deleteCharactersInRange:NSMakeRange(sb.length - 1, 1)];
+ }
+ return sb;
+}
+
+@end
diff --git a/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.h b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.h
new file mode 100644
index 0000000..e0cb928
--- /dev/null
+++ b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * The main class which implements MaxiCode decoding -- as opposed to locating and extracting
+ * the MaxiCode from an image.
+ */
+
+@class ZXBitMatrix, ZXDecodeHints, ZXDecoderResult;
+
+@interface ZXMaxiCodeDecoder : NSObject
+
+- (ZXDecoderResult *)decode:(ZXBitMatrix *)bits error:(NSError **)error;
+- (ZXDecoderResult *)decode:(ZXBitMatrix *)bits hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.m b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.m
new file mode 100644
index 0000000..0b11527
--- /dev/null
+++ b/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.m
@@ -0,0 +1,137 @@
+/*
+ * 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 "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXGenericGF.h"
+#import "ZXMaxiCodeBitMatrixParser.h"
+#import "ZXMaxiCodeDecodedBitStreamParser.h"
+#import "ZXMaxiCodeDecoder.h"
+#import "ZXReedSolomonDecoder.h"
+
+const int ALL = 0;
+const int EVEN = 1;
+const int ODD = 2;
+
+@interface ZXMaxiCodeDecoder ()
+
+@property (nonatomic, strong) ZXReedSolomonDecoder *rsDecoder;
+
+@end
+
+@implementation ZXMaxiCodeDecoder
+
+- (id)init {
+ if (self = [super init]) {
+ _rsDecoder = [[ZXReedSolomonDecoder alloc] initWithField:[ZXGenericGF MaxiCodeField64]];
+ }
+
+ return self;
+}
+
+- (ZXDecoderResult *)decode:(ZXBitMatrix *)bits error:(NSError **)error {
+ return [self decode:bits hints:nil error:error];
+}
+
+- (ZXDecoderResult *)decode:(ZXBitMatrix *)bits hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXMaxiCodeBitMatrixParser *parser = [[ZXMaxiCodeBitMatrixParser alloc] initWithBitMatrix:bits error:error];
+ if (!parser) {
+ return nil;
+ }
+ NSMutableArray *codewords = [[parser readCodewords] mutableCopy];
+
+ if (![self correctErrors:codewords start:0 dataCodewords:10 ecCodewords:10 mode:ALL error:error]) {
+ return nil;
+ }
+ int mode = [codewords[0] charValue] & 0x0F;
+ int datawordsLen;
+ switch (mode) {
+ case 2:
+ case 3:
+ case 4:
+ if (![self correctErrors:codewords start:20 dataCodewords:84 ecCodewords:40 mode:EVEN error:error]) {
+ return nil;
+ }
+ if (![self correctErrors:codewords start:20 dataCodewords:84 ecCodewords:40 mode:ODD error:error]) {
+ return nil;
+ }
+ datawordsLen = 94;
+ break;
+ case 5:
+ if (![self correctErrors:codewords start:20 dataCodewords:68 ecCodewords:56 mode:EVEN error:error]) {
+ return nil;
+ }
+ if (![self correctErrors:codewords start:20 dataCodewords:68 ecCodewords:56 mode:ODD error:error]) {
+ return nil;
+ }
+ datawordsLen = 78;
+ break;
+ default:
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ int8_t *datawords = (int8_t *)malloc(datawordsLen * sizeof(int8_t));
+ for (int i = 0; i < 10; i++) {
+ datawords[i] = [codewords[i] charValue];
+ }
+ for (int i = 20; i < datawordsLen + 10; i++) {
+ datawords[i - 10] = [codewords[i] charValue];
+ }
+
+ ZXDecoderResult *result = [ZXMaxiCodeDecodedBitStreamParser decode:datawords length:datawordsLen mode:mode];
+ free(datawords);
+ return result;
+}
+
+- (BOOL)correctErrors:(NSMutableArray *)codewordBytes start:(int)start dataCodewords:(int)dataCodewords
+ ecCodewords:(int)ecCodewords mode:(int)mode error:(NSError **)error {
+ int codewords = dataCodewords + ecCodewords;
+
+ // in EVEN or ODD mode only half the codewords
+ int divisor = mode == ALL ? 1 : 2;
+
+ // First read into an array of ints
+ int codewordsIntsLen = codewords / divisor;
+ int *codewordsInts = (int *)malloc(codewordsIntsLen * sizeof(int));
+ memset(codewordsInts, 0, codewordsIntsLen * sizeof(int));
+ for (int i = 0; i < codewords; i++) {
+ if ((mode == ALL) || (i % 2 == (mode - 1))) {
+ codewordsInts[i / divisor] = [codewordBytes[i + start] charValue] & 0xFF;
+ }
+ }
+
+ NSError *decodeError = nil;
+ if (![self.rsDecoder decode:codewordsInts receivedLen:codewordsIntsLen twoS:ecCodewords / divisor error:&decodeError]) {
+ if (decodeError.code == ZXReedSolomonError && error) {
+ *error = ChecksumErrorInstance();
+ }
+ return NO;
+ }
+ // Copy back into array of bytes -- only need to worry about the bytes that were data
+ // We don't care about errors in the error-correction codewords
+ for (int i = 0; i < dataCodewords; i++) {
+ if ((mode == ALL) || (i % 2 == (mode - 1))) {
+ codewordBytes[i + start] = [NSNumber numberWithChar:codewordsInts[i / divisor]];
+ }
+ }
+
+ return YES;
+}
+
+@end
diff --git a/ZXingObjC/multi/ZXByQuadrantReader.h b/ZXingObjC/multi/ZXByQuadrantReader.h
new file mode 100644
index 0000000..14aab08
--- /dev/null
+++ b/ZXingObjC/multi/ZXByQuadrantReader.h
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXReader.h"
+
+/**
+ * This class attempts to decode a barcode from an image, not by scanning the whole image,
+ * but by scanning subsets of the image. This is important when there may be multiple barcodes in
+ * an image, and detecting a barcode may find parts of multiple barcode and fail to decode
+ * (e.g. QR Codes). Instead this scans the four quadrants of the image -- and also the center
+ * 'quadrant' to cover the case where a barcode is found in the center.
+ */
+
+@interface ZXByQuadrantReader : NSObject <ZXReader>
+
+- (id)initWithDelegate:(id<ZXReader>)delegate;
+
+@end
diff --git a/ZXingObjC/multi/ZXByQuadrantReader.m b/ZXingObjC/multi/ZXByQuadrantReader.m
new file mode 100644
index 0000000..9a8f40e
--- /dev/null
+++ b/ZXingObjC/multi/ZXByQuadrantReader.m
@@ -0,0 +1,99 @@
+/*
+ * 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 "ZXBinaryBitmap.h"
+#import "ZXByQuadrantReader.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXResult.h"
+
+@interface ZXByQuadrantReader ()
+
+@property (nonatomic, weak) id<ZXReader> delegate;
+
+@end
+
+@implementation ZXByQuadrantReader
+
+- (id)initWithDelegate:(id<ZXReader>)delegate {
+ if (self = [super init]) {
+ _delegate = delegate;
+ }
+
+ return self;
+}
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decode:image hints:nil error:error];
+}
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ int width = image.width;
+ int height = image.height;
+ int halfWidth = width / 2;
+ int halfHeight = height / 2;
+
+ ZXBinaryBitmap *topLeft = [image crop:0 top:0 width:halfWidth height:halfHeight];
+ NSError *decodeError = nil;
+ ZXResult *result = [self.delegate decode:topLeft hints:hints error:&decodeError];
+ if (result) {
+ return result;
+ } else if (decodeError.code != ZXNotFoundError) {
+ if (error) *error = decodeError;
+ return nil;
+ }
+
+ ZXBinaryBitmap *topRight = [image crop:halfWidth top:0 width:halfWidth height:halfHeight];
+ decodeError = nil;
+ result = [self.delegate decode:topRight hints:hints error:&decodeError];
+ if (result) {
+ return result;
+ } else if (decodeError.code != ZXNotFoundError) {
+ if (error) *error = decodeError;
+ return nil;
+ }
+
+ ZXBinaryBitmap *bottomLeft = [image crop:0 top:halfHeight width:halfWidth height:halfHeight];
+ decodeError = nil;
+ result = [self.delegate decode:bottomLeft hints:hints error:&decodeError];
+ if (result) {
+ return result;
+ } else if (decodeError.code != ZXNotFoundError) {
+ if (error) *error = decodeError;
+ return nil;
+ }
+
+ ZXBinaryBitmap *bottomRight = [image crop:halfWidth top:halfHeight width:halfWidth height:halfHeight];
+ decodeError = nil;
+ result = [self.delegate decode:bottomRight hints:hints error:&decodeError];
+ if (result) {
+ return result;
+ } else if (decodeError.code != ZXNotFoundError) {
+ if (error) *error = decodeError;
+ return nil;
+ }
+
+ int quarterWidth = halfWidth / 2;
+ int quarterHeight = halfHeight / 2;
+ ZXBinaryBitmap *center = [image crop:quarterWidth top:quarterHeight width:halfWidth height:halfHeight];
+ return [self.delegate decode:center hints:hints error:error];
+}
+
+- (void)reset {
+ [self.delegate reset];
+}
+
+@end
diff --git a/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.h b/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.h
new file mode 100644
index 0000000..0df8a15
--- /dev/null
+++ b/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.h
@@ -0,0 +1,38 @@
+/*
+ * 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 "ZXMultipleBarcodeReader.h"
+
+/**
+ * Attempts to locate multiple barcodes in an image by repeatedly decoding portion of the image.
+ * After one barcode is found, the areas left, above, right and below the barcode's
+ * ZXResultPoints are scanned, recursively.
+ *
+ * A caller may want to also employ ZXByQuadrantReader when attempting to find multiple
+ * 2D barcodes, like QR Codes, in an image, where the presence of multiple barcodes might prevent
+ * detecting any one of them.
+ *
+ * That is, instead of passing an ZXReader a caller might pass
+ * [[ZXByQuadrantReader alloc] initWithDelegate:reader]</code>.
+ */
+
+@protocol ZXReader;
+
+@interface ZXGenericMultipleBarcodeReader : NSObject <ZXMultipleBarcodeReader>
+
+- (id)initWithDelegate:(id<ZXReader>)delegate;
+
+@end
diff --git a/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m b/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m
new file mode 100644
index 0000000..8a71225
--- /dev/null
+++ b/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m
@@ -0,0 +1,135 @@
+/*
+ * 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 "ZXErrors.h"
+#import "ZXGenericMultipleBarcodeReader.h"
+#import "ZXReader.h"
+#import "ZXResultPoint.h"
+
+int const MIN_DIMENSION_TO_RECUR = 100;
+int const MAX_DEPTH = 4;
+
+@interface ZXGenericMultipleBarcodeReader ()
+
+@property (nonatomic, weak) id<ZXReader> delegate;
+
+@end
+
+@implementation ZXGenericMultipleBarcodeReader
+
+- (id)initWithDelegate:(id<ZXReader>)delegate {
+ if (self = [super init]) {
+ _delegate = delegate;
+ }
+
+ return self;
+}
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decodeMultiple:image hints:nil error:error];
+}
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ NSMutableArray *results = [NSMutableArray array];
+ if (![self doDecodeMultiple:image hints:hints results:results xOffset:0 yOffset:0 currentDepth:0 error:error]) {
+ return nil;
+ } else if (results.count == 0) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ return results;
+}
+
+- (BOOL)doDecodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints results:(NSMutableArray *)results
+ xOffset:(int)xOffset yOffset:(int)yOffset currentDepth:(int)currentDepth error:(NSError **)error {
+ if (currentDepth > MAX_DEPTH) {
+ return YES;
+ }
+
+ ZXResult *result = [self.delegate decode:image hints:hints error:error];
+ if (!result) {
+ return NO;
+ }
+
+ BOOL alreadyFound = NO;
+ for (ZXResult *existingResult in results) {
+ if ([[existingResult text] isEqualToString:[result text]]) {
+ alreadyFound = YES;
+ break;
+ }
+ }
+ if (!alreadyFound) {
+ [results addObject:[self translateResultPoints:result xOffset:xOffset yOffset:yOffset]];
+ }
+ NSMutableArray *resultPoints = [result resultPoints];
+ if (resultPoints == nil || [resultPoints count] == 0) {
+ return YES;
+ }
+ int width = [image width];
+ int height = [image height];
+ float minX = width;
+ float minY = height;
+ float maxX = 0.0f;
+ float maxY = 0.0f;
+ for (ZXResultPoint *point in resultPoints) {
+ float x = [point x];
+ float y = [point y];
+ if (x < minX) {
+ minX = x;
+ }
+ if (y < minY) {
+ minY = y;
+ }
+ if (x > maxX) {
+ maxX = x;
+ }
+ if (y > maxY) {
+ maxY = y;
+ }
+ }
+
+ if (minX > MIN_DIMENSION_TO_RECUR) {
+ return [self doDecodeMultiple:[image crop:0 top:0 width:(int)minX height:height] hints:hints results:results xOffset:xOffset yOffset:yOffset currentDepth:currentDepth + 1 error:error];
+ }
+ if (minY > MIN_DIMENSION_TO_RECUR) {
+ return [self doDecodeMultiple:[image crop:0 top:0 width:width height:(int)minY] hints:hints results:results xOffset:xOffset yOffset:yOffset currentDepth:currentDepth + 1 error:error];
+ }
+ if (maxX < width - MIN_DIMENSION_TO_RECUR) {
+ return [self doDecodeMultiple:[image crop:(int)maxX top:0 width:width - (int)maxX height:height] hints:hints results:results xOffset:xOffset + (int)maxX yOffset:yOffset currentDepth:currentDepth + 1 error:error];
+ }
+ if (maxY < height - MIN_DIMENSION_TO_RECUR) {
+ return [self doDecodeMultiple:[image crop:0 top:(int)maxY width:width height:height - (int)maxY] hints:hints results:results xOffset:xOffset yOffset:yOffset + (int)maxY currentDepth:currentDepth + 1 error:error];
+ }
+
+ return YES;
+}
+
+- (ZXResult *)translateResultPoints:(ZXResult *)result xOffset:(int)xOffset yOffset:(int)yOffset {
+ NSArray *oldResultPoints = [result resultPoints];
+ if (oldResultPoints == nil) {
+ return result;
+ }
+ NSMutableArray *newResultPoints = [NSMutableArray arrayWithCapacity:[oldResultPoints count]];
+ for (ZXResultPoint *oldPoint in oldResultPoints) {
+ [newResultPoints addObject:[[ZXResultPoint alloc] initWithX:[oldPoint x] + xOffset y:[oldPoint y] + yOffset]];
+ }
+
+ ZXResult *newResult = [ZXResult resultWithText:result.text rawBytes:result.rawBytes length:result.length resultPoints:newResultPoints format:result.barcodeFormat];
+ [newResult putAllMetadata:result.resultMetadata];
+ return newResult;
+}
+
+@end
diff --git a/ZXingObjC/multi/ZXMultipleBarcodeReader.h b/ZXingObjC/multi/ZXMultipleBarcodeReader.h
new file mode 100644
index 0000000..e2fd647
--- /dev/null
+++ b/ZXingObjC/multi/ZXMultipleBarcodeReader.h
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXBinaryBitmap.h"
+#import "ZXResult.h"
+
+/**
+ * Implementation of this interface attempt to read several barcodes from one image.
+ */
+
+@class ZXDecodeHints;
+
+@protocol ZXMultipleBarcodeReader <NSObject>
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error;
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/multi/qrcode/ZXQRCodeMultiReader.h b/ZXingObjC/multi/qrcode/ZXQRCodeMultiReader.h
new file mode 100644
index 0000000..f6d80b6
--- /dev/null
+++ b/ZXingObjC/multi/qrcode/ZXQRCodeMultiReader.h
@@ -0,0 +1,26 @@
+/*
+ * 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 "ZXMultipleBarcodeReader.h"
+#import "ZXQRCodeReader.h"
+
+/**
+ * This implementation can detect and decode multiple QR Codes in an image.
+ */
+
+@interface ZXQRCodeMultiReader : ZXQRCodeReader <ZXMultipleBarcodeReader>
+
+@end
diff --git a/ZXingObjC/multi/qrcode/ZXQRCodeMultiReader.m b/ZXingObjC/multi/qrcode/ZXQRCodeMultiReader.m
new file mode 100644
index 0000000..c762f93
--- /dev/null
+++ b/ZXingObjC/multi/qrcode/ZXQRCodeMultiReader.m
@@ -0,0 +1,64 @@
+/*
+ * 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 "ZXDecoderResult.h"
+#import "ZXDetectorResult.h"
+#import "ZXMultiDetector.h"
+#import "ZXQRCodeDecoder.h"
+#import "ZXQRCodeMultiReader.h"
+#import "ZXResult.h"
+
+@implementation ZXQRCodeMultiReader
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decodeMultiple:image hints:nil error:error];
+}
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXBitMatrix *matrix = [image blackMatrixWithError:error];
+ if (!matrix) {
+ return nil;
+ }
+ NSMutableArray *results = [NSMutableArray array];
+ NSArray *detectorResult = [[[ZXMultiDetector alloc] initWithImage:matrix] detectMulti:hints error:error];
+ if (!detectorResult) {
+ return nil;
+ }
+ for (int i = 0; i < [detectorResult count]; i++) {
+ ZXDecoderResult *decoderResult = [[self decoder] decodeMatrix:[(ZXDetectorResult *)detectorResult[i] bits] hints:hints error:nil];
+ if (decoderResult) {
+ NSArray *points = [(ZXDetectorResult *)detectorResult[i] points];
+ ZXResult *result = [ZXResult resultWithText:decoderResult.text
+ rawBytes:decoderResult.rawBytes
+ length:decoderResult.length
+ resultPoints:points
+ format:kBarcodeFormatQRCode];
+ NSMutableArray *byteSegments = decoderResult.byteSegments;
+ if (byteSegments != nil) {
+ [result putMetadata:kResultMetadataTypeByteSegments value:byteSegments];
+ }
+ NSString *ecLevel = decoderResult.ecLevel;
+ if (ecLevel != nil) {
+ [result putMetadata:kResultMetadataTypeErrorCorrectionLevel value:ecLevel];
+ }
+ [results addObject:result];
+ }
+ }
+
+ return results;
+}
+
+@end
diff --git a/ZXingObjC/multi/qrcode/detector/ZXMultiDetector.h b/ZXingObjC/multi/qrcode/detector/ZXMultiDetector.h
new file mode 100644
index 0000000..348b768
--- /dev/null
+++ b/ZXingObjC/multi/qrcode/detector/ZXMultiDetector.h
@@ -0,0 +1,30 @@
+/*
+ * 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 "ZXQRCodeDetector.h"
+
+/**
+ * Encapsulates logic that can detect one or more QR Codes in an image, even if the QR Code
+ * is rotated or skewed, or partially obscured.
+ */
+
+@class ZXDecodeHints;
+
+@interface ZXMultiDetector : ZXQRCodeDetector
+
+- (NSArray *)detectMulti:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/multi/qrcode/detector/ZXMultiDetector.m b/ZXingObjC/multi/qrcode/detector/ZXMultiDetector.m
new file mode 100644
index 0000000..dca7baa
--- /dev/null
+++ b/ZXingObjC/multi/qrcode/detector/ZXMultiDetector.m
@@ -0,0 +1,45 @@
+/*
+ * 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 "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXMultiDetector.h"
+#import "ZXMultiFinderPatternFinder.h"
+#import "ZXResultPointCallback.h"
+
+@implementation ZXMultiDetector
+
+- (NSArray *)detectMulti:(ZXDecodeHints *)hints error:(NSError **)error {
+ id<ZXResultPointCallback> resultPointCallback = hints == nil ? nil : hints.resultPointCallback;
+ ZXMultiFinderPatternFinder *finder = [[ZXMultiFinderPatternFinder alloc] initWithImage:self.image resultPointCallback:resultPointCallback];
+ NSArray *info = [finder findMulti:hints error:error];
+ if ([info count] == 0) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ NSMutableArray *result = [NSMutableArray array];
+ for (int i = 0; i < [info count]; i++) {
+ ZXDetectorResult *patternInfo = [self processFinderPatternInfo:info[i] error:nil];
+ if (patternInfo) {
+ [result addObject:patternInfo];
+ }
+ }
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/multi/qrcode/detector/ZXMultiFinderPatternFinder.h b/ZXingObjC/multi/qrcode/detector/ZXMultiFinderPatternFinder.h
new file mode 100644
index 0000000..6faf80d
--- /dev/null
+++ b/ZXingObjC/multi/qrcode/detector/ZXMultiFinderPatternFinder.h
@@ -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 "ZXFinderPatternFinder.h"
+
+/**
+ * This class attempts to find finder patterns in a QR Code. Finder patterns are the square
+ * markers at three corners of a QR Code.
+ *
+ * This class is thread-safe but not reentrant. Each thread must allocate its own object.
+ *
+ * In contrast to ZXFinderPatternFinder, this class will return an array of all possible
+ * QR code locations in the image.
+ *
+ * Use the tryHarder hint to ask for a more thorough detection.
+ */
+
+@class ZXDecodeHints;
+
+@interface ZXMultiFinderPatternFinder : ZXFinderPatternFinder
+
+- (NSArray *)findMulti:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/multi/qrcode/detector/ZXMultiFinderPatternFinder.m b/ZXingObjC/multi/qrcode/detector/ZXMultiFinderPatternFinder.m
new file mode 100644
index 0000000..994a94a
--- /dev/null
+++ b/ZXingObjC/multi/qrcode/detector/ZXMultiFinderPatternFinder.m
@@ -0,0 +1,239 @@
+/*
+ * 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 "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXFinderPatternInfo.h"
+#import "ZXMultiFinderPatternFinder.h"
+#import "ZXQRCodeFinderPattern.h"
+
+// TODO MIN_MODULE_COUNT and MAX_MODULE_COUNT would be great hints to ask the user for
+// since it limits the number of regions to decode
+
+// max. legal count of modules per QR code edge (177)
+float const MAX_MODULE_COUNT_PER_EDGE = 180;
+// min. legal count per modules per QR code edge (11)
+float const MIN_MODULE_COUNT_PER_EDGE = 9;
+
+/**
+ * More or less arbitrary cutoff point for determining if two finder patterns might belong
+ * to the same code if they differ less than DIFF_MODSIZE_CUTOFF_PERCENT percent in their
+ * estimated modules sizes.
+ */
+float const DIFF_MODSIZE_CUTOFF_PERCENT = 0.05f;
+
+/**
+ * More or less arbitrary cutoff point for determining if two finder patterns might belong
+ * to the same code if they differ less than DIFF_MODSIZE_CUTOFF pixels/module in their
+ * estimated modules sizes.
+ */
+float const DIFF_MODSIZE_CUTOFF = 0.5f;
+
+@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
+ * size differs from the average among those patterns the least
+ */
+- (NSArray *)selectBestPatternsWithError:(NSError **)error {
+ NSMutableArray *_possibleCenters = [NSMutableArray arrayWithArray:[self possibleCenters]];
+ NSUInteger size = [_possibleCenters count];
+
+ if (size < 3) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ /*
+ * Begin HE modifications to safely detect multiple codes of equal size
+ */
+ if (size == 3) {
+ return @[@[_possibleCenters[0], _possibleCenters[1], _possibleCenters[2]]];
+ }
+
+ [_possibleCenters sortUsingFunction:moduleSizeCompare context:nil];
+
+ /*
+ * Now lets start: build a list of tuples of three finder locations that
+ * - feature similar module sizes
+ * - are placed in a distance so the estimated module count is within the QR specification
+ * - have similar distance between upper left/right and left top/bottom finder patterns
+ * - form a triangle with 90° angle (checked by comparing top right/bottom left distance
+ * with pythagoras)
+ *
+ * Note: we allow each point to be used for more than one code region: this might seem
+ * counterintuitive at first, but the performance penalty is not that big. At this point,
+ * we cannot make a good quality decision whether the three finders actually represent
+ * a QR code, or are just by chance layouted so it looks like there might be a QR code there.
+ * So, if the layout seems right, lets have the decoder try to decode.
+ */
+
+ NSMutableArray *results = [NSMutableArray array];
+
+ for (int i1 = 0; i1 < (size - 2); i1++) {
+ ZXQRCodeFinderPattern *p1 = self.possibleCenters[i1];
+ if (p1 == nil) {
+ continue;
+ }
+
+ for (int i2 = i1 + 1; i2 < (size - 1); i2++) {
+ ZXQRCodeFinderPattern *p2 = self.possibleCenters[i2];
+ if (p2 == nil) {
+ continue;
+ }
+
+ float vModSize12 = ([p1 estimatedModuleSize] - [p2 estimatedModuleSize]) / MIN([p1 estimatedModuleSize], [p2 estimatedModuleSize]);
+ float vModSize12A = fabsf([p1 estimatedModuleSize] - [p2 estimatedModuleSize]);
+ if (vModSize12A > DIFF_MODSIZE_CUTOFF && vModSize12 >= DIFF_MODSIZE_CUTOFF_PERCENT) {
+ break;
+ }
+
+ for (int i3 = i2 + 1; i3 < size; i3++) {
+ ZXQRCodeFinderPattern *p3 = self.possibleCenters[i3];
+ if (p3 == nil) {
+ continue;
+ }
+
+ float vModSize23 = ([p2 estimatedModuleSize] - [p3 estimatedModuleSize]) / MIN([p2 estimatedModuleSize], [p3 estimatedModuleSize]);
+ float vModSize23A = fabsf([p2 estimatedModuleSize] - [p3 estimatedModuleSize]);
+ if (vModSize23A > DIFF_MODSIZE_CUTOFF && vModSize23 >= DIFF_MODSIZE_CUTOFF_PERCENT) {
+ break;
+ }
+
+ NSMutableArray *test = [NSMutableArray arrayWithObjects:p1, p2, p3, nil];
+ [ZXResultPoint orderBestPatterns:test];
+
+ ZXFinderPatternInfo *info = [[ZXFinderPatternInfo alloc] initWithPatternCenters:test];
+ float dA = [ZXResultPoint distance:[info topLeft] pattern2:[info bottomLeft]];
+ float dC = [ZXResultPoint distance:[info topRight] pattern2:[info bottomLeft]];
+ float dB = [ZXResultPoint distance:[info topLeft] pattern2:[info topRight]];
+
+ float estimatedModuleCount = (dA + dB) / ([p1 estimatedModuleSize] * 2.0f);
+ if (estimatedModuleCount > MAX_MODULE_COUNT_PER_EDGE || estimatedModuleCount < MIN_MODULE_COUNT_PER_EDGE) {
+ continue;
+ }
+
+ float vABBC = fabsf((dA - dB) / MIN(dA, dB));
+ if (vABBC >= 0.1f) {
+ continue;
+ }
+
+ float dCpy = (float)sqrt(dA * dA + dB * dB);
+ float vPyC = fabsf((dC - dCpy) / MIN(dC, dCpy));
+
+ if (vPyC >= 0.1f) {
+ continue;
+ }
+
+ [results addObject:test];
+ }
+ }
+ }
+
+ if ([results count] > 0) {
+ return results;
+ }
+
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+}
+
+- (NSArray *)findMulti:(ZXDecodeHints *)hints error:(NSError **)error {
+ BOOL tryHarder = hints != nil && hints.tryHarder;
+ int maxI = self.image.height;
+ int maxJ = self.image.width;
+ // We are looking for black/white/black/white/black modules in
+ // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far
+
+ // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the
+ // 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 / (FINDER_PATTERN_MAX_MODULES * 4.0f) * 3);
+ if (iSkip < FINDER_PATTERN_MIN_SKIP || tryHarder) {
+ iSkip = FINDER_PATTERN_MIN_SKIP;
+ }
+
+ int stateCount[5];
+ for (int i = iSkip - 1; i < maxI; i += iSkip) {
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ stateCount[3] = 0;
+ stateCount[4] = 0;
+ int currentState = 0;
+
+ for (int j = 0; j < maxJ; j++) {
+ if ([self.image getX:j y:i]) {
+ if ((currentState & 1) == 1) {
+ currentState++;
+ }
+ stateCount[currentState]++;
+ } else {
+ if ((currentState & 1) == 0) {
+ if (currentState == 4) {
+ if ([ZXFinderPatternFinder foundPatternCross:stateCount] && [self handlePossibleCenter:stateCount i:i j:j]) {
+ currentState = 0;
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ stateCount[3] = 0;
+ stateCount[4] = 0;
+ } else {
+ stateCount[0] = stateCount[2];
+ stateCount[1] = stateCount[3];
+ stateCount[2] = stateCount[4];
+ stateCount[3] = 1;
+ stateCount[4] = 0;
+ currentState = 3;
+ }
+ } else {
+ stateCount[++currentState]++;
+ }
+ } else {
+ stateCount[currentState]++;
+ }
+ }
+ }
+
+ if ([ZXFinderPatternFinder foundPatternCross:stateCount]) {
+ [self handlePossibleCenter:stateCount i:i j:maxJ];
+ }
+ }
+ NSArray *patternInfo = [self selectBestPatternsWithError:error];
+ if (!patternInfo) {
+ return nil;
+ }
+ NSMutableArray *result = [NSMutableArray array];
+ for (NSMutableArray *pattern in patternInfo) {
+ [ZXResultPoint orderBestPatterns:pattern];
+ [result addObject:[[ZXFinderPatternInfo alloc] initWithPatternCenters:pattern]];
+ }
+
+ return result;
+}
+
+/**
+ * A comparator that orders FinderPatterns by their estimated module size.
+ */
+NSInteger moduleSizeCompare(id center1, id center2, void *context) {
+ float value = [((ZXQRCodeFinderPattern *)center2) estimatedModuleSize] - [((ZXQRCodeFinderPattern *)center1) estimatedModuleSize];
+ return value < 0.0 ? -1 : value > 0.0 ? 1 : 0;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXCodaBarReader.h b/ZXingObjC/oned/ZXCodaBarReader.h
new file mode 100644
index 0000000..b850d66
--- /dev/null
+++ b/ZXingObjC/oned/ZXCodaBarReader.h
@@ -0,0 +1,32 @@
+/*
+ * 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 "ZXOneDReader.h"
+
+extern const int CODA_ALPHABET_LEN;
+extern const char CODA_ALPHABET[];
+extern const int CODA_CHARACTER_ENCODINGS[];
+
+@class ZXBitArray, ZXDecodeHints, ZXResult;
+
+/**
+ * Decodes Codabar barcodes.
+ */
+@interface ZXCodaBarReader : ZXOneDReader
+
++ (BOOL)arrayContains:(char *)array length:(unsigned int)length key:(unichar)key;
+
+@end
diff --git a/ZXingObjC/oned/ZXCodaBarReader.m b/ZXingObjC/oned/ZXCodaBarReader.m
new file mode 100644
index 0000000..298b1a6
--- /dev/null
+++ b/ZXingObjC/oned/ZXCodaBarReader.m
@@ -0,0 +1,371 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXCodaBarReader.h"
+#import "ZXErrors.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+// These values are critical for determining how permissive the decoding
+// will be. All stripe sizes must be within the window these define, as
+// compared to the average stripe size.
+static int MAX_ACCEPTABLE;
+static int PADDING;
+
+const int CODA_ALPHABET_LEN = 22;
+const char CODA_ALPHABET[CODA_ALPHABET_LEN] = "0123456789-$:/.+ABCDTN";
+
+/**
+ * These represent the encodings of characters, as patterns of wide and narrow bars. The 7 least-significant bits of
+ * each int correspond to the pattern of wide and narrow, with 1s representing "wide" and 0s representing narrow.
+ */
+const int CODA_CHARACTER_ENCODINGS_LEN = 20;
+const int CODA_CHARACTER_ENCODINGS[CODA_CHARACTER_ENCODINGS_LEN] = {
+ 0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, // 0-9
+ 0x00c, 0x018, 0x045, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E, // -$:/.+ABCD
+};
+
+// minimal number of characters that should be present (inclusing start and stop characters)
+// under normal circumstances this should be set to 3, but can be set higher
+// as a last-ditch attempt to reduce false positives.
+const int MIN_CHARACTER_LENGTH = 3;
+
+// official start and end patterns
+const int STARTEND_ENCODING_LEN = 4;
+const char STARTEND_ENCODING[STARTEND_ENCODING_LEN] = {'A', 'B', 'C', 'D'};
+
+// some codabar generator allow the codabar string to be closed by every
+// character. This will cause lots of false positives!
+
+// some industries use a checksum standard but this is not part of the original codabar standard
+// for more information see : http://www.mecsw.com/specs/codabar.html
+
+@interface ZXCodaBarReader ()
+
+@property (nonatomic, strong) NSMutableString *decodeRowResult;
+@property (nonatomic, assign) int *counters;
+@property (nonatomic, assign) int countersLen;
+@property (nonatomic, assign) int counterLength;
+
+@end
+
+@implementation ZXCodaBarReader
+
++ (void)initialize {
+ MAX_ACCEPTABLE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 2.0f);
+ PADDING = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 1.5f);
+}
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeRowResult = [NSMutableString stringWithCapacity:20];
+ _countersLen = 80;
+ _counters = (int *)malloc(_countersLen * sizeof(int));
+ memset(_counters, 0, _countersLen * sizeof(int));
+ _counterLength = 0;
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_counters != NULL) {
+ free(_counters);
+ _counters = NULL;
+ }
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ if (![self setCountersWithRow:row]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ int startOffset = [self findStartPattern];
+ if (startOffset == -1) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ int nextStart = startOffset;
+
+ self.decodeRowResult = [NSMutableString string];
+ do {
+ int charOffset = [self toNarrowWidePattern:nextStart];
+ if (charOffset == -1) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ // Hack: We store the position in the alphabet table into a
+ // NSMutableString, so that we can access the decoded patterns in
+ // validatePattern. We'll translate to the actual characters later.
+ [self.decodeRowResult appendFormat:@"%C", (unichar)charOffset];
+ nextStart += 8;
+ // Stop as soon as we see the end character.
+ if (self.decodeRowResult.length > 1 &&
+ [ZXCodaBarReader arrayContains:(char *)STARTEND_ENCODING length:STARTEND_ENCODING_LEN key:CODA_ALPHABET[charOffset]]) {
+ break;
+ }
+ } while (nextStart < self.counterLength); // no fixed end pattern so keep on reading while data is available
+
+ // Look for whitespace after pattern:
+ int trailingWhitespace = self.counters[nextStart - 1];
+ int lastPatternSize = 0;
+ for (int i = -8; i < -1; i++) {
+ lastPatternSize += self.counters[nextStart + i];
+ }
+
+ // We need to see whitespace equal to 50% of the last pattern size,
+ // otherwise this is probably a false positive. The exception is if we are
+ // at the end of the row. (I.e. the barcode barely fits.)
+ if (nextStart < self.counterLength && trailingWhitespace < lastPatternSize / 2) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ if (![self validatePattern:startOffset]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ // Translate character table offsets to actual characters.
+ for (int i = 0; i < self.decodeRowResult.length; i++) {
+ [self.decodeRowResult replaceCharactersInRange:NSMakeRange(i, 1) withString:[NSString stringWithFormat:@"%c", CODA_ALPHABET[[self.decodeRowResult characterAtIndex:i]]]];
+ }
+ // Ensure a valid start and end character
+ unichar startchar = [self.decodeRowResult characterAtIndex:0];
+ if (![ZXCodaBarReader arrayContains:(char *)STARTEND_ENCODING length:STARTEND_ENCODING_LEN key:startchar]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ unichar endchar = [self.decodeRowResult characterAtIndex:self.decodeRowResult.length - 1];
+ if (![ZXCodaBarReader arrayContains:(char *)STARTEND_ENCODING length:STARTEND_ENCODING_LEN key:endchar]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ // remove stop/start characters character and check if a long enough string is contained
+ if (self.decodeRowResult.length <= MIN_CHARACTER_LENGTH) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ [self.decodeRowResult deleteCharactersInRange:NSMakeRange(self.decodeRowResult.length - 1, 1)];
+ [self.decodeRowResult deleteCharactersInRange:NSMakeRange(0, 1)];
+
+ int runningCount = 0;
+ for (int i = 0; i < startOffset; i++) {
+ runningCount += self.counters[i];
+ }
+ float left = (float) runningCount;
+ for (int i = startOffset; i < nextStart - 1; i++) {
+ runningCount += self.counters[i];
+ }
+ float right = (float) runningCount;
+ return [ZXResult resultWithText:self.decodeRowResult
+ rawBytes:nil
+ length:0
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
+ format:kBarcodeFormatCodabar];
+}
+
+- (BOOL)validatePattern:(int)start {
+ // First, sum up the total size of our four categories of stripe sizes;
+ int sizes[4] = {0, 0, 0, 0};
+ int counts[4] = {0, 0, 0, 0};
+ int end = (int)self.decodeRowResult.length - 1;
+
+ // We break out of this loop in the middle, in order to handle
+ // inter-character spaces properly.
+ int pos = start;
+ for (int i = 0; true; i++) {
+ int pattern = CODA_CHARACTER_ENCODINGS[[self.decodeRowResult characterAtIndex:i]];
+ for (int j = 6; j >= 0; j--) {
+ // Even j = bars, while odd j = spaces. Categories 2 and 3 are for
+ // long stripes, while 0 and 1 are for short stripes.
+ int category = (j & 1) + (pattern & 1) * 2;
+ sizes[category] += self.counters[pos + j];
+ counts[category]++;
+ pattern >>= 1;
+ }
+ if (i >= end) {
+ break;
+ }
+ // We ignore the inter-character space - it could be of any size.
+ pos += 8;
+ }
+
+ // Calculate our allowable size thresholds using fixed-point math.
+ int maxes[4] = {0};
+ int mins[4] = {0};
+ // Define the threshold of acceptability to be the midpoint between the
+ // average small stripe and the average large stripe. No stripe lengths
+ // should be on the "wrong" side of that line.
+ for (int i = 0; i < 2; i++) {
+ mins[i] = 0; // Accept arbitrarily small "short" stripes.
+ mins[i + 2] = ((sizes[i] << INTEGER_MATH_SHIFT) / counts[i] +
+ (sizes[i + 2] << INTEGER_MATH_SHIFT) / counts[i + 2]) >> 1;
+ maxes[i] = mins[i + 2];
+ maxes[i + 2] = (sizes[i + 2] * MAX_ACCEPTABLE + PADDING) / counts[i + 2];
+ }
+
+ // Now verify that all of the stripes are within the thresholds.
+ pos = start;
+ for (int i = 0; true; i++) {
+ int pattern = CODA_CHARACTER_ENCODINGS[[self.decodeRowResult characterAtIndex:i]];
+ for (int j = 6; j >= 0; j--) {
+ // Even j = bars, while odd j = spaces. Categories 2 and 3 are for
+ // long stripes, while 0 and 1 are for short stripes.
+ int category = (j & 1) + (pattern & 1) * 2;
+ int size = self.counters[pos + j] << INTEGER_MATH_SHIFT;
+ if (size < mins[category] || size > maxes[category]) {
+ return NO;
+ }
+ pattern >>= 1;
+ }
+ if (i >= end) {
+ break;
+ }
+ pos += 8;
+ }
+
+ return YES;
+}
+
+/**
+ * Records the size of all runs of white and black pixels, starting with white.
+ * This is just like recordPattern, except it records all the counters, and
+ * uses our builtin "counters" member for storage.
+ */
+- (BOOL)setCountersWithRow:(ZXBitArray *)row {
+ self.counterLength = 0;
+ // Start from the first white bit.
+ int i = [row nextUnset:0];
+ int end = row.size;
+ if (i >= end) {
+ return NO;
+ }
+ BOOL isWhite = YES;
+ int count = 0;
+ for (; i < end; i++) {
+ if ([row get:i] ^ isWhite) { // that is, exactly one is true
+ count++;
+ } else {
+ [self counterAppend:count];
+ count = 1;
+ isWhite = !isWhite;
+ }
+ }
+ [self counterAppend:count];
+ return YES;
+}
+
+- (void)counterAppend:(int)e {
+ self.counters[self.counterLength] = e;
+ self.counterLength++;
+ if (self.counterLength >= self.countersLen) {
+ int *temp = (int *)malloc(2 * self.counterLength * sizeof(int));
+ memcpy(temp, self.counters, self.countersLen * sizeof(int));
+ self.counters = temp;
+ memset(self.counters, 0, 2 * self.counterLength * sizeof(int));
+ self.countersLen = 2 * self.counterLength;
+ }
+}
+
+- (int)findStartPattern {
+ for (int i = 1; i < self.counterLength; i += 2) {
+ int charOffset = [self toNarrowWidePattern:i];
+ if (charOffset != -1 && [[self class] arrayContains:(char *)STARTEND_ENCODING length:STARTEND_ENCODING_LEN key:CODA_ALPHABET[charOffset]]) {
+ // Look for whitespace before start pattern, >= 50% of width of start pattern
+ // We make an exception if the whitespace is the first element.
+ int patternSize = 0;
+ for (int j = i; j < i + 7; j++) {
+ patternSize += self.counters[j];
+ }
+ if (i == 1 || self.counters[i-1] >= patternSize / 2) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+
++ (BOOL)arrayContains:(char *)array length:(unsigned int)length key:(unichar)key {
+ if (array != nil) {
+ for (int i = 0; i < length; i++) {
+ if (array[i] == key) {
+ return YES;
+ }
+ }
+ }
+ return NO;
+}
+
+// Assumes that counters[position] is a bar.
+- (int)toNarrowWidePattern:(int)position {
+ int end = position + 7;
+ if (end >= self.counterLength) {
+ return -1;
+ }
+
+ int maxBar = 0;
+ int minBar = INT_MAX;
+ for (int j = position; j < end; j += 2) {
+ int currentCounter = self.counters[j];
+ if (currentCounter < minBar) {
+ minBar = currentCounter;
+ }
+ if (currentCounter > maxBar) {
+ maxBar = currentCounter;
+ }
+ }
+ int thresholdBar = (minBar + maxBar) / 2;
+
+ int maxSpace = 0;
+ int minSpace = INT_MAX;
+ for (int j = position + 1; j < end; j += 2) {
+ int currentCounter = self.counters[j];
+ if (currentCounter < minSpace) {
+ minSpace = currentCounter;
+ }
+ if (currentCounter > maxSpace) {
+ maxSpace = currentCounter;
+ }
+ }
+ int thresholdSpace = (minSpace + maxSpace) / 2;
+
+ int bitmask = 1 << 7;
+ int pattern = 0;
+ for (int i = 0; i < 7; i++) {
+ int threshold = (i & 1) == 0 ? thresholdBar : thresholdSpace;
+ bitmask >>= 1;
+ if (self.counters[position + i] > threshold) {
+ pattern |= bitmask;
+ }
+ }
+
+ for (int i = 0; i < CODA_CHARACTER_ENCODINGS_LEN; i++) {
+ if (CODA_CHARACTER_ENCODINGS[i] == pattern) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXCodaBarWriter.h b/ZXingObjC/oned/ZXCodaBarWriter.h
new file mode 100644
index 0000000..a07648a
--- /dev/null
+++ b/ZXingObjC/oned/ZXCodaBarWriter.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 "ZXOneDimensionalCodeWriter.h"
+
+@interface ZXCodaBarWriter : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/ZXingObjC/oned/ZXCodaBarWriter.m b/ZXingObjC/oned/ZXCodaBarWriter.m
new file mode 100644
index 0000000..0555e1e
--- /dev/null
+++ b/ZXingObjC/oned/ZXCodaBarWriter.m
@@ -0,0 +1,110 @@
+/*
+ * 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 "ZXCodaBarReader.h"
+#import "ZXCodaBarWriter.h"
+
+const int START_CHARS_LEN = 4;
+const char START_CHARS[START_CHARS_LEN] = "ABCD";
+
+const int END_CHARS_LEN = 4;
+const char END_CHARS[END_CHARS_LEN] = "TN*E";
+
+@implementation ZXCodaBarWriter
+
+- (BOOL *)encode:(NSString *)contents length:(int *)pLength {
+ // Verify input and calculate decoded length.
+ if (![ZXCodaBarReader arrayContains:(char *)START_CHARS length:START_CHARS_LEN key:[[contents uppercaseString] characterAtIndex:0]]) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Codabar should start with one of the following: %@", [NSString stringWithCString:START_CHARS encoding:NSUTF8StringEncoding]]
+ userInfo:nil];
+ }
+ if (![ZXCodaBarReader arrayContains:(char *)END_CHARS length:END_CHARS_LEN key:[[contents uppercaseString] characterAtIndex:contents.length - 1]]) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Codabar should end with one of the following: %@", [NSString stringWithCString:END_CHARS encoding:NSUTF8StringEncoding]]
+ userInfo:nil];
+ }
+ // The start character and the end character are decoded to 10 length each.
+ int resultLength = 20;
+ char charsWhichAreTenLengthEachAfterDecoded[4] = {'/', ':', '+', '.'};
+ for (int i = 1; i < contents.length - 1; i++) {
+ if (([contents characterAtIndex:i] >= '0' && [contents characterAtIndex:i] <= '9') ||
+ [contents characterAtIndex:i] == '-' || [contents characterAtIndex:i] == '$') {
+ resultLength += 9;
+ } else if ([ZXCodaBarReader arrayContains:charsWhichAreTenLengthEachAfterDecoded length:4 key:[contents characterAtIndex:i]]) {
+ resultLength += 10;
+ } else {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Cannot encode : '%C'", [contents characterAtIndex:i]]
+ userInfo:nil];
+ }
+ }
+ // A blank is placed between each character.
+ resultLength += contents.length - 1;
+
+ if (pLength) *pLength = resultLength;
+ BOOL *result = (BOOL *)malloc(resultLength * sizeof(BOOL));
+ int position = 0;
+ for (int index = 0; index < contents.length; index++) {
+ unichar c = [[contents uppercaseString] characterAtIndex:index];
+ if (index == contents.length - 1) {
+ // The end chars are not in the CodaBarReader.ALPHABET.
+ switch (c) {
+ case 'T':
+ c = 'A';
+ break;
+ case 'N':
+ c = 'B';
+ break;
+ case '*':
+ c = 'C';
+ break;
+ case 'E':
+ c = 'D';
+ break;
+ }
+ }
+ int code = 0;
+ for (int i = 0; i < CODA_ALPHABET_LEN; i++) {
+ // Found any, because I checked above.
+ if (c == CODA_ALPHABET[i]) {
+ code = CODA_CHARACTER_ENCODINGS[i];
+ break;
+ }
+ }
+ BOOL color = YES;
+ int counter = 0;
+ int bit = 0;
+ while (bit < 7) { // A character consists of 7 digit.
+ result[position] = color;
+ position++;
+ if (((code >> (6 - bit)) & 1) == 0 || counter == 1) {
+ color = !color; // Flip the color.
+ bit++;
+ counter = 0;
+ } else {
+ counter++;
+ }
+ }
+ if (index < contents.length - 1) {
+ result[position] = NO;
+ position++;
+ }
+ }
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXCode128Reader.h b/ZXingObjC/oned/ZXCode128Reader.h
new file mode 100644
index 0000000..093ac40
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode128Reader.h
@@ -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 "ZXOneDReader.h"
+
+/**
+ * Decodes Code 128 barcodes.
+ */
+
+extern const int CODE_PATTERNS[][7];
+
+extern const int CODE_START_B;
+extern const int CODE_START_C;
+extern const int CODE_CODE_B;
+extern const int CODE_CODE_C;
+extern const int CODE_STOP;
+
+extern int const CODE_FNC_1;
+extern int const CODE_FNC_2;
+extern int const CODE_FNC_3;
+extern int const CODE_FNC_4_A;
+extern int const CODE_FNC_4_B;
+
+@class ZXDecodeHints, ZXResult;
+
+@interface ZXCode128Reader : ZXOneDReader
+
+@end
diff --git a/ZXingObjC/oned/ZXCode128Reader.m b/ZXingObjC/oned/ZXCode128Reader.m
new file mode 100644
index 0000000..eb7a5f3
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode128Reader.m
@@ -0,0 +1,511 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXCode128Reader.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXOneDReader.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+#define CODE_PATTERNS_LENGTH 107
+#define countersLength 7
+
+const int CODE_PATTERNS[CODE_PATTERNS_LENGTH][countersLength] = {
+ {2, 1, 2, 2, 2, 2}, // 0
+ {2, 2, 2, 1, 2, 2},
+ {2, 2, 2, 2, 2, 1},
+ {1, 2, 1, 2, 2, 3},
+ {1, 2, 1, 3, 2, 2},
+ {1, 3, 1, 2, 2, 2}, // 5
+ {1, 2, 2, 2, 1, 3},
+ {1, 2, 2, 3, 1, 2},
+ {1, 3, 2, 2, 1, 2},
+ {2, 2, 1, 2, 1, 3},
+ {2, 2, 1, 3, 1, 2}, // 10
+ {2, 3, 1, 2, 1, 2},
+ {1, 1, 2, 2, 3, 2},
+ {1, 2, 2, 1, 3, 2},
+ {1, 2, 2, 2, 3, 1},
+ {1, 1, 3, 2, 2, 2}, // 15
+ {1, 2, 3, 1, 2, 2},
+ {1, 2, 3, 2, 2, 1},
+ {2, 2, 3, 2, 1, 1},
+ {2, 2, 1, 1, 3, 2},
+ {2, 2, 1, 2, 3, 1}, // 20
+ {2, 1, 3, 2, 1, 2},
+ {2, 2, 3, 1, 1, 2},
+ {3, 1, 2, 1, 3, 1},
+ {3, 1, 1, 2, 2, 2},
+ {3, 2, 1, 1, 2, 2}, // 25
+ {3, 2, 1, 2, 2, 1},
+ {3, 1, 2, 2, 1, 2},
+ {3, 2, 2, 1, 1, 2},
+ {3, 2, 2, 2, 1, 1},
+ {2, 1, 2, 1, 2, 3}, // 30
+ {2, 1, 2, 3, 2, 1},
+ {2, 3, 2, 1, 2, 1},
+ {1, 1, 1, 3, 2, 3},
+ {1, 3, 1, 1, 2, 3},
+ {1, 3, 1, 3, 2, 1}, // 35
+ {1, 1, 2, 3, 1, 3},
+ {1, 3, 2, 1, 1, 3},
+ {1, 3, 2, 3, 1, 1},
+ {2, 1, 1, 3, 1, 3},
+ {2, 3, 1, 1, 1, 3}, // 40
+ {2, 3, 1, 3, 1, 1},
+ {1, 1, 2, 1, 3, 3},
+ {1, 1, 2, 3, 3, 1},
+ {1, 3, 2, 1, 3, 1},
+ {1, 1, 3, 1, 2, 3}, // 45
+ {1, 1, 3, 3, 2, 1},
+ {1, 3, 3, 1, 2, 1},
+ {3, 1, 3, 1, 2, 1},
+ {2, 1, 1, 3, 3, 1},
+ {2, 3, 1, 1, 3, 1}, // 50
+ {2, 1, 3, 1, 1, 3},
+ {2, 1, 3, 3, 1, 1},
+ {2, 1, 3, 1, 3, 1},
+ {3, 1, 1, 1, 2, 3},
+ {3, 1, 1, 3, 2, 1}, // 55
+ {3, 3, 1, 1, 2, 1},
+ {3, 1, 2, 1, 1, 3},
+ {3, 1, 2, 3, 1, 1},
+ {3, 3, 2, 1, 1, 1},
+ {3, 1, 4, 1, 1, 1}, // 60
+ {2, 2, 1, 4, 1, 1},
+ {4, 3, 1, 1, 1, 1},
+ {1, 1, 1, 2, 2, 4},
+ {1, 1, 1, 4, 2, 2},
+ {1, 2, 1, 1, 2, 4}, // 65
+ {1, 2, 1, 4, 2, 1},
+ {1, 4, 1, 1, 2, 2},
+ {1, 4, 1, 2, 2, 1},
+ {1, 1, 2, 2, 1, 4},
+ {1, 1, 2, 4, 1, 2}, // 70
+ {1, 2, 2, 1, 1, 4},
+ {1, 2, 2, 4, 1, 1},
+ {1, 4, 2, 1, 1, 2},
+ {1, 4, 2, 2, 1, 1},
+ {2, 4, 1, 2, 1, 1}, // 75
+ {2, 2, 1, 1, 1, 4},
+ {4, 1, 3, 1, 1, 1},
+ {2, 4, 1, 1, 1, 2},
+ {1, 3, 4, 1, 1, 1},
+ {1, 1, 1, 2, 4, 2}, // 80
+ {1, 2, 1, 1, 4, 2},
+ {1, 2, 1, 2, 4, 1},
+ {1, 1, 4, 2, 1, 2},
+ {1, 2, 4, 1, 1, 2},
+ {1, 2, 4, 2, 1, 1}, // 85
+ {4, 1, 1, 2, 1, 2},
+ {4, 2, 1, 1, 1, 2},
+ {4, 2, 1, 2, 1, 1},
+ {2, 1, 2, 1, 4, 1},
+ {2, 1, 4, 1, 2, 1}, // 90
+ {4, 1, 2, 1, 2, 1},
+ {1, 1, 1, 1, 4, 3},
+ {1, 1, 1, 3, 4, 1},
+ {1, 3, 1, 1, 4, 1},
+ {1, 1, 4, 1, 1, 3}, // 95
+ {1, 1, 4, 3, 1, 1},
+ {4, 1, 1, 1, 1, 3},
+ {4, 1, 1, 3, 1, 1},
+ {1, 1, 3, 1, 4, 1},
+ {1, 1, 4, 1, 3, 1}, // 100
+ {3, 1, 1, 1, 4, 1},
+ {4, 1, 1, 1, 3, 1},
+ {2, 1, 1, 4, 1, 2},
+ {2, 1, 1, 2, 1, 4},
+ {2, 1, 1, 2, 3, 2}, // 105
+ {2, 3, 3, 1, 1, 1, 2}
+};
+
+static int MAX_AVG_VARIANCE = -1;
+static int MAX_INDIVIDUAL_VARIANCE = -1;
+
+int const CODE_SHIFT = 98;
+int const CODE_CODE_C = 99;
+int const CODE_CODE_B = 100;
+int const CODE_CODE_A = 101;
+int const CODE_FNC_1 = 102;
+int const CODE_FNC_2 = 97;
+int const CODE_FNC_3 = 96;
+int const CODE_FNC_4_A = 101;
+int const CODE_FNC_4_B = 100;
+int const CODE_START_A = 103;
+int const CODE_START_B = 104;
+int const CODE_START_C = 105;
+int const CODE_STOP = 106;
+
+@implementation ZXCode128Reader
+
++ (void)initialize {
+ if (MAX_AVG_VARIANCE == -1) {
+ MAX_AVG_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.25f);
+ }
+
+ if (MAX_INDIVIDUAL_VARIANCE == -1) {
+ MAX_INDIVIDUAL_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f);
+ }
+}
+
+- (NSArray *)findStartPattern:(ZXBitArray *)row {
+ int width = row.size;
+ int rowOffset = [row nextSet:0];
+
+ int counterPosition = 0;
+
+ const int patternLength = 6;
+ int counters[patternLength];
+ memset(counters, 0, patternLength * sizeof(int));
+
+ int patternStart = rowOffset;
+ BOOL isWhite = NO;
+
+ for (int i = rowOffset; i < width; i++) {
+ if ([row get:i] ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ int bestVariance = MAX_AVG_VARIANCE;
+ int bestMatch = -1;
+ for (int startCode = CODE_START_A; startCode <= CODE_START_C; startCode++) {
+ int variance = [ZXOneDReader patternMatchVariance:counters countersSize:patternLength pattern:(int *)CODE_PATTERNS[startCode] maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE];
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = startCode;
+ }
+ }
+ // Look for whitespace before start pattern, >= 50% of width of start pattern
+ if (bestMatch >= 0 &&
+ [row isRange:MAX(0, patternStart - (i - patternStart) / 2) end:patternStart value:NO]) {
+ return @[@(patternStart), @(i), @(bestMatch)];
+ }
+ patternStart += counters[0] + counters[1];
+ for (int y = 2; y < patternLength; y++) {
+ counters[y - 2] = counters[y];
+ }
+ counters[patternLength - 2] = 0;
+ counters[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return nil;
+}
+
+- (int)decodeCode:(ZXBitArray *)row counters:(int[])counters countersCount:(int)countersCount rowOffset:(int)rowOffset {
+ if (![ZXOneDReader recordPattern:row start:rowOffset counters:counters countersSize:countersCount]) {
+ return -1;
+ }
+ int bestVariance = MAX_AVG_VARIANCE;
+ int bestMatch = -1;
+
+ for (int d = 0; d < CODE_PATTERNS_LENGTH; d++) {
+ int *pattern = (int *)CODE_PATTERNS[d];
+ int variance = [ZXOneDReader patternMatchVariance:counters countersSize:countersCount pattern:pattern maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE];
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = d;
+ }
+ }
+
+ if (bestMatch >= 0) {
+ return bestMatch;
+ } else {
+ return -1;
+ }
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ BOOL convertFNC1 = hints && hints.assumeGS1;
+
+ NSArray *startPatternInfo = [self findStartPattern:row];
+ if (!startPatternInfo) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ int startCode = [startPatternInfo[2] intValue];
+ int codeSet;
+
+ switch (startCode) {
+ case CODE_START_A:
+ codeSet = CODE_CODE_A;
+ break;
+ case CODE_START_B:
+ codeSet = CODE_CODE_B;
+ break;
+ case CODE_START_C:
+ codeSet = CODE_CODE_C;
+ break;
+ default:
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+
+ BOOL done = NO;
+ BOOL isNextShifted = NO;
+
+ NSMutableString *result = [NSMutableString stringWithCapacity:20];
+ NSMutableArray *rawCodes = [NSMutableArray arrayWithCapacity:20];
+
+ int lastStart = [startPatternInfo[0] intValue];
+ int nextStart = [startPatternInfo[1] intValue];
+
+ const int countersLen = 6;
+ int counters[countersLen];
+ memset(counters, 0, countersLen * sizeof(int));
+
+ int lastCode = 0;
+ int code = 0;
+ int checksumTotal = startCode;
+ int multiplier = 0;
+ BOOL lastCharacterWasPrintable = YES;
+
+ while (!done) {
+ BOOL unshift = isNextShifted;
+ isNextShifted = NO;
+
+ // Save off last code
+ lastCode = code;
+
+ // Decode another code from image
+ code = [self decodeCode:row counters:counters countersCount:countersLen rowOffset:nextStart];
+ if (code == -1) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ [rawCodes addObject:[NSNumber numberWithChar:(int8_t)code]];
+
+ // Remember whether the last code was printable or not (excluding CODE_STOP)
+ if (code != CODE_STOP) {
+ lastCharacterWasPrintable = YES;
+ }
+
+ // Add to checksum computation (if not CODE_STOP of course)
+ if (code != CODE_STOP) {
+ multiplier++;
+ checksumTotal += multiplier * code;
+ }
+
+ // Advance to where the next code will to start
+ lastStart = nextStart;
+ for (int i = 0; i < countersLen; i++) {
+ nextStart += counters[i];
+ }
+
+ // Take care of illegal start codes
+ switch (code) {
+ case CODE_START_A:
+ case CODE_START_B:
+ case CODE_START_C:
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+
+ switch (codeSet) {
+ case CODE_CODE_A:
+ if (code < 64) {
+ [result appendFormat:@"%C", (unichar)(' ' + code)];
+ } else if (code < 96) {
+ [result appendFormat:@"%C", (unichar)(code - 64)];
+ } else {
+ // Don't let CODE_STOP, which always appears, affect whether whether we think the last
+ // code was printable or not.
+ if (code != CODE_STOP) {
+ lastCharacterWasPrintable = NO;
+ }
+
+ switch (code) {
+ case CODE_FNC_1:
+ if (convertFNC1) {
+ if (result.length == 0) {
+ // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
+ // is FNC1 then this is GS1-128. We add the symbology identifier.
+ [result appendString:@"]C1"];
+ } else {
+ // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
+ [result appendFormat:@"%c", (char) 29];
+ }
+ }
+ break;
+ case CODE_FNC_2:
+ case CODE_FNC_3:
+ case CODE_FNC_4_A:
+ break;
+ case CODE_SHIFT:
+ isNextShifted = YES;
+ codeSet = CODE_CODE_B;
+ break;
+ case CODE_CODE_B:
+ codeSet = CODE_CODE_B;
+ break;
+ case CODE_CODE_C:
+ codeSet = CODE_CODE_C;
+ break;
+ case CODE_STOP:
+ done = YES;
+ break;
+ }
+ }
+ break;
+ case CODE_CODE_B:
+ if (code < 96) {
+ [result appendFormat:@"%C", (unichar)(' ' + code)];
+ } else {
+ if (code != CODE_STOP) {
+ lastCharacterWasPrintable = NO;
+ }
+
+ switch (code) {
+ case CODE_FNC_1:
+ if (convertFNC1) {
+ if (result.length == 0) {
+ // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
+ // is FNC1 then this is GS1-128. We add the symbology identifier.
+ [result appendString:@"]C1"];
+ } else {
+ // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
+ [result appendFormat:@"%c", (char) 29];
+ }
+ }
+ break;
+ case CODE_FNC_2:
+ case CODE_FNC_3:
+ case CODE_FNC_4_B:
+ break;
+ case CODE_SHIFT:
+ isNextShifted = YES;
+ codeSet = CODE_CODE_A;
+ break;
+ case CODE_CODE_A:
+ codeSet = CODE_CODE_A;
+ break;
+ case CODE_CODE_C:
+ codeSet = CODE_CODE_C;
+ break;
+ case CODE_STOP:
+ done = YES;
+ break;
+ }
+ }
+ break;
+ case CODE_CODE_C:
+ if (code < 100) {
+ if (code < 10) {
+ [result appendString:@"0"];
+ }
+ [result appendFormat:@"%d", code];
+ } else {
+ if (code != CODE_STOP) {
+ lastCharacterWasPrintable = NO;
+ }
+
+ switch (code) {
+ case CODE_FNC_1:
+ if (convertFNC1) {
+ if (result.length == 0) {
+ // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
+ // is FNC1 then this is GS1-128. We add the symbology identifier.
+ [result appendString:@"]C1"];
+ } else {
+ // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
+ [result appendFormat:@"%c", (char) 29];
+ }
+ }
+ break;
+ case CODE_CODE_A:
+ codeSet = CODE_CODE_A;
+ break;
+ case CODE_CODE_B:
+ codeSet = CODE_CODE_B;
+ break;
+ case CODE_STOP:
+ done = YES;
+ break;
+ }
+ }
+ break;
+ }
+
+ // Unshift back to another code set if we were shifted
+ if (unshift) {
+ codeSet = codeSet == CODE_CODE_A ? CODE_CODE_B : CODE_CODE_A;
+ }
+ }
+
+ // Check for ample whitespace following pattern, but, to do this we first need to remember that
+ // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left
+ // to read off. Would be slightly better to properly read. Here we just skip it:
+ nextStart = [row nextUnset:nextStart];
+ if (![row isRange:nextStart end:MIN(row.size, nextStart + (nextStart - lastStart) / 2) value:NO]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ // Pull out from sum the value of the penultimate check code
+ checksumTotal -= multiplier * lastCode;
+ // lastCode is the checksum then:
+ if (checksumTotal % 103 != lastCode) {
+ if (error) *error = ChecksumErrorInstance();
+ return nil;
+ }
+
+ // Need to pull out the check digits from string
+ NSUInteger resultLength = [result length];
+ if (resultLength == 0) {
+ // false positive
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ // Only bother if the result had at least one character, and if the checksum digit happened to
+ // be a printable character. If it was just interpreted as a control code, nothing to remove.
+ if (resultLength > 0 && lastCharacterWasPrintable) {
+ if (codeSet == CODE_CODE_C) {
+ [result deleteCharactersInRange:NSMakeRange(resultLength - 2, 2)];
+ } else {
+ [result deleteCharactersInRange:NSMakeRange(resultLength - 1, 1)];
+ }
+ }
+
+ float left = (float)([startPatternInfo[1] intValue] + [startPatternInfo[0] intValue]) / 2.0f;
+ float right = (float)(nextStart + lastStart) / 2.0f;
+
+ NSUInteger rawCodesSize = [rawCodes count];
+ int8_t rawBytes[rawCodesSize];
+ for (int i = 0; i < rawCodesSize; i++) {
+ rawBytes[i] = [rawCodes[i] charValue];
+ }
+
+ return [ZXResult resultWithText:result
+ rawBytes:rawBytes
+ length:(int)rawCodesSize
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
+ format:kBarcodeFormatCode128];
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXCode128Writer.h b/ZXingObjC/oned/ZXCode128Writer.h
new file mode 100644
index 0000000..99fe048
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode128Writer.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXOneDimensionalCodeWriter.h"
+
+/**
+ * This object renders a CODE128 code as a ZXBitMatrix.
+ */
+
+@interface ZXCode128Writer : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/ZXingObjC/oned/ZXCode128Writer.m b/ZXingObjC/oned/ZXCode128Writer.m
new file mode 100644
index 0000000..be0255a
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode128Writer.m
@@ -0,0 +1,191 @@
+/*
+ * 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 "ZXCode128Reader.h"
+#import "ZXCode128Writer.h"
+
+// Dummy characters used to specify control characters in input
+const unichar ESCAPE_FNC_1 = L'\u00f1';
+const unichar ESCAPE_FNC_2 = L'\u00f2';
+const unichar ESCAPE_FNC_3 = L'\u00f3';
+const unichar ESCAPE_FNC_4 = L'\u00f4';
+
+@implementation ZXCode128Writer
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if (format != kBarcodeFormatCode128) {
+ [NSException raise:NSInvalidArgumentException format:@"Can only encode CODE_128"];
+ }
+ return [super encode:contents format:format width:width height:height hints:hints error:error];
+}
+
+- (BOOL *)encode:(NSString *)contents length:(int *)pLength {
+ int length = (int)[contents length];
+ // Check length
+ if (length < 1 || length > 80) {
+ [NSException raise:NSInvalidArgumentException format:@"Contents length should be between 1 and 80 characters, but got %d", length];
+ }
+ // Check content
+ for (int i = 0; i < length; i++) {
+ unichar c = [contents characterAtIndex:i];
+ if (c < ' ' || c > '~') {
+ switch (c) {
+ case ESCAPE_FNC_1:
+ case ESCAPE_FNC_2:
+ case ESCAPE_FNC_3:
+ case ESCAPE_FNC_4:
+ break;
+ default:
+ [NSException raise:NSInvalidArgumentException format:@"Bad character in input: %C", c];
+ }
+ }
+ }
+
+ NSMutableArray *patterns = [NSMutableArray array]; // temporary storage for patterns
+ int checkSum = 0;
+ int checkWeight = 1;
+ int codeSet = 0; // selected code (CODE_CODE_B or CODE_CODE_C)
+ int position = 0; // position in contents
+
+ while (position < length) {
+ //Select code to use
+ int requiredDigitCount = codeSet == CODE_CODE_C ? 2 : 4;
+ int newCodeSet;
+ if ([self isDigits:contents start:position length:requiredDigitCount]) {
+ newCodeSet = CODE_CODE_C;
+ } else {
+ newCodeSet = CODE_CODE_B;
+ }
+
+ //Get the pattern index
+ int patternIndex;
+ if (newCodeSet == codeSet) {
+ // Encode the current character
+ if (codeSet == CODE_CODE_B) {
+ patternIndex = [contents characterAtIndex:position] - ' ';
+ position += 1;
+ } else { // CODE_CODE_C
+ switch ([contents characterAtIndex:position]) {
+ case ESCAPE_FNC_1:
+ patternIndex = CODE_FNC_1;
+ position++;
+ break;
+ case ESCAPE_FNC_2:
+ patternIndex = CODE_FNC_2;
+ position++;
+ break;
+ case ESCAPE_FNC_3:
+ patternIndex = CODE_FNC_3;
+ position++;
+ break;
+ case ESCAPE_FNC_4:
+ patternIndex = CODE_FNC_4_B; // FIXME if this ever outputs Code A
+ position++;
+ break;
+ default:
+ patternIndex = [[contents substringWithRange:NSMakeRange(position, 2)] intValue];
+ position += 2;
+ break;
+ }
+ }
+ } else {
+ // Should we change the current code?
+ // Do we have a code set?
+ if (codeSet == 0) {
+ // No, we don't have a code set
+ if (newCodeSet == CODE_CODE_B) {
+ patternIndex = CODE_START_B;
+ } else {
+ // CODE_CODE_C
+ patternIndex = CODE_START_C;
+ }
+ } else {
+ // Yes, we have a code set
+ patternIndex = newCodeSet;
+ }
+ codeSet = newCodeSet;
+ }
+
+ // Get the pattern
+ NSMutableArray *pattern = [NSMutableArray array];
+ for (int i = 0; i < sizeof(CODE_PATTERNS[patternIndex]) / sizeof(int); i++) {
+ [pattern addObject:@(CODE_PATTERNS[patternIndex][i])];
+ }
+ [patterns addObject:pattern];
+
+ // Compute checksum
+ checkSum += patternIndex * checkWeight;
+ if (position != 0) {
+ checkWeight++;
+ }
+ }
+
+ // Compute and append checksum
+ checkSum %= 103;
+ NSMutableArray *pattern = [NSMutableArray array];
+ for (int i = 0; i < sizeof(CODE_PATTERNS[checkSum]) / sizeof(int); i++) {
+ [pattern addObject:@(CODE_PATTERNS[checkSum][i])];
+ }
+ [patterns addObject:pattern];
+
+ // Append stop code
+ pattern = [NSMutableArray array];
+ for (int i = 0; i < sizeof(CODE_PATTERNS[CODE_STOP]) / sizeof(int); i++) {
+ [pattern addObject:@(CODE_PATTERNS[CODE_STOP][i])];
+ }
+ [patterns addObject:pattern];
+
+ // Compute code width
+ int codeWidth = 0;
+ for (pattern in patterns) {
+ for (int i = 0; i < pattern.count; i++) {
+ codeWidth += [pattern[i] intValue];
+ }
+ }
+
+ // Compute result
+ if (pLength) *pLength = codeWidth;
+ BOOL *result = (BOOL *)malloc(codeWidth * sizeof(BOOL));
+ int pos = 0;
+ for (NSArray *patternArray in patterns) {
+ int patternLen = (int)[patternArray count];
+ int pattern[patternLen];
+ for(int i = 0; i < patternLen; i++) {
+ pattern[i] = [patternArray[i] intValue];
+ }
+
+ pos += [super appendPattern:result pos:pos pattern:pattern patternLen:patternLen startColor:TRUE];
+ }
+
+ return result;
+}
+
+- (BOOL)isDigits:(NSString *)value start:(int)start length:(unsigned int)length {
+ int end = start + length;
+ 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 != ESCAPE_FNC_1) {
+ return NO;
+ }
+ end++; // ignore FNC_1
+ }
+ }
+ return end <= last; // end > last if we've run out of string
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXCode39Reader.h b/ZXingObjC/oned/ZXCode39Reader.h
new file mode 100644
index 0000000..7d5cfdf
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode39Reader.h
@@ -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 "ZXOneDReader.h"
+
+/**
+ * Decodes Code 39 barcodes. This does not support "Full ASCII Code 39" yet.
+ */
+
+extern char CODE39_ALPHABET[];
+extern NSString *CODE39_ALPHABET_STRING;
+extern int CODE39_CHARACTER_ENCODINGS[];
+
+@class ZXDecodeHints, ZXResult;
+
+@interface ZXCode39Reader : ZXOneDReader
+
+- (id)initUsingCheckDigit:(BOOL)usingCheckDigit;
+- (id)initUsingCheckDigit:(BOOL)usingCheckDigit extendedMode:(BOOL)extendedMode;
+
+@end
diff --git a/ZXingObjC/oned/ZXCode39Reader.m b/ZXingObjC/oned/ZXCode39Reader.m
new file mode 100644
index 0000000..51f343f
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode39Reader.m
@@ -0,0 +1,315 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXCode39Reader.h"
+#import "ZXErrors.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+char CODE39_ALPHABET[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%";
+NSString *CODE39_ALPHABET_STRING = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%";
+
+/**
+ * These represent the encodings of characters, as patterns of wide and narrow bars.
+ * The 9 least-significant bits of each int correspond to the pattern of wide and narrow,
+ * with 1s representing "wide" and 0s representing narrow.
+ */
+int CODE39_CHARACTER_ENCODINGS[44] = {
+ 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 // $-%
+};
+
+int const CODE39_ASTERISK_ENCODING = 0x094;
+
+@interface ZXCode39Reader ()
+
+@property (nonatomic, assign) BOOL extendedMode;
+@property (nonatomic, assign) BOOL usingCheckDigit;
+
+@end
+
+@implementation ZXCode39Reader
+
+/**
+ * Creates a reader that assumes all encoded data is data, and does not treat the final
+ * character as a check digit. It will not decoded "extended Code 39" sequences.
+ */
+- (id)init {
+ return [self initUsingCheckDigit:NO extendedMode:NO];
+}
+
+
+/**
+ * Creates a reader that can be configured to check the last character as a check digit.
+ * It will not decoded "extended Code 39" sequences.
+ */
+- (id)initUsingCheckDigit:(BOOL)isUsingCheckDigit {
+ return [self initUsingCheckDigit:isUsingCheckDigit extendedMode:NO];
+}
+
+
+/**
+ * Creates a reader that can be configured to check the last character as a check digit,
+ * or optionally attempt to decode "extended Code 39" sequences that are used to encode
+ * the full ASCII character set.
+ */
+- (id)initUsingCheckDigit:(BOOL)usingCheckDigit extendedMode:(BOOL)extendedMode {
+ if (self = [super init]) {
+ _usingCheckDigit = usingCheckDigit;
+ _extendedMode = extendedMode;
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ const int countersLen = 9;
+ int counters[countersLen];
+ memset(counters, 0, countersLen * sizeof(int));
+
+ int start[2] = {0};
+ if (![self findAsteriskPattern:row a:&start[0] b:&start[1] counters:counters countersLen:countersLen]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ // Read off white space
+ int nextStart = [row nextSet:start[1]];
+ int end = [row size];
+
+ NSMutableString *result = [NSMutableString stringWithCapacity:20];
+ unichar decodedChar;
+ int lastStart;
+ do {
+ if (![ZXOneDReader recordPattern:row start:nextStart counters:counters countersSize:countersLen]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ int pattern = [self toNarrowWidePattern:(int *)counters countersLen:countersLen];
+ if (pattern < 0) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ decodedChar = [self patternToChar:pattern];
+ if (decodedChar == 0) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ [result appendFormat:@"%C", decodedChar];
+ lastStart = nextStart;
+ for (int i = 0; i < sizeof(counters) / sizeof(int); i++) {
+ nextStart += counters[i];
+ }
+ // Read off white space
+ nextStart = [row nextSet:nextStart];
+ } while (decodedChar != '*');
+ [result deleteCharactersInRange:NSMakeRange([result length] - 1, 1)];
+
+ int lastPatternSize = 0;
+ for (int i = 0; i < sizeof(counters) / sizeof(int); i++) {
+ lastPatternSize += counters[i];
+ }
+ int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
+ if (nextStart != end && (whiteSpaceAfterEnd >> 1) < lastPatternSize) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ if (self.usingCheckDigit) {
+ int max = (int)[result length] - 1;
+ int total = 0;
+ for (int i = 0; i < max; i++) {
+ total += [CODE39_ALPHABET_STRING rangeOfString:[result substringWithRange:NSMakeRange(i, 1)]].location;
+ }
+ if ([result characterAtIndex:max] != CODE39_ALPHABET[total % 43]) {
+ if (error) *error = ChecksumErrorInstance();
+ return nil;
+ }
+ [result deleteCharactersInRange:NSMakeRange(max, 1)];
+ }
+
+ if ([result length] == 0) {
+ // false positive
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ NSString *resultString;
+ if (self.extendedMode) {
+ resultString = [self decodeExtended:result];
+ if (!resultString) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ } else {
+ resultString = result;
+ }
+
+ float left = (float) (start[1] + start[0]) / 2.0f;
+ float right = (float)(nextStart + lastStart) / 2.0f;
+
+ return [ZXResult resultWithText:resultString
+ rawBytes:nil
+ length:0
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
+ format:kBarcodeFormatCode39];
+}
+
+- (BOOL)findAsteriskPattern:(ZXBitArray *)row a:(int *)a b:(int *)b counters:(int *)counters countersLen:(int)countersLen {
+ int width = row.size;
+ int rowOffset = [row nextSet:0];
+
+ int counterPosition = 0;
+ int patternStart = rowOffset;
+ BOOL isWhite = NO;
+
+ for (int i = rowOffset; i < width; i++) {
+ if ([row get:i] ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == countersLen - 1) {
+ if ([self toNarrowWidePattern:counters countersLen:countersLen] == CODE39_ASTERISK_ENCODING &&
+ [row isRange:MAX(0, patternStart - ((i - patternStart) >> 1)) end:patternStart value:NO]) {
+ if (a) *a = patternStart;
+ if (b) *b = i;
+ return YES;
+ }
+ patternStart += counters[0] + counters[1];
+ for (int y = 2; y < countersLen; y++) {
+ counters[y - 2] = counters[y];
+ }
+ counters[countersLen - 2] = 0;
+ counters[countersLen - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return NO;
+}
+
+- (int)toNarrowWidePattern:(int *)counters countersLen:(unsigned int)countersLen {
+ int numCounters = countersLen;
+ int maxNarrowCounter = 0;
+ int wideCounters;
+ do {
+ int minCounter = INT_MAX;
+ for (int i = 0; i < numCounters; i++) {
+ int counter = counters[i];
+ if (counter < minCounter && counter > maxNarrowCounter) {
+ minCounter = counter;
+ }
+ }
+ maxNarrowCounter = minCounter;
+ wideCounters = 0;
+ int totalWideCountersWidth = 0;
+ int pattern = 0;
+ for (int i = 0; i < numCounters; i++) {
+ int counter = counters[i];
+ if (counters[i] > maxNarrowCounter) {
+ pattern |= 1 << (numCounters - 1 - i);
+ wideCounters++;
+ totalWideCountersWidth += counter;
+ }
+ }
+ if (wideCounters == 3) {
+ for (int i = 0; i < numCounters && wideCounters > 0; i++) {
+ int counter = counters[i];
+ if (counters[i] > maxNarrowCounter) {
+ wideCounters--;
+ if ((counter << 1) >= totalWideCountersWidth) {
+ return -1;
+ }
+ }
+ }
+ return pattern;
+ }
+ } while (wideCounters > 3);
+ return -1;
+}
+
+- (unichar)patternToChar:(int)pattern {
+ for (int i = 0; i < sizeof(CODE39_CHARACTER_ENCODINGS) / sizeof(int); i++) {
+ if (CODE39_CHARACTER_ENCODINGS[i] == pattern) {
+ return CODE39_ALPHABET[i];
+ }
+ }
+ return 0;
+}
+
+- (NSString *)decodeExtended:(NSMutableString *)encoded {
+ NSUInteger length = [encoded length];
+ NSMutableString *decoded = [NSMutableString stringWithCapacity:length];
+
+ for (int i = 0; i < length; i++) {
+ unichar c = [encoded characterAtIndex:i];
+ if (c == '+' || c == '$' || c == '%' || c == '/') {
+ unichar next = [encoded characterAtIndex:i + 1];
+ 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;
+ }
+ [decoded appendFormat:@"%C", decodedChar];
+ i++;
+ } else {
+ [decoded appendFormat:@"%C", c];
+ }
+ }
+
+ return decoded;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXCode39Writer.h b/ZXingObjC/oned/ZXCode39Writer.h
new file mode 100644
index 0000000..3265ba4
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode39Writer.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXOneDimensionalCodeWriter.h"
+
+/**
+ * This object renders a CODE39 code as a {@link BitMatrix}.
+ */
+
+@interface ZXCode39Writer : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/ZXingObjC/oned/ZXCode39Writer.m b/ZXingObjC/oned/ZXCode39Writer.m
new file mode 100644
index 0000000..08694dc
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode39Writer.m
@@ -0,0 +1,82 @@
+/*
+ * 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 "ZXCode39Reader.h"
+#import "ZXCode39Writer.h"
+
+#define ZX_CODE39_WHITELEN 1
+
+@implementation ZXCode39Writer
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if (format != kBarcodeFormatCode39) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Can only encode CODE_39."];
+ }
+ return [super encode:contents format:format width:width height:height hints:hints error:error];
+}
+
+- (BOOL *)encode:(NSString *)contents length:(int *)pLength {
+ NSUInteger length = [contents length];
+ if (length > 80) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Requested contents should be less than 80 digits long, but got %ld", (unsigned long)length];
+ }
+
+ const int widthsLengh = 9;
+ int widths[widthsLengh];
+ memset(widths, 0, widthsLengh * sizeof(int));
+
+ int codeWidth = 24 + 1 + (int)length;
+ for (int i = 0; i < length; i++) {
+ NSUInteger indexInString = [CODE39_ALPHABET_STRING rangeOfString:[contents substringWithRange:NSMakeRange(i, 1)]].location;
+ [self toIntArray:CODE39_CHARACTER_ENCODINGS[indexInString] toReturn:widths];
+ for (int j = 0; j < widthsLengh; j++) {
+ codeWidth += widths[j];
+ }
+ }
+
+ if (pLength) *pLength = codeWidth;
+ BOOL *result = (BOOL *)malloc(codeWidth * sizeof(BOOL));
+ [self toIntArray:CODE39_CHARACTER_ENCODINGS[39] toReturn:widths];
+ int pos = [super appendPattern:result pos:0 pattern:widths patternLen:widthsLengh startColor:TRUE];
+
+ const int narrowWhiteLen = ZX_CODE39_WHITELEN;
+ int narrowWhite[ZX_CODE39_WHITELEN] = {1};
+
+ pos += [super appendPattern:result pos:pos pattern:narrowWhite patternLen:narrowWhiteLen startColor:FALSE];
+
+ for (int i = (int)length - 1; i >= 0; i--) {
+ NSUInteger indexInString = [CODE39_ALPHABET_STRING rangeOfString:[contents substringWithRange:NSMakeRange(i, 1)]].location;
+ [self toIntArray:CODE39_CHARACTER_ENCODINGS[indexInString] toReturn:widths];
+ pos += [super appendPattern:result pos:pos pattern:widths patternLen:widthsLengh startColor:TRUE];
+ pos += [super appendPattern:result pos:pos pattern:narrowWhite patternLen:narrowWhiteLen startColor:FALSE];
+ }
+
+ [self toIntArray:CODE39_CHARACTER_ENCODINGS[39] toReturn:widths];
+ [super appendPattern:result pos:pos pattern:widths patternLen:widthsLengh startColor:TRUE];
+ return result;
+}
+
+- (void)toIntArray:(int)a toReturn:(int[])toReturn {
+ for (int i = 0; i < 9; i++) {
+ int temp = a & (1 << i);
+ toReturn[i] = temp == 0 ? 1 : 2;
+ }
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXCode93Reader.h b/ZXingObjC/oned/ZXCode93Reader.h
new file mode 100644
index 0000000..8b31cd7
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode93Reader.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXOneDReader.h"
+
+/**
+ * Decodes Code 93 barcodes.
+ */
+
+@interface ZXCode93Reader : ZXOneDReader
+
+@end
diff --git a/ZXingObjC/oned/ZXCode93Reader.m b/ZXingObjC/oned/ZXCode93Reader.m
new file mode 100644
index 0000000..22b023c
--- /dev/null
+++ b/ZXingObjC/oned/ZXCode93Reader.m
@@ -0,0 +1,291 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXCode93Reader.h"
+#import "ZXErrors.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+const NSString *CODE93_ALPHABET_STRING = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*";
+const char CODE93_ALPHABET[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*";
+
+/**
+ * These represent the encodings of characters, as patterns of wide and narrow bars.
+ * The 9 least-significant bits of each int correspond to the pattern of wide and narrow.
+ */
+const int CODE93_CHARACTER_ENCODINGS[48] = {
+ 0x114, 0x148, 0x144, 0x142, 0x128, 0x124, 0x122, 0x150, 0x112, 0x10A, // 0-9
+ 0x1A8, 0x1A4, 0x1A2, 0x194, 0x192, 0x18A, 0x168, 0x164, 0x162, 0x134, // A-J
+ 0x11A, 0x158, 0x14C, 0x146, 0x12C, 0x116, 0x1B4, 0x1B2, 0x1AC, 0x1A6, // K-T
+ 0x196, 0x19A, 0x16C, 0x166, 0x136, 0x13A, // U-Z
+ 0x12E, 0x1D4, 0x1D2, 0x1CA, 0x16E, 0x176, 0x1AE, // - - %
+ 0x126, 0x1DA, 0x1D6, 0x132, 0x15E, // Control chars? $-*
+};
+
+const int CODE93_ASTERISK_ENCODING = 0x15E;
+
+@interface ZXCode93Reader ()
+
+@property (nonatomic, strong) NSMutableString *decodeRowResult;
+
+@end
+
+@implementation ZXCode93Reader
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeRowResult = [NSMutableString stringWithCapacity:20];
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ const int countersLen = 6;
+ int counters[countersLen];
+ memset(counters, 0, countersLen * sizeof(int));
+
+ [self.decodeRowResult setString:@""];
+
+ int start[2] = {0};
+ if (![self findAsteriskPattern:row a:&start[0] b:&start[1]]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ // Read off white space
+ int nextStart = [row nextSet:start[1]];
+ int end = row.size;
+
+ unichar decodedChar;
+ int lastStart;
+ do {
+ if (![ZXOneDReader recordPattern:row start:nextStart counters:counters countersSize:countersLen]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ int pattern = [self toPattern:counters countersLen:countersLen];
+ if (pattern < 0) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ decodedChar = [self patternToChar:pattern];
+ if (decodedChar == 0) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ [self.decodeRowResult appendFormat:@"%C", decodedChar];
+ lastStart = nextStart;
+ for (int i = 0; i < countersLen; i++) {
+ nextStart += counters[i];
+ }
+ // Read off white space
+ nextStart = [row nextSet:nextStart];
+ } while (decodedChar != '*');
+ [self.decodeRowResult deleteCharactersInRange:NSMakeRange([self.decodeRowResult length] - 1, 1)];
+
+ if (nextStart == end || ![row get:nextStart]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ if ([self.decodeRowResult length] < 2) {
+ // false positive -- need at least 2 checksum digits
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ if (![self checkChecksums:self.decodeRowResult error:error]) {
+ return nil;
+ }
+ [self.decodeRowResult deleteCharactersInRange:NSMakeRange([self.decodeRowResult length] - 2, 2)];
+
+ NSString *resultString = [self decodeExtended:self.decodeRowResult];
+ if (!resultString) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+
+ float left = (float) (start[1] + start[0]) / 2.0f;
+ float right = (float) (nextStart + lastStart) / 2.0f;
+ return [ZXResult resultWithText:resultString
+ rawBytes:nil
+ length:0
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
+ format:kBarcodeFormatCode93];
+}
+
+- (BOOL)findAsteriskPattern:(ZXBitArray *)row a:(int *)a b:(int *)b {
+ int width = row.size;
+ int rowOffset = [row nextSet:0];
+
+ int counterPosition = 0;
+
+ const int patternLength = 6;
+ int counters[patternLength];
+ memset(counters, 0, patternLength * sizeof(int));
+
+ int patternStart = rowOffset;
+ BOOL isWhite = NO;
+
+ for (int i = rowOffset; i < width; i++) {
+ if ([row get:i] ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if ([self toPattern:counters countersLen:patternLength] == CODE93_ASTERISK_ENCODING) {
+ if (a) *a = patternStart;
+ if (b) *b = i;
+ return YES;
+ }
+ patternStart += counters[0] + counters[1];
+ for (int y = 2; y < patternLength; y++) {
+ counters[y - 2] = counters[y];
+ }
+ counters[patternLength - 2] = 0;
+ counters[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return NO;
+}
+
+- (int)toPattern:(int *)counters countersLen:(unsigned int)countersLen {
+ int max = countersLen;
+ int sum = 0;
+ for (int i = 0; i < max; i++) {
+ sum += counters[i];
+ }
+ int pattern = 0;
+ for (int i = 0; i < max; i++) {
+ int scaledShifted = (counters[i] << INTEGER_MATH_SHIFT) * 9 / sum;
+ int scaledUnshifted = scaledShifted >> INTEGER_MATH_SHIFT;
+ if ((scaledShifted & 0xFF) > 0x7F) {
+ scaledUnshifted++;
+ }
+ if (scaledUnshifted < 1 || scaledUnshifted > 4) {
+ return -1;
+ }
+ if ((i & 0x01) == 0) {
+ for (int j = 0; j < scaledUnshifted; j++) {
+ pattern = (pattern << 1) | 0x01;
+ }
+ } else {
+ pattern <<= scaledUnshifted;
+ }
+ }
+ return pattern;
+}
+
+- (unichar)patternToChar:(int)pattern {
+ for (int i = 0; i < sizeof(CODE93_CHARACTER_ENCODINGS) / sizeof(int); i++) {
+ if (CODE93_CHARACTER_ENCODINGS[i] == pattern) {
+ return CODE93_ALPHABET[i];
+ }
+ }
+
+ return -1;
+}
+
+- (NSString *)decodeExtended:(NSMutableString *)encoded {
+ NSUInteger length = [encoded length];
+ NSMutableString *decoded = [NSMutableString stringWithCapacity:length];
+ for (int i = 0; i < length; i++) {
+ unichar c = [encoded characterAtIndex:i];
+ if (c >= 'a' && c <= 'd') {
+ if (i >= length - 1) {
+ return nil;
+ }
+ unichar next = [encoded characterAtIndex:i + 1];
+ unichar decodedChar = '\0';
+ switch (c) {
+ case 'd':
+ if (next >= 'A' && next <= 'Z') {
+ decodedChar = (unichar)(next + 32);
+ } else {
+ return nil;
+ }
+ break;
+ case 'a':
+ if (next >= 'A' && next <= 'Z') {
+ decodedChar = (unichar)(next - 64);
+ } else {
+ return nil;
+ }
+ break;
+ case 'b':
+ if (next >= 'A' && next <= 'E') {
+ decodedChar = (unichar)(next - 38);
+ } else if (next >= 'F' && next <= 'W') {
+ decodedChar = (unichar)(next - 11);
+ } else {
+ return nil;
+ }
+ break;
+ case 'c':
+ if (next >= 'A' && next <= 'O') {
+ decodedChar = (unichar)(next - 32);
+ } else if (next == 'Z') {
+ decodedChar = ':';
+ } else {
+ return nil;
+ }
+ break;
+ }
+ [decoded appendFormat:@"%C", decodedChar];
+ i++;
+ } else {
+ [decoded appendFormat:@"%C", c];
+ }
+ }
+
+ return decoded;
+}
+
+- (BOOL)checkChecksums:(NSMutableString *)result error:(NSError **)error {
+ NSUInteger length = [result length];
+ if (![self checkOneChecksum:result checkPosition:(int)length - 2 weightMax:20 error:error]) {
+ return NO;
+ }
+ return [self checkOneChecksum:result checkPosition:(int)length - 1 weightMax:15 error:error];
+}
+
+- (BOOL)checkOneChecksum:(NSMutableString *)result checkPosition:(int)checkPosition weightMax:(int)weightMax error:(NSError **)error {
+ int weight = 1;
+ int total = 0;
+
+ for (int i = checkPosition - 1; i >= 0; i--) {
+ total += weight * [CODE93_ALPHABET_STRING rangeOfString:[NSString stringWithFormat:@"%C", [result characterAtIndex:i]]].location;
+ if (++weight > weightMax) {
+ weight = 1;
+ }
+ }
+
+ if ([result characterAtIndex:checkPosition] != CODE93_ALPHABET[total % 47]) {
+ if (error) *error = ChecksumErrorInstance();
+ return NO;
+ }
+ return YES;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXEAN13Reader.h b/ZXingObjC/oned/ZXEAN13Reader.h
new file mode 100644
index 0000000..34c64d2
--- /dev/null
+++ b/ZXingObjC/oned/ZXEAN13Reader.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXUPCEANReader.h"
+
+/**
+ * Implements decoding of the EAN-13 format.
+ */
+
+extern int FIRST_DIGIT_ENCODINGS[10];
+
+@interface ZXEAN13Reader : ZXUPCEANReader
+
+@end
diff --git a/ZXingObjC/oned/ZXEAN13Reader.m b/ZXingObjC/oned/ZXEAN13Reader.m
new file mode 100644
index 0000000..421cab7
--- /dev/null
+++ b/ZXingObjC/oned/ZXEAN13Reader.m
@@ -0,0 +1,150 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXEAN13Reader.h"
+#import "ZXErrors.h"
+
+// For an EAN-13 barcode, the first digit is represented by the parities used
+// to encode the next six digits, according to the table below. For example,
+// if the barcode is 5 123456 789012 then the value of the first digit is
+// signified by using odd for '1', even for '2', even for '3', odd for '4',
+// odd for '5', and even for '6'. See http://en.wikipedia.org/wiki/EAN-13
+//
+// Parity of next 6 digits
+// Digit 0 1 2 3 4 5
+// 0 Odd Odd Odd Odd Odd Odd
+// 1 Odd Odd Even Odd Even Even
+// 2 Odd Odd Even Even Odd Even
+// 3 Odd Odd Even Even Even Odd
+// 4 Odd Even Odd Odd Even Even
+// 5 Odd Even Even Odd Odd Even
+// 6 Odd Even Even Even Odd Odd
+// 7 Odd Even Odd Even Odd Even
+// 8 Odd Even Odd Even Even Odd
+// 9 Odd Even Even Odd Even Odd
+//
+// Note that the encoding for '0' uses the same parity as a UPC barcode. Hence
+// a UPC barcode can be converted to an EAN-13 barcode by prepending a 0.
+//
+// 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
+//
+int FIRST_DIGIT_ENCODINGS[10] = {
+ 0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A
+};
+
+@interface ZXEAN13Reader ()
+
+@property (nonatomic, assign) int *decodeMiddleCounters;
+
+@end
+
+@implementation ZXEAN13Reader
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeMiddleCounters = (int *)malloc(sizeof(4) * sizeof(int));
+ _decodeMiddleCounters[0] = 0;
+ _decodeMiddleCounters[1] = 0;
+ _decodeMiddleCounters[2] = 0;
+ _decodeMiddleCounters[3] = 0;
+ }
+ return self;
+}
+
+- (void)dealloc {
+ if (_decodeMiddleCounters != NULL) {
+ free(_decodeMiddleCounters);
+ _decodeMiddleCounters = NULL;
+ }
+}
+
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ int *counters = self.decodeMiddleCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+ const int countersLen = 4;
+ int end = row.size;
+ int rowOffset = (int)NSMaxRange(startRange);
+
+ int lgPatternFound = 0;
+
+ for (int x = 0; x < 6 && rowOffset < end; x++) {
+ int bestMatch = [ZXUPCEANReader decodeDigit:row counters:counters countersLen:countersLen rowOffset:rowOffset patternType:UPC_EAN_PATTERNS_L_AND_G_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch % 10)];
+ for (int i = 0; i < countersLen; i++) {
+ rowOffset += counters[i];
+ }
+ if (bestMatch >= 10) {
+ lgPatternFound |= 1 << (5 - x);
+ }
+ }
+
+ if (![self determineFirstDigit:result lgPatternFound:lgPatternFound]) {
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ }
+
+ NSRange middleRange = [[self class] findGuardPattern:row rowOffset:rowOffset whiteFirst:YES pattern:(int *)MIDDLE_PATTERN patternLen:MIDDLE_PATTERN_LEN error:error];
+ if (middleRange.location == NSNotFound) {
+ return -1;
+ }
+ rowOffset = (int)NSMaxRange(middleRange);
+
+ for (int x = 0; x < 6 && rowOffset < end; x++) {
+ int bestMatch = [ZXUPCEANReader decodeDigit:row counters:counters countersLen:countersLen rowOffset:rowOffset patternType:UPC_EAN_PATTERNS_L_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch)];
+ for (int i = 0; i < countersLen; i++) {
+ rowOffset += counters[i];
+ }
+ }
+
+ return rowOffset;
+}
+
+- (ZXBarcodeFormat)barcodeFormat {
+ return kBarcodeFormatEan13;
+}
+
+/**
+ * Based on pattern of odd-even ('L' and 'G') patterns used to encoded the explicitly-encoded
+ * digits in a barcode, determines the implicitly encoded first digit and adds it to the
+ * result string.
+ */
+- (BOOL)determineFirstDigit:(NSMutableString *)resultString lgPatternFound:(int)lgPatternFound {
+ for (int d = 0; d < 10; d++) {
+ if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d]) {
+ [resultString insertString:[NSString stringWithFormat:@"%C", (unichar)('0' + d)] atIndex:0];
+ return YES;
+ }
+ }
+ return NO;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXEAN13Writer.h b/ZXingObjC/oned/ZXEAN13Writer.h
new file mode 100644
index 0000000..1f83102
--- /dev/null
+++ b/ZXingObjC/oned/ZXEAN13Writer.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXUPCEANWriter.h"
+
+/**
+ * This object renders an EAN13 code as a {@link BitMatrix}.
+ */
+
+@interface ZXEAN13Writer : ZXUPCEANWriter
+
+@end
diff --git a/ZXingObjC/oned/ZXEAN13Writer.m b/ZXingObjC/oned/ZXEAN13Writer.m
new file mode 100644
index 0000000..3f767f8
--- /dev/null
+++ b/ZXingObjC/oned/ZXEAN13Writer.m
@@ -0,0 +1,79 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXEAN13Reader.h"
+#import "ZXEAN13Writer.h"
+#import "ZXUPCEANReader.h"
+
+const int EAN13_CODE_WIDTH = 3 + // start guard
+ (7 * 6) + // left bars
+ 5 + // middle guard
+ (7 * 6) + // right bars
+ 3; // end guard
+
+@implementation ZXEAN13Writer
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if (format != kBarcodeFormatEan13) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Can only encode EAN_13, but got %d", format]
+ userInfo:nil];
+ }
+
+ return [super encode:contents format:format width:width height:height hints:hints error:error];
+}
+
+- (BOOL *)encode:(NSString *)contents length:(int *)pLength {
+ if ([contents length] != 13) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Requested contents should be 13 digits long, but got %d", (int)[contents length]];
+ }
+
+ if (![ZXUPCEANReader checkStandardUPCEANChecksum:contents]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Contents do not pass checksum"];
+ }
+
+ int firstDigit = [[contents substringToIndex:1] intValue];
+ int parities = FIRST_DIGIT_ENCODINGS[firstDigit];
+ if (pLength) *pLength = EAN13_CODE_WIDTH;
+ BOOL *result = (BOOL *)malloc(EAN13_CODE_WIDTH * sizeof(BOOL));
+ memset(result, 0, EAN13_CODE_WIDTH * sizeof(int8_t));
+ int pos = 0;
+
+ pos += [super appendPattern:result pos:pos pattern:(int *)START_END_PATTERN patternLen:START_END_PATTERN_LEN startColor:TRUE];
+
+ for (int i = 1; i <= 6; i++) {
+ int digit = [[contents substringWithRange:NSMakeRange(i, 1)] intValue];
+ if ((parities >> (6 - i) & 1) == 1) {
+ digit += 10;
+ }
+ pos += [super appendPattern:result pos:pos pattern:(int *)L_AND_G_PATTERNS[digit] patternLen:L_PATTERNS_SUB_LEN startColor:FALSE];
+ }
+
+ pos += [super appendPattern:result pos:pos pattern:(int *)MIDDLE_PATTERN patternLen:MIDDLE_PATTERN_LEN startColor:FALSE];
+
+ for (int i = 7; i <= 12; i++) {
+ int digit = [[contents substringWithRange:NSMakeRange(i, 1)] intValue];
+ pos += [super appendPattern:result pos:pos pattern:(int *)L_PATTERNS[digit] patternLen:L_PATTERNS_SUB_LEN startColor:TRUE];
+ }
+ [super appendPattern:result pos:pos pattern:(int *)START_END_PATTERN patternLen:START_END_PATTERN_LEN startColor:TRUE];
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXEAN8Reader.h b/ZXingObjC/oned/ZXEAN8Reader.h
new file mode 100644
index 0000000..718acba
--- /dev/null
+++ b/ZXingObjC/oned/ZXEAN8Reader.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXUPCEANReader.h"
+
+/**
+ * Implements decoding of the EAN-8 format.
+ */
+
+@interface ZXEAN8Reader : ZXUPCEANReader
+
+@end
diff --git a/ZXingObjC/oned/ZXEAN8Reader.m b/ZXingObjC/oned/ZXEAN8Reader.m
new file mode 100644
index 0000000..51e1694
--- /dev/null
+++ b/ZXingObjC/oned/ZXEAN8Reader.m
@@ -0,0 +1,90 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXEAN8Reader.h"
+
+@interface ZXEAN8Reader ()
+
+@property (nonatomic, assign) int *decodeMiddleCounters;
+
+@end
+
+@implementation ZXEAN8Reader
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeMiddleCounters = (int *)malloc(sizeof(4) * sizeof(int));
+ _decodeMiddleCounters[0] = 0;
+ _decodeMiddleCounters[1] = 0;
+ _decodeMiddleCounters[2] = 0;
+ _decodeMiddleCounters[3] = 0;
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_decodeMiddleCounters != NULL) {
+ free(_decodeMiddleCounters);
+ _decodeMiddleCounters = NULL;
+ }
+}
+
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ const int countersLen = 4;
+ int counters[countersLen];
+ memset(counters, 0, countersLen * sizeof(int));
+
+ int end = row.size;
+ int rowOffset = (int)NSMaxRange(startRange);
+
+ for (int x = 0; x < 4 && rowOffset < end; x++) {
+ int bestMatch = [ZXUPCEANReader decodeDigit:row counters:counters countersLen:countersLen rowOffset:rowOffset patternType:UPC_EAN_PATTERNS_L_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch)];
+ for (int i = 0; i < countersLen; i++) {
+ rowOffset += counters[i];
+ }
+ }
+
+ NSRange middleRange = [[self class] findGuardPattern:row rowOffset:rowOffset whiteFirst:YES pattern:(int *)MIDDLE_PATTERN patternLen:MIDDLE_PATTERN_LEN error:error];
+ if (middleRange.location == NSNotFound) {
+ return -1;
+ }
+ rowOffset = (int)NSMaxRange(middleRange);
+
+ for (int x = 0; x < 4 && rowOffset < end; x++) {
+ int bestMatch = [ZXUPCEANReader decodeDigit:row counters:counters countersLen:countersLen rowOffset:rowOffset patternType:UPC_EAN_PATTERNS_L_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch)];
+ for (int i = 0; i < countersLen; i++) {
+ rowOffset += counters[i];
+ }
+ }
+
+ return rowOffset;
+}
+
+- (ZXBarcodeFormat)barcodeFormat {
+ return kBarcodeFormatEan8;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXEAN8Writer.h b/ZXingObjC/oned/ZXEAN8Writer.h
new file mode 100644
index 0000000..3d23660
--- /dev/null
+++ b/ZXingObjC/oned/ZXEAN8Writer.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXUPCEANWriter.h"
+
+/**
+ * This object renders an EAN8 code as a ZXBitMatrix.
+ */
+
+@interface ZXEAN8Writer : ZXUPCEANWriter
+
+@end
diff --git a/ZXingObjC/oned/ZXEAN8Writer.m b/ZXingObjC/oned/ZXEAN8Writer.m
new file mode 100644
index 0000000..8a8994c
--- /dev/null
+++ b/ZXingObjC/oned/ZXEAN8Writer.m
@@ -0,0 +1,64 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXEAN8Writer.h"
+#import "ZXUPCEANReader.h"
+
+int const EAN8codeWidth = 3 + (7 * 4) + 5 + (7 * 4) + 3;
+
+@implementation ZXEAN8Writer
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if (format != kBarcodeFormatEan8) {
+ [NSException raise:NSInvalidArgumentException format:@"Can only encode EAN_8"];
+ }
+ return [super encode:contents format:format width:width height:height hints:hints error:error];
+}
+
+/**
+ * Returns a byte array of horizontal pixels (FALSE = white, TRUE = black)
+ */
+- (BOOL *)encode:(NSString *)contents length:(int *)pLength {
+ if ([contents length] != 8) {
+ [NSException raise:NSInvalidArgumentException format:@"Requested contents should be 8 digits long, but got %d", (int)[contents length]];
+ }
+
+ if (pLength) *pLength = EAN8codeWidth;
+ BOOL *result = (BOOL *)malloc(EAN8codeWidth * sizeof(BOOL));
+ memset(result, 0, EAN8codeWidth * sizeof(int8_t));
+ int pos = 0;
+
+ pos += [super appendPattern:result pos:pos pattern:(int *)START_END_PATTERN patternLen:START_END_PATTERN_LEN startColor:TRUE];
+
+ for (int i = 0; i <= 3; i++) {
+ int digit = [[contents substringWithRange:NSMakeRange(i, 1)] intValue];
+ pos += [super appendPattern:result pos:pos pattern:(int *)L_PATTERNS[digit] patternLen:L_PATTERNS_SUB_LEN startColor:FALSE];
+ }
+
+ pos += [super appendPattern:result pos:pos pattern:(int *)MIDDLE_PATTERN patternLen:MIDDLE_PATTERN_LEN startColor:FALSE];
+
+ for (int i = 4; i <= 7; i++) {
+ int digit = [[contents substringWithRange:NSMakeRange(i, 1)] intValue];
+ pos += [super appendPattern:result pos:pos pattern:(int *)L_PATTERNS[digit] patternLen:L_PATTERNS_SUB_LEN startColor:TRUE];
+ }
+
+ [super appendPattern:result pos:pos pattern:(int *)START_END_PATTERN patternLen:START_END_PATTERN_LEN startColor:TRUE];
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXEANManufacturerOrgSupport.h b/ZXingObjC/oned/ZXEANManufacturerOrgSupport.h
new file mode 100644
index 0000000..ae70dfa
--- /dev/null
+++ b/ZXingObjC/oned/ZXEANManufacturerOrgSupport.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * Records EAN prefix to GS1 Member Organization, where the member organization
+ * correlates strongly with a country. This is an imperfect means of identifying
+ * a country of origin by EAN-13 barcode value. See
+ * http://en.wikipedia.org/wiki/List_of_GS1_country_codes
+ */
+
+@interface ZXEANManufacturerOrgSupport : NSObject
+
+- (NSString *)lookupCountryIdentifier:(NSString *)productCode;
+
+@end
diff --git a/ZXingObjC/oned/ZXEANManufacturerOrgSupport.m b/ZXingObjC/oned/ZXEANManufacturerOrgSupport.m
new file mode 100644
index 0000000..6b636c2
--- /dev/null
+++ b/ZXingObjC/oned/ZXEANManufacturerOrgSupport.m
@@ -0,0 +1,178 @@
+/*
+ * 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 "ZXEANManufacturerOrgSupport.h"
+
+@interface ZXEANManufacturerOrgSupport ()
+
+@property (nonatomic, strong) NSMutableArray *countryIdentifiers;
+@property (nonatomic, strong) NSMutableArray *ranges;
+
+@end
+
+@implementation ZXEANManufacturerOrgSupport
+
+- (id)init {
+ if (self = [super init]) {
+ _ranges = [NSMutableArray array];
+ _countryIdentifiers = [NSMutableArray array];
+ }
+
+ return self;
+}
+
+- (NSString *)lookupCountryIdentifier:(NSString *)productCode {
+ [self initIfNeeded];
+
+ int prefix = [[productCode substringToIndex:3] intValue];
+ NSUInteger max = self.ranges.count;
+
+ for (int i = 0; i < max; i++) {
+ NSArray *range = self.ranges[i];
+ int start = [range[0] intValue];
+ if (prefix < start) {
+ return nil;
+ }
+ int end = [range count] == 1 ? start : [range[1] intValue];
+ if (prefix <= end) {
+ return self.countryIdentifiers[i];
+ }
+ }
+
+ return nil;
+}
+
+- (void)add:(NSArray *)range identifier:(NSString *)identifier {
+ [self.ranges addObject:range];
+ [self.countryIdentifiers addObject:identifier];
+}
+
+- (void)initIfNeeded {
+ @synchronized(self.ranges) {
+ if ([self.ranges count] > 0) {
+ return;
+ }
+
+ [self add:@[@0, @19] identifier:@"US/CA"];
+ [self add:@[@30, @39] identifier:@"US"];
+ [self add:@[@60, @139] identifier:@"US/CA"];
+ [self add:@[@300, @379] identifier:@"FR"];
+ [self add:@[@380] identifier:@"BG"];
+ [self add:@[@383] identifier:@"SI"];
+ [self add:@[@385] identifier:@"HR"];
+ [self add:@[@387] identifier:@"BA"];
+ [self add:@[@400, @440] identifier:@"DE"];
+ [self add:@[@450, @459] identifier:@"JP"];
+ [self add:@[@460, @469] identifier:@"RU"];
+ [self add:@[@471] identifier:@"TW"];
+ [self add:@[@474] identifier:@"EE"];
+ [self add:@[@475] identifier:@"LV"];
+ [self add:@[@476] identifier:@"AZ"];
+ [self add:@[@477] identifier:@"LT"];
+ [self add:@[@478] identifier:@"UZ"];
+ [self add:@[@479] identifier:@"LK"];
+ [self add:@[@480] identifier:@"PH"];
+ [self add:@[@481] identifier:@"BY"];
+ [self add:@[@482] identifier:@"UA"];
+ [self add:@[@484] identifier:@"MD"];
+ [self add:@[@485] identifier:@"AM"];
+ [self add:@[@486] identifier:@"GE"];
+ [self add:@[@487] identifier:@"KZ"];
+ [self add:@[@489] identifier:@"HK"];
+ [self add:@[@490, @499] identifier:@"JP"];
+ [self add:@[@500, @509] identifier:@"GB"];
+ [self add:@[@520] identifier:@"GR"];
+ [self add:@[@528] identifier:@"LB"];
+ [self add:@[@529] identifier:@"CY"];
+ [self add:@[@531] identifier:@"MK"];
+ [self add:@[@535] identifier:@"MT"];
+ [self add:@[@539] identifier:@"IE"];
+ [self add:@[@540, @549] identifier:@"BE/LU"];
+ [self add:@[@560] identifier:@"PT"];
+ [self add:@[@569] identifier:@"IS"];
+ [self add:@[@570, @579] identifier:@"DK"];
+ [self add:@[@590] identifier:@"PL"];
+ [self add:@[@594] identifier:@"RO"];
+ [self add:@[@599] identifier:@"HU"];
+ [self add:@[@600, @601] identifier:@"ZA"];
+ [self add:@[@603] identifier:@"GH"];
+ [self add:@[@608] identifier:@"BH"];
+ [self add:@[@609] identifier:@"MU"];
+ [self add:@[@611] identifier:@"MA"];
+ [self add:@[@613] identifier:@"DZ"];
+ [self add:@[@616] identifier:@"KE"];
+ [self add:@[@618] identifier:@"CI"];
+ [self add:@[@619] identifier:@"TN"];
+ [self add:@[@621] identifier:@"SY"];
+ [self add:@[@622] identifier:@"EG"];
+ [self add:@[@624] identifier:@"LY"];
+ [self add:@[@625] identifier:@"JO"];
+ [self add:@[@626] identifier:@"IR"];
+ [self add:@[@627] identifier:@"KW"];
+ [self add:@[@628] identifier:@"SA"];
+ [self add:@[@629] identifier:@"AE"];
+ [self add:@[@640, @649] identifier:@"FI"];
+ [self add:@[@690, @695] identifier:@"CN"];
+ [self add:@[@700, @709] identifier:@"NO"];
+ [self add:@[@729] identifier:@"IL"];
+ [self add:@[@730, @739] identifier:@"SE"];
+ [self add:@[@740] identifier:@"GT"];
+ [self add:@[@741] identifier:@"SV"];
+ [self add:@[@742] identifier:@"HN"];
+ [self add:@[@743] identifier:@"NI"];
+ [self add:@[@744] identifier:@"CR"];
+ [self add:@[@745] identifier:@"PA"];
+ [self add:@[@746] identifier:@"DO"];
+ [self add:@[@750] identifier:@"MX"];
+ [self add:@[@754, @755] identifier:@"CA"];
+ [self add:@[@759] identifier:@"VE"];
+ [self add:@[@760, @769] identifier:@"CH"];
+ [self add:@[@770] identifier:@"CO"];
+ [self add:@[@773] identifier:@"UY"];
+ [self add:@[@775] identifier:@"PE"];
+ [self add:@[@777] identifier:@"BO"];
+ [self add:@[@779] identifier:@"AR"];
+ [self add:@[@780] identifier:@"CL"];
+ [self add:@[@784] identifier:@"PY"];
+ [self add:@[@785] identifier:@"PE"];
+ [self add:@[@786] identifier:@"EC"];
+ [self add:@[@789, @790] identifier:@"BR"];
+ [self add:@[@800, @839] identifier:@"IT"];
+ [self add:@[@840, @849] identifier:@"ES"];
+ [self add:@[@850] identifier:@"CU"];
+ [self add:@[@858] identifier:@"SK"];
+ [self add:@[@859] identifier:@"CZ"];
+ [self add:@[@860] identifier:@"YU"];
+ [self add:@[@865] identifier:@"MN"];
+ [self add:@[@867] identifier:@"KP"];
+ [self add:@[@868, @869] identifier:@"TR"];
+ [self add:@[@870, @879] identifier:@"NL"];
+ [self add:@[@880] identifier:@"KR"];
+ [self add:@[@885] identifier:@"TH"];
+ [self add:@[@888] identifier:@"SG"];
+ [self add:@[@890] identifier:@"IN"];
+ [self add:@[@893] identifier:@"VN"];
+ [self add:@[@896] identifier:@"PK"];
+ [self add:@[@899] identifier:@"ID"];
+ [self add:@[@900, @919] identifier:@"AT"];
+ [self add:@[@930, @939] identifier:@"AU"];
+ [self add:@[@940, @949] identifier:@"AZ"];
+ [self add:@[@955] identifier:@"MY"];
+ [self add:@[@958] identifier:@"MO"];
+ }
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXITFReader.h b/ZXingObjC/oned/ZXITFReader.h
new file mode 100644
index 0000000..9fa90cc
--- /dev/null
+++ b/ZXingObjC/oned/ZXITFReader.h
@@ -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 "ZXOneDReader.h"
+
+/**
+ * Implements decoding of the ITF format, or Interleaved Two of Five.
+ *
+ * This Reader will scan ITF barcodes of certain lengths only.
+ * At the moment it reads length 6, 8, 10, 12, 14, 16, 18, 20, 24, and 44 as these have appeared "in the wild". Not all
+ * lengths are scanned, especially shorter ones, to avoid false positives. This in turn is due to a lack of
+ * required checksum function.
+ *
+ * The checksum is optional and is not applied by this Reader. The consumer of the decoded
+ * value will have to apply a checksum if required.
+ *
+ * http://en.wikipedia.org/wiki/Interleaved_2_of_5 is a great reference for Interleaved 2 of 5 information.
+ */
+
+extern const int PATTERNS_LEN;
+extern const int PATTERNS[][5];
+
+@class ZXResult;
+
+@interface ZXITFReader : ZXOneDReader
+
+- (NSArray *)decodeStart:(ZXBitArray *)row;
+- (NSArray *)decodeEnd:(ZXBitArray *)row;
+
+@end
diff --git a/ZXingObjC/oned/ZXITFReader.m b/ZXingObjC/oned/ZXITFReader.m
new file mode 100644
index 0000000..0d8d641
--- /dev/null
+++ b/ZXingObjC/oned/ZXITFReader.m
@@ -0,0 +1,318 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXITFReader.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+static int MAX_AVG_VARIANCE;
+static int MAX_INDIVIDUAL_VARIANCE;
+
+static const int W = 3; // Pixel width of a wide line
+static const int N = 1; // Pixel width of a narrow line
+
+int const DEFAULT_ALLOWED_LENGTHS[11] = { 48, 44, 24, 20, 18, 16, 14, 12, 10, 8, 6 };
+
+/**
+ * Start/end guard pattern.
+ *
+ * Note: The end pattern is reversed because the row is reversed before
+ * searching for the END_PATTERN
+ */
+int const ITF_START_PATTERN[4] = {N, N, N, N};
+int const END_PATTERN_REVERSED[3] = {N, N, W};
+
+/**
+ * Patterns of Wide / Narrow lines to indicate each digit
+ */
+const int PATTERNS_LEN = 10;
+const int PATTERNS[PATTERNS_LEN][5] = {
+ {N, N, W, W, N}, // 0
+ {W, N, N, N, W}, // 1
+ {N, W, N, N, W}, // 2
+ {W, W, N, N, N}, // 3
+ {N, N, W, N, W}, // 4
+ {W, N, W, N, N}, // 5
+ {N, W, W, N, N}, // 6
+ {N, N, N, W, W}, // 7
+ {W, N, N, W, N}, // 8
+ {N, W, N, W, N} // 9
+};
+
+@interface ZXITFReader ()
+
+@property (nonatomic, assign) int narrowLineWidth;
+
+@end
+
+@implementation ZXITFReader
+
++ (void)initialize {
+ MAX_AVG_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f);
+ MAX_INDIVIDUAL_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.8f);
+}
+
+- (id)init {
+ if (self = [super init]) {
+ _narrowLineWidth = -1;
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ NSArray *startRange = [self decodeStart:row];
+ NSArray *endRange = [self decodeEnd:row];
+ if (!startRange || !endRange) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ NSMutableString *resultString = [NSMutableString stringWithCapacity:20];
+ if (![self decodeMiddle:row payloadStart:[startRange[1] intValue] payloadEnd:[endRange[0] intValue] resultString:resultString]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ NSArray *allowedLengths = nil;
+ if (hints != nil) {
+ allowedLengths = hints.allowedLengths;
+ }
+ if (allowedLengths == nil) {
+ NSMutableArray *temp = [NSMutableArray array];
+ for (int i = 0; i < sizeof(DEFAULT_ALLOWED_LENGTHS) / sizeof(int); i++) {
+ [temp addObject:@(DEFAULT_ALLOWED_LENGTHS[i])];
+ }
+ allowedLengths = [NSArray arrayWithArray:temp];
+ }
+
+ NSUInteger length = [resultString length];
+ BOOL lengthOK = NO;
+ for (NSNumber *i in allowedLengths) {
+ if (length == [i intValue]) {
+ lengthOK = YES;
+ break;
+ }
+ }
+ if (!lengthOK) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+
+ return [ZXResult resultWithText:resultString
+ rawBytes:nil
+ length:0
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:[startRange[1] floatValue] y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:[endRange[0] floatValue] y:(float)rowNumber]]
+ format:kBarcodeFormatITF];
+}
+
+
+- (BOOL)decodeMiddle:(ZXBitArray *)row payloadStart:(int)payloadStart payloadEnd:(int)payloadEnd resultString:(NSMutableString *)resultString {
+ const int counterDigitPairLen = 10;
+ int counterDigitPair[counterDigitPairLen];
+ memset(counterDigitPair, 0, counterDigitPairLen * sizeof(int));
+
+ const int counterBlackLen = 5;
+ int counterBlack[counterBlackLen];
+ memset(counterBlack, 0, counterBlackLen * sizeof(int));
+
+ const int counterWhiteLen = 5;
+ int counterWhite[counterWhiteLen];
+ memset(counterWhite, 0, counterWhiteLen * sizeof(int));
+
+ while (payloadStart < payloadEnd) {
+ if (![ZXOneDReader recordPattern:row start:payloadStart counters:counterDigitPair countersSize:counterDigitPairLen]) {
+ return NO;
+ }
+
+ for (int k = 0; k < 5; k++) {
+ int twoK = k << 1;
+ counterBlack[k] = counterDigitPair[twoK];
+ counterWhite[k] = counterDigitPair[twoK + 1];
+ }
+
+ int bestMatch = [self decodeDigit:counterBlack countersSize:counterBlackLen];
+ if (bestMatch == -1) {
+ return NO;
+ }
+ [resultString appendFormat:@"%C", (unichar)('0' + bestMatch)];
+ bestMatch = [self decodeDigit:counterWhite countersSize:counterWhiteLen];
+ if (bestMatch == -1) {
+ return NO;
+ }
+ [resultString appendFormat:@"%C", (unichar)('0' + bestMatch)];
+
+ for (int i = 0; i < counterDigitPairLen; i++) {
+ payloadStart += counterDigitPair[i];
+ }
+ }
+ return YES;
+}
+
+
+/**
+ * Identify where the start of the middle / payload section starts.
+ */
+- (NSArray *)decodeStart:(ZXBitArray *)row {
+ int endStart = [self skipWhiteSpace:row];
+ if (endStart == -1) {
+ return nil;
+ }
+ NSArray *startPattern = [self findGuardPattern:row rowOffset:endStart pattern:(int *)ITF_START_PATTERN patternLen:sizeof(ITF_START_PATTERN)/sizeof(int)];
+ if (!startPattern) {
+ return nil;
+ }
+
+ self.narrowLineWidth = ([startPattern[1] intValue] - [startPattern[0] intValue]) >> 2;
+
+ if (![self validateQuietZone:row startPattern:[startPattern[0] intValue]]) {
+ return nil;
+ }
+
+ return startPattern;
+}
+
+
+/**
+ * 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. Scan back until
+ * we either get to the start of the barcode or match the necessary number of
+ * quiet zone pixels.
+ *
+ * Note: Its assumed the row is reversed when using this method to find
+ * quiet zone after the end pattern.
+ *
+ * ref: http://www.barcode-1.net/i25code.html
+ */
+- (BOOL)validateQuietZone:(ZXBitArray *)row startPattern:(int)startPattern {
+ int quietCount = self.narrowLineWidth * 10;
+
+ for (int i = startPattern - 1; quietCount > 0 && i >= 0; i--) {
+ if ([row get:i]) {
+ break;
+ }
+ quietCount--;
+ }
+ if (quietCount != 0) {
+ return NO;
+ }
+ return YES;
+}
+
+
+/**
+ * Skip all whitespace until we get to the first black line.
+ */
+- (int)skipWhiteSpace:(ZXBitArray *)row {
+ int width = [row size];
+ int endStart = [row nextSet:0];
+ if (endStart == width) {
+ return -1;
+ }
+ return endStart;
+}
+
+
+/**
+ * Identify where the end of the middle / payload section ends.
+ */
+- (NSArray *)decodeEnd:(ZXBitArray *)row {
+ [row reverse];
+
+ int endStart = [self skipWhiteSpace:row];
+ if (endStart == -1) {
+ [row reverse];
+ return nil;
+ }
+ NSMutableArray *endPattern = [[self findGuardPattern:row rowOffset:endStart pattern:(int *)END_PATTERN_REVERSED patternLen:sizeof(END_PATTERN_REVERSED)/sizeof(int)] mutableCopy];
+ if (!endPattern) {
+ [row reverse];
+ return nil;
+ }
+ [self validateQuietZone:row startPattern:[endPattern[0] intValue]];
+ int temp = [endPattern[0] intValue];
+ endPattern[0] = @([row size] - [endPattern[1] intValue]);
+ endPattern[1] = @([row size] - temp);
+ [row reverse];
+ return endPattern;
+}
+
+- (NSArray *)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset pattern:(int[])pattern patternLen:(int)patternLen {
+ int patternLength = patternLen;
+ int counters[patternLength];
+ memset(counters, 0, patternLength * sizeof(int));
+ int width = row.size;
+ BOOL isWhite = NO;
+
+ int counterPosition = 0;
+ int patternStart = rowOffset;
+ for (int x = rowOffset; x < width; x++) {
+ if ([row get:x] ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if ([ZXOneDReader patternMatchVariance:counters countersSize:patternLength pattern:pattern maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE] < MAX_AVG_VARIANCE) {
+ return @[@(patternStart), @(x)];
+ }
+ patternStart += counters[0] + counters[1];
+ for (int y = 2; y < patternLength; y++) {
+ counters[y - 2] = counters[y];
+ }
+ counters[patternLength - 2] = 0;
+ counters[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return nil;
+}
+
+/**
+ * Attempts to decode a sequence of ITF black/white lines into single
+ * digit.
+ */
+- (int)decodeDigit:(int[])counters countersSize:(int)countersSize {
+ int bestVariance = MAX_AVG_VARIANCE;
+ int bestMatch = -1;
+ int max = PATTERNS_LEN;
+ for (int i = 0; i < max; i++) {
+ int pattern[countersSize];
+ for(int ind = 0; ind<countersSize; ind++){
+ pattern[ind] = PATTERNS[i][ind];
+ }
+ int variance = [ZXOneDReader patternMatchVariance:counters countersSize:countersSize pattern:pattern maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE];
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = i;
+ }
+ }
+ if (bestMatch >= 0) {
+ return bestMatch;
+ } else {
+ return -1;
+ }
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXITFWriter.h b/ZXingObjC/oned/ZXITFWriter.h
new file mode 100644
index 0000000..1ddb330
--- /dev/null
+++ b/ZXingObjC/oned/ZXITFWriter.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXOneDimensionalCodeWriter.h"
+
+/**
+ * This object renders a ITF code as a {@link BitMatrix}.
+ */
+
+@interface ZXITFWriter : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/ZXingObjC/oned/ZXITFWriter.m b/ZXingObjC/oned/ZXITFWriter.m
new file mode 100644
index 0000000..600a8a2
--- /dev/null
+++ b/ZXingObjC/oned/ZXITFWriter.m
@@ -0,0 +1,66 @@
+/*
+ * 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 "ZXITFReader.h"
+#import "ZXITFWriter.h"
+
+const int ITF_WRITER_START_PATTERN_LEN = 4;
+const int ITF_WRITER_START_PATTERN[ITF_WRITER_START_PATTERN_LEN] = {1, 1, 1, 1};
+
+const int ITF_WRITER_END_PATTERN_LEN = 3;
+const int ITF_WRITER_END_PATTERN[ITF_WRITER_END_PATTERN_LEN] = {3, 1, 1};
+
+@implementation ZXITFWriter
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if (format != kBarcodeFormatITF) {
+ [NSException raise:NSInvalidArgumentException format:@"Can only encode ITF"];
+ }
+
+ return [super encode:contents format:format width:width height:height hints:hints error:error];
+}
+
+- (BOOL *)encode:(NSString *)contents length:(int *)pLength {
+ NSUInteger length = [contents length];
+ if (length % 2 != 0) {
+ [NSException raise:NSInvalidArgumentException format:@"The length of the input should be even"];
+ }
+ if (length > 80) {
+ [NSException raise:NSInvalidArgumentException format:@"Requested contents should be less than 80 digits long, but got %ld", (unsigned long)length];
+ }
+
+ NSUInteger resultLen = 9 + 9 * length;
+ if (pLength) *pLength = (int)resultLen;
+ BOOL *result = (BOOL *)malloc(resultLen * sizeof(BOOL));
+ int pos = [super appendPattern:result pos:0 pattern:(int *)ITF_WRITER_START_PATTERN patternLen:ITF_WRITER_START_PATTERN_LEN startColor:TRUE];
+ 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;
+ int encoding[encodingLen];
+ memset(encoding, 0, encodingLen * sizeof(int));
+ for (int j = 0; j < 5; j++) {
+ encoding[j << 1] = PATTERNS[one][j];
+ encoding[(j << 1) + 1] = PATTERNS[two][j];
+ }
+ pos += [super appendPattern:result pos:pos pattern:encoding patternLen:encodingLen startColor:TRUE];
+ }
+ [super appendPattern:result pos:pos pattern:(int *)ITF_WRITER_END_PATTERN patternLen:ITF_WRITER_END_PATTERN_LEN startColor:TRUE];
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXMultiFormatOneDReader.h b/ZXingObjC/oned/ZXMultiFormatOneDReader.h
new file mode 100644
index 0000000..71a4eb2
--- /dev/null
+++ b/ZXingObjC/oned/ZXMultiFormatOneDReader.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXOneDReader.h"
+
+@class ZXDecodeHints;
+
+@interface ZXMultiFormatOneDReader : ZXOneDReader
+
+- (id)initWithHints:(ZXDecodeHints *)hints;
+
+@end
diff --git a/ZXingObjC/oned/ZXMultiFormatOneDReader.m b/ZXingObjC/oned/ZXMultiFormatOneDReader.m
new file mode 100644
index 0000000..f7f5986
--- /dev/null
+++ b/ZXingObjC/oned/ZXMultiFormatOneDReader.m
@@ -0,0 +1,111 @@
+/*
+ * 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 "ZXCodaBarReader.h"
+#import "ZXCode128Reader.h"
+#import "ZXCode39Reader.h"
+#import "ZXCode93Reader.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXITFReader.h"
+#import "ZXMultiFormatOneDReader.h"
+#import "ZXMultiFormatUPCEANReader.h"
+#import "ZXRSS14Reader.h"
+#import "ZXRSSExpandedReader.h"
+
+@interface ZXMultiFormatOneDReader ()
+
+@property (nonatomic, strong) NSMutableArray *readers;
+
+@end
+
+@implementation ZXMultiFormatOneDReader
+
+- (id)initWithHints:(ZXDecodeHints *)hints {
+ if (self = [super init]) {
+ BOOL useCode39CheckDigit = hints != nil && hints.assumeCode39CheckDigit;
+ _readers = [NSMutableArray array];
+ if (hints != nil) {
+ if ([hints containsFormat:kBarcodeFormatEan13] ||
+ [hints containsFormat:kBarcodeFormatUPCA] ||
+ [hints containsFormat:kBarcodeFormatEan8] ||
+ [hints containsFormat:kBarcodeFormatUPCE]) {
+ [_readers addObject:[[ZXMultiFormatUPCEANReader alloc] initWithHints:hints]];
+ }
+
+ if ([hints containsFormat:kBarcodeFormatCode39]) {
+ [_readers addObject:[[ZXCode39Reader alloc] initUsingCheckDigit:useCode39CheckDigit]];
+ }
+
+ if ([hints containsFormat:kBarcodeFormatCode93]) {
+ [_readers addObject:[[ZXCode93Reader alloc] init]];
+ }
+
+ if ([hints containsFormat:kBarcodeFormatCode128]) {
+ [_readers addObject:[[ZXCode128Reader alloc] init]];
+ }
+
+ if ([hints containsFormat:kBarcodeFormatITF]) {
+ [_readers addObject:[[ZXITFReader alloc] init]];
+ }
+
+ if ([hints containsFormat:kBarcodeFormatCodabar]) {
+ [_readers addObject:[[ZXCodaBarReader alloc] init]];
+ }
+
+ if ([hints containsFormat:kBarcodeFormatRSS14]) {
+ [_readers addObject:[[ZXRSS14Reader alloc] init]];
+ }
+
+ if ([hints containsFormat:kBarcodeFormatRSSExpanded]) {
+ [_readers addObject:[[ZXRSSExpandedReader alloc] init]];
+ }
+ }
+
+ if ([_readers count] == 0) {
+ [_readers addObject:[[ZXMultiFormatUPCEANReader alloc] initWithHints:hints]];
+ [_readers addObject:[[ZXCode39Reader alloc] init]];
+ [_readers addObject:[[ZXCodaBarReader alloc] init]];
+ [_readers addObject:[[ZXCode93Reader alloc] init]];
+ [_readers addObject:[[ZXCode128Reader alloc] init]];
+ [_readers addObject:[[ZXITFReader alloc] init]];
+ [_readers addObject:[[ZXRSS14Reader alloc] init]];
+ [_readers addObject:[[ZXRSSExpandedReader alloc] init]];
+ }
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ for (ZXOneDReader *reader in self.readers) {
+ ZXResult *result = [reader decodeRow:rowNumber row:row hints:hints error:error];
+ if (result) {
+ return result;
+ }
+ }
+
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+}
+
+- (void)reset {
+ for (id<ZXReader> reader in self.readers) {
+ [reader reset];
+ }
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXMultiFormatUPCEANReader.h b/ZXingObjC/oned/ZXMultiFormatUPCEANReader.h
new file mode 100644
index 0000000..32385e6
--- /dev/null
+++ b/ZXingObjC/oned/ZXMultiFormatUPCEANReader.h
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXOneDReader.h"
+
+/**
+ * A reader that can read all available UPC/EAN formats. If a caller wants to try to
+ * read all such formats, it is most efficient to use this implementation rather than invoke
+ * individual readers.
+ */
+
+@class ZXDecodeHints;
+
+@interface ZXMultiFormatUPCEANReader : ZXOneDReader
+
+- (id)initWithHints:(ZXDecodeHints *)hints;
+
+@end
diff --git a/ZXingObjC/oned/ZXMultiFormatUPCEANReader.m b/ZXingObjC/oned/ZXMultiFormatUPCEANReader.m
new file mode 100644
index 0000000..202d632
--- /dev/null
+++ b/ZXingObjC/oned/ZXMultiFormatUPCEANReader.m
@@ -0,0 +1,113 @@
+/*
+ * 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 "ZXDecodeHints.h"
+#import "ZXEAN8Reader.h"
+#import "ZXEAN13Reader.h"
+#import "ZXErrors.h"
+#import "ZXMultiFormatUPCEANReader.h"
+#import "ZXReader.h"
+#import "ZXResult.h"
+#import "ZXUPCAReader.h"
+#import "ZXUPCEReader.h"
+
+@interface ZXMultiFormatUPCEANReader ()
+
+@property (nonatomic, strong) NSMutableArray *readers;
+
+@end
+
+@implementation ZXMultiFormatUPCEANReader
+
+- (id)initWithHints:(ZXDecodeHints *)hints {
+ if (self = [super init]) {
+ _readers = [NSMutableArray array];
+
+ if (hints != nil) {
+ if ([hints containsFormat:kBarcodeFormatEan13]) {
+ [_readers addObject:[[ZXEAN13Reader alloc] init]];
+ } else if ([hints containsFormat:kBarcodeFormatUPCA]) {
+ [_readers addObject:[[ZXUPCAReader alloc] init]];
+ }
+
+ if ([hints containsFormat:kBarcodeFormatEan8]) {
+ [_readers addObject:[[ZXEAN8Reader alloc] init]];
+ }
+
+ if ([hints containsFormat:kBarcodeFormatUPCE]) {
+ [_readers addObject:[[ZXUPCEReader alloc] init]];
+ }
+ }
+
+ if ([_readers count] == 0) {
+ [_readers addObject:[[ZXEAN13Reader alloc] init]];
+ [_readers addObject:[[ZXEAN8Reader alloc] init]];
+ [_readers addObject:[[ZXUPCEReader alloc] init]];
+ }
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ NSRange startGuardPattern = [ZXUPCEANReader findStartGuardPattern:row error:error];
+ if (startGuardPattern.location == NSNotFound) {
+ return nil;
+ }
+ for (ZXUPCEANReader *reader in self.readers) {
+ ZXResult *result = [reader decodeRow:rowNumber row:row startGuardRange:startGuardPattern hints:hints error:error];
+ if (!result) {
+ continue;
+ }
+
+ // Special case: a 12-digit code encoded in UPC-A is identical to a "0"
+ // followed by those 12 digits encoded as EAN-13. Each will recognize such a code,
+ // UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with "0".
+ // Individually these are correct and their readers will both read such a code
+ // and correctly call it EAN-13, or UPC-A, respectively.
+ //
+ // In this case, if we've been looking for both types, we'd like to call it
+ // a UPC-A code. But for efficiency we only run the EAN-13 decoder to also read
+ // UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A
+ // result if appropriate.
+ //
+ // But, don't return UPC-A if UPC-A was not a requested format!
+ BOOL ean13MayBeUPCA = kBarcodeFormatEan13 == result.barcodeFormat && [result.text characterAtIndex:0] == '0';
+ BOOL canReturnUPCA = hints == nil || [hints numberOfPossibleFormats] == 0 || [hints containsFormat:kBarcodeFormatUPCA];
+ if (ean13MayBeUPCA && canReturnUPCA) {
+ // Transfer the metdata across
+ ZXResult *resultUPCA = [ZXResult resultWithText:[result.text substringFromIndex:1]
+ rawBytes:result.rawBytes
+ length:result.length
+ resultPoints:result.resultPoints
+ format:kBarcodeFormatUPCA];
+ [resultUPCA putAllMetadata:result.resultMetadata];
+ return resultUPCA;
+ }
+ return result;
+ }
+
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+}
+
+- (void)reset {
+ for (id<ZXReader> reader in self.readers) {
+ [reader reset];
+ }
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXOneDReader.h b/ZXingObjC/oned/ZXOneDReader.h
new file mode 100644
index 0000000..3752eed
--- /dev/null
+++ b/ZXingObjC/oned/ZXOneDReader.h
@@ -0,0 +1,36 @@
+/*
+ * 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 "ZXReader.h"
+
+/**
+ * Encapsulates functionality and implementation that is common to all families
+ * of one-dimensional barcodes.
+ */
+
+extern int const INTEGER_MATH_SHIFT;
+extern int const PATTERN_MATCH_RESULT_SCALE_FACTOR;
+
+@class ZXBitArray, ZXDecodeHints, ZXResult;
+
+@interface ZXOneDReader : NSObject <ZXReader>
+
++ (BOOL)recordPattern:(ZXBitArray *)row start:(int)start counters:(int[])counters countersSize:(int)countersSize;
++ (BOOL)recordPatternInReverse:(ZXBitArray *)row start:(int)start counters:(int[])counters countersSize:(int)countersSize;
++ (int)patternMatchVariance:(int[])counters countersSize:(int)countersSize pattern:(int[])pattern maxIndividualVariance:(int)maxIndividualVariance;
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/oned/ZXOneDReader.m b/ZXingObjC/oned/ZXOneDReader.m
new file mode 100644
index 0000000..d53bb96
--- /dev/null
+++ b/ZXingObjC/oned/ZXOneDReader.m
@@ -0,0 +1,259 @@
+/*
+ * 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 "ZXBinaryBitmap.h"
+#import "ZXBitArray.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXOneDReader.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+int const INTEGER_MATH_SHIFT = 8;
+int const PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << INTEGER_MATH_SHIFT;
+
+@implementation ZXOneDReader
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decode:image hints:nil error:error];
+}
+
+// Note that we don't try rotation without the try harder flag, even if rotation was supported.
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ NSError *decodeError = nil;
+ ZXResult *result = [self doDecode:image hints:hints error:&decodeError];
+ if (result) {
+ return result;
+ } else if (decodeError.code == ZXNotFoundError) {
+ BOOL tryHarder = hints != nil && hints.tryHarder;
+ if (tryHarder && [image rotateSupported]) {
+ ZXBinaryBitmap *rotatedImage = [image rotateCounterClockwise];
+ ZXResult *result = [self doDecode:rotatedImage hints:hints error:error];
+ if (!result) {
+ return nil;
+ }
+ // Record that we found it rotated 90 degrees CCW / 270 degrees CW
+ NSMutableDictionary *metadata = [result resultMetadata];
+ int orientation = 270;
+ if (metadata != nil && metadata[@(kResultMetadataTypeOrientation)]) {
+ // But if we found it reversed in doDecode(), add in that result here:
+ orientation = (orientation + [((NSNumber *)metadata[@(kResultMetadataTypeOrientation)]) intValue]) % 360;
+ }
+ [result putMetadata:kResultMetadataTypeOrientation value:@(orientation)];
+ // Update result points
+ NSMutableArray *points = [result resultPoints];
+ if (points != nil) {
+ int height = [rotatedImage height];
+ for (int i = 0; i < [points count]; i++) {
+ points[i] = [[ZXResultPoint alloc] initWithX:height - [(ZXResultPoint *)points[i] y]
+ y:[(ZXResultPoint *)points[i] x]];
+ }
+ }
+ return result;
+ }
+ }
+
+ if (error) *error = decodeError;
+ return nil;
+}
+
+- (void)reset {
+
+}
+
+
+/**
+ * We're going to examine rows from the middle outward, searching alternately above and below the
+ * middle, and farther out each time. rowStep is the number of rows between each successive
+ * attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
+ * middle + rowStep, then middle - (2 * rowStep), etc.
+ * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
+ * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
+ * image if "trying harder".
+ */
+- (ZXResult *)doDecode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ int width = image.width;
+ int height = image.height;
+ ZXBitArray *row = [[ZXBitArray alloc] initWithSize:width];
+ int middle = height >> 1;
+ BOOL tryHarder = hints != nil && hints.tryHarder;
+ int rowStep = MAX(1, height >> (tryHarder ? 8 : 5));
+ int maxLines;
+ if (tryHarder) {
+ maxLines = height;
+ } else {
+ maxLines = 15;
+ }
+
+ for (int x = 0; x < maxLines; x++) {
+ int rowStepsAboveOrBelow = (x + 1) >> 1;
+ BOOL isAbove = (x & 0x01) == 0;
+ int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
+ if (rowNumber < 0 || rowNumber >= height) {
+ break;
+ }
+
+ NSError *rowError = nil;
+ row = [image blackRow:rowNumber row:row error:&rowError];
+ if (!row && rowError.code == ZXNotFoundError) {
+ continue;
+ } else if (!row) {
+ if (error) *error = rowError;
+ return nil;
+ }
+
+ for (int attempt = 0; attempt < 2; attempt++) {
+ if (attempt == 1) {
+ [row reverse];
+ if (hints != nil && hints.resultPointCallback) {
+ hints = [hints copy];
+ hints.resultPointCallback = nil;
+ }
+ }
+
+ ZXResult *result = [self decodeRow:rowNumber row:row hints:hints error:nil];
+ if (result) {
+ if (attempt == 1) {
+ [result putMetadata:kResultMetadataTypeOrientation value:@180];
+ NSMutableArray *points = [result resultPoints];
+ if (points != nil) {
+ points[0] = [[ZXResultPoint alloc] initWithX:width - [(ZXResultPoint *)points[0] x]
+ y:[(ZXResultPoint *)points[0] y]];
+ points[1] = [[ZXResultPoint alloc] initWithX:width - [(ZXResultPoint *)points[1] x]
+ y:[(ZXResultPoint *)points[1] y]];
+ }
+ }
+ return result;
+ }
+ }
+ }
+
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+}
+
+
+/**
+ * Records the size of successive runs of white and black pixels in a row, starting at a given point.
+ * The values are recorded in the given array, and the number of runs recorded is equal to the size
+ * of the array. If the row starts on a white pixel at the given start point, then the first count
+ * recorded is the run of white pixels starting from that point; likewise it is the count of a run
+ * of black pixels if the row begin on a black pixels at that point.
+ */
++ (BOOL)recordPattern:(ZXBitArray *)row start:(int)start counters:(int[])counters countersSize:(int)countersSize {
+ int numCounters = countersSize;
+
+ memset(counters, 0, numCounters * sizeof(int));
+
+ int end = row.size;
+ if (start >= end) {
+ return NO;
+ }
+ BOOL isWhite = ![row get:start];
+ int counterPosition = 0;
+ int i = start;
+
+ while (i < end) {
+ if ([row get:i] ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ counterPosition++;
+ if (counterPosition == numCounters) {
+ break;
+ } else {
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ i++;
+ }
+
+ if (!(counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end))) {
+ return NO;
+ }
+ return YES;
+}
+
++ (BOOL)recordPatternInReverse:(ZXBitArray *)row start:(int)start counters:(int[])counters countersSize:(int)countersSize {
+ int numTransitionsLeft = countersSize;
+ BOOL last = [row get:start];
+
+ while (start > 0 && numTransitionsLeft >= 0) {
+ if ([row get:--start] != last) {
+ numTransitionsLeft--;
+ last = !last;
+ }
+ }
+
+ if (numTransitionsLeft >= 0 || ![self recordPattern:row start:start + 1 counters:counters countersSize:countersSize]) {
+ return NO;
+ }
+ return YES;
+}
+
+
+/**
+ * Determines how closely a set of observed counts of runs of black/white values matches a given
+ * target pattern. This is reported as the ratio of the total variance from the expected pattern
+ * proportions across all pattern elements, to the length of the pattern.
+ *
+ * Returns ratio of total variance between counters and pattern compared to total pattern size,
+ * where the ratio has been multiplied by 256. So, 0 means no variance (perfect match); 256 means
+ * the total variance between counters and patterns equals the pattern length, higher values mean
+ * even more variance
+ */
++ (int)patternMatchVariance:(int[])counters countersSize:(int)countersSize pattern:(int[])pattern maxIndividualVariance:(int)maxIndividualVariance {
+ int numCounters = countersSize;
+ int total = 0;
+ int patternLength = 0;
+
+ for (int i = 0; i < numCounters; i++) {
+ total += counters[i];
+ patternLength += pattern[i];
+ }
+
+ if (total < patternLength || patternLength == 0) {
+ return INT_MAX;
+ }
+ int unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength;
+ maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT;
+ int totalVariance = 0;
+
+ for (int x = 0; x < numCounters; x++) {
+ int counter = counters[x] << INTEGER_MATH_SHIFT;
+ int scaledPattern = pattern[x] * unitBarWidth;
+ int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
+ if (variance > maxIndividualVariance) {
+ return INT_MAX;
+ }
+ totalVariance += variance;
+ }
+
+ return totalVariance / total;
+}
+
+
+/**
+ * Attempts to decode a one-dimensional barcode format given a single row of
+ * an image.
+ */
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXOneDimensionalCodeWriter.h b/ZXingObjC/oned/ZXOneDimensionalCodeWriter.h
new file mode 100644
index 0000000..e7734ae
--- /dev/null
+++ b/ZXingObjC/oned/ZXOneDimensionalCodeWriter.h
@@ -0,0 +1,28 @@
+/*
+ * 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 "ZXWriter.h"
+
+/**
+ * Encapsulates functionality and implementation that is common to one-dimensional barcodes.
+ */
+@interface ZXOneDimensionalCodeWriter : NSObject <ZXWriter>
+
+- (BOOL *)encode:(NSString *)contents length:(int *)pLength;
+- (int)appendPattern:(BOOL *)target pos:(int)pos pattern:(int *)pattern patternLen:(int)patternLen startColor:(BOOL)startColor;
+- (int)defaultMargin;
+
+@end
diff --git a/ZXingObjC/oned/ZXOneDimensionalCodeWriter.m b/ZXingObjC/oned/ZXOneDimensionalCodeWriter.m
new file mode 100644
index 0000000..a80269e
--- /dev/null
+++ b/ZXingObjC/oned/ZXOneDimensionalCodeWriter.m
@@ -0,0 +1,102 @@
+/*
+ * 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 "ZXEncodeHints.h"
+#import "ZXOneDimensionalCodeWriter.h"
+
+@implementation ZXOneDimensionalCodeWriter
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error {
+ return [self encode:contents format:format width:width height:height hints:nil error:error];
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height
+ hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if (contents.length == 0) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Found empty contents" userInfo:nil];
+ }
+
+ if (width < 0 || height < 0) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Negative size is not allowed. Input: %dx%d", width, height]
+ userInfo:nil];
+ }
+
+ int sidesMargin = [self defaultMargin];
+ if (hints && hints.margin) {
+ sidesMargin = hints.margin.intValue;
+ }
+
+ int length;
+ BOOL *code = [self encode:contents length:&length];
+ ZXBitMatrix *result = [self renderResult:code length:length width:width height:height sidesMargin:sidesMargin];
+ free(code);
+ return result;
+}
+
+- (ZXBitMatrix *)renderResult:(BOOL *)code length:(int)length width:(int)width height:(int)height sidesMargin:(int)sidesMargin {
+ int inputWidth = length;
+ // Add quiet zone on both sides.
+ int fullWidth = inputWidth + sidesMargin;
+ int outputWidth = MAX(width, fullWidth);
+ int outputHeight = MAX(1, height);
+
+ int multiple = outputWidth / fullWidth;
+ int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
+
+ ZXBitMatrix *output = [ZXBitMatrix bitMatrixWithWidth:outputWidth height:outputHeight];
+ for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
+ if (code[inputX]) {
+ [output setRegionAtLeft:outputX top:0 width:multiple height:outputHeight];
+ }
+ }
+ return output;
+}
+
+/**
+ * Appends the given pattern to the target array starting at pos.
+ */
+- (int)appendPattern:(BOOL *)target pos:(int)pos pattern:(int *)pattern patternLen:(int)patternLen startColor:(BOOL)startColor {
+ BOOL color = startColor;
+ int numAdded = 0;
+ for (int i = 0; i < patternLen; i++) {
+ for (int j = 0; j < pattern[i]; j++) {
+ target[pos++] = color;
+ }
+ numAdded += pattern[i];
+ color = !color; // flip color after each segment
+ }
+ return numAdded;
+}
+
+- (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.
+ return 10;
+}
+
+/**
+ * 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.
+ */
+- (BOOL *)encode:(NSString *)contents length:(int *)pLength {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCAReader.h b/ZXingObjC/oned/ZXUPCAReader.h
new file mode 100644
index 0000000..b343228
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCAReader.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXUPCEANReader.h"
+
+/**
+ * Implements decoding of the UPC-A format.
+ */
+
+@interface ZXUPCAReader : ZXUPCEANReader
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCAReader.m b/ZXingObjC/oned/ZXUPCAReader.m
new file mode 100644
index 0000000..c38aef3
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCAReader.m
@@ -0,0 +1,115 @@
+/*
+ * 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 "ZXEAN13Reader.h"
+#import "ZXErrors.h"
+#import "ZXResult.h"
+#import "ZXUPCAReader.h"
+
+@interface ZXUPCAReader ()
+
+@property (nonatomic, strong) ZXUPCEANReader *ean13Reader;
+
+@end
+
+@implementation ZXUPCAReader
+
+- (id)init {
+ if (self = [super init]) {
+ _ean13Reader = [[ZXEAN13Reader alloc] init];
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row startGuardRange:(NSRange)startGuardRange hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXResult *result = [self.ean13Reader decodeRow:rowNumber row:row startGuardRange:startGuardRange hints:hints error:error];
+ if (result) {
+ result = [self maybeReturnResult:result];
+ if (!result) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ return result;
+ } else {
+ return nil;
+ }
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXResult *result = [self.ean13Reader decodeRow:rowNumber row:row hints:hints error:error];
+ if (result) {
+ result = [self maybeReturnResult:result];
+ if (!result) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ return result;
+ } else {
+ return nil;
+ }
+}
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
+ ZXResult *result = [self.ean13Reader decode:image error:error];
+ if (result) {
+ result = [self maybeReturnResult:result];
+ if (!result) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ return result;
+ } else {
+ return nil;
+ }
+}
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXResult *result = [self.ean13Reader decode:image hints:hints error:error];
+ if (result) {
+ result = [self maybeReturnResult:result];
+ if (!result) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ return result;
+ } else {
+ return nil;
+ }
+}
+
+- (ZXBarcodeFormat)barcodeFormat {
+ return kBarcodeFormatUPCA;
+}
+
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ return [self.ean13Reader decodeMiddle:row startRange:startRange result:result error:error];
+}
+
+- (ZXResult *)maybeReturnResult:(ZXResult *)result {
+ NSString *text = result.text;
+ if ([text characterAtIndex:0] == '0') {
+ return [ZXResult resultWithText:[text substringFromIndex:1]
+ rawBytes:NULL
+ length:0
+ resultPoints:result.resultPoints
+ format:kBarcodeFormatUPCA];
+ } else {
+ return nil;
+ }
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCAWriter.h b/ZXingObjC/oned/ZXUPCAWriter.h
new file mode 100644
index 0000000..9bff2cb
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCAWriter.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXWriter.h"
+
+/**
+ * This object renders a UPC-A code as a ZXBitMatrix.
+ */
+
+@interface ZXUPCAWriter : NSObject <ZXWriter>
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCAWriter.m b/ZXingObjC/oned/ZXUPCAWriter.m
new file mode 100644
index 0000000..c88ebc3
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCAWriter.m
@@ -0,0 +1,66 @@
+/*
+ * 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 "ZXEAN13Writer.h"
+#import "ZXUPCAWriter.h"
+
+@implementation ZXUPCAWriter
+
+- (ZXEAN13Writer *)subWriter {
+ static ZXEAN13Writer *subWriter = nil;
+ if (!subWriter) {
+ subWriter = [[ZXEAN13Writer alloc] init];
+ }
+
+ return subWriter;
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error {
+ return [self encode:contents format:format width:width height:height hints:nil error:error];
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if (format != kBarcodeFormatUPCA) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ 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];
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANExtension2Support.h b/ZXingObjC/oned/ZXUPCEANExtension2Support.h
new file mode 100644
index 0000000..438076c
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANExtension2Support.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@class ZXBitArray, ZXResult;
+
+@interface ZXUPCEANExtension2Support : NSObject
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row extensionStartRange:(NSRange)extensionStartRange error:(NSError **)error;
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANExtension2Support.m b/ZXingObjC/oned/ZXUPCEANExtension2Support.m
new file mode 100644
index 0000000..8f91063
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANExtension2Support.m
@@ -0,0 +1,99 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXBitArray.h"
+#import "ZXErrors.h"
+#import "ZXResult.h"
+#import "ZXResultMetadataType.h"
+#import "ZXResultPoint.h"
+#import "ZXUPCEANExtension2Support.h"
+#import "ZXUPCEANReader.h"
+
+@implementation ZXUPCEANExtension2Support
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row extensionStartRange:(NSRange)extensionStartRange error:(NSError **)error {
+ NSMutableString *resultString = [NSMutableString string];
+ int end = [self decodeMiddle:row startRange:extensionStartRange result:resultString error:error];
+ if (end == -1) {
+ return nil;
+ }
+
+ NSMutableDictionary *extensionData = [self parseExtensionString:resultString];
+
+ ZXResult *extensionResult = [[ZXResult alloc] initWithText:resultString
+ rawBytes:nil
+ length:0
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:(extensionStartRange.location + NSMaxRange(extensionStartRange)) / 2.0f y:rowNumber],
+ [[ZXResultPoint alloc] initWithX:end y:rowNumber]]
+ format:kBarcodeFormatUPCEANExtension];
+ if (extensionData != nil) {
+ [extensionResult putAllMetadata:extensionData];
+ }
+ return extensionResult;
+}
+
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ const int countersLen = 4;
+ int counters[countersLen];
+ memset(counters, 0, countersLen * sizeof(int));
+
+ int end = [row size];
+ int rowOffset = (int)NSMaxRange(startRange);
+
+ int checkParity = 0;
+
+ for (int x = 0; x < 2 && rowOffset < end; x++) {
+ int bestMatch = [ZXUPCEANReader decodeDigit:row counters:counters countersLen:countersLen rowOffset:rowOffset patternType:UPC_EAN_PATTERNS_L_AND_G_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch % 10)];
+ for (int i = 0; i < countersLen; i++) {
+ rowOffset += counters[i];
+ }
+ if (bestMatch >= 10) {
+ checkParity |= 1 << (1 - x);
+ }
+ if (x != 1) {
+ // Read off separator if not last
+ rowOffset = [row nextSet:rowOffset];
+ rowOffset = [row nextUnset:rowOffset];
+ }
+ }
+
+ if (result.length != 2) {
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ }
+
+ if ([result intValue] % 4 != checkParity) {
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ }
+
+ return rowOffset;
+}
+
+- (NSMutableDictionary *)parseExtensionString:(NSString *)raw {
+ if (raw.length != 2) {
+ return nil;
+ }
+ return [NSMutableDictionary dictionaryWithObject:@([raw intValue])
+ forKey:@(kResultMetadataTypeIssueNumber)];
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANExtension5Support.h b/ZXingObjC/oned/ZXUPCEANExtension5Support.h
new file mode 100644
index 0000000..31d1a16
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANExtension5Support.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@class ZXBitArray, ZXResult;
+
+@interface ZXUPCEANExtension5Support : NSObject
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row extensionStartRange:(NSRange)extensionStartRange error:(NSError **)error;
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANExtension5Support.m b/ZXingObjC/oned/ZXUPCEANExtension5Support.m
new file mode 100644
index 0000000..12eb9ed
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANExtension5Support.m
@@ -0,0 +1,166 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXBitArray.h"
+#import "ZXErrors.h"
+#import "ZXResult.h"
+#import "ZXResultMetadataType.h"
+#import "ZXResultPoint.h"
+#import "ZXUPCEANExtension5Support.h"
+#import "ZXUPCEANReader.h"
+
+const int CHECK_DIGIT_ENCODINGS[10] = {
+ 0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05
+};
+
+@implementation ZXUPCEANExtension5Support
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row extensionStartRange:(NSRange)extensionStartRange error:(NSError **)error {
+ NSMutableString *resultString = [NSMutableString string];
+ int end = [self decodeMiddle:row startRange:extensionStartRange result:resultString error:error];
+ if (end == -1) {
+ return nil;
+ }
+
+ NSMutableDictionary *extensionData = [self parseExtensionString:resultString];
+
+ ZXResult *extensionResult = [[ZXResult alloc] initWithText:resultString
+ rawBytes:nil
+ length:0
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:(extensionStartRange.location + NSMaxRange(extensionStartRange)) / 2.0f y:rowNumber],
+ [[ZXResultPoint alloc] initWithX:end y:rowNumber]]
+ format:kBarcodeFormatUPCEANExtension];
+ if (extensionData != nil) {
+ [extensionResult putAllMetadata:extensionData];
+ }
+ return extensionResult;
+}
+
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ const int countersLen = 4;
+ int counters[countersLen];
+ memset(counters, 0, countersLen * sizeof(int));
+
+ int end = [row size];
+ int rowOffset = (int)NSMaxRange(startRange);
+
+ int lgPatternFound = 0;
+
+ for (int x = 0; x < 5 && rowOffset < end; x++) {
+ int bestMatch = [ZXUPCEANReader decodeDigit:row counters:counters countersLen:countersLen rowOffset:rowOffset patternType:UPC_EAN_PATTERNS_L_AND_G_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch % 10)];
+ for (int i = 0; i < countersLen; i++) {
+ rowOffset += counters[i];
+ }
+ if (bestMatch >= 10) {
+ lgPatternFound |= 1 << (4 - x);
+ }
+ if (x != 4) {
+ rowOffset = [row nextSet:rowOffset];
+ rowOffset = [row nextUnset:rowOffset];
+ }
+ }
+
+ if (result.length != 5) {
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ }
+
+ int checkDigit = [self determineCheckDigit:lgPatternFound];
+ if (checkDigit == -1) {
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ } else if ([self extensionChecksum:result] != checkDigit) {
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ }
+
+ return rowOffset;
+}
+
+- (int)extensionChecksum:(NSString *)s {
+ int length = (int)[s length];
+ int sum = 0;
+ for (int i = length - 2; i >= 0; i -= 2) {
+ sum += (int)[s characterAtIndex:i] - (int)'0';
+ }
+ sum *= 3;
+ for (int i = length - 1; i >= 0; i -= 2) {
+ sum += (int)[s characterAtIndex:i] - (int)'0';
+ }
+ sum *= 3;
+ return sum % 10;
+}
+
+- (int)determineCheckDigit:(int)lgPatternFound {
+ for (int d = 0; d < 10; d++) {
+ if (lgPatternFound == CHECK_DIGIT_ENCODINGS[d]) {
+ return d;
+ }
+ }
+ return -1;
+}
+
+- (NSMutableDictionary *)parseExtensionString:(NSString *)raw {
+ if (raw.length != 5) {
+ return nil;
+ }
+ id value = [self parseExtension5String:raw];
+ if (value) {
+ return [NSMutableDictionary dictionaryWithObject:value forKey:@(kResultMetadataTypeSuggestedPrice)];
+ } else {
+ return nil;
+ }
+}
+
+- (NSString *)parseExtension5String:(NSString *)raw {
+ NSString *currency;
+ switch ([raw characterAtIndex:0]) {
+ case '0':
+ currency = @"£";
+ break;
+ case '5':
+ currency = @"$";
+ break;
+ case '9':
+ if ([@"90000" isEqualToString:raw]) {
+ return nil;
+ }
+ if ([@"99991" isEqualToString:raw]) {
+ return @"0.00";
+ }
+ if ([@"99990" isEqualToString:raw]) {
+ return @"Used";
+ }
+ currency = @"";
+ break;
+ default:
+ currency = @"";
+ break;
+ }
+ int rawAmount = [[raw substringFromIndex:1] intValue];
+ NSString *unitsString = [@(rawAmount / 100) stringValue];
+ int hundredths = rawAmount % 100;
+ NSString *hundredthsString = hundredths < 10 ?
+ [NSString stringWithFormat:@"0%d", hundredths] : [@(hundredths) stringValue];
+ return [NSString stringWithFormat:@"%@%@.%@", currency, unitsString, hundredthsString];
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANExtensionSupport.h b/ZXingObjC/oned/ZXUPCEANExtensionSupport.h
new file mode 100644
index 0000000..b94101c
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANExtensionSupport.h
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+@class ZXBitArray, ZXResult;
+
+@interface ZXUPCEANExtensionSupport : NSObject
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row rowOffset:(int)rowOffset error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANExtensionSupport.m b/ZXingObjC/oned/ZXUPCEANExtensionSupport.m
new file mode 100644
index 0000000..695448a
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANExtensionSupport.m
@@ -0,0 +1,58 @@
+/*
+ * 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 "ZXUPCEANExtensionSupport.h"
+#import "ZXUPCEANExtension2Support.h"
+#import "ZXUPCEANExtension5Support.h"
+#import "ZXUPCEANReader.h"
+
+#define EXTENSION_START_PATTERN_LEN 3
+const int EXTENSION_START_PATTERN[EXTENSION_START_PATTERN_LEN] = {1,1,2};
+
+@interface ZXUPCEANExtensionSupport ()
+
+@property (nonatomic, strong) ZXUPCEANExtension2Support *twoSupport;
+@property (nonatomic, strong) ZXUPCEANExtension5Support *fiveSupport;
+
+@end
+
+@implementation ZXUPCEANExtensionSupport
+
+- (id)init {
+ if (self = [super init]) {
+ _twoSupport = [[ZXUPCEANExtension2Support alloc] init];
+ _fiveSupport = [[ZXUPCEANExtension5Support alloc] init];
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row rowOffset:(int)rowOffset error:(NSError **)error {
+ NSRange extensionStartRange = [ZXUPCEANReader findGuardPattern:row rowOffset:rowOffset whiteFirst:NO pattern:(int *)EXTENSION_START_PATTERN patternLen:EXTENSION_START_PATTERN_LEN error:error];
+
+ if (extensionStartRange.location == NSNotFound) {
+ return nil;
+ }
+
+ ZXResult *result = [self.fiveSupport decodeRow:rowNumber row:row extensionStartRange:extensionStartRange error:error];
+ if (!result) {
+ result = [self.twoSupport decodeRow:rowNumber row:row extensionStartRange:extensionStartRange error:error];
+ }
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANReader.h b/ZXingObjC/oned/ZXUPCEANReader.h
new file mode 100644
index 0000000..225210c
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANReader.h
@@ -0,0 +1,54 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXOneDReader.h"
+
+/**
+ * Encapsulates functionality and implementation that is common to UPC and EAN families
+ * of one-dimensional barcodes.
+ */
+
+typedef enum {
+ UPC_EAN_PATTERNS_L_PATTERNS = 0,
+ UPC_EAN_PATTERNS_L_AND_G_PATTERNS
+} UPC_EAN_PATTERNS;
+
+#define START_END_PATTERN_LEN 3
+extern const int START_END_PATTERN[];
+#define MIDDLE_PATTERN_LEN 5
+extern const int MIDDLE_PATTERN[];
+#define L_PATTERNS_LEN 10
+#define L_PATTERNS_SUB_LEN 4
+extern const int L_PATTERNS[][4];
+extern const int L_AND_G_PATTERNS[][4];
+
+@class ZXDecodeHints, ZXEANManufacturerOrgSupport, ZXResult, ZXUPCEANExtensionSupport;
+
+@interface ZXUPCEANReader : ZXOneDReader
+
++ (NSRange)findStartGuardPattern:(ZXBitArray *)row error:(NSError **)error;
+- (ZXBarcodeFormat)barcodeFormat;
+- (BOOL)checkChecksum:(NSString *)s error:(NSError **)error;
++ (BOOL)checkStandardUPCEANChecksum:(NSString *)s;
++ (int)decodeDigit:(ZXBitArray *)row counters:(int[])counters countersLen:(int)countersLen rowOffset:(int)rowOffset patternType:(UPC_EAN_PATTERNS)patternType error:(NSError **)error;
+- (NSRange)decodeEnd:(ZXBitArray *)row endStart:(int)endStart error:(NSError **)error;
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error;
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row startGuardRange:(NSRange)startGuardRange hints:(ZXDecodeHints *)hints error:(NSError **)error;
++ (NSRange)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset whiteFirst:(BOOL)whiteFirst pattern:(int *)pattern patternLen:(int)patternLen error:(NSError **)error;
++ (NSRange)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset whiteFirst:(BOOL)whiteFirst pattern:(int *)pattern patternLen:(int)patternLen counters:(int *)counters error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANReader.m b/ZXingObjC/oned/ZXUPCEANReader.m
new file mode 100644
index 0000000..facc216
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANReader.m
@@ -0,0 +1,368 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXDecodeHints.h"
+#import "ZXEANManufacturerOrgSupport.h"
+#import "ZXErrors.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+#import "ZXResultPointCallback.h"
+#import "ZXUPCEANReader.h"
+#import "ZXUPCEANExtensionSupport.h"
+
+#define MAX_AVG_VARIANCE (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.48f)
+#define MAX_INDIVIDUAL_VARIANCE (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f)
+
+/**
+ * Start/end guard pattern.
+ */
+const int START_END_PATTERN[START_END_PATTERN_LEN] = {1, 1, 1};
+
+/**
+ * Pattern marking the middle of a UPC/EAN pattern, separating the two halves.
+ */
+const int MIDDLE_PATTERN[MIDDLE_PATTERN_LEN] = {1, 1, 1, 1, 1};
+
+/**
+ * "Odd", or "L" patterns used to encode UPC/EAN digits.
+ */
+const int L_PATTERNS[L_PATTERNS_LEN][L_PATTERNS_SUB_LEN] = {
+ {3, 2, 1, 1}, // 0
+ {2, 2, 2, 1}, // 1
+ {2, 1, 2, 2}, // 2
+ {1, 4, 1, 1}, // 3
+ {1, 1, 3, 2}, // 4
+ {1, 2, 3, 1}, // 5
+ {1, 1, 1, 4}, // 6
+ {1, 3, 1, 2}, // 7
+ {1, 2, 1, 3}, // 8
+ {3, 1, 1, 2} // 9
+};
+
+/**
+ * As above but also including the "even", or "G" patterns used to encode UPC/EAN digits.
+ */
+#define L_AND_G_PATTERNS_LEN 20
+#define L_AND_G_PATTERNS_SUB_LEN 4
+const int L_AND_G_PATTERNS[L_AND_G_PATTERNS_LEN][L_AND_G_PATTERNS_SUB_LEN] = {
+ {3, 2, 1, 1}, // 0
+ {2, 2, 2, 1}, // 1
+ {2, 1, 2, 2}, // 2
+ {1, 4, 1, 1}, // 3
+ {1, 1, 3, 2}, // 4
+ {1, 2, 3, 1}, // 5
+ {1, 1, 1, 4}, // 6
+ {1, 3, 1, 2}, // 7
+ {1, 2, 1, 3}, // 8
+ {3, 1, 1, 2}, // 9
+ {1, 1, 2, 3}, // 10 reversed 0
+ {1, 2, 2, 2}, // 11 reversed 1
+ {2, 2, 1, 2}, // 12 reversed 2
+ {1, 1, 4, 1}, // 13 reversed 3
+ {2, 3, 1, 1}, // 14 reversed 4
+ {1, 3, 2, 1}, // 15 reversed 5
+ {4, 1, 1, 1}, // 16 reversed 6
+ {2, 1, 3, 1}, // 17 reversed 7
+ {3, 1, 2, 1}, // 18 reversed 8
+ {2, 1, 1, 3} // 19 reversed 9
+};
+
+@interface ZXUPCEANReader ()
+
+@property (nonatomic, strong) NSMutableString *decodeRowNSMutableString;
+@property (nonatomic, strong) ZXUPCEANExtensionSupport *extensionReader;
+@property (nonatomic, strong) ZXEANManufacturerOrgSupport *eanManSupport;
+
+@end
+
+@implementation ZXUPCEANReader
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeRowNSMutableString = [NSMutableString stringWithCapacity:20];
+ _extensionReader = [[ZXUPCEANExtensionSupport alloc] init];
+ _eanManSupport = [[ZXEANManufacturerOrgSupport alloc] init];
+ }
+
+ return self;
+}
+
++ (NSRange)findStartGuardPattern:(ZXBitArray *)row error:(NSError **)error {
+ BOOL foundStart = NO;
+ NSRange startRange = NSMakeRange(NSNotFound, 0);
+ int nextStart = 0;
+ int counters[START_END_PATTERN_LEN];
+
+ while (!foundStart) {
+ startRange = [self findGuardPattern:row rowOffset:nextStart whiteFirst:NO pattern:(int *)START_END_PATTERN patternLen:START_END_PATTERN_LEN counters:counters error:error];
+ if (startRange.location == NSNotFound) {
+ return startRange;
+ }
+ int start = (int)startRange.location;
+ nextStart = (int)NSMaxRange(startRange);
+ // Make sure there is a quiet zone at least as big as the start pattern before the barcode.
+ // If this check would run off the left edge of the image, do not accept this barcode,
+ // as it is very likely to be a false positive.
+ int quietStart = start - (nextStart - start);
+ if (quietStart >= 0) {
+ foundStart = [row isRange:quietStart end:start value:NO];
+ }
+ }
+ return startRange;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ return [self decodeRow:rowNumber row:row startGuardRange:[[self class] findStartGuardPattern:row error:error] hints:hints error:error];
+}
+
+/**
+ * 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.
+ */
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row startGuardRange:(NSRange)startGuardRange hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ id<ZXResultPointCallback> resultPointCallback = hints == nil ? nil : hints.resultPointCallback;
+
+ if (resultPointCallback != nil) {
+ [resultPointCallback foundPossibleResultPoint:[[ZXResultPoint alloc] initWithX:(startGuardRange.location + NSMaxRange(startGuardRange)) / 2.0f y:rowNumber]];
+ }
+
+ NSMutableString *result = [NSMutableString string];
+ int endStart = [self decodeMiddle:row startRange:startGuardRange result:result error:error];
+ if (endStart == -1) {
+ return nil;
+ }
+
+ if (resultPointCallback != nil) {
+ [resultPointCallback foundPossibleResultPoint:[[ZXResultPoint alloc] initWithX:endStart y:rowNumber]];
+ }
+
+ NSRange endRange = [self decodeEnd:row endStart:endStart error:error];
+ if (endRange.location == NSNotFound) {
+ return nil;
+ }
+
+ if (resultPointCallback != nil) {
+ [resultPointCallback foundPossibleResultPoint:[[ZXResultPoint alloc] initWithX:(endRange.location + NSMaxRange(endRange)) / 2.0f y:rowNumber]];
+ }
+
+ // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The
+ // spec might want more whitespace, but in practice this is the maximum we can count on.
+ int end = (int)NSMaxRange(endRange);
+ int quietEnd = end + (end - (int)endRange.location);
+ if (quietEnd >= [row size] || ![row isRange:end end:quietEnd value:NO]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ NSString *resultString = [result description];
+ if (![self checkChecksum:resultString error:error]) {
+ if (error) *error = ChecksumErrorInstance();
+ return nil;
+ }
+
+ float left = (float)(NSMaxRange(startGuardRange) + startGuardRange.location) / 2.0f;
+ float right = (float)(NSMaxRange(endRange) + endRange.location) / 2.0f;
+ ZXBarcodeFormat format = [self barcodeFormat];
+
+ ZXResult *decodeResult = [ZXResult resultWithText:resultString
+ rawBytes:NULL
+ length:0
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber], [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
+ format:format];
+
+ ZXResult *extensionResult = [self.extensionReader decodeRow:rowNumber row:row rowOffset:(int)NSMaxRange(endRange) error:error];
+ if (extensionResult) {
+ [decodeResult putMetadata:kResultMetadataTypeUPCEANExtension value:extensionResult.text];
+ [decodeResult putAllMetadata:[extensionResult resultMetadata]];
+ [decodeResult addResultPoints:[extensionResult resultPoints]];
+ }
+
+ if (format == kBarcodeFormatEan13 || format == kBarcodeFormatUPCA) {
+ NSString *countryID = [self.eanManSupport lookupCountryIdentifier:resultString];
+ if (countryID != nil) {
+ [decodeResult putMetadata:kResultMetadataTypePossibleCountry value:countryID];
+ }
+ }
+ return decodeResult;
+}
+
+- (BOOL)checkChecksum:(NSString *)s error:(NSError **)error {
+ if ([[self class] checkStandardUPCEANChecksum:s]) {
+ return YES;
+ } else {
+ if (error) *error = FormatErrorInstance();
+ return NO;
+ }
+}
+
+
+/**
+ * Computes the UPC/EAN checksum on a string of digits, and reports
+ * whether the checksum is correct or not.
+ */
++ (BOOL)checkStandardUPCEANChecksum:(NSString *)s {
+ int length = (int)[s length];
+ if (length == 0) {
+ return NO;
+ }
+ int sum = 0;
+
+ for (int i = length - 2; i >= 0; i -= 2) {
+ int digit = (int)[s characterAtIndex:i] - (int)'0';
+ if (digit < 0 || digit > 9) {
+ return NO;
+ }
+ sum += digit;
+ }
+
+ sum *= 3;
+
+ for (int i = length - 1; i >= 0; i -= 2) {
+ int digit = (int)[s characterAtIndex:i] - (int)'0';
+ if (digit < 0 || digit > 9) {
+ return NO;
+ }
+ sum += digit;
+ }
+
+ return sum % 10 == 0;
+}
+
+- (NSRange)decodeEnd:(ZXBitArray *)row endStart:(int)endStart error:(NSError **)error {
+ return [[self class] findGuardPattern:row rowOffset:endStart whiteFirst:NO pattern:(int *)START_END_PATTERN patternLen:START_END_PATTERN_LEN error:error];
+}
+
++ (NSRange)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset whiteFirst:(BOOL)whiteFirst pattern:(int *)pattern patternLen:(int)patternLen error:(NSError **)error {
+ int counters[patternLen];
+ return [self findGuardPattern:row rowOffset:rowOffset whiteFirst:whiteFirst pattern:pattern patternLen:patternLen counters:counters error:error];
+}
+
++ (NSRange)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset whiteFirst:(BOOL)whiteFirst pattern:(int *)pattern patternLen:(int)patternLen counters:(int *)counters error:(NSError **)error {
+ int patternLength = patternLen;
+ memset(counters, 0, patternLength * sizeof(int));
+ int width = row.size;
+
+ BOOL isWhite = whiteFirst;
+ rowOffset = whiteFirst ? [row nextUnset:rowOffset] : [row nextSet:rowOffset];
+ int counterPosition = 0;
+ int patternStart = rowOffset;
+
+ for (int x = rowOffset; x < width; x++) {
+ if ([row get:x] ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if ([self patternMatchVariance:counters countersSize:patternLength pattern:pattern maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE] < MAX_AVG_VARIANCE) {
+ return NSMakeRange(patternStart, x - patternStart);
+ }
+ patternStart += counters[0] + counters[1];
+
+ for (int y = 2; y < patternLength; y++) {
+ counters[y - 2] = counters[y];
+ }
+
+ counters[patternLength - 2] = 0;
+ counters[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ if (error) *error = NotFoundErrorInstance();
+ return NSMakeRange(NSNotFound, 0);
+}
+
+
+/**
+ * Attempts to decode a single UPC/EAN-encoded digit.
+ */
++ (int)decodeDigit:(ZXBitArray *)row counters:(int[])counters countersLen:(int)countersLen rowOffset:(int)rowOffset patternType:(UPC_EAN_PATTERNS)patternType error:(NSError **)error {
+ if (![self recordPattern:row start:rowOffset counters:counters countersSize:countersLen]) {
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ }
+ int bestVariance = MAX_AVG_VARIANCE;
+ int bestMatch = -1;
+ int max = 0;
+ switch (patternType) {
+ case UPC_EAN_PATTERNS_L_PATTERNS:
+ max = L_PATTERNS_LEN;
+ for (int i = 0; i < max; i++) {
+ int pattern[countersLen];
+ for(int j = 0; j < countersLen; j++){
+ pattern[j] = L_PATTERNS[i][j];
+ }
+
+ int variance = [self patternMatchVariance:counters countersSize:countersLen pattern:pattern maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE];
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = i;
+ }
+ }
+ break;
+ case UPC_EAN_PATTERNS_L_AND_G_PATTERNS:
+ max = L_AND_G_PATTERNS_LEN;
+ for (int i = 0; i < max; i++) {
+ int pattern[countersLen];
+ for(int j = 0; j< countersLen; j++){
+ pattern[j] = L_AND_G_PATTERNS[i][j];
+ }
+
+ int variance = [self patternMatchVariance:counters countersSize:countersLen pattern:pattern maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE];
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = i;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (bestMatch >= 0) {
+ return bestMatch;
+ } else {
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ }
+}
+
+/**
+ * Get the format of this decoder.
+ */
+- (ZXBarcodeFormat)barcodeFormat {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+
+/**
+ * Subclasses override this to decode the portion of a barcode between the start
+ * and end guard patterns.
+ */
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANWriter.h b/ZXingObjC/oned/ZXUPCEANWriter.h
new file mode 100644
index 0000000..0236191
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANWriter.h
@@ -0,0 +1,26 @@
+/*
+ * 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 "ZXOneDimensionalCodeWriter.h"
+
+/**
+ * Encapsulates functionality and implementation that is common to UPC and EAN families
+ * of one-dimensional barcodes.
+ */
+
+@interface ZXUPCEANWriter : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEANWriter.m b/ZXingObjC/oned/ZXUPCEANWriter.m
new file mode 100644
index 0000000..84b1b3b
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEANWriter.m
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXBitMatrix.h"
+#import "ZXUPCEANReader.h"
+#import "ZXUPCEANWriter.h"
+
+@implementation ZXUPCEANWriter
+
+- (int)defaultMargin {
+ // Use a different default more appropriate for UPC/EAN
+ return START_END_PATTERN_LEN;
+}
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEReader.h b/ZXingObjC/oned/ZXUPCEReader.h
new file mode 100644
index 0000000..b64c56a
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEReader.h
@@ -0,0 +1,30 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXUPCEANReader.h"
+
+/**
+ * Implements decoding of the UPC-E format.
+ *
+ * http://www.barcodeisland.com/upce.phtml is a great reference for UPC-E information.
+ */
+
+@interface ZXUPCEReader : ZXUPCEANReader
+
++ (NSString *)convertUPCEtoUPCA:(NSString *)upce;
+
+@end
diff --git a/ZXingObjC/oned/ZXUPCEReader.m b/ZXingObjC/oned/ZXUPCEReader.m
new file mode 100644
index 0000000..690e9e0
--- /dev/null
+++ b/ZXingObjC/oned/ZXUPCEReader.m
@@ -0,0 +1,160 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXErrors.h"
+#import "ZXUPCEReader.h"
+
+/**
+ * The pattern that marks the middle, and end, of a UPC-E pattern.
+ * There is no "second half" to a UPC-E barcode.
+ */
+#define MIDDLE_END_PATTERN_LEN 6
+const int MIDDLE_END_PATTERN[MIDDLE_END_PATTERN_LEN] = {1, 1, 1, 1, 1, 1};
+
+/**
+ * See {@link #L_AND_G_PATTERNS}; these values similarly represent patterns of
+ * even-odd parity encodings of digits that imply both the number system (0 or 1)
+ * used, and the check digit.
+ */
+const int NUMSYS_AND_CHECK_DIGIT_PATTERNS[2][10] = {
+ {0x38, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25},
+ {0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A}
+};
+
+@interface ZXUPCEReader ()
+
+@property (nonatomic, assign) int *decodeMiddleCounters;
+
+@end
+
+@implementation ZXUPCEReader
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeMiddleCounters = (int *)malloc(sizeof(4) * sizeof(int));
+ _decodeMiddleCounters[0] = 0;
+ _decodeMiddleCounters[1] = 0;
+ _decodeMiddleCounters[2] = 0;
+ _decodeMiddleCounters[3] = 0;
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_decodeMiddleCounters != NULL) {
+ free(_decodeMiddleCounters);
+ _decodeMiddleCounters = NULL;
+ }
+}
+
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ const int countersLen = 4;
+ int counters[countersLen];
+ memset(counters, 0, countersLen * sizeof(int));
+
+ int end = [row size];
+ int rowOffset = (int)NSMaxRange(startRange);
+ int lgPatternFound = 0;
+
+ for (int x = 0; x < 6 && rowOffset < end; x++) {
+ int bestMatch = [ZXUPCEANReader decodeDigit:row counters:counters countersLen:countersLen rowOffset:rowOffset patternType:UPC_EAN_PATTERNS_L_AND_G_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch % 10)];
+
+ for (int i = 0; i < sizeof(counters) / sizeof(int); i++) {
+ rowOffset += counters[i];
+ }
+
+ if (bestMatch >= 10) {
+ lgPatternFound |= 1 << (5 - x);
+ }
+ }
+
+ if (![self determineNumSysAndCheckDigit:result lgPatternFound:lgPatternFound]) {
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ }
+ return rowOffset;
+}
+
+- (NSRange)decodeEnd:(ZXBitArray *)row endStart:(int)endStart error:(NSError **)error {
+ return [ZXUPCEANReader findGuardPattern:row rowOffset:endStart whiteFirst:YES pattern:(int *)MIDDLE_END_PATTERN patternLen:MIDDLE_END_PATTERN_LEN error:error];
+}
+
+- (BOOL)checkChecksum:(NSString *)s error:(NSError **)error {
+ return [super checkChecksum:[ZXUPCEReader convertUPCEtoUPCA:s] error:error];
+}
+
+- (BOOL)determineNumSysAndCheckDigit:(NSMutableString *)resultString lgPatternFound:(int)lgPatternFound {
+ for (int numSys = 0; numSys <= 1; numSys++) {
+ for (int d = 0; d < 10; d++) {
+ if (lgPatternFound == NUMSYS_AND_CHECK_DIGIT_PATTERNS[numSys][d]) {
+ [resultString insertString:[NSString stringWithFormat:@"%C", (unichar)('0' + numSys)] atIndex:0];
+ [resultString appendFormat:@"%C", (unichar)('0' + d)];
+ return YES;
+ }
+ }
+ }
+
+ return NO;
+}
+
+- (ZXBarcodeFormat)barcodeFormat {
+ return kBarcodeFormatUPCE;
+}
+
+/**
+ * Expands a UPC-E value back into its full, equivalent UPC-A code value.
+ */
++ (NSString *)convertUPCEtoUPCA:(NSString *)upce {
+ NSString *upceChars = [upce substringWithRange:NSMakeRange(1, 6)];
+ NSMutableString *result = [NSMutableString stringWithCapacity:12];
+ [result appendFormat:@"%C", [upce characterAtIndex:0]];
+ unichar lastChar = [upceChars characterAtIndex:5];
+ switch (lastChar) {
+ case '0':
+ case '1':
+ case '2':
+ [result appendString:[upceChars substringToIndex:2]];
+ [result appendFormat:@"%C", lastChar];
+ [result appendString:@"0000"];
+ [result appendString:[upceChars substringWithRange:NSMakeRange(2, 3)]];
+ break;
+ case '3':
+ [result appendString:[upceChars substringToIndex:3]];
+ [result appendString:@"00000"];
+ [result appendString:[upceChars substringWithRange:NSMakeRange(3, 2)]];
+ break;
+ case '4':
+ [result appendString:[upceChars substringToIndex:4]];
+ [result appendString:@"00000"];
+ [result appendString:[upceChars substringWithRange:NSMakeRange(4, 1)]];
+ break;
+ default:
+ [result appendString:[upceChars substringToIndex:5]];
+ [result appendString:@"0000"];
+ [result appendFormat:@"%C", lastChar];
+ break;
+ }
+ [result appendFormat:@"%C", [upce characterAtIndex:7]];
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXAbstractRSSReader.h b/ZXingObjC/oned/rss/ZXAbstractRSSReader.h
new file mode 100644
index 0000000..1737ba1
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXAbstractRSSReader.h
@@ -0,0 +1,45 @@
+/*
+ * 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 "ZXOneDReader.h"
+
+typedef enum {
+ RSS_PATTERNS_RSS14_PATTERNS = 0,
+ RSS_PATTERNS_RSS_EXPANDED_PATTERNS
+} RSS_PATTERNS;
+
+@interface ZXAbstractRSSReader : ZXOneDReader
+
+@property (nonatomic, assign, readonly) int *decodeFinderCounters;
+@property (nonatomic, assign, readonly) unsigned int decodeFinderCountersLen;
+@property (nonatomic, assign, readonly) int *dataCharacterCounters;
+@property (nonatomic, assign, readonly) unsigned int dataCharacterCountersLen;
+@property (nonatomic, assign, readonly) float *oddRoundingErrors;
+@property (nonatomic, assign, readonly) unsigned int oddRoundingErrorsLen;
+@property (nonatomic, assign, readonly) float *evenRoundingErrors;
+@property (nonatomic, assign, readonly) unsigned int evenRoundingErrorsLen;
+@property (nonatomic, assign, readonly) int *oddCounts;
+@property (nonatomic, assign, readonly) unsigned int oddCountsLen;
+@property (nonatomic, assign, readonly) int *evenCounts;
+@property (nonatomic, assign, readonly) unsigned int evenCountsLen;
+
++ (int)parseFinderValue:(int *)counters countersSize:(unsigned int)countersSize finderPatternType:(RSS_PATTERNS)finderPatternType;
++ (int)count:(int *)array arrayLen:(unsigned int)arrayLen;
++ (void)increment:(int *)array arrayLen:(unsigned int)arrayLen errors:(float *)errors;
++ (void)decrement:(int *)array arrayLen:(unsigned int)arrayLen errors:(float *)errors;
++ (BOOL)isFinderPattern:(int *)counters countersLen:(unsigned int)countersLen;
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXAbstractRSSReader.m b/ZXingObjC/oned/rss/ZXAbstractRSSReader.m
new file mode 100644
index 0000000..423999b
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXAbstractRSSReader.m
@@ -0,0 +1,200 @@
+/*
+ * 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 "ZXAbstractRSSReader.h"
+
+static int MAX_AVG_VARIANCE;
+static int MAX_INDIVIDUAL_VARIANCE;
+
+float const MIN_FINDER_PATTERN_RATIO = 9.5f / 12.0f;
+float const MAX_FINDER_PATTERN_RATIO = 12.5f / 14.0f;
+
+#define RSS14_FINDER_PATTERNS_LEN 9
+#define RSS14_FINDER_PATTERNS_SUB_LEN 4
+const int RSS14_FINDER_PATTERNS[RSS14_FINDER_PATTERNS_LEN][RSS14_FINDER_PATTERNS_SUB_LEN] = {
+ {3,8,2,1},
+ {3,5,5,1},
+ {3,3,7,1},
+ {3,1,9,1},
+ {2,7,4,1},
+ {2,5,6,1},
+ {2,3,8,1},
+ {1,5,7,1},
+ {1,3,9,1},
+};
+
+#define RSS_EXPANDED_FINDER_PATTERNS_LEN 6
+#define RSS_EXPANDED_FINDER_PATTERNS_SUB_LEN 4
+const int RSS_EXPANDED_FINDER_PATTERNS[RSS_EXPANDED_FINDER_PATTERNS_LEN][RSS_EXPANDED_FINDER_PATTERNS_SUB_LEN] = {
+ {1,8,4,1}, // A
+ {3,6,4,1}, // B
+ {3,4,6,1}, // C
+ {3,2,8,1}, // D
+ {2,6,5,1}, // E
+ {2,2,9,1} // F
+};
+
+@implementation ZXAbstractRSSReader
+
++ (void)initialize {
+ MAX_AVG_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.2f);
+ MAX_INDIVIDUAL_VARIANCE = (int)(PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.45f);
+}
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeFinderCountersLen = 4;
+ _decodeFinderCounters = (int *)malloc(_decodeFinderCountersLen * sizeof(int));
+ memset(self.decodeFinderCounters, 0, self.decodeFinderCountersLen * sizeof(int));
+
+ _dataCharacterCountersLen = 8;
+ _dataCharacterCounters = (int *)malloc(_dataCharacterCountersLen * sizeof(int));
+ memset(self.dataCharacterCounters, 0, self.dataCharacterCountersLen * sizeof(int));
+
+ _oddRoundingErrorsLen = 4;
+ _oddRoundingErrors = (float *)malloc(_oddRoundingErrorsLen * sizeof(float));
+ memset(_oddRoundingErrors, 0, _oddRoundingErrorsLen * sizeof(float));
+
+ _evenRoundingErrorsLen = 4;
+ _evenRoundingErrors = (float *)malloc(_evenRoundingErrorsLen * sizeof(float));
+ memset(_evenRoundingErrors, 0, _evenRoundingErrorsLen * sizeof(float));
+
+ _oddCountsLen = _dataCharacterCountersLen / 2;
+ _oddCounts = (int *)malloc(_oddCountsLen * sizeof(int));
+ memset(_oddCounts, 0, _oddCountsLen * sizeof(int));
+
+ _evenCountsLen = _dataCharacterCountersLen / 2;
+ _evenCounts = (int *)malloc(_evenCountsLen * sizeof(int));
+ memset(_evenCounts, 0, _evenCountsLen * sizeof(int));
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_decodeFinderCounters != NULL) {
+ free(_decodeFinderCounters);
+ _decodeFinderCounters = NULL;
+ }
+
+ if (_dataCharacterCounters != NULL) {
+ free(_dataCharacterCounters);
+ _dataCharacterCounters = NULL;
+ }
+
+ if (_oddRoundingErrors != NULL) {
+ free(_oddRoundingErrors);
+ _oddRoundingErrors = NULL;
+ }
+
+ if (_evenRoundingErrors != NULL) {
+ free(_evenRoundingErrors);
+ _evenRoundingErrors = NULL;
+ }
+
+ if (_oddCounts != NULL) {
+ free(_oddCounts);
+ _oddCounts = NULL;
+ }
+
+ if (_evenCounts != NULL) {
+ free(_evenCounts);
+ _evenCounts = NULL;
+ }
+}
+
++ (int)parseFinderValue:(int *)counters countersSize:(unsigned int)countersSize finderPatternType:(RSS_PATTERNS)finderPatternType {
+ switch (finderPatternType) {
+ case RSS_PATTERNS_RSS14_PATTERNS:
+ for (int value = 0; value < RSS14_FINDER_PATTERNS_LEN; value++) {
+ if ([self patternMatchVariance:counters countersSize:countersSize pattern:(int *)RSS14_FINDER_PATTERNS[value] maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE] < MAX_AVG_VARIANCE) {
+ return value;
+ }
+ }
+ break;
+
+ case RSS_PATTERNS_RSS_EXPANDED_PATTERNS:
+ for (int value = 0; value < RSS_EXPANDED_FINDER_PATTERNS_LEN; value++) {
+ if ([self patternMatchVariance:counters countersSize:countersSize pattern:(int *)RSS_EXPANDED_FINDER_PATTERNS[value] maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE] < MAX_AVG_VARIANCE) {
+ return value;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
++ (int)count:(int *)array arrayLen:(unsigned int)arrayLen {
+ int count = 0;
+
+ for (int i = 0; i < arrayLen; i++) {
+ count += array[i];
+ }
+
+ return count;
+}
+
++ (void)increment:(int *)array arrayLen:(unsigned int)arrayLen errors:(float *)errors {
+ int index = 0;
+ float biggestError = errors[0];
+ for (int i = 1; i < arrayLen; i++) {
+ if (errors[i] > biggestError) {
+ biggestError = errors[i];
+ index = i;
+ }
+ }
+ array[index]++;
+}
+
++ (void)decrement:(int *)array arrayLen:(unsigned int)arrayLen errors:(float *)errors {
+ int index = 0;
+ float biggestError = errors[0];
+ for (int i = 1; i < arrayLen; i++) {
+ if (errors[i] < biggestError) {
+ biggestError = errors[i];
+ index = i;
+ }
+ }
+ array[index]--;
+}
+
++ (BOOL)isFinderPattern:(int *)counters countersLen:(unsigned int)countersLen {
+ int firstTwoSum = counters[0] + counters[1];
+ int sum = firstTwoSum + counters[2] + counters[3];
+ float ratio = (float)firstTwoSum / (float)sum;
+ if (ratio >= MIN_FINDER_PATTERN_RATIO && ratio <= MAX_FINDER_PATTERN_RATIO) {
+ int minCounter = INT_MAX;
+ int maxCounter = INT_MIN;
+ for (int i = 0; i < countersLen; i++) {
+ int counter = counters[i];
+ if (counter > maxCounter) {
+ maxCounter = counter;
+ }
+ if (counter < minCounter) {
+ minCounter = counter;
+ }
+ }
+
+ return maxCounter < 10 * minCounter;
+ }
+ return NO;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXDataCharacter.h b/ZXingObjC/oned/rss/ZXDataCharacter.h
new file mode 100644
index 0000000..21bb259
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXDataCharacter.h
@@ -0,0 +1,24 @@
+/*
+ * 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 ZXDataCharacter : NSObject
+
+@property (nonatomic, assign, readonly) int value;
+@property (nonatomic, assign, readonly) int checksumPortion;
+
+- (id)initWithValue:(int)value checksumPortion:(int)checksumPortion;
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXDataCharacter.m b/ZXingObjC/oned/rss/ZXDataCharacter.m
new file mode 100644
index 0000000..908ff2c
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXDataCharacter.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 "ZXDataCharacter.h"
+
+@implementation ZXDataCharacter
+
+- (id)initWithValue:(int)value checksumPortion:(int)checksumPortion {
+ if (self = [super init]) {
+ _value = value;
+ _checksumPortion = checksumPortion;
+ }
+
+ return self;
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%d(%d)", self.value, self.checksumPortion];
+}
+
+- (BOOL)isEqual:(id)object {
+ if (![object isKindOfClass:[ZXDataCharacter class]]) {
+ return NO;
+ }
+
+ ZXDataCharacter *that = (ZXDataCharacter *)object;
+ return (self.value == that.value) && (self.checksumPortion == that.checksumPortion);
+}
+
+- (NSUInteger)hash {
+ return self.value ^ self.checksumPortion;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXPair.h b/ZXingObjC/oned/rss/ZXPair.h
new file mode 100644
index 0000000..62150b0
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXPair.h
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXDataCharacter.h"
+
+@class ZXRSSFinderPattern;
+
+@interface ZXPair : ZXDataCharacter
+
+@property (nonatomic, assign, readonly) int count;
+@property (nonatomic, strong, readonly) ZXRSSFinderPattern *finderPattern;
+
+- (id)initWithValue:(int)value checksumPortion:(int)checksumPortion finderPattern:(ZXRSSFinderPattern *)finderPattern;
+- (void)incrementCount;
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXPair.m b/ZXingObjC/oned/rss/ZXPair.m
new file mode 100644
index 0000000..b208a9d
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXPair.m
@@ -0,0 +1,40 @@
+/*
+ * 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 "ZXRSSFinderPattern.h"
+#import "ZXPair.h"
+
+@interface ZXPair ()
+
+@property (nonatomic, assign) int count;
+
+@end
+
+@implementation ZXPair
+
+- (id)initWithValue:(int)value checksumPortion:(int)checksumPortion finderPattern:(ZXRSSFinderPattern *)finderPattern {
+ if (self = [super initWithValue:value checksumPortion:checksumPortion]) {
+ _finderPattern = finderPattern;
+ }
+
+ return self;
+}
+
+- (void)incrementCount {
+ self.count++;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXRSS14Reader.h b/ZXingObjC/oned/rss/ZXRSS14Reader.h
new file mode 100644
index 0000000..3d1b60f
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXRSS14Reader.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXAbstractRSSReader.h"
+
+/**
+ * Decodes RSS-14, including truncated and stacked variants. See ISO/IEC 24724:2006.
+ */
+
+@class ZXDecodeHints, ZXResult;
+
+@interface ZXRSS14Reader : ZXAbstractRSSReader
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXRSS14Reader.m b/ZXingObjC/oned/rss/ZXRSS14Reader.m
new file mode 100644
index 0000000..4376178
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXRSS14Reader.m
@@ -0,0 +1,450 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXBarcodeFormat.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXPair.h"
+#import "ZXResult.h"
+#import "ZXResultPointCallback.h"
+#import "ZXRSS14Reader.h"
+#import "ZXRSSFinderPattern.h"
+#import "ZXRSSUtils.h"
+
+const int OUTSIDE_EVEN_TOTAL_SUBSET[5] = {1,10,34,70,126};
+const int INSIDE_ODD_TOTAL_SUBSET[4] = {4,20,48,81};
+const int OUTSIDE_GSUM[5] = {0,161,961,2015,2715};
+const int INSIDE_GSUM[4] = {0,336,1036,1516};
+const int OUTSIDE_ODD_WIDEST[5] = {8,6,4,3,1};
+const int INSIDE_ODD_WIDEST[4] = {2,4,6,8};
+
+@interface ZXRSS14Reader ()
+
+@property (nonatomic, strong) NSMutableArray *possibleLeftPairs;
+@property (nonatomic, strong) NSMutableArray *possibleRightPairs;
+
+@end
+
+@implementation ZXRSS14Reader
+
+- (id)init {
+ if (self = [super init]) {
+ _possibleLeftPairs = [NSMutableArray array];
+ _possibleRightPairs = [NSMutableArray array];
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXPair *leftPair = [self decodePair:row right:NO rowNumber:rowNumber hints:hints];
+ [self addOrTally:self.possibleLeftPairs pair:leftPair];
+ [row reverse];
+ ZXPair *rightPair = [self decodePair:row right:YES rowNumber:rowNumber hints:hints];
+ [self addOrTally:self.possibleRightPairs pair:rightPair];
+ [row reverse];
+
+ for (ZXPair *left in self.possibleLeftPairs) {
+ if ([left count] > 1) {
+ for (ZXPair *right in self.possibleRightPairs) {
+ if ([right count] > 1) {
+ if ([self checkChecksum:left rightPair:right]) {
+ return [self constructResult:left rightPair:right];
+ }
+ }
+ }
+ }
+ }
+
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+}
+
+- (void)addOrTally:(NSMutableArray *)possiblePairs pair:(ZXPair *)pair {
+ if (pair == nil) {
+ return;
+ }
+ BOOL found = NO;
+ for (ZXPair *other in possiblePairs) {
+ if (other.value == pair.value) {
+ [other incrementCount];
+ found = YES;
+ break;
+ }
+ }
+
+ if (!found) {
+ [possiblePairs addObject:pair];
+ }
+}
+
+- (void)reset {
+ [self.possibleLeftPairs removeAllObjects];
+ [self.possibleRightPairs removeAllObjects];
+}
+
+- (ZXResult *)constructResult:(ZXPair *)leftPair rightPair:(ZXPair *)rightPair {
+ long long symbolValue = 4537077LL * leftPair.value + rightPair.value;
+ NSString *text = [@(symbolValue) stringValue];
+ NSMutableString *buffer = [NSMutableString stringWithCapacity:14];
+
+ for (int i = 13 - (int)[text length]; i > 0; i--) {
+ [buffer appendString:@"0"];
+ }
+
+ [buffer appendString:text];
+ int checkDigit = 0;
+
+ for (int i = 0; i < 13; i++) {
+ int digit = [buffer characterAtIndex:i] - '0';
+ checkDigit += (i & 0x01) == 0 ? 3 * digit : digit;
+ }
+
+ checkDigit = 10 - (checkDigit % 10);
+ if (checkDigit == 10) {
+ checkDigit = 0;
+ }
+ [buffer appendFormat:@"%d", checkDigit];
+ NSArray *leftPoints = [[leftPair finderPattern] resultPoints];
+ NSArray *rightPoints = [[rightPair finderPattern] resultPoints];
+ return [ZXResult resultWithText:buffer
+ rawBytes:NULL
+ length:0
+ resultPoints:@[leftPoints[0], leftPoints[1], rightPoints[0], rightPoints[1]]
+ format:kBarcodeFormatRSS14];
+}
+
+- (BOOL)checkChecksum:(ZXPair *)leftPair rightPair:(ZXPair *)rightPair {
+// int leftFPValue = leftPair.finderPattern.value;
+// int rightFPValue = rightPair.finderPattern.value;
+// if ((leftFPValue == 0 && rightFPValue == 8) || (leftFPValue == 8 && rightFPValue == 0)) {
+// }
+ int checkValue = (leftPair.checksumPortion + 16 * rightPair.checksumPortion) % 79;
+ int targetCheckValue = 9 * leftPair.finderPattern.value + rightPair.finderPattern.value;
+ if (targetCheckValue > 72) {
+ targetCheckValue--;
+ }
+ if (targetCheckValue > 8) {
+ targetCheckValue--;
+ }
+ return checkValue == targetCheckValue;
+}
+
+- (ZXPair *)decodePair:(ZXBitArray *)row right:(BOOL)right rowNumber:(int)rowNumber hints:(ZXDecodeHints *)hints {
+ NSArray *startEnd = [self findFinderPattern:row rowOffset:0 rightFinderPattern:right];
+ if (!startEnd) {
+ return nil;
+ }
+ ZXRSSFinderPattern *pattern = [self parseFoundFinderPattern:row rowNumber:rowNumber right:right startEnd:startEnd];
+ if (!pattern) {
+ return nil;
+ }
+ id<ZXResultPointCallback> resultPointCallback = hints == nil ? nil : hints.resultPointCallback;
+ if (resultPointCallback != nil) {
+ float center = ([startEnd[0] intValue] + [startEnd[1] intValue]) / 2.0f;
+ if (right) {
+ center = [row size] - 1 - center;
+ }
+ [resultPointCallback foundPossibleResultPoint:[[ZXResultPoint alloc] initWithX:center y:rowNumber]];
+ }
+ ZXDataCharacter *outside = [self decodeDataCharacter:row pattern:pattern outsideChar:YES];
+ ZXDataCharacter *inside = [self decodeDataCharacter:row pattern:pattern outsideChar:NO];
+ if (!outside || !inside) {
+ return nil;
+ }
+ return [[ZXPair alloc] initWithValue:1597 * outside.value + inside.value
+ checksumPortion:outside.checksumPortion + 4 * inside.checksumPortion
+ finderPattern:pattern];
+}
+
+- (ZXDataCharacter *)decodeDataCharacter:(ZXBitArray *)row pattern:(ZXRSSFinderPattern *)pattern outsideChar:(BOOL)outsideChar {
+ int countersLen = self.dataCharacterCountersLen;
+ int *counters = self.dataCharacterCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+ counters[4] = 0;
+ counters[5] = 0;
+ counters[6] = 0;
+ counters[7] = 0;
+
+ if (outsideChar) {
+ if (![ZXOneDReader recordPatternInReverse:row start:[[pattern startEnd][0] intValue] counters:counters countersSize:countersLen]) {
+ return nil;
+ }
+ } else {
+ if (![ZXOneDReader recordPattern:row start:[[pattern startEnd][1] intValue] counters:counters countersSize:countersLen]) {
+ return nil;
+ }
+
+ for (int i = 0, j = countersLen - 1; i < j; i++, j--) {
+ int temp = counters[i];
+ counters[i] = counters[j];
+ counters[j] = temp;
+ }
+ }
+
+ int numModules = outsideChar ? 16 : 15;
+ float elementWidth = (float)[ZXAbstractRSSReader count:counters arrayLen:countersLen] / (float)numModules;
+
+ for (int i = 0; i < countersLen; i++) {
+ float value = (float) counters[i] / elementWidth;
+ int count = (int)(value + 0.5f);
+ if (count < 1) {
+ count = 1;
+ } else if (count > 8) {
+ count = 8;
+ }
+ int offset = i >> 1;
+ if ((i & 0x01) == 0) {
+ self.oddCounts[offset] = count;
+ self.oddRoundingErrors[offset] = value - count;
+ } else {
+ self.evenCounts[offset] = count;
+ self.evenRoundingErrors[offset] = value - count;
+ }
+ }
+
+ if (![self adjustOddEvenCounts:outsideChar numModules:numModules]) {
+ return nil;
+ }
+
+ int oddSum = 0;
+ int oddChecksumPortion = 0;
+ for (int i = self.oddCountsLen - 1; i >= 0; i--) {
+ oddChecksumPortion *= 9;
+ oddChecksumPortion += self.oddCounts[i];
+ oddSum += self.oddCounts[i];
+ }
+ int evenChecksumPortion = 0;
+ int evenSum = 0;
+ for (int i = self.evenCountsLen - 1; i >= 0; i--) {
+ evenChecksumPortion *= 9;
+ evenChecksumPortion += self.evenCounts[i];
+ evenSum += self.evenCounts[i];
+ }
+ int checksumPortion = oddChecksumPortion + 3 * evenChecksumPortion;
+
+ if (outsideChar) {
+ if ((oddSum & 0x01) != 0 || oddSum > 12 || oddSum < 4) {
+ return nil;
+ }
+ int group = (12 - oddSum) / 2;
+ int oddWidest = OUTSIDE_ODD_WIDEST[group];
+ int evenWidest = 9 - oddWidest;
+ int vOdd = [ZXRSSUtils rssValue:self.oddCounts widthsLen:self.oddCountsLen maxWidth:oddWidest noNarrow:NO];
+ int vEven = [ZXRSSUtils rssValue:self.evenCounts widthsLen:self.evenCountsLen maxWidth:evenWidest noNarrow:YES];
+ int tEven = OUTSIDE_EVEN_TOTAL_SUBSET[group];
+ int gSum = OUTSIDE_GSUM[group];
+ return [[ZXDataCharacter alloc] initWithValue:vOdd * tEven + vEven + gSum checksumPortion:checksumPortion];
+ } else {
+ if ((evenSum & 0x01) != 0 || evenSum > 10 || evenSum < 4) {
+ return nil;
+ }
+ int group = (10 - evenSum) / 2;
+ int oddWidest = INSIDE_ODD_WIDEST[group];
+ int evenWidest = 9 - oddWidest;
+ int vOdd = [ZXRSSUtils rssValue:self.oddCounts widthsLen:self.oddCountsLen maxWidth:oddWidest noNarrow:YES];
+ int vEven = [ZXRSSUtils rssValue:self.evenCounts widthsLen:self.evenCountsLen maxWidth:evenWidest noNarrow:NO];
+ int tOdd = INSIDE_ODD_TOTAL_SUBSET[group];
+ int gSum = INSIDE_GSUM[group];
+ return [[ZXDataCharacter alloc] initWithValue:vEven * tOdd + vOdd + gSum checksumPortion:checksumPortion];
+ }
+}
+
+- (NSArray *)findFinderPattern:(ZXBitArray *)row rowOffset:(int)rowOffset rightFinderPattern:(BOOL)rightFinderPattern {
+ int countersLen = self.decodeFinderCountersLen;
+ int *counters = self.decodeFinderCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+
+ int width = row.size;
+ BOOL isWhite = NO;
+ while (rowOffset < width) {
+ isWhite = ![row get:rowOffset];
+ if (rightFinderPattern == isWhite) {
+ break;
+ }
+ rowOffset++;
+ }
+
+ int counterPosition = 0;
+ int patternStart = rowOffset;
+ for (int x = rowOffset; x < width; x++) {
+ if ([row get:x] ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == 3) {
+ if ([ZXAbstractRSSReader isFinderPattern:counters countersLen:countersLen]) {
+ return @[@(patternStart), @(x)];
+ }
+ patternStart += counters[0] + counters[1];
+ counters[0] = counters[2];
+ counters[1] = counters[3];
+ counters[2] = 0;
+ counters[3] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return nil;
+}
+
+- (ZXRSSFinderPattern *)parseFoundFinderPattern:(ZXBitArray *)row rowNumber:(int)rowNumber right:(BOOL)right startEnd:(NSArray *)startEnd {
+ BOOL firstIsBlack = [row get:[startEnd[0] intValue]];
+ int firstElementStart = [startEnd[0] intValue] - 1;
+
+ while (firstElementStart >= 0 && firstIsBlack ^ [row get:firstElementStart]) {
+ firstElementStart--;
+ }
+
+ firstElementStart++;
+ int firstCounter = [startEnd[0] intValue] - firstElementStart;
+
+ int countersLen = self.decodeFinderCountersLen;
+ int *counters = self.decodeFinderCounters;
+ for (int i = countersLen - 1; i > 0; i--) {
+ counters[i] = counters[i-1];
+ }
+ counters[0] = firstCounter;
+ int value = [ZXAbstractRSSReader parseFinderValue:counters countersSize:countersLen finderPatternType:RSS_PATTERNS_RSS14_PATTERNS];
+ if (value == -1) {
+ return nil;
+ }
+ int start = firstElementStart;
+ int end = [startEnd[1] intValue];
+ if (right) {
+ start = [row size] - 1 - start;
+ end = [row size] - 1 - end;
+ }
+ return [[ZXRSSFinderPattern alloc] initWithValue:value
+ startEnd:[@[@(firstElementStart), startEnd[1]] mutableCopy]
+ start:start
+ end:end
+ rowNumber:rowNumber];
+}
+
+- (BOOL)adjustOddEvenCounts:(BOOL)outsideChar numModules:(int)numModules {
+ int oddSum = [ZXAbstractRSSReader count:self.oddCounts arrayLen:self.oddCountsLen];
+ int evenSum = [ZXAbstractRSSReader count:self.evenCounts arrayLen:self.evenCountsLen];
+ int mismatch = oddSum + evenSum - numModules;
+ BOOL oddParityBad = (oddSum & 0x01) == (outsideChar ? 1 : 0);
+ BOOL evenParityBad = (evenSum & 0x01) == 1;
+
+ BOOL incrementOdd = NO;
+ BOOL decrementOdd = NO;
+ BOOL incrementEven = NO;
+ BOOL decrementEven = NO;
+
+ if (outsideChar) {
+ if (oddSum > 12) {
+ decrementOdd = YES;
+ } else if (oddSum < 4) {
+ incrementOdd = YES;
+ }
+ if (evenSum > 12) {
+ decrementEven = YES;
+ } else if (evenSum < 4) {
+ incrementEven = YES;
+ }
+ } else {
+ if (oddSum > 11) {
+ decrementOdd = YES;
+ } else if (oddSum < 5) {
+ incrementOdd = YES;
+ }
+ if (evenSum > 10) {
+ decrementEven = YES;
+ } else if (evenSum < 4) {
+ incrementEven = YES;
+ }
+ }
+
+ if (mismatch == 1) {
+ if (oddParityBad) {
+ if (evenParityBad) {
+ return NO;
+ }
+ decrementOdd = YES;
+ } else {
+ if (!evenParityBad) {
+ return NO;
+ }
+ decrementEven = YES;
+ }
+ } else if (mismatch == -1) {
+ if (oddParityBad) {
+ if (evenParityBad) {
+ return NO;
+ }
+ incrementOdd = YES;
+ } else {
+ if (!evenParityBad) {
+ return NO;
+ }
+ incrementEven = YES;
+ }
+ } else if (mismatch == 0) {
+ if (oddParityBad) {
+ if (!evenParityBad) {
+ return NO;
+ }
+ if (oddSum < evenSum) {
+ incrementOdd = YES;
+ decrementEven = YES;
+ } else {
+ decrementOdd = YES;
+ incrementEven = YES;
+ }
+ } else {
+ if (evenParityBad) {
+ return NO;
+ }
+ }
+ } else {
+ return NO;
+ }
+ if (incrementOdd) {
+ if (decrementOdd) {
+ return NO;
+ }
+ [ZXAbstractRSSReader increment:self.oddCounts arrayLen:self.oddCountsLen errors:self.oddRoundingErrors];
+ }
+ if (decrementOdd) {
+ [ZXAbstractRSSReader decrement:self.oddCounts arrayLen:self.oddCountsLen errors:self.oddRoundingErrors];
+ }
+ if (incrementEven) {
+ if (decrementEven) {
+ return NO;
+ }
+ [ZXAbstractRSSReader increment:self.evenCounts arrayLen:self.evenCountsLen errors:self.oddRoundingErrors];
+ }
+ if (decrementEven) {
+ [ZXAbstractRSSReader decrement:self.evenCounts arrayLen:self.evenCountsLen errors:self.evenRoundingErrors];
+ }
+ return YES;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXRSSFinderPattern.h b/ZXingObjC/oned/rss/ZXRSSFinderPattern.h
new file mode 100644
index 0000000..008b997
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXRSSFinderPattern.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXResultPoint.h"
+
+@interface ZXRSSFinderPattern : NSObject
+
+@property (nonatomic, assign, readonly) int value;
+@property (nonatomic, strong, readonly) NSMutableArray *startEnd;
+@property (nonatomic, strong, readonly) NSMutableArray *resultPoints;
+
+- (id)initWithValue:(int)value startEnd:(NSMutableArray *)startEnd start:(int)start end:(int)end rowNumber:(int)rowNumber;
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXRSSFinderPattern.m b/ZXingObjC/oned/rss/ZXRSSFinderPattern.m
new file mode 100644
index 0000000..460bbbb
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXRSSFinderPattern.m
@@ -0,0 +1,45 @@
+/*
+ * 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 "ZXRSSFinderPattern.h"
+
+@implementation ZXRSSFinderPattern
+
+- (id)initWithValue:(int)value startEnd:(NSMutableArray *)startEnd start:(int)start end:(int)end rowNumber:(int)rowNumber {
+ if (self = [super init]) {
+ _value = value;
+ _startEnd = startEnd;
+ _resultPoints = [@[[[ZXResultPoint alloc] initWithX:(float)start y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:(float)end y:(float)rowNumber]] mutableCopy];
+ }
+
+ return self;
+}
+
+- (BOOL)isEqual:(id)object {
+ if (![object isKindOfClass:[ZXRSSFinderPattern class]]) {
+ return NO;
+ }
+
+ ZXRSSFinderPattern *that = (ZXRSSFinderPattern *)object;
+ return self.value == that.value;
+}
+
+- (NSUInteger)hash {
+ return self.value;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXRSSUtils.h b/ZXingObjC/oned/rss/ZXRSSUtils.h
new file mode 100644
index 0000000..1613bb7
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXRSSUtils.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/**
+ * Adapted from listings in ISO/IEC 24724 Appendix B and Appendix G.
+ */
+
+@interface ZXRSSUtils : NSObject
+
++ (NSArray *)rssWidths:(int)val n:(int)n elements:(int)elements maxWidth:(int)maxWidth noNarrow:(BOOL)noNarrow;
++ (int)rssValue:(int *)widths widthsLen:(unsigned int)widthsLen maxWidth:(int)maxWidth noNarrow:(BOOL)noNarrow;
++ (NSArray *)elements:(NSArray *)eDist N:(int)N K:(int)K;
+
+@end
diff --git a/ZXingObjC/oned/rss/ZXRSSUtils.m b/ZXingObjC/oned/rss/ZXRSSUtils.m
new file mode 100644
index 0000000..ea69433
--- /dev/null
+++ b/ZXingObjC/oned/rss/ZXRSSUtils.m
@@ -0,0 +1,151 @@
+/*
+ * 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 "ZXRSSUtils.h"
+
+@implementation ZXRSSUtils
+
++ (NSArray *)rssWidths:(int)val n:(int)n elements:(int)elements maxWidth:(int)maxWidth noNarrow:(BOOL)noNarrow {
+ NSMutableArray *widths = [NSMutableArray arrayWithCapacity:elements];
+ int bar;
+ int narrowMask = 0;
+ for (bar = 0; bar < elements - 1; bar++) {
+ narrowMask |= 1 << bar;
+ int elmWidth = 1;
+ int subVal;
+ while (YES) {
+ subVal = [self combins:n - elmWidth - 1 r:elements - bar - 2];
+ if (noNarrow && (narrowMask == 0) && (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
+ subVal -= [self combins:n - elmWidth - (elements - bar) r:elements - bar - 2];
+ }
+ if (elements - bar - 1 > 1) {
+ int lessVal = 0;
+ for (int mxwElement = n - elmWidth - (elements - bar - 2); mxwElement > maxWidth; mxwElement--) {
+ lessVal += [self combins:n - elmWidth - mxwElement - 1 r:elements - bar - 3];
+ }
+ subVal -= lessVal * (elements - 1 - bar);
+ } else if (n - elmWidth > maxWidth) {
+ subVal--;
+ }
+ val -= subVal;
+ if (val < 0) {
+ break;
+ }
+ elmWidth++;
+ narrowMask &= ~(1 << bar);
+ }
+ val += subVal;
+ n -= elmWidth;
+ [widths addObject:@(elmWidth)];
+ }
+
+ [widths addObject:@(n)];
+ return widths;
+}
+
++ (int)rssValue:(int *)widths widthsLen:(unsigned int)widthsLen maxWidth:(int)maxWidth noNarrow:(BOOL)noNarrow {
+ int elements = widthsLen;
+ int n = 0;
+ for (int i = 0; i < elements; i++) {
+ n += widths[i];
+ }
+ int val = 0;
+ int narrowMask = 0;
+ for (int bar = 0; bar < elements - 1; bar++) {
+ int elmWidth;
+ for (elmWidth = 1, narrowMask |= 1 << bar;
+ elmWidth < widths[bar];
+ elmWidth++, narrowMask &= ~(1 << bar)) {
+ int subVal = [self combins:n - elmWidth - 1 r:elements - bar - 2];
+ if (noNarrow && (narrowMask == 0) &&
+ (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
+ subVal -= [self combins:n - elmWidth - (elements - bar)
+ r:elements - bar - 2];
+ }
+ if (elements - bar - 1 > 1) {
+ int lessVal = 0;
+ for (int mxwElement = n - elmWidth - (elements - bar - 2);
+ mxwElement > maxWidth; mxwElement--) {
+ lessVal += [self combins:n - elmWidth - mxwElement - 1
+ r:elements - bar - 3];
+ }
+ subVal -= lessVal * (elements - 1 - bar);
+ } else if (n - elmWidth > maxWidth) {
+ subVal--;
+ }
+ val += subVal;
+ }
+ n -= elmWidth;
+ }
+ return val;
+}
+
++ (int)combins:(int)n r:(int)r {
+ int maxDenom;
+ int minDenom;
+ if (n - r > r) {
+ minDenom = r;
+ maxDenom = n - r;
+ } else {
+ minDenom = n - r;
+ maxDenom = r;
+ }
+ int val = 1;
+ int j = 1;
+ for (int i = n; i > maxDenom; i--) {
+ val *= i;
+ if (j <= minDenom) {
+ val /= j;
+ j++;
+ }
+ }
+ while (j <= minDenom) {
+ val /= j;
+ j++;
+ }
+ return val;
+}
+
++ (NSArray *)elements:(NSArray *)eDist N:(int)N K:(int)K {
+ NSMutableArray *widths = [NSMutableArray arrayWithCapacity:[eDist count] + 2];
+ int twoK = K << 1;
+ [widths addObject:@1];
+ int i;
+ int minEven = 10;
+ int barSum = 1;
+ for (i = 1; i < twoK - 2; i += 2) {
+ [widths addObject:@([eDist[i - 1] intValue] - [widths[i - 1] intValue])];
+ [widths addObject:@([eDist[i] intValue] - [widths[i] intValue])];
+ barSum += [widths[i] intValue] + [widths[i + 1] intValue];
+ if ([widths[i] intValue] < minEven) {
+ minEven = [widths[i] intValue];
+ }
+ }
+
+ [widths addObject:@(N - barSum)];
+ if ([widths[twoK - 1] intValue] < minEven) {
+ minEven = [widths[twoK - 1] intValue];
+ }
+ if (minEven > 1) {
+ for (i = 0; i < twoK; i += 2) {
+ widths[i] = @([widths[i] intValue] + minEven - 1);
+ widths[i + 1] = @([widths[i + 1] intValue] - minEven - 1);
+ }
+ }
+ return widths;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.h b/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.h
new file mode 100644
index 0000000..058b7cb
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.h
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+@class ZXBitArray;
+
+@interface ZXBitArrayBuilder : NSObject
+
++ (ZXBitArray *)buildBitArray:(NSArray *)pairs;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.m b/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.m
new file mode 100644
index 0000000..c31afa6
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.m
@@ -0,0 +1,70 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXBitArrayBuilder.h"
+#import "ZXDataCharacter.h"
+#import "ZXExpandedPair.h"
+
+@implementation ZXBitArrayBuilder
+
++ (ZXBitArray *)buildBitArray:(NSArray *)pairs {
+ int charNumber = ((int)[pairs count] << 1) - 1;
+ if ([pairs[pairs.count - 1] rightChar] == nil) {
+ charNumber -= 1;
+ }
+
+ int size = 12 * charNumber;
+
+ ZXBitArray *binary = [[ZXBitArray alloc] initWithSize:size];
+ int accPos = 0;
+
+ ZXExpandedPair *firstPair = pairs[0];
+ int firstValue = [[firstPair rightChar] value];
+ for (int i = 11; i >= 0; --i) {
+ if ((firstValue & (1 << i)) != 0) {
+ [binary set:accPos];
+ }
+ accPos++;
+ }
+
+ for (int i = 1; i < [pairs count]; ++i) {
+ ZXExpandedPair *currentPair = pairs[i];
+ int leftValue = [[currentPair leftChar] value];
+
+ for (int j = 11; j >= 0; --j) {
+ if ((leftValue & (1 << j)) != 0) {
+ [binary set:accPos];
+ }
+ accPos++;
+ }
+
+ if ([currentPair rightChar] != nil) {
+ int rightValue = [[currentPair rightChar] value];
+
+ for (int j = 11; j >= 0; --j) {
+ if ((rightValue & (1 << j)) != 0) {
+ [binary set:accPos];
+ }
+ accPos++;
+ }
+ }
+ }
+
+ return binary;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/ZXExpandedPair.h b/ZXingObjC/oned/rss/expanded/ZXExpandedPair.h
new file mode 100644
index 0000000..2d9fc53
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/ZXExpandedPair.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+@class ZXDataCharacter, ZXRSSFinderPattern;
+
+@interface ZXExpandedPair : NSObject
+
+@property (nonatomic, strong, readonly) ZXDataCharacter *leftChar;
+@property (nonatomic, strong, readonly) ZXDataCharacter *rightChar;
+@property (nonatomic, strong, readonly) ZXRSSFinderPattern *finderPattern;
+@property (nonatomic, assign, readonly) BOOL mayBeLast;
+@property (nonatomic, assign, readonly) BOOL mustBeLast;
+
+- (id)initWithLeftChar:(ZXDataCharacter *)leftChar rightChar:(ZXDataCharacter *)rightChar finderPattern:(ZXRSSFinderPattern *)finderPattern mayBeLast:(BOOL)mayBeLast;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/ZXExpandedPair.m b/ZXingObjC/oned/rss/expanded/ZXExpandedPair.m
new file mode 100644
index 0000000..cd760c2
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/ZXExpandedPair.m
@@ -0,0 +1,67 @@
+/*
+ * 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 "ZXExpandedPair.h"
+#import "ZXDataCharacter.h"
+#import "ZXRSSFinderPattern.h"
+
+@implementation ZXExpandedPair
+
+- (id)initWithLeftChar:(ZXDataCharacter *)leftChar rightChar:(ZXDataCharacter *)rightChar
+ finderPattern:(ZXRSSFinderPattern *)finderPattern mayBeLast:(BOOL)mayBeLast {
+ if (self = [super init]) {
+ _leftChar = leftChar;
+ _rightChar = rightChar;
+ _finderPattern = finderPattern;
+ _mayBeLast = mayBeLast;
+ }
+
+ return self;
+}
+
+- (BOOL)mustBeLast {
+ return self.rightChar == nil;
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"[ %@, %@ : %@ ]",
+ self.leftChar, self.rightChar,
+ self.finderPattern == nil ? @"null" : [NSString stringWithFormat:@"%d", self.finderPattern.value]];
+}
+
+- (BOOL)isEqual:(id)object {
+ if (![object isKindOfClass:[ZXExpandedPair class]]) {
+ return NO;
+ }
+ ZXExpandedPair *that = (ZXExpandedPair *)object;
+ return [ZXExpandedPair isEqualOrNil:self.leftChar toObject:that.leftChar] &&
+ [ZXExpandedPair isEqualOrNil:self.rightChar toObject:that.rightChar] &&
+ [ZXExpandedPair isEqualOrNil:self.finderPattern toObject:that.finderPattern];
+}
+
++ (BOOL)isEqualOrNil:(id)o1 toObject:(id)o2 {
+ return o1 == nil ? o2 == nil : [o1 isEqual:o2];
+}
+
+- (NSUInteger)hash {
+ return [self hashNotNil:self.leftChar] ^ [self hashNotNil:self.rightChar] ^ [self hashNotNil:self.finderPattern];
+}
+
+- (NSUInteger)hashNotNil:(NSObject *)o {
+ return o == nil ? 0 : o.hash;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/ZXExpandedRow.h b/ZXingObjC/oned/rss/expanded/ZXExpandedRow.h
new file mode 100644
index 0000000..8e57196
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/ZXExpandedRow.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * One row of an RSS Expanded Stacked symbol, consisting of 1+ expanded pairs.
+ */
+@interface ZXExpandedRow : NSObject
+
+@property (nonatomic, strong, readonly) NSArray *pairs;
+@property (nonatomic, assign, readonly) int rowNumber;
+@property (nonatomic, assign, readonly) BOOL wasReversed;
+
+- (id)initWithPairs:(NSArray *)pairs rowNumber:(int)rowNumber wasReversed:(BOOL)wasReversed;
+- (BOOL)isReversed;
+- (BOOL)isEquivalent:(NSArray *)otherPairs;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/ZXExpandedRow.m b/ZXingObjC/oned/rss/expanded/ZXExpandedRow.m
new file mode 100644
index 0000000..92251e5
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/ZXExpandedRow.m
@@ -0,0 +1,58 @@
+/*
+ * 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 "ZXExpandedRow.h"
+
+@implementation ZXExpandedRow
+
+- (id)initWithPairs:(NSArray *)pairs rowNumber:(int)rowNumber wasReversed:(BOOL)wasReversed {
+ if (self = [super init]) {
+ _pairs = [NSArray arrayWithArray:pairs];
+ _rowNumber = rowNumber;
+ _wasReversed = wasReversed;
+ }
+
+ return self;
+}
+
+- (BOOL)isReversed {
+ return self.wasReversed;
+}
+
+- (BOOL)isEquivalent:(NSArray *)otherPairs {
+ return [self.pairs isEqualToArray:otherPairs];
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"{%@}", self.pairs];
+}
+
+/**
+ * Two rows are equal if they contain the same pairs in the same order.
+ */
+- (BOOL)isEqual:(id)object {
+ if (![object isKindOfClass:[ZXExpandedRow class]]) {
+ return NO;
+ }
+ ZXExpandedRow *that = (ZXExpandedRow *)object;
+ return [self.pairs isEqual:that.pairs] && (self.wasReversed == that.wasReversed);
+}
+
+- (NSUInteger)hash {
+ return self.pairs.hash ^ @(self.wasReversed).hash;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.h b/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.h
new file mode 100644
index 0000000..076b11b
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.h
@@ -0,0 +1,32 @@
+/*
+ * 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 "ZXAbstractRSSReader.h"
+
+@class ZXDataCharacter, ZXExpandedPair, ZXResult, ZXRSSFinderPattern;
+
+@interface ZXRSSExpandedReader : ZXAbstractRSSReader
+
+@property (nonatomic, strong, readonly) NSMutableArray *rows;
+
+- (ZXDataCharacter *)decodeDataCharacter:(ZXBitArray *)row pattern:(ZXRSSFinderPattern *)pattern isOddPattern:(BOOL)isOddPattern leftChar:(BOOL)leftChar;
+
+// for tests
+- (NSMutableArray *)decodeRow2pairs:(int)rowNumber row:(ZXBitArray *)row;
+- (ZXResult *)constructResult:(NSMutableArray *)pairs error:(NSError **)error;
+- (ZXExpandedPair *)retrieveNextPair:(ZXBitArray *)row previousPairs:(NSMutableArray *)previousPairs rowNumber:(int)rowNumber;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.m b/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.m
new file mode 100644
index 0000000..b17ff46
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.m
@@ -0,0 +1,756 @@
+ /*
+ * 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 "ZXAbstractExpandedDecoder.h"
+#import "ZXBitArray.h"
+#import "ZXBitArrayBuilder.h"
+#import "ZXDataCharacter.h"
+#import "ZXErrors.h"
+#import "ZXExpandedPair.h"
+#import "ZXExpandedRow.h"
+#import "ZXResult.h"
+#import "ZXRSSExpandedReader.h"
+#import "ZXRSSFinderPattern.h"
+#import "ZXRSSUtils.h"
+
+const int SYMBOL_WIDEST[5] = {7, 5, 4, 3, 1};
+const int EVEN_TOTAL_SUBSET[5] = {4, 20, 52, 104, 204};
+const int GSUM[5] = {0, 348, 1388, 2948, 3988};
+
+const int WEIGHTS[23][8] = {
+ { 1, 3, 9, 27, 81, 32, 96, 77},
+ { 20, 60, 180, 118, 143, 7, 21, 63},
+ {189, 145, 13, 39, 117, 140, 209, 205},
+ {193, 157, 49, 147, 19, 57, 171, 91},
+ { 62, 186, 136, 197, 169, 85, 44, 132},
+ {185, 133, 188, 142, 4, 12, 36, 108},
+ {113, 128, 173, 97, 80, 29, 87, 50},
+ {150, 28, 84, 41, 123, 158, 52, 156},
+ { 46, 138, 203, 187, 139, 206, 196, 166},
+ { 76, 17, 51, 153, 37, 111, 122, 155},
+ { 43, 129, 176, 106, 107, 110, 119, 146},
+ { 16, 48, 144, 10, 30, 90, 59, 177},
+ {109, 116, 137, 200, 178, 112, 125, 164},
+ { 70, 210, 208, 202, 184, 130, 179, 115},
+ {134, 191, 151, 31, 93, 68, 204, 190},
+ {148, 22, 66, 198, 172, 94, 71, 2},
+ { 6, 18, 54, 162, 64, 192,154, 40},
+ {120, 149, 25, 75, 14, 42,126, 167},
+ { 79, 26, 78, 23, 69, 207,199, 175},
+ {103, 98, 83, 38, 114, 131, 182, 124},
+ {161, 61, 183, 127, 170, 88, 53, 159},
+ { 55, 165, 73, 8, 24, 72, 5, 15},
+ { 45, 135, 194, 160, 58, 174, 100, 89}
+};
+
+const int FINDER_PAT_A = 0;
+const int FINDER_PAT_B = 1;
+const int FINDER_PAT_C = 2;
+const int FINDER_PAT_D = 3;
+const int FINDER_PAT_E = 4;
+const int FINDER_PAT_F = 5;
+
+#define FINDER_PATTERN_SEQUENCES_LEN 10
+#define FINDER_PATTERN_SEQUENCES_SUBLEN 11
+const int FINDER_PATTERN_SEQUENCES[FINDER_PATTERN_SEQUENCES_LEN][FINDER_PATTERN_SEQUENCES_SUBLEN] = {
+ { FINDER_PAT_A, FINDER_PAT_A },
+ { FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B },
+ { FINDER_PAT_A, FINDER_PAT_C, FINDER_PAT_B, FINDER_PAT_D },
+ { FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_C },
+ { FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_F },
+ { FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F },
+ { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D },
+ { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E },
+ { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F },
+ { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F },
+};
+
+//#define LONGEST_SEQUENCE_SIZE FINDER_PATTERN_SEQUENCES_SUBLEN
+
+const int MAX_PAIRS = 11;
+
+@interface ZXRSSExpandedReader () {
+ int startEnd[2];
+// int currentSequence[LONGEST_SEQUENCE_SIZE];
+ BOOL startFromEven;
+}
+
+@property (nonatomic, strong) NSMutableArray *pairs;
+@property (nonatomic, strong) NSMutableArray *rows;
+
+@end
+
+@implementation ZXRSSExpandedReader
+
+- (id)init {
+ if (self = [super init]) {
+ _pairs = [NSMutableArray array];
+ _rows = [NSMutableArray array];
+ startFromEven = NO;
+ startEnd[0] = 0;
+ startEnd[1] = 0;
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ // Rows can start with even pattern in case in prev rows there where odd number of patters.
+ // So lets try twice
+ [self.pairs removeAllObjects];
+ startFromEven = NO;
+ NSMutableArray* pairs = [self decodeRow2pairs:rowNumber row:row];
+ if (pairs) {
+ ZXResult *result = [self constructResult:pairs error:error];
+ if (result) {
+ return result;
+ }
+ }
+
+ [self.pairs removeAllObjects];
+ startFromEven = YES;
+ pairs = [self decodeRow2pairs:rowNumber row:row];
+ if (!pairs) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ return [self constructResult:pairs error:error];
+}
+
+- (void)reset {
+ [self.pairs removeAllObjects];
+ [self.rows removeAllObjects];
+}
+
+- (NSMutableArray *)decodeRow2pairs:(int)rowNumber row:(ZXBitArray *)row {
+ while (YES) {
+ ZXExpandedPair *nextPair = [self retrieveNextPair:row previousPairs:self.pairs rowNumber:rowNumber];
+ if (!nextPair) {
+ if ([self.pairs count] == 0) {
+ return nil;
+ }
+ break;
+ }
+ [self.pairs addObject:nextPair];
+ }
+
+ // TODO: verify sequence of finder patterns as in checkPairSequence()
+ if ([self checkChecksum]) {
+ return self.pairs;
+ }
+
+ BOOL tryStackedDecode = [self.rows count] > 0;
+ BOOL wasReversed = NO; // TODO: deal with reversed rows
+ [self storeRow:rowNumber wasReversed:wasReversed];
+ if (tryStackedDecode) {
+ // When the image is 180-rotated, then rows are sorted in wrong dirrection.
+ // Try twice with both the directions.
+ NSMutableArray *ps = [self checkRows:NO];
+ if (ps) {
+ return ps;
+ }
+ ps = [self checkRows:YES];
+ if (ps) {
+ return ps;
+ }
+ }
+
+ return nil;
+}
+
+- (NSMutableArray *)checkRows:(BOOL)reverse {
+ // Limit number of rows we are checking
+ // We use recursive algorithm with pure complexity and don't want it to take forever
+ // Stacked barcode can have up to 11 rows, so 25 seems resonable enough
+ if (self.rows.count > 25) {
+ [self.rows removeAllObjects];
+ return nil;
+ }
+
+ [self.pairs removeAllObjects];
+ if (reverse) {
+ self.rows = [[[self.rows reverseObjectEnumerator] allObjects] mutableCopy];
+ }
+
+ NSMutableArray *ps = [self checkRows:[NSMutableArray array] current:0];
+
+ if (reverse) {
+ self.rows = [[[self.rows reverseObjectEnumerator] allObjects] mutableCopy];
+ }
+
+ return ps;
+}
+
+// Try to construct a valid rows sequence
+// Recursion is used to implement backtracking
+- (NSMutableArray *)checkRows:(NSMutableArray *)collectedRows current:(int)currentRow {
+ for (int i = currentRow; i < [self.rows count]; i++) {
+ ZXExpandedRow *row = self.rows[i];
+ [self.pairs removeAllObjects];
+ NSUInteger size = [collectedRows count];
+ for (int j = 0; j < size; j++) {
+ [self.pairs addObjectsFromArray:[collectedRows[j] pairs]];
+ }
+ [self.pairs addObjectsFromArray:row.pairs];
+
+ if (![self isValidSequence:self.pairs]) {
+ continue;
+ }
+
+ if ([self checkChecksum]) {
+ return self.pairs;
+ }
+
+ NSMutableArray *rs = [NSMutableArray array];
+ [rs addObjectsFromArray:collectedRows];
+ [rs addObject:row];
+ NSMutableArray *ps = [self checkRows:rs current:i + 1];
+ if (ps) {
+ return ps;
+ }
+ }
+ return nil;
+}
+
+// Whether the pairs form a valid find pattern seqience,
+// either complete or a prefix
+- (BOOL)isValidSequence:(NSArray *)pairs {
+ for (int i = 0, sz = 2; i < FINDER_PATTERN_SEQUENCES_LEN; i++, sz++) {
+ if ([self.pairs count] > sz) {
+ continue;
+ }
+
+ BOOL stop = YES;
+ for (int j = 0; j < [self.pairs count]; j++) {
+ if ([[self.pairs[j] finderPattern] value] != FINDER_PATTERN_SEQUENCES[i][j]) {
+ stop = NO;
+ break;
+ }
+ }
+
+ if (stop) {
+ return YES;
+ }
+ }
+
+ return NO;
+}
+
+- (void)storeRow:(int)rowNumber wasReversed:(BOOL)wasReversed {
+ // Discard if duplicate above or below; otherwise insert in order by row number.
+ int insertPos = 0;
+ BOOL prevIsSame = NO;
+ BOOL nextIsSame = NO;
+ while (insertPos < [self.rows count]) {
+ ZXExpandedRow *erow = self.rows[insertPos];
+ if (erow.rowNumber > rowNumber) {
+ nextIsSame = [erow isEquivalent:self.pairs];
+ break;
+ }
+ prevIsSame = [erow isEquivalent:self.pairs];
+ insertPos++;
+ }
+ if (nextIsSame || prevIsSame) {
+ return;
+ }
+
+ // When the row was partially decoded (e.g. 2 pairs found instead of 3),
+ // it will prevent us from detecting the barcode.
+ // Try to merge partial rows
+
+ // Check whether the row is part of an allready detected row
+ if ([self isPartialRow:self.pairs of:self.rows]) {
+ return;
+ }
+
+ [self.rows insertObject:[[ZXExpandedRow alloc] initWithPairs:self.pairs rowNumber:rowNumber wasReversed:wasReversed] atIndex:insertPos];
+
+ [self removePartialRows:self.pairs from:self.rows];
+}
+
+// Remove all the rows that contains only specified pairs
+- (void)removePartialRows:(NSArray *)pairs from:(NSMutableArray *)rows {
+ NSMutableArray *toRemove = [NSMutableArray array];
+ for (ZXExpandedRow *r in rows) {
+ if ([r.pairs count] == [pairs count]) {
+ continue;
+ }
+ BOOL allFound = YES;
+ for (ZXExpandedPair *p in r.pairs) {
+ BOOL found = NO;
+ for (ZXExpandedPair *pp in pairs) {
+ if ([p isEqual:pp]) {
+ found = YES;
+ break;
+ }
+ }
+ if (!found) {
+ allFound = NO;
+ break;
+ }
+ }
+ if (allFound) {
+ [toRemove addObject:r];
+ }
+ }
+
+ for (ZXExpandedRow *r in toRemove) {
+ [rows removeObject:r];
+ }
+}
+
+- (BOOL)isPartialRow:(NSArray *)pairs of:(NSArray *)rows {
+ for (ZXExpandedRow *r in rows) {
+ BOOL allFound = YES;
+ for (ZXExpandedPair *p in pairs) {
+ BOOL found = NO;
+ for (ZXExpandedPair *pp in r.pairs) {
+ if ([p isEqual:pp]) {
+ found = YES;
+ break;
+ }
+ }
+ if (!found) {
+ allFound = NO;
+ break;
+ }
+ }
+ if (allFound) {
+ // the row 'r' contain all the pairs from 'pairs'
+ return YES;
+ }
+ }
+ return NO;
+}
+
+- (ZXResult *)constructResult:(NSMutableArray *)pairs error:(NSError **)error {
+ ZXBitArray *binary = [ZXBitArrayBuilder buildBitArray:pairs];
+
+ ZXAbstractExpandedDecoder *decoder = [ZXAbstractExpandedDecoder createDecoder:binary];
+ NSString *resultingString = [decoder parseInformationWithError:error];
+ if (!resultingString) {
+ return nil;
+ }
+
+ NSArray *firstPoints = [[((ZXExpandedPair *)_pairs[0]) finderPattern] resultPoints];
+ NSArray *lastPoints = [[((ZXExpandedPair *)[_pairs lastObject]) finderPattern] resultPoints];
+
+ return [ZXResult resultWithText:resultingString
+ rawBytes:NULL
+ length:0
+ resultPoints:@[firstPoints[0], firstPoints[1], lastPoints[0], lastPoints[1]]
+ format:kBarcodeFormatRSSExpanded];
+}
+
+- (BOOL)checkChecksum {
+ ZXExpandedPair *firstPair = self.pairs[0];
+ ZXDataCharacter *checkCharacter = firstPair.leftChar;
+ ZXDataCharacter *firstCharacter = firstPair.rightChar;
+
+ if (!firstCharacter) {
+ return NO;
+ }
+
+ int checksum = [firstCharacter checksumPortion];
+ int s = 2;
+
+ for (int i = 1; i < self.pairs.count; ++i) {
+ ZXExpandedPair *currentPair = self.pairs[i];
+ checksum += currentPair.leftChar.checksumPortion;
+ s++;
+ ZXDataCharacter *currentRightChar = currentPair.rightChar;
+ if (currentRightChar != nil) {
+ checksum += currentRightChar.checksumPortion;
+ s++;
+ }
+ }
+
+ checksum %= 211;
+
+ int checkCharacterValue = 211 * (s - 4) + checksum;
+
+ return checkCharacterValue == checkCharacter.value;
+}
+
+- (int)nextSecondBar:(ZXBitArray *)row initialPos:(int)initialPos {
+ int currentPos;
+ if ([row get:initialPos]) {
+ currentPos = [row nextUnset:initialPos];
+ currentPos = [row nextSet:currentPos];
+ } else {
+ currentPos = [row nextSet:initialPos];
+ currentPos = [row nextUnset:currentPos];
+ }
+ return currentPos;
+}
+
+- (ZXExpandedPair *)retrieveNextPair:(ZXBitArray *)row previousPairs:(NSMutableArray *)previousPairs rowNumber:(int)rowNumber {
+ BOOL isOddPattern = [previousPairs count] % 2 == 0;
+ if (startFromEven) {
+ isOddPattern = !isOddPattern;
+ }
+
+ ZXRSSFinderPattern *pattern;
+
+ BOOL keepFinding = YES;
+ int forcedOffset = -1;
+ do {
+ if (![self findNextPair:row previousPairs:previousPairs forcedOffset:forcedOffset]) {
+ return nil;
+ }
+ pattern = [self parseFoundFinderPattern:row rowNumber:rowNumber oddPattern:isOddPattern];
+ if (pattern == nil) {
+ forcedOffset = [self nextSecondBar:row initialPos:startEnd[0]];
+ } else {
+ keepFinding = NO;
+ }
+ } while (keepFinding);
+
+ // When stacked symbol is split over multiple rows, there's no way to guess if this pair can be last or not.
+ // boolean mayBeLast = checkPairSequence(previousPairs, pattern);
+
+ ZXDataCharacter *leftChar = [self decodeDataCharacter:row pattern:pattern isOddPattern:isOddPattern leftChar:YES];
+ if (!leftChar) {
+ return nil;
+ }
+
+ if (previousPairs.count > 0 && [[previousPairs lastObject] mustBeLast]) {
+ return nil;
+ }
+
+ ZXDataCharacter *rightChar = [self decodeDataCharacter:row pattern:pattern isOddPattern:isOddPattern leftChar:NO];
+ BOOL mayBeLast = YES;
+ return [[ZXExpandedPair alloc] initWithLeftChar:leftChar rightChar:rightChar finderPattern:pattern mayBeLast:mayBeLast];
+}
+
+- (BOOL)findNextPair:(ZXBitArray *)row previousPairs:(NSMutableArray *)previousPairs forcedOffset:(int)forcedOffset {
+ const int countersLen = self.decodeFinderCountersLen;
+ int *counters = self.decodeFinderCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+
+ int width = row.size;
+
+ int rowOffset;
+ if (forcedOffset >= 0) {
+ rowOffset = forcedOffset;
+ } else if ([previousPairs count] == 0) {
+ rowOffset = 0;
+ } else {
+ ZXExpandedPair *lastPair = [previousPairs lastObject];
+ rowOffset = [[[lastPair finderPattern] startEnd][1] intValue];
+ }
+ BOOL searchingEvenPair = [previousPairs count] % 2 != 0;
+ if (startFromEven) {
+ searchingEvenPair = !searchingEvenPair;
+ }
+
+ BOOL isWhite = NO;
+ while (rowOffset < width) {
+ isWhite = ![row get:rowOffset];
+ if (!isWhite) {
+ break;
+ }
+ rowOffset++;
+ }
+
+ int counterPosition = 0;
+ int patternStart = rowOffset;
+ for (int x = rowOffset; x < width; x++) {
+ if ([row get:x] ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == 3) {
+ if (searchingEvenPair) {
+ [self reverseCounters:counters length:countersLen];
+ }
+
+ if ([ZXAbstractRSSReader isFinderPattern:counters countersLen:countersLen]) {
+ startEnd[0] = patternStart;
+ startEnd[1] = x;
+ return YES;
+ }
+
+ if (searchingEvenPair) {
+ [self reverseCounters:counters length:countersLen];
+ }
+
+ patternStart += counters[0] + counters[1];
+ counters[0] = counters[2];
+ counters[1] = counters[3];
+ counters[2] = 0;
+ counters[3] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ return NO;
+}
+
+- (void)reverseCounters:(int *)counters length:(unsigned int)length {
+ for(int i = 0; i < length / 2; ++i){
+ int tmp = counters[i];
+ counters[i] = counters[length - i - 1];
+ counters[length - i - 1] = tmp;
+ }
+}
+
+- (ZXRSSFinderPattern *)parseFoundFinderPattern:(ZXBitArray *)row rowNumber:(int)rowNumber oddPattern:(BOOL)oddPattern {
+ // Actually we found elements 2-5.
+ int firstCounter;
+ int start;
+ int end;
+
+ if (oddPattern) {
+ // If pattern number is odd, we need to locate element 1 *before *the current block.
+
+ int firstElementStart = startEnd[0] - 1;
+ // Locate element 1
+ while (firstElementStart >= 0 && ![row get:firstElementStart]) {
+ firstElementStart--;
+ }
+
+ firstElementStart++;
+ firstCounter = startEnd[0] - firstElementStart;
+ start = firstElementStart;
+ end = startEnd[1];
+ } else {
+ // If pattern number is even, the pattern is reversed, so we need to locate element 1 *after *the current block.
+
+ start = startEnd[0];
+
+ end = [row nextUnset:startEnd[1] + 1];
+ firstCounter = end - startEnd[1];
+ }
+
+ // Make 'counters' hold 1-4
+ int countersLen = self.decodeFinderCountersLen;
+ int counters[countersLen];
+ counters[0] = self.decodeFinderCounters[0];
+ for (int i = 1; i < countersLen; i++) {
+ counters[i] = self.decodeFinderCounters[i - 1];
+ }
+
+ counters[0] = firstCounter;
+ int value = [ZXAbstractRSSReader parseFinderValue:counters countersSize:countersLen
+ finderPatternType:RSS_PATTERNS_RSS_EXPANDED_PATTERNS];
+ if (value == -1) {
+ return nil;
+ }
+ return [[ZXRSSFinderPattern alloc] initWithValue:value startEnd:[@[@(start), @(end)] mutableCopy] start:start end:end rowNumber:rowNumber];
+}
+
+- (ZXDataCharacter *)decodeDataCharacter:(ZXBitArray *)row pattern:(ZXRSSFinderPattern *)pattern isOddPattern:(BOOL)isOddPattern leftChar:(BOOL)leftChar {
+ int countersLen = self.dataCharacterCountersLen;
+ int *counters = self.dataCharacterCounters;
+ counters[0] = 0;
+ counters[1] = 0;
+ counters[2] = 0;
+ counters[3] = 0;
+ counters[4] = 0;
+ counters[5] = 0;
+ counters[6] = 0;
+ counters[7] = 0;
+
+ if (leftChar) {
+ if (![ZXOneDReader recordPatternInReverse:row start:[[pattern startEnd][0] intValue] counters:counters countersSize:countersLen]) {
+ return nil;
+ }
+ } else {
+ if (![ZXOneDReader recordPattern:row start:[[pattern startEnd][1] intValue] counters:counters countersSize:countersLen]) {
+ return nil;
+ }
+ // reverse it
+ for (int i = 0, j = countersLen - 1; i < j; i++, j--) {
+ int temp = counters[i];
+ counters[i] = counters[j];
+ counters[j] = temp;
+ }
+ }//counters[] has the pixels of the module
+
+ int numModules = 17; //left and right data characters have all the same length
+ float elementWidth = (float)[ZXAbstractRSSReader count:counters arrayLen:countersLen] / (float)numModules;
+
+ // Sanity check: element width for pattern and the character should match
+ float expectedElementWidth = ([pattern.startEnd[1] intValue] - [pattern.startEnd[0] intValue]) / 15.0f;
+ if (fabsf(elementWidth - expectedElementWidth) / expectedElementWidth > 0.3f) {
+ return nil;
+ }
+
+ for (int i = 0; i < countersLen; i++) {
+ float value = 1.0f * counters[i] / elementWidth;
+ int count = (int)(value + 0.5f);
+ if (count < 1) {
+ if (value < 0.3f) {
+ return nil;
+ }
+ count = 1;
+ } else if (count > 8) {
+ if (value > 8.7f) {
+ return nil;
+ }
+ count = 8;
+ }
+ int offset = i >> 1;
+ if ((i & 0x01) == 0) {
+ self.oddCounts[offset] = count;
+ self.oddRoundingErrors[offset] = value - count;
+ } else {
+ self.evenCounts[offset] = count;
+ self.evenRoundingErrors[offset] = value - count;
+ }
+ }
+
+ if (![self adjustOddEvenCounts:numModules]) {
+ return nil;
+ }
+
+ int weightRowNumber = 4 * pattern.value + (isOddPattern ? 0 : 2) + (leftChar ? 0 : 1) - 1;
+
+ int oddSum = 0;
+ int oddChecksumPortion = 0;
+ for (int i = self.oddCountsLen - 1; i >= 0; i--) {
+ if ([self isNotA1left:pattern isOddPattern:isOddPattern leftChar:leftChar]) {
+ int weight = WEIGHTS[weightRowNumber][2 * i];
+ oddChecksumPortion += self.oddCounts[i] * weight;
+ }
+ oddSum += self.oddCounts[i];
+ }
+ int evenChecksumPortion = 0;
+ //int evenSum = 0;
+ for (int i = self.evenCountsLen - 1; i >= 0; i--) {
+ if ([self isNotA1left:pattern isOddPattern:isOddPattern leftChar:leftChar]) {
+ int weight = WEIGHTS[weightRowNumber][2 * i + 1];
+ evenChecksumPortion += self.evenCounts[i] * weight;
+ }
+ //evenSum += self.evenCounts[i];
+ }
+ int checksumPortion = oddChecksumPortion + evenChecksumPortion;
+
+ if ((oddSum & 0x01) != 0 || oddSum > 13 || oddSum < 4) {
+ return nil;
+ }
+
+ int group = (13 - oddSum) / 2;
+ int oddWidest = SYMBOL_WIDEST[group];
+ int evenWidest = 9 - oddWidest;
+ int vOdd = [ZXRSSUtils rssValue:self.oddCounts widthsLen:self.oddCountsLen maxWidth:oddWidest noNarrow:YES];
+ int vEven = [ZXRSSUtils rssValue:self.evenCounts widthsLen:self.evenCountsLen maxWidth:evenWidest noNarrow:NO];
+ int tEven = EVEN_TOTAL_SUBSET[group];
+ int gSum = GSUM[group];
+ int value = vOdd * tEven + vEven + gSum;
+ return [[ZXDataCharacter alloc] initWithValue:value checksumPortion:checksumPortion];
+}
+
+- (BOOL)isNotA1left:(ZXRSSFinderPattern *)pattern isOddPattern:(BOOL)isOddPattern leftChar:(BOOL)leftChar {
+ return !([pattern value] == 0 && isOddPattern && leftChar);
+}
+
+- (BOOL)adjustOddEvenCounts:(int)numModules {
+ int oddSum = [ZXAbstractRSSReader count:self.oddCounts arrayLen:self.oddCountsLen];
+ int evenSum = [ZXAbstractRSSReader count:self.evenCounts arrayLen:self.evenCountsLen];
+ int mismatch = oddSum + evenSum - numModules;
+ BOOL oddParityBad = (oddSum & 0x01) == 1;
+ BOOL evenParityBad = (evenSum & 0x01) == 0;
+ BOOL incrementOdd = NO;
+ BOOL decrementOdd = NO;
+ if (oddSum > 13) {
+ decrementOdd = YES;
+ } else if (oddSum < 4) {
+ incrementOdd = YES;
+ }
+ BOOL incrementEven = NO;
+ BOOL decrementEven = NO;
+ if (evenSum > 13) {
+ decrementEven = YES;
+ } else if (evenSum < 4) {
+ incrementEven = YES;
+ }
+
+ if (mismatch == 1) {
+ if (oddParityBad) {
+ if (evenParityBad) {
+ return NO;
+ }
+ decrementOdd = YES;
+ } else {
+ if (!evenParityBad) {
+ return NO;
+ }
+ decrementEven = YES;
+ }
+ } else if (mismatch == -1) {
+ if (oddParityBad) {
+ if (evenParityBad) {
+ return NO;
+ }
+ incrementOdd = YES;
+ } else {
+ if (!evenParityBad) {
+ return NO;
+ }
+ incrementEven = YES;
+ }
+ } else if (mismatch == 0) {
+ if (oddParityBad) {
+ if (!evenParityBad) {
+ return NO;
+ }
+ if (oddSum < evenSum) {
+ incrementOdd = YES;
+ decrementEven = YES;
+ } else {
+ decrementOdd = YES;
+ incrementEven = YES;
+ }
+ } else {
+ if (evenParityBad) {
+ return NO;
+ }
+ }
+ } else {
+ return NO;
+ }
+
+ if (incrementOdd) {
+ if (decrementOdd) {
+ return NO;
+ }
+ [ZXAbstractRSSReader increment:self.oddCounts arrayLen:self.oddCountsLen errors:self.oddRoundingErrors];
+ }
+ if (decrementOdd) {
+ [ZXAbstractRSSReader decrement:self.oddCounts arrayLen:self.oddCountsLen errors:self.oddRoundingErrors];
+ }
+ if (incrementEven) {
+ if (decrementEven) {
+ return NO;
+ }
+ [ZXAbstractRSSReader increment:self.evenCounts arrayLen:self.evenCountsLen errors:self.oddRoundingErrors];
+ }
+ if (decrementEven) {
+ [ZXAbstractRSSReader decrement:self.evenCounts arrayLen:self.evenCountsLen errors:self.evenRoundingErrors];
+ }
+ return YES;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.h
new file mode 100644
index 0000000..66aeb92
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.h
@@ -0,0 +1,24 @@
+/*
+ * 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 "ZXAI013x0xDecoder.h"
+
+@interface ZXAI013103decoder : ZXAI013x0xDecoder
+
+- (void)addWeightCode:(NSMutableString *)buf weight:(int)weight;
+- (int)checkWeight:(int)weight;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.m
new file mode 100644
index 0000000..06ce8d0
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.m
@@ -0,0 +1,30 @@
+/*
+ * 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 "ZXAI013103decoder.h"
+#import "ZXBitArray.h"
+
+@implementation ZXAI013103decoder
+
+- (void)addWeightCode:(NSMutableString *)buf weight:(int)weight {
+ [buf appendString:@"(3103)"];
+}
+
+- (int)checkWeight:(int)weight {
+ return weight;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.h
new file mode 100644
index 0000000..ea1d339
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.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 "ZXAI013x0xDecoder.h"
+
+@interface ZXAI01320xDecoder : ZXAI013x0xDecoder
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.m
new file mode 100644
index 0000000..714331c
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.m
@@ -0,0 +1,36 @@
+/*
+ * 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 "ZXAI01320xDecoder.h"
+
+@implementation ZXAI01320xDecoder
+
+- (void)addWeightCode:(NSMutableString *)buf weight:(int)weight {
+ if (weight < 10000) {
+ [buf appendString:@"(3202)"];
+ } else {
+ [buf appendString:@"(3203)"];
+ }
+}
+
+- (int)checkWeight:(int)weight {
+ if (weight < 10000) {
+ return weight;
+ }
+ return weight - 10000;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.h
new file mode 100644
index 0000000..4ae02cc
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.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 "ZXAI01decoder.h"
+
+@interface ZXAI01392xDecoder : ZXAI01decoder
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.m
new file mode 100644
index 0000000..d29e211
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.m
@@ -0,0 +1,42 @@
+/*
+ * 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 "ZXAI01392xDecoder.h"
+#import "ZXBitArray.h"
+#import "ZXDecodedInformation.h"
+#import "ZXErrors.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+int const AI01392x_HEADER_SIZE = 5 + 1 + 2;
+int const AI01392x_LAST_DIGIT_SIZE = 2;
+
+@implementation ZXAI01392xDecoder
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ if (self.information.size < AI01392x_HEADER_SIZE + GTIN_SIZE) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ NSMutableString *buf = [NSMutableString string];
+ [self encodeCompressedGtin:buf currentPos:AI01392x_HEADER_SIZE];
+ int lastAIdigit = [self.generalDecoder extractNumericValueFromBitArray:AI01392x_HEADER_SIZE + GTIN_SIZE bits:AI01392x_LAST_DIGIT_SIZE];
+ [buf appendFormat:@"(392%d)", lastAIdigit];
+ ZXDecodedInformation *decodedInformation = [self.generalDecoder decodeGeneralPurposeField:AI01392x_HEADER_SIZE + GTIN_SIZE + AI01392x_LAST_DIGIT_SIZE remaining:nil];
+ [buf appendString:decodedInformation.theNewString];
+ return buf;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.h
new file mode 100644
index 0000000..9fac134
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.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 "ZXAI01decoder.h"
+
+@interface ZXAI01393xDecoder : ZXAI01decoder
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.m
new file mode 100644
index 0000000..ff43dbb
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.m
@@ -0,0 +1,58 @@
+/*
+ * 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 "ZXAI01393xDecoder.h"
+#import "ZXBitArray.h"
+#import "ZXDecodedInformation.h"
+#import "ZXErrors.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+@implementation ZXAI01393xDecoder
+
+int const AI01393xDecoder_HEADER_SIZE = 5 + 1 + 2;
+int const AI01393xDecoder_LAST_DIGIT_SIZE = 2;
+int const AI01393xDecoder_FIRST_THREE_DIGITS_SIZE = 10;
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ if (self.information.size < AI01393xDecoder_HEADER_SIZE + GTIN_SIZE) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ NSMutableString *buf = [NSMutableString string];
+
+ [self encodeCompressedGtin:buf currentPos:AI01393xDecoder_HEADER_SIZE];
+
+ int lastAIdigit = [self.generalDecoder extractNumericValueFromBitArray:AI01393xDecoder_HEADER_SIZE + GTIN_SIZE bits:AI01393xDecoder_LAST_DIGIT_SIZE];
+
+ [buf appendFormat:@"(393%d)", lastAIdigit];
+
+ int firstThreeDigits = [self.generalDecoder extractNumericValueFromBitArray:AI01393xDecoder_HEADER_SIZE + GTIN_SIZE + AI01393xDecoder_LAST_DIGIT_SIZE bits:AI01393xDecoder_FIRST_THREE_DIGITS_SIZE];
+ if (firstThreeDigits / 100 == 0) {
+ [buf appendString:@"0"];
+ }
+ if (firstThreeDigits / 10 == 0) {
+ [buf appendString:@"0"];
+ }
+ [buf appendFormat:@"%d", firstThreeDigits];
+
+ ZXDecodedInformation *generalInformation = [self.generalDecoder decodeGeneralPurposeField:AI01393xDecoder_HEADER_SIZE + GTIN_SIZE + AI01393xDecoder_LAST_DIGIT_SIZE + AI01393xDecoder_FIRST_THREE_DIGITS_SIZE remaining:nil];
+ [buf appendString:generalInformation.theNewString];
+
+ return buf;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.h
new file mode 100644
index 0000000..3f2211d
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.h
@@ -0,0 +1,23 @@
+/*
+ * 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 "ZXAI01weightDecoder.h"
+
+@interface ZXAI013x0x1xDecoder : ZXAI01weightDecoder
+
+- (id)initWithInformation:(ZXBitArray *)information firstAIdigits:(NSString *)firstAIdigits dateCode:(NSString *)dateCode;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.m
new file mode 100644
index 0000000..ebb79c2
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.m
@@ -0,0 +1,90 @@
+/*
+ * 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 "ZXAI013x0x1xDecoder.h"
+#import "ZXBitArray.h"
+#import "ZXErrors.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+int const AI013x0x1x_HEADER_SIZE = 7 + 1;
+int const AI013x0x1x_WEIGHT_SIZE = 20;
+int const AI013x0x1x_DATE_SIZE = 16;
+
+@interface ZXAI013x0x1xDecoder ()
+
+@property (nonatomic, copy) NSString *dateCode;
+@property (nonatomic, copy) NSString *firstAIdigits;
+
+@end
+
+@implementation ZXAI013x0x1xDecoder
+
+- (id)initWithInformation:(ZXBitArray *)information firstAIdigits:(NSString *)firstAIdigits dateCode:(NSString *)dateCode {
+ if (self = [super initWithInformation:information]) {
+ _dateCode = dateCode;
+ _firstAIdigits = firstAIdigits;
+ }
+
+ return self;
+}
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ if (self.information.size != AI013x0x1x_HEADER_SIZE + GTIN_SIZE + AI013x0x1x_WEIGHT_SIZE + AI013x0x1x_DATE_SIZE) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ NSMutableString *buf = [NSMutableString string];
+ [self encodeCompressedGtin:buf currentPos:AI013x0x1x_HEADER_SIZE];
+ [self encodeCompressedWeight:buf currentPos:AI013x0x1x_HEADER_SIZE + GTIN_SIZE weightSize:AI013x0x1x_WEIGHT_SIZE];
+ [self encodeCompressedDate:buf currentPos:AI013x0x1x_HEADER_SIZE + GTIN_SIZE + AI013x0x1x_WEIGHT_SIZE];
+ return buf;
+}
+
+- (void)encodeCompressedDate:(NSMutableString *)buf currentPos:(int)currentPos {
+ int numericDate = [self.generalDecoder extractNumericValueFromBitArray:currentPos bits:AI013x0x1x_DATE_SIZE];
+ if (numericDate == 38400) {
+ return;
+ }
+ [buf appendFormat:@"(%@)", self.dateCode];
+ int day = numericDate % 32;
+ numericDate /= 32;
+ int month = numericDate % 12 + 1;
+ numericDate /= 12;
+ int year = numericDate;
+ if (year / 10 == 0) {
+ [buf appendString:@"0"];
+ }
+ [buf appendFormat:@"%d", year];
+ if (month / 10 == 0) {
+ [buf appendString:@"0"];
+ }
+ [buf appendFormat:@"%d", month];
+ if (day / 10 == 0) {
+ [buf appendString:@"0"];
+ }
+ [buf appendFormat:@"%d", day];
+}
+
+- (void)addWeightCode:(NSMutableString *)buf weight:(int)weight {
+ int lastAI = weight / 100000;
+ [buf appendFormat:@"(%@%d)", self.firstAIdigits, lastAI];
+}
+
+- (int)checkWeight:(int)weight {
+ return weight % 100000;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.h
new file mode 100644
index 0000000..0f02d6c
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.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 "ZXAI01weightDecoder.h"
+
+@interface ZXAI013x0xDecoder : ZXAI01weightDecoder
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.m
new file mode 100644
index 0000000..d6163c9
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.m
@@ -0,0 +1,40 @@
+/*
+ * 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 "ZXAI013x0xDecoder.h"
+#import "ZXBitArray.h"
+#import "ZXErrors.h"
+
+int const AI013x0x_HEADER_SIZE = 4 + 1;
+int const AI013x0x_WEIGHT_SIZE = 15;
+
+@implementation ZXAI013x0xDecoder
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ if (self.information.size != AI013x0x_HEADER_SIZE + GTIN_SIZE + AI013x0x_WEIGHT_SIZE) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ NSMutableString *buf = [NSMutableString string];
+
+ [self encodeCompressedGtin:buf currentPos:AI013x0x_HEADER_SIZE];
+ [self encodeCompressedWeight:buf currentPos:AI013x0x_HEADER_SIZE + GTIN_SIZE weightSize:AI013x0x_WEIGHT_SIZE];
+
+ return buf;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.h
new file mode 100644
index 0000000..4299580
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.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 "ZXAI01decoder.h"
+
+@interface ZXAI01AndOtherAIs : ZXAI01decoder
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.m
new file mode 100644
index 0000000..641ac77
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.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 "ZXAI01AndOtherAIs.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+int const AI01_HEADER_SIZE = 1 + 1 + 2;
+
+@implementation ZXAI01AndOtherAIs
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ NSMutableString *buff = [NSMutableString string];
+
+ [buff appendString:@"(01)"];
+ int initialGtinPosition = (int)[buff length];
+ int firstGtinDigit = [self.generalDecoder extractNumericValueFromBitArray:AI01_HEADER_SIZE bits:4];
+ [buff appendFormat:@"%d", firstGtinDigit];
+
+ [self encodeCompressedGtinWithoutAI:buff currentPos:AI01_HEADER_SIZE + 4 initialBufferPosition:initialGtinPosition];
+
+ return [self.generalDecoder decodeAllCodes:buff initialPosition:AI01_HEADER_SIZE + 44 error:error];
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.h
new file mode 100644
index 0000000..e562ffb
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.h
@@ -0,0 +1,26 @@
+/*
+ * 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 "ZXAbstractExpandedDecoder.h"
+
+extern const int GTIN_SIZE;
+
+@interface ZXAI01decoder : ZXAbstractExpandedDecoder
+
+- (void)encodeCompressedGtin:(NSMutableString *)buf currentPos:(int)currentPos;
+- (void)encodeCompressedGtinWithoutAI:(NSMutableString *)buf currentPos:(int)currentPos initialBufferPosition:(int)initialBufferPosition;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.m
new file mode 100644
index 0000000..18b10fd
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.m
@@ -0,0 +1,63 @@
+/*
+ * 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 "ZXAI01decoder.h"
+#import "ZXBitArray.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+int const GTIN_SIZE = 40;
+
+@implementation ZXAI01decoder
+
+- (void)encodeCompressedGtin:(NSMutableString *)buf currentPos:(int)currentPos {
+ [buf appendString:@"(01)"];
+ int initialPosition = (int)[buf length];
+ [buf appendString:@"9"];
+
+ [self encodeCompressedGtinWithoutAI:buf currentPos:currentPos initialBufferPosition:initialPosition];
+}
+
+- (void)encodeCompressedGtinWithoutAI:(NSMutableString *)buf currentPos:(int)currentPos initialBufferPosition:(int)initialBufferPosition {
+ for (int i = 0; i < 4; ++i) {
+ int currentBlock = [self.generalDecoder extractNumericValueFromBitArray:currentPos + 10 * i bits:10];
+ if (currentBlock / 100 == 0) {
+ [buf appendString:@"0"];
+ }
+ if (currentBlock / 10 == 0) {
+ [buf appendString:@"0"];
+ }
+ [buf appendFormat:@"%d", currentBlock];
+ }
+
+ [self appendCheckDigit:buf currentPos:initialBufferPosition];
+}
+
+- (void)appendCheckDigit:(NSMutableString *)buf currentPos:(int)currentPos {
+ int checkDigit = 0;
+ for (int i = 0; i < 13; i++) {
+ int digit = [buf characterAtIndex:i + currentPos] - '0';
+ checkDigit += (i & 0x01) == 0 ? 3 * digit : digit;
+ }
+
+ checkDigit = 10 - (checkDigit % 10);
+ if (checkDigit == 10) {
+ checkDigit = 0;
+ }
+
+ [buf appendFormat:@"%d", checkDigit];
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.h
new file mode 100644
index 0000000..40750a2
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.h
@@ -0,0 +1,27 @@
+/*
+ * 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 "ZXAI01decoder.h"
+
+@class ZXBitArray;
+
+@interface ZXAI01weightDecoder : ZXAI01decoder
+
+- (void)encodeCompressedWeight:(NSMutableString *)buf currentPos:(int)currentPos weightSize:(int)weightSize;
+- (void)addWeightCode:(NSMutableString *)buf weight:(int)weight;
+- (int)checkWeight:(int)weight;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.m
new file mode 100644
index 0000000..fe71cb8
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.m
@@ -0,0 +1,51 @@
+/*
+ * 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 "ZXAI01weightDecoder.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+@implementation ZXAI01weightDecoder
+
+- (void)encodeCompressedWeight:(NSMutableString *)buf currentPos:(int)currentPos weightSize:(int)weightSize {
+ int originalWeightNumeric = [self.generalDecoder extractNumericValueFromBitArray:currentPos bits:weightSize];
+ [self addWeightCode:buf weight:originalWeightNumeric];
+
+ int weightNumeric = [self checkWeight:originalWeightNumeric];
+
+ int currentDivisor = 100000;
+ for (int i = 0; i < 5; ++i) {
+ if (weightNumeric / currentDivisor == 0) {
+ [buf appendString:@"0"];
+ }
+ currentDivisor /= 10;
+ }
+
+ [buf appendFormat:@"%d", weightNumeric];
+}
+
+- (void)addWeightCode:(NSMutableString *)buf weight:(int)weight {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+- (int)checkWeight:(int)weight {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h
new file mode 100644
index 0000000..6bcc511
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+@class ZXBitArray, ZXGeneralAppIdDecoder;
+
+@interface ZXAbstractExpandedDecoder : NSObject
+
+@property (nonatomic, strong, readonly) ZXGeneralAppIdDecoder *generalDecoder;
+@property (nonatomic, strong, readonly) ZXBitArray *information;
+
+- (id)initWithInformation:(ZXBitArray *)information;
+- (NSString *)parseInformationWithError:(NSError **)error;
++ (ZXAbstractExpandedDecoder *)createDecoder:(ZXBitArray *)information;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.m
new file mode 100644
index 0000000..31e8c83
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.m
@@ -0,0 +1,95 @@
+/*
+ * 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 "ZXAbstractExpandedDecoder.h"
+#import "ZXAI013103decoder.h"
+#import "ZXAI01320xDecoder.h"
+#import "ZXAI01392xDecoder.h"
+#import "ZXAI01393xDecoder.h"
+#import "ZXAI013x0x1xDecoder.h"
+#import "ZXAI01AndOtherAIs.h"
+#import "ZXAnyAIDecoder.h"
+#import "ZXBitArray.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+@implementation ZXAbstractExpandedDecoder
+
+- (id)initWithInformation:(ZXBitArray *)information {
+ if (self = [super init]) {
+ _information = information;
+ _generalDecoder = [[ZXGeneralAppIdDecoder alloc] initWithInformation:information];
+ }
+
+ return self;
+}
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
++ (ZXAbstractExpandedDecoder *)createDecoder:(ZXBitArray *)information {
+ if ([information get:1]) {
+ return [[ZXAI01AndOtherAIs alloc] initWithInformation:information];
+ }
+ if (![information get:2]) {
+ return [[ZXAnyAIDecoder alloc] initWithInformation:information];
+ }
+
+ int fourBitEncodationMethod = [ZXGeneralAppIdDecoder extractNumericValueFromBitArray:information pos:1 bits:4];
+
+ switch (fourBitEncodationMethod) {
+ case 4:
+ return [[ZXAI013103decoder alloc] initWithInformation:information];
+ case 5:
+ return [[ZXAI01320xDecoder alloc] initWithInformation:information];
+ }
+
+ int fiveBitEncodationMethod = [ZXGeneralAppIdDecoder extractNumericValueFromBitArray:information pos:1 bits:5];
+ switch (fiveBitEncodationMethod) {
+ case 12:
+ return [[ZXAI01392xDecoder alloc] initWithInformation:information];
+ case 13:
+ return [[ZXAI01393xDecoder alloc] initWithInformation:information];
+ }
+
+ int sevenBitEncodationMethod = [ZXGeneralAppIdDecoder extractNumericValueFromBitArray:information pos:1 bits:7];
+ switch (sevenBitEncodationMethod) {
+ case 56:
+ return [[ZXAI013x0x1xDecoder alloc] initWithInformation:information firstAIdigits:@"310" dateCode:@"11"];
+ case 57:
+ return [[ZXAI013x0x1xDecoder alloc] initWithInformation:information firstAIdigits:@"320" dateCode:@"11"];
+ case 58:
+ return [[ZXAI013x0x1xDecoder alloc] initWithInformation:information firstAIdigits:@"310" dateCode:@"13"];
+ case 59:
+ return [[ZXAI013x0x1xDecoder alloc] initWithInformation:information firstAIdigits:@"320" dateCode:@"13"];
+ case 60:
+ return [[ZXAI013x0x1xDecoder alloc] initWithInformation:information firstAIdigits:@"310" dateCode:@"15"];
+ case 61:
+ return [[ZXAI013x0x1xDecoder alloc] initWithInformation:information firstAIdigits:@"320" dateCode:@"15"];
+ case 62:
+ return [[ZXAI013x0x1xDecoder alloc] initWithInformation:information firstAIdigits:@"310" dateCode:@"17"];
+ case 63:
+ return [[ZXAI013x0x1xDecoder alloc] initWithInformation:information firstAIdigits:@"320" dateCode:@"17"];
+ }
+
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"unknown decoder: %@", information]
+ userInfo:nil];
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.h
new file mode 100644
index 0000000..3dfda95
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.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 "ZXAbstractExpandedDecoder.h"
+
+@interface ZXAnyAIDecoder : ZXAbstractExpandedDecoder
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.m
new file mode 100644
index 0000000..0928330
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.m
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXAnyAIDecoder.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+int const ANY_AI_HEADER_SIZE = 2 + 1 + 2;
+
+@implementation ZXAnyAIDecoder
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ NSMutableString *buf = [NSMutableString string];
+ return [self.generalDecoder decodeAllCodes:buf initialPosition:ANY_AI_HEADER_SIZE error:error];
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXBlockParsedResult.h b/ZXingObjC/oned/rss/expanded/decoders/ZXBlockParsedResult.h
new file mode 100644
index 0000000..8549a01
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXBlockParsedResult.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+@class ZXDecodedInformation;
+
+@interface ZXBlockParsedResult : NSObject
+
+@property (nonatomic, strong, readonly) ZXDecodedInformation *decodedInformation;
+@property (nonatomic, assign, readonly) BOOL finished;
+
+- (id)initWithFinished:(BOOL)finished;
+- (id)initWithInformation:(ZXDecodedInformation *)information finished:(BOOL)finished;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXBlockParsedResult.m b/ZXingObjC/oned/rss/expanded/decoders/ZXBlockParsedResult.m
new file mode 100644
index 0000000..f1d3867
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXBlockParsedResult.m
@@ -0,0 +1,35 @@
+/*
+ * 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 "ZXBlockParsedResult.h"
+#import "ZXDecodedInformation.h"
+
+@implementation ZXBlockParsedResult
+
+- (id)initWithFinished:(BOOL)finished {
+ return [self initWithInformation:nil finished:finished];
+}
+
+- (id)initWithInformation:(ZXDecodedInformation *)information finished:(BOOL)finished {
+ if (self = [super init]) {
+ _decodedInformation = information;
+ _finished = finished;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXCurrentParsingState.h b/ZXingObjC/oned/rss/expanded/decoders/ZXCurrentParsingState.h
new file mode 100644
index 0000000..6a20935
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXCurrentParsingState.h
@@ -0,0 +1,28 @@
+/*
+ * 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 ZXCurrentParsingState : NSObject
+
+@property (nonatomic, assign) int position;
+
+- (BOOL)alpha;
+- (BOOL)numeric;
+- (BOOL)isoIec646;
+- (void)setNumeric;
+- (void)setAlpha;
+- (void)setIsoIec646;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXCurrentParsingState.m b/ZXingObjC/oned/rss/expanded/decoders/ZXCurrentParsingState.m
new file mode 100644
index 0000000..b8f4c69
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXCurrentParsingState.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 "ZXCurrentParsingState.h"
+
+enum {
+ NUMERIC_STATE,
+ ALPHA_STATE,
+ ISO_IEC_646_STATE
+};
+
+@interface ZXCurrentParsingState ()
+
+@property (nonatomic, assign) int encoding;
+
+@end
+
+@implementation ZXCurrentParsingState
+
+- (id)init {
+ if (self = [super init]) {
+ _position = 0;
+ _encoding = NUMERIC_STATE;
+ }
+ return self;
+}
+
+- (BOOL)alpha {
+ return self.encoding == ALPHA_STATE;
+}
+
+- (BOOL)numeric {
+ return self.encoding == NUMERIC_STATE;
+}
+
+- (BOOL)isoIec646 {
+ return self.encoding == ISO_IEC_646_STATE;
+}
+
+- (void)setNumeric {
+ self.encoding = NUMERIC_STATE;
+}
+
+- (void)setAlpha {
+ self.encoding = ALPHA_STATE;
+}
+
+- (void)setIsoIec646 {
+ self.encoding = ISO_IEC_646_STATE;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedChar.h b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedChar.h
new file mode 100644
index 0000000..f589413
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedChar.h
@@ -0,0 +1,28 @@
+/*
+ * 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 "ZXDecodedObject.h"
+
+extern unichar const FNC1char;
+
+@interface ZXDecodedChar : ZXDecodedObject
+
+@property (nonatomic, assign, readonly) unichar value;
+
+- (id)initWithNewPosition:(int)newPosition value:(unichar)value;
+- (BOOL)fnc1;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedChar.m b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedChar.m
new file mode 100644
index 0000000..472d009
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedChar.m
@@ -0,0 +1,35 @@
+/*
+ * 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 "ZXDecodedChar.h"
+
+unichar const FNC1char = '$';
+
+@implementation ZXDecodedChar
+
+- (id)initWithNewPosition:(int)newPosition value:(unichar)value {
+ if (self = [super initWithNewPosition:newPosition]) {
+ _value = value;
+ }
+
+ return self;
+}
+
+- (BOOL)fnc1 {
+ return self.value == FNC1char;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedInformation.h b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedInformation.h
new file mode 100644
index 0000000..d0531a9
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedInformation.h
@@ -0,0 +1,28 @@
+/*
+ * 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 "ZXDecodedObject.h"
+
+@interface ZXDecodedInformation : ZXDecodedObject
+
+@property (nonatomic, copy, readonly) NSString *theNewString;
+@property (nonatomic, assign, readonly) int remainingValue;
+@property (nonatomic, assign, readonly) BOOL remaining;
+
+- (id)initWithNewPosition:(int)newPosition newString:(NSString *)newString;
+- (id)initWithNewPosition:(int)newPosition newString:(NSString *)newString remainingValue:(int)remainingValue;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedInformation.m b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedInformation.m
new file mode 100644
index 0000000..c302c02
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedInformation.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 "ZXDecodedInformation.h"
+
+@implementation ZXDecodedInformation
+
+- (id)initWithNewPosition:(int)newPosition newString:(NSString *)newString {
+ if (self = [super initWithNewPosition:newPosition]) {
+ _remaining = NO;
+ _remainingValue = 0;
+ _theNewString = newString;
+ }
+
+ return self;
+}
+
+- (id)initWithNewPosition:(int)newPosition newString:(NSString *)newString remainingValue:(int)remainingValue {
+ if (self = [super initWithNewPosition:newPosition]) {
+ _remaining = YES;
+ _remainingValue = remainingValue;
+ _theNewString = newString;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedNumeric.h b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedNumeric.h
new file mode 100644
index 0000000..1583f4f
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedNumeric.h
@@ -0,0 +1,32 @@
+/*
+ * 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 "ZXDecodedObject.h"
+
+extern const int FNC1;
+
+@interface ZXDecodedNumeric : ZXDecodedObject
+
+@property (nonatomic, assign, readonly) int firstDigit;
+@property (nonatomic, assign, readonly) int secondDigit;
+@property (nonatomic, assign, readonly) int value;
+
+- (id)initWithNewPosition:(int)newPosition firstDigit:(int)firstDigit secondDigit:(int)secondDigit;
+- (BOOL)firstDigitFNC1;
+- (BOOL)secondDigitFNC1;
+- (BOOL)anyFNC1;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedNumeric.m b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedNumeric.m
new file mode 100644
index 0000000..cda9f93
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedNumeric.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 "ZXDecodedNumeric.h"
+
+const int FNC1 = 10;
+
+@implementation ZXDecodedNumeric
+
+- (id)initWithNewPosition:(int)newPosition firstDigit:(int)aFirstDigit secondDigit:(int)aSecondDigit {
+ if (self = [super initWithNewPosition:newPosition]) {
+ _firstDigit = aFirstDigit;
+ _secondDigit = aSecondDigit;
+
+ if (_firstDigit < 0 || _firstDigit > 10) {
+ [NSException raise:NSInvalidArgumentException format:@"Invalid firstDigit: %d", _firstDigit];
+ }
+
+ if (_secondDigit < 0 || _secondDigit > 10) {
+ [NSException raise:NSInvalidArgumentException format:@"Invalid secondDigit: %d", _secondDigit];
+ }
+ }
+
+ return self;
+}
+
+- (int)value {
+ return self.firstDigit * 10 + self.secondDigit;
+}
+
+- (BOOL)firstDigitFNC1 {
+ return self.firstDigit == FNC1;
+}
+
+- (BOOL)secondDigitFNC1 {
+ return self.secondDigit == FNC1;
+}
+
+- (BOOL)anyFNC1 {
+ return self.firstDigit == FNC1 || self.secondDigit == FNC1;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedObject.h b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedObject.h
new file mode 100644
index 0000000..fe68270
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedObject.h
@@ -0,0 +1,23 @@
+/*
+ * 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 ZXDecodedObject : NSObject
+
+@property (nonatomic, assign, readonly) int theNewPosition;
+
+- (id)initWithNewPosition:(int)newPosition;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedObject.m b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedObject.m
new file mode 100644
index 0000000..eabbf2f
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXDecodedObject.m
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXDecodedObject.h"
+
+@implementation ZXDecodedObject
+
+- (id)initWithNewPosition:(int)newPosition {
+ if (self = [super init]) {
+ _theNewPosition = newPosition;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXFieldParser.h b/ZXingObjC/oned/rss/expanded/decoders/ZXFieldParser.h
new file mode 100644
index 0000000..1ab9168
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXFieldParser.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.
+ */
+
+@interface ZXFieldParser : NSObject
+
++ (NSString *)parseFieldsInGeneralPurpose:(NSString *)rawInformation error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXFieldParser.m b/ZXingObjC/oned/rss/expanded/decoders/ZXFieldParser.m
new file mode 100644
index 0000000..e1377b6
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXFieldParser.m
@@ -0,0 +1,317 @@
+/*
+ * 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 "ZXErrors.h"
+#import "ZXFieldParser.h"
+
+static NSObject *VARIABLE_LENGTH = nil;
+static NSArray *TWO_DIGIT_DATA_LENGTH = nil;
+static NSArray *THREE_DIGIT_DATA_LENGTH = nil;
+static NSArray *THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH = nil;
+static NSArray *FOUR_DIGIT_DATA_LENGTH = nil;
+
+@implementation ZXFieldParser
+
++ (void)initialize {
+ if (VARIABLE_LENGTH == nil) {
+ VARIABLE_LENGTH = [[NSObject alloc] init];
+ }
+
+ if (TWO_DIGIT_DATA_LENGTH == nil) {
+ TWO_DIGIT_DATA_LENGTH = @[@[@"00", @18],
+ @[@"01", @14],
+ @[@"02", @14],
+
+ @[@"10", VARIABLE_LENGTH, @20],
+ @[@"11", @6],
+ @[@"12", @6],
+ @[@"13", @6],
+ @[@"15", @6],
+ @[@"17", @6],
+
+ @[@"20", @2],
+ @[@"21", VARIABLE_LENGTH, @20],
+ @[@"22", VARIABLE_LENGTH, @29],
+
+ @[@"30", VARIABLE_LENGTH, @8],
+ @[@"37", VARIABLE_LENGTH, @8],
+
+ //internal company codes
+ @[@"90", VARIABLE_LENGTH, @30],
+ @[@"91", VARIABLE_LENGTH, @30],
+ @[@"92", VARIABLE_LENGTH, @30],
+ @[@"93", VARIABLE_LENGTH, @30],
+ @[@"94", VARIABLE_LENGTH, @30],
+ @[@"95", VARIABLE_LENGTH, @30],
+ @[@"96", VARIABLE_LENGTH, @30],
+ @[@"97", VARIABLE_LENGTH, @30],
+ @[@"98", VARIABLE_LENGTH, @30],
+ @[@"99", VARIABLE_LENGTH, @30]];
+ }
+
+ if (THREE_DIGIT_DATA_LENGTH == nil) {
+ THREE_DIGIT_DATA_LENGTH = @[@[@"240", VARIABLE_LENGTH, @30],
+ @[@"241", VARIABLE_LENGTH, @30],
+ @[@"242", VARIABLE_LENGTH, @6],
+ @[@"250", VARIABLE_LENGTH, @30],
+ @[@"251", VARIABLE_LENGTH, @30],
+ @[@"253", VARIABLE_LENGTH, @17],
+ @[@"254", VARIABLE_LENGTH, @20],
+
+ @[@"400", VARIABLE_LENGTH, @30],
+ @[@"401", VARIABLE_LENGTH, @30],
+ @[@"402", @17],
+ @[@"403", VARIABLE_LENGTH, @30],
+ @[@"410", @13],
+ @[@"411", @13],
+ @[@"412", @13],
+ @[@"413", @13],
+ @[@"414", @13],
+ @[@"420", VARIABLE_LENGTH, @20],
+ @[@"421", VARIABLE_LENGTH, @15],
+ @[@"422", @3],
+ @[@"423", VARIABLE_LENGTH, @15],
+ @[@"424", @3],
+ @[@"425", @3],
+ @[@"426", @3]];
+
+ }
+
+ if (THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH == nil) {
+ THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH = @[@[@"310", @6],
+ @[@"311", @6],
+ @[@"312", @6],
+ @[@"313", @6],
+ @[@"314", @6],
+ @[@"315", @6],
+ @[@"316", @6],
+ @[@"320", @6],
+ @[@"321", @6],
+ @[@"322", @6],
+ @[@"323", @6],
+ @[@"324", @6],
+ @[@"325", @6],
+ @[@"326", @6],
+ @[@"327", @6],
+ @[@"328", @6],
+ @[@"329", @6],
+ @[@"330", @6],
+ @[@"331", @6],
+ @[@"332", @6],
+ @[@"333", @6],
+ @[@"334", @6],
+ @[@"335", @6],
+ @[@"336", @6],
+ @[@"340", @6],
+ @[@"341", @6],
+ @[@"342", @6],
+ @[@"343", @6],
+ @[@"344", @6],
+ @[@"345", @6],
+ @[@"346", @6],
+ @[@"347", @6],
+ @[@"348", @6],
+ @[@"349", @6],
+ @[@"350", @6],
+ @[@"351", @6],
+ @[@"352", @6],
+ @[@"353", @6],
+ @[@"354", @6],
+ @[@"355", @6],
+ @[@"356", @6],
+ @[@"357", @6],
+ @[@"360", @6],
+ @[@"361", @6],
+ @[@"362", @6],
+ @[@"363", @6],
+ @[@"364", @6],
+ @[@"365", @6],
+ @[@"366", @6],
+ @[@"367", @6],
+ @[@"368", @6],
+ @[@"369", @6],
+ @[@"390", VARIABLE_LENGTH, @15],
+ @[@"391", VARIABLE_LENGTH, @18],
+ @[@"392", VARIABLE_LENGTH, @15],
+ @[@"393", VARIABLE_LENGTH, @18],
+ @[@"703", VARIABLE_LENGTH, @30]];
+ }
+
+ if (FOUR_DIGIT_DATA_LENGTH == nil) {
+ FOUR_DIGIT_DATA_LENGTH = @[@[@"7001", @13],
+ @[@"7002", VARIABLE_LENGTH, @30],
+ @[@"7003", @10],
+
+ @[@"8001", @14],
+ @[@"8002", VARIABLE_LENGTH, @20],
+ @[@"8003", VARIABLE_LENGTH, @30],
+ @[@"8004", VARIABLE_LENGTH, @30],
+ @[@"8005", @6],
+ @[@"8006", @18],
+ @[@"8007", VARIABLE_LENGTH, @30],
+ @[@"8008", VARIABLE_LENGTH, @12],
+ @[@"8018", @18],
+ @[@"8020", VARIABLE_LENGTH, @25],
+ @[@"8100", @6],
+ @[@"8101", @10],
+ @[@"8102", @2],
+ @[@"8110", VARIABLE_LENGTH, @70],
+ @[@"8200", VARIABLE_LENGTH, @70]];
+ }
+}
+
++ (NSString *)parseFieldsInGeneralPurpose:(NSString *)rawInformation error:(NSError **)error {
+ if ([rawInformation length] == 0) {
+ return @"";
+ }
+ if ([rawInformation length] < 2) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ NSString *firstTwoDigits = [rawInformation substringWithRange:NSMakeRange(0, 2)];
+
+ for (int i = 0; i < [TWO_DIGIT_DATA_LENGTH count]; ++i) {
+ if ([TWO_DIGIT_DATA_LENGTH[i][0] isEqualToString:firstTwoDigits]) {
+ if ([TWO_DIGIT_DATA_LENGTH[i][1] isEqual:VARIABLE_LENGTH]) {
+ return [self processVariableAI:2
+ variableFieldSize:[TWO_DIGIT_DATA_LENGTH[i][2] intValue]
+ rawInformation:rawInformation];
+ }
+ NSString *result = [self processFixedAI:2
+ fieldSize:[TWO_DIGIT_DATA_LENGTH[i][1] intValue]
+ rawInformation:rawInformation];
+ if (!result) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ return result;
+ }
+ }
+
+ if ([rawInformation length] < 3) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ NSString *firstThreeDigits = [rawInformation substringWithRange:NSMakeRange(0, 3)];
+
+ for (int i = 0; i < [THREE_DIGIT_DATA_LENGTH count]; ++i) {
+ if ([THREE_DIGIT_DATA_LENGTH[i][0] isEqualToString:firstThreeDigits]) {
+ if ([THREE_DIGIT_DATA_LENGTH[i][1] isEqual:VARIABLE_LENGTH]) {
+ return [self processVariableAI:3
+ variableFieldSize:[THREE_DIGIT_DATA_LENGTH[i][2] intValue]
+ rawInformation:rawInformation];
+ }
+ NSString *result = [self processFixedAI:3
+ fieldSize:[THREE_DIGIT_DATA_LENGTH[i][1] intValue]
+ rawInformation:rawInformation];
+ if (!result) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ return result;
+ }
+ }
+
+ for (int i = 0; i < [THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH count]; ++i) {
+ if ([THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][0] isEqualToString:firstThreeDigits]) {
+ if ([THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][1] isEqual:VARIABLE_LENGTH]) {
+ return [self processVariableAI:4
+ variableFieldSize:[THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][2] intValue]
+ rawInformation:rawInformation];
+ }
+ NSString *result = [self processFixedAI:4
+ fieldSize:[THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH[i][1] intValue]
+ rawInformation:rawInformation];
+ if (!result) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ return result;
+ }
+ }
+
+ if ([rawInformation length] < 4) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ NSString *firstFourDigits = [rawInformation substringWithRange:NSMakeRange(0, 4)];
+
+ for (int i = 0; i < [FOUR_DIGIT_DATA_LENGTH count]; ++i) {
+ if ([FOUR_DIGIT_DATA_LENGTH[i][0] isEqualToString:firstFourDigits]) {
+ if ([FOUR_DIGIT_DATA_LENGTH[i][1] isEqual:VARIABLE_LENGTH]) {
+ NSString *result = [self processVariableAI:4
+ variableFieldSize:[FOUR_DIGIT_DATA_LENGTH[i][2] intValue]
+ rawInformation:rawInformation];
+ if (!result) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ return result;
+ }
+ NSString *result = [self processFixedAI:4
+ fieldSize:[FOUR_DIGIT_DATA_LENGTH[i][1] intValue]
+ rawInformation:rawInformation];
+ if (!result) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ return result;
+ }
+ }
+
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+}
+
++ (NSString *)processFixedAI:(int)aiSize fieldSize:(int)fieldSize rawInformation:(NSString *)rawInformation {
+ if ([rawInformation length] < aiSize) {
+ return nil;
+ }
+
+ NSString *ai = [rawInformation substringWithRange:NSMakeRange(0, aiSize)];
+ if ([rawInformation length] < aiSize + fieldSize) {
+ return nil;
+ }
+
+ NSString *field = [rawInformation substringWithRange:NSMakeRange(aiSize, fieldSize)];
+ NSString *remaining;
+ if (aiSize + fieldSize == rawInformation.length) {
+ remaining = @"";
+ } else {
+ remaining = [rawInformation substringFromIndex:aiSize + fieldSize];
+ }
+
+ NSString *result = [NSString stringWithFormat:@"(%@)%@", ai, field];
+ NSString *parsedAI = [self parseFieldsInGeneralPurpose:remaining error:nil];
+ return parsedAI == nil ? result : [result stringByAppendingString:parsedAI];
+}
+
++ (NSString *)processVariableAI:(int)aiSize variableFieldSize:(int)variableFieldSize rawInformation:(NSString *)rawInformation {
+ NSString *ai = [rawInformation substringWithRange:NSMakeRange(0, aiSize)];
+ int maxSize;
+ if ([rawInformation length] < aiSize + variableFieldSize) {
+ maxSize = (int)[rawInformation length];
+ } else {
+ maxSize = aiSize + variableFieldSize;
+ }
+ NSString *field = [rawInformation substringWithRange:NSMakeRange(aiSize, maxSize - aiSize)];
+ NSString *remaining = [rawInformation substringFromIndex:maxSize];
+ NSString *result = [NSString stringWithFormat:@"(%@)%@", ai, field];
+ NSString *parsedAI = [self parseFieldsInGeneralPurpose:remaining error:nil];
+ return parsedAI == nil ? result : [result stringByAppendingString:parsedAI];
+}
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXGeneralAppIdDecoder.h b/ZXingObjC/oned/rss/expanded/decoders/ZXGeneralAppIdDecoder.h
new file mode 100644
index 0000000..ae13a80
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXGeneralAppIdDecoder.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+@class ZXBitArray, ZXDecodedInformation;
+
+@interface ZXGeneralAppIdDecoder : NSObject
+
+- (id)initWithInformation:(ZXBitArray *)information;
+- (NSString *)decodeAllCodes:(NSMutableString *)buff initialPosition:(int)initialPosition error:(NSError **)error;
+- (int)extractNumericValueFromBitArray:(int)pos bits:(int)bits;
++ (int)extractNumericValueFromBitArray:(ZXBitArray *)information pos:(int)pos bits:(int)bits;
+- (ZXDecodedInformation *)decodeGeneralPurposeField:(int)pos remaining:(NSString *)remaining;
+
+@end
diff --git a/ZXingObjC/oned/rss/expanded/decoders/ZXGeneralAppIdDecoder.m b/ZXingObjC/oned/rss/expanded/decoders/ZXGeneralAppIdDecoder.m
new file mode 100644
index 0000000..c2cff1c
--- /dev/null
+++ b/ZXingObjC/oned/rss/expanded/decoders/ZXGeneralAppIdDecoder.m
@@ -0,0 +1,489 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXBlockParsedResult.h"
+#import "ZXCurrentParsingState.h"
+#import "ZXDecodedChar.h"
+#import "ZXDecodedInformation.h"
+#import "ZXDecodedNumeric.h"
+#import "ZXFieldParser.h"
+#import "ZXGeneralAppIdDecoder.h"
+
+@interface ZXGeneralAppIdDecoder ()
+
+@property (nonatomic, strong) ZXBitArray *information;
+@property (nonatomic, strong) ZXCurrentParsingState *current;
+@property (nonatomic, strong) NSMutableString *buffer;
+
+@end
+
+@implementation ZXGeneralAppIdDecoder
+
+- (id)initWithInformation:(ZXBitArray *)information {
+ if (self = [super init]) {
+ _current = [[ZXCurrentParsingState alloc] init];
+ _buffer = [NSMutableString string];
+ _information = information;
+ }
+
+ return self;
+}
+
+- (NSString *)decodeAllCodes:(NSMutableString *)buff initialPosition:(int)initialPosition error:(NSError **)error {
+ int currentPosition = initialPosition;
+ NSString *remaining = nil;
+ do {
+ ZXDecodedInformation *info = [self decodeGeneralPurposeField:currentPosition remaining:remaining];
+ NSString *parsedFields = [ZXFieldParser parseFieldsInGeneralPurpose:[info theNewString] error:error];
+ if (!parsedFields) {
+ return nil;
+ } else if (parsedFields.length > 0) {
+ [buff appendString:parsedFields];
+ }
+
+ if ([info remaining]) {
+ remaining = [@([info remainingValue]) stringValue];
+ } else {
+ remaining = nil;
+ }
+
+ if (currentPosition == [info theNewPosition]) {
+ break;
+ }
+ currentPosition = [info theNewPosition];
+ } while (YES);
+
+ return buff;
+}
+
+- (BOOL)isStillNumeric:(int)pos {
+ if (pos + 7 > self.information.size) {
+ return pos + 4 <= self.information.size;
+ }
+
+ for (int i = pos; i < pos + 3; ++i) {
+ if ([self.information get:i]) {
+ return YES;
+ }
+ }
+
+ return [self.information get:pos + 3];
+}
+
+- (ZXDecodedNumeric *)decodeNumeric:(int)pos {
+ if (pos + 7 > self.information.size) {
+ int numeric = [self extractNumericValueFromBitArray:pos bits:4];
+ if (numeric == 0) {
+ return [[ZXDecodedNumeric alloc] initWithNewPosition:self.information.size
+ firstDigit:FNC1
+ secondDigit:FNC1];
+ }
+ return [[ZXDecodedNumeric alloc] initWithNewPosition:self.information.size
+ firstDigit:numeric - 1
+ secondDigit:FNC1];
+ }
+ int numeric = [self extractNumericValueFromBitArray:pos bits:7];
+
+ int digit1 = (numeric - 8) / 11;
+ int digit2 = (numeric - 8) % 11;
+
+ return [[ZXDecodedNumeric alloc] initWithNewPosition:pos + 7
+ firstDigit:digit1
+ secondDigit:digit2];
+}
+
+- (int)extractNumericValueFromBitArray:(int)pos bits:(int)bits {
+ return [ZXGeneralAppIdDecoder extractNumericValueFromBitArray:self.information pos:pos bits:bits];
+}
+
++ (int)extractNumericValueFromBitArray:(ZXBitArray *)information pos:(int)pos bits:(int)bits {
+ if (bits > 32) {
+ [NSException raise:NSInvalidArgumentException format:@"extractNumberValueFromBitArray can't handle more than 32 bits"];
+ }
+
+ int value = 0;
+ for (int i = 0; i < bits; ++i) {
+ if ([information get:pos + i]) {
+ value |= 1 << (bits - i - 1);
+ }
+ }
+
+ return value;
+}
+
+- (ZXDecodedInformation *)decodeGeneralPurposeField:(int)pos remaining:(NSString *)remaining {
+ [self.buffer setString:@""];
+
+ if (remaining != nil) {
+ [self.buffer appendString:remaining];
+ }
+
+ self.current.position = pos;
+
+ ZXDecodedInformation *lastDecoded = [self parseBlocks];
+ if (lastDecoded != nil && [lastDecoded remaining]) {
+ return [[ZXDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer
+ remainingValue:lastDecoded.remainingValue];
+ }
+ return [[ZXDecodedInformation alloc] initWithNewPosition:self.current.position newString:self.buffer];
+}
+
+- (ZXDecodedInformation *)parseBlocks {
+ BOOL isFinished;
+ ZXBlockParsedResult *result;
+ do {
+ int initialPosition = self.current.position;
+
+ if (self.current.alpha) {
+ result = [self parseAlphaBlock];
+ isFinished = result.finished;
+ } else if (self.current.isoIec646) {
+ result = [self parseIsoIec646Block];
+ isFinished = result.finished;
+ } else {
+ result = [self parseNumericBlock];
+ isFinished = result.finished;
+ }
+
+ BOOL positionChanged = initialPosition != self.current.position;
+ if (!positionChanged && !isFinished) {
+ break;
+ }
+ } while (!isFinished);
+ return result.decodedInformation;
+}
+
+- (ZXBlockParsedResult *)parseNumericBlock {
+ while ([self isStillNumeric:self.current.position]) {
+ ZXDecodedNumeric *numeric = [self decodeNumeric:self.current.position];
+ self.current.position = numeric.theNewPosition;
+
+ if ([numeric firstDigitFNC1]) {
+ ZXDecodedInformation *information;
+ if ([numeric secondDigitFNC1]) {
+ information = [[ZXDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer];
+ } else {
+ information = [[ZXDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer
+ remainingValue:numeric.secondDigit];
+ }
+ return [[ZXBlockParsedResult alloc] initWithInformation:information finished:YES];
+ }
+ [self.buffer appendFormat:@"%d", numeric.firstDigit];
+
+ if (numeric.secondDigitFNC1) {
+ ZXDecodedInformation *information = [[ZXDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer];
+ return [[ZXBlockParsedResult alloc] initWithInformation:information finished:YES];
+ }
+ [self.buffer appendFormat:@"%d", numeric.secondDigit];
+ }
+
+ if ([self isNumericToAlphaNumericLatch:self.current.position]) {
+ [self.current setAlpha];
+ self.current.position += 4;
+ }
+ return [[ZXBlockParsedResult alloc] initWithFinished:NO];
+}
+
+- (ZXBlockParsedResult *)parseIsoIec646Block {
+ while ([self isStillIsoIec646:self.current.position]) {
+ ZXDecodedChar *iso = [self decodeIsoIec646:self.current.position];
+ self.current.position = iso.theNewPosition;
+
+ if (iso.fnc1) {
+ ZXDecodedInformation *information = [[ZXDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer];
+ return [[ZXBlockParsedResult alloc] initWithInformation:information finished:YES];
+ }
+ [self.buffer appendFormat:@"%C", iso.value];
+ }
+
+ if ([self isAlphaOr646ToNumericLatch:self.current.position]) {
+ self.current.position += 3;
+ [self.current setNumeric];
+ } else if ([self isAlphaTo646ToAlphaLatch:self.current.position]) {
+ if (self.current.position + 5 < self.information.size) {
+ self.current.position += 5;
+ } else {
+ self.current.position = self.information.size;
+ }
+
+ [self.current setAlpha];
+ }
+ return [[ZXBlockParsedResult alloc] initWithFinished:NO];
+}
+
+- (ZXBlockParsedResult *)parseAlphaBlock {
+ while ([self isStillAlpha:self.current.position]) {
+ ZXDecodedChar *alpha = [self decodeAlphanumeric:self.current.position];
+ self.current.position = alpha.theNewPosition;
+
+ if (alpha.fnc1) {
+ ZXDecodedInformation *information = [[ZXDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer];
+ return [[ZXBlockParsedResult alloc] initWithInformation:information finished:YES];
+ }
+
+ [self.buffer appendFormat:@"%C", alpha.value];
+ }
+
+ if ([self isAlphaOr646ToNumericLatch:self.current.position]) {
+ self.current.position += 3;
+ [self.current setNumeric];
+ } else if ([self isAlphaTo646ToAlphaLatch:self.current.position]) {
+ if (self.current.position + 5 < self.information.size) {
+ self.current.position += 5;
+ } else {
+ self.current.position = self.information.size;
+ }
+
+ [self.current setIsoIec646];
+ }
+ return [[ZXBlockParsedResult alloc] initWithFinished:NO];
+}
+
+- (BOOL)isStillIsoIec646:(int)pos {
+ if (pos + 5 > self.information.size) {
+ return NO;
+ }
+
+ int fiveBitValue = [self extractNumericValueFromBitArray:pos bits:5];
+ if (fiveBitValue >= 5 && fiveBitValue < 16) {
+ return YES;
+ }
+
+ if (pos + 7 > self.information.size) {
+ return NO;
+ }
+
+ int sevenBitValue = [self extractNumericValueFromBitArray:pos bits:7];
+ if (sevenBitValue >= 64 && sevenBitValue < 116) {
+ return YES;
+ }
+
+ if (pos + 8 > self.information.size) {
+ return NO;
+ }
+
+ int eightBitValue = [self extractNumericValueFromBitArray:pos bits:8];
+ return eightBitValue >= 232 && eightBitValue < 253;
+}
+
+- (ZXDecodedChar *)decodeIsoIec646:(int)pos {
+ int fiveBitValue = [self extractNumericValueFromBitArray:pos bits:5];
+ if (fiveBitValue == 15) {
+ return [[ZXDecodedChar alloc] initWithNewPosition:pos + 5 value:FNC1char];
+ }
+
+ if (fiveBitValue >= 5 && fiveBitValue < 15) {
+ return [[ZXDecodedChar alloc] initWithNewPosition:pos + 5 value:(unichar)('0' + fiveBitValue - 5)];
+ }
+
+ int sevenBitValue = [self extractNumericValueFromBitArray:pos bits:7];
+
+ if (sevenBitValue >= 64 && sevenBitValue < 90) {
+ return [[ZXDecodedChar alloc] initWithNewPosition:pos + 7 value:(unichar)(sevenBitValue + 1)];
+ }
+
+ if (sevenBitValue >= 90 && sevenBitValue < 116) {
+ return [[ZXDecodedChar alloc] initWithNewPosition:pos + 7 value:(unichar)(sevenBitValue + 7)];
+ }
+
+ int eightBitValue = [self extractNumericValueFromBitArray:pos bits:8];
+ unichar c;
+ switch (eightBitValue) {
+ case 232:
+ c = '!';
+ break;
+ case 233:
+ c = '"';
+ break;
+ case 234:
+ c ='%';
+ break;
+ case 235:
+ c = '&';
+ break;
+ case 236:
+ c = '\'';
+ break;
+ case 237:
+ c = '(';
+ break;
+ case 238:
+ c = ')';
+ break;
+ case 239:
+ c = '*';
+ break;
+ case 240:
+ c = '+';
+ break;
+ case 241:
+ c = ',';
+ break;
+ case 242:
+ c = '-';
+ break;
+ case 243:
+ c = '.';
+ break;
+ case 244:
+ c = '/';
+ break;
+ case 245:
+ c = ':';
+ break;
+ case 246:
+ c = ';';
+ break;
+ case 247:
+ c = '<';
+ break;
+ case 248:
+ c = '=';
+ break;
+ case 249:
+ c = '>';
+ break;
+ case 250:
+ c = '?';
+ break;
+ case 251:
+ c = '_';
+ break;
+ case 252:
+ c = ' ';
+ break;
+ default:
+ @throw [NSException exceptionWithName:@"RuntimeException"
+ reason:[NSString stringWithFormat:@"Decoding invalid ISO/IEC 646 value: %d", eightBitValue]
+ userInfo:nil];
+ }
+ return [[ZXDecodedChar alloc] initWithNewPosition:pos + 8 value:c];
+}
+
+- (BOOL)isStillAlpha:(int)pos {
+ if (pos + 5 > self.information.size) {
+ return NO;
+ }
+
+ int fiveBitValue = [self extractNumericValueFromBitArray:pos bits:5];
+ if (fiveBitValue >= 5 && fiveBitValue < 16) {
+ return YES;
+ }
+
+ if (pos + 6 > self.information.size) {
+ return NO;
+ }
+
+ int sixBitValue = [self extractNumericValueFromBitArray:pos bits:6];
+ return sixBitValue >= 16 && sixBitValue < 63;
+}
+
+- (ZXDecodedChar *)decodeAlphanumeric:(int)pos {
+ int fiveBitValue = [self extractNumericValueFromBitArray:pos bits:5];
+ if (fiveBitValue == 15) {
+ return [[ZXDecodedChar alloc] initWithNewPosition:pos + 5 value:FNC1char];
+ }
+
+ if (fiveBitValue >= 5 && fiveBitValue < 15) {
+ return [[ZXDecodedChar alloc] initWithNewPosition:pos + 5 value:(unichar)('0' + fiveBitValue - 5)];
+ }
+
+ int sixBitValue = [self extractNumericValueFromBitArray:pos bits:6];
+
+ if (sixBitValue >= 32 && sixBitValue < 58) {
+ return [[ZXDecodedChar alloc] initWithNewPosition:pos + 6 value:(unichar)(sixBitValue + 33)];
+ }
+
+ unichar c;
+ switch (sixBitValue){
+ case 58:
+ c = '*';
+ break;
+ case 59:
+ c = ',';
+ break;
+ case 60:
+ c = '-';
+ break;
+ case 61:
+ c = '.';
+ break;
+ case 62:
+ c = '/';
+ break;
+ default:
+ @throw [NSException exceptionWithName:@"RuntimeException"
+ reason:[NSString stringWithFormat:@"Decoding invalid alphanumeric value: %d", sixBitValue]
+ userInfo:nil];
+ }
+
+ return [[ZXDecodedChar alloc] initWithNewPosition:pos + 6 value:c];
+}
+
+- (BOOL)isAlphaTo646ToAlphaLatch:(int)pos {
+ if (pos + 1 > self.information.size) {
+ return NO;
+ }
+
+ for (int i = 0; i < 5 && i + pos < self.information.size; ++i) {
+ if (i == 2) {
+ if (![self.information get:pos + 2]) {
+ return NO;
+ }
+ } else if ([self.information get:pos + i]) {
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+- (BOOL)isAlphaOr646ToNumericLatch:(int)pos {
+ if (pos + 3 > self.information.size) {
+ return NO;
+ }
+
+ for (int i = pos; i < pos + 3; ++i) {
+ if ([self.information get:i]) {
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+- (BOOL)isNumericToAlphaNumericLatch:(int)pos {
+ if (pos + 1 > self.information.size) {
+ return NO;
+ }
+
+ for (int i = 0; i < 4 && i + pos < self.information.size; ++i) {
+ if ([self.information get:pos + i]) {
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/ZXPDF417Common.h b/ZXingObjC/pdf417/ZXPDF417Common.h
new file mode 100644
index 0000000..229cf18
--- /dev/null
+++ b/ZXingObjC/pdf417/ZXPDF417Common.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#define ZXPDF417_SYMBOL_TABLE_LEN 2787
+extern int ZXPDF417_SYMBOL_TABLE[ZXPDF417_SYMBOL_TABLE_LEN];
+
+#define ZXPDF417_CODEWORD_TABLE_LEN 2787
+extern int ZXPDF417_CODEWORD_TABLE[ZXPDF417_CODEWORD_TABLE_LEN];
+
+extern int const ZXPDF417_NUMBER_OF_CODEWORDS;
+extern int const ZXPDF417_MIN_ROWS_IN_BARCODE;
+extern int const ZXPDF417_MAX_ROWS_IN_BARCODE;
+extern int const ZXPDF417_MAX_CODEWORDS_IN_BARCODE;
+extern int const ZXPDF417_MODULES_IN_CODEWORD;
+extern int const ZXPDF417_MODULES_IN_STOP_PATTERN;
+#define ZXPDF417_BARS_IN_MODULE 8
+
+@interface ZXPDF417Common : NSObject
+
++ (int)bitCountSum:(NSArray *)moduleBitCount;
++ (int)codeword:(long)symbol;
+
+@end
diff --git a/ZXingObjC/pdf417/ZXPDF417Common.m b/ZXingObjC/pdf417/ZXPDF417Common.m
new file mode 100644
index 0000000..40f7c6a
--- /dev/null
+++ b/ZXingObjC/pdf417/ZXPDF417Common.m
@@ -0,0 +1,457 @@
+/*
+ * 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 "ZXPDF417.h"
+#import "ZXPDF417Common.h"
+
+int const ZXPDF417_NUMBER_OF_CODEWORDS = 929;
+// Maximum Codewords (Data + Error).
+int const ZXPDF417_MAX_CODEWORDS_IN_BARCODE = ZXPDF417_NUMBER_OF_CODEWORDS - 1;
+int const ZXPDF417_MIN_ROWS_IN_BARCODE = 3;
+int const ZXPDF417_MAX_ROWS_IN_BARCODE = 90;
+// One left row indication column + max 30 data columns + one right row indicator column
+int const ZXPDF417_MAX_CODEWORDS_IN_ROW = 32;
+int const ZXPDF417_MODULES_IN_CODEWORD = 17;
+int const ZXPDF417_MODULES_IN_STOP_PATTERN = 18;
+
+@implementation ZXPDF417Common
+
++ (int)bitCountSum:(NSArray *)moduleBitCount {
+ int bitCountSum = 0;
+ for (NSNumber *count in moduleBitCount) {
+ bitCountSum += [count intValue];
+ }
+ return bitCountSum;
+}
+
+/**
+ * Translate the symbol into a codeword.
+ */
++ (int)codeword:(long)symbol {
+ long sym = symbol & 0x3FFFF;
+ int i = [self findCodewordIndex:sym];
+ if (i == -1) {
+ return -1;
+ }
+ return (ZXPDF417_CODEWORD_TABLE[i] - 1) % ZXPDF417_NUMBER_OF_CODEWORDS;
+}
+
+/**
+ * Use a binary search to find the index of the codeword corresponding to
+ * this symbol.
+ */
++ (int)findCodewordIndex:(long)symbol {
+ int first = 0;
+ int upto = ZXPDF417_SYMBOL_TABLE_LEN;
+ while (first < upto) {
+ int mid = (first + upto) >> 1; // Compute mid point.
+ if (symbol < ZXPDF417_SYMBOL_TABLE[mid]) {
+ upto = mid; // continue search in bottom half.
+ } else if (symbol > ZXPDF417_SYMBOL_TABLE[mid]) {
+ first = mid + 1; // continue search in top half.
+ } else {
+ return mid; // Found it. return position
+ }
+ }
+ return -1;
+}
+
+@end
+
+/**
+ * The sorted table of all possible symbols. Extracted from the PDF417
+ * specification. The index of a symbol in this table corresponds to the
+ * index into the codeword table.
+ */
+int ZXPDF417_SYMBOL_TABLE[ZXPDF417_SYMBOL_TABLE_LEN] = {
+ 0x1025e, 0x1027a, 0x1029e, 0x102bc, 0x102f2, 0x102f4, 0x1032e, 0x1034e, 0x1035c, 0x10396, 0x103a6, 0x103ac,
+ 0x10422, 0x10428, 0x10436, 0x10442, 0x10444, 0x10448, 0x10450, 0x1045e, 0x10466, 0x1046c, 0x1047a, 0x10482,
+ 0x1049e, 0x104a0, 0x104bc, 0x104c6, 0x104d8, 0x104ee, 0x104f2, 0x104f4, 0x10504, 0x10508, 0x10510, 0x1051e,
+ 0x10520, 0x1053c, 0x10540, 0x10578, 0x10586, 0x1058c, 0x10598, 0x105b0, 0x105be, 0x105ce, 0x105dc, 0x105e2,
+ 0x105e4, 0x105e8, 0x105f6, 0x1062e, 0x1064e, 0x1065c, 0x1068e, 0x1069c, 0x106b8, 0x106de, 0x106fa, 0x10716,
+ 0x10726, 0x1072c, 0x10746, 0x1074c, 0x10758, 0x1076e, 0x10792, 0x10794, 0x107a2, 0x107a4, 0x107a8, 0x107b6,
+ 0x10822, 0x10828, 0x10842, 0x10848, 0x10850, 0x1085e, 0x10866, 0x1086c, 0x1087a, 0x10882, 0x10884, 0x10890,
+ 0x1089e, 0x108a0, 0x108bc, 0x108c6, 0x108cc, 0x108d8, 0x108ee, 0x108f2, 0x108f4, 0x10902, 0x10908, 0x1091e,
+ 0x10920, 0x1093c, 0x10940, 0x10978, 0x10986, 0x10998, 0x109b0, 0x109be, 0x109ce, 0x109dc, 0x109e2, 0x109e4,
+ 0x109e8, 0x109f6, 0x10a08, 0x10a10, 0x10a1e, 0x10a20, 0x10a3c, 0x10a40, 0x10a78, 0x10af0, 0x10b06, 0x10b0c,
+ 0x10b18, 0x10b30, 0x10b3e, 0x10b60, 0x10b7c, 0x10b8e, 0x10b9c, 0x10bb8, 0x10bc2, 0x10bc4, 0x10bc8, 0x10bd0,
+ 0x10bde, 0x10be6, 0x10bec, 0x10c2e, 0x10c4e, 0x10c5c, 0x10c62, 0x10c64, 0x10c68, 0x10c76, 0x10c8e, 0x10c9c,
+ 0x10cb8, 0x10cc2, 0x10cc4, 0x10cc8, 0x10cd0, 0x10cde, 0x10ce6, 0x10cec, 0x10cfa, 0x10d0e, 0x10d1c, 0x10d38,
+ 0x10d70, 0x10d7e, 0x10d82, 0x10d84, 0x10d88, 0x10d90, 0x10d9e, 0x10da0, 0x10dbc, 0x10dc6, 0x10dcc, 0x10dd8,
+ 0x10dee, 0x10df2, 0x10df4, 0x10e16, 0x10e26, 0x10e2c, 0x10e46, 0x10e58, 0x10e6e, 0x10e86, 0x10e8c, 0x10e98,
+ 0x10eb0, 0x10ebe, 0x10ece, 0x10edc, 0x10f0a, 0x10f12, 0x10f14, 0x10f22, 0x10f28, 0x10f36, 0x10f42, 0x10f44,
+ 0x10f48, 0x10f50, 0x10f5e, 0x10f66, 0x10f6c, 0x10fb2, 0x10fb4, 0x11022, 0x11028, 0x11042, 0x11048, 0x11050,
+ 0x1105e, 0x1107a, 0x11082, 0x11084, 0x11090, 0x1109e, 0x110a0, 0x110bc, 0x110c6, 0x110cc, 0x110d8, 0x110ee,
+ 0x110f2, 0x110f4, 0x11102, 0x1111e, 0x11120, 0x1113c, 0x11140, 0x11178, 0x11186, 0x11198, 0x111b0, 0x111be,
+ 0x111ce, 0x111dc, 0x111e2, 0x111e4, 0x111e8, 0x111f6, 0x11208, 0x1121e, 0x11220, 0x11278, 0x112f0, 0x1130c,
+ 0x11330, 0x1133e, 0x11360, 0x1137c, 0x1138e, 0x1139c, 0x113b8, 0x113c2, 0x113c8, 0x113d0, 0x113de, 0x113e6,
+ 0x113ec, 0x11408, 0x11410, 0x1141e, 0x11420, 0x1143c, 0x11440, 0x11478, 0x114f0, 0x115e0, 0x1160c, 0x11618,
+ 0x11630, 0x1163e, 0x11660, 0x1167c, 0x116c0, 0x116f8, 0x1171c, 0x11738, 0x11770, 0x1177e, 0x11782, 0x11784,
+ 0x11788, 0x11790, 0x1179e, 0x117a0, 0x117bc, 0x117c6, 0x117cc, 0x117d8, 0x117ee, 0x1182e, 0x11834, 0x1184e,
+ 0x1185c, 0x11862, 0x11864, 0x11868, 0x11876, 0x1188e, 0x1189c, 0x118b8, 0x118c2, 0x118c8, 0x118d0, 0x118de,
+ 0x118e6, 0x118ec, 0x118fa, 0x1190e, 0x1191c, 0x11938, 0x11970, 0x1197e, 0x11982, 0x11984, 0x11990, 0x1199e,
+ 0x119a0, 0x119bc, 0x119c6, 0x119cc, 0x119d8, 0x119ee, 0x119f2, 0x119f4, 0x11a0e, 0x11a1c, 0x11a38, 0x11a70,
+ 0x11a7e, 0x11ae0, 0x11afc, 0x11b08, 0x11b10, 0x11b1e, 0x11b20, 0x11b3c, 0x11b40, 0x11b78, 0x11b8c, 0x11b98,
+ 0x11bb0, 0x11bbe, 0x11bce, 0x11bdc, 0x11be2, 0x11be4, 0x11be8, 0x11bf6, 0x11c16, 0x11c26, 0x11c2c, 0x11c46,
+ 0x11c4c, 0x11c58, 0x11c6e, 0x11c86, 0x11c98, 0x11cb0, 0x11cbe, 0x11cce, 0x11cdc, 0x11ce2, 0x11ce4, 0x11ce8,
+ 0x11cf6, 0x11d06, 0x11d0c, 0x11d18, 0x11d30, 0x11d3e, 0x11d60, 0x11d7c, 0x11d8e, 0x11d9c, 0x11db8, 0x11dc4,
+ 0x11dc8, 0x11dd0, 0x11dde, 0x11de6, 0x11dec, 0x11dfa, 0x11e0a, 0x11e12, 0x11e14, 0x11e22, 0x11e24, 0x11e28,
+ 0x11e36, 0x11e42, 0x11e44, 0x11e50, 0x11e5e, 0x11e66, 0x11e6c, 0x11e82, 0x11e84, 0x11e88, 0x11e90, 0x11e9e,
+ 0x11ea0, 0x11ebc, 0x11ec6, 0x11ecc, 0x11ed8, 0x11eee, 0x11f1a, 0x11f2e, 0x11f32, 0x11f34, 0x11f4e, 0x11f5c,
+ 0x11f62, 0x11f64, 0x11f68, 0x11f76, 0x12048, 0x1205e, 0x12082, 0x12084, 0x12090, 0x1209e, 0x120a0, 0x120bc,
+ 0x120d8, 0x120f2, 0x120f4, 0x12108, 0x1211e, 0x12120, 0x1213c, 0x12140, 0x12178, 0x12186, 0x12198, 0x121b0,
+ 0x121be, 0x121e2, 0x121e4, 0x121e8, 0x121f6, 0x12204, 0x12210, 0x1221e, 0x12220, 0x12278, 0x122f0, 0x12306,
+ 0x1230c, 0x12330, 0x1233e, 0x12360, 0x1237c, 0x1238e, 0x1239c, 0x123b8, 0x123c2, 0x123c8, 0x123d0, 0x123e6,
+ 0x123ec, 0x1241e, 0x12420, 0x1243c, 0x124f0, 0x125e0, 0x12618, 0x1263e, 0x12660, 0x1267c, 0x126c0, 0x126f8,
+ 0x12738, 0x12770, 0x1277e, 0x12782, 0x12784, 0x12790, 0x1279e, 0x127a0, 0x127bc, 0x127c6, 0x127cc, 0x127d8,
+ 0x127ee, 0x12820, 0x1283c, 0x12840, 0x12878, 0x128f0, 0x129e0, 0x12bc0, 0x12c18, 0x12c30, 0x12c3e, 0x12c60,
+ 0x12c7c, 0x12cc0, 0x12cf8, 0x12df0, 0x12e1c, 0x12e38, 0x12e70, 0x12e7e, 0x12ee0, 0x12efc, 0x12f04, 0x12f08,
+ 0x12f10, 0x12f20, 0x12f3c, 0x12f40, 0x12f78, 0x12f86, 0x12f8c, 0x12f98, 0x12fb0, 0x12fbe, 0x12fce, 0x12fdc,
+ 0x1302e, 0x1304e, 0x1305c, 0x13062, 0x13068, 0x1308e, 0x1309c, 0x130b8, 0x130c2, 0x130c8, 0x130d0, 0x130de,
+ 0x130ec, 0x130fa, 0x1310e, 0x13138, 0x13170, 0x1317e, 0x13182, 0x13184, 0x13190, 0x1319e, 0x131a0, 0x131bc,
+ 0x131c6, 0x131cc, 0x131d8, 0x131f2, 0x131f4, 0x1320e, 0x1321c, 0x13270, 0x1327e, 0x132e0, 0x132fc, 0x13308,
+ 0x1331e, 0x13320, 0x1333c, 0x13340, 0x13378, 0x13386, 0x13398, 0x133b0, 0x133be, 0x133ce, 0x133dc, 0x133e2,
+ 0x133e4, 0x133e8, 0x133f6, 0x1340e, 0x1341c, 0x13438, 0x13470, 0x1347e, 0x134e0, 0x134fc, 0x135c0, 0x135f8,
+ 0x13608, 0x13610, 0x1361e, 0x13620, 0x1363c, 0x13640, 0x13678, 0x136f0, 0x1370c, 0x13718, 0x13730, 0x1373e,
+ 0x13760, 0x1377c, 0x1379c, 0x137b8, 0x137c2, 0x137c4, 0x137c8, 0x137d0, 0x137de, 0x137e6, 0x137ec, 0x13816,
+ 0x13826, 0x1382c, 0x13846, 0x1384c, 0x13858, 0x1386e, 0x13874, 0x13886, 0x13898, 0x138b0, 0x138be, 0x138ce,
+ 0x138dc, 0x138e2, 0x138e4, 0x138e8, 0x13906, 0x1390c, 0x13930, 0x1393e, 0x13960, 0x1397c, 0x1398e, 0x1399c,
+ 0x139b8, 0x139c8, 0x139d0, 0x139de, 0x139e6, 0x139ec, 0x139fa, 0x13a06, 0x13a0c, 0x13a18, 0x13a30, 0x13a3e,
+ 0x13a60, 0x13a7c, 0x13ac0, 0x13af8, 0x13b0e, 0x13b1c, 0x13b38, 0x13b70, 0x13b7e, 0x13b88, 0x13b90, 0x13b9e,
+ 0x13ba0, 0x13bbc, 0x13bcc, 0x13bd8, 0x13bee, 0x13bf2, 0x13bf4, 0x13c12, 0x13c14, 0x13c22, 0x13c24, 0x13c28,
+ 0x13c36, 0x13c42, 0x13c48, 0x13c50, 0x13c5e, 0x13c66, 0x13c6c, 0x13c82, 0x13c84, 0x13c90, 0x13c9e, 0x13ca0,
+ 0x13cbc, 0x13cc6, 0x13ccc, 0x13cd8, 0x13cee, 0x13d02, 0x13d04, 0x13d08, 0x13d10, 0x13d1e, 0x13d20, 0x13d3c,
+ 0x13d40, 0x13d78, 0x13d86, 0x13d8c, 0x13d98, 0x13db0, 0x13dbe, 0x13dce, 0x13ddc, 0x13de4, 0x13de8, 0x13df6,
+ 0x13e1a, 0x13e2e, 0x13e32, 0x13e34, 0x13e4e, 0x13e5c, 0x13e62, 0x13e64, 0x13e68, 0x13e76, 0x13e8e, 0x13e9c,
+ 0x13eb8, 0x13ec2, 0x13ec4, 0x13ec8, 0x13ed0, 0x13ede, 0x13ee6, 0x13eec, 0x13f26, 0x13f2c, 0x13f3a, 0x13f46,
+ 0x13f4c, 0x13f58, 0x13f6e, 0x13f72, 0x13f74, 0x14082, 0x1409e, 0x140a0, 0x140bc, 0x14104, 0x14108, 0x14110,
+ 0x1411e, 0x14120, 0x1413c, 0x14140, 0x14178, 0x1418c, 0x14198, 0x141b0, 0x141be, 0x141e2, 0x141e4, 0x141e8,
+ 0x14208, 0x14210, 0x1421e, 0x14220, 0x1423c, 0x14240, 0x14278, 0x142f0, 0x14306, 0x1430c, 0x14318, 0x14330,
+ 0x1433e, 0x14360, 0x1437c, 0x1438e, 0x143c2, 0x143c4, 0x143c8, 0x143d0, 0x143e6, 0x143ec, 0x14408, 0x14410,
+ 0x1441e, 0x14420, 0x1443c, 0x14440, 0x14478, 0x144f0, 0x145e0, 0x1460c, 0x14618, 0x14630, 0x1463e, 0x14660,
+ 0x1467c, 0x146c0, 0x146f8, 0x1471c, 0x14738, 0x14770, 0x1477e, 0x14782, 0x14784, 0x14788, 0x14790, 0x147a0,
+ 0x147bc, 0x147c6, 0x147cc, 0x147d8, 0x147ee, 0x14810, 0x14820, 0x1483c, 0x14840, 0x14878, 0x148f0, 0x149e0,
+ 0x14bc0, 0x14c30, 0x14c3e, 0x14c60, 0x14c7c, 0x14cc0, 0x14cf8, 0x14df0, 0x14e38, 0x14e70, 0x14e7e, 0x14ee0,
+ 0x14efc, 0x14f04, 0x14f08, 0x14f10, 0x14f1e, 0x14f20, 0x14f3c, 0x14f40, 0x14f78, 0x14f86, 0x14f8c, 0x14f98,
+ 0x14fb0, 0x14fce, 0x14fdc, 0x15020, 0x15040, 0x15078, 0x150f0, 0x151e0, 0x153c0, 0x15860, 0x1587c, 0x158c0,
+ 0x158f8, 0x159f0, 0x15be0, 0x15c70, 0x15c7e, 0x15ce0, 0x15cfc, 0x15dc0, 0x15df8, 0x15e08, 0x15e10, 0x15e20,
+ 0x15e40, 0x15e78, 0x15ef0, 0x15f0c, 0x15f18, 0x15f30, 0x15f60, 0x15f7c, 0x15f8e, 0x15f9c, 0x15fb8, 0x1604e,
+ 0x1605c, 0x1608e, 0x1609c, 0x160b8, 0x160c2, 0x160c4, 0x160c8, 0x160de, 0x1610e, 0x1611c, 0x16138, 0x16170,
+ 0x1617e, 0x16184, 0x16188, 0x16190, 0x1619e, 0x161a0, 0x161bc, 0x161c6, 0x161cc, 0x161d8, 0x161f2, 0x161f4,
+ 0x1620e, 0x1621c, 0x16238, 0x16270, 0x1627e, 0x162e0, 0x162fc, 0x16304, 0x16308, 0x16310, 0x1631e, 0x16320,
+ 0x1633c, 0x16340, 0x16378, 0x16386, 0x1638c, 0x16398, 0x163b0, 0x163be, 0x163ce, 0x163dc, 0x163e2, 0x163e4,
+ 0x163e8, 0x163f6, 0x1640e, 0x1641c, 0x16438, 0x16470, 0x1647e, 0x164e0, 0x164fc, 0x165c0, 0x165f8, 0x16610,
+ 0x1661e, 0x16620, 0x1663c, 0x16640, 0x16678, 0x166f0, 0x16718, 0x16730, 0x1673e, 0x16760, 0x1677c, 0x1678e,
+ 0x1679c, 0x167b8, 0x167c2, 0x167c4, 0x167c8, 0x167d0, 0x167de, 0x167e6, 0x167ec, 0x1681c, 0x16838, 0x16870,
+ 0x168e0, 0x168fc, 0x169c0, 0x169f8, 0x16bf0, 0x16c10, 0x16c1e, 0x16c20, 0x16c3c, 0x16c40, 0x16c78, 0x16cf0,
+ 0x16de0, 0x16e18, 0x16e30, 0x16e3e, 0x16e60, 0x16e7c, 0x16ec0, 0x16ef8, 0x16f1c, 0x16f38, 0x16f70, 0x16f7e,
+ 0x16f84, 0x16f88, 0x16f90, 0x16f9e, 0x16fa0, 0x16fbc, 0x16fc6, 0x16fcc, 0x16fd8, 0x17026, 0x1702c, 0x17046,
+ 0x1704c, 0x17058, 0x1706e, 0x17086, 0x1708c, 0x17098, 0x170b0, 0x170be, 0x170ce, 0x170dc, 0x170e8, 0x17106,
+ 0x1710c, 0x17118, 0x17130, 0x1713e, 0x17160, 0x1717c, 0x1718e, 0x1719c, 0x171b8, 0x171c2, 0x171c4, 0x171c8,
+ 0x171d0, 0x171de, 0x171e6, 0x171ec, 0x171fa, 0x17206, 0x1720c, 0x17218, 0x17230, 0x1723e, 0x17260, 0x1727c,
+ 0x172c0, 0x172f8, 0x1730e, 0x1731c, 0x17338, 0x17370, 0x1737e, 0x17388, 0x17390, 0x1739e, 0x173a0, 0x173bc,
+ 0x173cc, 0x173d8, 0x173ee, 0x173f2, 0x173f4, 0x1740c, 0x17418, 0x17430, 0x1743e, 0x17460, 0x1747c, 0x174c0,
+ 0x174f8, 0x175f0, 0x1760e, 0x1761c, 0x17638, 0x17670, 0x1767e, 0x176e0, 0x176fc, 0x17708, 0x17710, 0x1771e,
+ 0x17720, 0x1773c, 0x17740, 0x17778, 0x17798, 0x177b0, 0x177be, 0x177dc, 0x177e2, 0x177e4, 0x177e8, 0x17822,
+ 0x17824, 0x17828, 0x17836, 0x17842, 0x17844, 0x17848, 0x17850, 0x1785e, 0x17866, 0x1786c, 0x17882, 0x17884,
+ 0x17888, 0x17890, 0x1789e, 0x178a0, 0x178bc, 0x178c6, 0x178cc, 0x178d8, 0x178ee, 0x178f2, 0x178f4, 0x17902,
+ 0x17904, 0x17908, 0x17910, 0x1791e, 0x17920, 0x1793c, 0x17940, 0x17978, 0x17986, 0x1798c, 0x17998, 0x179b0,
+ 0x179be, 0x179ce, 0x179dc, 0x179e2, 0x179e4, 0x179e8, 0x179f6, 0x17a04, 0x17a08, 0x17a10, 0x17a1e, 0x17a20,
+ 0x17a3c, 0x17a40, 0x17a78, 0x17af0, 0x17b06, 0x17b0c, 0x17b18, 0x17b30, 0x17b3e, 0x17b60, 0x17b7c, 0x17b8e,
+ 0x17b9c, 0x17bb8, 0x17bc4, 0x17bc8, 0x17bd0, 0x17bde, 0x17be6, 0x17bec, 0x17c2e, 0x17c32, 0x17c34, 0x17c4e,
+ 0x17c5c, 0x17c62, 0x17c64, 0x17c68, 0x17c76, 0x17c8e, 0x17c9c, 0x17cb8, 0x17cc2, 0x17cc4, 0x17cc8, 0x17cd0,
+ 0x17cde, 0x17ce6, 0x17cec, 0x17d0e, 0x17d1c, 0x17d38, 0x17d70, 0x17d82, 0x17d84, 0x17d88, 0x17d90, 0x17d9e,
+ 0x17da0, 0x17dbc, 0x17dc6, 0x17dcc, 0x17dd8, 0x17dee, 0x17e26, 0x17e2c, 0x17e3a, 0x17e46, 0x17e4c, 0x17e58,
+ 0x17e6e, 0x17e72, 0x17e74, 0x17e86, 0x17e8c, 0x17e98, 0x17eb0, 0x17ece, 0x17edc, 0x17ee2, 0x17ee4, 0x17ee8,
+ 0x17ef6, 0x1813a, 0x18172, 0x18174, 0x18216, 0x18226, 0x1823a, 0x1824c, 0x18258, 0x1826e, 0x18272, 0x18274,
+ 0x18298, 0x182be, 0x182e2, 0x182e4, 0x182e8, 0x182f6, 0x1835e, 0x1837a, 0x183ae, 0x183d6, 0x18416, 0x18426,
+ 0x1842c, 0x1843a, 0x18446, 0x18458, 0x1846e, 0x18472, 0x18474, 0x18486, 0x184b0, 0x184be, 0x184ce, 0x184dc,
+ 0x184e2, 0x184e4, 0x184e8, 0x184f6, 0x18506, 0x1850c, 0x18518, 0x18530, 0x1853e, 0x18560, 0x1857c, 0x1858e,
+ 0x1859c, 0x185b8, 0x185c2, 0x185c4, 0x185c8, 0x185d0, 0x185de, 0x185e6, 0x185ec, 0x185fa, 0x18612, 0x18614,
+ 0x18622, 0x18628, 0x18636, 0x18642, 0x18650, 0x1865e, 0x1867a, 0x18682, 0x18684, 0x18688, 0x18690, 0x1869e,
+ 0x186a0, 0x186bc, 0x186c6, 0x186cc, 0x186d8, 0x186ee, 0x186f2, 0x186f4, 0x1872e, 0x1874e, 0x1875c, 0x18796,
+ 0x187a6, 0x187ac, 0x187d2, 0x187d4, 0x18826, 0x1882c, 0x1883a, 0x18846, 0x1884c, 0x18858, 0x1886e, 0x18872,
+ 0x18874, 0x18886, 0x18898, 0x188b0, 0x188be, 0x188ce, 0x188dc, 0x188e2, 0x188e4, 0x188e8, 0x188f6, 0x1890c,
+ 0x18930, 0x1893e, 0x18960, 0x1897c, 0x1898e, 0x189b8, 0x189c2, 0x189c8, 0x189d0, 0x189de, 0x189e6, 0x189ec,
+ 0x189fa, 0x18a18, 0x18a30, 0x18a3e, 0x18a60, 0x18a7c, 0x18ac0, 0x18af8, 0x18b1c, 0x18b38, 0x18b70, 0x18b7e,
+ 0x18b82, 0x18b84, 0x18b88, 0x18b90, 0x18b9e, 0x18ba0, 0x18bbc, 0x18bc6, 0x18bcc, 0x18bd8, 0x18bee, 0x18bf2,
+ 0x18bf4, 0x18c22, 0x18c24, 0x18c28, 0x18c36, 0x18c42, 0x18c48, 0x18c50, 0x18c5e, 0x18c66, 0x18c7a, 0x18c82,
+ 0x18c84, 0x18c90, 0x18c9e, 0x18ca0, 0x18cbc, 0x18ccc, 0x18cf2, 0x18cf4, 0x18d04, 0x18d08, 0x18d10, 0x18d1e,
+ 0x18d20, 0x18d3c, 0x18d40, 0x18d78, 0x18d86, 0x18d98, 0x18dce, 0x18de2, 0x18de4, 0x18de8, 0x18e2e, 0x18e32,
+ 0x18e34, 0x18e4e, 0x18e5c, 0x18e62, 0x18e64, 0x18e68, 0x18e8e, 0x18e9c, 0x18eb8, 0x18ec2, 0x18ec4, 0x18ec8,
+ 0x18ed0, 0x18efa, 0x18f16, 0x18f26, 0x18f2c, 0x18f46, 0x18f4c, 0x18f58, 0x18f6e, 0x18f8a, 0x18f92, 0x18f94,
+ 0x18fa2, 0x18fa4, 0x18fa8, 0x18fb6, 0x1902c, 0x1903a, 0x19046, 0x1904c, 0x19058, 0x19072, 0x19074, 0x19086,
+ 0x19098, 0x190b0, 0x190be, 0x190ce, 0x190dc, 0x190e2, 0x190e8, 0x190f6, 0x19106, 0x1910c, 0x19130, 0x1913e,
+ 0x19160, 0x1917c, 0x1918e, 0x1919c, 0x191b8, 0x191c2, 0x191c8, 0x191d0, 0x191de, 0x191e6, 0x191ec, 0x191fa,
+ 0x19218, 0x1923e, 0x19260, 0x1927c, 0x192c0, 0x192f8, 0x19338, 0x19370, 0x1937e, 0x19382, 0x19384, 0x19390,
+ 0x1939e, 0x193a0, 0x193bc, 0x193c6, 0x193cc, 0x193d8, 0x193ee, 0x193f2, 0x193f4, 0x19430, 0x1943e, 0x19460,
+ 0x1947c, 0x194c0, 0x194f8, 0x195f0, 0x19638, 0x19670, 0x1967e, 0x196e0, 0x196fc, 0x19702, 0x19704, 0x19708,
+ 0x19710, 0x19720, 0x1973c, 0x19740, 0x19778, 0x19786, 0x1978c, 0x19798, 0x197b0, 0x197be, 0x197ce, 0x197dc,
+ 0x197e2, 0x197e4, 0x197e8, 0x19822, 0x19824, 0x19842, 0x19848, 0x19850, 0x1985e, 0x19866, 0x1987a, 0x19882,
+ 0x19884, 0x19890, 0x1989e, 0x198a0, 0x198bc, 0x198cc, 0x198f2, 0x198f4, 0x19902, 0x19908, 0x1991e, 0x19920,
+ 0x1993c, 0x19940, 0x19978, 0x19986, 0x19998, 0x199ce, 0x199e2, 0x199e4, 0x199e8, 0x19a08, 0x19a10, 0x19a1e,
+ 0x19a20, 0x19a3c, 0x19a40, 0x19a78, 0x19af0, 0x19b18, 0x19b3e, 0x19b60, 0x19b9c, 0x19bc2, 0x19bc4, 0x19bc8,
+ 0x19bd0, 0x19be6, 0x19c2e, 0x19c34, 0x19c4e, 0x19c5c, 0x19c62, 0x19c64, 0x19c68, 0x19c8e, 0x19c9c, 0x19cb8,
+ 0x19cc2, 0x19cc8, 0x19cd0, 0x19ce6, 0x19cfa, 0x19d0e, 0x19d1c, 0x19d38, 0x19d70, 0x19d7e, 0x19d82, 0x19d84,
+ 0x19d88, 0x19d90, 0x19da0, 0x19dcc, 0x19df2, 0x19df4, 0x19e16, 0x19e26, 0x19e2c, 0x19e46, 0x19e4c, 0x19e58,
+ 0x19e74, 0x19e86, 0x19e8c, 0x19e98, 0x19eb0, 0x19ebe, 0x19ece, 0x19ee2, 0x19ee4, 0x19ee8, 0x19f0a, 0x19f12,
+ 0x19f14, 0x19f22, 0x19f24, 0x19f28, 0x19f42, 0x19f44, 0x19f48, 0x19f50, 0x19f5e, 0x19f6c, 0x19f9a, 0x19fae,
+ 0x19fb2, 0x19fb4, 0x1a046, 0x1a04c, 0x1a072, 0x1a074, 0x1a086, 0x1a08c, 0x1a098, 0x1a0b0, 0x1a0be, 0x1a0e2,
+ 0x1a0e4, 0x1a0e8, 0x1a0f6, 0x1a106, 0x1a10c, 0x1a118, 0x1a130, 0x1a13e, 0x1a160, 0x1a17c, 0x1a18e, 0x1a19c,
+ 0x1a1b8, 0x1a1c2, 0x1a1c4, 0x1a1c8, 0x1a1d0, 0x1a1de, 0x1a1e6, 0x1a1ec, 0x1a218, 0x1a230, 0x1a23e, 0x1a260,
+ 0x1a27c, 0x1a2c0, 0x1a2f8, 0x1a31c, 0x1a338, 0x1a370, 0x1a37e, 0x1a382, 0x1a384, 0x1a388, 0x1a390, 0x1a39e,
+ 0x1a3a0, 0x1a3bc, 0x1a3c6, 0x1a3cc, 0x1a3d8, 0x1a3ee, 0x1a3f2, 0x1a3f4, 0x1a418, 0x1a430, 0x1a43e, 0x1a460,
+ 0x1a47c, 0x1a4c0, 0x1a4f8, 0x1a5f0, 0x1a61c, 0x1a638, 0x1a670, 0x1a67e, 0x1a6e0, 0x1a6fc, 0x1a702, 0x1a704,
+ 0x1a708, 0x1a710, 0x1a71e, 0x1a720, 0x1a73c, 0x1a740, 0x1a778, 0x1a786, 0x1a78c, 0x1a798, 0x1a7b0, 0x1a7be,
+ 0x1a7ce, 0x1a7dc, 0x1a7e2, 0x1a7e4, 0x1a7e8, 0x1a830, 0x1a860, 0x1a87c, 0x1a8c0, 0x1a8f8, 0x1a9f0, 0x1abe0,
+ 0x1ac70, 0x1ac7e, 0x1ace0, 0x1acfc, 0x1adc0, 0x1adf8, 0x1ae04, 0x1ae08, 0x1ae10, 0x1ae20, 0x1ae3c, 0x1ae40,
+ 0x1ae78, 0x1aef0, 0x1af06, 0x1af0c, 0x1af18, 0x1af30, 0x1af3e, 0x1af60, 0x1af7c, 0x1af8e, 0x1af9c, 0x1afb8,
+ 0x1afc4, 0x1afc8, 0x1afd0, 0x1afde, 0x1b042, 0x1b05e, 0x1b07a, 0x1b082, 0x1b084, 0x1b088, 0x1b090, 0x1b09e,
+ 0x1b0a0, 0x1b0bc, 0x1b0cc, 0x1b0f2, 0x1b0f4, 0x1b102, 0x1b104, 0x1b108, 0x1b110, 0x1b11e, 0x1b120, 0x1b13c,
+ 0x1b140, 0x1b178, 0x1b186, 0x1b198, 0x1b1ce, 0x1b1e2, 0x1b1e4, 0x1b1e8, 0x1b204, 0x1b208, 0x1b210, 0x1b21e,
+ 0x1b220, 0x1b23c, 0x1b240, 0x1b278, 0x1b2f0, 0x1b30c, 0x1b33e, 0x1b360, 0x1b39c, 0x1b3c2, 0x1b3c4, 0x1b3c8,
+ 0x1b3d0, 0x1b3e6, 0x1b410, 0x1b41e, 0x1b420, 0x1b43c, 0x1b440, 0x1b478, 0x1b4f0, 0x1b5e0, 0x1b618, 0x1b660,
+ 0x1b67c, 0x1b6c0, 0x1b738, 0x1b782, 0x1b784, 0x1b788, 0x1b790, 0x1b79e, 0x1b7a0, 0x1b7cc, 0x1b82e, 0x1b84e,
+ 0x1b85c, 0x1b88e, 0x1b89c, 0x1b8b8, 0x1b8c2, 0x1b8c4, 0x1b8c8, 0x1b8d0, 0x1b8e6, 0x1b8fa, 0x1b90e, 0x1b91c,
+ 0x1b938, 0x1b970, 0x1b97e, 0x1b982, 0x1b984, 0x1b988, 0x1b990, 0x1b99e, 0x1b9a0, 0x1b9cc, 0x1b9f2, 0x1b9f4,
+ 0x1ba0e, 0x1ba1c, 0x1ba38, 0x1ba70, 0x1ba7e, 0x1bae0, 0x1bafc, 0x1bb08, 0x1bb10, 0x1bb20, 0x1bb3c, 0x1bb40,
+ 0x1bb98, 0x1bbce, 0x1bbe2, 0x1bbe4, 0x1bbe8, 0x1bc16, 0x1bc26, 0x1bc2c, 0x1bc46, 0x1bc4c, 0x1bc58, 0x1bc72,
+ 0x1bc74, 0x1bc86, 0x1bc8c, 0x1bc98, 0x1bcb0, 0x1bcbe, 0x1bcce, 0x1bce2, 0x1bce4, 0x1bce8, 0x1bd06, 0x1bd0c,
+ 0x1bd18, 0x1bd30, 0x1bd3e, 0x1bd60, 0x1bd7c, 0x1bd9c, 0x1bdc2, 0x1bdc4, 0x1bdc8, 0x1bdd0, 0x1bde6, 0x1bdfa,
+ 0x1be12, 0x1be14, 0x1be22, 0x1be24, 0x1be28, 0x1be42, 0x1be44, 0x1be48, 0x1be50, 0x1be5e, 0x1be66, 0x1be82,
+ 0x1be84, 0x1be88, 0x1be90, 0x1be9e, 0x1bea0, 0x1bebc, 0x1becc, 0x1bef4, 0x1bf1a, 0x1bf2e, 0x1bf32, 0x1bf34,
+ 0x1bf4e, 0x1bf5c, 0x1bf62, 0x1bf64, 0x1bf68, 0x1c09a, 0x1c0b2, 0x1c0b4, 0x1c11a, 0x1c132, 0x1c134, 0x1c162,
+ 0x1c164, 0x1c168, 0x1c176, 0x1c1ba, 0x1c21a, 0x1c232, 0x1c234, 0x1c24e, 0x1c25c, 0x1c262, 0x1c264, 0x1c268,
+ 0x1c276, 0x1c28e, 0x1c2c2, 0x1c2c4, 0x1c2c8, 0x1c2d0, 0x1c2de, 0x1c2e6, 0x1c2ec, 0x1c2fa, 0x1c316, 0x1c326,
+ 0x1c33a, 0x1c346, 0x1c34c, 0x1c372, 0x1c374, 0x1c41a, 0x1c42e, 0x1c432, 0x1c434, 0x1c44e, 0x1c45c, 0x1c462,
+ 0x1c464, 0x1c468, 0x1c476, 0x1c48e, 0x1c49c, 0x1c4b8, 0x1c4c2, 0x1c4c8, 0x1c4d0, 0x1c4de, 0x1c4e6, 0x1c4ec,
+ 0x1c4fa, 0x1c51c, 0x1c538, 0x1c570, 0x1c57e, 0x1c582, 0x1c584, 0x1c588, 0x1c590, 0x1c59e, 0x1c5a0, 0x1c5bc,
+ 0x1c5c6, 0x1c5cc, 0x1c5d8, 0x1c5ee, 0x1c5f2, 0x1c5f4, 0x1c616, 0x1c626, 0x1c62c, 0x1c63a, 0x1c646, 0x1c64c,
+ 0x1c658, 0x1c66e, 0x1c672, 0x1c674, 0x1c686, 0x1c68c, 0x1c698, 0x1c6b0, 0x1c6be, 0x1c6ce, 0x1c6dc, 0x1c6e2,
+ 0x1c6e4, 0x1c6e8, 0x1c712, 0x1c714, 0x1c722, 0x1c728, 0x1c736, 0x1c742, 0x1c744, 0x1c748, 0x1c750, 0x1c75e,
+ 0x1c766, 0x1c76c, 0x1c77a, 0x1c7ae, 0x1c7d6, 0x1c7ea, 0x1c81a, 0x1c82e, 0x1c832, 0x1c834, 0x1c84e, 0x1c85c,
+ 0x1c862, 0x1c864, 0x1c868, 0x1c876, 0x1c88e, 0x1c89c, 0x1c8b8, 0x1c8c2, 0x1c8c8, 0x1c8d0, 0x1c8de, 0x1c8e6,
+ 0x1c8ec, 0x1c8fa, 0x1c90e, 0x1c938, 0x1c970, 0x1c97e, 0x1c982, 0x1c984, 0x1c990, 0x1c99e, 0x1c9a0, 0x1c9bc,
+ 0x1c9c6, 0x1c9cc, 0x1c9d8, 0x1c9ee, 0x1c9f2, 0x1c9f4, 0x1ca38, 0x1ca70, 0x1ca7e, 0x1cae0, 0x1cafc, 0x1cb02,
+ 0x1cb04, 0x1cb08, 0x1cb10, 0x1cb20, 0x1cb3c, 0x1cb40, 0x1cb78, 0x1cb86, 0x1cb8c, 0x1cb98, 0x1cbb0, 0x1cbbe,
+ 0x1cbce, 0x1cbdc, 0x1cbe2, 0x1cbe4, 0x1cbe8, 0x1cbf6, 0x1cc16, 0x1cc26, 0x1cc2c, 0x1cc3a, 0x1cc46, 0x1cc58,
+ 0x1cc72, 0x1cc74, 0x1cc86, 0x1ccb0, 0x1ccbe, 0x1ccce, 0x1cce2, 0x1cce4, 0x1cce8, 0x1cd06, 0x1cd0c, 0x1cd18,
+ 0x1cd30, 0x1cd3e, 0x1cd60, 0x1cd7c, 0x1cd9c, 0x1cdc2, 0x1cdc4, 0x1cdc8, 0x1cdd0, 0x1cdde, 0x1cde6, 0x1cdfa,
+ 0x1ce22, 0x1ce28, 0x1ce42, 0x1ce50, 0x1ce5e, 0x1ce66, 0x1ce7a, 0x1ce82, 0x1ce84, 0x1ce88, 0x1ce90, 0x1ce9e,
+ 0x1cea0, 0x1cebc, 0x1cecc, 0x1cef2, 0x1cef4, 0x1cf2e, 0x1cf32, 0x1cf34, 0x1cf4e, 0x1cf5c, 0x1cf62, 0x1cf64,
+ 0x1cf68, 0x1cf96, 0x1cfa6, 0x1cfac, 0x1cfca, 0x1cfd2, 0x1cfd4, 0x1d02e, 0x1d032, 0x1d034, 0x1d04e, 0x1d05c,
+ 0x1d062, 0x1d064, 0x1d068, 0x1d076, 0x1d08e, 0x1d09c, 0x1d0b8, 0x1d0c2, 0x1d0c4, 0x1d0c8, 0x1d0d0, 0x1d0de,
+ 0x1d0e6, 0x1d0ec, 0x1d0fa, 0x1d11c, 0x1d138, 0x1d170, 0x1d17e, 0x1d182, 0x1d184, 0x1d188, 0x1d190, 0x1d19e,
+ 0x1d1a0, 0x1d1bc, 0x1d1c6, 0x1d1cc, 0x1d1d8, 0x1d1ee, 0x1d1f2, 0x1d1f4, 0x1d21c, 0x1d238, 0x1d270, 0x1d27e,
+ 0x1d2e0, 0x1d2fc, 0x1d302, 0x1d304, 0x1d308, 0x1d310, 0x1d31e, 0x1d320, 0x1d33c, 0x1d340, 0x1d378, 0x1d386,
+ 0x1d38c, 0x1d398, 0x1d3b0, 0x1d3be, 0x1d3ce, 0x1d3dc, 0x1d3e2, 0x1d3e4, 0x1d3e8, 0x1d3f6, 0x1d470, 0x1d47e,
+ 0x1d4e0, 0x1d4fc, 0x1d5c0, 0x1d5f8, 0x1d604, 0x1d608, 0x1d610, 0x1d620, 0x1d640, 0x1d678, 0x1d6f0, 0x1d706,
+ 0x1d70c, 0x1d718, 0x1d730, 0x1d73e, 0x1d760, 0x1d77c, 0x1d78e, 0x1d79c, 0x1d7b8, 0x1d7c2, 0x1d7c4, 0x1d7c8,
+ 0x1d7d0, 0x1d7de, 0x1d7e6, 0x1d7ec, 0x1d826, 0x1d82c, 0x1d83a, 0x1d846, 0x1d84c, 0x1d858, 0x1d872, 0x1d874,
+ 0x1d886, 0x1d88c, 0x1d898, 0x1d8b0, 0x1d8be, 0x1d8ce, 0x1d8e2, 0x1d8e4, 0x1d8e8, 0x1d8f6, 0x1d90c, 0x1d918,
+ 0x1d930, 0x1d93e, 0x1d960, 0x1d97c, 0x1d99c, 0x1d9c2, 0x1d9c4, 0x1d9c8, 0x1d9d0, 0x1d9e6, 0x1d9fa, 0x1da0c,
+ 0x1da18, 0x1da30, 0x1da3e, 0x1da60, 0x1da7c, 0x1dac0, 0x1daf8, 0x1db38, 0x1db82, 0x1db84, 0x1db88, 0x1db90,
+ 0x1db9e, 0x1dba0, 0x1dbcc, 0x1dbf2, 0x1dbf4, 0x1dc22, 0x1dc42, 0x1dc44, 0x1dc48, 0x1dc50, 0x1dc5e, 0x1dc66,
+ 0x1dc7a, 0x1dc82, 0x1dc84, 0x1dc88, 0x1dc90, 0x1dc9e, 0x1dca0, 0x1dcbc, 0x1dccc, 0x1dcf2, 0x1dcf4, 0x1dd04,
+ 0x1dd08, 0x1dd10, 0x1dd1e, 0x1dd20, 0x1dd3c, 0x1dd40, 0x1dd78, 0x1dd86, 0x1dd98, 0x1ddce, 0x1dde2, 0x1dde4,
+ 0x1dde8, 0x1de2e, 0x1de32, 0x1de34, 0x1de4e, 0x1de5c, 0x1de62, 0x1de64, 0x1de68, 0x1de8e, 0x1de9c, 0x1deb8,
+ 0x1dec2, 0x1dec4, 0x1dec8, 0x1ded0, 0x1dee6, 0x1defa, 0x1df16, 0x1df26, 0x1df2c, 0x1df46, 0x1df4c, 0x1df58,
+ 0x1df72, 0x1df74, 0x1df8a, 0x1df92, 0x1df94, 0x1dfa2, 0x1dfa4, 0x1dfa8, 0x1e08a, 0x1e092, 0x1e094, 0x1e0a2,
+ 0x1e0a4, 0x1e0a8, 0x1e0b6, 0x1e0da, 0x1e10a, 0x1e112, 0x1e114, 0x1e122, 0x1e124, 0x1e128, 0x1e136, 0x1e142,
+ 0x1e144, 0x1e148, 0x1e150, 0x1e166, 0x1e16c, 0x1e17a, 0x1e19a, 0x1e1b2, 0x1e1b4, 0x1e20a, 0x1e212, 0x1e214,
+ 0x1e222, 0x1e224, 0x1e228, 0x1e236, 0x1e242, 0x1e248, 0x1e250, 0x1e25e, 0x1e266, 0x1e26c, 0x1e27a, 0x1e282,
+ 0x1e284, 0x1e288, 0x1e290, 0x1e2a0, 0x1e2bc, 0x1e2c6, 0x1e2cc, 0x1e2d8, 0x1e2ee, 0x1e2f2, 0x1e2f4, 0x1e31a,
+ 0x1e332, 0x1e334, 0x1e35c, 0x1e362, 0x1e364, 0x1e368, 0x1e3ba, 0x1e40a, 0x1e412, 0x1e414, 0x1e422, 0x1e428,
+ 0x1e436, 0x1e442, 0x1e448, 0x1e450, 0x1e45e, 0x1e466, 0x1e46c, 0x1e47a, 0x1e482, 0x1e484, 0x1e490, 0x1e49e,
+ 0x1e4a0, 0x1e4bc, 0x1e4c6, 0x1e4cc, 0x1e4d8, 0x1e4ee, 0x1e4f2, 0x1e4f4, 0x1e502, 0x1e504, 0x1e508, 0x1e510,
+ 0x1e51e, 0x1e520, 0x1e53c, 0x1e540, 0x1e578, 0x1e586, 0x1e58c, 0x1e598, 0x1e5b0, 0x1e5be, 0x1e5ce, 0x1e5dc,
+ 0x1e5e2, 0x1e5e4, 0x1e5e8, 0x1e5f6, 0x1e61a, 0x1e62e, 0x1e632, 0x1e634, 0x1e64e, 0x1e65c, 0x1e662, 0x1e668,
+ 0x1e68e, 0x1e69c, 0x1e6b8, 0x1e6c2, 0x1e6c4, 0x1e6c8, 0x1e6d0, 0x1e6e6, 0x1e6fa, 0x1e716, 0x1e726, 0x1e72c,
+ 0x1e73a, 0x1e746, 0x1e74c, 0x1e758, 0x1e772, 0x1e774, 0x1e792, 0x1e794, 0x1e7a2, 0x1e7a4, 0x1e7a8, 0x1e7b6,
+ 0x1e812, 0x1e814, 0x1e822, 0x1e824, 0x1e828, 0x1e836, 0x1e842, 0x1e844, 0x1e848, 0x1e850, 0x1e85e, 0x1e866,
+ 0x1e86c, 0x1e87a, 0x1e882, 0x1e884, 0x1e888, 0x1e890, 0x1e89e, 0x1e8a0, 0x1e8bc, 0x1e8c6, 0x1e8cc, 0x1e8d8,
+ 0x1e8ee, 0x1e8f2, 0x1e8f4, 0x1e902, 0x1e904, 0x1e908, 0x1e910, 0x1e920, 0x1e93c, 0x1e940, 0x1e978, 0x1e986,
+ 0x1e98c, 0x1e998, 0x1e9b0, 0x1e9be, 0x1e9ce, 0x1e9dc, 0x1e9e2, 0x1e9e4, 0x1e9e8, 0x1e9f6, 0x1ea04, 0x1ea08,
+ 0x1ea10, 0x1ea20, 0x1ea40, 0x1ea78, 0x1eaf0, 0x1eb06, 0x1eb0c, 0x1eb18, 0x1eb30, 0x1eb3e, 0x1eb60, 0x1eb7c,
+ 0x1eb8e, 0x1eb9c, 0x1ebb8, 0x1ebc2, 0x1ebc4, 0x1ebc8, 0x1ebd0, 0x1ebde, 0x1ebe6, 0x1ebec, 0x1ec1a, 0x1ec2e,
+ 0x1ec32, 0x1ec34, 0x1ec4e, 0x1ec5c, 0x1ec62, 0x1ec64, 0x1ec68, 0x1ec8e, 0x1ec9c, 0x1ecb8, 0x1ecc2, 0x1ecc4,
+ 0x1ecc8, 0x1ecd0, 0x1ece6, 0x1ecfa, 0x1ed0e, 0x1ed1c, 0x1ed38, 0x1ed70, 0x1ed7e, 0x1ed82, 0x1ed84, 0x1ed88,
+ 0x1ed90, 0x1ed9e, 0x1eda0, 0x1edcc, 0x1edf2, 0x1edf4, 0x1ee16, 0x1ee26, 0x1ee2c, 0x1ee3a, 0x1ee46, 0x1ee4c,
+ 0x1ee58, 0x1ee6e, 0x1ee72, 0x1ee74, 0x1ee86, 0x1ee8c, 0x1ee98, 0x1eeb0, 0x1eebe, 0x1eece, 0x1eedc, 0x1eee2,
+ 0x1eee4, 0x1eee8, 0x1ef12, 0x1ef22, 0x1ef24, 0x1ef28, 0x1ef36, 0x1ef42, 0x1ef44, 0x1ef48, 0x1ef50, 0x1ef5e,
+ 0x1ef66, 0x1ef6c, 0x1ef7a, 0x1efae, 0x1efb2, 0x1efb4, 0x1efd6, 0x1f096, 0x1f0a6, 0x1f0ac, 0x1f0ba, 0x1f0ca,
+ 0x1f0d2, 0x1f0d4, 0x1f116, 0x1f126, 0x1f12c, 0x1f13a, 0x1f146, 0x1f14c, 0x1f158, 0x1f16e, 0x1f172, 0x1f174,
+ 0x1f18a, 0x1f192, 0x1f194, 0x1f1a2, 0x1f1a4, 0x1f1a8, 0x1f1da, 0x1f216, 0x1f226, 0x1f22c, 0x1f23a, 0x1f246,
+ 0x1f258, 0x1f26e, 0x1f272, 0x1f274, 0x1f286, 0x1f28c, 0x1f298, 0x1f2b0, 0x1f2be, 0x1f2ce, 0x1f2dc, 0x1f2e2,
+ 0x1f2e4, 0x1f2e8, 0x1f2f6, 0x1f30a, 0x1f312, 0x1f314, 0x1f322, 0x1f328, 0x1f342, 0x1f344, 0x1f348, 0x1f350,
+ 0x1f35e, 0x1f366, 0x1f37a, 0x1f39a, 0x1f3ae, 0x1f3b2, 0x1f3b4, 0x1f416, 0x1f426, 0x1f42c, 0x1f43a, 0x1f446,
+ 0x1f44c, 0x1f458, 0x1f46e, 0x1f472, 0x1f474, 0x1f486, 0x1f48c, 0x1f498, 0x1f4b0, 0x1f4be, 0x1f4ce, 0x1f4dc,
+ 0x1f4e2, 0x1f4e4, 0x1f4e8, 0x1f4f6, 0x1f506, 0x1f50c, 0x1f518, 0x1f530, 0x1f53e, 0x1f560, 0x1f57c, 0x1f58e,
+ 0x1f59c, 0x1f5b8, 0x1f5c2, 0x1f5c4, 0x1f5c8, 0x1f5d0, 0x1f5de, 0x1f5e6, 0x1f5ec, 0x1f5fa, 0x1f60a, 0x1f612,
+ 0x1f614, 0x1f622, 0x1f624, 0x1f628, 0x1f636, 0x1f642, 0x1f644, 0x1f648, 0x1f650, 0x1f65e, 0x1f666, 0x1f67a,
+ 0x1f682, 0x1f684, 0x1f688, 0x1f690, 0x1f69e, 0x1f6a0, 0x1f6bc, 0x1f6cc, 0x1f6f2, 0x1f6f4, 0x1f71a, 0x1f72e,
+ 0x1f732, 0x1f734, 0x1f74e, 0x1f75c, 0x1f762, 0x1f764, 0x1f768, 0x1f776, 0x1f796, 0x1f7a6, 0x1f7ac, 0x1f7ba,
+ 0x1f7d2, 0x1f7d4, 0x1f89a, 0x1f8ae, 0x1f8b2, 0x1f8b4, 0x1f8d6, 0x1f8ea, 0x1f91a, 0x1f92e, 0x1f932, 0x1f934,
+ 0x1f94e, 0x1f95c, 0x1f962, 0x1f964, 0x1f968, 0x1f976, 0x1f996, 0x1f9a6, 0x1f9ac, 0x1f9ba, 0x1f9ca, 0x1f9d2,
+ 0x1f9d4, 0x1fa1a, 0x1fa2e, 0x1fa32, 0x1fa34, 0x1fa4e, 0x1fa5c, 0x1fa62, 0x1fa64, 0x1fa68, 0x1fa76, 0x1fa8e,
+ 0x1fa9c, 0x1fab8, 0x1fac2, 0x1fac4, 0x1fac8, 0x1fad0, 0x1fade, 0x1fae6, 0x1faec, 0x1fb16, 0x1fb26, 0x1fb2c,
+ 0x1fb3a, 0x1fb46, 0x1fb4c, 0x1fb58, 0x1fb6e, 0x1fb72, 0x1fb74, 0x1fb8a, 0x1fb92, 0x1fb94, 0x1fba2, 0x1fba4,
+ 0x1fba8, 0x1fbb6, 0x1fbda};
+
+/**
+ * This table contains to codewords for all symbols.
+ */
+int ZXPDF417_CODEWORD_TABLE[ZXPDF417_CODEWORD_TABLE_LEN] = {
+ 2627, 1819, 2622, 2621, 1813, 1812, 2729, 2724, 2723, 2779, 2774, 2773, 902, 896, 908, 868, 865, 861, 859, 2511,
+ 873, 871, 1780, 835, 2493, 825, 2491, 842, 837, 844, 1764, 1762, 811, 810, 809, 2483, 807, 2482, 806, 2480, 815,
+ 814, 813, 812, 2484, 817, 816, 1745, 1744, 1742, 1746, 2655, 2637, 2635, 2626, 2625, 2623, 2628, 1820, 2752,
+ 2739, 2737, 2728, 2727, 2725, 2730, 2785, 2783, 2778, 2777, 2775, 2780, 787, 781, 747, 739, 736, 2413, 754, 752,
+ 1719, 692, 689, 681, 2371, 678, 2369, 700, 697, 694, 703, 1688, 1686, 642, 638, 2343, 631, 2341, 627, 2338, 651,
+ 646, 643, 2345, 654, 652, 1652, 1650, 1647, 1654, 601, 599, 2322, 596, 2321, 594, 2319, 2317, 611, 610, 608, 606,
+ 2324, 603, 2323, 615, 614, 612, 1617, 1616, 1614, 1612, 616, 1619, 1618, 2575, 2538, 2536, 905, 901, 898, 909,
+ 2509, 2507, 2504, 870, 867, 864, 860, 2512, 875, 872, 1781, 2490, 2489, 2487, 2485, 1748, 836, 834, 832, 830,
+ 2494, 827, 2492, 843, 841, 839, 845, 1765, 1763, 2701, 2676, 2674, 2653, 2648, 2656, 2634, 2633, 2631, 2629,
+ 1821, 2638, 2636, 2770, 2763, 2761, 2750, 2745, 2753, 2736, 2735, 2733, 2731, 1848, 2740, 2738, 2786, 2784, 591,
+ 588, 576, 569, 566, 2296, 1590, 537, 534, 526, 2276, 522, 2274, 545, 542, 539, 548, 1572, 1570, 481, 2245, 466,
+ 2242, 462, 2239, 492, 485, 482, 2249, 496, 494, 1534, 1531, 1528, 1538, 413, 2196, 406, 2191, 2188, 425, 419,
+ 2202, 415, 2199, 432, 430, 427, 1472, 1467, 1464, 433, 1476, 1474, 368, 367, 2160, 365, 2159, 362, 2157, 2155,
+ 2152, 378, 377, 375, 2166, 372, 2165, 369, 2162, 383, 381, 379, 2168, 1419, 1418, 1416, 1414, 385, 1411, 384,
+ 1423, 1422, 1420, 1424, 2461, 802, 2441, 2439, 790, 786, 783, 794, 2409, 2406, 2403, 750, 742, 738, 2414, 756,
+ 753, 1720, 2367, 2365, 2362, 2359, 1663, 693, 691, 684, 2373, 680, 2370, 702, 699, 696, 704, 1690, 1687, 2337,
+ 2336, 2334, 2332, 1624, 2329, 1622, 640, 637, 2344, 634, 2342, 630, 2340, 650, 648, 645, 2346, 655, 653, 1653,
+ 1651, 1649, 1655, 2612, 2597, 2595, 2571, 2568, 2565, 2576, 2534, 2529, 2526, 1787, 2540, 2537, 907, 904, 900,
+ 910, 2503, 2502, 2500, 2498, 1768, 2495, 1767, 2510, 2508, 2506, 869, 866, 863, 2513, 876, 874, 1782, 2720, 2713,
+ 2711, 2697, 2694, 2691, 2702, 2672, 2670, 2664, 1828, 2678, 2675, 2647, 2646, 2644, 2642, 1823, 2639, 1822, 2654,
+ 2652, 2650, 2657, 2771, 1855, 2765, 2762, 1850, 1849, 2751, 2749, 2747, 2754, 353, 2148, 344, 342, 336, 2142,
+ 332, 2140, 345, 1375, 1373, 306, 2130, 299, 2128, 295, 2125, 319, 314, 311, 2132, 1354, 1352, 1349, 1356, 262,
+ 257, 2101, 253, 2096, 2093, 274, 273, 267, 2107, 263, 2104, 280, 278, 275, 1316, 1311, 1308, 1320, 1318, 2052,
+ 202, 2050, 2044, 2040, 219, 2063, 212, 2060, 208, 2055, 224, 221, 2066, 1260, 1258, 1252, 231, 1248, 229, 1266,
+ 1264, 1261, 1268, 155, 1998, 153, 1996, 1994, 1991, 1988, 165, 164, 2007, 162, 2006, 159, 2003, 2000, 172, 171,
+ 169, 2012, 166, 2010, 1186, 1184, 1182, 1179, 175, 1176, 173, 1192, 1191, 1189, 1187, 176, 1194, 1193, 2313,
+ 2307, 2305, 592, 589, 2294, 2292, 2289, 578, 572, 568, 2297, 580, 1591, 2272, 2267, 2264, 1547, 538, 536, 529,
+ 2278, 525, 2275, 547, 544, 541, 1574, 1571, 2237, 2235, 2229, 1493, 2225, 1489, 478, 2247, 470, 2244, 465, 2241,
+ 493, 488, 484, 2250, 498, 495, 1536, 1533, 1530, 1539, 2187, 2186, 2184, 2182, 1432, 2179, 1430, 2176, 1427, 414,
+ 412, 2197, 409, 2195, 405, 2193, 2190, 426, 424, 421, 2203, 418, 2201, 431, 429, 1473, 1471, 1469, 1466, 434,
+ 1477, 1475, 2478, 2472, 2470, 2459, 2457, 2454, 2462, 803, 2437, 2432, 2429, 1726, 2443, 2440, 792, 789, 785,
+ 2401, 2399, 2393, 1702, 2389, 1699, 2411, 2408, 2405, 745, 741, 2415, 758, 755, 1721, 2358, 2357, 2355, 2353,
+ 1661, 2350, 1660, 2347, 1657, 2368, 2366, 2364, 2361, 1666, 690, 687, 2374, 683, 2372, 701, 698, 705, 1691, 1689,
+ 2619, 2617, 2610, 2608, 2605, 2613, 2593, 2588, 2585, 1803, 2599, 2596, 2563, 2561, 2555, 1797, 2551, 1795, 2573,
+ 2570, 2567, 2577, 2525, 2524, 2522, 2520, 1786, 2517, 1785, 2514, 1783, 2535, 2533, 2531, 2528, 1788, 2541, 2539,
+ 906, 903, 911, 2721, 1844, 2715, 2712, 1838, 1836, 2699, 2696, 2693, 2703, 1827, 1826, 1824, 2673, 2671, 2669,
+ 2666, 1829, 2679, 2677, 1858, 1857, 2772, 1854, 1853, 1851, 1856, 2766, 2764, 143, 1987, 139, 1986, 135, 133,
+ 131, 1984, 128, 1983, 125, 1981, 138, 137, 136, 1985, 1133, 1132, 1130, 112, 110, 1974, 107, 1973, 104, 1971,
+ 1969, 122, 121, 119, 117, 1977, 114, 1976, 124, 1115, 1114, 1112, 1110, 1117, 1116, 84, 83, 1953, 81, 1952, 78,
+ 1950, 1948, 1945, 94, 93, 91, 1959, 88, 1958, 85, 1955, 99, 97, 95, 1961, 1086, 1085, 1083, 1081, 1078, 100,
+ 1090, 1089, 1087, 1091, 49, 47, 1917, 44, 1915, 1913, 1910, 1907, 59, 1926, 56, 1925, 53, 1922, 1919, 66, 64,
+ 1931, 61, 1929, 1042, 1040, 1038, 71, 1035, 70, 1032, 68, 1048, 1047, 1045, 1043, 1050, 1049, 12, 10, 1869, 1867,
+ 1864, 1861, 21, 1880, 19, 1877, 1874, 1871, 28, 1888, 25, 1886, 22, 1883, 982, 980, 977, 974, 32, 30, 991, 989,
+ 987, 984, 34, 995, 994, 992, 2151, 2150, 2147, 2146, 2144, 356, 355, 354, 2149, 2139, 2138, 2136, 2134, 1359,
+ 343, 341, 338, 2143, 335, 2141, 348, 347, 346, 1376, 1374, 2124, 2123, 2121, 2119, 1326, 2116, 1324, 310, 308,
+ 305, 2131, 302, 2129, 298, 2127, 320, 318, 316, 313, 2133, 322, 321, 1355, 1353, 1351, 1357, 2092, 2091, 2089,
+ 2087, 1276, 2084, 1274, 2081, 1271, 259, 2102, 256, 2100, 252, 2098, 2095, 272, 269, 2108, 266, 2106, 281, 279,
+ 277, 1317, 1315, 1313, 1310, 282, 1321, 1319, 2039, 2037, 2035, 2032, 1203, 2029, 1200, 1197, 207, 2053, 205,
+ 2051, 201, 2049, 2046, 2043, 220, 218, 2064, 215, 2062, 211, 2059, 228, 226, 223, 2069, 1259, 1257, 1254, 232,
+ 1251, 230, 1267, 1265, 1263, 2316, 2315, 2312, 2311, 2309, 2314, 2304, 2303, 2301, 2299, 1593, 2308, 2306, 590,
+ 2288, 2287, 2285, 2283, 1578, 2280, 1577, 2295, 2293, 2291, 579, 577, 574, 571, 2298, 582, 581, 1592, 2263, 2262,
+ 2260, 2258, 1545, 2255, 1544, 2252, 1541, 2273, 2271, 2269, 2266, 1550, 535, 532, 2279, 528, 2277, 546, 543, 549,
+ 1575, 1573, 2224, 2222, 2220, 1486, 2217, 1485, 2214, 1482, 1479, 2238, 2236, 2234, 2231, 1496, 2228, 1492, 480,
+ 477, 2248, 473, 2246, 469, 2243, 490, 487, 2251, 497, 1537, 1535, 1532, 2477, 2476, 2474, 2479, 2469, 2468, 2466,
+ 2464, 1730, 2473, 2471, 2453, 2452, 2450, 2448, 1729, 2445, 1728, 2460, 2458, 2456, 2463, 805, 804, 2428, 2427,
+ 2425, 2423, 1725, 2420, 1724, 2417, 1722, 2438, 2436, 2434, 2431, 1727, 2444, 2442, 793, 791, 788, 795, 2388,
+ 2386, 2384, 1697, 2381, 1696, 2378, 1694, 1692, 2402, 2400, 2398, 2395, 1703, 2392, 1701, 2412, 2410, 2407, 751,
+ 748, 744, 2416, 759, 757, 1807, 2620, 2618, 1806, 1805, 2611, 2609, 2607, 2614, 1802, 1801, 1799, 2594, 2592,
+ 2590, 2587, 1804, 2600, 2598, 1794, 1793, 1791, 1789, 2564, 2562, 2560, 2557, 1798, 2554, 1796, 2574, 2572, 2569,
+ 2578, 1847, 1846, 2722, 1843, 1842, 1840, 1845, 2716, 2714, 1835, 1834, 1832, 1830, 1839, 1837, 2700, 2698, 2695,
+ 2704, 1817, 1811, 1810, 897, 862, 1777, 829, 826, 838, 1760, 1758, 808, 2481, 1741, 1740, 1738, 1743, 2624, 1818,
+ 2726, 2776, 782, 740, 737, 1715, 686, 679, 695, 1682, 1680, 639, 628, 2339, 647, 644, 1645, 1643, 1640, 1648,
+ 602, 600, 597, 595, 2320, 593, 2318, 609, 607, 604, 1611, 1610, 1608, 1606, 613, 1615, 1613, 2328, 926, 924, 892,
+ 886, 899, 857, 850, 2505, 1778, 824, 823, 821, 819, 2488, 818, 2486, 833, 831, 828, 840, 1761, 1759, 2649, 2632,
+ 2630, 2746, 2734, 2732, 2782, 2781, 570, 567, 1587, 531, 527, 523, 540, 1566, 1564, 476, 467, 463, 2240, 486,
+ 483, 1524, 1521, 1518, 1529, 411, 403, 2192, 399, 2189, 423, 416, 1462, 1457, 1454, 428, 1468, 1465, 2210, 366,
+ 363, 2158, 360, 2156, 357, 2153, 376, 373, 370, 2163, 1410, 1409, 1407, 1405, 382, 1402, 380, 1417, 1415, 1412,
+ 1421, 2175, 2174, 777, 774, 771, 784, 732, 725, 722, 2404, 743, 1716, 676, 674, 668, 2363, 665, 2360, 685, 1684,
+ 1681, 626, 624, 622, 2335, 620, 2333, 617, 2330, 641, 635, 649, 1646, 1644, 1642, 2566, 928, 925, 2530, 2527,
+ 894, 891, 888, 2501, 2499, 2496, 858, 856, 854, 851, 1779, 2692, 2668, 2665, 2645, 2643, 2640, 2651, 2768, 2759,
+ 2757, 2744, 2743, 2741, 2748, 352, 1382, 340, 337, 333, 1371, 1369, 307, 300, 296, 2126, 315, 312, 1347, 1342,
+ 1350, 261, 258, 250, 2097, 246, 2094, 271, 268, 264, 1306, 1301, 1298, 276, 1312, 1309, 2115, 203, 2048, 195,
+ 2045, 191, 2041, 213, 209, 2056, 1246, 1244, 1238, 225, 1234, 222, 1256, 1253, 1249, 1262, 2080, 2079, 154, 1997,
+ 150, 1995, 147, 1992, 1989, 163, 160, 2004, 156, 2001, 1175, 1174, 1172, 1170, 1167, 170, 1164, 167, 1185, 1183,
+ 1180, 1177, 174, 1190, 1188, 2025, 2024, 2022, 587, 586, 564, 559, 556, 2290, 573, 1588, 520, 518, 512, 2268,
+ 508, 2265, 530, 1568, 1565, 461, 457, 2233, 450, 2230, 446, 2226, 479, 471, 489, 1526, 1523, 1520, 397, 395,
+ 2185, 392, 2183, 389, 2180, 2177, 410, 2194, 402, 422, 1463, 1461, 1459, 1456, 1470, 2455, 799, 2433, 2430, 779,
+ 776, 773, 2397, 2394, 2390, 734, 728, 724, 746, 1717, 2356, 2354, 2351, 2348, 1658, 677, 675, 673, 670, 667, 688,
+ 1685, 1683, 2606, 2589, 2586, 2559, 2556, 2552, 927, 2523, 2521, 2518, 2515, 1784, 2532, 895, 893, 890, 2718,
+ 2709, 2707, 2689, 2687, 2684, 2663, 2662, 2660, 2658, 1825, 2667, 2769, 1852, 2760, 2758, 142, 141, 1139, 1138,
+ 134, 132, 129, 126, 1982, 1129, 1128, 1126, 1131, 113, 111, 108, 105, 1972, 101, 1970, 120, 118, 115, 1109, 1108,
+ 1106, 1104, 123, 1113, 1111, 82, 79, 1951, 75, 1949, 72, 1946, 92, 89, 86, 1956, 1077, 1076, 1074, 1072, 98,
+ 1069, 96, 1084, 1082, 1079, 1088, 1968, 1967, 48, 45, 1916, 42, 1914, 39, 1911, 1908, 60, 57, 54, 1923, 50, 1920,
+ 1031, 1030, 1028, 1026, 67, 1023, 65, 1020, 62, 1041, 1039, 1036, 1033, 69, 1046, 1044, 1944, 1943, 1941, 11, 9,
+ 1868, 7, 1865, 1862, 1859, 20, 1878, 16, 1875, 13, 1872, 970, 968, 966, 963, 29, 960, 26, 23, 983, 981, 978, 975,
+ 33, 971, 31, 990, 988, 985, 1906, 1904, 1902, 993, 351, 2145, 1383, 331, 330, 328, 326, 2137, 323, 2135, 339,
+ 1372, 1370, 294, 293, 291, 289, 2122, 286, 2120, 283, 2117, 309, 303, 317, 1348, 1346, 1344, 245, 244, 242, 2090,
+ 239, 2088, 236, 2085, 2082, 260, 2099, 249, 270, 1307, 1305, 1303, 1300, 1314, 189, 2038, 186, 2036, 183, 2033,
+ 2030, 2026, 206, 198, 2047, 194, 216, 1247, 1245, 1243, 1240, 227, 1237, 1255, 2310, 2302, 2300, 2286, 2284,
+ 2281, 565, 563, 561, 558, 575, 1589, 2261, 2259, 2256, 2253, 1542, 521, 519, 517, 514, 2270, 511, 533, 1569,
+ 1567, 2223, 2221, 2218, 2215, 1483, 2211, 1480, 459, 456, 453, 2232, 449, 474, 491, 1527, 1525, 1522, 2475, 2467,
+ 2465, 2451, 2449, 2446, 801, 800, 2426, 2424, 2421, 2418, 1723, 2435, 780, 778, 775, 2387, 2385, 2382, 2379,
+ 1695, 2375, 1693, 2396, 735, 733, 730, 727, 749, 1718, 2616, 2615, 2604, 2603, 2601, 2584, 2583, 2581, 2579,
+ 1800, 2591, 2550, 2549, 2547, 2545, 1792, 2542, 1790, 2558, 929, 2719, 1841, 2710, 2708, 1833, 1831, 2690, 2688,
+ 2686, 1815, 1809, 1808, 1774, 1756, 1754, 1737, 1736, 1734, 1739, 1816, 1711, 1676, 1674, 633, 629, 1638, 1636,
+ 1633, 1641, 598, 1605, 1604, 1602, 1600, 605, 1609, 1607, 2327, 887, 853, 1775, 822, 820, 1757, 1755, 1584, 524,
+ 1560, 1558, 468, 464, 1514, 1511, 1508, 1519, 408, 404, 400, 1452, 1447, 1444, 417, 1458, 1455, 2208, 364, 361,
+ 358, 2154, 1401, 1400, 1398, 1396, 374, 1393, 371, 1408, 1406, 1403, 1413, 2173, 2172, 772, 726, 723, 1712, 672,
+ 669, 666, 682, 1678, 1675, 625, 623, 621, 618, 2331, 636, 632, 1639, 1637, 1635, 920, 918, 884, 880, 889, 849,
+ 848, 847, 846, 2497, 855, 852, 1776, 2641, 2742, 2787, 1380, 334, 1367, 1365, 301, 297, 1340, 1338, 1335, 1343,
+ 255, 251, 247, 1296, 1291, 1288, 265, 1302, 1299, 2113, 204, 196, 192, 2042, 1232, 1230, 1224, 214, 1220, 210,
+ 1242, 1239, 1235, 1250, 2077, 2075, 151, 148, 1993, 144, 1990, 1163, 1162, 1160, 1158, 1155, 161, 1152, 157,
+ 1173, 1171, 1168, 1165, 168, 1181, 1178, 2021, 2020, 2018, 2023, 585, 560, 557, 1585, 516, 509, 1562, 1559, 458,
+ 447, 2227, 472, 1516, 1513, 1510, 398, 396, 393, 390, 2181, 386, 2178, 407, 1453, 1451, 1449, 1446, 420, 1460,
+ 2209, 769, 764, 720, 712, 2391, 729, 1713, 664, 663, 661, 659, 2352, 656, 2349, 671, 1679, 1677, 2553, 922, 919,
+ 2519, 2516, 885, 883, 881, 2685, 2661, 2659, 2767, 2756, 2755, 140, 1137, 1136, 130, 127, 1125, 1124, 1122, 1127,
+ 109, 106, 102, 1103, 1102, 1100, 1098, 116, 1107, 1105, 1980, 80, 76, 73, 1947, 1068, 1067, 1065, 1063, 90, 1060,
+ 87, 1075, 1073, 1070, 1080, 1966, 1965, 46, 43, 40, 1912, 36, 1909, 1019, 1018, 1016, 1014, 58, 1011, 55, 1008,
+ 51, 1029, 1027, 1024, 1021, 63, 1037, 1034, 1940, 1939, 1937, 1942, 8, 1866, 4, 1863, 1, 1860, 956, 954, 952,
+ 949, 946, 17, 14, 969, 967, 964, 961, 27, 957, 24, 979, 976, 972, 1901, 1900, 1898, 1896, 986, 1905, 1903, 350,
+ 349, 1381, 329, 327, 324, 1368, 1366, 292, 290, 287, 284, 2118, 304, 1341, 1339, 1337, 1345, 243, 240, 237, 2086,
+ 233, 2083, 254, 1297, 1295, 1293, 1290, 1304, 2114, 190, 187, 184, 2034, 180, 2031, 177, 2027, 199, 1233, 1231,
+ 1229, 1226, 217, 1223, 1241, 2078, 2076, 584, 555, 554, 552, 550, 2282, 562, 1586, 507, 506, 504, 502, 2257, 499,
+ 2254, 515, 1563, 1561, 445, 443, 441, 2219, 438, 2216, 435, 2212, 460, 454, 475, 1517, 1515, 1512, 2447, 798,
+ 797, 2422, 2419, 770, 768, 766, 2383, 2380, 2376, 721, 719, 717, 714, 731, 1714, 2602, 2582, 2580, 2548, 2546,
+ 2543, 923, 921, 2717, 2706, 2705, 2683, 2682, 2680, 1771, 1752, 1750, 1733, 1732, 1731, 1735, 1814, 1707, 1670,
+ 1668, 1631, 1629, 1626, 1634, 1599, 1598, 1596, 1594, 1603, 1601, 2326, 1772, 1753, 1751, 1581, 1554, 1552, 1504,
+ 1501, 1498, 1509, 1442, 1437, 1434, 401, 1448, 1445, 2206, 1392, 1391, 1389, 1387, 1384, 359, 1399, 1397, 1394,
+ 1404, 2171, 2170, 1708, 1672, 1669, 619, 1632, 1630, 1628, 1773, 1378, 1363, 1361, 1333, 1328, 1336, 1286, 1281,
+ 1278, 248, 1292, 1289, 2111, 1218, 1216, 1210, 197, 1206, 193, 1228, 1225, 1221, 1236, 2073, 2071, 1151, 1150,
+ 1148, 1146, 152, 1143, 149, 1140, 145, 1161, 1159, 1156, 1153, 158, 1169, 1166, 2017, 2016, 2014, 2019, 1582,
+ 510, 1556, 1553, 452, 448, 1506, 1500, 394, 391, 387, 1443, 1441, 1439, 1436, 1450, 2207, 765, 716, 713, 1709,
+ 662, 660, 657, 1673, 1671, 916, 914, 879, 878, 877, 882, 1135, 1134, 1121, 1120, 1118, 1123, 1097, 1096, 1094,
+ 1092, 103, 1101, 1099, 1979, 1059, 1058, 1056, 1054, 77, 1051, 74, 1066, 1064, 1061, 1071, 1964, 1963, 1007,
+ 1006, 1004, 1002, 999, 41, 996, 37, 1017, 1015, 1012, 1009, 52, 1025, 1022, 1936, 1935, 1933, 1938, 942, 940,
+ 938, 935, 932, 5, 2, 955, 953, 950, 947, 18, 943, 15, 965, 962, 958, 1895, 1894, 1892, 1890, 973, 1899, 1897,
+ 1379, 325, 1364, 1362, 288, 285, 1334, 1332, 1330, 241, 238, 234, 1287, 1285, 1283, 1280, 1294, 2112, 188, 185,
+ 181, 178, 2028, 1219, 1217, 1215, 1212, 200, 1209, 1227, 2074, 2072, 583, 553, 551, 1583, 505, 503, 500, 513,
+ 1557, 1555, 444, 442, 439, 436, 2213, 455, 451, 1507, 1505, 1502, 796, 763, 762, 760, 767, 711, 710, 708, 706,
+ 2377, 718, 715, 1710, 2544, 917, 915, 2681, 1627, 1597, 1595, 2325, 1769, 1749, 1747, 1499, 1438, 1435, 2204,
+ 1390, 1388, 1385, 1395, 2169, 2167, 1704, 1665, 1662, 1625, 1623, 1620, 1770, 1329, 1282, 1279, 2109, 1214, 1207,
+ 1222, 2068, 2065, 1149, 1147, 1144, 1141, 146, 1157, 1154, 2013, 2011, 2008, 2015, 1579, 1549, 1546, 1495, 1487,
+ 1433, 1431, 1428, 1425, 388, 1440, 2205, 1705, 658, 1667, 1664, 1119, 1095, 1093, 1978, 1057, 1055, 1052, 1062,
+ 1962, 1960, 1005, 1003, 1000, 997, 38, 1013, 1010, 1932, 1930, 1927, 1934, 941, 939, 936, 933, 6, 930, 3, 951,
+ 948, 944, 1889, 1887, 1884, 1881, 959, 1893, 1891, 35, 1377, 1360, 1358, 1327, 1325, 1322, 1331, 1277, 1275,
+ 1272, 1269, 235, 1284, 2110, 1205, 1204, 1201, 1198, 182, 1195, 179, 1213, 2070, 2067, 1580, 501, 1551, 1548,
+ 440, 437, 1497, 1494, 1490, 1503, 761, 709, 707, 1706, 913, 912, 2198, 1386, 2164, 2161, 1621, 1766, 2103, 1208,
+ 2058, 2054, 1145, 1142, 2005, 2002, 1999, 2009, 1488, 1429, 1426, 2200, 1698, 1659, 1656, 1975, 1053, 1957, 1954,
+ 1001, 998, 1924, 1921, 1918, 1928, 937, 934, 931, 1879, 1876, 1873, 1870, 945, 1885, 1882, 1323, 1273, 1270,
+ 2105, 1202, 1199, 1196, 1211, 2061, 2057, 1576, 1543, 1540, 1484, 1481, 1478, 1491, 1700};
diff --git a/ZXingObjC/pdf417/ZXPDF417Reader.h b/ZXingObjC/pdf417/ZXPDF417Reader.h
new file mode 100644
index 0000000..37fb031
--- /dev/null
+++ b/ZXingObjC/pdf417/ZXPDF417Reader.h
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXMultipleBarcodeReader.h"
+#import "ZXReader.h"
+
+/**
+ * This implementation can detect and decode PDF417 codes in an image.
+ */
+
+@class ZXDecodeHints, ZXResult;
+
+@interface ZXPDF417Reader : NSObject <ZXReader, ZXMultipleBarcodeReader>
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error;
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/pdf417/ZXPDF417Reader.m b/ZXingObjC/pdf417/ZXPDF417Reader.m
new file mode 100644
index 0000000..df191b3
--- /dev/null
+++ b/ZXingObjC/pdf417/ZXPDF417Reader.m
@@ -0,0 +1,127 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXBinaryBitmap.h"
+#import "ZXBitMatrix.h"
+#import "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXDetectorResult.h"
+#import "ZXErrors.h"
+#import "ZXPDF417Common.h"
+#import "ZXPDF417Detector.h"
+#import "ZXPDF417DetectorResult.h"
+#import "ZXPDF417Reader.h"
+#import "ZXPDF417ResultMetadata.h"
+#import "ZXPDF417ScanningDecoder.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+@implementation ZXPDF417Reader
+
+/**
+ * Locates and decodes a PDF417 code in an image.
+ */
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decode:image hints:nil error:error];
+}
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ NSArray *result = [self decode:image hints:hints multiple:NO error:error];
+ if (!result || result.count == 0 || !result[0]) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ return result[0];
+}
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decodeMultiple:image hints:nil error:error];
+}
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ return [self decode:image hints:hints multiple:YES error:error];
+}
+
+- (NSArray *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints multiple:(BOOL)multiple error:(NSError **)error {
+ NSMutableArray *results = [NSMutableArray array];
+ ZXPDF417DetectorResult *detectorResult = [ZXPDF417Detector detect:image hints:hints multiple:multiple error:error];
+ if (!detectorResult) {
+ return nil;
+ }
+ for (NSArray *points in detectorResult.points) {
+ ZXResultPoint *imageTopLeft = points[4] == [NSNull null] ? nil : points[4];
+ ZXResultPoint *imageBottomLeft = points[5] == [NSNull null] ? nil : points[5];
+ ZXResultPoint *imageTopRight = points[6] == [NSNull null] ? nil : points[6];
+ ZXResultPoint *imageBottomRight = points[7] == [NSNull null] ? nil : points[7];
+
+ ZXDecoderResult *decoderResult = [ZXPDF417ScanningDecoder decode:detectorResult.bits
+ imageTopLeft:imageTopLeft
+ imageBottomLeft:imageBottomLeft
+ imageTopRight:imageTopRight
+ imageBottomRight:imageBottomRight
+ minCodewordWidth:[self minCodewordWidth:points]
+ maxCodewordWidth:[self maxCodewordWidth:points]];
+ if (!decoderResult) {
+ return nil;
+ }
+ ZXResult *result = [[ZXResult alloc] initWithText:decoderResult.text rawBytes:decoderResult.rawBytes
+ length:decoderResult.length resultPoints:points format:kBarcodeFormatPDF417];
+ [result putMetadata:kResultMetadataTypeErrorCorrectionLevel value:decoderResult.ecLevel];
+ ZXPDF417ResultMetadata *pdf417ResultMetadata = decoderResult.other;
+ if (pdf417ResultMetadata) {
+ [result putMetadata:kResultMetadataTypePDF417ExtraMetadata value:pdf417ResultMetadata];
+ }
+ [results addObject:result];
+ }
+ return [NSArray arrayWithArray:results];
+}
+
+- (int)maxWidth:(ZXResultPoint *)p1 p2:(ZXResultPoint *)p2 {
+ if (!p1 || !p2 || (id)p1 == [NSNull null] || p2 == (id)[NSNull null]) {
+ return 0;
+ }
+ return abs(p1.x - p2.x);
+}
+
+- (int)minWidth:(ZXResultPoint *)p1 p2:(ZXResultPoint *)p2 {
+ if (!p1 || !p2 || (id)p1 == [NSNull null] || p2 == (id)[NSNull null]) {
+ return INT_MAX;
+ }
+ return abs(p1.x - p2.x);
+}
+
+- (int)maxCodewordWidth:(NSArray *)p {
+ return MAX(
+ MAX([self maxWidth:p[0] p2:p[4]], [self maxWidth:p[6] p2:p[2]] * ZXPDF417_MODULES_IN_CODEWORD /
+ ZXPDF417_MODULES_IN_STOP_PATTERN),
+ MAX([self maxWidth:p[1] p2:p[5]], [self maxWidth:p[7] p2:p[3]] * ZXPDF417_MODULES_IN_CODEWORD /
+ ZXPDF417_MODULES_IN_STOP_PATTERN));
+}
+
+- (int)minCodewordWidth:(NSArray *)p {
+ return MIN(
+ MIN([self minWidth:p[0] p2:p[4]], [self minWidth:p[6] p2:p[2]] * ZXPDF417_MODULES_IN_CODEWORD /
+ ZXPDF417_MODULES_IN_STOP_PATTERN),
+ MIN([self minWidth:p[1] p2:p[5]], [self minWidth:p[7] p2:p[3]] * ZXPDF417_MODULES_IN_CODEWORD /
+ ZXPDF417_MODULES_IN_STOP_PATTERN));
+}
+
+- (void)reset {
+ // nothing needs to be reset
+}
+
+@end
diff --git a/ZXingObjC/pdf417/ZXPDF417ResultMetadata.h b/ZXingObjC/pdf417/ZXPDF417ResultMetadata.h
new file mode 100644
index 0000000..1660049
--- /dev/null
+++ b/ZXingObjC/pdf417/ZXPDF417ResultMetadata.h
@@ -0,0 +1,24 @@
+/*
+ * 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 ZXPDF417ResultMetadata : NSObject
+
+@property (nonatomic, assign) int segmentIndex;
+@property (nonatomic, copy) NSString *fileId;
+@property (nonatomic, strong) NSArray *optionalData;
+@property (nonatomic, assign) BOOL lastSegment;
+
+@end
diff --git a/ZXingObjC/pdf417/ZXPDF417ResultMetadata.m b/ZXingObjC/pdf417/ZXPDF417ResultMetadata.m
new file mode 100644
index 0000000..c5e2d8a
--- /dev/null
+++ b/ZXingObjC/pdf417/ZXPDF417ResultMetadata.m
@@ -0,0 +1,21 @@
+/*
+ * 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 "ZXPDF417ResultMetadata.h"
+
+@implementation ZXPDF417ResultMetadata
+
+@end
diff --git a/ZXingObjC/pdf417/ZXPDF417Writer.h b/ZXingObjC/pdf417/ZXPDF417Writer.h
new file mode 100644
index 0000000..669f330
--- /dev/null
+++ b/ZXingObjC/pdf417/ZXPDF417Writer.h
@@ -0,0 +1,22 @@
+/*
+ * 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 "ZXCompaction.h"
+#import "ZXWriter.h"
+
+@interface ZXPDF417Writer : NSObject <ZXWriter>
+
+@end
diff --git a/ZXingObjC/pdf417/ZXPDF417Writer.m b/ZXingObjC/pdf417/ZXPDF417Writer.m
new file mode 100644
index 0000000..8ee0300
--- /dev/null
+++ b/ZXingObjC/pdf417/ZXPDF417Writer.m
@@ -0,0 +1,144 @@
+/*
+ * 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 "ZXBarcodeMatrix.h"
+#import "ZXBitMatrix.h"
+#import "ZXEncodeHints.h"
+#import "ZXPDF417.h"
+#import "ZXPDF417Writer.h"
+
+@implementation ZXPDF417Writer
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height
+ hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if (format != kBarcodeFormatPDF417) {
+ [NSException raise:NSInvalidArgumentException format:@"Can only encode PDF_417, but got %d", format];
+ }
+
+ ZXPDF417 *encoder = [[ZXPDF417 alloc] init];
+
+ if (hints != nil) {
+ encoder.compact = hints.pdf417Compact;
+ encoder.compaction = hints.pdf417Compaction;
+ if (hints.pdf417Dimensions != nil) {
+ ZXDimensions *dimensions = hints.pdf417Dimensions;
+ [encoder setDimensionsWithMaxCols:dimensions.maxCols
+ minCols:dimensions.minCols
+ maxRows:dimensions.maxRows
+ minRows:dimensions.minRows];
+ }
+ }
+
+ return [self bitMatrixFromEncoder:encoder contents:contents width:width height:height error:error];
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error {
+ return [self encode:contents format:format width:width height:height hints:nil error:error];
+}
+
+/**
+ * Takes encoder, accounts for width/height, and retrieves bit matrix
+ */
+- (ZXBitMatrix *)bitMatrixFromEncoder:(ZXPDF417 *)encoder contents:(NSString *)contents width:(int)width height:(int)height error:(NSError **)error {
+ int errorCorrectionLevel = 2;
+ if (![encoder generateBarcodeLogic:contents errorCorrectionLevel:errorCorrectionLevel error:error]) {
+ return nil;
+ }
+
+ int lineThickness = 2;
+ int aspectRatio = 4;
+
+ int scaleHeight;
+ int scaleWidth;
+ int8_t **originalScale = [[encoder barcodeMatrix] scaledMatrixWithHeight:&scaleHeight width:&scaleWidth xScale:lineThickness yScale:aspectRatio * lineThickness];
+ BOOL rotated = NO;
+ if ((height > width) ^ (scaleWidth < scaleHeight)) {
+ int8_t **oldOriginalScale = originalScale;
+ originalScale = [self rotateArray:oldOriginalScale height:scaleHeight width:scaleWidth];
+ free(oldOriginalScale);
+ rotated = YES;
+ }
+
+ int scaleX = width / scaleWidth;
+ int scaleY = height / scaleHeight;
+
+ int scale;
+ if (scaleX < scaleY) {
+ scale = scaleX;
+ } else {
+ scale = scaleY;
+ }
+
+ ZXBitMatrix *result = nil;
+ if (scale > 1) {
+ int8_t **scaledMatrix =
+ [[encoder barcodeMatrix] scaledMatrixWithHeight:&scaleHeight width:&scaleWidth xScale:scale * lineThickness yScale:scale * aspectRatio * lineThickness];
+ if (rotated) {
+ int8_t **oldScaledMatrix = scaledMatrix;
+ scaledMatrix = [self rotateArray:scaledMatrix height:scaleHeight width:scaleWidth];
+ free(oldScaledMatrix);
+ }
+ result = [self bitMatrixFrombitArray:scaledMatrix height:scaleHeight width:scaleWidth];
+ free(scaledMatrix);
+ } else {
+ result = [self bitMatrixFrombitArray:originalScale height:scaleHeight width:scaleWidth];
+ }
+ free(originalScale);
+ return result;
+}
+
+/**
+ * This takes an array holding the values of the PDF 417
+ */
+- (ZXBitMatrix *)bitMatrixFrombitArray:(int8_t **)input height:(int)height width:(int)width {
+ // Creates a small whitespace boarder around the barcode
+ int whiteSpace = 30;
+
+ // Creates the bitmatrix with extra space for whtespace
+ ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:width + 2 * whiteSpace height:height + 2 * whiteSpace];
+ [output clear];
+ for (int y = 0, yOutput = output.height - whiteSpace; y < height; y++, yOutput--) {
+ for (int x = 0; x < width; x++) {
+ // Zero is white in the bytematrix
+ if (input[y][x] == 1) {
+ [output setX:x + whiteSpace y:yOutput];
+ }
+ }
+ }
+ return output;
+}
+
+/**
+ * Takes and rotates the it 90 degrees
+ */
+- (int8_t **)rotateArray:(int8_t **)bitarray height:(int)height width:(int)width {
+ int8_t **temp = (int8_t **)malloc(width * sizeof(int8_t *));
+ for (int i = 0; i < width; i++) {
+ temp[i] = (int8_t *)malloc(height * sizeof(int8_t));
+ }
+
+ for (int ii = 0; ii < height; ii++) {
+ // This makes the direction consistent on screen when rotating the
+ // screen;
+ int inverseii = height - ii - 1;
+ for (int jj = 0; jj < width; jj++) {
+ temp[jj][inverseii] = bitarray[ii][jj];
+ }
+ }
+ return temp;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.h b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.h
new file mode 100644
index 0000000..f2fb7d9
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.h
@@ -0,0 +1,28 @@
+/*
+ * 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 ZXPDF417BarcodeMetadata : NSObject
+
+@property (nonatomic, assign, readonly) int columnCount;
+@property (nonatomic, assign, readonly) int errorCorrectionLevel;
+@property (nonatomic, assign, readonly) int rowCountUpperPart;
+@property (nonatomic, assign, readonly) int rowCountLowerPart;
+@property (nonatomic, assign, readonly) int rowCount;
+
+- (id)initWithColumnCount:(int)columnCount rowCountUpperPart:(int)rowCountUpperPart rowCountLowerPart:(int)rowCountLowerPart
+ errorCorrectionLevel:(int)errorCorrectionLevel;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.m b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.m
new file mode 100644
index 0000000..1173bbe
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.m
@@ -0,0 +1,35 @@
+/*
+ * 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 "ZXPDF417BarcodeMetadata.h"
+
+@implementation ZXPDF417BarcodeMetadata
+
+- (id)initWithColumnCount:(int)columnCount rowCountUpperPart:(int)rowCountUpperPart rowCountLowerPart:(int)rowCountLowerPart
+ errorCorrectionLevel:(int)errorCorrectionLevel {
+ self = [super init];
+ if (self) {
+ _columnCount = columnCount;
+ _errorCorrectionLevel = errorCorrectionLevel;
+ _rowCountUpperPart = rowCountUpperPart;
+ _rowCountLowerPart = rowCountLowerPart;
+ _rowCount = rowCountUpperPart + rowCountLowerPart;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h
new file mode 100644
index 0000000..9855c74
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h
@@ -0,0 +1,23 @@
+/*
+ * 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 ZXPDF417BarcodeValue : NSObject
+
+- (void)setValue:(int)value;
+- (NSArray *)value;
+- (NSNumber *)confidence:(int)value;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.m b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.m
new file mode 100644
index 0000000..ae4794a
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.m
@@ -0,0 +1,69 @@
+/*
+ * 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 "ZXPDF417BarcodeValue.h"
+
+@interface ZXPDF417BarcodeValue ()
+
+@property (nonatomic, strong) NSMutableDictionary *values;
+
+@end
+
+@implementation ZXPDF417BarcodeValue
+
+- (id)init {
+ self = [super init];
+ if (self) {
+ _values = [NSMutableDictionary dictionary];
+ }
+
+ return self;
+}
+
+- (void)setValue:(int)value {
+ NSNumber *confidence = self.values[@(value)];
+ if (!confidence) {
+ confidence = @0;
+ }
+ confidence = @([confidence intValue] + 1);
+ self.values[@(value)] = confidence;
+}
+
+/**
+ * Determines the maximum occurrence of a set value and returns all values which were set with this occurrence.
+ * Returns an array of int, containing the values with the highest occurrence, or null, if no value was set
+ */
+- (NSArray *)value {
+ int maxConfidence = -1;
+ NSMutableArray *result = [NSMutableArray array];
+ for (NSNumber *key in [self.values allKeys]) {
+ NSNumber *value = self.values[key];
+ if ([value intValue] > maxConfidence) {
+ maxConfidence = [value intValue];
+ [result removeAllObjects];
+ [result addObject:key];
+ } else if ([value intValue] == maxConfidence) {
+ [result addObject:key];
+ }
+ }
+ return [[[result sortedArrayUsingSelector:@selector(compare:)] reverseObjectEnumerator] allObjects];
+}
+
+- (NSNumber *)confidence:(int)value {
+ return self.values[@(value)];
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.h b/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.h
new file mode 100644
index 0000000..5772d97
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+@class ZXBitMatrix, ZXResultPoint;
+
+@interface ZXPDF417BoundingBox : NSObject
+
+@property (nonatomic, assign, readonly) int minX;
+@property (nonatomic, assign, readonly) int maxX;
+@property (nonatomic, assign, readonly) int minY;
+@property (nonatomic, assign, readonly) int maxY;
+@property (nonatomic, strong, readonly) ZXResultPoint *topLeft;
+@property (nonatomic, strong) ZXResultPoint *topRight;
+@property (nonatomic, strong, readonly) ZXResultPoint *bottomLeft;
+@property (nonatomic, strong) ZXResultPoint *bottomRight;
+
+- (id)initWithImage:(ZXBitMatrix *)image topLeft:(ZXResultPoint *)topLeft bottomLeft:(ZXResultPoint *)bottomLeft
+ topRight:(ZXResultPoint *)topRight bottomRight:(ZXResultPoint *)bottomRight;
+- (id)initWithBoundingBox:(ZXPDF417BoundingBox *)boundingBox;
+
++ (ZXPDF417BoundingBox *)mergeLeftBox:(ZXPDF417BoundingBox *)leftBox rightBox:(ZXPDF417BoundingBox *)rightBox;
+- (ZXPDF417BoundingBox *)addMissingRows:(int)missingStartRows missingEndRows:(int)missingEndRows isLeft:(BOOL)isLeft;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.m b/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.m
new file mode 100644
index 0000000..7b44b8c
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.m
@@ -0,0 +1,133 @@
+/*
+ * 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 "ZXBitMatrix.h"
+#import "ZXPDF417BoundingBox.h"
+#import "ZXResultPoint.h"
+
+@interface ZXPDF417BoundingBox ()
+
+@property (nonatomic, strong) ZXBitMatrix *image;
+@property (nonatomic, assign) int minX;
+@property (nonatomic, assign) int maxX;
+@property (nonatomic, assign) int minY;
+@property (nonatomic, assign) int maxY;
+
+@end
+
+@implementation ZXPDF417BoundingBox
+
+- (id)initWithImage:(ZXBitMatrix *)image topLeft:(ZXResultPoint *)topLeft bottomLeft:(ZXResultPoint *)bottomLeft
+ topRight:(ZXResultPoint *)topRight bottomRight:(ZXResultPoint *)bottomRight {
+ if ((!topLeft && !topRight) || (!bottomLeft && !bottomRight) ||
+ (topLeft && !bottomLeft) || (topRight && !bottomRight)) {
+ return nil;
+ }
+
+ self = [super init];
+ if (self) {
+ _image = image;
+ _topLeft = topLeft;
+ _bottomLeft = bottomLeft;
+ _topRight = topRight;
+ _bottomRight = bottomRight;
+ [self calculateMinMaxValues];
+ }
+
+ return self;
+}
+
+- (id)initWithBoundingBox:(ZXPDF417BoundingBox *)boundingBox {
+ return [self initWithImage:boundingBox.image topLeft:boundingBox.topLeft bottomLeft:boundingBox.bottomLeft
+ topRight:boundingBox.topRight bottomRight:boundingBox.bottomRight];
+}
+
++ (ZXPDF417BoundingBox *)mergeLeftBox:(ZXPDF417BoundingBox *)leftBox rightBox:(ZXPDF417BoundingBox *)rightBox {
+ if (!leftBox) {
+ return rightBox;
+ }
+ if (!rightBox) {
+ return leftBox;
+ }
+ return [[self alloc] initWithImage:leftBox.image topLeft:leftBox.topLeft bottomLeft:leftBox.bottomLeft
+ topRight:rightBox.topRight bottomRight:rightBox.bottomRight];
+}
+
+- (ZXPDF417BoundingBox *)addMissingRows:(int)missingStartRows missingEndRows:(int)missingEndRows isLeft:(BOOL)isLeft {
+ ZXResultPoint *newTopLeft = self.topLeft;
+ ZXResultPoint *newBottomLeft = self.bottomLeft;
+ ZXResultPoint *newTopRight = self.topRight;
+ ZXResultPoint *newBottomRight = self.bottomRight;
+
+ if (missingStartRows > 0) {
+ ZXResultPoint *top = isLeft ? self.topLeft : self.topRight;
+ int newMinY = (int) top.y - missingStartRows;
+ if (newMinY < 0) {
+ newMinY = 0;
+ }
+ // TODO use existing points to better interpolate the new x positions
+ ZXResultPoint *newTop = [[ZXResultPoint alloc] initWithX:top.x y:newMinY];
+ if (isLeft) {
+ newTopLeft = newTop;
+ } else {
+ newTopRight = newTop;
+ }
+ }
+
+ if (missingEndRows > 0) {
+ ZXResultPoint *bottom = isLeft ? self.bottomLeft : self.bottomRight;
+ int newMaxY = (int) bottom.y + missingEndRows;
+ if (newMaxY >= self.image.height) {
+ newMaxY = self.image.height - 1;
+ }
+ // TODO use existing points to better interpolate the new x positions
+ ZXResultPoint *newBottom = [[ZXResultPoint alloc] initWithX:bottom.x y:newMaxY];
+ if (isLeft) {
+ newBottomLeft = newBottom;
+ } else {
+ newBottomRight = newBottom;
+ }
+ }
+ [self calculateMinMaxValues];
+ return [[ZXPDF417BoundingBox alloc] initWithImage:self.image topLeft:newTopLeft bottomLeft:newBottomLeft topRight:newTopRight bottomRight:newBottomRight];
+}
+
+- (void)calculateMinMaxValues {
+ if (!self.topLeft) {
+ _topLeft = [[ZXResultPoint alloc] initWithX:0 y:self.topRight.y];
+ _bottomLeft = [[ZXResultPoint alloc] initWithX:0 y:self.bottomRight.y];
+ } else if (!self.topRight) {
+ _topRight = [[ZXResultPoint alloc] initWithX:self.image.width - 1 y:self.topLeft.y];
+ _bottomRight = [[ZXResultPoint alloc] initWithX:self.image.width - 1 y:self.bottomLeft.y];
+ }
+
+ self.minX = (int) MIN(self.topLeft.x, self.bottomLeft.x);
+ self.maxX = (int) MAX(self.topRight.x, self.bottomRight.x);
+ self.minY = (int) MIN(self.topLeft.y, self.topRight.y);
+ self.maxY = (int) MAX(self.bottomLeft.y, self.bottomRight.y);
+}
+
+- (void)setTopRight:(ZXResultPoint *)topRight {
+ _topRight = topRight;
+ [self calculateMinMaxValues];
+}
+
+- (void)setBottomRight:(ZXResultPoint *)bottomRight {
+ _bottomRight = bottomRight;
+ [self calculateMinMaxValues];
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.h b/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.h
new file mode 100644
index 0000000..d64bf47
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.h
@@ -0,0 +1,31 @@
+/*
+ * 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 ZXPDF417Codeword : NSObject
+
+@property (nonatomic, assign, readonly) int startX;
+@property (nonatomic, assign, readonly) int endX;
+@property (nonatomic, assign, readonly) int bucket;
+@property (nonatomic, assign, readonly) int value;
+@property (nonatomic, assign) int rowNumber;
+
+- (id)initWithStartX:(int)startX endX:(int)endX bucket:(int)bucket value:(int)value;
+- (BOOL)hasValidRowNumber;
+- (BOOL)isValidRowNumber:(int)rowNumber;
+- (void)setRowNumberAsRowIndicatorColumn;
+- (int)width;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.m b/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.m
new file mode 100644
index 0000000..ca59137
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.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 "ZXPDF417Codeword.h"
+
+const int BARCODE_ROW_UNKNOWN = -1;
+
+@implementation ZXPDF417Codeword
+
+- (id)initWithStartX:(int)startX endX:(int)endX bucket:(int)bucket value:(int)value {
+ self = [super init];
+ if (self) {
+ _startX = startX;
+ _endX = endX;
+ _bucket = bucket;
+ _value = value;
+ _rowNumber = BARCODE_ROW_UNKNOWN;
+ }
+
+ return self;
+}
+
+- (BOOL)hasValidRowNumber {
+ return [self isValidRowNumber:self.rowNumber];
+}
+
+- (BOOL)isValidRowNumber:(int)rowNumber {
+ return rowNumber != BARCODE_ROW_UNKNOWN && self.bucket == (rowNumber % 3) * 3;
+}
+
+- (void)setRowNumberAsRowIndicatorColumn {
+ self.rowNumber = (self.value / 30) * 3 + self.bucket / 3;
+}
+
+- (int)width {
+ return self.endX - self.startX;
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%d|%d", self.rowNumber, self.value];
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.h b/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.h
new file mode 100644
index 0000000..a50e347
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.h
@@ -0,0 +1,21 @@
+/*
+ * 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 ZXPDF417CodewordDecoder : NSObject
+
++ (int)decodedValue:(NSArray *)moduleBitCount;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m b/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m
new file mode 100644
index 0000000..cf7895d
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m
@@ -0,0 +1,108 @@
+/*
+ * 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 "ZXPDF417CodewordDecoder.h"
+#import "ZXPDF417Common.h"
+
+static float ZXPDF417_RATIOS_TABLE[ZXPDF417_SYMBOL_TABLE_LEN][ZXPDF417_BARS_IN_MODULE];
+
+@implementation ZXPDF417CodewordDecoder
+
++ (void)initialize {
+ // Pre-computes the symbol ratio table.
+ for (int i = 0; i < ZXPDF417_SYMBOL_TABLE_LEN; i++) {
+ int currentSymbol = ZXPDF417_SYMBOL_TABLE[i];
+ int currentBit = currentSymbol & 0x1;
+ for (int j = 0; j < ZXPDF417_BARS_IN_MODULE; j++) {
+ float size = 0.0f;
+ while ((currentSymbol & 0x1) == currentBit) {
+ size += 1.0f;
+ currentSymbol >>= 1;
+ }
+ currentBit = currentSymbol & 0x1;
+ ZXPDF417_RATIOS_TABLE[i][ZXPDF417_BARS_IN_MODULE - j - 1] = size / ZXPDF417_MODULES_IN_CODEWORD;
+ }
+ }
+}
+
++ (int)decodedValue:(NSArray *)moduleBitCount {
+ int decodedValue = [self decodedCodewordValue:[self sampleBitCounts:moduleBitCount]];
+ if (decodedValue != -1) {
+ return decodedValue;
+ }
+ return [self closestDecodedValue:moduleBitCount];
+}
+
++ (NSArray *)sampleBitCounts:(NSArray *)moduleBitCount {
+ float bitCountSum = [ZXPDF417Common bitCountSum:moduleBitCount];
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:ZXPDF417_BARS_IN_MODULE];
+ for (int i = 0; i < ZXPDF417_BARS_IN_MODULE; i++) {
+ [result addObject:@0];
+ }
+
+ int bitCountIndex = 0;
+ int sumPreviousBits = 0;
+ for (int i = 0; i < ZXPDF417_MODULES_IN_CODEWORD; i++) {
+ float sampleIndex =
+ bitCountSum / (2 * ZXPDF417_MODULES_IN_CODEWORD) +
+ (i * bitCountSum) / ZXPDF417_MODULES_IN_CODEWORD;
+ if (sumPreviousBits + [moduleBitCount[bitCountIndex] intValue] <= sampleIndex) {
+ sumPreviousBits += [moduleBitCount[bitCountIndex] intValue];
+ bitCountIndex++;
+ }
+ result[bitCountIndex] = @([result[bitCountIndex] intValue] + 1);
+ }
+ return result;
+}
+
++ (int)decodedCodewordValue:(NSArray *)moduleBitCount {
+ int decodedValue = [self bitValue:moduleBitCount];
+ return [ZXPDF417Common codeword:decodedValue] == -1 ? -1 : decodedValue;
+}
+
++ (int)bitValue:(NSArray *)moduleBitCount {
+ long result = 0;
+ for (int i = 0; i < [moduleBitCount count]; i++) {
+ for (int bit = 0; bit < [moduleBitCount[i] intValue]; bit++) {
+ result = (result << 1) | (i % 2 == 0 ? 1 : 0);
+ }
+ }
+ return (int) result;
+}
+
++ (int)closestDecodedValue:(NSArray *)moduleBitCount {
+ int bitCountSum = [ZXPDF417Common bitCountSum:moduleBitCount];
+ float bitCountRatios[ZXPDF417_BARS_IN_MODULE];
+ for (int i = 0; i < ZXPDF417_BARS_IN_MODULE; i++) {
+ bitCountRatios[i] = [moduleBitCount[i] intValue] / (float) bitCountSum;
+ }
+ float bestMatchError = MAXFLOAT;
+ int bestMatch = -1;
+ for (int j = 0; j < ZXPDF417_SYMBOL_TABLE_LEN; j++) {
+ float error = 0.0f;
+ for (int k = 0; k < ZXPDF417_BARS_IN_MODULE; k++) {
+ float diff = ZXPDF417_RATIOS_TABLE[j][k] - bitCountRatios[k];
+ error += diff * diff;
+ }
+ if (error < bestMatchError) {
+ bestMatchError = error;
+ bestMatch = ZXPDF417_SYMBOL_TABLE[j];
+ }
+ }
+ return bestMatch;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.h b/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.h
new file mode 100644
index 0000000..4490de2
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/**
+ * This class contains the methods for decoding the PDF417 codewords.
+ */
+
+@class ZXDecoderResult;
+
+@interface ZXPDF417DecodedBitStreamParser : NSObject
+
++ (ZXDecoderResult *)decode:(NSArray *)codewords ecLevel:(NSString *)ecLevel error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m b/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m
new file mode 100644
index 0000000..594c803
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m
@@ -0,0 +1,600 @@
+/*
+ * 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 "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXPDF417DecodedBitStreamParser.h"
+#import "ZXPDF417ResultMetadata.h"
+
+enum {
+ ALPHA,
+ LOWER,
+ MIXED,
+ PUNCT,
+ ALPHA_SHIFT,
+ PUNCT_SHIFT
+};
+
+int const TEXT_COMPACTION_MODE_LATCH = 900;
+int const BYTE_COMPACTION_MODE_LATCH = 901;
+int const NUMERIC_COMPACTION_MODE_LATCH = 902;
+int const BYTE_COMPACTION_MODE_LATCH_6 = 924;
+int const BEGIN_MACRO_PDF417_CONTROL_BLOCK = 928;
+int const BEGIN_MACRO_PDF417_OPTIONAL_FIELD = 923;
+int const MACRO_PDF417_TERMINATOR = 922;
+int const MODE_SHIFT_TO_BYTE_COMPACTION_MODE = 913;
+int const MAX_NUMERIC_CODEWORDS = 15;
+
+int const PL = 25;
+int const LL = 27;
+int const AS = 27;
+int const ML = 28;
+int const AL = 28;
+int const PS = 29;
+int const PAL = 29;
+
+char const PUNCT_CHARS[29] = {
+ ';', '<', '>', '@', '[', '\\', '}', '_', '`', '~', '!',
+ '\r', '\t', ',', ':', '\n', '-', '.', '$', '/', '"', '|', '*',
+ '(', ')', '?', '{', '}', '\''};
+
+char const MIXED_CHARS[25] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '&',
+ '\r', '\t', ',', ':', '#', '-', '.', '$', '/', '+', '%', '*',
+ '=', '^'};
+
+int const NUMBER_OF_SEQUENCE_CODEWORDS = 2;
+
+/**
+ * Table containing values for the exponent of 900.
+ * This is used in the numeric compaction decode algorithm.
+ */
+static NSArray *EXP900 = nil;
+
+@implementation ZXPDF417DecodedBitStreamParser
+
++ (void)initialize {
+ NSMutableArray *exponents = [NSMutableArray arrayWithCapacity:16];
+ [exponents addObject:[NSDecimalNumber one]];
+ NSDecimalNumber *nineHundred = [NSDecimalNumber decimalNumberWithString:@"900"];
+ [exponents addObject:nineHundred];
+ for (int i = 2; i < 16; i++) {
+ [exponents addObject:[exponents[i - 1] decimalNumberByMultiplyingBy:nineHundred]];
+ }
+ EXP900 = [[NSArray alloc] initWithArray:exponents];
+}
+
++ (ZXDecoderResult *)decode:(NSArray *)codewords ecLevel:(NSString *)ecLevel error:(NSError **)error {
+ if (!codewords) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ NSMutableString *result = [NSMutableString stringWithCapacity:codewords.count * 2];
+ // Get compaction mode
+ int codeIndex = 1;
+ int code = [codewords[codeIndex++] intValue];
+ ZXPDF417ResultMetadata *resultMetadata = [[ZXPDF417ResultMetadata alloc] init];
+ while (codeIndex < [codewords[0] intValue]) {
+ switch (code) {
+ case TEXT_COMPACTION_MODE_LATCH:
+ codeIndex = [self textCompaction:codewords codeIndex:codeIndex result:result];
+ break;
+ case BYTE_COMPACTION_MODE_LATCH:
+ codeIndex = [self byteCompaction:code codewords:codewords codeIndex:codeIndex result:result];
+ break;
+ case NUMERIC_COMPACTION_MODE_LATCH:
+ codeIndex = [self numericCompaction:codewords codeIndex:codeIndex result:result];
+ break;
+ case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
+ codeIndex = [self byteCompaction:code codewords:codewords codeIndex:codeIndex result:result];
+ break;
+ case BYTE_COMPACTION_MODE_LATCH_6:
+ codeIndex = [self byteCompaction:code codewords:codewords codeIndex:codeIndex result:result];
+ break;
+ case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
+ codeIndex = [self decodeMacroBlock:codewords codeIndex:codeIndex resultMetadata:resultMetadata];
+ if (codeIndex < 0) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ break;
+ default:
+ // Default to text compaction. During testing numerous barcodes
+ // appeared to be missing the starting mode. In these cases defaulting
+ // to text compaction seems to work.
+ codeIndex--;
+ codeIndex = [self textCompaction:codewords codeIndex:codeIndex result:result];
+ break;
+ }
+ if (codeIndex < [codewords count]) {
+ code = [codewords[codeIndex++] intValue];
+ } else {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ }
+ if ([result length] == 0) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ ZXDecoderResult *decoderResult = [[ZXDecoderResult alloc] initWithRawBytes:NULL length:0 text:result byteSegments:nil ecLevel:ecLevel];
+ decoderResult.other = resultMetadata;
+ return decoderResult;
+}
+
++ (int)decodeMacroBlock:(NSArray *)codewords codeIndex:(int)codeIndex resultMetadata:(ZXPDF417ResultMetadata *)resultMetadata {
+ if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > [codewords[0] intValue]) {
+ // we must have at least two bytes left for the segment index
+ return -1;
+ }
+ int segmentIndexArray[NUMBER_OF_SEQUENCE_CODEWORDS];
+ memset(segmentIndexArray, 0, NUMBER_OF_SEQUENCE_CODEWORDS * sizeof(int));
+ for (int i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
+ segmentIndexArray[i] = [codewords[codeIndex] intValue];
+ }
+ resultMetadata.segmentIndex = [[self decodeBase900toBase10:segmentIndexArray count:NUMBER_OF_SEQUENCE_CODEWORDS] intValue];
+
+ NSMutableString *fileId = [NSMutableString string];
+ codeIndex = [self textCompaction:codewords codeIndex:codeIndex result:fileId];
+ resultMetadata.fileId = [NSString stringWithString:fileId];
+
+ if ([codewords[codeIndex] intValue] == BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
+ codeIndex++;
+ NSMutableArray *additionalOptionCodeWords = [NSMutableArray array];
+
+ BOOL end = NO;
+ while ((codeIndex < [codewords[0] intValue]) && !end) {
+ int code = [codewords[codeIndex++] intValue];
+ if (code < TEXT_COMPACTION_MODE_LATCH) {
+ [additionalOptionCodeWords addObject:@(code)];
+ } else {
+ switch (code) {
+ case MACRO_PDF417_TERMINATOR:
+ resultMetadata.lastSegment = YES;
+ codeIndex++;
+ end = YES;
+ break;
+ default:
+ return -1;
+ }
+ }
+ }
+
+ resultMetadata.optionalData = additionalOptionCodeWords;
+ } else if ([codewords[codeIndex] intValue] == MACRO_PDF417_TERMINATOR) {
+ resultMetadata.lastSegment = YES;
+ codeIndex++;
+ }
+
+ return codeIndex;
+}
+
+/**
+ * Text Compaction mode (see 5.4.1.5) permits all printable ASCII characters to be
+ * encoded, i.e. values 32 - 126 inclusive in accordance with ISO/IEC 646 (IRV), as
+ * well as selected control characters.
+ */
++ (int)textCompaction:(NSArray *)codewords codeIndex:(int)codeIndex result:(NSMutableString *)result {
+ int count = ([codewords[0] intValue] - codeIndex) << 1;
+ // 2 character per codeword
+ int textCompactionData[count];
+ // Used to hold the byte compaction value if there is a mode shift
+ int byteCompactionData[count];
+
+ for (int i = 0; i < count; i++) {
+ textCompactionData[0] = 0;
+ byteCompactionData[0] = 0;
+ }
+
+ int index = 0;
+ BOOL end = NO;
+ while ((codeIndex < [codewords[0] intValue]) && !end) {
+ int code = [codewords[codeIndex++] intValue];
+ if (code < TEXT_COMPACTION_MODE_LATCH) {
+ textCompactionData[index] = code / 30;
+ textCompactionData[index + 1] = code % 30;
+ index += 2;
+ } else {
+ switch (code) {
+ case TEXT_COMPACTION_MODE_LATCH:
+ // reinitialize text compaction mode to alpha sub mode
+ textCompactionData[index++] = TEXT_COMPACTION_MODE_LATCH;
+ break;
+ case BYTE_COMPACTION_MODE_LATCH:
+ codeIndex--;
+ end = YES;
+ break;
+ case NUMERIC_COMPACTION_MODE_LATCH:
+ codeIndex--;
+ end = YES;
+ break;
+ case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
+ codeIndex--;
+ end = YES;
+ break;
+ case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
+ codeIndex--;
+ end = YES;
+ break;
+ case MACRO_PDF417_TERMINATOR:
+ codeIndex--;
+ end = YES;
+ break;
+ case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
+ // The Mode Shift codeword 913 shall cause a temporary
+ // switch from Text Compaction mode to Byte Compaction mode.
+ // This switch shall be in effect for only the next codeword,
+ // after which the mode shall revert to the prevailing sub-mode
+ // of the Text Compaction mode. Codeword 913 is only available
+ // in Text Compaction mode; its use is described in 5.4.2.4.
+ textCompactionData[index] = MODE_SHIFT_TO_BYTE_COMPACTION_MODE;
+ code = [codewords[codeIndex++] intValue];
+ byteCompactionData[index] = code;
+ index++;
+ break;
+ case BYTE_COMPACTION_MODE_LATCH_6:
+ codeIndex--;
+ end = YES;
+ break;
+ }
+ }
+ }
+
+ [self decodeTextCompaction:textCompactionData byteCompactionData:byteCompactionData length:index result:result];
+ return codeIndex;
+}
+
+
+/**
+ * The Text Compaction mode includes all the printable ASCII characters
+ * (i.e. values from 32 to 126) and three ASCII control characters: HT or tab
+ * (ASCII value 9), LF or line feed (ASCII value 10), and CR or carriage
+ * return (ASCII value 13). The Text Compaction mode also includes various latch
+ * and shift characters which are used exclusively within the mode. The Text
+ * Compaction mode encodes up to 2 characters per codeword. The compaction rules
+ * for converting data into PDF417 codewords are defined in 5.4.2.2. The sub-mode
+ * switches are defined in 5.4.2.3.
+ */
++ (void)decodeTextCompaction:(int *)textCompactionData byteCompactionData:(int *)byteCompactionData length:(unsigned int)length result:(NSMutableString *)result {
+ // Beginning from an initial state of the Alpha sub-mode
+ // The default compaction mode for PDF417 in effect at the start of each symbol shall always be Text
+ // Compaction mode Alpha sub-mode (uppercase alphabetic). A latch codeword from another mode to the Text
+ // Compaction mode shall always switch to the Text Compaction Alpha sub-mode.
+ int subMode = ALPHA;
+ int priorToShiftMode = ALPHA;
+ int i = 0;
+ while (i < length) {
+ int subModeCh = textCompactionData[i];
+ unichar ch = 0;
+ switch (subMode) {
+ case ALPHA:
+ // Alpha (uppercase alphabetic)
+ if (subModeCh < 26) {
+ // Upper case Alpha Character
+ ch = (unichar)('A' + subModeCh);
+ } else {
+ if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == LL) {
+ subMode = LOWER;
+ } else if (subModeCh == ML) {
+ subMode = MIXED;
+ } else if (subModeCh == PS) {
+ // Shift to punctuation
+ priorToShiftMode = subMode;
+ subMode = PUNCT_SHIFT;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ [result appendFormat:@"%C", (unichar)byteCompactionData[i]];
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+
+ case LOWER:
+ // Lower (lowercase alphabetic)
+ if (subModeCh < 26) {
+ ch = (unichar)('a' + subModeCh);
+ } else {
+ if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == AS) {
+ // Shift to alpha
+ priorToShiftMode = subMode;
+ subMode = ALPHA_SHIFT;
+ } else if (subModeCh == ML) {
+ subMode = MIXED;
+ } else if (subModeCh == PS) {
+ // Shift to punctuation
+ priorToShiftMode = subMode;
+ subMode = PUNCT_SHIFT;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ [result appendFormat:@"%C", (unichar)byteCompactionData[i]];
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+
+ case MIXED:
+ // Mixed (numeric and some punctuation)
+ if (subModeCh < PL) {
+ ch = MIXED_CHARS[subModeCh];
+ } else {
+ if (subModeCh == PL) {
+ subMode = PUNCT;
+ } else if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == LL) {
+ subMode = LOWER;
+ } else if (subModeCh == AL) {
+ subMode = ALPHA;
+ } else if (subModeCh == PS) {
+ // Shift to punctuation
+ priorToShiftMode = subMode;
+ subMode = PUNCT_SHIFT;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ [result appendFormat:@"%C", (unichar)byteCompactionData[i]];
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+
+ case PUNCT:
+ // Punctuation
+ if (subModeCh < PAL) {
+ ch = PUNCT_CHARS[subModeCh];
+ } else {
+ if (subModeCh == PAL) {
+ subMode = ALPHA;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ [result appendFormat:@"%C", (unichar)byteCompactionData[i]];
+ } else if (TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+
+ case ALPHA_SHIFT:
+ // Restore sub-mode
+ subMode = priorToShiftMode;
+ if (subModeCh < 26) {
+ ch = (unichar)('A' + subModeCh);
+ } else {
+ if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+
+ case PUNCT_SHIFT:
+ // Restore sub-mode
+ subMode = priorToShiftMode;
+ if (subModeCh < PAL) {
+ ch = PUNCT_CHARS[subModeCh];
+ } else {
+ if (subModeCh == PAL) {
+ subMode = ALPHA;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ // PS before Shift-to-Byte is used as a padding character,
+ // see 5.4.2.4 of the specification
+ [result appendFormat:@"%C", (unichar)byteCompactionData[i]];
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+ }
+ if (ch != 0) {
+ // Append decoded character to result
+ [result appendFormat:@"%C", ch];
+ }
+ i++;
+ }
+}
+
+
+/**
+ * Byte Compaction mode (see 5.4.3) permits all 256 possible 8-bit byte values to be encoded.
+ * This includes all ASCII characters value 0 to 127 inclusive and provides for international
+ * character set support.
+ */
++ (int)byteCompaction:(int)mode codewords:(NSArray *)codewords codeIndex:(int)codeIndex result:(NSMutableString *)result {
+ if (mode == BYTE_COMPACTION_MODE_LATCH) {
+ // Total number of Byte Compaction characters to be encoded
+ // is not a multiple of 6
+ int count = 0;
+ long long value = 0;
+ char decodedData[6] = {0, 0, 0, 0, 0, 0};
+ int byteCompactedCodewords[6] = {0, 0, 0, 0, 0, 0};
+ BOOL end = NO;
+ int nextCode = [codewords[codeIndex++] intValue];
+ while ((codeIndex < [codewords[0] intValue]) && !end) {
+ byteCompactedCodewords[count++] = nextCode;
+ // Base 900
+ value = 900 * value + nextCode;
+ nextCode = [codewords[codeIndex++] intValue];
+ // perhaps it should be ok to check only nextCode >= TEXT_COMPACTION_MODE_LATCH
+ if (nextCode == TEXT_COMPACTION_MODE_LATCH ||
+ nextCode == BYTE_COMPACTION_MODE_LATCH ||
+ nextCode == NUMERIC_COMPACTION_MODE_LATCH ||
+ nextCode == BYTE_COMPACTION_MODE_LATCH_6 ||
+ nextCode == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
+ nextCode == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
+ nextCode == MACRO_PDF417_TERMINATOR) {
+ codeIndex--;
+ end = YES;
+ } else {
+ if ((count % 5 == 0) && (count > 0)) {
+ // Decode every 5 codewords
+ // Convert to Base 256
+ for (int j = 0; j < 6; ++j) {
+ decodedData[5 - j] = (char) (value % 256);
+ value >>= 8;
+ }
+ [result appendString:[[NSString alloc] initWithBytes:decodedData length:6 encoding:NSISOLatin1StringEncoding]];
+ count = 0;
+ }
+ }
+ }
+
+ // if the end of all codewords is reached the last codeword needs to be added
+ if (codeIndex == [codewords[0] intValue] && nextCode < TEXT_COMPACTION_MODE_LATCH) {
+ byteCompactedCodewords[count++] = nextCode;
+ }
+
+ // If Byte Compaction mode is invoked with codeword 901,
+ // the last group of codewords is interpreted directly
+ // as one byte per codeword, without compaction.
+ for (int i = 0; i < count; i++) {
+ [result appendFormat:@"%C", (unichar)byteCompactedCodewords[i]];
+ }
+ } else if (mode == BYTE_COMPACTION_MODE_LATCH_6) {
+ // Total number of Byte Compaction characters to be encoded
+ // is an integer multiple of 6
+ int count = 0;
+ long long value = 0;
+ BOOL end = NO;
+ while (codeIndex < [codewords[0] intValue] && !end) {
+ int code = [codewords[codeIndex++] intValue];
+ if (code < TEXT_COMPACTION_MODE_LATCH) {
+ count++;
+ // Base 900
+ value = 900 * value + code;
+ } else {
+ if (code == TEXT_COMPACTION_MODE_LATCH ||
+ code == BYTE_COMPACTION_MODE_LATCH ||
+ code == NUMERIC_COMPACTION_MODE_LATCH ||
+ code == BYTE_COMPACTION_MODE_LATCH_6 ||
+ code == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
+ code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
+ code == MACRO_PDF417_TERMINATOR) {
+ codeIndex--;
+ end = YES;
+ }
+ }
+ if ((count % 5 == 0) && (count > 0)) {
+ // Decode every 5 codewords
+ // Convert to Base 256
+ unichar decodedData[6];
+ for (int j = 0; j < 6; ++j) {
+ decodedData[5 - j] = (unichar)(value & 0xFF);
+ value >>= 8;
+ }
+ [result appendString:[NSString stringWithCharacters:decodedData length:6]];
+ count = 0;
+ }
+ }
+ }
+ return codeIndex;
+}
+
+/**
+ * Numeric Compaction mode (see 5.4.4) permits efficient encoding of numeric data strings.
+ */
++ (int)numericCompaction:(NSArray *)codewords codeIndex:(int)codeIndex result:(NSMutableString *)result {
+ int count = 0;
+ BOOL end = NO;
+
+ int numericCodewords[MAX_NUMERIC_CODEWORDS];
+ memset(numericCodewords, 0, MAX_NUMERIC_CODEWORDS * sizeof(int));
+
+ while (codeIndex < [codewords[0] intValue] && !end) {
+ int code = [codewords[codeIndex++] intValue];
+ if (codeIndex == [codewords[0] intValue]) {
+ end = YES;
+ }
+ if (code < TEXT_COMPACTION_MODE_LATCH) {
+ numericCodewords[count] = code;
+ count++;
+ } else {
+ if (code == TEXT_COMPACTION_MODE_LATCH ||
+ code == BYTE_COMPACTION_MODE_LATCH ||
+ code == BYTE_COMPACTION_MODE_LATCH_6 ||
+ code == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
+ code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
+ code == MACRO_PDF417_TERMINATOR) {
+ codeIndex--;
+ end = YES;
+ }
+ }
+ if (count % MAX_NUMERIC_CODEWORDS == 0 || code == NUMERIC_COMPACTION_MODE_LATCH || end) {
+ NSString *s = [self decodeBase900toBase10:numericCodewords count:count];
+ if (s == nil) {
+ return INT_MAX;
+ }
+ [result appendString:s];
+ count = 0;
+ }
+ }
+ return codeIndex;
+}
+
+/**
+ * Convert a list of Numeric Compacted codewords from Base 900 to Base 10.
+ */
+/*
+ EXAMPLE
+ Encode the fifteen digit numeric string 000213298174000
+ Prefix the numeric string with a 1 and set the initial value of
+ t = 1 000 213 298 174 000
+ Calculate codeword 0
+ d0 = 1 000 213 298 174 000 mod 900 = 200
+
+ t = 1 000 213 298 174 000 div 900 = 1 111 348 109 082
+ Calculate codeword 1
+ d1 = 1 111 348 109 082 mod 900 = 282
+
+ t = 1 111 348 109 082 div 900 = 1 234 831 232
+ Calculate codeword 2
+ d2 = 1 234 831 232 mod 900 = 632
+
+ t = 1 234 831 232 div 900 = 1 372 034
+ Calculate codeword 3
+ d3 = 1 372 034 mod 900 = 434
+
+ t = 1 372 034 div 900 = 1 524
+ Calculate codeword 4u
+ d4 = 1 524 mod 900 = 624
+
+ t = 1 524 div 900 = 1
+ Calculate codeword 5
+ d5 = 1 mod 900 = 1
+ t = 1 div 900 = 0
+ Codeword sequence is: 1, 624, 434, 632, 282, 200
+
+ Decode the above codewords involves
+ 1 x 900 power of 5 + 624 x 900 power of 4 + 434 x 900 power of 3 +
+ 632 x 900 power of 2 + 282 x 900 power of 1 + 200 x 900 power of 0 = 1000213298174000
+
+ Remove leading 1 => Result is 000213298174000
+ */
++ (NSString *)decodeBase900toBase10:(int[])codewords count:(int)count {
+ NSDecimalNumber *result = [NSDecimalNumber zero];
+ for (int i = 0; i < count; i++) {
+ result = [result decimalNumberByAdding:[EXP900[count - i - 1] decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithDecimal:[@(codewords[i]) decimalValue]]]];
+ }
+ NSString *resultString = [result stringValue];
+ if (![resultString hasPrefix:@"1"]) {
+ return nil;
+ }
+ return [resultString substringFromIndex:1];
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.h b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.h
new file mode 100644
index 0000000..33c9d44
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+@class ZXPDF417BoundingBox, ZXPDF417DetectionResultColumn;
+
+@interface ZXPDF417DetectionResult : NSObject
+
+@property (nonatomic, strong) ZXPDF417BoundingBox *boundingBox;
+
+- (id)initWithBarcodeMetadata:(ZXPDF417BarcodeMetadata *)barcodeMetadata boundingBox:(ZXPDF417BoundingBox *)boundingBox;
+- (NSArray *)detectionResultColumns;
+- (int)barcodeColumnCount;
+- (int)barcodeRowCount;
+- (int)barcodeECLevel;
+- (void)setDetectionResultColumn:(int)barcodeColumn detectionResultColumn:(ZXPDF417DetectionResultColumn *)detectionResultColumn;
+- (ZXPDF417DetectionResultColumn *)detectionResultColumn:(int)barcodeColumn;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.m b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.m
new file mode 100644
index 0000000..101ee93
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.m
@@ -0,0 +1,308 @@
+/*
+ * 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 "ZXPDF417BarcodeMetadata.h"
+#import "ZXPDF417BoundingBox.h"
+#import "ZXPDF417Codeword.h"
+#import "ZXPDF417Common.h"
+#import "ZXPDF417DetectionResult.h"
+#import "ZXPDF417DetectionResultColumn.h"
+#import "ZXPDF417DetectionResultRowIndicatorColumn.h"
+
+int const ADJUST_ROW_NUMBER_SKIP = 2;
+
+@interface ZXPDF417DetectionResult ()
+
+@property (nonatomic, strong) ZXPDF417BarcodeMetadata *barcodeMetadata;
+@property (nonatomic, strong) NSMutableArray *detectionResultColumnsInternal;
+@property (nonatomic, assign) int barcodeColumnCount;
+
+@end
+
+@implementation ZXPDF417DetectionResult
+
+- (id)initWithBarcodeMetadata:(ZXPDF417BarcodeMetadata *)barcodeMetadata boundingBox:(ZXPDF417BoundingBox *)boundingBox {
+ self = [super init];
+ if (self) {
+ _barcodeMetadata = barcodeMetadata;
+ _barcodeColumnCount = barcodeMetadata.columnCount;
+ _boundingBox = boundingBox;
+ _detectionResultColumnsInternal = [NSMutableArray arrayWithCapacity:_barcodeColumnCount + 2];
+ for (int i = 0; i < _barcodeColumnCount + 2; i++) {
+ [_detectionResultColumnsInternal addObject:[NSNull null]];
+ }
+ }
+
+ return self;
+}
+
+- (NSArray *)detectionResultColumns {
+ [self adjustIndicatorColumnRowNumbers:self.detectionResultColumnsInternal[0]];
+ [self adjustIndicatorColumnRowNumbers:self.detectionResultColumnsInternal[self.barcodeColumnCount + 1]];
+ int unadjustedCodewordCount = ZXPDF417_MAX_CODEWORDS_IN_BARCODE;
+ int previousUnadjustedCount;
+ do {
+ previousUnadjustedCount = unadjustedCodewordCount;
+ unadjustedCodewordCount = [self adjustRowNumbers];
+ } while (unadjustedCodewordCount > 0 && unadjustedCodewordCount < previousUnadjustedCount);
+ return self.detectionResultColumnsInternal;
+}
+
+- (void)adjustIndicatorColumnRowNumbers:(ZXPDF417DetectionResultColumn *)detectionResultColumn {
+ if (detectionResultColumn && (id)detectionResultColumn != [NSNull null]) {
+ [(ZXPDF417DetectionResultRowIndicatorColumn *)detectionResultColumn adjustCompleteIndicatorColumnRowNumbers:self.barcodeMetadata];
+ }
+}
+
+// TODO ensure that no detected codewords with unknown row number are left
+// we should be able to estimate the row height and use it as a hint for the row number
+// we should also fill the rows top to bottom and bottom to top
+/**
+ * Returns the number of codewords which don't have a valid row number. Note that the count is not accurate as codewords
+ * will be counted several times. It just serves as an indicator to see when we can stop adjusting row numbers
+ */
+- (int)adjustRowNumbers {
+ int unadjustedCount = [self adjustRowNumbersByRow];
+ if (unadjustedCount == 0) {
+ return 0;
+ }
+ for (int barcodeColumn = 1; barcodeColumn < self.barcodeColumnCount + 1; barcodeColumn++) {
+ NSArray *codewords = [self.detectionResultColumnsInternal[barcodeColumn] codewords];
+ for (int codewordsRow = 0; codewordsRow < [codewords count]; codewordsRow++) {
+ if ((id)codewords[codewordsRow] == [NSNull null]) {
+ continue;
+ }
+ if (![codewords[codewordsRow] hasValidRowNumber]) {
+ [self adjustRowNumbers:barcodeColumn codewordsRow:codewordsRow codewords:codewords];
+ }
+ }
+ }
+ return unadjustedCount;
+}
+
+- (int)adjustRowNumbersByRow {
+ [self adjustRowNumbersFromBothRI];
+ // TODO we should only do full row adjustments if row numbers of left and right row indicator column match.
+ // Maybe it's even better to calculated the height (in codeword rows) and divide it by the number of barcode
+ // rows. This, together with the LRI and RRI row numbers should allow us to get a good estimate where a row
+ // number starts and ends.
+ int unadjustedCount = [self adjustRowNumbersFromLRI];
+ return unadjustedCount + [self adjustRowNumbersFromRRI];
+}
+
+- (int)adjustRowNumbersFromBothRI {
+ if (self.detectionResultColumnsInternal[0] == [NSNull null] || self.detectionResultColumnsInternal[self.barcodeColumnCount + 1] == [NSNull null]) {
+ return 0;
+ }
+ NSArray *LRIcodewords = [(ZXPDF417DetectionResultColumn *)self.detectionResultColumnsInternal[0] codewords];
+ NSArray *RRIcodewords = [(ZXPDF417DetectionResultColumn *)self.detectionResultColumnsInternal[self.barcodeColumnCount + 1] codewords];
+ for (int codewordsRow = 0; codewordsRow < [LRIcodewords count]; codewordsRow++) {
+ if (LRIcodewords[codewordsRow] != [NSNull null] &&
+ RRIcodewords[codewordsRow] != [NSNull null] &&
+ [(ZXPDF417Codeword *)LRIcodewords[codewordsRow] rowNumber] == [(ZXPDF417Codeword *)RRIcodewords[codewordsRow] rowNumber]) {
+ for (int barcodeColumn = 1; barcodeColumn <= self.barcodeColumnCount; barcodeColumn++) {
+ ZXPDF417Codeword *codeword = [(ZXPDF417DetectionResultColumn *)self.detectionResultColumnsInternal[barcodeColumn] codewords][codewordsRow];
+ if ((id)codeword == [NSNull null]) {
+ continue;
+ }
+ codeword.rowNumber = [(ZXPDF417Codeword *)LRIcodewords[codewordsRow] rowNumber];
+ if (![codeword hasValidRowNumber]) {
+ [(ZXPDF417DetectionResultColumn *)self.detectionResultColumnsInternal[barcodeColumn] codewords][codewordsRow] = [NSNull null];
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+- (int)adjustRowNumbersFromRRI {
+ if (self.detectionResultColumnsInternal[self.barcodeColumnCount + 1] == [NSNull null]) {
+ return 0;
+ }
+ int unadjustedCount = 0;
+ NSArray *codewords = [self.detectionResultColumnsInternal[self.barcodeColumnCount + 1] codewords];
+ for (int codewordsRow = 0; codewordsRow < [codewords count]; codewordsRow++) {
+ if ((id)codewords[codewordsRow] == [NSNull null]) {
+ continue;
+ }
+ int rowIndicatorRowNumber = [codewords[codewordsRow] rowNumber];
+ int invalidRowCounts = 0;
+ for (int barcodeColumn = self.barcodeColumnCount + 1; barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; barcodeColumn--) {
+ if (self.detectionResultColumnsInternal[barcodeColumn] != [NSNull null]) {
+ ZXPDF417Codeword *codeword = [self.detectionResultColumnsInternal[barcodeColumn] codewords][codewordsRow];
+ if ((id)codeword != [NSNull null]) {
+ invalidRowCounts = [self adjustRowNumberIfValid:rowIndicatorRowNumber invalidRowCounts:invalidRowCounts codeword:codeword];
+ if (![codeword hasValidRowNumber]) {
+ unadjustedCount++;
+ }
+ }
+ }
+ }
+ }
+ return unadjustedCount;
+}
+
+- (int)adjustRowNumbersFromLRI {
+ if (self.detectionResultColumnsInternal[0] == [NSNull null]) {
+ return 0;
+ }
+ int unadjustedCount = 0;
+ NSArray *codewords = [self.detectionResultColumnsInternal[0] codewords];
+ for (int codewordsRow = 0; codewordsRow < [codewords count]; codewordsRow++) {
+ if ((id)codewords[codewordsRow] == [NSNull null]) {
+ continue;
+ }
+ int rowIndicatorRowNumber = [codewords[codewordsRow] rowNumber];
+ int invalidRowCounts = 0;
+ for (int barcodeColumn = 1; barcodeColumn < self.barcodeColumnCount + 1 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; barcodeColumn++) {
+ if (self.detectionResultColumnsInternal[barcodeColumn] != [NSNull null]) {
+ ZXPDF417Codeword *codeword = [self.detectionResultColumnsInternal[barcodeColumn] codewords][codewordsRow];
+ if ((id)codeword != [NSNull null]) {
+ invalidRowCounts = [self adjustRowNumberIfValid:rowIndicatorRowNumber invalidRowCounts:invalidRowCounts codeword:codeword];
+ if (![codeword hasValidRowNumber]) {
+ unadjustedCount++;
+ }
+ }
+ }
+ }
+ }
+ return unadjustedCount;
+}
+
+- (int)adjustRowNumberIfValid:(int)rowIndicatorRowNumber invalidRowCounts:(int)invalidRowCounts codeword:(ZXPDF417Codeword *)codeword {
+ if (!codeword) {
+ return invalidRowCounts;
+ }
+ if (![codeword hasValidRowNumber]) {
+ if ([codeword isValidRowNumber:rowIndicatorRowNumber]) {
+ [codeword setRowNumber:rowIndicatorRowNumber];
+ invalidRowCounts = 0;
+ } else {
+ ++invalidRowCounts;
+ }
+ }
+ return invalidRowCounts;
+}
+
+- (void)adjustRowNumbers:(int)barcodeColumn codewordsRow:(int)codewordsRow codewords:(NSArray *)codewords {
+ ZXPDF417Codeword *codeword = codewords[codewordsRow];
+ NSArray *previousColumnCodewords = [self.detectionResultColumnsInternal[barcodeColumn - 1] codewords];
+ NSArray *nextColumnCodewords = previousColumnCodewords;
+ if (self.detectionResultColumnsInternal[barcodeColumn + 1] != [NSNull null]) {
+ nextColumnCodewords = [self.detectionResultColumnsInternal[barcodeColumn + 1] codewords];
+ }
+
+ NSMutableArray *otherCodewords = [NSMutableArray arrayWithCapacity:14];
+ for (int i = 0; i < 14; i++) {
+ [otherCodewords addObject:[NSNull null]];
+ }
+
+ otherCodewords[2] = previousColumnCodewords[codewordsRow];
+ otherCodewords[3] = nextColumnCodewords[codewordsRow];
+
+ if (codewordsRow > 0) {
+ otherCodewords[0] = codewords[codewordsRow - 1];
+ otherCodewords[4] = previousColumnCodewords[codewordsRow - 1];
+ otherCodewords[5] = nextColumnCodewords[codewordsRow - 1];
+ }
+ if (codewordsRow > 1) {
+ otherCodewords[8] = codewords[codewordsRow - 2];
+ otherCodewords[10] = previousColumnCodewords[codewordsRow - 2];
+ otherCodewords[11] = nextColumnCodewords[codewordsRow - 2];
+ }
+ if (codewordsRow < [codewords count] - 1) {
+ otherCodewords[1] = codewords[codewordsRow + 1];
+ otherCodewords[6] = previousColumnCodewords[codewordsRow + 1];
+ otherCodewords[7] = nextColumnCodewords[codewordsRow + 1];
+ }
+ if (codewordsRow < [codewords count] - 2) {
+ otherCodewords[9] = codewords[codewordsRow + 2];
+ otherCodewords[12] = previousColumnCodewords[codewordsRow + 2];
+ otherCodewords[13] = nextColumnCodewords[codewordsRow + 2];
+ }
+ for (ZXPDF417Codeword *otherCodeword in otherCodewords) {
+ if ([self adjustRowNumber:codeword otherCodeword:otherCodeword]) {
+ return;
+ }
+ }
+}
+
+/**
+ * Return true if row number was adjusted, false otherwise
+ */
+- (BOOL)adjustRowNumber:(ZXPDF417Codeword *)codeword otherCodeword:(ZXPDF417Codeword *)otherCodeword {
+ if ((id)otherCodeword == [NSNull null]) {
+ return NO;
+ }
+ if ([otherCodeword hasValidRowNumber] && otherCodeword.bucket == codeword.bucket) {
+ [codeword setRowNumber:otherCodeword.rowNumber];
+ return YES;
+ }
+ return NO;
+}
+
+- (int)barcodeColumnCount {
+ return _barcodeColumnCount;
+}
+
+- (int)barcodeRowCount {
+ return self.barcodeMetadata.rowCount;
+}
+
+- (int)barcodeECLevel {
+ return self.barcodeMetadata.errorCorrectionLevel;
+}
+
+- (void)setDetectionResultColumn:(int)barcodeColumn detectionResultColumn:(ZXPDF417DetectionResultColumn *)detectionResultColumn {
+ if (!detectionResultColumn) {
+ self.detectionResultColumnsInternal[barcodeColumn] = [NSNull null];
+ } else {
+ self.detectionResultColumnsInternal[barcodeColumn] = detectionResultColumn;
+ }
+}
+
+- (ZXPDF417DetectionResultColumn *)detectionResultColumn:(int)barcodeColumn {
+ ZXPDF417DetectionResultColumn *result = self.detectionResultColumnsInternal[barcodeColumn];
+ return (id)result == [NSNull null] ? nil : result;
+}
+
+- (NSString *)description {
+ ZXPDF417DetectionResultColumn *rowIndicatorColumn = self.detectionResultColumnsInternal[0];
+ if ((id)rowIndicatorColumn == [NSNull null]) {
+ rowIndicatorColumn = self.detectionResultColumnsInternal[self.barcodeColumnCount + 1];
+ }
+ NSMutableString *result = [NSMutableString string];
+ for (int codewordsRow = 0; codewordsRow < [rowIndicatorColumn.codewords count]; codewordsRow++) {
+ [result appendFormat:@"CW %3d:", codewordsRow];
+ for (int barcodeColumn = 0; barcodeColumn < self.barcodeColumnCount + 2; barcodeColumn++) {
+ if (self.detectionResultColumnsInternal[barcodeColumn] == [NSNull null]) {
+ [result appendString:@" | "];
+ continue;
+ }
+ ZXPDF417Codeword *codeword = [(ZXPDF417DetectionResultColumn *)self.detectionResultColumnsInternal[barcodeColumn] codewords][codewordsRow];
+ if ((id)codeword == [NSNull null]) {
+ [result appendString:@" | "];
+ continue;
+ }
+ [result appendFormat:@" %3d|%3d", codeword.rowNumber, codeword.value];
+ }
+ [result appendString:@"\n"];
+ }
+
+ return [NSString stringWithString:result];
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.h b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.h
new file mode 100644
index 0000000..78385d7
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+@class ZXPDF417BoundingBox, ZXPDF417Codeword;
+
+@interface ZXPDF417DetectionResultColumn : NSObject
+
+@property (nonatomic, strong, readonly) ZXPDF417BoundingBox *boundingBox;
+@property (nonatomic, strong, readonly) NSMutableArray *codewords;
+
+- (id)initWithBoundingBox:(ZXPDF417BoundingBox *)boundingBox;
+- (ZXPDF417Codeword *)codewordNearby:(int)imageRow;
+- (int)imageRowToCodewordIndex:(int)imageRow;
+- (int)codewordIndexToImageRow:(int)codewordIndex;
+- (void)setCodeword:(int)imageRow codeword:(ZXPDF417Codeword *)codeword;
+- (ZXPDF417Codeword *)codeword:(int)imageRow;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.m b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.m
new file mode 100644
index 0000000..b46ae7c
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.m
@@ -0,0 +1,102 @@
+/*
+ * 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 "ZXPDF417BoundingBox.h"
+#import "ZXPDF417Codeword.h"
+#import "ZXPDF417DetectionResultColumn.h"
+
+int const MAX_NEARBY_DISTANCE = 5;
+
+@interface ZXPDF417DetectionResultColumn ()
+
+@property (nonatomic, strong) ZXPDF417BoundingBox *boundingBox;
+@property (nonatomic, strong) NSMutableArray *codewords;
+
+@end
+
+@implementation ZXPDF417DetectionResultColumn
+
+- (id)initWithBoundingBox:(ZXPDF417BoundingBox *)boundingBox {
+ self = [super init];
+ if (self) {
+ _boundingBox = [[ZXPDF417BoundingBox alloc] initWithBoundingBox:boundingBox];
+ _codewords = [NSMutableArray array];
+ for (int i = 0; i < boundingBox.maxY - boundingBox.minY + 1; i++) {
+ [_codewords addObject:[NSNull null]];
+ }
+ }
+
+ return self;
+}
+
+- (ZXPDF417Codeword *)codewordNearby:(int)imageRow {
+ ZXPDF417Codeword *codeword = [self codeword:imageRow];
+ if (codeword) {
+ return codeword;
+ }
+ for (int i = 1; i < MAX_NEARBY_DISTANCE; i++) {
+ int nearImageRow = [self imageRowToCodewordIndex:imageRow] - i;
+ if (nearImageRow >= 0) {
+ codeword = self.codewords[nearImageRow];
+ if ((id)codeword != [NSNull null]) {
+ return codeword;
+ }
+ }
+ nearImageRow = [self imageRowToCodewordIndex:imageRow] + i;
+ if (nearImageRow < [self.codewords count]) {
+ codeword = self.codewords[nearImageRow];
+ if ((id)codeword != [NSNull null]) {
+ return codeword;
+ }
+ }
+ }
+ return nil;
+}
+
+- (int)imageRowToCodewordIndex:(int)imageRow {
+ return imageRow - self.boundingBox.minY;
+}
+
+- (int)codewordIndexToImageRow:(int)codewordIndex {
+ return self.boundingBox.minY + codewordIndex;
+}
+
+- (void)setCodeword:(int)imageRow codeword:(ZXPDF417Codeword *)codeword {
+ _codewords[[self imageRowToCodewordIndex:imageRow]] = codeword;
+}
+
+- (ZXPDF417Codeword *)codeword:(int)imageRow {
+ NSUInteger index = [self imageRowToCodewordIndex:imageRow];
+ if (_codewords[index] == [NSNull null]) {
+ return nil;
+ }
+ return _codewords[index];
+}
+
+- (NSString *)description {
+ NSMutableString *result = [NSMutableString string];
+ int row = 0;
+ for (ZXPDF417Codeword *codeword in self.codewords) {
+ if ((id)codeword == [NSNull null]) {
+ [result appendFormat:@"%3d: | \n", row++];
+ continue;
+ }
+ [result appendFormat:@"%3d: %3d|%3d\n", row++, codeword.rowNumber, codeword.value];
+ }
+ return [NSString stringWithString:result];
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.h b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.h
new file mode 100644
index 0000000..2b1cebe
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.h
@@ -0,0 +1,32 @@
+/*
+ * 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 "ZXPDF417DetectionResultColumn.h"
+
+@class ZXPDF417BarcodeMetadata, ZXPDF417BoundingBox;
+
+@interface ZXPDF417DetectionResultRowIndicatorColumn : ZXPDF417DetectionResultColumn
+
+@property (nonatomic, assign, readonly) BOOL isLeft;
+
+- (id)initWithBoundingBox:(ZXPDF417BoundingBox *)boundingBox isLeft:(BOOL)isLeft;
+- (void)setRowNumbers;
+- (NSArray *)rowHeights;
+- (int)adjustCompleteIndicatorColumnRowNumbers:(ZXPDF417BarcodeMetadata *)barcodeMetadata;
+- (int)adjustIncompleteIndicatorColumnRowNumbers:(ZXPDF417BarcodeMetadata *)barcodeMetadata;
+- (ZXPDF417BarcodeMetadata *)barcodeMetadata;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m
new file mode 100644
index 0000000..31d0734
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m
@@ -0,0 +1,269 @@
+/*
+ * 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 "ZXPDF417BarcodeMetadata.h"
+#import "ZXPDF417BarcodeValue.h"
+#import "ZXPDF417BoundingBox.h"
+#import "ZXPDF417Codeword.h"
+#import "ZXPDF417Common.h"
+#import "ZXPDF417DetectionResult.h"
+#import "ZXPDF417DetectionResultRowIndicatorColumn.h"
+#import "ZXResultPoint.h"
+
+@interface ZXPDF417DetectionResultRowIndicatorColumn ()
+
+@property (nonatomic, assign) BOOL isLeft;
+
+@end
+
+@implementation ZXPDF417DetectionResultRowIndicatorColumn
+
+- (id)initWithBoundingBox:(ZXPDF417BoundingBox *)boundingBox isLeft:(BOOL)isLeft {
+ self = [super initWithBoundingBox:boundingBox];
+ if (self) {
+ _isLeft = isLeft;
+ }
+
+ return self;
+}
+
+- (void)setRowNumbers {
+ for (ZXPDF417Codeword *codeword in [self codewords]) {
+ if ((id)codeword != [NSNull null]) {
+ [codeword setRowNumberAsRowIndicatorColumn];
+ }
+ }
+}
+
+// TODO implement properly
+// TODO maybe we should add missing codewords to store the correct row number to make
+// finding row numbers for other columns easier
+// use row height count to make detection of invalid row numbers more reliable
+- (int)adjustCompleteIndicatorColumnRowNumbers:(ZXPDF417BarcodeMetadata *)barcodeMetadata {
+ [self setRowNumbers];
+ [self removeIncorrectCodewords:barcodeMetadata];
+ ZXResultPoint *top = self.isLeft ? self.boundingBox.topLeft : self.boundingBox.topRight;
+ ZXResultPoint *bottom = self.isLeft ? self.boundingBox.bottomLeft : self.boundingBox.bottomRight;
+ int firstRow = [self imageRowToCodewordIndex:(int) top.y];
+ int lastRow = [self imageRowToCodewordIndex:(int) bottom.y];
+ // We need to be careful using the average row height. Barcode could be skewed so that we have smaller and
+ // taller rows
+ float averageRowHeight = (lastRow - firstRow) / (float) barcodeMetadata.rowCount;
+ int barcodeRow = -1;
+ int maxRowHeight = 1;
+ int currentRowHeight = 0;
+ for (int codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) {
+ if (self.codewords[codewordsRow] == [NSNull null]) {
+ continue;
+ }
+ ZXPDF417Codeword *codeword = self.codewords[codewordsRow];
+
+ // float expectedRowNumber = (codewordsRow - firstRow) / averageRowHeight;
+ // if (Math.abs(codeword.getRowNumber() - expectedRowNumber) > 2) {
+ // SimpleLog.log(LEVEL.WARNING,
+ // "Removing codeword, rowNumberSkew too high, codeword[" + codewordsRow + "]: Expected Row: " +
+ // expectedRowNumber + ", RealRow: " + codeword.getRowNumber() + ", value: " + codeword.getValue());
+ // codewords[codewordsRow] = null;
+ // }
+
+ int rowDifference = codeword.rowNumber - barcodeRow;
+
+ // TODO improve handling with case where first row indicator doesn't start with 0
+
+ if (rowDifference == 0) {
+ currentRowHeight++;
+ } else if (rowDifference == 1) {
+ maxRowHeight = MAX(maxRowHeight, currentRowHeight);
+ currentRowHeight = 1;
+ barcodeRow = codeword.rowNumber;
+ } else if (rowDifference < 0) {
+ self.codewords[codewordsRow] = [NSNull null];
+ } else if (codeword.rowNumber >= barcodeMetadata.rowCount) {
+ self.codewords[codewordsRow] = [NSNull null];
+ } else if (rowDifference > codewordsRow) {
+ self.codewords[codewordsRow] = [NSNull null];
+ } else {
+ int checkedRows;
+ if (maxRowHeight > 2) {
+ checkedRows = (maxRowHeight - 2) * rowDifference;
+ } else {
+ checkedRows = rowDifference;
+ }
+ BOOL closePreviousCodewordFound = checkedRows >= codewordsRow;
+ for (int i = 1; i <= checkedRows && !closePreviousCodewordFound; i++) {
+ // there must be (height * rowDifference) number of codewords missing. For now we assume height = 1.
+ // This should hopefully get rid of most problems already.
+ closePreviousCodewordFound = self.codewords[codewordsRow - i] != [NSNull null];
+ }
+ if (closePreviousCodewordFound) {
+ self.codewords[codewordsRow] = [NSNull null];
+ } else {
+ barcodeRow = codeword.rowNumber;
+ currentRowHeight = 1;
+ }
+ }
+ }
+ return (int) (averageRowHeight + 0.5);
+}
+
+- (NSArray *)rowHeights {
+ ZXPDF417BarcodeMetadata *barcodeMetadata = [self barcodeMetadata];
+ if (!barcodeMetadata) {
+ return nil;
+ }
+ [self adjustIncompleteIndicatorColumnRowNumbers:barcodeMetadata];
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:barcodeMetadata.rowCount];
+ for (int i = 0; i < barcodeMetadata.rowCount; i++) {
+ [result addObject:@0];
+ }
+
+ for (ZXPDF417Codeword *codeword in [self codewords]) {
+ if ((id)codeword != [NSNull null]) {
+ result[codeword.rowNumber] = @([result[codeword.rowNumber] intValue] + 1);
+ }
+ }
+ return result;
+}
+
+// TODO maybe we should add missing codewords to store the correct row number to make
+// finding row numbers for other columns easier
+// use row height count to make detection of invalid row numbers more reliable
+- (int)adjustIncompleteIndicatorColumnRowNumbers:(ZXPDF417BarcodeMetadata *)barcodeMetadata {
+ ZXResultPoint *top = self.isLeft ? self.boundingBox.topLeft : self.boundingBox.topRight;
+ ZXResultPoint *bottom = self.isLeft ? self.boundingBox.bottomLeft : self.boundingBox.bottomRight;
+ int firstRow = [self imageRowToCodewordIndex:(int) top.y];
+ int lastRow = [self imageRowToCodewordIndex:(int) bottom.y];
+ float averageRowHeight = (lastRow - firstRow) / (float) barcodeMetadata.rowCount;
+ int barcodeRow = -1;
+ int maxRowHeight = 1;
+ int currentRowHeight = 0;
+ for (int codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) {
+ if (self.codewords[codewordsRow] == [NSNull null]) {
+ continue;
+ }
+ ZXPDF417Codeword *codeword = self.codewords[codewordsRow];
+
+ [codeword setRowNumberAsRowIndicatorColumn];
+
+ int rowDifference = codeword.rowNumber - barcodeRow;
+
+ // TODO improve handling with case where first row indicator doesn't start with 0
+
+ if (rowDifference == 0) {
+ currentRowHeight++;
+ } else if (rowDifference == 1) {
+ maxRowHeight = MAX(maxRowHeight, currentRowHeight);
+ currentRowHeight = 1;
+ barcodeRow = codeword.rowNumber;
+ } else if (codeword.rowNumber >= barcodeMetadata.rowCount) {
+ self.codewords[codewordsRow] = [NSNull null];
+ } else {
+ barcodeRow = codeword.rowNumber;
+ currentRowHeight = 1;
+ }
+ }
+ return (int) (averageRowHeight + 0.5);
+}
+
+- (ZXPDF417BarcodeMetadata *)barcodeMetadata {
+ ZXPDF417BarcodeValue *barcodeColumnCount = [[ZXPDF417BarcodeValue alloc] init];
+ ZXPDF417BarcodeValue *barcodeRowCountUpperPart = [[ZXPDF417BarcodeValue alloc] init];
+ ZXPDF417BarcodeValue *barcodeRowCountLowerPart = [[ZXPDF417BarcodeValue alloc] init];
+ ZXPDF417BarcodeValue *barcodeECLevel = [[ZXPDF417BarcodeValue alloc] init];
+ for (ZXPDF417Codeword *codeword in self.codewords) {
+ if ((id)codeword == [NSNull null]) {
+ continue;
+ }
+ [codeword setRowNumberAsRowIndicatorColumn];
+ int rowIndicatorValue = codeword.value % 30;
+ int codewordRowNumber = codeword.rowNumber;
+ if (!self.isLeft) {
+ codewordRowNumber += 2;
+ }
+ switch (codewordRowNumber % 3) {
+ case 0:
+ [barcodeRowCountUpperPart setValue:rowIndicatorValue * 3 + 1];
+ break;
+ case 1:
+ [barcodeECLevel setValue:rowIndicatorValue / 3];
+ [barcodeRowCountLowerPart setValue:rowIndicatorValue % 3];
+ break;
+ case 2:
+ [barcodeColumnCount setValue:rowIndicatorValue + 1];
+ break;
+ }
+ }
+ // Maybe we should check if we have ambiguous values?
+ if (([[barcodeColumnCount value] count] == 0) ||
+ ([[barcodeRowCountUpperPart value] count] == 0) ||
+ ([[barcodeRowCountLowerPart value] count] == 0) ||
+ ([[barcodeECLevel value] count] == 0) ||
+ [[barcodeColumnCount value][0] intValue] < 1 ||
+ [[barcodeRowCountUpperPart value][0] intValue] + [[barcodeRowCountLowerPart value][0] intValue] < ZXPDF417_MIN_ROWS_IN_BARCODE ||
+ [[barcodeRowCountUpperPart value][0] intValue] + [[barcodeRowCountLowerPart value][0] intValue] > ZXPDF417_MAX_ROWS_IN_BARCODE) {
+ return nil;
+ }
+ ZXPDF417BarcodeMetadata *barcodeMetadata = [[ZXPDF417BarcodeMetadata alloc] initWithColumnCount:[[barcodeColumnCount value][0] intValue]
+ rowCountUpperPart:[[barcodeRowCountUpperPart value][0] intValue]
+ rowCountLowerPart:[[barcodeRowCountLowerPart value][0] intValue]
+ errorCorrectionLevel:[[barcodeECLevel value][0] intValue]];
+ [self removeIncorrectCodewords:barcodeMetadata];
+ return barcodeMetadata;
+}
+
+- (void)removeIncorrectCodewords:(ZXPDF417BarcodeMetadata *)barcodeMetadata {
+ // Remove codewords which do not match the metadata
+ // TODO Maybe we should keep the incorrect codewords for the start and end positions?
+ for (int codewordRow = 0; codewordRow < [self.codewords count]; codewordRow++) {
+ ZXPDF417Codeword *codeword = self.codewords[codewordRow];
+ if (self.codewords[codewordRow] == [NSNull null]) {
+ continue;
+ }
+ int rowIndicatorValue = codeword.value % 30;
+ int codewordRowNumber = codeword.rowNumber;
+ if (codewordRowNumber > barcodeMetadata.rowCount) {
+ self.codewords[codewordRow] = [NSNull null];
+ continue;
+ }
+ if (!self.isLeft) {
+ codewordRowNumber += 2;
+ }
+ switch (codewordRowNumber % 3) {
+ case 0:
+ if (rowIndicatorValue * 3 + 1 != barcodeMetadata.rowCountUpperPart) {
+ self.codewords[codewordRow] = [NSNull null];
+ }
+ break;
+ case 1:
+ if (rowIndicatorValue / 3 != barcodeMetadata.errorCorrectionLevel ||
+ rowIndicatorValue % 3 != barcodeMetadata.rowCountLowerPart) {
+ self.codewords[codewordRow] = [NSNull null];
+ }
+ break;
+ case 2:
+ if (rowIndicatorValue + 1 != barcodeMetadata.columnCount) {
+ self.codewords[codewordRow] = [NSNull null];
+ }
+ break;
+ }
+ }
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"IsLeft: %@\n%@", @(self.isLeft), [super description]];
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.h b/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.h
new file mode 100644
index 0000000..4329690
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+@class ZXBitMatrix, ZXDecoderResult, ZXResultPoint;
+
+extern const int ZXPDF417_CODEWORD_SKEW_SIZE;
+
+@interface ZXPDF417ScanningDecoder : NSObject
+
++ (ZXDecoderResult *)decode:(ZXBitMatrix *)image
+ imageTopLeft:(ZXResultPoint *)imageTopLeft
+ imageBottomLeft:(ZXResultPoint *)imageBottomLeft
+ imageTopRight:(ZXResultPoint *)imageTopRight
+ imageBottomRight:(ZXResultPoint *)imageBottomRight
+ minCodewordWidth:(int)minCodewordWidth
+ maxCodewordWidth:(int)maxCodewordWidth;
+- (NSString *)description:(NSArray *)barcodeMatrix;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m b/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m
new file mode 100644
index 0000000..89e2701
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m
@@ -0,0 +1,618 @@
+/*
+ * 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 "ZXBitMatrix.h"
+#import "ZXDecoderResult.h"
+#import "ZXPDF417BarcodeMetadata.h"
+#import "ZXPDF417BarcodeValue.h"
+#import "ZXPDF417BoundingBox.h"
+#import "ZXPDF417Codeword.h"
+#import "ZXPDF417CodewordDecoder.h"
+#import "ZXPDF417Common.h"
+#import "ZXPDF417DecodedBitStreamParser.h"
+#import "ZXPDF417DetectionResult.h"
+#import "ZXPDF417DetectionResultRowIndicatorColumn.h"
+#import "ZXPDF417ECErrorCorrection.h"
+#import "ZXPDF417ScanningDecoder.h"
+#import "ZXResultPoint.h"
+
+const int ZXPDF417_CODEWORD_SKEW_SIZE = 2;
+
+const int ZXPDF417_MAX_ERRORS = 3;
+const int ZXPDF417_MAX_EC_CODEWORDS = 512;
+static ZXPDF417ECErrorCorrection *errorCorrection;
+
+@implementation ZXPDF417ScanningDecoder
+
++ (void)initialize {
+ errorCorrection = [[ZXPDF417ECErrorCorrection alloc] init];
+}
+
+// TODO don't pass in minCodewordWidth and maxCodewordWidth, pass in barcode columns for start and stop pattern
+// columns. That way width can be deducted from the pattern column.
+// This approach also allows to detect more details about the barcode, e.g. if a bar type (white or black) is wider
+// than it should be. This can happen if the scanner used a bad blackpoint.
++ (ZXDecoderResult *)decode:(ZXBitMatrix *)image
+ imageTopLeft:(ZXResultPoint *)imageTopLeft
+ imageBottomLeft:(ZXResultPoint *)imageBottomLeft
+ imageTopRight:(ZXResultPoint *)imageTopRight
+ imageBottomRight:(ZXResultPoint *)imageBottomRight
+ minCodewordWidth:(int)minCodewordWidth
+ maxCodewordWidth:(int)maxCodewordWidth {
+ ZXPDF417BoundingBox *boundingBox = [[ZXPDF417BoundingBox alloc] initWithImage:image topLeft:imageTopLeft bottomLeft:imageBottomLeft topRight:imageTopRight bottomRight:imageBottomRight];
+ ZXPDF417DetectionResultRowIndicatorColumn *leftRowIndicatorColumn;
+ ZXPDF417DetectionResultRowIndicatorColumn *rightRowIndicatorColumn;
+ ZXPDF417DetectionResult *detectionResult;
+ for (int i = 0; i < 2; i++) {
+ if (imageTopLeft) {
+ leftRowIndicatorColumn = [self rowIndicatorColumn:image boundingBox:boundingBox startPoint:imageTopLeft leftToRight:YES
+ minCodewordWidth:minCodewordWidth maxCodewordWidth:maxCodewordWidth];
+ }
+ if (imageTopRight) {
+ rightRowIndicatorColumn = [self rowIndicatorColumn:image boundingBox:boundingBox startPoint:imageTopRight leftToRight:NO
+ minCodewordWidth:minCodewordWidth maxCodewordWidth:maxCodewordWidth];
+ }
+ detectionResult = [self merge:leftRowIndicatorColumn rightRowIndicatorColumn:rightRowIndicatorColumn];
+ if (!detectionResult) {
+ return nil;
+ }
+ if (i == 0 &&
+ ([detectionResult boundingBox].minY < boundingBox.minY ||
+ [detectionResult boundingBox].maxY > boundingBox.maxY)) {
+ boundingBox = [detectionResult boundingBox];
+ } else {
+ detectionResult.boundingBox = boundingBox;
+ break;
+ }
+ }
+ int maxBarcodeColumn = detectionResult.barcodeColumnCount + 1;
+ [detectionResult setDetectionResultColumn:0 detectionResultColumn:leftRowIndicatorColumn];
+ [detectionResult setDetectionResultColumn:maxBarcodeColumn detectionResultColumn:rightRowIndicatorColumn];
+
+ BOOL leftToRight = leftRowIndicatorColumn != nil;
+ for (int barcodeColumnCount = 1; barcodeColumnCount <= maxBarcodeColumn; barcodeColumnCount++) {
+ int barcodeColumn = leftToRight ? barcodeColumnCount : maxBarcodeColumn - barcodeColumnCount;
+ if ([detectionResult detectionResultColumn:barcodeColumn]) {
+ // This will be the case for the opposite row indicator column, which doesn't need to be decoded again.
+ continue;
+ }
+ ZXPDF417DetectionResultColumn *detectionResultColumn;
+ if (barcodeColumn == 0 || barcodeColumn == maxBarcodeColumn) {
+ detectionResultColumn = [[ZXPDF417DetectionResultRowIndicatorColumn alloc] initWithBoundingBox:boundingBox isLeft:barcodeColumn == 0];
+ } else {
+ detectionResultColumn = [[ZXPDF417DetectionResultColumn alloc] initWithBoundingBox:boundingBox];
+ }
+ [detectionResult setDetectionResultColumn:barcodeColumn detectionResultColumn:detectionResultColumn];
+ int startColumn = -1;
+ int previousStartColumn = startColumn;
+ // TODO start at a row for which we know the start position, then detect upwards and downwards from there.
+ for (int imageRow = boundingBox.minY; imageRow <= boundingBox.maxY; imageRow++) {
+ startColumn = [self startColumn:detectionResult barcodeColumn:barcodeColumn imageRow:imageRow leftToRight:leftToRight];
+ if (startColumn < 0 || startColumn > boundingBox.maxX) {
+ if (previousStartColumn == -1) {
+ continue;
+ }
+ startColumn = previousStartColumn;
+ }
+ ZXPDF417Codeword *codeword = [self detectCodeword:image minColumn:boundingBox.minX maxColumn:boundingBox.maxX leftToRight:leftToRight
+ startColumn:startColumn imageRow:imageRow minCodewordWidth:minCodewordWidth maxCodewordWidth:maxCodewordWidth];
+ if (codeword) {
+ [detectionResultColumn setCodeword:imageRow codeword:codeword];
+ previousStartColumn = startColumn;
+ minCodewordWidth = MIN(minCodewordWidth, codeword.width);
+ maxCodewordWidth = MAX(maxCodewordWidth, codeword.width);
+ }
+ }
+ }
+ return [self createDecoderResult:detectionResult];
+}
+
++ (ZXPDF417DetectionResult *)merge:(ZXPDF417DetectionResultRowIndicatorColumn *)leftRowIndicatorColumn
+ rightRowIndicatorColumn:(ZXPDF417DetectionResultRowIndicatorColumn *)rightRowIndicatorColumn {
+ if (!leftRowIndicatorColumn && !rightRowIndicatorColumn) {
+ return nil;
+ }
+ ZXPDF417BarcodeMetadata *barcodeMetadata = [self barcodeMetadata:leftRowIndicatorColumn rightRowIndicatorColumn:rightRowIndicatorColumn];
+ if (!barcodeMetadata) {
+ return nil;
+ }
+ ZXPDF417BoundingBox *boundingBox = [ZXPDF417BoundingBox mergeLeftBox:[self adjustBoundingBox:leftRowIndicatorColumn]
+ rightBox:[self adjustBoundingBox:rightRowIndicatorColumn]];
+ return [[ZXPDF417DetectionResult alloc] initWithBarcodeMetadata:barcodeMetadata boundingBox:boundingBox];
+}
+
++ (ZXPDF417BoundingBox *)adjustBoundingBox:(ZXPDF417DetectionResultRowIndicatorColumn *)rowIndicatorColumn {
+ if (!rowIndicatorColumn) {
+ return nil;
+ }
+ NSArray *rowHeights = [rowIndicatorColumn rowHeights];
+ int maxRowHeight = [self max:rowHeights];
+ int missingStartRows = 0;
+ for (NSNumber *rowHeight in rowHeights) {
+ missingStartRows += maxRowHeight - [rowHeight intValue];
+ if ([rowHeight intValue] > 0) {
+ break;
+ }
+ }
+ NSArray *codewords = rowIndicatorColumn.codewords;
+ for (int row = 0; missingStartRows > 0 && codewords[row] == [NSNull null]; row++) {
+ missingStartRows--;
+ }
+ int missingEndRows = 0;
+ for (int row = (int)[rowHeights count] - 1; row >= 0; row--) {
+ missingEndRows += maxRowHeight - [rowHeights[row] intValue];
+ if ([rowHeights[row] intValue] > 0) {
+ break;
+ }
+ }
+ for (int row = (int)[codewords count] - 1; missingEndRows > 0 && codewords[row] == [NSNull null]; row--) {
+ missingEndRows--;
+ }
+ return [rowIndicatorColumn.boundingBox addMissingRows:missingStartRows missingEndRows:missingEndRows
+ isLeft:rowIndicatorColumn.isLeft];
+}
+
++ (int)max:(NSArray *)values {
+ int maxValue = -1;
+ for (NSNumber *value in values) {
+ maxValue = MAX(maxValue, [value intValue]);
+ }
+ return maxValue;
+}
+
++ (ZXPDF417BarcodeMetadata *)barcodeMetadata:(ZXPDF417DetectionResultRowIndicatorColumn *)leftRowIndicatorColumn
+ rightRowIndicatorColumn:(ZXPDF417DetectionResultRowIndicatorColumn *)rightRowIndicatorColumn {
+ if (!leftRowIndicatorColumn || !leftRowIndicatorColumn.barcodeMetadata) {
+ return rightRowIndicatorColumn ? rightRowIndicatorColumn.barcodeMetadata : nil;
+ }
+ if (!rightRowIndicatorColumn || !rightRowIndicatorColumn.barcodeMetadata) {
+ return leftRowIndicatorColumn ? leftRowIndicatorColumn.barcodeMetadata : nil;
+ }
+ ZXPDF417BarcodeMetadata *leftBarcodeMetadata = leftRowIndicatorColumn.barcodeMetadata;
+ ZXPDF417BarcodeMetadata *rightBarcodeMetadata = rightRowIndicatorColumn.barcodeMetadata;
+
+ if (leftBarcodeMetadata.columnCount != rightBarcodeMetadata.columnCount &&
+ leftBarcodeMetadata.errorCorrectionLevel != rightBarcodeMetadata.errorCorrectionLevel &&
+ leftBarcodeMetadata.rowCount != rightBarcodeMetadata.rowCount) {
+ return nil;
+ }
+ return leftBarcodeMetadata;
+}
+
++ (ZXPDF417DetectionResultRowIndicatorColumn *)rowIndicatorColumn:(ZXBitMatrix *)image
+ boundingBox:(ZXPDF417BoundingBox *)boundingBox
+ startPoint:(ZXResultPoint *)startPoint
+ leftToRight:(BOOL)leftToRight
+ minCodewordWidth:(int)minCodewordWidth
+ maxCodewordWidth:(int)maxCodewordWidth {
+ ZXPDF417DetectionResultRowIndicatorColumn *rowIndicatorColumn = [[ZXPDF417DetectionResultRowIndicatorColumn alloc] initWithBoundingBox:boundingBox
+ isLeft:leftToRight];
+ for (int i = 0; i < 2; i++) {
+ int increment = i == 0 ? 1 : -1;
+ int startColumn = (int) startPoint.x;
+ for (int imageRow = (int) startPoint.y; imageRow <= boundingBox.maxY &&
+ imageRow >= boundingBox.minY; imageRow += increment) {
+ ZXPDF417Codeword *codeword = [self detectCodeword:image minColumn:0 maxColumn:image.width leftToRight:leftToRight startColumn:startColumn imageRow:imageRow
+ minCodewordWidth:minCodewordWidth maxCodewordWidth:maxCodewordWidth];
+ if (codeword) {
+ [rowIndicatorColumn setCodeword:imageRow codeword:codeword];
+ if (leftToRight) {
+ startColumn = codeword.startX;
+ } else {
+ startColumn = codeword.endX;
+ }
+ }
+ }
+ }
+ return rowIndicatorColumn;
+}
+
++ (BOOL)adjustCodewordCount:(ZXPDF417DetectionResult *)detectionResult barcodeMatrix:(NSArray *)barcodeMatrix {
+ NSArray *numberOfCodewords = [(ZXPDF417BarcodeValue *)barcodeMatrix[0][1] value];
+ int calculatedNumberOfCodewords = [detectionResult barcodeColumnCount] * [detectionResult barcodeRowCount];
+ [self numberOfECCodeWords:detectionResult.barcodeECLevel];
+ if ([numberOfCodewords count] == 0) {
+ if (calculatedNumberOfCodewords < 1 || calculatedNumberOfCodewords > ZXPDF417_MAX_CODEWORDS_IN_BARCODE) {
+ return NO;
+ }
+ [(ZXPDF417BarcodeValue *)barcodeMatrix[0][1] setValue:calculatedNumberOfCodewords];
+ } else if ([numberOfCodewords[0] intValue] != calculatedNumberOfCodewords) {
+ // The calculated one is more reliable as it is derived from the row indicator columns
+ [(ZXPDF417BarcodeValue *)barcodeMatrix[0][1] setValue:calculatedNumberOfCodewords];
+ }
+
+ return YES;
+}
+
++ (ZXDecoderResult *)createDecoderResult:(ZXPDF417DetectionResult *)detectionResult {
+ NSArray *barcodeMatrix = [self createBarcodeMatrix:detectionResult];
+ if (![self adjustCodewordCount:detectionResult barcodeMatrix:barcodeMatrix]) {
+ return nil;
+ }
+ NSMutableArray *erasures = [NSMutableArray array];
+ NSMutableArray *codewords = [NSMutableArray array];
+ for (int i = 0; i < detectionResult.barcodeRowCount * detectionResult.barcodeColumnCount; i++) {
+ [codewords addObject:@0];
+ }
+ NSMutableArray *ambiguousIndexValuesList = [NSMutableArray array];
+ NSMutableArray *ambiguousIndexesList = [NSMutableArray array];
+ for (int row = 0; row < detectionResult.barcodeRowCount; row++) {
+ for (int column = 0; column < detectionResult.barcodeColumnCount; column++) {
+ NSArray *values = [(ZXPDF417BarcodeValue *)barcodeMatrix[row][column + 1] value];
+ int codewordIndex = row * detectionResult.barcodeColumnCount + column;
+ if ([values count] == 0) {
+ [erasures addObject:@(codewordIndex)];
+ } else if ([values count] == 1) {
+ [codewords replaceObjectAtIndex:codewordIndex withObject:values[0]];
+ } else {
+ [ambiguousIndexesList addObject:@(codewordIndex)];
+ [ambiguousIndexValuesList addObject:values];
+ }
+ }
+ }
+ NSMutableArray *ambiguousIndexValues = [NSMutableArray array];
+ for (int i = 0; i < [ambiguousIndexValuesList count]; i++) {
+ ambiguousIndexValues[i] = ambiguousIndexValuesList[i];
+ }
+ return [self createDecoderResultFromAmbiguousValues:detectionResult.barcodeECLevel codewords:codewords
+ erasureArray:erasures ambiguousIndexes:ambiguousIndexesList
+ ambiguousIndexValues:ambiguousIndexValues];
+}
+
+/**
+ * This method deals with the fact, that the decoding process doesn't always yield a single most likely value. The
+ * current error correction implementation doesn't deal with erasures very well, so it's better to provide a value
+ * for these ambiguous codewords instead of treating it as an erasure. The problem is that we don't know which of
+ * the ambiguous values to choose. We try decode using the first value, and if that fails, we use another of the
+ * ambiguous values and try to decode again. This usually only happens on very hard to read and decode barcodes,
+ * so decoding the normal barcodes is not affected by this.
+ */
++ (ZXDecoderResult *)createDecoderResultFromAmbiguousValues:(int)ecLevel codewords:(NSMutableArray *)codewords
+ erasureArray:(NSArray *)erasureArray ambiguousIndexes:(NSArray *)ambiguousIndexes
+ ambiguousIndexValues:(NSArray *)ambiguousIndexValues {
+ int ambiguousIndexCount[[ambiguousIndexes count]];
+ memset(ambiguousIndexCount, 0, [ambiguousIndexes count] * sizeof(int));
+
+ int tries = 100;
+ while (tries-- > 0) {
+ for (int i = 0; i < [ambiguousIndexes count]; i++) {
+ codewords[[ambiguousIndexes[i] intValue]] = ambiguousIndexValues[i][(ambiguousIndexCount[i] + 1) % [ambiguousIndexValues[i] count]];
+ }
+ ZXDecoderResult *result = [self decodeCodewords:codewords ecLevel:ecLevel erasures:erasureArray];
+ if (result) {
+ return result;
+ }
+
+ if ([ambiguousIndexes count] == 0) {
+ return nil;
+ }
+ for (int i = 0; i < [ambiguousIndexes count]; i++) {
+ if (ambiguousIndexCount[i] < [ambiguousIndexValues[i] count] - 1) {
+ ambiguousIndexCount[i]++;
+ break;
+ } else {
+ ambiguousIndexCount[i] = 0;
+ if (i == [ambiguousIndexes count] - 1) {
+ return nil;
+ }
+ }
+ }
+ }
+ return nil;
+}
+
++ (NSArray *)createBarcodeMatrix:(ZXPDF417DetectionResult *)detectionResult {
+ NSMutableArray *barcodeMatrix = [NSMutableArray array];
+ for (int row = 0; row < detectionResult.barcodeRowCount; row++) {
+ [barcodeMatrix addObject:[NSMutableArray array]];
+ for (int column = 0; column < detectionResult.barcodeColumnCount + 2; column++) {
+ barcodeMatrix[row][column] = [[ZXPDF417BarcodeValue alloc] init];
+ }
+ }
+
+ int column = -1;
+ for (ZXPDF417DetectionResultColumn *detectionResultColumn in [detectionResult detectionResultColumns]) {
+ column++;
+ if ((id)detectionResultColumn == [NSNull null]) {
+ continue;
+ }
+ for (ZXPDF417Codeword *codeword in detectionResultColumn.codewords) {
+ if ((id)codeword == [NSNull null] || codeword.rowNumber == -1) {
+ continue;
+ }
+ [(ZXPDF417BarcodeValue *)barcodeMatrix[codeword.rowNumber][column] setValue:codeword.value];
+ }
+ }
+ return barcodeMatrix;
+}
+
++ (BOOL)isValidBarcodeColumn:(ZXPDF417DetectionResult *)detectionResult barcodeColumn:(int)barcodeColumn {
+ return barcodeColumn >= 0 && barcodeColumn <= detectionResult.barcodeColumnCount + 1;
+}
+
++ (int)startColumn:(ZXPDF417DetectionResult *)detectionResult
+ barcodeColumn:(int)barcodeColumn
+ imageRow:(int)imageRow
+ leftToRight:(BOOL)leftToRight {
+ int offset = leftToRight ? 1 : -1;
+ ZXPDF417Codeword *codeword;
+ if ([self isValidBarcodeColumn:detectionResult barcodeColumn:barcodeColumn - offset]) {
+ codeword = [[detectionResult detectionResultColumn:barcodeColumn - offset] codeword:imageRow];
+ }
+ if (codeword) {
+ return leftToRight ? codeword.endX : codeword.startX;
+ }
+ codeword = [[detectionResult detectionResultColumn:barcodeColumn] codewordNearby:imageRow];
+ if (codeword) {
+ return leftToRight ? codeword.startX : codeword.endX;
+ }
+ if ([self isValidBarcodeColumn:detectionResult barcodeColumn:barcodeColumn - offset]) {
+ codeword = [[detectionResult detectionResultColumn:barcodeColumn - offset] codewordNearby:imageRow];
+ }
+ if (codeword) {
+ return leftToRight ? codeword.endX : codeword.startX;
+ }
+ int skippedColumns = 0;
+
+ while ([self isValidBarcodeColumn:detectionResult barcodeColumn:barcodeColumn - offset]) {
+ barcodeColumn -= offset;
+ for (ZXPDF417Codeword *previousRowCodeword in [detectionResult detectionResultColumn:barcodeColumn].codewords) {
+ if ((id)previousRowCodeword != [NSNull null]) {
+ return (leftToRight ? previousRowCodeword.endX : previousRowCodeword.startX) +
+ offset *
+ skippedColumns *
+ (previousRowCodeword.endX - previousRowCodeword.startX);
+ }
+ }
+ skippedColumns++;
+ }
+ return leftToRight ? detectionResult.boundingBox.minX : detectionResult.boundingBox.maxX;
+}
+
++ (ZXPDF417Codeword *)detectCodeword:(ZXBitMatrix *)image
+ minColumn:(int)minColumn
+ maxColumn:(int)maxColumn
+ leftToRight:(BOOL)leftToRight
+ startColumn:(int)startColumn
+ imageRow:(int)imageRow
+ minCodewordWidth:(int)minCodewordWidth
+ maxCodewordWidth:(int)maxCodewordWidth {
+ startColumn = [self adjustCodewordStartColumn:image minColumn:minColumn maxColumn:maxColumn leftToRight:leftToRight codewordStartColumn:startColumn imageRow:imageRow];
+ // we usually know fairly exact now how long a codeword is. We should provide minimum and maximum expected length
+ // and try to adjust the read pixels, e.g. remove single pixel errors or try to cut off exceeding pixels.
+ // min and maxCodewordWidth should not be used as they are calculated for the whole barcode an can be inaccurate
+ // for the current position
+ NSMutableArray *moduleBitCount = [self moduleBitCount:image minColumn:minColumn maxColumn:maxColumn leftToRight:leftToRight startColumn:startColumn imageRow:imageRow];
+ if (!moduleBitCount) {
+ return nil;
+ }
+ int endColumn;
+ int codewordBitCount = [ZXPDF417Common bitCountSum:moduleBitCount];
+ if (leftToRight) {
+ endColumn = startColumn + codewordBitCount;
+ } else {
+ for (int i = 0; i < [moduleBitCount count] >> 1; i++) {
+ int tmpCount = [moduleBitCount[i] intValue];
+ moduleBitCount[i] = moduleBitCount[[moduleBitCount count] - 1 - i];
+ moduleBitCount[[moduleBitCount count] - 1 - i] = @(tmpCount);
+ }
+ endColumn = startColumn;
+ startColumn = endColumn - codewordBitCount;
+ }
+ // TODO implement check for width and correction of black and white bars
+ // use start (and maybe stop pattern) to determine if blackbars are wider than white bars. If so, adjust.
+ // should probably done only for codewords with a lot more than 17 bits.
+ // The following fixes 10-1.png, which has wide black bars and small white bars
+ // for (int i = 0; i < moduleBitCount.length; i++) {
+ // if (i % 2 == 0) {
+ // moduleBitCount[i]--;
+ // } else {
+ // moduleBitCount[i]++;
+ // }
+ // }
+
+ // We could also use the width of surrounding codewords for more accurate results, but this seems
+ // sufficient for now
+ if (![self checkCodewordSkew:codewordBitCount minCodewordWidth:minCodewordWidth maxCodewordWidth:maxCodewordWidth]) {
+ // We could try to use the startX and endX position of the codeword in the same column in the previous row,
+ // create the bit count from it and normalize it to 8. This would help with single pixel errors.
+ return nil;
+ }
+
+ int decodedValue = [ZXPDF417CodewordDecoder decodedValue:moduleBitCount];
+ int codeword = [ZXPDF417Common codeword:decodedValue];
+ if (codeword == -1) {
+ return nil;
+ }
+ return [[ZXPDF417Codeword alloc] initWithStartX:startColumn endX:endColumn bucket:[self codewordBucketNumber:decodedValue] value:codeword];
+}
+
++ (NSMutableArray *)moduleBitCount:(ZXBitMatrix *)image
+ minColumn:(int)minColumn
+ maxColumn:(int)maxColumn
+ leftToRight:(BOOL)leftToRight
+ startColumn:(int)startColumn
+ imageRow:(int)imageRow {
+ int imageColumn = startColumn;
+ NSMutableArray *moduleBitCount = [NSMutableArray arrayWithCapacity:8];
+ for (int i = 0; i < 8; i++) {
+ [moduleBitCount addObject:@0];
+ }
+ int moduleNumber = 0;
+ int increment = leftToRight ? 1 : -1;
+ BOOL previousPixelValue = leftToRight;
+ while (((leftToRight && imageColumn < maxColumn) || (!leftToRight && imageColumn >= minColumn)) &&
+ moduleNumber < [moduleBitCount count]) {
+ if ([image getX:imageColumn y:imageRow] == previousPixelValue) {
+ moduleBitCount[moduleNumber] = @([moduleBitCount[moduleNumber] intValue] + 1);
+ imageColumn += increment;
+ } else {
+ moduleNumber++;
+ previousPixelValue = !previousPixelValue;
+ }
+ }
+ if (moduleNumber == [moduleBitCount count] ||
+ (((leftToRight && imageColumn == maxColumn) || (!leftToRight && imageColumn == minColumn)) && moduleNumber == [moduleBitCount count] - 1)) {
+ return moduleBitCount;
+ }
+ return nil;
+}
+
++ (int)numberOfECCodeWords:(int)barcodeECLevel {
+ return 2 << barcodeECLevel;
+}
+
++ (int)adjustCodewordStartColumn:(ZXBitMatrix *)image
+ minColumn:(int)minColumn
+ maxColumn:(int)maxColumn
+ leftToRight:(BOOL)leftToRight
+ codewordStartColumn:(int)codewordStartColumn
+ imageRow:(int)imageRow {
+ int correctedStartColumn = codewordStartColumn;
+ int increment = leftToRight ? -1 : 1;
+ // there should be no black pixels before the start column. If there are, then we need to start earlier.
+ for (int i = 0; i < 2; i++) {
+ while (((leftToRight && correctedStartColumn >= minColumn) || (!leftToRight && correctedStartColumn < maxColumn)) &&
+ leftToRight == [image getX:correctedStartColumn y:imageRow]) {
+ if (abs(codewordStartColumn - correctedStartColumn) > ZXPDF417_CODEWORD_SKEW_SIZE) {
+ return codewordStartColumn;
+ }
+ correctedStartColumn += increment;
+ }
+ increment = -increment;
+ leftToRight = !leftToRight;
+ }
+ return correctedStartColumn;
+}
+
++ (BOOL)checkCodewordSkew:(int)codewordSize minCodewordWidth:(int)minCodewordWidth maxCodewordWidth:(int)maxCodewordWidth {
+ return minCodewordWidth - ZXPDF417_CODEWORD_SKEW_SIZE <= codewordSize &&
+ codewordSize <= maxCodewordWidth + ZXPDF417_CODEWORD_SKEW_SIZE;
+}
+
++ (ZXDecoderResult *)decodeCodewords:(NSMutableArray *)codewords ecLevel:(int)ecLevel erasures:(NSArray *)erasures {
+ if ([codewords count] == 0) {
+ return nil;
+ }
+
+ int numECCodewords = 1 << (ecLevel + 1);
+ int correctedErrorsCount = [self correctErrors:codewords erasures:erasures numECCodewords:numECCodewords];
+ if (correctedErrorsCount == -1) {
+ return nil;
+ }
+ if (![self verifyCodewordCount:codewords numECCodewords:numECCodewords]) {
+ return nil;
+ }
+
+ // Decode the codewords
+ ZXDecoderResult *decoderResult = [ZXPDF417DecodedBitStreamParser decode:codewords ecLevel:[@(ecLevel) stringValue] error:nil];
+ decoderResult.errorsCorrected = @(correctedErrorsCount);
+ decoderResult.erasures = @([erasures count]);
+ return decoderResult;
+}
+
+/**
+ * Given data and error-correction codewords received, possibly corrupted by errors, attempts to
+ * correct the errors in-place.
+ */
++ (int)correctErrors:(NSMutableArray *)codewords erasures:(NSArray *)erasures numECCodewords:(int)numECCodewords {
+ if (erasures &&
+ ([erasures count] > numECCodewords / 2 + ZXPDF417_MAX_ERRORS ||
+ numECCodewords < 0 ||
+ numECCodewords > ZXPDF417_MAX_EC_CODEWORDS)) {
+ // Too many errors or EC Codewords is corrupted
+ return -1;
+ }
+ return [errorCorrection decode:codewords numECCodewords:numECCodewords erasures:erasures];
+}
+
+/**
+ * Verify that all is OK with the codeword array.
+ */
++ (BOOL)verifyCodewordCount:(NSMutableArray *)codewords numECCodewords:(int)numECCodewords {
+ if ([codewords count] < 4) {
+ // Codeword array size should be at least 4 allowing for
+ // Count CW, At least one Data CW, Error Correction CW, Error Correction CW
+ return NO;
+ }
+ // The first codeword, the Symbol Length Descriptor, shall always encode the total number of data
+ // codewords in the symbol, including the Symbol Length Descriptor itself, data codewords and pad
+ // codewords, but excluding the number of error correction codewords.
+ int numberOfCodewords = [codewords[0] intValue];
+ if (numberOfCodewords > [codewords count]) {
+ return NO;
+ }
+ if (numberOfCodewords == 0) {
+ // Reset to the length of the array - 8 (Allow for at least level 3 Error Correction (8 Error Codewords)
+ if (numECCodewords < [codewords count]) {
+ codewords[0] = @([codewords count] - numECCodewords);
+ } else {
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
++ (NSArray *)bitCountForCodeword:(int)codeword {
+ NSMutableArray *result = [NSMutableArray array];
+ for (int i = 0; i < 8; i++) {
+ [result addObject:@0];
+ }
+
+ int previousValue = 0;
+ int i = (int)[result count] - 1;
+ while (YES) {
+ if ((codeword & 0x1) != previousValue) {
+ previousValue = codeword & 0x1;
+ i--;
+ if (i < 0) {
+ break;
+ }
+ }
+ result[i] = @([result[i] intValue] + 1);
+ codeword >>= 1;
+ }
+ return result;
+}
+
++ (int)codewordBucketNumber:(int)codeword {
+ return [self codewordBucketNumberWithModuleBitCount:[self bitCountForCodeword:codeword]];
+}
+
++ (int)codewordBucketNumberWithModuleBitCount:(NSArray *)moduleBitCount {
+ return ([moduleBitCount[0] intValue] - [moduleBitCount[2] intValue] + [moduleBitCount[4] intValue] - [moduleBitCount[6] intValue] + 9) % 9;
+}
+
+- (NSString *)description:(NSArray *)barcodeMatrix {
+ NSMutableString *result = [NSMutableString string];
+ for (int row = 0; row < [barcodeMatrix count]; row++) {
+ [result appendFormat:@"Row %2d: ", row];
+ for (int column = 0; column < [barcodeMatrix[row] count]; column++) {
+ ZXPDF417BarcodeValue *barcodeValue = barcodeMatrix[row][column];
+ if ([[barcodeValue value] count] == 0) {
+ [result appendString:@" "];
+ } else {
+ [result appendFormat:@"%4d(%2d)", [[barcodeValue value][0] intValue],
+ [[barcodeValue confidence:[[barcodeValue value][0] intValue]] intValue]];
+ }
+ }
+ [result appendString:@"\n"];
+ }
+ return [NSString stringWithString:result];
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.h b/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.h
new file mode 100644
index 0000000..cc07d7e
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.h
@@ -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.
+ */
+
+@class ZXModulusPoly;
+
+@interface ZXModulusGF : NSObject
+
+@property (nonatomic, strong) ZXModulusPoly *one;
+@property (nonatomic, strong) ZXModulusPoly *zero;
+
++ (ZXModulusGF *)PDF417_GF;
+
+- (id)initWithModulus:(int)modulus generator:(int)generator;
+
+- (ZXModulusPoly *)buildMonomial:(int)degree coefficient:(int)coefficient;
+- (int)add:(int)a b:(int)b;
+- (int)subtract:(int)a b:(int)b;
+- (int)exp:(int)a;
+- (int)log:(int)a;
+- (int)inverse:(int)a;
+- (int)multiply:(int)a b:(int)b;
+- (int)size;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.m b/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.m
new file mode 100644
index 0000000..a39ee44
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.m
@@ -0,0 +1,120 @@
+/*
+ * 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 "ZXModulusGF.h"
+#import "ZXModulusPoly.h"
+#import "ZXPDF417Common.h"
+
+@interface ZXModulusGF ()
+
+@property (nonatomic, strong) NSMutableArray *expTable;
+@property (nonatomic, strong) NSMutableArray *logTable;
+@property (nonatomic, assign) int modulus;
+
+@end
+
+@implementation ZXModulusGF
+
++ (ZXModulusGF *)PDF417_GF {
+ return [[ZXModulusGF alloc] initWithModulus:ZXPDF417_NUMBER_OF_CODEWORDS generator:3];
+}
+
+- (id)initWithModulus:(int)modulus generator:(int)generator {
+ if (self = [super init]) {
+ _modulus = modulus;
+ _expTable = [NSMutableArray arrayWithCapacity:self.modulus];
+ _logTable = [NSMutableArray arrayWithCapacity:self.modulus];
+ int x = 1;
+ for (int i = 0; i < modulus; i++) {
+ [_expTable addObject:@(x)];
+ x = (x * generator) % modulus;
+ }
+
+ for (int i = 0; i < self.size; i++) {
+ [_logTable addObject:@0];
+ }
+
+ for (int i = 0; i < self.size - 1; i++) {
+ _logTable[[_expTable[i] intValue]] = @(i);
+ }
+ // logTable[0] == 0 but this should never be used
+ int zeroInt = 0;
+ _zero = [[ZXModulusPoly alloc] initWithField:self coefficients:&zeroInt coefficientsLen:1];
+
+ int oneInt = 1;
+ _one = [[ZXModulusPoly alloc] initWithField:self coefficients:&oneInt coefficientsLen:1];
+ }
+
+ return self;
+}
+
+- (ZXModulusPoly *)buildMonomial:(int)degree coefficient:(int)coefficient {
+ if (degree < 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Degree must be greater than 0."];
+ }
+ if (coefficient == 0) {
+ return self.zero;
+ }
+
+ int coefficientsLen = degree + 1;
+ int coefficients[coefficientsLen];
+ coefficients[0] = coefficient;
+ for (int i = 1; i < coefficientsLen; i++) {
+ coefficients[i] = 0;
+ }
+ return [[ZXModulusPoly alloc] initWithField:self coefficients:coefficients coefficientsLen:coefficientsLen];
+}
+
+- (int)add:(int)a b:(int)b {
+ return (a + b) % self.modulus;
+}
+
+- (int)subtract:(int)a b:(int)b {
+ return (self.modulus + a - b) % self.modulus;
+}
+
+- (int)exp:(int)a {
+ return [self.expTable[a] intValue];
+}
+
+- (int)log:(int)a {
+ if (a == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Argument must be non-zero."];
+ }
+ return [self.logTable[a] intValue];
+}
+
+- (int)inverse:(int)a {
+ if (a == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Argument must be non-zero."];
+ }
+ return [self.expTable[self.size - [self.logTable[a] intValue] - 1] intValue];
+}
+
+- (int)multiply:(int)a b:(int)b {
+ if (a == 0 || b == 0) {
+ return 0;
+ }
+
+ int logSum = [self.logTable[a] intValue] + [self.logTable[b] intValue];
+ return [self.expTable[logSum % (self.modulus - 1)] intValue];
+}
+
+- (int)size {
+ return self.modulus;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.h b/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.h
new file mode 100644
index 0000000..5c491cb
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.h
@@ -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.
+ */
+
+@class ZXModulusGF;
+
+@interface ZXModulusPoly : NSObject
+
+- (id)initWithField:(ZXModulusGF *)field coefficients:(int *)coefficients coefficientsLen:(int)coefficientsLen;
+- (int)degree;
+- (BOOL)zero;
+- (int)coefficient:(int)degree;
+- (int)evaluateAt:(int)a;
+- (ZXModulusPoly *)add:(ZXModulusPoly *)other;
+- (ZXModulusPoly *)subtract:(ZXModulusPoly *)other;
+- (ZXModulusPoly *)multiply:(ZXModulusPoly *)other;
+- (ZXModulusPoly *)negative;
+- (ZXModulusPoly *)multiplyScalar:(int)scalar;
+- (ZXModulusPoly *)multiplyByMonomial:(int)degree coefficient:(int)coefficient;
+- (NSArray *)divide:(ZXModulusPoly *)other;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.m b/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.m
new file mode 100644
index 0000000..af9d68c
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.m
@@ -0,0 +1,270 @@
+/*
+ * 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 "ZXModulusGF.h"
+#import "ZXModulusPoly.h"
+
+@interface ZXModulusPoly ()
+
+@property (nonatomic, assign) int *coefficients;
+@property (nonatomic, assign) int coefficientsLen;
+@property (nonatomic, weak) ZXModulusGF *field;
+
+@end
+
+@implementation ZXModulusPoly
+
+- (id)initWithField:(ZXModulusGF *)field coefficients:(int *)coefficients coefficientsLen:(int)coefficientsLen {
+ if (self = [super init]) {
+ _field = field;
+ if (coefficientsLen > 1 && coefficients[0] == 0) {
+ // Leading term must be non-zero for anything except the constant polynomial "0"
+ int firstNonZero = 1;
+ while (firstNonZero < coefficientsLen && coefficients[firstNonZero] == 0) {
+ firstNonZero++;
+ }
+ if (firstNonZero == coefficientsLen) {
+ ZXModulusPoly *zero = field.zero;
+ _coefficients = (int *)malloc(zero.coefficientsLen * sizeof(int));
+ memcpy(_coefficients, zero.coefficients, zero.coefficientsLen * sizeof(int));
+ } else {
+ _coefficientsLen = (coefficientsLen - firstNonZero);
+ _coefficients = (int *)malloc(_coefficientsLen * sizeof(int));
+ for (int i = 0; i < _coefficientsLen; i++) {
+ _coefficients[i] = coefficients[firstNonZero + i];
+ }
+ }
+ } else {
+ _coefficients = (int *)malloc(coefficientsLen * sizeof(int));
+ memcpy(_coefficients, coefficients, coefficientsLen * sizeof(int));
+ _coefficientsLen = coefficientsLen;
+ }
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_coefficients != NULL) {
+ free(_coefficients);
+ _coefficients = NULL;
+ }
+}
+
+- (int)degree {
+ return self.coefficientsLen - 1;
+}
+
+- (BOOL)zero {
+ return self.coefficients[0] == 0;
+}
+
+- (int)coefficient:(int)degree {
+ return self.coefficients[self.coefficientsLen - 1 - degree];
+}
+
+- (int)evaluateAt:(int)a {
+ if (a == 0) {
+ return [self coefficient:0];
+ }
+ int size = self.coefficientsLen;
+ if (a == 1) {
+ // Just the sum of the coefficients
+ int result = 0;
+ for (int i = 0; i < size; i++) {
+ result = [self.field add:result b:self.coefficients[i]];
+ }
+ return result;
+ }
+ int result = self.coefficients[0];
+ for (int i = 1; i < size; i++) {
+ result = [self.field add:[self.field multiply:a b:result] b:self.coefficients[i]];
+ }
+ return result;
+}
+
+- (ZXModulusPoly *)add:(ZXModulusPoly *)other {
+ if (![self.field isEqual:other.field]) {
+ [NSException raise:NSInvalidArgumentException format:@"ZXModulusPolys do not have same ZXModulusGF field"];
+ }
+ if (self.zero) {
+ return other;
+ }
+ if (other.zero) {
+ return self;
+ }
+
+ int *smallerCoefficients = self.coefficients;
+ int smallerCoefficientsLen = self.coefficientsLen;
+ int *largerCoefficients = other.coefficients;
+ int largerCoefficientsLen = other.coefficientsLen;
+ if (smallerCoefficientsLen > largerCoefficientsLen) {
+ int *temp = smallerCoefficients;
+ int tempLen = smallerCoefficientsLen;
+ smallerCoefficients = largerCoefficients;
+ smallerCoefficientsLen = largerCoefficientsLen;
+ largerCoefficients = temp;
+ largerCoefficientsLen = tempLen;
+ }
+ int sumDiff[largerCoefficientsLen];
+ memset(sumDiff, 0, largerCoefficientsLen * sizeof(int));
+ int lengthDiff = largerCoefficientsLen - smallerCoefficientsLen;
+ for (int i = 0; i < lengthDiff; i++) {
+ sumDiff[i] = largerCoefficients[i];
+ }
+ for (int i = lengthDiff; i < largerCoefficientsLen; i++) {
+ sumDiff[i] = [self.field add:smallerCoefficients[i - lengthDiff] b:largerCoefficients[i]];
+ }
+
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:sumDiff coefficientsLen:largerCoefficientsLen];
+}
+
+- (ZXModulusPoly *)subtract:(ZXModulusPoly *)other {
+ if (![self.field isEqual:other.field]) {
+ [NSException raise:NSInvalidArgumentException format:@"ZXModulusPolys do not have same ZXModulusGF field"];
+ }
+ if (self.zero) {
+ return self;
+ }
+ return [self add:[other negative]];
+}
+
+- (ZXModulusPoly *)multiply:(ZXModulusPoly *)other {
+ if (![self.field isEqual:other.field]) {
+ [NSException raise:NSInvalidArgumentException format:@"ZXModulusPolys do not have same ZXModulusGF field"];
+ }
+ if (self.zero || other.zero) {
+ return self.field.zero;
+ }
+ int *aCoefficients = self.coefficients;
+ int aLength = self.coefficientsLen;
+ int *bCoefficients = other.coefficients;
+ int bLength = other.coefficientsLen;
+ int productLen = aLength + bLength - 1;
+ int product[productLen];
+ memset(product, 0, productLen * sizeof(int));
+
+ for (int i = 0; i < aLength; i++) {
+ int aCoeff = aCoefficients[i];
+ for (int j = 0; j < bLength; j++) {
+ product[i + j] = [self.field add:product[i + j]
+ b:[self.field multiply:aCoeff b:bCoefficients[j]]];
+ }
+ }
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:product coefficientsLen:productLen];
+}
+
+- (ZXModulusPoly *)negative {
+ int negativeCoefficientsLen = self.coefficientsLen;
+ int negativeCoefficients[negativeCoefficientsLen];
+ for (int i = 0; i < self.coefficientsLen; i++) {
+ negativeCoefficients[i] = [self.field subtract:0 b:self.coefficients[i]];
+ }
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:negativeCoefficients coefficientsLen:negativeCoefficientsLen];
+}
+
+- (ZXModulusPoly *)multiplyScalar:(int)scalar {
+ if (scalar == 0) {
+ return self.field.zero;
+ }
+ if (scalar == 1) {
+ return self;
+ }
+ int size = self.coefficientsLen;
+ int product[size];
+ for (int i = 0; i < size; i++) {
+ product[i] = [self.field multiply:self.coefficients[i] b:scalar];
+ }
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:product coefficientsLen:size];
+}
+
+- (ZXModulusPoly *)multiplyByMonomial:(int)degree coefficient:(int)coefficient {
+ if (degree < 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Degree must be greater than 0."];
+ }
+ if (coefficient == 0) {
+ return self.field.zero;
+ }
+ int size = self.coefficientsLen;
+ int product[size + degree];
+ for (int i = 0; i < size + degree; i++) {
+ if (i < size) {
+ product[i] = [self.field multiply:self.coefficients[i] b:coefficient];
+ } else {
+ product[i] = 0;
+ }
+ }
+
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:product coefficientsLen:size + degree];
+}
+
+- (NSArray *)divide:(ZXModulusPoly *)other {
+ if (![self.field isEqual:other.field]) {
+ [NSException raise:NSInvalidArgumentException format:@"ZXModulusPolys do not have same ZXModulusGF field"];
+ }
+ if (other.zero) {
+ [NSException raise:NSInvalidArgumentException format:@"Divide by 0"];
+ }
+
+ ZXModulusPoly *quotient = self.field.zero;
+ ZXModulusPoly *remainder = self;
+
+ int denominatorLeadingTerm = [other coefficient:other.degree];
+ int inverseDenominatorLeadingTerm = [self.field inverse:denominatorLeadingTerm];
+
+ while ([remainder degree] >= other.degree && !remainder.zero) {
+ int degreeDifference = remainder.degree - other.degree;
+ int scale = [self.field multiply:[remainder coefficient:remainder.degree] b:inverseDenominatorLeadingTerm];
+ ZXModulusPoly *term = [other multiplyByMonomial:degreeDifference coefficient:scale];
+ ZXModulusPoly *iterationQuotient = [self.field buildMonomial:degreeDifference coefficient:scale];
+ quotient = [quotient add:iterationQuotient];
+ remainder = [remainder subtract:term];
+ }
+
+ return @[quotient, remainder];
+}
+
+- (NSString *)description {
+ 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:@" - "];
+ coefficient = -coefficient;
+ } else {
+ if ([result length] > 0) {
+ [result appendString:@" + "];
+ }
+ }
+ if (degree == 0 || coefficient != 1) {
+ [result appendFormat:@"%d", coefficient];
+ }
+ if (degree != 0) {
+ if (degree == 1) {
+ [result appendString:@"x"];
+ } else {
+ [result appendString:@"x^"];
+ [result appendFormat:@"%d", degree];
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h b/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h
new file mode 100644
index 0000000..b65ef94
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/**
+ * PDF417 error correction implementation.
+ *
+ * This example <http://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction#Example>
+ * is quite useful in understanding the algorithm.
+ */
+
+@interface ZXPDF417ECErrorCorrection : NSObject
+
+- (int)decode:(NSMutableArray *)received numECCodewords:(int)numECCodewords erasures:(NSArray *)erasures;
+
+@end
diff --git a/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.m b/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.m
new file mode 100644
index 0000000..d0c97dc
--- /dev/null
+++ b/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.m
@@ -0,0 +1,190 @@
+/*
+ * 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 "ZXModulusGF.h"
+#import "ZXModulusPoly.h"
+#import "ZXPDF417ECErrorCorrection.h"
+
+@interface ZXPDF417ECErrorCorrection ()
+
+@property (nonatomic, strong) ZXModulusGF *field;
+
+@end
+
+@implementation ZXPDF417ECErrorCorrection
+
+- (id)init {
+ if (self = [super init]) {
+ _field = [ZXModulusGF PDF417_GF];
+ }
+
+ return self;
+}
+
+- (int)decode:(NSMutableArray *)received numECCodewords:(int)numECCodewords erasures:(NSArray *)erasures {
+ int coefficients[received.count];
+ for (int i = 0; i < received.count; i++) {
+ coefficients[i] = [received[i] intValue];
+ }
+ ZXModulusPoly *poly = [[ZXModulusPoly alloc] initWithField:self.field coefficients:coefficients coefficientsLen:(int)received.count];
+
+ int S[numECCodewords];
+ for (int i = 0; i < numECCodewords; i++) {
+ S[i] = 0;
+ }
+
+ BOOL error = NO;
+ for (int i = numECCodewords; i > 0; i--) {
+ int eval = [poly evaluateAt:[self.field exp:i]];
+ S[numECCodewords - i] = eval;
+ if (eval != 0) {
+ error = YES;
+ }
+ }
+
+ if (!error) {
+ return 0;
+ }
+
+ ZXModulusPoly *knownErrors = self.field.one;
+ for (NSNumber *erasure in erasures) {
+ int b = [self.field exp:(int)received.count - 1 - [erasure intValue]];
+ // Add (1 - bx) term:
+ int termCoefficients[2] = { [self.field subtract:0 b:b], 1 };
+ ZXModulusPoly *term = [[ZXModulusPoly alloc] initWithField:self.field coefficients:termCoefficients coefficientsLen:2];
+ knownErrors = [knownErrors multiply:term];
+ }
+
+ ZXModulusPoly *syndrome = [[ZXModulusPoly alloc] initWithField:self.field coefficients:S coefficientsLen:numECCodewords];
+ //[syndrome multiply:knownErrors];
+
+ NSArray *sigmaOmega = [self runEuclideanAlgorithm:[self.field buildMonomial:numECCodewords coefficient:1] b:syndrome R:numECCodewords];
+ if (!sigmaOmega) {
+ return -1;
+ }
+
+ ZXModulusPoly *sigma = sigmaOmega[0];
+ ZXModulusPoly *omega = sigmaOmega[1];
+
+ //sigma = [sigma multiply:knownErrors];
+
+ NSArray *errorLocations = [self findErrorLocations:sigma];
+ if (!errorLocations) return NO;
+ NSArray *errorMagnitudes = [self findErrorMagnitudes:omega errorLocator:sigma errorLocations:errorLocations];
+
+ for (int i = 0; i < [errorLocations count]; i++) {
+ int position = (int)received.count - 1 - [self.field log:[errorLocations[i] intValue]];
+ if (position < 0) {
+ return -1;
+ }
+ received[position] = @([self.field subtract:[received[position] intValue]
+ b:[errorMagnitudes[i] intValue]]);
+ }
+
+ return (int)[errorLocations count];
+}
+
+- (NSArray *)runEuclideanAlgorithm:(ZXModulusPoly *)a b:(ZXModulusPoly *)b R:(int)R {
+ // Assume a's degree is >= b's
+ if (a.degree < b.degree) {
+ ZXModulusPoly *temp = a;
+ a = b;
+ b = temp;
+ }
+
+ ZXModulusPoly *rLast = a;
+ ZXModulusPoly *r = b;
+ ZXModulusPoly *tLast = self.field.zero;
+ ZXModulusPoly *t = self.field.one;
+
+ // Run Euclidean algorithm until r's degree is less than R/2
+ while (r.degree >= R / 2) {
+ ZXModulusPoly *rLastLast = rLast;
+ ZXModulusPoly *tLastLast = tLast;
+ rLast = r;
+ tLast = t;
+
+ // Divide rLastLast by rLast, with quotient in q and remainder in r
+ if (rLast.zero) {
+ // Oops, Euclidean algorithm already terminated?
+ return nil;
+ }
+ r = rLastLast;
+ ZXModulusPoly *q = self.field.zero;
+ int denominatorLeadingTerm = [rLast coefficient:rLast.degree];
+ int dltInverse = [self.field inverse:denominatorLeadingTerm];
+ while (r.degree >= rLast.degree && !r.zero) {
+ int degreeDiff = r.degree - rLast.degree;
+ int scale = [self.field multiply:[r coefficient:r.degree] b:dltInverse];
+ q = [q add:[self.field buildMonomial:degreeDiff coefficient:scale]];
+ r = [r subtract:[rLast multiplyByMonomial:degreeDiff coefficient:scale]];
+ }
+
+ t = [[[q multiply:tLast] subtract:tLastLast] negative];
+ }
+
+ int sigmaTildeAtZero = [t coefficient:0];
+ if (sigmaTildeAtZero == 0) {
+ return nil;
+ }
+
+ int inverse = [self.field inverse:sigmaTildeAtZero];
+ ZXModulusPoly *sigma = [t multiplyScalar:inverse];
+ ZXModulusPoly *omega = [r multiplyScalar:inverse];
+ return @[sigma, omega];
+}
+
+- (NSArray *)findErrorLocations:(ZXModulusPoly *)errorLocator {
+ // This is a direct application of Chien's search
+ int numErrors = errorLocator.degree;
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:numErrors];
+ for (int i = 1; i < self.field.size && result.count < numErrors; i++) {
+ if ([errorLocator evaluateAt:i] == 0) {
+ [result addObject:@([self.field inverse:i])];
+ }
+ }
+ if (result.count != numErrors) {
+ return nil;
+ }
+ return result;
+}
+
+- (NSArray *)findErrorMagnitudes:(ZXModulusPoly *)errorEvaluator errorLocator:(ZXModulusPoly *)errorLocator errorLocations:(NSArray *)errorLocations {
+ int errorLocatorDegree = errorLocator.degree;
+ int formalDerivativeCoefficients[errorLocatorDegree];
+ for (int i = 0; i < errorLocatorDegree; i++) {
+ formalDerivativeCoefficients[i] = 0;
+ }
+
+ for (int i = 1; i <= errorLocatorDegree; i++) {
+ formalDerivativeCoefficients[errorLocatorDegree - i] =
+ [self.field multiply:i b:[errorLocator coefficient:i]];
+ }
+ ZXModulusPoly *formalDerivative = [[ZXModulusPoly alloc] initWithField:self.field coefficients:formalDerivativeCoefficients coefficientsLen:errorLocatorDegree];
+
+ // This is directly applying Forney's Formula
+ int s = (int)errorLocations.count;
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:s];
+ for (int i = 0; i < s; i++) {
+ int xiInverse = [self.field inverse:[errorLocations[i] intValue]];
+ int numerator = [self.field subtract:0 b:[errorEvaluator evaluateAt:xiInverse]];
+ int denominator = [self.field inverse:[formalDerivative evaluateAt:xiInverse]];
+ [result addObject:@([self.field multiply:numerator b:denominator])];
+ }
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/detector/ZXPDF417Detector.h b/ZXingObjC/pdf417/detector/ZXPDF417Detector.h
new file mode 100644
index 0000000..4b4a74b
--- /dev/null
+++ b/ZXingObjC/pdf417/detector/ZXPDF417Detector.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates logic that can detect a PDF417 Code in an image, even if the
+ * PDF417 Code is rotated or skewed, or partially obscured.
+ */
+
+@class ZXBinaryBitmap, ZXBitArray, ZXBitMatrix, ZXDecodeHints, ZXPDF417DetectorResult;
+
+@interface ZXPDF417Detector : NSObject
+
++ (ZXPDF417DetectorResult *)detect:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints multiple:(BOOL)multiple error:(NSError **)error;
++ (void)rotate180:(ZXBitMatrix *)bitMatrix;
++ (ZXBitArray *)mirror:(ZXBitArray *)input result:(ZXBitArray *)result;
+
+@end
diff --git a/ZXingObjC/pdf417/detector/ZXPDF417Detector.m b/ZXingObjC/pdf417/detector/ZXPDF417Detector.m
new file mode 100644
index 0000000..7a14070
--- /dev/null
+++ b/ZXingObjC/pdf417/detector/ZXPDF417Detector.m
@@ -0,0 +1,349 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXBitMatrix.h"
+#import "ZXBinaryBitmap.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXGridSampler.h"
+#import "ZXMathUtils.h"
+#import "ZXPDF417Detector.h"
+#import "ZXPDF417DetectorResult.h"
+#import "ZXPerspectiveTransform.h"
+#import "ZXResultPoint.h"
+
+const int INDEXES_PATTERN_LEN = 4;
+const int INDEXES_START_PATTERN[INDEXES_PATTERN_LEN] = {0, 4, 1, 5};
+const int INDEXES_STOP_PATTERN[INDEXES_PATTERN_LEN] = {6, 2, 7, 3};
+int const PDF417_INTEGER_MATH_SHIFT = 8;
+int const PDF417_PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << PDF417_INTEGER_MATH_SHIFT;
+int const MAX_AVG_VARIANCE = (int) (PDF417_PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f);
+int const MAX_INDIVIDUAL_VARIANCE = (int) (PDF417_PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.8f);
+
+// B S B S B S B S Bar/Space pattern
+// 11111111 0 1 0 1 0 1 000
+int const PDF417_START_PATTERN_LEN = 8;
+int const PDF417_START_PATTERN[PDF417_START_PATTERN_LEN] = {8, 1, 1, 1, 1, 1, 1, 3};
+
+// 1111111 0 1 000 1 0 1 00 1
+int const PDF417_STOP_PATTERN_LEN = 9;
+int const PDF417_STOP_PATTERN[PDF417_STOP_PATTERN_LEN] = {7, 1, 1, 3, 1, 1, 1, 2, 1};
+int const MAX_PIXEL_DRIFT = 3;
+int const MAX_PATTERN_DRIFT = 5;
+// if we set the value too low, then we don't detect the correct height of the bar if the start patterns are damaged.
+// if we set the value too high, then we might detect the start pattern from a neighbor barcode.
+int const SKIPPED_ROW_COUNT_MAX = 25;
+// A PDF471 barcode should have at least 3 rows, with each row being >= 3 times the module width. Therefore it should be at least
+// 9 pixels tall. To be conservative, we use about half the size to ensure we don't miss it.
+int const ROW_STEP = 5;
+int const BARCODE_MIN_HEIGHT = 10;
+
+@implementation ZXPDF417Detector
+
+/**
+ * Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations.
+ */
++ (ZXPDF417DetectorResult *)detect:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints multiple:(BOOL)multiple error:(NSError **)error {
+ // TODO detection improvement, tryHarder could try several different luminance thresholds/blackpoints or even
+ // different binarizers
+ //boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
+
+ ZXBitMatrix *bitMatrix = [image blackMatrixWithError:error];
+
+ NSArray *barcodeCoordinates = [self detect:multiple bitMatrix:bitMatrix error:error];
+ if (!barcodeCoordinates) {
+ return nil;
+ }
+ if ([barcodeCoordinates count] == 0) {
+ [[self class] rotate180:bitMatrix];
+ barcodeCoordinates = [self detect:multiple bitMatrix:bitMatrix error:error];
+ if (!barcodeCoordinates) {
+ return nil;
+ }
+ }
+ return [[ZXPDF417DetectorResult alloc] initWithBits:bitMatrix points:barcodeCoordinates];
+}
+
+/**
+ * Detects PDF417 codes in an image. Only checks 0 degree rotation
+ */
++ (NSArray *)detect:(BOOL)multiple bitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error {
+ NSMutableArray *barcodeCoordinates = [NSMutableArray array];
+ int row = 0;
+ int column = 0;
+ BOOL foundBarcodeInRow = NO;
+ while (row < bitMatrix.height) {
+ NSArray *vertices = [self findVertices:bitMatrix startRow:row startColumn:column];
+
+ if (vertices[0] == [NSNull null] && vertices[3] == [NSNull null]) {
+ if (!foundBarcodeInRow) {
+ // we didn't find any barcode so that's the end of searching
+ break;
+ }
+ // we didn't find a barcode starting at the given column and row. Try again from the first column and slightly
+ // below the lowest barcode we found so far.
+ foundBarcodeInRow = NO;
+ column = 0;
+ for (NSArray *barcodeCoordinate in barcodeCoordinates) {
+ if (barcodeCoordinate[1] != [NSNull null]) {
+ row = MAX(row, (int) [(ZXResultPoint *)barcodeCoordinate[1] y]);
+ }
+ if (barcodeCoordinate[3] != [NSNull null]) {
+ row = MAX(row, (int) [(ZXResultPoint *)barcodeCoordinate[3] y]);
+ }
+ }
+ row += ROW_STEP;
+ continue;
+ }
+ foundBarcodeInRow = YES;
+ [barcodeCoordinates addObject:vertices];
+ if (!multiple) {
+ break;
+ }
+ // if we didn't find a right row indicator column, then continue the search for the next barcode after the
+ // start pattern of the barcode just found.
+ if (vertices[2] != [NSNull null]) {
+ column = (int) [(ZXResultPoint *)vertices[2] x];
+ row = (int) [(ZXResultPoint *)vertices[2] y];
+ } else {
+ column = (int) [(ZXResultPoint *)vertices[4] x];
+ row = (int) [(ZXResultPoint *)vertices[4] y];
+ }
+ }
+ return barcodeCoordinates;
+}
+
+// The following could go to the BitMatrix class (maybe in a more efficient version using the BitMatrix internal
+// data structures)
+/**
+ * Rotates a bit matrix by 180 degrees.
+ */
++ (void)rotate180:(ZXBitMatrix *)bitMatrix {
+ int width = bitMatrix.width;
+ int height = bitMatrix.height;
+ ZXBitArray *firstRowBitArray = [[ZXBitArray alloc] initWithSize:width];
+ ZXBitArray *secondRowBitArray = [[ZXBitArray alloc] initWithSize:width];
+ ZXBitArray *tmpBitArray = [[ZXBitArray alloc] initWithSize:width];
+ for (int y = 0; y < (height + 1) >> 1; y++) {
+ firstRowBitArray = [bitMatrix rowAtY:y row:firstRowBitArray];
+ [bitMatrix setRowAtY:y row:[self mirror:[bitMatrix rowAtY:height - 1 - y row:secondRowBitArray] result:tmpBitArray]];
+ [bitMatrix setRowAtY:height - 1 - y row:[self mirror:firstRowBitArray result:tmpBitArray]];
+ }
+}
+
+/**
+ * Copies the bits from the input to the result BitArray in reverse order
+ */
++ (ZXBitArray *)mirror:(ZXBitArray *)input result:(ZXBitArray *)result {
+ [result clear];
+ int size = input.size;
+ for (int i = 0; i < size; i++) {
+ if ([input get:i]) {
+ [result set:size - 1 - i];
+ }
+ }
+ return result;
+}
+
+/**
+ * Locate the vertices and the codewords area of a black blob using the Start
+ * and Stop patterns as locators.
+ *
+ * Returns an array containing the vertices:
+ * vertices[0] x, y top left barcode
+ * vertices[1] x, y bottom left barcode
+ * vertices[2] x, y top right barcode
+ * vertices[3] x, y bottom right barcode
+ * vertices[4] x, y top left codeword area
+ * vertices[5] x, y bottom left codeword area
+ * vertices[6] x, y top right codeword area
+ * vertices[7] x, y bottom right codeword area
+ */
++ (NSMutableArray *)findVertices:(ZXBitMatrix *)matrix startRow:(int)startRow startColumn:(int)startColumn {
+ int height = matrix.height;
+ int width = matrix.width;
+
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:8];
+ for (int i = 0; i < 8; i++) {
+ [result addObject:[NSNull null]];
+ }
+ [self copyToResult:result tmpResult:[self findRowsWithPattern:matrix height:height width:width startRow:startRow startColumn:startColumn pattern:(int *)PDF417_START_PATTERN patternLen:PDF417_START_PATTERN_LEN] destinationIndexes:(int *)INDEXES_START_PATTERN];
+
+ if (result[4] != [NSNull null]) {
+ startColumn = (int) [(ZXResultPoint *)result[4] x];
+ startRow = (int) [(ZXResultPoint *)result[4] y];
+ }
+ [self copyToResult:result tmpResult:[self findRowsWithPattern:matrix height:height width:width startRow:startRow startColumn:startColumn pattern:(int *)PDF417_STOP_PATTERN patternLen:PDF417_STOP_PATTERN_LEN] destinationIndexes:(int *)INDEXES_STOP_PATTERN];
+ return result;
+}
+
++ (void)copyToResult:(NSMutableArray *)result tmpResult:(NSMutableArray *)tmpResult destinationIndexes:(int *)destinationIndexes {
+ for (int i = 0; i < INDEXES_PATTERN_LEN; i++) {
+ result[destinationIndexes[i]] = tmpResult[i];
+ }
+}
+
++ (NSMutableArray *)findRowsWithPattern:(ZXBitMatrix *)matrix height:(int)height width:(int)width startRow:(int)startRow
+ startColumn:(int)startColumn pattern:(int *)pattern patternLen:(int)patternLen {
+ NSMutableArray *result = [NSMutableArray array];
+ for (int i = 0; i < 4; i++) {
+ [result addObject:[NSNull null]];
+ }
+ BOOL found = NO;
+ int counters[patternLen];
+ memset(counters, 0, patternLen * sizeof(int));
+ for (; startRow < height; startRow += ROW_STEP) {
+ NSRange loc = [self findGuardPattern:matrix column:startColumn row:startRow width:width whiteFirst:false pattern:pattern patternLen:patternLen counters:counters];
+ if (loc.location != NSNotFound) {
+ while (startRow > 0) {
+ NSRange previousRowLoc = [self findGuardPattern:matrix column:startColumn row:--startRow width:width whiteFirst:false pattern:pattern patternLen:patternLen counters:counters];
+ if (previousRowLoc.location != NSNotFound) {
+ loc = previousRowLoc;
+ } else {
+ startRow++;
+ break;
+ }
+ }
+ result[0] = [[ZXResultPoint alloc] initWithX:loc.location y:startRow];
+ result[1] = [[ZXResultPoint alloc] initWithX:NSMaxRange(loc) y:startRow];
+ found = YES;
+ break;
+ }
+ }
+ int stopRow = startRow + 1;
+ // Last row of the current symbol that contains pattern
+ if (found) {
+ int skippedRowCount = 0;
+ NSRange previousRowLoc = NSMakeRange((NSUInteger) [(ZXResultPoint *)result[0] x], ((NSUInteger)[(ZXResultPoint *)result[1] x]) - ((NSUInteger)[(ZXResultPoint *)result[0] x]));
+ for (; stopRow < height; stopRow++) {
+ NSRange loc = [self findGuardPattern:matrix column:(int)previousRowLoc.location row:stopRow width:width whiteFirst:NO pattern:pattern patternLen:patternLen counters:counters];
+ // a found pattern is only considered to belong to the same barcode if the start and end positions
+ // don't differ too much. Pattern drift should be not bigger than two for consecutive rows. With
+ // a higher number of skipped rows drift could be larger. To keep it simple for now, we allow a slightly
+ // larger drift and don't check for skipped rows.
+ if (loc.location != NSNotFound &&
+ ABS((int)previousRowLoc.location - (int)loc.location) < MAX_PATTERN_DRIFT &&
+ ABS((int)NSMaxRange(previousRowLoc) - (int)NSMaxRange(loc)) < MAX_PATTERN_DRIFT) {
+ previousRowLoc = loc;
+ skippedRowCount = 0;
+ } else {
+ if (skippedRowCount > SKIPPED_ROW_COUNT_MAX) {
+ break;
+ } else {
+ skippedRowCount++;
+ }
+ }
+ }
+ stopRow -= skippedRowCount + 1;
+ result[2] = [[ZXResultPoint alloc] initWithX:previousRowLoc.location y:stopRow];
+ result[3] = [[ZXResultPoint alloc] initWithX:NSMaxRange(previousRowLoc) y:stopRow];
+ }
+ if (stopRow - startRow < BARCODE_MIN_HEIGHT) {
+ for (int i = 0; i < 4; i++) {
+ result[i] = [NSNull null];
+ }
+ }
+ return result;
+}
+
++ (NSRange)findGuardPattern:(ZXBitMatrix *)matrix
+ column:(int)column
+ row:(int)row
+ width:(int)width
+ whiteFirst:(BOOL)whiteFirst
+ pattern:(int *)pattern
+ patternLen:(int)patternLen
+ counters:(int *)counters {
+ int patternLength = patternLen;
+ memset(counters, 0, patternLength * sizeof(int));
+ BOOL isWhite = whiteFirst;
+ int patternStart = column;
+ int pixelDrift = 0;
+
+ // if there are black pixels left of the current pixel shift to the left, but only for MAX_PIXEL_DRIFT pixels
+ while ([matrix getX:patternStart y:row] && patternStart > 0 && pixelDrift++ < MAX_PIXEL_DRIFT) {
+ patternStart--;
+ }
+ int x = patternStart;
+ int counterPosition = 0;
+ for (;x < width; x++) {
+ BOOL pixel = [matrix getX:x y:row];
+ if (pixel ^ isWhite) {
+ counters[counterPosition] = counters[counterPosition] + 1;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if ([self patternMatchVariance:counters countersSize:patternLength pattern:pattern maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE] < MAX_AVG_VARIANCE) {
+ return NSMakeRange(patternStart, x - patternStart);
+ }
+ patternStart += counters[0] + counters[1];
+ for (int y = 2; y < patternLength; y++) {
+ counters[y - 2] = counters[y];
+ }
+ counters[patternLength - 2] = 0;
+ counters[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ if (counterPosition == patternLength - 1) {
+ if ([self patternMatchVariance:counters countersSize:patternLen pattern:pattern maxIndividualVariance:MAX_INDIVIDUAL_VARIANCE] < MAX_AVG_VARIANCE) {
+ return NSMakeRange(patternStart, x - patternStart - 1);
+ }
+ }
+ return NSMakeRange(NSNotFound, 0);
+}
+
+/**
+ * Determines how closely a set of observed counts of runs of black/white
+ * values matches a given target pattern. This is reported as the ratio of
+ * the total variance from the expected pattern proportions across all
+ * pattern elements, to the length of the pattern.
+ */
++ (int)patternMatchVariance:(int *)counters countersSize:(int)countersSize pattern:(int *)pattern maxIndividualVariance:(int)maxIndividualVariance {
+ int numCounters = countersSize;
+ int total = 0;
+ int patternLength = 0;
+ for (int i = 0; i < numCounters; i++) {
+ total += counters[i];
+ patternLength += pattern[i];
+ }
+
+ if (total < patternLength || patternLength == 0) {
+ return INT_MAX;
+ }
+ int unitBarWidth = (total << PDF417_INTEGER_MATH_SHIFT) / patternLength;
+ maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> PDF417_INTEGER_MATH_SHIFT;
+
+ int totalVariance = 0;
+ for (int x = 0; x < numCounters; x++) {
+ int counter = counters[x] << PDF417_INTEGER_MATH_SHIFT;
+ int scaledPattern = pattern[x] * unitBarWidth;
+ int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
+ if (variance > maxIndividualVariance) {
+ return INT_MAX;
+ }
+ totalVariance += variance;
+ }
+
+ return totalVariance / total;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.h b/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.h
new file mode 100644
index 0000000..b7e8c92
--- /dev/null
+++ b/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+@class ZXBitMatrix;
+
+@interface ZXPDF417DetectorResult : NSObject
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *bits;
+@property (nonatomic, strong, readonly) NSArray *points;
+
+- (id)initWithBits:(ZXBitMatrix *)bits points:(NSArray *)points;
+
+@end
diff --git a/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.m b/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.m
new file mode 100644
index 0000000..47fa823
--- /dev/null
+++ b/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.m
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXPDF417DetectorResult.h"
+
+@implementation ZXPDF417DetectorResult
+
+- (id)initWithBits:(ZXBitMatrix *)bits points:(NSArray *)points {
+ self = [super init];
+ if (self) {
+ _bits = bits;
+ _points = points;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXBarcodeMatrix.h b/ZXingObjC/pdf417/encoder/ZXBarcodeMatrix.h
new file mode 100644
index 0000000..855f9f8
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXBarcodeMatrix.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+@class ZXBarcodeRow;
+
+/**
+ * Holds all of the information for a barcode in a format where it can be easily accessable
+ */
+@interface ZXBarcodeMatrix : NSObject
+
+@property (nonatomic, assign, readonly) int height;
+@property (nonatomic, assign, readonly) int width;
+
+- (id)initWithHeight:(int)height width:(int)width;
+- (void)setX:(int)x y:(int)y value:(int8_t)value;
+- (void)setMatrixX:(int)x y:(int)y black:(BOOL)black;
+- (void)startRow;
+- (ZXBarcodeRow *)currentRow;
+- (int8_t **)matrixWithHeight:(int *)height width:(int *)width;
+- (int8_t **)scaledMatrixWithHeight:(int *)height width:(int *)width scale:(int)scale;
+- (int8_t **)scaledMatrixWithHeight:(int *)height width:(int *)width xScale:(int)xScale yScale:(int)yScale;
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXBarcodeMatrix.m b/ZXingObjC/pdf417/encoder/ZXBarcodeMatrix.m
new file mode 100644
index 0000000..0a87ce6
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXBarcodeMatrix.m
@@ -0,0 +1,82 @@
+/*
+ * 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 "ZXBarcodeMatrix.h"
+#import "ZXBarcodeRow.h"
+
+@interface ZXBarcodeMatrix ()
+
+@property (nonatomic, assign) int currentRowIndex;
+@property (nonatomic, strong) NSArray *rowMatrix;
+
+@end
+
+@implementation ZXBarcodeMatrix
+
+- (id)initWithHeight:(int)height width:(int)width {
+ if (self = [super init]) {
+ NSMutableArray *matrix = [NSMutableArray array];
+ for (int i = 0, matrixLength = height + 2; i < matrixLength; i++) {
+ [matrix addObject:[ZXBarcodeRow barcodeRowWithWidth:(width + 4) * 17 + 1]];
+ }
+ _rowMatrix = matrix;
+ _width = width * 17;
+ _height = height + 2;
+ _currentRowIndex = 0;
+ }
+
+ return self;
+}
+
+- (void)setX:(int)x y:(int)y value:(int8_t)value {
+ [self.rowMatrix[y] setX:x value:value];
+}
+
+- (void)setMatrixX:(int)x y:(int)y black:(BOOL)black {
+ [self setX:x y:y value:(int8_t)(black ? 1 : 0)];
+}
+
+- (void)startRow {
+ ++self.currentRowIndex;
+}
+
+- (ZXBarcodeRow *)currentRow {
+ return self.rowMatrix[self.currentRowIndex];
+}
+
+- (int8_t **)matrixWithHeight:(int *)pHeight width:(int *)pWidth {
+ return [self scaledMatrixWithHeight:pHeight width:pWidth xScale:1 yScale:1];
+}
+
+- (int8_t **)scaledMatrixWithHeight:(int *)pHeight width:(int *)pWidth scale:(int)scale {
+ return [self scaledMatrixWithHeight:pHeight width:pWidth xScale:scale yScale:scale];
+}
+
+- (int8_t **)scaledMatrixWithHeight:(int *)pHeight width:(int *)pWidth xScale:(int)xScale yScale:(int)yScale {
+ int matrixHeight = self.height * yScale;
+
+ if (pHeight) *pHeight = matrixHeight;
+ if (pWidth) *pWidth = (self.width + 69) * xScale;
+
+ int8_t **matrixOut = (int8_t **)malloc(matrixHeight * sizeof(int8_t *));
+ int yMax = self.height * yScale;
+ for (int ii = 0; ii < yMax; ii++) {
+ matrixOut[yMax - ii - 1] = [self.rowMatrix[ii / yScale] scaledRow:xScale];
+ }
+ return matrixOut;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXBarcodeRow.h b/ZXingObjC/pdf417/encoder/ZXBarcodeRow.h
new file mode 100644
index 0000000..6965f59
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXBarcodeRow.h
@@ -0,0 +1,29 @@
+/*
+ * 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 ZXBarcodeRow : NSObject
+
+@property (nonatomic, assign, readonly) int8_t *row;
+@property (nonatomic, assign, readonly) int rowLength;
+
++ (ZXBarcodeRow *)barcodeRowWithWidth:(int)width;
+- (id)initWithWidth:(int)width;
+- (void)setX:(int)x value:(int8_t)value;
+- (void)setX:(int)x black:(BOOL)black;
+- (void)addBar:(BOOL)black width:(int)width;
+- (int8_t *)scaledRow:(int)scale;
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXBarcodeRow.m b/ZXingObjC/pdf417/encoder/ZXBarcodeRow.m
new file mode 100644
index 0000000..e476632
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXBarcodeRow.m
@@ -0,0 +1,70 @@
+/*
+ * 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 "ZXBarcodeRow.h"
+
+@interface ZXBarcodeRow ()
+
+@property (nonatomic, assign) int currentLocation;
+
+@end
+
+@implementation ZXBarcodeRow
+
++ (ZXBarcodeRow *)barcodeRowWithWidth:(int)width {
+ return [[ZXBarcodeRow alloc] initWithWidth:width];
+}
+
+- (id)initWithWidth:(int)width {
+ if (self = [super init]) {
+ _rowLength = width;
+ _row = (int8_t *)malloc(_rowLength * sizeof(int8_t));
+ memset(_row, 0, self.rowLength * sizeof(int8_t));
+ _currentLocation = 0;
+ }
+ return self;
+}
+
+- (void)dealloc {
+ if (_row != NULL) {
+ free(_row);
+ _row = NULL;
+ }
+}
+
+- (void)setX:(int)x value:(int8_t)value {
+ self.row[x] = value;
+}
+
+- (void)setX:(int)x black:(BOOL)black {
+ self.row[x] = (int8_t)(black ? 1 : 0);
+}
+
+- (void)addBar:(BOOL)black width:(int)width {
+ for (int ii = 0; ii < width; ii++) {
+ [self setX:self.currentLocation++ black:black];
+ }
+}
+
+- (int8_t *)scaledRow:(int)scale {
+ int8_t *output = (int8_t *)malloc(self.rowLength * scale);
+ for (int i = 0; i < self.rowLength * scale; i++) {
+ output[i] = self.row[i / scale];
+ }
+ return output;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXCompaction.h b/ZXingObjC/pdf417/encoder/ZXCompaction.h
new file mode 100644
index 0000000..60705b0
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXCompaction.h
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+typedef enum {
+ ZX_COMPACTION_AUTO,
+ ZX_COMPACTION_TEXT,
+ ZX_COMPACTION_BYTE,
+ ZX_COMPACTION_NUMERIC
+} ZXCompaction;
\ No newline at end of file
diff --git a/ZXingObjC/pdf417/encoder/ZXDimensions.h b/ZXingObjC/pdf417/encoder/ZXDimensions.h
new file mode 100644
index 0000000..81b25a9
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXDimensions.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * Data object to specify the minimum and maximum number of rows and columns for a PDF417 barcode.
+ */
+@interface ZXDimensions : NSObject
+
+@property (nonatomic, assign) int minCols;
+@property (nonatomic, assign) int maxCols;
+@property (nonatomic, assign) int minRows;
+@property (nonatomic, assign) int maxRows;
+
+- (id)initWithMinCols:(int)minCols maxCols:(int)maxCols minRows:(int)minRows maxRows:(int)maxRows;
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXDimensions.m b/ZXingObjC/pdf417/encoder/ZXDimensions.m
new file mode 100644
index 0000000..17d70f6
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXDimensions.m
@@ -0,0 +1,32 @@
+/*
+ * 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 "ZXDimensions.h"
+
+@implementation ZXDimensions
+
+- (id)initWithMinCols:(int)minCols maxCols:(int)maxCols minRows:(int)minRows maxRows:(int)maxRows {
+ if (self = [super init]) {
+ _minCols = minCols;
+ _maxCols = maxCols;
+ _minRows = minRows;
+ _maxRows = maxRows;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417.h b/ZXingObjC/pdf417/encoder/ZXPDF417.h
new file mode 100644
index 0000000..52cedba
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXPDF417.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part
+ *
+ * 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 "ZXCompaction.h"
+
+@class ZXBarcodeMatrix;
+
+/*
+ * This file has been modified from its original form in Barcode4J.
+ */
+@interface ZXPDF417 : NSObject
+
+@property (nonatomic, strong, readonly) ZXBarcodeMatrix *barcodeMatrix;
+@property (nonatomic, assign) BOOL compact;
+@property (nonatomic, assign) ZXCompaction compaction;
+
+- (id)initWithCompact:(BOOL)compact;
+- (BOOL)generateBarcodeLogic:(NSString *)msg errorCorrectionLevel:(int)errorCorrectionLevel error:(NSError **)error;
+- (BOOL)determineDimensions:(int *)dimension sourceCodeWords:(int)sourceCodeWords errorCorrectionCodeWords:(int)errorCorrectionCodeWords error:(NSError **)error;
+- (void)setDimensionsWithMaxCols:(int)maxCols minCols:(int)minCols maxRows:(int)maxRows minRows:(int)minRows;
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417.m b/ZXingObjC/pdf417/encoder/ZXPDF417.m
new file mode 100644
index 0000000..d61fb8d
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXPDF417.m
@@ -0,0 +1,729 @@
+/*
+ * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part
+ *
+ * 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 "ZXBarcodeMatrix.h"
+#import "ZXBarcodeRow.h"
+#import "ZXErrors.h"
+#import "ZXPDF417.h"
+#import "ZXPDF417ErrorCorrection.h"
+#import "ZXPDF417HighLevelEncoder.h"
+
+/**
+ * The start pattern (17 bits)
+ */
+const int START_PATTERN_INT = 0x1fea8;
+/**
+ * The stop pattern (18 bits)
+ */
+const int STOP_PATTERN_INT = 0x3fa29;
+
+/**
+ * The codeword table from the Annex A of ISO/IEC 15438:2001(E).
+ */
+#define CODEWORD_TABLE_LEN 3
+#define CODEWORD_TABLE_SUB_LEN 929
+const int PDF_CODEWORD_TABLE[CODEWORD_TABLE_LEN][CODEWORD_TABLE_SUB_LEN] = {
+ {0x1d5c0, 0x1eaf0, 0x1f57c, 0x1d4e0, 0x1ea78, 0x1f53e,
+ 0x1a8c0, 0x1d470, 0x1a860, 0x15040, 0x1a830, 0x15020,
+ 0x1adc0, 0x1d6f0, 0x1eb7c, 0x1ace0, 0x1d678, 0x1eb3e,
+ 0x158c0, 0x1ac70, 0x15860, 0x15dc0, 0x1aef0, 0x1d77c,
+ 0x15ce0, 0x1ae78, 0x1d73e, 0x15c70, 0x1ae3c, 0x15ef0,
+ 0x1af7c, 0x15e78, 0x1af3e, 0x15f7c, 0x1f5fa, 0x1d2e0,
+ 0x1e978, 0x1f4be, 0x1a4c0, 0x1d270, 0x1e93c, 0x1a460,
+ 0x1d238, 0x14840, 0x1a430, 0x1d21c, 0x14820, 0x1a418,
+ 0x14810, 0x1a6e0, 0x1d378, 0x1e9be, 0x14cc0, 0x1a670,
+ 0x1d33c, 0x14c60, 0x1a638, 0x1d31e, 0x14c30, 0x1a61c,
+ 0x14ee0, 0x1a778, 0x1d3be, 0x14e70, 0x1a73c, 0x14e38,
+ 0x1a71e, 0x14f78, 0x1a7be, 0x14f3c, 0x14f1e, 0x1a2c0,
+ 0x1d170, 0x1e8bc, 0x1a260, 0x1d138, 0x1e89e, 0x14440,
+ 0x1a230, 0x1d11c, 0x14420, 0x1a218, 0x14410, 0x14408,
+ 0x146c0, 0x1a370, 0x1d1bc, 0x14660, 0x1a338, 0x1d19e,
+ 0x14630, 0x1a31c, 0x14618, 0x1460c, 0x14770, 0x1a3bc,
+ 0x14738, 0x1a39e, 0x1471c, 0x147bc, 0x1a160, 0x1d0b8,
+ 0x1e85e, 0x14240, 0x1a130, 0x1d09c, 0x14220, 0x1a118,
+ 0x1d08e, 0x14210, 0x1a10c, 0x14208, 0x1a106, 0x14360,
+ 0x1a1b8, 0x1d0de, 0x14330, 0x1a19c, 0x14318, 0x1a18e,
+ 0x1430c, 0x14306, 0x1a1de, 0x1438e, 0x14140, 0x1a0b0,
+ 0x1d05c, 0x14120, 0x1a098, 0x1d04e, 0x14110, 0x1a08c,
+ 0x14108, 0x1a086, 0x14104, 0x141b0, 0x14198, 0x1418c,
+ 0x140a0, 0x1d02e, 0x1a04c, 0x1a046, 0x14082, 0x1cae0,
+ 0x1e578, 0x1f2be, 0x194c0, 0x1ca70, 0x1e53c, 0x19460,
+ 0x1ca38, 0x1e51e, 0x12840, 0x19430, 0x12820, 0x196e0,
+ 0x1cb78, 0x1e5be, 0x12cc0, 0x19670, 0x1cb3c, 0x12c60,
+ 0x19638, 0x12c30, 0x12c18, 0x12ee0, 0x19778, 0x1cbbe,
+ 0x12e70, 0x1973c, 0x12e38, 0x12e1c, 0x12f78, 0x197be,
+ 0x12f3c, 0x12fbe, 0x1dac0, 0x1ed70, 0x1f6bc, 0x1da60,
+ 0x1ed38, 0x1f69e, 0x1b440, 0x1da30, 0x1ed1c, 0x1b420,
+ 0x1da18, 0x1ed0e, 0x1b410, 0x1da0c, 0x192c0, 0x1c970,
+ 0x1e4bc, 0x1b6c0, 0x19260, 0x1c938, 0x1e49e, 0x1b660,
+ 0x1db38, 0x1ed9e, 0x16c40, 0x12420, 0x19218, 0x1c90e,
+ 0x16c20, 0x1b618, 0x16c10, 0x126c0, 0x19370, 0x1c9bc,
+ 0x16ec0, 0x12660, 0x19338, 0x1c99e, 0x16e60, 0x1b738,
+ 0x1db9e, 0x16e30, 0x12618, 0x16e18, 0x12770, 0x193bc,
+ 0x16f70, 0x12738, 0x1939e, 0x16f38, 0x1b79e, 0x16f1c,
+ 0x127bc, 0x16fbc, 0x1279e, 0x16f9e, 0x1d960, 0x1ecb8,
+ 0x1f65e, 0x1b240, 0x1d930, 0x1ec9c, 0x1b220, 0x1d918,
+ 0x1ec8e, 0x1b210, 0x1d90c, 0x1b208, 0x1b204, 0x19160,
+ 0x1c8b8, 0x1e45e, 0x1b360, 0x19130, 0x1c89c, 0x16640,
+ 0x12220, 0x1d99c, 0x1c88e, 0x16620, 0x12210, 0x1910c,
+ 0x16610, 0x1b30c, 0x19106, 0x12204, 0x12360, 0x191b8,
+ 0x1c8de, 0x16760, 0x12330, 0x1919c, 0x16730, 0x1b39c,
+ 0x1918e, 0x16718, 0x1230c, 0x12306, 0x123b8, 0x191de,
+ 0x167b8, 0x1239c, 0x1679c, 0x1238e, 0x1678e, 0x167de,
+ 0x1b140, 0x1d8b0, 0x1ec5c, 0x1b120, 0x1d898, 0x1ec4e,
+ 0x1b110, 0x1d88c, 0x1b108, 0x1d886, 0x1b104, 0x1b102,
+ 0x12140, 0x190b0, 0x1c85c, 0x16340, 0x12120, 0x19098,
+ 0x1c84e, 0x16320, 0x1b198, 0x1d8ce, 0x16310, 0x12108,
+ 0x19086, 0x16308, 0x1b186, 0x16304, 0x121b0, 0x190dc,
+ 0x163b0, 0x12198, 0x190ce, 0x16398, 0x1b1ce, 0x1638c,
+ 0x12186, 0x16386, 0x163dc, 0x163ce, 0x1b0a0, 0x1d858,
+ 0x1ec2e, 0x1b090, 0x1d84c, 0x1b088, 0x1d846, 0x1b084,
+ 0x1b082, 0x120a0, 0x19058, 0x1c82e, 0x161a0, 0x12090,
+ 0x1904c, 0x16190, 0x1b0cc, 0x19046, 0x16188, 0x12084,
+ 0x16184, 0x12082, 0x120d8, 0x161d8, 0x161cc, 0x161c6,
+ 0x1d82c, 0x1d826, 0x1b042, 0x1902c, 0x12048, 0x160c8,
+ 0x160c4, 0x160c2, 0x18ac0, 0x1c570, 0x1e2bc, 0x18a60,
+ 0x1c538, 0x11440, 0x18a30, 0x1c51c, 0x11420, 0x18a18,
+ 0x11410, 0x11408, 0x116c0, 0x18b70, 0x1c5bc, 0x11660,
+ 0x18b38, 0x1c59e, 0x11630, 0x18b1c, 0x11618, 0x1160c,
+ 0x11770, 0x18bbc, 0x11738, 0x18b9e, 0x1171c, 0x117bc,
+ 0x1179e, 0x1cd60, 0x1e6b8, 0x1f35e, 0x19a40, 0x1cd30,
+ 0x1e69c, 0x19a20, 0x1cd18, 0x1e68e, 0x19a10, 0x1cd0c,
+ 0x19a08, 0x1cd06, 0x18960, 0x1c4b8, 0x1e25e, 0x19b60,
+ 0x18930, 0x1c49c, 0x13640, 0x11220, 0x1cd9c, 0x1c48e,
+ 0x13620, 0x19b18, 0x1890c, 0x13610, 0x11208, 0x13608,
+ 0x11360, 0x189b8, 0x1c4de, 0x13760, 0x11330, 0x1cdde,
+ 0x13730, 0x19b9c, 0x1898e, 0x13718, 0x1130c, 0x1370c,
+ 0x113b8, 0x189de, 0x137b8, 0x1139c, 0x1379c, 0x1138e,
+ 0x113de, 0x137de, 0x1dd40, 0x1eeb0, 0x1f75c, 0x1dd20,
+ 0x1ee98, 0x1f74e, 0x1dd10, 0x1ee8c, 0x1dd08, 0x1ee86,
+ 0x1dd04, 0x19940, 0x1ccb0, 0x1e65c, 0x1bb40, 0x19920,
+ 0x1eedc, 0x1e64e, 0x1bb20, 0x1dd98, 0x1eece, 0x1bb10,
+ 0x19908, 0x1cc86, 0x1bb08, 0x1dd86, 0x19902, 0x11140,
+ 0x188b0, 0x1c45c, 0x13340, 0x11120, 0x18898, 0x1c44e,
+ 0x17740, 0x13320, 0x19998, 0x1ccce, 0x17720, 0x1bb98,
+ 0x1ddce, 0x18886, 0x17710, 0x13308, 0x19986, 0x17708,
+ 0x11102, 0x111b0, 0x188dc, 0x133b0, 0x11198, 0x188ce,
+ 0x177b0, 0x13398, 0x199ce, 0x17798, 0x1bbce, 0x11186,
+ 0x13386, 0x111dc, 0x133dc, 0x111ce, 0x177dc, 0x133ce,
+ 0x1dca0, 0x1ee58, 0x1f72e, 0x1dc90, 0x1ee4c, 0x1dc88,
+ 0x1ee46, 0x1dc84, 0x1dc82, 0x198a0, 0x1cc58, 0x1e62e,
+ 0x1b9a0, 0x19890, 0x1ee6e, 0x1b990, 0x1dccc, 0x1cc46,
+ 0x1b988, 0x19884, 0x1b984, 0x19882, 0x1b982, 0x110a0,
+ 0x18858, 0x1c42e, 0x131a0, 0x11090, 0x1884c, 0x173a0,
+ 0x13190, 0x198cc, 0x18846, 0x17390, 0x1b9cc, 0x11084,
+ 0x17388, 0x13184, 0x11082, 0x13182, 0x110d8, 0x1886e,
+ 0x131d8, 0x110cc, 0x173d8, 0x131cc, 0x110c6, 0x173cc,
+ 0x131c6, 0x110ee, 0x173ee, 0x1dc50, 0x1ee2c, 0x1dc48,
+ 0x1ee26, 0x1dc44, 0x1dc42, 0x19850, 0x1cc2c, 0x1b8d0,
+ 0x19848, 0x1cc26, 0x1b8c8, 0x1dc66, 0x1b8c4, 0x19842,
+ 0x1b8c2, 0x11050, 0x1882c, 0x130d0, 0x11048, 0x18826,
+ 0x171d0, 0x130c8, 0x19866, 0x171c8, 0x1b8e6, 0x11042,
+ 0x171c4, 0x130c2, 0x171c2, 0x130ec, 0x171ec, 0x171e6,
+ 0x1ee16, 0x1dc22, 0x1cc16, 0x19824, 0x19822, 0x11028,
+ 0x13068, 0x170e8, 0x11022, 0x13062, 0x18560, 0x10a40,
+ 0x18530, 0x10a20, 0x18518, 0x1c28e, 0x10a10, 0x1850c,
+ 0x10a08, 0x18506, 0x10b60, 0x185b8, 0x1c2de, 0x10b30,
+ 0x1859c, 0x10b18, 0x1858e, 0x10b0c, 0x10b06, 0x10bb8,
+ 0x185de, 0x10b9c, 0x10b8e, 0x10bde, 0x18d40, 0x1c6b0,
+ 0x1e35c, 0x18d20, 0x1c698, 0x18d10, 0x1c68c, 0x18d08,
+ 0x1c686, 0x18d04, 0x10940, 0x184b0, 0x1c25c, 0x11b40,
+ 0x10920, 0x1c6dc, 0x1c24e, 0x11b20, 0x18d98, 0x1c6ce,
+ 0x11b10, 0x10908, 0x18486, 0x11b08, 0x18d86, 0x10902,
+ 0x109b0, 0x184dc, 0x11bb0, 0x10998, 0x184ce, 0x11b98,
+ 0x18dce, 0x11b8c, 0x10986, 0x109dc, 0x11bdc, 0x109ce,
+ 0x11bce, 0x1cea0, 0x1e758, 0x1f3ae, 0x1ce90, 0x1e74c,
+ 0x1ce88, 0x1e746, 0x1ce84, 0x1ce82, 0x18ca0, 0x1c658,
+ 0x19da0, 0x18c90, 0x1c64c, 0x19d90, 0x1cecc, 0x1c646,
+ 0x19d88, 0x18c84, 0x19d84, 0x18c82, 0x19d82, 0x108a0,
+ 0x18458, 0x119a0, 0x10890, 0x1c66e, 0x13ba0, 0x11990,
+ 0x18ccc, 0x18446, 0x13b90, 0x19dcc, 0x10884, 0x13b88,
+ 0x11984, 0x10882, 0x11982, 0x108d8, 0x1846e, 0x119d8,
+ 0x108cc, 0x13bd8, 0x119cc, 0x108c6, 0x13bcc, 0x119c6,
+ 0x108ee, 0x119ee, 0x13bee, 0x1ef50, 0x1f7ac, 0x1ef48,
+ 0x1f7a6, 0x1ef44, 0x1ef42, 0x1ce50, 0x1e72c, 0x1ded0,
+ 0x1ef6c, 0x1e726, 0x1dec8, 0x1ef66, 0x1dec4, 0x1ce42,
+ 0x1dec2, 0x18c50, 0x1c62c, 0x19cd0, 0x18c48, 0x1c626,
+ 0x1bdd0, 0x19cc8, 0x1ce66, 0x1bdc8, 0x1dee6, 0x18c42,
+ 0x1bdc4, 0x19cc2, 0x1bdc2, 0x10850, 0x1842c, 0x118d0,
+ 0x10848, 0x18426, 0x139d0, 0x118c8, 0x18c66, 0x17bd0,
+ 0x139c8, 0x19ce6, 0x10842, 0x17bc8, 0x1bde6, 0x118c2,
+ 0x17bc4, 0x1086c, 0x118ec, 0x10866, 0x139ec, 0x118e6,
+ 0x17bec, 0x139e6, 0x17be6, 0x1ef28, 0x1f796, 0x1ef24,
+ 0x1ef22, 0x1ce28, 0x1e716, 0x1de68, 0x1ef36, 0x1de64,
+ 0x1ce22, 0x1de62, 0x18c28, 0x1c616, 0x19c68, 0x18c24,
+ 0x1bce8, 0x19c64, 0x18c22, 0x1bce4, 0x19c62, 0x1bce2,
+ 0x10828, 0x18416, 0x11868, 0x18c36, 0x138e8, 0x11864,
+ 0x10822, 0x179e8, 0x138e4, 0x11862, 0x179e4, 0x138e2,
+ 0x179e2, 0x11876, 0x179f6, 0x1ef12, 0x1de34, 0x1de32,
+ 0x19c34, 0x1bc74, 0x1bc72, 0x11834, 0x13874, 0x178f4,
+ 0x178f2, 0x10540, 0x10520, 0x18298, 0x10510, 0x10508,
+ 0x10504, 0x105b0, 0x10598, 0x1058c, 0x10586, 0x105dc,
+ 0x105ce, 0x186a0, 0x18690, 0x1c34c, 0x18688, 0x1c346,
+ 0x18684, 0x18682, 0x104a0, 0x18258, 0x10da0, 0x186d8,
+ 0x1824c, 0x10d90, 0x186cc, 0x10d88, 0x186c6, 0x10d84,
+ 0x10482, 0x10d82, 0x104d8, 0x1826e, 0x10dd8, 0x186ee,
+ 0x10dcc, 0x104c6, 0x10dc6, 0x104ee, 0x10dee, 0x1c750,
+ 0x1c748, 0x1c744, 0x1c742, 0x18650, 0x18ed0, 0x1c76c,
+ 0x1c326, 0x18ec8, 0x1c766, 0x18ec4, 0x18642, 0x18ec2,
+ 0x10450, 0x10cd0, 0x10448, 0x18226, 0x11dd0, 0x10cc8,
+ 0x10444, 0x11dc8, 0x10cc4, 0x10442, 0x11dc4, 0x10cc2,
+ 0x1046c, 0x10cec, 0x10466, 0x11dec, 0x10ce6, 0x11de6,
+ 0x1e7a8, 0x1e7a4, 0x1e7a2, 0x1c728, 0x1cf68, 0x1e7b6,
+ 0x1cf64, 0x1c722, 0x1cf62, 0x18628, 0x1c316, 0x18e68,
+ 0x1c736, 0x19ee8, 0x18e64, 0x18622, 0x19ee4, 0x18e62,
+ 0x19ee2, 0x10428, 0x18216, 0x10c68, 0x18636, 0x11ce8,
+ 0x10c64, 0x10422, 0x13de8, 0x11ce4, 0x10c62, 0x13de4,
+ 0x11ce2, 0x10436, 0x10c76, 0x11cf6, 0x13df6, 0x1f7d4,
+ 0x1f7d2, 0x1e794, 0x1efb4, 0x1e792, 0x1efb2, 0x1c714,
+ 0x1cf34, 0x1c712, 0x1df74, 0x1cf32, 0x1df72, 0x18614,
+ 0x18e34, 0x18612, 0x19e74, 0x18e32, 0x1bef4},
+ {0x1f560, 0x1fab8, 0x1ea40, 0x1f530, 0x1fa9c, 0x1ea20,
+ 0x1f518, 0x1fa8e, 0x1ea10, 0x1f50c, 0x1ea08, 0x1f506,
+ 0x1ea04, 0x1eb60, 0x1f5b8, 0x1fade, 0x1d640, 0x1eb30,
+ 0x1f59c, 0x1d620, 0x1eb18, 0x1f58e, 0x1d610, 0x1eb0c,
+ 0x1d608, 0x1eb06, 0x1d604, 0x1d760, 0x1ebb8, 0x1f5de,
+ 0x1ae40, 0x1d730, 0x1eb9c, 0x1ae20, 0x1d718, 0x1eb8e,
+ 0x1ae10, 0x1d70c, 0x1ae08, 0x1d706, 0x1ae04, 0x1af60,
+ 0x1d7b8, 0x1ebde, 0x15e40, 0x1af30, 0x1d79c, 0x15e20,
+ 0x1af18, 0x1d78e, 0x15e10, 0x1af0c, 0x15e08, 0x1af06,
+ 0x15f60, 0x1afb8, 0x1d7de, 0x15f30, 0x1af9c, 0x15f18,
+ 0x1af8e, 0x15f0c, 0x15fb8, 0x1afde, 0x15f9c, 0x15f8e,
+ 0x1e940, 0x1f4b0, 0x1fa5c, 0x1e920, 0x1f498, 0x1fa4e,
+ 0x1e910, 0x1f48c, 0x1e908, 0x1f486, 0x1e904, 0x1e902,
+ 0x1d340, 0x1e9b0, 0x1f4dc, 0x1d320, 0x1e998, 0x1f4ce,
+ 0x1d310, 0x1e98c, 0x1d308, 0x1e986, 0x1d304, 0x1d302,
+ 0x1a740, 0x1d3b0, 0x1e9dc, 0x1a720, 0x1d398, 0x1e9ce,
+ 0x1a710, 0x1d38c, 0x1a708, 0x1d386, 0x1a704, 0x1a702,
+ 0x14f40, 0x1a7b0, 0x1d3dc, 0x14f20, 0x1a798, 0x1d3ce,
+ 0x14f10, 0x1a78c, 0x14f08, 0x1a786, 0x14f04, 0x14fb0,
+ 0x1a7dc, 0x14f98, 0x1a7ce, 0x14f8c, 0x14f86, 0x14fdc,
+ 0x14fce, 0x1e8a0, 0x1f458, 0x1fa2e, 0x1e890, 0x1f44c,
+ 0x1e888, 0x1f446, 0x1e884, 0x1e882, 0x1d1a0, 0x1e8d8,
+ 0x1f46e, 0x1d190, 0x1e8cc, 0x1d188, 0x1e8c6, 0x1d184,
+ 0x1d182, 0x1a3a0, 0x1d1d8, 0x1e8ee, 0x1a390, 0x1d1cc,
+ 0x1a388, 0x1d1c6, 0x1a384, 0x1a382, 0x147a0, 0x1a3d8,
+ 0x1d1ee, 0x14790, 0x1a3cc, 0x14788, 0x1a3c6, 0x14784,
+ 0x14782, 0x147d8, 0x1a3ee, 0x147cc, 0x147c6, 0x147ee,
+ 0x1e850, 0x1f42c, 0x1e848, 0x1f426, 0x1e844, 0x1e842,
+ 0x1d0d0, 0x1e86c, 0x1d0c8, 0x1e866, 0x1d0c4, 0x1d0c2,
+ 0x1a1d0, 0x1d0ec, 0x1a1c8, 0x1d0e6, 0x1a1c4, 0x1a1c2,
+ 0x143d0, 0x1a1ec, 0x143c8, 0x1a1e6, 0x143c4, 0x143c2,
+ 0x143ec, 0x143e6, 0x1e828, 0x1f416, 0x1e824, 0x1e822,
+ 0x1d068, 0x1e836, 0x1d064, 0x1d062, 0x1a0e8, 0x1d076,
+ 0x1a0e4, 0x1a0e2, 0x141e8, 0x1a0f6, 0x141e4, 0x141e2,
+ 0x1e814, 0x1e812, 0x1d034, 0x1d032, 0x1a074, 0x1a072,
+ 0x1e540, 0x1f2b0, 0x1f95c, 0x1e520, 0x1f298, 0x1f94e,
+ 0x1e510, 0x1f28c, 0x1e508, 0x1f286, 0x1e504, 0x1e502,
+ 0x1cb40, 0x1e5b0, 0x1f2dc, 0x1cb20, 0x1e598, 0x1f2ce,
+ 0x1cb10, 0x1e58c, 0x1cb08, 0x1e586, 0x1cb04, 0x1cb02,
+ 0x19740, 0x1cbb0, 0x1e5dc, 0x19720, 0x1cb98, 0x1e5ce,
+ 0x19710, 0x1cb8c, 0x19708, 0x1cb86, 0x19704, 0x19702,
+ 0x12f40, 0x197b0, 0x1cbdc, 0x12f20, 0x19798, 0x1cbce,
+ 0x12f10, 0x1978c, 0x12f08, 0x19786, 0x12f04, 0x12fb0,
+ 0x197dc, 0x12f98, 0x197ce, 0x12f8c, 0x12f86, 0x12fdc,
+ 0x12fce, 0x1f6a0, 0x1fb58, 0x16bf0, 0x1f690, 0x1fb4c,
+ 0x169f8, 0x1f688, 0x1fb46, 0x168fc, 0x1f684, 0x1f682,
+ 0x1e4a0, 0x1f258, 0x1f92e, 0x1eda0, 0x1e490, 0x1fb6e,
+ 0x1ed90, 0x1f6cc, 0x1f246, 0x1ed88, 0x1e484, 0x1ed84,
+ 0x1e482, 0x1ed82, 0x1c9a0, 0x1e4d8, 0x1f26e, 0x1dba0,
+ 0x1c990, 0x1e4cc, 0x1db90, 0x1edcc, 0x1e4c6, 0x1db88,
+ 0x1c984, 0x1db84, 0x1c982, 0x1db82, 0x193a0, 0x1c9d8,
+ 0x1e4ee, 0x1b7a0, 0x19390, 0x1c9cc, 0x1b790, 0x1dbcc,
+ 0x1c9c6, 0x1b788, 0x19384, 0x1b784, 0x19382, 0x1b782,
+ 0x127a0, 0x193d8, 0x1c9ee, 0x16fa0, 0x12790, 0x193cc,
+ 0x16f90, 0x1b7cc, 0x193c6, 0x16f88, 0x12784, 0x16f84,
+ 0x12782, 0x127d8, 0x193ee, 0x16fd8, 0x127cc, 0x16fcc,
+ 0x127c6, 0x16fc6, 0x127ee, 0x1f650, 0x1fb2c, 0x165f8,
+ 0x1f648, 0x1fb26, 0x164fc, 0x1f644, 0x1647e, 0x1f642,
+ 0x1e450, 0x1f22c, 0x1ecd0, 0x1e448, 0x1f226, 0x1ecc8,
+ 0x1f666, 0x1ecc4, 0x1e442, 0x1ecc2, 0x1c8d0, 0x1e46c,
+ 0x1d9d0, 0x1c8c8, 0x1e466, 0x1d9c8, 0x1ece6, 0x1d9c4,
+ 0x1c8c2, 0x1d9c2, 0x191d0, 0x1c8ec, 0x1b3d0, 0x191c8,
+ 0x1c8e6, 0x1b3c8, 0x1d9e6, 0x1b3c4, 0x191c2, 0x1b3c2,
+ 0x123d0, 0x191ec, 0x167d0, 0x123c8, 0x191e6, 0x167c8,
+ 0x1b3e6, 0x167c4, 0x123c2, 0x167c2, 0x123ec, 0x167ec,
+ 0x123e6, 0x167e6, 0x1f628, 0x1fb16, 0x162fc, 0x1f624,
+ 0x1627e, 0x1f622, 0x1e428, 0x1f216, 0x1ec68, 0x1f636,
+ 0x1ec64, 0x1e422, 0x1ec62, 0x1c868, 0x1e436, 0x1d8e8,
+ 0x1c864, 0x1d8e4, 0x1c862, 0x1d8e2, 0x190e8, 0x1c876,
+ 0x1b1e8, 0x1d8f6, 0x1b1e4, 0x190e2, 0x1b1e2, 0x121e8,
+ 0x190f6, 0x163e8, 0x121e4, 0x163e4, 0x121e2, 0x163e2,
+ 0x121f6, 0x163f6, 0x1f614, 0x1617e, 0x1f612, 0x1e414,
+ 0x1ec34, 0x1e412, 0x1ec32, 0x1c834, 0x1d874, 0x1c832,
+ 0x1d872, 0x19074, 0x1b0f4, 0x19072, 0x1b0f2, 0x120f4,
+ 0x161f4, 0x120f2, 0x161f2, 0x1f60a, 0x1e40a, 0x1ec1a,
+ 0x1c81a, 0x1d83a, 0x1903a, 0x1b07a, 0x1e2a0, 0x1f158,
+ 0x1f8ae, 0x1e290, 0x1f14c, 0x1e288, 0x1f146, 0x1e284,
+ 0x1e282, 0x1c5a0, 0x1e2d8, 0x1f16e, 0x1c590, 0x1e2cc,
+ 0x1c588, 0x1e2c6, 0x1c584, 0x1c582, 0x18ba0, 0x1c5d8,
+ 0x1e2ee, 0x18b90, 0x1c5cc, 0x18b88, 0x1c5c6, 0x18b84,
+ 0x18b82, 0x117a0, 0x18bd8, 0x1c5ee, 0x11790, 0x18bcc,
+ 0x11788, 0x18bc6, 0x11784, 0x11782, 0x117d8, 0x18bee,
+ 0x117cc, 0x117c6, 0x117ee, 0x1f350, 0x1f9ac, 0x135f8,
+ 0x1f348, 0x1f9a6, 0x134fc, 0x1f344, 0x1347e, 0x1f342,
+ 0x1e250, 0x1f12c, 0x1e6d0, 0x1e248, 0x1f126, 0x1e6c8,
+ 0x1f366, 0x1e6c4, 0x1e242, 0x1e6c2, 0x1c4d0, 0x1e26c,
+ 0x1cdd0, 0x1c4c8, 0x1e266, 0x1cdc8, 0x1e6e6, 0x1cdc4,
+ 0x1c4c2, 0x1cdc2, 0x189d0, 0x1c4ec, 0x19bd0, 0x189c8,
+ 0x1c4e6, 0x19bc8, 0x1cde6, 0x19bc4, 0x189c2, 0x19bc2,
+ 0x113d0, 0x189ec, 0x137d0, 0x113c8, 0x189e6, 0x137c8,
+ 0x19be6, 0x137c4, 0x113c2, 0x137c2, 0x113ec, 0x137ec,
+ 0x113e6, 0x137e6, 0x1fba8, 0x175f0, 0x1bafc, 0x1fba4,
+ 0x174f8, 0x1ba7e, 0x1fba2, 0x1747c, 0x1743e, 0x1f328,
+ 0x1f996, 0x132fc, 0x1f768, 0x1fbb6, 0x176fc, 0x1327e,
+ 0x1f764, 0x1f322, 0x1767e, 0x1f762, 0x1e228, 0x1f116,
+ 0x1e668, 0x1e224, 0x1eee8, 0x1f776, 0x1e222, 0x1eee4,
+ 0x1e662, 0x1eee2, 0x1c468, 0x1e236, 0x1cce8, 0x1c464,
+ 0x1dde8, 0x1cce4, 0x1c462, 0x1dde4, 0x1cce2, 0x1dde2,
+ 0x188e8, 0x1c476, 0x199e8, 0x188e4, 0x1bbe8, 0x199e4,
+ 0x188e2, 0x1bbe4, 0x199e2, 0x1bbe2, 0x111e8, 0x188f6,
+ 0x133e8, 0x111e4, 0x177e8, 0x133e4, 0x111e2, 0x177e4,
+ 0x133e2, 0x177e2, 0x111f6, 0x133f6, 0x1fb94, 0x172f8,
+ 0x1b97e, 0x1fb92, 0x1727c, 0x1723e, 0x1f314, 0x1317e,
+ 0x1f734, 0x1f312, 0x1737e, 0x1f732, 0x1e214, 0x1e634,
+ 0x1e212, 0x1ee74, 0x1e632, 0x1ee72, 0x1c434, 0x1cc74,
+ 0x1c432, 0x1dcf4, 0x1cc72, 0x1dcf2, 0x18874, 0x198f4,
+ 0x18872, 0x1b9f4, 0x198f2, 0x1b9f2, 0x110f4, 0x131f4,
+ 0x110f2, 0x173f4, 0x131f2, 0x173f2, 0x1fb8a, 0x1717c,
+ 0x1713e, 0x1f30a, 0x1f71a, 0x1e20a, 0x1e61a, 0x1ee3a,
+ 0x1c41a, 0x1cc3a, 0x1dc7a, 0x1883a, 0x1987a, 0x1b8fa,
+ 0x1107a, 0x130fa, 0x171fa, 0x170be, 0x1e150, 0x1f0ac,
+ 0x1e148, 0x1f0a6, 0x1e144, 0x1e142, 0x1c2d0, 0x1e16c,
+ 0x1c2c8, 0x1e166, 0x1c2c4, 0x1c2c2, 0x185d0, 0x1c2ec,
+ 0x185c8, 0x1c2e6, 0x185c4, 0x185c2, 0x10bd0, 0x185ec,
+ 0x10bc8, 0x185e6, 0x10bc4, 0x10bc2, 0x10bec, 0x10be6,
+ 0x1f1a8, 0x1f8d6, 0x11afc, 0x1f1a4, 0x11a7e, 0x1f1a2,
+ 0x1e128, 0x1f096, 0x1e368, 0x1e124, 0x1e364, 0x1e122,
+ 0x1e362, 0x1c268, 0x1e136, 0x1c6e8, 0x1c264, 0x1c6e4,
+ 0x1c262, 0x1c6e2, 0x184e8, 0x1c276, 0x18de8, 0x184e4,
+ 0x18de4, 0x184e2, 0x18de2, 0x109e8, 0x184f6, 0x11be8,
+ 0x109e4, 0x11be4, 0x109e2, 0x11be2, 0x109f6, 0x11bf6,
+ 0x1f9d4, 0x13af8, 0x19d7e, 0x1f9d2, 0x13a7c, 0x13a3e,
+ 0x1f194, 0x1197e, 0x1f3b4, 0x1f192, 0x13b7e, 0x1f3b2,
+ 0x1e114, 0x1e334, 0x1e112, 0x1e774, 0x1e332, 0x1e772,
+ 0x1c234, 0x1c674, 0x1c232, 0x1cef4, 0x1c672, 0x1cef2,
+ 0x18474, 0x18cf4, 0x18472, 0x19df4, 0x18cf2, 0x19df2,
+ 0x108f4, 0x119f4, 0x108f2, 0x13bf4, 0x119f2, 0x13bf2,
+ 0x17af0, 0x1bd7c, 0x17a78, 0x1bd3e, 0x17a3c, 0x17a1e,
+ 0x1f9ca, 0x1397c, 0x1fbda, 0x17b7c, 0x1393e, 0x17b3e,
+ 0x1f18a, 0x1f39a, 0x1f7ba, 0x1e10a, 0x1e31a, 0x1e73a,
+ 0x1ef7a, 0x1c21a, 0x1c63a, 0x1ce7a, 0x1defa, 0x1843a,
+ 0x18c7a, 0x19cfa, 0x1bdfa, 0x1087a, 0x118fa, 0x139fa,
+ 0x17978, 0x1bcbe, 0x1793c, 0x1791e, 0x138be, 0x179be,
+ 0x178bc, 0x1789e, 0x1785e, 0x1e0a8, 0x1e0a4, 0x1e0a2,
+ 0x1c168, 0x1e0b6, 0x1c164, 0x1c162, 0x182e8, 0x1c176,
+ 0x182e4, 0x182e2, 0x105e8, 0x182f6, 0x105e4, 0x105e2,
+ 0x105f6, 0x1f0d4, 0x10d7e, 0x1f0d2, 0x1e094, 0x1e1b4,
+ 0x1e092, 0x1e1b2, 0x1c134, 0x1c374, 0x1c132, 0x1c372,
+ 0x18274, 0x186f4, 0x18272, 0x186f2, 0x104f4, 0x10df4,
+ 0x104f2, 0x10df2, 0x1f8ea, 0x11d7c, 0x11d3e, 0x1f0ca,
+ 0x1f1da, 0x1e08a, 0x1e19a, 0x1e3ba, 0x1c11a, 0x1c33a,
+ 0x1c77a, 0x1823a, 0x1867a, 0x18efa, 0x1047a, 0x10cfa,
+ 0x11dfa, 0x13d78, 0x19ebe, 0x13d3c, 0x13d1e, 0x11cbe,
+ 0x13dbe, 0x17d70, 0x1bebc, 0x17d38, 0x1be9e, 0x17d1c,
+ 0x17d0e, 0x13cbc, 0x17dbc, 0x13c9e, 0x17d9e, 0x17cb8,
+ 0x1be5e, 0x17c9c, 0x17c8e, 0x13c5e, 0x17cde, 0x17c5c,
+ 0x17c4e, 0x17c2e, 0x1c0b4, 0x1c0b2, 0x18174, 0x18172,
+ 0x102f4, 0x102f2, 0x1e0da, 0x1c09a, 0x1c1ba, 0x1813a,
+ 0x1837a, 0x1027a, 0x106fa, 0x10ebe, 0x11ebc, 0x11e9e,
+ 0x13eb8, 0x19f5e, 0x13e9c, 0x13e8e, 0x11e5e, 0x13ede,
+ 0x17eb0, 0x1bf5c, 0x17e98, 0x1bf4e, 0x17e8c, 0x17e86,
+ 0x13e5c, 0x17edc, 0x13e4e, 0x17ece, 0x17e58, 0x1bf2e,
+ 0x17e4c, 0x17e46, 0x13e2e, 0x17e6e, 0x17e2c, 0x17e26,
+ 0x10f5e, 0x11f5c, 0x11f4e, 0x13f58, 0x19fae, 0x13f4c,
+ 0x13f46, 0x11f2e, 0x13f6e, 0x13f2c, 0x13f26},
+ {0x1abe0, 0x1d5f8, 0x153c0, 0x1a9f0, 0x1d4fc, 0x151e0,
+ 0x1a8f8, 0x1d47e, 0x150f0, 0x1a87c, 0x15078, 0x1fad0,
+ 0x15be0, 0x1adf8, 0x1fac8, 0x159f0, 0x1acfc, 0x1fac4,
+ 0x158f8, 0x1ac7e, 0x1fac2, 0x1587c, 0x1f5d0, 0x1faec,
+ 0x15df8, 0x1f5c8, 0x1fae6, 0x15cfc, 0x1f5c4, 0x15c7e,
+ 0x1f5c2, 0x1ebd0, 0x1f5ec, 0x1ebc8, 0x1f5e6, 0x1ebc4,
+ 0x1ebc2, 0x1d7d0, 0x1ebec, 0x1d7c8, 0x1ebe6, 0x1d7c4,
+ 0x1d7c2, 0x1afd0, 0x1d7ec, 0x1afc8, 0x1d7e6, 0x1afc4,
+ 0x14bc0, 0x1a5f0, 0x1d2fc, 0x149e0, 0x1a4f8, 0x1d27e,
+ 0x148f0, 0x1a47c, 0x14878, 0x1a43e, 0x1483c, 0x1fa68,
+ 0x14df0, 0x1a6fc, 0x1fa64, 0x14cf8, 0x1a67e, 0x1fa62,
+ 0x14c7c, 0x14c3e, 0x1f4e8, 0x1fa76, 0x14efc, 0x1f4e4,
+ 0x14e7e, 0x1f4e2, 0x1e9e8, 0x1f4f6, 0x1e9e4, 0x1e9e2,
+ 0x1d3e8, 0x1e9f6, 0x1d3e4, 0x1d3e2, 0x1a7e8, 0x1d3f6,
+ 0x1a7e4, 0x1a7e2, 0x145e0, 0x1a2f8, 0x1d17e, 0x144f0,
+ 0x1a27c, 0x14478, 0x1a23e, 0x1443c, 0x1441e, 0x1fa34,
+ 0x146f8, 0x1a37e, 0x1fa32, 0x1467c, 0x1463e, 0x1f474,
+ 0x1477e, 0x1f472, 0x1e8f4, 0x1e8f2, 0x1d1f4, 0x1d1f2,
+ 0x1a3f4, 0x1a3f2, 0x142f0, 0x1a17c, 0x14278, 0x1a13e,
+ 0x1423c, 0x1421e, 0x1fa1a, 0x1437c, 0x1433e, 0x1f43a,
+ 0x1e87a, 0x1d0fa, 0x14178, 0x1a0be, 0x1413c, 0x1411e,
+ 0x141be, 0x140bc, 0x1409e, 0x12bc0, 0x195f0, 0x1cafc,
+ 0x129e0, 0x194f8, 0x1ca7e, 0x128f0, 0x1947c, 0x12878,
+ 0x1943e, 0x1283c, 0x1f968, 0x12df0, 0x196fc, 0x1f964,
+ 0x12cf8, 0x1967e, 0x1f962, 0x12c7c, 0x12c3e, 0x1f2e8,
+ 0x1f976, 0x12efc, 0x1f2e4, 0x12e7e, 0x1f2e2, 0x1e5e8,
+ 0x1f2f6, 0x1e5e4, 0x1e5e2, 0x1cbe8, 0x1e5f6, 0x1cbe4,
+ 0x1cbe2, 0x197e8, 0x1cbf6, 0x197e4, 0x197e2, 0x1b5e0,
+ 0x1daf8, 0x1ed7e, 0x169c0, 0x1b4f0, 0x1da7c, 0x168e0,
+ 0x1b478, 0x1da3e, 0x16870, 0x1b43c, 0x16838, 0x1b41e,
+ 0x1681c, 0x125e0, 0x192f8, 0x1c97e, 0x16de0, 0x124f0,
+ 0x1927c, 0x16cf0, 0x1b67c, 0x1923e, 0x16c78, 0x1243c,
+ 0x16c3c, 0x1241e, 0x16c1e, 0x1f934, 0x126f8, 0x1937e,
+ 0x1fb74, 0x1f932, 0x16ef8, 0x1267c, 0x1fb72, 0x16e7c,
+ 0x1263e, 0x16e3e, 0x1f274, 0x1277e, 0x1f6f4, 0x1f272,
+ 0x16f7e, 0x1f6f2, 0x1e4f4, 0x1edf4, 0x1e4f2, 0x1edf2,
+ 0x1c9f4, 0x1dbf4, 0x1c9f2, 0x1dbf2, 0x193f4, 0x193f2,
+ 0x165c0, 0x1b2f0, 0x1d97c, 0x164e0, 0x1b278, 0x1d93e,
+ 0x16470, 0x1b23c, 0x16438, 0x1b21e, 0x1641c, 0x1640e,
+ 0x122f0, 0x1917c, 0x166f0, 0x12278, 0x1913e, 0x16678,
+ 0x1b33e, 0x1663c, 0x1221e, 0x1661e, 0x1f91a, 0x1237c,
+ 0x1fb3a, 0x1677c, 0x1233e, 0x1673e, 0x1f23a, 0x1f67a,
+ 0x1e47a, 0x1ecfa, 0x1c8fa, 0x1d9fa, 0x191fa, 0x162e0,
+ 0x1b178, 0x1d8be, 0x16270, 0x1b13c, 0x16238, 0x1b11e,
+ 0x1621c, 0x1620e, 0x12178, 0x190be, 0x16378, 0x1213c,
+ 0x1633c, 0x1211e, 0x1631e, 0x121be, 0x163be, 0x16170,
+ 0x1b0bc, 0x16138, 0x1b09e, 0x1611c, 0x1610e, 0x120bc,
+ 0x161bc, 0x1209e, 0x1619e, 0x160b8, 0x1b05e, 0x1609c,
+ 0x1608e, 0x1205e, 0x160de, 0x1605c, 0x1604e, 0x115e0,
+ 0x18af8, 0x1c57e, 0x114f0, 0x18a7c, 0x11478, 0x18a3e,
+ 0x1143c, 0x1141e, 0x1f8b4, 0x116f8, 0x18b7e, 0x1f8b2,
+ 0x1167c, 0x1163e, 0x1f174, 0x1177e, 0x1f172, 0x1e2f4,
+ 0x1e2f2, 0x1c5f4, 0x1c5f2, 0x18bf4, 0x18bf2, 0x135c0,
+ 0x19af0, 0x1cd7c, 0x134e0, 0x19a78, 0x1cd3e, 0x13470,
+ 0x19a3c, 0x13438, 0x19a1e, 0x1341c, 0x1340e, 0x112f0,
+ 0x1897c, 0x136f0, 0x11278, 0x1893e, 0x13678, 0x19b3e,
+ 0x1363c, 0x1121e, 0x1361e, 0x1f89a, 0x1137c, 0x1f9ba,
+ 0x1377c, 0x1133e, 0x1373e, 0x1f13a, 0x1f37a, 0x1e27a,
+ 0x1e6fa, 0x1c4fa, 0x1cdfa, 0x189fa, 0x1bae0, 0x1dd78,
+ 0x1eebe, 0x174c0, 0x1ba70, 0x1dd3c, 0x17460, 0x1ba38,
+ 0x1dd1e, 0x17430, 0x1ba1c, 0x17418, 0x1ba0e, 0x1740c,
+ 0x132e0, 0x19978, 0x1ccbe, 0x176e0, 0x13270, 0x1993c,
+ 0x17670, 0x1bb3c, 0x1991e, 0x17638, 0x1321c, 0x1761c,
+ 0x1320e, 0x1760e, 0x11178, 0x188be, 0x13378, 0x1113c,
+ 0x17778, 0x1333c, 0x1111e, 0x1773c, 0x1331e, 0x1771e,
+ 0x111be, 0x133be, 0x177be, 0x172c0, 0x1b970, 0x1dcbc,
+ 0x17260, 0x1b938, 0x1dc9e, 0x17230, 0x1b91c, 0x17218,
+ 0x1b90e, 0x1720c, 0x17206, 0x13170, 0x198bc, 0x17370,
+ 0x13138, 0x1989e, 0x17338, 0x1b99e, 0x1731c, 0x1310e,
+ 0x1730e, 0x110bc, 0x131bc, 0x1109e, 0x173bc, 0x1319e,
+ 0x1739e, 0x17160, 0x1b8b8, 0x1dc5e, 0x17130, 0x1b89c,
+ 0x17118, 0x1b88e, 0x1710c, 0x17106, 0x130b8, 0x1985e,
+ 0x171b8, 0x1309c, 0x1719c, 0x1308e, 0x1718e, 0x1105e,
+ 0x130de, 0x171de, 0x170b0, 0x1b85c, 0x17098, 0x1b84e,
+ 0x1708c, 0x17086, 0x1305c, 0x170dc, 0x1304e, 0x170ce,
+ 0x17058, 0x1b82e, 0x1704c, 0x17046, 0x1302e, 0x1706e,
+ 0x1702c, 0x17026, 0x10af0, 0x1857c, 0x10a78, 0x1853e,
+ 0x10a3c, 0x10a1e, 0x10b7c, 0x10b3e, 0x1f0ba, 0x1e17a,
+ 0x1c2fa, 0x185fa, 0x11ae0, 0x18d78, 0x1c6be, 0x11a70,
+ 0x18d3c, 0x11a38, 0x18d1e, 0x11a1c, 0x11a0e, 0x10978,
+ 0x184be, 0x11b78, 0x1093c, 0x11b3c, 0x1091e, 0x11b1e,
+ 0x109be, 0x11bbe, 0x13ac0, 0x19d70, 0x1cebc, 0x13a60,
+ 0x19d38, 0x1ce9e, 0x13a30, 0x19d1c, 0x13a18, 0x19d0e,
+ 0x13a0c, 0x13a06, 0x11970, 0x18cbc, 0x13b70, 0x11938,
+ 0x18c9e, 0x13b38, 0x1191c, 0x13b1c, 0x1190e, 0x13b0e,
+ 0x108bc, 0x119bc, 0x1089e, 0x13bbc, 0x1199e, 0x13b9e,
+ 0x1bd60, 0x1deb8, 0x1ef5e, 0x17a40, 0x1bd30, 0x1de9c,
+ 0x17a20, 0x1bd18, 0x1de8e, 0x17a10, 0x1bd0c, 0x17a08,
+ 0x1bd06, 0x17a04, 0x13960, 0x19cb8, 0x1ce5e, 0x17b60,
+ 0x13930, 0x19c9c, 0x17b30, 0x1bd9c, 0x19c8e, 0x17b18,
+ 0x1390c, 0x17b0c, 0x13906, 0x17b06, 0x118b8, 0x18c5e,
+ 0x139b8, 0x1189c, 0x17bb8, 0x1399c, 0x1188e, 0x17b9c,
+ 0x1398e, 0x17b8e, 0x1085e, 0x118de, 0x139de, 0x17bde,
+ 0x17940, 0x1bcb0, 0x1de5c, 0x17920, 0x1bc98, 0x1de4e,
+ 0x17910, 0x1bc8c, 0x17908, 0x1bc86, 0x17904, 0x17902,
+ 0x138b0, 0x19c5c, 0x179b0, 0x13898, 0x19c4e, 0x17998,
+ 0x1bcce, 0x1798c, 0x13886, 0x17986, 0x1185c, 0x138dc,
+ 0x1184e, 0x179dc, 0x138ce, 0x179ce, 0x178a0, 0x1bc58,
+ 0x1de2e, 0x17890, 0x1bc4c, 0x17888, 0x1bc46, 0x17884,
+ 0x17882, 0x13858, 0x19c2e, 0x178d8, 0x1384c, 0x178cc,
+ 0x13846, 0x178c6, 0x1182e, 0x1386e, 0x178ee, 0x17850,
+ 0x1bc2c, 0x17848, 0x1bc26, 0x17844, 0x17842, 0x1382c,
+ 0x1786c, 0x13826, 0x17866, 0x17828, 0x1bc16, 0x17824,
+ 0x17822, 0x13816, 0x17836, 0x10578, 0x182be, 0x1053c,
+ 0x1051e, 0x105be, 0x10d70, 0x186bc, 0x10d38, 0x1869e,
+ 0x10d1c, 0x10d0e, 0x104bc, 0x10dbc, 0x1049e, 0x10d9e,
+ 0x11d60, 0x18eb8, 0x1c75e, 0x11d30, 0x18e9c, 0x11d18,
+ 0x18e8e, 0x11d0c, 0x11d06, 0x10cb8, 0x1865e, 0x11db8,
+ 0x10c9c, 0x11d9c, 0x10c8e, 0x11d8e, 0x1045e, 0x10cde,
+ 0x11dde, 0x13d40, 0x19eb0, 0x1cf5c, 0x13d20, 0x19e98,
+ 0x1cf4e, 0x13d10, 0x19e8c, 0x13d08, 0x19e86, 0x13d04,
+ 0x13d02, 0x11cb0, 0x18e5c, 0x13db0, 0x11c98, 0x18e4e,
+ 0x13d98, 0x19ece, 0x13d8c, 0x11c86, 0x13d86, 0x10c5c,
+ 0x11cdc, 0x10c4e, 0x13ddc, 0x11cce, 0x13dce, 0x1bea0,
+ 0x1df58, 0x1efae, 0x1be90, 0x1df4c, 0x1be88, 0x1df46,
+ 0x1be84, 0x1be82, 0x13ca0, 0x19e58, 0x1cf2e, 0x17da0,
+ 0x13c90, 0x19e4c, 0x17d90, 0x1becc, 0x19e46, 0x17d88,
+ 0x13c84, 0x17d84, 0x13c82, 0x17d82, 0x11c58, 0x18e2e,
+ 0x13cd8, 0x11c4c, 0x17dd8, 0x13ccc, 0x11c46, 0x17dcc,
+ 0x13cc6, 0x17dc6, 0x10c2e, 0x11c6e, 0x13cee, 0x17dee,
+ 0x1be50, 0x1df2c, 0x1be48, 0x1df26, 0x1be44, 0x1be42,
+ 0x13c50, 0x19e2c, 0x17cd0, 0x13c48, 0x19e26, 0x17cc8,
+ 0x1be66, 0x17cc4, 0x13c42, 0x17cc2, 0x11c2c, 0x13c6c,
+ 0x11c26, 0x17cec, 0x13c66, 0x17ce6, 0x1be28, 0x1df16,
+ 0x1be24, 0x1be22, 0x13c28, 0x19e16, 0x17c68, 0x13c24,
+ 0x17c64, 0x13c22, 0x17c62, 0x11c16, 0x13c36, 0x17c76,
+ 0x1be14, 0x1be12, 0x13c14, 0x17c34, 0x13c12, 0x17c32,
+ 0x102bc, 0x1029e, 0x106b8, 0x1835e, 0x1069c, 0x1068e,
+ 0x1025e, 0x106de, 0x10eb0, 0x1875c, 0x10e98, 0x1874e,
+ 0x10e8c, 0x10e86, 0x1065c, 0x10edc, 0x1064e, 0x10ece,
+ 0x11ea0, 0x18f58, 0x1c7ae, 0x11e90, 0x18f4c, 0x11e88,
+ 0x18f46, 0x11e84, 0x11e82, 0x10e58, 0x1872e, 0x11ed8,
+ 0x18f6e, 0x11ecc, 0x10e46, 0x11ec6, 0x1062e, 0x10e6e,
+ 0x11eee, 0x19f50, 0x1cfac, 0x19f48, 0x1cfa6, 0x19f44,
+ 0x19f42, 0x11e50, 0x18f2c, 0x13ed0, 0x19f6c, 0x18f26,
+ 0x13ec8, 0x11e44, 0x13ec4, 0x11e42, 0x13ec2, 0x10e2c,
+ 0x11e6c, 0x10e26, 0x13eec, 0x11e66, 0x13ee6, 0x1dfa8,
+ 0x1efd6, 0x1dfa4, 0x1dfa2, 0x19f28, 0x1cf96, 0x1bf68,
+ 0x19f24, 0x1bf64, 0x19f22, 0x1bf62, 0x11e28, 0x18f16,
+ 0x13e68, 0x11e24, 0x17ee8, 0x13e64, 0x11e22, 0x17ee4,
+ 0x13e62, 0x17ee2, 0x10e16, 0x11e36, 0x13e76, 0x17ef6,
+ 0x1df94, 0x1df92, 0x19f14, 0x1bf34, 0x19f12, 0x1bf32,
+ 0x11e14, 0x13e34, 0x11e12, 0x17e74, 0x13e32, 0x17e72,
+ 0x1df8a, 0x19f0a, 0x1bf1a, 0x11e0a, 0x13e1a, 0x17e3a,
+ 0x1035c, 0x1034e, 0x10758, 0x183ae, 0x1074c, 0x10746,
+ 0x1032e, 0x1076e, 0x10f50, 0x187ac, 0x10f48, 0x187a6,
+ 0x10f44, 0x10f42, 0x1072c, 0x10f6c, 0x10726, 0x10f66,
+ 0x18fa8, 0x1c7d6, 0x18fa4, 0x18fa2, 0x10f28, 0x18796,
+ 0x11f68, 0x18fb6, 0x11f64, 0x10f22, 0x11f62, 0x10716,
+ 0x10f36, 0x11f76, 0x1cfd4, 0x1cfd2, 0x18f94, 0x19fb4,
+ 0x18f92, 0x19fb2, 0x10f14, 0x11f34, 0x10f12, 0x13f74,
+ 0x11f32, 0x13f72, 0x1cfca, 0x18f8a, 0x19f9a, 0x10f0a,
+ 0x11f1a, 0x13f3a, 0x103ac, 0x103a6, 0x107a8, 0x183d6,
+ 0x107a4, 0x107a2, 0x10396, 0x107b6, 0x187d4, 0x187d2,
+ 0x10794, 0x10fb4, 0x10792, 0x10fb2, 0x1c7ea}};
+
+static float PREFERRED_RATIO = 3.0f;
+static float DEFAULT_MODULE_WIDTH = 0.357f; //1px in mm
+static float HEIGHT = 2.0f; //mm
+
+@interface ZXPDF417 ()
+
+@property (nonatomic, strong) ZXBarcodeMatrix *barcodeMatrix;
+@property (nonatomic, assign) int minCols;
+@property (nonatomic, assign) int maxCols;
+@property (nonatomic, assign) int minRows;
+@property (nonatomic, assign) int maxRows;
+
+@end
+
+@implementation ZXPDF417
+
+- (id)init {
+ return [self initWithCompact:NO];
+}
+
+- (id)initWithCompact:(BOOL)compact {
+ if (self = [super init]) {
+ _compact = compact;
+ _compaction = ZX_COMPACTION_AUTO;
+ _minCols = 2;
+ _maxCols = 30;
+ _maxRows = 30;
+ _minRows = 2;
+ }
+
+ return self;
+}
+
+/**
+ * Calculates the necessary number of rows as described in annex Q of ISO/IEC 15438:2001(E).
+ */
+- (int)calculateNumberOfRowsM:(int)m k:(int)k c:(int)c {
+ int r = ((m + 1 + k) / c) + 1;
+ if (c * r >= (m + 1 + k + c)) {
+ r--;
+ }
+ return r;
+}
+
+/**
+ * Calculates the number of pad codewords as described in 4.9.2 of ISO/IEC 15438:2001(E).
+ */
+- (int)numberOfPadCodewordsM:(int)m k:(int)k c:(int)c r:(int)r {
+ int n = c * r - k;
+ return n > m + 1 ? n - m - 1 : 0;
+}
+
+- (void)encodeCharPattern:(int)pattern len:(int)len logic:(ZXBarcodeRow *)logic {
+ int map = 1 << (len - 1);
+ BOOL last = (pattern & map) != 0; //Initialize to inverse of first bit
+ int width = 0;
+ for (int i = 0; i < len; i++) {
+ BOOL black = (pattern & map) != 0;
+ if (last == black) {
+ width++;
+ } else {
+ [logic addBar:last width:width];
+
+ last = black;
+ width = 1;
+ }
+ map >>= 1;
+ }
+ [logic addBar:last width:width];
+}
+
+- (void)encodeLowLevel:(NSString *)fullCodewords c:(int)c r:(int)r errorCorrectionLevel:(int)errorCorrectionLevel logic:(ZXBarcodeMatrix *)logic {
+ int idx = 0;
+ for (int y = 0; y < r; y++) {
+ int cluster = y % 3;
+ [logic startRow];
+ [self encodeCharPattern:START_PATTERN_INT len:17 logic:logic.currentRow];
+
+ int left;
+ int right;
+ if (cluster == 0) {
+ left = (30 * (y / 3)) + ((r - 1) / 3);
+ right = (30 * (y / 3)) + (c - 1);
+ } else if (cluster == 1) {
+ left = (30 * (y / 3)) + (errorCorrectionLevel * 3) + ((r - 1) % 3);
+ right = (30 * (y / 3)) + ((r - 1) / 3);
+ } else {
+ left = (30 * (y / 3)) + (c - 1);
+ right = (30 * (y / 3)) + (errorCorrectionLevel * 3) + ((r - 1) % 3);
+ }
+
+ int pattern = PDF_CODEWORD_TABLE[cluster][left];
+ [self encodeCharPattern:pattern len:17 logic:logic.currentRow];
+
+ for (int x = 0; x < c; x++) {
+ pattern = PDF_CODEWORD_TABLE[cluster][[fullCodewords characterAtIndex:idx]];
+ [self encodeCharPattern:pattern len:17 logic:logic.currentRow];
+ idx++;
+ }
+
+ if (self.compact) {
+ [self encodeCharPattern:STOP_PATTERN_INT len:1 logic:logic.currentRow];
+ } else {
+ pattern = PDF_CODEWORD_TABLE[cluster][right];
+ [self encodeCharPattern:pattern len:17 logic:logic.currentRow];
+
+ [self encodeCharPattern:STOP_PATTERN_INT len:18 logic:logic.currentRow];
+ }
+ }
+}
+
+/**
+ * Generates the barcode logic.
+ */
+- (BOOL)generateBarcodeLogic:(NSString *)msg errorCorrectionLevel:(int)anErrorCorrectionLevel error:(NSError **)error {
+
+ //1. step: High-level encoding
+ int errorCorrectionCodeWords = [ZXPDF417ErrorCorrection errorCorrectionCodewordCount:anErrorCorrectionLevel];
+ NSString *highLevel = [ZXPDF417HighLevelEncoder encodeHighLevel:msg compaction:self.compaction error:error];
+ if (!highLevel) {
+ return NO;
+ }
+ int sourceCodeWords = (int)highLevel.length;
+
+ int dimension[2] = {0};
+ if (![self determineDimensions:dimension sourceCodeWords:sourceCodeWords errorCorrectionCodeWords:errorCorrectionCodeWords error:error]) {
+ return NO;
+ }
+
+ int cols = dimension[0];
+ int rows = dimension[1];
+
+ int pad = [self numberOfPadCodewordsM:sourceCodeWords k:errorCorrectionCodeWords c:cols r:rows];
+
+ //2. step: construct data codewords
+ if (sourceCodeWords + errorCorrectionCodeWords + 1 > 929) { // +1 for symbol length CW
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Encoded message contains to many code words, message to big (%d bytes)", (int)msg.length]};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+
+ int n = sourceCodeWords + pad + 1;
+ NSMutableString *sb = [NSMutableString stringWithCapacity:n];
+ [sb appendFormat:@"%C", (unichar)n];
+ [sb appendFormat:@"%@", highLevel];
+ for (int i = 0; i < pad; i++) {
+ [sb appendFormat:@"%C", (unichar) 900]; //PAD characters
+ }
+ NSString *dataCodewords = sb;
+
+ //3. step: Error correction
+ NSString *ec = [ZXPDF417ErrorCorrection generateErrorCorrection:dataCodewords errorCorrectionLevel:anErrorCorrectionLevel];
+ NSString *fullCodewords = [dataCodewords stringByAppendingString:ec];
+
+ //4. step: low-level encoding
+ self.barcodeMatrix = [[ZXBarcodeMatrix alloc] initWithHeight:rows width:cols];
+ [self encodeLowLevel:fullCodewords c:cols r:rows errorCorrectionLevel:anErrorCorrectionLevel logic:self.barcodeMatrix];
+
+ return YES;
+}
+
+/**
+ * Determine optimal nr of columns and rows for the specified number of
+ * codewords.
+ */
+- (BOOL)determineDimensions:(int *)dimension sourceCodeWords:(int)sourceCodeWords errorCorrectionCodeWords:(int)errorCorrectionCodeWords error:(NSError **)error{
+ float ratio = 0.0f;
+ BOOL result = NO;
+
+ for (int cols = self.minCols; cols <= self.maxCols; cols++) {
+
+ int rows = [self calculateNumberOfRowsM:sourceCodeWords k:errorCorrectionCodeWords c:cols];
+
+ if (rows < self.minRows) {
+ break;
+ }
+
+ if (rows > self.maxRows) {
+ continue;
+ }
+
+ float newRatio = ((17 * cols + 69) * DEFAULT_MODULE_WIDTH) / (rows * HEIGHT);
+
+ // ignore if previous ratio is closer to preferred ratio
+ if (result && fabsf(newRatio - PREFERRED_RATIO) > fabsf(ratio - PREFERRED_RATIO)) {
+ continue;
+ }
+
+ ratio = newRatio;
+ dimension[0] = cols;
+ dimension[1] = rows;
+ result = YES;
+ }
+
+ // Handle case when min values were larger than necessary
+ if (!result) {
+ int rows = [self calculateNumberOfRowsM:sourceCodeWords k:errorCorrectionCodeWords c:self.minCols];
+ if (rows < self.minRows) {
+ dimension[0] = self.minCols;
+ dimension[1] = self.minRows;
+ }
+ }
+
+ if (!result) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Unable to fit message in columns"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+
+ return result;
+}
+
+/**
+ * Sets max/min row/col values
+ */
+- (void)setDimensionsWithMaxCols:(int)maxCols minCols:(int)minCols maxRows:(int)maxRows minRows:(int)minRows {
+ self.maxCols = maxCols;
+ self.minCols = minCols;
+ self.maxRows = maxRows;
+ self.minRows = minRows;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.h b/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.h
new file mode 100644
index 0000000..e175854
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part
+ *
+ * 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.
+ */
+
+/**
+ * PDF417 error correction code following the algorithm described in ISO/IEC 15438:2001(E) in
+ * chapter 4.10.
+ */
+@interface ZXPDF417ErrorCorrection : NSObject
+
++ (int)errorCorrectionCodewordCount:(int)errorCorrectionLevel;
++ (int)recommendedMinimumErrorCorrectionLevel:(int)n error:(NSError **)error;
++ (NSString *)generateErrorCorrection:(NSString *)dataCodewords errorCorrectionLevel:(int)errorCorrectionLevel;
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.m b/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.m
new file mode 100644
index 0000000..4ef5f6e
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.m
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part
+ *
+ * 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 "ZXErrors.h"
+#import "ZXPDF417ErrorCorrection.h"
+
+/**
+ * Tables of coefficients for calculating error correction words
+ * (see annex F, ISO/IEC 15438:2001(E))
+ */
+const int EC_COEFFICIENTS[9][512] = {
+ {27, 917},
+ {522, 568, 723, 809},
+ {237, 308, 436, 284, 646, 653, 428, 379},
+ {274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295,
+ 42, 176, 65},
+ {361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687,
+ 284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803,
+ 133, 231, 390, 685, 330, 63, 410},
+ {539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733,
+ 877, 381, 612, 723, 476, 462, 172, 430, 609, 858, 822, 543,
+ 376, 511, 400, 672, 762, 283, 184, 440, 35, 519, 31, 460,
+ 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, 648,
+ 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843,
+ 623, 264, 543},
+ {521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400,
+ 925, 749, 415, 822, 93, 217, 208, 928, 244, 583, 620, 246,
+ 148, 447, 631, 292, 908, 490, 704, 516, 258, 457, 907, 594,
+ 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, 193,
+ 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712,
+ 463, 646, 776, 171, 491, 297, 763, 156, 732, 95, 270, 447,
+ 90, 507, 48, 228, 821, 808, 898, 784, 663, 627, 378, 382,
+ 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, 157,
+ 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814,
+ 587, 804, 34, 211, 330, 539, 297, 827, 865, 37, 517, 834,
+ 315, 550, 86, 801, 4, 108, 539},
+ {524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905,
+ 786, 138, 720, 858, 194, 311, 913, 275, 190, 375, 850, 438,
+ 733, 194, 280, 201, 280, 828, 757, 710, 814, 919, 89, 68,
+ 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, 439,
+ 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284,
+ 549, 209, 884, 315, 70, 329, 793, 490, 274, 877, 162, 749,
+ 812, 684, 461, 334, 376, 849, 521, 307, 291, 803, 712, 19,
+ 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, 637,
+ 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136,
+ 538, 906, 90, 2, 290, 743, 199, 655, 903, 329, 49, 802,
+ 580, 355, 588, 188, 462, 10, 134, 628, 320, 479, 130, 739,
+ 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, 722,
+ 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48,
+ 60, 732, 621, 895, 544, 261, 852, 655, 309, 697, 755, 756,
+ 60, 231, 773, 434, 421, 726, 528, 503, 118, 49, 795, 32,
+ 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, 73,
+ 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180,
+ 791, 893, 754, 605, 383, 228, 749, 760, 213, 54, 297, 134,
+ 54, 834, 299, 922, 191, 910, 532, 609, 829, 189, 20, 167,
+ 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, 404,
+ 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648,
+ 55, 497, 10},
+ {352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285,
+ 380, 350, 492, 197, 265, 920, 155, 914, 299, 229, 643, 294,
+ 871, 306, 88, 87, 193, 352, 781, 846, 75, 327, 520, 435,
+ 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, 539,
+ 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858,
+ 916, 552, 41, 542, 289, 122, 272, 383, 800, 485, 98, 752,
+ 472, 761, 107, 784, 860, 658, 741, 290, 204, 681, 407, 855,
+ 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, 808,
+ 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513,
+ 192, 516, 258, 240, 518, 794, 395, 768, 848, 51, 610, 384,
+ 168, 190, 826, 328, 596, 786, 303, 570, 381, 415, 641, 156,
+ 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, 40,
+ 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221,
+ 92, 358, 785, 288, 357, 850, 836, 827, 736, 707, 94, 8,
+ 494, 114, 521, 2, 499, 851, 543, 152, 729, 771, 95, 248,
+ 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, 669,
+ 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699,
+ 591, 452, 578, 37, 124, 298, 332, 552, 43, 427, 119, 662,
+ 777, 475, 850, 764, 364, 578, 911, 283, 711, 472, 420, 245,
+ 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, 842,
+ 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713,
+ 159, 672, 729, 624, 59, 193, 417, 158, 209, 563, 564, 343,
+ 693, 109, 608, 563, 365, 181, 772, 677, 310, 248, 353, 708,
+ 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, 618,
+ 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331,
+ 247, 184, 45, 787, 680, 18, 66, 407, 369, 54, 492, 228,
+ 613, 830, 922, 437, 519, 644, 905, 789, 420, 305, 441, 207,
+ 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, 242,
+ 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756,
+ 665, 397, 808, 851, 309, 473, 795, 378, 31, 647, 915, 459,
+ 806, 590, 731, 425, 216, 548, 249, 321, 881, 699, 535, 673,
+ 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, 660,
+ 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535,
+ 336, 286, 437, 375, 273, 610, 296, 183, 923, 116, 667, 751,
+ 353, 62, 366, 691, 379, 687, 842, 37, 357, 720, 742, 330,
+ 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, 342,
+ 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721,
+ 610, 46, 656, 447, 171, 616, 464, 190, 531, 297, 321, 762,
+ 752, 533, 175, 134, 14, 381, 433, 717, 45, 111, 20, 596,
+ 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, 407,
+ 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768,
+ 223, 849, 647, 63, 310, 863, 251, 366, 304, 282, 738, 675,
+ 410, 389, 244, 31, 121, 303, 263}};
+
+@implementation ZXPDF417ErrorCorrection
+
+/**
+ * Determines the number of error correction codewords for a specified error correction
+ * level.
+ */
++ (int)errorCorrectionCodewordCount:(int)errorCorrectionLevel {
+ if (errorCorrectionLevel < 0 || errorCorrectionLevel > 8) {
+ [NSException raise:NSInvalidArgumentException format:@"Error correction level must be between 0 and 8!"];
+ }
+ return 1 << (errorCorrectionLevel + 1);
+}
+
+/**
+ * Returns the recommended minimum error correction level as described in annex E of
+ * ISO/IEC 15438:2001(E).
+ */
++ (int)recommendedMinimumErrorCorrectionLevel:(int)n error:(NSError **)error {
+ if (n <= 0) {
+ [NSException raise:NSInvalidArgumentException format:@"n must be > 0"];
+ }
+ if (n <= 40) {
+ return 2;
+ }
+ if (n <= 160) {
+ return 3;
+ }
+ if (n <= 320) {
+ return 4;
+ }
+ if (n <= 863) {
+ return 5;
+ }
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"No recommendation possible"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return -1;
+}
+
+/**
+ * Generates the error correction codewords according to 4.10 in ISO/IEC 15438:2001(E).
+ */
++ (NSString *)generateErrorCorrection:(NSString *)dataCodewords errorCorrectionLevel:(int)errorCorrectionLevel {
+ int k = [self errorCorrectionCodewordCount:errorCorrectionLevel];
+ unichar e[k];
+ memset(e, 0, k * sizeof(unichar));
+
+ int sld = (int)dataCodewords.length;
+ for (int i = 0; i < sld; i++) {
+ int t1 = ([dataCodewords characterAtIndex:i] + e[k - 1]) % 929;
+ int t2;
+ int t3;
+ for (int j = k - 1; j >= 1; j--) {
+ t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][j]) % 929;
+ t3 = 929 - t2;
+ e[j] = (unichar) ((e[j - 1] + t3) % 929);
+ }
+ t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][0]) % 929;
+ t3 = 929 - t2;
+ e[0] = (unichar) (t3 % 929);
+ }
+ NSMutableString *sb = [NSMutableString stringWithCapacity:k];
+ for (int j = k - 1; j >= 0; j--) {
+ if (e[j] != 0) {
+ e[j] = (unichar) (929 - e[j]);
+ }
+ [sb appendFormat:@"%C", e[j]];
+ }
+ return sb;
+}
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.h b/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.h
new file mode 100644
index 0000000..b87a128
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part
+ *
+ * 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.
+ */
+
+/*
+ * This file has been modified from its original form in Barcode4J.
+ */
+
+#import "ZXCompaction.h"
+
+/**
+ * PDF417 high-level encoder following the algorithm described in ISO/IEC 15438:2001(E) in
+ * annex P.
+ */
+
+@interface ZXPDF417HighLevelEncoder : NSObject
+
++ (NSString *)encodeHighLevel:(NSString *)msg compaction:(ZXCompaction)compaction error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m b/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m
new file mode 100644
index 0000000..20bb5d0
--- /dev/null
+++ b/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m
@@ -0,0 +1,518 @@
+/*
+ * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part
+ *
+ * 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 "ZXErrors.h"
+#import "ZXPDF417HighLevelEncoder.h"
+
+/**
+ * code for Text compaction
+ */
+const int TEXT_COMPACTION = 0;
+
+/**
+ * code for Byte compaction
+ */
+const int BYTE_COMPACTION = 1;
+
+/**
+ * code for Numeric compaction
+ */
+const int NUMERIC_COMPACTION = 2;
+
+/**
+ * Text compaction submode Alpha
+ */
+const int SUBMODE_ALPHA = 0;
+
+/**
+ * Text compaction submode Lower
+ */
+const int SUBMODE_LOWER = 1;
+
+/**
+ * Text compaction submode Mixed
+ */
+const int SUBMODE_MIXED = 2;
+
+/**
+ * Text compaction submode Punctuation
+ */
+const int SUBMODE_PUNCTUATION = 3;
+
+/**
+ * mode latch to Text Compaction mode
+ */
+const int LATCH_TO_TEXT = 900;
+
+/**
+ * mode latch to Byte Compaction mode (number of characters NOT a multiple of 6)
+ */
+const int LATCH_TO_BYTE_PADDED = 901;
+
+/**
+ * mode latch to Numeric Compaction mode
+ */
+const int LATCH_TO_NUMERIC = 902;
+
+/**
+ * mode shift to Byte Compaction mode
+ */
+const int SHIFT_TO_BYTE = 913;
+
+/**
+ * mode latch to Byte Compaction mode (number of characters a multiple of 6)
+ */
+const int LATCH_TO_BYTE = 924;
+
+/**
+ * Raw code table for text compaction Mixed sub-mode
+ */
+const int TEXT_MIXED_RAW_LEN = 30;
+const int8_t TEXT_MIXED_RAW[TEXT_MIXED_RAW_LEN] = {
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 38, 13, 9, 44, 58,
+ 35, 45, 46, 36, 47, 43, 37, 42, 61, 94, 0, 32, 0, 0, 0};
+
+/**
+ * Raw code table for text compaction: Punctuation sub-mode
+ */
+const int TEXT_PUNCTUATION_RAW_LEN = 30;
+const int8_t TEXT_PUNCTUATION_RAW[TEXT_PUNCTUATION_RAW_LEN] = {
+ 59, 60, 62, 64, 91, 92, 93, 95, 96, 126, 33, 13, 9, 44, 58,
+ 10, 45, 46, 36, 47, 34, 124, 42, 40, 41, 63, 123, 125, 39, 0};
+
+const int MIXED_TABLE_LEN = 128;
+unichar MIXED_TABLE[MIXED_TABLE_LEN];
+
+const int PUNCTUATION_LEN = 128;
+unichar PUNCTUATION[PUNCTUATION_LEN];
+
+@implementation ZXPDF417HighLevelEncoder
+
++ (void)initialize {
+ //Construct inverse lookups
+ for (int i = 0; i < MIXED_TABLE_LEN; i++) {
+ MIXED_TABLE[i] = 0xFF;
+ }
+ for (int8_t i = 0; i < TEXT_MIXED_RAW_LEN; i++) {
+ int8_t b = TEXT_MIXED_RAW[i];
+ if (b > 0) {
+ MIXED_TABLE[b] = i;
+ }
+ }
+ for (int i = 0; i < PUNCTUATION_LEN; i++) {
+ PUNCTUATION[i] = 0xFF;
+ }
+ for (int8_t i = 0; i < TEXT_PUNCTUATION_RAW_LEN; i++) {
+ int8_t b = TEXT_PUNCTUATION_RAW[i];
+ if (b > 0) {
+ PUNCTUATION[b] = i;
+ }
+ }
+}
+
+/**
+ * Converts the message to a byte array using the default encoding (cp437) as defined by the
+ * specification
+ */
++ (int8_t *)bytesForMessage:(NSString *)msg {
+ return (int8_t *)[[msg dataUsingEncoding:(NSStringEncoding) 0x80000400] bytes];
+}
+
+/**
+ * Performs high-level encoding of a PDF417 message using the algorithm described in annex P
+ * of ISO/IEC 15438:2001(E). If byte compaction has been selected, then only byte compaction
+ * is used.
+ */
++ (NSString *)encodeHighLevel:(NSString *)msg compaction:(ZXCompaction)compaction error:(NSError **)error {
+ int8_t *bytes = NULL; //Fill later and only if needed
+
+ //the codewords 0..928 are encoded as Unicode characters
+ NSMutableString *sb = [NSMutableString stringWithCapacity:msg.length];
+
+ NSUInteger len = msg.length;
+ int p = 0;
+ int textSubMode = SUBMODE_ALPHA;
+
+ // User selected encoding mode
+ if (compaction == ZX_COMPACTION_TEXT) {
+ [self encodeText:msg startpos:p count:(int)len buffer:sb initialSubmode:textSubMode];
+ } else if (compaction == ZX_COMPACTION_BYTE) {
+ bytes = [self bytesForMessage:msg];
+ [self encodeBinary:bytes startpos:p count:(int)msg.length startmode:BYTE_COMPACTION buffer:sb];
+ } else if (compaction == ZX_COMPACTION_NUMERIC) {
+ [sb appendFormat:@"%C", (unichar) LATCH_TO_NUMERIC];
+ [self encodeNumeric:msg startpos:p count:(int)len buffer:sb];
+ } else {
+ int encodingMode = TEXT_COMPACTION; //Default mode, see 4.4.2.1
+ while (p < len) {
+ int n = [self determineConsecutiveDigitCount:msg startpos:p];
+ if (n >= 13) {
+ [sb appendFormat:@"%C", (unichar) LATCH_TO_NUMERIC];
+ encodingMode = NUMERIC_COMPACTION;
+ textSubMode = SUBMODE_ALPHA; //Reset after latch
+ [self encodeNumeric:msg startpos:p count:n buffer:sb];
+ p += n;
+ } else {
+ int t = [self determineConsecutiveTextCount:msg startpos:p];
+ if (t >= 5 || n == len) {
+ if (encodingMode != TEXT_COMPACTION) {
+ [sb appendFormat:@"%C", (unichar) LATCH_TO_TEXT];
+ encodingMode = TEXT_COMPACTION;
+ textSubMode = SUBMODE_ALPHA; //start with submode alpha after latch
+ }
+ textSubMode = [self encodeText:msg startpos:p count:t buffer:sb initialSubmode:textSubMode];
+ p += t;
+ } else {
+ if (bytes == NULL) {
+ bytes = [self bytesForMessage:msg];
+ }
+ int b = [self determineConsecutiveBinaryCount:msg bytes:bytes startpos:p error:error];
+ if (b == -1) {
+ return nil;
+ } else if (b == 0) {
+ b = 1;
+ }
+ if (b == 1 && encodingMode == TEXT_COMPACTION) {
+ //Switch for one byte (instead of latch)
+ [self encodeBinary:bytes startpos:p count:1 startmode:TEXT_COMPACTION buffer:sb];
+ } else {
+ //Mode latch performed by encodeBinary
+ [self encodeBinary:bytes startpos:p count:b startmode:encodingMode buffer:sb];
+ encodingMode = BYTE_COMPACTION;
+ textSubMode = SUBMODE_ALPHA; //Reset after latch
+ }
+ p += b;
+ }
+ }
+ }
+ }
+
+ return sb;
+}
+
+/**
+ * Encode parts of the message using Text Compaction as described in ISO/IEC 15438:2001(E),
+ * chapter 4.4.2.
+ */
++ (int)encodeText:(NSString *)msg startpos:(int)startpos count:(int)count buffer:(NSMutableString *)sb initialSubmode:(int)initialSubmode {
+ NSMutableString *tmp = [NSMutableString stringWithCapacity:count];
+ int submode = initialSubmode;
+ int idx = 0;
+ while (true) {
+ unichar ch = [msg characterAtIndex:startpos + idx];
+ switch (submode) {
+ case SUBMODE_ALPHA:
+ if ([self isAlphaUpper:ch]) {
+ if (ch == ' ') {
+ [tmp appendFormat:@"%C", (unichar) 26]; //space
+ } else {
+ [tmp appendFormat:@"%C", (unichar) (ch - 65)];
+ }
+ } else {
+ if ([self isAlphaLower:ch]) {
+ submode = SUBMODE_LOWER;
+ [tmp appendFormat:@"%C", (unichar) 27]; //ll
+ continue;
+ } else if ([self isMixed:ch]) {
+ submode = SUBMODE_MIXED;
+ [tmp appendFormat:@"%C", (unichar) 28]; //ml
+ continue;
+ } else {
+ [tmp appendFormat:@"%C", (unichar) 29]; //ps
+ [tmp appendFormat:@"%C", PUNCTUATION[ch]];
+ break;
+ }
+ }
+ break;
+ case SUBMODE_LOWER:
+ if ([self isAlphaLower:ch]) {
+ if (ch == ' ') {
+ [tmp appendFormat:@"%C", (unichar) 26]; //space
+ } else {
+ [tmp appendFormat:@"%C", (unichar) (ch - 97)];
+ }
+ } else {
+ if ([self isAlphaUpper:ch]) {
+ [tmp appendFormat:@"%C", (unichar) 27]; //as
+ [tmp appendFormat:@"%C", (unichar) (ch - 65)];
+ //space cannot happen here, it is also in "Lower"
+ break;
+ } else if ([self isMixed:ch]) {
+ submode = SUBMODE_MIXED;
+ [tmp appendFormat:@"%C", (unichar) 28]; //ml
+ continue;
+ } else {
+ [tmp appendFormat:@"%C", (unichar) 29]; //ps
+ [tmp appendFormat:@"%C", PUNCTUATION[ch]];
+ break;
+ }
+ }
+ break;
+ case SUBMODE_MIXED:
+ if ([self isMixed:ch]) {
+ [tmp appendFormat:@"%C", MIXED_TABLE[ch]]; //as
+ } else {
+ if ([self isAlphaUpper:ch]) {
+ submode = SUBMODE_ALPHA;
+ [tmp appendFormat:@"%C", (unichar) 28]; //al
+ continue;
+ } else if ([self isAlphaLower:ch]) {
+ submode = SUBMODE_LOWER;
+ [tmp appendFormat:@"%C", (unichar) 27]; //ll
+ continue;
+ } else {
+ if (startpos + idx + 1 < count) {
+ char next = [msg characterAtIndex:startpos + idx + 1];
+ if ([self isPunctuation:next]) {
+ submode = SUBMODE_PUNCTUATION;
+ [tmp appendFormat:@"%C", (unichar) 25]; //pl
+ continue;
+ }
+ }
+ [tmp appendFormat:@"%C", (unichar) 29]; //ps
+ [tmp appendFormat:@"%C", PUNCTUATION[ch]];
+ }
+ }
+ break;
+ default: //SUBMODE_PUNCTUATION
+ if ([self isPunctuation:ch]) {
+ [tmp appendFormat:@"%C", PUNCTUATION[ch]];
+ } else {
+ submode = SUBMODE_ALPHA;
+ [tmp appendFormat:@"%C", (unichar) 29]; //al
+ continue;
+ }
+ }
+ idx++;
+ if (idx >= count) {
+ break;
+ }
+ }
+ unichar h = 0;
+ NSUInteger len = tmp.length;
+ for (int i = 0; i < len; i++) {
+ BOOL odd = (i % 2) != 0;
+ if (odd) {
+ h = (unichar) ((h * 30) + [tmp characterAtIndex:i]);
+ [sb appendFormat:@"%C", h];
+ } else {
+ h = [tmp characterAtIndex:i];
+ }
+ }
+ if ((len % 2) != 0) {
+ [sb appendFormat:@"%C", (unichar) ((h * 30) + 29)]; //ps
+ }
+ return submode;
+}
+
+/**
+ * Encode parts of the message using Byte Compaction as described in ISO/IEC 15438:2001(E),
+ * chapter 4.4.3. The Unicode characters will be converted to binary using the cp437
+ * codepage.
+ */
++ (void)encodeBinary:(int8_t *)bytes startpos:(int)startpos count:(int)count startmode:(int)startmode buffer:(NSMutableString *)sb {
+ if (count == 1 && startmode == TEXT_COMPACTION) {
+ [sb appendFormat:@"%C", (unichar) SHIFT_TO_BYTE];
+ }
+
+ int idx = startpos;
+ // Encode sixpacks
+ if (count >= 6) {
+ [sb appendFormat:@"%C", (unichar) LATCH_TO_BYTE];
+ const int charsLen = 5;
+ unichar chars[charsLen];
+ memset(chars, 0, charsLen * sizeof(unichar));
+ while ((startpos + count - idx) >= 6) {
+ long t = 0;
+ for (int i = 0; i < 6; i++) {
+ t <<= 8;
+ t += bytes[idx + i] & 0xff;
+ }
+ for (int i = 0; i < 5; i++) {
+ chars[i] = (unichar) (t % 900);
+ t /= 900;
+ }
+ for (int i = charsLen - 1; i >= 0; i--) {
+ [sb appendFormat:@"%C", chars[i]];
+ }
+ idx += 6;
+ }
+ }
+ //Encode rest (remaining n<5 bytes if any)
+ if (idx < startpos + count) {
+ [sb appendFormat:@"%C", (unichar) LATCH_TO_BYTE_PADDED];
+ }
+ for (int i = idx; i < startpos + count; i++) {
+ int ch = bytes[i] & 0xff;
+ [sb appendFormat:@"%C", (unichar)ch];
+ }
+}
+
++ (void)encodeNumeric:(NSString *)msg startpos:(int)startpos count:(int)count buffer:(NSMutableString *)sb {
+ int idx = 0;
+ NSMutableString *tmp = [NSMutableString stringWithCapacity:count / 3 + 1];
+ while (idx < count - 1) {
+ [tmp setString:@""];
+ int len = MIN(44, count - idx);
+ NSString *part = [@"1" stringByAppendingString:[msg substringWithRange:NSMakeRange(startpos + idx, len)]];
+ long long bigint = [part longLongValue];
+ do {
+ long c = bigint % 900;
+ [tmp appendFormat:@"%C", (unichar) c];
+ bigint /= 900;
+ } while (bigint != 0);
+
+ //Reverse temporary string
+ for (int i = (int)tmp.length - 1; i >= 0; i--) {
+ [sb appendFormat:@"%C", [tmp characterAtIndex:i]];
+ }
+ idx += len;
+ }
+}
+
++ (BOOL)isDigit:(char)ch {
+ return ch >= '0' && ch <= '9';
+}
+
++ (BOOL)isAlphaUpper:(char)ch {
+ return ch == ' ' || (ch >= 'A' && ch <= 'Z');
+}
+
++ (BOOL)isAlphaLower:(char)ch {
+ return ch == ' ' || (ch >= 'a' && ch <= 'z');
+}
+
++ (BOOL)isMixed:(char)ch {
+ return MIXED_TABLE[ch] != 0xFF;
+}
+
++ (BOOL)isPunctuation:(char)ch {
+ return PUNCTUATION[ch] != 0xFF;
+}
+
++ (BOOL)isText:(char)ch {
+ return ch == '\t' || ch == '\n' || ch == '\r' || (ch >= 32 && ch <= 126);
+}
+
+/**
+ * Determines the number of consecutive characters that are encodable using numeric compaction.
+ */
++ (int)determineConsecutiveDigitCount:(NSString *)msg startpos:(int)startpos {
+ int count = 0;
+ NSUInteger len = msg.length;
+ int idx = startpos;
+ if (idx < len) {
+ char ch = [msg characterAtIndex:idx];
+ while ([self isDigit:ch] && idx < len) {
+ count++;
+ idx++;
+ if (idx < len) {
+ ch = [msg characterAtIndex:idx];
+ }
+ }
+ }
+ return count;
+}
+
+/**
+ * Determines the number of consecutive characters that are encodable using text compaction.
+ *
+ * @param msg the message
+ * @param startpos the start position within the message
+ * @return the requested character count
+ */
++ (int)determineConsecutiveTextCount:(NSString *)msg startpos:(int)startpos {
+ NSUInteger len = msg.length;
+ int idx = startpos;
+ while (idx < len) {
+ char ch = [msg characterAtIndex:idx];
+ int numericCount = 0;
+ while (numericCount < 13 && [self isDigit:ch] && idx < len) {
+ numericCount++;
+ idx++;
+ if (idx < len) {
+ ch = [msg characterAtIndex:idx];
+ }
+ }
+ if (numericCount >= 13) {
+ return idx - startpos - numericCount;
+ }
+ if (numericCount > 0) {
+ //Heuristic: All text-encodable chars or digits are binary encodable
+ continue;
+ }
+ ch = [msg characterAtIndex:idx];
+
+ //Check if character is encodable
+ if (![self isText:ch]) {
+ break;
+ }
+ idx++;
+ }
+ return idx - startpos;
+}
+
+/**
+ * Determines the number of consecutive characters that are encodable using binary compaction.
+ */
++ (int)determineConsecutiveBinaryCount:(NSString *)msg bytes:(int8_t *)bytes startpos:(int)startpos error:(NSError **)error {
+ NSUInteger len = msg.length;
+ int idx = startpos;
+ while (idx < len) {
+ char ch = [msg characterAtIndex:idx];
+ int numericCount = 0;
+
+ while (numericCount < 13 && [self isDigit:ch]) {
+ numericCount++;
+ //textCount++;
+ int i = idx + numericCount;
+ if (i >= len) {
+ break;
+ }
+ ch = [msg characterAtIndex:i];
+ }
+ if (numericCount >= 13) {
+ return idx - startpos;
+ }
+ int textCount = 0;
+ while (textCount < 5 && [self isText:ch]) {
+ textCount++;
+ int i = idx + textCount;
+ if (i >= len) {
+ break;
+ }
+ ch = [msg characterAtIndex:i];
+ }
+ if (textCount >= 5) {
+ 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[idx] == 63 && ch != '?') {
+ 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];
+ return -1;
+ }
+ idx++;
+ }
+ return idx - startpos;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/ZXQRCodeReader.h b/ZXingObjC/qrcode/ZXQRCodeReader.h
new file mode 100644
index 0000000..dc20be3
--- /dev/null
+++ b/ZXingObjC/qrcode/ZXQRCodeReader.h
@@ -0,0 +1,29 @@
+/*
+ * 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 "ZXReader.h"
+
+/**
+ * This implementation can detect and decode QR Codes in an image.
+ */
+
+@class ZXBinaryBitmap, ZXQRCodeDecoder, ZXResult;
+
+@interface ZXQRCodeReader : NSObject <ZXReader>
+
+@property (nonatomic, strong, readonly) ZXQRCodeDecoder *decoder;
+
+@end
diff --git a/ZXingObjC/qrcode/ZXQRCodeReader.m b/ZXingObjC/qrcode/ZXQRCodeReader.m
new file mode 100644
index 0000000..7b4905e
--- /dev/null
+++ b/ZXingObjC/qrcode/ZXQRCodeReader.m
@@ -0,0 +1,189 @@
+/*
+ * 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 "ZXBarcodeFormat.h"
+#import "ZXBinaryBitmap.h"
+#import "ZXBitMatrix.h"
+#import "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXDetectorResult.h"
+#import "ZXErrors.h"
+#import "ZXQRCodeDecoder.h"
+#import "ZXQRCodeDetector.h"
+#import "ZXQRCodeReader.h"
+#import "ZXResult.h"
+
+@implementation ZXQRCodeReader
+
+- (id)init {
+ if (self = [super init]) {
+ _decoder = [[ZXQRCodeDecoder alloc] init];
+ }
+
+ return self;
+}
+
+/**
+ * Locates and decodes a QR code in an image.
+ */
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
+ return [self decode:image hints:nil error:error];
+}
+
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXDecoderResult *decoderResult;
+ NSArray *points;
+ ZXBitMatrix *matrix = [image blackMatrixWithError:error];
+ if (!matrix) {
+ return nil;
+ }
+ if (hints != nil && hints.pureBarcode) {
+ ZXBitMatrix *bits = [self extractPureBits:matrix];
+ if (!bits) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ decoderResult = [self.decoder decodeMatrix:bits hints:hints error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ points = @[];
+ } else {
+ ZXDetectorResult *detectorResult = [[[ZXQRCodeDetector alloc] initWithImage:matrix] detect:hints error:error];
+ if (!detectorResult) {
+ return nil;
+ }
+ decoderResult = [self.decoder decodeMatrix:[detectorResult bits] hints:hints error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ points = [detectorResult points];
+ }
+
+ ZXResult *result = [ZXResult resultWithText:decoderResult.text
+ rawBytes:decoderResult.rawBytes
+ length:decoderResult.length
+ resultPoints:points
+ format:kBarcodeFormatQRCode];
+ NSMutableArray *byteSegments = decoderResult.byteSegments;
+ if (byteSegments != nil) {
+ [result putMetadata:kResultMetadataTypeByteSegments value:byteSegments];
+ }
+ NSString *ecLevel = decoderResult.ecLevel;
+ if (ecLevel != nil) {
+ [result putMetadata:kResultMetadataTypeErrorCorrectionLevel value:ecLevel];
+ }
+ return result;
+}
+
+- (void)reset {
+ // do nothing
+}
+
+/**
+ * This method detects a code in a "pure" image -- that is, pure monochrome image
+ * which contains only an unrotated, unskewed, image of a code, with some white border
+ * around it. This is a specialized method that works exceptionally fast in this special
+ * case.
+ */
+- (ZXBitMatrix *)extractPureBits:(ZXBitMatrix *)image {
+ NSArray *leftTopBlack = image.topLeftOnBit;
+ NSArray *rightBottomBlack = image.bottomRightOnBit;
+ if (leftTopBlack == nil || rightBottomBlack == nil) {
+ return nil;
+ }
+
+ float moduleSize = [self moduleSize:leftTopBlack image:image];
+ if (moduleSize == -1) {
+ return nil;
+ }
+
+ int top = [leftTopBlack[1] intValue];
+ int bottom = [rightBottomBlack[1] intValue];
+ int left = [leftTopBlack[0] intValue];
+ int right = [rightBottomBlack[0] intValue];
+
+ // Sanity check!
+ if (left >= right || top >= bottom) {
+ return nil;
+ }
+
+ if (bottom - top != right - left) {
+ // 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);
+ }
+
+ int matrixWidth = round((right - left + 1) / moduleSize);
+ int matrixHeight = round((bottom - top + 1) / moduleSize);
+ if (matrixWidth <= 0 || matrixHeight <= 0) {
+ return nil;
+ }
+ if (matrixHeight != matrixWidth) {
+ return nil;
+ }
+
+ int nudge = (int) (moduleSize / 2.0f);
+ top += nudge;
+ left += nudge;
+
+ // But careful that this does not sample off the edge
+ int nudgedTooFarRight = left + (int) ((matrixWidth - 1) * moduleSize) - (right - 1);
+ if (nudgedTooFarRight > 0) {
+ left -= nudgedTooFarRight;
+ }
+ int nudgedTooFarDown = top + (int) ((matrixHeight - 1) * moduleSize) - (bottom - 1);
+ if (nudgedTooFarDown > 0) {
+ top -= nudgedTooFarDown;
+ }
+
+ // Now just read off the bits
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithWidth:matrixWidth height:matrixHeight];
+ for (int y = 0; y < matrixHeight; y++) {
+ int iOffset = top + (int) (y * moduleSize);
+ for (int x = 0; x < matrixWidth; x++) {
+ if ([image getX:left + (int) (x * moduleSize) y:iOffset]) {
+ [bits setX:x y:y];
+ }
+ }
+ }
+ return bits;
+}
+
+- (float)moduleSize:(NSArray *)leftTopBlack image:(ZXBitMatrix *)image {
+ int height = image.height;
+ int width = image.width;
+ int x = [leftTopBlack[0] intValue];
+ int y = [leftTopBlack[1] intValue];
+ BOOL inBlack = YES;
+ int transitions = 0;
+ while (x < width && y < height) {
+ if (inBlack != [image getX:x y:y]) {
+ if (++transitions == 5) {
+ break;
+ }
+ }
+ x++;
+ y++;
+ }
+ if (x == width || y == height) {
+ return -1;
+ }
+
+ return (x - [leftTopBlack[0] intValue]) / 7.0f;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/ZXQRCodeWriter.h b/ZXingObjC/qrcode/ZXQRCodeWriter.h
new file mode 100644
index 0000000..e114ee3
--- /dev/null
+++ b/ZXingObjC/qrcode/ZXQRCodeWriter.h
@@ -0,0 +1,25 @@
+/*
+ * 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 "ZXWriter.h"
+
+/**
+ * This object renders a QR Code as a BitMatrix 2D array of greyscale values.
+ */
+
+@interface ZXQRCodeWriter : NSObject <ZXWriter>
+
+@end
diff --git a/ZXingObjC/qrcode/ZXQRCodeWriter.m b/ZXingObjC/qrcode/ZXQRCodeWriter.m
new file mode 100644
index 0000000..8633d2b
--- /dev/null
+++ b/ZXingObjC/qrcode/ZXQRCodeWriter.m
@@ -0,0 +1,94 @@
+/*
+ * 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 "ZXByteMatrix.h"
+#import "ZXEncodeHints.h"
+#import "ZXEncoder.h"
+#import "ZXErrorCorrectionLevel.h"
+#import "ZXQRCode.h"
+#import "ZXQRCodeWriter.h"
+
+int const QUIET_ZONE_SIZE = 4;
+
+@implementation ZXQRCodeWriter
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error {
+ return [self encode:contents format:format width:width height:height hints:nil error:error];
+}
+
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ if ([contents length] == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Found empty contents"];
+ }
+
+ if (format != kBarcodeFormatQRCode) {
+ [NSException raise:NSInvalidArgumentException format:@"Can only encode QR_CODE"];
+ }
+
+ if (width < 0 || height < 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Requested dimensions are too small: %dx%d", width, height];
+ }
+
+ ZXErrorCorrectionLevel *errorCorrectionLevel = [ZXErrorCorrectionLevel errorCorrectionLevelL];
+ int quietZone = QUIET_ZONE_SIZE;
+ if (hints != nil) {
+ if (hints.errorCorrectionLevel) {
+ errorCorrectionLevel = hints.errorCorrectionLevel;
+ }
+ if (hints.margin) {
+ quietZone = [hints.margin intValue];
+ }
+ }
+
+ ZXQRCode *code = [ZXEncoder encode:contents ecLevel:errorCorrectionLevel hints:hints error:error];
+ return [self renderResult:code width:width height:height quietZone:quietZone];
+}
+
+- (ZXBitMatrix *)renderResult:(ZXQRCode *)code width:(int)width height:(int)height quietZone:(int)quietZone {
+ ZXByteMatrix *input = code.matrix;
+ if (input == nil) {
+ return nil;
+ }
+ int inputWidth = input.width;
+ int inputHeight = input.height;
+ int qrWidth = inputWidth + (quietZone << 1);
+ int qrHeight = inputHeight + (quietZone << 1);
+ int outputWidth = MAX(width, qrWidth);
+ int outputHeight = MAX(height, qrHeight);
+
+ int multiple = MIN(outputWidth / qrWidth, outputHeight / qrHeight);
+ // Padding includes both the quiet zone and the extra white pixels to accommodate the requested
+ // dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
+ // If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
+ // handle all the padding from 100x100 (the actual QR) up to 200x160.
+ int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
+ int topPadding = (outputHeight - (inputHeight * multiple)) / 2;
+
+ ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:outputWidth height:outputHeight];
+
+ 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) {
+ [output setRegionAtLeft:outputX top:outputY width:multiple height:multiple];
+ }
+ }
+ }
+
+ return output;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXDataMask.h b/ZXingObjC/qrcode/decoder/ZXDataMask.h
new file mode 100644
index 0000000..325abe4
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXDataMask.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations
+ * of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix,
+ * including areas used for finder patterns, timing patterns, etc. These areas should be unused
+ * after the point they are unmasked anyway.
+ *
+ * Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position
+ * and j is row position. In fact, as the text says, i is row position and j is column position.
+ */
+
+@class ZXBitMatrix;
+
+@interface ZXDataMask : NSObject
+
+- (void)unmaskBitMatrix:(ZXBitMatrix *)bits dimension:(int)dimension;
+- (BOOL)isMasked:(int)i j:(int)j;
++ (ZXDataMask *)forReference:(int)reference;
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXDataMask.m b/ZXingObjC/qrcode/decoder/ZXDataMask.m
new file mode 100644
index 0000000..a9d3bc2
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXDataMask.m
@@ -0,0 +1,204 @@
+/*
+ * 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 "ZXDataMask.h"
+
+/**
+ * 000: mask bits for which (x + y) mod 2 == 0
+ */
+
+@interface ZXDataMask000 : ZXDataMask
+
+@end
+
+@implementation ZXDataMask000
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ return ((i + j) & 0x01) == 0;
+}
+
+@end
+
+
+/**
+ * 001: mask bits for which x mod 2 == 0
+ */
+
+@interface ZXDataMask001 : ZXDataMask
+
+@end
+
+@implementation ZXDataMask001
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ return (i & 0x01) == 0;
+}
+
+@end
+
+
+/**
+ * 010: mask bits for which y mod 3 == 0
+ */
+
+@interface ZXDataMask010 : ZXDataMask
+
+@end
+
+@implementation ZXDataMask010
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ return j % 3 == 0;
+}
+
+@end
+
+
+/**
+ * 011: mask bits for which (x + y) mod 3 == 0
+ */
+
+@interface ZXDataMask011 : ZXDataMask
+
+@end
+
+@implementation ZXDataMask011
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ return (i + j) % 3 == 0;
+}
+
+@end
+
+
+/**
+ * 100: mask bits for which (x/2 + y/3) mod 2 == 0
+ */
+
+@interface ZXDataMask100 : ZXDataMask
+
+@end
+
+@implementation ZXDataMask100
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ return (((int)((unsigned int)i >> 1) + (j / 3)) & 0x01) == 0;
+}
+
+@end
+
+
+/**
+ * 101: mask bits for which xy mod 2 + xy mod 3 == 0
+ */
+
+@interface ZXDataMask101 : ZXDataMask
+
+@end
+
+@implementation ZXDataMask101
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ int temp = i * j;
+ return (temp & 0x01) + (temp % 3) == 0;
+}
+
+@end
+
+
+/**
+ * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0
+ */
+
+@interface ZXDataMask110 : ZXDataMask
+
+@end
+
+@implementation ZXDataMask110
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ int temp = i * j;
+ return (((temp & 0x01) + (temp % 3)) & 0x01) == 0;
+}
+
+@end
+
+
+/**
+ * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0
+ */
+
+@interface ZXDataMask111 : ZXDataMask
+
+@end
+
+@implementation ZXDataMask111
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0;
+}
+
+@end
+
+
+@implementation ZXDataMask
+
+static NSArray *DATA_MASKS = nil;
+
+/**
+ * Implementations of this method reverse the data masking process applied to a QR Code and
+ * make its bits ready to read.
+ */
+- (void)unmaskBitMatrix:(ZXBitMatrix *)bits dimension:(int)dimension {
+ for (int i = 0; i < dimension; i++) {
+ for (int j = 0; j < dimension; j++) {
+ if ([self isMasked:i j:j]) {
+ [bits flipX:j y:i];
+ }
+ }
+ }
+}
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+
++ (ZXDataMask *)forReference:(int)reference {
+ if (!DATA_MASKS) {
+ /**
+ * See ISO 18004:2006 6.8.1
+ */
+ DATA_MASKS = @[[[ZXDataMask000 alloc] init],
+ [[ZXDataMask001 alloc] init],
+ [[ZXDataMask010 alloc] init],
+ [[ZXDataMask011 alloc] init],
+ [[ZXDataMask100 alloc] init],
+ [[ZXDataMask101 alloc] init],
+ [[ZXDataMask110 alloc] init],
+ [[ZXDataMask111 alloc] init]];
+ }
+
+ if (reference < 0 || reference > 7) {
+ [NSException raise:NSInvalidArgumentException format:@"Invalid reference value"];
+ }
+ return DATA_MASKS[reference];
+}
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXErrorCorrectionLevel.h b/ZXingObjC/qrcode/decoder/ZXErrorCorrectionLevel.h
new file mode 100644
index 0000000..060d27d
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXErrorCorrectionLevel.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+/**
+ * See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels
+ * defined by the QR code standard.
+ */
+
+@interface ZXErrorCorrectionLevel : NSObject
+
+@property (nonatomic, assign, readonly) int bits;
+@property (nonatomic, copy, readonly) NSString *name;
+@property (nonatomic, assign, readonly) int ordinal;
+
+- (id)initWithOrdinal:(int)anOrdinal bits:(int)bits name:(NSString *)name;
++ (ZXErrorCorrectionLevel *)forBits:(int)bits;
+
+/**
+ * L = ~7% correction
+ */
++ (ZXErrorCorrectionLevel *)errorCorrectionLevelL;
+
+/**
+ * M = ~15% correction
+ */
++ (ZXErrorCorrectionLevel *)errorCorrectionLevelM;
+
+/**
+ * Q = ~25% correction
+ */
++ (ZXErrorCorrectionLevel *)errorCorrectionLevelQ;
+
+/**
+ * H = ~30% correction
+ */
++ (ZXErrorCorrectionLevel *)errorCorrectionLevelH;
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXErrorCorrectionLevel.m b/ZXingObjC/qrcode/decoder/ZXErrorCorrectionLevel.m
new file mode 100644
index 0000000..f2d823f
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXErrorCorrectionLevel.m
@@ -0,0 +1,95 @@
+/*
+ * 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 "ZXErrorCorrectionLevel.h"
+
+@implementation ZXErrorCorrectionLevel
+
+static NSArray *FOR_BITS = nil;
+
+- (id)initWithOrdinal:(int)ordinal bits:(int)bits name:(NSString *)name {
+ if (self = [super init]) {
+ _ordinal = ordinal;
+ _bits = bits;
+ _name = name;
+ }
+
+ return self;
+}
+
+- (NSString *)description {
+ return self.name;
+}
+
++ (ZXErrorCorrectionLevel *)forBits:(int)bits {
+ if (!FOR_BITS) {
+ FOR_BITS = @[[ZXErrorCorrectionLevel errorCorrectionLevelM], [ZXErrorCorrectionLevel errorCorrectionLevelL],
+ [ZXErrorCorrectionLevel errorCorrectionLevelH], [ZXErrorCorrectionLevel errorCorrectionLevelQ]];
+ }
+
+ if (bits < 0 || bits >= [FOR_BITS count]) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"Invalid bits"
+ userInfo:nil];
+ }
+ return FOR_BITS[bits];
+}
+
+/**
+ * L = ~7% correction
+ */
++ (ZXErrorCorrectionLevel *)errorCorrectionLevelL {
+ static ZXErrorCorrectionLevel *thisLevel = nil;
+ if (!thisLevel) {
+ thisLevel = [[ZXErrorCorrectionLevel alloc] initWithOrdinal:0 bits:0x01 name:@"L"];
+ }
+ return thisLevel;
+}
+
+/**
+ * M = ~15% correction
+ */
++ (ZXErrorCorrectionLevel *)errorCorrectionLevelM {
+ static ZXErrorCorrectionLevel *thisLevel = nil;
+ if (!thisLevel) {
+ thisLevel = [[ZXErrorCorrectionLevel alloc] initWithOrdinal:1 bits:0x00 name:@"M"];
+ }
+ return thisLevel;
+}
+
+/**
+ * Q = ~25% correction
+ */
++ (ZXErrorCorrectionLevel *)errorCorrectionLevelQ {
+ static ZXErrorCorrectionLevel *thisLevel = nil;
+ if (!thisLevel) {
+ thisLevel = [[ZXErrorCorrectionLevel alloc] initWithOrdinal:2 bits:0x03 name:@"Q"];
+ }
+ return thisLevel;
+}
+
+/**
+ * H = ~30% correction
+ */
++ (ZXErrorCorrectionLevel *)errorCorrectionLevelH {
+ static ZXErrorCorrectionLevel *thisLevel = nil;
+ if (!thisLevel) {
+ thisLevel = [[ZXErrorCorrectionLevel alloc] initWithOrdinal:3 bits:0x02 name:@"H"];
+ }
+ return thisLevel;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXFormatInformation.h b/ZXingObjC/qrcode/decoder/ZXFormatInformation.h
new file mode 100644
index 0000000..231c493
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXFormatInformation.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates a QR Code's format information, including the data mask used and
+ * error correction level.
+ */
+
+@class ZXErrorCorrectionLevel;
+
+@interface ZXFormatInformation : NSObject
+
+@property (nonatomic, strong, readonly) ZXErrorCorrectionLevel *errorCorrectionLevel;
+@property (nonatomic, assign, readonly) char dataMask;
+
++ (int)numBitsDiffering:(int)a b:(int)b;
++ (ZXFormatInformation *)decodeFormatInformation:(int)maskedFormatInfo1 maskedFormatInfo2:(int)maskedFormatInfo2;
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXFormatInformation.m b/ZXingObjC/qrcode/decoder/ZXFormatInformation.m
new file mode 100644
index 0000000..4e5f550
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXFormatInformation.m
@@ -0,0 +1,138 @@
+/*
+ * 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 "ZXErrorCorrectionLevel.h"
+#import "ZXFormatInformation.h"
+
+int const FORMAT_INFO_MASK_QR = 0x5412;
+
+/**
+ * See ISO 18004:2006, Annex C, Table C.1
+ */
+int const FORMAT_INFO_DECODE_LOOKUP_LEN = 32;
+int const FORMAT_INFO_DECODE_LOOKUP[FORMAT_INFO_DECODE_LOOKUP_LEN][2] = {
+ {0x5412, 0x00},
+ {0x5125, 0x01},
+ {0x5E7C, 0x02},
+ {0x5B4B, 0x03},
+ {0x45F9, 0x04},
+ {0x40CE, 0x05},
+ {0x4F97, 0x06},
+ {0x4AA0, 0x07},
+ {0x77C4, 0x08},
+ {0x72F3, 0x09},
+ {0x7DAA, 0x0A},
+ {0x789D, 0x0B},
+ {0x662F, 0x0C},
+ {0x6318, 0x0D},
+ {0x6C41, 0x0E},
+ {0x6976, 0x0F},
+ {0x1689, 0x10},
+ {0x13BE, 0x11},
+ {0x1CE7, 0x12},
+ {0x19D0, 0x13},
+ {0x0762, 0x14},
+ {0x0255, 0x15},
+ {0x0D0C, 0x16},
+ {0x083B, 0x17},
+ {0x355F, 0x18},
+ {0x3068, 0x19},
+ {0x3F31, 0x1A},
+ {0x3A06, 0x1B},
+ {0x24B4, 0x1C},
+ {0x2183, 0x1D},
+ {0x2EDA, 0x1E},
+ {0x2BED, 0x1F},
+};
+
+/**
+ * Offset i holds the number of 1 bits in the binary representation of i
+ */
+int const BITS_SET_IN_HALF_BYTE[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+
+@implementation ZXFormatInformation
+
+- (id)initWithFormatInfo:(int)formatInfo {
+ if (self = [super init]) {
+ _errorCorrectionLevel = [ZXErrorCorrectionLevel forBits:(formatInfo >> 3) & 0x03];
+ _dataMask = (char)(formatInfo & 0x07);
+ }
+
+ return self;
+}
+
++ (int)numBitsDiffering:(int)a b:(int)b {
+ a ^= b;
+ return BITS_SET_IN_HALF_BYTE[a & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 4 & 0x0F)] +
+ BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 8 & 0x0F)] +
+ BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 12 & 0x0F)] +
+ BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 16 & 0x0F)] +
+ BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 20 & 0x0F)] +
+ BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 24 & 0x0F)] +
+ BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 28 & 0x0F)];
+}
+
++ (ZXFormatInformation *)decodeFormatInformation:(int)maskedFormatInfo1 maskedFormatInfo2:(int)maskedFormatInfo2 {
+ ZXFormatInformation *formatInfo = [self doDecodeFormatInformation:maskedFormatInfo1 maskedFormatInfo2:maskedFormatInfo2];
+ if (formatInfo != nil) {
+ return formatInfo;
+ }
+ return [self doDecodeFormatInformation:maskedFormatInfo1 ^ FORMAT_INFO_MASK_QR maskedFormatInfo2:maskedFormatInfo2 ^ FORMAT_INFO_MASK_QR];
+}
+
++ (ZXFormatInformation *)doDecodeFormatInformation:(int)maskedFormatInfo1 maskedFormatInfo2:(int)maskedFormatInfo2 {
+ int bestDifference = INT_MAX;
+ int bestFormatInfo = 0;
+
+ for (int i = 0; i < FORMAT_INFO_DECODE_LOOKUP_LEN; i++) {
+ int targetInfo = FORMAT_INFO_DECODE_LOOKUP[i][0];
+ if (targetInfo == maskedFormatInfo1 || targetInfo == maskedFormatInfo2) {
+ return [[ZXFormatInformation alloc] initWithFormatInfo:FORMAT_INFO_DECODE_LOOKUP[i][1]];
+ }
+ int bitsDifference = [self numBitsDiffering:maskedFormatInfo1 b:targetInfo];
+ if (bitsDifference < bestDifference) {
+ bestFormatInfo = FORMAT_INFO_DECODE_LOOKUP[i][1];
+ bestDifference = bitsDifference;
+ }
+ if (maskedFormatInfo1 != maskedFormatInfo2) {
+ bitsDifference = [self numBitsDiffering:maskedFormatInfo2 b:targetInfo];
+ if (bitsDifference < bestDifference) {
+ bestFormatInfo = FORMAT_INFO_DECODE_LOOKUP[i][1];
+ bestDifference = bitsDifference;
+ }
+ }
+ }
+
+ if (bestDifference <= 3) {
+ return [[ZXFormatInformation alloc] initWithFormatInfo:bestFormatInfo];
+ }
+ return nil;
+}
+
+- (NSUInteger)hash {
+ return (self.errorCorrectionLevel.ordinal << 3) | (int)self.dataMask;
+}
+
+- (BOOL)isEqual:(id)o {
+ if (![o isKindOfClass:[ZXFormatInformation class]]) {
+ return NO;
+ }
+ ZXFormatInformation *other = (ZXFormatInformation *)o;
+ return self.errorCorrectionLevel == other.errorCorrectionLevel && self.dataMask == other.dataMask;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXMode.h b/ZXingObjC/qrcode/decoder/ZXMode.h
new file mode 100644
index 0000000..e754515
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXMode.h
@@ -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.
+ */
+
+/**
+ * See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which
+ * data can be encoded to bits in the QR code standard.
+ */
+
+@class ZXQRCodeVersion;
+
+@interface ZXMode : NSObject
+
+@property (nonatomic, assign, readonly) int bits;
+@property (nonatomic, copy, readonly) NSString *name;
+
+- (id)initWithCharacterCountBitsForVersions:(NSArray *)characterCountBitsForVersions bits:(int)bits name:(NSString *)name;
++ (ZXMode *)forBits:(int)bits;
+- (int)characterCountBits:(ZXQRCodeVersion *)version;
+
++ (ZXMode *)terminatorMode; // Not really a mode...
++ (ZXMode *)numericMode;
++ (ZXMode *)alphanumericMode;
++ (ZXMode *)structuredAppendMode; // Not supported
++ (ZXMode *)byteMode;
++ (ZXMode *)eciMode; // character counts don't apply
++ (ZXMode *)kanjiMode;
++ (ZXMode *)fnc1FirstPositionMode;
++ (ZXMode *)fnc1SecondPositionMode;
+
+/** See GBT 18284-2000; "Hanzi" is a transliteration of this mode name. */
++ (ZXMode *)hanziMode;
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXMode.m b/ZXingObjC/qrcode/decoder/ZXMode.m
new file mode 100644
index 0000000..8c58388
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXMode.m
@@ -0,0 +1,165 @@
+/*
+ * 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 "ZXMode.h"
+#import "ZXQRCodeVersion.h"
+
+@interface ZXMode ()
+
+@property (nonatomic, strong) NSArray *characterCountBitsForVersions;
+
+@end
+
+@implementation ZXMode
+
+- (id)initWithCharacterCountBitsForVersions:(NSArray *)characterCountBitsForVersions bits:(int)bits name:(NSString *)name {
+ if (self = [super init]) {
+ _characterCountBitsForVersions = characterCountBitsForVersions;
+ _bits = bits;
+ _name = name;
+ }
+
+ return self;
+}
+
++ (ZXMode *)forBits:(int)bits {
+ switch (bits) {
+ case 0x0:
+ return [ZXMode terminatorMode];
+ case 0x1:
+ return [ZXMode numericMode];
+ case 0x2:
+ return [ZXMode alphanumericMode];
+ case 0x3:
+ return [ZXMode structuredAppendMode];
+ case 0x4:
+ return [ZXMode byteMode];
+ case 0x5:
+ return [ZXMode fnc1FirstPositionMode];
+ case 0x7:
+ return [ZXMode eciMode];
+ case 0x8:
+ return [ZXMode kanjiMode];
+ case 0x9:
+ return [ZXMode fnc1SecondPositionMode];
+ case 0xD:
+ return [ZXMode hanziMode];
+ default:
+ return nil;
+ }
+}
+
+- (int)characterCountBits:(ZXQRCodeVersion *)version {
+ int number = version.versionNumber;
+ int offset;
+ if (number <= 9) {
+ offset = 0;
+ } else if (number <= 26) {
+ offset = 1;
+ } else {
+ offset = 2;
+ }
+ return [self.characterCountBitsForVersions[offset] intValue];
+}
+
+- (NSString *)description {
+ return self.name;
+}
+
++ (ZXMode *)terminatorMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x00 name:@"TERMINATOR"];
+ }
+ return thisMode;
+}
+
++ (ZXMode *)numericMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@10, @12, @14] bits:0x01 name:@"NUMERIC"];
+ }
+ return thisMode;
+}
+
++ (ZXMode *)alphanumericMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@9, @11, @13] bits:0x02 name:@"ALPHANUMERIC"];
+ }
+ return thisMode;
+}
+
++ (ZXMode *)structuredAppendMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x03 name:@"STRUCTURED_APPEND"];
+ }
+ return thisMode;
+}
+
++ (ZXMode *)byteMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@8, @16, @16] bits:0x04 name:@"BYTE"];
+ }
+ return thisMode;
+}
+
++ (ZXMode *)eciMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x07 name:@"ECI"];
+ }
+ return thisMode;
+}
+
++ (ZXMode *)kanjiMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@8, @10, @12] bits:0x08 name:@"KANJI"];
+ }
+ return thisMode;
+}
+
++ (ZXMode *)fnc1FirstPositionMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x05 name:@"FNC1_FIRST_POSITION"];
+ }
+ return thisMode;
+}
+
++ (ZXMode *)fnc1SecondPositionMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x09 name:@"FNC1_SECOND_POSITION"];
+ }
+ return thisMode;
+}
+
+/**
+ * See GBT 18284-2000; "Hanzi" is a transliteration of this mode name.
+ */
++ (ZXMode *)hanziMode {
+ static ZXMode *thisMode = nil;
+ if (!thisMode) {
+ thisMode = [[ZXMode alloc] initWithCharacterCountBitsForVersions:@[@8, @10, @12] bits:0x0D name:@"HANZI"];
+ }
+ return thisMode;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.h b/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.h
new file mode 100644
index 0000000..9382d70
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+@class ZXBitMatrix, ZXFormatInformation, ZXQRCodeVersion;
+
+@interface ZXQRCodeBitMatrixParser : NSObject
+
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error;
+- (ZXFormatInformation *)readFormatInformationWithError:(NSError **)error;
+- (ZXQRCodeVersion *)readVersionWithError:(NSError **)error;
+- (NSArray *)readCodewordsWithError:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.m b/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.m
new file mode 100644
index 0000000..ae42c51
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.m
@@ -0,0 +1,202 @@
+/*
+ * 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 "ZXDataMask.h"
+#import "ZXErrors.h"
+#import "ZXFormatInformation.h"
+#import "ZXQRCodeBitMatrixParser.h"
+#import "ZXQRCodeVersion.h"
+
+@interface ZXQRCodeBitMatrixParser ()
+
+@property (nonatomic, strong) ZXBitMatrix *bitMatrix;
+@property (nonatomic, strong) ZXFormatInformation *parsedFormatInfo;
+@property (nonatomic, strong) ZXQRCodeVersion *parsedVersion;
+
+@end
+
+@implementation ZXQRCodeBitMatrixParser
+
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error {
+ int dimension = bitMatrix.height;
+ if (dimension < 21 || (dimension & 0x03) != 1) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+
+ if (self = [super init]) {
+ _bitMatrix = bitMatrix;
+ _parsedFormatInfo = nil;
+ _parsedVersion = nil;
+ }
+ return self;
+}
+
+/**
+ * Reads format information from one of its two locations within the QR Code.
+ */
+- (ZXFormatInformation *)readFormatInformationWithError:(NSError **)error {
+ if (self.parsedFormatInfo != nil) {
+ return self.parsedFormatInfo;
+ }
+ int formatInfoBits1 = 0;
+
+ for (int i = 0; i < 6; i++) {
+ formatInfoBits1 = [self copyBit:i j:8 versionBits:formatInfoBits1];
+ }
+
+ formatInfoBits1 = [self copyBit:7 j:8 versionBits:formatInfoBits1];
+ formatInfoBits1 = [self copyBit:8 j:8 versionBits:formatInfoBits1];
+ formatInfoBits1 = [self copyBit:8 j:7 versionBits:formatInfoBits1];
+
+ for (int j = 5; j >= 0; j--) {
+ formatInfoBits1 = [self copyBit:8 j:j versionBits:formatInfoBits1];
+ }
+
+ int dimension = self.bitMatrix.height;
+ int formatInfoBits2 = 0;
+ int jMin = dimension - 7;
+
+ for (int j = dimension - 1; j >= jMin; j--) {
+ formatInfoBits2 = [self copyBit:8 j:j versionBits:formatInfoBits2];
+ }
+
+ for (int i = dimension - 8; i < dimension; i++) {
+ formatInfoBits2 = [self copyBit:i j:8 versionBits:formatInfoBits2];
+ }
+
+ self.parsedFormatInfo = [ZXFormatInformation decodeFormatInformation:formatInfoBits1 maskedFormatInfo2:formatInfoBits2];
+ if (self.parsedFormatInfo != nil) {
+ return self.parsedFormatInfo;
+ }
+ if (error) *error = FormatErrorInstance();
+ return nil;
+}
+
+
+/**
+ * Reads version information from one of its two locations within the QR Code.
+ */
+- (ZXQRCodeVersion *)readVersionWithError:(NSError **)error {
+ if (self.parsedVersion != nil) {
+ return self.parsedVersion;
+ }
+ int dimension = self.bitMatrix.height;
+ int provisionalVersion = (dimension - 17) >> 2;
+ if (provisionalVersion <= 6) {
+ return [ZXQRCodeVersion versionForNumber:provisionalVersion];
+ }
+ int versionBits = 0;
+ int ijMin = dimension - 11;
+
+ for (int j = 5; j >= 0; j--) {
+
+ for (int i = dimension - 9; i >= ijMin; i--) {
+ versionBits = [self copyBit:i j:j versionBits:versionBits];
+ }
+
+ }
+
+ ZXQRCodeVersion *theParsedVersion = [ZXQRCodeVersion decodeVersionInformation:versionBits];
+ if (theParsedVersion != nil && theParsedVersion.dimensionForVersion == dimension) {
+ self.parsedVersion = theParsedVersion;
+ return self.parsedVersion;
+ }
+ versionBits = 0;
+
+ for (int i = 5; i >= 0; i--) {
+ for (int j = dimension - 9; j >= ijMin; j--) {
+ versionBits = [self copyBit:i j:j versionBits:versionBits];
+ }
+ }
+
+ theParsedVersion = [ZXQRCodeVersion decodeVersionInformation:versionBits];
+ if (theParsedVersion != nil && theParsedVersion.dimensionForVersion == dimension) {
+ self.parsedVersion = theParsedVersion;
+ return self.parsedVersion;
+ }
+ if (error) *error = FormatErrorInstance();
+ return nil;
+}
+
+- (int)copyBit:(int)i j:(int)j versionBits:(int)versionBits {
+ return [self.bitMatrix getX:i y:j] ? (versionBits << 1) | 0x1 : versionBits << 1;
+}
+
+
+/**
+ * Reads the bits in the {@link BitMatrix} representing the finder pattern in the
+ * correct order in order to reconstitute the codewords bytes contained within the
+ * QR Code.
+ */
+- (NSArray *)readCodewordsWithError:(NSError **)error {
+ ZXFormatInformation *formatInfo = [self readFormatInformationWithError:error];
+ if (!formatInfo) {
+ return nil;
+ }
+
+ ZXQRCodeVersion *version = [self readVersionWithError:error];
+ if (!version) {
+ return nil;
+ }
+
+ ZXDataMask *dataMask = [ZXDataMask forReference:(int)[formatInfo dataMask]];
+ int dimension = self.bitMatrix.height;
+ [dataMask unmaskBitMatrix:self.bitMatrix dimension:dimension];
+ ZXBitMatrix *functionPattern = [version buildFunctionPattern];
+ BOOL readingUp = YES;
+ NSMutableArray *result = [NSMutableArray array];
+ int resultOffset = 0;
+ int currentByte = 0;
+ int bitsRead = 0;
+
+ for (int j = dimension - 1; j > 0; j -= 2) {
+ if (j == 6) {
+ j--;
+ }
+
+ for (int count = 0; count < dimension; count++) {
+ int i = readingUp ? dimension - 1 - count : count;
+
+ for (int col = 0; col < 2; col++) {
+ if (![functionPattern getX:j - col y:i]) {
+ bitsRead++;
+ currentByte <<= 1;
+ if ([self.bitMatrix getX:j - col y:i]) {
+ currentByte |= 1;
+ }
+ if (bitsRead == 8) {
+ [result addObject:@((char)currentByte)];
+ resultOffset++;
+ bitsRead = 0;
+ currentByte = 0;
+ }
+ }
+ }
+ }
+
+ readingUp ^= YES;
+ }
+
+ if (resultOffset != [version totalCodewords]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.h b/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.h
new file mode 100644
index 0000000..cac0b77
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates a block of data within a QR Code. QR Codes may split their data into
+ * multiple blocks, each of which is a unit of data and error-correction codewords. Each
+ * is represented by an instance of this class.
+ */
+
+@class ZXErrorCorrectionLevel, ZXQRCodeVersion;
+
+@interface ZXQRCodeDataBlock : NSObject
+
+@property (nonatomic, strong, readonly) NSMutableArray *codewords;
+@property (nonatomic, assign, readonly) int numDataCodewords;
+
+- (id)initWithNumDataCodewords:(int)numDataCodewords codewords:(NSMutableArray *)codewords;
++ (NSArray *)dataBlocks:(NSArray *)rawCodewords version:(ZXQRCodeVersion *)version ecLevel:(ZXErrorCorrectionLevel *)ecLevel;
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.m b/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.m
new file mode 100644
index 0000000..5c878c8
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.m
@@ -0,0 +1,101 @@
+/*
+ * 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 "ZXErrorCorrectionLevel.h"
+#import "ZXQRCodeDataBlock.h"
+#import "ZXQRCodeVersion.h"
+
+@implementation ZXQRCodeDataBlock
+
+- (id)initWithNumDataCodewords:(int)numDataCodewords codewords:(NSMutableArray *)codewords {
+ if (self = [super init]) {
+ _numDataCodewords = numDataCodewords;
+ _codewords = codewords;
+ }
+
+ return self;
+}
+
+/**
+ * When QR Codes use multiple data blocks, they are actually interleaved.
+ * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
+ * method will separate the data into original blocks.
+ */
++ (NSArray *)dataBlocks:(NSArray *)rawCodewords version:(ZXQRCodeVersion *)version ecLevel:(ZXErrorCorrectionLevel *)ecLevel {
+ if (rawCodewords.count != version.totalCodewords) {
+ [NSException raise:NSInvalidArgumentException format:@"Invalid codewords count"];
+ }
+
+ ZXQRCodeECBlocks *ecBlocks = [version ecBlocksForLevel:ecLevel];
+
+ int totalBlocks = 0;
+ NSArray *ecBlockArray = ecBlocks.ecBlocks;
+ for (ZXQRCodeECB *ecBlock in ecBlockArray) {
+ totalBlocks += ecBlock.count;
+ }
+
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:totalBlocks];
+ for (ZXQRCodeECB *ecBlock in ecBlockArray) {
+ for (int i = 0; i < ecBlock.count; i++) {
+ int numDataCodewords = ecBlock.dataCodewords;
+ int numBlockCodewords = ecBlocks.ecCodewordsPerBlock + numDataCodewords;
+ NSMutableArray *newCodewords = [NSMutableArray arrayWithCapacity:numBlockCodewords];
+ for (int j = 0; j < numBlockCodewords; j++) {
+ [newCodewords addObject:[NSNull null]];
+ }
+
+ [result addObject:[[ZXQRCodeDataBlock alloc] initWithNumDataCodewords:numDataCodewords codewords:newCodewords]];
+ }
+ }
+
+ int shorterBlocksTotalCodewords = (int)[[result[0] codewords] count];
+ int longerBlocksStartAt = (int)[result count] - 1;
+
+ while (longerBlocksStartAt >= 0) {
+ int numCodewords = (int)[[result[longerBlocksStartAt] codewords] count];
+ if (numCodewords == shorterBlocksTotalCodewords) {
+ break;
+ }
+ longerBlocksStartAt--;
+ }
+
+ longerBlocksStartAt++;
+ int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.ecCodewordsPerBlock;
+ int rawCodewordsOffset = 0;
+ int numResultBlocks = (int)[result count];
+
+ for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {
+ for (int j = 0; j < numResultBlocks; j++) {
+ [result[j] codewords][i] = rawCodewords[rawCodewordsOffset++];
+ }
+ }
+
+ for (int j = longerBlocksStartAt; j < numResultBlocks; j++) {
+ [result[j] codewords][shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
+ }
+
+ int max = (int)[[result[0] codewords] count];
+ for (int i = shorterBlocksNumDataCodewords; i < max; i++) {
+ for (int j = 0; j < numResultBlocks; j++) {
+ int iOffset = j < longerBlocksStartAt ? i : i + 1;
+ [result[j] codewords][iOffset] = rawCodewords[rawCodewordsOffset++];
+ }
+ }
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.h b/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.h
new file mode 100644
index 0000000..730b2a3
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * QR Codes can encode text as bits in one of several modes, and can use multiple modes
+ * in one QR Code. This class decodes the bits back into text.
+ *
+ * See ISO 18004:2006, 6.4.3 - 6.4.7
+ */
+
+@class ZXDecodeHints, ZXDecoderResult, ZXErrorCorrectionLevel, ZXQRCodeVersion;
+
+@interface ZXQRCodeDecodedBitStreamParser : NSObject
+
++ (ZXDecoderResult *)decode:(int8_t *)bytes length:(unsigned int)length version:(ZXQRCodeVersion *)version
+ ecLevel:(ZXErrorCorrectionLevel *)ecLevel hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m b/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m
new file mode 100644
index 0000000..153911f
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m
@@ -0,0 +1,322 @@
+/*
+ * 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 "ZXBitSource.h"
+#import "ZXCharacterSetECI.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXErrorCorrectionLevel.h"
+#import "ZXMode.h"
+#import "ZXQRCodeDecodedBitStreamParser.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXStringUtils.h"
+
+
+/**
+ * See ISO 18004:2006, 6.4.4 Table 5
+ */
+char const ALPHANUMERIC_CHARS[45] = {
+ '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',
+ ' ', '$', '%', '*', '+', '-', '.', '/', ':'
+};
+
+int const GB2312_SUBSET = 1;
+
+@implementation ZXQRCodeDecodedBitStreamParser
+
++ (ZXDecoderResult *)decode:(int8_t *)bytes length:(unsigned int)length version:(ZXQRCodeVersion *)version
+ ecLevel:(ZXErrorCorrectionLevel *)ecLevel hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXBitSource *bits = [[ZXBitSource alloc] initWithBytes:bytes length:length];
+ NSMutableString *result = [NSMutableString stringWithCapacity:50];
+ ZXCharacterSetECI *currentCharacterSetECI = nil;
+ BOOL fc1InEffect = NO;
+ NSMutableArray *byteSegments = [NSMutableArray arrayWithCapacity:1];
+ ZXMode *mode;
+
+ do {
+ if ([bits available] < 4) {
+ mode = [ZXMode terminatorMode];
+ } else {
+ mode = [ZXMode forBits:[bits readBits:4]];
+ if (!mode) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ }
+ if (![mode isEqual:[ZXMode terminatorMode]]) {
+ if ([mode isEqual:[ZXMode fnc1FirstPositionMode]] || [mode isEqual:[ZXMode fnc1SecondPositionMode]]) {
+ fc1InEffect = YES;
+ } else if ([mode isEqual:[ZXMode structuredAppendMode]]) {
+ if (bits.available < 16) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ [bits readBits:16];
+ } else if ([mode isEqual:[ZXMode eciMode]]) {
+ int value = [self parseECIValue:bits];
+ currentCharacterSetECI = [ZXCharacterSetECI characterSetECIByValue:value];
+ if (currentCharacterSetECI == nil) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ } else {
+ if ([mode isEqual:[ZXMode hanziMode]]) {
+ int subset = [bits readBits:4];
+ int countHanzi = [bits readBits:[mode characterCountBits:version]];
+ if (subset == GB2312_SUBSET) {
+ if (![self decodeHanziSegment:bits result:result count:countHanzi]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ }
+ } else {
+ int count = [bits readBits:[mode characterCountBits:version]];
+ if ([mode isEqual:[ZXMode numericMode]]) {
+ if (![self decodeNumericSegment:bits result:result count:count]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ } else if ([mode isEqual:[ZXMode alphanumericMode]]) {
+ if (![self decodeAlphanumericSegment:bits result:result count:count fc1InEffect:fc1InEffect]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ } else if ([mode isEqual:[ZXMode byteMode]]) {
+ if (![self decodeByteSegment:bits result:result count:count currentCharacterSetECI:currentCharacterSetECI byteSegments:byteSegments hints:hints]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ } else if ([mode isEqual:[ZXMode kanjiMode]]) {
+ if (![self decodeKanjiSegment:bits result:result count:count]) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ } else {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ }
+ }
+ }
+ } while (![mode isEqual:[ZXMode terminatorMode]]);
+ return [[ZXDecoderResult alloc] initWithRawBytes:bytes
+ length:length
+ text:result.description
+ byteSegments:byteSegments.count == 0 ? nil : byteSegments
+ ecLevel:ecLevel == nil ? nil : ecLevel.description];
+}
+
+
+/**
+ * See specification GBT 18284-2000
+ */
++ (BOOL)decodeHanziSegment:(ZXBitSource *)bits result:(NSMutableString *)result count:(int)count {
+ if (count * 13 > bits.available) {
+ return NO;
+ }
+
+ NSMutableData *buffer = [NSMutableData dataWithCapacity:2 * count];
+ while (count > 0) {
+ int twoBytes = [bits readBits:13];
+ int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
+ if (assembledTwoBytes < 0x003BF) {
+ assembledTwoBytes += 0x0A1A1;
+ } else {
+ assembledTwoBytes += 0x0A6A1;
+ }
+ char bytes[2];
+ bytes[0] = (char)((assembledTwoBytes >> 8) & 0xFF);
+ bytes[1] = (char)(assembledTwoBytes & 0xFF);
+
+ [buffer appendBytes:bytes length:2];
+
+ count--;
+ }
+
+ NSString *string = [[NSString alloc] initWithData:buffer encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000)];
+ if (string) {
+ [result appendString:string];
+ }
+ return YES;
+}
+
++ (BOOL)decodeKanjiSegment:(ZXBitSource *)bits result:(NSMutableString *)result count:(int)count {
+ if (count * 13 > bits.available) {
+ return NO;
+ }
+
+ NSMutableData *buffer = [NSMutableData dataWithCapacity:2 * count];
+ while (count > 0) {
+ int twoBytes = [bits readBits:13];
+ int assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0);
+ if (assembledTwoBytes < 0x01F00) {
+ assembledTwoBytes += 0x08140;
+ } else {
+ assembledTwoBytes += 0x0C140;
+ }
+ char bytes[2];
+ bytes[0] = (char)(assembledTwoBytes >> 8);
+ bytes[1] = (char)assembledTwoBytes;
+
+ [buffer appendBytes:bytes length:2];
+
+ count--;
+ }
+
+ NSString *string = [[NSString alloc] initWithData:buffer encoding:NSShiftJISStringEncoding];
+ if (string) {
+ [result appendString:string];
+ }
+ return YES;
+}
+
++ (BOOL)decodeByteSegment:(ZXBitSource *)bits result:(NSMutableString *)result count:(int)count currentCharacterSetECI:(ZXCharacterSetECI *)currentCharacterSetECI byteSegments:(NSMutableArray *)byteSegments hints:(ZXDecodeHints *)hints {
+ if (count << 3 > bits.available) {
+ return NO;
+ }
+ int8_t readBytes[count];
+ NSMutableArray *readBytesArray = [NSMutableArray arrayWithCapacity:count];
+
+ for (int i = 0; i < count; i++) {
+ readBytes[i] = (char)[bits readBits:8];
+ [readBytesArray addObject:[NSNumber numberWithChar:readBytes[i]]];
+ }
+
+ NSStringEncoding encoding;
+ if (currentCharacterSetECI == nil) {
+ encoding = [ZXStringUtils guessEncoding:readBytes length:count hints:hints];
+ } else {
+ encoding = [currentCharacterSetECI encoding];
+ }
+
+ NSString *string = [[NSString alloc] initWithBytes:readBytes length:count encoding:encoding];
+ if (string) {
+ [result appendString:string];
+ }
+
+ [byteSegments addObject:readBytesArray];
+ return YES;
+}
+
++ (unichar)toAlphaNumericChar:(int)value {
+ if (value >= 45) {
+ return -1;
+ }
+ return ALPHANUMERIC_CHARS[value];
+}
+
++ (BOOL)decodeAlphanumericSegment:(ZXBitSource *)bits result:(NSMutableString *)result count:(int)count fc1InEffect:(BOOL)fc1InEffect {
+ int start = (int)result.length;
+
+ while (count > 1) {
+ if ([bits available] < 11) {
+ return NO;
+ }
+ int nextTwoCharsBits = [bits readBits:11];
+ unichar next1 = [self toAlphaNumericChar:nextTwoCharsBits / 45];
+ unichar next2 = [self toAlphaNumericChar:nextTwoCharsBits % 45];
+
+ [result appendFormat:@"%C%C", next1, next2];
+ count -= 2;
+ }
+
+ if (count == 1) {
+ if ([bits available] < 6) {
+ return NO;
+ }
+ unichar next1 = [self toAlphaNumericChar:[bits readBits:6]];
+ [result appendFormat:@"%C", next1];
+ }
+ if (fc1InEffect) {
+ for (int i = start; i < [result length]; i++) {
+ if ([result characterAtIndex:i] == '%') {
+ if (i < [result length] - 1 && [result characterAtIndex:i + 1] == '%') {
+ [result deleteCharactersInRange:NSMakeRange(i + 1, 1)];
+ } else {
+ [result insertString:[NSString stringWithFormat:@"%C", (unichar)0x1D]
+ atIndex:i];
+ }
+ }
+ }
+ }
+ return YES;
+}
+
++ (BOOL)decodeNumericSegment:(ZXBitSource *)bits result:(NSMutableString *)result count:(int)count {
+ // Read three digits at a time
+ while (count >= 3) {
+ // Each 10 bits encodes three digits
+ if (bits.available < 10) {
+ return NO;
+ }
+ int threeDigitsBits = [bits readBits:10];
+ if (threeDigitsBits >= 1000) {
+ return NO;
+ }
+ unichar next1 = [self toAlphaNumericChar:threeDigitsBits / 100];
+ unichar next2 = [self toAlphaNumericChar:(threeDigitsBits / 10) % 10];
+ unichar next3 = [self toAlphaNumericChar:threeDigitsBits % 10];
+
+ [result appendFormat:@"%C%C%C", next1, next2, next3];
+ count -= 3;
+ }
+
+ if (count == 2) {
+ // Two digits left over to read, encoded in 7 bits
+ if (bits.available < 7) {
+ return NO;
+ }
+ int twoDigitsBits = [bits readBits:7];
+ if (twoDigitsBits >= 100) {
+ return NO;
+ }
+ unichar next1 = [self toAlphaNumericChar:twoDigitsBits / 10];
+ unichar next2 = [self toAlphaNumericChar:twoDigitsBits % 10];
+ [result appendFormat:@"%C%C", next1, next2];
+ } else if (count == 1) {
+ // One digit left over to read
+ if (bits.available < 4) {
+ return NO;
+ }
+ int digitBits = [bits readBits:4];
+ if (digitBits >= 10) {
+ return NO;
+ }
+ unichar next1 = [self toAlphaNumericChar:digitBits];
+ [result appendFormat:@"%C", next1];
+ }
+ return YES;
+}
+
++ (int)parseECIValue:(ZXBitSource *)bits {
+ int firstByte = [bits readBits:8];
+ if ((firstByte & 0x80) == 0) {
+ return firstByte & 0x7F;
+ }
+ if ((firstByte & 0xC0) == 0x80) {
+ int secondByte = [bits readBits:8];
+ return ((firstByte & 0x3F) << 8) | secondByte;
+ }
+ if ((firstByte & 0xE0) == 0xC0) {
+ int secondThirdBytes = [bits readBits:16];
+ return ((firstByte & 0x1F) << 16) | secondThirdBytes;
+ }
+ return -1;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h b/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h
new file mode 100644
index 0000000..650a15c
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/**
+ * The main class which implements QR Code decoding -- as opposed to locating and extracting
+ * the QR Code from an image.
+ */
+
+@class ZXBitMatrix, ZXDecodeHints, ZXDecodeHints, ZXDecoderResult;
+
+@interface ZXQRCodeDecoder : NSObject
+
+- (ZXDecoderResult *)decode:(BOOL **)image length:(unsigned int)length error:(NSError **)error;
+- (ZXDecoderResult *)decode:(BOOL **)image length:(unsigned int)length 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/ZXQRCodeDecoder.m b/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.m
new file mode 100644
index 0000000..ae9b03d
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.m
@@ -0,0 +1,153 @@
+/*
+ * 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 "ZXDecoderResult.h"
+#import "ZXErrorCorrectionLevel.h"
+#import "ZXErrors.h"
+#import "ZXFormatInformation.h"
+#import "ZXGenericGF.h"
+#import "ZXQRCodeBitMatrixParser.h"
+#import "ZXQRCodeDataBlock.h"
+#import "ZXQRCodeDecodedBitStreamParser.h"
+#import "ZXQRCodeDecoder.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXReedSolomonDecoder.h"
+
+@interface ZXQRCodeDecoder ()
+
+@property (nonatomic, strong) ZXReedSolomonDecoder *rsDecoder;
+
+@end
+
+@implementation ZXQRCodeDecoder
+
+- (id)init {
+ if (self = [super init]) {
+ _rsDecoder = [[ZXReedSolomonDecoder alloc] initWithField:[ZXGenericGF QrCodeField256]];
+ }
+
+ return self;
+}
+
+- (ZXDecoderResult *)decode:(BOOL **)image length:(unsigned int)length error:(NSError **)error {
+ return [self decode:image length:length hints:nil error:error];
+}
+
+/**
+ * Convenience method that can decode a QR Code represented as a 2D array of booleans.
+ * "true" is taken to mean a black module.
+ */
+- (ZXDecoderResult *)decode:(BOOL **)image length:(unsigned int)length hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ int dimension = length;
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithDimension:dimension];
+ for (int i = 0; i < dimension; i++) {
+ for (int j = 0; j < dimension; j++) {
+ if (image[i][j]) {
+ [bits setX:j y:i];
+ }
+ }
+ }
+
+ return [self decodeMatrix:bits hints:hints error:error];
+}
+
+- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits error:(NSError **)error {
+ return [self decodeMatrix:bits hints:nil error:error];
+}
+
+/**
+ * Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black module.
+ */
+- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXQRCodeBitMatrixParser *parser = [[ZXQRCodeBitMatrixParser alloc] initWithBitMatrix:bits error:error];
+ if (!parser) {
+ return nil;
+ }
+ ZXQRCodeVersion *version = [parser readVersionWithError:error];
+ if (!version) {
+ return nil;
+ }
+ ZXFormatInformation *formatInfo = [parser readFormatInformationWithError:error];
+ if (!formatInfo) {
+ return nil;
+ }
+ ZXErrorCorrectionLevel *ecLevel = formatInfo.errorCorrectionLevel;
+
+ NSArray *codewords = [parser readCodewordsWithError:error];
+ if (!codewords) {
+ return nil;
+ }
+ NSArray *dataBlocks = [ZXQRCodeDataBlock dataBlocks:codewords version:version ecLevel:ecLevel];
+
+ int totalBytes = 0;
+ for (ZXQRCodeDataBlock *dataBlock in dataBlocks) {
+ totalBytes += dataBlock.numDataCodewords;
+ }
+
+ if (totalBytes == 0) {
+ return nil;
+ }
+
+ int8_t resultBytes[totalBytes];
+ int resultOffset = 0;
+
+ for (ZXQRCodeDataBlock *dataBlock in dataBlocks) {
+ NSMutableArray *codewordBytes = [dataBlock codewords];
+ int numDataCodewords = [dataBlock numDataCodewords];
+ if (![self correctErrors:codewordBytes numDataCodewords:numDataCodewords error:error]) {
+ return nil;
+ }
+ for (int i = 0; i < numDataCodewords; i++) {
+ resultBytes[resultOffset++] = [codewordBytes[i] charValue];
+ }
+ }
+
+ return [ZXQRCodeDecodedBitStreamParser decode:resultBytes length:totalBytes version:version ecLevel:ecLevel hints:hints error:error];
+}
+
+
+/**
+ * Given data and error-correction codewords received, possibly corrupted by errors, attempts to
+ * correct the errors in-place using Reed-Solomon error correction.
+ */
+- (BOOL)correctErrors:(NSMutableArray *)codewordBytes numDataCodewords:(int)numDataCodewords error:(NSError **)error {
+ int numCodewords = (int)[codewordBytes count];
+ int codewordsInts[numCodewords];
+
+ for (int i = 0; i < numCodewords; i++) {
+ codewordsInts[i] = [codewordBytes[i] charValue] & 0xFF;
+ }
+
+ int numECCodewords = (int)[codewordBytes count] - numDataCodewords;
+ NSError *decodeError = nil;
+ if (![self.rsDecoder decode:codewordsInts receivedLen:numCodewords twoS:numECCodewords error:&decodeError]) {
+ if (decodeError.code == ZXReedSolomonError) {
+ if (error) *error = ChecksumErrorInstance();
+ return NO;
+ } else {
+ if (error) *error = decodeError;
+ return NO;
+ }
+ }
+
+ for (int i = 0; i < numDataCodewords; i++) {
+ codewordBytes[i] = [NSNumber numberWithChar:codewordsInts[i]];
+ }
+ return YES;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.h b/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.h
new file mode 100644
index 0000000..5364302
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/**
+ * 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
+ * each set of blocks. It also holds the number of error-correction codewords per block since it
+ * will be the same across all blocks within one version.
+ */
+
+@class ZXQRCodeECB;
+
+@interface ZXQRCodeECBlocks : NSObject
+
+@property (nonatomic, assign, readonly) int ecCodewordsPerBlock;
+@property (nonatomic, assign, readonly) int numBlocks;
+@property (nonatomic, assign, readonly) int totalECCodewords;
+@property (nonatomic, strong, readonly) NSArray *ecBlocks;
+
+- (id)initWithEcCodewordsPerBlock:(int)ecCodewordsPerBlock ecBlocks:(ZXQRCodeECB *)ecBlocks;
+- (id)initWithEcCodewordsPerBlock:(int)ecCodewordsPerBlock ecBlocks1:(ZXQRCodeECB *)ecBlocks1 ecBlocks2:(ZXQRCodeECB *)ecBlocks2;
++ (ZXQRCodeECBlocks *)ecBlocksWithEcCodewordsPerBlock:(int)ecCodewordsPerBlock ecBlocks:(ZXQRCodeECB *)ecBlocks;
++ (ZXQRCodeECBlocks *)ecBlocksWithEcCodewordsPerBlock:(int)ecCodewordsPerBlock ecBlocks1:(ZXQRCodeECB *)ecBlocks1 ecBlocks2:(ZXQRCodeECB *)ecBlocks2;
+
+@end
+
+/**
+ * Encapsualtes the parameters for one error-correction block in one symbol version.
+ * This includes the number of data codewords, and the number of times a block with these
+ * parameters is used consecutively in the QR code version's format.
+ */
+
+@interface ZXQRCodeECB : NSObject
+
+@property (nonatomic, assign, readonly) int count;
+@property (nonatomic, assign, readonly) int dataCodewords;
+
+- (id)initWithCount:(int)count dataCodewords:(int)dataCodewords;
++ (ZXQRCodeECB *)ecbWithCount:(int)count dataCodewords:(int)dataCodewords;
+
+@end
+
+/**
+ * See ISO 18004:2006 Annex D
+ */
+
+@class ZXErrorCorrectionLevel, ZXBitMatrix;
+
+@interface ZXQRCodeVersion : NSObject
+
+@property (nonatomic, assign, readonly) int versionNumber;
+@property (nonatomic, strong, readonly) NSArray *alignmentPatternCenters;
+@property (nonatomic, strong, readonly) NSArray *ecBlocks;
+@property (nonatomic, assign, readonly) int totalCodewords;
+@property (nonatomic, assign, readonly) int dimensionForVersion;
+
+- (ZXQRCodeECBlocks *)ecBlocksForLevel:(ZXErrorCorrectionLevel *)ecLevel;
++ (ZXQRCodeVersion *)provisionalVersionForDimension:(int)dimension;
++ (ZXQRCodeVersion *)versionForNumber:(int)versionNumber;
++ (ZXQRCodeVersion *)decodeVersionInformation:(int)versionBits;
+- (ZXBitMatrix *)buildFunctionPattern;
+
+@end
diff --git a/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.m b/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.m
new file mode 100644
index 0000000..338410a
--- /dev/null
+++ b/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.m
@@ -0,0 +1,494 @@
+/*
+ * 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 "ZXErrorCorrectionLevel.h"
+#import "ZXFormatInformation.h"
+#import "ZXQRCodeVersion.h"
+
+@implementation ZXQRCodeECBlocks
+
+- (id)initWithEcCodewordsPerBlock:(int)ecCodewordsPerBlock ecBlocks:(ZXQRCodeECB *)ecBlocks {
+ if (self = [super init]) {
+ _ecCodewordsPerBlock = ecCodewordsPerBlock;
+ _ecBlocks = @[ecBlocks];
+ }
+
+ return self;
+}
+
+- (id)initWithEcCodewordsPerBlock:(int)ecCodewordsPerBlock ecBlocks1:(ZXQRCodeECB *)ecBlocks1 ecBlocks2:(ZXQRCodeECB *)ecBlocks2 {
+ if (self = [super init]) {
+ _ecCodewordsPerBlock = ecCodewordsPerBlock;
+ _ecBlocks = @[ecBlocks1, ecBlocks2];
+ }
+
+ return self;
+}
+
++ (ZXQRCodeECBlocks *)ecBlocksWithEcCodewordsPerBlock:(int)ecCodewordsPerBlock ecBlocks:(ZXQRCodeECB *)ecBlocks {
+ return [[ZXQRCodeECBlocks alloc] initWithEcCodewordsPerBlock:ecCodewordsPerBlock ecBlocks:ecBlocks];
+}
+
++ (ZXQRCodeECBlocks *)ecBlocksWithEcCodewordsPerBlock:(int)ecCodewordsPerBlock ecBlocks1:(ZXQRCodeECB *)ecBlocks1 ecBlocks2:(ZXQRCodeECB *)ecBlocks2 {
+ return [[ZXQRCodeECBlocks alloc] initWithEcCodewordsPerBlock:ecCodewordsPerBlock ecBlocks1:ecBlocks1 ecBlocks2:ecBlocks2];
+}
+
+- (int)numBlocks {
+ int total = 0;
+
+ for (ZXQRCodeECB *ecb in self.ecBlocks) {
+ total += [ecb count];
+ }
+
+ return total;
+}
+
+- (int)totalECCodewords {
+ return self.ecCodewordsPerBlock * [self numBlocks];
+}
+
+@end
+
+@implementation ZXQRCodeECB
+
+- (id)initWithCount:(int)count dataCodewords:(int)dataCodewords {
+ if (self = [super init]) {
+ _count = count;
+ _dataCodewords = dataCodewords;
+ }
+
+ return self;
+}
+
++ (ZXQRCodeECB *)ecbWithCount:(int)count dataCodewords:(int)dataCodewords {
+ return [[ZXQRCodeECB alloc] initWithCount:count dataCodewords:dataCodewords];
+}
+
+@end
+
+
+/**
+ * See ISO 18004:2006 Annex D.
+ * Element i represents the raw version bits that specify version i + 7
+ */
+
+int const VERSION_DECODE_INFO_LEN = 34;
+int const VERSION_DECODE_INFO[VERSION_DECODE_INFO_LEN] = {
+ 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,
+ 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,
+ 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,
+ 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,
+ 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,
+ 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,
+ 0x2542E, 0x26A64, 0x27541, 0x28C69
+};
+
+static NSArray *VERSIONS = nil;
+
+@implementation ZXQRCodeVersion
+
+- (id)initWithVersionNumber:(int)versionNumber alignmentPatternCenters:(NSArray *)alignmentPatternCenters ecBlocks1:(ZXQRCodeECBlocks *)ecBlocks1 ecBlocks2:(ZXQRCodeECBlocks *)ecBlocks2 ecBlocks3:(ZXQRCodeECBlocks *)ecBlocks3 ecBlocks4:(ZXQRCodeECBlocks *)ecBlocks4 {
+ if (self = [super init]) {
+ _versionNumber = versionNumber;
+ _alignmentPatternCenters = alignmentPatternCenters;
+ _ecBlocks = @[ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4];
+ int total = 0;
+ int ecCodewords = ecBlocks1.ecCodewordsPerBlock;
+
+ for (ZXQRCodeECB *ecBlock in ecBlocks1.ecBlocks) {
+ total += ecBlock.count * (ecBlock.dataCodewords + ecCodewords);
+ }
+
+ _totalCodewords = total;
+ }
+
+ return self;
+}
+
++ (ZXQRCodeVersion *)ZXQRCodeVersionWithVersionNumber:(int)aVersionNumber alignmentPatternCenters:(NSArray *)anAlignmentPatternCenters ecBlocks1:(ZXQRCodeECBlocks *)ecBlocks1 ecBlocks2:(ZXQRCodeECBlocks *)ecBlocks2 ecBlocks3:(ZXQRCodeECBlocks *)ecBlocks3 ecBlocks4:(ZXQRCodeECBlocks *)ecBlocks4 {
+ return [[ZXQRCodeVersion alloc] initWithVersionNumber:aVersionNumber alignmentPatternCenters:anAlignmentPatternCenters ecBlocks1:ecBlocks1 ecBlocks2:ecBlocks2 ecBlocks3:ecBlocks3 ecBlocks4:ecBlocks4];
+}
+
+- (int)dimensionForVersion {
+ return 17 + 4 * self.versionNumber;
+}
+
+- (ZXQRCodeECBlocks *)ecBlocksForLevel:(ZXErrorCorrectionLevel *)ecLevel {
+ return self.ecBlocks[[ecLevel ordinal]];
+}
+
+/**
+ * Deduces version information purely from QR Code dimensions.
+ */
++ (ZXQRCodeVersion *)provisionalVersionForDimension:(int)dimension {
+ if (dimension % 4 != 1) {
+ return nil;
+ }
+
+ return [self versionForNumber:(dimension - 17) >> 2];
+}
+
++ (ZXQRCodeVersion *)versionForNumber:(int)versionNumber {
+ if (versionNumber < 1 || versionNumber > 40) {
+ return nil;
+ }
+ return VERSIONS[versionNumber - 1];
+}
+
++ (ZXQRCodeVersion *)decodeVersionInformation:(int)versionBits {
+ int bestDifference = INT_MAX;
+ int bestVersion = 0;
+
+ for (int i = 0; i < VERSION_DECODE_INFO_LEN; i++) {
+ int targetVersion = VERSION_DECODE_INFO[i];
+ if (targetVersion == versionBits) {
+ return [self versionForNumber:i + 7];
+ }
+ int bitsDifference = [ZXFormatInformation numBitsDiffering:versionBits b:targetVersion];
+ if (bitsDifference < bestDifference) {
+ bestVersion = i + 7;
+ bestDifference = bitsDifference;
+ }
+ }
+
+ if (bestDifference <= 3) {
+ return [self versionForNumber:bestVersion];
+ }
+ return nil;
+}
+
+/**
+ * See ISO 18004:2006 Annex E
+ */
+- (ZXBitMatrix *)buildFunctionPattern {
+ int dimension = [self dimensionForVersion];
+ ZXBitMatrix *bitMatrix = [[ZXBitMatrix alloc] initWithDimension:dimension];
+ [bitMatrix setRegionAtLeft:0 top:0 width:9 height:9];
+ [bitMatrix setRegionAtLeft:dimension - 8 top:0 width:8 height:9];
+ [bitMatrix setRegionAtLeft:0 top:dimension - 8 width:9 height:8];
+ int max = (int)self.alignmentPatternCenters.count;
+
+ for (int x = 0; x < max; x++) {
+ int i = [(self.alignmentPatternCenters)[x] intValue] - 2;
+
+ for (int y = 0; y < max; y++) {
+ if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {
+ continue;
+ }
+ [bitMatrix setRegionAtLeft:[(self.alignmentPatternCenters)[y] intValue] - 2 top:i width:5 height:5];
+ }
+ }
+
+ [bitMatrix setRegionAtLeft:6 top:9 width:1 height:dimension - 17];
+ [bitMatrix setRegionAtLeft:9 top:6 width:dimension - 17 height:1];
+ if (self.versionNumber > 6) {
+ [bitMatrix setRegionAtLeft:dimension - 11 top:0 width:3 height:6];
+ [bitMatrix setRegionAtLeft:0 top:dimension - 11 width:6 height:3];
+ }
+ return bitMatrix;
+}
+
+- (NSString *)description {
+ return [@(self.versionNumber) stringValue];
+}
+
+/**
+ * See ISO 18004:2006 6.5.1 Table 9
+ */
++ (void)initialize {
+ VERSIONS = @[[ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:1
+ alignmentPatternCenters:@[]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:7 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:19]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:10 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:16]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:13 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:13]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:17 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:9]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:2
+ alignmentPatternCenters:@[@6, @18]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:10 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:34]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:16 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:28]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:22]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:3
+ alignmentPatternCenters:@[@6, @22]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:15 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:55]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:44]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:18 ecBlocks:[ZXQRCodeECB ecbWithCount:2 dataCodewords:17]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks:[ZXQRCodeECB ecbWithCount:2 dataCodewords:13]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:4
+ alignmentPatternCenters:@[@6, @26]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:20 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:80]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:18 ecBlocks:[ZXQRCodeECB ecbWithCount:2 dataCodewords:32]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks:[ZXQRCodeECB ecbWithCount:2 dataCodewords:24]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:16 ecBlocks:[ZXQRCodeECB ecbWithCount:4 dataCodewords:9]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:5
+ alignmentPatternCenters:@[@6, @30]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks:[ZXQRCodeECB ecbWithCount:1 dataCodewords:108]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks:[ZXQRCodeECB ecbWithCount:2 dataCodewords:43]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:18 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:16]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:11] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:12]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:6
+ alignmentPatternCenters:@[@6, @34]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:18 ecBlocks:[ZXQRCodeECB ecbWithCount:2 dataCodewords:68]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:16 ecBlocks:[ZXQRCodeECB ecbWithCount:4 dataCodewords:27]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks:[ZXQRCodeECB ecbWithCount:4 dataCodewords:19]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks:[ZXQRCodeECB ecbWithCount:4 dataCodewords:15]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:7
+ alignmentPatternCenters:@[@6, @22, @38]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:20 ecBlocks:[ZXQRCodeECB ecbWithCount:2 dataCodewords:78]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:18 ecBlocks:[ZXQRCodeECB ecbWithCount:4 dataCodewords:31]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:18 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:14] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:15]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:13] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:14]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:8
+ alignmentPatternCenters:@[@6, @24, @42]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks:[ZXQRCodeECB ecbWithCount:2 dataCodewords:97]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:38] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:39]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:18] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:19]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:14] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:15]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:9
+ alignmentPatternCenters:@[@6, @26, @46]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks:[ZXQRCodeECB ecbWithCount:2 dataCodewords:116]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:36] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:37]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:20 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:16] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:17]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:12] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:13]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:10
+ alignmentPatternCenters:@[@6, @28, @50]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:18 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:68] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:69]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:43] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:44]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:6 dataCodewords:19] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:20]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:6 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:11
+ alignmentPatternCenters:@[@6, @30, @54]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:20 ecBlocks:[ZXQRCodeECB ecbWithCount:4 dataCodewords:81]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:1 dataCodewords:50] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:51]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:22] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:23]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:12] ecBlocks2:[ZXQRCodeECB ecbWithCount:8 dataCodewords:13]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:12
+ alignmentPatternCenters:@[@6, @32, @58]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:92] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:93]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks1:[ZXQRCodeECB ecbWithCount:6 dataCodewords:36] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:37]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:20] ecBlocks2:[ZXQRCodeECB ecbWithCount:6 dataCodewords:21]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:7 dataCodewords:14] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:15]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:13
+ alignmentPatternCenters:@[@6, @34, @62]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks:[ZXQRCodeECB ecbWithCount:4 dataCodewords:107]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks1:[ZXQRCodeECB ecbWithCount:8 dataCodewords:37] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:38]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:8 dataCodewords:20] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:21]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks1:[ZXQRCodeECB ecbWithCount:12 dataCodewords:11] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:12]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:14
+ alignmentPatternCenters:@[@6, @26, @46, @66]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:115] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:116]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:40] ecBlocks2:[ZXQRCodeECB ecbWithCount:5 dataCodewords:41]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:20 ecBlocks1:[ZXQRCodeECB ecbWithCount:11 dataCodewords:16] ecBlocks2:[ZXQRCodeECB ecbWithCount:5 dataCodewords:17]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:11 dataCodewords:12] ecBlocks2:[ZXQRCodeECB ecbWithCount:5 dataCodewords:13]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:15
+ alignmentPatternCenters:@[@6, @26, @48, @70]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:22 ecBlocks1:[ZXQRCodeECB ecbWithCount:5 dataCodewords:87] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:88]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:5 dataCodewords:41] ecBlocks2:[ZXQRCodeECB ecbWithCount:5 dataCodewords:42]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:5 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:7 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:11 dataCodewords:12] ecBlocks2:[ZXQRCodeECB ecbWithCount:7 dataCodewords:13]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:16
+ alignmentPatternCenters:@[@6, @26, @50, @74]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:5 dataCodewords:98] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:99]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:7 dataCodewords:45] ecBlocks2:[ZXQRCodeECB ecbWithCount:3 dataCodewords:46]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks1:[ZXQRCodeECB ecbWithCount:15 dataCodewords:19] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:20]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:13 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:17
+ alignmentPatternCenters:@[@6, @30, @54, @78]
+ 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]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:14] ecBlocks2:[ZXQRCodeECB ecbWithCount:17 dataCodewords:15]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:18
+ alignmentPatternCenters:@[@6, @30, @56, @82]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:5 dataCodewords:120] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:121]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:9 dataCodewords:43] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:44]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:17 dataCodewords:22] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:23]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:14] ecBlocks2:[ZXQRCodeECB ecbWithCount:19 dataCodewords:15]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:19
+ alignmentPatternCenters:@[@6, @30, @58, @86]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:113] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:114]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:44] ecBlocks2:[ZXQRCodeECB ecbWithCount:11 dataCodewords:45]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:17 dataCodewords:21] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:22]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:9 dataCodewords:13] ecBlocks2:[ZXQRCodeECB ecbWithCount:16 dataCodewords:14]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:20
+ alignmentPatternCenters:@[@6, @34, @62, @90]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:107] ecBlocks2:[ZXQRCodeECB ecbWithCount:5 dataCodewords:108]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:41] ecBlocks2:[ZXQRCodeECB ecbWithCount:13 dataCodewords:42]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:15 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:5 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:15 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:10 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:21
+ alignmentPatternCenters:@[@6, @28, @50, @72, @94]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:116] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:117]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks:[ZXQRCodeECB ecbWithCount:17 dataCodewords:42]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:17 dataCodewords:22] ecBlocks2:[ZXQRCodeECB ecbWithCount:6 dataCodewords:23]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:19 dataCodewords:16] ecBlocks2:[ZXQRCodeECB ecbWithCount:6 dataCodewords:17]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:22
+ alignmentPatternCenters:@[@6, @26, @50, @74, @98]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:111] ecBlocks2:[ZXQRCodeECB ecbWithCount:7 dataCodewords:112]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks:[ZXQRCodeECB ecbWithCount:17 dataCodewords:46]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:7 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:16 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:24 ecBlocks:[ZXQRCodeECB ecbWithCount:34 dataCodewords:13]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:23
+ alignmentPatternCenters:@[@6, @30, @54, @78, @102]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:121] ecBlocks2:[ZXQRCodeECB ecbWithCount:5 dataCodewords:122]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:47] ecBlocks2:[ZXQRCodeECB ecbWithCount:14 dataCodewords:48]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:11 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:14 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:16 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:14 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:24
+ alignmentPatternCenters:@[@6, @28, @54, @80, @106]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:6 dataCodewords:117] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:118]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:6 dataCodewords:45] ecBlocks2:[ZXQRCodeECB ecbWithCount:14 dataCodewords:46]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:11 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:16 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:30 dataCodewords:16] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:17]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:25
+ alignmentPatternCenters:@[@6, @32, @58, @84, @110]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:26 ecBlocks1:[ZXQRCodeECB ecbWithCount:8 dataCodewords:106] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:107]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:8 dataCodewords:47] ecBlocks2:[ZXQRCodeECB ecbWithCount:13 dataCodewords:48]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:7 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:22 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:22 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:13 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:26
+ alignmentPatternCenters:@[@6, @30, @58, @86, @114]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:10 dataCodewords:114] ecBlocks2:[ZXQRCodeECB ecbWithCount:2 dataCodewords:115]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:19 dataCodewords:46] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:47]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:28 dataCodewords:22] ecBlocks2:[ZXQRCodeECB ecbWithCount:6 dataCodewords:23]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:33 dataCodewords:16] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:17]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:27
+ alignmentPatternCenters:@[@6, @34, @62, @90, @118]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:8 dataCodewords:122] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:123]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:22 dataCodewords:45] ecBlocks2:[ZXQRCodeECB ecbWithCount:3 dataCodewords:46]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:8 dataCodewords:23] ecBlocks2:[ZXQRCodeECB ecbWithCount:26 dataCodewords:24]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:12 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:28 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:28
+ alignmentPatternCenters:@[@6, @26, @50, @74, @98, @122]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:117] ecBlocks2:[ZXQRCodeECB ecbWithCount:10 dataCodewords:118]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:3 dataCodewords:45] ecBlocks2:[ZXQRCodeECB ecbWithCount:23 dataCodewords:46]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:31 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:11 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:31 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:29
+ alignmentPatternCenters:@[@6, @30, @54, @78, @102, @126]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:7 dataCodewords:116] ecBlocks2:[ZXQRCodeECB ecbWithCount:7 dataCodewords:117]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:21 dataCodewords:45] ecBlocks2:[ZXQRCodeECB ecbWithCount:7 dataCodewords:46]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:1 dataCodewords:23] ecBlocks2:[ZXQRCodeECB ecbWithCount:37 dataCodewords:24]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:19 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:26 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:30
+ alignmentPatternCenters:@[@6, @26, @52, @78, @104, @130]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:5 dataCodewords:115] ecBlocks2:[ZXQRCodeECB ecbWithCount:10 dataCodewords:116]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:19 dataCodewords:47] ecBlocks2:[ZXQRCodeECB ecbWithCount:10 dataCodewords:48]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:15 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:25 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:23 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:25 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:31
+ alignmentPatternCenters:@[@6, @30, @56, @82, @108, @134]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:13 dataCodewords:115] ecBlocks2:[ZXQRCodeECB ecbWithCount:3 dataCodewords:116]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:46] ecBlocks2:[ZXQRCodeECB ecbWithCount:29 dataCodewords:47]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:42 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:23 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:28 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:32
+ alignmentPatternCenters:@[@6, @34, @60, @86, @112, @138]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks:[ZXQRCodeECB ecbWithCount:17 dataCodewords:115]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:10 dataCodewords:46] ecBlocks2:[ZXQRCodeECB ecbWithCount:23 dataCodewords:47]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:10 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:35 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:19 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:35 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:33
+ alignmentPatternCenters:@[@6, @30, @58, @86, @114, @142]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:17 dataCodewords:115] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:116]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:14 dataCodewords:46] ecBlocks2:[ZXQRCodeECB ecbWithCount:21 dataCodewords:47]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:29 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:19 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:11 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:46 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:34
+ alignmentPatternCenters:@[@6, @34, @62, @90, @118, @146]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:13 dataCodewords:115] ecBlocks2:[ZXQRCodeECB ecbWithCount:6 dataCodewords:116]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:14 dataCodewords:46] ecBlocks2:[ZXQRCodeECB ecbWithCount:23 dataCodewords:47]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:44 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:7 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:59 dataCodewords:16] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:17]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:35
+ alignmentPatternCenters:@[@6, @30, @54, @78, @102, @126, @150]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:12 dataCodewords:121] ecBlocks2:[ZXQRCodeECB ecbWithCount:7 dataCodewords:122]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:12 dataCodewords:47] ecBlocks2:[ZXQRCodeECB ecbWithCount:26 dataCodewords:48]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:39 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:14 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:22 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:41 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:36
+ alignmentPatternCenters:@[@6, @24, @50, @76, @102, @128, @154]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:6 dataCodewords:121] ecBlocks2:[ZXQRCodeECB ecbWithCount:14 dataCodewords:122]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:6 dataCodewords:47] ecBlocks2:[ZXQRCodeECB ecbWithCount:34 dataCodewords:48]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:46 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:10 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:64 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:37
+ alignmentPatternCenters:@[@6, @28, @54, @80, @106, @132, @158]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:17 dataCodewords:122] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:123]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:29 dataCodewords:46] ecBlocks2:[ZXQRCodeECB ecbWithCount:14 dataCodewords:47]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:49 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:10 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:24 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:46 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:38
+ alignmentPatternCenters:@[@6, @32, @58, @84, @110, @136, @162]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:4 dataCodewords:122] ecBlocks2:[ZXQRCodeECB ecbWithCount:18 dataCodewords:123]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:13 dataCodewords:46] ecBlocks2:[ZXQRCodeECB ecbWithCount:32 dataCodewords:47]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:48 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:14 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:42 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:32 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:39
+ alignmentPatternCenters:@[@6, @26, @54, @82, @110, @138, @166]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:20 dataCodewords:117] ecBlocks2:[ZXQRCodeECB ecbWithCount:4 dataCodewords:118]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:40 dataCodewords:47] ecBlocks2:[ZXQRCodeECB ecbWithCount:7 dataCodewords:48]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:43 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:22 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:10 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:67 dataCodewords:16]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:40
+ alignmentPatternCenters:@[@6, @30, @58, @86, @114, @142, @170]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:19 dataCodewords:118] ecBlocks2:[ZXQRCodeECB ecbWithCount:6 dataCodewords:119]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:18 dataCodewords:47] ecBlocks2:[ZXQRCodeECB ecbWithCount:31 dataCodewords:48]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:34 dataCodewords:24] ecBlocks2:[ZXQRCodeECB ecbWithCount:34 dataCodewords:25]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:30 ecBlocks1:[ZXQRCodeECB ecbWithCount:20 dataCodewords:15] ecBlocks2:[ZXQRCodeECB ecbWithCount:61 dataCodewords:16]]]];
+}
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXAlignmentPattern.h b/ZXingObjC/qrcode/detector/ZXAlignmentPattern.h
new file mode 100644
index 0000000..25aa26c
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXAlignmentPattern.h
@@ -0,0 +1,30 @@
+/*
+ * 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 "ZXResultPoint.h"
+
+/**
+ * Encapsulates an alignment pattern, which are the smaller square patterns found in
+ * all but the simplest QR Codes.
+ */
+
+@interface ZXAlignmentPattern : ZXResultPoint
+
+- (id)initWithPosX:(float)posX posY:(float)posY estimatedModuleSize:(float)estimatedModuleSize;
+- (BOOL)aboutEquals:(float)moduleSize i:(float)i j:(float)j;
+- (ZXAlignmentPattern *)combineEstimateI:(float)i j:(float)j newModuleSize:(float)newModuleSize;
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXAlignmentPattern.m b/ZXingObjC/qrcode/detector/ZXAlignmentPattern.m
new file mode 100644
index 0000000..2663a00
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXAlignmentPattern.m
@@ -0,0 +1,59 @@
+/*
+ * 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 "ZXAlignmentPattern.h"
+
+@interface ZXAlignmentPattern ()
+
+@property (nonatomic, assign) float estimatedModuleSize;
+
+@end
+
+@implementation ZXAlignmentPattern
+
+- (id)initWithPosX:(float)posX posY:(float)posY estimatedModuleSize:(float)estimatedModuleSize {
+ if (self = [super initWithX:posX y:posY]) {
+ _estimatedModuleSize = estimatedModuleSize;
+ }
+
+ return self;
+}
+
+/**
+ * Determines if this alignment pattern "about equals" an alignment pattern at the stated
+ * position and size -- meaning, it is at nearly the same center with nearly the same size.
+ */
+- (BOOL)aboutEquals:(float)moduleSize i:(float)i j:(float)j {
+ if (fabsf(i - self.y) <= moduleSize && fabsf(j - self.x) <= moduleSize) {
+ float moduleSizeDiff = fabsf(moduleSize - self.estimatedModuleSize);
+ return moduleSizeDiff <= 1.0f || moduleSizeDiff <= self.estimatedModuleSize;
+ }
+
+ return NO;
+}
+
+/**
+ * Combines this object's current estimate of a finder pattern position and module size
+ * with a new estimate. It returns a new FinderPattern containing an average of the two.
+ */
+- (ZXAlignmentPattern *)combineEstimateI:(float)i j:(float)j newModuleSize:(float)newModuleSize {
+ float combinedX = (self.x + j) / 2.0f;
+ float combinedY = (self.y + i) / 2.0f;
+ float combinedModuleSize = (self.estimatedModuleSize + newModuleSize) / 2.0f;
+ return [[ZXAlignmentPattern alloc] initWithPosX:combinedX posY:combinedY estimatedModuleSize:combinedModuleSize];
+}
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXAlignmentPatternFinder.h b/ZXingObjC/qrcode/detector/ZXAlignmentPatternFinder.h
new file mode 100644
index 0000000..c601596
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXAlignmentPatternFinder.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * This class attempts to find alignment patterns in a QR Code. Alignment patterns look like finder
+ * patterns but are smaller and appear at regular intervals throughout the image.
+ *
+ * At the moment this only looks for the bottom-right alignment pattern.
+ *
+ * This is mostly a simplified copy of {@link FinderPatternFinder}. It is copied,
+ * pasted and stripped down here for maximum performance but does unfortunately duplicate
+ * some code.
+ *
+ * This class is thread-safe but not reentrant. Each thread must allocate its own object.
+ */
+
+@class ZXAlignmentPattern, ZXBitMatrix;
+@protocol ZXResultPointCallback;
+
+@interface ZXAlignmentPatternFinder : NSObject
+
+- (id)initWithImage:(ZXBitMatrix *)image startX:(int)startX startY:(int)startY width:(int)width height:(int)height moduleSize:(float)moduleSize resultPointCallback:(id<ZXResultPointCallback>)resultPointCallback;
+- (ZXAlignmentPattern *)findWithError:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXAlignmentPatternFinder.m b/ZXingObjC/qrcode/detector/ZXAlignmentPatternFinder.m
new file mode 100644
index 0000000..5681ea4
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXAlignmentPatternFinder.m
@@ -0,0 +1,236 @@
+/*
+ * 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 "ZXAlignmentPattern.h"
+#import "ZXAlignmentPatternFinder.h"
+#import "ZXBitMatrix.h"
+#import "ZXErrors.h"
+#import "ZXResultPointCallback.h"
+
+@interface ZXAlignmentPatternFinder ()
+
+@property (nonatomic, strong) ZXBitMatrix *image;
+@property (nonatomic, strong) NSMutableArray *possibleCenters;
+@property (nonatomic, assign) int startX;
+@property (nonatomic, assign) int startY;
+@property (nonatomic, assign) int width;
+@property (nonatomic, assign) int height;
+@property (nonatomic, assign) float moduleSize;
+@property (nonatomic, assign) int *crossCheckStateCount;
+@property (nonatomic, weak) id <ZXResultPointCallback> resultPointCallback;
+
+@end
+
+@implementation ZXAlignmentPatternFinder
+
+/**
+ * Creates a finder that will look in a portion of the whole image.
+ */
+- (id)initWithImage:(ZXBitMatrix *)image startX:(int)startX startY:(int)startY width:(int)width height:(int)height moduleSize:(float)moduleSize resultPointCallback:(id<ZXResultPointCallback>)resultPointCallback {
+ if (self = [super init]) {
+ _image = image;
+ _possibleCenters = [NSMutableArray arrayWithCapacity:5];
+ _startX = startX;
+ _startY = startY;
+ _width = width;
+ _height = height;
+ _moduleSize = moduleSize;
+ _crossCheckStateCount = (int *)malloc(3 * sizeof(int));
+ memset(_crossCheckStateCount, 0, 3 * sizeof(int));
+ _resultPointCallback = resultPointCallback;
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_crossCheckStateCount != NULL) {
+ free(_crossCheckStateCount);
+ _crossCheckStateCount = NULL;
+ }
+}
+
+/**
+ * This method attempts to find the bottom-right alignment pattern in the image. It is a bit messy since
+ * it's pretty performance-critical and so is written to be fast foremost.
+ */
+- (ZXAlignmentPattern *)findWithError:(NSError **)error {
+ int maxJ = self.startX + self.width;
+ int middleI = self.startY + (self.height >> 1);
+ int stateCount[3];
+
+ for (int iGen = 0; iGen < self.height; iGen++) {
+ int i = middleI + ((iGen & 0x01) == 0 ? (iGen + 1) >> 1 : -((iGen + 1) >> 1));
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ int j = self.startX;
+
+ while (j < maxJ && ![self.image getX:j y:i]) {
+ j++;
+ }
+
+ int currentState = 0;
+
+ while (j < maxJ) {
+ if ([self.image getX:j y:i]) {
+ if (currentState == 1) {
+ stateCount[currentState]++;
+ } else {
+ if (currentState == 2) {
+ if ([self foundPatternCross:stateCount]) {
+ ZXAlignmentPattern *confirmed = [self handlePossibleCenter:stateCount i:i j:j];
+ if (confirmed != nil) {
+ return confirmed;
+ }
+ }
+ stateCount[0] = stateCount[2];
+ stateCount[1] = 1;
+ stateCount[2] = 0;
+ currentState = 1;
+ } else {
+ stateCount[++currentState]++;
+ }
+ }
+ } else {
+ if (currentState == 1) {
+ currentState++;
+ }
+ stateCount[currentState]++;
+ }
+ j++;
+ }
+
+ if ([self foundPatternCross:stateCount]) {
+ ZXAlignmentPattern *confirmed = [self handlePossibleCenter:stateCount i:i j:maxJ];
+ if (confirmed != nil) {
+ return confirmed;
+ }
+ }
+ }
+
+ if ([self.possibleCenters count] > 0) {
+ return self.possibleCenters[0];
+ }
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+}
+
+/**
+ * Given a count of black/white/black pixels just seen and an end position,
+ * figures the location of the center of this black/white/black run.
+ */
+- (float)centerFromEnd:(int *)stateCount end:(int)end {
+ return (float)(end - stateCount[2]) - stateCount[1] / 2.0f;
+}
+
+- (BOOL)foundPatternCross:(int *)stateCount {
+ float maxVariance = self.moduleSize / 2.0f;
+
+ for (int i = 0; i < 3; i++) {
+ if (fabsf(self.moduleSize - stateCount[i]) >= maxVariance) {
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+/**
+ * After a horizontal scan finds a potential alignment pattern, this method
+ * "cross-checks" by scanning down vertically through the center of the possible
+ * alignment pattern to see if the same proportion is detected.
+ */
+- (float)crossCheckVertical:(int)startI centerJ:(int)centerJ maxCount:(int)maxCount originalStateCountTotal:(int)originalStateCountTotal {
+ int maxI = self.image.height;
+ int stateCount[3] = {0, 0, 0};
+ int i = startI;
+
+ while (i >= 0 && [self.image getX:centerJ y:i] && stateCount[1] <= maxCount) {
+ stateCount[1]++;
+ i--;
+ }
+
+ if (i < 0 || stateCount[1] > maxCount) {
+ return NAN;
+ }
+
+ while (i >= 0 && ![self.image getX:centerJ y:i] && stateCount[0] <= maxCount) {
+ stateCount[0]++;
+ i--;
+ }
+
+ if (stateCount[0] > maxCount) {
+ return NAN;
+ }
+ i = startI + 1;
+
+ while (i < maxI && [self.image getX:centerJ y:i] && stateCount[1] <= maxCount) {
+ stateCount[1]++;
+ i++;
+ }
+
+ if (i == maxI || stateCount[1] > maxCount) {
+ return NAN;
+ }
+
+ while (i < maxI && ![self.image getX:centerJ y:i] && stateCount[2] <= maxCount) {
+ stateCount[2]++;
+ i++;
+ }
+
+ if (stateCount[2] > maxCount) {
+ return NAN;
+ }
+ int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
+ if (5 * abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {
+ return NAN;
+ }
+ return [self foundPatternCross:stateCount] ? [self centerFromEnd:stateCount end:i] : NAN;
+}
+
+/**
+ * This is called when a horizontal scan finds a possible alignment pattern. It will
+ * cross check with a vertical scan, and if successful, will see if this pattern had been
+ * found on a previous horizontal scan. If so, we consider it confirmed and conclude we have
+ * found the alignment pattern.
+ */
+- (ZXAlignmentPattern *)handlePossibleCenter:(int *)stateCount i:(int)i j:(int)j {
+ int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
+ float centerJ = [self centerFromEnd:stateCount end:j];
+ float centerI = [self crossCheckVertical:i centerJ:(int)centerJ maxCount:2 * stateCount[1] originalStateCountTotal:stateCountTotal];
+ if (!isnan(centerI)) {
+ float estimatedModuleSize = (float)(stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f;
+ int max = (int)self.possibleCenters.count;
+
+ for (int index = 0; index < max; index++) {
+ ZXAlignmentPattern *center = self.possibleCenters[index];
+ // Look for about the same center and module size:
+ if ([center aboutEquals:estimatedModuleSize i:centerI j:centerJ]) {
+ return [center combineEstimateI:centerI j:centerJ newModuleSize:estimatedModuleSize];
+ }
+ }
+ // Hadn't found this before; save it
+ ZXResultPoint *point = [[ZXAlignmentPattern alloc] initWithPosX:centerJ posY:centerI estimatedModuleSize:estimatedModuleSize];
+ [self.possibleCenters addObject:point];
+ if (self.resultPointCallback != nil) {
+ [self.resultPointCallback foundPossibleResultPoint:point];
+ }
+ }
+ return nil;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXFinderPatternFinder.h b/ZXingObjC/qrcode/detector/ZXFinderPatternFinder.h
new file mode 100644
index 0000000..bb28083
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXFinderPatternFinder.h
@@ -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.
+ */
+
+/**
+ * This class attempts to find finder patterns in a QR Code. Finder patterns are the square
+ * markers at three corners of a QR Code.
+ *
+ * This class is thread-safe but not reentrant. Each thread must allocate its own object.
+ */
+
+extern int const FINDER_PATTERN_MIN_SKIP;
+extern int const FINDER_PATTERN_MAX_MODULES;
+
+@class ZXBitMatrix, ZXDecodeHints, ZXFinderPatternInfo;
+@protocol ZXResultPointCallback;
+
+@interface ZXFinderPatternFinder : NSObject
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *image;
+@property (nonatomic, strong, readonly) NSMutableArray *possibleCenters;
+
+- (id)initWithImage:(ZXBitMatrix *)image;
+- (id)initWithImage:(ZXBitMatrix *)image resultPointCallback:(id<ZXResultPointCallback>)resultPointCallback;
+- (ZXFinderPatternInfo *)find:(ZXDecodeHints *)hints error:(NSError **)error;
++ (BOOL)foundPatternCross:(int[])stateCount;
+- (BOOL)handlePossibleCenter:(int[])stateCount i:(int)i j:(int)j;
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXFinderPatternFinder.m b/ZXingObjC/qrcode/detector/ZXFinderPatternFinder.m
new file mode 100644
index 0000000..d182aca
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXFinderPatternFinder.m
@@ -0,0 +1,484 @@
+/*
+ * 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 "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXFinderPatternFinder.h"
+#import "ZXFinderPatternInfo.h"
+#import "ZXOneDReader.h"
+#import "ZXQRCodeFinderPattern.h"
+#import "ZXResultPoint.h"
+#import "ZXResultPointCallback.h"
+
+int const CENTER_QUORUM = 2;
+int const FINDER_PATTERN_MIN_SKIP = 3;
+int const FINDER_PATTERN_MAX_MODULES = 57;
+
+@interface ZXFinderPatternFinder ()
+
+NSInteger centerCompare(id center1, id center2, void *context);
+NSInteger furthestFromAverageCompare(id center1, id center2, void *context);
+
+@property (nonatomic, assign) BOOL hasSkipped;
+@property (nonatomic, weak) id <ZXResultPointCallback> resultPointCallback;
+@property (nonatomic, strong) NSMutableArray *possibleCenters;
+
+@end
+
+@implementation ZXFinderPatternFinder
+
+/**
+ * Creates a finder that will search the image for three finder patterns.
+ */
+- (id)initWithImage:(ZXBitMatrix *)image {
+ return [self initWithImage:image resultPointCallback:nil];
+}
+
+- (id)initWithImage:(ZXBitMatrix *)image resultPointCallback:(id<ZXResultPointCallback>)resultPointCallback {
+ if (self = [super init]) {
+ _image = image;
+ _possibleCenters = [NSMutableArray array];
+ _resultPointCallback = resultPointCallback;
+ }
+
+ return self;
+}
+
+- (ZXFinderPatternInfo *)find:(ZXDecodeHints *)hints error:(NSError **)error {
+ BOOL tryHarder = hints != nil && hints.tryHarder;
+ int maxI = self.image.height;
+ int maxJ = self.image.width;
+ int iSkip = (3 * maxI) / (4 * FINDER_PATTERN_MAX_MODULES);
+ if (iSkip < FINDER_PATTERN_MIN_SKIP || tryHarder) {
+ iSkip = FINDER_PATTERN_MIN_SKIP;
+ }
+
+ BOOL done = NO;
+ int stateCount[5];
+ for (int i = iSkip - 1; i < maxI && !done; i += iSkip) {
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ stateCount[3] = 0;
+ stateCount[4] = 0;
+ int currentState = 0;
+
+ for (int j = 0; j < maxJ; j++) {
+ if ([self.image getX:j y:i]) {
+ if ((currentState & 1) == 1) {
+ currentState++;
+ }
+ stateCount[currentState]++;
+ } else {
+ if ((currentState & 1) == 0) {
+ if (currentState == 4) {
+ if ([ZXFinderPatternFinder foundPatternCross:stateCount]) {
+ BOOL confirmed = [self handlePossibleCenter:stateCount i:i j:j];
+ if (confirmed) {
+ iSkip = 2;
+ if (self.hasSkipped) {
+ done = [self haveMultiplyConfirmedCenters];
+ } else {
+ int rowSkip = [self findRowSkip];
+ if (rowSkip > stateCount[2]) {
+ i += rowSkip - stateCount[2] - iSkip;
+ j = maxJ - 1;
+ }
+ }
+ } else {
+ stateCount[0] = stateCount[2];
+ stateCount[1] = stateCount[3];
+ stateCount[2] = stateCount[4];
+ stateCount[3] = 1;
+ stateCount[4] = 0;
+ currentState = 3;
+ continue;
+ }
+ currentState = 0;
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ stateCount[3] = 0;
+ stateCount[4] = 0;
+ } else {
+ stateCount[0] = stateCount[2];
+ stateCount[1] = stateCount[3];
+ stateCount[2] = stateCount[4];
+ stateCount[3] = 1;
+ stateCount[4] = 0;
+ currentState = 3;
+ }
+ } else {
+ stateCount[++currentState]++;
+ }
+ } else {
+ stateCount[currentState]++;
+ }
+ }
+ }
+
+ if ([ZXFinderPatternFinder foundPatternCross:stateCount]) {
+ BOOL confirmed = [self handlePossibleCenter:stateCount i:i j:maxJ];
+ if (confirmed) {
+ iSkip = stateCount[0];
+ if (self.hasSkipped) {
+ done = [self haveMultiplyConfirmedCenters];
+ }
+ }
+ }
+ }
+
+ NSMutableArray *patternInfo = [self selectBestPatterns];
+ if (!patternInfo) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ [ZXResultPoint orderBestPatterns:patternInfo];
+ return [[ZXFinderPatternInfo alloc] initWithPatternCenters:patternInfo];
+}
+
+/**
+ * Given a count of black/white/black/white/black pixels just seen and an end position,
+ * figures the location of the center of this run.
+ */
+- (float)centerFromEnd:(int *)stateCount end:(int)end {
+ return (float)(end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;
+}
+
++ (BOOL)foundPatternCross:(int[])stateCount {
+ int totalModuleSize = 0;
+
+ for (int i = 0; i < 5; i++) {
+ int count = stateCount[i];
+ if (count == 0) {
+ return NO;
+ }
+ totalModuleSize += count;
+ }
+
+ if (totalModuleSize < 7) {
+ return NO;
+ }
+ int moduleSize = (totalModuleSize << INTEGER_MATH_SHIFT) / 7;
+ int maxVariance = moduleSize / 2;
+ return abs(moduleSize - (stateCount[0] << INTEGER_MATH_SHIFT)) < maxVariance &&
+ abs(moduleSize - (stateCount[1] << INTEGER_MATH_SHIFT)) < maxVariance &&
+ abs(3 * moduleSize - (stateCount[2] << INTEGER_MATH_SHIFT)) < 3 * maxVariance &&
+ abs(moduleSize - (stateCount[3] << INTEGER_MATH_SHIFT)) < maxVariance &&
+ abs(moduleSize - (stateCount[4] << INTEGER_MATH_SHIFT)) < maxVariance;
+}
+
+/**
+ * After a horizontal scan finds a potential finder pattern, this method
+ * "cross-checks" by scanning down vertically through the center of the possible
+ * finder pattern to see if the same proportion is detected.
+ */
+- (float)crossCheckVertical:(int)startI centerJ:(int)centerJ maxCount:(int)maxCount originalStateCountTotal:(int)originalStateCountTotal {
+ int maxI = self.image.height;
+ int stateCount[5] = {0, 0, 0, 0, 0};
+
+ int i = startI;
+ while (i >= 0 && [self.image getX:centerJ y:i]) {
+ stateCount[2]++;
+ i--;
+ }
+ if (i < 0) {
+ return NAN;
+ }
+ while (i >= 0 && ![self.image getX:centerJ y:i] && stateCount[1] <= maxCount) {
+ stateCount[1]++;
+ i--;
+ }
+ if (i < 0 || stateCount[1] > maxCount) {
+ return NAN;
+ }
+ while (i >= 0 && [self.image getX:centerJ y:i] && stateCount[0] <= maxCount) {
+ stateCount[0]++;
+ i--;
+ }
+ if (stateCount[0] > maxCount) {
+ return NAN;
+ }
+
+ i = startI + 1;
+ while (i < maxI && [self.image getX:centerJ y:i]) {
+ stateCount[2]++;
+ i++;
+ }
+ if (i == maxI) {
+ return NAN;
+ }
+ while (i < maxI && ![self.image getX:centerJ y:i] && stateCount[3] < maxCount) {
+ stateCount[3]++;
+ i++;
+ }
+ if (i == maxI || stateCount[3] >= maxCount) {
+ return NAN;
+ }
+ while (i < maxI && [self.image getX:centerJ y:i] && stateCount[4] < maxCount) {
+ stateCount[4]++;
+ i++;
+ }
+ if (stateCount[4] >= maxCount) {
+ return NAN;
+ }
+
+ int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
+ if (5 * abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {
+ return NAN;
+ }
+ return [ZXFinderPatternFinder foundPatternCross:stateCount] ? [self centerFromEnd:stateCount end:i] : NAN;
+}
+
+/**
+ * Like crossCheckVertical, and in fact is basically identical,
+ * except it reads horizontally instead of vertically. This is used to cross-cross
+ * check a vertical cross check and locate the real center of the alignment pattern.
+ */
+- (float)crossCheckHorizontal:(int)startJ centerI:(int)centerI maxCount:(int)maxCount originalStateCountTotal:(int)originalStateCountTotal {
+ int maxJ = self.image.width;
+ int stateCount[5] = {0, 0, 0, 0, 0};
+
+ int j = startJ;
+ while (j >= 0 && [self.image getX:j y:centerI]) {
+ stateCount[2]++;
+ j--;
+ }
+ if (j < 0) {
+ return NAN;
+ }
+ while (j >= 0 && ![self.image getX:j y:centerI] && stateCount[1] <= maxCount) {
+ stateCount[1]++;
+ j--;
+ }
+ if (j < 0 || stateCount[1] > maxCount) {
+ return NAN;
+ }
+ while (j >= 0 && [self.image getX:j y:centerI] && stateCount[0] <= maxCount) {
+ stateCount[0]++;
+ j--;
+ }
+ if (stateCount[0] > maxCount) {
+ return NAN;
+ }
+
+ j = startJ + 1;
+ while (j < maxJ && [self.image getX:j y:centerI]) {
+ stateCount[2]++;
+ j++;
+ }
+ if (j == maxJ) {
+ return NAN;
+ }
+ while (j < maxJ && ![self.image getX:j y:centerI] && stateCount[3] < maxCount) {
+ stateCount[3]++;
+ j++;
+ }
+ if (j == maxJ || stateCount[3] >= maxCount) {
+ return NAN;
+ }
+ while (j < maxJ && [self.image getX:j y:centerI] && stateCount[4] < maxCount) {
+ stateCount[4]++;
+ j++;
+ }
+ if (stateCount[4] >= maxCount) {
+ return NAN;
+ }
+
+ int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
+ if (5 * abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
+ return NAN;
+ }
+
+ return [ZXFinderPatternFinder foundPatternCross:stateCount] ? [self centerFromEnd:stateCount end:j] : NAN;
+}
+
+
+/**
+ * This is called when a horizontal scan finds a possible alignment pattern. It will
+ * cross check with a vertical scan, and if successful, will, ah, cross-cross-check
+ * with another horizontal scan. This is needed primarily to locate the real horizontal
+ * center of the pattern in cases of extreme skew.
+ *
+ * If that succeeds the finder pattern location is added to a list that tracks
+ * the number of times each location has been nearly-matched as a finder pattern.
+ * Each additional find is more evidence that the location is in fact a finder
+ * pattern center
+ */
+- (BOOL)handlePossibleCenter:(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)) {
+ float estimatedModuleSize = (float)stateCountTotal / 7.0f;
+ BOOL found = NO;
+ int max = (int)[self.possibleCenters count];
+ for (int index = 0; index < max; index++) {
+ ZXQRCodeFinderPattern *center = self.possibleCenters[index];
+ if ([center aboutEquals:estimatedModuleSize i:centerI j:centerJ]) {
+ self.possibleCenters[index] = [center combineEstimateI:centerI j:centerJ newModuleSize:estimatedModuleSize];
+ found = YES;
+ break;
+ }
+ }
+
+ if (!found) {
+ ZXResultPoint *point = [[ZXQRCodeFinderPattern alloc] initWithPosX:centerJ posY:centerI estimatedModuleSize:estimatedModuleSize];
+ [self.possibleCenters addObject:point];
+ if (self.resultPointCallback != nil) {
+ [self.resultPointCallback foundPossibleResultPoint:point];
+ }
+ }
+ return YES;
+ }
+ }
+ return NO;
+}
+
+
+/**
+ * @return number of rows we could safely skip during scanning, based on the first
+ * two finder patterns that have been located. In some cases their position will
+ * allow us to infer that the third pattern must lie below a certain point farther
+ * down in the image.
+ */
+- (int) findRowSkip {
+ int max = (int)[self.possibleCenters count];
+ if (max <= 1) {
+ return 0;
+ }
+ ZXQRCodeFinderPattern *firstConfirmedCenter = nil;
+ for (int i = 0; i < max; i++) {
+ ZXQRCodeFinderPattern *center = self.possibleCenters[i];
+ if ([center count] >= CENTER_QUORUM) {
+ if (firstConfirmedCenter == nil) {
+ firstConfirmedCenter = center;
+ } else {
+ self.hasSkipped = YES;
+ return (int)(fabsf([firstConfirmedCenter x] - [center x]) - fabsf([firstConfirmedCenter y] - [center y])) / 2;
+ }
+ }
+ }
+ return 0;
+}
+
+
+- (BOOL)haveMultiplyConfirmedCenters {
+ int confirmedCount = 0;
+ float totalModuleSize = 0.0f;
+ int max = (int)[self.possibleCenters count];
+ for (int i = 0; i < max; i++) {
+ ZXQRCodeFinderPattern *pattern = self.possibleCenters[i];
+ if ([pattern count] >= CENTER_QUORUM) {
+ confirmedCount++;
+ totalModuleSize += [pattern estimatedModuleSize];
+ }
+ }
+ if (confirmedCount < 3) {
+ return NO;
+ }
+
+ float average = totalModuleSize / (float)max;
+ float totalDeviation = 0.0f;
+ for (int i = 0; i < max; i++) {
+ ZXQRCodeFinderPattern *pattern = self.possibleCenters[i];
+ totalDeviation += fabsf([pattern estimatedModuleSize] - average);
+ }
+ return totalDeviation <= 0.05f * totalModuleSize;
+}
+
+/**
+ * Orders by ZXFinderPattern count, descending.
+ */
+NSInteger centerCompare(id center1, id center2, void *context) {
+ float average = [(__bridge NSNumber *)context floatValue];
+
+ if ([((ZXQRCodeFinderPattern *)center2) count] == [((ZXQRCodeFinderPattern *)center1) count]) {
+ float dA = fabsf([((ZXQRCodeFinderPattern *)center2) estimatedModuleSize] - average);
+ float dB = fabsf([((ZXQRCodeFinderPattern *)center1) estimatedModuleSize] - average);
+ return dA < dB ? 1 : dA == dB ? 0 : -1;
+ } else {
+ return [((ZXQRCodeFinderPattern *)center2) count] - [((ZXQRCodeFinderPattern *)center1) count];
+ }
+}
+
+/**
+ * Orders by furthest from average
+ */
+NSInteger furthestFromAverageCompare(id center1, id center2, void *context) {
+ float average = [(__bridge NSNumber *)context floatValue];
+
+ float dA = fabsf([((ZXQRCodeFinderPattern *)center2) estimatedModuleSize] - average);
+ float dB = fabsf([((ZXQRCodeFinderPattern *)center1) estimatedModuleSize] - average);
+ return dA < dB ? -1 : dA == dB ? 0 : 1;
+}
+
+
+/**
+ * Returns the 3 best ZXFinderPatterns from our list of candidates. The "best" are
+ * those that have been detected at least CENTER_QUORUM times, and whose module
+ * size differs from the average among those patterns the least
+ */
+- (NSMutableArray *)selectBestPatterns {
+ int startSize = (int)[self.possibleCenters count];
+ if (startSize < 3) {
+ return nil;
+ }
+
+ if (startSize > 3) {
+ float totalModuleSize = 0.0f;
+ float square = 0.0f;
+ for (int i = 0; i < startSize; i++) {
+ float size = [self.possibleCenters[i] estimatedModuleSize];
+ totalModuleSize += size;
+ square += size * size;
+ }
+ float average = totalModuleSize / (float)startSize;
+ float stdDev = (float)sqrt(square / startSize - average * average);
+
+ [self.possibleCenters sortUsingFunction: furthestFromAverageCompare context: (__bridge void *)@(average)];
+
+ float limit = MAX(0.2f * average, stdDev);
+
+ for (int i = 0; i < [self.possibleCenters count] && [self.possibleCenters count] > 3; i++) {
+ ZXQRCodeFinderPattern *pattern = self.possibleCenters[i];
+ if (fabsf([pattern estimatedModuleSize] - average) > limit) {
+ [self.possibleCenters removeObjectAtIndex:i];
+ i--;
+ }
+ }
+ }
+
+ if ([self.possibleCenters count] > 3) {
+ float totalModuleSize = 0.0f;
+ for (int i = 0; i < [self.possibleCenters count]; i++) {
+ totalModuleSize += [self.possibleCenters[i] estimatedModuleSize];
+ }
+
+ float average = totalModuleSize / (float)[self.possibleCenters count];
+
+ [self.possibleCenters sortUsingFunction:centerCompare context:(__bridge void *)(@(average))];
+
+ self.possibleCenters = [[NSMutableArray alloc] initWithArray:[self.possibleCenters subarrayWithRange:NSMakeRange(0, 3)]];
+ }
+
+ return [@[self.possibleCenters[0], self.possibleCenters[1], self.possibleCenters[2]] mutableCopy];
+}
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXFinderPatternInfo.h b/ZXingObjC/qrcode/detector/ZXFinderPatternInfo.h
new file mode 100644
index 0000000..50eb71d
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXFinderPatternInfo.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates information about finder patterns in an image, including the location of
+ * the three finder patterns, and their estimated module size.
+ */
+
+@class ZXQRCodeFinderPattern;
+
+@interface ZXFinderPatternInfo : NSObject
+
+@property (nonatomic, strong, readonly) ZXQRCodeFinderPattern *bottomLeft;
+@property (nonatomic, strong, readonly) ZXQRCodeFinderPattern *topLeft;
+@property (nonatomic, strong, readonly) ZXQRCodeFinderPattern *topRight;
+
+- (id)initWithPatternCenters:(NSArray *)patternCenters;
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXFinderPatternInfo.m b/ZXingObjC/qrcode/detector/ZXFinderPatternInfo.m
new file mode 100644
index 0000000..7b08b0a
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXFinderPatternInfo.m
@@ -0,0 +1,32 @@
+/*
+ * 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 "ZXFinderPatternInfo.h"
+#import "ZXQRCodeFinderPattern.h"
+
+@implementation ZXFinderPatternInfo
+
+- (id)initWithPatternCenters:(NSArray *)patternCenters {
+ if (self = [super init]) {
+ _bottomLeft = patternCenters[0];
+ _topLeft = patternCenters[1];
+ _topRight = patternCenters[2];
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h b/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h
new file mode 100644
index 0000000..aa91176
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/**
+ * Encapsulates logic that can detect a QR Code in an image, even if the QR Code
+ * is rotated or skewed, or partially obscured.
+ */
+
+@class ZXAlignmentPattern, ZXBitMatrix, ZXDecodeHints, ZXDetectorResult, ZXFinderPatternInfo, ZXPerspectiveTransform, ZXResultPoint;
+@protocol ZXResultPointCallback;
+
+@interface ZXQRCodeDetector : NSObject
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *image;
+@property (nonatomic, weak, readonly) id <ZXResultPointCallback> resultPointCallback;
+
+- (id)initWithImage:(ZXBitMatrix *)image;
+- (ZXDetectorResult *)detectWithError:(NSError **)error;
+- (ZXDetectorResult *)detect:(ZXDecodeHints *)hints error:(NSError **)error;
+- (ZXDetectorResult *)processFinderPatternInfo:(ZXFinderPatternInfo *)info error:(NSError **)error;
++ (int)computeDimension:(ZXResultPoint *)topLeft topRight:(ZXResultPoint *)topRight bottomLeft:(ZXResultPoint *)bottomLeft moduleSize:(float)moduleSize error:(NSError **)error;
+- (float)calculateModuleSize:(ZXResultPoint *)topLeft topRight:(ZXResultPoint *)topRight bottomLeft:(ZXResultPoint *)bottomLeft;
+- (ZXAlignmentPattern *)findAlignmentInRegion:(float)overallEstModuleSize estAlignmentX:(int)estAlignmentX estAlignmentY:(int)estAlignmentY allowanceFactor:(float)allowanceFactor error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXQRCodeDetector.m b/ZXingObjC/qrcode/detector/ZXQRCodeDetector.m
new file mode 100644
index 0000000..750635b
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXQRCodeDetector.m
@@ -0,0 +1,329 @@
+/*
+ * 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 "ZXAlignmentPattern.h"
+#import "ZXAlignmentPatternFinder.h"
+#import "ZXBitMatrix.h"
+#import "ZXDecodeHints.h"
+#import "ZXDetectorResult.h"
+#import "ZXErrors.h"
+#import "ZXFinderPatternFinder.h"
+#import "ZXFinderPatternInfo.h"
+#import "ZXGridSampler.h"
+#import "ZXMathUtils.h"
+#import "ZXPerspectiveTransform.h"
+#import "ZXQRCodeDetector.h"
+#import "ZXQRCodeFinderPattern.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXResultPoint.h"
+#import "ZXResultPointCallback.h"
+
+@interface ZXQRCodeDetector ()
+
+@property (nonatomic, weak) id <ZXResultPointCallback> resultPointCallback;
+
+@end
+
+@implementation ZXQRCodeDetector
+
+- (id)initWithImage:(ZXBitMatrix *)image {
+ if (self = [super init]) {
+ _image = image;
+ }
+
+ return self;
+}
+
+/**
+ * Detects a QR Code in an image, simply.
+ */
+- (ZXDetectorResult *)detectWithError:(NSError **)error {
+ return [self detect:nil error:error];
+}
+
+/**
+ * Detects a QR Code in an image, simply.
+ */
+- (ZXDetectorResult *)detect:(ZXDecodeHints *)hints error:(NSError **)error {
+ self.resultPointCallback = hints == nil ? nil : hints.resultPointCallback;
+
+ ZXFinderPatternFinder *finder = [[ZXFinderPatternFinder alloc] initWithImage:self.image resultPointCallback:self.resultPointCallback];
+ ZXFinderPatternInfo *info = [finder find:hints error:error];
+ if (!info) {
+ return nil;
+ }
+
+ return [self processFinderPatternInfo:info error:error];
+}
+
+- (ZXDetectorResult *)processFinderPatternInfo:(ZXFinderPatternInfo *)info error:(NSError **)error {
+ ZXQRCodeFinderPattern *topLeft = info.topLeft;
+ ZXQRCodeFinderPattern *topRight = info.topRight;
+ ZXQRCodeFinderPattern *bottomLeft = info.bottomLeft;
+
+ float moduleSize = [self calculateModuleSize:topLeft topRight:topRight bottomLeft:bottomLeft];
+ if (moduleSize < 1.0f) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+ int dimension = [ZXQRCodeDetector computeDimension:topLeft topRight:topRight bottomLeft:bottomLeft moduleSize:moduleSize error:error];
+ if (dimension == -1) {
+ return nil;
+ }
+
+ ZXQRCodeVersion *provisionalVersion = [ZXQRCodeVersion provisionalVersionForDimension:dimension];
+ if (!provisionalVersion) {
+ if (error) *error = FormatErrorInstance();
+ return nil;
+ }
+ int modulesBetweenFPCenters = [provisionalVersion dimensionForVersion] - 7;
+
+ ZXAlignmentPattern *alignmentPattern = nil;
+ if ([[provisionalVersion alignmentPatternCenters] count] > 0) {
+ float bottomRightX = [topRight x] - [topLeft x] + [bottomLeft x];
+ float bottomRightY = [topRight y] - [topLeft y] + [bottomLeft y];
+
+ float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters;
+ int estAlignmentX = (int)([topLeft x] + correctionToTopLeft * (bottomRightX - [topLeft x]));
+ int estAlignmentY = (int)([topLeft y] + correctionToTopLeft * (bottomRightY - [topLeft y]));
+
+ for (int i = 4; i <= 16; i <<= 1) {
+ NSError *alignmentError = nil;
+ alignmentPattern = [self findAlignmentInRegion:moduleSize estAlignmentX:estAlignmentX estAlignmentY:estAlignmentY allowanceFactor:(float)i error:&alignmentError];
+ if (alignmentPattern) {
+ break;
+ } else if (alignmentError.code != ZXNotFoundError) {
+ if (error) *error = alignmentError;
+ return nil;
+ }
+ }
+ }
+
+ ZXPerspectiveTransform *transform = [ZXQRCodeDetector createTransform:topLeft topRight:topRight bottomLeft:bottomLeft alignmentPattern:alignmentPattern dimension:dimension];
+ ZXBitMatrix *bits = [self sampleGrid:self.image transform:transform dimension:dimension error:error];
+ if (!bits) {
+ return nil;
+ }
+ NSArray *points;
+ if (alignmentPattern == nil) {
+ points = @[bottomLeft, topLeft, topRight];
+ } else {
+ points = @[bottomLeft, topLeft, topRight, alignmentPattern];
+ }
+ return [[ZXDetectorResult alloc] initWithBits:bits points:points];
+}
+
++ (ZXPerspectiveTransform *)createTransform:(ZXResultPoint *)topLeft topRight:(ZXResultPoint *)topRight bottomLeft:(ZXResultPoint *)bottomLeft alignmentPattern:(ZXResultPoint *)alignmentPattern dimension:(int)dimension {
+ float dimMinusThree = (float)dimension - 3.5f;
+ float bottomRightX;
+ float bottomRightY;
+ float sourceBottomRightX;
+ float sourceBottomRightY;
+ if (alignmentPattern != nil) {
+ bottomRightX = alignmentPattern.x;
+ bottomRightY = alignmentPattern.y;
+ sourceBottomRightX = dimMinusThree - 3.0f;
+ sourceBottomRightY = sourceBottomRightX;
+ } else {
+ bottomRightX = (topRight.x - topLeft.x) + bottomLeft.x;
+ bottomRightY = (topRight.y - topLeft.y) + bottomLeft.y;
+ sourceBottomRightX = dimMinusThree;
+ sourceBottomRightY = dimMinusThree;
+ }
+ return [ZXPerspectiveTransform quadrilateralToQuadrilateral:3.5f y0:3.5f
+ x1:dimMinusThree y1:3.5f
+ x2:sourceBottomRightX y2:sourceBottomRightY
+ x3:3.5f y3:dimMinusThree
+ x0p:topLeft.x y0p:topLeft.y
+ x1p:topRight.x y1p:topRight.y
+ x2p:bottomRightX y2p:bottomRightY
+ x3p:bottomLeft.x y3p:bottomLeft.y];
+}
+
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)anImage transform:(ZXPerspectiveTransform *)transform dimension:(int)dimension error:(NSError **)error {
+ ZXGridSampler *sampler = [ZXGridSampler instance];
+ return [sampler sampleGrid:anImage dimensionX:dimension dimensionY:dimension transform:transform error:error];
+}
+
+/**
+ * Computes the dimension (number of modules on a size) of the QR Code based on the position
+ * of the finder patterns and estimated module size. Returns -1 on an error.
+ */
++ (int)computeDimension:(ZXResultPoint *)topLeft topRight:(ZXResultPoint *)topRight bottomLeft:(ZXResultPoint *)bottomLeft moduleSize:(float)moduleSize error:(NSError **)error {
+ int tltrCentersDimension = [ZXMathUtils round:[ZXResultPoint distance:topLeft pattern2:topRight] / moduleSize];
+ int tlblCentersDimension = [ZXMathUtils round:[ZXResultPoint distance:topLeft pattern2:bottomLeft] / moduleSize];
+ int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
+
+ switch (dimension & 0x03) {
+ case 0:
+ dimension++;
+ break;
+ case 2:
+ dimension--;
+ break;
+ case 3:
+ if (error) *error = NotFoundErrorInstance();
+ return -1;
+ }
+ return dimension;
+}
+
+/**
+ * Computes an average estimated module size based on estimated derived from the positions
+ * of the three finder patterns.
+ */
+- (float)calculateModuleSize:(ZXResultPoint *)topLeft topRight:(ZXResultPoint *)topRight bottomLeft:(ZXResultPoint *)bottomLeft {
+ return ([self calculateModuleSizeOneWay:topLeft otherPattern:topRight] + [self calculateModuleSizeOneWay:topLeft otherPattern:bottomLeft]) / 2.0f;
+}
+
+- (float)calculateModuleSizeOneWay:(ZXResultPoint *)pattern otherPattern:(ZXResultPoint *)otherPattern {
+ float moduleSizeEst1 = [self sizeOfBlackWhiteBlackRunBothWays:(int)[pattern x] fromY:(int)[pattern y] toX:(int)[otherPattern x] toY:(int)[otherPattern y]];
+ float moduleSizeEst2 = [self sizeOfBlackWhiteBlackRunBothWays:(int)[otherPattern x] fromY:(int)[otherPattern y] toX:(int)[pattern x] toY:(int)[pattern y]];
+ if (isnan(moduleSizeEst1)) {
+ return moduleSizeEst2 / 7.0f;
+ }
+ if (isnan(moduleSizeEst2)) {
+ return moduleSizeEst1 / 7.0f;
+ }
+ return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
+}
+
+- (float)sizeOfBlackWhiteBlackRunBothWays:(int)fromX fromY:(int)fromY toX:(int)toX toY:(int)toY {
+ float result = [self sizeOfBlackWhiteBlackRun:fromX fromY:fromY toX:toX toY:toY];
+
+ // Now count other way -- don't run off image though of course
+ float scale = 1.0f;
+ int otherToX = fromX - (toX - fromX);
+ if (otherToX < 0) {
+ scale = (float)fromX / (float)(fromX - otherToX);
+ otherToX = 0;
+ } else if (otherToX >= self.image.width) {
+ scale = (float)(self.image.width - 1 - fromX) / (float)(otherToX - fromX);
+ otherToX = self.image.width - 1;
+ }
+ int otherToY = (int)(fromY - (toY - fromY) * scale);
+
+ scale = 1.0f;
+ if (otherToY < 0) {
+ scale = (float)fromY / (float)(fromY - otherToY);
+ otherToY = 0;
+ } else if (otherToY >= self.image.height) {
+ scale = (float)(self.image.height - 1 - fromY) / (float)(otherToY - fromY);
+ otherToY = self.image.height - 1;
+ }
+ otherToX = (int)(fromX + (otherToX - fromX) * scale);
+
+ result += [self sizeOfBlackWhiteBlackRun:fromX fromY:fromY toX:otherToX toY:otherToY];
+
+ // Middle pixel is double-counted this way; subtract 1
+ return result - 1.0f;
+}
+
+/**
+ * This method traces a line from a point in the image, in the direction towards another point.
+ * It begins in a black region, and keeps going until it finds white, then black, then white again.
+ * It reports the distance from the start to this point.
+ *
+ * This is used when figuring out how wide a finder pattern is, when the finder pattern
+ * may be skewed or rotated.
+ */
+- (float)sizeOfBlackWhiteBlackRun:(int)fromX fromY:(int)fromY toX:(int)toX toY:(int)toY {
+ // Mild variant of Bresenham's algorithm;
+ // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
+ BOOL steep = abs(toY - fromY) > abs(toX - fromX);
+ if (steep) {
+ int temp = fromX;
+ fromX = fromY;
+ fromY = temp;
+ temp = toX;
+ toX = toY;
+ toY = temp;
+ }
+
+ int dx = abs(toX - fromX);
+ int dy = abs(toY - fromY);
+ int error = -dx >> 1;
+ int xstep = fromX < toX ? 1 : -1;
+ int ystep = fromY < toY ? 1 : -1;
+
+ // In black pixels, looking for white, first or second time.
+ int state = 0;
+ // Loop up until x == toX, but not beyond
+ int xLimit = toX + xstep;
+ for (int x = fromX, y = fromY; x != xLimit; x += xstep) {
+ int realX = steep ? y : x;
+ int realY = steep ? x : y;
+
+ // Does current pixel mean we have moved white to black or vice versa?
+ // Scanning black in state 0,2 and white in state 1, so if we find the wrong
+ // color, advance to next state or end if we are in state 2 already
+ if ((state == 1) == [self.image getX:realX y:realY]) {
+ if (state == 2) {
+ return [ZXMathUtils distanceInt:x aY:y bX:fromX bY:fromY];
+ }
+ state++;
+ }
+
+ error += dy;
+ if (error > 0) {
+ if (y == toY) {
+ break;
+ }
+ y += ystep;
+ error -= dx;
+ }
+ }
+ // Found black-white-black; give the benefit of the doubt that the next pixel outside the image
+ // is "white" so this last point at (toX+xStep,toY) is the right ending. This is really a
+ // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this.
+ if (state == 2) {
+ return [ZXMathUtils distanceInt:toX + xstep aY:toY bX:fromX bY:fromY];
+ }
+ // else we didn't find even black-white-black; no estimate is really possible
+ return NAN;
+}
+
+/**
+ * Attempts to locate an alignment pattern in a limited region of the image, which is
+ * guessed to contain it. This method uses ZXAlignmentPattern.
+ */
+- (ZXAlignmentPattern *)findAlignmentInRegion:(float)overallEstModuleSize estAlignmentX:(int)estAlignmentX estAlignmentY:(int)estAlignmentY allowanceFactor:(float)allowanceFactor error:(NSError **)error {
+ int allowance = (int)(allowanceFactor * overallEstModuleSize);
+ int alignmentAreaLeftX = MAX(0, estAlignmentX - allowance);
+ int alignmentAreaRightX = MIN(self.image.width - 1, estAlignmentX + allowance);
+ if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ int alignmentAreaTopY = MAX(0, estAlignmentY - allowance);
+ int alignmentAreaBottomY = MIN(self.image.height - 1, estAlignmentY + allowance);
+ if (alignmentAreaBottomY - alignmentAreaTopY < overallEstModuleSize * 3) {
+ if (error) *error = NotFoundErrorInstance();
+ return nil;
+ }
+
+ ZXAlignmentPatternFinder *alignmentFinder = [[ZXAlignmentPatternFinder alloc] initWithImage:self.image
+ startX:alignmentAreaLeftX
+ startY:alignmentAreaTopY
+ width:alignmentAreaRightX - alignmentAreaLeftX
+ height:alignmentAreaBottomY - alignmentAreaTopY
+ moduleSize:overallEstModuleSize
+ resultPointCallback:self.resultPointCallback];
+ return [alignmentFinder findWithError:error];
+}
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.h b/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.h
new file mode 100644
index 0000000..bfc5ba7
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.h
@@ -0,0 +1,36 @@
+/*
+ * 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 "ZXResultPoint.h"
+
+/**
+ * Encapsulates a finder pattern, which are the three square patterns found in
+ * the corners of QR Codes. It also encapsulates a count of similar finder patterns,
+ * as a convenience to the finder's bookkeeping.
+ */
+
+@interface ZXQRCodeFinderPattern : ZXResultPoint
+
+@property (nonatomic, assign, readonly) int count;
+@property (nonatomic, assign, readonly) float estimatedModuleSize;
+
+- (id)initWithPosX:(float)posX posY:(float)posY estimatedModuleSize:(float)estimatedModuleSize;
+- (id)initWithPosX:(float)posX posY:(float)posY estimatedModuleSize:(float)estimatedModuleSize count:(int)count;
+- (void)incrementCount;
+- (BOOL)aboutEquals:(float)moduleSize i:(float)i j:(float)j;
+- (ZXQRCodeFinderPattern *)combineEstimateI:(float)i j:(float)j newModuleSize:(float)newModuleSize;
+
+@end
diff --git a/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.m b/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.m
new file mode 100644
index 0000000..c427762
--- /dev/null
+++ b/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.m
@@ -0,0 +1,72 @@
+/*
+ * 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 "ZXQRCodeFinderPattern.h"
+
+@interface ZXQRCodeFinderPattern ()
+
+@property (nonatomic, assign) int count;
+
+@end
+
+@implementation ZXQRCodeFinderPattern
+
+- (id)initWithPosX:(float)posX posY:(float)posY estimatedModuleSize:(float)estimatedModuleSize {
+ return [self initWithPosX:posX posY:posY estimatedModuleSize:estimatedModuleSize count:1];
+}
+
+- (id)initWithPosX:(float)posX posY:(float)posY estimatedModuleSize:(float)estimatedModuleSize count:(int)count {
+ if (self = [super initWithX:posX y:posY]) {
+ _estimatedModuleSize = estimatedModuleSize;
+ _count = count;
+ }
+
+ return self;
+}
+
+- (void)incrementCount {
+ self.count++;
+}
+
+/**
+ * Determines if this finder pattern "about equals" a finder pattern at the stated
+ * position and size -- meaning, it is at nearly the same center with nearly the same size.
+ */
+- (BOOL)aboutEquals:(float)moduleSize i:(float)i j:(float)j {
+ if (fabsf(i - [self y]) <= moduleSize && fabsf(j - [self x]) <= moduleSize) {
+ float moduleSizeDiff = fabsf(moduleSize - self.estimatedModuleSize);
+ return moduleSizeDiff <= 1.0f || moduleSizeDiff <= self.estimatedModuleSize;
+ }
+ return NO;
+}
+
+/**
+ * Combines this object's current estimate of a finder pattern position and module size
+ * with a new estimate. It returns a new ZXQRCodeFinderPattern containing a weighted average
+ * based on count.
+ */
+- (ZXQRCodeFinderPattern *)combineEstimateI:(float)i j:(float)j newModuleSize:(float)newModuleSize {
+ int combinedCount = self.count + 1;
+ float combinedX = (self.count * self.x + j) / combinedCount;
+ float combinedY = (self.count * self.y + i) / combinedCount;
+ float combinedModuleSize = (self.count * self.estimatedModuleSize + newModuleSize) / combinedCount;
+ return [[ZXQRCodeFinderPattern alloc] initWithPosX:combinedX
+ posY:combinedY
+ estimatedModuleSize:combinedModuleSize
+ count:combinedCount];
+}
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXBlockPair.h b/ZXingObjC/qrcode/encoder/ZXBlockPair.h
new file mode 100644
index 0000000..b107260
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXBlockPair.h
@@ -0,0 +1,26 @@
+/*
+ * 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 ZXBlockPair : NSObject
+
+@property (nonatomic, assign, readonly) int8_t *dataBytes;
+@property (nonatomic, assign, readonly) int8_t *errorCorrectionBytes;
+@property (nonatomic, assign, readonly) int errorCorrectionLength;
+@property (nonatomic, assign, readonly) int length;
+
+- (id)initWithData:(int8_t *)data length:(unsigned int)length errorCorrection:(int8_t *)errorCorrection errorCorrectionLength:(unsigned int)errorCorrectionLength;
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXBlockPair.m b/ZXingObjC/qrcode/encoder/ZXBlockPair.m
new file mode 100644
index 0000000..3e0ab7d
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXBlockPair.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 "ZXBlockPair.h"
+
+@implementation ZXBlockPair
+
+- (id)initWithData:(int8_t *)data length:(unsigned int)length errorCorrection:(int8_t *)errorCorrection errorCorrectionLength:(unsigned int)errorCorrectionLength {
+ if (self = [super init]) {
+ _dataBytes = (int8_t *)malloc(length * sizeof(int8_t));
+ memcpy(_dataBytes, data, length * sizeof(int8_t));
+ _errorCorrectionBytes = (int8_t *)malloc(errorCorrectionLength * sizeof(int8_t));
+ memcpy(_errorCorrectionBytes, errorCorrection, errorCorrectionLength);
+ _length = length;
+ _errorCorrectionLength = errorCorrectionLength;
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_dataBytes != NULL) {
+ free(_dataBytes);
+ _dataBytes = NULL;
+ }
+
+ if (_errorCorrectionBytes != NULL) {
+ free(_errorCorrectionBytes);
+ _errorCorrectionBytes = NULL;
+ }
+}
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXByteMatrix.h b/ZXingObjC/qrcode/encoder/ZXByteMatrix.h
new file mode 100644
index 0000000..f504e38
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXByteMatrix.h
@@ -0,0 +1,30 @@
+/*
+ * 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 ZXByteMatrix : NSObject
+
+@property (nonatomic, assign, readonly) int height;
+@property (nonatomic, assign, readonly) int width;
+@property (nonatomic, assign, readonly) int8_t **array;
+
+- (id)initWithWidth:(int)width height:(int)height;
+- (char)getX:(int)x y:(int)y;
+- (void)setX:(int)x y:(int)y charValue:(char)value;
+- (void)setX:(int)x y:(int)y intValue:(int)value;
+- (void)setX:(int)x y:(int)y boolValue:(BOOL)value;
+- (void)clear:(char)value;
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXByteMatrix.m b/ZXingObjC/qrcode/encoder/ZXByteMatrix.m
new file mode 100644
index 0000000..15befa8
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXByteMatrix.m
@@ -0,0 +1,94 @@
+/*
+ * 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 "ZXByteMatrix.h"
+
+@implementation ZXByteMatrix
+
+- (id)initWithWidth:(int)width height:(int)height {
+ if (self = [super init]) {
+ _width = width;
+ _height = height;
+
+ _array = (int8_t **)malloc(height * sizeof(int8_t *));
+ for (int i = 0; i < height; i++) {
+ _array[i] = (int8_t *)malloc(width * sizeof(int8_t));
+ }
+ [self clear:0];
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_array != NULL) {
+ for (int i = 0; i < self.height; i++) {
+ free(_array[i]);
+ }
+ free(_array);
+ _array = NULL;
+ }
+}
+
+- (char)getX:(int)x y:(int)y {
+ return self.array[y][x];
+}
+
+- (void)setX:(int)x y:(int)y charValue:(char)value {
+ self.array[y][x] = value;
+}
+
+- (void)setX:(int)x y:(int)y intValue:(int)value {
+ self.array[y][x] = (char)value;
+}
+
+- (void)setX:(int)x y:(int)y boolValue:(BOOL)value {
+ self.array[y][x] = (char)value;
+}
+
+- (void)clear:(char)value {
+ for (int y = 0; y < self.height; ++y) {
+ for (int x = 0; x < self.width; ++x) {
+ self.array[y][x] = value;
+ }
+ }
+}
+
+- (NSString *)description {
+ NSMutableString *result = [NSMutableString string];
+
+ for (int y = 0; y < self.height; ++y) {
+ for (int x = 0; x < self.width; ++x) {
+ switch (self.array[y][x]) {
+ case 0:
+ [result appendString:@" 0"];
+ break;
+ case 1:
+ [result appendString:@" 1"];
+ break;
+ default:
+ [result appendString:@" "];
+ break;
+ }
+ }
+
+ [result appendString:@"\n"];
+ }
+
+ return result;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXEncoder.h b/ZXingObjC/qrcode/encoder/ZXEncoder.h
new file mode 100644
index 0000000..2fdab43
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXEncoder.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+@class ZXBitArray, ZXEncodeHints, ZXErrorCorrectionLevel, ZXMode, ZXQRCode, ZXQRCodeVersion;
+
+extern const NSStringEncoding DEFAULT_BYTE_MODE_ENCODING;
+
+@interface ZXEncoder : NSObject
+
++ (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXErrorCorrectionLevel *)ecLevel error:(NSError **)error;
++ (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXErrorCorrectionLevel *)ecLevel hints:(ZXEncodeHints *)hints error:(NSError **)error;
++ (int)alphanumericCode:(int)code;
++ (ZXMode *)chooseMode:(NSString *)content;
++ (BOOL)terminateBits:(int)numDataBytes bits:(ZXBitArray *)bits error:(NSError **)error;
++ (BOOL)numDataBytesAndNumECBytesForBlockID:(int)numTotalBytes numDataBytes:(int)numDataBytes numRSBlocks:(int)numRSBlocks blockID:(int)blockID numDataBytesInBlock:(int[])numDataBytesInBlock numECBytesInBlock:(int[])numECBytesInBlock error:(NSError **)error;
++ (ZXBitArray *)interleaveWithECBytes:(ZXBitArray *)bits numTotalBytes:(int)numTotalBytes numDataBytes:(int)numDataBytes numRSBlocks:(int)numRSBlocks error:(NSError **)error;
++ (int8_t *)generateECBytes:(int8_t *)dataBytes numDataBytes:(int)numDataBytes numEcBytesInBlock:(int)numEcBytesInBlock;
++ (void)appendModeInfo:(ZXMode *)mode bits:(ZXBitArray *)bits;
++ (BOOL)appendLengthInfo:(int)numLetters version:(ZXQRCodeVersion *)version mode:(ZXMode *)mode bits:(ZXBitArray *)bits error:(NSError **)error;
++ (BOOL)appendBytes:(NSString *)content mode:(ZXMode *)mode bits:(ZXBitArray *)bits encoding:(NSStringEncoding)encoding error:(NSError **)error;
++ (void)appendNumericBytes:(NSString *)content bits:(ZXBitArray *)bits;
++ (BOOL)appendAlphanumericBytes:(NSString *)content bits:(ZXBitArray *)bits error:(NSError **)error;
++ (void)append8BitBytes:(NSString *)content bits:(ZXBitArray *)bits encoding:(NSStringEncoding)encoding;
++ (BOOL)appendKanjiBytes:(NSString *)content bits:(ZXBitArray *)bits error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXEncoder.m b/ZXingObjC/qrcode/encoder/ZXEncoder.m
new file mode 100644
index 0000000..4c337e3
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXEncoder.m
@@ -0,0 +1,598 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXBlockPair.h"
+#import "ZXByteMatrix.h"
+#import "ZXCharacterSetECI.h"
+#import "ZXECI.h"
+#import "ZXEncoder.h"
+#import "ZXEncodeHints.h"
+#import "ZXErrors.h"
+#import "ZXErrorCorrectionLevel.h"
+#import "ZXGenericGF.h"
+#import "ZXMaskUtil.h"
+#import "ZXMatrixUtil.h"
+#import "ZXMode.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXQRCode.h"
+#import "ZXReedSolomonEncoder.h"
+
+// The original table is defined in the table 5 of JISX0510:2004 (p.19).
+const int ALPHANUMERIC_TABLE[96] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x00-0x0f
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x10-0x1f
+ 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, // 0x20-0x2f
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, // 0x30-0x3f
+ -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 0x40-0x4f
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 0x50-0x5f
+};
+
+const NSStringEncoding DEFAULT_BYTE_MODE_ENCODING = NSISOLatin1StringEncoding;
+
+@implementation ZXEncoder
+
++ (int)calculateMaskPenalty:(ZXByteMatrix *)matrix {
+ return [ZXMaskUtil applyMaskPenaltyRule1:matrix]
+ + [ZXMaskUtil applyMaskPenaltyRule2:matrix]
+ + [ZXMaskUtil applyMaskPenaltyRule3:matrix]
+ + [ZXMaskUtil applyMaskPenaltyRule4:matrix];
+}
+
+/**
+ * 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.
+ */
++ (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXErrorCorrectionLevel *)ecLevel error:(NSError **)error {
+ return [self encode:content ecLevel:ecLevel hints:nil error:error];
+}
+
++ (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXErrorCorrectionLevel *)ecLevel hints:(ZXEncodeHints *)hints error:(NSError **)error {
+ // Determine what character encoding has been specified by the caller, if any
+ NSStringEncoding encoding = hints == nil ? 0 : hints.encoding;
+ if (encoding == 0) {
+ encoding = DEFAULT_BYTE_MODE_ENCODING;
+ }
+
+ // Pick an encoding mode appropriate for the content. Note that this will not attempt to use
+ // multiple modes / segments even if that were more efficient. Twould be nice.
+ ZXMode *mode = [self chooseMode:content encoding:encoding];
+
+ // This will store the header information, like mode and
+ // length, as well as "header" segments like an ECI segment.
+ ZXBitArray *headerBits = [[ZXBitArray alloc] init];
+
+ // Append ECI segment if applicable
+ if ([mode isEqual:[ZXMode byteMode]] && DEFAULT_BYTE_MODE_ENCODING != encoding) {
+ ZXCharacterSetECI *eci = [ZXCharacterSetECI characterSetECIByEncoding:encoding];
+ if (eci != nil) {
+ [self appendECI:eci bits:headerBits];
+ }
+ }
+
+ // (With ECI in place,) Write the mode marker
+ [self appendModeInfo:mode bits:headerBits];
+
+ // Collect data within the main segment, separately, to count its size if needed. Don't add it to
+ // main payload yet.
+ ZXBitArray *dataBits = [[ZXBitArray alloc] init];
+ if (![self appendBytes:content mode:mode bits:dataBits encoding:encoding error:error]) {
+ 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;
+ }
+
+ // 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;
+ }
+
+ ZXBitArray *headerAndDataBits = [[ZXBitArray alloc] init];
+ [headerAndDataBits appendBitArray:headerBits];
+ // Find "length" of main segment and write it
+ int numLetters = [mode isEqual:[ZXMode byteMode]] ? [dataBits sizeInBytes] : (int)[content length];
+ if (![self appendLengthInfo:numLetters version:version mode:mode bits:headerAndDataBits error:error]) {
+ return nil;
+ }
+ // Put data together into the overall payload
+ [headerAndDataBits appendBitArray:dataBits];
+
+ ZXQRCodeECBlocks *ecBlocks = [version ecBlocksForLevel:ecLevel];
+ int numDataBytes = version.totalCodewords - ecBlocks.totalECCodewords;
+
+ // Terminate the bits properly.
+ if (![self terminateBits:numDataBytes bits:headerAndDataBits error:error]) {
+ return nil;
+ }
+
+ // Interleave data bits with error correction code.
+ ZXBitArray *finalBits = [self interleaveWithECBytes:headerAndDataBits numTotalBytes:version.totalCodewords numDataBytes:numDataBytes
+ numRSBlocks:ecBlocks.numBlocks error:error];
+ if (!finalBits) {
+ return nil;
+ }
+
+ ZXQRCode *qrCode = [[ZXQRCode alloc] init];
+
+ qrCode.ecLevel = ecLevel;
+ qrCode.mode = mode;
+ qrCode.version = version;
+
+ // Choose the mask pattern and set to "qrCode".
+ int dimension = version.dimensionForVersion;
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:dimension height:dimension];
+ int maskPattern = [self chooseMaskPattern:finalBits ecLevel:[qrCode ecLevel] version:[qrCode version] matrix:matrix error:error];
+ if (maskPattern == -1) {
+ return nil;
+ }
+ [qrCode setMaskPattern:maskPattern];
+
+ // Build the matrix and set it to "qrCode".
+ if (![ZXMatrixUtil buildMatrix:finalBits ecLevel:ecLevel version:version maskPattern:maskPattern matrix:matrix error:error]) {
+ return nil;
+ }
+ [qrCode setMatrix:matrix];
+
+ return qrCode;
+}
+
+/**
+ * Return the code point of the table used in alphanumeric mode or
+ * -1 if there is no corresponding code in the table.
+ */
++ (int)alphanumericCode:(int)code {
+ if (code < sizeof(ALPHANUMERIC_TABLE) / sizeof(int)) {
+ return ALPHANUMERIC_TABLE[code];
+ }
+ return -1;
+}
+
++ (ZXMode *)chooseMode:(NSString *)content {
+ return [self chooseMode:content encoding:-1];
+}
+
+/**
+ * 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}.
+ */
++ (ZXMode *)chooseMode:(NSString *)content encoding:(NSStringEncoding)encoding {
+ if (NSShiftJISStringEncoding == encoding) {
+ return [self isOnlyDoubleByteKanji:content] ? [ZXMode kanjiMode] : [ZXMode byteMode];
+ }
+ BOOL hasNumeric = NO;
+ BOOL hasAlphanumeric = NO;
+ for (int i = 0; i < [content length]; ++i) {
+ unichar c = [content characterAtIndex:i];
+ if (c >= '0' && c <= '9') {
+ hasNumeric = YES;
+ } else if ([self alphanumericCode:c] != -1) {
+ hasAlphanumeric = YES;
+ } else {
+ return [ZXMode byteMode];
+ }
+ }
+ if (hasAlphanumeric) {
+ return [ZXMode alphanumericMode];
+ }
+ if (hasNumeric) {
+ return [ZXMode numericMode];
+ }
+ return [ZXMode byteMode];
+}
+
++ (BOOL)isOnlyDoubleByteKanji:(NSString *)content {
+ NSData *data = [content dataUsingEncoding:NSShiftJISStringEncoding];
+ int8_t *bytes = (int8_t *)[data bytes];
+ NSUInteger length = [data length];
+ if (length % 2 != 0) {
+ return NO;
+ }
+ for (int i = 0; i < length; i += 2) {
+ int byte1 = bytes[i] & 0xFF;
+ if ((byte1 < 0x81 || byte1 > 0x9F) && (byte1 < 0xE0 || byte1 > 0xEB)) {
+ return NO;
+ }
+ }
+ return YES;
+}
+
++ (int)chooseMaskPattern:(ZXBitArray *)bits ecLevel:(ZXErrorCorrectionLevel *)ecLevel version:(ZXQRCodeVersion *)version matrix:(ZXByteMatrix *)matrix error:(NSError **)error {
+ int minPenalty = INT_MAX;
+ int bestMaskPattern = -1;
+
+ for (int maskPattern = 0; maskPattern < NUM_MASK_PATTERNS; maskPattern++) {
+ if (![ZXMatrixUtil buildMatrix:bits ecLevel:ecLevel version:version maskPattern:maskPattern matrix:matrix error:error]) {
+ return -1;
+ }
+ int penalty = [self calculateMaskPenalty:matrix];
+ if (penalty < minPenalty) {
+ minPenalty = penalty;
+ bestMaskPattern = maskPattern;
+ }
+ }
+ return bestMaskPattern;
+}
+
++ (ZXQRCodeVersion *)chooseVersion:(int)numInputBits ecLevel:(ZXErrorCorrectionLevel *)ecLevel error:(NSError **)error {
+ // 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) {
+ return version;
+ }
+ }
+
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Data too big"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return nil;
+}
+
++ (int)totalInputBytes:(int)numInputBits version:(ZXQRCodeVersion *)version mode:(ZXMode *)mode {
+ int modeInfoBits = 4;
+ int charCountBits = [mode characterCountBits:version];
+ int headerBits = modeInfoBits + charCountBits;
+ int totalBits = numInputBits + headerBits;
+
+ return (totalBits + 7) / 8;
+}
+
+/**
+ * Terminate bits as described in 8.4.8 and 8.4.9 of JISX0510:2004 (p.24).
+ */
++ (BOOL)terminateBits:(int)numDataBytes bits:(ZXBitArray *)bits error:(NSError **)error {
+ int capacity = numDataBytes << 3;
+ if ([bits size] > capacity) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"data bits cannot fit in the QR Code %d > %d", [bits size], capacity]};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ for (int i = 0; i < 4 && [bits size] < capacity; ++i) {
+ [bits appendBit:NO];
+ }
+ int numBitsInLastByte = [bits size] & 0x07;
+ if (numBitsInLastByte > 0) {
+ for (int i = numBitsInLastByte; i < 8; i++) {
+ [bits appendBit:NO];
+ }
+ }
+ int numPaddingBytes = numDataBytes - [bits sizeInBytes];
+ for (int i = 0; i < numPaddingBytes; ++i) {
+ [bits appendBits:(i & 0x01) == 0 ? 0xEC : 0x11 numBits:8];
+ }
+ if ([bits size] != capacity) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Bits size does not equal capacity"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ return YES;
+}
+
+/**
+ * Get number of data bytes and number of error correction bytes for block id "blockID". Store
+ * the result in "numDataBytesInBlock", and "numECBytesInBlock". See table 12 in 8.5.1 of
+ * JISX0510:2004 (p.30)
+ */
++ (BOOL)numDataBytesAndNumECBytesForBlockID:(int)numTotalBytes numDataBytes:(int)numDataBytes numRSBlocks:(int)numRSBlocks blockID:(int)blockID numDataBytesInBlock:(int[])numDataBytesInBlock numECBytesInBlock:(int[])numECBytesInBlock error:(NSError **)error {
+ if (blockID >= numRSBlocks) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Block ID too large"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ int numRsBlocksInGroup2 = numTotalBytes % numRSBlocks;
+ int numRsBlocksInGroup1 = numRSBlocks - numRsBlocksInGroup2;
+ int numTotalBytesInGroup1 = numTotalBytes / numRSBlocks;
+ int numTotalBytesInGroup2 = numTotalBytesInGroup1 + 1;
+ int numDataBytesInGroup1 = numDataBytes / numRSBlocks;
+ int numDataBytesInGroup2 = numDataBytesInGroup1 + 1;
+ int numEcBytesInGroup1 = numTotalBytesInGroup1 - numDataBytesInGroup1;
+ int numEcBytesInGroup2 = numTotalBytesInGroup2 - numDataBytesInGroup2;
+ if (numEcBytesInGroup1 != numEcBytesInGroup2) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"EC bytes mismatch"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ if (numRSBlocks != numRsBlocksInGroup1 + numRsBlocksInGroup2) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"RS blocks mismatch"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ if (numTotalBytes != ((numDataBytesInGroup1 + numEcBytesInGroup1) * numRsBlocksInGroup1) + ((numDataBytesInGroup2 + numEcBytesInGroup2) * numRsBlocksInGroup2)) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Total bytes mismatch"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ if (blockID < numRsBlocksInGroup1) {
+ numDataBytesInBlock[0] = numDataBytesInGroup1;
+ numECBytesInBlock[0] = numEcBytesInGroup1;
+ } else {
+ numDataBytesInBlock[0] = numDataBytesInGroup2;
+ numECBytesInBlock[0] = numEcBytesInGroup2;
+ }
+ return YES;
+}
+
+/**
+ * Interleave "bits" with corresponding error correction bytes. On success, store the result in
+ * "result". The interleave rule is complicated. See 8.6 of JISX0510:2004 (p.37) for details.
+ */
++ (ZXBitArray *)interleaveWithECBytes:(ZXBitArray *)bits numTotalBytes:(int)numTotalBytes numDataBytes:(int)numDataBytes numRSBlocks:(int)numRSBlocks error:(NSError **)error {
+ // "bits" must have "getNumDataBytes" bytes of data.
+ if ([bits sizeInBytes] != numDataBytes) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Number of bits and data bytes does not match"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return nil;
+ }
+
+ // Step 1. Divide data bytes into blocks and generate error correction bytes for them. We'll
+ // store the divided data bytes blocks and error correction bytes blocks into "blocks".
+ int dataBytesOffset = 0;
+ int maxNumDataBytes = 0;
+ int maxNumEcBytes = 0;
+
+ // Since, we know the number of reedsolmon blocks, we can initialize the vector with the number.
+ NSMutableArray *blocks = [NSMutableArray arrayWithCapacity:numRSBlocks];
+
+ for (int i = 0; i < numRSBlocks; ++i) {
+ int numDataBytesInBlock[1];
+ int numEcBytesInBlock[1];
+ if (![self numDataBytesAndNumECBytesForBlockID:numTotalBytes numDataBytes:numDataBytes numRSBlocks:numRSBlocks
+ blockID:i numDataBytesInBlock:numDataBytesInBlock
+ numECBytesInBlock:numEcBytesInBlock error:error]) {
+ return nil;
+ }
+
+ int size = numDataBytesInBlock[0];
+ int8_t dataBytes[size];
+ [bits toBytes:8 * dataBytesOffset array:dataBytes offset:0 numBytes:size];
+ int8_t *ecBytes = [self generateECBytes:dataBytes numDataBytes:size numEcBytesInBlock:numEcBytesInBlock[0]];
+ [blocks addObject:[[ZXBlockPair alloc] initWithData:dataBytes length:size errorCorrection:ecBytes errorCorrectionLength:numEcBytesInBlock[0]]];
+
+ maxNumDataBytes = MAX(maxNumDataBytes, size);
+ maxNumEcBytes = MAX(maxNumEcBytes, numEcBytesInBlock[0]);
+ dataBytesOffset += numDataBytesInBlock[0];
+ free(ecBytes);
+ }
+ if (numDataBytes != dataBytesOffset) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Data bytes does not match offset"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return nil;
+ }
+
+ ZXBitArray *result = [[ZXBitArray alloc] init];
+
+ // First, place data blocks.
+ for (int i = 0; i < maxNumDataBytes; ++i) {
+ for (ZXBlockPair *block in blocks) {
+ int8_t *dataBytes = block.dataBytes;
+ int length = block.length;
+ if (i < length) {
+ [result appendBits:dataBytes[i] numBits:8];
+ }
+ }
+ }
+ // Then, place error correction blocks.
+ for (int i = 0; i < maxNumEcBytes; ++i) {
+ for (ZXBlockPair *block in blocks) {
+ int8_t *ecBytes = block.errorCorrectionBytes;
+ int length = block.errorCorrectionLength;
+ if (i < length) {
+ [result appendBits:ecBytes[i] numBits:8];
+ }
+ }
+ }
+ if (numTotalBytes != [result sizeInBytes]) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Interleaving error: %d and %d differ.", numTotalBytes, [result sizeInBytes]]};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return nil;
+ }
+
+ return result;
+}
+
++ (int8_t *)generateECBytes:(int8_t[])dataBytes numDataBytes:(int)numDataBytes numEcBytesInBlock:(int)numEcBytesInBlock {
+ int toEncodeLen = numDataBytes + numEcBytesInBlock;
+ int toEncode[toEncodeLen];
+ for (int i = 0; i < numDataBytes; i++) {
+ toEncode[i] = dataBytes[i] & 0xFF;
+ }
+ for (int i = numDataBytes; i < toEncodeLen; i++) {
+ toEncode[i] = 0;
+ }
+
+ [[[ZXReedSolomonEncoder alloc] initWithField:[ZXGenericGF QrCodeField256]] encode:toEncode toEncodeLen:toEncodeLen ecBytes:numEcBytesInBlock];
+
+ int8_t *ecBytes = (int8_t *)malloc(numEcBytesInBlock * sizeof(int8_t));
+ for (int i = 0; i < numEcBytesInBlock; i++) {
+ ecBytes[i] = (int8_t)toEncode[numDataBytes + i];
+ }
+
+ return ecBytes;
+}
+
+/**
+ * Append mode info. On success, store the result in "bits".
+ */
++ (void)appendModeInfo:(ZXMode *)mode bits:(ZXBitArray *)bits {
+ [bits appendBits:[mode bits] numBits:4];
+}
+
+/**
+ * Append length info. On success, store the result in "bits".
+ */
++ (BOOL)appendLengthInfo:(int)numLetters version:(ZXQRCodeVersion *)version mode:(ZXMode *)mode bits:(ZXBitArray *)bits error:(NSError **)error {
+ int numBits = [mode characterCountBits:version];
+ if (numLetters >= (1 << numBits)) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"%d is bigger than %d", numLetters, ((1 << numBits) - 1)]};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ [bits appendBits:numLetters numBits:numBits];
+ return YES;
+}
+
+/**
+ * Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
+ */
++ (BOOL)appendBytes:(NSString *)content mode:(ZXMode *)mode bits:(ZXBitArray *)bits encoding:(NSStringEncoding)encoding error:(NSError **)error {
+ if ([mode isEqual:[ZXMode numericMode]]) {
+ [self appendNumericBytes:content bits:bits];
+ } else if ([mode isEqual:[ZXMode alphanumericMode]]) {
+ if (![self appendAlphanumericBytes:content bits:bits error:error]) {
+ return NO;
+ }
+ } else if ([mode isEqual:[ZXMode byteMode]]) {
+ [self append8BitBytes:content bits:bits encoding:encoding];
+ } else if ([mode isEqual:[ZXMode kanjiMode]]) {
+ if (![self appendKanjiBytes:content bits:bits error:error]) {
+ return NO;
+ }
+ } else {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Invalid mode: %@", mode]};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ return YES;
+}
+
++ (void)appendNumericBytes:(NSString *)content bits:(ZXBitArray *)bits {
+ NSUInteger length = [content length];
+ int i = 0;
+ while (i < length) {
+ int num1 = [content characterAtIndex:i] - '0';
+ if (i + 2 < length) {
+ int num2 = [content characterAtIndex:i + 1] - '0';
+ int num3 = [content characterAtIndex:i + 2] - '0';
+ [bits appendBits:num1 * 100 + num2 * 10 + num3 numBits:10];
+ i += 3;
+ } else if (i + 1 < length) {
+ int num2 = [content characterAtIndex:i + 1] - '0';
+ [bits appendBits:num1 * 10 + num2 numBits:7];
+ i += 2;
+ } else {
+ [bits appendBits:num1 numBits:4];
+ i++;
+ }
+ }
+}
+
++ (BOOL)appendAlphanumericBytes:(NSString *)content bits:(ZXBitArray *)bits error:(NSError **)error {
+ NSUInteger length = [content length];
+ int i = 0;
+
+ while (i < length) {
+ int code1 = [self alphanumericCode:[content characterAtIndex:i]];
+ if (code1 == -1) {
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:nil];
+ return NO;
+ }
+ if (i + 1 < length) {
+ int code2 = [self alphanumericCode:[content characterAtIndex:i + 1]];
+ if (code2 == -1) {
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:nil];
+ return NO;
+ }
+ [bits appendBits:code1 * 45 + code2 numBits:11];
+ i += 2;
+ } else {
+ [bits appendBits:code1 numBits:6];
+ i++;
+ }
+ }
+ return YES;
+}
+
++ (void)append8BitBytes:(NSString *)content bits:(ZXBitArray *)bits encoding:(NSStringEncoding)encoding {
+ NSData *data = [content dataUsingEncoding:encoding];
+ int8_t *bytes = (int8_t *)[data bytes];
+
+ for (int i = 0; i < [data length]; ++i) {
+ [bits appendBits:bytes[i] numBits:8];
+ }
+}
+
++ (BOOL)appendKanjiBytes:(NSString *)content bits:(ZXBitArray *)bits error:(NSError **)error {
+ NSData *data = [content dataUsingEncoding:NSShiftJISStringEncoding];
+ int8_t *bytes = (int8_t *)[data bytes];
+ for (int i = 0; i < [data length]; i += 2) {
+ int byte1 = bytes[i] & 0xFF;
+ int byte2 = bytes[i + 1] & 0xFF;
+ int code = (byte1 << 8) | byte2;
+ int subtracted = -1;
+ if (code >= 0x8140 && code <= 0x9ffc) {
+ subtracted = code - 0x8140;
+ } else if (code >= 0xe040 && code <= 0xebbf) {
+ subtracted = code - 0xc140;
+ }
+ if (subtracted == -1) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Invalid byte sequence"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ int encoded = ((subtracted >> 8) * 0xc0) + (subtracted & 0xff);
+ [bits appendBits:encoded numBits:13];
+ }
+ return YES;
+}
+
++ (void)appendECI:(ZXECI *)eci bits:(ZXBitArray *)bits {
+ [bits appendBits:[[ZXMode eciMode] bits] numBits:4];
+ [bits appendBits:[eci value] numBits:8];
+}
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXMaskUtil.h b/ZXingObjC/qrcode/encoder/ZXMaskUtil.h
new file mode 100644
index 0000000..9d7f146
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXMaskUtil.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+@class ZXByteMatrix;
+
+@interface ZXMaskUtil : NSObject
+
++ (int)applyMaskPenaltyRule1:(ZXByteMatrix *)matrix;
++ (int)applyMaskPenaltyRule2:(ZXByteMatrix *)matrix;
++ (int)applyMaskPenaltyRule3:(ZXByteMatrix *)matrix;
++ (int)applyMaskPenaltyRule4:(ZXByteMatrix *)matrix;
++ (BOOL)dataMaskBit:(int)maskPattern x:(int)x y:(int)y;
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXMaskUtil.m b/ZXingObjC/qrcode/encoder/ZXMaskUtil.m
new file mode 100644
index 0000000..bdf6b68
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXMaskUtil.m
@@ -0,0 +1,214 @@
+/*
+ * 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 "ZXByteMatrix.h"
+#import "ZXMaskUtil.h"
+#import "ZXQRCode.h"
+
+// Penalty weights from section 6.8.2.1
+const int N1 = 3;
+const int N2 = 3;
+const int N3 = 40;
+const int N4 = 10;
+
+@implementation ZXMaskUtil
+
+/**
+ * Apply mask penalty rule 1 and return the penalty. Find repetitive cells with the same color and
+ * give penalty to them. Example: 00000 or 11111.
+ */
++ (int)applyMaskPenaltyRule1:(ZXByteMatrix *)matrix {
+ return [self applyMaskPenaltyRule1Internal:matrix isHorizontal:YES] + [self applyMaskPenaltyRule1Internal:matrix isHorizontal:NO];
+}
+
+/**
+ * Apply mask penalty rule 2 and return the penalty. Find 2x2 blocks with the same color and give
+ * penalty to them. This is actually equivalent to the spec's rule, which is to find MxN blocks and give a
+ * penalty proportional to (M-1)x(N-1), because this is the number of 2x2 blocks inside such a block.
+ */
++ (int)applyMaskPenaltyRule2:(ZXByteMatrix *)matrix {
+ int penalty = 0;
+ int8_t **array = matrix.array;
+ int width = matrix.width;
+ int height = matrix.height;
+
+ for (int y = 0; y < height - 1; y++) {
+ for (int x = 0; x < width - 1; x++) {
+ int value = array[y][x];
+ if (value == array[y][x + 1] && value == array[y + 1][x] && value == array[y + 1][x + 1]) {
+ penalty++;
+ }
+ }
+ }
+
+ return N2 * penalty;
+}
+
+/**
+ * Apply mask penalty rule 3 and return the penalty. Find consecutive cells of 00001011101 or
+ * 10111010000, and give penalty to them. If we find patterns like 000010111010000, we give
+ * penalties twice (i.e. 40 * 2).
+ */
++ (int)applyMaskPenaltyRule3:(ZXByteMatrix *)matrix {
+ int penalty = 0;
+ int8_t **array = matrix.array;
+ int width = matrix.width;
+ int height = matrix.height;
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ if (x + 6 < width &&
+ array[y][x] == 1 &&
+ array[y][x + 1] == 0 &&
+ array[y][x + 2] == 1 &&
+ array[y][x + 3] == 1 &&
+ array[y][x + 4] == 1 &&
+ array[y][x + 5] == 0 &&
+ array[y][x + 6] == 1 &&
+ ((x + 10 < width &&
+ array[y][x + 7] == 0 &&
+ array[y][x + 8] == 0 &&
+ array[y][x + 9] == 0 &&
+ array[y][x + 10] == 0) ||
+ (x - 4 >= 0 &&
+ array[y][x - 1] == 0 &&
+ array[y][x - 2] == 0 &&
+ array[y][x - 3] == 0 &&
+ array[y][x - 4] == 0))) {
+ penalty += N3;
+ }
+ if (y + 6 < height &&
+ array[y][x] == 1 &&
+ array[y + 1][x] == 0 &&
+ array[y + 2][x] == 1 &&
+ array[y + 3][x] == 1 &&
+ array[y + 4][x] == 1 &&
+ array[y + 5][x] == 0 &&
+ array[y + 6][x] == 1 &&
+ ((y + 10 < height &&
+ array[y + 7][x] == 0 &&
+ array[y + 8][x] == 0 &&
+ array[y + 9][x] == 0 &&
+ array[y + 10][x] == 0) ||
+ (y - 4 >= 0 &&
+ array[y - 1][x] == 0 &&
+ array[y - 2][x] == 0 &&
+ array[y - 3][x] == 0 &&
+ array[y - 4][x] == 0))) {
+ penalty += N3;
+ }
+ }
+ }
+ return penalty;
+}
+
+/**
+ * Apply mask penalty rule 4 and return the penalty. Calculate the ratio of dark cells and give
+ * penalty if the ratio is far from 50%. It gives 10 penalty for 5% distance.
+ */
++ (int)applyMaskPenaltyRule4:(ZXByteMatrix *)matrix {
+ int numDarkCells = 0;
+ int8_t **array = matrix.array;
+ int width = matrix.width;
+ int height = matrix.height;
+ for (int y = 0; y < height; y++) {
+ int8_t *arrayY = array[y];
+ for (int x = 0; x < width; x++) {
+ if (arrayY[x] == 1) {
+ numDarkCells++;
+ }
+ }
+ }
+ int numTotalCells = [matrix height] * [matrix width];
+ double darkRatio = (double) numDarkCells / numTotalCells;
+ int fivePercentVariances = abs((int)(darkRatio * 100 - 50)) / 5; // * 100.0 / 5.0
+ return fivePercentVariances * N4;
+}
+
+/**
+ * Return the mask bit for "getMaskPattern" at "x" and "y". See 8.8 of JISX0510:2004 for mask
+ * pattern conditions.
+ */
++ (BOOL)dataMaskBit:(int)maskPattern x:(int)x y:(int)y {
+ int intermediate;
+ int temp;
+ switch (maskPattern) {
+ case 0:
+ intermediate = (y + x) & 0x1;
+ break;
+ case 1:
+ intermediate = y & 0x1;
+ break;
+ case 2:
+ intermediate = x % 3;
+ break;
+ case 3:
+ intermediate = (y + x) % 3;
+ break;
+ case 4:
+ intermediate = ((int)((unsigned int)y >> 1) + (x / 3)) & 0x1;
+ break;
+ case 5:
+ temp = y * x;
+ intermediate = (temp & 0x1) + (temp % 3);
+ break;
+ case 6:
+ temp = y * x;
+ intermediate = ((temp & 0x1) + (temp % 3)) & 0x1;
+ break;
+ case 7:
+ temp = y * x;
+ intermediate = ((temp % 3) + ((y + x) & 0x1)) & 0x1;
+ break;
+ default:
+ [NSException raise:NSInvalidArgumentException
+ format:@"Invalid mask pattern: %d", maskPattern];
+ }
+ return intermediate == 0;
+}
+
+/**
+ * Helper function for applyMaskPenaltyRule1. We need this for doing this calculation in both
+ * vertical and horizontal orders respectively.
+ */
++ (int)applyMaskPenaltyRule1Internal:(ZXByteMatrix *)matrix isHorizontal:(BOOL)isHorizontal {
+ int penalty = 0;
+ int iLimit = isHorizontal ? matrix.height : matrix.width;
+ int jLimit = isHorizontal ? matrix.width : matrix.height;
+ int8_t **array = matrix.array;
+ for (int i = 0; i < iLimit; i++) {
+ int numSameBitCells = 0;
+ int prevBit = -1;
+ for (int j = 0; j < jLimit; j++) {
+ int bit = isHorizontal ? array[i][j] : array[j][i];
+ if (bit == prevBit) {
+ numSameBitCells++;
+ } else {
+ if (numSameBitCells >= 5) {
+ penalty += N1 + (numSameBitCells - 5);
+ }
+ numSameBitCells = 1; // Include the cell itself.
+ prevBit = bit;
+ }
+ }
+ if (numSameBitCells >= 5) {
+ penalty += N1 + (numSameBitCells - 5);
+ }
+ }
+ return penalty;
+}
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXMatrixUtil.h b/ZXingObjC/qrcode/encoder/ZXMatrixUtil.h
new file mode 100644
index 0000000..759e070
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXMatrixUtil.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+@class ZXBitArray, ZXByteMatrix, ZXErrorCorrectionLevel, ZXQRCodeVersion;
+
+@interface ZXMatrixUtil : NSObject
+
++ (BOOL)buildMatrix:(ZXBitArray *)dataBits ecLevel:(ZXErrorCorrectionLevel *)ecLevel version:(ZXQRCodeVersion *)version maskPattern:(int)maskPattern matrix:(ZXByteMatrix *)matrix error:(NSError **)error;
++ (void)clearMatrix:(ZXByteMatrix *)matrix;
++ (BOOL)embedBasicPatterns:(ZXQRCodeVersion *)version matrix:(ZXByteMatrix *)matrix error:(NSError **)error;
++ (BOOL)embedTypeInfo:(ZXErrorCorrectionLevel *)ecLevel maskPattern:(int)maskPattern matrix:(ZXByteMatrix *)matrix error:(NSError **)error;
++ (BOOL)maybeEmbedVersionInfo:(ZXQRCodeVersion *)version matrix:(ZXByteMatrix *)matrix error:(NSError **)error;
++ (BOOL)embedDataBits:(ZXBitArray *)dataBits maskPattern:(int)maskPattern matrix:(ZXByteMatrix *)matrix error:(NSError **)error;
++ (int)findMSBSet:(int)value;
++ (int)calculateBCHCode:(int)value poly:(int)poly;
++ (BOOL)makeTypeInfoBits:(ZXErrorCorrectionLevel *)ecLevel maskPattern:(int)maskPattern bits:(ZXBitArray *)bits error:(NSError **)error;
++ (BOOL)makeVersionInfoBits:(ZXQRCodeVersion *)version bits:(ZXBitArray *)bits error:(NSError **)error;
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXMatrixUtil.m b/ZXingObjC/qrcode/encoder/ZXMatrixUtil.m
new file mode 100644
index 0000000..277b7b5
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXMatrixUtil.m
@@ -0,0 +1,516 @@
+/*
+ * 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 "ZXBitArray.h"
+#import "ZXByteMatrix.h"
+#import "ZXErrors.h"
+#import "ZXErrorCorrectionLevel.h"
+#import "ZXMaskUtil.h"
+#import "ZXMatrixUtil.h"
+#import "ZXQRCode.h"
+#import "ZXQRCodeVersion.h"
+
+int const POSITION_DETECTION_PATTERN[7][7] = {
+ {1, 1, 1, 1, 1, 1, 1},
+ {1, 0, 0, 0, 0, 0, 1},
+ {1, 0, 1, 1, 1, 0, 1},
+ {1, 0, 1, 1, 1, 0, 1},
+ {1, 0, 1, 1, 1, 0, 1},
+ {1, 0, 0, 0, 0, 0, 1},
+ {1, 1, 1, 1, 1, 1, 1},
+};
+
+int const POSITION_ADJUSTMENT_PATTERN[5][5] = {
+ {1, 1, 1, 1, 1},
+ {1, 0, 0, 0, 1},
+ {1, 0, 1, 0, 1},
+ {1, 0, 0, 0, 1},
+ {1, 1, 1, 1, 1},
+};
+
+// From Appendix E. Table 1, JIS0510X:2004 (p 71). The table was double-checked by komatsu.
+int const POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7] = {
+ {-1, -1, -1, -1, -1, -1, -1}, // Version 1
+ { 6, 18, -1, -1, -1, -1, -1}, // Version 2
+ { 6, 22, -1, -1, -1, -1, -1}, // Version 3
+ { 6, 26, -1, -1, -1, -1, -1}, // Version 4
+ { 6, 30, -1, -1, -1, -1, -1}, // Version 5
+ { 6, 34, -1, -1, -1, -1, -1}, // Version 6
+ { 6, 22, 38, -1, -1, -1, -1}, // Version 7
+ { 6, 24, 42, -1, -1, -1, -1}, // Version 8
+ { 6, 26, 46, -1, -1, -1, -1}, // Version 9
+ { 6, 28, 50, -1, -1, -1, -1}, // Version 10
+ { 6, 30, 54, -1, -1, -1, -1}, // Version 11
+ { 6, 32, 58, -1, -1, -1, -1}, // Version 12
+ { 6, 34, 62, -1, -1, -1, -1}, // Version 13
+ { 6, 26, 46, 66, -1, -1, -1}, // Version 14
+ { 6, 26, 48, 70, -1, -1, -1}, // Version 15
+ { 6, 26, 50, 74, -1, -1, -1}, // Version 16
+ { 6, 30, 54, 78, -1, -1, -1}, // Version 17
+ { 6, 30, 56, 82, -1, -1, -1}, // Version 18
+ { 6, 30, 58, 86, -1, -1, -1}, // Version 19
+ { 6, 34, 62, 90, -1, -1, -1}, // Version 20
+ { 6, 28, 50, 72, 94, -1, -1}, // Version 21
+ { 6, 26, 50, 74, 98, -1, -1}, // Version 22
+ { 6, 30, 54, 78, 102, -1, -1}, // Version 23
+ { 6, 28, 54, 80, 106, -1, -1}, // Version 24
+ { 6, 32, 58, 84, 110, -1, -1}, // Version 25
+ { 6, 30, 58, 86, 114, -1, -1}, // Version 26
+ { 6, 34, 62, 90, 118, -1, -1}, // Version 27
+ { 6, 26, 50, 74, 98, 122, -1}, // Version 28
+ { 6, 30, 54, 78, 102, 126, -1}, // Version 29
+ { 6, 26, 52, 78, 104, 130, -1}, // Version 30
+ { 6, 30, 56, 82, 108, 134, -1}, // Version 31
+ { 6, 34, 60, 86, 112, 138, -1}, // Version 32
+ { 6, 30, 58, 86, 114, 142, -1}, // Version 33
+ { 6, 34, 62, 90, 118, 146, -1}, // Version 34
+ { 6, 30, 54, 78, 102, 126, 150}, // Version 35
+ { 6, 24, 50, 76, 102, 128, 154}, // Version 36
+ { 6, 28, 54, 80, 106, 132, 158}, // Version 37
+ { 6, 32, 58, 84, 110, 136, 162}, // Version 38
+ { 6, 26, 54, 82, 110, 138, 166}, // Version 39
+ { 6, 30, 58, 86, 114, 142, 170}, // Version 40
+};
+
+// Type info cells at the left top corner.
+int const TYPE_INFO_COORDINATES[15][2] = {
+ {8, 0},
+ {8, 1},
+ {8, 2},
+ {8, 3},
+ {8, 4},
+ {8, 5},
+ {8, 7},
+ {8, 8},
+ {7, 8},
+ {5, 8},
+ {4, 8},
+ {3, 8},
+ {2, 8},
+ {1, 8},
+ {0, 8},
+};
+
+// From Appendix D in JISX0510:2004 (p. 67)
+int const VERSION_INFO_POLY = 0x1f25; // 1 1111 0010 0101
+
+// From Appendix C in JISX0510:2004 (p.65).
+int const TYPE_INFO_POLY = 0x537;
+int const TYPE_INFO_MASK_PATTERN = 0x5412;
+
+@implementation ZXMatrixUtil
+
+// Set all cells to -1. -1 means that the cell is empty (not set yet).
++ (void)clearMatrix:(ZXByteMatrix *)matrix {
+ [matrix clear:(char) -1];
+}
+
+// Build 2D matrix of QR Code from "dataBits" with "ecLevel", "version" and "getMaskPattern". On
+// success, store the result in "matrix" and return true.
++ (BOOL)buildMatrix:(ZXBitArray *)dataBits ecLevel:(ZXErrorCorrectionLevel *)ecLevel version:(ZXQRCodeVersion *)version maskPattern:(int)maskPattern matrix:(ZXByteMatrix *)matrix error:(NSError **)error {
+ [self clearMatrix:matrix];
+ if (![self embedBasicPatterns:version matrix:matrix error:error]) {
+ return NO;
+ }
+ // Type information appear with any version.
+ if (![self embedTypeInfo:ecLevel maskPattern:maskPattern matrix:matrix error:error]) {
+ return NO;
+ }
+ // Version info appear if version >= 7.
+ if (![self maybeEmbedVersionInfo:version matrix:matrix error:error]) {
+ return NO;
+ }
+ // Data should be embedded at end.
+ if (![self embedDataBits:dataBits maskPattern:maskPattern matrix:matrix error:error]) {
+ return NO;
+ }
+ return YES;
+}
+
+// Embed basic patterns. On success, modify the matrix and return true.
+// The basic patterns are:
+// - Position detection patterns
+// - Timing patterns
+// - Dark dot at the left bottom corner
+// - Position adjustment patterns, if need be
++ (BOOL)embedBasicPatterns:(ZXQRCodeVersion *)version matrix:(ZXByteMatrix *)matrix error:(NSError **)error {
+ // Let's get started with embedding big squares at corners.
+ if (![self embedPositionDetectionPatternsAndSeparators:matrix]) {
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:nil];
+ return NO;
+ }
+ // Then, embed the dark dot at the left bottom corner.
+ if (![self embedDarkDotAtLeftBottomCorner:matrix]) {
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:nil];
+ return NO;
+ }
+
+ // Position adjustment patterns appear if version >= 2.
+ [self maybeEmbedPositionAdjustmentPatterns:version matrix:matrix];
+ // Timing patterns should be embedded after position adj. patterns.
+ [self embedTimingPatterns:matrix];
+
+ return YES;
+}
+
+// Embed type information. On success, modify the matrix.
++ (BOOL)embedTypeInfo:(ZXErrorCorrectionLevel *)ecLevel maskPattern:(int)maskPattern matrix:(ZXByteMatrix *)matrix error:(NSError **)error {
+ ZXBitArray *typeInfoBits = [[ZXBitArray alloc] init];
+ if (![self makeTypeInfoBits:ecLevel maskPattern:maskPattern bits:typeInfoBits error:error]) {
+ return NO;
+ }
+
+ for (int i = 0; i < [typeInfoBits size]; ++i) {
+ // Place bits in LSB to MSB order. LSB (least significant bit) is the last value in
+ // "typeInfoBits".
+ BOOL bit = [typeInfoBits get:[typeInfoBits size] - 1 - i];
+
+ // Type info bits at the left top corner. See 8.9 of JISX0510:2004 (p.46).
+ int x1 = TYPE_INFO_COORDINATES[i][0];
+ int y1 = TYPE_INFO_COORDINATES[i][1];
+ [matrix setX:x1 y:y1 boolValue:bit];
+
+ if (i < 8) {
+ // Right top corner.
+ int x2 = [matrix width] - i - 1;
+ int y2 = 8;
+ [matrix setX:x2 y:y2 boolValue:bit];
+ } else {
+ // Left bottom corner.
+ int x2 = 8;
+ int y2 = [matrix height] - 7 + (i - 8);
+ [matrix setX:x2 y:y2 boolValue:bit];
+ }
+ }
+
+ return YES;
+}
+
+// Embed version information if need be. On success, modify the matrix and return true.
+// See 8.10 of JISX0510:2004 (p.47) for how to embed version information.
++ (BOOL)maybeEmbedVersionInfo:(ZXQRCodeVersion *)version matrix:(ZXByteMatrix *)matrix error:(NSError **)error {
+ if (version.versionNumber < 7) { // Version info is necessary if version >= 7.
+ return YES; // Don't need version info.
+ }
+ ZXBitArray *versionInfoBits = [[ZXBitArray alloc] init];
+ if (![self makeVersionInfoBits:version bits:versionInfoBits error:error]) {
+ return NO;
+ }
+
+ int bitIndex = 6 * 3 - 1; // It will decrease from 17 to 0.
+ for (int i = 0; i < 6; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ // Place bits in LSB (least significant bit) to MSB order.
+ BOOL bit = [versionInfoBits get:bitIndex];
+ bitIndex--;
+ // Left bottom corner.
+ [matrix setX:i y:[matrix height] - 11 + j boolValue:bit];
+ // Right bottom corner.
+ [matrix setX:[matrix height] - 11 + j y:i boolValue:bit];
+ }
+ }
+
+ return YES;
+}
+
+// Embed "dataBits" using "getMaskPattern". On success, modify the matrix and return true.
+// For debugging purposes, it skips masking process if "getMaskPattern" is -1.
+// See 8.7 of JISX0510:2004 (p.38) for how to embed data bits.
++ (BOOL)embedDataBits:(ZXBitArray *)dataBits maskPattern:(int)maskPattern matrix:(ZXByteMatrix *)matrix error:(NSError **)error {
+ int bitIndex = 0;
+ int direction = -1;
+ // Start from the right bottom cell.
+ int x = [matrix width] - 1;
+ int y = [matrix height] - 1;
+ while (x > 0) {
+ // Skip the vertical timing pattern.
+ if (x == 6) {
+ x -= 1;
+ }
+ while (y >= 0 && y < [matrix height]) {
+ for (int i = 0; i < 2; ++i) {
+ int xx = x - i;
+ // Skip the cell if it's not empty.
+ if (![self isEmpty:[matrix getX:xx y:y]]) {
+ continue;
+ }
+ BOOL bit;
+ if (bitIndex < [dataBits size]) {
+ bit = [dataBits get:bitIndex];
+ ++bitIndex;
+ } else {
+ // Padding bit. If there is no bit left, we'll fill the left cells with 0, as described
+ // in 8.4.9 of JISX0510:2004 (p. 24).
+ bit = NO;
+ }
+
+ // Skip masking if mask_pattern is -1.
+ if (maskPattern != -1 && [ZXMaskUtil dataMaskBit:maskPattern x:xx y:y]) {
+ bit = !bit;
+ }
+ [matrix setX:xx y:y boolValue:bit];
+ }
+ y += direction;
+ }
+ direction = -direction; // Reverse the direction.
+ y += direction;
+ x -= 2; // Move to the left.
+ }
+ // All bits should be consumed.
+ if (bitIndex != [dataBits size]) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Not all bits consumed: %d/%d", bitIndex, [dataBits size]]};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:userInfo];
+ return NO;
+ }
+
+ return YES;
+}
+
+// Return the position of the most significant bit set (to one) in the "value". The most
+// significant bit is position 32. If there is no bit set, return 0. Examples:
+// - findMSBSet(0) => 0
+// - findMSBSet(1) => 1
+// - findMSBSet(255) => 8
++ (int)findMSBSet:(int)value {
+ int numDigits = 0;
+ while (value != 0) {
+ value = (int)((unsigned int)value >> 1);
+ ++numDigits;
+ }
+ return numDigits;
+}
+
+// Calculate BCH (Bose-Chaudhuri-Hocquenghem) code for "value" using polynomial "poly". The BCH
+// code is used for encoding type information and version information.
+// Example: Calculation of version information of 7.
+// f(x) is created from 7.
+// - 7 = 000111 in 6 bits
+// - f(x) = x^2 + x^1 + x^0
+// g(x) is given by the standard (p. 67)
+// - g(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1
+// Multiply f(x) by x^(18 - 6)
+// - f'(x) = f(x) * x^(18 - 6)
+// - f'(x) = x^14 + x^13 + x^12
+// Calculate the remainder of f'(x) / g(x)
+// x^2
+// __________________________________________________
+// g(x) )x^14 + x^13 + x^12
+// x^14 + x^13 + x^12 + x^11 + x^10 + x^7 + x^4 + x^2
+// --------------------------------------------------
+// x^11 + x^10 + x^7 + x^4 + x^2
+//
+// The remainder is x^11 + x^10 + x^7 + x^4 + x^2
+// Encode it in binary: 110010010100
+// The return value is 0xc94 (1100 1001 0100)
+//
+// Since all coefficients in the polynomials are 1 or 0, we can do the calculation by bit
+// operations. We don't care if cofficients are positive or negative.
++ (int)calculateBCHCode:(int)value poly:(int)poly {
+ // If poly is "1 1111 0010 0101" (version info poly), msbSetInPoly is 13. We'll subtract 1
+ // from 13 to make it 12.
+ int msbSetInPoly = [self findMSBSet:poly];
+ value <<= msbSetInPoly - 1;
+ // Do the division business using exclusive-or operations.
+ while ([self findMSBSet:value] >= msbSetInPoly) {
+ value ^= poly << ([self findMSBSet:value] - msbSetInPoly);
+ }
+ // Now the "value" is the remainder (i.e. the BCH code)
+ return value;
+}
+
+// Make bit vector of type information. On success, store the result in "bits" and return true.
+// Encode error correction level and mask pattern. See 8.9 of
+// JISX0510:2004 (p.45) for details.
++ (BOOL)makeTypeInfoBits:(ZXErrorCorrectionLevel *)ecLevel maskPattern:(int)maskPattern bits:(ZXBitArray *)bits error:(NSError **)error {
+ if (![ZXQRCode isValidMaskPattern:maskPattern]) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Invalid mask pattern"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:userInfo];
+ return NO;
+ }
+ int typeInfo = ([ecLevel bits] << 3) | maskPattern;
+ [bits appendBits:typeInfo numBits:5];
+
+ int bchCode = [self calculateBCHCode:typeInfo poly:TYPE_INFO_POLY];
+ [bits appendBits:bchCode numBits:10];
+
+ ZXBitArray *maskBits = [[ZXBitArray alloc] init];
+ [maskBits appendBits:TYPE_INFO_MASK_PATTERN numBits:15];
+ [bits xor:maskBits];
+
+ if ([bits size] != 15) { // Just in case.
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"should not happen but we got: %d", [bits size]]};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:userInfo];
+ return NO;
+ }
+
+ return YES;
+}
+
+// Make bit vector of version information. On success, store the result in "bits" and return true.
+// See 8.10 of JISX0510:2004 (p.45) for details.
++ (BOOL)makeVersionInfoBits:(ZXQRCodeVersion *)version bits:(ZXBitArray *)bits error:(NSError **)error {
+ [bits appendBits:version.versionNumber numBits:6];
+ int bchCode = [self calculateBCHCode:version.versionNumber poly:VERSION_INFO_POLY];
+ [bits appendBits:bchCode numBits:12];
+
+ if ([bits size] != 18) { // Just in case.
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"should not happen but we got: %d", [bits size]]};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:userInfo];
+ return NO;
+ }
+
+ return YES;
+}
+
+// Check if "value" is empty.
++ (BOOL)isEmpty:(int)value {
+ return value == -1;
+}
+
++ (void)embedTimingPatterns:(ZXByteMatrix *)matrix {
+ // -8 is for skipping position detection patterns (size 7), and two horizontal/vertical
+ // separation patterns (size 1). Thus, 8 = 7 + 1.
+ for (int i = 8; i < [matrix width] - 8; ++i) {
+ int bit = (i + 1) % 2;
+ // Horizontal line.
+ if ([self isEmpty:[matrix getX:i y:6]]) {
+ [matrix setX:i y:6 boolValue:bit];
+ }
+ // Vertical line.
+ if ([self isEmpty:[matrix getX:6 y:i]]) {
+ [matrix setX:6 y:i boolValue:bit];
+ }
+ }
+}
+
+// Embed the lonely dark dot at left bottom corner. JISX0510:2004 (p.46)
++ (BOOL)embedDarkDotAtLeftBottomCorner:(ZXByteMatrix *)matrix {
+ if ([matrix getX:8 y:matrix.height - 8] == 0) {
+ return NO;
+ }
+ [matrix setX:8 y:matrix.height - 8 intValue:1];
+
+ return YES;
+}
+
++ (BOOL)embedHorizontalSeparationPattern:(int)xStart yStart:(int)yStart matrix:(ZXByteMatrix *)matrix {
+ for (int x = 0; x < 8; ++x) {
+ if (![self isEmpty:[matrix getX:xStart + x y:yStart]]) {
+ return NO;
+ }
+ [matrix setX:xStart + x y:yStart intValue:0];
+ }
+
+ return YES;
+}
+
++ (BOOL)embedVerticalSeparationPattern:(int)xStart yStart:(int)yStart matrix:(ZXByteMatrix *)matrix {
+ for (int y = 0; y < 7; ++y) {
+ if (![self isEmpty:[matrix getX:xStart y:yStart + y]]) {
+ return NO;
+ }
+ [matrix setX:xStart y:yStart + y intValue:0];
+ }
+
+ return YES;
+}
+
+// Note that we cannot unify the function with embedPositionDetectionPattern() despite they are
+// almost identical, since we cannot write a function that takes 2D arrays in different sizes in
+// C/C++. We should live with the fact.
++ (void)embedPositionAdjustmentPattern:(int)xStart yStart:(int)yStart matrix:(ZXByteMatrix *)matrix {
+ for (int y = 0; y < 5; ++y) {
+ for (int x = 0; x < 5; ++x) {
+ [matrix setX:xStart + x y:yStart + y intValue:POSITION_ADJUSTMENT_PATTERN[y][x]];
+ }
+ }
+}
+
++ (void)embedPositionDetectionPattern:(int)xStart yStart:(int)yStart matrix:(ZXByteMatrix *)matrix {
+ for (int y = 0; y < 7; ++y) {
+ for (int x = 0; x < 7; ++x) {
+ [matrix setX:xStart + x y:yStart + y intValue:POSITION_DETECTION_PATTERN[y][x]];
+ }
+ }
+}
+
+// Embed position detection patterns and surrounding vertical/horizontal separators.
++ (BOOL)embedPositionDetectionPatternsAndSeparators:(ZXByteMatrix *)matrix {
+ // Embed three big squares at corners.
+ int pdpWidth = sizeof(POSITION_DETECTION_PATTERN[0]) / sizeof(int);
+ // Left top corner.
+ [self embedPositionDetectionPattern:0 yStart:0 matrix:matrix];
+ // Right top corner.
+ [self embedPositionDetectionPattern:[matrix width] - pdpWidth yStart:0 matrix:matrix];
+ // Left bottom corner.
+ [self embedPositionDetectionPattern:0 yStart:[matrix width] - pdpWidth matrix:matrix];
+
+ // Embed horizontal separation patterns around the squares.
+ int hspWidth = 8;
+ // Left top corner.
+ [self embedHorizontalSeparationPattern:0 yStart:hspWidth - 1 matrix:matrix];
+ // Right top corner.
+ [self embedHorizontalSeparationPattern:[matrix width] - hspWidth yStart:hspWidth - 1 matrix:matrix];
+ // Left bottom corner.
+ [self embedHorizontalSeparationPattern:0 yStart:[matrix width] - hspWidth matrix:matrix];
+
+ // Embed vertical separation patterns around the squares.
+ int vspSize = 7;
+ // Left top corner.
+ if (![self embedVerticalSeparationPattern:vspSize yStart:0 matrix:matrix]) {
+ return NO;
+ }
+ // Right top corner.
+ if (![self embedVerticalSeparationPattern:[matrix height] - vspSize - 1 yStart:0 matrix:matrix]) {
+ return NO;
+ }
+ // Left bottom corner.
+ if (![self embedVerticalSeparationPattern:vspSize yStart:[matrix height] - vspSize matrix:matrix]) {
+ return NO;
+ }
+
+ return YES;
+}
+
+// Embed position adjustment patterns if need be.
++ (void)maybeEmbedPositionAdjustmentPatterns:(ZXQRCodeVersion *)version matrix:(ZXByteMatrix *)matrix {
+ if (version.versionNumber < 2) { // The patterns appear if version >= 2
+ return;
+ }
+ int index = version.versionNumber - 1;
+ int numCoordinates = sizeof(POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index]) / sizeof(int);
+ for (int i = 0; i < numCoordinates; ++i) {
+ for (int j = 0; j < numCoordinates; ++j) {
+ int y = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][i];
+ int x = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][j];
+ if (x == -1 || y == -1) {
+ continue;
+ }
+ // If the cell is unset, we embed the position adjustment pattern here.
+ if ([self isEmpty:[matrix getX:x y:y]]) {
+ // -2 is necessary since the x/y coordinates point to the center of the pattern, not the
+ // left top corner.
+ [self embedPositionAdjustmentPattern:x - 2 yStart:y - 2 matrix:matrix];
+ }
+ }
+ }
+}
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXQRCode.h b/ZXingObjC/qrcode/encoder/ZXQRCode.h
new file mode 100644
index 0000000..45629b1
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXQRCode.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+extern int const NUM_MASK_PATTERNS;
+
+@class ZXByteMatrix, ZXErrorCorrectionLevel, ZXMode, ZXQRCodeVersion;
+
+@interface ZXQRCode : NSObject
+
+@property (nonatomic, strong) ZXMode *mode;
+@property (nonatomic, strong) ZXErrorCorrectionLevel *ecLevel;
+@property (nonatomic, strong) ZXQRCodeVersion *version;
+@property (nonatomic, assign) int maskPattern;
+@property (nonatomic, strong) ZXByteMatrix *matrix;
+
++ (BOOL)isValidMaskPattern:(int)maskPattern;
+
+@end
diff --git a/ZXingObjC/qrcode/encoder/ZXQRCode.m b/ZXingObjC/qrcode/encoder/ZXQRCode.m
new file mode 100644
index 0000000..97ad51a
--- /dev/null
+++ b/ZXingObjC/qrcode/encoder/ZXQRCode.m
@@ -0,0 +1,58 @@
+/*
+ * 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 "ZXByteMatrix.h"
+#import "ZXErrorCorrectionLevel.h"
+#import "ZXMode.h"
+#import "ZXQRCode.h"
+
+int const NUM_MASK_PATTERNS = 8;
+
+@implementation ZXQRCode
+
+- (id)init {
+ if (self = [super init]) {
+ _mode = nil;
+ _ecLevel = nil;
+ _version = nil;
+ _maskPattern = -1;
+ _matrix = nil;
+ }
+
+ return self;
+}
+
+- (NSString *)description {
+ NSMutableString *result = [NSMutableString stringWithCapacity:200];
+ [result appendFormat:@"<<\n mode: %@", self.mode];
+ [result appendFormat:@"\n ecLevel: %@", self.ecLevel];
+ [result appendFormat:@"\n version: %@", self.version];
+ [result appendFormat:@"\n maskPattern: %d", self.maskPattern];
+ if (self.matrix == nil) {
+ [result appendString:@"\n matrix: (null)\n"];
+ } else {
+ [result appendFormat:@"\n matrix:\n%@", [self.matrix description]];
+ }
+ [result appendString:@">>\n"];
+ return [NSString stringWithString:result];
+}
+
+// Check if "mask_pattern" is valid.
++ (BOOL)isValidMaskPattern:(int)maskPattern {
+ return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS;
+}
+
+@end
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/fail-1.jpg b/ZXingObjCTests/Resources/benchmark/android-1/fail-1.jpg
new file mode 100755
index 0000000..72699a1
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/fail-1.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/fail-2.jpg b/ZXingObjCTests/Resources/benchmark/android-1/fail-2.jpg
new file mode 100755
index 0000000..8f403d8
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/fail-2.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/fail-3.jpg b/ZXingObjCTests/Resources/benchmark/android-1/fail-3.jpg
new file mode 100755
index 0000000..1db5b5c
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/fail-3.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/fail-4.jpg b/ZXingObjCTests/Resources/benchmark/android-1/fail-4.jpg
new file mode 100755
index 0000000..d603504
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/fail-4.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/qrcode-1.jpg b/ZXingObjCTests/Resources/benchmark/android-1/qrcode-1.jpg
new file mode 100755
index 0000000..2324d62
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/qrcode-1.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/qrcode-2.jpg b/ZXingObjCTests/Resources/benchmark/android-1/qrcode-2.jpg
new file mode 100755
index 0000000..67dad51
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/qrcode-2.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/qrcode-3.jpg b/ZXingObjCTests/Resources/benchmark/android-1/qrcode-3.jpg
new file mode 100755
index 0000000..d3d75c4
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/qrcode-3.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/qrcode-4.jpg b/ZXingObjCTests/Resources/benchmark/android-1/qrcode-4.jpg
new file mode 100755
index 0000000..6ec3cd5
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/qrcode-4.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/upca-1.jpg b/ZXingObjCTests/Resources/benchmark/android-1/upca-1.jpg
new file mode 100755
index 0000000..982f43a
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/upca-1.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/upca-2.jpg b/ZXingObjCTests/Resources/benchmark/android-1/upca-2.jpg
new file mode 100755
index 0000000..d02d642
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/upca-2.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-1/upca-3.jpg b/ZXingObjCTests/Resources/benchmark/android-1/upca-3.jpg
new file mode 100755
index 0000000..b0d8949
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-1/upca-3.jpg
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/code128-1.png b/ZXingObjCTests/Resources/benchmark/android-2/code128-1.png
new file mode 100755
index 0000000..d916dd5
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/code128-1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/code39-1.png b/ZXingObjCTests/Resources/benchmark/android-2/code39-1.png
new file mode 100755
index 0000000..300ba7e
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/code39-1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/datamatrix-1.png b/ZXingObjCTests/Resources/benchmark/android-2/datamatrix-1.png
new file mode 100755
index 0000000..53628a1
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/datamatrix-1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/ean13-1.png b/ZXingObjCTests/Resources/benchmark/android-2/ean13-1.png
new file mode 100755
index 0000000..9847b5b
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/ean13-1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/fail-1.png b/ZXingObjCTests/Resources/benchmark/android-2/fail-1.png
new file mode 100755
index 0000000..242f103
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/fail-1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/fail-2.png b/ZXingObjCTests/Resources/benchmark/android-2/fail-2.png
new file mode 100755
index 0000000..290c86c
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/fail-2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/fail-3.png b/ZXingObjCTests/Resources/benchmark/android-2/fail-3.png
new file mode 100755
index 0000000..ef96f80
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/fail-3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/itf-1.png b/ZXingObjCTests/Resources/benchmark/android-2/itf-1.png
new file mode 100755
index 0000000..da70250
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/itf-1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/pdf417-1.png b/ZXingObjCTests/Resources/benchmark/android-2/pdf417-1.png
new file mode 100755
index 0000000..5a5c37f
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/pdf417-1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/qrcode-1.png b/ZXingObjCTests/Resources/benchmark/android-2/qrcode-1.png
new file mode 100755
index 0000000..8ef4db6
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/qrcode-1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/benchmark/android-2/upca-1.png b/ZXingObjCTests/Resources/benchmark/android-2/upca-1.png
new file mode 100755
index 0000000..24f764e
--- /dev/null
+++ b/ZXingObjCTests/Resources/benchmark/android-2/upca-1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/README b/ZXingObjCTests/Resources/blackbox/README
new file mode 100644
index 0000000..387f12d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/README
@@ -0,0 +1 @@
+Thanks to Enrique G-S for contributing many of the EAN-13 test images.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/7.png b/ZXingObjCTests/Resources/blackbox/aztec-1/7.png
new file mode 100644
index 0000000..2c7cfe8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/7.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/7.txt
new file mode 100644
index 0000000..b83fc50
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/7.txt
@@ -0,0 +1 @@
+Code 2D!
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/Historico.png b/ZXingObjCTests/Resources/blackbox/aztec-1/Historico.png
new file mode 100644
index 0000000..3fe2bd0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/Historico.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/Historico.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/Historico.txt
new file mode 100644
index 0000000..73d59fa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/Historico.txt
@@ -0,0 +1 @@
+Histórico
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/HistoricoLong.png b/ZXingObjCTests/Resources/blackbox/aztec-1/HistoricoLong.png
new file mode 100644
index 0000000..18103e6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/HistoricoLong.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/HistoricoLong.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/HistoricoLong.txt
new file mode 100644
index 0000000..6ffe3b7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/HistoricoLong.txt
@@ -0,0 +1 @@
+Históóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóóórico
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/abc-19x19C.png b/ZXingObjCTests/Resources/blackbox/aztec-1/abc-19x19C.png
new file mode 100644
index 0000000..ffc782a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/abc-19x19C.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/abc-19x19C.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/abc-19x19C.txt
new file mode 100644
index 0000000..e85d5b4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/abc-19x19C.txt
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwxyz
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/abc-37x37.png b/ZXingObjCTests/Resources/blackbox/aztec-1/abc-37x37.png
new file mode 100644
index 0000000..3739189
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/abc-37x37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/abc-37x37.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/abc-37x37.txt
new file mode 100644
index 0000000..f5a90a5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/abc-37x37.txt
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-075x075.png b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-075x075.png
new file mode 100644
index 0000000..139282a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-075x075.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-075x075.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-075x075.txt
new file mode 100644
index 0000000..9b04afb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-075x075.txt
@@ -0,0 +1 @@
+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. Donec ac nunc sodales elit placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu tristique ac, p
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-105x105.png b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-105x105.png
new file mode 100644
index 0000000..f630e16
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-105x105.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-105x105.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-105x105.txt
new file mode 100644
index 0000000..893acaf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-105x105.txt
@@ -0,0 +1 @@
+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. Donec ac nunc sodales elit placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu tristique ac, p.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. Donec ac nunc sodales elit placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu tristique ac, p
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-151x151.png b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-151x151.png
new file mode 100644
index 0000000..c37468b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-151x151.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-151x151.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-151x151.txt
new file mode 100644
index 0000000..ab683d7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/lorem-151x151.txt
@@ -0,0 +1 @@
+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. Donec ac nunc sodales elit placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu tristique ac, p.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. Donec ac nunc sodales elit placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu tristique ac, p. 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. Donec ac nunc sodales elit placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu tristique ac, p.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. Donec ac nunc sodales elit placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu tris. 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.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/tableShifts.png b/ZXingObjCTests/Resources/blackbox/aztec-1/tableShifts.png
new file mode 100644
index 0000000..6e3b086
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/tableShifts.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/tableShifts.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/tableShifts.txt
new file mode 100644
index 0000000..d23102f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/tableShifts.txt
@@ -0,0 +1 @@
+AhUUDgdy672;..:8KjHH776JHHn3g. 8lm/%22Nn873R2897ks4JKDJ9JJaza2323!::;09UJRrhDQSKJDKdSJSdskjdslkEdjseze:ze
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/tag.png b/ZXingObjCTests/Resources/blackbox/aztec-1/tag.png
new file mode 100644
index 0000000..e969da5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/tag.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/tag.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/tag.txt
new file mode 100644
index 0000000..029a248
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/tag.txt
@@ -0,0 +1 @@
+Ceci est un tag.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/texte.png b/ZXingObjCTests/Resources/blackbox/aztec-1/texte.png
new file mode 100644
index 0000000..3c6a7c9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/texte.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-1/texte.txt b/ZXingObjCTests/Resources/blackbox/aztec-1/texte.txt
new file mode 100644
index 0000000..d716a9f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-1/texte.txt
@@ -0,0 +1 @@
+Ceci est un texte!
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/01.png b/ZXingObjCTests/Resources/blackbox/aztec-2/01.png
new file mode 100755
index 0000000..4e91dc2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/01.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/01.txt
new file mode 100644
index 0000000..60a24c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/01.txt
@@ -0,0 +1 @@
+This is a real world Aztec barcode test.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/02.png b/ZXingObjCTests/Resources/blackbox/aztec-2/02.png
new file mode 100755
index 0000000..0385104
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/02.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/02.txt
new file mode 100644
index 0000000..60a24c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/02.txt
@@ -0,0 +1 @@
+This is a real world Aztec barcode test.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/03.png b/ZXingObjCTests/Resources/blackbox/aztec-2/03.png
new file mode 100755
index 0000000..51d9fe6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/03.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/03.txt
new file mode 100644
index 0000000..60a24c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/03.txt
@@ -0,0 +1 @@
+This is a real world Aztec barcode test.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/04.png b/ZXingObjCTests/Resources/blackbox/aztec-2/04.png
new file mode 100755
index 0000000..34ed31c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/04.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/04.txt
new file mode 100644
index 0000000..60a24c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/04.txt
@@ -0,0 +1 @@
+This is a real world Aztec barcode test.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/05.png b/ZXingObjCTests/Resources/blackbox/aztec-2/05.png
new file mode 100755
index 0000000..48d0bda
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/05.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/05.txt
new file mode 100644
index 0000000..60a24c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/05.txt
@@ -0,0 +1 @@
+This is a real world Aztec barcode test.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/06.png b/ZXingObjCTests/Resources/blackbox/aztec-2/06.png
new file mode 100755
index 0000000..9f6f6cb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/06.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/06.txt
new file mode 100644
index 0000000..60a24c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/06.txt
@@ -0,0 +1 @@
+This is a real world Aztec barcode test.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/07.png b/ZXingObjCTests/Resources/blackbox/aztec-2/07.png
new file mode 100755
index 0000000..3705ae3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/07.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/07.txt
new file mode 100644
index 0000000..60a24c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/07.txt
@@ -0,0 +1 @@
+This is a real world Aztec barcode test.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/08.png b/ZXingObjCTests/Resources/blackbox/aztec-2/08.png
new file mode 100755
index 0000000..df07690
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/08.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/08.txt
new file mode 100644
index 0000000..60a24c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/08.txt
@@ -0,0 +1 @@
+This is a real world Aztec barcode test.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/09.png b/ZXingObjCTests/Resources/blackbox/aztec-2/09.png
new file mode 100755
index 0000000..87b5c99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/09.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/09.txt
new file mode 100644
index 0000000..30afa17
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/09.txt
@@ -0,0 +1 @@
+mailto:zxing@googlegroups.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/10.png b/ZXingObjCTests/Resources/blackbox/aztec-2/10.png
new file mode 100755
index 0000000..830d38f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/10.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/10.txt
new file mode 100644
index 0000000..30afa17
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/10.txt
@@ -0,0 +1 @@
+mailto:zxing@googlegroups.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/11.png b/ZXingObjCTests/Resources/blackbox/aztec-2/11.png
new file mode 100755
index 0000000..650f682
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/11.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/11.txt
new file mode 100644
index 0000000..30afa17
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/11.txt
@@ -0,0 +1 @@
+mailto:zxing@googlegroups.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/12.png b/ZXingObjCTests/Resources/blackbox/aztec-2/12.png
new file mode 100755
index 0000000..a38e6f6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/12.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/12.txt
new file mode 100644
index 0000000..30afa17
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/12.txt
@@ -0,0 +1 @@
+mailto:zxing@googlegroups.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/13.png b/ZXingObjCTests/Resources/blackbox/aztec-2/13.png
new file mode 100755
index 0000000..c08006c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/13.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/13.txt
new file mode 100644
index 0000000..30afa17
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/13.txt
@@ -0,0 +1 @@
+mailto:zxing@googlegroups.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/14.png b/ZXingObjCTests/Resources/blackbox/aztec-2/14.png
new file mode 100755
index 0000000..bfce4e6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/14.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/14.txt
new file mode 100644
index 0000000..30afa17
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/14.txt
@@ -0,0 +1 @@
+mailto:zxing@googlegroups.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/15.png b/ZXingObjCTests/Resources/blackbox/aztec-2/15.png
new file mode 100755
index 0000000..b62bf4d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/15.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/15.txt
new file mode 100644
index 0000000..30afa17
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/15.txt
@@ -0,0 +1 @@
+mailto:zxing@googlegroups.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/16.png b/ZXingObjCTests/Resources/blackbox/aztec-2/16.png
new file mode 100755
index 0000000..ce1cfde
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/16.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/16.txt
new file mode 100644
index 0000000..8399dfe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/16.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/result/URIResultHandler.java
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/17.png b/ZXingObjCTests/Resources/blackbox/aztec-2/17.png
new file mode 100755
index 0000000..c3ecf49
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/17.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/17.txt
new file mode 100644
index 0000000..8399dfe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/17.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/result/URIResultHandler.java
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/18.png b/ZXingObjCTests/Resources/blackbox/aztec-2/18.png
new file mode 100755
index 0000000..ed20f46
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/18.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/18.txt
new file mode 100644
index 0000000..8399dfe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/18.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/result/URIResultHandler.java
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/19.png b/ZXingObjCTests/Resources/blackbox/aztec-2/19.png
new file mode 100755
index 0000000..0103a9f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/19.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/19.txt
new file mode 100644
index 0000000..8399dfe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/19.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/result/URIResultHandler.java
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/20.png b/ZXingObjCTests/Resources/blackbox/aztec-2/20.png
new file mode 100755
index 0000000..9475e6b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/20.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/20.txt
new file mode 100644
index 0000000..8399dfe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/20.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/result/URIResultHandler.java
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/21.png b/ZXingObjCTests/Resources/blackbox/aztec-2/21.png
new file mode 100755
index 0000000..ff5d143
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/21.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/21.txt
new file mode 100644
index 0000000..8399dfe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/21.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/result/URIResultHandler.java
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/22.png b/ZXingObjCTests/Resources/blackbox/aztec-2/22.png
new file mode 100755
index 0000000..2d96c9d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/aztec-2/22.txt b/ZXingObjCTests/Resources/blackbox/aztec-2/22.txt
new file mode 100644
index 0000000..8399dfe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/aztec-2/22.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/result/URIResultHandler.java
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/01.png b/ZXingObjCTests/Resources/blackbox/codabar-1/01.png
new file mode 100644
index 0000000..9b5f504
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/01.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/01.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/01.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/02.png b/ZXingObjCTests/Resources/blackbox/codabar-1/02.png
new file mode 100644
index 0000000..f0c25ff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/02.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/02.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/02.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/03.png b/ZXingObjCTests/Resources/blackbox/codabar-1/03.png
new file mode 100644
index 0000000..2a6bf91
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/03.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/03.txt
new file mode 100644
index 0000000..b8ec6e4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/03.txt
@@ -0,0 +1 @@
+294/586
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/04.png b/ZXingObjCTests/Resources/blackbox/codabar-1/04.png
new file mode 100644
index 0000000..d0fb5c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/04.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/04.txt
new file mode 100644
index 0000000..cf537db
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/04.txt
@@ -0,0 +1 @@
+123455
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/09.png b/ZXingObjCTests/Resources/blackbox/codabar-1/09.png
new file mode 100644
index 0000000..549d50a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/09.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/09.txt
new file mode 100644
index 0000000..bd41cba
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/09.txt
@@ -0,0 +1 @@
+12345
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/10.png b/ZXingObjCTests/Resources/blackbox/codabar-1/10.png
new file mode 100644
index 0000000..290d467
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/10.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/10.txt
new file mode 100644
index 0000000..4632e06
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/10.txt
@@ -0,0 +1 @@
+123456
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/11.png b/ZXingObjCTests/Resources/blackbox/codabar-1/11.png
new file mode 100644
index 0000000..3a05c3e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/11.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/11.txt
new file mode 100644
index 0000000..675525a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/11.txt
@@ -0,0 +1 @@
+3419500
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/12.png b/ZXingObjCTests/Resources/blackbox/codabar-1/12.png
new file mode 100644
index 0000000..45d7995
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/12.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/12.txt
new file mode 100644
index 0000000..8782ad7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/12.txt
@@ -0,0 +1 @@
+31117013206375
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/13.png b/ZXingObjCTests/Resources/blackbox/codabar-1/13.png
new file mode 100644
index 0000000..c78270c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/13.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/13.txt
new file mode 100644
index 0000000..bd41cba
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/13.txt
@@ -0,0 +1 @@
+12345
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/14.png b/ZXingObjCTests/Resources/blackbox/codabar-1/14.png
new file mode 100644
index 0000000..d034407
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/14.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/14.txt
new file mode 100644
index 0000000..8782ad7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/14.txt
@@ -0,0 +1 @@
+31117013206375
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/15.png b/ZXingObjCTests/Resources/blackbox/codabar-1/15.png
new file mode 100644
index 0000000..ab82e04
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/codabar-1/15.txt b/ZXingObjCTests/Resources/blackbox/codabar-1/15.txt
new file mode 100644
index 0000000..4d38188
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/codabar-1/15.txt
@@ -0,0 +1 @@
+123456789012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/1.png b/ZXingObjCTests/Resources/blackbox/code128-1/1.png
new file mode 100644
index 0000000..6005428
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/1.txt b/ZXingObjCTests/Resources/blackbox/code128-1/1.txt
new file mode 100644
index 0000000..a5aa28d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/1.txt
@@ -0,0 +1 @@
+168901
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/2.png b/ZXingObjCTests/Resources/blackbox/code128-1/2.png
new file mode 100644
index 0000000..4d4f4ba
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/2.txt b/ZXingObjCTests/Resources/blackbox/code128-1/2.txt
new file mode 100644
index 0000000..5d9d0d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/2.txt
@@ -0,0 +1 @@
+Code 128
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/3.png b/ZXingObjCTests/Resources/blackbox/code128-1/3.png
new file mode 100644
index 0000000..da88e52
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/3.txt b/ZXingObjCTests/Resources/blackbox/code128-1/3.txt
new file mode 100644
index 0000000..0bfc696
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/3.txt
@@ -0,0 +1 @@
+102030405060708090
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/4.png b/ZXingObjCTests/Resources/blackbox/code128-1/4.png
new file mode 100644
index 0000000..9d2fff2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/4.txt b/ZXingObjCTests/Resources/blackbox/code128-1/4.txt
new file mode 100644
index 0000000..4632e06
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/4.txt
@@ -0,0 +1 @@
+123456
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/5.png b/ZXingObjCTests/Resources/blackbox/code128-1/5.png
new file mode 100644
index 0000000..ad71ae3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-1/5.txt b/ZXingObjCTests/Resources/blackbox/code128-1/5.txt
new file mode 100644
index 0000000..50bf455
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-1/5.txt
@@ -0,0 +1 @@
+8101054321120021123456
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/01.png b/ZXingObjCTests/Resources/blackbox/code128-2/01.png
new file mode 100644
index 0000000..0a17958
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/01.txt b/ZXingObjCTests/Resources/blackbox/code128-2/01.txt
new file mode 100644
index 0000000..a34fa65
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/01.txt
@@ -0,0 +1 @@
+005-3379497200006
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/02.png b/ZXingObjCTests/Resources/blackbox/code128-2/02.png
new file mode 100644
index 0000000..8773ae9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/02.txt b/ZXingObjCTests/Resources/blackbox/code128-2/02.txt
new file mode 100644
index 0000000..a34fa65
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/02.txt
@@ -0,0 +1 @@
+005-3379497200006
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/03.png b/ZXingObjCTests/Resources/blackbox/code128-2/03.png
new file mode 100644
index 0000000..c1c0372
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/03.txt b/ZXingObjCTests/Resources/blackbox/code128-2/03.txt
new file mode 100644
index 0000000..a34fa65
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/03.txt
@@ -0,0 +1 @@
+005-3379497200006
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/04.png b/ZXingObjCTests/Resources/blackbox/code128-2/04.png
new file mode 100644
index 0000000..c06c62c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/04.txt b/ZXingObjCTests/Resources/blackbox/code128-2/04.txt
new file mode 100644
index 0000000..a34fa65
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/04.txt
@@ -0,0 +1 @@
+005-3379497200006
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/05.png b/ZXingObjCTests/Resources/blackbox/code128-2/05.png
new file mode 100644
index 0000000..06cefb6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/05.txt b/ZXingObjCTests/Resources/blackbox/code128-2/05.txt
new file mode 100644
index 0000000..f8406b6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/05.txt
@@ -0,0 +1 @@
+15182881
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/06.png b/ZXingObjCTests/Resources/blackbox/code128-2/06.png
new file mode 100644
index 0000000..54728e3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/06.txt b/ZXingObjCTests/Resources/blackbox/code128-2/06.txt
new file mode 100644
index 0000000..f8406b6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/06.txt
@@ -0,0 +1 @@
+15182881
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/07.png b/ZXingObjCTests/Resources/blackbox/code128-2/07.png
new file mode 100644
index 0000000..1a2652c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/07.txt b/ZXingObjCTests/Resources/blackbox/code128-2/07.txt
new file mode 100644
index 0000000..f8406b6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/07.txt
@@ -0,0 +1 @@
+15182881
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/08.png b/ZXingObjCTests/Resources/blackbox/code128-2/08.png
new file mode 100644
index 0000000..24a5485
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/08.txt b/ZXingObjCTests/Resources/blackbox/code128-2/08.txt
new file mode 100644
index 0000000..f8406b6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/08.txt
@@ -0,0 +1 @@
+15182881
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/09.png b/ZXingObjCTests/Resources/blackbox/code128-2/09.png
new file mode 100644
index 0000000..e987d68
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/09.txt b/ZXingObjCTests/Resources/blackbox/code128-2/09.txt
new file mode 100644
index 0000000..545c961
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/09.txt
@@ -0,0 +1 @@
+CNK8181G2C
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/10.png b/ZXingObjCTests/Resources/blackbox/code128-2/10.png
new file mode 100644
index 0000000..df6b8db
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/10.txt b/ZXingObjCTests/Resources/blackbox/code128-2/10.txt
new file mode 100644
index 0000000..545c961
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/10.txt
@@ -0,0 +1 @@
+CNK8181G2C
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/11.png b/ZXingObjCTests/Resources/blackbox/code128-2/11.png
new file mode 100644
index 0000000..b604e46
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/11.txt b/ZXingObjCTests/Resources/blackbox/code128-2/11.txt
new file mode 100644
index 0000000..545c961
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/11.txt
@@ -0,0 +1 @@
+CNK8181G2C
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/12.png b/ZXingObjCTests/Resources/blackbox/code128-2/12.png
new file mode 100644
index 0000000..5ea515d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/12.txt b/ZXingObjCTests/Resources/blackbox/code128-2/12.txt
new file mode 100644
index 0000000..545c961
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/12.txt
@@ -0,0 +1 @@
+CNK8181G2C
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/13.png b/ZXingObjCTests/Resources/blackbox/code128-2/13.png
new file mode 100644
index 0000000..fb97e47
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/13.txt b/ZXingObjCTests/Resources/blackbox/code128-2/13.txt
new file mode 100644
index 0000000..3e4497e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/13.txt
@@ -0,0 +1 @@
+1PEF224A4
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/14.png b/ZXingObjCTests/Resources/blackbox/code128-2/14.png
new file mode 100644
index 0000000..93e597e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/14.txt b/ZXingObjCTests/Resources/blackbox/code128-2/14.txt
new file mode 100644
index 0000000..3e4497e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/14.txt
@@ -0,0 +1 @@
+1PEF224A4
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/15.png b/ZXingObjCTests/Resources/blackbox/code128-2/15.png
new file mode 100644
index 0000000..21777a1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/15.txt b/ZXingObjCTests/Resources/blackbox/code128-2/15.txt
new file mode 100644
index 0000000..3e4497e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/15.txt
@@ -0,0 +1 @@
+1PEF224A4
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/16.png b/ZXingObjCTests/Resources/blackbox/code128-2/16.png
new file mode 100644
index 0000000..93d0790
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/16.txt b/ZXingObjCTests/Resources/blackbox/code128-2/16.txt
new file mode 100644
index 0000000..3e4497e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/16.txt
@@ -0,0 +1 @@
+1PEF224A4
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/17.png b/ZXingObjCTests/Resources/blackbox/code128-2/17.png
new file mode 100644
index 0000000..5772376
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/17.txt b/ZXingObjCTests/Resources/blackbox/code128-2/17.txt
new file mode 100644
index 0000000..75824d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/17.txt
@@ -0,0 +1 @@
+FW727
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/18.png b/ZXingObjCTests/Resources/blackbox/code128-2/18.png
new file mode 100644
index 0000000..068478d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/18.txt b/ZXingObjCTests/Resources/blackbox/code128-2/18.txt
new file mode 100644
index 0000000..75824d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/18.txt
@@ -0,0 +1 @@
+FW727
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/19.png b/ZXingObjCTests/Resources/blackbox/code128-2/19.png
new file mode 100644
index 0000000..b03cc9f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/19.txt b/ZXingObjCTests/Resources/blackbox/code128-2/19.txt
new file mode 100644
index 0000000..75824d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/19.txt
@@ -0,0 +1 @@
+FW727
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/20.png b/ZXingObjCTests/Resources/blackbox/code128-2/20.png
new file mode 100644
index 0000000..e75f3bb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/20.txt b/ZXingObjCTests/Resources/blackbox/code128-2/20.txt
new file mode 100644
index 0000000..75824d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/20.txt
@@ -0,0 +1 @@
+FW727
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/21.png b/ZXingObjCTests/Resources/blackbox/code128-2/21.png
new file mode 100644
index 0000000..626bc5f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/21.txt b/ZXingObjCTests/Resources/blackbox/code128-2/21.txt
new file mode 100644
index 0000000..f093728
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/21.txt
@@ -0,0 +1 @@
+005-3354174500018
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/22.png b/ZXingObjCTests/Resources/blackbox/code128-2/22.png
new file mode 100644
index 0000000..81666ea
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/22.txt b/ZXingObjCTests/Resources/blackbox/code128-2/22.txt
new file mode 100644
index 0000000..f093728
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/22.txt
@@ -0,0 +1 @@
+005-3354174500018
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/23.png b/ZXingObjCTests/Resources/blackbox/code128-2/23.png
new file mode 100644
index 0000000..b2cabfd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/23.txt b/ZXingObjCTests/Resources/blackbox/code128-2/23.txt
new file mode 100644
index 0000000..f093728
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/23.txt
@@ -0,0 +1 @@
+005-3354174500018
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/24.png b/ZXingObjCTests/Resources/blackbox/code128-2/24.png
new file mode 100644
index 0000000..2cf6513
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/24.txt b/ZXingObjCTests/Resources/blackbox/code128-2/24.txt
new file mode 100644
index 0000000..f093728
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/24.txt
@@ -0,0 +1 @@
+005-3354174500018
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/25.png b/ZXingObjCTests/Resources/blackbox/code128-2/25.png
new file mode 100644
index 0000000..d49bc6f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/25.txt b/ZXingObjCTests/Resources/blackbox/code128-2/25.txt
new file mode 100644
index 0000000..ab6367f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/25.txt
@@ -0,0 +1 @@
+31001171800000017989625355702636
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/26.png b/ZXingObjCTests/Resources/blackbox/code128-2/26.png
new file mode 100644
index 0000000..a1d074e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/26.txt b/ZXingObjCTests/Resources/blackbox/code128-2/26.txt
new file mode 100644
index 0000000..ab6367f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/26.txt
@@ -0,0 +1 @@
+31001171800000017989625355702636
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/27.png b/ZXingObjCTests/Resources/blackbox/code128-2/27.png
new file mode 100644
index 0000000..0885124
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/27.txt b/ZXingObjCTests/Resources/blackbox/code128-2/27.txt
new file mode 100644
index 0000000..ab6367f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/27.txt
@@ -0,0 +1 @@
+31001171800000017989625355702636
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/28.png b/ZXingObjCTests/Resources/blackbox/code128-2/28.png
new file mode 100644
index 0000000..83990dc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/28.txt b/ZXingObjCTests/Resources/blackbox/code128-2/28.txt
new file mode 100644
index 0000000..ab6367f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/28.txt
@@ -0,0 +1 @@
+31001171800000017989625355702636
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/29.png b/ZXingObjCTests/Resources/blackbox/code128-2/29.png
new file mode 100644
index 0000000..32a5391
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/29.txt b/ZXingObjCTests/Resources/blackbox/code128-2/29.txt
new file mode 100644
index 0000000..e7d384f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/29.txt
@@ -0,0 +1 @@
+42094043
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/30.png b/ZXingObjCTests/Resources/blackbox/code128-2/30.png
new file mode 100644
index 0000000..bed8eeb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/30.txt b/ZXingObjCTests/Resources/blackbox/code128-2/30.txt
new file mode 100644
index 0000000..e7d384f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/30.txt
@@ -0,0 +1 @@
+42094043
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/31.png b/ZXingObjCTests/Resources/blackbox/code128-2/31.png
new file mode 100644
index 0000000..ce6a050
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/31.txt b/ZXingObjCTests/Resources/blackbox/code128-2/31.txt
new file mode 100644
index 0000000..e7d384f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/31.txt
@@ -0,0 +1 @@
+42094043
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/32.png b/ZXingObjCTests/Resources/blackbox/code128-2/32.png
new file mode 100644
index 0000000..1966591
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/32.txt b/ZXingObjCTests/Resources/blackbox/code128-2/32.txt
new file mode 100644
index 0000000..e7d384f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/32.txt
@@ -0,0 +1 @@
+42094043
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/33.png b/ZXingObjCTests/Resources/blackbox/code128-2/33.png
new file mode 100644
index 0000000..5869313
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/33.txt b/ZXingObjCTests/Resources/blackbox/code128-2/33.txt
new file mode 100644
index 0000000..1e4f8e3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/33.txt
@@ -0,0 +1 @@
+30885909173823
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/34.png b/ZXingObjCTests/Resources/blackbox/code128-2/34.png
new file mode 100644
index 0000000..a957a36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/34.txt b/ZXingObjCTests/Resources/blackbox/code128-2/34.txt
new file mode 100644
index 0000000..1e4f8e3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/34.txt
@@ -0,0 +1 @@
+30885909173823
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/35.png b/ZXingObjCTests/Resources/blackbox/code128-2/35.png
new file mode 100644
index 0000000..47f00f9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/35.txt b/ZXingObjCTests/Resources/blackbox/code128-2/35.txt
new file mode 100644
index 0000000..1e4f8e3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/35.txt
@@ -0,0 +1 @@
+30885909173823
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/36.png b/ZXingObjCTests/Resources/blackbox/code128-2/36.png
new file mode 100644
index 0000000..95841e8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/36.txt b/ZXingObjCTests/Resources/blackbox/code128-2/36.txt
new file mode 100644
index 0000000..1e4f8e3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/36.txt
@@ -0,0 +1 @@
+30885909173823
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/37.png b/ZXingObjCTests/Resources/blackbox/code128-2/37.png
new file mode 100644
index 0000000..005c68d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/37.txt b/ZXingObjCTests/Resources/blackbox/code128-2/37.txt
new file mode 100644
index 0000000..2aa6bce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/37.txt
@@ -0,0 +1 @@
+FGGQ6D1
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/38.png b/ZXingObjCTests/Resources/blackbox/code128-2/38.png
new file mode 100644
index 0000000..13011cc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/38.txt b/ZXingObjCTests/Resources/blackbox/code128-2/38.txt
new file mode 100644
index 0000000..2aa6bce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/38.txt
@@ -0,0 +1 @@
+FGGQ6D1
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/39.png b/ZXingObjCTests/Resources/blackbox/code128-2/39.png
new file mode 100644
index 0000000..d5eb0a9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/39.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/39.txt b/ZXingObjCTests/Resources/blackbox/code128-2/39.txt
new file mode 100644
index 0000000..2aa6bce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/39.txt
@@ -0,0 +1 @@
+FGGQ6D1
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/40.png b/ZXingObjCTests/Resources/blackbox/code128-2/40.png
new file mode 100644
index 0000000..9f91cc8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/40.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-2/40.txt b/ZXingObjCTests/Resources/blackbox/code128-2/40.txt
new file mode 100644
index 0000000..2aa6bce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-2/40.txt
@@ -0,0 +1 @@
+FGGQ6D1
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-3/1.png b/ZXingObjCTests/Resources/blackbox/code128-3/1.png
new file mode 100644
index 0000000..0607a23
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-3/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-3/1.txt b/ZXingObjCTests/Resources/blackbox/code128-3/1.txt
new file mode 100644
index 0000000..f55057e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-3/1.txt
@@ -0,0 +1 @@
+10064908
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code128-3/2.png b/ZXingObjCTests/Resources/blackbox/code128-3/2.png
new file mode 100644
index 0000000..0274a61
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-3/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code128-3/2.txt b/ZXingObjCTests/Resources/blackbox/code128-3/2.txt
new file mode 100644
index 0000000..f2ea59d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code128-3/2.txt
@@ -0,0 +1 @@
+10068408
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-1/1.png b/ZXingObjCTests/Resources/blackbox/code39-1/1.png
new file mode 100644
index 0000000..d2fe31e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-1/1.txt b/ZXingObjCTests/Resources/blackbox/code39-1/1.txt
new file mode 100644
index 0000000..c21ac75
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-1/1.txt
@@ -0,0 +1 @@
+TEST-SHEET
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-1/2.png b/ZXingObjCTests/Resources/blackbox/code39-1/2.png
new file mode 100644
index 0000000..98a5462
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-1/2.txt b/ZXingObjCTests/Resources/blackbox/code39-1/2.txt
new file mode 100644
index 0000000..4ed0aa9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-1/2.txt
@@ -0,0 +1 @@
+ WWW.CITRONSOFT.COM
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-1/3.png b/ZXingObjCTests/Resources/blackbox/code39-1/3.png
new file mode 100644
index 0000000..461a15f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-1/3.txt b/ZXingObjCTests/Resources/blackbox/code39-1/3.txt
new file mode 100644
index 0000000..4e5ac1f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-1/3.txt
@@ -0,0 +1 @@
+MOROVIA
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-1/4.png b/ZXingObjCTests/Resources/blackbox/code39-1/4.png
new file mode 100644
index 0000000..7e917f7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-1/4.txt b/ZXingObjCTests/Resources/blackbox/code39-1/4.txt
new file mode 100644
index 0000000..8edce44
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-1/4.txt
@@ -0,0 +1 @@
+ABC123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-2/1.png b/ZXingObjCTests/Resources/blackbox/code39-2/1.png
new file mode 100644
index 0000000..a7fbb5c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-2/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-2/1.txt b/ZXingObjCTests/Resources/blackbox/code39-2/1.txt
new file mode 100644
index 0000000..40fe1ed
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-2/1.txt
@@ -0,0 +1 @@
+Extended !?*#
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-2/2.png b/ZXingObjCTests/Resources/blackbox/code39-2/2.png
new file mode 100644
index 0000000..77add61
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-2/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-2/2.txt b/ZXingObjCTests/Resources/blackbox/code39-2/2.txt
new file mode 100644
index 0000000..882383b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-2/2.txt
@@ -0,0 +1 @@
+12ab
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/01.png b/ZXingObjCTests/Resources/blackbox/code39-3/01.png
new file mode 100644
index 0000000..8b2891d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/01.txt b/ZXingObjCTests/Resources/blackbox/code39-3/01.txt
new file mode 100644
index 0000000..9fead42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/01.txt
@@ -0,0 +1 @@
+165627
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/02.png b/ZXingObjCTests/Resources/blackbox/code39-3/02.png
new file mode 100644
index 0000000..84ae58b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/02.txt b/ZXingObjCTests/Resources/blackbox/code39-3/02.txt
new file mode 100644
index 0000000..9fead42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/02.txt
@@ -0,0 +1 @@
+165627
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/03.png b/ZXingObjCTests/Resources/blackbox/code39-3/03.png
new file mode 100644
index 0000000..09cf586
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/03.txt b/ZXingObjCTests/Resources/blackbox/code39-3/03.txt
new file mode 100644
index 0000000..ab1000e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/03.txt
@@ -0,0 +1 @@
+001EC947D49B
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/04.png b/ZXingObjCTests/Resources/blackbox/code39-3/04.png
new file mode 100644
index 0000000..21a6edd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/04.txt b/ZXingObjCTests/Resources/blackbox/code39-3/04.txt
new file mode 100644
index 0000000..ab1000e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/04.txt
@@ -0,0 +1 @@
+001EC947D49B
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/05.png b/ZXingObjCTests/Resources/blackbox/code39-3/05.png
new file mode 100644
index 0000000..1959e97
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/05.txt b/ZXingObjCTests/Resources/blackbox/code39-3/05.txt
new file mode 100644
index 0000000..ab1000e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/05.txt
@@ -0,0 +1 @@
+001EC947D49B
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/06.png b/ZXingObjCTests/Resources/blackbox/code39-3/06.png
new file mode 100644
index 0000000..4b5b075
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/06.txt b/ZXingObjCTests/Resources/blackbox/code39-3/06.txt
new file mode 100644
index 0000000..897a2d8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/06.txt
@@ -0,0 +1 @@
+165340
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/07.png b/ZXingObjCTests/Resources/blackbox/code39-3/07.png
new file mode 100644
index 0000000..897b171
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/07.txt b/ZXingObjCTests/Resources/blackbox/code39-3/07.txt
new file mode 100644
index 0000000..897a2d8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/07.txt
@@ -0,0 +1 @@
+165340
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/08.png b/ZXingObjCTests/Resources/blackbox/code39-3/08.png
new file mode 100644
index 0000000..9bc051d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/08.txt b/ZXingObjCTests/Resources/blackbox/code39-3/08.txt
new file mode 100644
index 0000000..897a2d8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/08.txt
@@ -0,0 +1 @@
+165340
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/09.png b/ZXingObjCTests/Resources/blackbox/code39-3/09.png
new file mode 100644
index 0000000..b37ced4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/09.txt b/ZXingObjCTests/Resources/blackbox/code39-3/09.txt
new file mode 100644
index 0000000..897a2d8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/09.txt
@@ -0,0 +1 @@
+165340
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/10.png b/ZXingObjCTests/Resources/blackbox/code39-3/10.png
new file mode 100644
index 0000000..2946604
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/10.txt b/ZXingObjCTests/Resources/blackbox/code39-3/10.txt
new file mode 100644
index 0000000..400ea68
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/10.txt
@@ -0,0 +1 @@
+001EC94767E0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/11.png b/ZXingObjCTests/Resources/blackbox/code39-3/11.png
new file mode 100644
index 0000000..8abfad2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/11.txt b/ZXingObjCTests/Resources/blackbox/code39-3/11.txt
new file mode 100644
index 0000000..400ea68
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/11.txt
@@ -0,0 +1 @@
+001EC94767E0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/12.png b/ZXingObjCTests/Resources/blackbox/code39-3/12.png
new file mode 100644
index 0000000..42d9368
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/12.txt b/ZXingObjCTests/Resources/blackbox/code39-3/12.txt
new file mode 100644
index 0000000..400ea68
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/12.txt
@@ -0,0 +1 @@
+001EC94767E0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/13.png b/ZXingObjCTests/Resources/blackbox/code39-3/13.png
new file mode 100644
index 0000000..722c9ef
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/13.txt b/ZXingObjCTests/Resources/blackbox/code39-3/13.txt
new file mode 100644
index 0000000..400ea68
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/13.txt
@@ -0,0 +1 @@
+001EC94767E0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/14.png b/ZXingObjCTests/Resources/blackbox/code39-3/14.png
new file mode 100644
index 0000000..1be4473
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/14.txt b/ZXingObjCTests/Resources/blackbox/code39-3/14.txt
new file mode 100644
index 0000000..9e87084
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/14.txt
@@ -0,0 +1 @@
+404785
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/15.png b/ZXingObjCTests/Resources/blackbox/code39-3/15.png
new file mode 100644
index 0000000..b292dff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/15.txt b/ZXingObjCTests/Resources/blackbox/code39-3/15.txt
new file mode 100644
index 0000000..9e87084
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/15.txt
@@ -0,0 +1 @@
+404785
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/16.png b/ZXingObjCTests/Resources/blackbox/code39-3/16.png
new file mode 100644
index 0000000..a3255cd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/16.txt b/ZXingObjCTests/Resources/blackbox/code39-3/16.txt
new file mode 100644
index 0000000..9e87084
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/16.txt
@@ -0,0 +1 @@
+404785
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/17.png b/ZXingObjCTests/Resources/blackbox/code39-3/17.png
new file mode 100644
index 0000000..788948f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code39-3/17.txt b/ZXingObjCTests/Resources/blackbox/code39-3/17.txt
new file mode 100644
index 0000000..9e87084
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code39-3/17.txt
@@ -0,0 +1 @@
+404785
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code93-1/1.png b/ZXingObjCTests/Resources/blackbox/code93-1/1.png
new file mode 100644
index 0000000..bc9ef62
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code93-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code93-1/1.txt b/ZXingObjCTests/Resources/blackbox/code93-1/1.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code93-1/1.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code93-1/2.png b/ZXingObjCTests/Resources/blackbox/code93-1/2.png
new file mode 100644
index 0000000..1afbfcb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code93-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code93-1/2.txt b/ZXingObjCTests/Resources/blackbox/code93-1/2.txt
new file mode 100644
index 0000000..f6df9d7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code93-1/2.txt
@@ -0,0 +1 @@
+CODE 93
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/code93-1/3.png b/ZXingObjCTests/Resources/blackbox/code93-1/3.png
new file mode 100644
index 0000000..ea39b8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code93-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/code93-1/3.txt b/ZXingObjCTests/Resources/blackbox/code93-1/3.txt
new file mode 100644
index 0000000..418d6c3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/code93-1/3.txt
@@ -0,0 +1 @@
+DATA
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/0123456789.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/0123456789.png
new file mode 100644
index 0000000..dbe5122
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/0123456789.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/0123456789.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/0123456789.txt
new file mode 100644
index 0000000..ad47100
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/0123456789.txt
@@ -0,0 +1 @@
+0123456789
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/GUID.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/GUID.png
new file mode 100644
index 0000000..183175b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/GUID.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/GUID.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/GUID.txt
new file mode 100644
index 0000000..0a226ac
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/GUID.txt
@@ -0,0 +1 @@
+10f27ce-acb7-4e4e-a7ae-a0b98da6ed4a
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa.png
new file mode 100644
index 0000000..46e0051
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa.txt
new file mode 100644
index 0000000..5e1c309
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_1_error_byte.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_1_error_byte.png
new file mode 100644
index 0000000..223b757
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_1_error_byte.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_1_error_byte.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_1_error_byte.txt
new file mode 100644
index 0000000..5e1c309
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_1_error_byte.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_2_error_byte.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_2_error_byte.png
new file mode 100644
index 0000000..030fa5f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_2_error_byte.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_2_error_byte.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_2_error_byte.txt
new file mode 100644
index 0000000..5e1c309
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_2_error_byte.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_3_error_byte.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_3_error_byte.png
new file mode 100644
index 0000000..230f97c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_3_error_byte.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_3_error_byte.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_3_error_byte.txt
new file mode 100644
index 0000000..5e1c309
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_3_error_byte.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_4_error_byte.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_4_error_byte.png
new file mode 100644
index 0000000..4a66877
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_4_error_byte.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_4_error_byte.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_4_error_byte.txt
new file mode 100644
index 0000000..5e1c309
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_4_error_byte.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_6_error_byte.png.error b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_6_error_byte.png.error
new file mode 100644
index 0000000..35a2795
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_6_error_byte.png.error
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_6_error_byte.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_6_error_byte.txt
new file mode 100644
index 0000000..5e1c309
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/HelloWorld_Text_L_Kaywa_6_error_byte.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-18x8.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-18x8.png
new file mode 100644
index 0000000..c58bc75
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-18x8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-18x8.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-18x8.txt
new file mode 100644
index 0000000..6a81654
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-18x8.txt
@@ -0,0 +1 @@
+abcde
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-26x12.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-26x12.png
new file mode 100644
index 0000000..8f41fa7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-26x12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-26x12.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-26x12.txt
new file mode 100644
index 0000000..f9fb130
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-26x12.txt
@@ -0,0 +1 @@
+abcdefghijklm
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-32x8.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-32x8.png
new file mode 100644
index 0000000..f0f1292
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-32x8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-32x8.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-32x8.txt
new file mode 100644
index 0000000..d96dc95
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-32x8.txt
@@ -0,0 +1 @@
+abcdef
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x12.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x12.png
new file mode 100644
index 0000000..72f90ec
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x12.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x12.txt
new file mode 100644
index 0000000..3005ca6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x12.txt
@@ -0,0 +1 @@
+abcdefghijklmnopq
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x16.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x16.png
new file mode 100644
index 0000000..2a1a05c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x16.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x16.txt
new file mode 100644
index 0000000..e85d5b4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-36x16.txt
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwxyz
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-48x16.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-48x16.png
new file mode 100644
index 0000000..f6ee357
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-48x16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-48x16.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-48x16.txt
new file mode 100644
index 0000000..7997473
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-48x16.txt
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52-IDAutomation.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52-IDAutomation.png
new file mode 100644
index 0000000..8b0e2a1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52-IDAutomation.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52-IDAutomation.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52-IDAutomation.txt
new file mode 100644
index 0000000..d01ae5a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52-IDAutomation.txt
@@ -0,0 +1 @@
+abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52.png
new file mode 100644
index 0000000..01283fe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52.txt
new file mode 100644
index 0000000..d01ae5a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcd-52x52.txt
@@ -0,0 +1 @@
+abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg-64x64.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg-64x64.png
new file mode 100644
index 0000000..048cea7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg-64x64.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg-64x64.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg-64x64.txt
new file mode 100644
index 0000000..6285fc2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg-64x64.txt
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(),./\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(),./\abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(),./\
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg.png
new file mode 100644
index 0000000..b005ee5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg.txt
new file mode 100644
index 0000000..a2d2b73
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/abcdefg.txt
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(),./\
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/zxing_URL_L_Kayway.png b/ZXingObjCTests/Resources/blackbox/datamatrix-1/zxing_URL_L_Kayway.png
new file mode 100644
index 0000000..abf7a73
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/zxing_URL_L_Kayway.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-1/zxing_URL_L_Kayway.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-1/zxing_URL_L_Kayway.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-1/zxing_URL_L_Kayway.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/01.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/01.png
new file mode 100644
index 0000000..2401b62
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/01.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/01.txt
new file mode 100644
index 0000000..f86d0df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/01.txt
@@ -0,0 +1 @@
+http://google.com/m
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/02.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/02.png
new file mode 100644
index 0000000..dd6cc7d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/02.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/02.txt
new file mode 100644
index 0000000..f86d0df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/02.txt
@@ -0,0 +1 @@
+http://google.com/m
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/03.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/03.png
new file mode 100644
index 0000000..ef2b8a6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/03.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/03.txt
new file mode 100644
index 0000000..f86d0df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/03.txt
@@ -0,0 +1 @@
+http://google.com/m
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/04.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/04.png
new file mode 100644
index 0000000..1b2350f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/04.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/04.txt
new file mode 100644
index 0000000..f86d0df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/04.txt
@@ -0,0 +1 @@
+http://google.com/m
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/05.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/05.png
new file mode 100644
index 0000000..eb0b9f1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/05.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/05.txt
new file mode 100644
index 0000000..f86d0df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/05.txt
@@ -0,0 +1 @@
+http://google.com/m
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/06.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/06.png
new file mode 100644
index 0000000..0e7a6ae
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/06.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/06.txt
new file mode 100644
index 0000000..f86d0df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/06.txt
@@ -0,0 +1 @@
+http://google.com/m
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/07.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/07.png
new file mode 100644
index 0000000..2bd6e4d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/07.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/07.txt
new file mode 100644
index 0000000..f86d0df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/07.txt
@@ -0,0 +1 @@
+http://google.com/m
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/08.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/08.png
new file mode 100644
index 0000000..11dff7c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/08.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/08.txt
new file mode 100644
index 0000000..f86d0df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/08.txt
@@ -0,0 +1 @@
+http://google.com/m
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/09.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/09.png
new file mode 100644
index 0000000..4c22c38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/09.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/09.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/09.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/10.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/10.png
new file mode 100644
index 0000000..725d3ff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/10.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/10.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/10.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/11.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/11.png
new file mode 100644
index 0000000..40418e4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/11.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/11.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/11.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/12.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/12.png
new file mode 100644
index 0000000..5173109
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/12.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/12.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/12.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/13.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/13.png
new file mode 100644
index 0000000..8dff8dc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/13.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/13.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/13.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/14.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/14.png
new file mode 100644
index 0000000..7c84e59
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/14.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/14.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/14.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/15.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/15.png
new file mode 100644
index 0000000..bf757fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/15.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/15.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/15.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/16.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/16.png
new file mode 100644
index 0000000..7157853
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/16.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/16.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/16.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/17.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/17.png
new file mode 100644
index 0000000..a08d0ea
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/17.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/17.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/17.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/18.png b/ZXingObjCTests/Resources/blackbox/datamatrix-2/18.png
new file mode 100644
index 0000000..0aa34c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/datamatrix-2/18.txt b/ZXingObjCTests/Resources/blackbox/datamatrix-2/18.txt
new file mode 100644
index 0000000..a8ae2d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/datamatrix-2/18.txt
@@ -0,0 +1 @@
+This is a test of our DataMatrix support using a longer piece of text, and therefore a more dense barcode.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/1.png b/ZXingObjCTests/Resources/blackbox/ean13-1/1.png
new file mode 100644
index 0000000..0a51478
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/1.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/1.txt
new file mode 100644
index 0000000..2bed7f6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/1.txt
@@ -0,0 +1 @@
+8413000065504
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/10.png b/ZXingObjCTests/Resources/blackbox/ean13-1/10.png
new file mode 100644
index 0000000..58903e1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/10.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/10.txt
new file mode 100644
index 0000000..7d7c3d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/10.txt
@@ -0,0 +1 @@
+8480010001136
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/12.png b/ZXingObjCTests/Resources/blackbox/ean13-1/12.png
new file mode 100644
index 0000000..645bfcd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/12.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/12.txt
new file mode 100644
index 0000000..3f2faf2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/12.txt
@@ -0,0 +1 @@
+5201815331227
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/13.png b/ZXingObjCTests/Resources/blackbox/ean13-1/13.png
new file mode 100644
index 0000000..9a0a193
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/13.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/13.txt
new file mode 100644
index 0000000..8cf1aed
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/13.txt
@@ -0,0 +1 @@
+8413600298517
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/14.png b/ZXingObjCTests/Resources/blackbox/ean13-1/14.png
new file mode 100644
index 0000000..f6f4b8f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/14.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/14.txt
new file mode 100644
index 0000000..8e2c07e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/14.txt
@@ -0,0 +1 @@
+3560070169443
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/15.png b/ZXingObjCTests/Resources/blackbox/ean13-1/15.png
new file mode 100644
index 0000000..68ce984
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/15.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/15.txt
new file mode 100644
index 0000000..313c9f0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/15.txt
@@ -0,0 +1 @@
+4045787034318
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/18.png b/ZXingObjCTests/Resources/blackbox/ean13-1/18.png
new file mode 100644
index 0000000..c518046
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/18.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/18.txt
new file mode 100644
index 0000000..fd2c67c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/18.txt
@@ -0,0 +1 @@
+3086126100326
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/19.png b/ZXingObjCTests/Resources/blackbox/ean13-1/19.png
new file mode 100644
index 0000000..1243b69
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/19.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/19.txt
new file mode 100644
index 0000000..c839e11
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/19.txt
@@ -0,0 +1 @@
+4820024790635
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/2.png b/ZXingObjCTests/Resources/blackbox/ean13-1/2.png
new file mode 100644
index 0000000..3cac546
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/2.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/2.txt
new file mode 100644
index 0000000..bbefd6e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/2.txt
@@ -0,0 +1 @@
+8480010092271
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/20.png b/ZXingObjCTests/Resources/blackbox/ean13-1/20.png
new file mode 100644
index 0000000..0ccb337
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/20.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/20.txt
new file mode 100644
index 0000000..4168b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/20.txt
@@ -0,0 +1 @@
+4000539017100
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/21.png b/ZXingObjCTests/Resources/blackbox/ean13-1/21.png
new file mode 100644
index 0000000..724eac1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/21.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/21.txt
new file mode 100644
index 0000000..3ae180b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/21.txt
@@ -0,0 +1 @@
+7622200008018
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/22.png b/ZXingObjCTests/Resources/blackbox/ean13-1/22.png
new file mode 100644
index 0000000..63434fa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/22.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/22.txt
new file mode 100644
index 0000000..050090b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/22.txt
@@ -0,0 +1 @@
+5603667020517
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/23.png b/ZXingObjCTests/Resources/blackbox/ean13-1/23.png
new file mode 100644
index 0000000..c5563a3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/23.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/23.txt
new file mode 100644
index 0000000..ade11f7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/23.txt
@@ -0,0 +1 @@
+7622400791949
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/24.png b/ZXingObjCTests/Resources/blackbox/ean13-1/24.png
new file mode 100644
index 0000000..27a2540
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/24.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/24.txt
new file mode 100644
index 0000000..5163aef
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/24.txt
@@ -0,0 +1 @@
+5709262942503
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/25.png b/ZXingObjCTests/Resources/blackbox/ean13-1/25.png
new file mode 100644
index 0000000..5e7d187
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/25.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/25.txt
new file mode 100644
index 0000000..cd9874a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/25.txt
@@ -0,0 +1 @@
+9780140013993
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/26.png b/ZXingObjCTests/Resources/blackbox/ean13-1/26.png
new file mode 100644
index 0000000..55cc6f1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/26.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/26.txt
new file mode 100644
index 0000000..9e109c5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/26.txt
@@ -0,0 +1 @@
+4901780188352
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/28.png b/ZXingObjCTests/Resources/blackbox/ean13-1/28.png
new file mode 100644
index 0000000..6d18782
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/28.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/28.txt
new file mode 100644
index 0000000..da99d28
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/28.txt
@@ -0,0 +1 @@
+9771699057002
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/29.png b/ZXingObjCTests/Resources/blackbox/ean13-1/29.png
new file mode 100644
index 0000000..a8fd534
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/29.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/29.txt
new file mode 100644
index 0000000..5882140
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/29.txt
@@ -0,0 +1 @@
+4007817327098
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/3.png b/ZXingObjCTests/Resources/blackbox/ean13-1/3.png
new file mode 100644
index 0000000..5071c64
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/3.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/3.txt
new file mode 100644
index 0000000..29b2fcc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/3.txt
@@ -0,0 +1 @@
+8480000823274
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/30.png b/ZXingObjCTests/Resources/blackbox/ean13-1/30.png
new file mode 100644
index 0000000..0c884df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/30.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/30.txt
new file mode 100644
index 0000000..9193e22
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/30.txt
@@ -0,0 +1 @@
+5025121072311
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/31.png b/ZXingObjCTests/Resources/blackbox/ean13-1/31.png
new file mode 100644
index 0000000..50d2ad0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/31.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/31.txt
new file mode 100644
index 0000000..5dde677
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/31.txt
@@ -0,0 +1 @@
+9780393058673
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/32.png b/ZXingObjCTests/Resources/blackbox/ean13-1/32.png
new file mode 100644
index 0000000..2a2a1cf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/32.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/32.txt
new file mode 100644
index 0000000..5dde677
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/32.txt
@@ -0,0 +1 @@
+9780393058673
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/33.png b/ZXingObjCTests/Resources/blackbox/ean13-1/33.png
new file mode 100644
index 0000000..ac34f8d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/33.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/33.txt
new file mode 100644
index 0000000..b2327fc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/33.txt
@@ -0,0 +1 @@
+9781558604971
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/34.png b/ZXingObjCTests/Resources/blackbox/ean13-1/34.png
new file mode 100644
index 0000000..225cc73
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/34.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/34.txt
new file mode 100644
index 0000000..b2327fc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/34.txt
@@ -0,0 +1 @@
+9781558604971
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/35.png b/ZXingObjCTests/Resources/blackbox/ean13-1/35.png
new file mode 100644
index 0000000..c2e9602
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/35.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/35.txt
new file mode 100644
index 0000000..acc8244
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/35.txt
@@ -0,0 +1 @@
+5030159003930
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/36.png b/ZXingObjCTests/Resources/blackbox/ean13-1/36.png
new file mode 100644
index 0000000..3df7a74
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/36.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/36.txt
new file mode 100644
index 0000000..8860f23
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/36.txt
@@ -0,0 +1 @@
+5000213101025
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/37.png b/ZXingObjCTests/Resources/blackbox/ean13-1/37.png
new file mode 100644
index 0000000..4802760
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/37.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/37.txt
new file mode 100644
index 0000000..645fe52
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/37.txt
@@ -0,0 +1 @@
+5000213002834
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/38.png b/ZXingObjCTests/Resources/blackbox/ean13-1/38.png
new file mode 100644
index 0000000..d1f7e62
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/38.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/38.txt
new file mode 100644
index 0000000..89052f6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/38.txt
@@ -0,0 +1 @@
+9780201752847
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/4.png b/ZXingObjCTests/Resources/blackbox/ean13-1/4.png
new file mode 100644
index 0000000..cad316b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/4.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/4.txt
new file mode 100644
index 0000000..28ad258
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/4.txt
@@ -0,0 +1 @@
+5449000039231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/5.png b/ZXingObjCTests/Resources/blackbox/ean13-1/5.png
new file mode 100644
index 0000000..4c9afe1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/5.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/5.txt
new file mode 100644
index 0000000..5d98de1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/5.txt
@@ -0,0 +1 @@
+8410054010412
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/6.png b/ZXingObjCTests/Resources/blackbox/ean13-1/6.png
new file mode 100644
index 0000000..8a2cba8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/6.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/6.txt
new file mode 100644
index 0000000..13edf65
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/6.txt
@@ -0,0 +1 @@
+8480010045062
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/7.png b/ZXingObjCTests/Resources/blackbox/ean13-1/7.png
new file mode 100644
index 0000000..d78c77d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/7.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/7.txt
new file mode 100644
index 0000000..ca3f2bb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/7.txt
@@ -0,0 +1 @@
+9788430532674
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/8.png b/ZXingObjCTests/Resources/blackbox/ean13-1/8.png
new file mode 100644
index 0000000..81509a2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/8.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/8.txt
new file mode 100644
index 0000000..2322328
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/8.txt
@@ -0,0 +1 @@
+8480017507990
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/9.png b/ZXingObjCTests/Resources/blackbox/ean13-1/9.png
new file mode 100644
index 0000000..768175d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-1/9.txt b/ZXingObjCTests/Resources/blackbox/ean13-1/9.txt
new file mode 100644
index 0000000..134bb0f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-1/9.txt
@@ -0,0 +1 @@
+3166298099809
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/01.png b/ZXingObjCTests/Resources/blackbox/ean13-2/01.png
new file mode 100755
index 0000000..e9f5576
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/01.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/01.txt
new file mode 100644
index 0000000..a98aacb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/01.txt
@@ -0,0 +1 @@
+9780804816632
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/02.png b/ZXingObjCTests/Resources/blackbox/ean13-2/02.png
new file mode 100755
index 0000000..5d2d9c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/02.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/02.txt
new file mode 100644
index 0000000..a98aacb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/02.txt
@@ -0,0 +1 @@
+9780804816632
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/03.png b/ZXingObjCTests/Resources/blackbox/ean13-2/03.png
new file mode 100755
index 0000000..ca71946
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/03.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/03.txt
new file mode 100644
index 0000000..a98aacb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/03.txt
@@ -0,0 +1 @@
+9780804816632
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/04.png b/ZXingObjCTests/Resources/blackbox/ean13-2/04.png
new file mode 100755
index 0000000..054a664
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/04.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/04.txt
new file mode 100644
index 0000000..a98aacb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/04.txt
@@ -0,0 +1 @@
+9780804816632
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/05.png b/ZXingObjCTests/Resources/blackbox/ean13-2/05.png
new file mode 100755
index 0000000..ae58951
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/05.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/05.txt
new file mode 100644
index 0000000..a98aacb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/05.txt
@@ -0,0 +1 @@
+9780804816632
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/06.png b/ZXingObjCTests/Resources/blackbox/ean13-2/06.png
new file mode 100755
index 0000000..c1bcb9e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/06.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/06.txt
new file mode 100644
index 0000000..a98aacb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/06.txt
@@ -0,0 +1 @@
+9780804816632
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/07.png b/ZXingObjCTests/Resources/blackbox/ean13-2/07.png
new file mode 100755
index 0000000..b059d22
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/07.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/07.txt
new file mode 100644
index 0000000..a98aacb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/07.txt
@@ -0,0 +1 @@
+9780804816632
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/08.png b/ZXingObjCTests/Resources/blackbox/ean13-2/08.png
new file mode 100755
index 0000000..b435b9c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/08.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/08.txt
new file mode 100644
index 0000000..8dab35e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/08.txt
@@ -0,0 +1 @@
+9780345348036
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/09.png b/ZXingObjCTests/Resources/blackbox/ean13-2/09.png
new file mode 100755
index 0000000..f8573a3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/09.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/09.txt
new file mode 100644
index 0000000..8dab35e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/09.txt
@@ -0,0 +1 @@
+9780345348036
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/10.png b/ZXingObjCTests/Resources/blackbox/ean13-2/10.png
new file mode 100755
index 0000000..f9142fa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/10.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/10.txt
new file mode 100644
index 0000000..8dab35e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/10.txt
@@ -0,0 +1 @@
+9780345348036
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/11.png b/ZXingObjCTests/Resources/blackbox/ean13-2/11.png
new file mode 100755
index 0000000..1c37db7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/11.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/11.txt
new file mode 100644
index 0000000..8dab35e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/11.txt
@@ -0,0 +1 @@
+9780345348036
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/12.png b/ZXingObjCTests/Resources/blackbox/ean13-2/12.png
new file mode 100755
index 0000000..e5a3811
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/12.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/12.txt
new file mode 100644
index 0000000..8dab35e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/12.txt
@@ -0,0 +1 @@
+9780345348036
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/13.png b/ZXingObjCTests/Resources/blackbox/ean13-2/13.png
new file mode 100755
index 0000000..c809e93
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/13.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/13.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/13.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/14.png b/ZXingObjCTests/Resources/blackbox/ean13-2/14.png
new file mode 100755
index 0000000..d770fbe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/14.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/14.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/14.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/15.png b/ZXingObjCTests/Resources/blackbox/ean13-2/15.png
new file mode 100755
index 0000000..7b9ad95
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/15.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/15.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/15.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/16.png b/ZXingObjCTests/Resources/blackbox/ean13-2/16.png
new file mode 100755
index 0000000..a38b462
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/16.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/16.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/16.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/17.png b/ZXingObjCTests/Resources/blackbox/ean13-2/17.png
new file mode 100755
index 0000000..2ccb7ba
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/17.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/17.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/17.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/18.png b/ZXingObjCTests/Resources/blackbox/ean13-2/18.png
new file mode 100755
index 0000000..f2c59bf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/18.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/18.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/18.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/19.png b/ZXingObjCTests/Resources/blackbox/ean13-2/19.png
new file mode 100755
index 0000000..5dc54a4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/19.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/19.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/19.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/20.png b/ZXingObjCTests/Resources/blackbox/ean13-2/20.png
new file mode 100755
index 0000000..4c50c4f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/20.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/20.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/20.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/21.png b/ZXingObjCTests/Resources/blackbox/ean13-2/21.png
new file mode 100755
index 0000000..03cfa8c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/21.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/21.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/21.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/22.png b/ZXingObjCTests/Resources/blackbox/ean13-2/22.png
new file mode 100755
index 0000000..c647d61
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/22.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/22.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/22.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/23.png b/ZXingObjCTests/Resources/blackbox/ean13-2/23.png
new file mode 100755
index 0000000..95cc049
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/23.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/23.txt
new file mode 100644
index 0000000..764ab85
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/23.txt
@@ -0,0 +1 @@
+1920081045006
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/24.png b/ZXingObjCTests/Resources/blackbox/ean13-2/24.png
new file mode 100755
index 0000000..201b772
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/24.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/24.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/24.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/25.png b/ZXingObjCTests/Resources/blackbox/ean13-2/25.png
new file mode 100755
index 0000000..cc43e76
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/25.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/25.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/25.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/26.png b/ZXingObjCTests/Resources/blackbox/ean13-2/26.png
new file mode 100755
index 0000000..0fa6750
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/26.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/26.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/26.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/27.png b/ZXingObjCTests/Resources/blackbox/ean13-2/27.png
new file mode 100755
index 0000000..4dcedb8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/27.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/27.txt
new file mode 100644
index 0000000..e5bf71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/27.txt
@@ -0,0 +1 @@
+9784872348880
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/28.png b/ZXingObjCTests/Resources/blackbox/ean13-2/28.png
new file mode 100755
index 0000000..9883d40
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-2/28.txt b/ZXingObjCTests/Resources/blackbox/ean13-2/28.txt
new file mode 100644
index 0000000..764ab85
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-2/28.txt
@@ -0,0 +1 @@
+1920081045006
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/01.png b/ZXingObjCTests/Resources/blackbox/ean13-3/01.png
new file mode 100644
index 0000000..c7cfc75
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/01.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/01.txt
new file mode 100644
index 0000000..2374d38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/01.txt
@@ -0,0 +1 @@
+9780764544200
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/02.png b/ZXingObjCTests/Resources/blackbox/ean13-3/02.png
new file mode 100644
index 0000000..acdb380
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/02.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/02.txt
new file mode 100644
index 0000000..2374d38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/02.txt
@@ -0,0 +1 @@
+9780764544200
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/03.png b/ZXingObjCTests/Resources/blackbox/ean13-3/03.png
new file mode 100644
index 0000000..94c5acf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/03.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/03.txt
new file mode 100644
index 0000000..2374d38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/03.txt
@@ -0,0 +1 @@
+9780764544200
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/04.png b/ZXingObjCTests/Resources/blackbox/ean13-3/04.png
new file mode 100644
index 0000000..dbc0b01
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/04.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/04.txt
new file mode 100644
index 0000000..2374d38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/04.txt
@@ -0,0 +1 @@
+9780764544200
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/05.png b/ZXingObjCTests/Resources/blackbox/ean13-3/05.png
new file mode 100644
index 0000000..74b52a4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/05.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/05.txt
new file mode 100644
index 0000000..2374d38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/05.txt
@@ -0,0 +1 @@
+9780764544200
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/06.png b/ZXingObjCTests/Resources/blackbox/ean13-3/06.png
new file mode 100644
index 0000000..2e63f21
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/06.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/06.txt
new file mode 100644
index 0000000..2374d38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/06.txt
@@ -0,0 +1 @@
+9780764544200
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/07.png b/ZXingObjCTests/Resources/blackbox/ean13-3/07.png
new file mode 100644
index 0000000..06e44d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/07.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/07.txt
new file mode 100644
index 0000000..2374d38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/07.txt
@@ -0,0 +1 @@
+9780764544200
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/08.png b/ZXingObjCTests/Resources/blackbox/ean13-3/08.png
new file mode 100644
index 0000000..cf7f6eb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/08.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/08.txt
new file mode 100644
index 0000000..2374d38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/08.txt
@@ -0,0 +1 @@
+9780764544200
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/09.png b/ZXingObjCTests/Resources/blackbox/ean13-3/09.png
new file mode 100644
index 0000000..a150b6c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/09.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/09.txt
new file mode 100644
index 0000000..2374d38
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/09.txt
@@ -0,0 +1 @@
+9780764544200
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/10.png b/ZXingObjCTests/Resources/blackbox/ean13-3/10.png
new file mode 100644
index 0000000..477085b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/10.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/10.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/10.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/11.png b/ZXingObjCTests/Resources/blackbox/ean13-3/11.png
new file mode 100644
index 0000000..70d398e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/11.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/11.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/11.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/12.png b/ZXingObjCTests/Resources/blackbox/ean13-3/12.png
new file mode 100644
index 0000000..8690d95
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/12.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/12.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/12.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/13.png b/ZXingObjCTests/Resources/blackbox/ean13-3/13.png
new file mode 100644
index 0000000..bf3713f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/13.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/13.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/13.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/14.png b/ZXingObjCTests/Resources/blackbox/ean13-3/14.png
new file mode 100644
index 0000000..82c9a9e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/14.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/14.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/14.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/15.png b/ZXingObjCTests/Resources/blackbox/ean13-3/15.png
new file mode 100644
index 0000000..af37ac3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/15.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/15.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/15.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/16.png b/ZXingObjCTests/Resources/blackbox/ean13-3/16.png
new file mode 100644
index 0000000..ae5b5a1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/16.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/16.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/16.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/17.png b/ZXingObjCTests/Resources/blackbox/ean13-3/17.png
new file mode 100644
index 0000000..adb7d8b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/17.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/17.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/17.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/18.png b/ZXingObjCTests/Resources/blackbox/ean13-3/18.png
new file mode 100644
index 0000000..28e0f6e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/18.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/18.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/18.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/19.png b/ZXingObjCTests/Resources/blackbox/ean13-3/19.png
new file mode 100644
index 0000000..8af9f3e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/19.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/19.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/19.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/20.png b/ZXingObjCTests/Resources/blackbox/ean13-3/20.png
new file mode 100644
index 0000000..28d64fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/20.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/20.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/20.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/21.png b/ZXingObjCTests/Resources/blackbox/ean13-3/21.png
new file mode 100644
index 0000000..a4dd352
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/21.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/21.txt
new file mode 100644
index 0000000..0418ac5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/21.txt
@@ -0,0 +1 @@
+9780596008574
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/22.png b/ZXingObjCTests/Resources/blackbox/ean13-3/22.png
new file mode 100644
index 0000000..bdfaa4b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/22.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/22.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/22.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/23.png b/ZXingObjCTests/Resources/blackbox/ean13-3/23.png
new file mode 100644
index 0000000..90926cd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/23.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/23.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/23.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/24.png b/ZXingObjCTests/Resources/blackbox/ean13-3/24.png
new file mode 100644
index 0000000..0b6366b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/24.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/24.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/24.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/25.png b/ZXingObjCTests/Resources/blackbox/ean13-3/25.png
new file mode 100644
index 0000000..988d61e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/25.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/25.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/25.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/26.png b/ZXingObjCTests/Resources/blackbox/ean13-3/26.png
new file mode 100644
index 0000000..c8a7696
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/26.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/26.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/26.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/27.png b/ZXingObjCTests/Resources/blackbox/ean13-3/27.png
new file mode 100644
index 0000000..c82a19e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/27.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/27.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/27.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/28.png b/ZXingObjCTests/Resources/blackbox/ean13-3/28.png
new file mode 100644
index 0000000..e7cfe2b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/28.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/28.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/28.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/29.png b/ZXingObjCTests/Resources/blackbox/ean13-3/29.png
new file mode 100644
index 0000000..351117e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/29.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/29.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/29.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/30.png b/ZXingObjCTests/Resources/blackbox/ean13-3/30.png
new file mode 100644
index 0000000..bd90227
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/30.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/30.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/30.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/31.png b/ZXingObjCTests/Resources/blackbox/ean13-3/31.png
new file mode 100644
index 0000000..8768ac3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/31.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/31.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/31.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/32.png b/ZXingObjCTests/Resources/blackbox/ean13-3/32.png
new file mode 100644
index 0000000..e227c6c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/32.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/32.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/32.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/33.png b/ZXingObjCTests/Resources/blackbox/ean13-3/33.png
new file mode 100644
index 0000000..d0ca931
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/33.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/33.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/33.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/34.png b/ZXingObjCTests/Resources/blackbox/ean13-3/34.png
new file mode 100644
index 0000000..6960608
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/34.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/34.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/34.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/35.png b/ZXingObjCTests/Resources/blackbox/ean13-3/35.png
new file mode 100644
index 0000000..4b97179
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/35.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/35.txt
new file mode 100644
index 0000000..af323ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/35.txt
@@ -0,0 +1 @@
+9780201310054
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/36.png b/ZXingObjCTests/Resources/blackbox/ean13-3/36.png
new file mode 100644
index 0000000..44b201f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/36.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/36.txt
new file mode 100644
index 0000000..9a81d5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/36.txt
@@ -0,0 +1 @@
+9781585730575
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/37.png b/ZXingObjCTests/Resources/blackbox/ean13-3/37.png
new file mode 100644
index 0000000..ae59a37
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/37.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/37.txt
new file mode 100644
index 0000000..9a81d5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/37.txt
@@ -0,0 +1 @@
+9781585730575
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/38.png b/ZXingObjCTests/Resources/blackbox/ean13-3/38.png
new file mode 100644
index 0000000..2b711c4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/38.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/38.txt
new file mode 100644
index 0000000..9a81d5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/38.txt
@@ -0,0 +1 @@
+9781585730575
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/39.png b/ZXingObjCTests/Resources/blackbox/ean13-3/39.png
new file mode 100644
index 0000000..ef58665
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/39.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/39.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/39.txt
new file mode 100644
index 0000000..9a81d5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/39.txt
@@ -0,0 +1 @@
+9781585730575
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/40.png b/ZXingObjCTests/Resources/blackbox/ean13-3/40.png
new file mode 100644
index 0000000..bde68d3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/40.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/40.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/40.txt
new file mode 100644
index 0000000..9a81d5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/40.txt
@@ -0,0 +1 @@
+9781585730575
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/41.png b/ZXingObjCTests/Resources/blackbox/ean13-3/41.png
new file mode 100644
index 0000000..d3a314e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/41.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/41.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/41.txt
new file mode 100644
index 0000000..9a81d5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/41.txt
@@ -0,0 +1 @@
+9781585730575
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/42.png b/ZXingObjCTests/Resources/blackbox/ean13-3/42.png
new file mode 100644
index 0000000..4d204f0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/42.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/42.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/42.txt
new file mode 100644
index 0000000..9a81d5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/42.txt
@@ -0,0 +1 @@
+9781585730575
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/43.png b/ZXingObjCTests/Resources/blackbox/ean13-3/43.png
new file mode 100644
index 0000000..1dd551f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/43.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/43.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/43.txt
new file mode 100644
index 0000000..9a81d5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/43.txt
@@ -0,0 +1 @@
+9781585730575
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/44.png b/ZXingObjCTests/Resources/blackbox/ean13-3/44.png
new file mode 100644
index 0000000..a89a755
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/44.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/44.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/44.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/44.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/45.png b/ZXingObjCTests/Resources/blackbox/ean13-3/45.png
new file mode 100644
index 0000000..a9bbe60
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/45.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/45.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/45.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/45.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/46.png b/ZXingObjCTests/Resources/blackbox/ean13-3/46.png
new file mode 100644
index 0000000..f132a70
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/46.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/46.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/46.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/46.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/47.png b/ZXingObjCTests/Resources/blackbox/ean13-3/47.png
new file mode 100644
index 0000000..2b40bdf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/47.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/47.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/47.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/47.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/48.png b/ZXingObjCTests/Resources/blackbox/ean13-3/48.png
new file mode 100644
index 0000000..5415ac3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/48.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/48.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/48.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/48.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/49.png b/ZXingObjCTests/Resources/blackbox/ean13-3/49.png
new file mode 100644
index 0000000..aba0846
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/49.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/49.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/49.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/49.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/50.png b/ZXingObjCTests/Resources/blackbox/ean13-3/50.png
new file mode 100644
index 0000000..f46bf5a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/50.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/50.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/50.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/50.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/51.png b/ZXingObjCTests/Resources/blackbox/ean13-3/51.png
new file mode 100644
index 0000000..e8b9969
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/51.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/51.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/51.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/51.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/52.png b/ZXingObjCTests/Resources/blackbox/ean13-3/52.png
new file mode 100644
index 0000000..10cd368
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/52.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/52.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/52.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/52.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/53.png b/ZXingObjCTests/Resources/blackbox/ean13-3/53.png
new file mode 100644
index 0000000..1214abb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/53.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/53.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/53.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/53.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/54.png b/ZXingObjCTests/Resources/blackbox/ean13-3/54.png
new file mode 100644
index 0000000..6b3154f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/54.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/54.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/54.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/54.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/55.png b/ZXingObjCTests/Resources/blackbox/ean13-3/55.png
new file mode 100644
index 0000000..d639123
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/55.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-3/55.txt b/ZXingObjCTests/Resources/blackbox/ean13-3/55.txt
new file mode 100644
index 0000000..bc4f1af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-3/55.txt
@@ -0,0 +1 @@
+9780735619937
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/01.png b/ZXingObjCTests/Resources/blackbox/ean13-4/01.png
new file mode 100644
index 0000000..1373c22
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/01.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/01.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/01.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/02.png b/ZXingObjCTests/Resources/blackbox/ean13-4/02.png
new file mode 100644
index 0000000..3f6a0ab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/02.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/02.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/02.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/03.png b/ZXingObjCTests/Resources/blackbox/ean13-4/03.png
new file mode 100644
index 0000000..711f430
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/03.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/03.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/03.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/04.png b/ZXingObjCTests/Resources/blackbox/ean13-4/04.png
new file mode 100644
index 0000000..6a0e4d2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/04.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/04.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/04.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/05.png b/ZXingObjCTests/Resources/blackbox/ean13-4/05.png
new file mode 100644
index 0000000..4891c6e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/05.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/05.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/05.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/06.png b/ZXingObjCTests/Resources/blackbox/ean13-4/06.png
new file mode 100644
index 0000000..b6d4d3f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/06.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/06.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/06.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/07.png b/ZXingObjCTests/Resources/blackbox/ean13-4/07.png
new file mode 100644
index 0000000..7700663
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/07.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/07.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/07.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/08.png b/ZXingObjCTests/Resources/blackbox/ean13-4/08.png
new file mode 100644
index 0000000..4dd7190
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/08.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/08.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/08.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/09.png b/ZXingObjCTests/Resources/blackbox/ean13-4/09.png
new file mode 100644
index 0000000..3095d76
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/09.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/09.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/09.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/10.png b/ZXingObjCTests/Resources/blackbox/ean13-4/10.png
new file mode 100644
index 0000000..07ea6bd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/10.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/10.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/10.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/11.png b/ZXingObjCTests/Resources/blackbox/ean13-4/11.png
new file mode 100644
index 0000000..b0c10a8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/11.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/11.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/11.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/12.png b/ZXingObjCTests/Resources/blackbox/ean13-4/12.png
new file mode 100644
index 0000000..ea56ff1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/12.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/12.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/12.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/13.png b/ZXingObjCTests/Resources/blackbox/ean13-4/13.png
new file mode 100644
index 0000000..97ab926
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/13.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/13.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/13.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/14.png b/ZXingObjCTests/Resources/blackbox/ean13-4/14.png
new file mode 100644
index 0000000..eccc8e3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/14.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/14.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/14.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/15.png b/ZXingObjCTests/Resources/blackbox/ean13-4/15.png
new file mode 100644
index 0000000..951202d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/15.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/15.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/15.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/16.png b/ZXingObjCTests/Resources/blackbox/ean13-4/16.png
new file mode 100644
index 0000000..4f2b039
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/16.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/16.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/16.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/17.png b/ZXingObjCTests/Resources/blackbox/ean13-4/17.png
new file mode 100644
index 0000000..938ff1f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/17.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/17.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/17.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/18.png b/ZXingObjCTests/Resources/blackbox/ean13-4/18.png
new file mode 100644
index 0000000..426088b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/18.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/18.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/18.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/19.png b/ZXingObjCTests/Resources/blackbox/ean13-4/19.png
new file mode 100644
index 0000000..f606373
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/19.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/19.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/19.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/20.png b/ZXingObjCTests/Resources/blackbox/ean13-4/20.png
new file mode 100644
index 0000000..d49140a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/20.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/20.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/20.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/21.png b/ZXingObjCTests/Resources/blackbox/ean13-4/21.png
new file mode 100644
index 0000000..76d38fc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/21.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/21.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/21.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/22.png b/ZXingObjCTests/Resources/blackbox/ean13-4/22.png
new file mode 100644
index 0000000..60184e8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-4/22.txt b/ZXingObjCTests/Resources/blackbox/ean13-4/22.txt
new file mode 100644
index 0000000..33d6b99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-4/22.txt
@@ -0,0 +1 @@
+9780441014989
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/01.png b/ZXingObjCTests/Resources/blackbox/ean13-5/01.png
new file mode 100755
index 0000000..eb69b6c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/01.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/01.txt
new file mode 100644
index 0000000..e39e9a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/01.txt
@@ -0,0 +1 @@
+9780679601050
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/02.png b/ZXingObjCTests/Resources/blackbox/ean13-5/02.png
new file mode 100755
index 0000000..e0f79a8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/02.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/02.txt
new file mode 100644
index 0000000..e39e9a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/02.txt
@@ -0,0 +1 @@
+9780679601050
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/03.png b/ZXingObjCTests/Resources/blackbox/ean13-5/03.png
new file mode 100755
index 0000000..6305539
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/03.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/03.txt
new file mode 100644
index 0000000..e39e9a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/03.txt
@@ -0,0 +1 @@
+9780679601050
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/04.png b/ZXingObjCTests/Resources/blackbox/ean13-5/04.png
new file mode 100755
index 0000000..d356850
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/04.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/04.txt
new file mode 100644
index 0000000..e39e9a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/04.txt
@@ -0,0 +1 @@
+9780679601050
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/05.png b/ZXingObjCTests/Resources/blackbox/ean13-5/05.png
new file mode 100755
index 0000000..5afee8a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/05.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/05.txt
new file mode 100644
index 0000000..e39e9a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/05.txt
@@ -0,0 +1 @@
+9780679601050
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/06.png b/ZXingObjCTests/Resources/blackbox/ean13-5/06.png
new file mode 100755
index 0000000..23abf72
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/06.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/06.txt
new file mode 100644
index 0000000..a083c8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/06.txt
@@ -0,0 +1 @@
+9780345460950
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/07.png b/ZXingObjCTests/Resources/blackbox/ean13-5/07.png
new file mode 100755
index 0000000..2db9044
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/07.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/07.txt
new file mode 100644
index 0000000..a083c8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/07.txt
@@ -0,0 +1 @@
+9780345460950
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/08.png b/ZXingObjCTests/Resources/blackbox/ean13-5/08.png
new file mode 100755
index 0000000..0f462ab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/08.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/08.txt
new file mode 100644
index 0000000..a083c8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/08.txt
@@ -0,0 +1 @@
+9780345460950
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/09.png b/ZXingObjCTests/Resources/blackbox/ean13-5/09.png
new file mode 100755
index 0000000..4914c9e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/09.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/09.txt
new file mode 100644
index 0000000..a083c8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/09.txt
@@ -0,0 +1 @@
+9780345460950
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/10.png b/ZXingObjCTests/Resources/blackbox/ean13-5/10.png
new file mode 100755
index 0000000..28e0a1e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/10.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/10.txt
new file mode 100644
index 0000000..a083c8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/10.txt
@@ -0,0 +1 @@
+9780345460950
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/11.png b/ZXingObjCTests/Resources/blackbox/ean13-5/11.png
new file mode 100755
index 0000000..481aea3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/11.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/11.txt
new file mode 100644
index 0000000..a083c8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/11.txt
@@ -0,0 +1 @@
+9780345460950
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/12.png b/ZXingObjCTests/Resources/blackbox/ean13-5/12.png
new file mode 100755
index 0000000..14581d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/12.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/12.txt
new file mode 100644
index 0000000..a083c8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/12.txt
@@ -0,0 +1 @@
+9780345460950
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/13.png b/ZXingObjCTests/Resources/blackbox/ean13-5/13.png
new file mode 100755
index 0000000..6a1b0e7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/13.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/13.txt
new file mode 100644
index 0000000..efab0d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/13.txt
@@ -0,0 +1 @@
+9780446579803
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/14.png b/ZXingObjCTests/Resources/blackbox/ean13-5/14.png
new file mode 100755
index 0000000..46539e3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/14.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/14.txt
new file mode 100644
index 0000000..efab0d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/14.txt
@@ -0,0 +1 @@
+9780446579803
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/15.png b/ZXingObjCTests/Resources/blackbox/ean13-5/15.png
new file mode 100755
index 0000000..6c91854
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/15.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/15.txt
new file mode 100644
index 0000000..efab0d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/15.txt
@@ -0,0 +1 @@
+9780446579803
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/16.png b/ZXingObjCTests/Resources/blackbox/ean13-5/16.png
new file mode 100755
index 0000000..d677819
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/16.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/16.txt
new file mode 100644
index 0000000..efab0d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/16.txt
@@ -0,0 +1 @@
+9780446579803
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/17.png b/ZXingObjCTests/Resources/blackbox/ean13-5/17.png
new file mode 100755
index 0000000..a97d780
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/17.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/17.txt
new file mode 100644
index 0000000..efab0d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/17.txt
@@ -0,0 +1 @@
+9780446579803
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/18.png b/ZXingObjCTests/Resources/blackbox/ean13-5/18.png
new file mode 100755
index 0000000..a231bcd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean13-5/18.txt b/ZXingObjCTests/Resources/blackbox/ean13-5/18.txt
new file mode 100644
index 0000000..efab0d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean13-5/18.txt
@@ -0,0 +1 @@
+9780446579803
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/1.png b/ZXingObjCTests/Resources/blackbox/ean8-1/1.png
new file mode 100644
index 0000000..14195c2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/1.txt b/ZXingObjCTests/Resources/blackbox/ean8-1/1.txt
new file mode 100644
index 0000000..cf23e89
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/1.txt
@@ -0,0 +1 @@
+48512343
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/2.png b/ZXingObjCTests/Resources/blackbox/ean8-1/2.png
new file mode 100644
index 0000000..d9d93bc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/2.txt b/ZXingObjCTests/Resources/blackbox/ean8-1/2.txt
new file mode 100644
index 0000000..c1c1178
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/2.txt
@@ -0,0 +1 @@
+12345670
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/3.png b/ZXingObjCTests/Resources/blackbox/ean8-1/3.png
new file mode 100644
index 0000000..2e29b6b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/3.txt b/ZXingObjCTests/Resources/blackbox/ean8-1/3.txt
new file mode 100644
index 0000000..c1c1178
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/3.txt
@@ -0,0 +1 @@
+12345670
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/4.png b/ZXingObjCTests/Resources/blackbox/ean8-1/4.png
new file mode 100644
index 0000000..ab36270
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/4.txt b/ZXingObjCTests/Resources/blackbox/ean8-1/4.txt
new file mode 100644
index 0000000..2ab0cf4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/4.txt
@@ -0,0 +1 @@
+67678983
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/5.png b/ZXingObjCTests/Resources/blackbox/ean8-1/5.png
new file mode 100644
index 0000000..8dba684
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/5.txt b/ZXingObjCTests/Resources/blackbox/ean8-1/5.txt
new file mode 100644
index 0000000..4911bf2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/5.txt
@@ -0,0 +1 @@
+80674313
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/6.png b/ZXingObjCTests/Resources/blackbox/ean8-1/6.png
new file mode 100644
index 0000000..87f8893
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/6.txt b/ZXingObjCTests/Resources/blackbox/ean8-1/6.txt
new file mode 100644
index 0000000..d0ada6f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/6.txt
@@ -0,0 +1 @@
+59001270
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/7.png b/ZXingObjCTests/Resources/blackbox/ean8-1/7.png
new file mode 100644
index 0000000..1a99a31
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/7.txt b/ZXingObjCTests/Resources/blackbox/ean8-1/7.txt
new file mode 100644
index 0000000..36db36b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/7.txt
@@ -0,0 +1 @@
+50487066
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/8.png b/ZXingObjCTests/Resources/blackbox/ean8-1/8.png
new file mode 100644
index 0000000..faddfd7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/ean8-1/8.txt b/ZXingObjCTests/Resources/blackbox/ean8-1/8.txt
new file mode 100644
index 0000000..a6c3069
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/ean8-1/8.txt
@@ -0,0 +1 @@
+55123457
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/01.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/01.png
new file mode 100755
index 0000000..21660d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/02.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/02.png
new file mode 100755
index 0000000..a66976e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/03.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/03.png
new file mode 100755
index 0000000..f67db15
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/04.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/04.png
new file mode 100755
index 0000000..efb94fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/05.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/05.png
new file mode 100755
index 0000000..efc2da3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/06.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/06.png
new file mode 100755
index 0000000..a5ccaed
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/07.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/07.png
new file mode 100755
index 0000000..82056bd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/08.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/08.png
new file mode 100755
index 0000000..c5ae82b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/09.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/09.png
new file mode 100755
index 0000000..147a1b2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/10.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/10.png
new file mode 100755
index 0000000..c7d6011
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/11.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/11.png
new file mode 100755
index 0000000..5710efc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/12.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/12.png
new file mode 100755
index 0000000..8d630ca
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/13.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/13.png
new file mode 100755
index 0000000..ad3b971
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/14.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/14.png
new file mode 100755
index 0000000..4f61d20
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/15.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/15.png
new file mode 100755
index 0000000..68c8aba
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/16.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/16.png
new file mode 100755
index 0000000..1d975d7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/17.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/17.png
new file mode 100755
index 0000000..760ca90
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/18.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/18.png
new file mode 100755
index 0000000..2c770e2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/19.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/19.png
new file mode 100755
index 0000000..bd518c4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/20.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/20.png
new file mode 100755
index 0000000..c675e29
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/21.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/21.png
new file mode 100755
index 0000000..3a0e038
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/22.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/22.png
new file mode 100755
index 0000000..c05690d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/23.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/23.png
new file mode 100755
index 0000000..74fbaed
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/24.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/24.png
new file mode 100755
index 0000000..b023c46
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives-2/25.png b/ZXingObjCTests/Resources/blackbox/falsepositives-2/25.png
new file mode 100755
index 0000000..cfead59
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives-2/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/01.png b/ZXingObjCTests/Resources/blackbox/falsepositives/01.png
new file mode 100644
index 0000000..f842d1e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/02.png b/ZXingObjCTests/Resources/blackbox/falsepositives/02.png
new file mode 100644
index 0000000..daf2164
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/03.png b/ZXingObjCTests/Resources/blackbox/falsepositives/03.png
new file mode 100644
index 0000000..ef23c14
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/04.png b/ZXingObjCTests/Resources/blackbox/falsepositives/04.png
new file mode 100644
index 0000000..9d6ac9e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/05.png b/ZXingObjCTests/Resources/blackbox/falsepositives/05.png
new file mode 100644
index 0000000..cdc990a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/06.png b/ZXingObjCTests/Resources/blackbox/falsepositives/06.png
new file mode 100644
index 0000000..2a21197
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/07.png b/ZXingObjCTests/Resources/blackbox/falsepositives/07.png
new file mode 100644
index 0000000..f029515
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/08.png b/ZXingObjCTests/Resources/blackbox/falsepositives/08.png
new file mode 100644
index 0000000..5336ab9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/09.png b/ZXingObjCTests/Resources/blackbox/falsepositives/09.png
new file mode 100644
index 0000000..72ca3f6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/10.png b/ZXingObjCTests/Resources/blackbox/falsepositives/10.png
new file mode 100644
index 0000000..75e5093
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/11.png b/ZXingObjCTests/Resources/blackbox/falsepositives/11.png
new file mode 100644
index 0000000..d803ca4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/12.png b/ZXingObjCTests/Resources/blackbox/falsepositives/12.png
new file mode 100644
index 0000000..24334ea
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/13.png b/ZXingObjCTests/Resources/blackbox/falsepositives/13.png
new file mode 100644
index 0000000..4511988
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/14.png b/ZXingObjCTests/Resources/blackbox/falsepositives/14.png
new file mode 100644
index 0000000..f3911a9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/15.png b/ZXingObjCTests/Resources/blackbox/falsepositives/15.png
new file mode 100644
index 0000000..0ba6581
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/16.png b/ZXingObjCTests/Resources/blackbox/falsepositives/16.png
new file mode 100644
index 0000000..d6403f3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/17.png b/ZXingObjCTests/Resources/blackbox/falsepositives/17.png
new file mode 100644
index 0000000..fbca1f3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/18.png b/ZXingObjCTests/Resources/blackbox/falsepositives/18.png
new file mode 100644
index 0000000..227218a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/19.png b/ZXingObjCTests/Resources/blackbox/falsepositives/19.png
new file mode 100644
index 0000000..eeb4108
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/20.png b/ZXingObjCTests/Resources/blackbox/falsepositives/20.png
new file mode 100644
index 0000000..69bc08f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/21.png b/ZXingObjCTests/Resources/blackbox/falsepositives/21.png
new file mode 100644
index 0000000..6e986cb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/falsepositives/22.png b/ZXingObjCTests/Resources/blackbox/falsepositives/22.png
new file mode 100644
index 0000000..66330ae
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/falsepositives/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/1.png b/ZXingObjCTests/Resources/blackbox/itf-1/1.png
new file mode 100644
index 0000000..39f3c09
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/1.txt b/ZXingObjCTests/Resources/blackbox/itf-1/1.txt
new file mode 100644
index 0000000..f17cae6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/1.txt
@@ -0,0 +1 @@
+30712345000010
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/10.png b/ZXingObjCTests/Resources/blackbox/itf-1/10.png
new file mode 100644
index 0000000..6715057
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/10.txt b/ZXingObjCTests/Resources/blackbox/itf-1/10.txt
new file mode 100644
index 0000000..d46b0cf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/10.txt
@@ -0,0 +1 @@
+0053611912
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/13.png b/ZXingObjCTests/Resources/blackbox/itf-1/13.png
new file mode 100644
index 0000000..c17aacc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/13.txt b/ZXingObjCTests/Resources/blackbox/itf-1/13.txt
new file mode 100644
index 0000000..1351c69
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/13.txt
@@ -0,0 +1 @@
+0829220875
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/14.png b/ZXingObjCTests/Resources/blackbox/itf-1/14.png
new file mode 100644
index 0000000..881b1de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/14.txt b/ZXingObjCTests/Resources/blackbox/itf-1/14.txt
new file mode 100644
index 0000000..1351c69
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/14.txt
@@ -0,0 +1 @@
+0829220875
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/15.png b/ZXingObjCTests/Resources/blackbox/itf-1/15.png
new file mode 100644
index 0000000..5974885
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/15.txt b/ZXingObjCTests/Resources/blackbox/itf-1/15.txt
new file mode 100644
index 0000000..1351c69
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/15.txt
@@ -0,0 +1 @@
+0829220875
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/16.png b/ZXingObjCTests/Resources/blackbox/itf-1/16.png
new file mode 100644
index 0000000..02b340d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/16.txt b/ZXingObjCTests/Resources/blackbox/itf-1/16.txt
new file mode 100644
index 0000000..a92b62e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/16.txt
@@ -0,0 +1 @@
+0829220874
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/2.png b/ZXingObjCTests/Resources/blackbox/itf-1/2.png
new file mode 100644
index 0000000..3315f80
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/2.txt b/ZXingObjCTests/Resources/blackbox/itf-1/2.txt
new file mode 100644
index 0000000..eabb743
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/2.txt
@@ -0,0 +1 @@
+00012345678905
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/3.png b/ZXingObjCTests/Resources/blackbox/itf-1/3.png
new file mode 100644
index 0000000..3b654f7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/3.txt b/ZXingObjCTests/Resources/blackbox/itf-1/3.txt
new file mode 100644
index 0000000..d46b0cf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/3.txt
@@ -0,0 +1 @@
+0053611912
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/5.png b/ZXingObjCTests/Resources/blackbox/itf-1/5.png
new file mode 100644
index 0000000..640d5c4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/5.txt b/ZXingObjCTests/Resources/blackbox/itf-1/5.txt
new file mode 100644
index 0000000..1351c69
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/5.txt
@@ -0,0 +1 @@
+0829220875
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/6.png b/ZXingObjCTests/Resources/blackbox/itf-1/6.png
new file mode 100644
index 0000000..50972f6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/6.txt b/ZXingObjCTests/Resources/blackbox/itf-1/6.txt
new file mode 100644
index 0000000..a92b62e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/6.txt
@@ -0,0 +1 @@
+0829220874
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/7.png b/ZXingObjCTests/Resources/blackbox/itf-1/7.png
new file mode 100644
index 0000000..4e78fc5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/7.txt b/ZXingObjCTests/Resources/blackbox/itf-1/7.txt
new file mode 100644
index 0000000..6c4c26e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/7.txt
@@ -0,0 +1 @@
+0817605453
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/8.png b/ZXingObjCTests/Resources/blackbox/itf-1/8.png
new file mode 100644
index 0000000..ef7557e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/8.txt b/ZXingObjCTests/Resources/blackbox/itf-1/8.txt
new file mode 100644
index 0000000..a92b62e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/8.txt
@@ -0,0 +1 @@
+0829220874
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/9.png b/ZXingObjCTests/Resources/blackbox/itf-1/9.png
new file mode 100644
index 0000000..bd1ec3c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-1/9.txt b/ZXingObjCTests/Resources/blackbox/itf-1/9.txt
new file mode 100644
index 0000000..d46b0cf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-1/9.txt
@@ -0,0 +1 @@
+0053611912
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/01.png b/ZXingObjCTests/Resources/blackbox/itf-2/01.png
new file mode 100644
index 0000000..f00ab8d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/01.txt b/ZXingObjCTests/Resources/blackbox/itf-2/01.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/01.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/02.png b/ZXingObjCTests/Resources/blackbox/itf-2/02.png
new file mode 100644
index 0000000..f3ca5bb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/02.txt b/ZXingObjCTests/Resources/blackbox/itf-2/02.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/02.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/03.png b/ZXingObjCTests/Resources/blackbox/itf-2/03.png
new file mode 100644
index 0000000..7a2e0a6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/03.txt b/ZXingObjCTests/Resources/blackbox/itf-2/03.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/03.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/04.png b/ZXingObjCTests/Resources/blackbox/itf-2/04.png
new file mode 100644
index 0000000..2a5d15e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/04.txt b/ZXingObjCTests/Resources/blackbox/itf-2/04.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/04.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/05.png b/ZXingObjCTests/Resources/blackbox/itf-2/05.png
new file mode 100644
index 0000000..3a8a6c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/05.txt b/ZXingObjCTests/Resources/blackbox/itf-2/05.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/05.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/06.png b/ZXingObjCTests/Resources/blackbox/itf-2/06.png
new file mode 100644
index 0000000..97513cb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/06.txt b/ZXingObjCTests/Resources/blackbox/itf-2/06.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/06.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/07.png b/ZXingObjCTests/Resources/blackbox/itf-2/07.png
new file mode 100644
index 0000000..0a63686
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/07.txt b/ZXingObjCTests/Resources/blackbox/itf-2/07.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/07.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/08.png b/ZXingObjCTests/Resources/blackbox/itf-2/08.png
new file mode 100644
index 0000000..adfe9bc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/08.txt b/ZXingObjCTests/Resources/blackbox/itf-2/08.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/08.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/09.png b/ZXingObjCTests/Resources/blackbox/itf-2/09.png
new file mode 100644
index 0000000..00adc80
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/09.txt b/ZXingObjCTests/Resources/blackbox/itf-2/09.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/09.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/10.png b/ZXingObjCTests/Resources/blackbox/itf-2/10.png
new file mode 100644
index 0000000..65db849
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/10.txt b/ZXingObjCTests/Resources/blackbox/itf-2/10.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/10.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/11.png b/ZXingObjCTests/Resources/blackbox/itf-2/11.png
new file mode 100644
index 0000000..82dad01
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/11.txt b/ZXingObjCTests/Resources/blackbox/itf-2/11.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/11.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/12.png b/ZXingObjCTests/Resources/blackbox/itf-2/12.png
new file mode 100644
index 0000000..bf93d01
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/12.txt b/ZXingObjCTests/Resources/blackbox/itf-2/12.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/12.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/13.png b/ZXingObjCTests/Resources/blackbox/itf-2/13.png
new file mode 100644
index 0000000..fb7deb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/itf-2/13.txt b/ZXingObjCTests/Resources/blackbox/itf-2/13.txt
new file mode 100644
index 0000000..a8fb53d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/itf-2/13.txt
@@ -0,0 +1 @@
+070429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/partial/01.png b/ZXingObjCTests/Resources/blackbox/partial/01.png
new file mode 100644
index 0000000..1e8d4bf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/02.png b/ZXingObjCTests/Resources/blackbox/partial/02.png
new file mode 100644
index 0000000..5337ec3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/03.png b/ZXingObjCTests/Resources/blackbox/partial/03.png
new file mode 100644
index 0000000..8ad85fe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/04.png b/ZXingObjCTests/Resources/blackbox/partial/04.png
new file mode 100644
index 0000000..36c9317
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/05.png b/ZXingObjCTests/Resources/blackbox/partial/05.png
new file mode 100644
index 0000000..27a29c6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/06.png b/ZXingObjCTests/Resources/blackbox/partial/06.png
new file mode 100644
index 0000000..09f48a5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/07.png b/ZXingObjCTests/Resources/blackbox/partial/07.png
new file mode 100644
index 0000000..228b3c4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/08.png b/ZXingObjCTests/Resources/blackbox/partial/08.png
new file mode 100644
index 0000000..7f3f19d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/09.png b/ZXingObjCTests/Resources/blackbox/partial/09.png
new file mode 100644
index 0000000..6b5e102
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/10.png b/ZXingObjCTests/Resources/blackbox/partial/10.png
new file mode 100644
index 0000000..1302789
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/11.png b/ZXingObjCTests/Resources/blackbox/partial/11.png
new file mode 100644
index 0000000..ae1a7f1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/12.png b/ZXingObjCTests/Resources/blackbox/partial/12.png
new file mode 100644
index 0000000..6b5d0d1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/13.png b/ZXingObjCTests/Resources/blackbox/partial/13.png
new file mode 100644
index 0000000..450e91e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/14.png b/ZXingObjCTests/Resources/blackbox/partial/14.png
new file mode 100644
index 0000000..eaade21
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/15.png b/ZXingObjCTests/Resources/blackbox/partial/15.png
new file mode 100644
index 0000000..ff83852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/16.png b/ZXingObjCTests/Resources/blackbox/partial/16.png
new file mode 100644
index 0000000..acaeea8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/17.png b/ZXingObjCTests/Resources/blackbox/partial/17.png
new file mode 100644
index 0000000..55ec618
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/18.png b/ZXingObjCTests/Resources/blackbox/partial/18.png
new file mode 100644
index 0000000..52c253b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/19.png b/ZXingObjCTests/Resources/blackbox/partial/19.png
new file mode 100644
index 0000000..72365cd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/20.png b/ZXingObjCTests/Resources/blackbox/partial/20.png
new file mode 100644
index 0000000..87ce76d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/21.png b/ZXingObjCTests/Resources/blackbox/partial/21.png
new file mode 100644
index 0000000..ba74867
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/22.png b/ZXingObjCTests/Resources/blackbox/partial/22.png
new file mode 100644
index 0000000..6c9892a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/23.png b/ZXingObjCTests/Resources/blackbox/partial/23.png
new file mode 100644
index 0000000..d9db0bd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/24.png b/ZXingObjCTests/Resources/blackbox/partial/24.png
new file mode 100644
index 0000000..f932457
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/25.png b/ZXingObjCTests/Resources/blackbox/partial/25.png
new file mode 100644
index 0000000..be35161
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/26.png b/ZXingObjCTests/Resources/blackbox/partial/26.png
new file mode 100644
index 0000000..50ab71e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/27.png b/ZXingObjCTests/Resources/blackbox/partial/27.png
new file mode 100644
index 0000000..b55c177
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/28.png b/ZXingObjCTests/Resources/blackbox/partial/28.png
new file mode 100644
index 0000000..23f9558
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/29.png b/ZXingObjCTests/Resources/blackbox/partial/29.png
new file mode 100644
index 0000000..547f0c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/30.png b/ZXingObjCTests/Resources/blackbox/partial/30.png
new file mode 100644
index 0000000..3a64f1f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/31.png b/ZXingObjCTests/Resources/blackbox/partial/31.png
new file mode 100644
index 0000000..7e42138
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/32.png b/ZXingObjCTests/Resources/blackbox/partial/32.png
new file mode 100644
index 0000000..514cf40
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/33.png b/ZXingObjCTests/Resources/blackbox/partial/33.png
new file mode 100644
index 0000000..ecb1f12
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/34.png b/ZXingObjCTests/Resources/blackbox/partial/34.png
new file mode 100644
index 0000000..6f3998b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/35.png b/ZXingObjCTests/Resources/blackbox/partial/35.png
new file mode 100644
index 0000000..d06cd60
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/36.png b/ZXingObjCTests/Resources/blackbox/partial/36.png
new file mode 100644
index 0000000..93e577e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/37.png b/ZXingObjCTests/Resources/blackbox/partial/37.png
new file mode 100644
index 0000000..0e62b8f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/38.png b/ZXingObjCTests/Resources/blackbox/partial/38.png
new file mode 100644
index 0000000..2c48b79
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/39.png b/ZXingObjCTests/Resources/blackbox/partial/39.png
new file mode 100644
index 0000000..5882b24
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/39.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/40.png b/ZXingObjCTests/Resources/blackbox/partial/40.png
new file mode 100644
index 0000000..6b139f9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/40.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/41.png b/ZXingObjCTests/Resources/blackbox/partial/41.png
new file mode 100644
index 0000000..fbb367c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/41.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/42.png b/ZXingObjCTests/Resources/blackbox/partial/42.png
new file mode 100644
index 0000000..fbe2a1c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/42.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/43.png b/ZXingObjCTests/Resources/blackbox/partial/43.png
new file mode 100644
index 0000000..17cacde
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/43.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/44.png b/ZXingObjCTests/Resources/blackbox/partial/44.png
new file mode 100644
index 0000000..df26022
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/44.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/45.png b/ZXingObjCTests/Resources/blackbox/partial/45.png
new file mode 100644
index 0000000..c19a1b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/45.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/46.png b/ZXingObjCTests/Resources/blackbox/partial/46.png
new file mode 100644
index 0000000..0f61817
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/46.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/47.png b/ZXingObjCTests/Resources/blackbox/partial/47.png
new file mode 100644
index 0000000..7daa309
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/47.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/48.png b/ZXingObjCTests/Resources/blackbox/partial/48.png
new file mode 100644
index 0000000..bdaefa7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/48.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/49.png b/ZXingObjCTests/Resources/blackbox/partial/49.png
new file mode 100644
index 0000000..9ca9c46
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/49.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/50.png b/ZXingObjCTests/Resources/blackbox/partial/50.png
new file mode 100644
index 0000000..7ee0c8a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/50.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/51.png b/ZXingObjCTests/Resources/blackbox/partial/51.png
new file mode 100644
index 0000000..9eb02ea
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/51.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/52.png b/ZXingObjCTests/Resources/blackbox/partial/52.png
new file mode 100644
index 0000000..0a1e1cc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/52.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/53.png b/ZXingObjCTests/Resources/blackbox/partial/53.png
new file mode 100644
index 0000000..b9b4282
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/53.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/54.png b/ZXingObjCTests/Resources/blackbox/partial/54.png
new file mode 100644
index 0000000..cd4b859
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/54.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/55.png b/ZXingObjCTests/Resources/blackbox/partial/55.png
new file mode 100644
index 0000000..db2ceb1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/55.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/56.png b/ZXingObjCTests/Resources/blackbox/partial/56.png
new file mode 100644
index 0000000..8652f4f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/56.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/57.png b/ZXingObjCTests/Resources/blackbox/partial/57.png
new file mode 100644
index 0000000..184b09b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/57.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/59.png b/ZXingObjCTests/Resources/blackbox/partial/59.png
new file mode 100644
index 0000000..0135a46
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/59.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/60.png b/ZXingObjCTests/Resources/blackbox/partial/60.png
new file mode 100644
index 0000000..7bce219
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/60.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/partial/61.png b/ZXingObjCTests/Resources/blackbox/partial/61.png
new file mode 100644
index 0000000..a983142
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/partial/61.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/01.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/01.png
new file mode 100644
index 0000000..76de458
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/01.txt b/ZXingObjCTests/Resources/blackbox/pdf417-1/01.txt
new file mode 100644
index 0000000..8c84eae
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/01.txt
@@ -0,0 +1 @@
+This is PDF417
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/02.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/02.png
new file mode 100644
index 0000000..5d41771
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/02.txt b/ZXingObjCTests/Resources/blackbox/pdf417-1/02.txt
new file mode 100644
index 0000000..e9a9ea1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/02.txt
@@ -0,0 +1 @@
+12345678
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/03.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/03.png
new file mode 100644
index 0000000..7a13bb9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/03.txt b/ZXingObjCTests/Resources/blackbox/pdf417-1/03.txt
new file mode 100644
index 0000000..8a97eec
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/03.txt
@@ -0,0 +1 @@
+ActiveBarcode
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/04.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/04.png
new file mode 100644
index 0000000..bda5cda
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/04.txt b/ZXingObjCTests/Resources/blackbox/pdf417-1/04.txt
new file mode 100644
index 0000000..aa0e5da
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/04.txt
@@ -0,0 +1 @@
+-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/05.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/05.png
new file mode 100644
index 0000000..db2c031
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/05.txt b/ZXingObjCTests/Resources/blackbox/pdf417-1/05.txt
new file mode 100644
index 0000000..b6c1c37
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/05.txt
@@ -0,0 +1 @@
+-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/06.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/06.png
new file mode 100644
index 0000000..f77ab92
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/06.txt b/ZXingObjCTests/Resources/blackbox/pdf417-1/06.txt
new file mode 100644
index 0000000..f61edfc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/06.txt
@@ -0,0 +1 @@
+-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/07.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/07.png
new file mode 100644
index 0000000..3ab2624
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/07.txt b/ZXingObjCTests/Resources/blackbox/pdf417-1/07.txt
new file mode 100644
index 0000000..13e3209
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/07.txt
@@ -0,0 +1 @@
+-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-ActiveBarcode-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/09.bin b/ZXingObjCTests/Resources/blackbox/pdf417-1/09.bin
new file mode 100644
index 0000000..7633e3a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/09.bin
@@ -0,0 +1 @@
+! !Eô 5/D? ?FZ c'ÿ mAÉ #F
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/09.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/09.png
new file mode 100644
index 0000000..a876eb5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/10.png b/ZXingObjCTests/Resources/blackbox/pdf417-1/10.png
new file mode 100755
index 0000000..863844f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-1/10.txt b/ZXingObjCTests/Resources/blackbox/pdf417-1/10.txt
new file mode 100755
index 0000000..2215b03
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-1/10.txt
@@ -0,0 +1 @@
+PDF-417
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/01.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/01.png
new file mode 100755
index 0000000..44a1775
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/01.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/01.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/01.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/02.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/02.png
new file mode 100755
index 0000000..7236ea2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/02.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/02.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/02.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/03.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/03.png
new file mode 100755
index 0000000..857e8ba
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/03.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/03.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/03.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/04.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/04.png
new file mode 100755
index 0000000..5684848
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/04.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/04.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/04.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/05.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/05.png
new file mode 100755
index 0000000..1d5a366
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/05.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/05.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/05.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/06.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/06.png
new file mode 100755
index 0000000..0e979b6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/06.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/06.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/06.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/07.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/07.png
new file mode 100755
index 0000000..54bd9bc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/07.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/07.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/07.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/08.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/08.png
new file mode 100755
index 0000000..51de70f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/08.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/08.txt
new file mode 100644
index 0000000..cd7a77d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/08.txt
@@ -0,0 +1 @@
+A PDF 417 barcode with ASCII text
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/09.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/09.png
new file mode 100755
index 0000000..aa072cb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/09.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/09.txt
new file mode 100644
index 0000000..cd7a77d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/09.txt
@@ -0,0 +1 @@
+A PDF 417 barcode with ASCII text
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/10.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/10.png
new file mode 100755
index 0000000..d19e85d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/10.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/10.txt
new file mode 100644
index 0000000..cd7a77d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/10.txt
@@ -0,0 +1 @@
+A PDF 417 barcode with ASCII text
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/11.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/11.png
new file mode 100755
index 0000000..5df3a06
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/11.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/11.txt
new file mode 100644
index 0000000..cd7a77d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/11.txt
@@ -0,0 +1 @@
+A PDF 417 barcode with ASCII text
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/12.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/12.png
new file mode 100755
index 0000000..678a8a1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/12.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/12.txt
new file mode 100644
index 0000000..cd7a77d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/12.txt
@@ -0,0 +1 @@
+A PDF 417 barcode with ASCII text
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/13.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/13.png
new file mode 100755
index 0000000..2ce4a04
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/13.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/13.txt
new file mode 100644
index 0000000..cd7a77d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/13.txt
@@ -0,0 +1 @@
+A PDF 417 barcode with ASCII text
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/14.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/14.png
new file mode 100755
index 0000000..bbd0c6f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/14.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/14.txt
new file mode 100644
index 0000000..cd7a77d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/14.txt
@@ -0,0 +1 @@
+A PDF 417 barcode with ASCII text
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/15.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/15.png
new file mode 100755
index 0000000..4735dc6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/15.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/15.txt
new file mode 100644
index 0000000..cd7a77d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/15.txt
@@ -0,0 +1 @@
+A PDF 417 barcode with ASCII text
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/16.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/16.png
new file mode 100755
index 0000000..b97f607
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/16.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/16.txt
new file mode 100644
index 0000000..ccef763
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/16.txt
@@ -0,0 +1 @@
+A larger PDF 417 barcode with a greater amount of text. This is a more difficult test for mobile devices to resolve.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/17.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/17.png
new file mode 100755
index 0000000..cfd5b8c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/17.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/17.txt
new file mode 100644
index 0000000..ccef763
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/17.txt
@@ -0,0 +1 @@
+A larger PDF 417 barcode with a greater amount of text. This is a more difficult test for mobile devices to resolve.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/18.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/18.png
new file mode 100755
index 0000000..ed618b1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/18.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/18.txt
new file mode 100644
index 0000000..ccef763
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/18.txt
@@ -0,0 +1 @@
+A larger PDF 417 barcode with a greater amount of text. This is a more difficult test for mobile devices to resolve.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/19.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/19.png
new file mode 100755
index 0000000..c290a05
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/19.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/19.txt
new file mode 100644
index 0000000..ccef763
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/19.txt
@@ -0,0 +1 @@
+A larger PDF 417 barcode with a greater amount of text. This is a more difficult test for mobile devices to resolve.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/20.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/20.png
new file mode 100755
index 0000000..1d5dfb8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/20.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/20.txt
new file mode 100644
index 0000000..ccef763
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/20.txt
@@ -0,0 +1 @@
+A larger PDF 417 barcode with a greater amount of text. This is a more difficult test for mobile devices to resolve.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/21.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/21.png
new file mode 100755
index 0000000..9dffd89
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/21.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/21.txt
new file mode 100644
index 0000000..ccef763
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/21.txt
@@ -0,0 +1 @@
+A larger PDF 417 barcode with a greater amount of text. This is a more difficult test for mobile devices to resolve.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/22.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/22.png
new file mode 100755
index 0000000..4ec0353
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/22.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/22.txt
new file mode 100644
index 0000000..ccef763
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/22.txt
@@ -0,0 +1 @@
+A larger PDF 417 barcode with a greater amount of text. This is a more difficult test for mobile devices to resolve.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/23.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/23.png
new file mode 100755
index 0000000..ccdded2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/23.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/23.txt
new file mode 100644
index 0000000..ccef763
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/23.txt
@@ -0,0 +1 @@
+A larger PDF 417 barcode with a greater amount of text. This is a more difficult test for mobile devices to resolve.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/24.bin b/ZXingObjCTests/Resources/blackbox/pdf417-2/24.bin
new file mode 100755
index 0000000..4effe2e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/24.bin
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/24.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/24.png
new file mode 100755
index 0000000..fd88028
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/25.png b/ZXingObjCTests/Resources/blackbox/pdf417-2/25.png
new file mode 100755
index 0000000..739a9a9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-2/25.txt b/ZXingObjCTests/Resources/blackbox/pdf417-2/25.txt
new file mode 100644
index 0000000..8c84eae
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-2/25.txt
@@ -0,0 +1 @@
+This is PDF417
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/01.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/01.png
new file mode 100644
index 0000000..06acdc1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/01.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/01.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/01.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/02.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/02.png
new file mode 100644
index 0000000..1d1395a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/02.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/02.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/02.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/03.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/03.png
new file mode 100644
index 0000000..cd176be
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/03.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/03.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/03.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/04.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/04.png
new file mode 100644
index 0000000..2cc8b1c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/04.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/04.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/04.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/05.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/05.png
new file mode 100644
index 0000000..82a2892
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/05.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/05.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/05.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/06.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/06.png
new file mode 100644
index 0000000..39b4901
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/06.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/06.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/06.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/07.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/07.png
new file mode 100644
index 0000000..16acf0b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/07.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/07.txt
new file mode 100644
index 0000000..3d34dff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/07.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 4.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/08.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/08.png
new file mode 100644
index 0000000..161e567
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/08.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/08.txt
new file mode 100644
index 0000000..3d34dff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/08.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 4.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/09.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/09.png
new file mode 100644
index 0000000..7ed3153
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/09.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/09.txt
new file mode 100644
index 0000000..3d34dff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/09.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 4.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/10.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/10.png
new file mode 100644
index 0000000..c32bf8a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/10.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/10.txt
new file mode 100644
index 0000000..3d34dff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/10.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 4.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/11.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/11.png
new file mode 100755
index 0000000..21219c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/11.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/11.txt
new file mode 100755
index 0000000..3d34dff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/11.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 4.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/12.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/12.png
new file mode 100644
index 0000000..fd16e2d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/12.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/12.txt
new file mode 100755
index 0000000..6cb0094
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/12.txt
@@ -0,0 +1 @@
+[)>010210011840539080122327430201FDE238351251289 1/13.0LBY76 NINTH AVENUENEW YORK CITYNYSUSAN ZOLEZZI0610ZED00411ZGOOGLE12Z212565418630Z3100119200000114Z4TH FLOOR15Z39795720Z0.000.0028Z9080122327430201K533 PROGRAMS26Z584a
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/13.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/13.png
new file mode 100755
index 0000000..f2d9d26
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/13.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/13.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/13.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/14.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/14.png
new file mode 100755
index 0000000..ecb5b09
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/14.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/14.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/14.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/15.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/15.png
new file mode 100755
index 0000000..41bca85
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/15.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/15.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/15.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/16.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/16.png
new file mode 100755
index 0000000..0b4674a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/16.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/16.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/16.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/17.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/17.png
new file mode 100755
index 0000000..48ab2d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/17.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/17.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/17.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/18.png b/ZXingObjCTests/Resources/blackbox/pdf417-3/18.png
new file mode 100755
index 0000000..7ca0e67
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-3/18.txt b/ZXingObjCTests/Resources/blackbox/pdf417-3/18.txt
new file mode 100644
index 0000000..26c04ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-3/18.txt
@@ -0,0 +1 @@
+A larger PDF417 barcode with text and error correction level 8.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-4/01-01.png b/ZXingObjCTests/Resources/blackbox/pdf417-4/01-01.png
new file mode 100644
index 0000000..c1bf329
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-4/01-01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-4/01.bin b/ZXingObjCTests/Resources/blackbox/pdf417-4/01.bin
new file mode 100644
index 0000000..4effe2e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-4/01.bin
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-4/02-01.png b/ZXingObjCTests/Resources/blackbox/pdf417-4/02-01.png
new file mode 100644
index 0000000..12d12ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-4/02-01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-4/02-02.png b/ZXingObjCTests/Resources/blackbox/pdf417-4/02-02.png
new file mode 100644
index 0000000..55ac0bb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-4/02-02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/pdf417-4/02.bin b/ZXingObjCTests/Resources/blackbox/pdf417-4/02.bin
new file mode 100644
index 0000000..9c07c8f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/pdf417-4/02.bin
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/1.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/1.png
new file mode 100644
index 0000000..8c80b11
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/1.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/1.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/1.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/10.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/10.png
new file mode 100644
index 0000000..cd727f2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/10.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/10.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/10.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/11.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/11.png
new file mode 100644
index 0000000..388c40b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/11.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/11.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/11.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/12.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/12.png
new file mode 100644
index 0000000..c47eb55
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/12.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/12.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/12.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/13.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/13.png
new file mode 100644
index 0000000..5568fef
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/13.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/13.txt
new file mode 100644
index 0000000..c6adb03
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/13.txt
@@ -0,0 +1 @@
+http://google.com/gwt/n?u=bluenile.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/14.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/14.png
new file mode 100644
index 0000000..a22d5b3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/14.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/14.txt
new file mode 100644
index 0000000..c6adb03
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/14.txt
@@ -0,0 +1 @@
+http://google.com/gwt/n?u=bluenile.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/15.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/15.png
new file mode 100644
index 0000000..004d36f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/15.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/15.txt
new file mode 100644
index 0000000..c6adb03
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/15.txt
@@ -0,0 +1 @@
+http://google.com/gwt/n?u=bluenile.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/16.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/16.png
new file mode 100644
index 0000000..5666aaa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/16.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/16.txt
new file mode 100644
index 0000000..31a244c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/16.txt
@@ -0,0 +1,4 @@
+Sean Owen
+srowen@google.com
+917-364-2918
+http://awesome-thoughts.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/17.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/17.png
new file mode 100644
index 0000000..62d86d1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/17.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/17.txt
new file mode 100644
index 0000000..31a244c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/17.txt
@@ -0,0 +1,4 @@
+Sean Owen
+srowen@google.com
+917-364-2918
+http://awesome-thoughts.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/18.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/18.png
new file mode 100644
index 0000000..7d39c4a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/18.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/18.txt
new file mode 100644
index 0000000..31a244c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/18.txt
@@ -0,0 +1,4 @@
+Sean Owen
+srowen@google.com
+917-364-2918
+http://awesome-thoughts.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/19.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/19.png
new file mode 100644
index 0000000..3839f58
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/19.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/19.txt
new file mode 100644
index 0000000..31a244c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/19.txt
@@ -0,0 +1,4 @@
+Sean Owen
+srowen@google.com
+917-364-2918
+http://awesome-thoughts.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/2.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/2.png
new file mode 100644
index 0000000..528030d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/2.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/2.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/2.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/20.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/20.png
new file mode 100644
index 0000000..97b4f0a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/20.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/20.txt
new file mode 100644
index 0000000..31a244c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/20.txt
@@ -0,0 +1,4 @@
+Sean Owen
+srowen@google.com
+917-364-2918
+http://awesome-thoughts.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/3.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/3.png
new file mode 100644
index 0000000..2611b88
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/3.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/3.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/3.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/4.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/4.png
new file mode 100644
index 0000000..9c02d90
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/4.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/4.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/4.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/5.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/5.png
new file mode 100644
index 0000000..3667ca6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/5.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/5.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/5.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/6.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/6.png
new file mode 100644
index 0000000..5d38294
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/6.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/6.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/6.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/7.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/7.png
new file mode 100644
index 0000000..44c1557
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/7.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/7.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/7.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/8.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/8.png
new file mode 100644
index 0000000..4513892
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/8.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/8.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/8.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/9.png b/ZXingObjCTests/Resources/blackbox/qrcode-1/9.png
new file mode 100644
index 0000000..a589ee4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-1/9.txt b/ZXingObjCTests/Resources/blackbox/qrcode-1/9.txt
new file mode 100644
index 0000000..cb6b805
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-1/9.txt
@@ -0,0 +1 @@
+MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/1.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/1.png
new file mode 100644
index 0000000..9924161
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/1.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/1.txt
new file mode 100644
index 0000000..58493bd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/1.txt
@@ -0,0 +1 @@
+When we at WRT talk about \"text,\" we are generally talking about a particular kind of readable information encoding - and readable is a complex proposition. Text may be stylized in a way we are unfamiliar with, as in blackletter - it may be interspersed with some markup we don\'t understand, such as HTML - it may be be a substitution system we aren\'t familiar with, such as braille or morse code - or it may be a system that, while technically human-readable, isn\'t particularly optimized for reading by humans, as with barcodes (although barcodes can be read).
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/10.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/10.png
new file mode 100644
index 0000000..e8e208e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/10.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/10.txt
new file mode 100644
index 0000000..14632d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/10.txt
@@ -0,0 +1,2 @@
+Google モバイル
+http://google.jp
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/11.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/11.png
new file mode 100644
index 0000000..e96bb81
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/11.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/11.txt
new file mode 100644
index 0000000..2b574b7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/11.txt
@@ -0,0 +1,12 @@
+BEGIN:VCARD
+N:Kennedy;Steve
+TEL:+44 (0)7775 755503
+ADR;HOME:;;Flat 2, 43 Howitt Road, Belsize Park;London;;NW34LU;UK
+ORG:NetTek Ltd;
+TITLE:Consultant
+EMAIL:steve@nettek.co.uk
+URL:www.nettek.co.uk
+EMAIL;IM:MSN:steve@gbnet.net
+NOTE:Testing 1 2 3
+BDAY:19611105
+END:VCARD
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/12.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/12.png
new file mode 100644
index 0000000..adfdcd9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/12.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/12.txt
new file mode 100644
index 0000000..6c62da9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/12.txt
@@ -0,0 +1 @@
+The 2005 USGS aerial photography of the Washington Monument is censored.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/13.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/13.png
new file mode 100644
index 0000000..406a7cf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/13.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/13.txt
new file mode 100644
index 0000000..7729d64
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/13.txt
@@ -0,0 +1 @@
+The 2005 USGS aerial photograph of the Washington Monument is censored.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/14.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/14.png
new file mode 100644
index 0000000..230a352
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/14.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/14.txt
new file mode 100644
index 0000000..454a60e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/14.txt
@@ -0,0 +1 @@
+http://bbc.co.uk/programmes
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/15.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/15.png
new file mode 100644
index 0000000..5ff1520
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/15.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/15.txt
new file mode 100644
index 0000000..e6b5a97
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/15.txt
@@ -0,0 +1 @@
+In 25 words or less in the comments, below, tell us how QR codes will make the world less ordinary.
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/16.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/16.png
new file mode 100644
index 0000000..d0effb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/16.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/16.txt
new file mode 100644
index 0000000..f2c0201
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/16.txt
@@ -0,0 +1,4 @@
+[外側QRコード]
+
+*ダブルQR*
+http://d-qr.net/ex/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/17.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/17.png
new file mode 100644
index 0000000..33e42cb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/17.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/17.txt
new file mode 100644
index 0000000..7fba436
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/17.txt
@@ -0,0 +1,2 @@
+デザインQR
+http://d-qr.net/ex/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/18.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/18.png
new file mode 100644
index 0000000..13d65cb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/18.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/18.txt
new file mode 100644
index 0000000..beb8901
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/18.txt
@@ -0,0 +1,2 @@
+*デザインQR*
+http://d-qr.net/ex/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/19.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/19.png
new file mode 100644
index 0000000..ec1df04
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/19.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/19.txt
new file mode 100644
index 0000000..88f2165
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/19.txt
@@ -0,0 +1,2 @@
+*デザインQR*
+http://d-qr.net/ex/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/2.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/2.png
new file mode 100644
index 0000000..18f1f8a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/2.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/2.txt
new file mode 100644
index 0000000..38d534e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/2.txt
@@ -0,0 +1 @@
+LANDBYASCARC PERCEPTIBLEC EEK,OOZI GITSWAYTHROU AWILDERNESSOFBESUPPOSED,I CANT,ORATL ASTDWARFISH.NO REESOFANYM NITUDEARETOBESOMEMISERA EFRAMEBUIL I GS,TENANTED, U INGSUMMER THEFUGITIVE;BUTTHEWHO ISLAND,WI H EXCEPTIONOFT W STERNPOI ,ANDALINEOFLLIAMLEGR .HEWASOF N ENTHUGUENOTF Y ANDHADON BEENWEALTHTIONCONSE ENTUPONH SD STERS,HELEFTNE LE NS,THEC OFHISFOREOUTHCARO A.THISISLA AVERYSINGULARO TCONSISTSO ITTLEELSEDSAQUART FAMILE. TI PARATEDFROMTHEMA AN BYASCAR YPERCEPTERESORT MARSH EN EVEGETATION,ASMIGH SU POSED, CANT,ORATREMITY, ORT OULTRIESTANDS,ANDWHEREARESOM MIS FRAMEBUIFEVER,MAYBE INDEED, TO;BUTT EISLAND,WITNYYEARSAGO,IC ACTED LLIAM AND.HEWASOFANNESHADREDUCEDHIM OWA IONC NSEQUENTUPONHISDSIDENCEATSULLIVA \'S HC ROLINA.THISISLANOUTTHR LESLON . THATN OINTE U RTEROF E.ITISTHROU ERNE DSANDSLI ,AFAVOR TOFT HEN.T
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/20.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/20.png
new file mode 100644
index 0000000..0a645ce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/20.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/20.txt
new file mode 100644
index 0000000..d88f5eb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/20.txt
@@ -0,0 +1,2 @@
+*デザインQR*
+http://d-qr.net/ex/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/21.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/21.png
new file mode 100644
index 0000000..be83a0b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/21.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/21.txt
new file mode 100644
index 0000000..09c84c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/21.txt
@@ -0,0 +1,2 @@
+*デザインQR*
+http://d-qr.net/ex/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/22.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/22.png
new file mode 100644
index 0000000..083f511
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/22.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/22.txt
new file mode 100644
index 0000000..eeaa3a7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/22.txt
@@ -0,0 +1 @@
+http://www.hotpepper.jp/mobile/cgi-bin/MBLC80100.cgi?SA=00&Z=AG&vos=hpp064&uid=NULLGWDOCOMO
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/23.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/23.png
new file mode 100644
index 0000000..27ced01
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/23.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/23.txt
new file mode 100644
index 0000000..c7cd5be
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/23.txt
@@ -0,0 +1 @@
+http://aniful.jp/pr/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/24.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/24.png
new file mode 100644
index 0000000..1b3854a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/24.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/24.txt
new file mode 100644
index 0000000..41bcbc1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/24.txt
@@ -0,0 +1,2 @@
+*デザインQR*
+http://d-qr.net/ex/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/25.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/25.png
new file mode 100644
index 0000000..d284360
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/25.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/25.txt
new file mode 100644
index 0000000..2742bc1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/25.txt
@@ -0,0 +1 @@
+MEBKM:TITLE:;URL:http://d.kaywa.com/2020400102;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/26.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/26.png
new file mode 100644
index 0000000..421072a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/26.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/26.txt
new file mode 100644
index 0000000..c4f62fe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/26.txt
@@ -0,0 +1,3 @@
+<デザインQR>
+イラスト入りカラーQRコード
+http://d-qr.net/ex/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/27.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/27.png
new file mode 100644
index 0000000..29cda4b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/27.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/27.txt
new file mode 100644
index 0000000..bb0c693
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/27.txt
@@ -0,0 +1,2 @@
+*デザインQR*
+http://d-qr.net/ex/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/28.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/28.png
new file mode 100644
index 0000000..ccbb4a6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/28.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/28.txt
new file mode 100644
index 0000000..c44369e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/28.txt
@@ -0,0 +1 @@
+http://www.webtech.co.jp/k/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/29.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/29.png
new file mode 100644
index 0000000..64fee6d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/29.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/29.txt
new file mode 100644
index 0000000..87ad299
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/29.txt
@@ -0,0 +1,3 @@
+http://live.fdgm.jp/u/event/hype/hype_top.html
+
+MEBKM:TITLE:hypeモバイル;URL:http\://live.fdgm.jp/u/event/hype/hype_top.html;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/30.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/30.png
new file mode 100644
index 0000000..2dc5e45
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/30.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/30.txt
new file mode 100644
index 0000000..bc64130
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/30.txt
@@ -0,0 +1 @@
+MECARD:N:測試;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/31.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/31.png
new file mode 100644
index 0000000..e57d2d2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/31.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/31.txt
new file mode 100644
index 0000000..59d2e9d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/31.txt
@@ -0,0 +1 @@
+今度のバージョンでは文章の暗号化ができます。
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/32.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/32.png
new file mode 100644
index 0000000..86572c5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/32.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/32.txt
new file mode 100644
index 0000000..2b574b7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/32.txt
@@ -0,0 +1,12 @@
+BEGIN:VCARD
+N:Kennedy;Steve
+TEL:+44 (0)7775 755503
+ADR;HOME:;;Flat 2, 43 Howitt Road, Belsize Park;London;;NW34LU;UK
+ORG:NetTek Ltd;
+TITLE:Consultant
+EMAIL:steve@nettek.co.uk
+URL:www.nettek.co.uk
+EMAIL;IM:MSN:steve@gbnet.net
+NOTE:Testing 1 2 3
+BDAY:19611105
+END:VCARD
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/33.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/33.png
new file mode 100644
index 0000000..45d6b39
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/33.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/33.txt
new file mode 100644
index 0000000..a8d077e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/33.txt
@@ -0,0 +1 @@
+AD:SUB:阿;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/34.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/34.png
new file mode 100644
index 0000000..0f55ee4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/34.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/34.txt
new file mode 100644
index 0000000..d83e8aa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/34.txt
@@ -0,0 +1 @@
+http://www.google.com/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/35.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/35.png
new file mode 100644
index 0000000..6b17f3e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/35.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/35.txt
new file mode 100644
index 0000000..d83e8aa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/35.txt
@@ -0,0 +1 @@
+http://www.google.com/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/4.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/4.png
new file mode 100644
index 0000000..f11eb70
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/4.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/4.txt
new file mode 100644
index 0000000..dd36eda
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/4.txt
@@ -0,0 +1 @@
+http://wwws.keihin.ktr.mlit.go.jp/keitai/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/5.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/5.png
new file mode 100644
index 0000000..d7f3de7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/5.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/5.txt
new file mode 100644
index 0000000..9a35ecd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/5.txt
@@ -0,0 +1 @@
+2021200000
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/6.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/6.png
new file mode 100644
index 0000000..c3689de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/6.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/6.txt
new file mode 100644
index 0000000..87c34b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/6.txt
@@ -0,0 +1 @@
+http://d.kaywa.com/20207100
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/7.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/7.png
new file mode 100644
index 0000000..a8bea69
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/7.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/7.txt
new file mode 100644
index 0000000..b8c822d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/7.txt
@@ -0,0 +1 @@
+BIZCARD:N:Todd;X:Ogasawara;T:Tech Geek;C:MobileViews.com;A:MobileTown USA;E:editor@mobileviews.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/8.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/8.png
new file mode 100644
index 0000000..f2aeaeb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/8.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/8.txt
new file mode 100644
index 0000000..9e0a7f8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/8.txt
@@ -0,0 +1 @@
+http://staticrooster.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/9.png b/ZXingObjCTests/Resources/blackbox/qrcode-2/9.png
new file mode 100644
index 0000000..dde744c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-2/9.txt b/ZXingObjCTests/Resources/blackbox/qrcode-2/9.txt
new file mode 100644
index 0000000..292aea1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-2/9.txt
@@ -0,0 +1 @@
+Morden
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/01.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/01.png
new file mode 100644
index 0000000..0516fde
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/01.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/01.txt
new file mode 100644
index 0000000..4960897
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/01.txt
@@ -0,0 +1 @@
+http://arnaud.sahuguet.com/graffiti/test.php?ll=-74.00309961503218,40.74102573163046,0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/02.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/02.png
new file mode 100644
index 0000000..c5f1503
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/02.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/02.txt
new file mode 100644
index 0000000..4960897
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/02.txt
@@ -0,0 +1 @@
+http://arnaud.sahuguet.com/graffiti/test.php?ll=-74.00309961503218,40.74102573163046,0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/03.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/03.png
new file mode 100644
index 0000000..d343328
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/03.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/03.txt
new file mode 100644
index 0000000..4960897
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/03.txt
@@ -0,0 +1 @@
+http://arnaud.sahuguet.com/graffiti/test.php?ll=-74.00309961503218,40.74102573163046,0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/04.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/04.png
new file mode 100644
index 0000000..2b91e82
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/04.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/04.txt
new file mode 100644
index 0000000..4960897
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/04.txt
@@ -0,0 +1 @@
+http://arnaud.sahuguet.com/graffiti/test.php?ll=-74.00309961503218,40.74102573163046,0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/05.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/05.png
new file mode 100644
index 0000000..91ba4c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/05.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/05.txt
new file mode 100644
index 0000000..4960897
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/05.txt
@@ -0,0 +1 @@
+http://arnaud.sahuguet.com/graffiti/test.php?ll=-74.00309961503218,40.74102573163046,0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/06.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/06.png
new file mode 100644
index 0000000..a817273
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/06.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/06.txt
new file mode 100644
index 0000000..4960897
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/06.txt
@@ -0,0 +1 @@
+http://arnaud.sahuguet.com/graffiti/test.php?ll=-74.00309961503218,40.74102573163046,0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/07.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/07.png
new file mode 100644
index 0000000..40d4e90
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/07.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/07.txt
new file mode 100644
index 0000000..4960897
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/07.txt
@@ -0,0 +1 @@
+http://arnaud.sahuguet.com/graffiti/test.php?ll=-74.00309961503218,40.74102573163046,0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/08.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/08.png
new file mode 100644
index 0000000..0f66362
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/08.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/08.txt
new file mode 100644
index 0000000..4960897
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/08.txt
@@ -0,0 +1 @@
+http://arnaud.sahuguet.com/graffiti/test.php?ll=-74.00309961503218,40.74102573163046,0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/09.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/09.png
new file mode 100644
index 0000000..cdc8ffe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/09.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/09.txt
new file mode 100644
index 0000000..4960897
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/09.txt
@@ -0,0 +1 @@
+http://arnaud.sahuguet.com/graffiti/test.php?ll=-74.00309961503218,40.74102573163046,0
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/10.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/10.png
new file mode 100644
index 0000000..11878d1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/10.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/10.txt
new file mode 100644
index 0000000..352576d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/10.txt
@@ -0,0 +1 @@
+MECARD:N:Google 411,;TEL:18665881077;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/11.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/11.png
new file mode 100644
index 0000000..1ac137b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/11.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/11.txt
new file mode 100644
index 0000000..352576d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/11.txt
@@ -0,0 +1 @@
+MECARD:N:Google 411,;TEL:18665881077;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/12.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/12.png
new file mode 100644
index 0000000..2f10260
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/12.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/12.txt
new file mode 100644
index 0000000..352576d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/12.txt
@@ -0,0 +1 @@
+MECARD:N:Google 411,;TEL:18665881077;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/13.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/13.png
new file mode 100644
index 0000000..4cdc64d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/13.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/13.txt
new file mode 100644
index 0000000..352576d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/13.txt
@@ -0,0 +1 @@
+MECARD:N:Google 411,;TEL:18665881077;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/14.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/14.png
new file mode 100644
index 0000000..e1386f8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/14.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/14.txt
new file mode 100644
index 0000000..352576d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/14.txt
@@ -0,0 +1 @@
+MECARD:N:Google 411,;TEL:18665881077;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/15.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/15.png
new file mode 100644
index 0000000..c871b97
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/15.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/15.txt
new file mode 100644
index 0000000..352576d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/15.txt
@@ -0,0 +1 @@
+MECARD:N:Google 411,;TEL:18665881077;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/16.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/16.png
new file mode 100644
index 0000000..da6406d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/16.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/16.txt
new file mode 100644
index 0000000..352576d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/16.txt
@@ -0,0 +1 @@
+MECARD:N:Google 411,;TEL:18665881077;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/17.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/17.png
new file mode 100644
index 0000000..d31cf51
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/17.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/17.txt
new file mode 100644
index 0000000..352576d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/17.txt
@@ -0,0 +1 @@
+MECARD:N:Google 411,;TEL:18665881077;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/18.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/18.png
new file mode 100644
index 0000000..64de4bc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/18.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/18.txt
new file mode 100644
index 0000000..44a23fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/18.txt
@@ -0,0 +1,2 @@
+UI office hours signup
+http://www.corp.google.com/sparrow/ui_office_hours/
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/19.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/19.png
new file mode 100644
index 0000000..c8e84f5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/19.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/19.txt
new file mode 100644
index 0000000..44a23fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/19.txt
@@ -0,0 +1,2 @@
+UI office hours signup
+http://www.corp.google.com/sparrow/ui_office_hours/
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/20.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/20.png
new file mode 100644
index 0000000..e973428
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/20.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/20.txt
new file mode 100644
index 0000000..44a23fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/20.txt
@@ -0,0 +1,2 @@
+UI office hours signup
+http://www.corp.google.com/sparrow/ui_office_hours/
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/21.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/21.png
new file mode 100644
index 0000000..c9aa5ab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/21.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/21.txt
new file mode 100644
index 0000000..44a23fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/21.txt
@@ -0,0 +1,2 @@
+UI office hours signup
+http://www.corp.google.com/sparrow/ui_office_hours/
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/22.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/22.png
new file mode 100644
index 0000000..56fc693
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/22.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/22.txt
new file mode 100644
index 0000000..44a23fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/22.txt
@@ -0,0 +1,2 @@
+UI office hours signup
+http://www.corp.google.com/sparrow/ui_office_hours/
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/23.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/23.png
new file mode 100644
index 0000000..ff41d0e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/23.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/23.txt
new file mode 100644
index 0000000..44a23fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/23.txt
@@ -0,0 +1,2 @@
+UI office hours signup
+http://www.corp.google.com/sparrow/ui_office_hours/
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/24.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/24.png
new file mode 100644
index 0000000..ea7b5b7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/24.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/24.txt
new file mode 100644
index 0000000..44a23fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/24.txt
@@ -0,0 +1,2 @@
+UI office hours signup
+http://www.corp.google.com/sparrow/ui_office_hours/
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/25.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/25.png
new file mode 100644
index 0000000..8ccf05c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/25.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/25.txt
new file mode 100644
index 0000000..44a23fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/25.txt
@@ -0,0 +1,2 @@
+UI office hours signup
+http://www.corp.google.com/sparrow/ui_office_hours/
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/26.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/26.png
new file mode 100644
index 0000000..4c73b76
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/26.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/26.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/26.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/27.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/27.png
new file mode 100644
index 0000000..62ff369
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/27.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/27.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/27.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/28.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/28.png
new file mode 100644
index 0000000..fce05e1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/28.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/28.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/28.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/29.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/29.png
new file mode 100644
index 0000000..5663531
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/29.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/29.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/29.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/30.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/30.png
new file mode 100644
index 0000000..cfd247c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/30.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/30.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/30.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/31.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/31.png
new file mode 100644
index 0000000..1613197
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/31.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/31.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/31.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/32.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/32.png
new file mode 100644
index 0000000..64faf8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/32.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/32.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/32.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/33.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/33.png
new file mode 100644
index 0000000..d58e983
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/33.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/33.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/33.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/34.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/34.png
new file mode 100644
index 0000000..cb6b401
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/34.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/34.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/34.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/35.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/35.png
new file mode 100644
index 0000000..f9d38b1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/35.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/35.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/35.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/36.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/36.png
new file mode 100644
index 0000000..9e63693
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/36.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/36.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/36.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/37.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/37.png
new file mode 100644
index 0000000..c47245e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/37.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/37.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/37.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/38.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/38.png
new file mode 100644
index 0000000..ebf084d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/38.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/38.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/38.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/39.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/39.png
new file mode 100644
index 0000000..197c78c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/39.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/39.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/39.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/39.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/40.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/40.png
new file mode 100644
index 0000000..50ff9b8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/40.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/40.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/40.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/40.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/41.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/41.png
new file mode 100644
index 0000000..bcd098f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/41.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/41.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/41.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/41.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/42.png b/ZXingObjCTests/Resources/blackbox/qrcode-3/42.png
new file mode 100644
index 0000000..96aa633
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/42.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-3/42.txt b/ZXingObjCTests/Resources/blackbox/qrcode-3/42.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-3/42.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/01.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/01.png
new file mode 100644
index 0000000..9332ace
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/01.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/01.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/01.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/02.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/02.png
new file mode 100644
index 0000000..ca10fc5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/02.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/02.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/02.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/03.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/03.png
new file mode 100644
index 0000000..f0eea85
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/03.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/03.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/03.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/04.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/04.png
new file mode 100644
index 0000000..8922b2d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/04.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/04.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/04.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/05.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/05.png
new file mode 100644
index 0000000..3660418
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/05.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/05.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/05.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/06.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/06.png
new file mode 100644
index 0000000..d720caf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/06.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/06.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/06.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/07.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/07.png
new file mode 100644
index 0000000..3a206bd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/07.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/07.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/07.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/08.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/08.png
new file mode 100644
index 0000000..a79726b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/08.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/08.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/08.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/09.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/09.png
new file mode 100644
index 0000000..5ea0640
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/09.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/09.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/09.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/10.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/10.png
new file mode 100644
index 0000000..1e3b8a4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/10.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/10.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/10.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/11.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/11.png
new file mode 100644
index 0000000..82c9652
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/11.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/11.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/11.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/12.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/12.png
new file mode 100644
index 0000000..6f10785
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/12.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/12.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/12.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/13.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/13.png
new file mode 100644
index 0000000..4020548
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/13.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/13.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/13.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/14.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/14.png
new file mode 100644
index 0000000..b547f72
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/14.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/14.txt
new file mode 100644
index 0000000..f94af84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/14.txt
@@ -0,0 +1 @@
+Google Print Ads - T.G.I.A.F. - January 31, 2008
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/15.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/15.png
new file mode 100644
index 0000000..008c271
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/15.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/15.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/15.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/16.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/16.png
new file mode 100644
index 0000000..38a5be2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/16.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/16.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/16.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/17.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/17.png
new file mode 100644
index 0000000..c40df6a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/17.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/17.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/17.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/18.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/18.png
new file mode 100644
index 0000000..9ce0eae
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/18.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/18.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/18.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/19.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/19.png
new file mode 100644
index 0000000..fdf79a8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/19.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/19.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/19.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/20.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/20.png
new file mode 100644
index 0000000..afcce6f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/20.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/20.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/20.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/21.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/21.png
new file mode 100644
index 0000000..3379b17
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/21.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/21.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/21.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/22.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/22.png
new file mode 100644
index 0000000..1a40424
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/22.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/22.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/22.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/23.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/23.png
new file mode 100644
index 0000000..c13d170
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/23.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/23.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/23.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/24.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/24.png
new file mode 100644
index 0000000..e026f48
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/24.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/24.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/24.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/25.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/25.png
new file mode 100644
index 0000000..2e1000e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/25.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/25.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/25.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/26.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/26.png
new file mode 100644
index 0000000..1547094
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/26.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/26.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/26.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/27.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/27.png
new file mode 100644
index 0000000..668a20b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/27.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/27.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/27.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/28.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/28.png
new file mode 100644
index 0000000..de12827
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/28.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/28.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/28.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/29.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/29.png
new file mode 100644
index 0000000..bc4adad
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/29.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/29.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/29.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/30.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/30.png
new file mode 100644
index 0000000..bcef3ad
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/30.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/30.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/30.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/31.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/31.png
new file mode 100644
index 0000000..bb2f55a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/31.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/31.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/31.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/32.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/32.png
new file mode 100644
index 0000000..1203c16
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/32.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/32.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/32.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/33.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/33.png
new file mode 100644
index 0000000..ed103fa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/33.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/33.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/33.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/34.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/34.png
new file mode 100644
index 0000000..8591a93
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/34.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/34.txt
new file mode 100644
index 0000000..1469db2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/34.txt
@@ -0,0 +1 @@
+http://code.google.com
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/35.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/35.png
new file mode 100644
index 0000000..ca31d89
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/35.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/35.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/35.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/36.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/36.png
new file mode 100644
index 0000000..19056ff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/36.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/36.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/36.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/37.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/37.png
new file mode 100644
index 0000000..a68653a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/37.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/37.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/37.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/38.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/38.png
new file mode 100644
index 0000000..d243afe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/38.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/38.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/38.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/39.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/39.png
new file mode 100644
index 0000000..4b35768
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/39.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/39.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/39.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/39.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/40.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/40.png
new file mode 100644
index 0000000..1511411
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/40.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/40.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/40.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/40.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/41.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/41.png
new file mode 100644
index 0000000..5de6d84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/41.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/41.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/41.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/41.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/42.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/42.png
new file mode 100644
index 0000000..fcdbf1a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/42.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/42.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/42.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/42.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/43.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/43.png
new file mode 100644
index 0000000..798dbe8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/43.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/43.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/43.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/43.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/44.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/44.png
new file mode 100644
index 0000000..d060a16
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/44.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/44.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/44.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/44.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/45.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/45.png
new file mode 100644
index 0000000..8e389ad
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/45.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/45.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/45.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/45.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/46.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/46.png
new file mode 100644
index 0000000..57313f0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/46.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/46.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/46.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/46.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/47.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/47.png
new file mode 100644
index 0000000..65cd1b7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/47.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/47.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/47.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/47.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/48.png b/ZXingObjCTests/Resources/blackbox/qrcode-4/48.png
new file mode 100644
index 0000000..e6b2cfc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/48.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-4/48.txt b/ZXingObjCTests/Resources/blackbox/qrcode-4/48.txt
new file mode 100644
index 0000000..41872c8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-4/48.txt
@@ -0,0 +1 @@
+http://code.google.com/p/zxing/
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/01.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/01.png
new file mode 100644
index 0000000..98957e6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/01.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/01.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/01.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/02.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/02.png
new file mode 100644
index 0000000..ca77f8e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/02.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/02.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/02.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/03.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/03.png
new file mode 100644
index 0000000..e5e468a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/03.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/03.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/03.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/04.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/04.png
new file mode 100644
index 0000000..efc4d8f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/04.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/04.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/04.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/05.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/05.png
new file mode 100644
index 0000000..34ca8c5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/05.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/05.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/05.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/06.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/06.png
new file mode 100644
index 0000000..993d417
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/06.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/06.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/06.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/07.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/07.png
new file mode 100644
index 0000000..2be78b6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/07.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/07.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/07.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/08.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/08.png
new file mode 100644
index 0000000..77f8e24
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/08.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/08.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/08.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/09.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/09.png
new file mode 100644
index 0000000..1d3eee5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/09.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/09.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/09.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/10.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/10.png
new file mode 100644
index 0000000..8f1b71a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/10.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/10.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/10.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/11.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/11.png
new file mode 100644
index 0000000..79d403f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/11.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/11.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/11.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/12.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/12.png
new file mode 100644
index 0000000..75758fd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/12.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/12.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/12.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/13.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/13.png
new file mode 100644
index 0000000..ea965f7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/13.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/13.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/13.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/14.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/14.png
new file mode 100644
index 0000000..011b4e1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/14.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/14.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/14.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/15.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/15.png
new file mode 100644
index 0000000..a6d4ddc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/15.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/15.txt
new file mode 100644
index 0000000..424f852
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/15.txt
@@ -0,0 +1 @@
+MECARD:N:Sean Owen;TEL:+12125658770;EMAIL:srowen@google.com;;
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/16.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/16.png
new file mode 100644
index 0000000..ceabbad
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/16.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/16.txt
new file mode 100644
index 0000000..7175d7a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/16.txt
@@ -0,0 +1,57 @@
+THROUGH THE LOOKING-GLASS
+
+By Lewis Carroll
+
+
+CHAPTER I. Looking-Glass house
+
+One thing was certain, that the WHITE kitten had had nothing to do with
+it:--it was the black kitten's fault entirely. For the white kitten had
+been having its face washed by the old cat for the last quarter of
+an hour (and bearing it pretty well, considering); so you see that it
+COULDN'T have had any hand in the mischief.
+
+The way Dinah washed her children's faces was this: first she held the
+poor thing down by its ear with one paw, and then with the other paw she
+rubbed its face all over, the wrong way, beginning at the nose: and
+just now, as I said, she was hard at work on the white kitten, which was
+lying quite still and trying to purr--no doubt feeling that it was all
+meant for its good.
+
+But the black kitten had been finished with earlier in the afternoon,
+and so, while Alice was sitting curled up in a corner of the great
+arm-chair, half talking to herself and half asleep, the kitten had been
+having a grand game of romps with the ball of worsted Alice had been
+trying to wind up, and had been rolling it up and down till it had all
+come undone again; and there it was, spread over the hearth-rug, all
+knots and tangles, with the kitten running after its own tail in the
+middle.
+
+'Oh, you wicked little thing!' cried Alice, catching up the kitten, and
+giving it a little kiss to make it understand that it was in disgrace.
+'Really, Dinah ought to have taught you better manners! You OUGHT,
+Dinah, you know you ought!' she added, looking reproachfully at the old
+cat, and speaking in as cross a voice as she could manage--and then she
+scrambled back into the arm-chair, taking the kitten and the worsted
+with her, and began winding up the ball again. But she didn't get on
+very fast, as she was talking all the time, sometimes to the kitten, and
+sometimes to herself. Kitty sat very demurely on her knee, pretending to
+watch the progress of the winding, and now and then putting out one
+paw and gently touching the ball, as if it would be glad to help, if it
+might.
+
+'Do you know what to-morrow is, Kitty?' Alice began. 'You'd have guessed
+if you'd been up in the window with me--only Dinah was making you tidy,
+so you couldn't. I was watching the boys getting in sticks for the
+bonfire--and it wants plenty of sticks, Kitty! Only it got so cold, and
+it snowed so, they had to leave off. Never mind, Kitty, we'll go and
+see the bonfire to-morrow.' Here Alice wound two or three turns of the
+worsted round the kitten's neck, just to see how it would look: this led
+to a scramble, in which the ball rolled down upon the floor, and yards
+and yards of it got unwound again.
+
+'Do you know, I was so angry, Kitty,' Alice went on as soon as they were
+comfortably settled again, 'when I saw all the mischief you had been
+doing, I was very nearly opening the window, and putting you out into
+the snow! And you'd have deserved it, you little mischievous darling!
+Wha
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/17.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/17.png
new file mode 100644
index 0000000..8446be0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/17.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/17.txt
new file mode 100644
index 0000000..967a10b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/17.txt
@@ -0,0 +1,46 @@
+THROUGH THE LOOKING-GLASS
+
+By Lewis Carroll
+
+
+CHAPTER I. Looking-Glass house
+
+One thing was certain, that the WHITE kitten had had nothing to do with
+it:--it was the black kitten's fault entirely. For the white kitten had
+been having its face washed by the old cat for the last quarter of
+an hour (and bearing it pretty well, considering); so you see that it
+COULDN'T have had any hand in the mischief.
+
+The way Dinah washed her children's faces was this: first she held the
+poor thing down by its ear with one paw, and then with the other paw she
+rubbed its face all over, the wrong way, beginning at the nose: and
+just now, as I said, she was hard at work on the white kitten, which was
+lying quite still and trying to purr--no doubt feeling that it was all
+meant for its good.
+
+But the black kitten had been finished with earlier in the afternoon,
+and so, while Alice was sitting curled up in a corner of the great
+arm-chair, half talking to herself and half asleep, the kitten had been
+having a grand game of romps with the ball of worsted Alice had been
+trying to wind up, and had been rolling it up and down till it had all
+come undone again; and there it was, spread over the hearth-rug, all
+knots and tangles, with the kitten running after its own tail in the
+middle.
+
+'Oh, you wicked little thing!' cried Alice, catching up the kitten, and
+giving it a little kiss to make it understand that it was in disgrace.
+'Really, Dinah ought to have taught you better manners! You OUGHT,
+Dinah, you know you ought!' she added, looking reproachfully at the old
+cat, and speaking in as cross a voice as she could manage--and then she
+scrambled back into the arm-chair, taking the kitten and the worsted
+with her, and began winding up the ball again. But she didn't get on
+very fast, as she was talking all the time, sometimes to the kitten, and
+sometimes to herself. Kitty sat very demurely on her knee, pretending to
+watch the progress of the winding, and now and then putting out one
+paw and gently touching the ball, as if it would be glad to help, if it
+might.
+
+'Do you know what to-morrow is, Kitty?' Alice began. 'You'd have guessed
+if you'd been up in the window with me--only Dinah was making you tidy,
+so you couldn't. I was watching the boys getting in sticks for the
+bonfire--and it wants plenty of sticks, Kitty! Only it
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/18.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/18.png
new file mode 100644
index 0000000..a52cb39
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/18.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/18.txt
new file mode 100644
index 0000000..863b77f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/18.txt
@@ -0,0 +1,36 @@
+THROUGH THE LOOKING-GLASS
+
+By Lewis Carroll
+
+
+CHAPTER I. Looking-Glass house
+
+One thing was certain, that the WHITE kitten had had nothing to do with
+it:--it was the black kitten's fault entirely. For the white kitten had
+been having its face washed by the old cat for the last quarter of
+an hour (and bearing it pretty well, considering); so you see that it
+COULDN'T have had any hand in the mischief.
+
+The way Dinah washed her children's faces was this: first she held the
+poor thing down by its ear with one paw, and then with the other paw she
+rubbed its face all over, the wrong way, beginning at the nose: and
+just now, as I said, she was hard at work on the white kitten, which was
+lying quite still and trying to purr--no doubt feeling that it was all
+meant for its good.
+
+But the black kitten had been finished with earlier in the afternoon,
+and so, while Alice was sitting curled up in a corner of the great
+arm-chair, half talking to herself and half asleep, the kitten had been
+having a grand game of romps with the ball of worsted Alice had been
+trying to wind up, and had been rolling it up and down till it had all
+come undone again; and there it was, spread over the hearth-rug, all
+knots and tangles, with the kitten running after its own tail in the
+middle.
+
+'Oh, you wicked little thing!' cried Alice, catching up the kitten, and
+giving it a little kiss to make it understand that it was in disgrace.
+'Really, Dinah ought to have taught you better manners! You OUGHT,
+Dinah, you know you ought!' she added, looking reproachfully at the old
+cat, and speaking in as cross a voice as she could manage--and then she
+scrambled back into the arm-ch
+
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/19.png b/ZXingObjCTests/Resources/blackbox/qrcode-5/19.png
new file mode 100644
index 0000000..4ed10c6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-5/19.txt b/ZXingObjCTests/Resources/blackbox/qrcode-5/19.txt
new file mode 100644
index 0000000..845cd05
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-5/19.txt
@@ -0,0 +1,28 @@
+THROUGH THE LOOKING-GLASS
+
+By Lewis Carroll
+
+
+CHAPTER I. Looking-Glass house
+
+One thing was certain, that the WHITE kitten had had nothing to do with
+it:--it was the black kitten's fault entirely. For the white kitten had
+been having its face washed by the old cat for the last quarter of
+an hour (and bearing it pretty well, considering); so you see that it
+COULDN'T have had any hand in the mischief.
+
+The way Dinah washed her children's faces was this: first she held the
+poor thing down by its ear with one paw, and then with the other paw she
+rubbed its face all over, the wrong way, beginning at the nose: and
+just now, as I said, she was hard at work on the white kitten, which was
+lying quite still and trying to purr--no doubt feeling that it was all
+meant for its good.
+
+But the black kitten had been finished with earlier in the afternoon,
+and so, while Alice was sitting curled up in a corner of the great
+arm-chair, half talking to herself and half asleep, the kitten had been
+having a grand game of romps with the ball of worsted Alice had been
+trying to wind up, and had been rolling it up and down till it had all
+come undone again; and there it was, spread over the hearth-rug, all
+knots and tangles, with the kitten running after its own tail in the
+midd
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/1.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/1.png
new file mode 100755
index 0000000..295e792
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/1.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/1.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/1.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/10.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/10.png
new file mode 100755
index 0000000..1bc5261
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/10.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/10.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/10.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/11.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/11.png
new file mode 100755
index 0000000..5c6039b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/11.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/11.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/11.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/12.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/12.png
new file mode 100755
index 0000000..9f315b1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/12.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/12.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/12.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/13.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/13.png
new file mode 100755
index 0000000..3e0523a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/13.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/13.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/13.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/14.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/14.png
new file mode 100755
index 0000000..44e312d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/14.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/14.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/14.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/15.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/15.png
new file mode 100644
index 0000000..2ec4ec5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/15.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/15.txt
new file mode 100644
index 0000000..3b12464
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/15.txt
@@ -0,0 +1 @@
+TEST
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/2.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/2.png
new file mode 100755
index 0000000..b573832
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/2.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/2.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/2.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/3.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/3.png
new file mode 100755
index 0000000..e4d7f8b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/3.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/3.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/3.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/4.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/4.png
new file mode 100755
index 0000000..458823b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/4.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/4.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/4.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/5.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/5.png
new file mode 100755
index 0000000..baf5814
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/5.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/5.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/5.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/6.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/6.png
new file mode 100755
index 0000000..d4289e7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/6.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/6.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/6.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/7.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/7.png
new file mode 100755
index 0000000..c4c602d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/7.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/7.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/7.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/8.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/8.png
new file mode 100755
index 0000000..2619be2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/8.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/8.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/8.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/9.png b/ZXingObjCTests/Resources/blackbox/qrcode-6/9.png
new file mode 100755
index 0000000..174e36d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/qrcode-6/9.txt b/ZXingObjCTests/Resources/blackbox/qrcode-6/9.txt
new file mode 100644
index 0000000..6a537b5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/qrcode-6/9.txt
@@ -0,0 +1 @@
+1234567890
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/1.png b/ZXingObjCTests/Resources/blackbox/rss14-1/1.png
new file mode 100644
index 0000000..55b2905
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/1.txt b/ZXingObjCTests/Resources/blackbox/rss14-1/1.txt
new file mode 100644
index 0000000..da8b2e7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/1.txt
@@ -0,0 +1 @@
+04412345678909
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/2.png b/ZXingObjCTests/Resources/blackbox/rss14-1/2.png
new file mode 100644
index 0000000..c286f91
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/2.txt b/ZXingObjCTests/Resources/blackbox/rss14-1/2.txt
new file mode 100644
index 0000000..6a694e3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/2.txt
@@ -0,0 +1 @@
+00821935106427
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/3.png b/ZXingObjCTests/Resources/blackbox/rss14-1/3.png
new file mode 100644
index 0000000..2a2f812
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/3.txt b/ZXingObjCTests/Resources/blackbox/rss14-1/3.txt
new file mode 100644
index 0000000..accc36e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/3.txt
@@ -0,0 +1 @@
+00075678164125
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/4.png b/ZXingObjCTests/Resources/blackbox/rss14-1/4.png
new file mode 100644
index 0000000..e9ee653
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/4.txt b/ZXingObjCTests/Resources/blackbox/rss14-1/4.txt
new file mode 100644
index 0000000..b8d2ea4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/4.txt
@@ -0,0 +1 @@
+20012345678909
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/5.png b/ZXingObjCTests/Resources/blackbox/rss14-1/5.png
new file mode 100644
index 0000000..46c29f9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/5.txt b/ZXingObjCTests/Resources/blackbox/rss14-1/5.txt
new file mode 100644
index 0000000..50109f5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/5.txt
@@ -0,0 +1 @@
+00034567890125
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/6.png b/ZXingObjCTests/Resources/blackbox/rss14-1/6.png
new file mode 100644
index 0000000..e7b4c47
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-1/6.txt b/ZXingObjCTests/Resources/blackbox/rss14-1/6.txt
new file mode 100644
index 0000000..eabb743
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-1/6.txt
@@ -0,0 +1 @@
+00012345678905
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/1.png b/ZXingObjCTests/Resources/blackbox/rss14-2/1.png
new file mode 100755
index 0000000..d2033e8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/1.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/1.txt
new file mode 100644
index 0000000..da8b2e7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/1.txt
@@ -0,0 +1 @@
+04412345678909
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/10.png b/ZXingObjCTests/Resources/blackbox/rss14-2/10.png
new file mode 100755
index 0000000..a2a7b03
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/10.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/10.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/10.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/11.png b/ZXingObjCTests/Resources/blackbox/rss14-2/11.png
new file mode 100755
index 0000000..149cfec
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/11.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/11.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/11.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/12.png b/ZXingObjCTests/Resources/blackbox/rss14-2/12.png
new file mode 100755
index 0000000..b007039
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/12.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/12.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/12.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/13.png b/ZXingObjCTests/Resources/blackbox/rss14-2/13.png
new file mode 100755
index 0000000..c2306f3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/13.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/13.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/13.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/14.png b/ZXingObjCTests/Resources/blackbox/rss14-2/14.png
new file mode 100755
index 0000000..4a9dea6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/14.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/14.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/14.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/15.png b/ZXingObjCTests/Resources/blackbox/rss14-2/15.png
new file mode 100755
index 0000000..a0f8e64
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/15.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/15.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/15.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/16.png b/ZXingObjCTests/Resources/blackbox/rss14-2/16.png
new file mode 100755
index 0000000..e919782
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/16.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/16.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/16.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/17.png b/ZXingObjCTests/Resources/blackbox/rss14-2/17.png
new file mode 100755
index 0000000..b2e7e8f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/17.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/17.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/17.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/18.png b/ZXingObjCTests/Resources/blackbox/rss14-2/18.png
new file mode 100755
index 0000000..76a5599
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/18.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/18.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/18.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/19.png b/ZXingObjCTests/Resources/blackbox/rss14-2/19.png
new file mode 100755
index 0000000..c2408e1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/19.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/19.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/19.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/2.png b/ZXingObjCTests/Resources/blackbox/rss14-2/2.png
new file mode 100755
index 0000000..7b348da
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/2.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/2.txt
new file mode 100644
index 0000000..da8b2e7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/2.txt
@@ -0,0 +1 @@
+04412345678909
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/20.png b/ZXingObjCTests/Resources/blackbox/rss14-2/20.png
new file mode 100755
index 0000000..6075a07
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/20.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/20.txt
new file mode 100644
index 0000000..eabb743
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/20.txt
@@ -0,0 +1 @@
+00012345678905
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/21.png b/ZXingObjCTests/Resources/blackbox/rss14-2/21.png
new file mode 100755
index 0000000..afbb277
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/21.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/21.txt
new file mode 100644
index 0000000..eabb743
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/21.txt
@@ -0,0 +1 @@
+00012345678905
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/22.png b/ZXingObjCTests/Resources/blackbox/rss14-2/22.png
new file mode 100755
index 0000000..15afdf8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/22.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/22.txt
new file mode 100644
index 0000000..eabb743
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/22.txt
@@ -0,0 +1 @@
+00012345678905
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/23.png b/ZXingObjCTests/Resources/blackbox/rss14-2/23.png
new file mode 100755
index 0000000..4dbfeba
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/23.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/23.txt
new file mode 100644
index 0000000..eabb743
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/23.txt
@@ -0,0 +1 @@
+00012345678905
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/24.png b/ZXingObjCTests/Resources/blackbox/rss14-2/24.png
new file mode 100755
index 0000000..469e37c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/24.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/24.txt
new file mode 100644
index 0000000..eabb743
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/24.txt
@@ -0,0 +1 @@
+00012345678905
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/3.png b/ZXingObjCTests/Resources/blackbox/rss14-2/3.png
new file mode 100755
index 0000000..badf6d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/3.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/3.txt
new file mode 100644
index 0000000..da8b2e7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/3.txt
@@ -0,0 +1 @@
+04412345678909
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/4.png b/ZXingObjCTests/Resources/blackbox/rss14-2/4.png
new file mode 100755
index 0000000..47028a6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/4.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/4.txt
new file mode 100644
index 0000000..da8b2e7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/4.txt
@@ -0,0 +1 @@
+04412345678909
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/5.png b/ZXingObjCTests/Resources/blackbox/rss14-2/5.png
new file mode 100755
index 0000000..eb5287a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/5.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/5.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/5.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/6.png b/ZXingObjCTests/Resources/blackbox/rss14-2/6.png
new file mode 100755
index 0000000..70051bd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/6.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/6.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/6.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/7.png b/ZXingObjCTests/Resources/blackbox/rss14-2/7.png
new file mode 100755
index 0000000..8f5d9f8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/7.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/7.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/7.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/8.png b/ZXingObjCTests/Resources/blackbox/rss14-2/8.png
new file mode 100755
index 0000000..0412c1c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/8.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/8.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/8.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/9.png b/ZXingObjCTests/Resources/blackbox/rss14-2/9.png
new file mode 100755
index 0000000..7f169ca
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rss14-2/9.txt b/ZXingObjCTests/Resources/blackbox/rss14-2/9.txt
new file mode 100644
index 0000000..adb4ff3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rss14-2/9.txt
@@ -0,0 +1 @@
+02001234567893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/1.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/1.png
new file mode 100644
index 0000000..51f66d8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/1.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/1.txt
new file mode 100644
index 0000000..8b369b3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/1.txt
@@ -0,0 +1 @@
+(11)100224(17)110224(3102)000100
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/10.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/10.png
new file mode 100644
index 0000000..7b75027
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/10.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/10.txt
new file mode 100644
index 0000000..09d4208
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/10.txt
@@ -0,0 +1 @@
+(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/11.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/11.png
new file mode 100644
index 0000000..9c142a1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/11.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/11.txt
new file mode 100644
index 0000000..abe2a81
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/11.txt
@@ -0,0 +1 @@
+(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/12.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/12.png
new file mode 100644
index 0000000..1841ee5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/12.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/12.txt
new file mode 100644
index 0000000..32ad2da
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/12.txt
@@ -0,0 +1 @@
+(01)98898765432106(3103)001750
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/13.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/13.png
new file mode 100644
index 0000000..79b9398
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/13.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/13.txt
new file mode 100644
index 0000000..dd36aab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/13.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/14.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/14.png
new file mode 100644
index 0000000..97a42de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/14.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/14.txt
new file mode 100644
index 0000000..fb00e31
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/14.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)0401234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/15.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/15.png
new file mode 100644
index 0000000..3acd716
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/15.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/15.txt
new file mode 100644
index 0000000..f2bfc4b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/15.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(11)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/16.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/16.png
new file mode 100644
index 0000000..ce53c59
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/16.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/16.txt
new file mode 100644
index 0000000..c9f248d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/16.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(11)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/17.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/17.png
new file mode 100644
index 0000000..d2d127f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/17.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/17.txt
new file mode 100644
index 0000000..9b4fc49
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/17.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(13)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/18.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/18.png
new file mode 100644
index 0000000..74c7521
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/18.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/18.txt
new file mode 100644
index 0000000..cd15aa0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/18.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(13)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/19.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/19.png
new file mode 100644
index 0000000..6602780
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/19.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/19.txt
new file mode 100644
index 0000000..dcd1561
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/19.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(15)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/2.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/2.png
new file mode 100644
index 0000000..acc6753
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/2.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/2.txt
new file mode 100644
index 0000000..b4113ac
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/2.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)001750
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/20.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/20.png
new file mode 100644
index 0000000..a4171e2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/20.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/20.txt
new file mode 100644
index 0000000..830845f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/20.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(15)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/21.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/21.png
new file mode 100644
index 0000000..32afeb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/21.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/21.txt
new file mode 100644
index 0000000..506b17b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/21.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(17)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/22.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/22.png
new file mode 100644
index 0000000..34f7588
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/22.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/22.txt
new file mode 100644
index 0000000..ca6045a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/22.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(17)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/23.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/23.png
new file mode 100644
index 0000000..4032f51
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/23.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/23.txt
new file mode 100644
index 0000000..a6f7e24
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/23.txt
@@ -0,0 +1 @@
+(10)56789(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/24.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/24.png
new file mode 100644
index 0000000..846a4f3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/24.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/24.txt
new file mode 100644
index 0000000..a7b3497
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/24.txt
@@ -0,0 +1 @@
+(10)567890(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/25.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/25.png
new file mode 100644
index 0000000..1b93c2d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/25.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/25.txt
new file mode 100644
index 0000000..62c17f1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/25.txt
@@ -0,0 +1 @@
+(10)123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/26.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/26.png
new file mode 100644
index 0000000..9beca4c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/26.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/26.txt
new file mode 100644
index 0000000..17966ee
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/26.txt
@@ -0,0 +1 @@
+(10)5678(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/27.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/27.png
new file mode 100644
index 0000000..0a1b491
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/27.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/27.txt
new file mode 100644
index 0000000..5263f7f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/27.txt
@@ -0,0 +1 @@
+(10)1098-1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/28.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/28.png
new file mode 100644
index 0000000..3079c03
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/28.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/28.txt
new file mode 100644
index 0000000..9208d92
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/28.txt
@@ -0,0 +1 @@
+(10)1098/1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/29.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/29.png
new file mode 100644
index 0000000..0bfb742
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/29.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/29.txt
new file mode 100644
index 0000000..b78623a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/29.txt
@@ -0,0 +1 @@
+(10)1098.1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/3.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/3.png
new file mode 100644
index 0000000..b78843b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/3.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/3.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/3.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/30.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/30.png
new file mode 100644
index 0000000..6427feb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/30.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/30.txt
new file mode 100644
index 0000000..82bfa6a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/30.txt
@@ -0,0 +1 @@
+(10)1098*1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/31.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/31.png
new file mode 100644
index 0000000..743f1fa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/31.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/31.txt
new file mode 100644
index 0000000..f6413d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/31.txt
@@ -0,0 +1 @@
+(10)1098,1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/32.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/32.png
new file mode 100644
index 0000000..bfedb3b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/32.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/32.txt
new file mode 100644
index 0000000..5e76631
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/32.txt
@@ -0,0 +1 @@
+(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/4.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/4.png
new file mode 100644
index 0000000..5f69ce2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/4.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/4.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/4.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/5.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/5.png
new file mode 100644
index 0000000..14e227a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/5.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/5.txt
new file mode 100644
index 0000000..4a70860
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/5.txt
@@ -0,0 +1 @@
+(01)90614141000015(3202)000150
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/6.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/6.png
new file mode 100644
index 0000000..a8a71ff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/6.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/6.txt
new file mode 100644
index 0000000..84f8807
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/6.txt
@@ -0,0 +1 @@
+(10)567(01)90012345678908(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/7.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/7.png
new file mode 100644
index 0000000..4561ad7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/7.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/7.txt
new file mode 100644
index 0000000..e8c7268
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/7.txt
@@ -0,0 +1 @@
+(10)567(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/8.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/8.png
new file mode 100644
index 0000000..d3cf3ec
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/8.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/8.txt
new file mode 100644
index 0000000..56981cd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/8.txt
@@ -0,0 +1 @@
+(10)567(11)010101(13)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/9.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/9.png
new file mode 100644
index 0000000..f6491ef
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-1/9.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/9.txt
new file mode 100644
index 0000000..84cf63c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-1/9.txt
@@ -0,0 +1 @@
+(10)567(3102)123456
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/12.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/12.png
new file mode 100644
index 0000000..a1427a7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/12.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/12.txt
new file mode 100644
index 0000000..32ad2da
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/12.txt
@@ -0,0 +1 @@
+(01)98898765432106(3103)001750
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/13.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/13.png
new file mode 100644
index 0000000..89e3347
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/13.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/13.txt
new file mode 100644
index 0000000..dd36aab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/13.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/16.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/16.png
new file mode 100644
index 0000000..4f46840
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/16.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/16.txt
new file mode 100644
index 0000000..c9f248d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/16.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(11)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/17.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/17.png
new file mode 100644
index 0000000..2db6061
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/17.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/17.txt
new file mode 100644
index 0000000..9b4fc49
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/17.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(13)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18.png
new file mode 100644
index 0000000..9a65044
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18.txt
new file mode 100644
index 0000000..cd15aa0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(13)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18b.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18b.png
new file mode 100644
index 0000000..0c84454
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18b.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18b.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18b.txt
new file mode 100644
index 0000000..cd15aa0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/18b.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)001750(13)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/19.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/19.png
new file mode 100644
index 0000000..0a028ab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/19.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/19.txt
new file mode 100644
index 0000000..dcd1561
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/19.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(15)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/21.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/21.png
new file mode 100644
index 0000000..13c9695
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/21.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/21.txt
new file mode 100644
index 0000000..506b17b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/21.txt
@@ -0,0 +1 @@
+(01)90012345678908(3102)001750(17)100312
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_01.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_01.png
new file mode 100644
index 0000000..927b956
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_01.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_01.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_01.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_02.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_02.png
new file mode 100644
index 0000000..87ae281
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_02.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_02.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_02.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_03.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_03.png
new file mode 100644
index 0000000..1ff07d7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_03.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_03.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_03.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_04.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_04.png
new file mode 100644
index 0000000..a5595ed
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_04.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_04.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_04.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_05.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_05.png
new file mode 100644
index 0000000..189d10e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_05.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_05.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_05.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_06.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_06.png
new file mode 100644
index 0000000..dabd86a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_06.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_06.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_06.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_07.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_07.png
new file mode 100644
index 0000000..26ec765
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_07.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_07.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_07.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_09.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_09.png
new file mode 100644
index 0000000..ee9eb52
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_09.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_09.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/3_09.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_00.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_00.png
new file mode 100644
index 0000000..d426a0a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_00.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_00.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_00.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_00.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_01.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_01.png
new file mode 100644
index 0000000..d176e1d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_01.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_01.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_01.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_02.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_02.png
new file mode 100644
index 0000000..4b5f5c3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_02.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_02.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_02.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_03.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_03.png
new file mode 100644
index 0000000..6a008b7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_03.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_03.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_03.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_04.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_04.png
new file mode 100644
index 0000000..a780e9b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_04.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_04.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_04.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_05.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_05.png
new file mode 100644
index 0000000..9acd7db
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_05.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_05.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/4_05.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/5.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/5.png
new file mode 100644
index 0000000..72c9e3b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-2/5.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/5.txt
new file mode 100644
index 0000000..4a70860
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-2/5.txt
@@ -0,0 +1 @@
+(01)90614141000015(3202)000150
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/1.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/1.png
new file mode 100644
index 0000000..d8099a4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/1.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/1.txt
new file mode 100644
index 0000000..ed31c4d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/1.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)012233(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/10.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/10.png
new file mode 100644
index 0000000..2c241ba
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/10.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/10.txt
new file mode 100644
index 0000000..e8f98fe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/10.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)010000
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/100.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/100.png
new file mode 100644
index 0000000..82bb8b9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/100.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/100.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/100.txt
new file mode 100644
index 0000000..4339de9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/100.txt
@@ -0,0 +1 @@
+(10)1098 1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/101.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/101.png
new file mode 100644
index 0000000..a66894c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/101.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/101.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/101.txt
new file mode 100644
index 0000000..6f63fb0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/101.txt
@@ -0,0 +1 @@
+(10)123456A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/102.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/102.png
new file mode 100644
index 0000000..72d8e36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/102.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/102.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/102.txt
new file mode 100644
index 0000000..5c1b912
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/102.txt
@@ -0,0 +1 @@
+(10)123456A1
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/103.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/103.png
new file mode 100644
index 0000000..d829e85
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/103.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/103.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/103.txt
new file mode 100644
index 0000000..d77a476
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/103.txt
@@ -0,0 +1 @@
+(10)123456A123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/104.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/104.png
new file mode 100644
index 0000000..152f5dd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/104.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/104.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/104.txt
new file mode 100644
index 0000000..2e2ec43
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/104.txt
@@ -0,0 +1 @@
+(10)123456A1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/105.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/105.png
new file mode 100644
index 0000000..a2cf18f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/105.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/105.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/105.txt
new file mode 100644
index 0000000..b607d14
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/105.txt
@@ -0,0 +1 @@
+(10)123456A1234A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/106.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/106.png
new file mode 100644
index 0000000..33af0cf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/106.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/106.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/106.txt
new file mode 100644
index 0000000..389adca
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/106.txt
@@ -0,0 +1 @@
+(10)123456A123456
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/107.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/107.png
new file mode 100644
index 0000000..d87581b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/107.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/107.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/107.txt
new file mode 100644
index 0000000..fffde5d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/107.txt
@@ -0,0 +1 @@
+(10)123456A12345678
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/108.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/108.png
new file mode 100644
index 0000000..c4bfab6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/108.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/108.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/108.txt
new file mode 100644
index 0000000..1ad0fbd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/108.txt
@@ -0,0 +1 @@
+(10)123456A1234A(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/109.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/109.png
new file mode 100644
index 0000000..99e9e70
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/109.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/109.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/109.txt
new file mode 100644
index 0000000..ac79617
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/109.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/1234567
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/11.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/11.png
new file mode 100644
index 0000000..c85138d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/11.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/11.txt
new file mode 100644
index 0000000..9895a67
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/11.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)032767
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/110.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/110.png
new file mode 100644
index 0000000..6c35a4a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/110.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/110.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/110.txt
new file mode 100644
index 0000000..163b64b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/110.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/ABCDEFG
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/111.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/111.png
new file mode 100644
index 0000000..dc8e829
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/111.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/111.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/111.txt
new file mode 100644
index 0000000..d359328
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/111.txt
@@ -0,0 +1 @@
+(10)1;:/ABCDEFGHIJKLM
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/112.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/112.png
new file mode 100644
index 0000000..cafb665
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/112.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/112.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/112.txt
new file mode 100644
index 0000000..c25e84f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/112.txt
@@ -0,0 +1 @@
+(10)1;:/0123456789012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/113.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/113.png
new file mode 100644
index 0000000..25f428b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/113.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/113.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/113.txt
new file mode 100644
index 0000000..2914766
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/113.txt
@@ -0,0 +1 @@
+(10)1;:/0123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/114.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/114.png
new file mode 100644
index 0000000..12d8942
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/114.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/114.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/114.txt
new file mode 100644
index 0000000..c8be9f3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/114.txt
@@ -0,0 +1 @@
+(10)1;:/0123(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/115.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/115.png
new file mode 100644
index 0000000..1a89487
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/115.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/115.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/115.txt
new file mode 100644
index 0000000..9a1581d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/115.txt
@@ -0,0 +1 @@
+(10)1
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/116.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/116.png
new file mode 100644
index 0000000..9df4779
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/116.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/116.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/116.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/116.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/117.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/117.png
new file mode 100644
index 0000000..1b93c2d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/117.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/117.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/117.txt
new file mode 100644
index 0000000..62c17f1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/117.txt
@@ -0,0 +1 @@
+(10)123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/12.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/12.png
new file mode 100644
index 0000000..ea645f8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/12.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/12.txt
new file mode 100644
index 0000000..dd36aab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/12.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/13.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/13.png
new file mode 100644
index 0000000..3a75edc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/13.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/13.txt
new file mode 100644
index 0000000..0429d93
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/13.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/14.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/14.png
new file mode 100644
index 0000000..a0b3613
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/14.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/14.txt
new file mode 100644
index 0000000..fb00e31
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/14.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)0401234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/15.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/15.png
new file mode 100644
index 0000000..1e23828
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/15.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/15.txt
new file mode 100644
index 0000000..9066194
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/15.txt
@@ -0,0 +1 @@
+(01)00012345678905(10)ABC123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/16.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/16.png
new file mode 100644
index 0000000..0a5dca7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/16.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/16.txt
new file mode 100644
index 0000000..8f0841f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/16.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)UNIVERSITY-OF-DEUSTO
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/17.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/17.png
new file mode 100644
index 0000000..37809c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/17.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/17.txt
new file mode 100644
index 0000000..89fda98
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/17.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)PIRAMIDE-PROJECT
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/18.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/18.png
new file mode 100644
index 0000000..af317f1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/18.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/18.txt
new file mode 100644
index 0000000..b120324
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/18.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)TREELOGIC
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/19.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/19.png
new file mode 100644
index 0000000..9beca4c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/19.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/19.txt
new file mode 100644
index 0000000..17966ee
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/19.txt
@@ -0,0 +1 @@
+(10)5678(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/2.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/2.png
new file mode 100644
index 0000000..2331373
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/2.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/2.txt
new file mode 100644
index 0000000..d7f0a6a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/2.txt
@@ -0,0 +1 @@
+(01)91234567980129(3103)012233(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/20.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/20.png
new file mode 100644
index 0000000..2cf7a1b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/20.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/20.txt
new file mode 100644
index 0000000..b948648
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/20.txt
@@ -0,0 +1 @@
+(10)5678(11)001010
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/21.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/21.png
new file mode 100644
index 0000000..846a4f3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/21.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/21.txt
new file mode 100644
index 0000000..a7b3497
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/21.txt
@@ -0,0 +1 @@
+(10)567890(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/22.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/22.png
new file mode 100644
index 0000000..359f41e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/22.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/22.txt
new file mode 100644
index 0000000..e8c7268
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/22.txt
@@ -0,0 +1 @@
+(10)567(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/23.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/23.png
new file mode 100644
index 0000000..0a1b491
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/23.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/23.txt
new file mode 100644
index 0000000..5263f7f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/23.txt
@@ -0,0 +1 @@
+(10)1098-1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/24.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/24.png
new file mode 100644
index 0000000..743f1fa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/24.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/24.txt
new file mode 100644
index 0000000..f6413d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/24.txt
@@ -0,0 +1 @@
+(10)1098,1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/25.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/25.png
new file mode 100644
index 0000000..3079c03
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/25.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/25.txt
new file mode 100644
index 0000000..9208d92
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/25.txt
@@ -0,0 +1 @@
+(10)1098/1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/26.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/26.png
new file mode 100644
index 0000000..0bfb742
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/26.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/26.txt
new file mode 100644
index 0000000..b78623a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/26.txt
@@ -0,0 +1 @@
+(10)1098.1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/27.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/27.png
new file mode 100644
index 0000000..6427feb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/27.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/27.txt
new file mode 100644
index 0000000..82bfa6a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/27.txt
@@ -0,0 +1 @@
+(10)1098*1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/28.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/28.png
new file mode 100644
index 0000000..bf00890
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/28.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/28.txt
new file mode 100644
index 0000000..6263d99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/28.txt
@@ -0,0 +1 @@
+(10)1098a1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/29.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/29.png
new file mode 100644
index 0000000..6988b64
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/29.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/29.txt
new file mode 100644
index 0000000..35fc529
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/29.txt
@@ -0,0 +1 @@
+(10)1098!1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/3.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/3.png
new file mode 100644
index 0000000..a6527d7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/3.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/3.txt
new file mode 100644
index 0000000..ab93c97
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/3.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/30.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/30.png
new file mode 100644
index 0000000..25aea80
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/30.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/30.txt
new file mode 100644
index 0000000..d0d95d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/30.txt
@@ -0,0 +1 @@
+(10)1098"1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/31.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/31.png
new file mode 100644
index 0000000..6fa0755
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/31.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/31.txt
new file mode 100644
index 0000000..53bf781
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/31.txt
@@ -0,0 +1 @@
+(10)1098%1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/32.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/32.png
new file mode 100644
index 0000000..334d1a2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/32.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/32.txt
new file mode 100644
index 0000000..5d1d351
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/32.txt
@@ -0,0 +1 @@
+(10)1098&1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/33.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/33.png
new file mode 100644
index 0000000..803ea0b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/33.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/33.txt
new file mode 100644
index 0000000..f00c6bb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/33.txt
@@ -0,0 +1 @@
+(10)1098'1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/34.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/34.png
new file mode 100644
index 0000000..3bbc1e8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/34.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/34.txt
new file mode 100644
index 0000000..18b90ec
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/34.txt
@@ -0,0 +1 @@
+(10)1098+1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/35.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/35.png
new file mode 100644
index 0000000..edba7f2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/35.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/35.txt
new file mode 100644
index 0000000..96f9049
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/35.txt
@@ -0,0 +1 @@
+(10)1098:1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/36.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/36.png
new file mode 100644
index 0000000..ef1755f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/36.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/36.txt
new file mode 100644
index 0000000..2dd84d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/36.txt
@@ -0,0 +1 @@
+(10)1098;1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/37.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/37.png
new file mode 100644
index 0000000..940fa56
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/37.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/37.txt
new file mode 100644
index 0000000..a64a6db
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/37.txt
@@ -0,0 +1 @@
+(10)1098<1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/38.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/38.png
new file mode 100644
index 0000000..336cd5f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/38.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/38.txt
new file mode 100644
index 0000000..c7cc606
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/38.txt
@@ -0,0 +1 @@
+(10)1098=1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/39.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/39.png
new file mode 100644
index 0000000..ca9024c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/39.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/39.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/39.txt
new file mode 100644
index 0000000..7345e4e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/39.txt
@@ -0,0 +1 @@
+(10)1098>1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/4.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/4.png
new file mode 100644
index 0000000..52e1b5d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/4.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/4.txt
new file mode 100644
index 0000000..fca726b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/4.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)000101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/40.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/40.png
new file mode 100644
index 0000000..1aefb4c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/40.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/40.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/40.txt
new file mode 100644
index 0000000..5e152de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/40.txt
@@ -0,0 +1 @@
+(10)1098?1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/41.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/41.png
new file mode 100644
index 0000000..d2bece9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/41.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/41.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/41.txt
new file mode 100644
index 0000000..aad1b28
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/41.txt
@@ -0,0 +1 @@
+(10)1098_1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/42.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/42.png
new file mode 100644
index 0000000..fdbfe03
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/42.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/42.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/42.txt
new file mode 100644
index 0000000..4339de9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/42.txt
@@ -0,0 +1 @@
+(10)1098 1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/43.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/43.png
new file mode 100644
index 0000000..322a0a5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/43.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/43.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/43.txt
new file mode 100644
index 0000000..6f63fb0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/43.txt
@@ -0,0 +1 @@
+(10)123456A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/44.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/44.png
new file mode 100644
index 0000000..19cb99c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/44.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/44.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/44.txt
new file mode 100644
index 0000000..2e2ec43
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/44.txt
@@ -0,0 +1 @@
+(10)123456A1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/45.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/45.png
new file mode 100644
index 0000000..fa8ebe8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/45.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/45.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/45.txt
new file mode 100644
index 0000000..b607d14
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/45.txt
@@ -0,0 +1 @@
+(10)123456A1234A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/46.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/46.png
new file mode 100644
index 0000000..e69a1b1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/46.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/46.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/46.txt
new file mode 100644
index 0000000..389adca
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/46.txt
@@ -0,0 +1 @@
+(10)123456A123456
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/47.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/47.png
new file mode 100644
index 0000000..3e902d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/47.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/47.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/47.txt
new file mode 100644
index 0000000..fffde5d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/47.txt
@@ -0,0 +1 @@
+(10)123456A12345678
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/48.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/48.png
new file mode 100644
index 0000000..f76300a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/48.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/48.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/48.txt
new file mode 100644
index 0000000..ac79617
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/48.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/1234567
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/49.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/49.png
new file mode 100644
index 0000000..2800ea0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/49.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/49.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/49.txt
new file mode 100644
index 0000000..163b64b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/49.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/ABCDEFG
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/5.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/5.png
new file mode 100644
index 0000000..847a523
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/5.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/5.txt
new file mode 100644
index 0000000..b4113ac
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/5.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)001750
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/50.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/50.png
new file mode 100644
index 0000000..c8d5dac
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/50.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/50.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/50.txt
new file mode 100644
index 0000000..d359328
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/50.txt
@@ -0,0 +1 @@
+(10)1;:/ABCDEFGHIJKLM
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/51.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/51.png
new file mode 100644
index 0000000..a0fd5ab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/51.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/51.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/51.txt
new file mode 100644
index 0000000..c25e84f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/51.txt
@@ -0,0 +1 @@
+(10)1;:/0123456789012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/52.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/52.png
new file mode 100644
index 0000000..0c7a973
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/52.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/52.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/52.txt
new file mode 100644
index 0000000..2914766
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/52.txt
@@ -0,0 +1 @@
+(10)1;:/0123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/53.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/53.png
new file mode 100644
index 0000000..6216161
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/53.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/53.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/53.txt
new file mode 100644
index 0000000..c8be9f3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/53.txt
@@ -0,0 +1 @@
+(10)1;:/0123(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/54.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/54.png
new file mode 100644
index 0000000..5440e2d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/54.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/54.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/54.txt
new file mode 100644
index 0000000..ed31c4d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/54.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)012233(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/55.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/55.png
new file mode 100644
index 0000000..0f14fbc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/55.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/55.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/55.txt
new file mode 100644
index 0000000..d7f0a6a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/55.txt
@@ -0,0 +1 @@
+(01)91234567980129(3103)012233(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/56.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/56.png
new file mode 100644
index 0000000..0c1a9b2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/56.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/56.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/56.txt
new file mode 100644
index 0000000..ab93c97
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/56.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/57.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/57.png
new file mode 100644
index 0000000..ab0be98
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/57.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/57.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/57.txt
new file mode 100644
index 0000000..fca726b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/57.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)000101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/58.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/58.png
new file mode 100644
index 0000000..ad8a1b9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/58.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/58.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/58.txt
new file mode 100644
index 0000000..b4113ac
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/58.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)001750
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/59.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/59.png
new file mode 100644
index 0000000..6cbc6de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/59.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/59.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/59.txt
new file mode 100644
index 0000000..57a2c64
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/59.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)032767
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/6.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/6.png
new file mode 100644
index 0000000..37cf344
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/6.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/6.txt
new file mode 100644
index 0000000..57a2c64
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/6.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)032767
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/60.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/60.png
new file mode 100644
index 0000000..6a5e4df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/60.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/60.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/60.txt
new file mode 100644
index 0000000..bfa4177
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/60.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)000000
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/61.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/61.png
new file mode 100644
index 0000000..91e2bb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/61.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/61.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/61.txt
new file mode 100644
index 0000000..e0da7fa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/61.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)000156
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/62.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/62.png
new file mode 100644
index 0000000..1c16204
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/62.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/62.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/62.txt
new file mode 100644
index 0000000..01af485
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/62.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)009999
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/63.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/63.png
new file mode 100644
index 0000000..1fef978
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/63.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/63.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/63.txt
new file mode 100644
index 0000000..e8f98fe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/63.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)010000
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/64.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/64.png
new file mode 100644
index 0000000..96861ae
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/64.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/64.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/64.txt
new file mode 100644
index 0000000..9895a67
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/64.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)032767
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/65.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/65.png
new file mode 100644
index 0000000..79b9398
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/65.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/65.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/65.txt
new file mode 100644
index 0000000..dd36aab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/65.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/66.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/66.png
new file mode 100644
index 0000000..c1c95b3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/66.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/66.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/66.txt
new file mode 100644
index 0000000..0429d93
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/66.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/67.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/67.png
new file mode 100644
index 0000000..97a42de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/67.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/67.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/67.txt
new file mode 100644
index 0000000..fb00e31
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/67.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)0401234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/68.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/68.png
new file mode 100644
index 0000000..5261789
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/68.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/68.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/68.txt
new file mode 100644
index 0000000..b5f3fe9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/68.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)040EUR
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/69.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/69.png
new file mode 100644
index 0000000..c90290c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/69.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/69.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/69.txt
new file mode 100644
index 0000000..e95bc8d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/69.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)04055GBP
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/7.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/7.png
new file mode 100644
index 0000000..d96918e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/7.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/7.txt
new file mode 100644
index 0000000..bfa4177
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/7.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)000000
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/70.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/70.png
new file mode 100644
index 0000000..0cd2128
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/70.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/70.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/70.txt
new file mode 100644
index 0000000..37c6cb3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/70.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)04066USD778899
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/71.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/71.png
new file mode 100644
index 0000000..93539de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/71.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/71.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/71.txt
new file mode 100644
index 0000000..9066194
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/71.txt
@@ -0,0 +1 @@
+(01)00012345678905(10)ABC123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/72.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/72.png
new file mode 100644
index 0000000..8d5fa2a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/72.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/72.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/72.txt
new file mode 100644
index 0000000..8f0841f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/72.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)UNIVERSITY-OF-DEUSTO
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/73.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/73.png
new file mode 100644
index 0000000..0232411
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/73.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/73.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/73.txt
new file mode 100644
index 0000000..89fda98
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/73.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)PIRAMIDE-PROJECT
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/74.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/74.png
new file mode 100644
index 0000000..44c936d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/74.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/74.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/74.txt
new file mode 100644
index 0000000..b120324
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/74.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)TREELOGIC
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/75.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/75.png
new file mode 100644
index 0000000..7b75027
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/75.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/75.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/75.txt
new file mode 100644
index 0000000..09d4208
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/75.txt
@@ -0,0 +1 @@
+(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/76.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/76.png
new file mode 100644
index 0000000..bfedb3b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/76.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/76.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/76.txt
new file mode 100644
index 0000000..5e76631
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/76.txt
@@ -0,0 +1 @@
+(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/77.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/77.png
new file mode 100644
index 0000000..baac622
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/77.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/77.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/77.txt
new file mode 100644
index 0000000..17966ee
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/77.txt
@@ -0,0 +1 @@
+(10)5678(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/78.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/78.png
new file mode 100644
index 0000000..923e2a4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/78.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/78.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/78.txt
new file mode 100644
index 0000000..b948648
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/78.txt
@@ -0,0 +1 @@
+(10)5678(11)001010
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/79.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/79.png
new file mode 100644
index 0000000..1e6bf4d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/79.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/79.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/79.txt
new file mode 100644
index 0000000..a7b3497
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/79.txt
@@ -0,0 +1 @@
+(10)567890(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/8.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/8.png
new file mode 100644
index 0000000..6155417
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/8.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/8.txt
new file mode 100644
index 0000000..e0da7fa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/8.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)000156
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/80.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/80.png
new file mode 100644
index 0000000..4561ad7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/80.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/80.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/80.txt
new file mode 100644
index 0000000..e8c7268
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/80.txt
@@ -0,0 +1 @@
+(10)567(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/81.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/81.png
new file mode 100644
index 0000000..030d820
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/81.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/81.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/81.txt
new file mode 100644
index 0000000..5263f7f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/81.txt
@@ -0,0 +1 @@
+(10)1098-1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/82.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/82.png
new file mode 100644
index 0000000..039e01e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/82.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/82.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/82.txt
new file mode 100644
index 0000000..f6413d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/82.txt
@@ -0,0 +1 @@
+(10)1098,1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/83.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/83.png
new file mode 100644
index 0000000..c6cb58f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/83.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/83.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/83.txt
new file mode 100644
index 0000000..9208d92
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/83.txt
@@ -0,0 +1 @@
+(10)1098/1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/84.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/84.png
new file mode 100644
index 0000000..c6e3d3b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/84.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/84.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/84.txt
new file mode 100644
index 0000000..b78623a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/84.txt
@@ -0,0 +1 @@
+(10)1098.1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/85.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/85.png
new file mode 100644
index 0000000..4f03be8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/85.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/85.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/85.txt
new file mode 100644
index 0000000..82bfa6a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/85.txt
@@ -0,0 +1 @@
+(10)1098*1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/86.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/86.png
new file mode 100644
index 0000000..42c485a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/86.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/86.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/86.txt
new file mode 100644
index 0000000..6263d99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/86.txt
@@ -0,0 +1 @@
+(10)1098a1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/87.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/87.png
new file mode 100644
index 0000000..c55f813
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/87.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/87.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/87.txt
new file mode 100644
index 0000000..35fc529
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/87.txt
@@ -0,0 +1 @@
+(10)1098!1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/88.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/88.png
new file mode 100644
index 0000000..6a463ed
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/88.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/88.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/88.txt
new file mode 100644
index 0000000..d0d95d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/88.txt
@@ -0,0 +1 @@
+(10)1098"1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/89.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/89.png
new file mode 100644
index 0000000..816f932
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/89.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/89.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/89.txt
new file mode 100644
index 0000000..53bf781
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/89.txt
@@ -0,0 +1 @@
+(10)1098%1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/9.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/9.png
new file mode 100644
index 0000000..d9c8734
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/9.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/9.txt
new file mode 100644
index 0000000..01af485
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/9.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)009999
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/90.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/90.png
new file mode 100644
index 0000000..182300a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/90.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/90.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/90.txt
new file mode 100644
index 0000000..5d1d351
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/90.txt
@@ -0,0 +1 @@
+(10)1098&1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/91.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/91.png
new file mode 100644
index 0000000..349944e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/91.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/91.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/91.txt
new file mode 100644
index 0000000..f00c6bb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/91.txt
@@ -0,0 +1 @@
+(10)1098'1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/92.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/92.png
new file mode 100644
index 0000000..d1e9f99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/92.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/92.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/92.txt
new file mode 100644
index 0000000..18b90ec
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/92.txt
@@ -0,0 +1 @@
+(10)1098+1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/93.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/93.png
new file mode 100644
index 0000000..674b7fe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/93.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/93.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/93.txt
new file mode 100644
index 0000000..96f9049
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/93.txt
@@ -0,0 +1 @@
+(10)1098:1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/94.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/94.png
new file mode 100644
index 0000000..235b371
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/94.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/94.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/94.txt
new file mode 100644
index 0000000..2dd84d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/94.txt
@@ -0,0 +1 @@
+(10)1098;1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/95.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/95.png
new file mode 100644
index 0000000..7c63c70
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/95.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/95.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/95.txt
new file mode 100644
index 0000000..a64a6db
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/95.txt
@@ -0,0 +1 @@
+(10)1098<1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/96.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/96.png
new file mode 100644
index 0000000..c3b8ac7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/96.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/96.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/96.txt
new file mode 100644
index 0000000..c7cc606
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/96.txt
@@ -0,0 +1 @@
+(10)1098=1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/97.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/97.png
new file mode 100644
index 0000000..df6572a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/97.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/97.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/97.txt
new file mode 100644
index 0000000..7345e4e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/97.txt
@@ -0,0 +1 @@
+(10)1098>1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/98.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/98.png
new file mode 100644
index 0000000..120cd95
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/98.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/98.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/98.txt
new file mode 100644
index 0000000..5e152de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/98.txt
@@ -0,0 +1 @@
+(10)1098?1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/99.png b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/99.png
new file mode 100644
index 0000000..f9ce0f3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/99.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/99.txt b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/99.txt
new file mode 100644
index 0000000..aad1b28
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/99.txt
@@ -0,0 +1 @@
+(10)1098_1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/generate.py b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/generate.py
new file mode 100644
index 0000000..5ec05c4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/generate.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+
+import os
+import glob
+import sys
+import subprocess
+import traceback
+import hashlib
+import urllib
+import urllib2
+
+ZINT = 'zint'
+ZINT_RSS_EXPANDED_CODE = 31
+ZINT_BINARY = "zint" # If available in PATH
+
+POSTSCRIPT = 'postscript'
+
+TEST_FILE = "../../../src/com/google/zxing/oned/rss/RSSExpandedBlackBox3TestCase.java"
+
+def check_zint():
+ try:
+ subprocess.Popen("zint", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ except:
+ print >> sys.stderr, "zint not installed. Go to http://www.zint.org.uk/ and install it"
+ return False
+ return True
+
+def check_postscript():
+ return True
+
+GENERATORS = []
+if check_zint():
+ GENERATORS.append(ZINT)
+if check_postscript():
+ GENERATORS.append(POSTSCRIPT)
+
+def generate_image_zint(image_filename, barcode):
+ braces_barcode = barcode.replace("(","[").replace(")","]")
+ os.system('%s -o %s -b %s -d "%s"' % (ZINT_BINARY, image_filename, ZINT_RSS_EXPANDED_CODE, braces_barcode.replace('"','\\"')))
+
+def generate_image_postscript(image_filename, barcode):
+ hashname = "cache/%s.png" % hashlib.new("md5", barcode).hexdigest()
+ # If it exists in the cache, don't download it
+ if os.path.exists(hashname):
+ content = open(hashname).read()
+ open(image_filename,'w').write(content)
+ return
+
+ # We tried use the Python, Perl and LaTeX bindings without success :-(
+ baseurl = "http://www.terryburton.co.uk/barcodewriter/generator/"
+ encoded = urllib.urlencode({
+ "encoder" : "rssexpanded",
+ "data" : barcode,
+ "options" : "",
+ "translate_x" : "50", "translate_y" : "50",
+ "scale_x" : "2", "scale_y" : "2",
+ "rotate" : "0", "submit" : "Make Barcode"
+ })
+ web_urlobject = urllib2.urlopen(baseurl, data = encoded)
+ web_content = web_urlobject.read()
+ png_url = web_content.split('">PNG</a>')[0].split('<a href="')[-1]
+ if not png_url.startswith("tmp"):
+ raise Exception("There was an error processing barcode %s in postscript" % barcode)
+ full_url = baseurl + png_url
+ png_content = urllib2.urlopen(full_url).read()
+ open(hashname,'w').write(png_content)
+ open(image_filename,'w').write(png_content)
+
+def generate_image(image_filename, barcode, generator):
+ if generator == ZINT:
+ generate_image_zint(image_filename, barcode)
+ elif generator == POSTSCRIPT:
+ generate_image_postscript(image_filename, barcode)
+ else:
+ raise Exception("Unknown generator: %s" % generator)
+
+def extract_barcodes():
+ for line in open("generation.config"):
+ content = line.split("#")[0].strip()
+ if content != "":
+ if content[0] == '-':
+ pos = content[1:].find('-')
+ exceptions = content[1:pos+1].split(",")
+ barcode = content[pos + 2:]
+ yield exceptions, barcode
+ else:
+ yield (), content
+
+if __name__ == '__main__':
+ counter = 0
+
+ for image_to_delete in glob.glob("*.png"):
+ os.remove(image_to_delete)
+
+ for text_to_delete in glob.glob("*.txt"):
+ os.remove(text_to_delete)
+
+ for generator in GENERATORS:
+ for exceptions, barcode in extract_barcodes():
+ if generator in exceptions:
+ continue
+ try:
+ counter += 1
+ image_filename = str(counter) + ".png"
+ text_filename = str(counter) + ".txt"
+ open(text_filename, "w").write(barcode)
+ generate_image(image_filename, barcode, generator)
+ except Exception:
+ print "Error with generator %s and barcode %s" % (generator, barcode)
+ traceback.print_exc()
+ counter -= 1
+
+ open(TEST_FILE,'w').write("""package com.google.zxing.oned.rss;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.common.AbstractBlackBoxTestCase;
+
+public class RSSExpandedBlackBox3TestCase extends AbstractBlackBoxTestCase {
+
+ public RSSExpandedBlackBox3TestCase() {
+ super("test/data/blackbox/rssexpanded-3", new MultiFormatReader(), BarcodeFormat.RSS_EXPANDED);
+ addTest(%(number)s, %(number)s, 0.0f);
+ addTest(%(number)s, %(number)s, 180.0f);
+ }
+}
+ """ % {"number" : counter})
+
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpanded-3/generation.config b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/generation.config
new file mode 100644
index 0000000..7a973a3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpanded-3/generation.config
@@ -0,0 +1,127 @@
+###########################################################
+#
+# Place codes in this file, and they will be automatically
+# generated by "generate.py". Everything placed after a "#"
+# will be ignored, as well as every space before and after
+# the codes and empty lines.
+#
+# If a generator can't generate a code, then place:
+# -LIBRARY-. For example, if zint doesn't support a code,
+# place -zint-. If neither zint or postscript support it,
+# place -zint,postscript-.
+#
+#
+
+#################################################
+# Fixed length examples
+
+# Encodation 0111000 - 0111111
+
+(01)90012345678908(3103)012233(15)991231 # Example taken from 7.2.5.4.4
+(01)91234567980129(3103)012233(15)991231 # Testing with other AI
+(01)91234567980129(3102)012233(15)991231 # Testing with 3102 instead of 3103
+(01)91234567980129(3102)012233(15)000101 # January 1st, 2000
+
+# Encodation 0100
+
+(01)90012345678908(3103)001750 # Example taken from 7.2.5.4.2
+(01)92109876543213(3103)032767 # Maximum weight value
+(01)92109876543213(3103)000000 # Minimum weight value
+
+# Encodation 0101
+
+(01)90012345678908(3202)000156 # Example taken from 7.2.5.4.3
+(01)90012345678908(3202)009999 # 9,999 has a different behaviour than 10,000
+(01)90012345678908(3203)010000 # 10,000 has a different behaviour than 9,999
+(01)90012345678908(3203)032767 # 10,000 has a different behaviour than 9,999
+
+#################################################
+# Variable length examples
+
+# Encodation 01100
+
+(01)90012345678908(3922)795 # Example taken from 7.2.5.4.5
+(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888 # Longer information
+
+# Encodation 01101
+
+(01)90012345678908(3932)0401234 # Example taken from 7.2.5.4.6
+
+# These three examples don't work due to a bug in zint. It has been reported.
+# However, they work with http://www.terryburton.co.uk/barcodewriter/generator/
+#
+-zint-(01)90012345678908(3932)040EUR # Testing with alphanumeric instead of numeric
+-zint-(01)90012345678908(3932)04055GBP # Testing with numeric + alphanumeric instead of only numeric
+-zint-(01)90012345678908(3932)04066USD778899 # Testing with numeric + alphanumeric + numeric instead of only numeric
+
+# Encodation 1
+
+(01)00012345678905(10)ABC123 # Example taken from 7.2.5.4.1
+(01)12345678901231(10)UNIVERSITY-OF-DEUSTO # Adding other type of information
+(01)12345678901231(10)PIRAMIDE-PROJECT # Adding other type of information
+(01)12345678901231(10)TREELOGIC # Adding other type of information
+
+#
+# Zint doesn't support this one because after 12A (alphanumeric) it goes back to numeric without a alpha to numeric latch
+-zint-(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901 # Adding a lot of information
+
+# Encodation 00
+
+# # Zint doesn't support this one because after 12A (alphanumeric) it goes back to numeric without a alpha to numeric latch
+-zint-(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012 # Adding a lot of information
+(10)5678(11)010101 # This one optimizes the last 4 bits as detailed in the end of 7.2.5.5.1
+(10)5678(11)001010
+(10)567890(11)010101
+(10)567(11)010101
+
+
+# Other tests with special characters, such as: '*',',','-','/','.',
+# and ISO/IEC646 encodation characters
+(10)1098-1234
+(10)1098,1234
+(10)1098/1234
+(10)1098.1234
+(10)1098*1234
+(10)1098a1234
+(10)1098!1234
+(10)1098"1234
+(10)1098%1234
+(10)1098&1234
+(10)1098'1234
+(10)1098+1234
+(10)1098:1234
+(10)1098;1234
+(10)1098<1234
+(10)1098=1234
+(10)1098>1234
+(10)1098?1234
+(10)1098_1234
+(10)1098 1234
+
+# Testing transitions
+
+(10)123456A # numeric -> alpha
+-zint-(10)123456A1 # numeric -> alpha
+-zint-(10)123456A123 # numeric -> alpha
+(10)123456A1234 # numeric -> alpha -> numeric
+(10)123456A1234A # numeric -> alpha
+(10)123456A123456 # numeric -> alpha -> numeric
+(10)123456A12345678 # numeric -> alpha -> numeric
+-zint-(10)123456A1234A(15)991231 # numeric -> alpha -> FNC1
+
+(10)1ABCDEF;:/1234567 # numeric -> alpha -> 646 -> numeric
+(10)1ABCDEF;:/ABCDEFG # numeric -> alpha -> 646 -> alpha
+
+(10)1;:/ABCDEFGHIJKLM # numeric -> 646 -> alpha
+(10)1;:/0123456789012 # numeric -> 646 -> numeric
+(10)1;:/0123 # numeric -> 646
+(10)1;:/0123(15)991231 # numeric -> 646 -> FNC1 numeric
+
+# Another tests, from 7.2.5.5.2
+-zint-(10)1
+
+# Another bug in zint, it works with http://www.terryburton.co.uk/barcodewriter/generator/
+-zint-(10)12A
+# Another bug in zint, it works with the http://www.terryburton.co.uk/barcodewriter/generator/
+-zint-(10)123
+
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/1.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/1.png
new file mode 100644
index 0000000..9032bef
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/1.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/1.txt
new file mode 100644
index 0000000..ed31c4d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/1.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)012233(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/10.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/10.png
new file mode 100644
index 0000000..b2c4386
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/10.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/10.txt
new file mode 100644
index 0000000..e8f98fe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/10.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)010000
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/11.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/11.png
new file mode 100644
index 0000000..2381e25
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/11.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/11.txt
new file mode 100644
index 0000000..9895a67
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/11.txt
@@ -0,0 +1 @@
+(01)90012345678908(3203)032767
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/12.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/12.png
new file mode 100644
index 0000000..228c5e4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/12.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/12.txt
new file mode 100644
index 0000000..dd36aab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/12.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/13.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/13.png
new file mode 100644
index 0000000..4081641
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/13.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/13.txt
new file mode 100644
index 0000000..0429d93
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/13.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/14.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/14.png
new file mode 100644
index 0000000..bd4f28c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/14.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/14.txt
new file mode 100644
index 0000000..fb00e31
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/14.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)0401234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/15.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/15.png
new file mode 100644
index 0000000..293ec41
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/15.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/15.txt
new file mode 100644
index 0000000..b5f3fe9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/15.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)040EUR
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/16.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/16.png
new file mode 100644
index 0000000..1b25ed6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/16.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/16.txt
new file mode 100644
index 0000000..e95bc8d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/16.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)04055GBP
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/17.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/17.png
new file mode 100644
index 0000000..021f7bd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/17.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/17.txt
new file mode 100644
index 0000000..37c6cb3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/17.txt
@@ -0,0 +1 @@
+(01)90012345678908(3932)04066USD778899
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/18.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/18.png
new file mode 100644
index 0000000..7471e95
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/18.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/18.txt
new file mode 100644
index 0000000..9066194
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/18.txt
@@ -0,0 +1 @@
+(01)00012345678905(10)ABC123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/19.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/19.png
new file mode 100644
index 0000000..5a9f74f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/19.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/19.txt
new file mode 100644
index 0000000..8f0841f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/19.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)UNIVERSITY-OF-DEUSTO
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/2.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/2.png
new file mode 100644
index 0000000..8f54fb1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/2.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/2.txt
new file mode 100644
index 0000000..d7f0a6a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/2.txt
@@ -0,0 +1 @@
+(01)91234567980129(3103)012233(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/20.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/20.png
new file mode 100644
index 0000000..d0a075c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/20.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/20.txt
new file mode 100644
index 0000000..89fda98
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/20.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)PIRAMIDE-PROJECT
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/21.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/21.png
new file mode 100644
index 0000000..25fd610
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/21.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/21.txt
new file mode 100644
index 0000000..b120324
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/21.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)TREELOGIC
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/22.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/22.png
new file mode 100644
index 0000000..61250af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/22.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/22.txt
new file mode 100644
index 0000000..09d4208
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/22.txt
@@ -0,0 +1 @@
+(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/23.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/23.png
new file mode 100644
index 0000000..19811bf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/23.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/23.txt
new file mode 100644
index 0000000..5e76631
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/23.txt
@@ -0,0 +1 @@
+(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/24.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/24.png
new file mode 100644
index 0000000..a4c6ae8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/24.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/24.txt
new file mode 100644
index 0000000..17966ee
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/24.txt
@@ -0,0 +1 @@
+(10)5678(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/25.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/25.png
new file mode 100644
index 0000000..ba14d25
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/25.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/25.txt
new file mode 100644
index 0000000..b948648
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/25.txt
@@ -0,0 +1 @@
+(10)5678(11)001010
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/26.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/26.png
new file mode 100644
index 0000000..af0226f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/26.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/26.txt
new file mode 100644
index 0000000..a7b3497
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/26.txt
@@ -0,0 +1 @@
+(10)567890(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/27.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/27.png
new file mode 100644
index 0000000..5a673ec
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/27.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/27.txt
new file mode 100644
index 0000000..e8c7268
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/27.txt
@@ -0,0 +1 @@
+(10)567(11)010101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/28.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/28.png
new file mode 100644
index 0000000..cdff613
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/28.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/28.txt
new file mode 100644
index 0000000..5263f7f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/28.txt
@@ -0,0 +1 @@
+(10)1098-1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/29.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/29.png
new file mode 100644
index 0000000..c7aef19
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/29.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/29.txt
new file mode 100644
index 0000000..f6413d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/29.txt
@@ -0,0 +1 @@
+(10)1098,1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/3.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/3.png
new file mode 100644
index 0000000..ea28950
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/3.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/3.txt
new file mode 100644
index 0000000..ab93c97
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/3.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/30.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/30.png
new file mode 100644
index 0000000..7d575d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/30.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/30.txt
new file mode 100644
index 0000000..9208d92
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/30.txt
@@ -0,0 +1 @@
+(10)1098/1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/31.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/31.png
new file mode 100644
index 0000000..546046b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/31.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/31.txt
new file mode 100644
index 0000000..b78623a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/31.txt
@@ -0,0 +1 @@
+(10)1098.1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/32.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/32.png
new file mode 100644
index 0000000..198f8a6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/32.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/32.txt
new file mode 100644
index 0000000..82bfa6a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/32.txt
@@ -0,0 +1 @@
+(10)1098*1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/33.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/33.png
new file mode 100644
index 0000000..a173e8d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/33.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/33.txt
new file mode 100644
index 0000000..6263d99
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/33.txt
@@ -0,0 +1 @@
+(10)1098a1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/34.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/34.png
new file mode 100644
index 0000000..775c1c2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/34.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/34.txt
new file mode 100644
index 0000000..35fc529
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/34.txt
@@ -0,0 +1 @@
+(10)1098!1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/35.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/35.png
new file mode 100644
index 0000000..890494d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/35.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/35.txt
new file mode 100644
index 0000000..d0d95d0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/35.txt
@@ -0,0 +1 @@
+(10)1098"1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/36.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/36.png
new file mode 100644
index 0000000..50a7796
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/36.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/36.txt
new file mode 100644
index 0000000..53bf781
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/36.txt
@@ -0,0 +1 @@
+(10)1098%1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/37.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/37.png
new file mode 100644
index 0000000..58d16f5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/37.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/37.txt
new file mode 100644
index 0000000..5d1d351
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/37.txt
@@ -0,0 +1 @@
+(10)1098&1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/38.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/38.png
new file mode 100644
index 0000000..9b0a795
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/38.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/38.txt
new file mode 100644
index 0000000..f00c6bb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/38.txt
@@ -0,0 +1 @@
+(10)1098'1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/39.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/39.png
new file mode 100644
index 0000000..a324207
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/39.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/39.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/39.txt
new file mode 100644
index 0000000..18b90ec
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/39.txt
@@ -0,0 +1 @@
+(10)1098+1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/4.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/4.png
new file mode 100644
index 0000000..5147f84
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/4.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/4.txt
new file mode 100644
index 0000000..fca726b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/4.txt
@@ -0,0 +1 @@
+(01)91234567980129(3102)012233(15)000101
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/40.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/40.png
new file mode 100644
index 0000000..5a18fc9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/40.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/40.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/40.txt
new file mode 100644
index 0000000..96f9049
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/40.txt
@@ -0,0 +1 @@
+(10)1098:1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/41.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/41.png
new file mode 100644
index 0000000..2ae4497
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/41.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/41.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/41.txt
new file mode 100644
index 0000000..2dd84d5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/41.txt
@@ -0,0 +1 @@
+(10)1098;1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/42.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/42.png
new file mode 100644
index 0000000..ea4d68c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/42.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/42.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/42.txt
new file mode 100644
index 0000000..a64a6db
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/42.txt
@@ -0,0 +1 @@
+(10)1098<1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/43.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/43.png
new file mode 100644
index 0000000..cba68a2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/43.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/43.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/43.txt
new file mode 100644
index 0000000..c7cc606
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/43.txt
@@ -0,0 +1 @@
+(10)1098=1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/44.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/44.png
new file mode 100644
index 0000000..690c825
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/44.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/44.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/44.txt
new file mode 100644
index 0000000..7345e4e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/44.txt
@@ -0,0 +1 @@
+(10)1098>1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/45.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/45.png
new file mode 100644
index 0000000..57a1a4c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/45.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/45.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/45.txt
new file mode 100644
index 0000000..5e152de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/45.txt
@@ -0,0 +1 @@
+(10)1098?1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/46.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/46.png
new file mode 100644
index 0000000..ad09098
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/46.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/46.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/46.txt
new file mode 100644
index 0000000..aad1b28
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/46.txt
@@ -0,0 +1 @@
+(10)1098_1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/47.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/47.png
new file mode 100644
index 0000000..c80ab17
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/47.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/47.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/47.txt
new file mode 100644
index 0000000..4339de9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/47.txt
@@ -0,0 +1 @@
+(10)1098 1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/48.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/48.png
new file mode 100644
index 0000000..f616013
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/48.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/48.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/48.txt
new file mode 100644
index 0000000..6f63fb0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/48.txt
@@ -0,0 +1 @@
+(10)123456A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/49.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/49.png
new file mode 100644
index 0000000..08c8a25
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/49.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/49.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/49.txt
new file mode 100644
index 0000000..5c1b912
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/49.txt
@@ -0,0 +1 @@
+(10)123456A1
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/5.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/5.png
new file mode 100644
index 0000000..eb3d533
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/5.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/5.txt
new file mode 100644
index 0000000..b4113ac
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/5.txt
@@ -0,0 +1 @@
+(01)90012345678908(3103)001750
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/50.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/50.png
new file mode 100644
index 0000000..cfc13b0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/50.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/50.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/50.txt
new file mode 100644
index 0000000..d77a476
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/50.txt
@@ -0,0 +1 @@
+(10)123456A123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/51.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/51.png
new file mode 100644
index 0000000..40f2218
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/51.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/51.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/51.txt
new file mode 100644
index 0000000..2e2ec43
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/51.txt
@@ -0,0 +1 @@
+(10)123456A1234
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/52.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/52.png
new file mode 100644
index 0000000..7537a41
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/52.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/52.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/52.txt
new file mode 100644
index 0000000..b607d14
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/52.txt
@@ -0,0 +1 @@
+(10)123456A1234A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/53.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/53.png
new file mode 100644
index 0000000..ce7408f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/53.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/53.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/53.txt
new file mode 100644
index 0000000..389adca
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/53.txt
@@ -0,0 +1 @@
+(10)123456A123456
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/54.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/54.png
new file mode 100644
index 0000000..73a5588
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/54.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/54.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/54.txt
new file mode 100644
index 0000000..fffde5d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/54.txt
@@ -0,0 +1 @@
+(10)123456A12345678
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/55.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/55.png
new file mode 100644
index 0000000..7c65f74
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/55.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/55.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/55.txt
new file mode 100644
index 0000000..1ad0fbd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/55.txt
@@ -0,0 +1 @@
+(10)123456A1234A(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/56.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/56.png
new file mode 100644
index 0000000..ebd1f36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/56.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/56.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/56.txt
new file mode 100644
index 0000000..ac79617
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/56.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/1234567
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/57.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/57.png
new file mode 100644
index 0000000..529a179
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/57.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/57.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/57.txt
new file mode 100644
index 0000000..163b64b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/57.txt
@@ -0,0 +1 @@
+(10)1ABCDEF;:/ABCDEFG
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/58.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/58.png
new file mode 100644
index 0000000..dbe8cc0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/58.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/58.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/58.txt
new file mode 100644
index 0000000..d359328
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/58.txt
@@ -0,0 +1 @@
+(10)1;:/ABCDEFGHIJKLM
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/59.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/59.png
new file mode 100644
index 0000000..e06150d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/59.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/59.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/59.txt
new file mode 100644
index 0000000..c25e84f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/59.txt
@@ -0,0 +1 @@
+(10)1;:/0123456789012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/6.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/6.png
new file mode 100644
index 0000000..311893a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/6.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/6.txt
new file mode 100644
index 0000000..57a2c64
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/6.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)032767
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/60.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/60.png
new file mode 100644
index 0000000..5c6f00f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/60.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/60.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/60.txt
new file mode 100644
index 0000000..2914766
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/60.txt
@@ -0,0 +1 @@
+(10)1;:/0123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/61.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/61.png
new file mode 100644
index 0000000..6f5b3d9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/61.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/61.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/61.txt
new file mode 100644
index 0000000..c8be9f3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/61.txt
@@ -0,0 +1 @@
+(10)1;:/0123(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/62.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/62.png
new file mode 100644
index 0000000..2506755
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/62.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/62.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/62.txt
new file mode 100644
index 0000000..9a1581d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/62.txt
@@ -0,0 +1 @@
+(10)1
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/63.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/63.png
new file mode 100644
index 0000000..fbb6ac2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/63.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/63.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/63.txt
new file mode 100644
index 0000000..4c3769f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/63.txt
@@ -0,0 +1 @@
+(10)12A
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/64.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/64.png
new file mode 100644
index 0000000..400eb00
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/64.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/64.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/64.txt
new file mode 100644
index 0000000..62c17f1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/64.txt
@@ -0,0 +1 @@
+(10)123
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/7.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/7.png
new file mode 100644
index 0000000..677ff18
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/7.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/7.txt
new file mode 100644
index 0000000..bfa4177
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/7.txt
@@ -0,0 +1 @@
+(01)92109876543213(3103)000000
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/8.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/8.png
new file mode 100644
index 0000000..f2c44fb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/8.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/8.txt
new file mode 100644
index 0000000..e0da7fa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/8.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)000156
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/9.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/9.png
new file mode 100644
index 0000000..4a80388
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/9.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/9.txt
new file mode 100644
index 0000000..01af485
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-1/9.txt
@@ -0,0 +1 @@
+(01)90012345678908(3202)009999
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1.png
new file mode 100644
index 0000000..dda9e26
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1.txt
new file mode 100644
index 0000000..963f111
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1.txt
@@ -0,0 +1 @@
+(8110)10014141012345290110100
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1000.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1000.png
new file mode 100644
index 0000000..865e1f5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1000.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1000.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1000.txt
new file mode 100644
index 0000000..4e8655c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/1000.txt
@@ -0,0 +1 @@
+(01)98898765432106(3202)012345(15)991231
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/13.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/13.png
new file mode 100644
index 0000000..4081641
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/13.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/13.txt
new file mode 100644
index 0000000..0429d93
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/13.txt
@@ -0,0 +1 @@
+(01)90012345678908(3922)795888888888888888888888888888888888888888888888888888
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/19.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/19.png
new file mode 100644
index 0000000..5a9f74f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/19.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/19.txt
new file mode 100644
index 0000000..8f0841f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/19.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)UNIVERSITY-OF-DEUSTO
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/20.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/20.png
new file mode 100644
index 0000000..d0a075c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/20.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/20.txt
new file mode 100644
index 0000000..89fda98
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/20.txt
@@ -0,0 +1 @@
+(01)12345678901231(10)PIRAMIDE-PROJECT
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/22.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/22.png
new file mode 100644
index 0000000..61250af
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/22.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/22.txt
new file mode 100644
index 0000000..09d4208
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/22.txt
@@ -0,0 +1 @@
+(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/23.png b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/23.png
new file mode 100644
index 0000000..19811bf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/23.txt b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/23.txt
new file mode 100644
index 0000000..5e76631
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/rssexpandedstacked-2/23.txt
@@ -0,0 +1 @@
+(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/unsupported/01.png b/ZXingObjCTests/Resources/blackbox/unsupported/01.png
new file mode 100644
index 0000000..fe56386
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/unsupported/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/unsupported/03.png b/ZXingObjCTests/Resources/blackbox/unsupported/03.png
new file mode 100644
index 0000000..8df6942
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/unsupported/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/unsupported/04.png b/ZXingObjCTests/Resources/blackbox/unsupported/04.png
new file mode 100644
index 0000000..8340e4f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/unsupported/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/unsupported/05.png b/ZXingObjCTests/Resources/blackbox/unsupported/05.png
new file mode 100644
index 0000000..d935143
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/unsupported/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/1.png b/ZXingObjCTests/Resources/blackbox/upca-1/1.png
new file mode 100644
index 0000000..cca38d1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/1.txt b/ZXingObjCTests/Resources/blackbox/upca-1/1.txt
new file mode 100644
index 0000000..8304219
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/1.txt
@@ -0,0 +1 @@
+036602301467
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/10.png b/ZXingObjCTests/Resources/blackbox/upca-1/10.png
new file mode 100644
index 0000000..3eb798d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/10.txt b/ZXingObjCTests/Resources/blackbox/upca-1/10.txt
new file mode 100644
index 0000000..9a6f1d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/10.txt
@@ -0,0 +1 @@
+027011006951
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/11.png b/ZXingObjCTests/Resources/blackbox/upca-1/11.png
new file mode 100644
index 0000000..e255c55
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/11.txt b/ZXingObjCTests/Resources/blackbox/upca-1/11.txt
new file mode 100644
index 0000000..9a6f1d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/11.txt
@@ -0,0 +1 @@
+027011006951
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/12.png b/ZXingObjCTests/Resources/blackbox/upca-1/12.png
new file mode 100644
index 0000000..3e5ff90
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/12.txt b/ZXingObjCTests/Resources/blackbox/upca-1/12.txt
new file mode 100644
index 0000000..4ea41b0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/12.txt
@@ -0,0 +1 @@
+781735802045
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/13.png b/ZXingObjCTests/Resources/blackbox/upca-1/13.png
new file mode 100644
index 0000000..66fe9ab
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/13.txt b/ZXingObjCTests/Resources/blackbox/upca-1/13.txt
new file mode 100644
index 0000000..4ea41b0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/13.txt
@@ -0,0 +1 @@
+781735802045
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/16.png b/ZXingObjCTests/Resources/blackbox/upca-1/16.png
new file mode 100644
index 0000000..8524580
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/16.txt b/ZXingObjCTests/Resources/blackbox/upca-1/16.txt
new file mode 100644
index 0000000..ec6ea1e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/16.txt
@@ -0,0 +1 @@
+456314319671
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/17.png b/ZXingObjCTests/Resources/blackbox/upca-1/17.png
new file mode 100644
index 0000000..280977c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/17.txt b/ZXingObjCTests/Resources/blackbox/upca-1/17.txt
new file mode 100644
index 0000000..99d98e6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/17.txt
@@ -0,0 +1 @@
+434704791429
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/18.png b/ZXingObjCTests/Resources/blackbox/upca-1/18.png
new file mode 100644
index 0000000..3b17018
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/18.txt b/ZXingObjCTests/Resources/blackbox/upca-1/18.txt
new file mode 100644
index 0000000..d357ddf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/18.txt
@@ -0,0 +1 @@
+024543136538
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/19.png b/ZXingObjCTests/Resources/blackbox/upca-1/19.png
new file mode 100644
index 0000000..e33d291
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/19.txt b/ZXingObjCTests/Resources/blackbox/upca-1/19.txt
new file mode 100644
index 0000000..d357ddf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/19.txt
@@ -0,0 +1 @@
+024543136538
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/2.png b/ZXingObjCTests/Resources/blackbox/upca-1/2.png
new file mode 100644
index 0000000..a27da98
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/2.txt b/ZXingObjCTests/Resources/blackbox/upca-1/2.txt
new file mode 100644
index 0000000..8304219
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/2.txt
@@ -0,0 +1 @@
+036602301467
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/20.png b/ZXingObjCTests/Resources/blackbox/upca-1/20.png
new file mode 100644
index 0000000..cc4b297
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/20.txt b/ZXingObjCTests/Resources/blackbox/upca-1/20.txt
new file mode 100644
index 0000000..ac41ca8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/20.txt
@@ -0,0 +1 @@
+752919460009
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/21.png b/ZXingObjCTests/Resources/blackbox/upca-1/21.png
new file mode 100644
index 0000000..ac09a1b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/21.txt b/ZXingObjCTests/Resources/blackbox/upca-1/21.txt
new file mode 100644
index 0000000..ac41ca8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/21.txt
@@ -0,0 +1 @@
+752919460009
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/27.png b/ZXingObjCTests/Resources/blackbox/upca-1/27.png
new file mode 100644
index 0000000..c307ad8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/27.txt b/ZXingObjCTests/Resources/blackbox/upca-1/27.txt
new file mode 100644
index 0000000..592cb74
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/27.txt
@@ -0,0 +1 @@
+606949762520
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/28.png b/ZXingObjCTests/Resources/blackbox/upca-1/28.png
new file mode 100644
index 0000000..902f654
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/28.txt b/ZXingObjCTests/Resources/blackbox/upca-1/28.txt
new file mode 100644
index 0000000..051a382
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/28.txt
@@ -0,0 +1 @@
+061869053712
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/29.png b/ZXingObjCTests/Resources/blackbox/upca-1/29.png
new file mode 100644
index 0000000..7643633
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/29.txt b/ZXingObjCTests/Resources/blackbox/upca-1/29.txt
new file mode 100644
index 0000000..1335b71
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/29.txt
@@ -0,0 +1 @@
+619659023935
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/3.png b/ZXingObjCTests/Resources/blackbox/upca-1/3.png
new file mode 100644
index 0000000..fb9f41a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/3.txt b/ZXingObjCTests/Resources/blackbox/upca-1/3.txt
new file mode 100644
index 0000000..e53c211
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/3.txt
@@ -0,0 +1 @@
+070097025088
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/35.png b/ZXingObjCTests/Resources/blackbox/upca-1/35.png
new file mode 100644
index 0000000..f53d8b8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/35.txt b/ZXingObjCTests/Resources/blackbox/upca-1/35.txt
new file mode 100644
index 0000000..9b3f5d3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/35.txt
@@ -0,0 +1 @@
+045496442736
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/4.png b/ZXingObjCTests/Resources/blackbox/upca-1/4.png
new file mode 100644
index 0000000..0e3e739
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/4.txt b/ZXingObjCTests/Resources/blackbox/upca-1/4.txt
new file mode 100644
index 0000000..e53c211
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/4.txt
@@ -0,0 +1 @@
+070097025088
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/5.png b/ZXingObjCTests/Resources/blackbox/upca-1/5.png
new file mode 100644
index 0000000..201d191
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/5.txt b/ZXingObjCTests/Resources/blackbox/upca-1/5.txt
new file mode 100644
index 0000000..e53c211
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/5.txt
@@ -0,0 +1 @@
+070097025088
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/8.png b/ZXingObjCTests/Resources/blackbox/upca-1/8.png
new file mode 100644
index 0000000..9e325e5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/8.txt b/ZXingObjCTests/Resources/blackbox/upca-1/8.txt
new file mode 100644
index 0000000..37e4df6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/8.txt
@@ -0,0 +1 @@
+071831007995
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/9.png b/ZXingObjCTests/Resources/blackbox/upca-1/9.png
new file mode 100644
index 0000000..dfca269
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-1/9.txt b/ZXingObjCTests/Resources/blackbox/upca-1/9.txt
new file mode 100644
index 0000000..37e4df6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-1/9.txt
@@ -0,0 +1 @@
+071831007995
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/01.png b/ZXingObjCTests/Resources/blackbox/upca-2/01.png
new file mode 100644
index 0000000..9fc6f6b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/01.txt b/ZXingObjCTests/Resources/blackbox/upca-2/01.txt
new file mode 100644
index 0000000..ad9b706
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/01.txt
@@ -0,0 +1 @@
+890444000335
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/02.png b/ZXingObjCTests/Resources/blackbox/upca-2/02.png
new file mode 100644
index 0000000..a5c90a6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/02.txt b/ZXingObjCTests/Resources/blackbox/upca-2/02.txt
new file mode 100644
index 0000000..ad9b706
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/02.txt
@@ -0,0 +1 @@
+890444000335
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/03.png b/ZXingObjCTests/Resources/blackbox/upca-2/03.png
new file mode 100644
index 0000000..4f3da3f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/03.txt b/ZXingObjCTests/Resources/blackbox/upca-2/03.txt
new file mode 100644
index 0000000..ad9b706
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/03.txt
@@ -0,0 +1 @@
+890444000335
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/04.png b/ZXingObjCTests/Resources/blackbox/upca-2/04.png
new file mode 100644
index 0000000..a177ccb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/04.txt b/ZXingObjCTests/Resources/blackbox/upca-2/04.txt
new file mode 100644
index 0000000..ad9b706
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/04.txt
@@ -0,0 +1 @@
+890444000335
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/05.png b/ZXingObjCTests/Resources/blackbox/upca-2/05.png
new file mode 100644
index 0000000..9de2936
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/05.txt b/ZXingObjCTests/Resources/blackbox/upca-2/05.txt
new file mode 100644
index 0000000..ad9b706
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/05.txt
@@ -0,0 +1 @@
+890444000335
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/06.png b/ZXingObjCTests/Resources/blackbox/upca-2/06.png
new file mode 100644
index 0000000..4b6ba58
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/06.txt b/ZXingObjCTests/Resources/blackbox/upca-2/06.txt
new file mode 100644
index 0000000..ad9b706
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/06.txt
@@ -0,0 +1 @@
+890444000335
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/07.png b/ZXingObjCTests/Resources/blackbox/upca-2/07.png
new file mode 100644
index 0000000..476a6b1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/07.txt b/ZXingObjCTests/Resources/blackbox/upca-2/07.txt
new file mode 100644
index 0000000..ad9b706
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/07.txt
@@ -0,0 +1 @@
+890444000335
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/08.png b/ZXingObjCTests/Resources/blackbox/upca-2/08.png
new file mode 100644
index 0000000..a0a5419
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/08.txt b/ZXingObjCTests/Resources/blackbox/upca-2/08.txt
new file mode 100644
index 0000000..00773d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/08.txt
@@ -0,0 +1 @@
+181497000879
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/09.png b/ZXingObjCTests/Resources/blackbox/upca-2/09.png
new file mode 100644
index 0000000..d9bb859
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/09.txt b/ZXingObjCTests/Resources/blackbox/upca-2/09.txt
new file mode 100644
index 0000000..00773d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/09.txt
@@ -0,0 +1 @@
+181497000879
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/10.png b/ZXingObjCTests/Resources/blackbox/upca-2/10.png
new file mode 100644
index 0000000..2759f87
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/10.txt b/ZXingObjCTests/Resources/blackbox/upca-2/10.txt
new file mode 100644
index 0000000..00773d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/10.txt
@@ -0,0 +1 @@
+181497000879
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/11.png b/ZXingObjCTests/Resources/blackbox/upca-2/11.png
new file mode 100644
index 0000000..c047131
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/11.txt b/ZXingObjCTests/Resources/blackbox/upca-2/11.txt
new file mode 100644
index 0000000..00773d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/11.txt
@@ -0,0 +1 @@
+181497000879
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/12.png b/ZXingObjCTests/Resources/blackbox/upca-2/12.png
new file mode 100644
index 0000000..3401092
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/12.txt b/ZXingObjCTests/Resources/blackbox/upca-2/12.txt
new file mode 100644
index 0000000..00773d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/12.txt
@@ -0,0 +1 @@
+181497000879
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/13.png b/ZXingObjCTests/Resources/blackbox/upca-2/13.png
new file mode 100644
index 0000000..2a1ced6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/13.txt b/ZXingObjCTests/Resources/blackbox/upca-2/13.txt
new file mode 100644
index 0000000..00773d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/13.txt
@@ -0,0 +1 @@
+181497000879
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/14.png b/ZXingObjCTests/Resources/blackbox/upca-2/14.png
new file mode 100644
index 0000000..41e1426
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/14.txt b/ZXingObjCTests/Resources/blackbox/upca-2/14.txt
new file mode 100644
index 0000000..2d0688a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/14.txt
@@ -0,0 +1 @@
+051000000675
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/15.png b/ZXingObjCTests/Resources/blackbox/upca-2/15.png
new file mode 100644
index 0000000..23f9f7d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/15.txt b/ZXingObjCTests/Resources/blackbox/upca-2/15.txt
new file mode 100644
index 0000000..2d0688a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/15.txt
@@ -0,0 +1 @@
+051000000675
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/16.png b/ZXingObjCTests/Resources/blackbox/upca-2/16.png
new file mode 100644
index 0000000..0933231
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/16.txt b/ZXingObjCTests/Resources/blackbox/upca-2/16.txt
new file mode 100644
index 0000000..2d0688a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/16.txt
@@ -0,0 +1 @@
+051000000675
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/17.png b/ZXingObjCTests/Resources/blackbox/upca-2/17.png
new file mode 100644
index 0000000..e0c4118
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/17.txt b/ZXingObjCTests/Resources/blackbox/upca-2/17.txt
new file mode 100644
index 0000000..2d0688a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/17.txt
@@ -0,0 +1 @@
+051000000675
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/18.png b/ZXingObjCTests/Resources/blackbox/upca-2/18.png
new file mode 100644
index 0000000..8f7af59
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/18.txt b/ZXingObjCTests/Resources/blackbox/upca-2/18.txt
new file mode 100644
index 0000000..2d0688a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/18.txt
@@ -0,0 +1 @@
+051000000675
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/19.png b/ZXingObjCTests/Resources/blackbox/upca-2/19.png
new file mode 100644
index 0000000..cc606ac
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/19.txt b/ZXingObjCTests/Resources/blackbox/upca-2/19.txt
new file mode 100644
index 0000000..2d0688a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/19.txt
@@ -0,0 +1 @@
+051000000675
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/20.png b/ZXingObjCTests/Resources/blackbox/upca-2/20.png
new file mode 100644
index 0000000..71de73a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/20.txt b/ZXingObjCTests/Resources/blackbox/upca-2/20.txt
new file mode 100644
index 0000000..2d0688a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/20.txt
@@ -0,0 +1 @@
+051000000675
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/21.png b/ZXingObjCTests/Resources/blackbox/upca-2/21.png
new file mode 100644
index 0000000..11b9aa3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/21.txt b/ZXingObjCTests/Resources/blackbox/upca-2/21.txt
new file mode 100644
index 0000000..2d0688a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/21.txt
@@ -0,0 +1 @@
+051000000675
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/22.png b/ZXingObjCTests/Resources/blackbox/upca-2/22.png
new file mode 100644
index 0000000..882a6c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/22.txt b/ZXingObjCTests/Resources/blackbox/upca-2/22.txt
new file mode 100644
index 0000000..2d0688a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/22.txt
@@ -0,0 +1 @@
+051000000675
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/23.png b/ZXingObjCTests/Resources/blackbox/upca-2/23.png
new file mode 100644
index 0000000..cc697c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/23.txt b/ZXingObjCTests/Resources/blackbox/upca-2/23.txt
new file mode 100644
index 0000000..2598343
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/23.txt
@@ -0,0 +1 @@
+752050200137
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/24.png b/ZXingObjCTests/Resources/blackbox/upca-2/24.png
new file mode 100644
index 0000000..7745fbd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/24.txt b/ZXingObjCTests/Resources/blackbox/upca-2/24.txt
new file mode 100644
index 0000000..2598343
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/24.txt
@@ -0,0 +1 @@
+752050200137
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/25.png b/ZXingObjCTests/Resources/blackbox/upca-2/25.png
new file mode 100644
index 0000000..4679ca3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/25.txt b/ZXingObjCTests/Resources/blackbox/upca-2/25.txt
new file mode 100644
index 0000000..2598343
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/25.txt
@@ -0,0 +1 @@
+752050200137
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/26.png b/ZXingObjCTests/Resources/blackbox/upca-2/26.png
new file mode 100644
index 0000000..3caf90c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/26.txt b/ZXingObjCTests/Resources/blackbox/upca-2/26.txt
new file mode 100644
index 0000000..2598343
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/26.txt
@@ -0,0 +1 @@
+752050200137
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/27.png b/ZXingObjCTests/Resources/blackbox/upca-2/27.png
new file mode 100644
index 0000000..9dad573
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/27.txt b/ZXingObjCTests/Resources/blackbox/upca-2/27.txt
new file mode 100644
index 0000000..2598343
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/27.txt
@@ -0,0 +1 @@
+752050200137
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/28.png b/ZXingObjCTests/Resources/blackbox/upca-2/28.png
new file mode 100644
index 0000000..5ef9930
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/28.txt b/ZXingObjCTests/Resources/blackbox/upca-2/28.txt
new file mode 100644
index 0000000..2598343
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/28.txt
@@ -0,0 +1 @@
+752050200137
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/29.png b/ZXingObjCTests/Resources/blackbox/upca-2/29.png
new file mode 100644
index 0000000..235198b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/29.txt b/ZXingObjCTests/Resources/blackbox/upca-2/29.txt
new file mode 100644
index 0000000..2598343
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/29.txt
@@ -0,0 +1 @@
+752050200137
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/30.png b/ZXingObjCTests/Resources/blackbox/upca-2/30.png
new file mode 100644
index 0000000..94d23a1
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/30.txt b/ZXingObjCTests/Resources/blackbox/upca-2/30.txt
new file mode 100644
index 0000000..2598343
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/30.txt
@@ -0,0 +1 @@
+752050200137
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/31.png b/ZXingObjCTests/Resources/blackbox/upca-2/31.png
new file mode 100644
index 0000000..7c702e7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/31.txt b/ZXingObjCTests/Resources/blackbox/upca-2/31.txt
new file mode 100644
index 0000000..8889039
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/31.txt
@@ -0,0 +1 @@
+899684001003
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/32.png b/ZXingObjCTests/Resources/blackbox/upca-2/32.png
new file mode 100644
index 0000000..03c64a8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/32.txt b/ZXingObjCTests/Resources/blackbox/upca-2/32.txt
new file mode 100644
index 0000000..8889039
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/32.txt
@@ -0,0 +1 @@
+899684001003
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/33.png b/ZXingObjCTests/Resources/blackbox/upca-2/33.png
new file mode 100644
index 0000000..cadb672
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/33.txt b/ZXingObjCTests/Resources/blackbox/upca-2/33.txt
new file mode 100644
index 0000000..8889039
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/33.txt
@@ -0,0 +1 @@
+899684001003
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/34.png b/ZXingObjCTests/Resources/blackbox/upca-2/34.png
new file mode 100644
index 0000000..bc7b1e8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/34.txt b/ZXingObjCTests/Resources/blackbox/upca-2/34.txt
new file mode 100644
index 0000000..8889039
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/34.txt
@@ -0,0 +1 @@
+899684001003
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/35.png b/ZXingObjCTests/Resources/blackbox/upca-2/35.png
new file mode 100644
index 0000000..b5c6467
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/35.txt b/ZXingObjCTests/Resources/blackbox/upca-2/35.txt
new file mode 100644
index 0000000..8889039
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/35.txt
@@ -0,0 +1 @@
+899684001003
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/36.png b/ZXingObjCTests/Resources/blackbox/upca-2/36.png
new file mode 100644
index 0000000..dabb687
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/36.txt b/ZXingObjCTests/Resources/blackbox/upca-2/36.txt
new file mode 100644
index 0000000..8889039
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/36.txt
@@ -0,0 +1 @@
+899684001003
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/37.png b/ZXingObjCTests/Resources/blackbox/upca-2/37.png
new file mode 100644
index 0000000..fdf58f0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/37.txt b/ZXingObjCTests/Resources/blackbox/upca-2/37.txt
new file mode 100644
index 0000000..8889039
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/37.txt
@@ -0,0 +1 @@
+899684001003
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/38.png b/ZXingObjCTests/Resources/blackbox/upca-2/38.png
new file mode 100644
index 0000000..8ae3e83
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/38.txt b/ZXingObjCTests/Resources/blackbox/upca-2/38.txt
new file mode 100644
index 0000000..43914c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/38.txt
@@ -0,0 +1 @@
+012546619592
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/39.png b/ZXingObjCTests/Resources/blackbox/upca-2/39.png
new file mode 100644
index 0000000..a96ede7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/39.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/39.txt b/ZXingObjCTests/Resources/blackbox/upca-2/39.txt
new file mode 100644
index 0000000..43914c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/39.txt
@@ -0,0 +1 @@
+012546619592
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/40.png b/ZXingObjCTests/Resources/blackbox/upca-2/40.png
new file mode 100644
index 0000000..64ebb43
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/40.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/40.txt b/ZXingObjCTests/Resources/blackbox/upca-2/40.txt
new file mode 100644
index 0000000..43914c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/40.txt
@@ -0,0 +1 @@
+012546619592
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/41.png b/ZXingObjCTests/Resources/blackbox/upca-2/41.png
new file mode 100644
index 0000000..ee40c2c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/41.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/41.txt b/ZXingObjCTests/Resources/blackbox/upca-2/41.txt
new file mode 100644
index 0000000..43914c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/41.txt
@@ -0,0 +1 @@
+012546619592
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/42.png b/ZXingObjCTests/Resources/blackbox/upca-2/42.png
new file mode 100644
index 0000000..de7c052
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/42.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/42.txt b/ZXingObjCTests/Resources/blackbox/upca-2/42.txt
new file mode 100644
index 0000000..43914c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/42.txt
@@ -0,0 +1 @@
+012546619592
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/43.png b/ZXingObjCTests/Resources/blackbox/upca-2/43.png
new file mode 100644
index 0000000..754859b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/43.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/43.txt b/ZXingObjCTests/Resources/blackbox/upca-2/43.txt
new file mode 100644
index 0000000..43914c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/43.txt
@@ -0,0 +1 @@
+012546619592
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/44.png b/ZXingObjCTests/Resources/blackbox/upca-2/44.png
new file mode 100644
index 0000000..6f90964
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/44.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/44.txt b/ZXingObjCTests/Resources/blackbox/upca-2/44.txt
new file mode 100644
index 0000000..43914c7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/44.txt
@@ -0,0 +1 @@
+012546619592
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/45.png b/ZXingObjCTests/Resources/blackbox/upca-2/45.png
new file mode 100644
index 0000000..a777b9b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/45.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/45.txt b/ZXingObjCTests/Resources/blackbox/upca-2/45.txt
new file mode 100644
index 0000000..2c50e36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/45.txt
@@ -0,0 +1 @@
+075720003259
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/46.png b/ZXingObjCTests/Resources/blackbox/upca-2/46.png
new file mode 100644
index 0000000..abed441
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/46.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/46.txt b/ZXingObjCTests/Resources/blackbox/upca-2/46.txt
new file mode 100644
index 0000000..2c50e36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/46.txt
@@ -0,0 +1 @@
+075720003259
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/47.png b/ZXingObjCTests/Resources/blackbox/upca-2/47.png
new file mode 100644
index 0000000..e027b74
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/47.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/47.txt b/ZXingObjCTests/Resources/blackbox/upca-2/47.txt
new file mode 100644
index 0000000..2c50e36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/47.txt
@@ -0,0 +1 @@
+075720003259
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/48.png b/ZXingObjCTests/Resources/blackbox/upca-2/48.png
new file mode 100644
index 0000000..b75b7c0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/48.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/48.txt b/ZXingObjCTests/Resources/blackbox/upca-2/48.txt
new file mode 100644
index 0000000..2c50e36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/48.txt
@@ -0,0 +1 @@
+075720003259
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/49.png b/ZXingObjCTests/Resources/blackbox/upca-2/49.png
new file mode 100644
index 0000000..8131571
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/49.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/49.txt b/ZXingObjCTests/Resources/blackbox/upca-2/49.txt
new file mode 100644
index 0000000..2c50e36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/49.txt
@@ -0,0 +1 @@
+075720003259
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/50.png b/ZXingObjCTests/Resources/blackbox/upca-2/50.png
new file mode 100644
index 0000000..cdea119
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/50.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/50.txt b/ZXingObjCTests/Resources/blackbox/upca-2/50.txt
new file mode 100644
index 0000000..2c50e36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/50.txt
@@ -0,0 +1 @@
+075720003259
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/51.png b/ZXingObjCTests/Resources/blackbox/upca-2/51.png
new file mode 100644
index 0000000..6637e56
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/51.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/51.txt b/ZXingObjCTests/Resources/blackbox/upca-2/51.txt
new file mode 100644
index 0000000..2c50e36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/51.txt
@@ -0,0 +1 @@
+075720003259
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/52.png b/ZXingObjCTests/Resources/blackbox/upca-2/52.png
new file mode 100644
index 0000000..611f01b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/52.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-2/52.txt b/ZXingObjCTests/Resources/blackbox/upca-2/52.txt
new file mode 100644
index 0000000..2c50e36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-2/52.txt
@@ -0,0 +1 @@
+075720003259
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/01.png b/ZXingObjCTests/Resources/blackbox/upca-3/01.png
new file mode 100644
index 0000000..f05ca04
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/01.txt b/ZXingObjCTests/Resources/blackbox/upca-3/01.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/01.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/02.png b/ZXingObjCTests/Resources/blackbox/upca-3/02.png
new file mode 100644
index 0000000..0ac9ac2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/02.txt b/ZXingObjCTests/Resources/blackbox/upca-3/02.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/02.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/03.png b/ZXingObjCTests/Resources/blackbox/upca-3/03.png
new file mode 100644
index 0000000..7f41178
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/03.txt b/ZXingObjCTests/Resources/blackbox/upca-3/03.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/03.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/04.png b/ZXingObjCTests/Resources/blackbox/upca-3/04.png
new file mode 100644
index 0000000..4508bdd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/04.txt b/ZXingObjCTests/Resources/blackbox/upca-3/04.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/04.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/05.png b/ZXingObjCTests/Resources/blackbox/upca-3/05.png
new file mode 100644
index 0000000..eaf4988
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/05.txt b/ZXingObjCTests/Resources/blackbox/upca-3/05.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/05.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/06.png b/ZXingObjCTests/Resources/blackbox/upca-3/06.png
new file mode 100644
index 0000000..ee606a8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/06.txt b/ZXingObjCTests/Resources/blackbox/upca-3/06.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/06.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/07.png b/ZXingObjCTests/Resources/blackbox/upca-3/07.png
new file mode 100644
index 0000000..e28b619
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/07.txt b/ZXingObjCTests/Resources/blackbox/upca-3/07.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/07.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/08.png b/ZXingObjCTests/Resources/blackbox/upca-3/08.png
new file mode 100644
index 0000000..8e57927
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/08.txt b/ZXingObjCTests/Resources/blackbox/upca-3/08.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/08.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/09.png b/ZXingObjCTests/Resources/blackbox/upca-3/09.png
new file mode 100644
index 0000000..e83fca8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/09.txt b/ZXingObjCTests/Resources/blackbox/upca-3/09.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/09.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/10.png b/ZXingObjCTests/Resources/blackbox/upca-3/10.png
new file mode 100644
index 0000000..7c3e68a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/10.txt b/ZXingObjCTests/Resources/blackbox/upca-3/10.txt
new file mode 100644
index 0000000..6883994
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/10.txt
@@ -0,0 +1 @@
+049000042566
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/11.png b/ZXingObjCTests/Resources/blackbox/upca-3/11.png
new file mode 100644
index 0000000..edf12c4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/11.txt b/ZXingObjCTests/Resources/blackbox/upca-3/11.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/11.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/12.png b/ZXingObjCTests/Resources/blackbox/upca-3/12.png
new file mode 100644
index 0000000..875ace6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/12.txt b/ZXingObjCTests/Resources/blackbox/upca-3/12.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/12.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/13.png b/ZXingObjCTests/Resources/blackbox/upca-3/13.png
new file mode 100644
index 0000000..9d6fe59
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/13.txt b/ZXingObjCTests/Resources/blackbox/upca-3/13.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/13.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/14.png b/ZXingObjCTests/Resources/blackbox/upca-3/14.png
new file mode 100644
index 0000000..2b66246
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/14.txt b/ZXingObjCTests/Resources/blackbox/upca-3/14.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/14.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/15.png b/ZXingObjCTests/Resources/blackbox/upca-3/15.png
new file mode 100644
index 0000000..9269a83
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/15.txt b/ZXingObjCTests/Resources/blackbox/upca-3/15.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/15.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/16.png b/ZXingObjCTests/Resources/blackbox/upca-3/16.png
new file mode 100644
index 0000000..c554e5a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/16.txt b/ZXingObjCTests/Resources/blackbox/upca-3/16.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/16.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/17.png b/ZXingObjCTests/Resources/blackbox/upca-3/17.png
new file mode 100644
index 0000000..576fb35
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/17.txt b/ZXingObjCTests/Resources/blackbox/upca-3/17.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/17.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/18.png b/ZXingObjCTests/Resources/blackbox/upca-3/18.png
new file mode 100644
index 0000000..db79853
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/18.txt b/ZXingObjCTests/Resources/blackbox/upca-3/18.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/18.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/19.png b/ZXingObjCTests/Resources/blackbox/upca-3/19.png
new file mode 100644
index 0000000..5370421
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/19.txt b/ZXingObjCTests/Resources/blackbox/upca-3/19.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/19.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/20.png b/ZXingObjCTests/Resources/blackbox/upca-3/20.png
new file mode 100644
index 0000000..ba90d01
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/20.txt b/ZXingObjCTests/Resources/blackbox/upca-3/20.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/20.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/21.png b/ZXingObjCTests/Resources/blackbox/upca-3/21.png
new file mode 100644
index 0000000..9e81db3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-3/21.txt b/ZXingObjCTests/Resources/blackbox/upca-3/21.txt
new file mode 100644
index 0000000..389d4d6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-3/21.txt
@@ -0,0 +1 @@
+854818000116
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/1.png b/ZXingObjCTests/Resources/blackbox/upca-4/1.png
new file mode 100644
index 0000000..59813c9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/1.txt b/ZXingObjCTests/Resources/blackbox/upca-4/1.txt
new file mode 100644
index 0000000..6759a5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/1.txt
@@ -0,0 +1 @@
+023942431015
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/10.png b/ZXingObjCTests/Resources/blackbox/upca-4/10.png
new file mode 100644
index 0000000..a319098
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/10.txt b/ZXingObjCTests/Resources/blackbox/upca-4/10.txt
new file mode 100644
index 0000000..3e76dac
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/10.txt
@@ -0,0 +1 @@
+066721010995
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/11.png b/ZXingObjCTests/Resources/blackbox/upca-4/11.png
new file mode 100644
index 0000000..f550ef7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/11.txt b/ZXingObjCTests/Resources/blackbox/upca-4/11.txt
new file mode 100644
index 0000000..cef4bfc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/11.txt
@@ -0,0 +1 @@
+059290522143
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/12.png b/ZXingObjCTests/Resources/blackbox/upca-4/12.png
new file mode 100644
index 0000000..49c51e5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/12.txt b/ZXingObjCTests/Resources/blackbox/upca-4/12.txt
new file mode 100644
index 0000000..6491be4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/12.txt
@@ -0,0 +1 @@
+057961000228
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/13.png b/ZXingObjCTests/Resources/blackbox/upca-4/13.png
new file mode 100644
index 0000000..48e2d5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/13.txt b/ZXingObjCTests/Resources/blackbox/upca-4/13.txt
new file mode 100644
index 0000000..cef4bfc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/13.txt
@@ -0,0 +1 @@
+059290522143
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/14.png b/ZXingObjCTests/Resources/blackbox/upca-4/14.png
new file mode 100644
index 0000000..1ac10fc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/14.txt b/ZXingObjCTests/Resources/blackbox/upca-4/14.txt
new file mode 100644
index 0000000..14eb468
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/14.txt
@@ -0,0 +1 @@
+066721017185
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/15.png b/ZXingObjCTests/Resources/blackbox/upca-4/15.png
new file mode 100644
index 0000000..895a5a4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/15.txt b/ZXingObjCTests/Resources/blackbox/upca-4/15.txt
new file mode 100644
index 0000000..8d6fe86
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/15.txt
@@ -0,0 +1 @@
+059290571110
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/16.png b/ZXingObjCTests/Resources/blackbox/upca-4/16.png
new file mode 100644
index 0000000..1153abc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/16.txt b/ZXingObjCTests/Resources/blackbox/upca-4/16.txt
new file mode 100644
index 0000000..969c6d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/16.txt
@@ -0,0 +1 @@
+067932000263
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/17.png b/ZXingObjCTests/Resources/blackbox/upca-4/17.png
new file mode 100644
index 0000000..932d863
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/17.txt b/ZXingObjCTests/Resources/blackbox/upca-4/17.txt
new file mode 100644
index 0000000..52692d4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/17.txt
@@ -0,0 +1 @@
+069000061015
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/18.png b/ZXingObjCTests/Resources/blackbox/upca-4/18.png
new file mode 100644
index 0000000..df42f21
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/18.txt b/ZXingObjCTests/Resources/blackbox/upca-4/18.txt
new file mode 100644
index 0000000..3445d0e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/18.txt
@@ -0,0 +1 @@
+071691155775
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/19.png b/ZXingObjCTests/Resources/blackbox/upca-4/19.png
new file mode 100644
index 0000000..eada78e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/19.txt b/ZXingObjCTests/Resources/blackbox/upca-4/19.txt
new file mode 100644
index 0000000..b3b9f9c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/19.txt
@@ -0,0 +1 @@
+807648011401
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/2.png b/ZXingObjCTests/Resources/blackbox/upca-4/2.png
new file mode 100644
index 0000000..bc77c6a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/2.txt b/ZXingObjCTests/Resources/blackbox/upca-4/2.txt
new file mode 100644
index 0000000..6759a5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/2.txt
@@ -0,0 +1 @@
+023942431015
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/3.png b/ZXingObjCTests/Resources/blackbox/upca-4/3.png
new file mode 100644
index 0000000..92fdf2c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/3.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/3.txt b/ZXingObjCTests/Resources/blackbox/upca-4/3.txt
new file mode 100644
index 0000000..6759a5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/3.txt
@@ -0,0 +1 @@
+023942431015
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/4.png b/ZXingObjCTests/Resources/blackbox/upca-4/4.png
new file mode 100644
index 0000000..abdee5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/4.txt b/ZXingObjCTests/Resources/blackbox/upca-4/4.txt
new file mode 100644
index 0000000..6759a5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/4.txt
@@ -0,0 +1 @@
+023942431015
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/5.png b/ZXingObjCTests/Resources/blackbox/upca-4/5.png
new file mode 100644
index 0000000..cb717cb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/5.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/5.txt b/ZXingObjCTests/Resources/blackbox/upca-4/5.txt
new file mode 100644
index 0000000..6759a5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/5.txt
@@ -0,0 +1 @@
+023942431015
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/6.png b/ZXingObjCTests/Resources/blackbox/upca-4/6.png
new file mode 100644
index 0000000..a426f7c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/6.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/6.txt b/ZXingObjCTests/Resources/blackbox/upca-4/6.txt
new file mode 100644
index 0000000..6759a5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/6.txt
@@ -0,0 +1 @@
+023942431015
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/7.png b/ZXingObjCTests/Resources/blackbox/upca-4/7.png
new file mode 100644
index 0000000..c37eee2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/7.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/7.txt b/ZXingObjCTests/Resources/blackbox/upca-4/7.txt
new file mode 100644
index 0000000..6759a5e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/7.txt
@@ -0,0 +1 @@
+023942431015
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/8.png b/ZXingObjCTests/Resources/blackbox/upca-4/8.png
new file mode 100644
index 0000000..d09bc83
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/8.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/8.txt b/ZXingObjCTests/Resources/blackbox/upca-4/8.txt
new file mode 100644
index 0000000..29cffd2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/8.txt
@@ -0,0 +1 @@
+060410049235
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/9.png b/ZXingObjCTests/Resources/blackbox/upca-4/9.png
new file mode 100644
index 0000000..d3c9ba2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/9.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-4/9.txt b/ZXingObjCTests/Resources/blackbox/upca-4/9.txt
new file mode 100644
index 0000000..29cffd2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-4/9.txt
@@ -0,0 +1 @@
+060410049235
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/01.png b/ZXingObjCTests/Resources/blackbox/upca-5/01.png
new file mode 100755
index 0000000..5145f5d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/01.txt b/ZXingObjCTests/Resources/blackbox/upca-5/01.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/01.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/02.png b/ZXingObjCTests/Resources/blackbox/upca-5/02.png
new file mode 100755
index 0000000..78bf767
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/02.txt b/ZXingObjCTests/Resources/blackbox/upca-5/02.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/02.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/03.png b/ZXingObjCTests/Resources/blackbox/upca-5/03.png
new file mode 100755
index 0000000..04408f5
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/03.txt b/ZXingObjCTests/Resources/blackbox/upca-5/03.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/03.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/04.png b/ZXingObjCTests/Resources/blackbox/upca-5/04.png
new file mode 100755
index 0000000..878ed4c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/04.txt b/ZXingObjCTests/Resources/blackbox/upca-5/04.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/04.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/05.png b/ZXingObjCTests/Resources/blackbox/upca-5/05.png
new file mode 100755
index 0000000..537a138
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/05.txt b/ZXingObjCTests/Resources/blackbox/upca-5/05.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/05.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/06.png b/ZXingObjCTests/Resources/blackbox/upca-5/06.png
new file mode 100755
index 0000000..6e46ffe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/06.txt b/ZXingObjCTests/Resources/blackbox/upca-5/06.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/06.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/07.png b/ZXingObjCTests/Resources/blackbox/upca-5/07.png
new file mode 100755
index 0000000..cd5edc3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/07.txt b/ZXingObjCTests/Resources/blackbox/upca-5/07.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/07.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/08.png b/ZXingObjCTests/Resources/blackbox/upca-5/08.png
new file mode 100755
index 0000000..0e08383
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/08.txt b/ZXingObjCTests/Resources/blackbox/upca-5/08.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/08.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/09.png b/ZXingObjCTests/Resources/blackbox/upca-5/09.png
new file mode 100755
index 0000000..f736834
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/09.txt b/ZXingObjCTests/Resources/blackbox/upca-5/09.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/09.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/10.png b/ZXingObjCTests/Resources/blackbox/upca-5/10.png
new file mode 100755
index 0000000..126330e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/10.txt b/ZXingObjCTests/Resources/blackbox/upca-5/10.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/10.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/11.png b/ZXingObjCTests/Resources/blackbox/upca-5/11.png
new file mode 100755
index 0000000..5cd11f0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/11.txt b/ZXingObjCTests/Resources/blackbox/upca-5/11.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/11.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/12.png b/ZXingObjCTests/Resources/blackbox/upca-5/12.png
new file mode 100755
index 0000000..bb2a93a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/12.txt b/ZXingObjCTests/Resources/blackbox/upca-5/12.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/12.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/13.png b/ZXingObjCTests/Resources/blackbox/upca-5/13.png
new file mode 100755
index 0000000..5a1f344
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/13.txt b/ZXingObjCTests/Resources/blackbox/upca-5/13.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/13.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/14.png b/ZXingObjCTests/Resources/blackbox/upca-5/14.png
new file mode 100755
index 0000000..1a23917
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/14.txt b/ZXingObjCTests/Resources/blackbox/upca-5/14.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/14.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/15.png b/ZXingObjCTests/Resources/blackbox/upca-5/15.png
new file mode 100755
index 0000000..fa3466c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/15.txt b/ZXingObjCTests/Resources/blackbox/upca-5/15.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/15.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/16.png b/ZXingObjCTests/Resources/blackbox/upca-5/16.png
new file mode 100755
index 0000000..202bd01
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/16.txt b/ZXingObjCTests/Resources/blackbox/upca-5/16.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/16.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/17.png b/ZXingObjCTests/Resources/blackbox/upca-5/17.png
new file mode 100755
index 0000000..3ad9d42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/17.txt b/ZXingObjCTests/Resources/blackbox/upca-5/17.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/17.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/18.png b/ZXingObjCTests/Resources/blackbox/upca-5/18.png
new file mode 100755
index 0000000..9f70d9f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/18.txt b/ZXingObjCTests/Resources/blackbox/upca-5/18.txt
new file mode 100644
index 0000000..108f623
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/18.txt
@@ -0,0 +1 @@
+312547701310
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/19.png b/ZXingObjCTests/Resources/blackbox/upca-5/19.png
new file mode 100755
index 0000000..e7f4abc
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/19.txt b/ZXingObjCTests/Resources/blackbox/upca-5/19.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/19.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/20.png b/ZXingObjCTests/Resources/blackbox/upca-5/20.png
new file mode 100755
index 0000000..5b22bca
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/20.txt b/ZXingObjCTests/Resources/blackbox/upca-5/20.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/20.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/21.png b/ZXingObjCTests/Resources/blackbox/upca-5/21.png
new file mode 100755
index 0000000..5d9b440
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/21.txt b/ZXingObjCTests/Resources/blackbox/upca-5/21.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/21.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/22.png b/ZXingObjCTests/Resources/blackbox/upca-5/22.png
new file mode 100755
index 0000000..0262598
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/22.txt b/ZXingObjCTests/Resources/blackbox/upca-5/22.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/22.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/23.png b/ZXingObjCTests/Resources/blackbox/upca-5/23.png
new file mode 100755
index 0000000..90eb50e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/23.txt b/ZXingObjCTests/Resources/blackbox/upca-5/23.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/23.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/24.png b/ZXingObjCTests/Resources/blackbox/upca-5/24.png
new file mode 100755
index 0000000..eb3aa47
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/24.txt b/ZXingObjCTests/Resources/blackbox/upca-5/24.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/24.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/25.png b/ZXingObjCTests/Resources/blackbox/upca-5/25.png
new file mode 100755
index 0000000..95ff85c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/25.txt b/ZXingObjCTests/Resources/blackbox/upca-5/25.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/25.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/26.png b/ZXingObjCTests/Resources/blackbox/upca-5/26.png
new file mode 100755
index 0000000..831264e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/26.txt b/ZXingObjCTests/Resources/blackbox/upca-5/26.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/26.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/27.png b/ZXingObjCTests/Resources/blackbox/upca-5/27.png
new file mode 100755
index 0000000..9e561a8
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/27.txt b/ZXingObjCTests/Resources/blackbox/upca-5/27.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/27.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/28.png b/ZXingObjCTests/Resources/blackbox/upca-5/28.png
new file mode 100755
index 0000000..04c3a96
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/28.txt b/ZXingObjCTests/Resources/blackbox/upca-5/28.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/28.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/29.png b/ZXingObjCTests/Resources/blackbox/upca-5/29.png
new file mode 100755
index 0000000..c6f668f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/29.txt b/ZXingObjCTests/Resources/blackbox/upca-5/29.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/29.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/30.png b/ZXingObjCTests/Resources/blackbox/upca-5/30.png
new file mode 100755
index 0000000..0995fff
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/30.txt b/ZXingObjCTests/Resources/blackbox/upca-5/30.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/30.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/31.png b/ZXingObjCTests/Resources/blackbox/upca-5/31.png
new file mode 100755
index 0000000..85416fb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/31.txt b/ZXingObjCTests/Resources/blackbox/upca-5/31.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/31.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/32.png b/ZXingObjCTests/Resources/blackbox/upca-5/32.png
new file mode 100755
index 0000000..2842cce
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/32.txt b/ZXingObjCTests/Resources/blackbox/upca-5/32.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/32.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/33.png b/ZXingObjCTests/Resources/blackbox/upca-5/33.png
new file mode 100755
index 0000000..f79dbd9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/33.txt b/ZXingObjCTests/Resources/blackbox/upca-5/33.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/33.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/34.png b/ZXingObjCTests/Resources/blackbox/upca-5/34.png
new file mode 100755
index 0000000..a37435b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/34.txt b/ZXingObjCTests/Resources/blackbox/upca-5/34.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/34.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/35.png b/ZXingObjCTests/Resources/blackbox/upca-5/35.png
new file mode 100755
index 0000000..8751c51
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-5/35.txt b/ZXingObjCTests/Resources/blackbox/upca-5/35.txt
new file mode 100644
index 0000000..5546cb7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-5/35.txt
@@ -0,0 +1 @@
+625034201058
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/01.png b/ZXingObjCTests/Resources/blackbox/upca-6/01.png
new file mode 100755
index 0000000..38c8dd4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/01.txt b/ZXingObjCTests/Resources/blackbox/upca-6/01.txt
new file mode 100644
index 0000000..37e4df6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/01.txt
@@ -0,0 +1 @@
+071831007995
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/02.png b/ZXingObjCTests/Resources/blackbox/upca-6/02.png
new file mode 100755
index 0000000..d11d067
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/02.txt b/ZXingObjCTests/Resources/blackbox/upca-6/02.txt
new file mode 100644
index 0000000..37e4df6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/02.txt
@@ -0,0 +1 @@
+071831007995
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/03.png b/ZXingObjCTests/Resources/blackbox/upca-6/03.png
new file mode 100755
index 0000000..3377da7
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/03.txt b/ZXingObjCTests/Resources/blackbox/upca-6/03.txt
new file mode 100644
index 0000000..37e4df6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/03.txt
@@ -0,0 +1 @@
+071831007995
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/04.png b/ZXingObjCTests/Resources/blackbox/upca-6/04.png
new file mode 100755
index 0000000..c544d1a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/04.txt b/ZXingObjCTests/Resources/blackbox/upca-6/04.txt
new file mode 100644
index 0000000..37e4df6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/04.txt
@@ -0,0 +1 @@
+071831007995
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/05.png b/ZXingObjCTests/Resources/blackbox/upca-6/05.png
new file mode 100755
index 0000000..1097850
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/05.txt b/ZXingObjCTests/Resources/blackbox/upca-6/05.txt
new file mode 100644
index 0000000..37e4df6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/05.txt
@@ -0,0 +1 @@
+071831007995
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/06.png b/ZXingObjCTests/Resources/blackbox/upca-6/06.png
new file mode 100755
index 0000000..52953f4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/06.txt b/ZXingObjCTests/Resources/blackbox/upca-6/06.txt
new file mode 100644
index 0000000..37e4df6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/06.txt
@@ -0,0 +1 @@
+071831007995
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/07.png b/ZXingObjCTests/Resources/blackbox/upca-6/07.png
new file mode 100755
index 0000000..66be786
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/07.txt b/ZXingObjCTests/Resources/blackbox/upca-6/07.txt
new file mode 100644
index 0000000..fcc02a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/07.txt
@@ -0,0 +1 @@
+605482330012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/08.png b/ZXingObjCTests/Resources/blackbox/upca-6/08.png
new file mode 100755
index 0000000..d02f1f9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/08.txt b/ZXingObjCTests/Resources/blackbox/upca-6/08.txt
new file mode 100644
index 0000000..fcc02a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/08.txt
@@ -0,0 +1 @@
+605482330012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/09.png b/ZXingObjCTests/Resources/blackbox/upca-6/09.png
new file mode 100755
index 0000000..119f93f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/09.txt b/ZXingObjCTests/Resources/blackbox/upca-6/09.txt
new file mode 100644
index 0000000..fcc02a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/09.txt
@@ -0,0 +1 @@
+605482330012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/10.png b/ZXingObjCTests/Resources/blackbox/upca-6/10.png
new file mode 100755
index 0000000..0f6d463
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/10.txt b/ZXingObjCTests/Resources/blackbox/upca-6/10.txt
new file mode 100644
index 0000000..fcc02a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/10.txt
@@ -0,0 +1 @@
+605482330012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/11.png b/ZXingObjCTests/Resources/blackbox/upca-6/11.png
new file mode 100755
index 0000000..7b1ae81
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/11.txt b/ZXingObjCTests/Resources/blackbox/upca-6/11.txt
new file mode 100644
index 0000000..fcc02a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/11.txt
@@ -0,0 +1 @@
+605482330012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/12.png b/ZXingObjCTests/Resources/blackbox/upca-6/12.png
new file mode 100755
index 0000000..da5a150
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/12.txt b/ZXingObjCTests/Resources/blackbox/upca-6/12.txt
new file mode 100644
index 0000000..fcc02a0
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/12.txt
@@ -0,0 +1 @@
+605482330012
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/13.png b/ZXingObjCTests/Resources/blackbox/upca-6/13.png
new file mode 100755
index 0000000..425ab48
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/13.txt b/ZXingObjCTests/Resources/blackbox/upca-6/13.txt
new file mode 100644
index 0000000..359b01d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/13.txt
@@ -0,0 +1 @@
+073333531084
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/14.png b/ZXingObjCTests/Resources/blackbox/upca-6/14.png
new file mode 100755
index 0000000..2d5bb4b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/14.txt b/ZXingObjCTests/Resources/blackbox/upca-6/14.txt
new file mode 100644
index 0000000..359b01d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/14.txt
@@ -0,0 +1 @@
+073333531084
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/15.png b/ZXingObjCTests/Resources/blackbox/upca-6/15.png
new file mode 100755
index 0000000..761f196
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/15.txt b/ZXingObjCTests/Resources/blackbox/upca-6/15.txt
new file mode 100644
index 0000000..359b01d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/15.txt
@@ -0,0 +1 @@
+073333531084
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/16.png b/ZXingObjCTests/Resources/blackbox/upca-6/16.png
new file mode 100755
index 0000000..0fb2e9e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/16.txt b/ZXingObjCTests/Resources/blackbox/upca-6/16.txt
new file mode 100644
index 0000000..359b01d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/16.txt
@@ -0,0 +1 @@
+073333531084
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/17.png b/ZXingObjCTests/Resources/blackbox/upca-6/17.png
new file mode 100755
index 0000000..5940d3c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/17.txt b/ZXingObjCTests/Resources/blackbox/upca-6/17.txt
new file mode 100644
index 0000000..359b01d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/17.txt
@@ -0,0 +1 @@
+073333531084
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/18.png b/ZXingObjCTests/Resources/blackbox/upca-6/18.png
new file mode 100755
index 0000000..926f1d3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/18.txt b/ZXingObjCTests/Resources/blackbox/upca-6/18.txt
new file mode 100644
index 0000000..359b01d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/18.txt
@@ -0,0 +1 @@
+073333531084
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/19.png b/ZXingObjCTests/Resources/blackbox/upca-6/19.png
new file mode 100755
index 0000000..0589049
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upca-6/19.txt b/ZXingObjCTests/Resources/blackbox/upca-6/19.txt
new file mode 100644
index 0000000..359b01d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upca-6/19.txt
@@ -0,0 +1 @@
+073333531084
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-1/1.png b/ZXingObjCTests/Resources/blackbox/upce-1/1.png
new file mode 100644
index 0000000..ada741f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-1/1.txt b/ZXingObjCTests/Resources/blackbox/upce-1/1.txt
new file mode 100644
index 0000000..ff99f0e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-1/1.txt
@@ -0,0 +1 @@
+01234565
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-1/2.png b/ZXingObjCTests/Resources/blackbox/upce-1/2.png
new file mode 100644
index 0000000..dc060f2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-1/2.txt b/ZXingObjCTests/Resources/blackbox/upce-1/2.txt
new file mode 100644
index 0000000..f17aea9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-1/2.txt
@@ -0,0 +1 @@
+00123457
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-1/4.png b/ZXingObjCTests/Resources/blackbox/upce-1/4.png
new file mode 100644
index 0000000..64451b3
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-1/4.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-1/4.txt b/ZXingObjCTests/Resources/blackbox/upce-1/4.txt
new file mode 100644
index 0000000..8e866d2
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-1/4.txt
@@ -0,0 +1 @@
+01234531
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/01.png b/ZXingObjCTests/Resources/blackbox/upce-2/01.png
new file mode 100644
index 0000000..6adeb46
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/01.txt b/ZXingObjCTests/Resources/blackbox/upce-2/01.txt
new file mode 100644
index 0000000..142011d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/01.txt
@@ -0,0 +1 @@
+05096893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/02.png b/ZXingObjCTests/Resources/blackbox/upce-2/02.png
new file mode 100644
index 0000000..eadeec6
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/02.txt b/ZXingObjCTests/Resources/blackbox/upce-2/02.txt
new file mode 100644
index 0000000..142011d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/02.txt
@@ -0,0 +1 @@
+05096893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/03.png b/ZXingObjCTests/Resources/blackbox/upce-2/03.png
new file mode 100644
index 0000000..8b13bad
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/03.txt b/ZXingObjCTests/Resources/blackbox/upce-2/03.txt
new file mode 100644
index 0000000..142011d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/03.txt
@@ -0,0 +1 @@
+05096893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/04.png b/ZXingObjCTests/Resources/blackbox/upce-2/04.png
new file mode 100644
index 0000000..0326beb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/04.txt b/ZXingObjCTests/Resources/blackbox/upce-2/04.txt
new file mode 100644
index 0000000..142011d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/04.txt
@@ -0,0 +1 @@
+05096893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/05.png b/ZXingObjCTests/Resources/blackbox/upce-2/05.png
new file mode 100644
index 0000000..caf4459
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/05.txt b/ZXingObjCTests/Resources/blackbox/upce-2/05.txt
new file mode 100644
index 0000000..142011d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/05.txt
@@ -0,0 +1 @@
+05096893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/06.png b/ZXingObjCTests/Resources/blackbox/upce-2/06.png
new file mode 100644
index 0000000..31e41de
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/06.txt b/ZXingObjCTests/Resources/blackbox/upce-2/06.txt
new file mode 100644
index 0000000..142011d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/06.txt
@@ -0,0 +1 @@
+05096893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/07.png b/ZXingObjCTests/Resources/blackbox/upce-2/07.png
new file mode 100644
index 0000000..e165266
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/07.txt b/ZXingObjCTests/Resources/blackbox/upce-2/07.txt
new file mode 100644
index 0000000..142011d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/07.txt
@@ -0,0 +1 @@
+05096893
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/08.png b/ZXingObjCTests/Resources/blackbox/upce-2/08.png
new file mode 100644
index 0000000..1b82632
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/08.txt b/ZXingObjCTests/Resources/blackbox/upce-2/08.txt
new file mode 100644
index 0000000..5d7eb42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/08.txt
@@ -0,0 +1 @@
+04963406
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/09.png b/ZXingObjCTests/Resources/blackbox/upce-2/09.png
new file mode 100644
index 0000000..fa0b17f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/09.txt b/ZXingObjCTests/Resources/blackbox/upce-2/09.txt
new file mode 100644
index 0000000..5d7eb42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/09.txt
@@ -0,0 +1 @@
+04963406
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/10.png b/ZXingObjCTests/Resources/blackbox/upce-2/10.png
new file mode 100644
index 0000000..7310fbd
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/10.txt b/ZXingObjCTests/Resources/blackbox/upce-2/10.txt
new file mode 100644
index 0000000..5d7eb42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/10.txt
@@ -0,0 +1 @@
+04963406
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/11.png b/ZXingObjCTests/Resources/blackbox/upce-2/11.png
new file mode 100644
index 0000000..d3dbbfe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/11.txt b/ZXingObjCTests/Resources/blackbox/upce-2/11.txt
new file mode 100644
index 0000000..5d7eb42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/11.txt
@@ -0,0 +1 @@
+04963406
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/12.png b/ZXingObjCTests/Resources/blackbox/upce-2/12.png
new file mode 100644
index 0000000..c139274
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/12.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/12.txt b/ZXingObjCTests/Resources/blackbox/upce-2/12.txt
new file mode 100644
index 0000000..5d7eb42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/12.txt
@@ -0,0 +1 @@
+04963406
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/13.png b/ZXingObjCTests/Resources/blackbox/upce-2/13.png
new file mode 100644
index 0000000..12bdbfe
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/13.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/13.txt b/ZXingObjCTests/Resources/blackbox/upce-2/13.txt
new file mode 100644
index 0000000..5d7eb42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/13.txt
@@ -0,0 +1 @@
+04963406
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/14.png b/ZXingObjCTests/Resources/blackbox/upce-2/14.png
new file mode 100644
index 0000000..ede5239
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/14.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/14.txt b/ZXingObjCTests/Resources/blackbox/upce-2/14.txt
new file mode 100644
index 0000000..5d7eb42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/14.txt
@@ -0,0 +1 @@
+04963406
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/15.png b/ZXingObjCTests/Resources/blackbox/upce-2/15.png
new file mode 100644
index 0000000..150154e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/15.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/15.txt b/ZXingObjCTests/Resources/blackbox/upce-2/15.txt
new file mode 100644
index 0000000..5d7eb42
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/15.txt
@@ -0,0 +1 @@
+04963406
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/16.png b/ZXingObjCTests/Resources/blackbox/upce-2/16.png
new file mode 100644
index 0000000..c248806
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/16.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/16.txt b/ZXingObjCTests/Resources/blackbox/upce-2/16.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/16.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/17.png b/ZXingObjCTests/Resources/blackbox/upce-2/17.png
new file mode 100644
index 0000000..4ee5519
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/17.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/17.txt b/ZXingObjCTests/Resources/blackbox/upce-2/17.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/17.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/18.png b/ZXingObjCTests/Resources/blackbox/upce-2/18.png
new file mode 100644
index 0000000..2a30921
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/18.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/18.txt b/ZXingObjCTests/Resources/blackbox/upce-2/18.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/18.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/19.png b/ZXingObjCTests/Resources/blackbox/upce-2/19.png
new file mode 100644
index 0000000..d4b6ffb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/19.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/19.txt b/ZXingObjCTests/Resources/blackbox/upce-2/19.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/19.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/20.png b/ZXingObjCTests/Resources/blackbox/upce-2/20.png
new file mode 100644
index 0000000..1a6ec9e
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/20.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/20.txt b/ZXingObjCTests/Resources/blackbox/upce-2/20.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/20.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/21.png b/ZXingObjCTests/Resources/blackbox/upce-2/21.png
new file mode 100644
index 0000000..4ffc238
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/21.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/21.txt b/ZXingObjCTests/Resources/blackbox/upce-2/21.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/21.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/22.png b/ZXingObjCTests/Resources/blackbox/upce-2/22.png
new file mode 100644
index 0000000..371a347
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/22.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/22.txt b/ZXingObjCTests/Resources/blackbox/upce-2/22.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/22.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/23.png b/ZXingObjCTests/Resources/blackbox/upce-2/23.png
new file mode 100644
index 0000000..8aeda39
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/23.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/23.txt b/ZXingObjCTests/Resources/blackbox/upce-2/23.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/23.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/24.png b/ZXingObjCTests/Resources/blackbox/upce-2/24.png
new file mode 100644
index 0000000..963632b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/24.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/24.txt b/ZXingObjCTests/Resources/blackbox/upce-2/24.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/24.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/25.png b/ZXingObjCTests/Resources/blackbox/upce-2/25.png
new file mode 100644
index 0000000..6b42977
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/25.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/25.txt b/ZXingObjCTests/Resources/blackbox/upce-2/25.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/25.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/26.png b/ZXingObjCTests/Resources/blackbox/upce-2/26.png
new file mode 100644
index 0000000..23664e9
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/26.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/26.txt b/ZXingObjCTests/Resources/blackbox/upce-2/26.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/26.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/27.png b/ZXingObjCTests/Resources/blackbox/upce-2/27.png
new file mode 100644
index 0000000..e768073
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/27.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/27.txt b/ZXingObjCTests/Resources/blackbox/upce-2/27.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/27.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/28.png b/ZXingObjCTests/Resources/blackbox/upce-2/28.png
new file mode 100644
index 0000000..68a5ff4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/28.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/28.txt b/ZXingObjCTests/Resources/blackbox/upce-2/28.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/28.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/29.png b/ZXingObjCTests/Resources/blackbox/upce-2/29.png
new file mode 100644
index 0000000..ed02c34
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/29.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/29.txt b/ZXingObjCTests/Resources/blackbox/upce-2/29.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/29.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/30.png b/ZXingObjCTests/Resources/blackbox/upce-2/30.png
new file mode 100644
index 0000000..1ce103d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/30.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/30.txt b/ZXingObjCTests/Resources/blackbox/upce-2/30.txt
new file mode 100644
index 0000000..1c6c6df
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/30.txt
@@ -0,0 +1 @@
+04124498
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/31.png b/ZXingObjCTests/Resources/blackbox/upce-2/31.png
new file mode 100644
index 0000000..bce80ae
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/31.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/31.txt b/ZXingObjCTests/Resources/blackbox/upce-2/31.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/31.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/32.png b/ZXingObjCTests/Resources/blackbox/upce-2/32.png
new file mode 100644
index 0000000..9e06adf
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/32.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/32.txt b/ZXingObjCTests/Resources/blackbox/upce-2/32.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/32.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/33.png b/ZXingObjCTests/Resources/blackbox/upce-2/33.png
new file mode 100644
index 0000000..d99d813
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/33.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/33.txt b/ZXingObjCTests/Resources/blackbox/upce-2/33.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/33.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/34.png b/ZXingObjCTests/Resources/blackbox/upce-2/34.png
new file mode 100644
index 0000000..48bf307
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/34.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/34.txt b/ZXingObjCTests/Resources/blackbox/upce-2/34.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/34.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/35.png b/ZXingObjCTests/Resources/blackbox/upce-2/35.png
new file mode 100644
index 0000000..b074973
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/35.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/35.txt b/ZXingObjCTests/Resources/blackbox/upce-2/35.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/35.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/36.png b/ZXingObjCTests/Resources/blackbox/upce-2/36.png
new file mode 100644
index 0000000..bfe64aa
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/36.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/36.txt b/ZXingObjCTests/Resources/blackbox/upce-2/36.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/36.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/37.png b/ZXingObjCTests/Resources/blackbox/upce-2/37.png
new file mode 100644
index 0000000..14dde54
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/37.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/37.txt b/ZXingObjCTests/Resources/blackbox/upce-2/37.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/37.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/38.png b/ZXingObjCTests/Resources/blackbox/upce-2/38.png
new file mode 100644
index 0000000..f3a16e4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/38.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/38.txt b/ZXingObjCTests/Resources/blackbox/upce-2/38.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/38.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/39.png b/ZXingObjCTests/Resources/blackbox/upce-2/39.png
new file mode 100644
index 0000000..411d57c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/39.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/39.txt b/ZXingObjCTests/Resources/blackbox/upce-2/39.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/39.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/40.png b/ZXingObjCTests/Resources/blackbox/upce-2/40.png
new file mode 100644
index 0000000..5084b0a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/40.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/40.txt b/ZXingObjCTests/Resources/blackbox/upce-2/40.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/40.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/41.png b/ZXingObjCTests/Resources/blackbox/upce-2/41.png
new file mode 100644
index 0000000..39f8254
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/41.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-2/41.txt b/ZXingObjCTests/Resources/blackbox/upce-2/41.txt
new file mode 100644
index 0000000..e9c1b63
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-2/41.txt
@@ -0,0 +1 @@
+01264904
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/01.png b/ZXingObjCTests/Resources/blackbox/upce-3/01.png
new file mode 100644
index 0000000..d545a18
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/01.txt b/ZXingObjCTests/Resources/blackbox/upce-3/01.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/01.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/02.png b/ZXingObjCTests/Resources/blackbox/upce-3/02.png
new file mode 100644
index 0000000..bf53207
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/02.txt b/ZXingObjCTests/Resources/blackbox/upce-3/02.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/02.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/03.png b/ZXingObjCTests/Resources/blackbox/upce-3/03.png
new file mode 100644
index 0000000..2911a4f
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/03.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/03.txt b/ZXingObjCTests/Resources/blackbox/upce-3/03.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/03.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/04.png b/ZXingObjCTests/Resources/blackbox/upce-3/04.png
new file mode 100644
index 0000000..cfac890
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/04.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/04.txt b/ZXingObjCTests/Resources/blackbox/upce-3/04.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/04.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/05.png b/ZXingObjCTests/Resources/blackbox/upce-3/05.png
new file mode 100644
index 0000000..8ba2136
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/05.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/05.txt b/ZXingObjCTests/Resources/blackbox/upce-3/05.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/05.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/06.png b/ZXingObjCTests/Resources/blackbox/upce-3/06.png
new file mode 100644
index 0000000..7a760f4
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/06.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/06.txt b/ZXingObjCTests/Resources/blackbox/upce-3/06.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/06.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/07.png b/ZXingObjCTests/Resources/blackbox/upce-3/07.png
new file mode 100644
index 0000000..53cf17b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/07.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/07.txt b/ZXingObjCTests/Resources/blackbox/upce-3/07.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/07.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/08.png b/ZXingObjCTests/Resources/blackbox/upce-3/08.png
new file mode 100644
index 0000000..2105281
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/08.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/08.txt b/ZXingObjCTests/Resources/blackbox/upce-3/08.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/08.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/09.png b/ZXingObjCTests/Resources/blackbox/upce-3/09.png
new file mode 100644
index 0000000..96c3157
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/09.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/09.txt b/ZXingObjCTests/Resources/blackbox/upce-3/09.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/09.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/10.png b/ZXingObjCTests/Resources/blackbox/upce-3/10.png
new file mode 100644
index 0000000..c47671c
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/10.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/10.txt b/ZXingObjCTests/Resources/blackbox/upce-3/10.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/10.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/11.png b/ZXingObjCTests/Resources/blackbox/upce-3/11.png
new file mode 100644
index 0000000..a6674eb
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/11.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upce-3/11.txt b/ZXingObjCTests/Resources/blackbox/upce-3/11.txt
new file mode 100644
index 0000000..e33c450
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upce-3/11.txt
@@ -0,0 +1 @@
+04965802
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upcean-extension-1/1.metadata.txt b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/1.metadata.txt
new file mode 100644
index 0000000..6ad3f36
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/1.metadata.txt
@@ -0,0 +1 @@
+SUGGESTED_PRICE=$12.99
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upcean-extension-1/1.png b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/1.png
new file mode 100644
index 0000000..33d0a6b
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/1.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upcean-extension-1/1.txt b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/1.txt
new file mode 100644
index 0000000..101471a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/1.txt
@@ -0,0 +1 @@
+9780735200449
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upcean-extension-1/2.metadata.txt b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/2.metadata.txt
new file mode 100644
index 0000000..e14808d
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/2.metadata.txt
@@ -0,0 +1 @@
+SUGGESTED_PRICE=$24.95
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/blackbox/upcean-extension-1/2.png b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/2.png
new file mode 100644
index 0000000..dcd092a
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/2.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/blackbox/upcean-extension-1/2.txt b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/2.txt
new file mode 100644
index 0000000..576a811
--- /dev/null
+++ b/ZXingObjCTests/Resources/blackbox/upcean-extension-1/2.txt
@@ -0,0 +1 @@
+9780884271789
\ No newline at end of file
diff --git a/ZXingObjCTests/Resources/golden/qrcode/renderer-test-01.png b/ZXingObjCTests/Resources/golden/qrcode/renderer-test-01.png
new file mode 100644
index 0000000..5841d86
--- /dev/null
+++ b/ZXingObjCTests/Resources/golden/qrcode/renderer-test-01.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/golden/qrcode/renderer-test-02.png b/ZXingObjCTests/Resources/golden/qrcode/renderer-test-02.png
new file mode 100644
index 0000000..5fd2504
--- /dev/null
+++ b/ZXingObjCTests/Resources/golden/qrcode/renderer-test-02.png
Binary files differ
diff --git a/ZXingObjCTests/Resources/golden/qrcode/renderer-test-03.png b/ZXingObjCTests/Resources/golden/qrcode/renderer-test-03.png
new file mode 100644
index 0000000..884024d
--- /dev/null
+++ b/ZXingObjCTests/Resources/golden/qrcode/renderer-test-03.png
Binary files differ
diff --git a/ZXingObjCTests/Supporting Files/Tests-OSX-Prefix.pch b/ZXingObjCTests/Supporting Files/Tests-OSX-Prefix.pch
new file mode 100644
index 0000000..378c764
--- /dev/null
+++ b/ZXingObjCTests/Supporting Files/Tests-OSX-Prefix.pch
@@ -0,0 +1,9 @@
+//
+// Prefix header for all source files of the 'ZXingObjC' target in the 'ZXingObjC' project
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+
+ #import "ZXingObjC.h"
+#endif
diff --git a/ZXingObjCTests/Supporting Files/Tests-iOS-Prefix.pch b/ZXingObjCTests/Supporting Files/Tests-iOS-Prefix.pch
new file mode 100644
index 0000000..56feaa4
--- /dev/null
+++ b/ZXingObjCTests/Supporting Files/Tests-iOS-Prefix.pch
@@ -0,0 +1,9 @@
+//
+// Prefix header for all source files of the 'ZXingObjC' target in the 'ZXingObjC' project
+//
+
+#ifdef __OBJC__
+ #import <Foundation/Foundation.h>
+
+ #import "ZXingObjC.h"
+#endif
diff --git a/ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist b/ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist
new file mode 100644
index 0000000..26ba8de
--- /dev/null
+++ b/ZXingObjCTests/Supporting Files/ZXingObjCTests-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.zxing.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/ZXingObjCTests/Supporting Files/ios-Prefix.pch b/ZXingObjCTests/Supporting Files/ios-Prefix.pch
new file mode 100644
index 0000000..56feaa4
--- /dev/null
+++ b/ZXingObjCTests/Supporting Files/ios-Prefix.pch
@@ -0,0 +1,9 @@
+//
+// Prefix header for all source files of the 'ZXingObjC' target in the 'ZXingObjC' project
+//
+
+#ifdef __OBJC__
+ #import <Foundation/Foundation.h>
+
+ #import "ZXingObjC.h"
+#endif
diff --git a/ZXingObjCTests/Supporting Files/osx-Prefix.pch b/ZXingObjCTests/Supporting Files/osx-Prefix.pch
new file mode 100644
index 0000000..a35ac77
--- /dev/null
+++ b/ZXingObjCTests/Supporting Files/osx-Prefix.pch
@@ -0,0 +1,8 @@
+//
+// Prefix header for all source files of the 'ZXingObjC' target in the 'ZXingObjC' project
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+ #import "ZXingObjC.h"
+#endif
diff --git a/ZXingObjCTests/ZXingObjCTests-Info.plist b/ZXingObjCTests/ZXingObjCTests-Info.plist
new file mode 100644
index 0000000..26ba8de
--- /dev/null
+++ b/ZXingObjCTests/ZXingObjCTests-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.zxing.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/ZXingObjCTests/aztec/AztecBlackBox1TestCase.h b/ZXingObjCTests/aztec/AztecBlackBox1TestCase.h
new file mode 100644
index 0000000..34ab01f
--- /dev/null
+++ b/ZXingObjCTests/aztec/AztecBlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface AztecBlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/aztec/AztecBlackBox1TestCase.m b/ZXingObjCTests/aztec/AztecBlackBox1TestCase.m
new file mode 100644
index 0000000..cad62e0
--- /dev/null
+++ b/ZXingObjCTests/aztec/AztecBlackBox1TestCase.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 "AztecBlackBox1TestCase.h"
+
+@implementation AztecBlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/aztec-1"
+ barcodeReader:[[ZXAztecReader alloc] init]
+ expectedFormat:kBarcodeFormatAztec];
+
+ if (self) {
+ [self addTest:11 tryHarderCount:11 rotation:0.0f];
+ [self addTest:11 tryHarderCount:11 rotation:90.0f];
+ [self addTest:11 tryHarderCount:11 rotation:180.0f];
+ [self addTest:11 tryHarderCount:11 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/aztec/AztecBlackBox2TestCase.h b/ZXingObjCTests/aztec/AztecBlackBox2TestCase.h
new file mode 100644
index 0000000..5ca5e47
--- /dev/null
+++ b/ZXingObjCTests/aztec/AztecBlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface AztecBlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/aztec/AztecBlackBox2TestCase.m b/ZXingObjCTests/aztec/AztecBlackBox2TestCase.m
new file mode 100644
index 0000000..9a755f7
--- /dev/null
+++ b/ZXingObjCTests/aztec/AztecBlackBox2TestCase.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 "AztecBlackBox2TestCase.h"
+
+@implementation AztecBlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/aztec-2"
+ barcodeReader:[[ZXAztecReader alloc] init]
+ expectedFormat:kBarcodeFormatAztec];
+
+ if (self) {
+ [self addTest:2 tryHarderCount:2 rotation:0.0f];
+ [self addTest:2 tryHarderCount:2 rotation:90.0f];
+ [self addTest:3 tryHarderCount:3 rotation:180.0f];
+ [self addTest:1 tryHarderCount:1 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.h b/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.h
new file mode 100644
index 0000000..008d2f9
--- /dev/null
+++ b/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.h
@@ -0,0 +1,21 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXAztecEncoderTest : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.m b/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.m
new file mode 100644
index 0000000..6e2f208
--- /dev/null
+++ b/ZXingObjCTests/aztec/encoder/ZXAztecEncoderTest.m
@@ -0,0 +1,412 @@
+/*
+ * 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 "ZXAztecEncoderTest.h"
+
+unsigned int ZXAztecEncoderTest_RANDOM_SEED = 3735928559;
+
+@implementation ZXAztecEncoderTest
+
+// real life tests
+
+- (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"];
+}
+
+- (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."
+ 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 \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 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 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 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 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 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 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 \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 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 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 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 \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 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 \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 {
+ 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];
+ int8_t bytes[4096];
+ [data getCString:(char *)bytes maxLength:4096 encoding:NSISOLatin1StringEncoding];
+ int bytesLen = (int)[data lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding];
+ ZXAztecCode *aztec = [ZXAztecEncoder encode:bytes len:bytesLen minECCPercent:ZX_DEFAULT_AZTEC_EC_PERCENT];
+ ZXBitMatrix *expectedMatrix = aztec.matrix;
+ STAssertEqualObjects(expectedMatrix, matrix, @"Expected matrices to be equal");
+}
+
+// synthetic tests (encode-decode round-trip)
+
+- (void)testEncodeDecode1 {
+ [self testEncodeDecode:@"Abc123!" compact:YES layers:1];
+}
+
+- (void)testEncodeDecode2 {
+ [self testEncodeDecode:@"Lorem ipsum. http://test/" compact:YES layers:2];
+}
+
+- (void)testEncodeDecode3 {
+ [self testEncodeDecode:@"AAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAAN" compact:YES layers:3];
+}
+
+- (void)testEncodeDecode4 {
+ [self testEncodeDecode:@"http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384" compact:YES layers:4];
+}
+
+- (void)testEncodeDecode5 {
+ [self testEncodeDecode:@"http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384756<>/?abc" 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."
+ compact:NO layers:10];
+}
+
+- (void)testEncodeDecode23 {
+ [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. Donec ac nunc sodales elit placerat eleifend."
+ " Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus"
+ " justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu"
+ " tristique ac, p.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. Donec ac nunc sodales elit placerat"
+ " eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra"
+ " fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo"
+ " diam, lobortis eu tristique ac, p. 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."
+ compact:NO layers:23];
+}
+
+- (void)testEncodeDecode31 {
+ [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. Donec ac nunc sodales elit placerat eleifend."
+ " Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus"
+ " justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu"
+ " tristique ac, p.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. Donec ac nunc sodales elit placerat"
+ " eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra"
+ " fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo"
+ " diam, lobortis eu tristique ac, p. 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. Donec ac nunc sodales elit"
+ " placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at"
+ " pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est."
+ " Ut justo diam, lobortis eu tristique ac, p.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. Donec ac"
+ " nunc sodales elit placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula,"
+ " massa at pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus"
+ " sed est. Ut justo diam, lobortis eu tris. 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."
+ compact:NO layers:31];
+}
+
+- (void)testGenerateModeMessage {
+ [self testModeMessageCompact:YES layers:2 words:29 expected:@".X .XXX.. ...X XX.. ..X .XX. .XX.X"];
+ [self testModeMessageCompact:YES layers:4 words:64 expected:@"XX XXXXXX .X.. ...X ..XX .X.. XX.."];
+ [self testModeMessageCompact:NO layers:21 words:660 expected:@"X.X.. .X.X..X..XX .XXX ..X.. .XXX. .X... ..XXX"];
+ [self testModeMessageCompact:NO layers:32 words:4096 expected:@"XXXXX XXXXXXXXXXX X.X. ..... XXX.X ..X.. X.XXX"];
+}
+
+- (void)testStuffBits {
+ [self testStuffBits:5 bits:@".X.X. X.X.X .X.X." expected:@".X.X. X.X.X .X.X."];
+ [self testStuffBits:5 bits:@".X.X. ..... .X.X"
+ expected:@".X.X. ....X ..X.X"];
+ [self testStuffBits:3 bits:@"XX. ... ... ..X XXX .X. .."
+ expected:@"XX. ..X ..X ..X ..X .XX XX. .X. ..X"];
+ [self testStuffBits:6 bits:@".X.X.. ...... ..X.XX"
+ expected:@".X.X.. .....X. ..X.XX XXXX."];
+ [self testStuffBits:6 bits:@".X.X.. ...... ...... ..X.X."
+ expected:@".X.X.. .....X .....X ....X. X.XXXX"];
+ [self testStuffBits:6 bits:@".X.X.. XXXXXX ...... ..X.XX"
+ expected:@".X.X.. XXXXX. X..... ...X.X XXXXX."];
+ [self testStuffBits:6
+ bits:@"...... ..XXXX X..XX. .X.... .X.X.X .....X .X.... ...X.X .....X ....XX ..X... ....X. X..XXX X.XX.X"
+ expected:@".....X ...XXX XX..XX ..X... ..X.X. X..... X.X... ....X. X..... X....X X..X.. .....X X.X..X XXX.XX .XXXXX"];
+}
+
+- (void)testHighLevelEncode {
+ [self testHighLevelEncodeString:@"A. b."
+ expectedBits:@"...X. ..... ...XX XXX.. ...XX XXXX. XX.X"];
+ [self testHighLevelEncodeString:@"Lorem ipsum."
+ 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."
+ expectedBits:@".XX.X XXX.. X.... ..... ...XX XXX.. X.X.X ..XX. X.X.. X.X.X ....X XXXX. ..XX .X.. .X.X XX.X"];
+ [self testHighLevelEncodeString:@"Lo...x"
+ expectedBits:@".XX.X XXX.. X.... XXXX. XX.X XX.X XX.X XXX. XXX.. XX..X"];
+ [self testHighLevelEncodeString:@". x://abc/."
+ expectedBits:@"..... ...XX XXX.. XX..X ..... X.X.X ..... X.X.. ..... X.X.. ...X. ...XX ..X.. ..... X.X.. XXXX. XX.X"];
+}
+
+- (void)testHighLevelEncodeBinary {
+ // binary short form single byte
+ [self testHighLevelEncodeString:@"N\0N"
+ expectedBits:@".XXXX XXXXX ...X. ........ .X..XXX."];
+ // binary short form consecutive bytes
+ [self testHighLevelEncodeString:[NSString stringWithFormat:@"N\0%C A", 0x0080]
+ expectedBits:@".XXXX XXXXX ...X. ........ X....... ....X ...X."];
+ // binary skipping over single character
+ [self testHighLevelEncodeString:[NSString stringWithFormat:@"\0a%C%C A", 0x00FF, 0x0080]
+ expectedBits:@"XXXXX ..X.. ........ .XX....X XXXXXXXX X....... ....X ...X."];
+ // binary long form optimization into 2 short forms (saves 1 bit)
+ [self testHighLevelEncodeString:[NSString stringWithFormat:@"\0\0\0\0 \0\0\0\0 \0\0\0\0 \0\0\0\0 \0\0\0\0 \0\0\0\0 %C%C%C\0 \0\0\0\0 \0\0\0\0 ", 0x0082, 0x0084, 0x0088]
+ expectedBits:
+ @"XXXXX XXXXX ........ ........ ........ ........ ..X....."
+ " ........ ........ ........ ........ ..X....."
+ " ........ ........ ........ ........ ..X....."
+ " ........ ........ ........ ........ ..X....."
+ " ........ ........ ........ ........ ..X....."
+ " ........ ........ ........ ........ ..X....."
+ " X.....X. XXXXX .XXX. X....X.. X...X... ........ ..X....."
+ " ........ ........ ........ ........ ..X....."
+ " ........ ........ ........ ........ ..X....."];
+ // binary long form
+ [self testHighLevelEncodeString:[NSString stringWithFormat:@"\0\0\0\0 \0\0\1\0 \0\0\2\0 \0\0\3\0 \0\0\4\0 \0\0\5\0 \0\0\6\0 \0\0\7\0 \0\0%C\0 \0\0%C\0 \0\0\u00F0\0 \0\0\u00F1\0 \0\0\u00F2\0A", 0x0008, 0x0009]
+ expectedBits:
+ @"XXXXX ..... .....X...X. ........ ........ ........ ........ ..X....."
+ " ........ ........ .......X ........ ..X....."
+ " ........ ........ ......X. ........ ..X....."
+ " ........ ........ ......XX ........ ..X....."
+ " ........ ........ .....X.. ........ ..X....."
+ " ........ ........ .....X.X ........ ..X....."
+ " ........ ........ .....XX. ........ ..X....."
+ " ........ ........ .....XXX ........ ..X....."
+ " ........ ........ ....X... ........ ..X....."
+ " ........ ........ ....X..X ........ ..X....."
+ " ........ ........ XXXX.... ........ ..X....."
+ " ........ ........ XXXX...X ........ ..X....."
+ " ........ ........ XXXX..X. ........ .X.....X"];
+}
+
+// Helper routines
+
+- (void)testEncode:(NSString *)data compact:(BOOL)compact layers:(int)layers expected:(NSString *)expected {
+ int8_t bytes[4096];
+ [data getCString:(char *)bytes maxLength:4096 encoding:NSISOLatin1StringEncoding];
+ int bytesLen = (int)[data lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding];
+
+ ZXAztecCode *aztec = [ZXAztecEncoder encode:bytes len:bytesLen minECCPercent:33];
+ STAssertEquals(aztec.compact, compact, @"Unexpected symbol format (compact)");
+ STAssertEquals(aztec.layers, layers, @"Unexpected nr. of layers");
+ ZXBitMatrix *matrix = aztec.matrix;
+ STAssertEqualObjects([matrix description], expected, @"encode() failed");
+}
+
+- (void)testEncodeDecode:(NSString *)data compact:(BOOL)compact layers:(int)layers {
+ int8_t bytes[4096];
+ [data getCString:(char *)bytes maxLength:4096 encoding:NSISOLatin1StringEncoding];
+ int bytesLen = (int)[data lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding];
+
+ ZXAztecCode *aztec = [ZXAztecEncoder encode:bytes len:bytesLen minECCPercent:25];
+ STAssertEquals(aztec.compact, compact, @"Unexpected symbol format (compact)");
+ STAssertEquals(aztec.layers, layers, @"Unexpected nr. of layers");
+ ZXBitMatrix *matrix = aztec.matrix;
+ ZXAztecDetectorResult *r = [[ZXAztecDetectorResult alloc] initWithBits:matrix points:@[] compact:aztec.compact nbDatablocks:aztec.codeWords nbLayers:aztec.layers];
+ ZXDecoderResult *res = [[[ZXAztecDecoder alloc] init] decode:r error:nil];
+ STAssertEqualObjects(res.text, data, @"Data did not match");
+ // Check error correction by introducing a few minor errors
+ srand(ZXAztecEncoderTest_RANDOM_SEED);
+ [matrix flipX:rand() % matrix.width y:rand() % 2];
+ [matrix flipX:rand() % matrix.width y:matrix.height - 2 + rand() % 2];
+ [matrix flipX:rand() % 2 y:rand() % matrix.height];
+ [matrix flipX:matrix.width - 2 + rand() % 2 y:rand() % matrix.height];
+ r = [[ZXAztecDetectorResult alloc] initWithBits:matrix points:@[] compact:aztec.compact nbDatablocks:aztec.codeWords nbLayers:aztec.layers];
+ res = [[[ZXAztecDecoder alloc] init] decode:r error:nil];
+ STAssertEqualObjects(res.text, data, @"Data did not match");
+}
+
+- (void)testWriter:(NSString *)data encoding:(NSStringEncoding)encoding eccPercent:(int)eccPercent compact:(BOOL)compact layers:(int)layers {
+ // 1. Perform an encode-decode round-trip because it can be lossy.
+ // 2. Aztec Decoder currently always decodes the data with a LATIN-1 charset:
+ NSData *rawData = [data dataUsingEncoding:encoding];
+ int8_t *bytes = (int8_t *)[rawData bytes];
+ int bytesLen = (int)[rawData length];
+ NSString *expectedData = [[NSString alloc] initWithBytes:bytes length:bytesLen encoding:NSISOLatin1StringEncoding];
+ ZXEncodeHints *hints = [ZXEncodeHints hints];
+ hints.encoding = encoding;
+ hints.errorCorrectionPercent = @(eccPercent);
+ 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 len:bytesLen minECCPercent:eccPercent];
+ STAssertEquals(aztec.compact, compact, @"Unexpected symbol format (compact)");
+ STAssertEquals(aztec.layers, layers, @"Unexpected nr. of layers");
+ ZXBitMatrix *matrix2 = aztec.matrix;
+ STAssertEqualObjects(matrix2, matrix, @"Expected matrices to be equal");
+ ZXAztecDetectorResult *r = [[ZXAztecDetectorResult alloc] initWithBits:matrix points:@[] compact:aztec.compact nbDatablocks:aztec.codeWords nbLayers:aztec.layers];
+ ZXDecoderResult *res = [[[ZXAztecDecoder alloc] init] decode:r error:nil];
+ STAssertEqualObjects(res.text, expectedData, @"Data did not match");
+ // Check error correction by introducing up to eccPercent errors
+ srand(ZXAztecEncoderTest_RANDOM_SEED);
+ NSInteger ecWords = aztec.codeWords * eccPercent / 100;
+ 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);
+ int y = rand() % 2 > 0 ?
+ 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];
+ res = [[[ZXAztecDecoder alloc] init] decode:r error:nil];
+ STAssertEqualObjects(res.text, expectedData, @"Data did not match");
+}
+
+- (void)testModeMessageCompact:(BOOL)compact layers:(int)layers words:(int)words expected:(NSString *)expected {
+ ZXBitArray *inArray = [ZXAztecEncoder generateModeMessageCompact:compact layers:layers messageSizeInWords:words];
+ STAssertEqualObjects([[inArray description] stringByReplacingOccurrencesOfString:@" " withString:@""], [expected stringByReplacingOccurrencesOfString:@" " withString:@""], @"generateModeMessage() failed");
+}
+
+- (void)testStuffBits:(int)wordSize bits:(NSString *)bits expected:(NSString *)expected {
+ ZXBitArray *inArray = [self toBitArray:bits];
+ ZXBitArray *stuffed = [ZXAztecEncoder stuffBits:inArray wordSize:wordSize];
+ STAssertEqualObjects([[stuffed description] stringByReplacingOccurrencesOfString:@" " withString:@""], [expected stringByReplacingOccurrencesOfString:@" " withString:@""], @"stuffBits() failed for input string: %@", bits);
+}
+
+- (ZXBitArray *)toBitArray:(NSString *)bits {
+ static NSRegularExpression *DOTX = nil;
+ if (!DOTX) {
+ DOTX = [NSRegularExpression regularExpressionWithPattern:@"[^.X]" options:0 error:nil];
+ }
+
+ ZXBitArray *inArray = [[ZXBitArray alloc] init];
+ NSString *str = [DOTX stringByReplacingMatchesInString:bits options:0 range:NSMakeRange(0, bits.length) withTemplate:@""];
+ for (NSInteger i = 0; i < str.length; i++) {
+ unichar aStr = [str characterAtIndex:i];
+ [inArray appendBit:aStr == 'X'];
+ }
+ return inArray;
+}
+
+- (void)testHighLevelEncodeString:(NSString *)s expectedBits:(NSString *)expectedBits {
+ int8_t bytes[4096];
+ [s getCString:(char *)bytes maxLength:4096 encoding:NSISOLatin1StringEncoding];
+ int bytesLen = (int)[s lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding];
+
+ ZXBitArray *bits = [ZXAztecEncoder highLevelEncode:bytes len:bytesLen];
+ NSString *receivedBits = [[bits description] stringByReplacingOccurrencesOfString:@" " withString:@""];
+ STAssertEqualObjects(receivedBits, [expectedBits stringByReplacingOccurrencesOfString:@" " withString:@""], @"highLevelEncode() failed for input string: %@", s);
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXAddressBookParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXAddressBookParsedResultTestCase.h
new file mode 100644
index 0000000..4221360
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXAddressBookParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXAddressBookParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXAddressBookParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXAddressBookParsedResultTestCase.m
new file mode 100644
index 0000000..57c34d4
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXAddressBookParsedResultTestCase.m
@@ -0,0 +1,223 @@
+/*
+ * 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 "ZXAddressBookParsedResultTestCase.h"
+
+@implementation ZXAddressBookParsedResultTestCase
+
+- (void)testAddressBookDocomo {
+ [self doTestWithContents:@"MECARD:N:Sean Owen;;"
+ title:nil
+ names:@[@"Sean Owen"]
+ pronunciation:nil
+ addresses:nil
+ emails:nil
+ phoneNumbers:nil
+ org:nil
+ urls:nil
+ birthday:nil
+ note:nil];
+
+ [self doTestWithContents:@"MECARD:NOTE:ZXing Team;N:Sean Owen;URL:google.com;EMAIL:srowen@example.org;;"
+ title:nil
+ names:@[@"Sean Owen"]
+ pronunciation:nil
+ addresses:nil
+ emails:@[@"srowen@example.org"]
+ phoneNumbers:nil
+ org:nil
+ urls:@[@"google.com"]
+ birthday:nil
+ note:@"ZXing Team"];
+}
+
+- (void)testAddressBookAU {
+ [self doTestWithContents:@"MEMORY:foo\r\nNAME1:Sean\r\nTEL1:+12125551212\r\n"
+ title:nil
+ names:@[@"Sean"]
+ pronunciation:nil
+ addresses:nil
+ emails:nil
+ phoneNumbers:@[@"+12125551212"]
+ org:nil
+ urls:nil
+ birthday:nil
+ note:@"foo"];
+}
+
+- (void)testVCard {
+ [self doTestWithContents:@"BEGIN:VCARD\r\nADR;HOME:123 Main St\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD"
+ title:nil
+ names:@[@"Sean Owen"]
+ pronunciation:nil
+ addresses:@[@"123 Main St"]
+ emails:nil
+ phoneNumbers:nil
+ org:nil
+ urls:nil
+ birthday:nil
+ note:nil];
+}
+
+- (void)testVCardCaseInsensitive {
+ [self doTestWithContents:@"begin:vcard\r\nadr;HOME:123 Main St\r\nVersion:2.1\r\nn:Owen;Sean\r\nEND:VCARD"
+ title:nil
+ names:@[@"Sean Owen"]
+ pronunciation:nil
+ addresses:@[@"123 Main St"]
+ emails:nil
+ phoneNumbers:nil
+ org:nil
+ urls:nil
+ birthday:nil
+ note:nil];
+}
+
+- (void)testEscapedVCard {
+ [self doTestWithContents:@"BEGIN:VCARD\r\nADR;HOME:123\\;\\\\ Main\\, St\\nHome\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD"
+ title:nil
+ names:@[@"Sean Owen"]
+ pronunciation:nil
+ addresses:@[@"123;\\ Main, St\nHome"]
+ emails:nil
+ phoneNumbers:nil
+ org:nil
+ urls:nil
+ birthday:nil
+ note:nil];
+}
+
+- (void)testBizcard {
+ [self doTestWithContents:@"BIZCARD:N:Sean;X:Owen;C:Google;A:123 Main St;M:+12125551212;E:srowen@example.org;"
+ title:nil
+ names:@[@"Sean Owen"]
+ pronunciation:nil
+ addresses:@[@"123 Main St"]
+ emails:@[@"srowen@example.org"]
+ phoneNumbers:@[@"+12125551212"]
+ org:@"Google"
+ urls:nil
+ birthday:nil
+ note:nil];
+}
+
+- (void)testSeveralAddresses {
+ [self doTestWithContents:@"MECARD:N:Foo Bar;ORG:Company;TEL:5555555555;EMAIL:foo.bar@xyz.com;ADR:City, 10001;"
+ @"ADR:City, 10001;NOTE:This is the memo.;;"
+ title:nil
+ names:@[@"Foo Bar"]
+ pronunciation:nil
+ addresses:@[@"City, 10001", @"City, 10001"]
+ emails:@[@"foo.bar@xyz.com"]
+ phoneNumbers:@[@"5555555555"]
+ org:@"Company"
+ urls:nil
+ birthday:nil
+ note:@"This is the memo."];
+}
+
+- (void)testQuotedPrintable {
+ [self doTestWithContents:@"BEGIN:VCARD\r\nADR;HOME;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;;"
+ @"=38=38=20=4C=79=6E=62=72=6F=6F=6B=0D=0A=43=\r\n"
+ @"=4F=20=36=39=39=\r\n"
+ @"=39=39;;;\r\nEND:VCARD"
+ title:nil
+ names:nil
+ pronunciation:nil
+ addresses:@[@"88 Lynbrook\r\nCO 69999"]
+ emails:nil
+ phoneNumbers:nil
+ org:nil
+ urls:nil
+ birthday:nil
+ note:nil];
+}
+
+- (void)testVCardEscape {
+ [self doTestWithContents:@"BEGIN:VCARD\r\nNOTE:foo\\nbar\r\nEND:VCARD"
+ title:nil
+ names:nil
+ pronunciation:nil
+ addresses:nil
+ emails:nil
+ phoneNumbers:nil
+ org:nil
+ urls:nil
+ birthday:nil
+ note:@"foo\nbar"];
+ [self doTestWithContents:@"BEGIN:VCARD\r\nNOTE:foo\\;bar\r\nEND:VCARD"
+ title:nil
+ names:nil
+ pronunciation:nil
+ addresses:nil
+ emails:nil
+ phoneNumbers:nil
+ org:nil
+ urls:nil
+ birthday:nil
+ note:@"foo;bar"];
+ [self doTestWithContents:@"BEGIN:VCARD\r\nNOTE:foo\\\\bar\r\nEND:VCARD"
+ title:nil
+ names:nil
+ pronunciation:nil
+ addresses:nil
+ emails:nil
+ phoneNumbers:nil
+ org:nil
+ urls:nil
+ birthday:nil
+ note:@"foo\\bar"];
+ [self doTestWithContents:@"BEGIN:VCARD\r\nNOTE:foo\\,bar\r\nEND:VCARD"
+ title:nil
+ names:nil
+ pronunciation:nil
+ addresses:nil
+ emails:nil
+ phoneNumbers:nil
+ org:nil
+ urls:nil
+ birthday:nil
+ note:@"foo,bar"];
+}
+
+- (void)doTestWithContents:(NSString *)contents
+ title:(NSString *)title
+ names:(NSArray *)names
+ pronunciation:(NSArray *)pronunciation
+ addresses:(NSArray *)addresses
+ emails:(NSArray *)emails
+ phoneNumbers:(NSArray *)phoneNumbers
+ org:(NSString *)org
+ urls:(NSArray *)urls
+ birthday:(NSString *)birthday
+ note:(NSString *)note {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatQRCode];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(kParsedResultTypeAddressBook, result.type, @"Result type mismatch");
+ ZXAddressBookParsedResult *addressResult = (ZXAddressBookParsedResult *)result;
+ STAssertEqualObjects(addressResult.title, title, @"Titles do not match");
+ STAssertEqualObjects(addressResult.names, names, @"Names do not match");
+ STAssertEqualObjects(addressResult.pronunciation, pronunciation, @"Pronunciation does not match");
+ STAssertEqualObjects(addressResult.addresses, addresses, @"Addresses do not match");
+ STAssertEqualObjects(addressResult.emails, emails, @"Emails do not match");
+ STAssertEqualObjects(addressResult.phoneNumbers, phoneNumbers, @"Phone numbers do not match");
+ STAssertEqualObjects(addressResult.org, org, @"Org does not match");
+ STAssertEqualObjects(addressResult.urls, urls, @"URLs do not match");
+ STAssertEqualObjects(addressResult.birthday, birthday, @"Birthday does not match");
+ STAssertEqualObjects(addressResult.note, note, @"Note does not match");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXCalendarParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXCalendarParsedResultTestCase.h
new file mode 100644
index 0000000..4dfcbc6
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXCalendarParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXCalendarParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXCalendarParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXCalendarParsedResultTestCase.m
new file mode 100644
index 0000000..2a7bab9
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXCalendarParsedResultTestCase.m
@@ -0,0 +1,265 @@
+/*
+ * 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 "ZXCalendarParsedResultTestCase.h"
+
+@implementation ZXCalendarParsedResultTestCase
+
+static double EPSILON = 0.0000000001;
+static NSDateFormatter *DATE_TIME_FORMAT = nil;
+
++ (void)initialize {
+ DATE_TIME_FORMAT = [[NSDateFormatter alloc] init];
+ DATE_TIME_FORMAT.dateFormat = @"yyyyMMdd'T'HHmmss'Z'";
+}
+
+- (void)testStartEnd {
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"DTEND:20080505T234555Z\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:nil
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:@"20080505T234555Z"];
+}
+
+- (void)testNoVCalendar {
+ [self doTestWithContents:@"BEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"DTEND:20080505T234555Z\r\n"
+ @"END:VEVENT"
+ description:nil
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:@"20080505T234555Z"];
+}
+
+- (void)testStart {
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:nil
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:nil];
+}
+
+- (void)testDuration {
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"DURATION:P1D\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:nil
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:@"20080505T123456Z"];
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"DURATION:P1DT2H3M4S\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:nil
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:@"20080505T143800Z"];
+}
+
+- (void)testSummary {
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"SUMMARY:foo\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:nil
+ summary:@"foo"
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:nil];
+}
+
+- (void)testLocation {
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"LOCATION:Miami\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:nil
+ summary:nil
+ location:@"Miami"
+ startString:@"20080504T123456Z"
+ endString:nil];
+}
+
+- (void)testDescription {
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"DESCRIPTION:This is a test\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:@"This is a test"
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:nil];
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"DESCRIPTION:This is a test\r\n\t with a continuation\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:@"This is a test with a continuation"
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:nil];
+}
+
+- (void)testGeo {
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"GEO:-12.345;-45.678\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:nil
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:nil
+ organizer:nil
+ attendees:nil
+ latitude:-12.345
+ longitude:-45.678];
+}
+
+- (void)testOrganizer {
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"ORGANIZER:mailto:bob@example.org\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:nil
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:nil
+ organizer:@"bob@example.org"
+ attendees:nil
+ latitude:NAN
+ longitude:NAN];
+}
+
+- (void)testAttendees {
+ [self doTestWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n"
+ @"DTSTART:20080504T123456Z\r\n"
+ @"ATTENDEE:mailto:bob@example.org\r\n"
+ @"ATTENDEE:mailto:alice@example.org\r\n"
+ @"END:VEVENT\r\nEND:VCALENDAR"
+ description:nil
+ summary:nil
+ location:nil
+ startString:@"20080504T123456Z"
+ endString:nil
+ organizer:nil
+ attendees:@[@"bob@example.org", @"alice@example.org"]
+ latitude:NAN
+ longitude:NAN];
+}
+
+- (void)testVEventEscapes {
+ [self doTestWithContents:@"BEGIN:VEVENT\n"
+ @"CREATED:20111109T110351Z\n"
+ @"LAST-MODIFIED:20111109T170034Z\n"
+ @"DTSTAMP:20111109T170034Z\n"
+ @"UID:0f6d14ef-6cb7-4484-9080-61447ccdf9c2\n"
+ @"SUMMARY:Summary line\n"
+ @"CATEGORIES:Private\n"
+ @"DTSTART;TZID=Europe/Vienna:20111110T110000\n"
+ @"DTEND;TZID=Europe/Vienna:20111110T120000\n"
+ @"LOCATION:Location\\, with\\, escaped\\, commas\n"
+ @"DESCRIPTION:Meeting with a friend\\nlook at homepage first\\n\\n\n"
+ @" \\n\n"
+ @"SEQUENCE:1\n"
+ @"X-MOZ-GENERATION:1\n"
+ @"END:VEVENT"
+ description:@"Meeting with a friend\nlook at homepage first\n\n\n \n"
+ summary:@"Summary line"
+ location:@"Location, with, escaped, commas"
+ startString:@"20111110T110000Z"
+ endString:@"20111110T120000Z"];
+}
+
+- (void)testAllDayValueDate {
+ [self doTestWithContents:@"BEGIN:VEVENT\n"
+ @"DTSTART;VALUE=DATE:20111110\n"
+ @"DTEND;VALUE=DATE:20111110\n"
+ @"END:VEVENT"
+ description:nil
+ summary:nil
+ location:nil
+ startString:@"20111110T000000Z"
+ endString:@"20111110T000000Z"];
+}
+
+- (void)doTestWithContents:(NSString *)contents
+ description:(NSString *)description
+ summary:(NSString *)summary
+ location:(NSString *)location
+ startString:(NSString *)startString
+ endString:(NSString *)endString {
+ [self doTestWithContents:contents
+ description:description
+ summary:summary
+ location:location
+ startString:startString
+ endString:endString
+ organizer:nil
+ attendees:nil
+ latitude:NAN
+ longitude:NAN];
+}
+
+- (void)doTestWithContents:(NSString *)contents
+ description:(NSString *)description
+ summary:(NSString *)summary
+ location:(NSString *)location
+ startString:(NSString *)startString
+ endString:(NSString *)endString
+ organizer:(NSString *)organizer
+ attendees:(NSArray *)attendees
+ latitude:(double)latitude
+ longitude:(double)longitude {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatQRCode];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(result.type, kParsedResultTypeCalendar, @"Types do not match");
+ ZXCalendarParsedResult *calResult = (ZXCalendarParsedResult *)result;
+ STAssertEqualObjects(calResult.description, description, @"Descriptions do not match");
+ STAssertEqualObjects(calResult.summary, summary, @"Summaries do not match");
+ STAssertEqualObjects(calResult.location, location, @"Locations do not match");
+ STAssertEqualObjects([DATE_TIME_FORMAT stringFromDate:calResult.start], startString, @"Starts do not match");
+ STAssertEqualObjects([DATE_TIME_FORMAT stringFromDate:calResult.end], endString, @"Ends do not match");
+ STAssertEqualObjects(organizer, calResult.organizer, @"Organizers do not match");
+ STAssertEqualObjects(attendees, calResult.attendees, @"Attendees do not match");
+ [self assertEqualOrNAN:latitude actual:calResult.latitude];
+ [self assertEqualOrNAN:longitude actual:calResult.longitude];
+}
+
+- (void)assertEqualOrNAN:(double)expected actual:(double)actual {
+ if (isnan(expected)) {
+ STAssertTrue(isnan(actual), @"Expected %f to be NAN", actual);
+ } else {
+ STAssertEqualsWithAccuracy(actual, expected, EPSILON, @"Expected %f to equal %f", actual, expected);
+ }
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXEmailAddressParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXEmailAddressParsedResultTestCase.h
new file mode 100644
index 0000000..964a45a
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXEmailAddressParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXEmailAddressParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXEmailAddressParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXEmailAddressParsedResultTestCase.m
new file mode 100644
index 0000000..f68fd3d
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXEmailAddressParsedResultTestCase.m
@@ -0,0 +1,54 @@
+/*
+ * 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 "ZXEmailAddressParsedResultTestCase.h"
+
+@implementation ZXEmailAddressParsedResultTestCase
+
+- (void)testEmailAddress {
+ [self doTestWithContents:@"srowen@example.org" email:@"srowen@example.org" subject:nil body:nil];
+ [self doTestWithContents:@"mailto:srowen@example.org" email:@"srowen@example.org" subject:nil body:nil];
+}
+
+- (void)testEmailDocomo {
+ [self doTestWithContents:@"MATMSG:TO:srowen@example.org;;" email:@"srowen@example.org" subject:nil body:nil];
+ [self doTestWithContents:@"MATMSG:TO:srowen@example.org;SUB:Stuff;;" email:@"srowen@example.org" subject:@"Stuff" body:nil];
+ [self doTestWithContents:@"MATMSG:TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;"
+ email:@"srowen@example.org" subject:@"Stuff" body:@"This is some text"];
+}
+
+- (void)testSMTP {
+ [self doTestWithContents:@"smtp:srowen@example.org" email:@"srowen@example.org" subject:nil body:nil];
+ [self doTestWithContents:@"SMTP:srowen@example.org" email:@"srowen@example.org" subject:nil body:nil];
+ [self doTestWithContents:@"SMTP:srowen@example.org:foo" email:@"srowen@example.org" subject:@"foo" body:nil];
+ [self doTestWithContents:@"SMTP:srowen@example.org:foo:bar" email:@"srowen@example.org" subject:@"foo" body:@"bar"];
+}
+
+- (void)doTestWithContents:(NSString *)contents
+ email:(NSString *)email
+ subject:(NSString *)subject
+ body:(NSString *)body {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatQRCode];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(result.type, kParsedResultTypeEmailAddress, @"Types do not match");
+ ZXEmailAddressParsedResult *emailResult = (ZXEmailAddressParsedResult *)result;
+ STAssertEqualObjects(emailResult.emailAddress, email, @"Email addresses do not match");
+ STAssertEqualObjects(emailResult.mailtoURI, [@"mailto:" stringByAppendingString:emailResult.emailAddress], @"Mailto URIs do not match");
+ STAssertEqualObjects(emailResult.subject, subject, @"Subjects do not match");
+ STAssertEqualObjects(emailResult.body, body, @"Bodies do not match");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXExpandedProductParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXExpandedProductParsedResultTestCase.h
new file mode 100644
index 0000000..e47b5a7
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXExpandedProductParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXExpandedProductParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXExpandedProductParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXExpandedProductParsedResultTestCase.m
new file mode 100644
index 0000000..2ca9102
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXExpandedProductParsedResultTestCase.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 "ZXExpandedProductParsedResultTestCase.h"
+
+@implementation ZXExpandedProductParsedResultTestCase
+
+- (void)test_RSSExpanded {
+ NSDictionary *uncommonAIs = @{@"123": @"544654"};
+ ZXResult *result = [ZXResult resultWithText:@"(01)66546(13)001205(3932)4455(3102)6544(123)544654"
+ rawBytes:NULL
+ length:0
+ resultPoints:nil
+ format:kBarcodeFormatRSSExpanded];
+ ZXExpandedProductParsedResult *o = (ZXExpandedProductParsedResult *)[[[ZXExpandedProductResultParser alloc] init] parse:result];
+ STAssertNotNil(o, @"Expected result to be non-nil");
+ STAssertEqualObjects(o.productID, @"66546", @"Product IDs don't match");
+ STAssertNil(o.sscc, @"Expected sscc to be nil");
+ STAssertNil(o.lotNumber, @"Expected lot number to be nil");
+ STAssertNil(o.productionDate, @"Expected production dates to be nil");
+ STAssertEqualObjects(o.packagingDate, @"001205", @"Packaging dates don't match");
+ STAssertNil(o.bestBeforeDate, @"Expected best before date to be nil");
+ STAssertNil(o.expirationDate, @"Expected expiration date to be nil");
+ STAssertEqualObjects(o.weight, @"6544", @"Weights don't match");
+ STAssertEqualObjects(o.weightType, @"KG", @"Weight types don't match");
+ STAssertEqualObjects(o.weightIncrement, @"2", @"Weight increments don't match");
+ STAssertEqualObjects(o.price, @"5", @"Prices don't match");
+ STAssertEqualObjects(o.priceIncrement, @"2", @"Price increments don't match");
+ STAssertEqualObjects(o.priceCurrency, @"445", @"Price currencies don't match");
+ STAssertEqualObjects(o.uncommonAIs, uncommonAIs, @"Uncommon AIs don't match");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXGeoParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXGeoParsedResultTestCase.h
new file mode 100644
index 0000000..39bb878
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXGeoParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXGeoParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXGeoParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXGeoParsedResultTestCase.m
new file mode 100644
index 0000000..ca59cb7
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXGeoParsedResultTestCase.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 "ZXGeoParsedResultTestCase.h"
+
+@implementation ZXGeoParsedResultTestCase
+
+static double EPSILON = 0.0000000001;
+
+- (void)testGeo {
+ [self doTestWithContents:@"geo:1,2" latitude:1.0 longitude:2.0 altitude:0.0 query:nil];
+ [self doTestWithContents:@"geo:80.33,-32.3344,3.35" latitude:80.33 longitude:-32.3344 altitude:3.35 query:nil];
+ [self doTestWithContents:@"geo:-20.33,132.3344,0.01" latitude:-20.33 longitude:132.3344 altitude:0.01 query:nil];
+ [self doTestWithContents:@"geo:-20.33,132.3344,0.01?q=foobar" latitude:-20.33 longitude:132.3344 altitude:0.01 query:@"q=foobar"];
+ [self doTestWithContents:@"GEO:-20.33,132.3344,0.01?q=foobar" latitude:-20.33 longitude:132.3344 altitude:0.01 query:@"q=foobar"];
+}
+
+- (void)doTestWithContents:(NSString *)contents
+ latitude:(double)latitude
+ longitude:(double)longitude
+ altitude:(double)altitude
+ query:(NSString *)query {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatQRCode];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(result.type, kParsedResultTypeGeo, @"Types don't match");
+ ZXGeoParsedResult *geoResult = (ZXGeoParsedResult *)result;
+ STAssertEqualsWithAccuracy(geoResult.latitude, latitude, EPSILON, @"Latitudes don't match");
+ STAssertEqualsWithAccuracy(geoResult.longitude, longitude, EPSILON, @"Longitudes don't match");
+ STAssertEqualsWithAccuracy(geoResult.altitude, altitude, EPSILON, @"Altitudes don't match");
+ STAssertEqualObjects(geoResult.query, query, @"Queries don't match");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXISBNParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXISBNParsedResultTestCase.h
new file mode 100644
index 0000000..f7642da
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXISBNParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXISBNParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXISBNParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXISBNParsedResultTestCase.m
new file mode 100644
index 0000000..6d4462d
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXISBNParsedResultTestCase.m
@@ -0,0 +1,33 @@
+/*
+ * 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 "ZXISBNParsedResultTestCase.h"
+
+@implementation ZXISBNParsedResultTestCase
+
+- (void)testISBN {
+ [self doTestWithContents:@"9784567890123"];
+}
+
+- (void)doTestWithContents:(NSString *)contents {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatEan13];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(result.type, kParsedResultTypeISBN, @"Types don't match");
+ ZXISBNParsedResult *isbnResult = (ZXISBNParsedResult *)result;
+ STAssertEqualObjects(isbnResult.isbn, contents, @"Contents don't match");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXParsedReaderResultTestCase.h b/ZXingObjCTests/client/result/ZXParsedReaderResultTestCase.h
new file mode 100644
index 0000000..e48047a
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXParsedReaderResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXParsedReaderResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXParsedReaderResultTestCase.m b/ZXingObjCTests/client/result/ZXParsedReaderResultTestCase.m
new file mode 100644
index 0000000..3c67d50
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXParsedReaderResultTestCase.m
@@ -0,0 +1,269 @@
+/*
+ * 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 "ZXParsedReaderResultTestCase.h"
+
+@implementation ZXParsedReaderResultTestCase
+
+- (void)testTextType {
+ [self doTestResultWithContents:@"" goldenResult:@"" type:kParsedResultTypeText];
+ [self doTestResultWithContents:@"foo" goldenResult:@"foo" type:kParsedResultTypeText];
+ [self doTestResultWithContents:@"Hi." goldenResult:@"Hi." type:kParsedResultTypeText];
+ [self doTestResultWithContents:@"This is a test\nwith newlines" goldenResult:@"This is a test\nwith newlines"
+ type:kParsedResultTypeText];
+ [self doTestResultWithContents:@"This: a test with lots of @ nearly-random punctuation! No? OK then."
+ goldenResult:@"This: a test with lots of @ nearly-random punctuation! No? OK then."
+ type:kParsedResultTypeText];
+}
+
+- (void)testBookmarkType {
+ [self doTestResultWithContents:@"MEBKM:URL:google.com;;" goldenResult:@"http://google.com" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"MEBKM:URL:google.com;TITLE:Google;;" goldenResult:@"Google\nhttp://google.com"
+ type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"MEBKM:TITLE:Google;URL:google.com;;" goldenResult:@"Google\nhttp://google.com"
+ type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"MEBKM:URL:http://google.com;;" goldenResult:@"http://google.com" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"MEBKM:URL:HTTPS://google.com;;" goldenResult:@"HTTPS://google.com" type:kParsedResultTypeURI];
+}
+
+- (void)testURLTOType {
+ [self doTestResultWithContents:@"urlto:foo:bar.com" goldenResult:@"foo\nhttp://bar.com" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"URLTO:foo:bar.com" goldenResult:@"foo\nhttp://bar.com" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"URLTO::bar.com" goldenResult:@"http://bar.com" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"URLTO::http://bar.com" goldenResult:@"http://bar.com" type:kParsedResultTypeURI];
+}
+
+- (void)testEmailType {
+ [self doTestResultWithContents:@"MATMSG:TO:srowen@example.org;;" goldenResult:@"srowen@example.org"
+ type:kParsedResultTypeEmailAddress];
+ [self doTestResultWithContents:@"MATMSG:TO:srowen@example.org;SUB:Stuff;;" goldenResult:@"srowen@example.org\nStuff"
+ type:kParsedResultTypeEmailAddress];
+ [self doTestResultWithContents:@"MATMSG:TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;"
+ goldenResult:@"srowen@example.org\nStuff\nThis is some text" type:kParsedResultTypeEmailAddress];
+ [self doTestResultWithContents:@"MATMSG:SUB:Stuff;BODY:This is some text;TO:srowen@example.org;;"
+ goldenResult:@"srowen@example.org\nStuff\nThis is some text" type:kParsedResultTypeEmailAddress];
+ [self doTestResultWithContents:@"TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;"
+ goldenResult:@"TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;" type:kParsedResultTypeText];
+}
+
+- (void)testEmailAddressType {
+ [self doTestResultWithContents:@"srowen@example.org" goldenResult:@"srowen@example.org" type:kParsedResultTypeEmailAddress];
+ [self doTestResultWithContents:@"mailto:srowen@example.org" goldenResult:@"srowen@example.org" type:kParsedResultTypeEmailAddress];
+ [self doTestResultWithContents:@"MAILTO:srowen@example.org" goldenResult:@"srowen@example.org" type:kParsedResultTypeEmailAddress];
+ [self doTestResultWithContents:@"srowen@example" goldenResult:@"srowen@example" type:kParsedResultTypeEmailAddress];
+ [self doTestResultWithContents:@"srowen" goldenResult:@"srowen" type:kParsedResultTypeText];
+ [self doTestResultWithContents:@"Let's meet @ 2" goldenResult:@"Let's meet @ 2" type:kParsedResultTypeText];
+}
+
+- (void)testAddressBookType {
+ [self doTestResultWithContents:@"MECARD:N:Sean Owen;;" goldenResult:@"Sean Owen" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"MECARD:TEL:+12125551212;N:Sean Owen;;" goldenResult:@"Sean Owen\n+12125551212"
+ type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"MECARD:TEL:+12125551212;N:Sean Owen;URL:google.com;;"
+ goldenResult:@"Sean Owen\n+12125551212\ngoogle.com" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"MECARD:TEL:+12125551212;N:Sean Owen;URL:google.com;EMAIL:srowen@example.org;"
+ goldenResult:@"Sean Owen\n+12125551212\nsrowen@example.org\ngoogle.com" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"MECARD:ADR:76 9th Ave;N:Sean Owen;URL:google.com;EMAIL:srowen@example.org;"
+ goldenResult:@"Sean Owen\n76 9th Ave\nsrowen@example.org\ngoogle.com" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"MECARD:BDAY:19760520;N:Sean Owen;URL:google.com;EMAIL:srowen@example.org;"
+ goldenResult:@"Sean Owen\nsrowen@example.org\ngoogle.com\n19760520" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"MECARD:ORG:Google;N:Sean Owen;URL:google.com;EMAIL:srowen@example.org;"
+ goldenResult:@"Sean Owen\nGoogle\nsrowen@example.org\ngoogle.com" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"MECARD:NOTE:ZXing Team;N:Sean Owen;URL:google.com;EMAIL:srowen@example.org;"
+ goldenResult:@"Sean Owen\nsrowen@example.org\ngoogle.com\nZXing Team" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"N:Sean Owen;TEL:+12125551212;;" goldenResult:@"N:Sean Owen;TEL:+12125551212;;"
+ type:kParsedResultTypeText];
+}
+
+- (void)testAddressBookAUType {
+ [self doTestResultWithContents:@"MEMORY:\r\n" goldenResult:@"" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"MEMORY:foo\r\nNAME1:Sean\r\n" goldenResult:@"Sean\nfoo" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"TEL1:+12125551212\r\nMEMORY:\r\n" goldenResult:@"+12125551212" type:kParsedResultTypeAddressBook];
+}
+
+- (void)testBizcard {
+ [self doTestResultWithContents:@"BIZCARD:N:Sean;X:Owen;C:Google;A:123 Main St;M:+12225551212;E:srowen@example.org;"
+ goldenResult:@"Sean Owen\nGoogle\n123 Main St\n+12225551212\nsrowen@example.org"
+ type:kParsedResultTypeAddressBook];
+}
+
+- (void)testUPCA {
+ [self doTestResultWithContents:@"123456789012" goldenResult:@"123456789012" type:kParsedResultTypeProduct format:kBarcodeFormatUPCA];
+ [self doTestResultWithContents:@"1234567890123" goldenResult:@"1234567890123" type:kParsedResultTypeProduct format:kBarcodeFormatUPCA];
+ [self doTestResultWithContents:@"12345678901" goldenResult:@"12345678901" type:kParsedResultTypeText];
+}
+
+- (void)testUPCE {
+ [self doTestResultWithContents:@"01234565" goldenResult:@"01234565" type:kParsedResultTypeProduct format:kBarcodeFormatUPCE];
+}
+
+- (void)testEAN {
+ [self doTestResultWithContents:@"00393157" goldenResult:@"00393157" type:kParsedResultTypeProduct format:kBarcodeFormatEan8];
+ [self doTestResultWithContents:@"00393158" goldenResult:@"00393158" type:kParsedResultTypeText];
+ [self doTestResultWithContents:@"5051140178499" goldenResult:@"5051140178499" type:kParsedResultTypeProduct format:kBarcodeFormatEan13];
+ [self doTestResultWithContents:@"5051140178490" goldenResult:@"5051140178490" type:kParsedResultTypeText];
+}
+
+- (void)testISBN {
+ [self doTestResultWithContents:@"9784567890123" goldenResult:@"9784567890123" type:kParsedResultTypeISBN format:kBarcodeFormatEan13];
+ [self doTestResultWithContents:@"9794567890123" goldenResult:@"9794567890123" type:kParsedResultTypeISBN format:kBarcodeFormatEan13];
+ [self doTestResultWithContents:@"97845678901" goldenResult:@"97845678901" type:kParsedResultTypeText];
+ [self doTestResultWithContents:@"97945678901" goldenResult:@"97945678901" type:kParsedResultTypeText];
+}
+
+- (void)testURI {
+ [self doTestResultWithContents:@"http://google.com" goldenResult:@"http://google.com" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"google.com" goldenResult:@"http://google.com" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"https://google.com" goldenResult:@"https://google.com" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"HTTP://google.com" goldenResult:@"HTTP://google.com" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"http://google.com/foobar" goldenResult:@"http://google.com/foobar" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"https://google.com:443/foobar" goldenResult:@"https://google.com:443/foobar" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"google.com:443" goldenResult:@"http://google.com:443" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"google.com:443/" goldenResult:@"http://google.com:443/" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"google.com:443/foobar" goldenResult:@"http://google.com:443/foobar" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"http://google.com:443/foobar" goldenResult:@"http://google.com:443/foobar" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"https://google.com:443/foobar" goldenResult:@"https://google.com:443/foobar" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"ftp://google.com/fake" goldenResult:@"ftp://google.com/fake" type:kParsedResultTypeURI];
+ [self doTestResultWithContents:@"gopher://google.com/obsolete" goldenResult:@"gopher://google.com/obsolete" type:kParsedResultTypeURI];
+}
+
+- (void)testGeo {
+ [self doTestResultWithContents:@"geo:1,2" goldenResult:@"1.000000, 2.000000" type:kParsedResultTypeGeo];
+ [self doTestResultWithContents:@"geo:1,2,3" goldenResult:@"1.000000, 2.000000, 3.000000m" type:kParsedResultTypeGeo];
+ [self doTestResultWithContents:@"geo:80.33,-32.3344,3.35" goldenResult:@"80.330000, -32.334400, 3.350000m" type:kParsedResultTypeGeo];
+ [self doTestResultWithContents:@"geo" goldenResult:@"geo" type:kParsedResultTypeText];
+ [self doTestResultWithContents:@"geography" goldenResult:@"geography" type:kParsedResultTypeText];
+}
+
+- (void)testTel {
+ [self doTestResultWithContents:@"tel:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeTel];
+ [self doTestResultWithContents:@"TEL:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeTel];
+ [self doTestResultWithContents:@"tel:212 555 1212" goldenResult:@"212 555 1212" type:kParsedResultTypeTel];
+ [self doTestResultWithContents:@"tel:2125551212" goldenResult:@"2125551212" type:kParsedResultTypeTel];
+ [self doTestResultWithContents:@"tel:212-555-1212" goldenResult:@"212-555-1212" type:kParsedResultTypeTel];
+ [self doTestResultWithContents:@"tel" goldenResult:@"tel" type:kParsedResultTypeText];
+ [self doTestResultWithContents:@"telephone" goldenResult:@"telephone" type:kParsedResultTypeText];
+}
+
+- (void)testVCard {
+ [self doTestResultWithContents:@"BEGIN:VCARD\r\nEND:VCARD" goldenResult:@"" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"BEGIN:VCARD\r\nN:Owen;Sean\r\nEND:VCARD" goldenResult:@"Sean Owen"
+ type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"BEGIN:VCARD\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD" goldenResult:@"Sean Owen"
+ type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"BEGIN:VCARD\r\nADR;HOME:123 Main St\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD"
+ goldenResult:@"Sean Owen\n123 Main St" type:kParsedResultTypeAddressBook];
+ [self doTestResultWithContents:@"BEGIN:VCARD" goldenResult:@"" type:kParsedResultTypeAddressBook];
+}
+
+- (void)testVEvent {
+ // UTC times
+ [self doTestResultWithContents:@"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\n"
+ @"DTEND:20080505T234555Z\r\nEND:VEVENT\r\nEND:VCALENDAR"
+ goldenResult:@"foo\nMay 4, 2008 12:34:56 PM\nMay 5, 2008 11:45:55 PM"
+ type:kParsedResultTypeCalendar];
+ [self doTestResultWithContents:@"BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\n"
+ @"DTEND:20080505T234555Z\r\nEND:VEVENT"
+ goldenResult:@"foo\nMay 4, 2008 12:34:56 PM\nMay 5, 2008 11:45:55 PM"
+ type:kParsedResultTypeCalendar];
+ // Local times
+ [self doTestResultWithContents:@"BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456\r\n"
+ @"DTEND:20080505T234555\r\nEND:VEVENT"
+ goldenResult:@"foo\nMay 4, 2008 12:34:56 PM\nMay 5, 2008 11:45:55 PM"
+ type:kParsedResultTypeCalendar];
+ // Date only (all day event)
+ [self doTestResultWithContents:@"BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504\r\n"
+ @"DTEND:20080505\r\nEND:VEVENT"
+ goldenResult:@"foo\nMay 4, 2008\nMay 5, 2008"
+ type:kParsedResultTypeCalendar];
+ // Start time only
+ [self doTestResultWithContents:@"BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\nEND:VEVENT"
+ goldenResult:@"foo\nMay 4, 2008 12:34:56 PM" type:kParsedResultTypeCalendar];
+ [self doTestResultWithContents:@"BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456\r\nEND:VEVENT"
+ goldenResult:@"foo\nMay 4, 2008 12:34:56 PM" type:kParsedResultTypeCalendar];
+ [self doTestResultWithContents:@"BEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504\r\nEND:VEVENT"
+ goldenResult:@"foo\nMay 4, 2008" type:kParsedResultTypeCalendar];
+ [self doTestResultWithContents:@"BEGIN:VEVENT\r\nDTEND:20080505T\r\nEND:VEVENT"
+ goldenResult:@"BEGIN:VEVENT\r\nDTEND:20080505T\r\nEND:VEVENT" type:kParsedResultTypeURI];
+ // Yeah, it's OK that this is thought of as maybe a URI as long as it's not CALENDAR
+ // Make sure illegal entries without newlines don't crash
+ [self doTestResultWithContents:@"BEGIN:VEVENTSUMMARY:EventDTSTART:20081030T122030ZDTEND:20081030T132030ZEND:VEVENT"
+ goldenResult:@"BEGIN:VEVENTSUMMARY:EventDTSTART:20081030T122030ZDTEND:20081030T132030ZEND:VEVENT"
+ type:kParsedResultTypeURI];
+}
+
+- (void)testSMS {
+ [self doTestResultWithContents:@"sms:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"SMS:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"sms:+15551212;via=999333" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"sms:+15551212?subject=foo&body=bar" goldenResult:@"+15551212\nfoo\nbar" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"sms:+15551212,+12124440101" goldenResult:@"+15551212\n+12124440101" type:kParsedResultTypeSMS];
+}
+
+- (void)testSMSTO {
+ [self doTestResultWithContents:@"SMSTO:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"smsto:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"smsto:+15551212:subject" goldenResult:@"+15551212\nsubject" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"smsto:+15551212:My message" goldenResult:@"+15551212\nMy message" type:kParsedResultTypeSMS];
+ // Need to handle question mark in the subject
+ [self doTestResultWithContents:@"smsto:+15551212:What's up?" goldenResult:@"+15551212\nWhat's up?" type:kParsedResultTypeSMS];
+ // Need to handle colon in the subject
+ [self doTestResultWithContents:@"smsto:+15551212:Directions: Do this"
+ goldenResult:@"+15551212\nDirections: Do this" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"smsto:212-555-1212:Here's a longer message. Should be fine."
+ goldenResult:@"212-555-1212\nHere's a longer message. Should be fine." type:kParsedResultTypeSMS];
+}
+
+- (void)testMMS {
+ [self doTestResultWithContents:@"mms:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"MMS:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"mms:+15551212;via=999333" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"mms:+15551212?subject=foo&body=bar" goldenResult:@"+15551212\nfoo\nbar" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"mms:+15551212,+12124440101" goldenResult:@"+15551212\n+12124440101" type:kParsedResultTypeSMS];
+}
+
+- (void)testMMSTO {
+ [self doTestResultWithContents:@"MMSTO:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"mmsto:+15551212" goldenResult:@"+15551212" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"mmsto:+15551212:subject" goldenResult:@"+15551212\nsubject" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"mmsto:+15551212:My message" goldenResult:@"+15551212\nMy message" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"mmsto:+15551212:What's up?" goldenResult:@"+15551212\nWhat's up?" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"mmsto:+15551212:Directions: Do this"
+ goldenResult:@"+15551212\nDirections: Do this" type:kParsedResultTypeSMS];
+ [self doTestResultWithContents:@"mmsto:212-555-1212:Here's a longer message. Should be fine."
+ goldenResult:@"212-555-1212\nHere's a longer message. Should be fine." type:kParsedResultTypeSMS];
+}
+
+- (void)doTestResultWithContents:(NSString *)contents
+ goldenResult:(NSString *)goldenResult
+ type:(ZXParsedResultType)type {
+ [self doTestResultWithContents:contents goldenResult:goldenResult type:type format:kBarcodeFormatQRCode]; // QR code is arbitrary
+}
+
+- (void)doTestResultWithContents:(NSString *)contents
+ goldenResult:(NSString *)goldenResult
+ type:(ZXParsedResultType)type
+ format:(ZXBarcodeFormat)format {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:format];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertNotNil(result, @"Result is nil");
+ STAssertEquals(result.type, type, @"Types don't match");
+
+ NSString *displayResult = result.displayResult;
+ STAssertEqualObjects(displayResult, goldenResult, @"Display result doesn't match golden result");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXProductParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXProductParsedResultTestCase.h
new file mode 100644
index 0000000..3f81a10
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXProductParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXProductParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXProductParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXProductParsedResultTestCase.m
new file mode 100644
index 0000000..a6643d3
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXProductParsedResultTestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "ZXProductParsedResultTestCase.h"
+
+@implementation ZXProductParsedResultTestCase
+
+- (void)testProduct {
+ [self doTestWithContents:@"123456789012" normalized:@"123456789012" format:kBarcodeFormatUPCA];
+ [self doTestWithContents:@"00393157" normalized:@"00393157" format:kBarcodeFormatEan8];
+ [self doTestWithContents:@"5051140178499" normalized:@"5051140178499" format:kBarcodeFormatEan13];
+ [self doTestWithContents:@"01234565" normalized:@"012345000065" format:kBarcodeFormatUPCE];
+}
+
+- (void)doTestWithContents:(NSString *)contents
+ normalized:(NSString *)normalized
+ format:(ZXBarcodeFormat)format {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:format];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(result.type, kParsedResultTypeProduct, @"Types don't match");
+ ZXProductParsedResult *productResult = (ZXProductParsedResult *)result;
+ STAssertEqualObjects(productResult.productID, contents, @"Contents don't match");
+ STAssertEqualObjects(productResult.normalizedProductID, normalized, @"Normalized doesn't match");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXSMSMMSParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXSMSMMSParsedResultTestCase.h
new file mode 100644
index 0000000..9c58781
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXSMSMMSParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXSMSMMSParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXSMSMMSParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXSMSMMSParsedResultTestCase.m
new file mode 100644
index 0000000..fba6fe8
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXSMSMMSParsedResultTestCase.m
@@ -0,0 +1,60 @@
+/*
+ * 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 "ZXSMSMMSParsedResultTestCase.h"
+
+@implementation ZXSMSMMSParsedResultTestCase
+
+- (void)testSMS {
+ [self doTestWithContents:@"sms:+15551212" number:@"+15551212" subject:nil body:nil via:nil];
+ [self doTestWithContents:@"sms:+15551212?subject=foo&body=bar" number:@"+15551212" subject:@"foo" body:@"bar" via:nil];
+ [self doTestWithContents:@"sms:+15551212;via=999333" number:@"+15551212" subject:nil body:nil via:@"999333"];
+}
+
+- (void)testMMS {
+ [self doTestWithContents:@"mms:+15551212" number:@"+15551212" subject:nil body:nil via:nil];
+ [self doTestWithContents:@"mms:+15551212?subject=foo&body=bar" number:@"+15551212" subject:@"foo" body:@"bar" via:nil];
+ [self doTestWithContents:@"mms:+15551212;via=999333" number:@"+15551212" subject:nil body:nil via:@"999333"];
+}
+
+- (void)doTestWithContents:(NSString *)contents
+ number:(NSString *)number
+ subject:(NSString *)subject
+ body:(NSString *)body
+ via:(NSString *)via {
+ [self doTestWithContents:contents
+ numbers:@[number ? number : [NSNull null]]
+ subject:subject
+ body:body
+ vias:@[via ? via : [NSNull null]]];
+}
+
+- (void)doTestWithContents:(NSString *)contents
+ numbers:(NSArray *)numbers
+ subject:(NSString *)subject
+ body:(NSString *)body
+ vias:(NSArray *)vias {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatQRCode];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(result.type, kParsedResultTypeSMS, @"Types don't match");
+ ZXSMSParsedResult *smsResult = (ZXSMSParsedResult *)result;
+ STAssertEqualObjects(smsResult.numbers, numbers, @"Numbers don't match");
+ STAssertEqualObjects(smsResult.subject, subject, @"Subjects don't match");
+ STAssertEqualObjects(smsResult.body, body, @"Bodies don't match");
+ STAssertEqualObjects(smsResult.vias, vias, @"Vias don't match");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXTelParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXTelParsedResultTestCase.h
new file mode 100644
index 0000000..7584731
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXTelParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXTelParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXTelParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXTelParsedResultTestCase.m
new file mode 100644
index 0000000..c84b12d
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXTelParsedResultTestCase.m
@@ -0,0 +1,36 @@
+/*
+ * 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 "ZXTelParsedResultTestCase.h"
+
+@implementation ZXTelParsedResultTestCase
+
+- (void)testTel {
+ [self doTestWithContents:@"tel:+15551212" number:@"+15551212" title:nil];
+ [self doTestWithContents:@"tel:2125551212" number:@"2125551212" title:nil];
+}
+
+- (void)doTestWithContents:(NSString *)contents number:(NSString *)number title:(NSString *)title {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatQRCode];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(result.type, kParsedResultTypeTel, @"Types don't match");
+ ZXTelParsedResult *telResult = (ZXTelParsedResult *)result;
+ STAssertEqualObjects(telResult.number, number, @"Numbers don't match");
+ STAssertEqualObjects(telResult.title, title, @"Titles don't match");
+ STAssertEqualObjects(telResult.telURI, [@"tel:" stringByAppendingString:number], @"Tel URIs don't match");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXURIParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXURIParsedResultTestCase.h
new file mode 100644
index 0000000..f22853b
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXURIParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXURIParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXURIParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXURIParsedResultTestCase.m
new file mode 100644
index 0000000..dc1a725
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXURIParsedResultTestCase.m
@@ -0,0 +1,116 @@
+/*
+ * 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 "ZXURIParsedResultTestCase.h"
+
+@implementation ZXURIParsedResultTestCase
+
+- (void)testBookmarkDocomo {
+ [self doTestWithContents:@"MEBKM:URL:google.com;;" uri:@"http://google.com" title:nil];
+ [self doTestWithContents:@"MEBKM:URL:http://google.com;;" uri:@"http://google.com" title:nil];
+ [self doTestWithContents:@"MEBKM:URL:google.com;TITLE:Google;" uri:@"http://google.com" title:@"Google"];
+}
+
+- (void)testURI {
+ [self doTestWithContents:@"google.com" uri:@"http://google.com" title:nil];
+ [self doTestWithContents:@"http://google.com" uri:@"http://google.com" title:nil];
+ [self doTestWithContents:@"https://google.com" uri:@"https://google.com" title:nil];
+ [self doTestWithContents:@"google.com:443" uri:@"http://google.com:443" title:nil];
+ [self doTestWithContents:@"https://www.google.com/calendar/hosted/google.com/embed?mode=AGENDA&force_login=true&src=google.com_726f6f6d5f6265707075@resource.calendar.google.com"
+ uri:@"https://www.google.com/calendar/hosted/google.com/embed?mode=AGENDA&force_login=true&src=google.com_726f6f6d5f6265707075@resource.calendar.google.com"
+ title:nil];
+ [self doTestWithContents:@"otpauth://remoteaccess?devaddr=00%a1b2%c3d4&devname=foo&key=bar"
+ uri:@"otpauth://remoteaccess?devaddr=00%a1b2%c3d4&devname=foo&key=bar"
+ title:nil];
+ [self doTestWithContents:@"s3://amazon.com:8123" uri:@"s3://amazon.com:8123" title:nil];
+ [self doTestWithContents:@"HTTP://R.BEETAGG.COM/?12345" uri:@"HTTP://R.BEETAGG.COM/?12345" title:nil];
+}
+
+- (void)testNotURI {
+ [self doTestNotUri:@"google.c"];
+ [self doTestNotUri:@".com"];
+ [self doTestNotUri:@":80/"];
+ [self doTestNotUri:@"ABC,20.3,AB,AD"];
+ [self doTestNotUri:@"http://google.com?q=foo bar"];
+}
+
+- (void)testURLTO {
+ [self doTestWithContents:@"urlto::bar.com" uri:@"http://bar.com" title:nil];
+ [self doTestWithContents:@"urlto::http://bar.com" uri:@"http://bar.com" title:nil];
+ [self doTestWithContents:@"urlto:foo:bar.com" uri:@"http://bar.com" title:@"foo"];
+}
+
+- (void)testGarbage {
+ [self doTestNotUri:@"Da65cV1g^>%^f0bAbPn1CJB6lV7ZY8hs0Sm:DXU0cd]GyEeWBz8]bUHLB"];
+ [self doTestNotUri:[NSString stringWithFormat:@"DEA%C%CM%C%C\bå%C‡HO%CX$%C%C%Cwfc%C!þ“˜%C%C¾Z{ùÎÝڗZ§¨+y_zbñk%C¸%C†Ü%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C%C£.ux",
+ (unichar)0x0003, (unichar)0x0019, (unichar)0x0006, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0001,
+ (unichar)0x0000, (unichar)0x001F, (unichar)0x0007, (unichar)0x0013, (unichar)0x0013, (unichar)0x00117, (unichar)0x000E,
+ (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000,
+ (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000,
+ (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000,
+ (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000, (unichar)0x0000]];
+}
+
+- (void)testIsPossiblyMalicious {
+ [self doTestIsPossiblyMalicious:@"http://google.com" expected:NO];
+ [self doTestIsPossiblyMalicious:@"http://google.com@evil.com" expected:YES];
+ [self doTestIsPossiblyMalicious:@"http://google.com:@evil.com" expected:YES];
+ [self doTestIsPossiblyMalicious:@"google.com:@evil.com" expected:NO];
+ [self doTestIsPossiblyMalicious:@"https://google.com:443" expected:NO];
+ [self doTestIsPossiblyMalicious:@"https://google.com:443/" expected:NO];
+ [self doTestIsPossiblyMalicious:@"https://evil@google.com:443" expected:YES];
+ [self doTestIsPossiblyMalicious:@"http://google.com/foo@bar" expected:NO];
+ [self doTestIsPossiblyMalicious:@"http://google.com/@@" expected:NO];
+}
+
+- (void)testExotic {
+ [self doTestWithContents:@"bitcoin:mySD89iqpmptrK3PhHFW9fa7BXiP7ANy3Y"
+ uri:@"bitcoin:mySD89iqpmptrK3PhHFW9fa7BXiP7ANy3Y"
+ title:nil];
+ [self doTestWithContents:@"BTCTX:-TC4TO3$ZYZTC5NC83/SYOV+YGUGK:$BSF0P8/STNTKTKS.V84+JSA$LB+EHCG+8A725.2AZ-NAVX3VBV5K4MH7UL2.2M:"
+ "F*M9HSL*$2P7T*FX.ZT80GWDRV0QZBPQ+O37WDCNZBRM3EQ0S9SZP+3BPYZG02U/LA*89C2U.V1TS.CT1VF3DIN*HN3W-O-"
+ "0ZAKOAB32/.8:J501GJJTTWOA+5/6$MIYBERPZ41NJ6-WSG/*Z48ZH*LSAOEM*IXP81L:$F*W08Z60CR*C*P.JEEVI1F02J07L6+"
+ "W4L1G$/IC*$16GK6A+:I1-:LJ:Z-P3NW6Z6ADFB-F2AKE$2DWN23GYCYEWX9S8L+LF$VXEKH7/R48E32PU+A:9H:8O5"
+ uri:@"BTCTX:-TC4TO3$ZYZTC5NC83/SYOV+YGUGK:$BSF0P8/STNTKTKS.V84+JSA$LB+EHCG+8A725.2AZ-NAVX3VBV5K4MH7UL2.2M:"
+ "F*M9HSL*$2P7T*FX.ZT80GWDRV0QZBPQ+O37WDCNZBRM3EQ0S9SZP+3BPYZG02U/LA*89C2U.V1TS.CT1VF3DIN*HN3W-O-"
+ "0ZAKOAB32/.8:J501GJJTTWOA+5/6$MIYBERPZ41NJ6-WSG/*Z48ZH*LSAOEM*IXP81L:$F*W08Z60CR*C*P.JEEVI1F02J07L6+"
+ "W4L1G$/IC*$16GK6A+:I1-:LJ:Z-P3NW6Z6ADFB-F2AKE$2DWN23GYCYEWX9S8L+LF$VXEKH7/R48E32PU+A:9H:8O5"
+ title:nil];
+}
+
+- (void)doTestWithContents:(NSString *)contents uri:(NSString *)uri title:(NSString *)title {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatQRCode];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(result.type, kParsedResultTypeURI, @"Types don't match");
+ ZXURIParsedResult *uriResult = (ZXURIParsedResult *)result;
+ STAssertEqualObjects(uriResult.uri, uri, @"URIs don't match");
+ STAssertEqualObjects(uriResult.title, title, @"Titles don't match");
+}
+
+- (void)doTestNotUri:(NSString *)text {
+ ZXResult *fakeResult = [ZXResult resultWithText:text rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatQRCode];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+ STAssertEquals(result.type, kParsedResultTypeText, @"Types don't match");
+ STAssertEqualObjects(result.displayResult, text, @"Display result doesn't match");
+}
+
+- (void)doTestIsPossiblyMalicious:(NSString *)uri expected:(BOOL)expected {
+ ZXURIParsedResult *result = [ZXURIParsedResult uriParsedResultWithUri:uri title:nil];
+ STAssertEquals([result possiblyMaliciousURI], expected,
+ expected ? @"Expected to be possibly malicious URI but wasn't" : @"Not expected to be possibly malicious URI but was");
+}
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXWifiParsedResultTestCase.h b/ZXingObjCTests/client/result/ZXWifiParsedResultTestCase.h
new file mode 100644
index 0000000..658e715
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXWifiParsedResultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXWifiParsedResultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/client/result/ZXWifiParsedResultTestCase.m b/ZXingObjCTests/client/result/ZXWifiParsedResultTestCase.m
new file mode 100644
index 0000000..dae5ceb
--- /dev/null
+++ b/ZXingObjCTests/client/result/ZXWifiParsedResultTestCase.m
@@ -0,0 +1,70 @@
+/*
+ * 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 "ZXWifiParsedResultTestCase.h"
+
+@implementation ZXWifiParsedResultTestCase
+
+- (void)testNoPassword {
+ [self doTestWithContents:@"WIFI:S:NoPassword;P:;T:;;" ssid:@"NoPassword" password:nil type:@"nopass"];
+ [self doTestWithContents:@"WIFI:S:No Password;P:;T:;;" ssid:@"No Password" password:nil type:@"nopass"];
+}
+
+- (void)testWep {
+ [self doTestWithContents:@"WIFI:S:TenChars;P:0123456789;T:WEP;;" ssid:@"TenChars" password:@"0123456789" type:@"WEP"];
+ [self doTestWithContents:@"WIFI:S:TenChars;P:abcde56789;T:WEP;;" ssid:@"TenChars" password:@"abcde56789" type:@"WEP"];
+ // Non hex should not fail at this level
+ [self doTestWithContents:@"WIFI:S:TenChars;P:hellothere;T:WEP;;" ssid:@"TenChars" password:@"hellothere" type:@"WEP"];
+
+ // Escaped semicolons
+ [self doTestWithContents:@"WIFI:S:Ten\\;\\;Chars;P:0123456789;T:WEP;;" ssid:@"Ten;;Chars" password:@"0123456789" type:@"WEP"];
+ // Escaped colons
+ [self doTestWithContents:@"WIFI:S:Ten\\:\\:Chars;P:0123456789;T:WEP;;" ssid:@"Ten::Chars" password:@"0123456789" type:@"WEP"];
+
+ // TODO Need a test for SB as well.
+}
+
+/**
+ * Put in checks for the length of the password for wep.
+ */
+- (void)testWpa {
+ [self doTestWithContents:@"WIFI:S:TenChars;P:wow;T:WPA;;" ssid:@"TenChars" password:@"wow" type:@"WPA"];
+ [self doTestWithContents:@"WIFI:S:TenChars;P:space is silent;T:WPA;;" ssid:@"TenChars" password:@"space is silent" type:@"WPA"];
+ [self doTestWithContents:@"WIFI:S:TenChars;P:hellothere;T:WEP;;" ssid:@"TenChars" password:@"hellothere" type:@"WEP"];
+
+ // Escaped semicolons
+ [self doTestWithContents:@"WIFI:S:TenChars;P:hello\\;there;T:WEP;;" ssid:@"TenChars" password:@"hello;there" type:@"WEP"];
+ // Escaped colons
+ [self doTestWithContents:@"WIFI:S:TenChars;P:hello\\:there;T:WEP;;" ssid:@"TenChars" password:@"hello:there" type:@"WEP"];
+}
+
+/**
+ * Given the string contents for the barcode, check that it matches our expectations
+ */
+- (void)doTestWithContents:(NSString *)contents ssid:(NSString *)ssid password:(NSString *)password type:(NSString *)type {
+ ZXResult *fakeResult = [ZXResult resultWithText:contents rawBytes:NULL length:0 resultPoints:nil format:kBarcodeFormatQRCode];
+ ZXParsedResult *result = [ZXResultParser parseResult:fakeResult];
+
+ // Ensure it is a wifi code
+ STAssertEquals(result.type, kParsedResultTypeWifi, @"Types don't match");
+ ZXWifiParsedResult *wifiResult = (ZXWifiParsedResult *)result;
+
+ STAssertEqualObjects(wifiResult.ssid, ssid, @"Ssid's don't match");
+ STAssertEqualObjects(wifiResult.password, password, @"Passwords don't match");
+ STAssertEqualObjects(wifiResult.networkEncryption, type, @"Network encryption doesn't match");
+}
+
+@end
diff --git a/ZXingObjCTests/common/AbstractBlackBoxTestCase.h b/ZXingObjCTests/common/AbstractBlackBoxTestCase.h
new file mode 100644
index 0000000..4632aa1
--- /dev/null
+++ b/ZXingObjCTests/common/AbstractBlackBoxTestCase.h
@@ -0,0 +1,36 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+@interface AbstractBlackBoxTestCase : SenTestCase
+
+@property (nonatomic, strong, readonly) id<ZXReader> barcodeReader;
+@property (nonatomic, assign) ZXBarcodeFormat expectedFormat;
+@property (nonatomic, copy) NSString *testBase;
+@property (nonatomic, strong) NSMutableArray *testResults;
+
+- (id)initWithInvocation:(NSInvocation *)invocation testBasePathSuffix:(NSString *)testBasePathSuffix barcodeReader:(id<ZXReader>)barcodeReader expectedFormat:(ZXBarcodeFormat)expectedFormat;
++ (NSString *)barcodeFormatAsString:(ZXBarcodeFormat)format;
+- (void)addTest:(int)mustPassCount tryHarderCount:(int)tryHarderCount rotation:(float)rotation;
+- (void)addTest:(int)mustPassCount tryHarderCount:(int)tryHarderCount maxMisreads:(int)maxMisreads maxTryHarderMisreads:(int)maxTryHarderMisreads rotation:(float)rotation;
+- (void)runTests;
+
+- (NSArray *)imageFiles;
+- (NSString *)readFileAsString:(NSString *)file encoding:(NSStringEncoding)encoding;
+- (ZXImage *)rotateImage:(ZXImage *)original degrees:(float)degrees;
+
+@end
diff --git a/ZXingObjCTests/common/AbstractBlackBoxTestCase.m b/ZXingObjCTests/common/AbstractBlackBoxTestCase.m
new file mode 100644
index 0000000..a4cb896
--- /dev/null
+++ b/ZXingObjCTests/common/AbstractBlackBoxTestCase.m
@@ -0,0 +1,344 @@
+/*
+ * 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 "AbstractBlackBoxTestCase.h"
+#import "TestResult.h"
+
+@implementation AbstractBlackBoxTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation testBasePathSuffix:(NSString *)testBasePathSuffix barcodeReader:(id<ZXReader>)barcodeReader expectedFormat:(ZXBarcodeFormat)expectedFormat {
+ if (self = [super initWithInvocation:invocation]) {
+ _testBase = testBasePathSuffix;
+ _barcodeReader = barcodeReader;
+ _expectedFormat = expectedFormat;
+ _testResults = [NSMutableArray array];
+ }
+
+ return self;
+}
+
+- (void)addTest:(int)mustPassCount tryHarderCount:(int)tryHarderCount rotation:(float)rotation {
+ [self addTest:mustPassCount tryHarderCount:tryHarderCount maxMisreads:0 maxTryHarderMisreads:0 rotation:rotation];
+}
+
+/**
+ * Adds a new test for the current directory of images.
+ */
+- (void)addTest:(int)mustPassCount tryHarderCount:(int)tryHarderCount maxMisreads:(int)maxMisreads maxTryHarderMisreads:(int)maxTryHarderMisreads rotation:(float)rotation {
+ [self.testResults addObject:[[TestResult alloc] initWithMustPassCount:mustPassCount tryHarderCount:tryHarderCount maxMisreads:maxMisreads maxTryHarderMisreads:maxTryHarderMisreads rotation:rotation]];
+}
+
+- (NSArray *)imageFiles {
+ NSMutableArray *imageFiles = [NSMutableArray array];
+ for (NSString *file in [[NSBundle bundleForClass:[self class]] pathsForResourcesOfType:nil inDirectory:self.testBase]) {
+ if ([[[file pathExtension] lowercaseString] isEqualToString:@"jpg"] ||
+ [[[file pathExtension] lowercaseString] isEqualToString:@"jpeg"] ||
+ [[[file pathExtension] lowercaseString] isEqualToString:@"gif"] ||
+ [[[file pathExtension] lowercaseString] isEqualToString:@"png"]) {
+ [imageFiles addObject:[NSURL fileURLWithPath:file]];
+ }
+ }
+
+ return imageFiles;
+}
+
+- (void)runTests {
+ [self testBlackBoxCountingResults:YES];
+}
+
++ (NSString *)barcodeFormatAsString:(ZXBarcodeFormat)format {
+ switch (format) {
+ case kBarcodeFormatAztec:
+ return @"Aztec";
+ break;
+ case kBarcodeFormatCodabar:
+ return @"CODABAR";
+ break;
+ case kBarcodeFormatCode39:
+ return @"Code 39";
+ break;
+ case kBarcodeFormatCode93:
+ return @"Code 93";
+ break;
+ case kBarcodeFormatCode128:
+ return @"Code 128";
+ break;
+ case kBarcodeFormatDataMatrix:
+ return @"Data Matrix";
+ break;
+ case kBarcodeFormatEan8:
+ return @"EAN-8";
+ break;
+ case kBarcodeFormatEan13:
+ return @"EAN-13";
+ break;
+ case kBarcodeFormatITF:
+ return @"ITF";
+ break;
+ case kBarcodeFormatMaxiCode:
+ return @"MaxiCode";
+ break;
+ case kBarcodeFormatPDF417:
+ return @"PDF417";
+ break;
+ case kBarcodeFormatQRCode:
+ return @"QR Code";
+ break;
+ case kBarcodeFormatRSS14:
+ return @"RSS 14";
+ break;
+ case kBarcodeFormatRSSExpanded:
+ return @"RSS EXPANDED";
+ break;
+ case kBarcodeFormatUPCA:
+ return @"UPC-A";
+ break;
+ case kBarcodeFormatUPCE:
+ return @"UPC-E";
+ break;
+ case kBarcodeFormatUPCEANExtension:
+ return @"UPC/EAN extension";
+ break;
+ }
+
+ return nil;
+}
+
+- (NSString *)pathInBundle:(NSURL *)file {
+ NSInteger startOfResources = [[file path] rangeOfString:@"Resources"].location;
+ if (startOfResources == NSNotFound) {
+ return [file path];
+ } else {
+ return [[file path] substringFromIndex:startOfResources];
+ }
+}
+
+- (void)testBlackBoxCountingResults:(BOOL)assertOnFailure {
+ if (self.testResults.count == 0) {
+ STFail(@"No test results");
+ }
+
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ NSArray *imageFiles = [self imageFiles];
+ int testCount = (int)[self.testResults count];
+
+ int passedCounts[testCount];
+ memset(passedCounts, 0, testCount * sizeof(int));
+
+ int misreadCounts[testCount];
+ memset(misreadCounts, 0, testCount * sizeof(int));
+
+ int tryHarderCounts[testCount];
+ memset(tryHarderCounts, 0, testCount * sizeof(int));
+
+ int tryHarderMisreadCounts[testCount];
+ memset(tryHarderMisreadCounts, 0, testCount * sizeof(int));
+
+ 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];
+ } else {
+ NSString *expectedTextFile = [[NSBundle bundleForClass:[self class]] pathForResource:fileBaseName ofType:@"bin" inDirectory:self.testBase];
+ STAssertNotNil(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 = [(TestResult *)self.testResults[x] rotation];
+ ZXImage *rotatedImage = [self rotateImage:image degrees:rotation];
+ ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage.cgimage];
+ 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]) {
+ passedCounts[x]++;
+ } else if(misread) {
+ misreadCounts[x]++;
+ } else {
+ NSLog(@"could not read at rotation %f", rotation);
+ }
+
+ if ([self decode:bitmap rotation:rotation expectedText:expectedText expectedMetadata:expectedMetadata tryHarder:YES misread:&misread]) {
+ tryHarderCounts[x]++;
+ } else if(misread) {
+ tryHarderMisreadCounts[x]++;
+ } else {
+ NSLog(@"could not read at rotation %f w/TH", rotation);
+ }
+ }
+ }
+
+ // 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++) {
+ TestResult *testResult = self.testResults[x];
+ NSLog(@"Rotation %d degrees:", (int) testResult.rotation);
+ NSLog(@" %d of %d images passed (%d required)",
+ passedCounts[x], (int)imageFiles.count, testResult.mustPassCount);
+ int failed = (int)imageFiles.count - passedCounts[x];
+ NSLog(@" %d failed due to misreads, %d not detected",
+ misreadCounts[x], failed - misreadCounts[x]);
+ NSLog(@" %d of %d images passed with try harder (%d required)",
+ tryHarderCounts[x], (int)imageFiles.count, testResult.tryHarderCount);
+ failed = (int)imageFiles.count - tryHarderCounts[x];
+ NSLog(@" %d failed due to misreads, %d not detected",
+ tryHarderMisreadCounts[x], failed - tryHarderMisreadCounts[x]);
+ totalFound += passedCounts[x] + tryHarderCounts[x];
+ totalMustPass += testResult.mustPassCount + testResult.tryHarderCount;
+ totalMisread += misreadCounts[x] + tryHarderMisreadCounts[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(@" --- 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++) {
+ TestResult *testResult = self.testResults[x];
+ NSString *label = [NSString stringWithFormat:@"Rotation %f degrees: Too many images failed", testResult.rotation];
+ STAssertTrue(passedCounts[x] >= testResult.mustPassCount, label);
+ STAssertTrue(tryHarderCounts[x] >= testResult.tryHarderCount, @"Try harder, %@", label);
+ label = [NSString stringWithFormat:@"Rotation %f degrees: Too many images misread", testResult.rotation];
+ STAssertTrue(misreadCounts[x] <= testResult.maxMisreads, label);
+ STAssertTrue(tryHarderMisreadCounts[x] <= testResult.maxTryHarderMisreads, @"Try harder, %@", label);
+ }
+ }
+}
+
+- (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;
+
+ ZXDecodeHints *hints = [ZXDecodeHints hints];
+ if (tryHarder) {
+ hints.tryHarder = YES;
+ }
+
+ 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];
+ id expectedValue = expectedMetadata[keyObj];
+ id actualValue = resultMetadata[keyObj];
+ if (![expectedValue isEqual:actualValue]) {
+ NSLog(@"Metadata mismatch: for key '%d' expected '%@' but got '%@'", key, expectedValue, actualValue);
+ *misread = YES;
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+- (NSString *)readFileAsString:(NSString *)file encoding:(NSStringEncoding)encoding {
+ 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);
+ }
+ return stringContents;
+}
+
+// Adapted from http://blog.coriolis.ch/2009/09/04/arbitrary-rotation-of-a-cgimage/ and https://github.com/JanX2/CreateRotateWriteCGImage
+- (ZXImage *)rotateImage:(ZXImage *)original degrees:(float)degrees {
+ if (degrees == 0.0f) {
+ 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,
+ rotatedRect.size.height,
+ CGImageGetBitsPerComponent(original.cgimage),
+ 0,
+ colorSpace,
+ kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedFirst);
+ 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];
+}
+
+@end
diff --git a/ZXingObjCTests/common/AbstractNegativeBlackBoxTestCase.h b/ZXingObjCTests/common/AbstractNegativeBlackBoxTestCase.h
new file mode 100644
index 0000000..7b4fbc5
--- /dev/null
+++ b/ZXingObjCTests/common/AbstractNegativeBlackBoxTestCase.h
@@ -0,0 +1,29 @@
+/*
+ * 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 "AbstractBlackBoxTestCase.h"
+
+/**
+ * This abstract class looks for negative results, i.e. it only allows a certain number of false
+ * positives in images which should not decode. This helps ensure that we are not too lenient.
+ */
+@interface AbstractNegativeBlackBoxTestCase : AbstractBlackBoxTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation testBasePathSuffix:(NSString *)testBasePathSuffix;
+- (void)addTest:(int)falsePositivesAllowed rotation:(float)rotation;
+- (void)runTests;
+
+@end
diff --git a/ZXingObjCTests/common/AbstractNegativeBlackBoxTestCase.m b/ZXingObjCTests/common/AbstractNegativeBlackBoxTestCase.m
new file mode 100644
index 0000000..35b2dc8
--- /dev/null
+++ b/ZXingObjCTests/common/AbstractNegativeBlackBoxTestCase.m
@@ -0,0 +1,137 @@
+/*
+ * 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 "AbstractNegativeBlackBoxTestCase.h"
+
+@interface NegativeTestResult : NSObject
+
+@property (nonatomic, assign) int falsePositivesAllowed;
+@property (nonatomic, assign) float rotation;
+
+@end
+
+@implementation NegativeTestResult
+
+- (id)initWithFalsePositivesAllowed:(int)falsePositivesAllowed rotation:(float)rotation {
+ if (self = [super init]) {
+ _falsePositivesAllowed = falsePositivesAllowed;
+ _rotation = rotation;
+ }
+
+ return self;
+}
+
+@end
+
+@implementation AbstractNegativeBlackBoxTestCase
+
+// Use the multiformat reader to evaluate all decoders in the system.
+- (id)initWithInvocation:(NSInvocation *)invocation testBasePathSuffix:(NSString *)testBasePathSuffix {
+ if (self = [super initWithInvocation:invocation testBasePathSuffix:testBasePathSuffix barcodeReader:[[ZXMultiFormatReader alloc] init] expectedFormat:0]) {
+ self.testResults = [NSMutableArray array];
+ }
+
+ return self;
+}
+
+- (void)addTest:(int)falsePositivesAllowed rotation:(float)rotation {
+ [self.testResults addObject:[[NegativeTestResult alloc] initWithFalsePositivesAllowed:falsePositivesAllowed rotation:rotation]];
+}
+
+- (NSString *)pathInBundle:(NSURL *)file {
+ NSInteger startOfResources = [[file path] rangeOfString:@"Resources"].location;
+ if (startOfResources == NSNotFound) {
+ return [file path];
+ } else {
+ return [[file path] substringFromIndex:startOfResources];
+ }
+}
+
+- (void)runTests {
+ if (self.testResults.count == 0) {
+ STFail(@"No test results");
+ }
+
+ NSArray *imageFiles = [self imageFiles];
+
+ int falsePositives[self.testResults.count];
+ memset(falsePositives, 0, self.testResults.count * sizeof(int));
+
+ for (NSURL *testImage in imageFiles) {
+ NSLog(@"Starting %@", [self pathInBundle:testImage]);
+
+ ZXImage *image = [[ZXImage alloc] initWithURL:testImage];
+ for (int x = 0; x < self.testResults.count; x++) {
+ NegativeTestResult *testResult = self.testResults[x];
+ if (![self checkForFalsePositives:image rotationInDegrees:testResult.rotation]) {
+ falsePositives[x]++;
+ }
+ }
+ }
+
+ int totalFalsePositives = 0;
+ int totalAllowed = 0;
+
+ for (int x = 0; x < self.testResults.count; x++) {
+ NegativeTestResult *testResult = self.testResults[x];
+ totalFalsePositives += falsePositives[x];
+ totalAllowed += testResult.falsePositivesAllowed;
+ }
+
+ if (totalFalsePositives < totalAllowed) {
+ NSLog(@" +++ Test too lax by %d images", totalAllowed - totalFalsePositives);
+ } else if (totalFalsePositives > totalAllowed) {
+ NSLog(@" --- Test failed by %d images", totalFalsePositives - totalAllowed);
+ }
+
+ for (int x = 0; x < self.testResults.count; x++) {
+ NegativeTestResult *testResult = self.testResults[x];
+ NSLog(@"Rotation %d degrees: %d of %d images were false positives (%d allowed)",
+ (int)testResult.rotation, falsePositives[x], (int)imageFiles.count,
+ testResult.falsePositivesAllowed);
+ STAssertTrue(falsePositives[x] <= testResult.falsePositivesAllowed,
+ @"Rotation %f degrees: Too many false positives found", testResult.rotation);
+ }
+}
+
+/**
+ * Make sure ZXing does NOT find a barcode in the image.
+ */
+- (BOOL)checkForFalsePositives:(ZXImage *)image rotationInDegrees:(CGFloat)rotationInDegrees {
+ ZXImage *rotatedImage = [self rotateImage:image degrees:rotationInDegrees];
+ ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage.cgimage];
+ ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXHybridBinarizer alloc] initWithSource:source]];
+ NSError *error = nil;
+ ZXResult *result = [self.barcodeReader decode:bitmap error:&error];
+ if (result) {
+ NSLog(@"Found false positive: '%@' with format '%@' (rotation: %d)",
+ result.text, [AbstractBlackBoxTestCase barcodeFormatAsString:result.barcodeFormat], (int) rotationInDegrees);
+ return NO;
+ }
+
+ // Try "try harder" getMode
+ ZXDecodeHints *hints = [ZXDecodeHints hints];
+ hints.tryHarder = YES;
+ result = [self.barcodeReader decode:bitmap hints:hints error:&error];
+ if (result) {
+ NSLog(@"Try harder found false positive: '%@' with format '%@' (rotation: %d)",
+ result.text, [AbstractBlackBoxTestCase barcodeFormatAsString:result.barcodeFormat], (int) rotationInDegrees);
+ return NO;
+ }
+ return YES;
+}
+
+@end
diff --git a/ZXingObjCTests/common/TestResult.h b/ZXingObjCTests/common/TestResult.h
new file mode 100644
index 0000000..8c13e7c
--- /dev/null
+++ b/ZXingObjCTests/common/TestResult.h
@@ -0,0 +1,29 @@
+/*
+ * 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 TestResult : NSObject
+
+@property (nonatomic, readonly) int mustPassCount;
+@property (nonatomic, readonly) int tryHarderCount;
+@property (nonatomic, readonly) int maxMisreads;
+@property (nonatomic, readonly) int maxTryHarderMisreads;
+@property (nonatomic, readonly) float rotation;
+
+- (id)initWithMustPassCount:(int)mustPassCount tryHarderCount:(int)tryHarderCount maxMisreads:(int)maxMisreads
+ maxTryHarderMisreads:(int)maxTryHarderMisreads rotation:(float)rotation;
+
+@end
+
diff --git a/ZXingObjCTests/common/TestResult.m b/ZXingObjCTests/common/TestResult.m
new file mode 100644
index 0000000..4dad006
--- /dev/null
+++ b/ZXingObjCTests/common/TestResult.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 "TestResult.h"
+
+@implementation TestResult
+
+- (id)initWithMustPassCount:(int)mustPassCount tryHarderCount:(int)tryHarderCount maxMisreads:(int)maxMisreads
+ maxTryHarderMisreads:(int)maxTryHarderMisreads rotation:(float)rotation {
+ if (self = [super init]) {
+ _mustPassCount = mustPassCount;
+ _tryHarderCount = tryHarderCount;
+ _maxMisreads = maxMisreads;
+ _maxTryHarderMisreads = maxTryHarderMisreads;
+ _rotation = rotation;
+ }
+
+ return self;
+}
+
+@end
diff --git a/ZXingObjCTests/common/ZXBitArrayTestCase.h b/ZXingObjCTests/common/ZXBitArrayTestCase.h
new file mode 100644
index 0000000..0faded2
--- /dev/null
+++ b/ZXingObjCTests/common/ZXBitArrayTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXBitArrayTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/common/ZXBitArrayTestCase.m b/ZXingObjCTests/common/ZXBitArrayTestCase.m
new file mode 100644
index 0000000..630eafd
--- /dev/null
+++ b/ZXingObjCTests/common/ZXBitArrayTestCase.m
@@ -0,0 +1,164 @@
+/*
+ * 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 "ZXBitArrayTestCase.h"
+
+@implementation ZXBitArrayTestCase
+
+- (void)testGetSet {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:33];
+ for (int i = 0; i < 33; i++) {
+ STAssertFalse([array get:i], @"Expected [array get:%d] to be false", i);
+ [array set:i];
+ STAssertTrue([array get:i], @"Expected [array get:%d] to be true");
+ }
+}
+
+- (void)testGetNextSet1 {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:32];
+ for (int i = 0; i < array.size; i++) {
+ STAssertEquals([array nextSet:i], 32, @"Expected [array nextSet:%d] to equal 32", i);
+ }
+ array = [[ZXBitArray alloc] initWithSize:33];
+ for (int i = 0; i < array.size; i++) {
+ STAssertEquals([array nextSet:i], 33, @"Expected [array nextSet:%d] to equal 33", i);
+ }
+}
+
+- (void)testGetNextSet2 {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:33];
+ [array set:31];
+ for (int i = 0; i < array.size; i++) {
+ int expected = i <= 31 ? 31 : 33;
+ STAssertEquals([array nextSet:i], expected, @"Expected [array nextSet:%d] to equal %d", i, expected);
+ }
+ array = [[ZXBitArray alloc] initWithSize:33];
+ [array set:32];
+ for (int i = 0; i < array.size; i++) {
+ STAssertEquals([array nextSet:i], 32, @"Expected [array nextSet:%d] to equal 32", i);
+ }
+}
+
+- (void)testGetNextSet3 {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:63];
+ [array set:31];
+ [array set:32];
+ for (int i = 0; i < array.size; i++) {
+ int expected;
+ if (i <= 31) {
+ expected = 31;
+ } else if (i == 32) {
+ expected = 32;
+ } else {
+ expected = 63;
+ }
+ STAssertEquals([array nextSet:i], expected, @"Expected [array nextSet:%d] to equal %d", i, expected);
+ }
+}
+
+- (void)testGetNextSet4 {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:63];
+ [array set:33];
+ [array set:40];
+ for (int i = 0; i < array.size; i++) {
+ int expected;
+ if (i <= 33) {
+ expected = 33;
+ } else if (i <= 40) {
+ expected = 40;
+ } else {
+ expected = 63;
+ }
+ STAssertEquals([array nextSet:i], expected, @"Expected [array nextSet:%d] to equal %d", i, expected);
+ }
+}
+
+- (void)testGetNextSet5 {
+ for (int i = 0; i < 10; i++) {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:(arc4random() % 100) + 1];
+ int numSet = arc4random() % 20;
+ for (int j = 0; j < numSet; j++) {
+ [array set:arc4random() % array.size];
+ }
+ int numQueries = arc4random() % 20;
+ for (int j = 0; j < numQueries; j++) {
+ int query = arc4random() % array.size;
+ int expected = query;
+ while (expected < array.size && ![array get:expected]) {
+ expected++;
+ }
+ int actual = [array nextSet:query];
+ if (actual != expected) {
+ [array nextSet:query];
+ }
+ STAssertEquals(actual, expected, @"Expected %d to equal %d", actual, expected);
+ }
+ }
+}
+
+- (void)testSetBulk {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:64];
+ [array setBulk:32 newBits:0xFFFF0000];
+ for (int i = 0; i < 48; i++) {
+ STAssertFalse([array get:i], @"Expected [array get:%d] to be false", i);
+ }
+ for (int i = 48; i < 64; i++) {
+ STAssertTrue([array get:i], @"Expected [array get:%d] to be true", i);
+ }
+}
+
+- (void)testClear {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:32];
+ for (int i = 0; i < 32; i++) {
+ [array set:i];
+ }
+ [array clear];
+ for (int i = 0; i < 32; i++) {
+ STAssertFalse([array get:i], @"Expected [array get:%d] to be false", i);
+ }
+}
+
+- (void)testGetArray {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:64];
+ [array set:0];
+ [array set:63];
+ int32_t *ints = array.bits;
+ STAssertEquals(ints[0], 1, @"Expected ints[0] to equal 1");
+ STAssertEquals(ints[1], INT_MIN, @"Expected ints[1] to equal INT_MIN");
+}
+
+- (void)testIsRange {
+ ZXBitArray *array = [[ZXBitArray alloc] initWithSize:64];
+ STAssertTrue([array isRange:0 end:64 value:NO], @"Expected range 0-64 of NO to be true");
+ STAssertFalse([array isRange:0 end:64 value:YES], @"Expected range 0-64 of YES to be false");
+ [array set:32];
+ STAssertTrue([array isRange:32 end:33 value:YES], @"Expected range 32-33 of YES to be true");
+ [array set:31];
+ STAssertTrue([array isRange:31 end:33 value:YES], @"Expected range 31-33 of YES to be true");
+ [array set:34];
+ STAssertFalse([array isRange:31 end:35 value:YES], @"Expected range 31-35 of YES to be false");
+ for (int i = 0; i < 31; i++) {
+ [array set:i];
+ }
+ STAssertTrue([array isRange:0 end:33 value:YES], @"Expected range 0-33 of YES to be true");
+ for (int i = 33; i < 64; i++) {
+ [array set:i];
+ }
+ STAssertTrue([array isRange:0 end:64 value:YES], @"Expected range 0-64 of YES to be true");
+ STAssertFalse([array isRange:0 end:64 value:NO], @"Expected range 0-64 of YES to be false");
+}
+
+@end
diff --git a/ZXingObjCTests/common/ZXBitMatrixTestCase.h b/ZXingObjCTests/common/ZXBitMatrixTestCase.h
new file mode 100644
index 0000000..f26c484
--- /dev/null
+++ b/ZXingObjCTests/common/ZXBitMatrixTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXBitMatrixTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/common/ZXBitMatrixTestCase.m b/ZXingObjCTests/common/ZXBitMatrixTestCase.m
new file mode 100644
index 0000000..1c7338e
--- /dev/null
+++ b/ZXingObjCTests/common/ZXBitMatrixTestCase.m
@@ -0,0 +1,120 @@
+/*
+ * 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 "ZXBitMatrixTestCase.h"
+
+@implementation ZXBitMatrixTestCase
+
+- (void)testGetSet {
+ ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithDimension:33];
+ STAssertEquals(matrix.height, 33, @"Expected matrix height to be 33");
+ for (int y = 0; y < 33; y++) {
+ for (int x = 0; x < 33; x++) {
+ if ((y * x % 3) == 0) {
+ [matrix setX:x y:y];
+ }
+ }
+ }
+ for (int y = 0; y < 33; y++) {
+ for (int x = 0; x < 33; x++) {
+ STAssertEquals([matrix getX:x y:y], (BOOL)(y * x % 3 == 0), @"Expected matrix (%d,%d) to equal %d", x, y, y * x % 3 == 0);
+ }
+ }
+}
+
+- (void)testSetRegion {
+ ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithDimension:5];
+ [matrix setRegionAtLeft:1 top:1 width:3 height:3];
+ for (int y = 0; y < 5; y++) {
+ for (int x = 0; x < 5; x++) {
+ BOOL expected = y >= 1 && y <= 3 && x >= 1 && x <= 3;
+ STAssertEquals([matrix getX:x y:y], expected, @"Expected (%d,%d) to be %d", x, y, expected);
+ }
+ }
+}
+
+- (void)testRectangularMatrix {
+ ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithWidth:75 height:20];
+ STAssertEquals(matrix.width, 75, @"Expected matrix.width to be 75");
+ STAssertEquals(matrix.height, 20, @"Expected matrix.height to be 20");
+ [matrix setX:10 y:0];
+ [matrix setX:11 y:1];
+ [matrix setX:50 y:2];
+ [matrix setX:51 y:3];
+ [matrix flipX:74 y:4];
+ [matrix flipX:0 y:5];
+
+ // Should all be on
+ STAssertTrue([matrix getX:10 y:0], @"Expected (10,0) to be on");
+ STAssertTrue([matrix getX:11 y:1], @"Expected (11,1) to be on");
+ STAssertTrue([matrix getX:50 y:2], @"Expected (50,2) to be on");
+ STAssertTrue([matrix getX:51 y:3], @"Expected (51,3) to be on");
+ STAssertTrue([matrix getX:74 y:4], @"Expected (74,4) to be on");
+ STAssertTrue([matrix getX:0 y:5], @"Expected (0,5) to be on");
+
+ // Flip a couple back off
+ [matrix flipX:50 y:2];
+ [matrix flipX:51 y:3];
+ STAssertFalse([matrix getX:50 y:2], @"Expected (50,2) to be off");
+ STAssertFalse([matrix getX:51 y:3], @"Expected (51,3) to be off");
+}
+
+- (void)testRectangularSetRegion {
+ ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithWidth:320 height:240];
+ STAssertEquals(matrix.width, 320, @"Expected matrix.width to be 320");
+ STAssertEquals(matrix.height, 240, @"Expected matrix.height to be 240");
+ [matrix setRegionAtLeft:105 top:22 width:80 height:12];
+
+ // Only bits in the region should be on
+ for (int y = 0; y < 240; y++) {
+ for (int x = 0; x < 320; x++) {
+ BOOL expected = y >= 22 && y < 34 && x >= 105 && x < 185;
+ STAssertEquals([matrix getX:x y:y], expected, @"Expected matrix (%d,%d) to equal %d", x, y, expected);
+ }
+ }
+}
+
+- (void)testGetRow {
+ ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithWidth:102 height:5];
+ for (int x = 0; x < 102; x++) {
+ if ((x & 0x03) == 0) {
+ [matrix setX:x y:2];
+ }
+ }
+
+ // Should allocate
+ ZXBitArray *array = [matrix rowAtY:2 row:nil];
+ STAssertEquals(array.size, 102, @"Expected array.size to equal 102");
+
+ // Should reallocate
+ ZXBitArray *array2 = [[ZXBitArray alloc] initWithSize:60];
+ array2 = [matrix rowAtY:2 row:array2];
+ STAssertEquals(array2.size, 102, @"Expected array2.size to equal 102");
+
+ // Should use provided object, with original BitArray size
+ ZXBitArray *array3 = [[ZXBitArray alloc] initWithSize:200];
+ array3 = [matrix rowAtY:2 row:array3];
+ STAssertEquals(array3.size, 200, @"Expected array3.size to equal 200");
+
+ for (int x = 0; x < 102; x++) {
+ BOOL on = (x & 0x03) == 0;
+ STAssertEquals([array get:x], on, @"Expected [array get:%d] to be %d", x, on);
+ STAssertEquals([array2 get:x], on, @"Expected [array2 get:%d] to be %d", x, on);
+ STAssertEquals([array3 get:x], on, @"Expected [array3 get:%d] to be %d", x, on);
+ }
+}
+
+@end
diff --git a/ZXingObjCTests/common/ZXBitSourceBuilder.h b/ZXingObjCTests/common/ZXBitSourceBuilder.h
new file mode 100644
index 0000000..656fa85
--- /dev/null
+++ b/ZXingObjCTests/common/ZXBitSourceBuilder.h
@@ -0,0 +1,23 @@
+/*
+ * 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 ZXBitSourceBuilder : NSObject
+
+- (void)write:(int)value numBits:(int)numBits;
+- (int8_t *)toByteArray;
+- (int)byteArrayLength;
+
+@end
diff --git a/ZXingObjCTests/common/ZXBitSourceBuilder.m b/ZXingObjCTests/common/ZXBitSourceBuilder.m
new file mode 100644
index 0000000..63737ca
--- /dev/null
+++ b/ZXingObjCTests/common/ZXBitSourceBuilder.m
@@ -0,0 +1,74 @@
+/*
+ * 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 "ZXBitSourceBuilder.h"
+
+@interface ZXBitSourceBuilder ()
+
+@property (nonatomic, assign) int bitsLeftInNextByte;
+@property (nonatomic, assign) int nextByte;
+@property (nonatomic, strong) NSMutableData *output;
+
+@end
+
+
+/**
+ * Class that lets one easily build an array of bytes by appending bits at a time.
+ */
+@implementation ZXBitSourceBuilder
+
+- (id)init {
+ if(self = [super init]) {
+ _bitsLeftInNextByte = 8;
+ _nextByte = 0;
+ _output = [NSMutableData data];
+ }
+
+ return self;
+}
+
+- (void)write:(int)value numBits:(int)numBits {
+ if (numBits <= self.bitsLeftInNextByte) {
+ self.nextByte <<= numBits;
+ self.nextByte |= value;
+ self.bitsLeftInNextByte -= numBits;
+ if (self.bitsLeftInNextByte == 0) {
+ [self.output appendBytes:&_nextByte length:1];
+ self.nextByte = 0;
+ self.bitsLeftInNextByte = 8;
+ }
+ } else {
+ int bitsToWriteNow = self.bitsLeftInNextByte;
+ int numRestOfBits = numBits - bitsToWriteNow;
+ int mask = 0xFF >> (8 - bitsToWriteNow);
+ int valueToWriteNow = (int)(((unsigned int)value) >> numRestOfBits) & mask;
+ [self write:valueToWriteNow numBits:bitsToWriteNow];
+ [self write:value numBits:numRestOfBits];
+ }
+}
+
+- (int8_t *)toByteArray {
+ if (self.bitsLeftInNextByte < 8) {
+ [self write:0 numBits:self.bitsLeftInNextByte];
+ }
+ return (int8_t *)[self.output bytes];
+}
+
+- (int)byteArrayLength {
+ return (int)[self.output length];
+}
+
+@end
diff --git a/ZXingObjCTests/common/ZXBitSourceTestCase.h b/ZXingObjCTests/common/ZXBitSourceTestCase.h
new file mode 100644
index 0000000..6b6c228
--- /dev/null
+++ b/ZXingObjCTests/common/ZXBitSourceTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXBitSourceTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/common/ZXBitSourceTestCase.m b/ZXingObjCTests/common/ZXBitSourceTestCase.m
new file mode 100644
index 0000000..7e957d6
--- /dev/null
+++ b/ZXingObjCTests/common/ZXBitSourceTestCase.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 "ZXBitSourceTestCase.h"
+
+@implementation ZXBitSourceTestCase
+
+- (void)testSource {
+ int8_t bytes[5] = {1, 2, 3, 4, 5};
+ ZXBitSource *source = [[ZXBitSource alloc] initWithBytes:bytes length:5];
+ STAssertEquals(source.available, 40, @"Expected source.available to 40");
+ STAssertEquals([source readBits:1], 0, @"Expected [source readBits:1] to 0");
+ STAssertEquals(source.available, 39, @"Expected source.available to 39");
+ STAssertEquals([source readBits:6], 0, @"Expected [source readBits:6] to 0");
+ STAssertEquals(source.available, 33, @"Expected source.available to 33");
+ STAssertEquals([source readBits:1], 1, @"Expected [source readBits:1] to 1");
+ STAssertEquals(source.available, 32, @"Expected source.available to 32");
+ STAssertEquals([source readBits:8], 2, @"Expected [source readBits:1] to 1");
+ STAssertEquals(source.available, 24, @"Expected source.available to 24");
+ STAssertEquals([source readBits:10], 12, @"Expected [source readBits:10] to 1");
+ STAssertEquals(source.available, 14, @"Expected source.available to 14");
+ STAssertEquals([source readBits:8], 16, @"Expected [source readBits:8] to 16");
+ STAssertEquals(source.available, 6, @"Expected source.available to 6");
+ STAssertEquals([source readBits:6], 5, @"Expected [source readBits:6] to 5");
+ STAssertEquals(source.available, 0, @"Expected source.available to 0");
+}
+
+@end
diff --git a/ZXingObjCTests/common/ZXPerspectiveTransformTestCase.h b/ZXingObjCTests/common/ZXPerspectiveTransformTestCase.h
new file mode 100644
index 0000000..68fe5ec
--- /dev/null
+++ b/ZXingObjCTests/common/ZXPerspectiveTransformTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXPerspectiveTransformTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/common/ZXPerspectiveTransformTestCase.m b/ZXingObjCTests/common/ZXPerspectiveTransformTestCase.m
new file mode 100644
index 0000000..1b68e09
--- /dev/null
+++ b/ZXingObjCTests/common/ZXPerspectiveTransformTestCase.m
@@ -0,0 +1,64 @@
+/*
+ * 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 "ZXPerspectiveTransformTestCase.h"
+
+@implementation ZXPerspectiveTransformTestCase
+
+static float EPSILON = 0.0001f;
+
+- (void)testSquareToQuadrilateral {
+ ZXPerspectiveTransform *pt = [ZXPerspectiveTransform squareToQuadrilateral:2.0f y0:3.0f
+ x1:10.0f y1:4.0f
+ x2:16.0f y2:15.0f
+ x3:4.0f y3:9.0f];
+ [self assertPointEqualsExpectedX:2.0f expectedY:3.0f sourceX:0.0f sourceY:0.0f pt:pt];
+ [self assertPointEqualsExpectedX:10.0f expectedY:4.0f sourceX:1.0f sourceY:0.0f pt:pt];
+ [self assertPointEqualsExpectedX:4.0f expectedY:9.0f sourceX:0.0f sourceY:1.0f pt:pt];
+ [self assertPointEqualsExpectedX:16.0f expectedY:15.0f sourceX:1.0f sourceY:1.0f pt:pt];
+ [self assertPointEqualsExpectedX:6.535211f expectedY:6.8873234f sourceX:0.5f sourceY:0.5f pt:pt];
+ [self assertPointEqualsExpectedX:48.0f expectedY:42.42857f sourceX:1.5f sourceY:1.5f pt:pt];
+}
+
+- (void)testQuadrilateralToQuadrilateral {
+ ZXPerspectiveTransform *pt = [ZXPerspectiveTransform quadrilateralToQuadrilateral:2.0f y0:3.0f
+ x1:10.0f y1:4.0f
+ x2:16.0f y2:15.0f
+ x3:4.0f y3:9.0f
+ x0p:103.0f y0p:110.0f
+ x1p:300.0f y1p:120.0f
+ x2p:290.0f y2p:270.0f
+ x3p:150.0f y3p:280.0f];
+ [self assertPointEqualsExpectedX:103.0f expectedY:110.0f sourceX:2.0f sourceY:3.0f pt:pt];
+ [self assertPointEqualsExpectedX:300.0f expectedY:120.0f sourceX:10.0f sourceY:4.0f pt:pt];
+ [self assertPointEqualsExpectedX:290.0f expectedY:270.0f sourceX:16.0f sourceY:15.0f pt:pt];
+ [self assertPointEqualsExpectedX:150.0f expectedY:280.0f sourceX:4.0f sourceY:9.0f pt:pt];
+ [self assertPointEqualsExpectedX:7.1516876f expectedY:-64.60185f sourceX:0.5f sourceY:0.5f pt:pt];
+ [self assertPointEqualsExpectedX:328.09116f expectedY:334.16385f sourceX:50.0f sourceY:50.0f pt:pt];
+}
+
+- (void)assertPointEqualsExpectedX:(float)expectedX
+ expectedY:(float)expectedY
+ sourceX:(float)sourceX
+ sourceY:(float)sourceY
+ pt:(ZXPerspectiveTransform *)pt {
+ float points[2] = {sourceX, sourceY};
+ [pt transformPoints:points pointsLen:2];
+ STAssertEqualsWithAccuracy(points[0], expectedX, EPSILON, @"Expected %f to equal %f", points[0], expectedX);
+ STAssertEqualsWithAccuracy(points[1], expectedY, EPSILON, @"Expected %f to equal %f", points[1], expectedY);
+}
+
+@end
diff --git a/ZXingObjCTests/common/ZXStringUtilsTestCase.h b/ZXingObjCTests/common/ZXStringUtilsTestCase.h
new file mode 100644
index 0000000..94ec1d4
--- /dev/null
+++ b/ZXingObjCTests/common/ZXStringUtilsTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXStringUtilsTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/common/ZXStringUtilsTestCase.m b/ZXingObjCTests/common/ZXStringUtilsTestCase.m
new file mode 100644
index 0000000..b72293d
--- /dev/null
+++ b/ZXingObjCTests/common/ZXStringUtilsTestCase.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 "ZXStringUtilsTestCase.h"
+
+@implementation ZXStringUtilsTestCase
+
+- (void)testShortShiftJIS_1 {
+ // 金魚
+ int8_t bytes[4] = { 0x8b, 0xe0, 0x8b, 0x9b };
+ [self doTestWithBytes:bytes length:4 encoding:NSShiftJISStringEncoding];
+}
+
+- (void)testShortISO88591_1 {
+ // båd
+ int8_t bytes[3] = { 0x62, 0xe5, 0x64 };
+ [self doTestWithBytes:bytes length:3 encoding:NSISOLatin1StringEncoding];
+}
+
+- (void)testMixedShiftJIS_1 {
+ // Hello Èáë!
+ int8_t bytes[9] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x8b, 0xe0, 0x21 };
+ [self doTestWithBytes:bytes length:9 encoding:NSShiftJISStringEncoding];
+}
+
+- (void)doTestWithBytes:(int8_t *)bytes length:(int)length encoding:(NSStringEncoding)encoding {
+ STAssertEquals([ZXStringUtils guessEncoding:bytes length:length hints:nil], encoding, @"Encodings do not match");
+}
+
+@end
diff --git a/ZXingObjCTests/common/reedsolomon/ReedSolomonTestCase.h b/ZXingObjCTests/common/reedsolomon/ReedSolomonTestCase.h
new file mode 100644
index 0000000..65d94ca
--- /dev/null
+++ b/ZXingObjCTests/common/reedsolomon/ReedSolomonTestCase.h
@@ -0,0 +1,21 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+@interface ReedSolomonTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/common/reedsolomon/ReedSolomonTestCase.m b/ZXingObjCTests/common/reedsolomon/ReedSolomonTestCase.m
new file mode 100644
index 0000000..fe0f371
--- /dev/null
+++ b/ZXingObjCTests/common/reedsolomon/ReedSolomonTestCase.m
@@ -0,0 +1,516 @@
+/*
+ * 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 "ReedSolomonTestCase.h"
+
+const int DECODER_RANDOM_TEST_ITERATIONS = 3;
+const int DECODER_TEST_ITERATIONS = 10;
+const int ReedSolomonTestCase_RANDOM_SEED = 3735928559;
+
+@implementation ReedSolomonTestCase
+
+- (void)testDataMatrix {
+ // real life test cases
+ int dataWords1[3] = { 142, 164, 186 };
+ int ecWords1[5] = { 114, 25, 5, 88, 102 };
+ [self testEncodeDecode:[ZXGenericGF DataMatrixField256] dataWords:dataWords1 dataWordsLen:3 ecWords:ecWords1 ecWordsLen:5];
+
+ int dataWords2[36] = {
+ 0x69, 0x75, 0x75, 0x71, 0x3B, 0x30, 0x30, 0x64,
+ 0x70, 0x65, 0x66, 0x2F, 0x68, 0x70, 0x70, 0x68,
+ 0x6D, 0x66, 0x2F, 0x64, 0x70, 0x6E, 0x30, 0x71,
+ 0x30, 0x7B, 0x79, 0x6A, 0x6F, 0x68, 0x30, 0x81,
+ 0xF0, 0x88, 0x1F, 0xB5 };
+ int ecWords2[24] = {
+ 0x1C, 0x64, 0xEE, 0xEB, 0xD0, 0x1D, 0x00, 0x03,
+ 0xF0, 0x1C, 0xF1, 0xD0, 0x6D, 0x00, 0x98, 0xDA,
+ 0x80, 0x88, 0xBE, 0xFF, 0xB7, 0xFA, 0xA9, 0x95 };
+ [self testEncodeDecode:[ZXGenericGF DataMatrixField256] dataWords:dataWords2 dataWordsLen:36 ecWords:ecWords2 ecWordsLen:24];
+
+ // synthetic test cases
+ [self testEncodeDecodeRandom:[ZXGenericGF DataMatrixField256] dataSize:10 ecSize:240];
+ [self testEncodeDecodeRandom:[ZXGenericGF DataMatrixField256] dataSize:128 ecSize:127];
+ [self testEncodeDecodeRandom:[ZXGenericGF DataMatrixField256] dataSize:220 ecSize:35];
+}
+
+- (void)testQRCode {
+ // Test case from example given in ISO 18004, Annex I
+ int dataWords1[16] = {
+ 0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11,
+ 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 };
+ int ecWords1[10] = {
+ 0xA5, 0x24, 0xD4, 0xC1, 0xED, 0x36, 0xC7, 0x87,
+ 0x2C, 0x55 };
+ [self testEncodeDecode:[ZXGenericGF QrCodeField256] dataWords:dataWords1 dataWordsLen:16 ecWords:ecWords1 ecWordsLen:10];
+
+ int dataWords2[32] = {
+ 0x72, 0x67, 0x2F, 0x77, 0x69, 0x6B, 0x69, 0x2F,
+ 0x4D, 0x61, 0x69, 0x6E, 0x5F, 0x50, 0x61, 0x67,
+ 0x65, 0x3B, 0x3B, 0x00, 0xEC, 0x11, 0xEC, 0x11,
+ 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 };
+ int ecWords2[18] = {
+ 0xD8, 0xB8, 0xEF, 0x14, 0xEC, 0xD0, 0xCC, 0x85,
+ 0x73, 0x40, 0x0B, 0xB5, 0x5A, 0xB8, 0x8B, 0x2E,
+ 0x08, 0x62 };
+ [self testEncodeDecode:[ZXGenericGF QrCodeField256] dataWords:dataWords2 dataWordsLen:32 ecWords:ecWords2 ecWordsLen:18];
+
+ // real life test cases
+ // synthetic test cases
+ [self testEncodeDecodeRandom:[ZXGenericGF QrCodeField256] dataSize:10 ecSize:240];
+ [self testEncodeDecodeRandom:[ZXGenericGF QrCodeField256] dataSize:128 ecSize:127];
+ [self testEncodeDecodeRandom:[ZXGenericGF QrCodeField256] dataSize:220 ecSize:35];
+}
+
+- (void)testAztec {
+ // real life test cases
+ int dataWords1[2] = { 0x5, 0x6 };
+ int ecWords1[5] = { 0x3, 0x2, 0xB, 0xB, 0x7 };
+ [self testEncodeDecode:[ZXGenericGF AztecParam] dataWords:dataWords1 dataWordsLen:2 ecWords:ecWords1 ecWordsLen:5];
+
+ int dataWords2[4] = { 0x0, 0x0, 0x0, 0x9 };
+ int ecWords2[6] = { 0xA, 0xD, 0x8, 0x6, 0x5, 0x6 };
+ [self testEncodeDecode:[ZXGenericGF AztecParam] dataWords:dataWords2 dataWordsLen:4 ecWords:ecWords2 ecWordsLen:6];
+
+ int dataWords3[4] = { 0x2, 0x8, 0x8, 0x7 };
+ int ecWords3[6] = { 0xE, 0xC, 0xA, 0x9, 0x6, 0x8 };
+ [self testEncodeDecode:[ZXGenericGF AztecParam] dataWords:dataWords3 dataWordsLen:4 ecWords:ecWords3 ecWordsLen:6];
+
+ int dataWords4[10] = {
+ 0x9, 0x32, 0x1, 0x29, 0x2F, 0x2, 0x27, 0x25, 0x1, 0x1B };
+ int ecWords4[11] = {
+ 0x2C, 0x2, 0xD, 0xD, 0xA, 0x16, 0x28, 0x9, 0x22, 0xA, 0x14 };
+ [self testEncodeDecode:[ZXGenericGF AztecData6] dataWords:dataWords4 dataWordsLen:10 ecWords:ecWords4 ecWordsLen:11];
+
+ int dataWords5[69] = {
+ 0xE0, 0x86, 0x42, 0x98, 0xE8, 0x4A, 0x96, 0xC6,
+ 0xB9, 0xF0, 0x8C, 0xA7, 0x4A, 0xDA, 0xF8, 0xCE,
+ 0xB7, 0xDE, 0x88, 0x64, 0x29, 0x8E, 0x84, 0xA9,
+ 0x6C, 0x6B, 0x9F, 0x08, 0xCA, 0x74, 0xAD, 0xAF,
+ 0x8C, 0xEB, 0x7C, 0x10, 0xC8, 0x53, 0x1D, 0x09,
+ 0x52, 0xD8, 0xD7, 0x3E, 0x11, 0x94, 0xE9, 0x5B,
+ 0x5F, 0x19, 0xD6, 0xFB, 0xD1, 0x0C, 0x85, 0x31,
+ 0xD0, 0x95, 0x2D, 0x8D, 0x73, 0xE1, 0x19, 0x4E,
+ 0x95, 0xB5, 0xF1, 0x9D, 0x6F };
+ int ecWords5[51] = {
+ 0x31, 0xD7, 0x04, 0x46, 0xB2, 0xC1, 0x06, 0x94,
+ 0x17, 0xE5, 0x0C, 0x2B, 0xA3, 0x99, 0x15, 0x7F,
+ 0x16, 0x3C, 0x66, 0xBA, 0x33, 0xD9, 0xE8, 0x87,
+ 0x86, 0xBB, 0x4B, 0x15, 0x4E, 0x4A, 0xDE, 0xD4,
+ 0xED, 0xA1, 0xF8, 0x47, 0x2A, 0x50, 0xA6, 0xBC,
+ 0x53, 0x7D, 0x29, 0xFE, 0x06, 0x49, 0xF3, 0x73,
+ 0x9F, 0xC1, 0x75 };
+ [self testEncodeDecode:[ZXGenericGF AztecData8] dataWords:dataWords5 dataWordsLen:69 ecWords:ecWords5 ecWordsLen:51];
+
+ int dataWords6[330] = {
+ 0x15C, 0x1E1, 0x2D5, 0x02E, 0x048, 0x1E2, 0x037, 0x0CD,
+ 0x02E, 0x056, 0x26A, 0x281, 0x1C2, 0x1A6, 0x296, 0x045,
+ 0x041, 0x0AA, 0x095, 0x2CE, 0x003, 0x38F, 0x2CD, 0x1A2,
+ 0x036, 0x1AD, 0x04E, 0x090, 0x271, 0x0D3, 0x02E, 0x0D5,
+ 0x2D4, 0x032, 0x2CA, 0x281, 0x0AA, 0x04E, 0x024, 0x2D3,
+ 0x296, 0x281, 0x0E2, 0x08A, 0x1AA, 0x28A, 0x280, 0x07C,
+ 0x286, 0x0A1, 0x1D0, 0x1AD, 0x154, 0x032, 0x2C2, 0x1C1,
+ 0x145, 0x02B, 0x2D4, 0x2B0, 0x033, 0x2D5, 0x276, 0x1C1,
+ 0x282, 0x10A, 0x2B5, 0x154, 0x003, 0x385, 0x20F, 0x0C4,
+ 0x02D, 0x050, 0x266, 0x0D5, 0x033, 0x2D5, 0x276, 0x1C1,
+ 0x0D4, 0x2A0, 0x08F, 0x0C4, 0x024, 0x20F, 0x2E2, 0x1AD,
+ 0x154, 0x02E, 0x056, 0x26A, 0x281, 0x090, 0x1E5, 0x14E,
+ 0x0CF, 0x2B6, 0x1C1, 0x28A, 0x2A1, 0x04E, 0x0D5, 0x003,
+ 0x391, 0x122, 0x286, 0x1AD, 0x2D4, 0x028, 0x262, 0x2EA,
+ 0x0A2, 0x004, 0x176, 0x295, 0x201, 0x0D5, 0x024, 0x20F,
+ 0x116, 0x0C1, 0x056, 0x095, 0x213, 0x004, 0x1EA, 0x28A,
+ 0x02A, 0x234, 0x2CE, 0x037, 0x157, 0x0D3, 0x262, 0x026,
+ 0x262, 0x2A0, 0x086, 0x106, 0x2A1, 0x126, 0x1E5, 0x266,
+ 0x26A, 0x2A1, 0x0E6, 0x1AA, 0x281, 0x2B6, 0x271, 0x154,
+ 0x02F, 0x0C4, 0x02D, 0x213, 0x0CE, 0x003, 0x38F, 0x2CD,
+ 0x1A2, 0x036, 0x1B5, 0x26A, 0x086, 0x280, 0x086, 0x1AA,
+ 0x2A1, 0x226, 0x1AD, 0x0CF, 0x2A6, 0x292, 0x2C6, 0x022,
+ 0x1AA, 0x256, 0x0D5, 0x02D, 0x050, 0x266, 0x0D5, 0x004,
+ 0x176, 0x295, 0x201, 0x0D3, 0x055, 0x031, 0x2CD, 0x2EA,
+ 0x1E2, 0x261, 0x1EA, 0x28A, 0x004, 0x145, 0x026, 0x1A6,
+ 0x1C6, 0x1F5, 0x2CE, 0x034, 0x051, 0x146, 0x1E1, 0x0B0,
+ 0x1B0, 0x261, 0x0D5, 0x025, 0x142, 0x1C0, 0x07C, 0x0B0,
+ 0x1E6, 0x081, 0x044, 0x02F, 0x2CF, 0x081, 0x290, 0x0A2,
+ 0x1A6, 0x281, 0x0CD, 0x155, 0x031, 0x1A2, 0x086, 0x262,
+ 0x2A1, 0x0CD, 0x0CA, 0x0E6, 0x1E5, 0x003, 0x394, 0x0C5,
+ 0x030, 0x26F, 0x053, 0x0C1, 0x1B6, 0x095, 0x2D4, 0x030,
+ 0x26F, 0x053, 0x0C0, 0x07C, 0x2E6, 0x295, 0x143, 0x2CD,
+ 0x2CE, 0x037, 0x0C9, 0x144, 0x2CD, 0x040, 0x08E, 0x054,
+ 0x282, 0x022, 0x2A1, 0x229, 0x053, 0x0D5, 0x262, 0x027,
+ 0x26A, 0x1E8, 0x14D, 0x1A2, 0x004, 0x26A, 0x296, 0x281,
+ 0x176, 0x295, 0x201, 0x0E2, 0x2C4, 0x143, 0x2D4, 0x026,
+ 0x262, 0x2A0, 0x08F, 0x0C4, 0x031, 0x213, 0x2B5, 0x155,
+ 0x213, 0x02F, 0x143, 0x121, 0x2A6, 0x1AD, 0x2D4, 0x034,
+ 0x0C5, 0x026, 0x295, 0x003, 0x396, 0x2A1, 0x176, 0x295,
+ 0x201, 0x0AA, 0x04E, 0x004, 0x1B0, 0x070, 0x275, 0x154,
+ 0x026, 0x2C1, 0x2B3, 0x154, 0x2AA, 0x256, 0x0C1, 0x044,
+ 0x004, 0x23F };
+ int ecWords6[140] = {
+ 0x379, 0x099, 0x348, 0x010, 0x090, 0x196, 0x09C, 0x1FF,
+ 0x1B0, 0x32D, 0x244, 0x0DE, 0x201, 0x386, 0x163, 0x11F,
+ 0x39B, 0x344, 0x3FE, 0x02F, 0x188, 0x113, 0x3D9, 0x102,
+ 0x04A, 0x2E1, 0x1D1, 0x18E, 0x077, 0x262, 0x241, 0x20D,
+ 0x1B8, 0x11D, 0x0D0, 0x0A5, 0x29C, 0x24D, 0x3E7, 0x006,
+ 0x2D0, 0x1B7, 0x337, 0x178, 0x0F1, 0x1E0, 0x00B, 0x01E,
+ 0x0DA, 0x1C6, 0x2D9, 0x00D, 0x28B, 0x34A, 0x252, 0x27A,
+ 0x057, 0x0CA, 0x2C2, 0x2E4, 0x3A6, 0x0E3, 0x22B, 0x307,
+ 0x174, 0x292, 0x10C, 0x1ED, 0x2FD, 0x2D4, 0x0A7, 0x051,
+ 0x34F, 0x07A, 0x1D5, 0x01D, 0x22E, 0x2C2, 0x1DF, 0x08F,
+ 0x105, 0x3FE, 0x286, 0x2A2, 0x3B1, 0x131, 0x285, 0x362,
+ 0x315, 0x13C, 0x0F9, 0x1A2, 0x28D, 0x246, 0x1B3, 0x12C,
+ 0x2AD, 0x0F8, 0x222, 0x0EC, 0x39F, 0x358, 0x014, 0x229,
+ 0x0C8, 0x360, 0x1C2, 0x031, 0x098, 0x041, 0x3E4, 0x046,
+ 0x332, 0x318, 0x2E3, 0x24E, 0x3E2, 0x1E1, 0x0BE, 0x239,
+ 0x306, 0x3A5, 0x352, 0x351, 0x275, 0x0ED, 0x045, 0x229,
+ 0x0BF, 0x05D, 0x253, 0x1BE, 0x02E, 0x35A, 0x0E4, 0x2E9,
+ 0x17A, 0x166, 0x03C, 0x007 };
+ [self testEncodeDecode:[ZXGenericGF AztecData10] dataWords:dataWords6 dataWordsLen:330 ecWords:ecWords6 ecWordsLen:140];
+
+ int dataWords7[1229] = {
+ 0x571, 0xE1B, 0x542, 0xE12, 0x1E2, 0x0DC, 0xCD0, 0xB85,
+ 0x69A, 0xA81, 0x709, 0xA6A, 0x584, 0x510, 0x4AA, 0x256,
+ 0xCE0, 0x0F8, 0xFB3, 0x5A2, 0x0D9, 0xAD1, 0x389, 0x09C,
+ 0x4D3, 0x0B8, 0xD5B, 0x503, 0x2B2, 0xA81, 0x2A8, 0x4E0,
+ 0x92D, 0x3A5, 0xA81, 0x388, 0x8A6, 0xAA8, 0xAA0, 0x07C,
+ 0xA18, 0xA17, 0x41A, 0xD55, 0x032, 0xB09, 0xC15, 0x142,
+ 0xBB5, 0x2B0, 0x0CE, 0xD59, 0xD9C, 0x1A0, 0x90A, 0xAD5,
+ 0x540, 0x0F8, 0x583, 0xCC4, 0x0B4, 0x509, 0x98D, 0x50C,
+ 0xED5, 0x9D9, 0xC13, 0x52A, 0x023, 0xCC4, 0x092, 0x0FB,
+ 0x89A, 0xD55, 0x02E, 0x15A, 0x6AA, 0x049, 0x079, 0x54E,
+ 0x33E, 0xB67, 0x068, 0xAA8, 0x44E, 0x354, 0x03E, 0x452,
+ 0x2A1, 0x9AD, 0xB50, 0x289, 0x8AE, 0xA28, 0x804, 0x5DA,
+ 0x958, 0x04D, 0x509, 0x20F, 0x458, 0xC11, 0x589, 0x584,
+ 0xC04, 0x7AA, 0x8A0, 0xAA3, 0x4B3, 0x837, 0x55C, 0xD39,
+ 0x882, 0x698, 0xAA0, 0x219, 0x06A, 0x852, 0x679, 0x666,
+ 0x9AA, 0xA13, 0x99A, 0xAA0, 0x6B6, 0x9C5, 0x540, 0xBCC,
+ 0x40B, 0x613, 0x338, 0x03E, 0x3EC, 0xD68, 0x836, 0x6D6,
+ 0x6A2, 0x1A8, 0x021, 0x9AA, 0xA86, 0x266, 0xB4C, 0xFA9,
+ 0xA92, 0xB18, 0x226, 0xAA5, 0x635, 0x42D, 0x142, 0x663,
+ 0x540, 0x45D, 0xA95, 0x804, 0xD31, 0x543, 0x1B3, 0x6EA,
+ 0x78A, 0x617, 0xAA8, 0xA01, 0x145, 0x099, 0xA67, 0x19F,
+ 0x5B3, 0x834, 0x145, 0x467, 0x84B, 0x06C, 0x261, 0x354,
+ 0x255, 0x09C, 0x01F, 0x0B0, 0x798, 0x811, 0x102, 0xFB3,
+ 0xC81, 0xA40, 0xA26, 0x9A8, 0x133, 0x555, 0x0C5, 0xA22,
+ 0x1A6, 0x2A8, 0x4CD, 0x328, 0xE67, 0x940, 0x3E5, 0x0C5,
+ 0x0C2, 0x6F1, 0x4CC, 0x16D, 0x895, 0xB50, 0x309, 0xBC5,
+ 0x330, 0x07C, 0xB9A, 0x955, 0x0EC, 0xDB3, 0x837, 0x325,
+ 0x44B, 0x344, 0x023, 0x854, 0xA08, 0x22A, 0x862, 0x914,
+ 0xCD5, 0x988, 0x279, 0xA9E, 0x853, 0x5A2, 0x012, 0x6AA,
+ 0x5A8, 0x15D, 0xA95, 0x804, 0xE2B, 0x114, 0x3B5, 0x026,
+ 0x98A, 0xA02, 0x3CC, 0x40C, 0x613, 0xAD5, 0x558, 0x4C2,
+ 0xF50, 0xD21, 0xA99, 0xADB, 0x503, 0x431, 0x426, 0xA54,
+ 0x03E, 0x5AA, 0x15D, 0xA95, 0x804, 0xAA1, 0x380, 0x46C,
+ 0x070, 0x9D5, 0x540, 0x9AC, 0x1AC, 0xD54, 0xAAA, 0x563,
+ 0x044, 0x401, 0x220, 0x9F1, 0x4F0, 0xDAA, 0x170, 0x90F,
+ 0x106, 0xE66, 0x85C, 0x2B4, 0xD54, 0x0B8, 0x4D3, 0x52C,
+ 0x228, 0x825, 0x512, 0xB67, 0x007, 0xC7D, 0x9AD, 0x106,
+ 0xCD6, 0x89C, 0x484, 0xE26, 0x985, 0xC6A, 0xDA8, 0x195,
+ 0x954, 0x095, 0x427, 0x049, 0x69D, 0x2D4, 0x09C, 0x445,
+ 0x355, 0x455, 0x003, 0xE50, 0xC50, 0xBA0, 0xD6A, 0xA81,
+ 0x958, 0x4E0, 0xA8A, 0x15D, 0xA95, 0x806, 0x76A, 0xCEC,
+ 0xE0D, 0x048, 0x556, 0xAAA, 0x007, 0xC2C, 0x1E6, 0x205,
+ 0xA28, 0x4CC, 0x6A8, 0x676, 0xACE, 0xCE0, 0x9A9, 0x501,
+ 0x1E6, 0x204, 0x907, 0xDC4, 0xD6A, 0xA81, 0x70A, 0xD35,
+ 0x502, 0x483, 0xCAA, 0x719, 0xF5B, 0x383, 0x455, 0x422,
+ 0x71A, 0xA01, 0xF22, 0x915, 0x0CD, 0x6DA, 0x814, 0x4C5,
+ 0x751, 0x440, 0x22E, 0xD4A, 0xC02, 0x6A8, 0x490, 0x7A2,
+ 0xC60, 0x8AC, 0x4AC, 0x260, 0x23D, 0x545, 0x055, 0x1A5,
+ 0x9C1, 0xBAA, 0xE69, 0xCC4, 0x134, 0xC55, 0x010, 0xC83,
+ 0x542, 0x933, 0xCB3, 0x34D, 0x550, 0x9CC, 0xD55, 0x035,
+ 0xB4E, 0x2AA, 0x05E, 0x620, 0x5B0, 0x999, 0xC01, 0xF1F,
+ 0x66B, 0x441, 0xB36, 0xB35, 0x10D, 0x401, 0x0CD, 0x554,
+ 0x313, 0x35A, 0x67D, 0x4D4, 0x958, 0xC11, 0x355, 0x2B1,
+ 0xAA1, 0x68A, 0x133, 0x1AA, 0x022, 0xED4, 0xAC0, 0x269,
+ 0x8AA, 0x18D, 0x9B7, 0x53C, 0x530, 0xBD5, 0x450, 0x08A,
+ 0x284, 0xCD3, 0x38C, 0xFAD, 0x9C1, 0xA0A, 0x2A3, 0x3C2,
+ 0x583, 0x613, 0x09A, 0xA12, 0xA84, 0xE00, 0xF85, 0x83C,
+ 0xC40, 0x888, 0x17D, 0x9E4, 0x0D2, 0x051, 0x34D, 0x409,
+ 0x9AA, 0xA86, 0x2D1, 0x10D, 0x315, 0x426, 0x699, 0x473,
+ 0x3CA, 0x01F, 0x286, 0x286, 0x137, 0x8A6, 0x60B, 0x6C4,
+ 0xADA, 0x818, 0x4DE, 0x299, 0x803, 0xE5C, 0xD4A, 0xA87,
+ 0x66D, 0x9C1, 0xB99, 0x2A2, 0x59A, 0x201, 0x1C2, 0xA50,
+ 0x411, 0x543, 0x148, 0xA66, 0xACC, 0x413, 0xCD4, 0xF42,
+ 0x9AD, 0x100, 0x935, 0x52D, 0x40A, 0xED4, 0xAC0, 0x271,
+ 0x588, 0xA1D, 0xA81, 0x34C, 0x550, 0x11E, 0x620, 0x630,
+ 0x9D6, 0xAAA, 0xC26, 0x17A, 0x869, 0x0D4, 0xCD6, 0xDA8,
+ 0x1A1, 0x8A1, 0x352, 0xA01, 0xF2D, 0x50A, 0xED4, 0xAC0,
+ 0x255, 0x09C, 0x023, 0x603, 0x84E, 0xAAA, 0x04D, 0x60D,
+ 0x66A, 0xA55, 0x52B, 0x182, 0x220, 0x091, 0x00F, 0x8A7,
+ 0x86D, 0x50B, 0x848, 0x788, 0x373, 0x342, 0xE15, 0xA6A,
+ 0xA05, 0xC26, 0x9A9, 0x611, 0x441, 0x2A8, 0x95B, 0x380,
+ 0x3E3, 0xECD, 0x688, 0x366, 0xB44, 0xE24, 0x271, 0x34C,
+ 0x2E3, 0x56D, 0x40C, 0xACA, 0xA04, 0xAA1, 0x382, 0x4B4,
+ 0xE96, 0xA04, 0xE22, 0x29A, 0xAA2, 0xA80, 0x1F2, 0x862,
+ 0x85D, 0x06B, 0x554, 0x0CA, 0xC27, 0x054, 0x50A, 0xED4,
+ 0xAC0, 0x33B, 0x567, 0x670, 0x682, 0x42A, 0xB55, 0x500,
+ 0x3E1, 0x60F, 0x310, 0x2D1, 0x426, 0x635, 0x433, 0xB56,
+ 0x767, 0x04D, 0x4A8, 0x08F, 0x310, 0x248, 0x3EE, 0x26B,
+ 0x554, 0x0B8, 0x569, 0xAA8, 0x124, 0x1E5, 0x538, 0xCFA,
+ 0xD9C, 0x1A2, 0xAA1, 0x138, 0xD50, 0x0F9, 0x148, 0xA86,
+ 0x6B6, 0xD40, 0xA26, 0x2BA, 0x8A2, 0x011, 0x76A, 0x560,
+ 0x135, 0x424, 0x83D, 0x163, 0x045, 0x625, 0x613, 0x011,
+ 0xEAA, 0x282, 0xA8D, 0x2CE, 0x0DD, 0x573, 0x4E6, 0x209,
+ 0xA62, 0xA80, 0x864, 0x1AA, 0x149, 0x9E5, 0x99A, 0x6AA,
+ 0x84E, 0x66A, 0xA81, 0xADA, 0x715, 0x502, 0xF31, 0x02D,
+ 0x84C, 0xCE0, 0x0F8, 0xFB3, 0x5A2, 0x0D9, 0xB59, 0xA88,
+ 0x6A0, 0x086, 0x6AA, 0xA18, 0x99A, 0xD33, 0xEA6, 0xA4A,
+ 0xC60, 0x89A, 0xA95, 0x8D5, 0x0B4, 0x509, 0x98D, 0x501,
+ 0x176, 0xA56, 0x013, 0x4C5, 0x50C, 0x6CD, 0xBA9, 0xE29,
+ 0x85E, 0xAA2, 0x804, 0x514, 0x266, 0x99C, 0x67D, 0x6CE,
+ 0x0D0, 0x515, 0x19E, 0x12C, 0x1B0, 0x984, 0xD50, 0x954,
+ 0x270, 0x07C, 0x2C1, 0xE62, 0x044, 0x40B, 0xECF, 0x206,
+ 0x902, 0x89A, 0x6A0, 0x4CD, 0x554, 0x316, 0x888, 0x698,
+ 0xAA1, 0x334, 0xCA3, 0x99E, 0x500, 0xF94, 0x314, 0x309,
+ 0xBC5, 0x330, 0x5B6, 0x256, 0xD40, 0xC26, 0xF14, 0xCC0,
+ 0x1F2, 0xE6A, 0x554, 0x3B3, 0x6CE, 0x0DC, 0xC95, 0x12C,
+ 0xD10, 0x08E, 0x152, 0x820, 0x8AA, 0x18A, 0x453, 0x356,
+ 0x620, 0x9E6, 0xA7A, 0x14D, 0x688, 0x049, 0xAA9, 0x6A0,
+ 0x576, 0xA56, 0x013, 0x8AC, 0x450, 0xED4, 0x09A, 0x62A,
+ 0x808, 0xF31, 0x031, 0x84E, 0xB55, 0x561, 0x30B, 0xD43,
+ 0x486, 0xA66, 0xB6D, 0x40D, 0x0C5, 0x09A, 0x950, 0x0F9,
+ 0x6A8, 0x576, 0xA56, 0x012, 0xA84, 0xE01, 0x1B0, 0x1C2,
+ 0x755, 0x502, 0x6B0, 0x6B3, 0x552, 0xAA9, 0x58C, 0x111,
+ 0x004, 0x882, 0x7C5, 0x3C3, 0x6A8, 0x5C2, 0x43C, 0x41B,
+ 0x99A, 0x170, 0xAD3, 0x550, 0x2E1, 0x34D, 0x4B0, 0x8A2,
+ 0x095, 0x44A, 0xD9C, 0x01F, 0x1F6, 0x6B4, 0x41B, 0x35A,
+ 0x271, 0x213, 0x89A, 0x617, 0x1AB, 0x6A0, 0x656, 0x550,
+ 0x255, 0x09C, 0x125, 0xA74, 0xB50, 0x271, 0x114, 0xD55,
+ 0x154, 0x00F, 0x943, 0x142, 0xE83, 0x5AA, 0xA06, 0x561,
+ 0x382, 0xA28, 0x576, 0xA56, 0x019, 0xDAB, 0x3B3, 0x834,
+ 0x121, 0x55A, 0xAA8, 0x01F, 0x0B0, 0x798, 0x816, 0x8A1,
+ 0x331, 0xAA1, 0x9DA, 0xB3B, 0x382, 0x6A5, 0x404, 0x798,
+ 0x812, 0x41F, 0x713, 0x5AA, 0xA05, 0xC2B, 0x4D5, 0x409,
+ 0x20F, 0x2A9, 0xC67, 0xD6C, 0xE0D, 0x155, 0x089, 0xC6A,
+ 0x807, 0xC8A, 0x454, 0x335, 0xB6A, 0x051, 0x315, 0xD45,
+ 0x100, 0x8BB, 0x52B, 0x009, 0xAA1, 0x241, 0xE8B, 0x182,
+ 0x2B1, 0x2B0, 0x980, 0x8F5, 0x514, 0x154, 0x696, 0x706,
+ 0xEAB, 0x9A7, 0x310, 0x4D3, 0x154, 0x043, 0x20D, 0x50A,
+ 0x4CF, 0x2CC, 0xD35, 0x542, 0x733, 0x554, 0x0D6, 0xD38,
+ 0xAA8, 0x179, 0x881, 0x6C2, 0x667, 0x007, 0xC7D, 0x9AD,
+ 0x106, 0xCDA, 0xCD4, 0x435, 0x004, 0x335, 0x550, 0xC4C,
+ 0xD69, 0x9F5, 0x352, 0x563, 0x044, 0xD54, 0xAC6, 0xA85,
+ 0xA28, 0x4CC, 0x6A8, 0x08B, 0xB52, 0xB00, 0x9A6, 0x2A8,
+ 0x636, 0x6DD, 0x4F1, 0x4C2, 0xF55, 0x140, 0x228, 0xA13,
+ 0x34C, 0xE33, 0xEB6, 0x706, 0x828, 0xA8C, 0xF09, 0x60D,
+ 0x84C, 0x26A, 0x84A, 0xA13, 0x803, 0xE16, 0x0F3, 0x102,
+ 0x220, 0x5F6, 0x790, 0x348, 0x144, 0xD35, 0x026, 0x6AA,
+ 0xA18, 0xB44, 0x434, 0xC55, 0x099, 0xA65, 0x1CC, 0xF28,
+ 0x07C, 0xA18, 0xA18, 0x4DE, 0x299, 0x82D, 0xB12, 0xB6A,
+ 0x061, 0x378, 0xA66, 0x00F, 0x973, 0x52A, 0xA1D, 0x9B6,
+ 0x706, 0xE64, 0xA89, 0x668, 0x804, 0x70A, 0x941, 0x045,
+ 0x50C, 0x522, 0x99A, 0xB31, 0x04F, 0x353, 0xD0A, 0x6B4,
+ 0x402, 0x4D5, 0x4B5, 0x02B, 0xB52, 0xB00, 0x9C5, 0x622,
+ 0x876, 0xA04, 0xD31, 0x540, 0x479, 0x881, 0x8C2, 0x75A,
+ 0xAAB, 0x098, 0x5EA, 0x1A4, 0x353, 0x35B, 0x6A0, 0x686,
+ 0x284, 0xD4A, 0x807, 0xCB5, 0x42B, 0xB52, 0xB00, 0x954,
+ 0x270, 0x08D, 0x80E, 0x13A, 0xAA8, 0x135, 0x835, 0x9AA,
+ 0x801, 0xF14, 0xF0D, 0xAA1, 0x709, 0x0F1, 0x06E, 0x668,
+ 0x5C2, 0xB4D, 0x540, 0xB84, 0xD35, 0x2C2, 0x288, 0x255,
+ 0x12B, 0x670, 0x07C, 0x7D9, 0xAD1, 0x06C, 0xD68, 0x9C4,
+ 0x84E, 0x269, 0x85C, 0x6AD, 0xA81, 0x959, 0x540, 0x954,
+ 0x270, 0x496, 0x9D2, 0xD40, 0x9C4, 0x453, 0x554, 0x550,
+ 0x03E, 0x50C, 0x50B, 0xA0D, 0x6AA, 0x819, 0x584, 0xE0A,
+ 0x8A1, 0x5DA, 0x958, 0x067, 0x6AC, 0xECE, 0x0D0, 0x485,
+ 0x56A, 0xAA0, 0x07C, 0x2C1, 0xE62, 0x05A, 0x284, 0xCC6,
+ 0xA86, 0x76A, 0xCEC, 0xE09, 0xA95, 0x011, 0xE62, 0x049,
+ 0x07D, 0xC4D, 0x6AA, 0x817, 0x0AD, 0x355, 0x024, 0x83C,
+ 0xAA7, 0x19F, 0x5B3, 0x834, 0x554, 0x227, 0x1AA, 0x01F,
+ 0x229, 0x150, 0xCD6, 0xDA8, 0x144, 0xC57, 0x514, 0x402,
+ 0x2ED, 0x4AC, 0x026, 0xA84, 0x907, 0xA2C, 0x608, 0xAC4,
+ 0xAC2, 0x602, 0x3D5, 0x450, 0x551, 0xA59, 0xC1B, 0xAAE,
+ 0x69C, 0xC41, 0x34C, 0x550, 0x10C, 0x835, 0x429, 0x33C,
+ 0xB33, 0x4D5, 0x509, 0xCCD, 0x550, 0x35B, 0x4E2, 0xAA0,
+ 0x5E6, 0x205, 0xB09, 0x99C, 0x09F };
+ int ecWords7[435] = {
+ 0xD54, 0x221, 0x154, 0x7CD, 0xBF3, 0x112, 0x89B, 0xC5E,
+ 0x9CD, 0x07E, 0xFB6, 0x78F, 0x7FA, 0x16F, 0x377, 0x4B4,
+ 0x62D, 0x475, 0xBC2, 0x861, 0xB72, 0x9D0, 0x76A, 0x5A1,
+ 0x22A, 0xF74, 0xDBA, 0x8B1, 0x139, 0xDCD, 0x012, 0x293,
+ 0x705, 0xA34, 0xDD5, 0x3D2, 0x7F8, 0x0A6, 0x89A, 0x346,
+ 0xCE0, 0x690, 0x40E, 0xFF3, 0xC4D, 0x97F, 0x9C9, 0x016,
+ 0x73A, 0x923, 0xBCE, 0xFA9, 0xE6A, 0xB92, 0x02A, 0x07C,
+ 0x04B, 0x8D5, 0x753, 0x42E, 0x67E, 0x87C, 0xEE6, 0xD7D,
+ 0x2BF, 0xFB2, 0xFF8, 0x42F, 0x4CB, 0x214, 0x779, 0x02D,
+ 0x606, 0xA02, 0x08A, 0xD4F, 0xB87, 0xDDF, 0xC49, 0xB51,
+ 0x0E9, 0xF89, 0xAEF, 0xC92, 0x383, 0x98D, 0x367, 0xBD3,
+ 0xA55, 0x148, 0x9DB, 0x913, 0xC79, 0x6FF, 0x387, 0x6EA,
+ 0x7FA, 0xC1B, 0x12D, 0x303, 0xBCA, 0x503, 0x0FB, 0xB14,
+ 0x0D4, 0xAD1, 0xAFC, 0x9DD, 0x404, 0x145, 0x6E5, 0x8ED,
+ 0xF94, 0xD72, 0x645, 0xA21, 0x1A8, 0xABF, 0xC03, 0x91E,
+ 0xD53, 0x48C, 0x471, 0x4E4, 0x408, 0x33C, 0x5DF, 0x73D,
+ 0xA2A, 0x454, 0xD77, 0xC48, 0x2F5, 0x96A, 0x9CF, 0x047,
+ 0x611, 0xE92, 0xC2F, 0xA98, 0x56D, 0x919, 0x615, 0x535,
+ 0x67A, 0x8C1, 0x2E2, 0xBC4, 0xBE8, 0x328, 0x04F, 0x257,
+ 0x3F9, 0xFA5, 0x477, 0x12E, 0x94B, 0x116, 0xEF7, 0x65F,
+ 0x6B3, 0x915, 0xC64, 0x9AF, 0xB6C, 0x6A2, 0x50D, 0xEA3,
+ 0x26E, 0xC23, 0x817, 0xA42, 0x71A, 0x9DD, 0xDA8, 0x84D,
+ 0x3F3, 0x85B, 0xB00, 0x1FC, 0xB0A, 0xC2F, 0x00C, 0x095,
+ 0xC58, 0x0E3, 0x807, 0x962, 0xC4B, 0x29A, 0x6FC, 0x958,
+ 0xD29, 0x59E, 0xB14, 0x95A, 0xEDE, 0xF3D, 0xFB8, 0x0E5,
+ 0x348, 0x2E7, 0x38E, 0x56A, 0x410, 0x3B1, 0x4B0, 0x793,
+ 0xAB7, 0x0BC, 0x648, 0x719, 0xE3E, 0xFB4, 0x3B4, 0xE5C,
+ 0x950, 0xD2A, 0x50B, 0x76F, 0x8D2, 0x3C7, 0xECC, 0x87C,
+ 0x53A, 0xBA7, 0x4C3, 0x148, 0x437, 0x820, 0xECD, 0x660,
+ 0x095, 0x2F4, 0x661, 0x6A4, 0xB74, 0x5F3, 0x1D2, 0x7EC,
+ 0x8E2, 0xA40, 0xA6F, 0xFC3, 0x3BE, 0x1E9, 0x52C, 0x233,
+ 0x173, 0x4EF, 0xA7C, 0x40B, 0x14C, 0x88D, 0xF30, 0x8D9,
+ 0xBDB, 0x0A6, 0x940, 0xD46, 0xB2B, 0x03E, 0x46A, 0x641,
+ 0xF08, 0xAFF, 0x496, 0x68A, 0x7A4, 0x0BA, 0xD43, 0x515,
+ 0xB26, 0xD8F, 0x05C, 0xD6E, 0xA2C, 0xF25, 0x628, 0x4E5,
+ 0x81D, 0xA2A, 0x1FF, 0x302, 0xFBD, 0x6D9, 0x711, 0xD8B,
+ 0xE5C, 0x5CF, 0x42E, 0x008, 0x863, 0xB6F, 0x1E1, 0x3DA,
+ 0xACE, 0x82B, 0x2DB, 0x7EB, 0xC15, 0x79F, 0xA79, 0xDAF,
+ 0x00D, 0x2F6, 0x0CE, 0x370, 0x7E8, 0x9E6, 0x89F, 0xAE9,
+ 0x175, 0xA95, 0x06B, 0x9DF, 0xAFF, 0x45B, 0x823, 0xAA4,
+ 0xC79, 0x773, 0x886, 0x854, 0x0A5, 0x6D1, 0xE55, 0xEBB,
+ 0x518, 0xE50, 0xF8F, 0x8CC, 0x834, 0x388, 0xCD2, 0xFC1,
+ 0xA55, 0x1F8, 0xD1F, 0xE08, 0xF93, 0x362, 0xA22, 0x9FA,
+ 0xCE5, 0x3C3, 0xDD4, 0xC53, 0xB94, 0xAD0, 0x6EB, 0x68D,
+ 0x660, 0x8FC, 0xBCD, 0x914, 0x16F, 0x4C0, 0x134, 0xE1A,
+ 0x76F, 0x9CB, 0x660, 0xEA0, 0x320, 0x15A, 0xCE3, 0x7E8,
+ 0x03E, 0xB9A, 0xC90, 0xA14, 0x256, 0x1A8, 0x639, 0x7C6,
+ 0xA59, 0xA65, 0x956, 0x9E4, 0x592, 0x6A9, 0xCFF, 0x4DC,
+ 0xAA3, 0xD2A, 0xFDE, 0xA87, 0xBF5, 0x9F0, 0xC32, 0x94F,
+ 0x675, 0x9A6, 0x369, 0x648, 0x289, 0x823, 0x498, 0x574,
+ 0x8D1, 0xA13, 0xD1A, 0xBB5, 0xA19, 0x7F7, 0x775, 0x138,
+ 0x949, 0xA4C, 0xE36, 0x126, 0xC85, 0xE05, 0xFEE, 0x962,
+ 0x36D, 0x08D, 0xC76, 0x1E1, 0x1EC, 0x8D7, 0x231, 0xB68,
+ 0x03C, 0x1DE, 0x7DF, 0x2B1, 0x09D, 0xC81, 0xDA4, 0x8F7,
+ 0x6B9, 0x947, 0x9B0 };
+ [self testEncodeDecode:[ZXGenericGF AztecData12] dataWords:dataWords7 dataWordsLen:1229 ecWords:ecWords7 ecWordsLen:435];
+ // synthetic test cases
+ [self testEncodeDecodeRandom:[ZXGenericGF AztecParam] dataSize:2 ecSize:5]; // compact mode message
+ [self testEncodeDecodeRandom:[ZXGenericGF AztecParam] dataSize:4 ecSize:6]; // full mode message
+ [self testEncodeDecodeRandom:[ZXGenericGF AztecData6] dataSize:10 ecSize:7];
+ [self testEncodeDecodeRandom:[ZXGenericGF AztecData6] dataSize:20 ecSize:12];
+ [self testEncodeDecodeRandom:[ZXGenericGF AztecData8] dataSize:20 ecSize:11];
+ [self testEncodeDecodeRandom:[ZXGenericGF AztecData8] dataSize:128 ecSize:127];
+ [self testEncodeDecodeRandom:[ZXGenericGF AztecData10] dataSize:128 ecSize:128];
+ [self testEncodeDecodeRandom:[ZXGenericGF AztecData10] dataSize:768 ecSize:255];
+ [self testEncodeDecodeRandom:[ZXGenericGF AztecData12] dataSize:3072 ecSize:1023];
+}
+
+- (void)corrupt:(int *)received receivedLen:(int)receivedLen howMany:(int)howMany max:(int)max {
+ BOOL corrupted[receivedLen];
+ for (int i = 0; i < receivedLen; i++) {
+ corrupted[i] = NO;
+ }
+
+ for (int j = 0; j < howMany; j++) {
+ int location = rand() % receivedLen;
+ int value = rand() % max;
+ if (corrupted[location] || received[location] == value) {
+ j--;
+ } else {
+ corrupted[location] = YES;
+ received[location] = value;
+ }
+ }
+}
+
+- (void)testEncodeDecodeRandom:(ZXGenericGF *)field dataSize:(int)dataSize ecSize:(int)ecSize {
+ STAssertTrue(dataSize > 0 && dataSize <= field.size - 3, @"Invalid data size for %@", field);
+ STAssertTrue(ecSize > 0 && ecSize + dataSize <= field.size, @"Invalid ECC size for %@", field);
+ ZXReedSolomonEncoder *encoder = [[ZXReedSolomonEncoder alloc] initWithField:field];
+ int message[dataSize + ecSize];
+ int dataWords[dataSize];
+ int ecWords[ecSize];
+ srand(ReedSolomonTestCase_RANDOM_SEED);
+ int iterations = field.size > 256 ? 1 : DECODER_RANDOM_TEST_ITERATIONS;
+ for (int i = 0; i < iterations; i++) {
+ // generate random data
+ for (int k = 0; k < dataSize; k++) {
+ dataWords[k] = rand() % field.size;
+ }
+ // generate ECC words
+ memcpy(message, dataWords, dataSize * sizeof(int));
+ [encoder encode:message toEncodeLen:dataSize + ecSize ecBytes:ecSize];
+ memcpy(ecWords, message + dataSize, ecSize * sizeof(int));
+ // check to see if Decoder can fix up to ecWords/2 random errors
+ [self testDecoder:field dataWords:dataWords dataWordsLen:dataSize ecWords:ecWords ecWordsLen:ecSize];
+ }
+}
+
+- (void)testEncodeDecode:(ZXGenericGF *)field dataWords:(int *)dataWords dataWordsLen:(int)dataWordsLen ecWords:(int *)ecWords ecWordsLen:(int)ecWordsLen {
+ [self testEncoder:field dataWords:dataWords dataWordsLen:dataWordsLen ecWords:ecWords ecWordsLen:ecWordsLen];
+ [self testDecoder:field dataWords:dataWords dataWordsLen:dataWordsLen ecWords:ecWords ecWordsLen:ecWordsLen];
+}
+
+- (void)testEncoder:(ZXGenericGF *)field dataWords:(int *)dataWords dataWordsLen:(int)dataWordsLen ecWords:(int *)ecWords ecWordsLen:(int)ecWordsLen {
+ ZXReedSolomonEncoder *encoder = [[ZXReedSolomonEncoder alloc] initWithField:field];
+
+ int length = dataWordsLen + ecWordsLen;
+ int messageExpected[length];
+ int message[length];
+ memcpy(messageExpected, dataWords, dataWordsLen * sizeof(int));
+ memcpy(messageExpected + dataWordsLen, ecWords, ecWordsLen * sizeof(int));
+ memcpy(message, dataWords, dataWordsLen * sizeof(int));
+ [encoder encode:message toEncodeLen:length ecBytes:ecWordsLen];
+ [self assertDataEqualsExpected:messageExpected received:message length:length
+ message:[NSString stringWithFormat:@"Encode in %@ (%d,%d) failed", field, dataWordsLen, ecWordsLen]];
+}
+
+- (void)testDecoder:(ZXGenericGF *)field dataWords:(int *)dataWords dataWordsLen:(int)dataWordsLen ecWords:(int *)ecWords ecWordsLen:(int)ecWordsLen {
+ ZXReedSolomonDecoder *decoder = [[ZXReedSolomonDecoder alloc] initWithField:field];
+ int length = dataWordsLen + ecWordsLen;
+ int message[length];
+ int maxErrors = ecWordsLen / 2;
+ srand(ReedSolomonTestCase_RANDOM_SEED);
+ int iterations = field.size > 256 ? 1 : DECODER_TEST_ITERATIONS;
+ for (int j = 0; j < iterations; j++) {
+ for (int i = 0; i < ecWordsLen; i++) {
+ if (i > 10 && i < ecWordsLen / 2 - 10) {
+ // performance improvement - skip intermediate cases in long-running tests
+ i += ecWordsLen / 10;
+ }
+ memcpy(message, dataWords, dataWordsLen * sizeof(int));
+ memcpy(message + dataWordsLen, ecWords, ecWordsLen * sizeof(int));
+ [self corrupt:message receivedLen:length howMany:i max:field.size];
+
+ NSError *error;
+ if (![decoder decode:message receivedLen:length twoS:ecWordsLen error:&error]) {
+ // fail only if maxErrors exceeded
+ STAssertTrue(i > maxErrors, @"Decode in %@ (%d,%d) failed at %d errors: %@",
+ field, dataWordsLen, ecWordsLen, i, error);
+ // else stop
+ break;
+ }
+ if (i < maxErrors) {
+ [self assertDataEqualsExpected:dataWords received:message length:dataWordsLen
+ message:[NSString stringWithFormat:@"Decode in %@ (%d,%d) failed at %d errors", field, dataWordsLen, ecWordsLen, i]];
+ }
+ }
+ }
+}
+
+- (void)assertDataEqualsExpected:(int *)expected received:(int *)received length:(int)length message:(NSString *)message {
+ for (int i = 0; i < length; i++) {
+ if (expected[i] != received[i]) {
+ STFail(@"%@. Mismatch at %d. Expected %@, got %@", message, i, [self arrayToString:expected length:length], [self arrayToString:received length:length]);
+ }
+ }
+}
+
+- (NSString *)arrayToString:(int *)data length:(int)length {
+ NSMutableString *sb = [NSMutableString stringWithString:@"{"];
+ for (int i=0; i < length; i++) {
+ [sb appendFormat:i > 0 ? @",%X" : @"%X", data[i]];
+ }
+ [sb appendString:@"}"];
+
+ return [NSString stringWithString:sb];
+}
+
+@end
diff --git a/ZXingObjCTests/datamatrix/DataMatrixBlackBox1TestCase.h b/ZXingObjCTests/datamatrix/DataMatrixBlackBox1TestCase.h
new file mode 100644
index 0000000..396e20d
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/DataMatrixBlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface DataMatrixBlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/datamatrix/DataMatrixBlackBox1TestCase.m b/ZXingObjCTests/datamatrix/DataMatrixBlackBox1TestCase.m
new file mode 100644
index 0000000..0fd5500
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/DataMatrixBlackBox1TestCase.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 "DataMatrixBlackBox1TestCase.h"
+
+@implementation DataMatrixBlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/datamatrix-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ 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];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/datamatrix/DataMatrixBlackBox2TestCase.h b/ZXingObjCTests/datamatrix/DataMatrixBlackBox2TestCase.h
new file mode 100644
index 0000000..bdd3c88
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/DataMatrixBlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface DataMatrixBlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/datamatrix/DataMatrixBlackBox2TestCase.m b/ZXingObjCTests/datamatrix/DataMatrixBlackBox2TestCase.m
new file mode 100644
index 0000000..208a619
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/DataMatrixBlackBox2TestCase.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 "DataMatrixBlackBox2TestCase.h"
+
+@implementation DataMatrixBlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/datamatrix-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatDataMatrix];
+
+ if (self) {
+ [self addTest:8 tryHarderCount:15 maxMisreads:0 maxTryHarderMisreads:1 rotation:0.0f];
+ [self addTest:14 tryHarderCount:16 maxMisreads:0 maxTryHarderMisreads:1 rotation:90.0f];
+ [self addTest:14 tryHarderCount:15 maxMisreads:0 maxTryHarderMisreads:1 rotation:180.0f];
+ [self addTest:13 tryHarderCount:16 maxMisreads:0 maxTryHarderMisreads:1 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.h b/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.h
new file mode 100644
index 0000000..9ece930
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.h
@@ -0,0 +1,21 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXDataMatrixWriterTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.m b/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.m
new file mode 100644
index 0000000..766514d
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/ZXDataMatrixWriterTestCase.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 "ZXDataMatrixWriterTestCase.h"
+
+@implementation ZXDataMatrixWriterTestCase
+
+- (void)testDataMatrixImageWriter {
+ ZXEncodeHints *hints = [ZXEncodeHints hints];
+ hints.dataMatrixShape = [ZXSymbolShapeHint forceSquare];
+
+ int bigEnough = 64;
+ ZXDataMatrixWriter *writer = [[ZXDataMatrixWriter alloc] init];
+ ZXBitMatrix *matrix = [writer encode:@"Hello Google" format:kBarcodeFormatDataMatrix width:bigEnough height:bigEnough hints:hints error:nil];
+ STAssertNotNil(matrix, @"Matrix should not be nil");
+ STAssertTrue(bigEnough >= matrix.width, @"Matrix width should be less than %d", bigEnough);
+ STAssertTrue(bigEnough >= matrix.height, @"Matrix height should be less than %d", bigEnough);
+}
+
+- (void)testDataMatrixWriter {
+ ZXEncodeHints *hints = [ZXEncodeHints hints];
+ hints.dataMatrixShape = [ZXSymbolShapeHint forceSquare];
+
+ int bigEnough = 14;
+ ZXDataMatrixWriter *writer = [[ZXDataMatrixWriter alloc] init];
+ ZXBitMatrix *matrix = [writer encode:@"Hello Me" format:kBarcodeFormatDataMatrix width:bigEnough height:bigEnough hints:hints error:nil];
+ STAssertNotNil(matrix, @"Matrix should not be nil");
+ STAssertEquals(matrix.width, bigEnough, @"Expected matrix width to equal %d", bigEnough);
+ STAssertEquals(matrix.height, bigEnough, @"Expected matrix height to equal %d", bigEnough);
+}
+
+- (void)testDataMatrixTooSmall {
+ // The DataMatrix will not fit in this size, so the matrix should come back bigger
+ int tooSmall = 8;
+ ZXDataMatrixWriter *writer = [[ZXDataMatrixWriter alloc] init];
+ ZXBitMatrix *matrix = [writer encode:@"http://www.google.com/" format:kBarcodeFormatDataMatrix width:tooSmall height:tooSmall hints:nil error:nil];
+
+ STAssertNotNil(matrix, @"Matrix should not be nil");
+ STAssertTrue(tooSmall < matrix.width, @"Expected matrix width to be less than %d", tooSmall);
+ STAssertTrue(tooSmall < matrix.height, @"Expected matrix height to be less than %d", tooSmall);
+}
+
+@end
diff --git a/ZXingObjCTests/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParserTestCase.h b/ZXingObjCTests/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParserTestCase.h
new file mode 100644
index 0000000..fd93507
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParserTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXDataMatrixDecodedBitStreamParserTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParserTestCase.m b/ZXingObjCTests/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParserTestCase.m
new file mode 100644
index 0000000..b0995a8
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParserTestCase.m
@@ -0,0 +1,31 @@
+/*
+ * 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 "ZXDataMatrixDecodedBitStreamParserTestCase.h"
+
+@implementation ZXDataMatrixDecodedBitStreamParserTestCase
+
+- (void)testAsciiStandardDecode {
+ // ASCII characters 0-127 are encoded as the value + 1
+ int8_t bytes[6] = {
+ (int8_t) ('a' + 1), (int8_t) ('b' + 1), (int8_t) ('c' + 1),
+ (int8_t) ('A' + 1), (int8_t) ('B' + 1), (int8_t) ('C' + 1) };
+ NSString *decodedString = [ZXDataMatrixDecodedBitStreamParser decode:bytes length:6 error:nil].text;
+ NSString *expected = @"abcABC";
+ STAssertEqualObjects(decodedString, expected, @"Expected \"%@\" to equal \"%@\"", decodedString, expected);
+}
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixErrorCorrectionTestCase.h b/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixErrorCorrectionTestCase.h
new file mode 100644
index 0000000..3c89380
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixErrorCorrectionTestCase.h
@@ -0,0 +1,25 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+/**
+ * Tests for the ECC200 error correction.
+ */
+
+@interface ZXDataMatrixErrorCorrectionTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixErrorCorrectionTestCase.m b/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixErrorCorrectionTestCase.m
new file mode 100644
index 0000000..aa975a6
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXDataMatrixErrorCorrectionTestCase.m
@@ -0,0 +1,35 @@
+/*
+ * 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 "ZXDataMatrixErrorCorrectionTestCase.h"
+#import "ZXHighLevelEncodeTestCase.h"
+
+@implementation ZXDataMatrixErrorCorrectionTestCase
+
+- (void)testRS {
+ //Sample from Annexe R in ISO/IEC 16022:2000(E)
+ const char cw1[4] = {142, 164, 186, (char)NULL};
+ ZXSymbolInfo *symbolInfo = [ZXSymbolInfo lookup:3];
+ NSString *s = [ZXDataMatrixErrorCorrection encodeECC200:[NSString stringWithCString:cw1 encoding:NSISOLatin1StringEncoding] symbolInfo:symbolInfo];
+ STAssertEqualObjects([ZXHighLevelEncodeTestCase visualize:s], @"142 164 186 114 25 5 88 102", @"");
+
+ //"A" encoded (ASCII encoding + 2 padding characters)
+ const char cw2[4] = {66, 129, 70, (char)NULL};
+ s = [ZXDataMatrixErrorCorrection encodeECC200:[NSString stringWithCString:cw2 encoding:NSISOLatin1StringEncoding] symbolInfo:symbolInfo];
+ STAssertEqualObjects([ZXHighLevelEncodeTestCase visualize:s], @"66 129 70 138 234 82 82 95", @"");
+}
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXDebugPlacement.h b/ZXingObjCTests/datamatrix/encoder/ZXDebugPlacement.h
new file mode 100644
index 0000000..f4a1b70
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXDebugPlacement.h
@@ -0,0 +1,23 @@
+/*
+ * 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 ZXDebugPlacement : ZXDefaultPlacement
+
+- (NSString *)toBitFieldString;
+- (NSArray *)toBitFieldStringArray;
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXDebugPlacement.m b/ZXingObjCTests/datamatrix/encoder/ZXDebugPlacement.m
new file mode 100644
index 0000000..69c5fd5
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXDebugPlacement.m
@@ -0,0 +1,43 @@
+/*
+ * 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 "ZXDebugPlacement.h"
+
+@implementation ZXDebugPlacement
+
+- (NSString *)toBitFieldString {
+ NSMutableString *sb = [NSMutableString stringWithCapacity:self.bitsLen];
+ for (int i = 0; i < self.bitsLen; i++) {
+ [sb appendString:self.bits[i] == 1 ? @"1" : @"0"];
+ }
+ return [NSString stringWithString:sb];
+}
+
+- (NSArray *)toBitFieldStringArray {
+ NSMutableArray *array = [NSMutableArray arrayWithCapacity:self.numrows];
+ int startpos = 0;
+ for (int row = 0; row < self.numrows; row++) {
+ NSMutableString *sb = [NSMutableString stringWithCapacity:self.bitsLen];
+ for (int i = 0; i < self.numcols; i++) {
+ [sb appendString:self.bits[startpos + i] == 1 ? @"1" : @"0"];
+ }
+ [array addObject:[NSString stringWithString:sb]];
+ startpos += self.numcols;
+ }
+ return array;
+}
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXHighLevelEncodeTestCase.h b/ZXingObjCTests/datamatrix/encoder/ZXHighLevelEncodeTestCase.h
new file mode 100644
index 0000000..560bfe7
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXHighLevelEncodeTestCase.h
@@ -0,0 +1,27 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXHighLevelEncodeTestCase : SenTestCase
+
+/**
+ * Convert a string of char codewords into a different string which lists each character
+ * using its decimal value.
+ */
++ (NSString *)visualize:(NSString *)codewords;
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXHighLevelEncodeTestCase.m b/ZXingObjCTests/datamatrix/encoder/ZXHighLevelEncodeTestCase.m
new file mode 100644
index 0000000..fdf8110
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXHighLevelEncodeTestCase.m
@@ -0,0 +1,305 @@
+/*
+ * 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 "ZXHighLevelEncodeTestCase.h"
+
+static NSArray *TEST_SYMBOLS;
+
+@implementation ZXHighLevelEncodeTestCase
+
++ (void)initialize {
+ TEST_SYMBOLS = @[[[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:3 errorCodewords:5 matrixWidth:8 matrixHeight:8 dataRegions:1],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:5 errorCodewords:7 matrixWidth:10 matrixHeight:10 dataRegions:1],
+ /*rect*/[[ZXSymbolInfo alloc] initWithRectangular:YES dataCapacity:5 errorCodewords:7 matrixWidth:16 matrixHeight:6 dataRegions:1],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:8 errorCodewords:10 matrixWidth:12 matrixHeight:12 dataRegions:1],
+ /*rect*/[[ZXSymbolInfo alloc] initWithRectangular:YES dataCapacity:10 errorCodewords:11 matrixWidth:14 matrixHeight:6 dataRegions:2],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:13 errorCodewords:0 matrixWidth:0 matrixHeight:0 dataRegions:1],
+ [[ZXSymbolInfo alloc] initWithRectangular:NO dataCapacity:77 errorCodewords:0 matrixWidth:0 matrixHeight:0 dataRegions:1]];
+ //The last entries are fake entries to test special conditions with C40 encoding
+}
+
+- (void)useTestSymbols {
+ [ZXSymbolInfo overrideSymbolSet:TEST_SYMBOLS];
+}
+
+- (void)resetSymbols {
+ [ZXSymbolInfo overrideSymbolSet:[ZXSymbolInfo prodSymbols]];
+}
+
+- (void)testASCIIEncodation {
+ NSString *visualized = [self encodeHighLevel:@"123456"];
+ STAssertEqualObjects(visualized, @"142 164 186", @"");
+
+ visualized = [self encodeHighLevel:@"123456£"];
+ STAssertEqualObjects(visualized, @"142 164 186 235 36", @"");
+
+ visualized = [self encodeHighLevel:@"30Q324343430794<OQQ"];
+ STAssertEqualObjects(visualized, @"160 82 162 173 173 173 137 224 61 80 82 82", @"");
+}
+
+- (void)testC40EncodationBasic1 {
+ NSString *visualized = [self encodeHighLevel:@"AIMAIMAIM"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 254", @"");
+ //230 shifts to C40 encodation, 254 unlatches, "else" case
+}
+
+- (void)testC40EncodationBasic2 {
+ NSString *visualized = [self encodeHighLevel:@"AIMAIAB"];
+ STAssertEqualObjects(visualized, @"230 91 11 90 255 254 67 129", @"");
+ //"B" is normally encoded as "15" (one C40 value)
+ //"else" case: "B" is encoded as ASCII
+
+ visualized = [self encodeHighLevel:@"AIMAIAb"];
+ STAssertEqualObjects(visualized, @"66 74 78 66 74 66 99 129", @""); //Encoded as ASCII
+ //Alternative solution:
+ //STAssertEqualObjects(visualized, @"230 91 11 90 255 254 99 129", @"");
+ //"b" is normally encoded as "Shift 3, 2" (two C40 values)
+ //"else" case: "b" is encoded as ASCII
+
+ visualized = [self encodeHighLevel:@"AIMAIMAIMË"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 254 235 76", @"");
+ //Alternative solution:
+ //STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 11 9 254", @"");
+ //Expl: 230 = shift to C40, "91 11" = "AIM",
+ //"11 9" = "�" = "Shift 2, UpperShift, <char>
+ //"else" case
+
+ visualized = [self encodeHighLevel:@"AIMAIMAIMë"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 254 235 108", @""); //Activate when additional rectangulars are available
+ //Expl: 230 = shift to C40, "91 11" = "AIM",
+ //"�" in C40 encodes to: 1 30 2 11 which doesn't fit into a triplet
+ //"10 243" =
+ //254 = unlatch, 235 = Upper Shift, 108 = � = 0xEB/235 - 128 + 1
+ //"else" case
+}
+
+- (void)testC40EncodationSpecExample {
+ //Example in Figure 1 in the spec
+ NSString *visualized = [self encodeHighLevel:@"A1B2C3D4E5F6G7H8I9J0K1L2"];
+ STAssertEqualObjects(visualized, @"230 88 88 40 8 107 147 59 67 126 206 78 126 144 121 35 47 254", @"");
+}
+
+- (void)testC40EncodationSpecialCases1 {
+ //Special tests avoiding ultra-long test strings because these tests are only used
+ //with the 16x48 symbol (47 data codewords)
+ [self useTestSymbols];
+
+ NSString *visualized = [self encodeHighLevel:@"AIMAIMAIMAIMAIMAIM"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 91 11 91 11 91 11", @"");
+ //case "a": Unlatch is not required
+
+ visualized = [self encodeHighLevel:@"AIMAIMAIMAIMAIMAI"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 91 11 91 11 90 241", @"");
+ //case "b": Add trailing shift 0 and Unlatch is not required
+
+ visualized = [self encodeHighLevel:@"AIMAIMAIMAIMAIMA"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 91 11 91 11 254 66", @"");
+ //case "c": Unlatch and write last character in ASCII
+
+ [self resetSymbols];
+
+ visualized = [self encodeHighLevel:@"AIMAIMAIMAIMAIMAI"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 91 11 91 11 254 66 74 129 237", @"");
+
+ visualized = [self encodeHighLevel:@"AIMAIMAIMA"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 66", @"");
+ //case "d": Skip Unlatch and write last character in ASCII
+}
+
+- (void)testC40EncodationSpecialCases2 {
+ NSString *visualized = [self encodeHighLevel:@"AIMAIMAIMAIMAIMAIMAI"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 91 11 91 11 91 11 254 66 74", @"");
+ //available > 2, rest = 2 --> unlatch and encode as ASCII
+}
+
+- (void)testTextEncodation {
+ NSString *visualized = [self encodeHighLevel:@"aimaimaim"];
+ STAssertEqualObjects(visualized, @"239 91 11 91 11 91 11 254", @"");
+ //239 shifts to Text encodation, 254 unlatches
+
+ visualized = [self encodeHighLevel:@"aimaimaim'"];
+ STAssertEqualObjects(visualized, @"239 91 11 91 11 91 11 254 40 129", @"");
+ //assertEquals("239 91 11 91 11 91 11 7 49 254", visualized);
+ //This is an alternative, but doesn't strictly follow the rules in the spec.
+
+ visualized = [self encodeHighLevel:@"aimaimaIm"];
+ STAssertEqualObjects(visualized, @"239 91 11 91 11 87 218 110", @"");
+
+ visualized = [self encodeHighLevel:@"aimaimaimB"];
+ STAssertEqualObjects(visualized, @"239 91 11 91 11 91 11 254 67 129", @"");
+
+ visualized = [self encodeHighLevel:[NSString stringWithFormat:@"aimaimaim{txt}%c", (char)0x0004]];
+ STAssertEqualObjects(visualized, @"239 91 11 91 11 91 11 16 218 236 107 181 69 254 129 237", @"");
+}
+
+- (void)testX12Encodation {
+ //238 shifts to X12 encodation, 254 unlatches
+
+ NSString *visualized = [self encodeHighLevel:@"ABC>ABC123>AB"];
+ STAssertEqualObjects(visualized, @"238 89 233 14 192 100 207 44 31 67", @"");
+
+ visualized = [self encodeHighLevel:@"ABC>ABC123>ABC"];
+ STAssertEqualObjects(visualized, @"238 89 233 14 192 100 207 44 31 254 67 68", @"");
+
+ visualized = [self encodeHighLevel:@"ABC>ABC123>ABCD"];
+ STAssertEqualObjects(visualized, @"238 89 233 14 192 100 207 44 31 96 82 254", @"");
+
+ visualized = [self encodeHighLevel:@"ABC>ABC123>ABCDE"];
+ STAssertEqualObjects(visualized, @"238 89 233 14 192 100 207 44 31 96 82 70", @"");
+
+ visualized = [self encodeHighLevel:@"ABC>ABC123>ABCDEF"];
+ STAssertEqualObjects(visualized, @"238 89 233 14 192 100 207 44 31 96 82 254 70 71 129 237", @"");
+}
+
+- (void)testEDIFACTEncodation {
+ //240 shifts to EDIFACT encodation
+
+ NSString *visualized = [self encodeHighLevel:@".A.C1.3.DATA.123DATA.123DATA"];
+ STAssertEqualObjects(visualized, @"240 184 27 131 198 236 238 16 21 1 187 28 179 16 21 1 187 28 179 16 21 1", @"");
+
+ visualized = [self encodeHighLevel:@".A.C1.3.X.X2.."];
+ STAssertEqualObjects(visualized, @"240 184 27 131 198 236 238 98 230 50 47 47", @"");
+
+ visualized = [self encodeHighLevel:@".A.C1.3.X.X2."];
+ STAssertEqualObjects(visualized, @"240 184 27 131 198 236 238 98 230 50 47 129", @"");
+
+ visualized = [self encodeHighLevel:@".A.C1.3.X.X2"];
+ STAssertEqualObjects(visualized, @"240 184 27 131 198 236 238 98 230 50", @"");
+
+ visualized = [self encodeHighLevel:@".A.C1.3.X.X"];
+ STAssertEqualObjects(visualized, @"240 184 27 131 198 236 238 98 230 31", @"");
+
+ visualized = [self encodeHighLevel:@".A.C1.3.X."];
+ STAssertEqualObjects(visualized, @"240 184 27 131 198 236 238 98 231 192", @"");
+
+ visualized = [self encodeHighLevel:@".A.C1.3.X"];
+ STAssertEqualObjects(visualized, @"240 184 27 131 198 236 238 89", @"");
+
+ //Checking temporary unlatch from EDIFACT
+ visualized = [self encodeHighLevel:@".XXX.XXX.XXX.XXX.XXX.XXX.üXX.XXX.XXX.XXX.XXX.XXX.XXX"];
+ STAssertEqualObjects(visualized, @"240 185 134 24 185 134 24 185 134 24 185 134 24 185 134 24 185 134 24"
+ @" 124 47 235 125 240" //<-- this is the temporary unlatch
+ @" 97 139 152 97 139 152 97 139 152 97 139 152 97 139 152 97 139 152 89 89",
+ @"");
+}
+
+- (void)testBase256Encodation {
+ //231 shifts to Base256 encodation
+
+ NSString *visualized = [self encodeHighLevel:@"\u00ABäöüé\u00BB"];
+ STAssertEqualObjects(visualized, @"231 44 108 59 226 126 1 104", @"");
+ visualized = [self encodeHighLevel:@"\u00ABäöüéà\u00BB"];
+ STAssertEqualObjects(visualized, @"231 51 108 59 226 126 1 141 254 129", @"");
+ visualized = [self encodeHighLevel:@"\u00ABäöüéàá\u00BB"];
+ STAssertEqualObjects(visualized, @"231 44 108 59 226 126 1 141 36 147", @"");
+
+ visualized = [self encodeHighLevel:@" 23£"]; //ASCII only (for reference)
+ STAssertEqualObjects(visualized, @"33 153 235 36 129", @"");
+
+ visualized = [self encodeHighLevel:@"\u00ABäöüé\u00BB 234"]; //Mixed Base256 + ASCII
+ STAssertEqualObjects(visualized, @"231 51 108 59 226 126 1 104 99 153 53 129", @"");
+
+ visualized = [self encodeHighLevel:@"\u00ABäöüé\u00BB 23£ 1234567890123456789"];
+ STAssertEqualObjects(visualized, @"231 55 108 59 226 126 1 104 99 10 161 167 185 142 164 186 208"
+ @" 220 142 164 186 208 58 129 59 209 104 254 150 45", @"");
+
+ visualized = [self encodeHighLevel:[self createBinaryMessage:20]];
+ STAssertEqualObjects(visualized, @"231 44 108 59 226 126 1 141 36 5 37 187 80 230 123 17 166 60 210 103 253 150", @"");
+ visualized = [self encodeHighLevel:[self createBinaryMessage:19]]; //padding necessary at the end
+ STAssertEqualObjects(visualized, @"231 63 108 59 226 126 1 141 36 5 37 187 80 230 123 17 166 60 210 103 1 129", @"");
+
+ visualized = [self encodeHighLevel:[self createBinaryMessage:276]];
+ STAssertTrue([visualized hasPrefix:@"231 38 219 2 208 120 20 150 35"], @"");
+ STAssertTrue([visualized hasSuffix:@"146 40 194 129"], @"");
+
+ visualized = [self encodeHighLevel:[self createBinaryMessage:277]];
+ STAssertTrue([visualized hasPrefix:@"231 38 220 2 208 120 20 150 35"], @"");
+ STAssertTrue([visualized hasSuffix:@"146 40 190 87"], @"");
+}
+
+- (NSString *)createBinaryMessage:(int)len {
+ NSMutableString *sb = [NSMutableString string];
+ [sb appendString:@"\u00ABäöüéàá-"];
+ for (int i = 0; i < len - 9; i++) {
+ [sb appendFormat:@"%C", (unichar)0x00B7];
+ }
+ [sb appendString:@"\u00BB"];
+ return [NSString stringWithString:sb];
+}
+
+- (void)testUnlatchingFromC40 {
+ NSString *visualized = [self encodeHighLevel:@"AIMAIMAIMAIMaimaimaim"];
+ STAssertEqualObjects(visualized, @"230 91 11 91 11 91 11 254 66 74 78 239 91 11 91 11 91 11", @"");
+}
+
+- (void)testUnlatchingFromText {
+ NSString *visualized = [self encodeHighLevel:@"aimaimaimaim12345678"];
+ STAssertEqualObjects(visualized, @"239 91 11 91 11 91 11 91 11 254 142 164 186 208 129 237", @"");
+}
+
+- (void)testHelloWorld {
+ NSString *visualized = [self encodeHighLevel:@"Hello World!"];
+ STAssertEqualObjects(visualized, @"73 239 116 130 175 123 148 64 158 233 254 34", @"");
+}
+
+- (void)testBug1664266 {
+ //There was an exception and the encoder did not handle the unlatching from
+ //EDIFACT encoding correctly
+
+ NSString *visualized = [self encodeHighLevel:@"CREX-TAN:h"];
+ STAssertEqualObjects(visualized, @"240 13 33 88 181 64 78 124 59 105", @"");
+
+ visualized = [self encodeHighLevel:@"CREX-TAN:hh"];
+ STAssertEqualObjects(visualized, @"240 13 33 88 181 64 78 124 59 105 105 129", @"");
+
+ visualized = [self encodeHighLevel:@"CREX-TAN:hhh"];
+ STAssertEqualObjects(visualized, @"240 13 33 88 181 64 78 124 59 105 105 105", @"");
+}
+
+- (void)testBug3048549 {
+ //There was an IllegalArgumentException for an illegal character here because
+ //of an encoding problem of the character 0x0060 in Java source code.
+
+ NSString *visualized = [self encodeHighLevel:@"fiykmj*Rh2`,e6"];
+ STAssertEqualObjects(visualized, @"239 122 87 154 40 7 171 115 207 12 130 71 155 254 129 237", @"");
+}
+
+- (void)testMacroCharacters {
+ NSString *visualized = [self encodeHighLevel:[NSString stringWithFormat:@"[)>%C05%C5555%C6666%C%C",
+ (unichar)0x001E, (unichar)0x001D, (unichar)0x001C,
+ (unichar)0x001E, (unichar)0x0004]];
+ //STAssertEqualObjects(visualized, @"92 42 63 31 135 30 185 185 29 196 196 31 5 129 87 237", @"");
+ STAssertEqualObjects(visualized, @"236 185 185 29 196 196 129 56", @"");
+}
+
+- (NSString *)encodeHighLevel:(NSString *)msg {
+ NSString *encoded = [ZXHighLevelEncoder encodeHighLevel:msg];
+ //[ZXDecodeHighLevel decode:encoded];
+ return [[self class] visualize:encoded];
+}
+
++ (NSString *)visualize:(NSString *)codewords {
+ NSMutableString *sb = [NSMutableString string];
+ for (int i = 0; i < codewords.length; i++) {
+ if (i > 0) {
+ [sb appendString:@" "];
+ }
+ [sb appendFormat:@"%d", [codewords characterAtIndex:i] & 0xFF];
+ }
+ return [NSString stringWithString:sb];
+}
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXPlacementTestCase.h b/ZXingObjCTests/datamatrix/encoder/ZXPlacementTestCase.h
new file mode 100644
index 0000000..2f45eee
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXPlacementTestCase.h
@@ -0,0 +1,25 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+/**
+ * Tests the DataMatrix placement algorithm.
+ */
+
+@interface ZXPlacementTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXPlacementTestCase.m b/ZXingObjCTests/datamatrix/encoder/ZXPlacementTestCase.m
new file mode 100644
index 0000000..7134735
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXPlacementTestCase.m
@@ -0,0 +1,43 @@
+/*
+ * 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 "ZXDebugPlacement.h"
+#import "ZXPlacementTestCase.h"
+
+@implementation ZXPlacementTestCase
+
+- (void)testPlacement {
+ NSString *codewords = [self unvisualize:@"66 74 78 66 74 78 129 56 35 102 192 96 226 100 156 1 107 221"]; //"AIMAIM" encoded
+ ZXDebugPlacement *placement = [[ZXDebugPlacement alloc] initWithCodewords:codewords numcols:12 numrows:12];
+ [placement place];
+ NSArray *expected = @[@"011100001111", @"001010101000", @"010001010100", @"001010100010", @"000111000100",
+ @"011000010100", @"000100001101", @"011000010000", @"001100001101", @"100010010111",
+ @"011101011010", @"001011001010"];
+ NSArray *actual = [placement toBitFieldStringArray];
+ for (int i = 0; i < actual.count; i++) {
+ STAssertEqualObjects(actual[i], expected[i], @"Row %d", i);
+ }
+}
+
+- (NSString *)unvisualize:(NSString *)visualize {
+ NSMutableString *sb = [NSMutableString string];
+ for (NSString *token in [visualize componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]) {
+ [sb appendFormat:@"%C", (unichar)[token intValue]];
+ }
+ return [NSString stringWithString:sb];
+}
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXSymbolInfoTestCase.h b/ZXingObjCTests/datamatrix/encoder/ZXSymbolInfoTestCase.h
new file mode 100644
index 0000000..eefb010
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXSymbolInfoTestCase.h
@@ -0,0 +1,25 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+/**
+ * Tests the SymbolInfo class.
+ */
+
+@interface ZXSymbolInfoTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/datamatrix/encoder/ZXSymbolInfoTestCase.m b/ZXingObjCTests/datamatrix/encoder/ZXSymbolInfoTestCase.m
new file mode 100644
index 0000000..4ac279c
--- /dev/null
+++ b/ZXingObjCTests/datamatrix/encoder/ZXSymbolInfoTestCase.m
@@ -0,0 +1,95 @@
+/*
+ * 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 "ZXSymbolInfoTestCase.h"
+
+@implementation ZXSymbolInfoTestCase
+
+- (void)testSymbolInfo {
+ ZXSymbolInfo *info = [ZXSymbolInfo lookup:3];
+ STAssertEquals(info.errorCodewords, 5, @"");
+ STAssertEquals(info.matrixWidth, 8, @"");
+ STAssertEquals(info.matrixHeight, 8, @"");
+ STAssertEquals(info.symbolWidth, 10, @"");
+ STAssertEquals(info.symbolHeight, 10, @"");
+
+ info = [ZXSymbolInfo lookup:3 shape:[ZXSymbolShapeHint forceRectangle]];
+ STAssertEquals(info.errorCodewords, 7, @"");
+ STAssertEquals(info.matrixWidth, 16, @"");
+ STAssertEquals(info.matrixHeight, 6, @"");
+ STAssertEquals(info.symbolWidth, 18, @"");
+ STAssertEquals(info.symbolHeight, 8, @"");
+
+ info = [ZXSymbolInfo lookup:9];
+ STAssertEquals(info.errorCodewords, 11, @"");
+ STAssertEquals(info.matrixWidth, 14, @"");
+ STAssertEquals(info.matrixHeight, 6, @"");
+ STAssertEquals(info.symbolWidth, 32, @"");
+ STAssertEquals(info.symbolHeight, 8, @"");
+
+ info = [ZXSymbolInfo lookup:9 shape:[ZXSymbolShapeHint forceSquare]];
+ STAssertEquals(info.errorCodewords, 12, @"");
+ STAssertEquals(info.matrixWidth, 14, @"");
+ STAssertEquals(info.matrixHeight, 14, @"");
+ STAssertEquals(info.symbolWidth, 16, @"");
+ STAssertEquals(info.symbolHeight, 16, @"");
+
+ @try {
+ [ZXSymbolInfo lookup:1559];
+ STFail(@"There's no rectangular symbol for more than 1558 data codewords");
+ } @catch (NSException *exception) {
+ // expected
+ }
+
+ @try {
+ [ZXSymbolInfo lookup:50 shape:[ZXSymbolShapeHint forceRectangle]];
+ STFail(@"There's no rectangular symbol for 50 data codewords");
+ } @catch (NSException *exception) {
+ // expected
+ }
+
+ info = [ZXSymbolInfo lookup:35];
+ STAssertEquals(info.symbolWidth, 24, @"");
+ STAssertEquals(info.symbolHeight, 24, @"");
+
+ ZXDimension *fixedSize = [[ZXDimension alloc] initWithWidth:26 height:26];
+ info = [ZXSymbolInfo lookup:35 shape:[ZXSymbolShapeHint forceNone] minSize:fixedSize maxSize:fixedSize fail:NO];
+ STAssertEquals(info.symbolWidth, 26, @"");
+ STAssertEquals(info.symbolHeight, 26, @"");
+
+ info = [ZXSymbolInfo lookup:45 shape:[ZXSymbolShapeHint forceNone] minSize:fixedSize maxSize:fixedSize fail:NO];
+ STAssertNil(info, @"");
+
+ ZXDimension *minSize = fixedSize;
+ ZXDimension *maxSize = [[ZXDimension alloc] initWithWidth:32 height:32];
+
+ info = [ZXSymbolInfo lookup:35 shape:[ZXSymbolShapeHint forceNone] minSize:minSize maxSize:maxSize fail:NO];
+ STAssertEquals(info.symbolWidth, 26, @"");
+ STAssertEquals(info.symbolHeight, 26, @"");
+
+ info = [ZXSymbolInfo lookup:40 shape:[ZXSymbolShapeHint forceNone] minSize:minSize maxSize:maxSize fail:NO];
+ STAssertEquals(info.symbolWidth, 26, @"");
+ STAssertEquals(info.symbolHeight, 26, @"");
+
+ info = [ZXSymbolInfo lookup:45 shape:[ZXSymbolShapeHint forceNone] minSize:minSize maxSize:maxSize fail:NO];
+ STAssertEquals(info.symbolWidth, 32, @"");
+ STAssertEquals(info.symbolHeight, 32, @"");
+
+ info = [ZXSymbolInfo lookup:63 shape:[ZXSymbolShapeHint forceNone] minSize:minSize maxSize:maxSize fail:NO];
+ STAssertNil(info, @"");
+}
+
+@end
diff --git a/ZXingObjCTests/negative/FalsePositives2BlackBoxTestCase.h b/ZXingObjCTests/negative/FalsePositives2BlackBoxTestCase.h
new file mode 100644
index 0000000..49da653
--- /dev/null
+++ b/ZXingObjCTests/negative/FalsePositives2BlackBoxTestCase.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 "AbstractNegativeBlackBoxTestCase.h"
+
+@interface FalsePositives2BlackBoxTestCase : AbstractNegativeBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/negative/FalsePositives2BlackBoxTestCase.m b/ZXingObjCTests/negative/FalsePositives2BlackBoxTestCase.m
new file mode 100644
index 0000000..f4767aa
--- /dev/null
+++ b/ZXingObjCTests/negative/FalsePositives2BlackBoxTestCase.m
@@ -0,0 +1,38 @@
+/*
+ * 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 "FalsePositives2BlackBoxTestCase.h"
+
+@implementation FalsePositives2BlackBoxTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation testBasePathSuffix:@"Resources/blackbox/falsepositives-2"];
+
+ if (self) {
+ [self addTest:4 rotation:0.0f];
+ [self addTest:4 rotation:90.0f];
+ [self addTest:4 rotation:180.0f];
+ [self addTest:4 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/negative/FalsePositivesBlackBoxTestCase.h b/ZXingObjCTests/negative/FalsePositivesBlackBoxTestCase.h
new file mode 100644
index 0000000..b5a4577
--- /dev/null
+++ b/ZXingObjCTests/negative/FalsePositivesBlackBoxTestCase.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 "AbstractNegativeBlackBoxTestCase.h"
+
+@interface FalsePositivesBlackBoxTestCase : AbstractNegativeBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/negative/FalsePositivesBlackBoxTestCase.m b/ZXingObjCTests/negative/FalsePositivesBlackBoxTestCase.m
new file mode 100644
index 0000000..abbc105
--- /dev/null
+++ b/ZXingObjCTests/negative/FalsePositivesBlackBoxTestCase.m
@@ -0,0 +1,38 @@
+/*
+ * 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 "FalsePositivesBlackBoxTestCase.h"
+
+@implementation FalsePositivesBlackBoxTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation testBasePathSuffix:@"Resources/blackbox/falsepositives"];
+
+ if (self) {
+ [self addTest:2 rotation:0.0f];
+ [self addTest:2 rotation:90.0f];
+ [self addTest:2 rotation:180.0f];
+ [self addTest:2 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/negative/PartialBlackBoxTestCase.h b/ZXingObjCTests/negative/PartialBlackBoxTestCase.h
new file mode 100644
index 0000000..303895e
--- /dev/null
+++ b/ZXingObjCTests/negative/PartialBlackBoxTestCase.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 "AbstractNegativeBlackBoxTestCase.h"
+
+@interface PartialBlackBoxTestCase : AbstractNegativeBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/negative/PartialBlackBoxTestCase.m b/ZXingObjCTests/negative/PartialBlackBoxTestCase.m
new file mode 100644
index 0000000..5dc6ca1
--- /dev/null
+++ b/ZXingObjCTests/negative/PartialBlackBoxTestCase.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 "PartialBlackBoxTestCase.h"
+
+/**
+ * This test ensures that partial barcodes do not decode.
+ */
+@implementation PartialBlackBoxTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation testBasePathSuffix:@"Resources/blackbox/partial"];
+
+ if (self) {
+ [self addTest:2 rotation:0.0f];
+ [self addTest:2 rotation:90.0f];
+ [self addTest:2 rotation:180.0f];
+ [self addTest:2 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/negative/UnsupportedBlackBoxTestCase.h b/ZXingObjCTests/negative/UnsupportedBlackBoxTestCase.h
new file mode 100644
index 0000000..1451705
--- /dev/null
+++ b/ZXingObjCTests/negative/UnsupportedBlackBoxTestCase.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 "AbstractNegativeBlackBoxTestCase.h"
+
+@interface UnsupportedBlackBoxTestCase : AbstractNegativeBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/negative/UnsupportedBlackBoxTestCase.m b/ZXingObjCTests/negative/UnsupportedBlackBoxTestCase.m
new file mode 100644
index 0000000..4e54b86
--- /dev/null
+++ b/ZXingObjCTests/negative/UnsupportedBlackBoxTestCase.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 "UnsupportedBlackBoxTestCase.h"
+
+/**
+ * This test ensures that unsupported barcodes do not decode.
+ */
+@implementation UnsupportedBlackBoxTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation testBasePathSuffix:@"Resources/blackbox/unsupported"];
+
+ if (self) {
+ [self addTest:0 rotation:0.0f];
+ [self addTest:0 rotation:90.0f];
+ [self addTest:0 rotation:180.0f];
+ [self addTest:0 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/CodabarBlackBox1TestCase.h b/ZXingObjCTests/oned/CodabarBlackBox1TestCase.h
new file mode 100644
index 0000000..b0ba672
--- /dev/null
+++ b/ZXingObjCTests/oned/CodabarBlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface CodabarBlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/CodabarBlackbox1TestCase.m b/ZXingObjCTests/oned/CodabarBlackbox1TestCase.m
new file mode 100644
index 0000000..9bc16f2
--- /dev/null
+++ b/ZXingObjCTests/oned/CodabarBlackbox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "CodabarBlackBox1TestCase.h"
+
+@implementation CodabarBlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/codabar-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatCodabar];
+
+ if (self) {
+ [self addTest:11 tryHarderCount:11 rotation:0.0f];
+ [self addTest:11 tryHarderCount:11 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/Code128BlackBox1TestCase.h b/ZXingObjCTests/oned/Code128BlackBox1TestCase.h
new file mode 100644
index 0000000..735ab2b
--- /dev/null
+++ b/ZXingObjCTests/oned/Code128BlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface Code128BlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/Code128BlackBox1TestCase.m b/ZXingObjCTests/oned/Code128BlackBox1TestCase.m
new file mode 100644
index 0000000..4bdc892
--- /dev/null
+++ b/ZXingObjCTests/oned/Code128BlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "Code128BlackBox1TestCase.h"
+
+@implementation Code128BlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/code128-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatCode128];
+
+ if (self) {
+ [self addTest:5 tryHarderCount:5 rotation:0.0f];
+ [self addTest:5 tryHarderCount:5 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/Code128BlackBox2TestCase.h b/ZXingObjCTests/oned/Code128BlackBox2TestCase.h
new file mode 100644
index 0000000..999df40
--- /dev/null
+++ b/ZXingObjCTests/oned/Code128BlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface Code128BlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/Code128BlackBox2TestCase.m b/ZXingObjCTests/oned/Code128BlackBox2TestCase.m
new file mode 100644
index 0000000..50eda83
--- /dev/null
+++ b/ZXingObjCTests/oned/Code128BlackBox2TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "Code128BlackBox2TestCase.h"
+
+@implementation Code128BlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/code128-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatCode128];
+
+ if (self) {
+ [self addTest:36 tryHarderCount:39 rotation:0.0f];
+ [self addTest:36 tryHarderCount:39 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/Code128BlackBox3TestCase.h b/ZXingObjCTests/oned/Code128BlackBox3TestCase.h
new file mode 100644
index 0000000..8bf00b2
--- /dev/null
+++ b/ZXingObjCTests/oned/Code128BlackBox3TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface Code128BlackBox3TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/Code128BlackBox3TestCase.m b/ZXingObjCTests/oned/Code128BlackBox3TestCase.m
new file mode 100644
index 0000000..80b9e98
--- /dev/null
+++ b/ZXingObjCTests/oned/Code128BlackBox3TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "Code128BlackBox3TestCase.h"
+
+@implementation Code128BlackBox3TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/code128-3"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatCode128];
+
+ if (self) {
+ [self addTest:2 tryHarderCount:2 rotation:0.0f];
+ [self addTest:2 tryHarderCount:2 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/Code39BlackBox1TestCase.h b/ZXingObjCTests/oned/Code39BlackBox1TestCase.h
new file mode 100644
index 0000000..ad8f498
--- /dev/null
+++ b/ZXingObjCTests/oned/Code39BlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface Code39BlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/Code39BlackBox1TestCase.m b/ZXingObjCTests/oned/Code39BlackBox1TestCase.m
new file mode 100644
index 0000000..da6fd0b
--- /dev/null
+++ b/ZXingObjCTests/oned/Code39BlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "Code39BlackBox1TestCase.h"
+
+@implementation Code39BlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/code39-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatCode39];
+
+ if (self) {
+ [self addTest:4 tryHarderCount:4 rotation:0.0f];
+ [self addTest:4 tryHarderCount:4 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/Code39BlackBox3TestCase.h b/ZXingObjCTests/oned/Code39BlackBox3TestCase.h
new file mode 100644
index 0000000..9f590c6
--- /dev/null
+++ b/ZXingObjCTests/oned/Code39BlackBox3TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface Code39BlackBox3TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/Code39BlackBox3TestCase.m b/ZXingObjCTests/oned/Code39BlackBox3TestCase.m
new file mode 100644
index 0000000..3333667
--- /dev/null
+++ b/ZXingObjCTests/oned/Code39BlackBox3TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "Code39BlackBox3TestCase.h"
+
+@implementation Code39BlackBox3TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/code39-3"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatCode39];
+
+ if (self) {
+ [self addTest:17 tryHarderCount:17 rotation:0.0f];
+ [self addTest:17 tryHarderCount:17 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/Code39ExtendedBlackBox2TestCase.h b/ZXingObjCTests/oned/Code39ExtendedBlackBox2TestCase.h
new file mode 100644
index 0000000..5e03e27
--- /dev/null
+++ b/ZXingObjCTests/oned/Code39ExtendedBlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface Code39ExtendedBlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/Code39ExtendedBlackBox2TestCase.m b/ZXingObjCTests/oned/Code39ExtendedBlackBox2TestCase.m
new file mode 100644
index 0000000..f30852a
--- /dev/null
+++ b/ZXingObjCTests/oned/Code39ExtendedBlackBox2TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "Code39ExtendedBlackBox2TestCase.h"
+
+@implementation Code39ExtendedBlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/code39-2"
+ barcodeReader:[[ZXCode39Reader alloc] initUsingCheckDigit:NO extendedMode:YES]
+ expectedFormat:kBarcodeFormatCode39];
+
+ if (self) {
+ [self addTest:2 tryHarderCount:2 rotation:0.0f];
+ [self addTest:2 tryHarderCount:2 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/Code93BlackBox1TestCase.h b/ZXingObjCTests/oned/Code93BlackBox1TestCase.h
new file mode 100644
index 0000000..91d2b55
--- /dev/null
+++ b/ZXingObjCTests/oned/Code93BlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface Code93BlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/Code93BlackBox1TestCase.m b/ZXingObjCTests/oned/Code93BlackBox1TestCase.m
new file mode 100644
index 0000000..0a45c75
--- /dev/null
+++ b/ZXingObjCTests/oned/Code93BlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "Code93BlackBox1TestCase.h"
+
+@implementation Code93BlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/code93-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatCode93];
+
+ if (self) {
+ [self addTest:3 tryHarderCount:3 rotation:0.0f];
+ [self addTest:3 tryHarderCount:3 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox1TestCase.h b/ZXingObjCTests/oned/EAN13BlackBox1TestCase.h
new file mode 100644
index 0000000..173528d
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface EAN13BlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox1TestCase.m b/ZXingObjCTests/oned/EAN13BlackBox1TestCase.m
new file mode 100644
index 0000000..3f78264
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "EAN13BlackBox1TestCase.h"
+
+@implementation EAN13BlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/ean13-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatEan13];
+
+ if (self) {
+ [self addTest:30 tryHarderCount:32 rotation:0.0f];
+ [self addTest:27 tryHarderCount:32 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox2TestCase.h b/ZXingObjCTests/oned/EAN13BlackBox2TestCase.h
new file mode 100644
index 0000000..a228748
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface EAN13BlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox2TestCase.m b/ZXingObjCTests/oned/EAN13BlackBox2TestCase.m
new file mode 100644
index 0000000..a22110d
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox2TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "EAN13BlackBox2TestCase.h"
+
+@implementation EAN13BlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/ean13-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatEan13];
+
+ if (self) {
+ [self addTest:12 tryHarderCount:17 maxMisreads:0 maxTryHarderMisreads:1 rotation:0.0f];
+ [self addTest:11 tryHarderCount:17 maxMisreads:0 maxTryHarderMisreads:1 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox3TestCase.h b/ZXingObjCTests/oned/EAN13BlackBox3TestCase.h
new file mode 100644
index 0000000..bbd90c0
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox3TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface EAN13BlackBox3TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox3TestCase.m b/ZXingObjCTests/oned/EAN13BlackBox3TestCase.m
new file mode 100644
index 0000000..b17c51e
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox3TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "EAN13BlackBox3TestCase.h"
+
+@implementation EAN13BlackBox3TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/ean13-3"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatEan13];
+
+ if (self) {
+ [self addTest:53 tryHarderCount:55 rotation:0.0f];
+ [self addTest:55 tryHarderCount:55 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox4TestCase.h b/ZXingObjCTests/oned/EAN13BlackBox4TestCase.h
new file mode 100644
index 0000000..de1007d
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox4TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface EAN13BlackBox4TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox4TestCase.m b/ZXingObjCTests/oned/EAN13BlackBox4TestCase.m
new file mode 100644
index 0000000..e4f82d9
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox4TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "EAN13BlackBox4TestCase.h"
+
+@implementation EAN13BlackBox4TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/ean13-4"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatEan13];
+
+ if (self) {
+ [self addTest:6 tryHarderCount:13 maxMisreads:1 maxTryHarderMisreads:1 rotation:0.0f];
+ [self addTest:7 tryHarderCount:13 maxMisreads:1 maxTryHarderMisreads:1 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox5BlurryTestCase.h b/ZXingObjCTests/oned/EAN13BlackBox5BlurryTestCase.h
new file mode 100644
index 0000000..e850d46
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox5BlurryTestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface EAN13BlackBox5BlurryTestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/EAN13BlackBox5BlurryTestCase.m b/ZXingObjCTests/oned/EAN13BlackBox5BlurryTestCase.m
new file mode 100644
index 0000000..5a32e2c
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN13BlackBox5BlurryTestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "EAN13BlackBox5BlurryTestCase.h"
+
+@implementation EAN13BlackBox5BlurryTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/ean13-5"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatEan13];
+
+ if (self) {
+ [self addTest:0 tryHarderCount:0 rotation:0.0f];
+ [self addTest:0 tryHarderCount:0 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/EAN8BlackBox1TestCase.h b/ZXingObjCTests/oned/EAN8BlackBox1TestCase.h
new file mode 100644
index 0000000..d8ece06
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN8BlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface EAN8BlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/EAN8BlackBox1TestCase.m b/ZXingObjCTests/oned/EAN8BlackBox1TestCase.m
new file mode 100644
index 0000000..cc8b7e8
--- /dev/null
+++ b/ZXingObjCTests/oned/EAN8BlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "EAN8BlackBox1TestCase.h"
+
+@implementation EAN8BlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/ean8-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatEan8];
+
+ if (self) {
+ [self addTest:8 tryHarderCount:8 rotation:0.0f];
+ [self addTest:8 tryHarderCount:8 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/ITFBlackBox1TestCase.h b/ZXingObjCTests/oned/ITFBlackBox1TestCase.h
new file mode 100644
index 0000000..a06889a
--- /dev/null
+++ b/ZXingObjCTests/oned/ITFBlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface ITFBlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/ITFBlackBox1TestCase.m b/ZXingObjCTests/oned/ITFBlackBox1TestCase.m
new file mode 100644
index 0000000..d70dfb0
--- /dev/null
+++ b/ZXingObjCTests/oned/ITFBlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "ITFBlackBox1TestCase.h"
+
+@implementation ITFBlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/itf-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatITF];
+
+ if (self) {
+ [self addTest:8 tryHarderCount:12 rotation:0.0f];
+ [self addTest:11 tryHarderCount:12 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/ITFBlackBox2TestCase.h b/ZXingObjCTests/oned/ITFBlackBox2TestCase.h
new file mode 100644
index 0000000..2a89e46
--- /dev/null
+++ b/ZXingObjCTests/oned/ITFBlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface ITFBlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/ITFBlackBox2TestCase.m b/ZXingObjCTests/oned/ITFBlackBox2TestCase.m
new file mode 100644
index 0000000..7705d2b
--- /dev/null
+++ b/ZXingObjCTests/oned/ITFBlackBox2TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "ITFBlackBox2TestCase.h"
+
+@implementation ITFBlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/itf-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatITF];
+
+ if (self) {
+ [self addTest:8 tryHarderCount:9 rotation:0.0f];
+ [self addTest:7 tryHarderCount:9 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox1TestCase.h b/ZXingObjCTests/oned/UPCABlackBox1TestCase.h
new file mode 100644
index 0000000..df72bc3
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCABlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox1TestCase.m b/ZXingObjCTests/oned/UPCABlackBox1TestCase.m
new file mode 100644
index 0000000..36718b1
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "UPCABlackBox1TestCase.h"
+
+@implementation UPCABlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upca-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatUPCA];
+
+ if (self) {
+ [self addTest:14 tryHarderCount:18 maxMisreads:0 maxTryHarderMisreads:1 rotation:0.0f];
+ [self addTest:16 tryHarderCount:18 maxMisreads:0 maxTryHarderMisreads:1 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox2TestCase.h b/ZXingObjCTests/oned/UPCABlackBox2TestCase.h
new file mode 100644
index 0000000..a0c348a
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCABlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox2TestCase.m b/ZXingObjCTests/oned/UPCABlackBox2TestCase.m
new file mode 100644
index 0000000..360ae4c
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox2TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "UPCABlackBox2TestCase.h"
+
+@implementation UPCABlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upca-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatUPCA];
+
+ if (self) {
+ [self addTest:30 tryHarderCount:36 maxMisreads:0 maxTryHarderMisreads:2 rotation:0.0f];
+ [self addTest:31 tryHarderCount:36 maxMisreads:0 maxTryHarderMisreads:2 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox3ReflectiveTestCase.h b/ZXingObjCTests/oned/UPCABlackBox3ReflectiveTestCase.h
new file mode 100644
index 0000000..52d6074
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox3ReflectiveTestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCABlackBox3ReflectiveTestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox3ReflectiveTestCase.m b/ZXingObjCTests/oned/UPCABlackBox3ReflectiveTestCase.m
new file mode 100644
index 0000000..8f95afb
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox3ReflectiveTestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "UPCABlackBox3ReflectiveTestCase.h"
+
+@implementation UPCABlackBox3ReflectiveTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upca-3"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatUPCA];
+
+ if (self) {
+ [self addTest:7 tryHarderCount:9 maxMisreads:0 maxTryHarderMisreads:2 rotation:0.0f];
+ [self addTest:8 tryHarderCount:9 maxMisreads:0 maxTryHarderMisreads:2 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox4TestCase.h b/ZXingObjCTests/oned/UPCABlackBox4TestCase.h
new file mode 100644
index 0000000..afb0609
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox4TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCABlackBox4TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox4TestCase.m b/ZXingObjCTests/oned/UPCABlackBox4TestCase.m
new file mode 100644
index 0000000..a63f7ce
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox4TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "UPCABlackBox4TestCase.h"
+
+@implementation UPCABlackBox4TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upca-4"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatUPCA];
+
+ if (self) {
+ [self addTest:9 tryHarderCount:11 maxMisreads:0 maxTryHarderMisreads:1 rotation:0.0f];
+ [self addTest:9 tryHarderCount:11 maxMisreads:0 maxTryHarderMisreads:1 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox5TestCase.h b/ZXingObjCTests/oned/UPCABlackBox5TestCase.h
new file mode 100644
index 0000000..dc9b97f
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox5TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCABlackBox5TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox5TestCase.m b/ZXingObjCTests/oned/UPCABlackBox5TestCase.m
new file mode 100644
index 0000000..980abb3
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox5TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "UPCABlackBox5TestCase.h"
+
+@implementation UPCABlackBox5TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upca-5"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatUPCA];
+
+ if (self) {
+ [self addTest:20 tryHarderCount:23 maxMisreads:0 maxTryHarderMisreads:0 rotation:0.0f];
+ [self addTest:22 tryHarderCount:23 maxMisreads:0 maxTryHarderMisreads:0 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox6BlurryTestCase.h b/ZXingObjCTests/oned/UPCABlackBox6BlurryTestCase.h
new file mode 100644
index 0000000..783c821
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox6BlurryTestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCABlackBox6BlurryTestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCABlackBox6BlurryTestCase.m b/ZXingObjCTests/oned/UPCABlackBox6BlurryTestCase.m
new file mode 100644
index 0000000..1f50773
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCABlackBox6BlurryTestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "UPCABlackBox6BlurryTestCase.h"
+
+@implementation UPCABlackBox6BlurryTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upca-6"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatUPCA];
+
+ if (self) {
+ [self addTest:0 tryHarderCount:0 rotation:0.0f];
+ [self addTest:0 tryHarderCount:0 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCEANExtensionBlackBox1TestCase.h b/ZXingObjCTests/oned/UPCEANExtensionBlackBox1TestCase.h
new file mode 100644
index 0000000..20af8f6
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCEANExtensionBlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCEANExtensionBlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCEANExtensionBlackBox1TestCase.m b/ZXingObjCTests/oned/UPCEANExtensionBlackBox1TestCase.m
new file mode 100644
index 0000000..b1e1918
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCEANExtensionBlackBox1TestCase.m
@@ -0,0 +1,38 @@
+/*
+ * 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 "UPCEANExtensionBlackBox1TestCase.h"
+
+@implementation UPCEANExtensionBlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upcean-extension-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatEan13];
+
+ if (self) {
+ [self addTest:2 tryHarderCount:2 rotation:0.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCEBlackBox1TestCase.h b/ZXingObjCTests/oned/UPCEBlackBox1TestCase.h
new file mode 100644
index 0000000..92c9ad5
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCEBlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCEBlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCEBlackBox1TestCase.m b/ZXingObjCTests/oned/UPCEBlackBox1TestCase.m
new file mode 100644
index 0000000..c585d1e
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCEBlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "UPCEBlackBox1TestCase.h"
+
+@implementation UPCEBlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upce-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatUPCE];
+
+ if (self) {
+ [self addTest:3 tryHarderCount:3 rotation:0.0f];
+ [self addTest:3 tryHarderCount:3 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCEBlackBox2TestCase.h b/ZXingObjCTests/oned/UPCEBlackBox2TestCase.h
new file mode 100644
index 0000000..d424251
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCEBlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCEBlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCEBlackBox2TestCase.m b/ZXingObjCTests/oned/UPCEBlackBox2TestCase.m
new file mode 100644
index 0000000..ff460cb
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCEBlackBox2TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "UPCEBlackBox2TestCase.h"
+
+@implementation UPCEBlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upce-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatUPCE];
+
+ if (self) {
+ [self addTest:31 tryHarderCount:35 maxMisreads:0 maxTryHarderMisreads:1 rotation:0.0f];
+ [self addTest:31 tryHarderCount:35 maxMisreads:1 maxTryHarderMisreads:1 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/UPCEBlackBox3ReflectiveTestCase.h b/ZXingObjCTests/oned/UPCEBlackBox3ReflectiveTestCase.h
new file mode 100644
index 0000000..bb81bba
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCEBlackBox3ReflectiveTestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface UPCEBlackBox3ReflectiveTestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/UPCEBlackBox3ReflectiveTestCase.m b/ZXingObjCTests/oned/UPCEBlackBox3ReflectiveTestCase.m
new file mode 100644
index 0000000..191c710
--- /dev/null
+++ b/ZXingObjCTests/oned/UPCEBlackBox3ReflectiveTestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "UPCEBlackBox3ReflectiveTestCase.h"
+
+@implementation UPCEBlackBox3ReflectiveTestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/upce-3"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatUPCE];
+
+ if (self) {
+ [self addTest:6 tryHarderCount:8 rotation:0.0f];
+ [self addTest:6 tryHarderCount:8 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/ZXCodaBarWriterTestCase.h b/ZXingObjCTests/oned/ZXCodaBarWriterTestCase.h
new file mode 100644
index 0000000..16c4771
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXCodaBarWriterTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXCodaBarWriterTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/ZXCodaBarWriterTestCase.m b/ZXingObjCTests/oned/ZXCodaBarWriterTestCase.m
new file mode 100644
index 0000000..ccc90b1
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXCodaBarWriterTestCase.m
@@ -0,0 +1,33 @@
+/*
+ * 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 "ZXCodaBarWriterTestCase.h"
+
+@implementation ZXCodaBarWriterTestCase
+
+- (void) testEncode {
+ // 1001001011 0 110101001 0 101011001 0 110101001 0 101001101 0 110010101 0 1101101011 0
+ // 1001001011
+ NSString *resultStr = @"0000000000"
+ @"1001001011011010100101010110010110101001010100110101100101010110110101101001001011"
+ @"0000000000";
+ ZXBitMatrix *result = [[[ZXCodaBarWriter alloc] init] encode:@"B515-3/N" format:kBarcodeFormatCodabar width:(int)resultStr.length height:0 error:nil];
+ for (int i = 0; i < resultStr.length; i++) {
+ STAssertEquals([result getX:i y:0], (BOOL)([resultStr characterAtIndex:i] == '1'), @"Element %d", i);
+ }
+}
+
+@end
diff --git a/ZXingObjCTests/oned/ZXEAN13WriterTestCase.h b/ZXingObjCTests/oned/ZXEAN13WriterTestCase.h
new file mode 100644
index 0000000..32297ae
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXEAN13WriterTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXEAN13WriterTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/ZXEAN13WriterTestCase.m b/ZXingObjCTests/oned/ZXEAN13WriterTestCase.m
new file mode 100644
index 0000000..67c1da2
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXEAN13WriterTestCase.m
@@ -0,0 +1,33 @@
+/*
+ * 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 "ZXEAN13WriterTestCase.h"
+
+@implementation ZXEAN13WriterTestCase
+
+- (void)testEncode {
+ NSString *testStr = @"00010100010110100111011001100100110111101001110101010110011011011001000010101110010011101000100101000";
+ ZXBitMatrix *result = [[[ZXEAN13Writer alloc] init] encode:@"5901234123457"
+ format:kBarcodeFormatEan13
+ width:(int)testStr.length
+ height:0
+ error:nil];
+ for (int i = 0; i < testStr.length; i++) {
+ STAssertEquals([result getX:i y:0], (BOOL)([testStr characterAtIndex:i] == '1'), @"Element %d", i);
+ }
+}
+
+@end
diff --git a/ZXingObjCTests/oned/ZXEAN8WriterTestCase.h b/ZXingObjCTests/oned/ZXEAN8WriterTestCase.h
new file mode 100644
index 0000000..379766e
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXEAN8WriterTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXEAN8WriterTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/ZXEAN8WriterTestCase.m b/ZXingObjCTests/oned/ZXEAN8WriterTestCase.m
new file mode 100644
index 0000000..575a638
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXEAN8WriterTestCase.m
@@ -0,0 +1,33 @@
+/*
+ * 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 "ZXEAN8WriterTestCase.h"
+
+@implementation ZXEAN8WriterTestCase
+
+- (void)testEncode {
+ NSString *testStr = @"0001010001011010111101111010110111010101001110111001010001001011100101000";
+ ZXBitMatrix *result = [[[ZXEAN8Writer alloc] init] encode:@"96385074"
+ format:kBarcodeFormatEan8
+ width:(int)testStr.length
+ height:0
+ error:nil];
+ for (int i = 0; i < testStr.length; i++) {
+ STAssertEquals([result getX:i y:0], (BOOL)([testStr characterAtIndex:i] == '1'), @"Element %d", i);
+ }
+}
+
+@end
diff --git a/ZXingObjCTests/oned/ZXEANManufacturerOrgSupportTest.h b/ZXingObjCTests/oned/ZXEANManufacturerOrgSupportTest.h
new file mode 100644
index 0000000..b10e5cf
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXEANManufacturerOrgSupportTest.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXEANManufacturerOrgSupportTest : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/ZXEANManufacturerOrgSupportTest.m b/ZXingObjCTests/oned/ZXEANManufacturerOrgSupportTest.m
new file mode 100644
index 0000000..d7e8a00
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXEANManufacturerOrgSupportTest.m
@@ -0,0 +1,30 @@
+/*
+ * 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 "ZXEANManufacturerOrgSupportTest.h"
+
+@implementation ZXEANManufacturerOrgSupportTest
+
+- (void)testEncode {
+ ZXEANManufacturerOrgSupport *support = [[ZXEANManufacturerOrgSupport alloc] init];
+ STAssertNil([support lookupCountryIdentifier:@"472000"], @"Expected country identifier to be nil");
+ STAssertEqualObjects([support lookupCountryIdentifier:@"000000"], @"US/CA", @"Expected country identifier to be US/CA");
+ STAssertEqualObjects([support lookupCountryIdentifier:@"958000"], @"MO", @"Expected country identifier to be MO");
+ STAssertEqualObjects([support lookupCountryIdentifier:@"500000"], @"GB", @"Expected country identifier to be GB");
+ STAssertEqualObjects([support lookupCountryIdentifier:@"509000"], @"GB", @"Expected country identifier to be GB");
+}
+
+@end
diff --git a/ZXingObjCTests/oned/ZXUPCAWriterTestCase.h b/ZXingObjCTests/oned/ZXUPCAWriterTestCase.h
new file mode 100644
index 0000000..0561d64
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXUPCAWriterTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXUPCAWriterTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/ZXUPCAWriterTestCase.m b/ZXingObjCTests/oned/ZXUPCAWriterTestCase.m
new file mode 100644
index 0000000..8988fc1
--- /dev/null
+++ b/ZXingObjCTests/oned/ZXUPCAWriterTestCase.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 "ZXUPCAWriterTestCase.h"
+
+@implementation ZXUPCAWriterTestCase
+
+- (void)testEncode {
+ NSString *testStr = @"00010101000110110111011000100010110101111011110101010111001011101001001110110011011011001011100101000";
+ ZXBitMatrix *result = [[[ZXUPCAWriter alloc] init] encode:@"485963095124"
+ format:kBarcodeFormatUPCA
+ width:(int)testStr.length
+ height:0
+ error:nil];
+ for (int i = 0; i < testStr.length; i++) {
+ BOOL expected = [testStr characterAtIndex:i] == '1';
+ STAssertEquals([result getX:i y:0], expected, @"Expected (%d, 0) to be %d", i, expected);
+ }
+}
+
+- (void)testAddChecksumAndEncode {
+ NSString *testStr = @"00010100110010010011011110101000110110001010111101010100010010010001110100111001011001101101100101000";
+ ZXBitMatrix *result = [[[ZXUPCAWriter alloc] init] encode:@"12345678901"
+ format:kBarcodeFormatUPCA
+ width:(int)testStr.length
+ height:0
+ error:nil];
+ for (int i = 0; i < testStr.length; i++) {
+ BOOL expected = [testStr characterAtIndex:i] == '1';
+ STAssertEquals([result getX:i y:0], expected, @"Expected (%d, 0) to be %d", i, expected);
+ }
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/RSS14BlackBox1TestCase.h b/ZXingObjCTests/oned/rss/RSS14BlackBox1TestCase.h
new file mode 100644
index 0000000..863bd28
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/RSS14BlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface RSS14BlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/RSS14BlackBox1TestCase.m b/ZXingObjCTests/oned/rss/RSS14BlackBox1TestCase.m
new file mode 100644
index 0000000..086d067
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/RSS14BlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "RSS14BlackBox1TestCase.h"
+
+@implementation RSS14BlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/rss14-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatRSS14];
+
+ if (self) {
+ [self addTest:6 tryHarderCount:6 rotation:0.0f];
+ [self addTest:6 tryHarderCount:6 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/RSS14BlackBox2TestCase.h b/ZXingObjCTests/oned/rss/RSS14BlackBox2TestCase.h
new file mode 100644
index 0000000..2e0cde6
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/RSS14BlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface RSS14BlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/RSS14BlackBox2TestCase.m b/ZXingObjCTests/oned/rss/RSS14BlackBox2TestCase.m
new file mode 100644
index 0000000..fb91a96
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/RSS14BlackBox2TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "RSS14BlackBox2TestCase.h"
+
+@implementation RSS14BlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/rss14-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatRSS14];
+
+ if (self) {
+ [self addTest:4 tryHarderCount:8 maxMisreads:1 maxTryHarderMisreads:1 rotation:0.0f];
+ [self addTest:2 tryHarderCount:8 maxMisreads:0 maxTryHarderMisreads:1 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox1TestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox1TestCase.h
new file mode 100644
index 0000000..063b929
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface RSSExpandedBlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox1TestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox1TestCase.m
new file mode 100644
index 0000000..8309b22
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "RSSExpandedBlackBox1TestCase.h"
+
+@implementation RSSExpandedBlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/rssexpanded-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatRSSExpanded];
+
+ if (self) {
+ [self addTest:32 tryHarderCount:32 rotation:0.0f];
+ [self addTest:32 tryHarderCount:32 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox2TestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox2TestCase.h
new file mode 100644
index 0000000..0c38aed
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface RSSExpandedBlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox2TestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox2TestCase.m
new file mode 100644
index 0000000..b09d7f7
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox2TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "RSSExpandedBlackBox2TestCase.h"
+
+@implementation RSSExpandedBlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/rssexpanded-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatRSSExpanded];
+
+ if (self) {
+ [self addTest:21 tryHarderCount:23 rotation:0.0f];
+ [self addTest:21 tryHarderCount:23 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox3TestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox3TestCase.h
new file mode 100644
index 0000000..c18449c
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox3TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface RSSExpandedBlackBox3TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox3TestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox3TestCase.m
new file mode 100644
index 0000000..8c9c9e6
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedBlackBox3TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "RSSExpandedBlackBox3TestCase.h"
+
+@implementation RSSExpandedBlackBox3TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/rssexpanded-3"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatRSSExpanded];
+
+ if (self) {
+ [self addTest:117 tryHarderCount:117 rotation:0.0f];
+ [self addTest:117 tryHarderCount:117 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2binaryTestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2binaryTestCase.h
new file mode 100644
index 0000000..e9e14fb
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2binaryTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface RSSExpandedImage2binaryTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2binaryTestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2binaryTestCase.m
new file mode 100644
index 0000000..196db3f
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2binaryTestCase.m
@@ -0,0 +1,192 @@
+/*
+ * 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 "RSSExpandedImage2binaryTestCase.h"
+
+@implementation RSSExpandedImage2binaryTestCase
+
+- (void)testDecodeRow2binary_1 {
+ // (11)100224(17)110224(3102)000100
+ NSString *path = @"Resources/blackbox/rssexpanded-1/1.png";
+ NSString *expected = @" ...X...X .X....X. .XX...X. X..X...X ...XX.X. ..X.X... ..X.X..X ...X..X. X.X....X .X....X. .....X.. X...X...";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_2 {
+ // (01)90012345678908(3103)001750
+ NSString *path = @"Resources/blackbox/rssexpanded-1/2.png";
+ NSString *expected = @" ..X..... ......X. .XXX.X.X .X...XX. XXXXX.XX XX.X.... .XX.XX.X .XX.";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_3 {
+ // (10)12A
+ NSString *path = @"Resources/blackbox/rssexpanded-1/3.png";
+ NSString *expected = @" .......X ..XX..X. X.X....X .......X ....";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_4 {
+ // (01)98898765432106(3202)012345(15)991231
+ NSString *path = @"Resources/blackbox/rssexpanded-1/4.png";
+ NSString *expected = @" ..XXXX.X XX.XXXX. .XXX.XX. XX..X... .XXXXX.. XX.X..X. ..XX..XX XX.X.XXX X..XX..X .X.XXXXX XXXX";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_5 {
+ // (01)90614141000015(3202)000150
+ NSString *path = @"Resources/blackbox/rssexpanded-1/5.png";
+ NSString *expected = @" ..X.X... .XXXX.X. XX..XXXX ....XX.. X....... ....X... ....X..X .XX.";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_10 {
+ // (01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012
+ NSString *path = @"Resources/blackbox/rssexpanded-1/10.png";
+ NSString *expected = @" .X.XX..X XX.XXXX. .XXX.XX. XX..X... .XXXXX.. XX.X..X. ..XX...X XX.X.... X.X.X.X. X.X..X.X .X....X. XX...X.. ...XX.X. .XXXXXX. .X..XX.. X.X.X... .X...... XXXX.... XX.XX... XXXXX.X. ...XXXXX .....X.X ...X.... X.XXX..X X.X.X... XX.XX..X .X..X..X .X.X.X.X X.XX...X .XX.XXX. XXX.X.XX ..X.";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_11 {
+ // (01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456
+ NSString *expected = @" .X.XX..X XX.XXXX. .XXX.XX. XX..X... .XXXXX.. XX.X..X. ..XX...X XX.X.... X.X.X.X. X.X..X.X .X....X. XX...X.. ...XX.X. .XXXXXX. .X..XX.. X.X.X... .X...... XXXX.... XX.XX... XXXXX.X. ...XXXXX .....X.X ...X.... X.XXX..X X.X.X... ....";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/11.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_12 {
+ // (01)98898765432106(3103)001750
+
+ NSString *expected = @" ..X..XX. XXXX..XX X.XX.XX. .X....XX XXX..XX. X..X.... .XX.XX.X .XX.";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/12.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_13 {
+ // (01)90012345678908(3922)795
+
+ NSString *expected = @" ..XX..X. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. X.X.XXXX .X..X..X ......X.";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/13.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_14 {
+ // (01)90012345678908(3932)0401234
+
+ NSString *expected = @" ..XX.X.. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. X.....X. X.....X. X.X.X.XX .X...... X...";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/14.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_15 {
+ // (01)90012345678908(3102)001750(11)100312
+
+ NSString *expected = @" ..XXX... ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/15.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_16 {
+ // (01)90012345678908(3202)001750(11)100312
+
+ NSString *expected = @" ..XXX..X ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/16.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_17 {
+ // (01)90012345678908(3102)001750(13)100312
+
+ NSString *expected = @" ..XXX.X. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/17.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_18 {
+ // (01)90012345678908(3202)001750(13)100312
+
+ NSString *expected = @" ..XXX.XX ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/18.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_19 {
+ // (01)90012345678908(3102)001750(15)100312
+
+ NSString *expected = @" ..XXXX.. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/19.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_20 {
+ // (01)90012345678908(3202)001750(15)100312
+
+ NSString *expected = @" ..XXXX.X ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/20.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_21 {
+ // (01)90012345678908(3102)001750(17)100312
+
+ NSString *expected = @" ..XXXXX. ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/21.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)testDecodeRow2binary_22 {
+ // (01)90012345678908(3202)001750(17)100312
+
+ NSString *expected = @" ..XXXXXX ........ .X..XXX. X.X.X... XX.XXXXX .XXXX.X. ..XX...X .X.....X .XX..... XXXX.X.. XX..";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/22.png";
+
+ [self assertCorrectImage2binary:path expected:expected];
+}
+
+- (void)assertCorrectImage2binary:(NSString *)path expected:(NSString *)expected {
+ ZXImage *image = [[ZXImage alloc] initWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:path withExtension:nil]];
+ ZXBinaryBitmap *binaryMap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXGlobalHistogramBinarizer alloc] initWithSource:[[ZXCGImageLuminanceSource alloc] initWithZXImage:image]]];
+ int rowNumber = binaryMap.height / 2;
+ ZXBitArray *row = [binaryMap blackRow:rowNumber row:nil error:nil];
+
+ ZXRSSExpandedReader *rssExpandedReader = [[ZXRSSExpandedReader alloc] init];
+ NSArray *pairs = [rssExpandedReader decodeRow2pairs:rowNumber row:row];
+ if (!pairs) {
+ STFail(@"Unable to decode pairs");
+ return;
+ }
+ ZXBitArray *binary = [ZXBitArrayBuilder buildBitArray:pairs];
+ STAssertEqualObjects([binary description], expected, @"Expected %@ to equal %@", [binary description], expected);
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2resultTestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2resultTestCase.h
new file mode 100644
index 0000000..454c503
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2resultTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface RSSExpandedImage2resultTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2resultTestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2resultTestCase.m
new file mode 100644
index 0000000..2f0cc9f
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2resultTestCase.m
@@ -0,0 +1,54 @@
+/*
+ * 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 "RSSExpandedImage2resultTestCase.h"
+
+@implementation RSSExpandedImage2resultTestCase
+
+- (void)testDecodeRow2result_2 {
+ // (01)90012345678908(3103)001750
+ NSString *path = @"Resources/blackbox/rssexpanded-1/2.png";
+ ZXExpandedProductParsedResult *expected =
+ [ZXExpandedProductParsedResult expandedProductParsedResultWithRawText:@"(01)90012345678908(3103)001750" productID:@"90012345678908" sscc:nil lotNumber:nil productionDate:nil
+ packagingDate:nil bestBeforeDate:nil expirationDate:nil weight:@"001750"
+ weightType:ZX_KILOGRAM weightIncrement:@"3" price:nil priceIncrement:nil
+ priceCurrency:nil uncommonAIs:[NSMutableDictionary dictionary]];
+
+ [self assertCorrectImage2result:path expected:expected];
+}
+
+- (void)assertCorrectImage2result:(NSString *)path expected:(ZXExpandedProductParsedResult *)expected {
+ ZXImage *image = [[ZXImage alloc] initWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:path withExtension:nil]];
+ ZXBinaryBitmap *binaryMap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXGlobalHistogramBinarizer alloc] initWithSource:[[ZXCGImageLuminanceSource alloc] initWithZXImage:image]]];
+ int rowNumber = binaryMap.height / 2;
+ ZXBitArray *row = [binaryMap blackRow:rowNumber row:nil error:nil];
+
+ NSError *error;
+ ZXRSSExpandedReader *rssExpandedReader = [[ZXRSSExpandedReader alloc] init];
+ ZXResult *theResult = [rssExpandedReader decodeRow:rowNumber row:row hints:nil error:&error];
+ if (!theResult) {
+ STFail([error description]);
+ return;
+ }
+
+ STAssertEquals(theResult.barcodeFormat, kBarcodeFormatRSSExpanded, @"Expected format to be kBarcodeFormatRSSExpanded");
+
+ ZXParsedResult *result = [ZXResultParser parseResult:theResult];
+
+ STAssertEqualObjects(result, expected, @"Result does not match expected");
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2stringTestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2stringTestCase.h
new file mode 100644
index 0000000..e5bfc31
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2stringTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface RSSExpandedImage2stringTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2stringTestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2stringTestCase.m
new file mode 100644
index 0000000..923b74f
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedImage2stringTestCase.m
@@ -0,0 +1,229 @@
+/*
+ * 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 "RSSExpandedImage2stringTestCase.h"
+
+@implementation RSSExpandedImage2stringTestCase
+
+- (void)testDecodeRow2string_1 {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/1.png";
+ NSString *expected = @"(11)100224(17)110224(3102)000100";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_2 {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/2.png";
+ NSString *expected = @"(01)90012345678908(3103)001750";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_3 {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/3.png";
+ NSString *expected = @"(10)12A";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_4 {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/4.png";
+ NSString *expected = @"(01)98898765432106(3202)012345(15)991231";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_5 {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/5.png";
+ NSString *expected = @"(01)90614141000015(3202)000150";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_7 {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/7.png";
+ NSString *expected = @"(10)567(11)010101";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_10 {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/10.png";
+ NSString *expected = @"(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456(423)012345678901";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_11 {
+ NSString *expected = @"(01)98898765432106(15)991231(3103)001750(10)12A(422)123(21)123456";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/11.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_12 {
+ NSString *expected = @"(01)98898765432106(3103)001750";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/12.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_13 {
+ NSString *expected = @"(01)90012345678908(3922)795";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/13.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_14 {
+ NSString *expected = @"(01)90012345678908(3932)0401234";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/14.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_15 {
+ NSString *expected = @"(01)90012345678908(3102)001750(11)100312";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/15.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_16 {
+ NSString *expected = @"(01)90012345678908(3202)001750(11)100312";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/16.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_17 {
+ NSString *expected = @"(01)90012345678908(3102)001750(13)100312";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/17.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_18 {
+ NSString *expected = @"(01)90012345678908(3202)001750(13)100312";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/18.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_19 {
+ NSString *expected = @"(01)90012345678908(3102)001750(15)100312";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/19.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_20 {
+ NSString *expected = @"(01)90012345678908(3202)001750(15)100312";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/20.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_21 {
+ NSString *expected = @"(01)90012345678908(3102)001750(17)100312";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/21.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_22 {
+ NSString *expected = @"(01)90012345678908(3202)001750(17)100312";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/22.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_25 {
+ NSString *expected = @"(10)123";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/25.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_26 {
+ NSString *expected = @"(10)5678(11)010101";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/26.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_27 {
+ NSString *expected = @"(10)1098-1234";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/27.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_28 {
+ NSString *expected = @"(10)1098/1234";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/28.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_29 {
+ NSString *expected = @"(10)1098.1234";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/29.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_30 {
+ NSString *expected = @"(10)1098*1234";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/30.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_31 {
+ NSString *expected = @"(10)1098,1234";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/31.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)testDecodeRow2string_32 {
+ NSString *expected = @"(15)991231(3103)001750(10)12A(422)123(21)123456(423)0123456789012";
+ NSString *path = @"Resources/blackbox/rssexpanded-1/32.png";
+
+ [self assertCorrectImage2string:path expected:expected];
+}
+
+- (void)assertCorrectImage2string:(NSString *)path expected:(NSString *)expected {
+ ZXRSSExpandedReader *rssExpandedReader = [[ZXRSSExpandedReader alloc] init];
+
+ ZXImage *image = [[ZXImage alloc] initWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:path withExtension:nil]];
+ ZXBinaryBitmap *binaryMap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXGlobalHistogramBinarizer alloc] initWithSource:[[ZXCGImageLuminanceSource alloc] initWithZXImage:image]]];
+ int rowNumber = binaryMap.height / 2;
+ ZXBitArray *row = [binaryMap blackRow:rowNumber row:nil error:nil];
+
+ NSError *error = nil;
+ ZXResult *result = [rssExpandedReader decodeRow:rowNumber row:row hints:nil error:&error];
+ if (!result) {
+ STFail([error description]);
+ return;
+ }
+
+ STAssertEquals(result.barcodeFormat, kBarcodeFormatRSSExpanded, @"Expected barcode format to be kBarcodeFormatRSSExpanded");
+ STAssertEqualObjects(result.text, expected, @"Expected %@ to equal %@", result.text, expected);
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedInternalTestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedInternalTestCase.h
new file mode 100644
index 0000000..8693e6a
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedInternalTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface RSSExpandedInternalTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedInternalTestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedInternalTestCase.m
new file mode 100644
index 0000000..ecdb2ab
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedInternalTestCase.m
@@ -0,0 +1,109 @@
+/*
+ * 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 "RSSExpandedInternalTestCase.h"
+
+@implementation RSSExpandedInternalTestCase
+
+- (void)testFindFinderPatterns {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/2.png";
+ ZXImage *image = [[ZXImage alloc] initWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:path withExtension:nil]];
+ ZXBinaryBitmap *binaryMap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXGlobalHistogramBinarizer alloc] initWithSource:[[ZXCGImageLuminanceSource alloc] initWithZXImage:image]]];
+ int rowNumber = binaryMap.height / 2;
+ ZXBitArray *row = [binaryMap blackRow:rowNumber row:nil error:nil];
+ NSMutableArray *previousPairs = [NSMutableArray array];
+
+ ZXRSSExpandedReader *rssExpandedReader = [[ZXRSSExpandedReader alloc] init];
+ ZXExpandedPair *pair1 = [rssExpandedReader retrieveNextPair:row previousPairs:previousPairs rowNumber:rowNumber];
+ [previousPairs addObject:pair1];
+ ZXRSSFinderPattern *finderPattern = pair1.finderPattern;
+ STAssertNotNil(finderPattern, @"Expected finderPattern to be non-nil");
+ STAssertEquals(finderPattern.value, 0, @"Expected finderPattern to equal 0");
+
+ ZXExpandedPair *pair2 = [rssExpandedReader retrieveNextPair:row previousPairs:previousPairs rowNumber:rowNumber];
+ [previousPairs addObject:pair2];
+ finderPattern = pair2.finderPattern;
+ STAssertNotNil(finderPattern, @"Expected finderPattern to be non-nil");
+ STAssertEquals(finderPattern.value, 1, @"Expected finderPattern to equal 1");
+
+ ZXExpandedPair *pair3 = [rssExpandedReader retrieveNextPair:row previousPairs:previousPairs rowNumber:rowNumber];
+ [previousPairs addObject:pair3];
+ finderPattern = pair3.finderPattern;
+ STAssertNotNil(finderPattern, @"Expected finderPattern to be non-nil");
+ STAssertEquals(finderPattern.value, 1, @"Expected finderPattern to equal 1");
+
+ if ([rssExpandedReader retrieveNextPair:row previousPairs:previousPairs rowNumber:rowNumber]) {
+ // the previous was the last pair
+ STFail(@"Error expected");
+ }
+}
+
+- (void)testRetrieveNextPairPatterns {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/3.png";
+ ZXImage *image = [[ZXImage alloc] initWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:path withExtension:nil]];
+ ZXBinaryBitmap *binaryMap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXGlobalHistogramBinarizer alloc] initWithSource:[[ZXCGImageLuminanceSource alloc] initWithZXImage:image]]];
+ int rowNumber = binaryMap.height / 2;
+ ZXBitArray *row = [binaryMap blackRow:rowNumber row:nil error:nil];
+ NSMutableArray *previousPairs = [NSMutableArray array];
+
+ ZXRSSExpandedReader *rssExpandedReader = [[ZXRSSExpandedReader alloc] init];
+ ZXExpandedPair *pair1 = [rssExpandedReader retrieveNextPair:row previousPairs:previousPairs rowNumber:rowNumber];
+ [previousPairs addObject:pair1];
+ ZXRSSFinderPattern *finderPattern = pair1.finderPattern;
+ STAssertNotNil(finderPattern, @"Expected finderPattern to be non-nil");
+ STAssertEquals(finderPattern.value, 0, @"Expected finderPattern to equal 0");
+
+ ZXExpandedPair *pair2 = [rssExpandedReader retrieveNextPair:row previousPairs:previousPairs rowNumber:rowNumber];
+ [previousPairs addObject:pair2];
+ finderPattern = pair2.finderPattern;
+ STAssertNotNil(finderPattern, @"Expected finderPattern to be non-nil");
+ STAssertEquals(finderPattern.value, 0, @"Expected finderPattern to equal 0");
+}
+
+- (void)testDecodeCheckCharacter {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/3.png";
+ ZXImage *image = [[ZXImage alloc] initWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:path withExtension:nil]];
+ ZXBinaryBitmap *binaryMap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXGlobalHistogramBinarizer alloc] initWithSource:[[ZXCGImageLuminanceSource alloc] initWithZXImage:image]]];
+ ZXBitArray *row = [binaryMap blackRow:binaryMap.height / 2 row:nil error:nil];
+
+ NSMutableArray *startEnd = [@[@145, @243] mutableCopy];//image pixels where the A1 pattern starts (at 124) and ends (at 214)
+ int value = 0;// A
+ ZXRSSFinderPattern *finderPatternA1 = [[ZXRSSFinderPattern alloc] initWithValue:value startEnd:startEnd start:[startEnd[0] intValue] end:[startEnd[1] intValue] rowNumber:(int)image.height / 2];
+ //{1, 8, 4, 1, 1};
+ ZXRSSExpandedReader *rssExpandedReader = [[ZXRSSExpandedReader alloc] init];
+ ZXDataCharacter *dataCharacter = [rssExpandedReader decodeDataCharacter:row pattern:finderPatternA1 isOddPattern:YES leftChar:YES];
+
+ STAssertEquals(dataCharacter.value, 98, @"Expected dataCharacter.value to equal 98");
+}
+
+- (void)testDecodeDataCharacter {
+ NSString *path = @"Resources/blackbox/rssexpanded-1/3.png";
+ ZXImage *image = [[ZXImage alloc] initWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:path withExtension:nil]];
+ ZXBinaryBitmap *binaryMap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXGlobalHistogramBinarizer alloc] initWithSource:[[ZXCGImageLuminanceSource alloc] initWithZXImage:image]]];
+ ZXBitArray *row = [binaryMap blackRow:binaryMap.height / 2 row:nil error:nil];
+
+ NSMutableArray *startEnd = [NSMutableArray arrayWithObjects:@145, @243, nil];//image pixels where the A1 pattern starts (at 124) and ends (at 214)
+ int value = 0;// A
+ ZXRSSFinderPattern *finderPatternA1 = [[ZXRSSFinderPattern alloc] initWithValue:value startEnd:startEnd start:[startEnd[0] intValue] end:[startEnd[1] intValue] rowNumber:(int)image.height / 2];
+ //{1, 8, 4, 1, 1};
+ ZXRSSExpandedReader *rssExpandedReader = [[ZXRSSExpandedReader alloc] init];
+ ZXDataCharacter *dataCharacter = [rssExpandedReader decodeDataCharacter:row pattern:finderPatternA1 isOddPattern:YES leftChar:NO];
+
+ STAssertEquals(dataCharacter.value, 19, @"Expected dataCharacter.value to equal 19");
+ STAssertEquals(dataCharacter.checksumPortion, 1007, @"Expected dataCharacter.checksumPortion to equal 1007");
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox1TestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox1TestCase.h
new file mode 100644
index 0000000..876b27a
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface RSSExpandedStackedBlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox1TestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox1TestCase.m
new file mode 100644
index 0000000..dc39fe9
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "RSSExpandedStackedBlackBox1TestCase.h"
+
+@implementation RSSExpandedStackedBlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/rssexpandedstacked-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatRSSExpanded];
+
+ if (self) {
+ [self addTest:59 tryHarderCount:64 rotation:0.0f];
+ [self addTest:59 tryHarderCount:64 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox2TestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox2TestCase.h
new file mode 100644
index 0000000..6de2c61
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface RSSExpandedStackedBlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox2TestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox2TestCase.m
new file mode 100644
index 0000000..76a5904
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedBlackBox2TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "RSSExpandedStackedBlackBox2TestCase.h"
+
+@implementation RSSExpandedStackedBlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/rssexpandedstacked-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatRSSExpanded];
+
+ if (self) {
+ [self addTest:2 tryHarderCount:7 rotation:0.0f];
+ [self addTest:2 tryHarderCount:7 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedInternalTestCase.h b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedInternalTestCase.h
new file mode 100644
index 0000000..5683104
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedInternalTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface RSSExpandedStackedInternalTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedInternalTestCase.m b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedInternalTestCase.m
new file mode 100644
index 0000000..f3a0ad4
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/RSSExpandedStackedInternalTestCase.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 "RSSExpandedStackedInternalTestCase.h"
+#import "TestCaseUtil.h"
+
+@implementation RSSExpandedStackedInternalTestCase
+
+- (void)testDecodingRowByRow {
+ ZXRSSExpandedReader *rssExpandedReader = [[ZXRSSExpandedReader alloc] init];
+
+ ZXBinaryBitmap *binaryMap = [TestCaseUtil binaryBitmap:@"Resources/blackbox/rssexpandedstacked-2/1000.png"];
+
+ int firstRowNumber = [binaryMap height] / 3;
+ NSError *error = nil;
+ ZXBitArray *firstRow = [binaryMap blackRow:firstRowNumber row:nil error:&error];
+ STAssertNil(error, [error description]);
+
+ if ([rssExpandedReader decodeRow2pairs:firstRowNumber row:firstRow]) {
+ STFail(@"Not found error expected");
+ }
+
+ STAssertEquals([[rssExpandedReader rows] count], (NSUInteger)1, @"the first row not recognized");
+ ZXExpandedRow *firstExpandedRow = rssExpandedReader.rows[0];
+ STAssertEquals(firstExpandedRow.rowNumber, firstRowNumber, @"the first row number doesn't match");
+
+ STAssertEquals([firstExpandedRow.pairs count], (NSUInteger)2, @"wrong number if pairs in the first row");
+
+ [firstExpandedRow.pairs[1] finderPattern].startEnd[1] = @0;
+
+ int secondRowNumber = 2 * [binaryMap height] / 3;
+ error = nil;
+ ZXBitArray *secondRow = [binaryMap blackRow:secondRowNumber row:nil error:&error];
+ STAssertNil(error, [error description]);
+ [secondRow reverse];
+
+ NSMutableArray* totalPairs = [rssExpandedReader decodeRow2pairs:secondRowNumber row:secondRow];
+ error = nil;
+
+ ZXResult *result = [rssExpandedReader constructResult:totalPairs error:&error];
+ STAssertNil(error, [error description]);
+ STAssertEqualObjects(result.text, @"(01)98898765432106(3202)012345(15)991231", @"wrong result");
+}
+
+- (void)testCompleteDecoding {
+ ZXRSSExpandedReader *rssExpandedReader = [[ZXRSSExpandedReader alloc] init];
+
+ ZXBinaryBitmap *binaryMap = [TestCaseUtil binaryBitmap:@"Resources/blackbox/rssexpandedstacked-2/1000.png"];
+
+ NSError *error = nil;
+ ZXResult *result = [rssExpandedReader decode:binaryMap error:&error];
+ STAssertNil(error, [error description]);
+ STAssertEqualObjects(result.text, @"(01)98898765432106(3202)012345(15)991231", @"wrong result");
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/TestCaseUtil.h b/ZXingObjCTests/oned/rss/expanded/TestCaseUtil.h
new file mode 100644
index 0000000..4aa5183
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/TestCaseUtil.h
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+@class ZXBinaryBitmap;
+
+@interface TestCaseUtil : NSObject
+
++ (ZXBinaryBitmap *)binaryBitmap:(NSString *)path;
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/TestCaseUtil.m b/ZXingObjCTests/oned/rss/expanded/TestCaseUtil.m
new file mode 100644
index 0000000..7974635
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/TestCaseUtil.m
@@ -0,0 +1,26 @@
+/*
+ * 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 "TestCaseUtil.h"
+
+@implementation TestCaseUtil
+
++ (ZXBinaryBitmap *)binaryBitmap:(NSString *)path {
+ ZXImage *image = [[ZXImage alloc] initWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:path withExtension:nil]];
+ return [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXGlobalHistogramBinarizer alloc] initWithSource:[[ZXCGImageLuminanceSource alloc] initWithZXImage:image]]];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtil.h b/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtil.h
new file mode 100644
index 0000000..6de8b02
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtil.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@class ZXBitArray;
+
+@interface ZXBinaryUtil : NSObject
+
++ (ZXBitArray *)buildBitArrayFromString:(NSString *)data;
++ (ZXBitArray *)buildBitArrayFromStringWithoutSpaces:(NSString *)data;
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtil.m b/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtil.m
new file mode 100644
index 0000000..2479143
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtil.m
@@ -0,0 +1,66 @@
+/*
+ * 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 "ZXBinaryUtil.h"
+
+@implementation ZXBinaryUtil
+
+/*
+ * Constructs a BitArray from a String like the one returned from BitArray.toString()
+ */
++ (ZXBitArray *)buildBitArrayFromString:(NSString *)data {
+ NSString *dotsAndXs = [[data stringByReplacingOccurrencesOfString:@"1" withString:@"X"]
+ stringByReplacingOccurrencesOfString:@"0" withString:@"."];
+ ZXBitArray *binary = [[ZXBitArray alloc] initWithSize:(int)[dotsAndXs stringByReplacingOccurrencesOfString:@" " withString:@""].length];
+ int counter = 0;
+
+ for (int i = 0; i < dotsAndXs.length; ++i){
+ if(i % 9 == 0) { // spaces
+ if([dotsAndXs characterAtIndex:i] != ' ') {
+ @throw [NSException exceptionWithName:@"IllegalStateException" reason:@"space expected" userInfo:nil];
+ }
+ continue;
+ }
+
+ unichar currentChar = [dotsAndXs characterAtIndex:i];
+ if (currentChar == 'X' || currentChar == 'x') {
+ [binary set:counter];
+ }
+ counter++;
+ }
+ return binary;
+}
+
++ (ZXBitArray *)buildBitArrayFromStringWithoutSpaces:(NSString *)data {
+ NSMutableString *sb = [NSMutableString string];
+
+ NSString *dotsAndXs = [[data stringByReplacingOccurrencesOfString:@"1" withString:@"X"]
+ stringByReplacingOccurrencesOfString:@"0" withString:@"."];
+
+ int current = 0;
+ while (current < dotsAndXs.length) {
+ [sb appendString:@" "];
+ for (int i = 0; i < 8 && current < dotsAndXs.length; ++i){
+ [sb appendFormat:@"%C", [dotsAndXs characterAtIndex:current]];
+ current++;
+ }
+ }
+
+ return [self buildBitArrayFromString:sb];
+}
+
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtilTest.h b/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtilTest.h
new file mode 100644
index 0000000..a8f5876
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtilTest.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXBinaryUtilTest : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtilTest.m b/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtilTest.m
new file mode 100644
index 0000000..e79ea65
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/ZXBinaryUtilTest.m
@@ -0,0 +1,51 @@
+/*
+ * 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 "ZXBinaryUtil.h"
+#import "ZXBinaryUtilTest.h"
+
+@implementation ZXBinaryUtilTest
+
+- (void)testBuildBitArrayFromString {
+
+ NSString *data = @" ..X..X.. ..XXX... XXXXXXXX ........";
+ [self check:data];
+
+ data = @" XXX..X..";
+ [self check:data];
+
+ data = @" XX";
+ [self check:data];
+
+ data = @" ....XX.. ..XX";
+ [self check:data];
+
+ data = @" ....XX.. ..XX..XX ....X.X. ........";
+ [self check:data];
+}
+
+- (void)check:(NSString *)data {
+ ZXBitArray *binary = [ZXBinaryUtil buildBitArrayFromString:data];
+ STAssertEqualObjects([binary description], data, @"Expected %@ to equal %@", [binary description], data);
+}
+
+- (void)checkWithoutSpaces:(NSString *)data {
+ NSString *dataWithoutSpaces = [data stringByReplacingOccurrencesOfString:@" " withString:@""];
+ ZXBitArray *binary = [ZXBinaryUtil buildBitArrayFromStringWithoutSpaces:dataWithoutSpaces];
+ STAssertEqualObjects([binary description], data, @"Expected %@ to equal %@", [binary description], data);
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/ZXBitArrayBuilderTest.h b/ZXingObjCTests/oned/rss/expanded/ZXBitArrayBuilderTest.h
new file mode 100644
index 0000000..8c37798
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/ZXBitArrayBuilderTest.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXBitArrayBuilderTest : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/ZXBitArrayBuilderTest.m b/ZXingObjCTests/oned/rss/expanded/ZXBitArrayBuilderTest.m
new file mode 100644
index 0000000..4346cce
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/ZXBitArrayBuilderTest.m
@@ -0,0 +1,68 @@
+/*
+ * 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 "ZXBitArrayBuilderTest.h"
+
+@implementation ZXBitArrayBuilderTest
+
+- (void)testBuildBitArray1 {
+ int lengths[2] = {1, 2};
+ int pairValue1[1] = { 19 };
+ int pairValue2[2] = { 673, 16 };
+
+ int *pairValues[2];
+ pairValues[0] = pairValue1;
+ pairValues[1] = pairValue2;
+
+ NSString *expected = @" .......X ..XX..X. X.X....X .......X ....";
+
+ [self checkBinaryValues:pairValues pairValuesLen:2 lengths:lengths expected:expected];
+}
+
+- (void)checkBinaryValues:(int **)pairValues pairValuesLen:(int)pairValuesLen lengths:(int *)lengths expected:(NSString *)expected {
+ ZXBitArray *binary = [self buildBitArrayPairValues:pairValues pairValuesLen:pairValuesLen lengths:lengths];
+ STAssertEqualObjects([binary description], expected, @"Expected %@ to equal %@", [binary description], expected);
+}
+
+- (ZXBitArray *)buildBitArrayPairValues:(int **)pairValues pairValuesLen:(int)pairValuesLen lengths:(int *)lengths {
+ NSMutableArray *pairs = [NSMutableArray arrayWithCapacity:2];
+ for (int i = 0; i < pairValuesLen; ++i) {
+ int *pair = pairValues[i];
+
+ ZXDataCharacter *leftChar;
+ if (i == 0) {
+ leftChar = nil;
+ } else {
+ leftChar = [[ZXDataCharacter alloc] initWithValue:pair[0] checksumPortion:0];
+ }
+
+ ZXDataCharacter *rightChar;
+ if (i == 0) {
+ rightChar = [[ZXDataCharacter alloc] initWithValue:pair[0] checksumPortion:0];
+ } else if (lengths[i] == 2) {
+ rightChar = [[ZXDataCharacter alloc] initWithValue:pair[1] checksumPortion:0];
+ } else {
+ rightChar = nil;
+ }
+
+ ZXExpandedPair *expandedPair = [[ZXExpandedPair alloc] initWithLeftChar:leftChar rightChar:rightChar finderPattern:nil mayBeLast:YES];
+ [pairs addObject:expandedPair];
+ }
+
+ return [ZXBitArrayBuilder buildBitArray:pairs];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/ZXExpandedInformationDecoderTest.h b/ZXingObjCTests/oned/rss/expanded/ZXExpandedInformationDecoderTest.h
new file mode 100644
index 0000000..20a80b9
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/ZXExpandedInformationDecoderTest.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXExpandedInformationDecoderTest : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/ZXExpandedInformationDecoderTest.m b/ZXingObjCTests/oned/rss/expanded/ZXExpandedInformationDecoderTest.m
new file mode 100644
index 0000000..09c63ea
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/ZXExpandedInformationDecoderTest.m
@@ -0,0 +1,30 @@
+/*
+ * 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 "ZXBinaryUtil.h"
+#import "ZXExpandedInformationDecoderTest.h"
+
+@implementation ZXExpandedInformationDecoderTest
+
+- (void)testNoAi {
+ ZXBitArray *information = [ZXBinaryUtil buildBitArrayFromString:@" .......X ..XX..X. X.X....X .......X ...."];
+
+ ZXAbstractExpandedDecoder *decoder = [ZXAbstractExpandedDecoder createDecoder:information];
+ NSString *decoded = [decoder parseInformationWithError:nil];
+ STAssertEqualObjects(decoded, @"(10)12A", @"Expected %@ to equal \"(10)12A\"");
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3103_DecoderTest.h b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3103_DecoderTest.h
new file mode 100644
index 0000000..7e4b793
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3103_DecoderTest.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 "AbstractDecoderTest.h"
+
+@interface AI01_3103_DecoderTest : AbstractDecoderTest
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3103_DecoderTest.m b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3103_DecoderTest.m
new file mode 100644
index 0000000..80cd6a1
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3103_DecoderTest.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 "AI01_3103_DecoderTest.h"
+
+static NSString *header = @"..X..";
+
+@implementation AI01_3103_DecoderTest
+
+- (void)test01_3103_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@", header, compressedGtin_900123456798908, compressed15bitWeight_1750];
+ NSString *expected = @"(01)90012345678908(3103)001750";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_3103_2 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@", header, compressedGtin_900000000000008, compressed15bitWeight_0];
+ NSString *expected = @"(01)90000000000003(3103)000000";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_3103_invalid {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@..", header, compressedGtin_900123456798908, compressed15bitWeight_1750];
+
+ NSError *error;
+ if([self assertCorrectBinaryString:data expectedNumber:@"" error:&error] || error.code != ZXNotFoundError) {
+ STFail(@"NotFoundError expected");
+ }
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3202_3203_DecoderTest.h b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3202_3203_DecoderTest.h
new file mode 100644
index 0000000..087fadb
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3202_3203_DecoderTest.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 "AbstractDecoderTest.h"
+
+@interface AI01_3202_3203_DecoderTest : AbstractDecoderTest
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3202_3203_DecoderTest.m b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3202_3203_DecoderTest.m
new file mode 100644
index 0000000..e39864f
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3202_3203_DecoderTest.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 "AI01_3202_3203_DecoderTest.h"
+
+static NSString *header = @"..X.X";
+
+@implementation AI01_3202_3203_DecoderTest
+
+- (void)test01_3202_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@", header, compressedGtin_900123456798908, compressed15bitWeight_1750];
+ NSString *expected = @"(01)90012345678908(3202)001750";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_3203_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@", header, compressedGtin_900123456798908, compressed15bitWeight_11750];
+ NSString *expected = @"(01)90012345678908(3203)001750";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3X0X_1X_DecoderTest.h b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3X0X_1X_DecoderTest.h
new file mode 100644
index 0000000..3ad933e
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3X0X_1X_DecoderTest.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 "AbstractDecoderTest.h"
+
+@interface AI01_3X0X_1X_DecoderTest : AbstractDecoderTest
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3X0X_1X_DecoderTest.m b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3X0X_1X_DecoderTest.m
new file mode 100644
index 0000000..8961df5
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AI01_3X0X_1X_DecoderTest.m
@@ -0,0 +1,102 @@
+/*
+ * 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 "AI01_3X0X_1X_DecoderTest.h"
+
+static NSString *header_310x_11 = @"..XXX...";
+static NSString *header_320x_11 = @"..XXX..X";
+static NSString *header_310x_13 = @"..XXX.X.";
+static NSString *header_320x_13 = @"..XXX.XX";
+static NSString *header_310x_15 = @"..XXXX..";
+static NSString *header_320x_15 = @"..XXXX.X";
+static NSString *header_310x_17 = @"..XXXXX.";
+static NSString *header_320x_17 = @"..XXXXXX";
+
+@implementation AI01_3X0X_1X_DecoderTest
+
+- (void)test01_310X_1X_endDate {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@", header_310x_11, compressedGtin_900123456798908,
+ compressed20bitWeight_1750, compressedDate_End];
+ NSString *expected = @"(01)90012345678908(3100)001750";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_310X_11_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@", header_310x_11, compressedGtin_900123456798908,
+ compressed20bitWeight_1750, compressedDate_March_12th_2010];
+ NSString *expected = @"(01)90012345678908(3100)001750(11)100312";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_320X_11_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@", header_320x_11, compressedGtin_900123456798908,
+ compressed20bitWeight_1750, compressedDate_March_12th_2010];
+ NSString *expected = @"(01)90012345678908(3200)001750(11)100312";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_310X_13_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@", header_310x_13, compressedGtin_900123456798908,
+ compressed20bitWeight_1750, compressedDate_March_12th_2010];
+ NSString *expected = @"(01)90012345678908(3100)001750(13)100312";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_320X_13_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@", header_320x_13, compressedGtin_900123456798908,
+ compressed20bitWeight_1750, compressedDate_March_12th_2010];
+ NSString *expected = @"(01)90012345678908(3200)001750(13)100312";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_310X_15_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@", header_310x_15, compressedGtin_900123456798908,
+ compressed20bitWeight_1750, compressedDate_March_12th_2010];
+ NSString *expected = @"(01)90012345678908(3100)001750(15)100312";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_320X_15_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@", header_320x_15, compressedGtin_900123456798908,
+ compressed20bitWeight_1750, compressedDate_March_12th_2010];
+ NSString *expected = @"(01)90012345678908(3200)001750(15)100312";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_310X_17_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@", header_310x_17, compressedGtin_900123456798908,
+ compressed20bitWeight_1750, compressedDate_March_12th_2010];
+ NSString *expected = @"(01)90012345678908(3100)001750(17)100312";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)test01_320X_17_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@", header_320x_17, compressedGtin_900123456798908,
+ compressed20bitWeight_1750, compressedDate_March_12th_2010];
+ NSString *expected = @"(01)90012345678908(3200)001750(17)100312";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AbstractDecoderTest.h b/ZXingObjCTests/oned/rss/expanded/decoders/AbstractDecoderTest.h
new file mode 100644
index 0000000..38cfb52
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AbstractDecoderTest.h
@@ -0,0 +1,52 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+extern const NSString *numeric_10;
+extern const NSString *numeric_12;
+extern const NSString *numeric_1FNC1;
+extern const NSString *numeric_FNC11;
+
+extern const NSString *numeric2alpha;
+
+extern const NSString *alpha_A;
+extern const NSString *alpha_FNC1;
+extern const NSString *alpha2numeric;
+extern const NSString *alpha2isoiec646;
+
+extern const NSString *i646_B;
+extern const NSString *i646_C;
+extern const NSString *i646_FNC1;
+extern const NSString *isoiec646_2alpha;
+
+extern const NSString *compressedGtin_900123456798908;
+extern const NSString *compressedGtin_900000000000008;
+
+extern const NSString *compressed15bitWeight_1750;
+extern const NSString *compressed15bitWeight_11750;
+extern const NSString *compressed15bitWeight_0;
+
+extern const NSString *compressed20bitWeight_1750;
+
+extern const NSString *compressedDate_March_12th_2010;
+extern const NSString *compressedDate_End;
+
+@interface AbstractDecoderTest : SenTestCase
+
+- (BOOL)assertCorrectBinaryString:(NSString *)binaryString expectedNumber:(NSString *)expectedNumber error:(NSError **)error;
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AbstractDecoderTest.m b/ZXingObjCTests/oned/rss/expanded/decoders/AbstractDecoderTest.m
new file mode 100644
index 0000000..a88d7cf
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AbstractDecoderTest.m
@@ -0,0 +1,62 @@
+/*
+ * 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 "AbstractDecoderTest.h"
+#import "ZXBinaryUtil.h"
+
+const NSString *numeric_10 = @"..X..XX";
+const NSString *numeric_12 = @"..X.X.X";
+const NSString *numeric_1FNC1 = @"..XXX.X";
+const NSString *numeric_FNC11 = @"XXX.XXX";
+
+const NSString *numeric2alpha = @"....";
+
+const NSString *alpha_A = @"X.....";
+const NSString *alpha_FNC1 = @".XXXX";
+const NSString *alpha2numeric = @"...";
+const NSString *alpha2isoiec646 = @"..X..";
+
+const NSString *i646_B = @"X.....X";
+const NSString *i646_C = @"X....X.";
+const NSString *i646_FNC1 = @".XXXX";
+const NSString *isoiec646_2alpha = @"..X..";
+
+const NSString *compressedGtin_900123456798908 = @".........X..XXX.X.X.X...XX.XXXXX.XXXX.X.";
+const NSString *compressedGtin_900000000000008 = @"........................................";
+
+const NSString *compressed15bitWeight_1750 = @"....XX.XX.X.XX.";
+const NSString *compressed15bitWeight_11750 = @".X.XX.XXXX..XX.";
+const NSString *compressed15bitWeight_0 = @"...............";
+
+const NSString *compressed20bitWeight_1750 = @".........XX.XX.X.XX.";
+
+const NSString *compressedDate_March_12th_2010 = @"....XXXX.X..XX..";
+const NSString *compressedDate_End = @"X..X.XX.........";
+
+@implementation AbstractDecoderTest
+
+- (BOOL)assertCorrectBinaryString:(NSString *)binaryString expectedNumber:(NSString *)expectedNumber error:(NSError **)error {
+ ZXBitArray *binary = [ZXBinaryUtil buildBitArrayFromStringWithoutSpaces:binaryString];
+ ZXAbstractExpandedDecoder *decoder = [ZXAbstractExpandedDecoder createDecoder:binary];
+ NSString *result = [decoder parseInformationWithError:error];
+ if (!result) {
+ return NO;
+ }
+ STAssertEqualObjects(result, expectedNumber, @"Expected %@ to equal %@", result, expectedNumber);
+ return YES;
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AnyAIDecoderTest.h b/ZXingObjCTests/oned/rss/expanded/decoders/AnyAIDecoderTest.h
new file mode 100644
index 0000000..668fc0f
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AnyAIDecoderTest.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 "AbstractDecoderTest.h"
+
+@interface AnyAIDecoderTest : AbstractDecoderTest
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/AnyAIDecoderTest.m b/ZXingObjCTests/oned/rss/expanded/decoders/AnyAIDecoderTest.m
new file mode 100644
index 0000000..319e396
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/AnyAIDecoderTest.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 "AnyAIDecoderTest.h"
+
+static NSString *header = @".....";
+
+@implementation AnyAIDecoderTest
+
+- (void)testAnyAIDecoder_1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@%@%@%@", header, numeric_10, numeric_12, numeric2alpha, alpha_A,
+ alpha2numeric, numeric_12];
+ NSString *expected = @"(10)12A12";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)testAnyAIDecoder_2 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@%@%@%@", header, numeric_10, numeric_12, numeric2alpha, alpha_A,
+ alpha2isoiec646, i646_B];
+ NSString *expected = @"(10)12AB";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)testAnyAIDecoder_3 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@%@%@%@%@%@%@", header, numeric_10, numeric2alpha, alpha2isoiec646, i646_B,
+ i646_C, isoiec646_2alpha, alpha_A, alpha2numeric, numeric_10];
+ NSString *expected = @"(10)BCA10";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)testAnyAIDecoder_numericFNC1_secondDigit {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@", header, numeric_10, numeric_1FNC1];
+ NSString *expected = @"(10)1";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)testAnyAIDecoder_alphaFNC1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@%@", header, numeric_10, numeric2alpha, alpha_A, alpha_FNC1];
+ NSString *expected = @"(10)A";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+- (void)testAnyAIDecoder_646FNC1 {
+ NSString *data = [NSString stringWithFormat:@"%@%@%@%@%@%@%@", header, numeric_10, numeric2alpha, alpha_A, isoiec646_2alpha,
+ i646_B, i646_FNC1];
+ NSString *expected = @"(10)AB";
+
+ [self assertCorrectBinaryString:data expectedNumber:expected error:nil];
+}
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/ZXFieldParserTest.h b/ZXingObjCTests/oned/rss/expanded/decoders/ZXFieldParserTest.h
new file mode 100644
index 0000000..adbeb19
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/ZXFieldParserTest.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXFieldParserTest : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/oned/rss/expanded/decoders/ZXFieldParserTest.m b/ZXingObjCTests/oned/rss/expanded/decoders/ZXFieldParserTest.m
new file mode 100644
index 0000000..e1b28c9
--- /dev/null
+++ b/ZXingObjCTests/oned/rss/expanded/decoders/ZXFieldParserTest.m
@@ -0,0 +1,36 @@
+/*
+ * 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 "ZXFieldParserTest.h"
+
+@implementation ZXFieldParserTest
+
+- (void)checkFields:(NSString *)expected {
+ NSString *field = [[expected stringByReplacingOccurrencesOfString:@"(" withString:@""]
+ stringByReplacingOccurrencesOfString:@")" withString:@""];
+ NSString *actual = [ZXFieldParser parseFieldsInGeneralPurpose:field error:nil];
+ STAssertEqualObjects(actual, expected, @"Expected %@ to equal %@", actual, expected);
+}
+
+- (void)testParseField {
+ [self checkFields:@"(15)991231(3103)001750(10)12A"];
+}
+
+- (void)testParseField2 {
+ [self checkFields:@"(15)991231(15)991231(3103)001750(10)12A"];
+}
+
+@end
diff --git a/ZXingObjCTests/pdf417/PDF417BlackBox1TestCase.h b/ZXingObjCTests/pdf417/PDF417BlackBox1TestCase.h
new file mode 100644
index 0000000..a4f899b
--- /dev/null
+++ b/ZXingObjCTests/pdf417/PDF417BlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface PDF417BlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/pdf417/PDF417BlackBox1TestCase.m b/ZXingObjCTests/pdf417/PDF417BlackBox1TestCase.m
new file mode 100644
index 0000000..02b112d
--- /dev/null
+++ b/ZXingObjCTests/pdf417/PDF417BlackBox1TestCase.m
@@ -0,0 +1,39 @@
+/*
+ * 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 "PDF417BlackBox1TestCase.h"
+
+@implementation PDF417BlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/pdf417-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatPDF417];
+
+ if (self) {
+ [self addTest:9 tryHarderCount:9 rotation:0.0f];
+ [self addTest:9 tryHarderCount:9 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/pdf417/PDF417BlackBox2TestCase.h b/ZXingObjCTests/pdf417/PDF417BlackBox2TestCase.h
new file mode 100644
index 0000000..908e3e4
--- /dev/null
+++ b/ZXingObjCTests/pdf417/PDF417BlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface PDF417BlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/pdf417/PDF417BlackBox2TestCase.m b/ZXingObjCTests/pdf417/PDF417BlackBox2TestCase.m
new file mode 100644
index 0000000..c99cc86
--- /dev/null
+++ b/ZXingObjCTests/pdf417/PDF417BlackBox2TestCase.m
@@ -0,0 +1,42 @@
+/*
+ * 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 "PDF417BlackBox2TestCase.h"
+
+/**
+ * This test contains 480x240 images captured from an Android device at preview resolution.
+ */
+@implementation PDF417BlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/pdf417-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatPDF417];
+
+ if (self) {
+ [self addTest:25 tryHarderCount:25 maxMisreads:0 maxTryHarderMisreads:0 rotation:0.0f];
+ [self addTest:25 tryHarderCount:25 maxMisreads:0 maxTryHarderMisreads:0 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/pdf417/PDF417BlackBox3TestCase.h b/ZXingObjCTests/pdf417/PDF417BlackBox3TestCase.h
new file mode 100644
index 0000000..4d303e0
--- /dev/null
+++ b/ZXingObjCTests/pdf417/PDF417BlackBox3TestCase.h
@@ -0,0 +1,21 @@
+/*
+ * 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 "AbstractBlackBoxTestCase.h"
+
+@interface PDF417BlackBox3TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/pdf417/PDF417BlackBox3TestCase.m b/ZXingObjCTests/pdf417/PDF417BlackBox3TestCase.m
new file mode 100644
index 0000000..cbafdbb
--- /dev/null
+++ b/ZXingObjCTests/pdf417/PDF417BlackBox3TestCase.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 "PDF417BlackBox3TestCase.h"
+
+@implementation PDF417BlackBox3TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/pdf417-3"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatPDF417];
+
+ if (self) {
+ [self addTest:18 tryHarderCount:18 rotation:0.0f];
+ [self addTest:18 tryHarderCount:18 rotation:180.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/pdf417/PDF417BlackBox4TestCase.h b/ZXingObjCTests/pdf417/PDF417BlackBox4TestCase.h
new file mode 100644
index 0000000..bca0dab
--- /dev/null
+++ b/ZXingObjCTests/pdf417/PDF417BlackBox4TestCase.h
@@ -0,0 +1,21 @@
+/*
+ * 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 "AbstractBlackBoxTestCase.h"
+
+@interface PDF417BlackBox4TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/pdf417/PDF417BlackBox4TestCase.m b/ZXingObjCTests/pdf417/PDF417BlackBox4TestCase.m
new file mode 100644
index 0000000..ec52f3b
--- /dev/null
+++ b/ZXingObjCTests/pdf417/PDF417BlackBox4TestCase.m
@@ -0,0 +1,189 @@
+/*
+ * 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 "PDF417BlackBox4TestCase.h"
+#import "TestResult.h"
+
+/**
+ * This class tests Macro PDF417 barcode specific functionality. It ensures that information, which is split into
+ * several barcodes can be properly combined again to yield the original data content.
+ */
+@implementation PDF417BlackBox4TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/pdf417-4"
+ barcodeReader:[[ZXPDF417Reader alloc] init]
+ expectedFormat:kBarcodeFormatPDF417];
+
+ if (self) {
+ [self.testResults addObject:[[TestResult alloc] initWithMustPassCount:2 tryHarderCount:2 maxMisreads:0 maxTryHarderMisreads:0 rotation:0.0f]];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [self testPDF417BlackBoxCountingResults:YES];
+}
+
+- (void)testPDF417BlackBoxCountingResults:(BOOL)assertOnFailure {
+ STAssertFalse([self.testResults count] == 0, @"Expected testResults to be non-empty");
+
+ NSDictionary *imageFiles = [self imageFileLists];
+ int testCount = (int)[self.testResults count];
+
+ int passedCounts[testCount];
+ memset(passedCounts, 0, testCount * sizeof(int));
+
+ int misreadCounts[testCount];
+ memset(misreadCounts, 0, testCount * sizeof(int));
+
+ int tryHarderCounts[testCount];
+ memset(tryHarderCounts, 0, testCount * sizeof(int));
+
+ int tryHarderMisreadCounts[testCount];
+ memset(tryHarderMisreadCounts, 0, testCount * sizeof(int));
+
+ for (NSString *fileBaseName in [imageFiles allKeys]) {
+ NSLog(@"Starting Image Group %@", fileBaseName);
+
+ NSString *expectedText;
+ NSString *expectedTextFile = [[NSBundle bundleForClass:[self class]] pathForResource:fileBaseName ofType:@"txt" inDirectory:self.testBase];
+ if (expectedTextFile) {
+ expectedText = [self readFileAsString:expectedTextFile encoding:NSUTF8StringEncoding];
+ } else {
+ NSString *expectedTextFile = [[NSBundle bundleForClass:[self class]] pathForResource:fileBaseName ofType:@"bin" inDirectory:self.testBase];
+ STAssertNotNil(expectedTextFile, @"Expected text does not exist");
+ expectedText = [self readFileAsString:expectedTextFile encoding:NSISOLatin1StringEncoding];
+ }
+
+ for (int x = 0; x < testCount; x++) {
+ NSMutableArray *results = [NSMutableArray array];
+ for (NSURL *imageFile in imageFiles[fileBaseName]) {
+ ZXImage *image = [[ZXImage alloc] initWithURL:imageFile];
+ float rotation = [(TestResult *)self.testResults[x] rotation];
+ ZXImage *rotatedImage = [self rotateImage:image degrees:rotation];
+ ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage.cgimage];
+ ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:[[ZXHybridBinarizer alloc] initWithSource:source]];
+
+ NSArray *imageResults = [self decode:bitmap tryHarder:NO];
+ if (!imageResults) {
+ continue;
+ }
+
+ [results addObjectsFromArray:imageResults];
+ }
+ [results sortUsingComparator:^NSComparisonResult(ZXResult *arg0, ZXResult *arg1) {
+ ZXPDF417ResultMetadata *resultMetadata = [self meta:arg0];
+ ZXPDF417ResultMetadata *otherResultMetadata = [self meta:arg1];
+ return resultMetadata.segmentIndex - otherResultMetadata.segmentIndex;
+ }];
+ NSMutableString *resultText = [NSMutableString string];
+ NSString *fileId;
+ for (ZXResult *result in results) {
+ ZXPDF417ResultMetadata *resultMetadata = [self meta:result];
+ STAssertNotNil(resultMetadata, @"resultMetadata");
+ if (!fileId) {
+ fileId = resultMetadata.fileId;
+ }
+ STAssertEqualObjects(resultMetadata.fileId, fileId, @"FileId");
+ [resultText appendString:result.text];
+ }
+ STAssertEqualObjects(resultText, expectedText, @"ExpectedText");
+ passedCounts[x]++;
+ tryHarderCounts[x]++;
+ }
+ }
+
+ // Print the results of all tests first
+ int totalFound = 0;
+ int totalMustPass = 0;
+ int totalMisread = 0;
+ int totalMaxMisread = 0;
+
+ int numberOfTests = (int)[imageFiles count];
+ for (int x = 0; x < [self.testResults count]; x++) {
+ TestResult *testResult = self.testResults[x];
+ NSLog(@"Rotation %d degrees:", (int) testResult.rotation);
+ NSLog(@" %d of %d images passed (%d required)", passedCounts[x], numberOfTests, testResult.mustPassCount);
+ int failed = numberOfTests - passedCounts[x];
+ NSLog(@" %d failed due to misreads, %d not detected", misreadCounts[x], failed - misreadCounts[x]);
+ NSLog(@" %d of %d images passed with try harder (%d required)", tryHarderCounts[x], numberOfTests, testResult.tryHarderCount);
+ failed = numberOfTests - tryHarderCounts[x];
+ NSLog(@" %d failed due to misreads, %d not detected", tryHarderMisreadCounts[x], failed - tryHarderMisreadCounts[x]);
+ totalFound += passedCounts[x] + tryHarderCounts[x];
+ totalMustPass += testResult.mustPassCount + testResult.tryHarderCount;
+ totalMisread += misreadCounts[x] + tryHarderMisreadCounts[x];
+ totalMaxMisread += testResult.maxMisreads + testResult.maxTryHarderMisreads;
+ }
+
+ int totalTests = numberOfTests * testCount * 2;
+ NSLog(@"Decoded %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(@"--- 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++) {
+ TestResult *testResult = self.testResults[x];
+ NSString *label = [NSString stringWithFormat:@"Rotation %f degrees: Too many images failed", testResult.rotation];
+ STAssertTrue(passedCounts[x] >= testResult.mustPassCount, label);
+ STAssertTrue(tryHarderCounts[x] >= testResult.tryHarderCount, @"Try harder, %@", label);
+ label = [NSString stringWithFormat:@"Rotation %f degrees: Too many images misread", testResult.rotation];
+ STAssertTrue(misreadCounts[x] <= testResult.maxMisreads, label);
+ STAssertTrue(tryHarderMisreadCounts[x] <= testResult.maxTryHarderMisreads, @"Try harder, %@", label);
+ }
+ }
+}
+
+- (ZXPDF417ResultMetadata *)meta:(ZXResult *)result {
+ return result.resultMetadata == nil ? nil : (ZXPDF417ResultMetadata *)result.resultMetadata[@(kResultMetadataTypePDF417ExtraMetadata)];
+}
+
+- (NSArray *)decode:(ZXBinaryBitmap *)source tryHarder:(BOOL)tryHarder {
+ ZXDecodeHints *hints = [ZXDecodeHints hints];
+ hints.tryHarder = tryHarder;
+
+ return [(ZXPDF417Reader *)self.barcodeReader decodeMultiple:source hints:hints error:nil];
+}
+
+- (NSDictionary *)imageFileLists {
+ NSMutableDictionary *result = [NSMutableDictionary dictionary];
+ for (NSURL *file in [self imageFiles]) {
+ NSString *testImageFileName = [[[file path] componentsSeparatedByString:@"/"] lastObject];
+ NSString *fileBaseName = [testImageFileName substringToIndex:[testImageFileName rangeOfString:@"-"].location];
+ NSMutableArray *files = result[fileBaseName];
+ if (!files) {
+ files = [NSMutableArray array];
+ result[fileBaseName] = files;
+ }
+ [files addObject:file];
+ }
+ return result;
+}
+
+@end
diff --git a/ZXingObjCTests/pdf417/ZXPDF417DetectorTest.h b/ZXingObjCTests/pdf417/ZXPDF417DetectorTest.h
new file mode 100644
index 0000000..ecb1a7b
--- /dev/null
+++ b/ZXingObjCTests/pdf417/ZXPDF417DetectorTest.h
@@ -0,0 +1,21 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXPDF417DetectorTest : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/pdf417/ZXPDF417DetectorTest.m b/ZXingObjCTests/pdf417/ZXPDF417DetectorTest.m
new file mode 100644
index 0000000..99d54d8
--- /dev/null
+++ b/ZXingObjCTests/pdf417/ZXPDF417DetectorTest.m
@@ -0,0 +1,93 @@
+/*
+ * 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 "ZXPDF417DetectorTest.h"
+
+const int BIT_SET_INDEX_LEN = 4;
+const int BIT_SET_INDEX[BIT_SET_INDEX_LEN] = { 1, 2, 3, 5 };
+
+const int BIT_MATRIX_POINTS_LEN = 6;
+const int BIT_MATRIX_POINTS[BIT_MATRIX_POINTS_LEN] = { 1, 2, 2, 0, 3, 1 };
+
+@implementation ZXPDF417DetectorTest
+
+- (void)testMirror {
+ [self testMirror:7];
+ [self testMirror:8];
+}
+
+- (void)testMirror:(int)size {
+ ZXBitArray *result = [[ZXBitArray alloc] initWithSize:size];
+ [ZXPDF417Detector mirror:[self input:size] result:result];
+
+ ZXBitArray *expected = [self expected:size];
+ STAssertEqualObjects([result description], [expected description], @"Expected %@, got %@", expected, result);
+}
+
+- (void)testRotate180 {
+ [self testRotate180:7 height:4];
+ [self testRotate180:7 height:5];
+ [self testRotate180:8 height:4];
+ [self testRotate180:8 height:5];
+}
+
+- (void)testRotate180:(int)width height:(int)height {
+ ZXBitMatrix *input = [self input:width height:height];
+ [ZXPDF417Detector rotate180:input];
+ ZXBitMatrix *expected = [self expected:width height:height];
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ STAssertEquals([input getX:x y:y], [expected getX:x y:y], @"(%d,%d)", x, y);
+ }
+ }
+}
+
+- (ZXBitMatrix *)expected:(int)width height:(int)height {
+ ZXBitMatrix *result = [[ZXBitMatrix alloc] initWithWidth:width height:height];
+ for (int i = 0; i < BIT_MATRIX_POINTS_LEN; i += 2) {
+ [result setX:width - 1 - BIT_MATRIX_POINTS[i] y:height - 1 - BIT_MATRIX_POINTS[i + 1]];
+ }
+ return result;
+}
+
+- (ZXBitMatrix *)input:(int)width height:(int)height {
+ ZXBitMatrix *result = [[ZXBitMatrix alloc] initWithWidth:width height:height];
+ for (int i = 0; i < BIT_MATRIX_POINTS_LEN; i += 2) {
+ [result setX:BIT_MATRIX_POINTS[i] y:BIT_MATRIX_POINTS[i + 1]];
+ }
+ return result;
+}
+
+- (ZXBitArray *)expected:(int)size {
+ ZXBitArray *expected = [[ZXBitArray alloc] initWithSize:size];
+ for (int i = 0; i < BIT_SET_INDEX_LEN; i++) {
+ int index = BIT_SET_INDEX[i];
+ [expected set:size - 1 - index];
+ }
+ return expected;
+}
+
+- (ZXBitArray *)input:(int)size {
+ ZXBitArray *input = [[ZXBitArray alloc] initWithSize:size];
+ for (int i = 0; i < BIT_SET_INDEX_LEN; i++) {
+ int index = BIT_SET_INDEX[i];
+ [input set:index];
+ }
+ return input;
+}
+
+@end
diff --git a/ZXingObjCTests/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.h b/ZXingObjCTests/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.h
new file mode 100644
index 0000000..4d18741
--- /dev/null
+++ b/ZXingObjCTests/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.h
@@ -0,0 +1,24 @@
+/*
+ * 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 <SenTestingKit/SenTestingKit.h>
+
+@interface AbstractErrorCorrectionTestCase : SenTestCase
+
+- (void)corrupt:(NSMutableArray *)received howMany:(int)howMany;
+- (NSArray *)erase:(NSMutableArray *)received howMany:(int)howMany;
+
+@end
diff --git a/ZXingObjCTests/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.m b/ZXingObjCTests/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.m
new file mode 100644
index 0000000..2477f17
--- /dev/null
+++ b/ZXingObjCTests/pdf417/decoder/ec/AbstractErrorCorrectionTestCase.m
@@ -0,0 +1,58 @@
+/*
+ * 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 "AbstractErrorCorrectionTestCase.h"
+
+@implementation AbstractErrorCorrectionTestCase
+
+- (void)corrupt:(NSMutableArray *)received howMany:(int)howMany {
+ BOOL corrupted[received.count];
+ for (int i = 0; i < received.count; i++) {
+ corrupted[i] = NO;
+ }
+
+ for (int j = 0; j < howMany; j++) {
+ int location = arc4random() % received.count;
+ if (corrupted[location]) {
+ j--;
+ } else {
+ corrupted[location] = YES;
+ received[location] = [NSNumber numberWithInt:arc4random() % 929];
+ }
+ }
+}
+
+- (NSArray *)erase:(NSMutableArray *)received howMany:(int)howMany {
+ BOOL erased[received.count];
+ for (int i = 0; i < received.count; i++) {
+ erased[i] = NO;
+ }
+
+ NSMutableArray *erasures = [NSMutableArray arrayWithCapacity:howMany];
+ for (int j = 0; j < howMany; j++) {
+ int location = arc4random() % received.count;
+ if (erased[location]) {
+ j--;
+ } else {
+ erased[location] = YES;
+ received[location] = @0;
+ [erasures addObject:@(location)];
+ }
+ }
+ return erasures;
+}
+
+@end
diff --git a/ZXingObjCTests/pdf417/decoder/ec/ZXPDF417ECErrorCorrectionTestCase.h b/ZXingObjCTests/pdf417/decoder/ec/ZXPDF417ECErrorCorrectionTestCase.h
new file mode 100644
index 0000000..d79729b
--- /dev/null
+++ b/ZXingObjCTests/pdf417/decoder/ec/ZXPDF417ECErrorCorrectionTestCase.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 "AbstractErrorCorrectionTestCase.h"
+
+@interface ZXPDF417ECErrorCorrectionTestCase : AbstractErrorCorrectionTestCase
+
+@end
diff --git a/ZXingObjCTests/pdf417/decoder/ec/ZXPDF417ECErrorCorrectionTestCase.m b/ZXingObjCTests/pdf417/decoder/ec/ZXPDF417ECErrorCorrectionTestCase.m
new file mode 100644
index 0000000..898fc45
--- /dev/null
+++ b/ZXingObjCTests/pdf417/decoder/ec/ZXPDF417ECErrorCorrectionTestCase.m
@@ -0,0 +1,128 @@
+/*
+ * 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 "ZXPDF417ECErrorCorrectionTestCase.h"
+
+@interface ZXPDF417ECErrorCorrectionTestCase ()
+
+@property (nonatomic, strong) ZXPDF417ECErrorCorrection *ec;
+
+@end
+
+@implementation ZXPDF417ECErrorCorrectionTestCase
+
+static NSMutableArray *PDF417_TEST = nil;
+static NSMutableArray *PDF417_TEST_WITH_EC = nil;
+static int ECC_BYTES;
+// Example is EC level 1 (s=1). The number of erasures (l) and substitutions (f) must obey:
+// l + 2f <= 2^(s+1) - 3
+const int EC_LEVEL = 5;
+const int ERROR_LIMIT = (1 << (EC_LEVEL + 1)) - 3;
+const int MAX_ERRORS = ERROR_LIMIT / 2;
+//const int MAX_ERASURES = ERROR_LIMIT;
+
++ (void)initialize {
+ /** See ISO 15438, Annex Q */
+ //PDF417_TEST =
+ // [@[ @5, @453, @178, @121, @239 ] mutableCopy];
+ //PDF417_TEST_WITH_EC =
+ // [@[ @5, @453, @178, @121, @239, @452, @327, @657, @619 ] mutableCopy];
+
+ PDF417_TEST = [@[
+ @48, @901, @56, @141, @627, @856, @330, @69, @244, @900, @852, @169, @843, @895, @852, @895, @913, @154, @845, @778, @387, @89, @869,
+ @901, @219, @474, @543, @650, @169, @201, @9, @160, @35, @70, @900, @900, @900, @900, @900, @900, @900, @900, @900, @900, @900, @900,
+ @900, @900] mutableCopy];
+
+ PDF417_TEST_WITH_EC = [@[
+ @48, @901, @56, @141, @627, @856, @330, @69, @244, @900, @852, @169, @843, @895, @852, @895, @913, @154, @845, @778, @387, @89, @869,
+ @901, @219, @474, @543, @650, @169, @201, @9, @160, @35, @70, @900, @900, @900, @900, @900, @900, @900, @900, @900, @900, @900, @900,
+ @900, @900, @769, @843, @591, @910, @605, @206, @706, @917, @371, @469, @79, @718, @47, @777, @249, @262, @193, @620, @597, @477, @450,
+ @806, @908, @309, @153, @871, @686, @838, @185, @674, @68, @679, @691, @794, @497, @479, @234, @250, @496, @43, @347, @582, @882, @536,
+ @322, @317, @273, @194, @917, @237, @420, @859, @340, @115, @222, @808, @866, @836, @417, @121, @833, @459, @64, @159] mutableCopy];
+
+ ECC_BYTES = (int)PDF417_TEST_WITH_EC.count - (int)PDF417_TEST.count;
+}
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ if (self = [super initWithInvocation:invocation]) {
+ _ec = [[ZXPDF417ECErrorCorrection alloc] init];
+ }
+
+ return self;
+}
+
+- (void)testNoError {
+ NSMutableArray *received = [NSMutableArray arrayWithArray:PDF417_TEST_WITH_EC];
+ // no errors
+ [self checkDecode:received];
+}
+
+- (void)testOneError {
+ for (int i = 0; i < PDF417_TEST_WITH_EC.count; i++) {
+ NSMutableArray *received = [NSMutableArray arrayWithArray:PDF417_TEST_WITH_EC];
+ received[i] = [NSNumber numberWithInt:arc4random() % 256];
+ [self checkDecode:received];
+ }
+}
+
+- (void)testMaxErrors {
+ for (int testIterations = 0; testIterations < 100; testIterations++) { // # iterations is kind of arbitrary
+ NSMutableArray *received = [NSMutableArray arrayWithArray:PDF417_TEST_WITH_EC];
+ [self corrupt:received howMany:MAX_ERRORS];
+ [self checkDecode:received];
+ }
+}
+
+- (void)testTooManyErrors {
+ NSMutableArray *received = [NSMutableArray arrayWithArray:PDF417_TEST_WITH_EC];
+ [self corrupt:received howMany:MAX_ERRORS + 3]; // +3 since the algo can actually correct 2 more than it should here
+
+ STAssertFalse([self checkDecode:received], @"Should not have decoded");
+}
+
+/*
+- (void)testMaxErasures {
+ for (int i = 0; i < PDF417_TEST.count; i++) { // # iterations is kind of arbitrary
+ NSMutableArray *received = [NSMutableArray arrayWithArray:PDF417_TEST_WITH_EC];
+ NSArray *erasures = [self erase:received howMany:MAX_ERASURES];
+ [self checkDecode:received erasures:erasures];
+ }
+}
+
+- (void)testTooManyErasures {
+ NSMutableArray *received = [NSMutableArray arrayWithArray:PDF417_TEST_WITH_EC];
+ NSArray *erasures = [self erase:received howMany:MAX_ERASURES + 1];
+
+ STAssertFalse([self checkDecode:received erasures:erasures], @"Should not have decoded");
+}
+*/
+
+- (BOOL)checkDecode:(NSMutableArray *)received {
+ return [self checkDecode:received erasures:@[]];
+}
+
+- (BOOL)checkDecode:(NSMutableArray *)received erasures:(NSArray *)erasures {
+ if (![self.ec decode:received numECCodewords:ECC_BYTES erasures:erasures]) {
+ return NO;
+ }
+
+ for (int i = 0; i < PDF417_TEST.count; i++) {
+ STAssertEquals([received[i] intValue], [PDF417_TEST[i] intValue], @"Expected %@ to equal %@", received[i], PDF417_TEST[i]);
+ }
+ return YES;
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox1TestCase.h b/ZXingObjCTests/qrcode/QRCodeBlackBox1TestCase.h
new file mode 100644
index 0000000..6c73a6f
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox1TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface QRCodeBlackBox1TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox1TestCase.m b/ZXingObjCTests/qrcode/QRCodeBlackBox1TestCase.m
new file mode 100644
index 0000000..64d7198
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox1TestCase.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 "QRCodeBlackBox1TestCase.h"
+
+@implementation QRCodeBlackBox1TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/qrcode-1"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatQRCode];
+
+ if (self) {
+ [self addTest:17 tryHarderCount:17 rotation:0.0f];
+ [self addTest:14 tryHarderCount:15 rotation:90.0f];
+ [self addTest:17 tryHarderCount:17 rotation:180.0f];
+ [self addTest:14 tryHarderCount:15 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox2TestCase.h b/ZXingObjCTests/qrcode/QRCodeBlackBox2TestCase.h
new file mode 100644
index 0000000..113b8df
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox2TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface QRCodeBlackBox2TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox2TestCase.m b/ZXingObjCTests/qrcode/QRCodeBlackBox2TestCase.m
new file mode 100644
index 0000000..4e4cff9
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox2TestCase.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 "QRCodeBlackBox2TestCase.h"
+
+@implementation QRCodeBlackBox2TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/qrcode-2"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatQRCode];
+
+ if (self) {
+ [self addTest:30 tryHarderCount:31 rotation:0.0f];
+ [self addTest:29 tryHarderCount:30 rotation:90.0f];
+ [self addTest:30 tryHarderCount:30 rotation:180.0f];
+ [self addTest:29 tryHarderCount:30 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox3TestCase.h b/ZXingObjCTests/qrcode/QRCodeBlackBox3TestCase.h
new file mode 100644
index 0000000..0472885
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox3TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface QRCodeBlackBox3TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox3TestCase.m b/ZXingObjCTests/qrcode/QRCodeBlackBox3TestCase.m
new file mode 100644
index 0000000..e7420f5
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox3TestCase.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 "QRCodeBlackBox3TestCase.h"
+
+@implementation QRCodeBlackBox3TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/qrcode-3"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatQRCode];
+
+ if (self) {
+ [self addTest:38 tryHarderCount:38 rotation:0.0f];
+ [self addTest:38 tryHarderCount:39 rotation:90.0f];
+ [self addTest:36 tryHarderCount:38 rotation:180.0f];
+ [self addTest:39 tryHarderCount:39 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox4TestCase.h b/ZXingObjCTests/qrcode/QRCodeBlackBox4TestCase.h
new file mode 100644
index 0000000..0446dd8
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox4TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface QRCodeBlackBox4TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox4TestCase.m b/ZXingObjCTests/qrcode/QRCodeBlackBox4TestCase.m
new file mode 100644
index 0000000..07f43b8
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox4TestCase.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 "QRCodeBlackBox4TestCase.h"
+
+@implementation QRCodeBlackBox4TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/qrcode-4"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatQRCode];
+
+ if (self) {
+ [self addTest:36 tryHarderCount:36 rotation:0.0f];
+ [self addTest:35 tryHarderCount:35 rotation:90.0f];
+ [self addTest:35 tryHarderCount:36 rotation:180.0f];
+ [self addTest:35 tryHarderCount:36 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox5TestCase.h b/ZXingObjCTests/qrcode/QRCodeBlackBox5TestCase.h
new file mode 100644
index 0000000..161e31f
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox5TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface QRCodeBlackBox5TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox5TestCase.m b/ZXingObjCTests/qrcode/QRCodeBlackBox5TestCase.m
new file mode 100644
index 0000000..588c4ba
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox5TestCase.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 "QRCodeBlackBox5TestCase.h"
+
+@implementation QRCodeBlackBox5TestCase
+
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/qrcode-5"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatQRCode];
+
+ if (self) {
+ [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:19 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox6TestCase.h b/ZXingObjCTests/qrcode/QRCodeBlackBox6TestCase.h
new file mode 100644
index 0000000..f5699d7
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox6TestCase.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 "AbstractBlackBoxTestCase.h"
+
+@interface QRCodeBlackBox6TestCase : AbstractBlackBoxTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/QRCodeBlackBox6TestCase.m b/ZXingObjCTests/qrcode/QRCodeBlackBox6TestCase.m
new file mode 100644
index 0000000..f045724
--- /dev/null
+++ b/ZXingObjCTests/qrcode/QRCodeBlackBox6TestCase.m
@@ -0,0 +1,45 @@
+/*
+ * 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 "QRCodeBlackBox6TestCase.h"
+
+@implementation QRCodeBlackBox6TestCase
+
+/**
+ * These tests are supplied by Tim Gernat and test finder pattern detection at small size and under
+ * rotation, which was a weak spot.
+ */
+- (id)initWithInvocation:(NSInvocation *)invocation {
+ self = [super initWithInvocation:invocation
+ testBasePathSuffix:@"Resources/blackbox/qrcode-6"
+ barcodeReader:[[ZXMultiFormatReader alloc] init]
+ expectedFormat:kBarcodeFormatQRCode];
+
+ if (self) {
+ [self addTest:15 tryHarderCount:15 rotation:0.0f];
+ [self addTest:14 tryHarderCount:15 rotation:90.0f];
+ [self addTest:12 tryHarderCount:15 rotation:180.0f];
+ [self addTest:14 tryHarderCount:15 rotation:270.0f];
+ }
+
+ return self;
+}
+
+- (void)testBlackBox {
+ [super runTests];
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/ZXQRCodeWriterTestCase.h b/ZXingObjCTests/qrcode/ZXQRCodeWriterTestCase.h
new file mode 100644
index 0000000..27d3ae4
--- /dev/null
+++ b/ZXingObjCTests/qrcode/ZXQRCodeWriterTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXQRCodeWriterTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/ZXQRCodeWriterTestCase.m b/ZXingObjCTests/qrcode/ZXQRCodeWriterTestCase.m
new file mode 100644
index 0000000..9d85c03
--- /dev/null
+++ b/ZXingObjCTests/qrcode/ZXQRCodeWriterTestCase.m
@@ -0,0 +1,127 @@
+/*
+ * 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 "ZXQRCodeWriterTestCase.h"
+
+static NSString *BASE_IMAGE_PATH = @"Resources/golden/qrcode/";
+
+@implementation ZXQRCodeWriterTestCase
+
+- (ZXImage *)loadImage:(NSString *)fileName {
+ return [[ZXImage alloc] initWithURL:
+ [[NSBundle bundleForClass:[self class]] URLForResource:
+ [BASE_IMAGE_PATH stringByAppendingString:fileName] withExtension:nil]];
+}
+
+// In case the golden images are not monochromatic, convert the RGB values to greyscale.
+- (ZXBitMatrix *)createMatrixFromImage:(ZXImage *)image {
+ size_t width = image.width;
+ size_t height = image.height;
+ uint32_t *data;
+
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(0, width, height, 8, width * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
+ CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
+ CGContextSetShouldAntialias(context, NO);
+
+ CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.cgimage);
+
+ data = (uint32_t *) malloc(width * height * sizeof(uint32_t));
+ memcpy(data, CGBitmapContextGetData(context), width * height * sizeof(uint32_t));
+
+ ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithWidth:(int)width height:(int)height];
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ int pixel = data[y * width + x];
+ int luminance = (306 * ((pixel >> 16) & 0xFF) +
+ 601 * ((pixel >> 8) & 0xFF) +
+ 117 * (pixel & 0xFF)) >> 10;
+ if (luminance <= 0x7F) {
+ [matrix setX:x y:y];
+ }
+ }
+ }
+ return matrix;
+}
+
+- (void)testQRCodeWriter {
+ // The QR should be multiplied up to fit, with extra padding if necessary
+ int bigEnough = 256;
+ ZXQRCodeWriter *writer = [[ZXQRCodeWriter alloc] init];
+ ZXBitMatrix *matrix = [writer encode:@"http://www.google.com/" format:kBarcodeFormatQRCode width:bigEnough
+ height:bigEnough hints:nil error:nil];
+ STAssertNotNil(matrix, @"Matrix should not be nil");
+ STAssertEquals(matrix.width, bigEnough, @"Width should be %d", bigEnough);
+ STAssertEquals(matrix.height, bigEnough, @"Height should be %d", bigEnough);
+
+ // The QR will not fit in this size, so the matrix should come back bigger
+ int tooSmall = 20;
+ matrix = [writer encode:@"http://www.google.com/" format:kBarcodeFormatQRCode width:tooSmall
+ height:tooSmall hints:nil error:nil];
+ STAssertNotNil(matrix, @"Matrix should not be nil");
+ STAssertTrue(tooSmall < matrix.width, @"Matrix width should be greater than %d", tooSmall);
+ STAssertTrue(tooSmall < matrix.height, @"Matrix height should be greater than %d", tooSmall);
+
+ // We should also be able to handle non-square requests by padding them
+ int strangeWidth = 500;
+ int strangeHeight = 100;
+ matrix = [writer encode:@"http://www.google.com/" format:kBarcodeFormatQRCode width:strangeWidth
+ height:strangeHeight hints:nil error:nil];
+ STAssertNotNil(matrix, @"Matrix should not be nil");
+ STAssertEquals(matrix.width, strangeWidth, @"Width should be %d", strangeWidth);
+ STAssertEquals(matrix.height, strangeHeight, @"Height should be %d", strangeHeight);
+}
+
+- (void)compareToGoldenFile:(NSString *)contents ecLevel:(ZXErrorCorrectionLevel *)ecLevel
+ resolution:(int)resolution fileName:(NSString *)fileName {
+ ZXImage *image = [self loadImage:fileName];
+ STAssertNotNil(image, @"Image should not be nil");
+ ZXBitMatrix *goldenResult = [self createMatrixFromImage:image];
+ STAssertNotNil(goldenResult, @"Golden result should not be nil");
+
+ ZXEncodeHints *hints = [[ZXEncodeHints alloc] init];
+ hints.errorCorrectionLevel = ecLevel;
+ ZXQRCodeWriter *writer = [[ZXQRCodeWriter alloc] init];
+ ZXBitMatrix *generatedResult = [writer encode:contents format:kBarcodeFormatQRCode width:resolution
+ height:resolution hints:hints error:nil];
+
+ STAssertEquals(generatedResult.width, resolution, @"Expected generatedResult width to be %d", resolution);
+ STAssertEquals(generatedResult.height, resolution, @"Expected generatedResult height to be %d", resolution);
+ STAssertEqualObjects(generatedResult, goldenResult, @"Expected generatedResult to equal goldenResult");
+}
+
+// Golden images are generated with "qrcode_sample.cc". The images are checked with both eye balls
+// and cell phones. We expect pixel-perfect results, because the error correction level is known,
+// and the pixel dimensions matches exactly.
+- (void)testRegressionTest {
+ [self compareToGoldenFile:@"http://www.google.com/" ecLevel:[ZXErrorCorrectionLevel errorCorrectionLevelM]
+ resolution:99 fileName:@"renderer-test-01.png"];
+
+ [self compareToGoldenFile:@"12345" ecLevel:[ZXErrorCorrectionLevel errorCorrectionLevelL]
+ resolution:58 fileName:@"renderer-test-02.png"];
+
+ // Test in Katakana in Shift_JIS.
+ // TODO: this test is bogus now that byte mode has been basically fixed to assuming ISO-8859-1 encoding
+ // The real solution is to implement Kanji mode, in which case the golden file will be wrong again
+ /*
+ compareToGoldenFile(
+ new String(new byte[] {(byte)0x83, 0x65, (byte)0x83, 0x58, (byte)0x83, 0x67}, "Shift_JIS"),
+ ErrorCorrectionLevel.H, 145,
+ "renderer-test-03.png");
+ */
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXDataMaskTestCase.h b/ZXingObjCTests/qrcode/decoder/ZXDataMaskTestCase.h
new file mode 100644
index 0000000..b992f65
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXDataMaskTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXDataMaskTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXDataMaskTestCase.m b/ZXingObjCTests/qrcode/decoder/ZXDataMaskTestCase.m
new file mode 100644
index 0000000..1249082
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXDataMaskTestCase.m
@@ -0,0 +1,90 @@
+/*
+ * 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 "ZXDataMaskTestCase.h"
+
+typedef BOOL (^MaskCondition)(int i, int j);
+
+@implementation ZXDataMaskTestCase
+
+- (void)testMask0 {
+ [self runTestMaskAcrossDimensions:0 condition:^(int i, int j) {
+ return (BOOL)((i + j) % 2 == 0);
+ }];
+}
+
+- (void)testMask1 {
+ [self runTestMaskAcrossDimensions:1 condition:^(int i, int j) {
+ return (BOOL)(i % 2 == 0);
+ }];
+}
+
+- (void)testMask2 {
+ [self runTestMaskAcrossDimensions:2 condition:^(int i, int j) {
+ return (BOOL)(j % 3 == 0);
+ }];
+}
+
+- (void)testMask3 {
+ [self runTestMaskAcrossDimensions:3 condition:^(int i, int j) {
+ return (BOOL)((i + j) % 3 == 0);
+ }];
+}
+
+- (void)testMask4 {
+ [self runTestMaskAcrossDimensions:4 condition:^(int i, int j) {
+ return (BOOL)((i / 2 + j / 3) % 2 == 0);
+ }];
+}
+
+- (void)testMask5 {
+ [self runTestMaskAcrossDimensions:5 condition:^(int i, int j) {
+ return (BOOL)((i * j) % 2 + (i * j) % 3 == 0);
+ }];
+}
+
+- (void)testMask6 {
+ [self runTestMaskAcrossDimensions:6 condition:^(int i, int j) {
+ return (BOOL)(((i * j) % 2 + (i * j) % 3) % 2 == 0);
+ }];
+}
+
+- (void)testMask7 {
+ [self runTestMaskAcrossDimensions:7 condition:^(int i, int j) {
+ return (BOOL)(((i + j) % 2 + (i * j) % 3) % 2 == 0);
+ }];
+}
+
+- (void)runTestMaskAcrossDimensions:(int)reference condition:(MaskCondition)condition {
+ ZXDataMask *mask = [ZXDataMask forReference:reference];
+ for (int version = 1; version <= 40; version++) {
+ int dimension = 17 + 4 * version;
+ [self runTestMask:mask dimension:dimension condition:condition];
+ }
+}
+
+- (void)runTestMask:(ZXDataMask *)mask dimension:(int)dimension condition:(MaskCondition)condition {
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithDimension:dimension];
+ [mask unmaskBitMatrix:bits dimension:dimension];
+ for (int i = 0; i < dimension; i++) {
+ for (int j = 0; j < dimension; j++) {
+ BOOL expected = condition(i, j);
+ STAssertEquals([bits getX:j y:i], expected, @"Expected (%d,%d) to equal %d", j, i, expected);
+ }
+ }
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXErrorCorrectionLevelTestCase.h b/ZXingObjCTests/qrcode/decoder/ZXErrorCorrectionLevelTestCase.h
new file mode 100644
index 0000000..c80d648
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXErrorCorrectionLevelTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXErrorCorrectionLevelTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXErrorCorrectionLevelTestCase.m b/ZXingObjCTests/qrcode/decoder/ZXErrorCorrectionLevelTestCase.m
new file mode 100644
index 0000000..310cd4d
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXErrorCorrectionLevelTestCase.m
@@ -0,0 +1,38 @@
+/*
+ * 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 "ZXErrorCorrectionLevelTestCase.h"
+
+@implementation ZXErrorCorrectionLevelTestCase
+
+- (void)testForBits {
+ STAssertEqualObjects([ZXErrorCorrectionLevel forBits:0], [ZXErrorCorrectionLevel errorCorrectionLevelM],
+ @"Expected forBits:0 to equal error correction level M");
+ STAssertEqualObjects([ZXErrorCorrectionLevel forBits:1], [ZXErrorCorrectionLevel errorCorrectionLevelL],
+ @"Expected forBits:1 to equal error correction level M");
+ STAssertEqualObjects([ZXErrorCorrectionLevel forBits:2], [ZXErrorCorrectionLevel errorCorrectionLevelH],
+ @"Expected forBits:2 to equal error correction level M");
+ STAssertEqualObjects([ZXErrorCorrectionLevel forBits:3], [ZXErrorCorrectionLevel errorCorrectionLevelQ],
+ @"Expected forBits:3 to equal error correction level M");
+ @try {
+ [ZXErrorCorrectionLevel forBits:4];
+ STFail(@"Should have thrown an exception");
+ } @catch (NSException *ex) {
+ // good
+ }
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXFormatInformationTestCase.h b/ZXingObjCTests/qrcode/decoder/ZXFormatInformationTestCase.h
new file mode 100644
index 0000000..12779fa
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXFormatInformationTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXFormatInformationTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXFormatInformationTestCase.m b/ZXingObjCTests/qrcode/decoder/ZXFormatInformationTestCase.m
new file mode 100644
index 0000000..4425d86
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXFormatInformationTestCase.m
@@ -0,0 +1,59 @@
+/*
+ * 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 "ZXFormatInformationTestCase.h"
+
+const int MASKED_TEST_FORMAT_INFO = 0x2BED;
+const int UNMASKED_TEST_FORMAT_INFO = MASKED_TEST_FORMAT_INFO ^ 0x5412;
+
+@implementation ZXFormatInformationTestCase
+
+- (void)testBitsDiffering {
+ STAssertEquals([ZXFormatInformation numBitsDiffering:1 b:1], 0, @"Expected numBitsDiffering 1, 1 to equal 0");
+ STAssertEquals([ZXFormatInformation numBitsDiffering:0 b:2], 1, @"Expected numBitsDiffering 0, 2 to equal 1");
+ STAssertEquals([ZXFormatInformation numBitsDiffering:1 b:2], 2, @"Expected numBitsDiffering 1, 2 to equal 2");
+ STAssertEquals([ZXFormatInformation numBitsDiffering:-1 b:0], 32, @"Expected numBitsDiffering -1, 0 to equal 32");
+}
+
+- (void)testDecode {
+ // Normal case
+ ZXFormatInformation *expected =
+ [ZXFormatInformation decodeFormatInformation:MASKED_TEST_FORMAT_INFO maskedFormatInfo2:MASKED_TEST_FORMAT_INFO];
+ STAssertNotNil(expected, @"Expected expected to be non-nil");
+ STAssertEquals(expected.dataMask, (char) 0x07, @"Expected data mask to equal 0x07");
+ STAssertEqualObjects(expected.errorCorrectionLevel, [ZXErrorCorrectionLevel errorCorrectionLevelQ],
+ @"Expected error correction level to be Q");
+ // where the code forgot the mask!
+ STAssertEqualObjects([ZXFormatInformation decodeFormatInformation:UNMASKED_TEST_FORMAT_INFO maskedFormatInfo2:MASKED_TEST_FORMAT_INFO], expected, @"Expected decode to be %@", expected);
+}
+
+- (void)testDecodeWithBitDifference {
+ ZXFormatInformation *expected =
+ [ZXFormatInformation decodeFormatInformation:MASKED_TEST_FORMAT_INFO maskedFormatInfo2:MASKED_TEST_FORMAT_INFO];
+ // 1,2,3,4 bits difference
+ STAssertEqualObjects([ZXFormatInformation decodeFormatInformation:MASKED_TEST_FORMAT_INFO ^ 0x01 maskedFormatInfo2:MASKED_TEST_FORMAT_INFO ^ 0x01], expected, @"Expected decode to be %@", expected);
+ STAssertEqualObjects([ZXFormatInformation decodeFormatInformation:MASKED_TEST_FORMAT_INFO ^ 0x03 maskedFormatInfo2:MASKED_TEST_FORMAT_INFO ^ 0x03], expected, @"Expected decode to be %@", expected);
+ STAssertEqualObjects([ZXFormatInformation decodeFormatInformation:MASKED_TEST_FORMAT_INFO ^ 0x07 maskedFormatInfo2:MASKED_TEST_FORMAT_INFO ^ 0x07], expected, @"Expected decode to be %@", expected);
+ STAssertNil([ZXFormatInformation decodeFormatInformation:MASKED_TEST_FORMAT_INFO ^ 0x0F maskedFormatInfo2:MASKED_TEST_FORMAT_INFO ^ 0x0F], @"Expected decode to be nil");
+}
+
+- (void)testDecodeWithMisread {
+ ZXFormatInformation *expected =
+ [ZXFormatInformation decodeFormatInformation:MASKED_TEST_FORMAT_INFO maskedFormatInfo2:MASKED_TEST_FORMAT_INFO];
+ STAssertEqualObjects([ZXFormatInformation decodeFormatInformation:MASKED_TEST_FORMAT_INFO ^ 0x03 maskedFormatInfo2:MASKED_TEST_FORMAT_INFO ^ 0x0F], expected, @"Expected decode to be %@", expected);
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXModeTestCase.h b/ZXingObjCTests/qrcode/decoder/ZXModeTestCase.h
new file mode 100644
index 0000000..efd74fc
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXModeTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXModeTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXModeTestCase.m b/ZXingObjCTests/qrcode/decoder/ZXModeTestCase.m
new file mode 100644
index 0000000..b94f3f6
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXModeTestCase.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 "ZXModeTestCase.h"
+
+@implementation ZXModeTestCase
+
+- (void)testForBits {
+ STAssertEqualObjects([ZXMode forBits:0x00], [ZXMode terminatorMode], @"Expected terminator mode");
+ STAssertEqualObjects([ZXMode forBits:0x01], [ZXMode numericMode], @"Expected numeric mode");
+ STAssertEqualObjects([ZXMode forBits:0x02], [ZXMode alphanumericMode], @"Expected alphanumeric mode");
+ STAssertEqualObjects([ZXMode forBits:0x04], [ZXMode byteMode], @"Expected byte mode");
+ STAssertEqualObjects([ZXMode forBits:0x08], [ZXMode kanjiMode], @"Expected kanji mode");
+ if ([ZXMode forBits:0x10]) {
+ STFail(@"Should have failed");
+ }
+}
+
+- (void)testCharacterCount {
+ // Spot check a few values
+ STAssertEquals([[ZXMode numericMode] characterCountBits:[ZXQRCodeVersion versionForNumber:5]], 10,
+ @"Expected character count bits to be 10");
+ STAssertEquals([[ZXMode numericMode] characterCountBits:[ZXQRCodeVersion versionForNumber:26]], 12,
+ @"Expected character count bits to be 12");
+ STAssertEquals([[ZXMode numericMode] characterCountBits:[ZXQRCodeVersion versionForNumber:40]], 14,
+ @"Expected character count bits to be 14");
+ STAssertEquals([[ZXMode byteMode] characterCountBits:[ZXQRCodeVersion versionForNumber:7]], 8,
+ @"Expected character count bits to be 8");
+ STAssertEquals([[ZXMode kanjiMode] characterCountBits:[ZXQRCodeVersion versionForNumber:8]], 8,
+ @"Expected character count bits to be 8");
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.h b/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.h
new file mode 100644
index 0000000..dbea8c5
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXQRCodeDecodedBitStreamParserTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.m b/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.m
new file mode 100644
index 0000000..8a97455
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXQRCodeDecodedBitStreamParserTestCase.m
@@ -0,0 +1,76 @@
+/*
+ * 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 "ZXBitSourceBuilder.h"
+#import "ZXQRCodeDecodedBitStreamParserTestCase.h"
+
+@implementation ZXQRCodeDecodedBitStreamParserTestCase
+
+- (void)testSimpleByteMode {
+ ZXBitSourceBuilder *builder = [[ZXBitSourceBuilder alloc] init];
+ [builder write:0x04 numBits:4]; // Byte mode
+ [builder write:0x03 numBits:8]; // 3 bytes
+ [builder write:0xF1 numBits:8];
+ [builder write:0xF2 numBits:8];
+ [builder write:0xF3 numBits:8];
+ NSString *result = [[ZXQRCodeDecodedBitStreamParser decode:[builder toByteArray] length:[builder byteArrayLength]
+ version:[ZXQRCodeVersion versionForNumber:1] ecLevel:nil hints:nil error:nil] text];
+ NSString *expected = @"\u00f1\u00f2\u00f3";
+ STAssertEqualObjects(result, expected, @"Expected %@ to equal %@", result, expected);
+}
+
+- (void)testSimpleSJIS {
+ ZXBitSourceBuilder *builder = [[ZXBitSourceBuilder alloc] init];
+ [builder write:0x04 numBits:4]; // Byte mode
+ [builder write:0x04 numBits:8]; // 4 bytes
+ [builder write:0xA1 numBits:8];
+ [builder write:0xA2 numBits:8];
+ [builder write:0xA3 numBits:8];
+ [builder write:0xD0 numBits:8];
+ NSString *result = [[ZXQRCodeDecodedBitStreamParser decode:[builder toByteArray] length:[builder byteArrayLength]
+ version:[ZXQRCodeVersion versionForNumber:1] ecLevel:nil hints:nil error:nil] text];
+ NSString *expected = @"\uff61\uff62\uff63\uff90";
+ STAssertEqualObjects(result, expected, @"Expected %@ to equal %@", result, expected);
+}
+
+- (void)testECI {
+ ZXBitSourceBuilder *builder = [[ZXBitSourceBuilder alloc] init];
+ [builder write:0x07 numBits:4]; // ECI mode
+ [builder write:0x02 numBits:8]; // ECI 2 = CP437 encoding
+ [builder write:0x04 numBits:4]; // Byte mode
+ [builder write:0x03 numBits:8]; // 3 bytes
+ [builder write:0xA1 numBits:8];
+ [builder write:0xA2 numBits:8];
+ [builder write:0xA3 numBits:8];
+ NSString *result = [[ZXQRCodeDecodedBitStreamParser decode:[builder toByteArray] length:[builder byteArrayLength]
+ version:[ZXQRCodeVersion versionForNumber:1] ecLevel:nil hints:nil error:nil] text];
+ NSString *expected = @"\u00ed\u00f3\u00fa";
+ STAssertEqualObjects(result, expected, @"Expected %@ to equal %@", result, expected);
+}
+
+- (void)testHanzi {
+ 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
+ [builder write:0x03C1 numBits:13];
+ NSString *result = [[ZXQRCodeDecodedBitStreamParser decode:[builder toByteArray] length:[builder byteArrayLength]
+ version:[ZXQRCodeVersion versionForNumber:1] ecLevel:nil hints:nil error:nil] text];
+ NSString *expected = @"\u963f";
+ STAssertEqualObjects(result, expected, @"Expected %@ to equal %@", result, expected);
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXQRCodeVersionTestCase.h b/ZXingObjCTests/qrcode/decoder/ZXQRCodeVersionTestCase.h
new file mode 100644
index 0000000..b489f47
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXQRCodeVersionTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXQRCodeVersionTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/decoder/ZXQRCodeVersionTestCase.m b/ZXingObjCTests/qrcode/decoder/ZXQRCodeVersionTestCase.m
new file mode 100644
index 0000000..c303df4
--- /dev/null
+++ b/ZXingObjCTests/qrcode/decoder/ZXQRCodeVersionTestCase.m
@@ -0,0 +1,74 @@
+/*
+ * 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 "ZXErrorCorrectionLevel.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXQRCodeVersionTestCase.h"
+
+@implementation ZXQRCodeVersionTestCase
+
+- (void)testVersionForNumber {
+ if ([ZXQRCodeVersion versionForNumber:0]) {
+ STFail(@"Should have failed");
+ }
+ for (int i = 1; i <= 40; i++) {
+ [self checkVersion:[ZXQRCodeVersion versionForNumber:i] number:i dimension:4*i + 17];
+ }
+}
+
+- (void)checkVersion:(ZXQRCodeVersion *)version number:(int)number dimension:(int)dimension {
+ STAssertNotNil(version, @"Expected version to be non-nil");
+ STAssertEquals(version.versionNumber, number, @"Expected version number to be %d", number);
+ STAssertNotNil(version.alignmentPatternCenters, @"Expected alignmentPatternCenters to be non-nil");
+ if (number > 1) {
+ STAssertTrue(version.alignmentPatternCenters.count > 0, @"Expected alignmentPatternCenters to be non-empty");
+ }
+ STAssertEquals(version.dimensionForVersion, dimension, @"Expected dimension to be %d");
+ STAssertNotNil([version ecBlocksForLevel:[ZXErrorCorrectionLevel errorCorrectionLevelH]],
+ @"Expected ecblocks for error correction level H to be non-nil");
+ STAssertNotNil([version ecBlocksForLevel:[ZXErrorCorrectionLevel errorCorrectionLevelL]],
+ @"Expected ecblocks for error correction level L to be non-nil");
+ STAssertNotNil([version ecBlocksForLevel:[ZXErrorCorrectionLevel errorCorrectionLevelM]],
+ @"Expected ecblocks for error correction level M to be non-nil");
+ STAssertNotNil([version ecBlocksForLevel:[ZXErrorCorrectionLevel errorCorrectionLevelQ]],
+ @"Expected ecblocks for error correction level Q to be non-nil");
+ STAssertNotNil([version buildFunctionPattern], @"Expected version buildFunctionPattern to be non-nil");
+}
+
+- (void)testGetProvisionalVersionForDimension {
+ for (int i = 1; i <= 40; i++) {
+ STAssertEquals([ZXQRCodeVersion provisionalVersionForDimension:4*i + 17].versionNumber, i,
+ @"Expected version number to be %d", i);
+ }
+}
+
+- (void)testDecodeVersionInformation {
+ // Spot check
+ [self doTestVersion:7 mask:0x07C94];
+ [self doTestVersion:12 mask:0x0C762];
+ [self doTestVersion:17 mask:0x1145D];
+ [self doTestVersion:22 mask:0x168C9];
+ [self doTestVersion:27 mask:0x1B08E];
+ [self doTestVersion:32 mask:0x209D5];
+}
+
+- (void)doTestVersion:(int)expectedVersion mask:(int)mask {
+ ZXQRCodeVersion *version = [ZXQRCodeVersion decodeVersionInformation:mask];
+ STAssertNotNil(version, @"Expected version to be non-nil");
+ STAssertEquals(version.versionNumber, expectedVersion, @"Expected version number to be %d", expectedVersion);
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/BitVectorTestCase.h b/ZXingObjCTests/qrcode/encoder/BitVectorTestCase.h
new file mode 100644
index 0000000..53c0790
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/BitVectorTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface BitVectorTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/BitVectorTestCase.m b/ZXingObjCTests/qrcode/encoder/BitVectorTestCase.m
new file mode 100644
index 0000000..d5aeca1
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/BitVectorTestCase.m
@@ -0,0 +1,169 @@
+/*
+ * 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 "BitVectorTestCase.h"
+
+@implementation BitVectorTestCase
+
+- (unsigned long)unsignedInt:(ZXBitArray *)v index:(int)index {
+ unsigned long result = 0L;
+ for (int i = 0, offset = index << 3; i < 32; i++) {
+ if ([v get:offset + i]) {
+ result |= 1L << (31 - i);
+ }
+ }
+ return result;
+}
+
+- (void)testAppendBit {
+ ZXBitArray *v = [[ZXBitArray alloc] init];
+ STAssertEquals(v.sizeInBytes, 0, @"Expected sizeInBytes to be 0");
+ // 1
+ [v appendBit:YES];
+ STAssertEquals(v.size, 1, @"Expected size to be 1");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0x80000000L, @"Expected unsigned int at index 0 to equal %d", 0x80000000L);
+ // 10
+ [v appendBit:NO];
+ STAssertEquals(v.size, 2, @"Expected size to be 2");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0x80000000L, @"Expected unsigned int at index 0 to equal %d", 0x80000000L);
+ // 101
+ [v appendBit:YES];
+ STAssertEquals(v.size, 3, @"Expected size to be 3");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xa0000000L, @"Expected unsigned int at index 0 to equal %d", 0xa0000000L);
+ // 1010
+ [v appendBit:NO];
+ STAssertEquals(v.size, 4, @"Expected size to be 4");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xa0000000L, @"Expected unsigned int at index 0 to equal %d", 0xa0000000L);
+ // 10101
+ [v appendBit:YES];
+ STAssertEquals(v.size, 5, @"Expected size to be 5");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xa8000000L, @"Expected unsigned int at index 0 to equal %d", 0xa8000000L);
+ // 101010
+ [v appendBit:NO];
+ STAssertEquals(v.size, 6, @"Expected size to be 6");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xa8000000L, @"Expected unsigned int at index 0 to equal %d", 0xa8000000L);
+ // 1010101
+ [v appendBit:YES];
+ STAssertEquals(v.size, 7, @"Expected size to be 7");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xaa000000L, @"Expected unsigned int at index 0 to equal %d", 0xaa000000L);
+ // 10101010
+ [v appendBit:NO];
+ STAssertEquals(v.size, 8, @"Expected size to be 8");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xaa000000L, @"Expected unsigned int at index 0 to equal %d", 0xaa000000L);
+ // 10101010 1
+ [v appendBit:YES];
+ STAssertEquals(v.size, 9, @"Expected size to be 9");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xaa800000L, @"Expected unsigned int at index 0 to equal %d", 0xaa800000L);
+ // 10101010 10
+ [v appendBit:NO];
+ STAssertEquals(v.size, 10, @"Expected size to be 10");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xaa800000L, @"Expected unsigned int at index 0 to equal %d", 0xaa800000L);
+}
+
+- (void)testAppendBits {
+ ZXBitArray *v = [[ZXBitArray alloc] init];
+ [v appendBits:0x1 numBits:1];
+ STAssertEquals(v.size, 1, @"Expected size to be 1");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0x80000000L, @"Expected unsigned int at index 0 to equal %d", 0x80000000L);
+ v = [[ZXBitArray alloc] init];
+ [v appendBits:0xff numBits:8];
+ STAssertEquals(v.size, 8, @"Expected size to be 8");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xff000000L, @"Expected unsigned int at index 0 to equal %d", 0xff000000L);
+ v = [[ZXBitArray alloc] init];
+ [v appendBits:0xff7 numBits:12];
+ STAssertEquals(v.size, 12, @"Expected size to be 12");
+ STAssertEquals([self unsignedInt:v index:0], (unsigned long)0xff700000L, @"Expected unsigned int at index 0 to equal %d", 0xff700000L);
+}
+
+- (void)testNumBytes {
+ ZXBitArray *v = [[ZXBitArray alloc] init];
+ STAssertEquals(v.sizeInBytes, 0, @"Expected sizeInBytes to be 0");
+ [v appendBit:NO];
+ // 1 bit was added in the vector, so 1 byte should be consumed.
+ STAssertEquals(v.sizeInBytes, 1, @"Expected sizeInBytes to be 1");
+ [v appendBits:0 numBits:7];
+ STAssertEquals(v.sizeInBytes, 1, @"Expected sizeInBytes to be 1");
+ [v appendBits:0 numBits:8];
+ STAssertEquals(v.sizeInBytes, 2, @"Expected sizeInBytes to be 2");
+ [v appendBits:0 numBits:1];
+ // We now have 17 bits, so 3 bytes should be consumed.
+ STAssertEquals(v.sizeInBytes, 3, @"Expected sizeInBytes to be 3");
+}
+
+- (void)testAppendBitVector {
+ ZXBitArray *v1 = [[ZXBitArray alloc] init];
+ [v1 appendBits:0xbe numBits:8];
+ ZXBitArray *v2 = [[ZXBitArray alloc] init];
+ [v2 appendBits:0xef numBits:8];
+ [v1 appendBitArray:v2];
+ // beef = 1011 1110 1110 1111
+ NSString *expected = @" X.XXXXX. XXX.XXXX";
+ STAssertEqualObjects([v1 description], expected, @"Expected v1 to be %@", expected);
+}
+
+- (void)testXOR {
+ {
+ ZXBitArray *v1 = [[ZXBitArray alloc] init];
+ [v1 appendBits:0x5555aaaa numBits:32];
+ ZXBitArray *v2 = [[ZXBitArray alloc] init];
+ [v2 appendBits:0xaaaa5555 numBits:32];
+ [v1 xor:v2];
+ STAssertEquals([self unsignedInt:v1 index:0], (unsigned long)0xffffffffL,
+ @"Expected unsigned int at index 0 to equal %d", 0xffffffffL);
+ }
+ {
+ ZXBitArray *v1 = [[ZXBitArray alloc] init];
+ [v1 appendBits:0x2a numBits:7]; // 010 1010
+ ZXBitArray *v2 = [[ZXBitArray alloc] init];
+ [v2 appendBits:0x55 numBits:7]; // 101 0101
+ [v1 xor:v2];
+ STAssertEquals([self unsignedInt:v1 index:0], (unsigned long)0xfe000000L,
+ @"Expected unsigned int at index 0 to equal %d", 0xfe000000L); // 1111 1110
+ }
+}
+
+- (void)testAt {
+ ZXBitArray *v = [[ZXBitArray alloc] init];
+ [v appendBits:0xdead numBits:16]; // 1101 1110 1010 1101
+ STAssertTrue([v get:0], @"Expected value at 0 to be 1");
+ STAssertTrue([v get:1], @"Expected value at 1 to be 1");
+ STAssertFalse([v get:2], @"Expected value at 2 to be 0");
+ STAssertTrue([v get:3], @"Expected value at 3 to be 1");
+
+ STAssertTrue([v get:4], @"Expected value at 4 to be 1");
+ STAssertTrue([v get:5], @"Expected value at 5 to be 1");
+ STAssertTrue([v get:6], @"Expected value at 6 to be 1");
+ STAssertFalse([v get:7], @"Expected value at 7 to be 0");
+
+ STAssertTrue([v get:8], @"Expected value at 8 to be 1");
+ STAssertFalse([v get:9], @"Expected value at 9 to be 0");
+ STAssertTrue([v get:10], @"Expected value at 10 to be 1");
+ STAssertFalse([v get:11], @"Expected value at 11 to be 0");
+
+ STAssertTrue([v get:12], @"Expected value at 12 to be 1");
+ STAssertTrue([v get:13], @"Expected value at 13 to be 1");
+ STAssertFalse([v get:14], @"Expected value at 14 to be 0");
+ STAssertTrue([v get:15], @"Expected value at 15 to be 1");
+}
+
+- (void)testToString {
+ ZXBitArray *v = [[ZXBitArray alloc] init];
+ [v appendBits:0xdead numBits:16]; // 1101 1110 1010 1101
+ NSString *expected = @" XX.XXXX. X.X.XX.X";
+ STAssertEqualObjects([v description], expected, @"Expected v to be %@", expected);
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/ZXEncoderTestCase.h b/ZXingObjCTests/qrcode/encoder/ZXEncoderTestCase.h
new file mode 100644
index 0000000..5246cbb
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/ZXEncoderTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXEncoderTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/ZXEncoderTestCase.m b/ZXingObjCTests/qrcode/encoder/ZXEncoderTestCase.m
new file mode 100644
index 0000000..e291519
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/ZXEncoderTestCase.m
@@ -0,0 +1,532 @@
+/*
+ * 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 "ZXEncoderTestCase.h"
+
+@implementation ZXEncoderTestCase
+
+- (void)testGetAlphanumericCode {
+ // The first ten code points are numbers.
+ for (int i = 0; i < 10; ++i) {
+ STAssertEquals([ZXEncoder alphanumericCode:'0' + i], i, @"Expected %d", i);
+ }
+
+ // The next 26 code points are capital alphabet letters.
+ for (int i = 10; i < 36; ++i) {
+ STAssertEquals([ZXEncoder alphanumericCode:'A' + i - 10], i, @"Expected %d", i);
+ }
+
+ // Others are symbol letters
+ STAssertEquals([ZXEncoder alphanumericCode:' '], 36, @"Expected %d", 36);
+ STAssertEquals([ZXEncoder alphanumericCode:'$'], 37, @"Expected %d", 37);
+ STAssertEquals([ZXEncoder alphanumericCode:'%'], 38, @"Expected %d", 38);
+ STAssertEquals([ZXEncoder alphanumericCode:'*'], 39, @"Expected %d", 39);
+ STAssertEquals([ZXEncoder alphanumericCode:'+'], 40, @"Expected %d", 40);
+ STAssertEquals([ZXEncoder alphanumericCode:'-'], 41, @"Expected %d", 41);
+ STAssertEquals([ZXEncoder alphanumericCode:'.'], 42, @"Expected %d", 42);
+ STAssertEquals([ZXEncoder alphanumericCode:'/'], 43, @"Expected %d", 43);
+ STAssertEquals([ZXEncoder alphanumericCode:':'], 44, @"Expected %d", 44);
+
+ // Should return -1 for other letters;
+ STAssertEquals([ZXEncoder alphanumericCode:'a'], -1, @"Expected -1");
+ STAssertEquals([ZXEncoder alphanumericCode:'#'], -1, @"Expected -1");
+ STAssertEquals([ZXEncoder alphanumericCode:'\0'], -1, @"Expected -1");
+}
+
+- (void)testChooseMode {
+ // Numeric mode.
+ STAssertEqualObjects([ZXEncoder chooseMode:@"0"], [ZXMode numericMode], @"Expected numeric mode");
+ STAssertEqualObjects([ZXEncoder chooseMode:@"0123456789"], [ZXMode numericMode], @"Expected numeric mode");
+ // Alphanumeric mode.
+ STAssertEqualObjects([ZXEncoder chooseMode:@"A"], [ZXMode alphanumericMode], @"Expected alphanumeric mode");
+ STAssertEqualObjects([ZXEncoder chooseMode:@"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"],
+ [ZXMode alphanumericMode], @"Expected alphanumeric mode");
+ // 8-bit byte mode.
+ STAssertEqualObjects([ZXEncoder chooseMode:@"a"], [ZXMode byteMode], @"Expected byte mode");
+ STAssertEqualObjects([ZXEncoder chooseMode:@"#"], [ZXMode byteMode], @"Expected byte mode");
+ STAssertEqualObjects([ZXEncoder chooseMode:@""], [ZXMode byteMode], @"Expected byte mode");
+ // Kanji mode. We used to use MODE_KANJI for these, but we stopped
+ // doing that as we cannot distinguish Shift_JIS from other encodings
+ // from data bytes alone. See also comments in qrcode_encoder.h.
+
+ // AIUE in Hiragana in Shift_JIS
+ int8_t hiraganaBytes[8] = {0x8, 0xa, 0x8, 0xa, 0x8, 0xa, 0x8, 0xa6};
+ STAssertEqualObjects([ZXEncoder chooseMode:[self shiftJISString:hiraganaBytes bytesLen:8]], [ZXMode byteMode],
+ @"Expected byte mode");
+
+ // Nihon in Kanji in Shift_JIS.
+ int8_t kanjiBytes[4] = {0x9, 0xf, 0x9, 0x7b};
+ STAssertEqualObjects([ZXEncoder chooseMode:[self shiftJISString:kanjiBytes bytesLen:4]], [ZXMode byteMode],
+ @"Expected byte mode");
+
+ // Sou-Utsu-Byou in Kanji in Shift_JIS.
+ int8_t kanjiBytes2[6] = {0xe, 0x4, 0x9, 0x5, 0x9, 0x61};
+ STAssertEqualObjects([ZXEncoder chooseMode:[self shiftJISString:kanjiBytes2 bytesLen:6]], [ZXMode byteMode],
+ @"Expected byte mode");
+}
+
+- (void)testEncode {
+ ZXQRCode *qrCode = [ZXEncoder encode:@"ABCDEF" ecLevel:[ZXErrorCorrectionLevel errorCorrectionLevelH] error:nil];
+ // The following is a valid QR Code that can be read by cell phones.
+ NSString *expected =
+ @"<<\n"
+ " mode: ALPHANUMERIC\n"
+ " ecLevel: H\n"
+ " version: 1\n"
+ " maskPattern: 0\n"
+ " matrix:\n"
+ " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 1 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 0 1 1 1 0 1 0 0 1 0 1 1 0 1 0 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 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 1 1 0 0 1 0 1 1 1 0 1\n"
+ " 1 0 0 0 0 0 1 0 0 1 0 0 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 1 0 0 0 0 0 0 0 0\n"
+ " 0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 0 0 1 0 0 1\n"
+ " 1 0 1 1 1 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0\n"
+ " 0 0 1 1 0 0 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0\n"
+ " 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 0\n"
+ " 0 0 1 1 0 1 1 1 1 0 0 0 1 0 1 0 1 1 1 1 0\n"
+ " 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 1 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 1\n"
+ " 1 0 0 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 0 0 0 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 0 1 0\n"
+ " 1 0 1 1 1 0 1 0 1 0 0 0 1 0 1 0 1 1 1 0 1\n"
+ " 1 0 0 0 0 0 1 0 0 1 1 0 1 1 0 1 0 0 0 1 1\n"
+ " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1\n"
+ ">>\n";
+ STAssertEqualObjects([qrCode description], expected, @"Expected qr code to equal %@", expected);
+}
+
+- (void)testSimpleUTF8ECI {
+ ZXEncodeHints *hints = [ZXEncodeHints hints];
+ hints.encoding = NSUTF8StringEncoding;
+ ZXQRCode *qrCode = [ZXEncoder encode:@"hello" ecLevel:[ZXErrorCorrectionLevel errorCorrectionLevelH] hints:hints error:nil];
+ NSString *expected =
+ @"<<\n"
+ " mode: BYTE\n"
+ " ecLevel: H\n"
+ " version: 1\n"
+ " maskPattern: 3\n"
+ " matrix:\n"
+ " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1\n"
+ " 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 0 0 0 0 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 0 1 1 0 1 0 1 0 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1\n"
+ " 1 0 0 0 0 0 1 0 0 0 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 0 0 0 0 0 0 0 0 0 0\n"
+ " 0 0 1 1 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 0 0\n"
+ " 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 0\n"
+ " 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 1 1 1\n"
+ " 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 0 1 0 1 1 0\n"
+ " 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0\n"
+ " 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 0 0 0 1\n"
+ " 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0\n"
+ " 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0\n"
+ " 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 1 0 0 0\n"
+ " 1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 0 0 0\n"
+ " 1 0 0 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 0\n"
+ " 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 0\n"
+ ">>\n";
+ STAssertEqualObjects([qrCode description], expected, @"Expected qr code to equal %@", expected);
+}
+
+- (void)testAppendModeInfo {
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendModeInfo:[ZXMode numericMode] bits:bits];
+ NSString *expected = @" ...X";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+}
+
+- (void)testAppendLengthInfo {
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendLengthInfo:1 // 1 letter (1/1).
+ version:[ZXQRCodeVersion versionForNumber:1]
+ mode:[ZXMode numericMode]
+ bits:bits
+ error:nil];
+ NSString *expected = @" ........ .X";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected); // 10 bits.
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendLengthInfo:2 // 2 letter (2/1).
+ version:[ZXQRCodeVersion versionForNumber:10]
+ mode:[ZXMode alphanumericMode]
+ bits:bits
+ error:nil];
+ expected = @" ........ .X.";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected); // 11 bits.
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendLengthInfo:255 // 255 letter (255/1).
+ version:[ZXQRCodeVersion versionForNumber:27]
+ mode:[ZXMode byteMode]
+ bits:bits
+ error:nil];
+ expected = @" ........ XXXXXXXX";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected); // 16 bits.
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendLengthInfo:512 // 512 letter (1024/2).
+ version:[ZXQRCodeVersion versionForNumber:40]
+ mode:[ZXMode kanjiMode]
+ bits:bits
+ error:nil];
+ expected = @" ..X..... ....";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected); // 12 bits.
+}
+
+- (void)testAppendBytes {
+ // Should use appendNumericBytes.
+ // 1 = 01 = 0001 in 4 bits.
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendBytes:@"1" mode:[ZXMode numericMode] bits:bits encoding:DEFAULT_BYTE_MODE_ENCODING error:nil];
+ NSString *expected = @" ...X";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // Should use appendAlphanumericBytes.
+ // A = 10 = 0xa = 001010 in 6 bits
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendBytes:@"A" mode:[ZXMode alphanumericMode] bits:bits encoding:DEFAULT_BYTE_MODE_ENCODING error:nil];
+ expected = @" ..X.X.";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // Lower letters such as 'a' cannot be encoded in MODE_ALPHANUMERIC.
+ NSError *error;
+ if ([ZXEncoder appendBytes:@"a" mode:[ZXMode alphanumericMode] bits:bits encoding:DEFAULT_BYTE_MODE_ENCODING error:&error] ||
+ error.code != ZXWriterError) {
+ STFail(@"Expected ZXWriterError");
+ }
+ // Should use append8BitBytes.
+ // 0x61, 0x62, 0x63
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendBytes:@"abc" mode:[ZXMode byteMode] bits:bits encoding:DEFAULT_BYTE_MODE_ENCODING error:nil];
+ expected = @" .XX....X .XX...X. .XX...XX";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // Anything can be encoded in QRCode.MODE_8BIT_BYTE.
+ [ZXEncoder appendBytes:@"\0" mode:[ZXMode byteMode] bits:bits encoding:DEFAULT_BYTE_MODE_ENCODING error:nil];
+ // Should use appendKanjiBytes.
+ // 0x93, 0x5f
+ bits = [[ZXBitArray alloc] init];
+ int8_t bytes[2] = {0x93, 0x5f};
+ [ZXEncoder appendBytes:[self shiftJISString:bytes bytesLen:2] mode:[ZXMode kanjiMode] bits:bits encoding:DEFAULT_BYTE_MODE_ENCODING error:nil];
+ expected = @" .XX.XX.. XXXXX";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+}
+
+- (void)testTerminateBits {
+ ZXBitArray *v = [[ZXBitArray alloc] init];
+ [ZXEncoder terminateBits:0 bits:v error:nil];
+ STAssertEqualObjects([v description], @"", @"Expected v to equal \"\"");
+ v = [[ZXBitArray alloc] init];
+ [ZXEncoder terminateBits:1 bits:v error:nil];
+ NSString *expected = @" ........";
+ STAssertEqualObjects([v description], expected, @"Expected v to equal %@");
+ v = [[ZXBitArray alloc] init];
+ [v appendBits:0 numBits:3]; // Append 000
+ [ZXEncoder terminateBits:1 bits:v error:nil];
+ expected = @" ........";
+ STAssertEqualObjects([v description], expected, @"Expected v to equal %@");
+ v = [[ZXBitArray alloc] init];
+ [v appendBits:0 numBits:5]; // Append 00000
+ [ZXEncoder terminateBits:1 bits:v error:nil];
+ expected = @" ........";
+ STAssertEqualObjects([v description], expected, @"Expected v to equal %@");
+ v = [[ZXBitArray alloc] init];
+ [v appendBits:0 numBits:8]; // Append 00000000
+ [ZXEncoder terminateBits:1 bits:v error:nil];
+ expected = @" ........";
+ STAssertEqualObjects([v description], expected, @"Expected v to equal %@");
+ v = [[ZXBitArray alloc] init];
+ [ZXEncoder terminateBits:2 bits:v error:nil];
+ expected = @" ........ XXX.XX..";
+ STAssertEqualObjects([v description], expected, @"Expected v to equal %@");
+ v = [[ZXBitArray alloc] init];
+ [v appendBits:0 numBits:1]; // Append 0
+ [ZXEncoder terminateBits:3 bits:v error:nil];
+ expected = @" ........ XXX.XX.. ...X...X";
+ STAssertEqualObjects([v description], expected, @"Expected v to equal %@");
+}
+
+- (void)testGetNumDataBytesAndNumECBytesForBlockID {
+ int numDataBytes[1] = {0};
+ int numEcBytes[1] = {0};
+ // Version 1-H.
+ [ZXEncoder numDataBytesAndNumECBytesForBlockID:26 numDataBytes:9 numRSBlocks:1 blockID:0
+ numDataBytesInBlock:numDataBytes numECBytesInBlock:numEcBytes error:nil];
+ STAssertEquals(numDataBytes[0], 9, @"Expected numDataBytes[0] to equal %d", 9);
+ STAssertEquals(numEcBytes[0], 17, @"Expected numEcBytes[0] to equal %d", 17);
+
+ // Version 3-H. 2 blocks.
+ [ZXEncoder numDataBytesAndNumECBytesForBlockID:70 numDataBytes:26 numRSBlocks:2 blockID:0
+ numDataBytesInBlock:numDataBytes numECBytesInBlock:numEcBytes error:nil];
+ STAssertEquals(numDataBytes[0], 13, @"Expected numDataBytes[0] to equal %d", 13);
+ STAssertEquals(numEcBytes[0], 22, @"Expected numEcBytes[0] to equal %d", 22);
+ [ZXEncoder numDataBytesAndNumECBytesForBlockID:70 numDataBytes:26 numRSBlocks:2 blockID:1
+ numDataBytesInBlock:numDataBytes numECBytesInBlock:numEcBytes error:nil];
+ STAssertEquals(numDataBytes[0], 13, @"Expected numDataBytes[0] to equal %d", 13);
+ STAssertEquals(numEcBytes[0], 22, @"Expected numEcBytes[0] to equal %d", 22);
+
+ // Version 7-H. (4 + 1) blocks.
+ [ZXEncoder numDataBytesAndNumECBytesForBlockID:196 numDataBytes:66 numRSBlocks:5 blockID:0
+ numDataBytesInBlock:numDataBytes numECBytesInBlock:numEcBytes error:nil];
+ STAssertEquals(numDataBytes[0], 13, @"Expected numDataBytes[0] to equal %d", 13);
+ STAssertEquals(numEcBytes[0], 26, @"Expected numEcBytes[0] to equal %d", 26);
+ [ZXEncoder numDataBytesAndNumECBytesForBlockID:196 numDataBytes:66 numRSBlocks:5 blockID:4
+ numDataBytesInBlock:numDataBytes numECBytesInBlock:numEcBytes error:nil];
+ STAssertEquals(numDataBytes[0], 14, @"Expected numDataBytes[0] to equal %d", 14);
+ STAssertEquals(numEcBytes[0], 26, @"Expected numEcBytes[0] to equal %d", 22);
+
+ // Version 40-H. (20 + 61) blocks.
+ [ZXEncoder numDataBytesAndNumECBytesForBlockID:3706 numDataBytes:1276 numRSBlocks:81 blockID:0
+ numDataBytesInBlock:numDataBytes numECBytesInBlock:numEcBytes error:nil];
+ STAssertEquals(numDataBytes[0], 15, @"Expected numDataBytes[0] to equal %d", 15);
+ STAssertEquals(numEcBytes[0], 30, @"Expected numEcBytes[0] to equal %d", 30);
+ [ZXEncoder numDataBytesAndNumECBytesForBlockID:3706 numDataBytes:1276 numRSBlocks:81 blockID:20
+ numDataBytesInBlock:numDataBytes numECBytesInBlock:numEcBytes error:nil];
+ STAssertEquals(numDataBytes[0], 16, @"Expected numDataBytes[0] to equal %d", 16);
+ STAssertEquals(numEcBytes[0], 30, @"Expected numEcBytes[0] to equal %d", 30);
+ [ZXEncoder numDataBytesAndNumECBytesForBlockID:3706 numDataBytes:1276 numRSBlocks:81 blockID:80
+ numDataBytesInBlock:numDataBytes numECBytesInBlock:numEcBytes error:nil];
+ STAssertEquals(numDataBytes[0], 16, @"Expected numDataBytes[0] to equal %d", 16);
+ STAssertEquals(numEcBytes[0], 30, @"Expected numEcBytes[0] to equal %d", 30);
+}
+
+- (void)testInterleaveWithECBytes {
+ const int dataBytesLen = 9;
+ int8_t dataBytes[dataBytesLen] = {32, 65, 205, 69, 41, 220, 46, 128, 236};
+ ZXBitArray *in = [[ZXBitArray alloc] init];
+ for (int i = 0; i < dataBytesLen; i++) {
+ [in appendBits:dataBytes[i] numBits:8];
+ }
+ ZXBitArray *out = [ZXEncoder interleaveWithECBytes:in numTotalBytes:26 numDataBytes:9 numRSBlocks:1 error:nil];
+ const int expectedLen = 26;
+ int8_t expected[expectedLen] = {
+ // Data bytes.
+ 32, 65, 205, 69, 41, 220, 46, 128, 236,
+ // Error correction bytes.
+ 42, 159, 74, 221, 244, 169, 239, 150, 138, 70,
+ 237, 85, 224, 96, 74, 219, 61,
+ };
+ STAssertEquals(out.sizeInBytes, expectedLen, @"Expected out sizeInBytes to equal %d", expectedLen);
+ int8_t outArray[expectedLen];
+ memset(outArray, 0, expectedLen * sizeof(int8_t));
+ [out toBytes:0 array:outArray offset:0 numBytes:expectedLen];
+ for (int x = 0; x < expectedLen; x++) {
+ STAssertEquals(outArray[x], expected[x], @"Expected outArray[%d] to equal %d", x, expected[x]);
+ }
+ const int dataBytesLen2 = 62;
+ int8_t dataBytes2[dataBytesLen2] = {
+ 67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182,
+ 198, 214, 230, 247, 7, 23, 39, 55, 71, 87, 103, 119, 135,
+ 151, 166, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166,
+ 182, 198, 214, 230, 247, 7, 23, 39, 55, 71, 87, 103, 119,
+ 135, 151, 160, 236, 17, 236, 17, 236, 17, 236,
+ 17
+ };
+ in = [[ZXBitArray alloc] init];
+ for (int i = 0; i < dataBytesLen2; i++) {
+ [in appendBits:dataBytes2[i] numBits:8];
+ }
+ out = [ZXEncoder interleaveWithECBytes:in numTotalBytes:134 numDataBytes:62 numRSBlocks:4 error:nil];
+ const int expectedLen2 = 134;
+ int8_t expected2[expectedLen2] = {
+ // Data bytes.
+ 67, 230, 54, 55, 70, 247, 70, 71, 22, 7, 86, 87, 38, 23, 102, 103, 54, 39,
+ 118, 119, 70, 55, 134, 135, 86, 71, 150, 151, 102, 87, 166,
+ 160, 118, 103, 182, 236, 134, 119, 198, 17, 150,
+ 135, 214, 236, 166, 151, 230, 17, 182,
+ 166, 247, 236, 198, 22, 7, 17, 214, 38, 23, 236, 39,
+ 17,
+ // Error correction bytes.
+ 175, 155, 245, 236, 80, 146, 56, 74, 155, 165,
+ 133, 142, 64, 183, 132, 13, 178, 54, 132, 108, 45,
+ 113, 53, 50, 214, 98, 193, 152, 233, 147, 50, 71, 65,
+ 190, 82, 51, 209, 199, 171, 54, 12, 112, 57, 113, 155, 117,
+ 211, 164, 117, 30, 158, 225, 31, 190, 242, 38,
+ 140, 61, 179, 154, 214, 138, 147, 87, 27, 96, 77, 47,
+ 187, 49, 156, 214,
+ };
+ STAssertEquals(out.sizeInBytes, expectedLen2, @"Expected out sizeInBytes to equal %d", expectedLen2);
+ int8_t outArray2[expectedLen2];
+ memset(outArray2, 0, expectedLen2 * sizeof(int8_t));
+ [out toBytes:0 array:outArray2 offset:0 numBytes:expectedLen2];
+ for (int x = 0; x < expectedLen2; x++) {
+ STAssertEquals(outArray2[x], expected2[x], @"Expected outArray[%d] to equal %d", x, expected2[x]);
+ }
+}
+
+- (void)testAppendNumericBytes {
+ // 1 = 01 = 0001 in 4 bits.
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendNumericBytes:@"1" bits:bits];
+ NSString *expected = @" ...X";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // 12 = 0xc = 0001100 in 7 bits.
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendNumericBytes:@"12" bits:bits];
+ expected = @" ...XX..";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // 123 = 0x7b = 0001111011 in 10 bits.
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendNumericBytes:@"123" bits:bits];
+ expected = @" ...XXXX. XX";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // 1234 = "123" + "4" = 0001111011 + 0100
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendNumericBytes:@"1234" bits:bits];
+ expected = @" ...XXXX. XX.X..";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // Empty.
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendNumericBytes:@"" bits:bits];
+ STAssertEqualObjects([bits description], @"", @"Expected bits to equal \"\"");
+}
+
+- (void)testAppendAlphanumericBytes {
+ // A = 10 = 0xa = 001010 in 6 bits
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendAlphanumericBytes:@"A" bits:bits error:nil];
+ NSString *expected = @" ..X.X.";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // AB = 10 * 45 + 11 = 461 = 0x1cd = 00111001101 in 11 bits
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendAlphanumericBytes:@"AB" bits:bits error:nil];
+ expected = @" ..XXX..X X.X";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // ABC = "AB" + "C" = 00111001101 + 001100
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendAlphanumericBytes:@"ABC" bits:bits error:nil];
+ expected = @" ..XXX..X X.X..XX. .";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // Empty.
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder appendAlphanumericBytes:@"" bits:bits error:nil];
+ STAssertEqualObjects([bits description], @"", @"Expected bits to equal \"\"");
+ // Invalid data.
+ NSError *error;
+ if ([ZXEncoder appendAlphanumericBytes:@"abc" bits:[[ZXBitArray alloc] init] error:&error] || error.code != ZXWriterError) {
+ STFail(@"Expected ZXWriterError");
+ }
+}
+
+- (void)testAppend8BitBytes {
+ // 0x61, 0x62, 0x63
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ [ZXEncoder append8BitBytes:@"abc" bits:bits encoding:DEFAULT_BYTE_MODE_ENCODING];
+ NSString *expected = @" .XX....X .XX...X. .XX...XX";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ // Empty.
+ bits = [[ZXBitArray alloc] init];
+ [ZXEncoder append8BitBytes:@"" bits:bits encoding:DEFAULT_BYTE_MODE_ENCODING];
+ STAssertEqualObjects([bits description], @"", @"Expected bits to equal \"\"");
+}
+
+// Numbers are from page 21 of JISX0510:2004
+- (void)testAppendKanjiBytes {
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ int8_t bytes[2] = {0x93,0x5f};
+ [ZXEncoder appendKanjiBytes:[self shiftJISString:bytes bytesLen:2] bits:bits error:nil];
+ NSString *expected = @" .XX.XX.. XXXXX";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+ int8_t bytes2[2] = {0xe4,0xaa};
+ [ZXEncoder appendKanjiBytes:[self shiftJISString:bytes2 bytesLen:2] bits:bits error:nil];
+ expected = @" .XX.XX.. XXXXXXX. X.X.X.X. X.";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+}
+
+// Numbers are from http://www.swetake.com/qr/qr3.html and
+// http://www.swetake.com/qr/qr9.html
+- (void)testGenerateECBytes {
+ const int dataBytesLen = 9;
+ int8_t dataBytes[dataBytesLen] = {32, 65, 205, 69, 41, 220, 46, 128, 236};
+ int8_t *ecBytes = [ZXEncoder generateECBytes:dataBytes numDataBytes:dataBytesLen numEcBytesInBlock:17];
+ const int expectedLen = 17;
+ int expected[expectedLen] = {
+ 42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61
+ };
+ for (int x = 0; x < expectedLen; x++) {
+ STAssertEquals(ecBytes[x] & 0xFF, expected[x], @"Expected exBytes[%d] to equal %d", x, expected[x]);
+ }
+ free(ecBytes);
+ const int dataBytesLen2 = 15;
+ int8_t dataBytes2[dataBytesLen2] = {67, 70, 22, 38, 54, 70, 86, 102, 118,
+ 134, 150, 166, 182, 198, 214};
+ int8_t *ecBytes2 = [ZXEncoder generateECBytes:dataBytes2 numDataBytes:dataBytesLen2 numEcBytesInBlock:18];
+ const int expectedLen2 = 18;
+ int expected2[expectedLen2] = {
+ 175, 80, 155, 64, 178, 45, 214, 233, 65, 209, 12, 155, 117, 31, 140, 214, 27, 187
+ };
+ for (int x = 0; x < expectedLen2; x++) {
+ STAssertEquals(ecBytes2[x] & 0xFF, expected2[x], @"Expected exBytes[%d] to equal %d", x, expected2[x]);
+ }
+ free(ecBytes2);
+ // High-order zero coefficient case.
+ const int dataBytesLen3 = 9;
+ int8_t dataBytes3[dataBytesLen3] = {32, 49, 205, 69, 42, 20, 0, 236, 17};
+ int8_t *ecBytes3 = [ZXEncoder generateECBytes:dataBytes3 numDataBytes:dataBytesLen3 numEcBytesInBlock:17];
+ const int expectedLen3 = 17;
+ int expected3[expectedLen3] = {
+ 0, 3, 130, 179, 194, 0, 55, 211, 110, 79, 98, 72, 170, 96, 211, 137, 213
+ };
+ for (int x = 0; x < expectedLen3; x++) {
+ STAssertEquals(ecBytes3[x] & 0xFF, expected3[x], @"Expected exBytes[%d] to equal %d", x, expected3[x]);
+ }
+ free(ecBytes3);
+}
+
+- (void)testBugInBitVectorNumBytes {
+ // There was a bug in BitVector.sizeInBytes() that caused it to return a
+ // smaller-by-one value (ex. 1465 instead of 1466) if the number of bits
+ // in the vector is not 8-bit aligned. In QRCodeEncoder::InitQRCode(),
+ // BitVector::sizeInBytes() is used for finding the smallest QR Code
+ // version that can fit the given data. Hence there were corner cases
+ // where we chose a wrong QR Code version that cannot fit the given
+ // data. Note that the issue did not occur with MODE_8BIT_BYTE, as the
+ // bits in the bit vector are always 8-bit aligned.
+ //
+ // Before the bug was fixed, the following test didn't pass, because:
+ //
+ // - MODE_NUMERIC is chosen as all bytes in the data are '0'
+ // - The 3518-byte numeric data needs 1466 bytes
+ // - 3518 / 3 * 10 + 7 = 11727 bits = 1465.875 bytes
+ // - 3 numeric bytes are encoded in 10 bits, hence the first
+ // 3516 bytes are encoded in 3516 / 3 * 10 = 11720 bits.
+ // - 2 numeric bytes can be encoded in 7 bits, hence the last
+ // 2 bytes are encoded in 7 bits.
+ // - The version 27 QR Code with the EC level L has 1468 bytes for data.
+ // - 1828 - 360 = 1468
+ // - In InitQRCode(), 3 bytes are reserved for a header. Hence 1465 bytes
+ // (1468 -3) are left for data.
+ // - Because of the bug in BitVector::sizeInBytes(), InitQRCode() determines
+ // the given data can fit in 1465 bytes, despite it needs 1466 bytes.
+ // - Hence QRCodeEncoder.encode() failed and returned false.
+ // - To be precise, it needs 11727 + 4 (getMode info) + 14 (length info) =
+ // 11745 bits = 1468.125 bytes are needed (i.e. cannot fit in 1468
+ // bytes).
+ NSMutableString *builder = [NSMutableString stringWithCapacity:3518];
+ for (int x = 0; x < 3518; x++) {
+ [builder appendString:@"0"];
+ }
+ ZXQRCode *qrCode = [ZXEncoder encode:builder ecLevel:[ZXErrorCorrectionLevel errorCorrectionLevelL] error:nil];
+ STAssertNotNil(qrCode, @"Excepted QR code");
+}
+
+- (NSString *)shiftJISString:(int8_t *)bytes bytesLen:(int)bytesLen {
+ return [[NSString alloc] initWithBytes:bytes length:bytesLen encoding:NSShiftJISStringEncoding];
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/ZXMaskUtilTestCase.h b/ZXingObjCTests/qrcode/encoder/ZXMaskUtilTestCase.h
new file mode 100644
index 0000000..1e9ac0b
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/ZXMaskUtilTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXMaskUtilTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/ZXMaskUtilTestCase.m b/ZXingObjCTests/qrcode/encoder/ZXMaskUtilTestCase.m
new file mode 100644
index 0000000..4bee224
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/ZXMaskUtilTestCase.m
@@ -0,0 +1,249 @@
+/*
+ * 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 "ZXMaskUtilTestCase.h"
+
+@implementation ZXMaskUtilTestCase
+
+- (void)testApplyMaskPenaltyRule1 {
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:4 height:1];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:1 y:0 intValue:0];
+ [matrix setX:2 y:0 intValue:0];
+ [matrix setX:3 y:0 intValue:0];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule1:matrix], 0, @"Expected applyMaskPenaltyRule1 to return 0");
+ // Horizontal.
+ matrix = [[ZXByteMatrix alloc] initWithWidth:6 height:1];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:1 y:0 intValue:0];
+ [matrix setX:2 y:0 intValue:0];
+ [matrix setX:3 y:0 intValue:0];
+ [matrix setX:4 y:0 intValue:0];
+ [matrix setX:5 y:0 intValue:1];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule1:matrix], 3, @"Expected applyMaskPenaltyRule1 to return 3");
+ [matrix setX:5 y:0 intValue:0];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule1:matrix], 4, @"Expected applyMaskPenaltyRule1 to return 4");
+ // Vertical.
+ matrix = [[ZXByteMatrix alloc] initWithWidth:1 height:6];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:0 y:1 intValue:0];
+ [matrix setX:0 y:2 intValue:0];
+ [matrix setX:0 y:3 intValue:0];
+ [matrix setX:0 y:4 intValue:0];
+ [matrix setX:0 y:5 intValue:1];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule1:matrix], 3, @"Expected applyMaskPenaltyRule1 to return 3");
+ [matrix setX:0 y:5 intValue:0];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule1:matrix], 4, @"Expected applyMaskPenaltyRule1 to return 4");
+}
+
+- (void)testApplyMaskPenaltyRule2 {
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:1 height:1];
+ [matrix setX:0 y:0 intValue:0];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule2:matrix], 0, @"Expected applyMaskPenaltyRule2 to return 0");
+ matrix = [[ZXByteMatrix alloc] initWithWidth:2 height:2];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:1 y:0 intValue:0];
+ [matrix setX:0 y:1 intValue:0];
+ [matrix setX:1 y:1 intValue:1];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule2:matrix], 0, @"Expected applyMaskPenaltyRule2 to return 0");
+ matrix = [[ZXByteMatrix alloc] initWithWidth:2 height:2];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:1 y:0 intValue:0];
+ [matrix setX:0 y:1 intValue:0];
+ [matrix setX:1 y:1 intValue:0];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule2:matrix], 3, @"Expected applyMaskPenaltyRule2 to return 3");
+ matrix = [[ZXByteMatrix alloc] initWithWidth:3 height:3];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:1 y:0 intValue:0];
+ [matrix setX:2 y:0 intValue:0];
+ [matrix setX:0 y:1 intValue:0];
+ [matrix setX:1 y:1 intValue:0];
+ [matrix setX:2 y:1 intValue:0];
+ [matrix setX:0 y:2 intValue:0];
+ [matrix setX:1 y:2 intValue:0];
+ [matrix setX:2 y:2 intValue:0];
+ // Four instances of 2x2 blocks.
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule2:matrix], 3 * 4, @"Expected applyMaskPenaltyRule2 to return 3 * 4");
+}
+
+- (void)testApplyMaskPenaltyRule3 {
+ // Horizontal 00001011101.
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:11 height:1];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:1 y:0 intValue:0];
+ [matrix setX:2 y:0 intValue:0];
+ [matrix setX:3 y:0 intValue:0];
+ [matrix setX:4 y:0 intValue:1];
+ [matrix setX:5 y:0 intValue:0];
+ [matrix setX:6 y:0 intValue:1];
+ [matrix setX:7 y:0 intValue:1];
+ [matrix setX:8 y:0 intValue:1];
+ [matrix setX:9 y:0 intValue:0];
+ [matrix setX:10 y:0 intValue:1];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule3:matrix], 40, @"Expected applyMaskPenaltyRule3 to return 40");
+ // Horizontal 10111010000.
+ matrix = [[ZXByteMatrix alloc] initWithWidth:11 height:1];
+ [matrix setX:0 y:0 intValue:1];
+ [matrix setX:1 y:0 intValue:0];
+ [matrix setX:2 y:0 intValue:1];
+ [matrix setX:3 y:0 intValue:1];
+ [matrix setX:4 y:0 intValue:1];
+ [matrix setX:5 y:0 intValue:0];
+ [matrix setX:6 y:0 intValue:1];
+ [matrix setX:7 y:0 intValue:0];
+ [matrix setX:8 y:0 intValue:0];
+ [matrix setX:9 y:0 intValue:0];
+ [matrix setX:10 y:0 intValue:0];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule3:matrix], 40, @"Expected applyMaskPenaltyRule3 to return 40");
+ // Vertical 00001011101.
+ matrix = [[ZXByteMatrix alloc] initWithWidth:11 height:1];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:1 y:0 intValue:0];
+ [matrix setX:2 y:0 intValue:0];
+ [matrix setX:3 y:0 intValue:0];
+ [matrix setX:4 y:0 intValue:1];
+ [matrix setX:5 y:0 intValue:0];
+ [matrix setX:6 y:0 intValue:1];
+ [matrix setX:7 y:0 intValue:1];
+ [matrix setX:8 y:0 intValue:1];
+ [matrix setX:9 y:0 intValue:0];
+ [matrix setX:10 y:0 intValue:1];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule3:matrix], 40, @"Expected applyMaskPenaltyRule3 to return 40");
+ // Vertical 10111010000.
+ matrix = [[ZXByteMatrix alloc] initWithWidth:11 height:1];
+ [matrix setX:0 y:0 intValue:1];
+ [matrix setX:1 y:0 intValue:0];
+ [matrix setX:2 y:0 intValue:1];
+ [matrix setX:3 y:0 intValue:1];
+ [matrix setX:4 y:0 intValue:1];
+ [matrix setX:5 y:0 intValue:0];
+ [matrix setX:6 y:0 intValue:1];
+ [matrix setX:7 y:0 intValue:0];
+ [matrix setX:8 y:0 intValue:0];
+ [matrix setX:9 y:0 intValue:0];
+ [matrix setX:10 y:0 intValue:0];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule3:matrix], 40, @"Expected applyMaskPenaltyRule3 to return 40");
+}
+
+- (void)testApplyMaskPenaltyRule4 {
+ // Dark cell ratio = 0%
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:1 height:1];
+ [matrix setX:0 y:0 intValue:0];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule4:matrix], 100, @"Expected applyMaskPenaltyRule4 to return 100");
+ // Dark cell ratio = 5%
+ matrix = [[ZXByteMatrix alloc] initWithWidth:2 height:1];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:0 y:0 intValue:1];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule4:matrix], 0, @"Expected applyMaskPenaltyRule4 to return 0");
+ // Dark cell ratio = 66.67%
+ matrix = [[ZXByteMatrix alloc] initWithWidth:6 height:1];
+ [matrix setX:0 y:0 intValue:0];
+ [matrix setX:1 y:0 intValue:1];
+ [matrix setX:2 y:0 intValue:1];
+ [matrix setX:3 y:0 intValue:1];
+ [matrix setX:4 y:0 intValue:1];
+ [matrix setX:5 y:0 intValue:0];
+ STAssertEquals([ZXMaskUtil applyMaskPenaltyRule4:matrix], 30, @"Expected applyMaskPenaltyRule4 to return 30");
+}
+
+BOOL TestGetDataMaskBitInternal(int maskPattern, int *expected) {
+ for (int x = 0; x < 6; ++x) {
+ for (int y = 0; y < 6; ++y) {
+ if ((expected[y*6+x] == 1) != [ZXMaskUtil dataMaskBit:maskPattern x:x y:y]) {
+ return NO;
+ }
+ }
+ }
+ return YES;
+}
+
+// See mask patterns on the page 43 of JISX0510:2004.
+- (void)testGetDataMaskBit {
+ int mask0[6][6] = {
+ {1, 0, 1, 0, 1, 0},
+ {0, 1, 0, 1, 0, 1},
+ {1, 0, 1, 0, 1, 0},
+ {0, 1, 0, 1, 0, 1},
+ {1, 0, 1, 0, 1, 0},
+ {0, 1, 0, 1, 0, 1},
+ };
+ STAssertTrue(TestGetDataMaskBitInternal(0, (int *)mask0), @"Expected TestGetDataMaskBitInternal to return YES");
+ int mask1[6][6] = {
+ {1, 1, 1, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0},
+ {1, 1, 1, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0},
+ {1, 1, 1, 1, 1, 1},
+ {0, 0, 0, 0, 0, 0},
+ };
+ STAssertTrue(TestGetDataMaskBitInternal(1, (int *)mask1), @"Expected TestGetDataMaskBitInternal to return YES");
+ int mask2[6][6] = {
+ {1, 0, 0, 1, 0, 0},
+ {1, 0, 0, 1, 0, 0},
+ {1, 0, 0, 1, 0, 0},
+ {1, 0, 0, 1, 0, 0},
+ {1, 0, 0, 1, 0, 0},
+ {1, 0, 0, 1, 0, 0},
+ };
+ STAssertTrue(TestGetDataMaskBitInternal(2, (int *)mask2), @"Expected TestGetDataMaskBitInternal to return YES");
+ int mask3[6][6] = {
+ {1, 0, 0, 1, 0, 0},
+ {0, 0, 1, 0, 0, 1},
+ {0, 1, 0, 0, 1, 0},
+ {1, 0, 0, 1, 0, 0},
+ {0, 0, 1, 0, 0, 1},
+ {0, 1, 0, 0, 1, 0},
+ };
+ STAssertTrue(TestGetDataMaskBitInternal(3, (int *)mask3), @"Expected TestGetDataMaskBitInternal to return YES");
+ int mask4[6][6] = {
+ {1, 1, 1, 0, 0, 0},
+ {1, 1, 1, 0, 0, 0},
+ {0, 0, 0, 1, 1, 1},
+ {0, 0, 0, 1, 1, 1},
+ {1, 1, 1, 0, 0, 0},
+ {1, 1, 1, 0, 0, 0},
+ };
+ STAssertTrue(TestGetDataMaskBitInternal(4, (int *)mask4), @"Expected TestGetDataMaskBitInternal to return YES");
+ int mask5[6][6] = {
+ {1, 1, 1, 1, 1, 1},
+ {1, 0, 0, 0, 0, 0},
+ {1, 0, 0, 1, 0, 0},
+ {1, 0, 1, 0, 1, 0},
+ {1, 0, 0, 1, 0, 0},
+ {1, 0, 0, 0, 0, 0},
+ };
+ STAssertTrue(TestGetDataMaskBitInternal(5, (int *)mask5), @"Expected TestGetDataMaskBitInternal to return YES");
+ int mask6[6][6] = {
+ {1, 1, 1, 1, 1, 1},
+ {1, 1, 1, 0, 0, 0},
+ {1, 1, 0, 1, 1, 0},
+ {1, 0, 1, 0, 1, 0},
+ {1, 0, 1, 1, 0, 1},
+ {1, 0, 0, 0, 1, 1},
+ };
+ STAssertTrue(TestGetDataMaskBitInternal(6, (int *)mask6), @"Expected TestGetDataMaskBitInternal to return YES");
+ int mask7[6][6] = {
+ {1, 0, 1, 0, 1, 0},
+ {0, 0, 0, 1, 1, 1},
+ {1, 0, 0, 0, 1, 1},
+ {0, 1, 0, 1, 0, 1},
+ {1, 1, 1, 0, 0, 0},
+ {0, 1, 1, 1, 0, 0},
+ };
+ STAssertTrue(TestGetDataMaskBitInternal(7, (int *)mask7), @"Expected TestGetDataMaskBitInternal to return YES");
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/ZXMatrixUtilTestCase.h b/ZXingObjCTests/qrcode/encoder/ZXMatrixUtilTestCase.h
new file mode 100644
index 0000000..ae8b4d6
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/ZXMatrixUtilTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXMatrixUtilTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/ZXMatrixUtilTestCase.m b/ZXingObjCTests/qrcode/encoder/ZXMatrixUtilTestCase.m
new file mode 100644
index 0000000..26fb8bf
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/ZXMatrixUtilTestCase.m
@@ -0,0 +1,293 @@
+/*
+ * 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 "ZXMatrixUtilTestCase.h"
+
+@implementation ZXMatrixUtilTestCase
+
+- (void)testToString {
+ ZXByteMatrix *array = [[ZXByteMatrix alloc] initWithWidth:3 height:3];
+ [array setX:0 y:0 intValue:0];
+ [array setX:1 y:0 intValue:1];
+ [array setX:2 y:0 intValue:0];
+ [array setX:0 y:1 intValue:1];
+ [array setX:1 y:1 intValue:0];
+ [array setX:2 y:1 intValue:1];
+ [array setX:0 y:2 intValue:-1];
+ [array setX:1 y:2 intValue:-1];
+ [array setX:2 y:2 intValue:-1];
+ NSString *expected = @" 0 1 0\n 1 0 1\n \n";
+ STAssertEqualObjects([array description], expected, @"Expected array to equal %@", expected);
+}
+
+- (void)testClearMatrix {
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:2 height:2];
+ [ZXMatrixUtil clearMatrix:matrix];
+ STAssertEquals([matrix getX:0 y:0], (char)-1, @"Expected (0, 0) to equal -1");
+ STAssertEquals([matrix getX:1 y:0], (char)-1, @"Expected (1, 0) to equal -1");
+ STAssertEquals([matrix getX:0 y:1], (char)-1, @"Expected (0, 1) to equal -1");
+ STAssertEquals([matrix getX:1 y:1], (char)-1, @"Expected (1, 1) to equal -1");
+}
+
+- (void)testEmbedBasicPatterns1 {
+ // Version 1.
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:21 height:21];
+ [ZXMatrixUtil clearMatrix:matrix];
+ [ZXMatrixUtil embedBasicPatterns:[ZXQRCodeVersion versionForNumber:1] matrix:matrix error:nil];
+ NSString *expected =
+ @" 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1\n"
+ " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ " 1 0 0 0 0 0 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 0 0 0 0 0 0\n"
+ " 1 \n"
+ " 0 \n"
+ " 1 \n"
+ " 0 \n"
+ " 1 \n"
+ " 0 0 0 0 0 0 0 0 1 \n"
+ " 1 1 1 1 1 1 1 0 \n"
+ " 1 0 0 0 0 0 1 0 \n"
+ " 1 0 1 1 1 0 1 0 \n"
+ " 1 0 1 1 1 0 1 0 \n"
+ " 1 0 1 1 1 0 1 0 \n"
+ " 1 0 0 0 0 0 1 0 \n"
+ " 1 1 1 1 1 1 1 0 \n";
+ STAssertEqualObjects([matrix description], expected, @"Expected matrix to equal %@", expected);
+}
+
+- (void)testEmbedBasicPatterns2 {
+ // Version 2. Position adjustment pattern should apppear at right
+ // bottom corner.
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:25 height:25];
+ [ZXMatrixUtil clearMatrix:matrix];
+ [ZXMatrixUtil embedBasicPatterns:[ZXQRCodeVersion versionForNumber:2] matrix:matrix error:nil];
+ NSString *expected =
+ @" 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1\n"
+ " 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 1 0 1 1 1 0 1\n"
+ " 1 0 0 0 0 0 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 0 0 0 0 0 0 0 0\n"
+ " 1 \n"
+ " 0 \n"
+ " 1 \n"
+ " 0 \n"
+ " 1 \n"
+ " 0 \n"
+ " 1 \n"
+ " 0 \n"
+ " 1 1 1 1 1 1 \n"
+ " 0 0 0 0 0 0 0 0 1 1 0 0 0 1 \n"
+ " 1 1 1 1 1 1 1 0 1 0 1 0 1 \n"
+ " 1 0 0 0 0 0 1 0 1 0 0 0 1 \n"
+ " 1 0 1 1 1 0 1 0 1 1 1 1 1 \n"
+ " 1 0 1 1 1 0 1 0 \n"
+ " 1 0 1 1 1 0 1 0 \n"
+ " 1 0 0 0 0 0 1 0 \n"
+ " 1 1 1 1 1 1 1 0 \n";
+ STAssertEqualObjects([matrix description], expected, @"Expected matrix to equal %@", expected);
+}
+
+- (void)testEmbedTypeInfo {
+ // Type info bits = 100000011001110.
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:21 height:21];
+ [ZXMatrixUtil clearMatrix:matrix];
+ [ZXMatrixUtil embedTypeInfo:[ZXErrorCorrectionLevel errorCorrectionLevelM] maskPattern:5 matrix:matrix error:nil];
+ NSString *expected =
+ @" 0 \n"
+ " 1 \n"
+ " 1 \n"
+ " 1 \n"
+ " 0 \n"
+ " 0 \n"
+ " \n"
+ " 1 \n"
+ " 1 0 0 0 0 0 0 1 1 1 0 0 1 1 1 0\n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " 0 \n"
+ " 0 \n"
+ " 0 \n"
+ " 0 \n"
+ " 0 \n"
+ " 0 \n"
+ " 1 \n";
+ STAssertEqualObjects([matrix description], expected, @"Expected matrix to equal %@", expected);
+}
+
+- (void)testEmbedVersionInfo {
+ // Version info bits = 000111 110010 010100
+ // Actually, version 7 QR Code has 45x45 matrix but we use 21x21 here
+ // since 45x45 matrix is too big to depict.
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:21 height:21];
+ [ZXMatrixUtil clearMatrix:matrix];
+ [ZXMatrixUtil maybeEmbedVersionInfo:[ZXQRCodeVersion versionForNumber:7] matrix:matrix error:nil];
+ NSString *expected =
+ @" 0 0 1 \n"
+ " 0 1 0 \n"
+ " 0 1 0 \n"
+ " 0 1 1 \n"
+ " 1 1 1 \n"
+ " 0 0 0 \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " 0 0 0 0 1 0 \n"
+ " 0 1 1 1 1 0 \n"
+ " 1 0 0 1 1 0 \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " \n";
+ STAssertEqualObjects([matrix description], expected, @"Expected matrix to equal %@", expected);
+}
+
+- (void)testEmbedDataBits {
+ // Cells other than basic patterns should be filled with zero.
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:21 height:21];
+ [ZXMatrixUtil clearMatrix:matrix];
+ [ZXMatrixUtil embedBasicPatterns:[ZXQRCodeVersion versionForNumber:1] matrix:matrix error:nil];
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ [ZXMatrixUtil embedDataBits:bits maskPattern:-1 matrix:matrix error:nil];
+ NSString *expected =
+ @" 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1\n"
+ " 1 0 0 0 0 0 1 0 0 0 0 0 0 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 0 0 0 0 0 1 0 1 1 1 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 0 0 0 0 1 0 0 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
+ " 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
+ STAssertEqualObjects([matrix description], expected, @"Expected matrix to equal %@", expected);
+}
+
+- (void)testBuildMatrix {
+ // From http://www.swetake.com/qr/qr7.html
+ const int bytesLen = 26;
+ int8_t bytes[bytesLen] = {32, 65, 205, 69, 41, 220, 46, 128, 236,
+ 42, 159, 74, 221, 244, 169, 239, 150, 138,
+ 70, 237, 85, 224, 96, 74, 219, 61};
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ for (int i = 0; i < bytesLen; i++) {
+ [bits appendBits:bytes[i] numBits:8];
+ }
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:21 height:21];
+ [ZXMatrixUtil buildMatrix:bits
+ ecLevel:[ZXErrorCorrectionLevel errorCorrectionLevelH]
+ version:[ZXQRCodeVersion versionForNumber:1]
+ maskPattern:3 // Mask pattern 3
+ matrix:matrix
+ error:nil];
+ NSString *expected =
+ @" 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 1 1 1\n"
+ " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 0 0 1 1 0 0 0 1 0 1 1 1 0 1\n"
+ " 1 0 1 1 1 0 1 0 1 1 0 0 1 0 1 0 1 1 1 0 1\n"
+ " 1 0 0 0 0 0 1 0 0 0 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 1 0 1 1 0 0 0 0 0 0 0 0\n"
+ " 0 0 1 1 0 0 1 1 1 0 0 1 1 1 1 0 1 0 0 0 0\n"
+ " 1 0 1 0 1 0 0 0 0 0 1 1 1 0 0 1 0 1 1 1 0\n"
+ " 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 1 1 0 1 0\n"
+ " 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 0\n"
+ " 0 0 1 0 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 1 1\n"
+ " 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 1\n"
+ " 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 1 0 1 1 0\n"
+ " 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0\n"
+ " 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1\n"
+ " 1 0 1 1 1 0 1 0 1 1 0 1 0 0 0 0 0 1 1 1 0\n"
+ " 1 0 1 1 1 0 1 0 1 1 1 1 0 0 0 0 1 1 1 0 0\n"
+ " 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0\n"
+ " 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 1 0 0 1 0\n";
+ STAssertEqualObjects([matrix description], expected, @"Expected matrix to equal %@", expected);
+}
+
+- (void)testFindMSBSet {
+ STAssertEquals([ZXMatrixUtil findMSBSet:0], 0, @"Expected findMSBSet to equal 0");
+ STAssertEquals([ZXMatrixUtil findMSBSet:1], 1, @"Expected findMSBSet to equal 1");
+ STAssertEquals([ZXMatrixUtil findMSBSet:0x80], 8, @"Expected findMSBSet to equal 8");
+ STAssertEquals([ZXMatrixUtil findMSBSet:0x80000000], 32, @"Expected findMSBSet to equal 32");
+}
+
+- (void)testCalculateBCHCode {
+ // Encoding of type information.
+ // From Appendix C in JISX0510:2004 (p 65)
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:5 poly:0x537], 0xdc, @"Expected calculateBCHCode to equal 0xdc");
+ // From http://www.swetake.com/qr/qr6.html
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:0x13 poly:0x537], 0x1c2, @"Expected calculateBCHCode to equal 0x1c2");
+ // From http://www.swetake.com/qr/qr11.html
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:0x1b poly:0x537], 0x214, @"Expected calculateBCHCode to equal 0x214");
+
+ // Encofing of version information.
+ // From Appendix D in JISX0510:2004 (p 68)
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:7 poly:0x1f25], 0xc94, @"Expected calculateBCHCode to equal 0xc94");
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:8 poly:0x1f25], 0x5bc, @"Expected calculateBCHCode to equal 0x5bc");
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:9 poly:0x1f25], 0xa99, @"Expected calculateBCHCode to equal 0xa99");
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:10 poly:0x1f25], 0x4d3, @"Expected calculateBCHCode to equal 0x4d3");
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:20 poly:0x1f25], 0x9a6, @"Expected calculateBCHCode to equal 0x9a6");
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:30 poly:0x1f25], 0xd75, @"Expected calculateBCHCode to equal 0xd75");
+ STAssertEquals([ZXMatrixUtil calculateBCHCode:40 poly:0x1f25], 0xc69, @"Expected calculateBCHCode to equal 0xc69");
+}
+
+// We don't test a lot of cases in this function since we've already
+// tested them in TEST(calculateBCHCode).
+- (void)testMakeVersionInfoBits {
+ // From Appendix D in JISX0510:2004 (p 68)
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ [ZXMatrixUtil makeVersionInfoBits:[ZXQRCodeVersion versionForNumber:7] bits:bits error:nil];
+ NSString *expected = @" ...XXXXX ..X..X.X ..";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+}
+
+// We don't test a lot of cases in this function since we've already
+// tested them in TEST(calculateBCHCode).
+- (void)testMakeTypeInfoInfoBits {
+ // From Appendix C in JISX0510:2004 (p 65)
+ ZXBitArray *bits = [[ZXBitArray alloc] init];
+ [ZXMatrixUtil makeTypeInfoBits:[ZXErrorCorrectionLevel errorCorrectionLevelM] maskPattern:5 bits:bits error:nil];
+ NSString *expected = @" X......X X..XXX.";
+ STAssertEqualObjects([bits description], expected, @"Expected bits to equal %@", expected);
+}
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/ZXQRCodeTestCase.h b/ZXingObjCTests/qrcode/encoder/ZXQRCodeTestCase.h
new file mode 100644
index 0000000..2d0b0a6
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/ZXQRCodeTestCase.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 <SenTestingKit/SenTestingKit.h>
+
+@interface ZXQRCodeTestCase : SenTestCase
+
+@end
diff --git a/ZXingObjCTests/qrcode/encoder/ZXQRCodeTestCase.m b/ZXingObjCTests/qrcode/encoder/ZXQRCodeTestCase.m
new file mode 100644
index 0000000..2a095d7
--- /dev/null
+++ b/ZXingObjCTests/qrcode/encoder/ZXQRCodeTestCase.m
@@ -0,0 +1,116 @@
+/*
+ * 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 "ZXQRCodeTestCase.h"
+
+@implementation ZXQRCodeTestCase
+
+- (void)test {
+ ZXQRCode *qrCode = [[ZXQRCode alloc] init];
+
+ // First, test simple setters and getters.
+ // We use numbers of version 7-H.
+ qrCode.mode = [ZXMode byteMode];
+ qrCode.ecLevel = [ZXErrorCorrectionLevel errorCorrectionLevelH];
+ qrCode.version = [ZXQRCodeVersion versionForNumber:7];
+ qrCode.maskPattern = 3;
+
+ STAssertEqualObjects(qrCode.mode, [ZXMode byteMode], @"Expected qrCode mode to be byteMode");
+ STAssertEqualObjects(qrCode.ecLevel, [ZXErrorCorrectionLevel errorCorrectionLevelH],
+ @"Expected qrCode error correction level to be H");
+ STAssertEquals(qrCode.version.versionNumber, 7, @"Expected qrCode version to be 7");
+ STAssertEquals(qrCode.maskPattern, 3, @"Expected qrCode maskPattern to be 3");
+
+ // Prepare the matrix.
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:45 height:45];
+ // Just set bogus zero/one values.
+ for (int y = 0; y < 45; ++y) {
+ for (int x = 0; x < 45; ++x) {
+ [matrix setX:x y:y intValue:(y + x) % 2];
+ }
+ }
+
+ // Set the matrix.
+ qrCode.matrix = matrix;
+ STAssertEqualObjects(qrCode.matrix, matrix, @"Expected matrices to be equal");
+}
+
+- (void)testToString1 {
+ ZXQRCode *qrCode = [[ZXQRCode alloc] init];
+ NSString *expected =
+ @"<<\n"
+ " mode: (null)\n"
+ " ecLevel: (null)\n"
+ " version: (null)\n"
+ " maskPattern: -1\n"
+ " matrix: (null)\n"
+ ">>\n";
+ STAssertEqualObjects([qrCode description], expected, @"Expected qrCode to equal %@", expected);
+}
+
+- (void)testToString2 {
+ ZXQRCode *qrCode = [[ZXQRCode alloc] init];
+ qrCode.mode = [ZXMode byteMode];
+ qrCode.ecLevel = [ZXErrorCorrectionLevel errorCorrectionLevelH];
+ qrCode.version = [ZXQRCodeVersion versionForNumber:1];
+ qrCode.maskPattern = 3;
+ ZXByteMatrix *matrix = [[ZXByteMatrix alloc] initWithWidth:21 height:21];
+ for (int y = 0; y < 21; ++y) {
+ for (int x = 0; x < 21; ++x) {
+ [matrix setX:x y:y intValue:(y + x) % 2];
+ }
+ }
+ qrCode.matrix = matrix;
+ NSString *expected =
+ @"<<\n"
+ " mode: BYTE\n"
+ " ecLevel: H\n"
+ " version: 1\n"
+ " maskPattern: 3\n"
+ " matrix:\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ " 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1\n"
+ " 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0\n"
+ ">>\n";
+ STAssertEqualObjects([qrCode description], expected, @"Expected qrCode to equal %@", expected);
+}
+
+- (void)testIsValidMaskPattern {
+ STAssertFalse([ZXQRCode isValidMaskPattern:-1], @"Expected -1 not to be a valid mask pattern");
+ STAssertTrue([ZXQRCode isValidMaskPattern:0], @"Expected 0 to be a valid mask pattern");
+ STAssertTrue([ZXQRCode isValidMaskPattern:7], @"Expected 7 to be a valid mask pattern");
+ STAssertFalse([ZXQRCode isValidMaskPattern:8], @"Expected 8 not to be a valid mask pattern");
+}
+
+@end
diff --git a/ios-Prefix.pch b/ios-Prefix.pch
new file mode 100644
index 0000000..d46e2e3
--- /dev/null
+++ b/ios-Prefix.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'ZXingObjC' target in the 'ZXingObjC' project
+//
+
+#ifdef __OBJC__
+ #import <Foundation/Foundation.h>
+#endif
diff --git a/osx-Prefix.pch b/osx-Prefix.pch
new file mode 100644
index 0000000..60358ea
--- /dev/null
+++ b/osx-Prefix.pch
@@ -0,0 +1,9 @@
+//
+// Prefix header for all source files of the 'ZXingObjC' target in the 'ZXingObjC' project
+//
+
+#ifdef __OBJC__
+
+#import <Cocoa/Cocoa.h>
+
+#endif