+ *
+ * @return the number of corrected bits, or 0 if the input contains too many errors
+ */
+- (ZXBoolArray *)correctBits:(ZXBoolArray *)rawbits error:(NSError **)error {
+ ZXGenericGF *gf;
+ int codewordSize;
+
+ if ([self.ddata nbLayers] <= 2) {
+ codewordSize = 6;
+ gf = [ZXGenericGF AztecData6];
+ } else if ([self.ddata nbLayers] <= 8) {
+ codewordSize = 8;
+ gf = [ZXGenericGF AztecData8];
+ } else if ([self.ddata nbLayers] <= 22) {
+ codewordSize = 10;
+ gf = [ZXGenericGF AztecData10];
+ } else {
+ codewordSize = 12;
+ gf = [ZXGenericGF AztecData12];
+ }
+
+ int numDataCodewords = [self.ddata nbDatablocks];
+ int numCodewords = rawbits.length / codewordSize;
+ if (numCodewords < numDataCodewords) {
+ if (error) *error = ZXFormatErrorInstance();
+ return 0;
+ }
+ int offset = rawbits.length % codewordSize;
+ int numECCodewords = numCodewords - numDataCodewords;
+
+ ZXIntArray *dataWords = [[ZXIntArray alloc] initWithLength:numCodewords];
+ for (int i = 0; i < numCodewords; i++, offset += codewordSize) {
+ dataWords.array[i] = [[self class] readCode:rawbits startIndex:offset length:codewordSize];
+ }
+
+ ZXReedSolomonDecoder *rsDecoder = [[ZXReedSolomonDecoder alloc] initWithField:gf];
+ NSError *decodeError = nil;
+ if (![rsDecoder decode:dataWords twoS:numECCodewords error:&decodeError]) {
+ if (decodeError.code == ZXReedSolomonError) {
+ if (error) *error = ZXFormatErrorInstance();
+ } else {
+ if (error) *error = decodeError;
+ }
+ return 0;
+ }
+
+ // Now perform the unstuffing operation.
+ // First, count how many bits are going to be thrown out as stuffing
+ int mask = (1 << codewordSize) - 1;
+ int stuffedBits = 0;
+ for (int i = 0; i < numDataCodewords; i++) {
+ int32_t dataWord = dataWords.array[i];
+ if (dataWord == 0 || dataWord == mask) {
+ if (error) *error = ZXFormatErrorInstance();
+ return 0;
+ } else if (dataWord == 1 || dataWord == mask - 1) {
+ stuffedBits++;
+ }
+ }
+
+ // Now, actually unpack the bits and remove the stuffing
+ ZXBoolArray *correctedBits = [[ZXBoolArray alloc] initWithLength:numDataCodewords * codewordSize - stuffedBits];
+ int index = 0;
+ for (int i = 0; i < numDataCodewords; i++) {
+ int dataWord = dataWords.array[i];
+ if (dataWord == 1 || dataWord == mask - 1) {
+ // next codewordSize-1 bits are all zeros or all ones
+ memset(correctedBits.array + index * sizeof(BOOL), dataWord > 1, codewordSize - 1);
+ index += codewordSize - 1;
+ } else {
+ for (int bit = codewordSize - 1; bit >= 0; --bit) {
+ correctedBits.array[index++] = (dataWord & (1 << bit)) != 0;
+ }
+ }
+ }
+ return correctedBits;
+}
+
+/**
+ * Gets the array of bits from an Aztec Code matrix
+ *
+ * @return the size of the array of bits
+ */
+- (ZXBoolArray *)extractBits:(ZXBitMatrix *)matrix {
+ BOOL compact = self.ddata.isCompact;
+ int layers = self.ddata.nbLayers;
+ int baseMatrixSize = compact ? 11 + layers * 4 : 14 + layers * 4; // not including alignment lines
+ ZXIntArray *alignmentMap = [[ZXIntArray alloc] initWithLength:baseMatrixSize];
+ ZXBoolArray *rawbits = [[ZXBoolArray alloc] initWithLength:[self totalBitsInLayer:layers compact:compact]];
+
+ if (compact) {
+ for (int i = 0; i < alignmentMap.length; i++) {
+ alignmentMap.array[i] = i;
+ }
+ } else {
+ int 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.array[origCenter - i - 1] = (int32_t)(center - newOffset - 1);
+ alignmentMap.array[origCenter + i] = (int32_t)(center + newOffset + 1);
+ }
+ }
+ for (int i = 0, rowOffset = 0; i < layers; i++) {
+ int rowSize = compact ? (layers - i) * 4 + 9 : (layers - i) * 4 + 12;
+ // The top-left most point of this layer is (not including alignment lines)
+ int low = i * 2;
+ // The bottom-right most point of this layer is (not including alignment lines)
+ int high = baseMatrixSize - 1 - low;
+ // We pull bits from the two 2 x rowSize columns and two rowSize x 2 rows
+ for (int j = 0; j < rowSize; j++) {
+ int columnOffset = j * 2;
+ for (int k = 0; k < 2; k++) {
+ // left column
+ rawbits.array[rowOffset + columnOffset + k] =
+ [matrix getX:alignmentMap.array[low + k] y:alignmentMap.array[low + j]];
+ // bottom row
+ rawbits.array[rowOffset + 2 * rowSize + columnOffset + k] =
+ [matrix getX:alignmentMap.array[low + j] y:alignmentMap.array[high - k]];
+ // right column
+ rawbits.array[rowOffset + 4 * rowSize + columnOffset + k] =
+ [matrix getX:alignmentMap.array[high - k] y:alignmentMap.array[high - j]];
+ // top row
+ rawbits.array[rowOffset + 6 * rowSize + columnOffset + k] =
+ [matrix getX:alignmentMap.array[high - j] y:alignmentMap.array[low + k]];
+ }
+ }
+ rowOffset += rowSize * 8;
+ }
+ return rawbits;
+}
+
+/**
+ * Reads a code of given length and at given index in an array of bits
+ */
++ (int)readCode:(ZXBoolArray *)rawbits startIndex:(int)startIndex length:(int)length {
+ int res = 0;
+ for (int i = startIndex; i < startIndex + length; i++) {
+ res <<= 1;
+ if (rawbits.array[i]) {
+ res |= 0x01;
+ }
+ }
+ return res;
+}
+
+- (int)totalBitsInLayer:(int)layers compact:(BOOL)compact {
+ return ((compact ? 88 : 112) + 16 * layers) * layers;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/detector/ZXAztecDetector.h b/Pods/ZXingObjC/ZXingObjC/aztec/detector/ZXAztecDetector.h
new file mode 100644
index 0000000..31aad24
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/detector/ZXAztecDetector.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.
+ */
+
+@interface ZXAztecPoint : NSObject
+
+@property (nonatomic, assign, readonly) int x;
+@property (nonatomic, assign, readonly) int y;
+
+- (id)initWithX:(int)x y:(int)y;
+
+@end
+
+@class ZXAztecDetectorResult, ZXBitMatrix;
+
+/**
+ * Encapsulates logic that can detect an Aztec Code in an image, even if the Aztec Code
+ * is rotated or skewed, or partially obscured.
+ */
+@interface ZXAztecDetector : NSObject
+
+- (id)initWithImage:(ZXBitMatrix *)image;
+
+- (ZXAztecDetectorResult *)detectWithError:(NSError **)error;
+
+/**
+ * Detects an Aztec Code in an image.
+ *
+ * @return ZXAztecDetectorResult encapsulating results of detecting an Aztec Code, or nil if no Aztec Code can be found
+ */
+- (ZXAztecDetectorResult *)detectWithMirror:(BOOL)isMirror error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/detector/ZXAztecDetector.m b/Pods/ZXingObjC/ZXingObjC/aztec/detector/ZXAztecDetector.m
new file mode 100644
index 0000000..30c13fd
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/detector/ZXAztecDetector.m
@@ -0,0 +1,619 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXIntArray.h"
+#import "ZXMathUtils.h"
+#import "ZXReedSolomonDecoder.h"
+#import "ZXResultPoint.h"
+#import "ZXWhiteRectangleDetector.h"
+
+@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];
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%d %d>", self.x, self.y];
+}
+
+@end
+
+@interface ZXAztecDetector ()
+
+@property (nonatomic, assign, getter = isCompact) 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;
+}
+
+- (ZXAztecDetectorResult *)detectWithError:(NSError **)error {
+ return [self detectWithMirror:NO error:error];
+}
+
+- (ZXAztecDetectorResult *)detectWithMirror:(BOOL)isMirror error:(NSError **)error {
+ // 1. Get the center of the aztec matrix
+ ZXAztecPoint *pCenter = [self matrixCenter];
+ if (!pCenter) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ // 2. Get the center points of the four diagonal points just outside the bull's eye
+ // [topRight, bottomRight, bottomLeft, topLeft]
+ NSMutableArray *bullsEyeCorners = [self bullsEyeCorners:pCenter];
+ if (!bullsEyeCorners) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ if (isMirror) {
+ ZXResultPoint *temp = bullsEyeCorners[0];
+ bullsEyeCorners[0] = bullsEyeCorners[2];
+ bullsEyeCorners[2] = temp;
+ }
+
+ // 3. Get the size of the matrix and other parameters from the bull's eye
+ if (![self extractParameters:bullsEyeCorners]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ // 4. Sample the grid
+ ZXBitMatrix *bits = [self sampleGrid:self.image
+ topLeft:bullsEyeCorners[self.shift % 4]
+ topRight:bullsEyeCorners[(self.shift + 1) % 4]
+ bottomRight:bullsEyeCorners[(self.shift + 2) % 4]
+ bottomLeft:bullsEyeCorners[(self.shift + 3) % 4]];
+ if (!bits) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ // 5. Get the corners of the matrix.
+ NSArray *corners = [self matrixCornerPoints:bullsEyeCorners];
+ if (!corners) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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 *)bullsEyeCorners {
+ ZXResultPoint *p0 = bullsEyeCorners[0];
+ ZXResultPoint *p1 = bullsEyeCorners[1];
+ ZXResultPoint *p2 = bullsEyeCorners[2];
+ ZXResultPoint *p3 = bullsEyeCorners[3];
+
+ if (![self isValid:p0] || ![self isValid:p1] ||
+ ![self isValid:p2] || ![self isValid:p3]) {
+ return NO;
+ }
+ int length = 2 * self.nbCenterLayers;
+ // Get the bits around the bull's eye
+ int sides[] = {
+ [self sampleLine:p0 p2:p1 size:length], // Right side
+ [self sampleLine:p1 p2:p2 size:length], // Bottom
+ [self sampleLine:p2 p2:p3 size:length], // Left side
+ [self sampleLine:p3 p2:p0 size:length] // Top
+ };
+
+ // bullsEyeCorners[shift] is the corner of the bulls'eye that has three
+ // orientation marks.
+ // sides[shift] is the row/column that goes from the corner with three
+ // orientation marks to the corner with two.
+ int shift = [self rotationForSides:sides length:length];
+ if (shift == -1) {
+ return NO;
+ }
+ self.shift = shift;
+
+ // Flatten the parameter bits into a single 28- or 40-bit long
+ long parameterData = 0;
+ for (int i = 0; i < 4; i++) {
+ int side = sides[(self.shift + i) % 4];
+ if (self.isCompact) {
+ // Each side of the form ..XXXXXXX. where Xs are parameter data
+ parameterData <<= 7;
+ parameterData += (side >> 1) & 0x7F;
+ } else {
+ // Each side of the form ..XXXXX.XXXXX. where Xs are parameter data
+ parameterData <<= 10;
+ parameterData += ((side >> 2) & (0x1f << 5)) + ((side >> 1) & 0x1F);
+ }
+ }
+
+ // Corrects parameter data using RS. Returns just the data portion
+ // without the error correction.
+ int correctedData = [self correctedParameterData:parameterData compact:self.isCompact];
+ if (correctedData == -1) {
+ return NO;
+ }
+
+ if (self.isCompact) {
+ // 8 bits: 2 bits layers and 6 bits data blocks
+ self.nbLayers = (correctedData >> 6) + 1;
+ self.nbDataBlocks = (correctedData & 0x3F) + 1;
+ } else {
+ // 16 bits: 5 bits layers and 11 bits data blocks
+ self.nbLayers = (correctedData >> 11) + 1;
+ self.nbDataBlocks = (correctedData & 0x7FF) + 1;
+ }
+
+ return YES;
+}
+
+int expectedCornerBits[] = {
+ 0xee0, // 07340 XXX .XX X.. ...
+ 0x1dc, // 00734 ... XXX .XX X..
+ 0x83b, // 04073 X.. ... XXX .XX
+ 0x707, // 03407 .XX X.. ... XXX
+};
+
+int bitCount(uint32_t i) {
+ i = i - ((i >> 1) & 0x55555555);
+ i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
+ return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
+}
+
+- (int)rotationForSides:(const int[])sides length:(int)length {
+ // In a normal pattern, we expect to See
+ // ** .* D A
+ // * *
+ //
+ // . *
+ // .. .. C B
+ //
+ // Grab the 3 bits from each of the sides the form the locator pattern and concatenate
+ // into a 12-bit integer. Start with the bit at A
+ int cornerBits = 0;
+ for (int i = 0; i < 4; i++) {
+ int side = sides[i];
+ // XX......X where X's are orientation marks
+ int t = ((side >> (length - 2)) << 1) + (side & 1);
+ cornerBits = (cornerBits << 3) + t;
+ }
+ // Mov the bottom bit to the top, so that the three bits of the locator pattern at A are
+ // together. cornerBits is now:
+ // 3 orientation bits at A || 3 orientation bits at B || ... || 3 orientation bits at D
+ cornerBits = ((cornerBits & 1) << 11) + (cornerBits >> 1);
+ // The result shift indicates which element of BullsEyeCorners[] goes into the top-left
+ // corner. Since the four rotation values have a Hamming distance of 8, we
+ // can easily tolerate two errors.
+ for (int shift = 0; shift < 4; shift++) {
+ if (bitCount(cornerBits ^ expectedCornerBits[shift]) <= 2) {
+ return shift;
+ }
+ }
+ return -1;
+}
+
+/**
+ * Corrects the parameter bits using Reed-Solomon algorithm.
+ *
+ * @param parameterData parameter bits
+ * @param compact true if this is a compact Aztec code
+ * @return -1 if the array contains too many errors
+ */
+- (int)correctedParameterData:(long)parameterData compact:(BOOL)compact {
+ int numCodewords;
+ int numDataCodewords;
+
+ if (compact) {
+ numCodewords = 7;
+ numDataCodewords = 2;
+ } else {
+ numCodewords = 10;
+ numDataCodewords = 4;
+ }
+
+ int numECCodewords = numCodewords - numDataCodewords;
+ ZXIntArray *parameterWords = [[ZXIntArray alloc] initWithLength:numCodewords];
+ for (int i = numCodewords - 1; i >= 0; --i) {
+ parameterWords.array[i] = (int32_t) parameterData & 0xF;
+ parameterData >>= 4;
+ }
+
+ ZXReedSolomonDecoder *rsDecoder = [[ZXReedSolomonDecoder alloc] initWithField:[ZXGenericGF AztecParam]];
+ if (![rsDecoder decode:parameterWords twoS:numECCodewords error:nil]) {
+ return NO;
+ }
+ // Toss the error correction. Just return the data as an integer
+ int result = 0;
+ for (int i = 0; i < numDataCodewords; i++) {
+ result = (result << 4) + parameterWords.array[i];
+ }
+ return result;
+}
+
+/**
+ * Finds the corners of a bull-eye centered on the passed point.
+ * This returns the centers of the diagonal points just outside the bull's eye
+ * Returns [topRight, bottomRight, bottomLeft, topLeft]
+ *
+ * @param pCenter Center point
+ * @return The corners of the bull-eye, or nil if no valid bull-eye can be found
+ */
+- (NSMutableArray *)bullsEyeCorners:(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];
+
+ //d a
+ //
+ //c b
+
+ 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;
+
+ // Expand the square by .5 pixel in each direction so that we're on the border
+ // between the white square and the black square
+ ZXResultPoint *pinax = [[ZXResultPoint alloc] initWithX:pina.x + 0.5f y:pina.y - 0.5f];
+ ZXResultPoint *pinbx = [[ZXResultPoint alloc] initWithX:pinb.x + 0.5f y:pinb.y + 0.5f];
+ ZXResultPoint *pincx = [[ZXResultPoint alloc] initWithX:pinc.x - 0.5f y:pinc.y + 0.5f];
+ ZXResultPoint *pindx = [[ZXResultPoint alloc] initWithX:pind.x - 0.5f y:pind.y - 0.5f];
+
+ // Expand the square so that its corners are the centers of the points
+ // just outside the bull's eye.
+ return [[self expandSquare:@[pinax, pinbx, pincx, pindx]
+ oldSide:2 * self.nbCenterLayers - 3
+ newSide:2 * self.nbCenterLayers] mutableCopy];
+}
+
+/**
+ * Finds a candidate center point of an Aztec code from an image
+ */
+- (ZXAztecPoint *)matrixCenter {
+ ZXResultPoint *pointA;
+ ZXResultPoint *pointB;
+ ZXResultPoint *pointC;
+ ZXResultPoint *pointD;
+
+ ZXWhiteRectangleDetector *detector = [[ZXWhiteRectangleDetector alloc] initWithImage:self.image error:nil];
+ NSArray *cornerPoints = [detector detectWithError:nil];
+
+ if (cornerPoints) {
+ pointA = cornerPoints[0];
+ pointB = cornerPoints[1];
+ pointC = cornerPoints[2];
+ pointD = cornerPoints[3];
+ } else {
+ // This exception can be in case the initial rectangle is white
+ // In that case, surely in the bull's eye, we try to expand the rectangle.
+ 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];
+ }
+
+ //Compute the center of the rectangle
+ 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];
+
+ // Redetermine the white rectangle starting from previously computed center.
+ // This will ensure that we end up with a white rectangle in center bull's eye
+ // in order to compute a more accurate center.
+ detector = [[ZXWhiteRectangleDetector alloc] initWithImage:self.image initSize:15 x:cx y:cy error:nil];
+ cornerPoints = [detector detectWithError:nil];
+
+ if (cornerPoints) {
+ pointA = cornerPoints[0];
+ pointB = cornerPoints[1];
+ pointC = cornerPoints[2];
+ pointD = cornerPoints[3];
+ } else {
+ // This exception can be in case the initial rectangle is white
+ // In that case we try to expand the rectangle.
+ 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];
+ }
+
+ cx = [ZXMathUtils round:([pointA x] + [pointD x] + [pointB x] + [pointC x]) / 4];
+ cy = [ZXMathUtils round:([pointA y] + [pointD y] + [pointB y] + [pointC y]) / 4];
+
+ // Recompute the center of the rectangle
+ return [[ZXAztecPoint alloc] initWithX:cx y:cy];
+}
+
+/**
+ * Gets the Aztec code corners from the bull's eye corners and the parameters.
+ *
+ * @param bullsEyeCorners the array of bull's eye corners
+ * @return the array of aztec code corners, or nil if the corner points do not fit in the image
+ */
+- (NSArray *)matrixCornerPoints:(NSArray *)bullsEyeCorners {
+ return [self expandSquare:bullsEyeCorners oldSide:2 * self.nbCenterLayers newSide:[self dimension]];
+}
+
+/**
+ * Creates a BitMatrix by sampling the provided image.
+ * topLeft, topRight, bottomRight, and bottomLeft are the centers of the squares on the
+ * diagonal just outside the bull's eye.
+ */
+- (ZXBitMatrix *)sampleGrid:(ZXBitMatrix *)anImage
+ topLeft:(ZXResultPoint *)topLeft
+ topRight:(ZXResultPoint *)topRight
+ bottomRight:(ZXResultPoint *)bottomRight
+ bottomLeft:(ZXResultPoint *)bottomLeft {
+ ZXGridSampler *sampler = [ZXGridSampler instance];
+ int dimension = [self dimension];
+
+ float low = dimension / 2.0f - self.nbCenterLayers;
+ float high = dimension / 2.0f + self.nbCenterLayers;
+
+ return [sampler sampleGrid:anImage
+ dimensionX:dimension
+ dimensionY:dimension
+ p1ToX:low p1ToY:low // topleft
+ p2ToX:high p2ToY:low // topright
+ p3ToX:high p3ToY:high // bottomright
+ p4ToX:low p4ToY:high // bottomleft
+ 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:nil];
+}
+
+/**
+ * Samples a line.
+ *
+ * @param p1 start point (inclusive)
+ * @param p2 end point (exclusive)
+ * @param size number of bits
+ * @return the array of bits as an int (first bit is high-order bit of result)
+ */
+- (int)sampleLine:(ZXResultPoint *)p1 p2:(ZXResultPoint *)p2 size:(int)size {
+ int result = 0;
+
+ float d = [self resultDistance:p1 b:p2];
+ float moduleSize = d / size;
+ float px = p1.x;
+ float py = p1.y;
+ float dx = moduleSize * (p2.x - p1.x) / d;
+ float dy = moduleSize * (p2.y - p1.y) / d;
+ for (int i = 0; i < size; i++) {
+ if ([self.image getX:[ZXMathUtils round:px + i * dx] y:[ZXMathUtils round:py + i * dy]]) {
+ result |= 1 << (size - i - 1);
+ }
+ }
+
+ return result;
+}
+
+/**
+ * @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];
+}
+
+/**
+ * Expand the square represented by the corner points by pushing out equally in all directions
+ *
+ * @param cornerPoints the corners of the square, which has the bull's eye at its center
+ * @param oldSide the original length of the side of the square in the target bit matrix
+ * @param newSide the new length of the size of the square in the target bit matrix
+ * @return the corners of the expanded square
+ */
+- (NSArray *)expandSquare:(NSArray *)cornerPoints oldSide:(float)oldSide newSide:(float)newSide {
+ ZXResultPoint *cornerPoints0 = (ZXResultPoint *)cornerPoints[0];
+ ZXResultPoint *cornerPoints1 = (ZXResultPoint *)cornerPoints[1];
+ ZXResultPoint *cornerPoints2 = (ZXResultPoint *)cornerPoints[2];
+ ZXResultPoint *cornerPoints3 = (ZXResultPoint *)cornerPoints[3];
+
+ float ratio = newSide / (2 * oldSide);
+ float dx = cornerPoints0.x - cornerPoints2.x;
+ float dy = cornerPoints0.y - cornerPoints2.y;
+ float centerx = (cornerPoints0.x + cornerPoints2.x) / 2.0f;
+ float centery = (cornerPoints0.y + cornerPoints2.y) / 2.0f;
+
+ ZXResultPoint *result0 = [[ZXResultPoint alloc] initWithX:centerx + ratio * dx y:centery + ratio * dy];
+ ZXResultPoint *result2 = [[ZXResultPoint alloc] initWithX:centerx - ratio * dx y:centery - ratio * dy];
+
+ dx = cornerPoints1.x - cornerPoints3.x;
+ dy = cornerPoints1.y - cornerPoints3.y;
+ centerx = (cornerPoints1.x + cornerPoints3.x) / 2.0f;
+ centery = (cornerPoints1.y + cornerPoints3.y) / 2.0f;
+ ZXResultPoint *result1 = [[ZXResultPoint alloc] initWithX:centerx + ratio * dx y:centery + ratio * dy];
+ ZXResultPoint *result3 = [[ZXResultPoint alloc] initWithX:centerx - ratio * dx y:centery - ratio * dy];
+
+ return @[result0, result1, result2, result3];
+}
+
+- (BOOL)isValidX:(int)x y:(int)y {
+ return x >= 0 && x < self.image.width && y > 0 && y < self.image.height;
+}
+
+- (BOOL)isValid:(ZXResultPoint *)point {
+ int x = [ZXMathUtils round:point.x];
+ int y = [ZXMathUtils round:point.y];
+ return [self isValidX:x y:y];
+}
+
+- (float)distance:(ZXAztecPoint *)a b:(ZXAztecPoint *)b {
+ return [ZXMathUtils distance:a.x aY:a.y bX:b.x bY:b.y];
+}
+
+- (float)resultDistance:(ZXResultPoint *)a b:(ZXResultPoint *)b {
+ return [ZXMathUtils distance:a.x aY:a.y bX:b.x bY:b.y];
+}
+
+- (int)dimension {
+ if (self.compact) {
+ return 4 * self.nbLayers + 11;
+ }
+ if (self.nbLayers <= 4) {
+ return 4 * self.nbLayers + 15;
+ }
+ return 4 * self.nbLayers + 2 * ((self.nbLayers-4)/8 + 1) + 15;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecBinaryShiftToken.h b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecBinaryShiftToken.h
new file mode 100644
index 0000000..9bf4095
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecBinaryShiftToken.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXAztecToken.h"
+
+@interface ZXAztecBinaryShiftToken : ZXAztecToken
+
+- (id)initWithPrevious:(ZXAztecToken *)previous binaryShiftStart:(int)binaryShiftStart binaryShiftByteCount:(int)binaryShiftByteCount;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecBinaryShiftToken.m b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecBinaryShiftToken.m
new file mode 100644
index 0000000..2ca14ce
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecBinaryShiftToken.m
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXAztecBinaryShiftToken.h"
+#import "ZXBitArray.h"
+#import "ZXByteArray.h"
+
+@interface ZXAztecBinaryShiftToken ()
+
+@property (nonatomic, assign, readonly) int16_t binaryShiftStart;
+@property (nonatomic, assign, readonly) int16_t binaryShiftByteCount;
+
+@end
+
+@implementation ZXAztecBinaryShiftToken
+
+- (id)initWithPrevious:(ZXAztecToken *)previous binaryShiftStart:(int)binaryShiftStart binaryShiftByteCount:(int)binaryShiftByteCount {
+ if (self = [super initWithPrevious:previous]) {
+ _binaryShiftStart = (int16_t) binaryShiftStart;
+ _binaryShiftByteCount = (int16_t) binaryShiftByteCount;
+ }
+
+ return self;
+}
+
+- (void)appendTo:(ZXBitArray *)bitArray text:(ZXByteArray *)text {
+ for (int i = 0; i < self.binaryShiftByteCount; i++) {
+ if (i == 0 || (i == 31 && self.binaryShiftByteCount <= 62)) {
+ // We need a header before the first character, and before
+ // character 31 when the total byte code is <= 62
+ [bitArray appendBits:31 numBits:5]; // BINARY_SHIFT
+ if (self.binaryShiftByteCount > 62) {
+ [bitArray appendBits:self.binaryShiftByteCount - 31 numBits:16];
+ } else if (i == 0) {
+ // 1 <= binaryShiftByteCode <= 62
+ [bitArray appendBits:MIN(self.binaryShiftByteCount, 31) numBits:5];
+ } else {
+ // 32 <= binaryShiftCount <= 62 and i == 31
+ [bitArray appendBits:self.binaryShiftByteCount - 31 numBits:5];
+ }
+ }
+ [bitArray appendBits:text.array[self.binaryShiftStart + i] numBits:8];
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecCode.h b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecCode.h
new file mode 100644
index 0000000..41a086e
--- /dev/null
+++ b/Pods/ZXingObjC/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, getter = isCompact) 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/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecCode.m b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecCode.m
new file mode 100644
index 0000000..c7054d5
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecEncoder.h b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecEncoder.h
new file mode 100644
index 0000000..549ffdd
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecEncoder.h
@@ -0,0 +1,48 @@
+/*
+ * 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 const int ZX_AZTEC_DEFAULT_EC_PERCENT;
+extern const int ZX_AZTEC_DEFAULT_LAYERS;
+
+@class ZXAztecCode, ZXBitArray, ZXByteArray, ZXGenericGF;
+
+/**
+ * Generates Aztec 2D barcodes.
+ */
+@interface ZXAztecEncoder : NSObject
+
+/**
+ * Encodes the given binary content as an Aztec symbol
+ *
+ * @param data input data string
+ * @return Aztec symbol matrix with metadata
+ */
++ (ZXAztecCode *)encode:(ZXByteArray *)data;
+
+/**
+ * Encodes the given binary content as an Aztec symbol
+ *
+ * @param data input data string
+ * @param minECCPercent minimal percentage of error check words (According to ISO/IEC 24778:2008,
+ * a minimum of 23% + 3 words is recommended)
+ * @param userSpecifiedLayers if non-zero, a user-specified value for the number of layers
+ * @return Aztec symbol matrix with metadata
+ */
++ (ZXAztecCode *)encode:(ZXByteArray *)data
+ minECCPercent:(int)minECCPercent
+ userSpecifiedLayers:(int)userSpecifiedLayers;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecEncoder.m b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecEncoder.m
new file mode 100644
index 0000000..ef0c0e9
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecEncoder.m
@@ -0,0 +1,335 @@
+/*
+ * 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 "ZXAztecHighLevelEncoder.h"
+#import "ZXBitArray.h"
+#import "ZXBitMatrix.h"
+#import "ZXByteArray.h"
+#import "ZXGenericGF.h"
+#import "ZXIntArray.h"
+#import "ZXReedSolomonEncoder.h"
+
+const int ZX_AZTEC_DEFAULT_EC_PERCENT = 33; // default minimal percentage of error check words
+const int ZX_AZTEC_DEFAULT_LAYERS = 0;
+const int ZX_AZTEC_MAX_NB_BITS = 32;
+const int ZX_AZTEC_MAX_NB_BITS_COMPACT = 4;
+
+const int ZX_AZTEC_WORD_SIZE[] = {
+ 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
+
++ (ZXAztecCode *)encode:(ZXByteArray *)data {
+ return [self encode:data minECCPercent:ZX_AZTEC_DEFAULT_EC_PERCENT userSpecifiedLayers:ZX_AZTEC_DEFAULT_LAYERS];
+}
+
++ (ZXAztecCode *)encode:(ZXByteArray *)data minECCPercent:(int)minECCPercent userSpecifiedLayers:(int)userSpecifiedLayers {
+ // High-level encode
+ ZXBitArray *bits = [[[ZXAztecHighLevelEncoder alloc] initWithText:data] encode];
+
+ // stuff bits and choose symbol size
+ int eccBits = bits.size * minECCPercent / 100 + 11;
+ int totalSizeBits = bits.size + eccBits;
+ BOOL compact;
+ int layers;
+ int totalBitsInLayer;
+ int wordSize = ZX_AZTEC_WORD_SIZE[0];
+ ZXBitArray *stuffedBits;
+ if (userSpecifiedLayers != ZX_AZTEC_DEFAULT_LAYERS) {
+ compact = userSpecifiedLayers < 0;
+ layers = abs(userSpecifiedLayers);
+ if (layers > (compact ? ZX_AZTEC_MAX_NB_BITS_COMPACT : ZX_AZTEC_MAX_NB_BITS)) {
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:[NSString stringWithFormat:@"Illegal value %d for layers", userSpecifiedLayers]
+ userInfo:nil];
+ }
+ totalBitsInLayer = [self totalBitsInLayer:layers compact:compact];
+ wordSize = ZX_AZTEC_WORD_SIZE[layers];
+ int usableBitsInLayers = totalBitsInLayer - (totalBitsInLayer % wordSize);
+ stuffedBits = [self stuffBits:bits wordSize:wordSize];
+ if (stuffedBits.size + eccBits > usableBitsInLayers) {
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:@"Data too large for user specified layer"
+ userInfo:nil];
+ }
+ if (compact && stuffedBits.size > wordSize * 64) {
+ // Compact format only allows 64 data words, though C4 can hold more words than that
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:@"Data too large for user specified layer"
+ userInfo:nil];
+ }
+ } else {
+ // We look at the possible table sizes in the order Compact1, Compact2, Compact3,
+ // Compact4, Normal4,... Normal(i) for i < 4 isn't typically used since Compact(i+1)
+ // is the same size, but has more data.
+ for (int i = 0; ; i++) {
+ if (i > ZX_AZTEC_MAX_NB_BITS) {
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:@"Data too large for an Aztec code"
+ userInfo:nil];
+ }
+ compact = i <= 3;
+ layers = compact ? i + 1 : i;
+ totalBitsInLayer = [self totalBitsInLayer:layers compact:compact];
+ if (totalSizeBits > totalBitsInLayer) {
+ continue;
+ }
+ // [Re]stuff the bits if this is the first opportunity, or if the
+ // wordSize has changed
+ if (wordSize != ZX_AZTEC_WORD_SIZE[layers]) {
+ wordSize = ZX_AZTEC_WORD_SIZE[layers];
+ stuffedBits = [self stuffBits:bits wordSize:wordSize];
+ }
+ int usableBitsInLayers = totalBitsInLayer - (totalBitsInLayer % wordSize);
+ if (compact && stuffedBits.size > wordSize * 64) {
+ // Compact format only allows 64 data words, though C4 can hold more words than that
+ continue;
+ }
+ if (stuffedBits.size + eccBits <= usableBitsInLayers) {
+ break;
+ }
+ }
+ }
+ ZXBitArray *messageBits = [self generateCheckWords:stuffedBits totalBits:totalBitsInLayer wordSize:wordSize];
+
+ // generate check words
+ int messageSizeInWords = stuffedBits.size / wordSize;
+ 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];
+ memset(alignmentMap, 0, baseMatrixSize * sizeof(int));
+ 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 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;
+ }
+
+ // draw mode message
+ [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 totalBits:28 wordSize:4];
+ } else {
+ [modeMessage appendBits:layers - 1 numBits:5];
+ [modeMessage appendBits:messageSizeInWords - 1 numBits:11];
+ modeMessage = [self generateCheckWords:modeMessage totalBits:40 wordSize:4];
+ }
+ return modeMessage;
+}
+
++ (void)drawModeMessage:(ZXBitMatrix *)matrix compact:(BOOL)compact matrixSize:(int)matrixSize modeMessage:(ZXBitArray *)modeMessage {
+ int center = matrixSize / 2;
+ if (compact) {
+ for (int i = 0; i < 7; i++) {
+ int offset = center - 3 + i;
+ if ([modeMessage get:i]) {
+ [matrix setX:offset y:center - 5];
+ }
+ if ([modeMessage get:i + 7]) {
+ [matrix setX:center + 5 y:offset];
+ }
+ if ([modeMessage get:20 - i]) {
+ [matrix setX:offset y:center + 5];
+ }
+ if ([modeMessage get:27 - i]) {
+ [matrix setX:center - 5 y:offset];
+ }
+ }
+ } else {
+ for (int i = 0; i < 10; i++) {
+ int offset = center - 5 + i + i / 5;
+ if ([modeMessage get:i]) {
+ [matrix setX:offset y:center - 7];
+ }
+ if ([modeMessage get:i + 10]) {
+ [matrix setX:center + 7 y:offset];
+ }
+ if ([modeMessage get:29 - i]) {
+ [matrix setX:offset y:center + 7];
+ }
+ if ([modeMessage get:39 - i]) {
+ [matrix setX:center - 7 y:offset];
+ }
+ }
+ }
+}
+
++ (ZXBitArray *)generateCheckWords:(ZXBitArray *)bitArray totalBits:(int)totalBits wordSize:(int)wordSize {
+ // bitArray is guaranteed to be a multiple of the wordSize, so no padding needed
+ int messageSizeInWords = bitArray.size / wordSize;
+ ZXReedSolomonEncoder *rs = [[ZXReedSolomonEncoder alloc] initWithField:[self getGF:wordSize]];
+ int totalWords = totalBits / wordSize;
+
+ ZXIntArray *messageWords = [self bitsToWords:bitArray wordSize:wordSize totalWords:totalWords];
+ [rs encode:messageWords ecBytes:totalWords - messageSizeInWords];
+ int startPad = totalBits % wordSize;
+ ZXBitArray *messageBits = [[ZXBitArray alloc] init];
+ [messageBits appendBits:0 numBits:startPad];
+ for (int i = 0; i < totalWords; i++) {
+ [messageBits appendBits:messageWords.array[i] numBits:wordSize];
+ }
+ return messageBits;
+}
+
++ (ZXIntArray *)bitsToWords:(ZXBitArray *)stuffedBits wordSize:(int)wordSize totalWords:(int)totalWords {
+ ZXIntArray *message = [[ZXIntArray alloc] initWithLength:totalWords];
+ int i;
+ int n;
+ for (i = 0, n = stuffedBits.size / wordSize; i < n; i++) {
+ int32_t value = 0;
+ for (int j = 0; j < wordSize; j++) {
+ value |= [stuffedBits get:i * wordSize + j] ? (1 << (wordSize - j - 1)) : 0;
+ }
+ message.array[i] = value;
+ }
+ return message;
+}
+
++ (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];
+
+ 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];
+ }
+ }
+
+ return arrayOut;
+}
+
++ (int)totalBitsInLayer:(int)layers compact:(BOOL)compact {
+ return ((compact ? 88 : 112) + 16 * layers) * layers;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.h b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.h
new file mode 100644
index 0000000..9355b86
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+extern NSArray *ZX_AZTEC_MODE_NAMES;
+
+extern const int ZX_AZTEC_MODE_UPPER;
+extern const int ZX_AZTEC_MODE_LOWER;
+extern const int ZX_AZTEC_MODE_DIGIT;
+extern const int ZX_AZTEC_MODE_MIXED;
+extern const int ZX_AZTEC_MODE_PUNCT;
+
+extern const int ZX_AZTEC_LATCH_TABLE[][5];
+
+#define ZX_AZTEC_SHIFT_TABLE_SIZE 6
+extern int ZX_AZTEC_SHIFT_TABLE[ZX_AZTEC_SHIFT_TABLE_SIZE][ZX_AZTEC_SHIFT_TABLE_SIZE];
+
+@class ZXBitArray, ZXByteArray;
+
+/**
+ * This produces nearly optimal encodings of text into the first-level of
+ * encoding used by Aztec code.
+ *
+ * It uses a dynamic algorithm. For each prefix of the string, it determines
+ * a set of encodings that could lead to this prefix. We repeatedly add a
+ * character and generate a new set of optimal encodings until we have read
+ * through the entire input.
+ */
+@interface ZXAztecHighLevelEncoder : NSObject
+
+- (id)initWithText:(ZXByteArray *)text;
+
+/**
+ * Convert the text represented by this High Level Encoder into a BitArray.
+ */
+- (ZXBitArray *)encode;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.m b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.m
new file mode 100644
index 0000000..119ff81
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecHighLevelEncoder.m
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXAztecHighLevelEncoder.h"
+#import "ZXAztecState.h"
+#import "ZXByteArray.h"
+
+NSArray *ZX_AZTEC_MODE_NAMES = nil;
+
+const int ZX_AZTEC_MODE_UPPER = 0; // 5 bits
+const int ZX_AZTEC_MODE_LOWER = 1; // 5 bits
+const int ZX_AZTEC_MODE_DIGIT = 2; // 4 bits
+const int ZX_AZTEC_MODE_MIXED = 3; // 5 bits
+const int ZX_AZTEC_MODE_PUNCT = 4; // 5 bits
+
+// The Latch Table shows, for each pair of Modes, the optimal method for
+// getting from one mode to another. In the worst possible case, this can
+// be up to 14 bits. In the best possible case, we are already there!
+// The high half-word of each entry gives the number of bits.
+// The low half-word of each entry are the actual bits necessary to change
+const int ZX_AZTEC_LATCH_TABLE[][5] = {
+ {
+ 0,
+ (5 << 16) + 28, // UPPER -> LOWER
+ (5 << 16) + 30, // UPPER -> DIGIT
+ (5 << 16) + 29, // UPPER -> MIXED
+ (10 << 16) + (29 << 5) + 30, // UPPER -> MIXED -> PUNCT
+ },
+ {
+ (9 << 16) + (30 << 4) + 14, // LOWER -> DIGIT -> UPPER
+ 0,
+ (5 << 16) + 30, // LOWER -> DIGIT
+ (5 << 16) + 29, // LOWER -> MIXED
+ (10 << 16) + (29 << 5) + 30, // LOWER -> MIXED -> PUNCT
+ },
+ {
+ (4 << 16) + 14, // DIGIT -> UPPER
+ (9 << 16) + (14 << 5) + 28, // DIGIT -> UPPER -> LOWER
+ 0,
+ (9 << 16) + (14 << 5) + 29, // DIGIT -> UPPER -> MIXED
+ (14 << 16) + (14 << 10) + (29 << 5) + 30,
+ // DIGIT -> UPPER -> MIXED -> PUNCT
+ },
+ {
+ (5 << 16) + 29, // MIXED -> UPPER
+ (5 << 16) + 28, // MIXED -> LOWER
+ (10 << 16) + (29 << 5) + 30, // MIXED -> UPPER -> DIGIT
+ 0,
+ (5 << 16) + 30, // MIXED -> PUNCT
+ },
+ {
+ (5 << 16) + 31, // PUNCT -> UPPER
+ (10 << 16) + (31 << 5) + 28, // PUNCT -> UPPER -> LOWER
+ (10 << 16) + (31 << 5) + 30, // PUNCT -> UPPER -> DIGIT
+ (10 << 16) + (31 << 5) + 29, // PUNCT -> UPPER -> MIXED
+ 0,
+ },
+};
+
+// A reverse mapping from [mode][char] to the encoding for that character
+// in that mode. An entry of 0 indicates no mapping exists.
+const int ZX_AZTEC_CHAR_MAP_HEIGHT = 5;
+const int ZX_AZTEC_CHAR_MAP_WIDTH = 256;
+static int ZX_AZTEC_CHAR_MAP[ZX_AZTEC_CHAR_MAP_HEIGHT][ZX_AZTEC_CHAR_MAP_WIDTH];
+
+// A map showing the available shift codes. (The shifts to BINARY are not
+// shown
+int ZX_AZTEC_SHIFT_TABLE[ZX_AZTEC_SHIFT_TABLE_SIZE][ZX_AZTEC_SHIFT_TABLE_SIZE];
+
+@interface ZXAztecHighLevelEncoder ()
+
+@property (nonatomic, assign, readonly) ZXByteArray *text;
+
+@end
+
+@implementation ZXAztecHighLevelEncoder
+
++ (void)load {
+ ZX_AZTEC_MODE_NAMES = @[@"UPPER", @"LOWER", @"DIGIT", @"MIXED", @"PUNCT"];
+
+ memset(ZX_AZTEC_CHAR_MAP, 0, ZX_AZTEC_CHAR_MAP_HEIGHT * ZX_AZTEC_CHAR_MAP_WIDTH * sizeof(int));
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_UPPER][' '] = 1;
+ for (int c = 'A'; c <= 'Z'; c++) {
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_UPPER][c] = c - 'A' + 2;
+ }
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_LOWER][' '] = 1;
+ for (int c = 'a'; c <= 'z'; c++) {
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_LOWER][c] = c - 'a' + 2;
+ }
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_DIGIT][' '] = 1;
+ for (int c = '0'; c <= '9'; c++) {
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_DIGIT][c] = c - '0' + 2;
+ }
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_DIGIT][','] = 12;
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_DIGIT]['.'] = 13;
+
+ const int mixedTable[] = {
+ '\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 < sizeof(mixedTable) / sizeof(int); i++) {
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_MIXED][mixedTable[i]] = i;
+ }
+
+ const int punctTable[] = {
+ '\0', '\r', '\0', '\0', '\0', '\0', '!', '\'', '#', '$', '%', '&', '\'',
+ '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?',
+ '[', ']', '{', '}'
+ };
+ for (int i = 0; i < sizeof(punctTable) / sizeof(int); i++) {
+ if (punctTable[i] > 0) {
+ ZX_AZTEC_CHAR_MAP[ZX_AZTEC_MODE_PUNCT][punctTable[i]] = i;
+ }
+ }
+
+ memset(ZX_AZTEC_SHIFT_TABLE, -1, ZX_AZTEC_SHIFT_TABLE_SIZE * ZX_AZTEC_SHIFT_TABLE_SIZE * sizeof(int));
+ ZX_AZTEC_SHIFT_TABLE[ZX_AZTEC_MODE_UPPER][ZX_AZTEC_MODE_PUNCT] = 0;
+
+ ZX_AZTEC_SHIFT_TABLE[ZX_AZTEC_MODE_LOWER][ZX_AZTEC_MODE_PUNCT] = 0;
+ ZX_AZTEC_SHIFT_TABLE[ZX_AZTEC_MODE_LOWER][ZX_AZTEC_MODE_UPPER] = 28;
+
+ ZX_AZTEC_SHIFT_TABLE[ZX_AZTEC_MODE_MIXED][ZX_AZTEC_MODE_PUNCT] = 0;
+
+ ZX_AZTEC_SHIFT_TABLE[ZX_AZTEC_MODE_DIGIT][ZX_AZTEC_MODE_PUNCT] = 0;
+ ZX_AZTEC_SHIFT_TABLE[ZX_AZTEC_MODE_DIGIT][ZX_AZTEC_MODE_UPPER] = 15;
+}
+
+- (id)initWithText:(ZXByteArray *)text {
+ if (self = [super init]) {
+ _text = text;
+ }
+
+ return self;
+}
+
+- (ZXBitArray *)encode {
+ NSArray *states = @[[ZXAztecState initialState]];
+ for (int index = 0; index < self.text.length; index++) {
+ int pairCode;
+ int nextChar = index + 1 < self.text.length ? self.text.array[index + 1] : 0;
+ switch (self.text.array[index]) {
+ case '\r':
+ pairCode = nextChar == '\n' ? 2 : 0;
+ break;
+ case '.' :
+ pairCode = nextChar == ' ' ? 3 : 0;
+ break;
+ case ',' :
+ pairCode = nextChar == ' ' ? 4 : 0;
+ break;
+ case ':' :
+ pairCode = nextChar == ' ' ? 5 : 0;
+ break;
+ default:
+ pairCode = 0;
+ }
+ if (pairCode > 0) {
+ // We have one of the four special PUNCT pairs. Treat them specially.
+ // Get a new set of states for the two new characters.
+ states = [self updateStateListForPair:states index:index pairCode:pairCode];
+ index++;
+ } else {
+ // Get a new set of states for the new character.
+ states = [self updateStateListForChar:states index:index];
+ }
+ }
+ // We are left with a set of states. Find the shortest one.
+ ZXAztecState *minState = [[states sortedArrayUsingComparator:^NSComparisonResult(ZXAztecState *a, ZXAztecState *b) {
+ return a.bitCount - b.bitCount;
+ }] firstObject];
+ // Convert it to a bit array, and return.
+ return [minState toBitArray:self.text];
+}
+
+// We update a set of states for a new character by updating each state
+// for the new character, merging the results, and then removing the
+// non-optimal states.
+- (NSArray *)updateStateListForChar:(NSArray *)states index:(int)index {
+ NSMutableArray *result = [NSMutableArray array];
+ for (ZXAztecState *state in states) {
+ [self updateStateForChar:state index:index result:result];
+ }
+ return [self simplifyStates:result];
+}
+
+// Return a set of states that represent the possible ways of updating this
+// state for the next character. The resulting set of states are added to
+// the "result" list.
+- (void)updateStateForChar:(ZXAztecState *)state index:(int)index result:(NSMutableArray *)result {
+ unichar ch = (unichar) (self.text.array[index] & 0xFF);
+ BOOL charInCurrentTable = ZX_AZTEC_CHAR_MAP[state.mode][ch] > 0;
+ ZXAztecState *stateNoBinary = nil;
+ for (int mode = 0; mode <= ZX_AZTEC_MODE_PUNCT; mode++) {
+ int charInMode = ZX_AZTEC_CHAR_MAP[mode][ch];
+ if (charInMode > 0) {
+ if (!stateNoBinary) {
+ // Only create stateNoBinary the first time it's required.
+ stateNoBinary = [state endBinaryShift:index];
+ }
+ // Try generating the character by latching to its mode
+ if (!charInCurrentTable || mode == state.mode || mode == ZX_AZTEC_MODE_DIGIT) {
+ // If the character is in the current table, we don't want to latch to
+ // any other mode except possibly digit (which uses only 4 bits). Any
+ // other latch would be equally successful *after* this character, and
+ // so wouldn't save any bits.
+ ZXAztecState *latch_state = [stateNoBinary latchAndAppend:mode value:charInMode];
+ [result addObject:latch_state];
+ }
+ // Try generating the character by switching to its mode.
+ if (!charInCurrentTable && ZX_AZTEC_SHIFT_TABLE[state.mode][mode] >= 0) {
+ // It never makes sense to temporarily shift to another mode if the
+ // character exists in the current mode. That can never save bits.
+ ZXAztecState *shift_state = [stateNoBinary shiftAndAppend:mode value:charInMode];
+ [result addObject:shift_state];
+ }
+ }
+ }
+ if (state.binaryShiftByteCount > 0 || ZX_AZTEC_CHAR_MAP[state.mode][ch] == 0) {
+ // It's never worthwhile to go into binary shift mode if you're not already
+ // in binary shift mode, and the character exists in your current mode.
+ // That can never save bits over just outputting the char in the current mode.
+ ZXAztecState *binaryState = [state addBinaryShiftChar:index];
+ [result addObject:binaryState];
+ }
+}
+
+- (NSArray *)updateStateListForPair:(NSArray *)states index:(int)index pairCode:(int)pairCode {
+ NSMutableArray *result = [NSMutableArray array];
+ for (ZXAztecState *state in states) {
+ [self updateStateForPair:state index:index pairCode:pairCode result:result];
+ }
+ return [self simplifyStates:result];
+}
+
+- (void)updateStateForPair:(ZXAztecState *)state index:(int)index pairCode:(int)pairCode result:(NSMutableArray *)result {
+ ZXAztecState *stateNoBinary = [state endBinaryShift:index];
+ // Possibility 1. Latch to ZX_AZTEC_MODE_PUNCT, and then append this code
+ [result addObject:[stateNoBinary latchAndAppend:ZX_AZTEC_MODE_PUNCT value:pairCode]];
+ if (state.mode != ZX_AZTEC_MODE_PUNCT) {
+ // Possibility 2. Shift to ZX_AZTEC_MODE_PUNCT, and then append this code.
+ // Every state except ZX_AZTEC_MODE_PUNCT (handled above) can shift
+ [result addObject:[stateNoBinary shiftAndAppend:ZX_AZTEC_MODE_PUNCT value:pairCode]];
+ }
+ if (pairCode == 3 || pairCode == 4) {
+ // both characters are in DIGITS. Sometimes better to just add two digits
+ ZXAztecState *digit_state = [[stateNoBinary
+ latchAndAppend:ZX_AZTEC_MODE_DIGIT value:16 - pairCode] // period or comma in DIGIT
+ latchAndAppend:ZX_AZTEC_MODE_DIGIT value:1]; // space in DIGIT
+ [result addObject:digit_state];
+ }
+ if (state.binaryShiftByteCount > 0) {
+ // It only makes sense to do the characters as binary if we're already
+ // in binary mode.
+ ZXAztecState *binaryState = [[state addBinaryShiftChar:index] addBinaryShiftChar:index + 1];
+ [result addObject:binaryState];
+ }
+}
+
+- (NSArray *)simplifyStates:(NSArray *)states {
+ NSMutableArray *result = [NSMutableArray array];
+ for (ZXAztecState *newState in states) {
+ BOOL add = YES;
+ NSArray *resultCopy = [NSArray arrayWithArray:result];
+ for (ZXAztecState *oldState in resultCopy) {
+ if ([oldState isBetterThanOrEqualTo:newState]) {
+ add = NO;
+ break;
+ }
+ if ([newState isBetterThanOrEqualTo:oldState]) {
+ [result removeObject:oldState];
+ }
+ }
+ if (add) {
+ [result addObject:newState];
+ }
+ }
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecSimpleToken.h b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecSimpleToken.h
new file mode 100644
index 0000000..ab9ac11
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecSimpleToken.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXAztecToken.h"
+
+@interface ZXAztecSimpleToken : ZXAztecToken
+
+- (id)initWithPrevious:(ZXAztecToken *)previous value:(int)value bitCount:(int)bitCount;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecSimpleToken.m b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecSimpleToken.m
new file mode 100644
index 0000000..d22e3ce
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecSimpleToken.m
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXAztecSimpleToken.h"
+#import "ZXBitArray.h"
+
+@interface ZXAztecSimpleToken ()
+
+// For normal words, indicates value and bitCount
+@property (nonatomic, assign, readonly) int16_t value;
+@property (nonatomic, assign, readonly) int16_t bitCount;
+
+@end
+
+@implementation ZXAztecSimpleToken
+
+- (id)initWithPrevious:(ZXAztecToken *)previous value:(int)value bitCount:(int)bitCount {
+ if (self = [super initWithPrevious:previous]) {
+ _value = (int16_t)value;
+ _bitCount = (int16_t)bitCount;
+ }
+
+ return self;
+}
+
+- (void)appendTo:(ZXBitArray *)bitArray text:(ZXByteArray *)text {
+ [bitArray appendBits:self.value numBits:self.bitCount];
+}
+
+- (NSString *)description {
+ int value = self.value & ((1 << self.bitCount) - 1);
+ value |= 1 << self.bitCount;
+
+ NSMutableString *str = [NSMutableString string];
+ for (int i = value | (1 << self.bitCount); i > 0; i >>= 1) {
+ [str insertString:((i & 1) ? @"1" : @"0") atIndex:0];
+ }
+
+ return [NSString stringWithFormat:@"<%@>", [str substringFromIndex:1]];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecState.h b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecState.h
new file mode 100644
index 0000000..36eb6e0
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecState.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@class ZXAztecToken, ZXBitArray, ZXByteArray;
+
+/**
+ * State represents all information about a sequence necessary to generate the current output.
+ * Note that a state is immutable.
+ */
+@interface ZXAztecState : NSObject
+
+// The current mode of the encoding (or the mode to which we'll return if
+// we're in Binary Shift mode.
+@property (nonatomic, assign, readonly) int mode;
+
+// The list of tokens that we output. If we are in Binary Shift mode, this
+// token list does *not* yet included the token for those bytes
+@property (nonatomic, strong, readonly) ZXAztecToken *token;
+
+// If non-zero, the number of most recent bytes that should be output
+// in Binary Shift mode.
+@property (nonatomic, assign, readonly) int binaryShiftByteCount;
+
+// The total number of bits generated (including Binary Shift).
+@property (nonatomic, assign, readonly) int bitCount;
+
+- (id)initWithToken:(ZXAztecToken *)token mode:(int)mode binaryBytes:(int)binaryBytes bitCount:(int)bitCount;
++ (ZXAztecState *)initialState;
+- (ZXAztecState *)latchAndAppend:(int)mode value:(int)value;
+- (ZXAztecState *)shiftAndAppend:(int)mode value:(int)value;
+- (ZXAztecState *)addBinaryShiftChar:(int)index;
+- (ZXAztecState *)endBinaryShift:(int)index;
+- (BOOL)isBetterThanOrEqualTo:(ZXAztecState *)other;
+- (ZXBitArray *)toBitArray:(ZXByteArray *)text;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecState.m b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecState.m
new file mode 100644
index 0000000..4a7ad50
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecState.m
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXAztecHighLevelEncoder.h"
+#import "ZXAztecState.h"
+#import "ZXAztecToken.h"
+#import "ZXBitArray.h"
+#import "ZXByteArray.h"
+
+@implementation ZXAztecState
+
+- (id)initWithToken:(ZXAztecToken *)token mode:(int)mode binaryBytes:(int)binaryBytes bitCount:(int)bitCount {
+ if (self = [super init]) {
+ _token = token;
+ _mode = mode;
+ _binaryShiftByteCount = binaryBytes;
+ _bitCount = bitCount;
+ }
+
+ return self;
+}
+
++ (ZXAztecState *)initialState {
+ return [[ZXAztecState alloc] initWithToken:[ZXAztecToken empty] mode:ZX_AZTEC_MODE_UPPER binaryBytes:0 bitCount:0];
+}
+
+// Create a new state representing this state with a latch to a (not
+// necessary different) mode, and then a code.
+- (ZXAztecState *)latchAndAppend:(int)mode value:(int)value {
+ int bitCount = self.bitCount;
+ ZXAztecToken *token = self.token;
+ if (mode != self.mode) {
+ int latch = ZX_AZTEC_LATCH_TABLE[self.mode][mode];
+ token = [token add:latch & 0xFFFF bitCount:latch >> 16];
+ bitCount += latch >> 16;
+ }
+ int latchModeBitCount = mode == ZX_AZTEC_MODE_DIGIT ? 4 : 5;
+ token = [token add:value bitCount:latchModeBitCount];
+ return [[ZXAztecState alloc] initWithToken:token mode:mode binaryBytes:0 bitCount:bitCount + latchModeBitCount];
+}
+
+// Create a new state representing this state, with a temporary shift
+// to a different mode to output a single value.
+- (ZXAztecState *)shiftAndAppend:(int)mode value:(int)value {
+ //assert binaryShiftByteCount == 0 && this.mode != mode;
+ ZXAztecToken *token = self.token;
+ int thisModeBitCount = self.mode == ZX_AZTEC_MODE_DIGIT ? 4 : 5;
+ // Shifts exist only to UPPER and PUNCT, both with tokens size 5.
+ token = [token add:ZX_AZTEC_SHIFT_TABLE[self.mode][mode] bitCount:thisModeBitCount];
+ token = [token add:value bitCount:5];
+ return [[ZXAztecState alloc] initWithToken:token mode:self.mode binaryBytes:0 bitCount:self.bitCount + thisModeBitCount + 5];
+}
+
+// Create a new state representing this state, but an additional character
+// output in Binary Shift mode.
+- (ZXAztecState *)addBinaryShiftChar:(int)index {
+ ZXAztecToken *token = self.token;
+ int mode = self.mode;
+ int bitCount = self.bitCount;
+ if (self.mode == ZX_AZTEC_MODE_PUNCT || self.mode == ZX_AZTEC_MODE_DIGIT) {
+ int latch = ZX_AZTEC_LATCH_TABLE[mode][ZX_AZTEC_MODE_UPPER];
+ token = [token add:latch & 0xFFFF bitCount:latch >> 16];
+ bitCount += latch >> 16;
+ mode = ZX_AZTEC_MODE_UPPER;
+ }
+ int deltaBitCount =
+ (self.binaryShiftByteCount == 0 || self.binaryShiftByteCount == 31) ? 18 :
+ (self.binaryShiftByteCount == 62) ? 9 : 8;
+ ZXAztecState *result = [[ZXAztecState alloc] initWithToken:token mode:mode binaryBytes:self.binaryShiftByteCount + 1 bitCount:bitCount + deltaBitCount];
+ if (result.binaryShiftByteCount == 2047 + 31) {
+ // The string is as long as it's allowed to be. We should end it.
+ result = [result endBinaryShift:index + 1];
+ }
+ return result;
+}
+
+// Create the state identical to this one, but we are no longer in
+// Binary Shift mode.
+- (ZXAztecState *)endBinaryShift:(int)index {
+ if (self.binaryShiftByteCount == 0) {
+ return self;
+ }
+ ZXAztecToken *token = self.token;
+ token = [token addBinaryShift:index - self.binaryShiftByteCount byteCount:self.binaryShiftByteCount];
+ return [[ZXAztecState alloc] initWithToken:token mode:self.mode binaryBytes:0 bitCount:self.bitCount];
+}
+
+// Returns true if "this" state is better (or equal) to be in than "that"
+// state under all possible circumstances.
+- (BOOL)isBetterThanOrEqualTo:(ZXAztecState *)other {
+ int mySize = self.bitCount + (ZX_AZTEC_LATCH_TABLE[self.mode][other.mode] >> 16);
+ if (other.binaryShiftByteCount > 0 &&
+ (self.binaryShiftByteCount == 0 || self.binaryShiftByteCount > other.binaryShiftByteCount)) {
+ mySize += 10; // Cost of entering Binary Shift mode.
+ }
+ return mySize <= other.bitCount;
+}
+
+- (ZXBitArray *)toBitArray:(ZXByteArray *)text {
+ // Reverse the tokens, so that they are in the order that they should
+ // be output
+ NSMutableArray *symbols = [NSMutableArray array];
+ for (ZXAztecToken *token = [self endBinaryShift:text.length].token; token != nil; token = token.previous) {
+ [symbols insertObject:token atIndex:0];
+ }
+ ZXBitArray *bitArray = [[ZXBitArray alloc] init];
+ // Add each token to the result.
+ for (ZXAztecToken *symbol in symbols) {
+ [symbol appendTo:bitArray text:text];
+ }
+ return bitArray;
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%@ bits=%d bytes=%d", ZX_AZTEC_MODE_NAMES[self.mode],
+ self.bitCount, self.binaryShiftByteCount];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecToken.h b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecToken.h
new file mode 100644
index 0000000..a95ff32
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecToken.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@class ZXBitArray, ZXByteArray;
+
+@interface ZXAztecToken : NSObject
+
+@property (nonatomic, strong, readonly) ZXAztecToken *previous;
+
+- (id)initWithPrevious:(ZXAztecToken *)previous;
++ (ZXAztecToken *)empty;
+- (ZXAztecToken *)add:(int)value bitCount:(int)bitCount;
+- (ZXAztecToken *)addBinaryShift:(int)start byteCount:(int)byteCount;
+- (void)appendTo:(ZXBitArray *)bitArray text:(ZXByteArray *)text;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecToken.m b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecToken.m
new file mode 100644
index 0000000..5e1d810
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/aztec/encoder/ZXAztecToken.m
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXAztecBinaryShiftToken.h"
+#import "ZXAztecSimpleToken.h"
+#import "ZXAztecToken.h"
+#import "ZXBitArray.h"
+
+@implementation ZXAztecToken
+
+- (id)initWithPrevious:(ZXAztecToken *)previous {
+ if (self = [super init]) {
+ _previous = previous;
+ }
+
+ return self;
+}
+
++ (ZXAztecToken *)empty {
+ return [[ZXAztecSimpleToken alloc] initWithPrevious:nil value:0 bitCount:0];
+}
+
+- (ZXAztecToken *)add:(int)value bitCount:(int)bitCount {
+ return [[ZXAztecSimpleToken alloc] initWithPrevious:self value:value bitCount:bitCount];
+}
+
+- (ZXAztecToken *)addBinaryShift:(int)start byteCount:(int)byteCount {
+// int bitCount = (byteCount * 8) + (byteCount <= 31 ? 10 : byteCount <= 62 ? 20 : 21);
+ return [[ZXAztecBinaryShiftToken alloc] initWithPrevious:self binaryShiftStart:start binaryShiftByteCount:byteCount];
+}
+
+- (void)appendTo:(ZXBitArray *)bitArray text:(ZXByteArray *)text {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/ZXCGImageLuminanceSource.h b/Pods/ZXingObjC/ZXingObjC/client/ZXCGImageLuminanceSource.h
new file mode 100644
index 0000000..cfee4fb
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/ZXCGImageLuminanceSource.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+#import "ZXLuminanceSource.h"
+
+@class ZXImage;
+
+@interface ZXCGImageLuminanceSource : ZXLuminanceSource
+
++ (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer CF_RETURNS_RETAINED;
++ (CGImageRef)createImageFromBuffer:(CVImageBufferRef)buffer
+ left:(size_t)left
+ top:(size_t)top
+ 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/Pods/ZXingObjC/ZXingObjC/client/ZXCGImageLuminanceSource.m b/Pods/ZXingObjC/ZXingObjC/client/ZXCGImageLuminanceSource.m
new file mode 100644
index 0000000..2f65e9a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/ZXCGImageLuminanceSource.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
+#import "ZXByteArray.h"
+#import "ZXCGImageLuminanceSource.h"
+#import "ZXImage.h"
+
+@interface ZXCGImageLuminanceSource ()
+
+@property (nonatomic, assign, readonly) CGImageRef image;
+@property (nonatomic, assign, readonly) int8_t *data;
+@property (nonatomic, assign, readonly) size_t left;
+@property (nonatomic, assign, readonly) size_t top;
+
+@end
+
+@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= self.height) {
+ [NSException raise:NSInvalidArgumentException format:@"Requested row is outside the image: %d", y];
+ }
+
+ if (!row || row.length < self.width) {
+ row = [[ZXByteArray alloc] initWithLength:self.width];
+ }
+ int offset = y * self.width;
+ memcpy(row.array, self.data + offset, self.width * sizeof(int8_t));
+ return row;
+}
+
+- (ZXByteArray *)matrix {
+ int area = self.width * self.height;
+
+ ZXByteArray *matrix = [[ZXByteArray alloc] initWithLength:area];
+ memcpy(matrix.array, self.data, area * sizeof(int8_t));
+ return matrix;
+}
+
+- (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);
+ size_t selfWidth = self.width;
+ size_t selfHeight= self.height;
+
+ if (left + selfWidth > sourceWidth ||
+ top + selfHeight > sourceHeight) {
+ [NSException raise:NSInvalidArgumentException format:@"Crop rectangle does not fit within image data."];
+ }
+
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(NULL, selfWidth, selfHeight, 8, selfWidth * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
+ CGColorSpaceRelease(colorSpace);
+
+ CGContextSetAllowsAntialiasing(context, FALSE);
+ CGContextSetInterpolationQuality(context, kCGInterpolationNone);
+
+ if (top || left) {
+ CGContextClipToRect(context, CGRectMake(0, 0, selfWidth, selfHeight));
+ }
+
+ CGContextDrawImage(context, CGRectMake(-left, -top, selfWidth, selfHeight), self.image);
+
+ uint32_t *pixelData = CGBitmapContextGetData(context);
+
+ _data = (int8_t *)malloc(selfWidth * selfHeight * sizeof(int8_t));
+
+ dispatch_apply(selfHeight, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(size_t idx) {
+ size_t stripe_start = idx * selfWidth;
+ size_t stripe_stop = stripe_start + selfWidth;
+
+ for (size_t i = stripe_start; i < stripe_stop; i++) {
+ uint32_t rgbPixelIn = pixelData[i];
+ uint32_t rgbPixelOut = 0;
+
+ uint32_t red = (rgbPixelIn >> 24) & 0xFF;
+ uint32_t green = (rgbPixelIn >> 16) & 0xFF;
+ uint32_t blue = (rgbPixelIn >> 8) & 0xFF;
+ uint32_t alpha = (rgbPixelIn & 0xFF);
+
+ // ImageIO premultiplies all PNGs, so we have to "un-premultiply them":
+ // http://code.google.com/p/cocos2d-iphone/issues/detail?id=697#c26
+ if (alpha != 0xFF) {
+ red = red > 0 ? ((red << 20) / (alpha << 2)) >> 10 : 0;
+ green = green > 0 ? ((green << 20) / (alpha << 2)) >> 10 : 0;
+ blue = blue > 0 ? ((blue << 20) / (alpha << 2)) >> 10 : 0;
+ }
+
+ if (red == green && green == blue) {
+ rgbPixelOut = red;
+ } else {
+ rgbPixelOut = (306 * red +
+ 601 * green +
+ 117 * blue +
+ (0x200)) >> 10; // 0x200 = 1<<9, half an lsb of the result to force rounding
+ }
+
+ if (rgbPixelOut > 255) {
+ rgbPixelOut = 255;
+ }
+
+ _data[i] = rgbPixelOut;
+ }
+ });
+
+ CGContextRelease(context);
+
+ _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:self.top
+ top:sourceWidth - (self.left + self.width)
+ width:self.height
+ height:self.width];
+
+ CGImageRelease(rotatedImage);
+
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/ZXCapture.h b/Pods/ZXingObjC/ZXingObjC/client/ZXCapture.h
new file mode 100644
index 0000000..d8e529d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/ZXCapture.h
@@ -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
+
+@protocol ZXCaptureDelegate, ZXReader;
+@class ZXDecodeHints;
+
+@interface ZXCapture : NSObject
+
+@property (nonatomic, assign) int camera;
+@property (nonatomic, strong) AVCaptureDevice *captureDevice;
+@property (nonatomic, copy) NSString *captureToFilename;
+@property (nonatomic, weak) id delegate;
+@property (nonatomic, assign) AVCaptureFocusMode focusMode;
+@property (nonatomic, strong) ZXDecodeHints *hints;
+@property (nonatomic, assign) CGImageRef lastScannedImage;
+@property (nonatomic, assign) BOOL invert;
+@property (nonatomic, strong, readonly) CALayer *layer;
+@property (nonatomic, assign) BOOL mirror;
+@property (nonatomic, strong, readonly) AVCaptureVideoDataOutput *output;
+@property (nonatomic, strong) id reader;
+@property (nonatomic, assign) CGFloat rotation;
+@property (nonatomic, assign, readonly) BOOL running;
+@property (nonatomic, assign) CGRect scanRect;
+@property (nonatomic, copy) NSString *sessionPreset;
+@property (nonatomic, assign) BOOL torch;
+@property (nonatomic, assign) CGAffineTransform transform;
+
+- (int)back;
+- (int)front;
+- (BOOL)hasBack;
+- (BOOL)hasFront;
+- (BOOL)hasTorch;
+
+- (CALayer *)binary;
+- (void)setBinary:(BOOL)on_off;
+
+- (CALayer *)luminance;
+- (void)setLuminance:(BOOL)on_off;
+
+- (void)hard_stop;
+- (void)order_skip;
+- (void)start;
+- (void)stop;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/ZXCapture.m b/Pods/ZXingObjC/ZXingObjC/client/ZXCapture.m
new file mode 100644
index 0000000..ec7139c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/ZXCapture.m
@@ -0,0 +1,544 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import
+#import "ZXBinaryBitmap.h"
+#import "ZXCapture.h"
+#import "ZXCaptureDelegate.h"
+#import "ZXCGImageLuminanceSource.h"
+#import "ZXDecodeHints.h"
+#import "ZXHybridBinarizer.h"
+#import "ZXReader.h"
+#import "ZXResult.h"
+
+@interface ZXCapture ()
+
+@property (nonatomic, strong) CALayer *binaryLayer;
+@property (nonatomic, assign) BOOL cameraIsReady;
+@property (nonatomic, assign) int captureDeviceIndex;
+@property (nonatomic, strong) dispatch_queue_t captureQueue;
+@property (nonatomic, assign) BOOL hardStop;
+@property (nonatomic, strong) AVCaptureDeviceInput *input;
+@property (nonatomic, strong) AVCaptureVideoPreviewLayer *layer;
+@property (nonatomic, strong) CALayer *luminanceLayer;
+@property (nonatomic, assign) int orderInSkip;
+@property (nonatomic, assign) int orderOutSkip;
+@property (nonatomic, assign) BOOL onScreen;
+@property (nonatomic, strong) AVCaptureVideoDataOutput *output;
+@property (nonatomic, assign) BOOL running;
+@property (nonatomic, strong) AVCaptureSession *session;
+
+@end
+
+@implementation ZXCapture
+
+- (ZXCapture *)init {
+ if (self = [super init]) {
+ _captureDeviceIndex = -1;
+ _captureQueue = dispatch_queue_create("com.zxing.captureQueue", NULL);
+ _focusMode = AVCaptureFocusModeContinuousAutoFocus;
+ _hardStop = NO;
+ _hints = [ZXDecodeHints hints];
+ _lastScannedImage = NULL;
+ _onScreen = NO;
+ _orderInSkip = 0;
+ _orderOutSkip = 0;
+
+ if (NSClassFromString(@"ZXMultiFormatReader")) {
+ _reader = [NSClassFromString(@"ZXMultiFormatReader") performSelector:@selector(reader)];
+ }
+
+ _rotation = 0.0f;
+ _running = NO;
+ _sessionPreset = AVCaptureSessionPresetMedium;
+ _transform = CGAffineTransformIdentity;
+ _scanRect = CGRectZero;
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_lastScannedImage) {
+ CGImageRelease(_lastScannedImage);
+ }
+
+ if (_session && _session.inputs) {
+ for (AVCaptureInput *input in _session.inputs) {
+ [_session removeInput:input];
+ }
+ }
+
+ if (_session && _session.outputs) {
+ for (AVCaptureOutput *output in _session.outputs) {
+ [_session removeOutput:output];
+ }
+ }
+}
+
+#pragma mark - Property Getters
+
+- (CALayer *)layer {
+ AVCaptureVideoPreviewLayer *layer = (AVCaptureVideoPreviewLayer *)_layer;
+ if (!_layer) {
+ layer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
+ layer.affineTransform = self.transform;
+ layer.delegate = self;
+ layer.videoGravity = AVLayerVideoGravityResizeAspect;
+ layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
+
+ _layer = layer;
+ }
+ return layer;
+}
+
+- (AVCaptureVideoDataOutput *)output {
+ if (!_output) {
+ _output = [[AVCaptureVideoDataOutput alloc] init];
+ [_output setVideoSettings:@{
+ (NSString *)kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]
+ }];
+ [_output setAlwaysDiscardsLateVideoFrames:YES];
+ [_output setSampleBufferDelegate:self queue:_captureQueue];
+
+ [self.session addOutput:_output];
+ }
+
+ return _output;
+}
+
+#pragma mark - Property Setters
+
+- (void)setCamera:(int)camera {
+ if (_camera != camera) {
+ _camera = camera;
+ self.captureDeviceIndex = -1;
+ self.captureDevice = nil;
+ [self replaceInput];
+ }
+}
+
+- (void)setDelegate:(id)delegate {
+ _delegate = delegate;
+
+ if (delegate) {
+ self.hardStop = NO;
+ }
+ [self startStop];
+}
+
+- (void)setFocusMode:(AVCaptureFocusMode)focusMode {
+ if ([self.input.device isFocusModeSupported:focusMode] && self.input.device.focusMode != focusMode) {
+ _focusMode = focusMode;
+
+ [self.input.device lockForConfiguration:nil];
+ self.input.device.focusMode = focusMode;
+ [self.input.device unlockForConfiguration];
+ }
+}
+
+- (void)setLastScannedImage:(CGImageRef)lastScannedImage {
+ if (_lastScannedImage) {
+ CGImageRelease(_lastScannedImage);
+ }
+
+ if (lastScannedImage) {
+ CGImageRetain(lastScannedImage);
+ }
+
+ _lastScannedImage = lastScannedImage;
+}
+
+- (void)setMirror:(BOOL)mirror {
+ if (_mirror != mirror) {
+ _mirror = mirror;
+ if (self.layer) {
+ CGAffineTransform transform = self.transform;
+ transform.a = - transform.a;
+ self.transform = transform;
+ [self.layer setAffineTransform:self.transform];
+ }
+ }
+}
+
+- (void)setTorch:(BOOL)torch {
+ _torch = torch;
+
+ [self.input.device lockForConfiguration:nil];
+ self.input.device.torchMode = self.torch ? AVCaptureTorchModeOn : AVCaptureTorchModeOff;
+ [self.input.device unlockForConfiguration];
+}
+
+- (void)setTransform:(CGAffineTransform)transform {
+ _transform = transform;
+ [self.layer setAffineTransform:transform];
+}
+
+#pragma mark - Back, Front, Torch
+
+- (int)back {
+ return 1;
+}
+
+- (int)front {
+ return 0;
+}
+
+- (BOOL)hasFront {
+ NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
+ return [devices count] > 1;
+}
+
+- (BOOL)hasBack {
+ NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
+ return [devices count] > 0;
+}
+
+- (BOOL)hasTorch {
+ if ([self device]) {
+ return [self device].hasTorch;
+ } else {
+ return NO;
+ }
+}
+
+#pragma mark - Binary
+
+- (CALayer *)binary {
+ return self.binaryLayer;
+}
+
+- (void)setBinary:(BOOL)on {
+ if (on && !self.binaryLayer) {
+ self.binaryLayer = [CALayer layer];
+ } else if (!on && self.binaryLayer) {
+ self.binaryLayer = nil;
+ }
+}
+
+#pragma mark - Luminance
+
+- (CALayer *)luminance {
+ return self.luminanceLayer;
+}
+
+- (void)setLuminance:(BOOL)on {
+ if (on && !self.luminanceLayer) {
+ self.luminanceLayer = [CALayer layer];
+ } else if (!on && self.luminanceLayer) {
+ self.luminanceLayer = nil;
+ }
+}
+
+#pragma mark - Start, Stop
+
+- (void)hard_stop {
+ self.hardStop = YES;
+
+ if (self.running) {
+ [self stop];
+ }
+}
+
+- (void)order_skip {
+ self.orderInSkip = 1;
+ self.orderOutSkip = 1;
+}
+
+- (void)start {
+ if (self.hardStop) {
+ return;
+ }
+
+ if (self.delegate || self.luminanceLayer || self.binaryLayer) {
+ (void)[self output];
+ }
+
+ if (!self.session.running) {
+ static int i = 0;
+ if (++i == -2) {
+ abort();
+ }
+
+ [self.session startRunning];
+ }
+ self.running = YES;
+}
+
+- (void)stop {
+ if (!self.running) {
+ return;
+ }
+
+ if (self.session.running) {
+ [self.session stopRunning];
+ }
+
+ self.running = NO;
+}
+
+#pragma mark - CAAction
+
+- (id)actionForLayer:(CALayer *)_layer forKey:(NSString *)event {
+ [CATransaction setValue:[NSNumber numberWithFloat:0.0f] forKey:kCATransactionAnimationDuration];
+
+ if ([event isEqualToString:kCAOnOrderIn] || [event isEqualToString:kCAOnOrderOut]) {
+ return self;
+ }
+
+ return nil;
+}
+
+- (void)runActionForKey:(NSString *)key object:(id)anObject arguments:(NSDictionary *)dict {
+ if ([key isEqualToString:kCAOnOrderIn]) {
+ if (self.orderInSkip) {
+ self.orderInSkip--;
+ return;
+ }
+
+ self.onScreen = YES;
+ [self startStop];
+ } else if ([key isEqualToString:kCAOnOrderOut]) {
+ if (self.orderOutSkip) {
+ self.orderOutSkip--;
+ return;
+ }
+
+ self.onScreen = NO;
+ [self startStop];
+ }
+}
+
+#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate
+
+- (void)captureOutput:(AVCaptureOutput *)captureOutput
+didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
+ fromConnection:(AVCaptureConnection *)connection {
+ if (!self.running) return;
+
+ @autoreleasepool {
+ if (!self.cameraIsReady) {
+ self.cameraIsReady = YES;
+ if ([self.delegate respondsToSelector:@selector(captureCameraIsReady:)]) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.delegate captureCameraIsReady:self];
+ });
+ }
+ }
+
+ if (!self.captureToFilename && !self.luminanceLayer && !self.binaryLayer && !self.delegate) {
+ return;
+ }
+
+ CVImageBufferRef videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer);
+
+ CGImageRef videoFrameImage = [ZXCGImageLuminanceSource createImageFromBuffer:videoFrame];
+ CGImageRef rotatedImage = [self createRotatedImage:videoFrameImage degrees:self.rotation];
+ CGImageRelease(videoFrameImage);
+
+ // If scanRect is set, crop the current image to include only the desired rect
+ if (!CGRectIsEmpty(self.scanRect)) {
+ CGImageRef croppedImage = CGImageCreateWithImageInRect(rotatedImage, self.scanRect);
+ CFRelease(rotatedImage);
+ rotatedImage = croppedImage;
+ }
+
+ self.lastScannedImage = rotatedImage;
+
+ if (self.captureToFilename) {
+ NSURL *url = [NSURL fileURLWithPath:self.captureToFilename];
+ CGImageDestinationRef dest = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, (__bridge CFStringRef)@"public.png", 1, nil);
+ CGImageDestinationAddImage(dest, rotatedImage, nil);
+ CGImageDestinationFinalize(dest);
+ CFRelease(dest);
+ self.captureToFilename = nil;
+ }
+
+ ZXCGImageLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:rotatedImage];
+ CGImageRelease(rotatedImage);
+
+ if (self.luminanceLayer) {
+ CGImageRef image = source.image;
+ CGImageRetain(image);
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{
+ self.luminanceLayer.contents = (__bridge id)image;
+ CGImageRelease(image);
+ });
+ }
+
+ if (self.binaryLayer || self.delegate) {
+ ZXHybridBinarizer *binarizer = [[ZXHybridBinarizer alloc] initWithSource:self.invert ? [source invert] : source];
+
+ if (self.binaryLayer) {
+ CGImageRef image = [binarizer createImage];
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0), dispatch_get_main_queue(), ^{
+ self.binaryLayer.contents = (__bridge id)image;
+ CGImageRelease(image);
+ });
+ }
+
+ if (self.delegate) {
+ ZXBinaryBitmap *bitmap = [[ZXBinaryBitmap alloc] initWithBinarizer:binarizer];
+
+ NSError *error;
+ ZXResult *result = [self.reader decode:bitmap hints:self.hints error:&error];
+ if (result) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.delegate captureResult:self result:result];
+ });
+ }
+ }
+ }
+ }
+}
+
+#pragma mark - Private
+
+// 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;
+ }
+}
+
+- (AVCaptureDevice *)device {
+ if (self.captureDevice) {
+ return self.captureDevice;
+ }
+
+ AVCaptureDevice *zxd = nil;
+
+ NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
+
+ if ([devices count] > 0) {
+ if (self.captureDeviceIndex == -1) {
+ AVCaptureDevicePosition position = AVCaptureDevicePositionBack;
+ if (self.camera == self.front) {
+ position = AVCaptureDevicePositionFront;
+ }
+
+ for (unsigned int i = 0; i < [devices count]; ++i) {
+ AVCaptureDevice *dev = [devices objectAtIndex:i];
+ if (dev.position == position) {
+ self.captureDeviceIndex = i;
+ zxd = dev;
+ break;
+ }
+ }
+ }
+
+ if (!zxd && self.captureDeviceIndex != -1) {
+ zxd = [devices objectAtIndex:self.captureDeviceIndex];
+ }
+ }
+
+ if (!zxd) {
+ zxd = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
+ }
+
+ self.captureDevice = zxd;
+
+ return zxd;
+}
+
+- (void)replaceInput {
+ [self.session beginConfiguration];
+
+ if (self.session && self.input) {
+ [self.session removeInput:self.input];
+ self.input = nil;
+ }
+
+ AVCaptureDevice *zxd = [self device];
+
+ if (zxd) {
+ self.input = [AVCaptureDeviceInput deviceInputWithDevice:zxd error:nil];
+ self.focusMode = self.focusMode;
+ }
+
+ if (self.input) {
+ self.session.sessionPreset = self.sessionPreset;
+ [self.session addInput:self.input];
+ }
+
+ [self.session commitConfiguration];
+}
+
+- (AVCaptureSession *)session {
+ if (!_session) {
+ _session = [[AVCaptureSession alloc] init];
+ [self replaceInput];
+ }
+
+ return _session;
+}
+
+- (void)startStop {
+ if ((!self.running && (self.delegate || self.onScreen)) ||
+ (!self.output &&
+ (self.delegate ||
+ (self.onScreen && (self.luminanceLayer || self.binaryLayer))))) {
+ [self start];
+ }
+
+ if (self.running && !self.delegate && !self.onScreen) {
+ [self stop];
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/ZXCaptureDelegate.h b/Pods/ZXingObjC/ZXingObjC/client/ZXCaptureDelegate.h
new file mode 100644
index 0000000..33a7f48
--- /dev/null
+++ b/Pods/ZXingObjC/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
+
+- (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/Pods/ZXingObjC/ZXingObjC/client/ZXImage.h b/Pods/ZXingObjC/ZXingObjC/client/ZXImage.h
new file mode 100644
index 0000000..03600c2
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/ZXImage.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
+
+@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;
++ (ZXImage *)imageWithMatrix:(ZXBitMatrix *)matrix onColor:(CGColorRef)onColor offColor:(CGColorRef)offColor;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/ZXImage.m b/Pods/ZXingObjC/ZXingObjC/client/ZXImage.m
new file mode 100644
index 0000000..7c09d6b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/ZXImage.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 "ZXImage.h"
+
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+#import
+#endif
+
+@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 {
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
+
+ CGFloat blackComponents[] = {0.0f, 1.0f};
+ CGColorRef black = CGColorCreate(colorSpace, blackComponents);
+ CGFloat whiteComponents[] = {1.0f, 1.0f};
+ CGColorRef white = CGColorCreate(colorSpace, whiteComponents);
+
+ CFRelease(colorSpace);
+
+ ZXImage *result = [self imageWithMatrix:matrix onColor:black offColor:white];
+
+ CGColorRelease(white);
+ CGColorRelease(black);
+
+ return result;
+}
+
++ (ZXImage *)imageWithMatrix:(ZXBitMatrix *)matrix onColor:(CGColorRef)onColor offColor:(CGColorRef)offColor {
+ int8_t onIntensities[4], offIntensities[4];
+
+ [self setColorIntensities:onIntensities color:onColor];
+ [self setColorIntensities:offIntensities color:offColor];
+
+ int width = matrix.width;
+ int height = matrix.height;
+ int8_t *bytes = (int8_t *)malloc(width * height * 4);
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ BOOL bit = [matrix getX:x y:y];
+ for (int i = 0; i < 4; i++) {
+ int8_t intensity = bit ? onIntensities[i] : offIntensities[i];
+ bytes[y * width * 4 + x * 4 + i] = intensity;
+ }
+ }
+ }
+
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef c = CGBitmapContextCreate(bytes, width, height, 8, 4 * width, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);
+ CFRelease(colorSpace);
+ CGImageRef image = CGBitmapContextCreateImage(c);
+ CFRelease(c);
+ free(bytes);
+
+ ZXImage *zxImage = [[ZXImage alloc] initWithCGImageRef:image];
+
+ CFRelease(image);
+ return zxImage;
+}
+
++ (void)setColorIntensities:(int8_t *)intensities color:(CGColorRef)color {
+ memset(intensities, 0, 4);
+
+ size_t numberOfComponents = CGColorGetNumberOfComponents(color);
+ const CGFloat *components = CGColorGetComponents(color);
+
+ if (numberOfComponents == 4) {
+ for (int i = 0; i < 4; i++) {
+ intensities[i] = components[i] * 255;
+ }
+ } else if (numberOfComponents == 2) {
+ for (int i = 0; i < 3; i++) {
+ intensities[i] = components[0] * 255;
+ }
+ intensities[3] = components[1] * 255;
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.h
new file mode 100644
index 0000000..c1d10f7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.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"
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAbstractDoCoMoResultParser.m
new file mode 100644
index 0000000..fc881b4
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookAUResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookAUResultParser.h
new file mode 100644
index 0000000..33700ab
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookAUResultParser.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"
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookAUResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookAUResultParser.m
new file mode 100644
index 0000000..4c9f7d8
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.h
new file mode 100644
index 0000000..daabf68
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.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 "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/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.m
new file mode 100644
index 0000000..7357473
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookDoCoMoResultParser.m
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 (![[self class] isStringOfDigits:birthday length:8]) {
+ birthday = nil;
+ }
+ NSArray *urls = [[self class] matchDoCoMoPrefixedField:@"URL:" rawText:rawText trim:YES];
+
+ // Although ORG may not be strictly legal in MECARD, it does exist in VCARD and we might as well
+ // honor it when found in the wild.
+ 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) {
+ // Format may be last,first; switch it around
+ return [NSString stringWithFormat:@"%@ %@", [name substringFromIndex:comma + 1], [name substringToIndex:comma]];
+ }
+ return name;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookParsedResult.h
new file mode 100644
index 0000000..b05748f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookParsedResult.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+/**
+ * In Japanese, the name is written in kanji, which can have multiple readings. Therefore a hint
+ * is often provided, called furigana, which spells the name phonetically.
+ *
+ * @return The pronunciation of the names property, often in hiragana or katakana.
+ */
+@property (nonatomic, readonly, copy) NSString *pronunciation;
+
+@property (nonatomic, readonly, strong) NSArray *phoneNumbers;
+
+/**
+ * @return optional descriptions of the type of each phone number. It could be like "HOME", but,
+ * there is no guaranteed or standard format.
+ */
+@property (nonatomic, readonly, strong) NSArray *phoneTypes;
+
+@property (nonatomic, readonly, strong) NSArray *emails;
+
+/**
+ * @return optional descriptions of the type of each e-mail. It could be like "WORK", but,
+ * there is no guaranteed or standard format.
+ */
+@property (nonatomic, readonly, strong) NSArray *emailTypes;
+
+@property (nonatomic, readonly, copy) NSString *instantMessenger;
+@property (nonatomic, readonly, copy) NSString *note;
+@property (nonatomic, readonly, strong) NSArray *addresses;
+
+/**
+ * @return optional descriptions of the type of each e-mail. It could be like "WORK", but,
+ * there is no guaranteed or standard format.
+ */
+@property (nonatomic, readonly, strong) NSArray *addressTypes;
+
+@property (nonatomic, readonly, copy) NSString *title;
+@property (nonatomic, readonly, copy) NSString *org;
+@property (nonatomic, readonly, strong) NSArray *urls;
+
+/**
+ * @return birthday formatted as yyyyMMdd (e.g. 19780917)
+ */
+@property (nonatomic, readonly, copy) NSString *birthday;
+
+/**
+ * @return a location as a latitude/longitude pair
+ */
+@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/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXAddressBookParsedResult.m
new file mode 100644
index 0000000..13a5e24
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXBizcardResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXBizcardResultParser.h
new file mode 100644
index 0000000..00eae58
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXBizcardResultParser.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 "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/Pods/ZXingObjC/ZXingObjC/client/result/ZXBizcardResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXBizcardResultParser.m
new file mode 100644
index 0000000..f6a297c
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.h
new file mode 100644
index 0000000..bb9ca2d
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXBookmarkDoCoMoResultParser.m
new file mode 100644
index 0000000..50f50a5
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXCalendarParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXCalendarParsedResult.h
new file mode 100644
index 0000000..c9f665e
--- /dev/null
+++ b/Pods/ZXingObjC/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, copy, readonly) NSString *summary;
+@property (nonatomic, strong, readonly) NSDate *start;
+@property (nonatomic, assign, readonly) BOOL startAllDay;
+@property (nonatomic, strong, readonly) NSDate *end;
+@property (nonatomic, assign, readonly) BOOL endAllDay;
+@property (nonatomic, copy, readonly) NSString *location;
+@property (nonatomic, copy, readonly) NSString *organizer;
+@property (nonatomic, strong, readonly) NSArray *attendees;
+@property (nonatomic, copy, readonly) NSString *resultDescription;
+@property (nonatomic, assign, readonly) double latitude;
+@property (nonatomic, assign, 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXCalendarParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXCalendarParsedResult.m
new file mode 100644
index 0000000..d439c3a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXCalendarParsedResult.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 "ZXCalendarParsedResult.h"
+
+static NSRegularExpression *ZX_DATE_TIME = nil;
+static NSRegularExpression *ZX_RFC2445_DURATION = nil;
+
+const long ZX_RFC2445_DURATION_FIELD_UNITS[] = {
+ 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 {
+ if ([self class] != [ZXCalendarParsedResult class]) return;
+
+ ZX_DATE_TIME = [[NSRegularExpression alloc] initWithPattern:@"[0-9]{8}(T[0-9]{6}Z?)?"
+ options:0
+ error:nil];
+
+ ZX_RFC2445_DURATION = [[NSRegularExpression alloc] initWithPattern:@"P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?"
+ options:NSRegularExpressionCaseInsensitive
+ error:nil];
+}
+
+- (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;
+ _resultDescription = 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.description 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 = [ZX_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 [[self buildDateFormat] 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 [[self buildDateTimeFormat] dateFromString:[when substringToIndex:15]];
+ } else {
+ return [[self buildDateTimeFormat] 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 = [ZX_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 < sizeof(ZX_RFC2445_DURATION_FIELD_UNITS) / sizeof(long); i++) {
+ if ([match rangeAtIndex:i + 1].location != NSNotFound) {
+ NSString *fieldValue = [durationString substringWithRange:[match rangeAtIndex:i + 1]];
+ if (fieldValue != nil) {
+ durationMS += ZX_RFC2445_DURATION_FIELD_UNITS[i] * [fieldValue intValue];
+ }
+ }
+ }
+ return durationMS;
+}
+
+- (NSDateFormatter *)buildDateFormat {
+ NSDateFormatter *format = [[NSDateFormatter alloc] init];
+ format.dateFormat = @"yyyyMMdd";
+ format.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
+ return format;
+}
+
+- (NSDateFormatter *)buildDateTimeFormat {
+ NSDateFormatter *format = [[NSDateFormatter alloc] init];
+ format.dateFormat = @"yyyyMMdd'T'HHmmss";
+ return format;
+}
+
+- (NSString *)description {
+ return self.resultDescription;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressParsedResult.h
new file mode 100644
index 0000000..0dd30ff
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressParsedResult.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.
+ */
+
+#import "ZXParsedResult.h"
+
+@interface ZXEmailAddressParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSArray *tos;
+@property (nonatomic, copy, readonly) NSArray *ccs;
+@property (nonatomic, copy, readonly) NSArray *bccs;
+@property (nonatomic, copy, readonly) NSString *subject;
+@property (nonatomic, copy, readonly) NSString *body;
+
+/**
+ * @return first elements of tos or nil if none
+ * @deprecated use tos
+ */
+@property (nonatomic, copy, readonly) NSString *emailAddress DEPRECATED_ATTRIBUTE;
+
+/**
+ * @return "mailto:"
+ * @deprecated without replacement
+ */
+@property (nonatomic, copy, readonly) NSString *mailtoURI DEPRECATED_ATTRIBUTE;
+
+- (id)initWithTo:(NSString *)to;
+- (id)initWithTos:(NSArray *)tos
+ ccs:(NSArray *)ccs
+ bccs:(NSArray *)bccs
+ subject:(NSString *)subject
+ body:(NSString *)body;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressParsedResult.m
new file mode 100644
index 0000000..f56f215
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressParsedResult.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 "ZXParsedResultType.h"
+
+@implementation ZXEmailAddressParsedResult
+
+- (id)initWithTo:(NSString *)to {
+ return [self initWithTos:@[to] ccs:nil bccs:nil subject:nil body:nil];
+}
+
+- (id)initWithTos:(NSArray *)tos
+ ccs:(NSArray *)ccs
+ bccs:(NSArray *)bccs
+ subject:(NSString *)subject
+ body:(NSString *)body {
+ if (self = [super initWithType:kParsedResultTypeEmailAddress]) {
+ _tos = tos;
+ _ccs = ccs;
+ _bccs = bccs;
+ _subject = subject;
+ _body = body;
+ }
+
+ return self;
+}
+
+- (NSString *)emailAddress {
+ return !self.tos || self.tos.count == 0 ? nil : self.tos[0];
+}
+
+- (NSString *)mailtoURI {
+ return @"mailto:";
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString stringWithCapacity:30];
+ [ZXParsedResult maybeAppendArray:self.tos result:result];
+ [ZXParsedResult maybeAppendArray:self.ccs result:result];
+ [ZXParsedResult maybeAppendArray:self.bccs result:result];
+ [ZXParsedResult maybeAppend:self.subject result:result];
+ [ZXParsedResult maybeAppend:self.body result:result];
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressResultParser.h
new file mode 100644
index 0000000..2e7e765
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressResultParser.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"
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressResultParser.m
new file mode 100644
index 0000000..9bfb324
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailAddressResultParser.m
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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"
+
+static NSCharacterSet *ZX_EMAIL_ADDRESS_RESULT_COMMA = nil;
+
+@implementation ZXEmailAddressResultParser
+
++ (void)initialize {
+ if ([self class] != [ZXEmailAddressResultParser class]) return;
+
+ ZX_EMAIL_ADDRESS_RESULT_COMMA = [NSCharacterSet characterSetWithCharactersInString:@","];
+}
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if ([rawText hasPrefix:@"mailto:"] || [rawText hasPrefix:@"MAILTO:"]) {
+ // If it starts with mailto:, assume it is definitely trying to be an email address
+ NSString *hostEmail = [rawText substringFromIndex:7];
+ NSUInteger queryStart = [hostEmail rangeOfString:@"?"].location;
+ if (queryStart != NSNotFound) {
+ hostEmail = [hostEmail substringToIndex:queryStart];
+ }
+ hostEmail = [[self class] urlDecode:hostEmail];
+ NSArray *tos;
+ if (hostEmail.length > 0) {
+ tos = [hostEmail componentsSeparatedByCharactersInSet:ZX_EMAIL_ADDRESS_RESULT_COMMA];
+ }
+ NSMutableDictionary *nameValues = [self parseNameValuePairs:rawText];
+ NSArray *ccs;
+ NSArray *bccs;
+ NSString *subject = nil;
+ NSString *body = nil;
+ if (nameValues != nil) {
+ if (!tos) {
+ NSString *tosString = nameValues[@"to"];
+ if (tosString) {
+ tos = [tosString componentsSeparatedByCharactersInSet:ZX_EMAIL_ADDRESS_RESULT_COMMA];
+ }
+ }
+ NSString *ccString = nameValues[@"cc"];
+ if (ccString) {
+ ccs = [ccString componentsSeparatedByCharactersInSet:ZX_EMAIL_ADDRESS_RESULT_COMMA];
+ }
+ NSString *bccString = nameValues[@"bcc"];
+ if (bccString) {
+ bccs = [bccString componentsSeparatedByCharactersInSet:ZX_EMAIL_ADDRESS_RESULT_COMMA];
+ }
+ subject = nameValues[@"subject"];
+ body = nameValues[@"body"];
+ }
+ return [[ZXEmailAddressParsedResult alloc] initWithTos:tos ccs:ccs bccs:bccs subject:subject body:body];
+ } else {
+ if (![ZXEmailDoCoMoResultParser isBasicallyValidEmailAddress:rawText]) {
+ return nil;
+ }
+ return [[ZXEmailAddressParsedResult alloc] initWithTo:rawText];
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.h
new file mode 100644
index 0000000..631be8e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.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 "ZXAbstractDoCoMoResultParser.h"
+
+/**
+ * Implements the "MATMSG" email message entry format.
+ *
+ * Supported keys: TO, SUB, BODY
+ */
+@interface ZXEmailDoCoMoResultParser : ZXAbstractDoCoMoResultParser
+
+/**
+ * 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;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.m
new file mode 100644
index 0000000..c8ca5d3
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXEmailDoCoMoResultParser.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 "ZXEmailAddressParsedResult.h"
+#import "ZXEmailDoCoMoResultParser.h"
+#import "ZXResult.h"
+
+static NSRegularExpression *ZX_ATEXT_ALPHANUMERIC = nil;
+
+@implementation ZXEmailDoCoMoResultParser
+
++ (void)initialize {
+ if ([self class] != [ZXEmailDoCoMoResultParser class]) return;
+
+ ZX_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 *tos = [[self class] matchDoCoMoPrefixedField:@"TO:" rawText:rawText trim:YES];
+ if (tos == nil) {
+ return nil;
+ }
+ for (NSString *to in tos) {
+ 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 alloc] initWithTos:tos ccs:nil bccs:nil subject:subject body:body];
+}
+
++ (BOOL)isBasicallyValidEmailAddress:(NSString *)email {
+ return email != nil && [ZX_ATEXT_ALPHANUMERIC numberOfMatchesInString:email options:0 range:NSMakeRange(0, email.length)] > 0 && [email rangeOfString:@"@"].location != NSNotFound;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductParsedResult.h
new file mode 100644
index 0000000..3341d6d
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductParsedResult.m
new file mode 100644
index 0000000..f217dc8
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductResultParser.h
new file mode 100644
index 0000000..195c82d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductResultParser.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 "ZXResultParser.h"
+
+/**
+ * Parses strings of digits that represent a RSS Extended code.
+ */
+@interface ZXExpandedProductResultParser : ZXResultParser
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductResultParser.m
new file mode 100644
index 0000000..4b76560
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXExpandedProductResultParser.m
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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) {
+ // ExtendedProductParsedResult NOT created. Not a RSS Expanded barcode
+ return nil;
+ }
+ NSString *rawText = [ZXResultParser massagedText:result];
+
+ 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) {
+ // The value must have more of 3 symbols (3 for currency and
+ // 1 at least for the price)
+ // ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern
+ return nil;
+ }
+ price = [value substringFromIndex:3];
+ priceCurrency = [value substringToIndex:3];
+ priceIncrement = [ai substringFromIndex:3];
+ } else {
+ // No match with common AIs
+ 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];
+ // First character must be a open parenthesis.If not, ERROR
+ 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 == '(') {
+ // We look for a new AI. If it doesn't exist (ERROR), we coninue
+ // with the iteration
+ if ([self findAIvalue:index rawText:rawTextAux] == nil) {
+ [buf appendString:@"("];
+ } else {
+ break;
+ }
+ } else {
+ [buf appendFormat:@"%C", c];
+ }
+ }
+
+ return buf;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoParsedResult.h
new file mode 100644
index 0000000..3f4c354
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoParsedResult.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 "ZXParsedResult.h"
+
+@interface ZXGeoParsedResult : ZXParsedResult
+
+/**
+ * @return latitude in degrees
+ */
+@property (nonatomic, assign, readonly) double latitude;
+
+/**
+ * @return longitude in degrees
+ */
+@property (nonatomic, assign, readonly) double longitude;
+
+/**
+ * @return altitude in meters. If not specified, in the geo URI, returns 0.0
+ */
+@property (nonatomic, assign, readonly) double altitude;
+
+/**
+ * @return query string associated with geo URI or null if none exists
+ */
+@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/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoParsedResult.m
new file mode 100644
index 0000000..d2ec38b
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoResultParser.h
new file mode 100644
index 0000000..9b16e3d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoResultParser.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"
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoResultParser.m
new file mode 100644
index 0000000..732a63d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXGeoResultParser.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 "ZXGeoParsedResult.h"
+#import "ZXGeoResultParser.h"
+
+static NSRegularExpression *ZX_GEO_URL_PATTERN = nil;
+
+@implementation ZXGeoResultParser
+
++ (void)initialize {
+ if ([self class] != [ZXGeoResultParser class]) return;
+
+ ZX_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 = [ZX_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/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNParsedResult.h
new file mode 100644
index 0000000..76adecb
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNParsedResult.m
new file mode 100644
index 0000000..22f2aab
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNResultParser.h
new file mode 100644
index 0000000..d364e1e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNResultParser.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 "ZXResultParser.h"
+
+/**
+ * Parses strings of digits that represent a ISBN.
+ */
+@interface ZXISBNResultParser : ZXResultParser
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNResultParser.m
new file mode 100644
index 0000000..696d70d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXISBNResultParser.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 "ZXISBNParsedResult.h"
+#import "ZXISBNResultParser.h"
+
+@implementation ZXISBNResultParser
+
+/**
+ * See ISBN-13 For Dummies
+ */
+- (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/Pods/ZXingObjC/ZXingObjC/client/result/ZXParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXParsedResult.h
new file mode 100644
index 0000000..50691cf
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXParsedResult.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 "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, assign, 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXParsedResult.m
new file mode 100644
index 0000000..5a363a1
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXParsedResult.m
@@ -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.
+ */
+
+#import "ZXParsedResult.h"
+
+@implementation ZXParsedResult
+
+- (id)initWithType:(ZXParsedResultType)type {
+ if (self = [super init]) {
+ _type = type;
+ }
+
+ return self;
+}
+
++ (id)parsedResultWithType:(ZXParsedResultType)type {
+ return [[ZXParsedResult 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) {
+ // Don't add a newline before the first value
+ 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXParsedResultType.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXParsedResultType.h
new file mode 100644
index 0000000..cdb375c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXParsedResultType.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.
+ */
+
+/**
+ * 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,
+ kParsedResultTypeVIN
+} ZXParsedResultType;
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductParsedResult.h
new file mode 100644
index 0000000..b2039c0
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductParsedResult.m
new file mode 100644
index 0000000..5fa5371
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductResultParser.h
new file mode 100644
index 0000000..4954a40
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductResultParser.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 "ZXResultParser.h"
+
+/**
+ * Parses strings of digits that represent a UPC code.
+ */
+@interface ZXProductResultParser : ZXResultParser
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductResultParser.m
new file mode 100644
index 0000000..a20446d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXProductResultParser.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 "ZXBarcodeFormat.h"
+#import "ZXProductParsedResult.h"
+#import "ZXProductResultParser.h"
+#import "ZXUPCEReader.h"
+
+@implementation ZXProductResultParser
+
+// Treat all UPC and EAN variants as UPCs, in the sense that they are all product barcodes.
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ ZXBarcodeFormat format = [result barcodeFormat];
+ if (!(format == kBarcodeFormatUPCA || format == kBarcodeFormatUPCE || format == kBarcodeFormatEan8 || format == kBarcodeFormatEan13)) {
+ return nil;
+ }
+ NSString *rawText = [ZXResultParser massagedText:result];
+ if (![[self class] isStringOfDigits:rawText length:(unsigned int)[rawText length]]) {
+ return nil;
+ }
+ // Not actually checking the checksum again here
+
+ NSString *normalizedProductID;
+ if (format == kBarcodeFormatUPCE && [rawText length] == 8) {
+ normalizedProductID = [ZXUPCEReader convertUPCEtoUPCA:rawText];
+ } else {
+ normalizedProductID = rawText;
+ }
+ return [ZXProductParsedResult productParsedResultWithProductID:rawText normalizedProductID:normalizedProductID];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXResultParser.h
new file mode 100644
index 0000000..688a438
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXResultParser.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 ZXParsedResult, ZXResult;
+
+/**
+ * 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 ZXResultParser : NSObject
+
+/**
+ * Attempts to parse the raw ZXResult's contents as a particular type
+ * of information (email, URL, etc.) and return a ZXParsedResult encapsulating
+ * the result of parsing.
+ */
+- (ZXParsedResult *)parse:(ZXResult *)result;
+
++ (NSString *)massagedText:(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:(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/Pods/ZXingObjC/ZXingObjC/client/result/ZXResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXResultParser.m
new file mode 100644
index 0000000..8981f7e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXResultParser.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 "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 "ZXVINResultParser.h"
+#import "ZXWifiParsedResult.h"
+#import "ZXWifiResultParser.h"
+
+static NSArray *ZX_PARSERS = nil;
+static NSRegularExpression *ZX_DIGITS = nil;
+static NSString *ZX_AMPERSAND = @"&";
+static NSString *ZX_EQUALS = @"=";
+static unichar ZX_BYTE_ORDER_MARK = L'\ufeff';
+
+@implementation ZXResultParser
+
++ (void)initialize {
+ if ([self class] != [ZXResultParser class]) return;
+
+ ZX_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],
+ [[ZXVINResultParser alloc] init]];
+ ZX_DIGITS = [[NSRegularExpression alloc] initWithPattern:@"^\\d+$" options:0 error:nil];
+}
+
+- (ZXParsedResult *)parse:(ZXResult *)result {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
++ (NSString *)massagedText:(ZXResult *)result {
+ NSString *text = result.text;
+ if (text.length > 0 && [text characterAtIndex:0] == ZX_BYTE_ORDER_MARK) {
+ text = [text substringFromIndex:1];
+ }
+ return text;
+}
+
++ (ZXParsedResult *)parseResult:(ZXResult *)theResult {
+ for (ZXResultParser *parser in ZX_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 > 0 && length == value.length && [ZX_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:(int)length {
+ if (value == nil || length <= 0) {
+ return NO;
+ }
+ int max = offset + length;
+ return value.length >= max && [ZX_DIGITS 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:ZX_AMPERSAND]) {
+ [self appendKeyValue:keyValue result:result];
+ }
+ return result;
+}
+
+- (void)appendKeyValue:(NSString *)keyValue result:(NSMutableDictionary *)result {
+ NSRange equalsRange = [keyValue rangeOfString:ZX_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]; // Skip past this prefix we found to start
+ NSUInteger start = i; // Found the start of a match here
+ BOOL more = YES;
+ while (more) {
+ i = [rawText rangeOfString:[NSString stringWithFormat:@"%C", endChar] options:NSLiteralSearch range:NSMakeRange(i, [rawText length] - i)].location;
+ if (i == NSNotFound) {
+ // No terminating end character? uh, done. Set i such that loop terminates and break
+ i = [rawText length];
+ more = NO;
+ } else if ([self countPrecedingBackslashes:rawText pos:i] % 2 != 0) {
+ // semicolon was escaped (odd count of preceding backslashes) so continue
+ i++;
+ } else {
+ // found a match
+ if (matches == nil) {
+ matches = [NSMutableArray arrayWithCapacity:3]; // lazy init
+ }
+ 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;
+}
+
++ (int)countPrecedingBackslashes:(NSString *)s pos:(NSInteger)pos {
+ int count = 0;
+ for (NSInteger i = pos - 1; i >= 0; i--) {
+ if ([s characterAtIndex:i] == '\\') {
+ count++;
+ } else {
+ break;
+ }
+ }
+ return count;
+}
+
++ (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/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSMMSResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSMMSResultParser.h
new file mode 100644
index 0000000..be2ec7f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSMMSResultParser.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 "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/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSMMSResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSMMSResultParser.m
new file mode 100644
index 0000000..6510b50
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSMMSResultParser.m
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+ }
+
+ // Check up front if this is a URI syntax string with query arguments
+ 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;
+ }
+
+ // Drop sms, query portion
+ NSUInteger queryStart = [rawText rangeOfString:@"?" options:NSLiteralSearch range:NSMakeRange(4, [rawText length] - 4)].location;
+ NSString *smsURIWithoutQuery;
+ // If it's not query syntax, the question mark is part of the subject or message
+ 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSParsedResult.h
new file mode 100644
index 0000000..0f594ff
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSParsedResult.m
new file mode 100644
index 0000000..6d4510e
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.h
new file mode 100644
index 0000000..2408e67
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.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 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.m
new file mode 100644
index 0000000..832c931
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMSTOMMSTOResultParser.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 "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;
+ }
+ // Thanks to dominik.wild for suggesting this enhancement to support
+ // smsto:number:body URIs
+ 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMTPResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMTPResultParser.h
new file mode 100644
index 0000000..9897c72
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMTPResultParser.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 an "smtp:" URI result, whose format is not standardized but appears to be like:
+ * smtp[:subject[:body]].
+ */
+@interface ZXSMTPResultParser : ZXResultParser
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMTPResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMTPResultParser.m
new file mode 100644
index 0000000..f6b593b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXSMTPResultParser.m
@@ -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.
+ */
+
+#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];
+ }
+ }
+ return [[ZXEmailAddressParsedResult alloc] initWithTos:@[emailAddress] ccs:nil bccs:nil subject:subject body:body];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelParsedResult.h
new file mode 100644
index 0000000..7c5d2d1
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelParsedResult.m
new file mode 100644
index 0000000..aed1b28
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelResultParser.h
new file mode 100644
index 0000000..39c1e0a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelResultParser.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 "ZXResultParser.h"
+
+/**
+ * Parses a "tel:" URI result, which specifies a phone number.
+ */
+@interface ZXTelResultParser : ZXResultParser
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelResultParser.m
new file mode 100644
index 0000000..529a934
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXTelResultParser.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 "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;
+ }
+ // Normalize "TEL:" to "tel:"
+ NSString *telURI = [rawText hasPrefix:@"TEL:"] ? [@"tel:" stringByAppendingString:[rawText substringFromIndex:4]] : rawText;
+ // Drop tel, query portion
+ 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXTextParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXTextParsedResult.h
new file mode 100644
index 0000000..deb211f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXTextParsedResult.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"
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXTextParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXTextParsedResult.m
new file mode 100644
index 0000000..059fae0
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIParsedResult.h
new file mode 100644
index 0000000..8443e6e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIParsedResult.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 "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;
+
+/**
+ * @return 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;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIParsedResult.m
new file mode 100644
index 0000000..3e66a76
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIParsedResult.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 "ZXResultParser.h"
+#import "ZXURIParsedResult.h"
+
+static NSRegularExpression *ZX_USER_IN_HOST = nil;
+
+@implementation ZXURIParsedResult
+
++ (void)initialize {
+ if ([self class] != [ZXURIParsedResult class]) return;
+
+ ZX_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];
+}
+
+- (BOOL)possiblyMaliciousURI {
+ return [ZX_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 *)uri protocolEnd:(int)protocolEnd {
+ int start = protocolEnd + 1;
+ NSUInteger nextSlash = [uri rangeOfString:@"/" options:0 range:NSMakeRange(start, [uri length] - start)].location;
+ if (nextSlash == NSNotFound) {
+ nextSlash = [uri length];
+ }
+ return [ZXResultParser isSubstringOfDigits:uri offset:start length:(int)nextSlash - start];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIResultParser.h
new file mode 100644
index 0000000..6b17f8a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIResultParser.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"
+
+/**
+ * Tries to parse results that are a URI of some kind.
+ */
+@interface ZXURIResultParser : ZXResultParser
+
++ (BOOL)isBasicallyValidURI:(NSString *)uri;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIResultParser.m
new file mode 100644
index 0000000..b1b4403
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURIResultParser.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 "ZXURIResultParser.h"
+#import "ZXResult.h"
+#import "ZXURIParsedResult.h"
+
+static NSRegularExpression *ZX_URL_WITH_PROTOCOL_PATTERN = nil;
+static NSRegularExpression *ZX_URL_WITHOUT_PROTOCOL_PATTERN = nil;
+
+@implementation ZXURIResultParser
+
++ (void)initialize {
+ if ([self class] != [ZXURIResultParser class]) return;
+
+ // See http://www.ietf.org/rfc/rfc2396.txt
+ ZX_URL_WITH_PROTOCOL_PATTERN = [[NSRegularExpression alloc] initWithPattern:@"^[a-zA-Z][a-zA-Z0-9+-.]+:"
+ options:0
+ error:nil];
+ ZX_URL_WITHOUT_PROTOCOL_PATTERN = [[NSRegularExpression alloc] initWithPattern:
+ [[@"([a-zA-Z0-9\\-]+\\.)+[a-zA-Z]{2,}" // 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 ([ZX_URL_WITH_PROTOCOL_PATTERN numberOfMatchesInString:uri options:NSMatchingWithoutAnchoringBounds range:NSMakeRange(0, uri.length)] > 0) { // match at start only
+ return YES;
+ }
+ return [ZX_URL_WITHOUT_PROTOCOL_PATTERN numberOfMatchesInString:uri options:NSMatchingWithoutAnchoringBounds range:NSMakeRange(0, uri.length)] > 0;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXURLTOResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURLTOResultParser.h
new file mode 100644
index 0000000..dd1c01a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURLTOResultParser.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"
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXURLTOResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXURLTOResultParser.m
new file mode 100644
index 0000000..b95b884
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXVCardResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVCardResultParser.h
new file mode 100644
index 0000000..c1d946b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVCardResultParser.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 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXVCardResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVCardResultParser.m
new file mode 100644
index 0000000..f82f104
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVCardResultParser.m
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 *ZX_BEGIN_VCARD = nil;
+static NSRegularExpression *ZX_VCARD_LIKE_DATE = nil;
+static NSRegularExpression *ZX_CR_LF_SPACE_TAB = nil;
+static NSRegularExpression *ZX_NEWLINE_ESCAPE = nil;
+static NSRegularExpression *ZX_VCARD_ESCAPES = nil;
+static NSString *ZX_EQUALS = @"=";
+static NSString *ZX_SEMICOLON = @";";
+static NSRegularExpression *ZX_UNESCAPED_SEMICOLONS = nil;
+static NSCharacterSet *ZX_COMMA = nil;
+static NSCharacterSet *ZX_SEMICOLON_OR_COMMA = nil;
+
+@implementation ZXVCardResultParser
+
++ (void)initialize {
+ if ([self class] != [ZXVCardResultParser class]) return;
+
+ ZX_BEGIN_VCARD = [[NSRegularExpression alloc] initWithPattern:@"BEGIN:VCARD" options:NSRegularExpressionCaseInsensitive error:nil];
+ ZX_VCARD_LIKE_DATE = [[NSRegularExpression alloc] initWithPattern:@"\\d{4}-?\\d{2}-?\\d{2}" options:0 error:nil];
+ ZX_CR_LF_SPACE_TAB = [[NSRegularExpression alloc] initWithPattern:@"\r\n[ \t]" options:0 error:nil];
+ ZX_NEWLINE_ESCAPE = [[NSRegularExpression alloc] initWithPattern:@"\\\\[nN]" options:0 error:nil];
+ ZX_VCARD_ESCAPES = [[NSRegularExpression alloc] initWithPattern:@"\\\\([,;\\\\])" options:0 error:nil];
+ ZX_UNESCAPED_SEMICOLONS = [[NSRegularExpression alloc] initWithPattern:@"(? 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:ZX_SEMICOLON]) {
+ if (metadata == nil) {
+ metadata = [NSMutableArray array];
+ }
+ [metadata addObject:metadatum];
+ NSUInteger equals = [metadatum rangeOfString:ZX_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 = [[ZX_UNESCAPED_SEMICOLONS stringByReplacingMatchesInString:element options:0 range:NSMakeRange(0, element.length) withTemplate:@"\n"]
+ stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ }
+ } else {
+ if (parseFieldDivider) {
+ element = [[ZX_UNESCAPED_SEMICOLONS stringByReplacingMatchesInString:element options:0 range:NSMakeRange(0, element.length) withTemplate:@"\n"]
+ stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ }
+ element = [ZX_CR_LF_SPACE_TAB stringByReplacingMatchesInString:element options:0 range:NSMakeRange(0, element.length) withTemplate:@""];
+ element = [ZX_NEWLINE_ESCAPE stringByReplacingMatchesInString:element options:0 range:NSMakeRange(0, element.length) withTemplate:@"\n"];
+ element = [ZX_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))];
+ if (!fragment) {
+ fragment = [[NSString alloc] initWithData:fragmentBuffer encoding:NSUTF8StringEncoding];
+ }
+ }
+ [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 || [ZX_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".
+ *
+ * @param names name values to format, in place
+ */
+- (void)formatNames:(NSMutableArray *)names {
+ if (names != nil) {
+ for (NSMutableArray *list in names) {
+ NSString *name = list[0];
+ NSArray *allComponents = [name componentsSeparatedByString:@";"];
+ NSMutableArray *components = [NSMutableArray array];
+ for (NSString *component in allComponents) {
+ if ([component length] > 0) {
+ [components addObject:component];
+ }
+ }
+
+ 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] && [(NSString *)components[i] length] > 0) {
+ if ([newName length] > 0) {
+ [newName appendString:@" "];
+ }
+ [newName appendString:components[i]];
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXVEventResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVEventResultParser.h
new file mode 100644
index 0000000..bedc558
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVEventResultParser.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"
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXVEventResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVEventResultParser.m
new file mode 100644
index 0000000..f564087
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVEventResultParser.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 "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;
+ if (semicolon == NSNotFound) {
+ return nil;
+ }
+ 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/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINParsedResult.h
new file mode 100644
index 0000000..e312462
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINParsedResult.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXParsedResult.h"
+
+@interface ZXVINParsedResult : ZXParsedResult
+
+@property (nonatomic, copy, readonly) NSString *vin;
+@property (nonatomic, copy, readonly) NSString *worldManufacturerID;
+@property (nonatomic, copy, readonly) NSString *vehicleDescriptorSection;
+@property (nonatomic, copy, readonly) NSString *vehicleIdentifierSection;
+@property (nonatomic, copy, readonly) NSString *countryCode;
+@property (nonatomic, copy, readonly) NSString *vehicleAttributes;
+@property (nonatomic, assign, readonly) int modelYear;
+@property (nonatomic, assign, readonly) unichar plantCode;
+@property (nonatomic, copy, readonly) NSString *sequentialNumber;
+
+- (id)initWithVIN:(NSString *)vin worldManufacturerID:(NSString *)worldManufacturerID
+ vehicleDescriptorSection:(NSString *)vehicleDescriptorSection vehicleIdentifierSection:(NSString *)vehicleIdentifierSection
+ countryCode:(NSString *)countryCode vehicleAttributes:(NSString *)vehicleAttributes modelYear:(int)modelYear
+ plantCode:(unichar)plantCode sequentialNumber:(NSString *)sequentialNumber;
+
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINParsedResult.m
new file mode 100644
index 0000000..1baea36
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINParsedResult.m
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXVINParsedResult.h"
+
+@implementation ZXVINParsedResult
+
+- (id)initWithVIN:(NSString *)vin worldManufacturerID:(NSString *)worldManufacturerID
+vehicleDescriptorSection:(NSString *)vehicleDescriptorSection vehicleIdentifierSection:(NSString *)vehicleIdentifierSection
+ countryCode:(NSString *)countryCode vehicleAttributes:(NSString *)vehicleAttributes modelYear:(int)modelYear
+ plantCode:(unichar)plantCode sequentialNumber:(NSString *)sequentialNumber {
+ if (self = [super initWithType:kParsedResultTypeVIN]) {
+ _vin = vin;
+ _worldManufacturerID = worldManufacturerID;
+ _vehicleDescriptorSection = vehicleDescriptorSection;
+ _vehicleIdentifierSection = vehicleIdentifierSection;
+ _countryCode = countryCode;
+ _vehicleAttributes = vehicleAttributes;
+ _modelYear = modelYear;
+ _plantCode = plantCode;
+ _sequentialNumber = sequentialNumber;
+ }
+
+ return self;
+}
+
+- (NSString *)displayResult {
+ NSMutableString *result = [NSMutableString stringWithCapacity:50];
+ [result appendFormat:@"%@ ", self.worldManufacturerID];
+ [result appendFormat:@"%@ ", self.vehicleDescriptorSection];
+ [result appendFormat:@"%@\n", self.vehicleIdentifierSection];
+ if (self.countryCode) {
+ [result appendFormat:@"%@ ", self.countryCode];
+ }
+ [result appendFormat:@"%d ", self.modelYear];
+ [result appendFormat:@"%C ", self.plantCode];
+ [result appendFormat:@"%@\n", self.sequentialNumber];
+ return [NSString stringWithString:result];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINResultParser.h
new file mode 100644
index 0000000..73f5b3b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINResultParser.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXResultParser.h"
+
+/**
+ * Detects a result that is likely a vehicle identification number.
+ */
+@interface ZXVINResultParser : ZXResultParser
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINResultParser.m
new file mode 100644
index 0000000..6865792
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/client/result/ZXVINResultParser.m
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXVINParsedResult.h"
+#import "ZXVINResultParser.h"
+
+static NSRegularExpression *ZX_IOQ = nil;
+static NSRegularExpression *ZX_AZ09 = nil;
+
+@implementation ZXVINResultParser
+
++ (void)initialize {
+ if ([self class] != [ZXVINResultParser class]) return;
+
+ ZX_IOQ = [[NSRegularExpression alloc] initWithPattern:@"[IOQ]" options:0 error:nil];
+ ZX_AZ09 = [[NSRegularExpression alloc] initWithPattern:@"[A-Z0-9]{17}" options:0 error:nil];
+}
+
+- (ZXVINParsedResult *)parse:(ZXResult *)result {
+ if (result.barcodeFormat != kBarcodeFormatCode39) {
+ return nil;
+ }
+ NSString *rawText = result.text;
+ rawText = [[ZX_IOQ stringByReplacingMatchesInString:rawText options:0 range:NSMakeRange(0, rawText.length) withTemplate:@""] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ if ([ZX_AZ09 matchesInString:rawText options:0 range:NSMakeRange(0, rawText.length)] == 0) {
+ return nil;
+ }
+ if (![self checkChecksum:rawText]) {
+ return nil;
+ }
+
+ int modelYear = [self modelYear:[rawText characterAtIndex:9]];
+ if (modelYear == -1) {
+ return nil;
+ }
+
+ NSString *wmi = [rawText substringToIndex:3];
+ return [[ZXVINParsedResult alloc] initWithVIN:rawText
+ worldManufacturerID:wmi
+ vehicleDescriptorSection:[rawText substringWithRange:NSMakeRange(3, 6)]
+ vehicleIdentifierSection:[rawText substringWithRange:NSMakeRange(9, 8)]
+ countryCode:[self countryCode:wmi]
+ vehicleAttributes:[rawText substringWithRange:NSMakeRange(3, 5)]
+ modelYear:modelYear
+ plantCode:[rawText characterAtIndex:10]
+ sequentialNumber:[rawText substringFromIndex:11]];
+}
+
+- (BOOL)checkChecksum:(NSString *)vin {
+ int sum = 0;
+ for (int i = 0; i < [vin length]; i++) {
+ int vinPositionWeight = [self vinPositionWeight:i + 1];
+ if (vinPositionWeight == -1) {
+ return NO;
+ }
+ int vinCharValue = [self vinCharValue:[vin characterAtIndex:i]];
+ if (vinCharValue == -1) {
+ return NO;
+ }
+ sum += vinPositionWeight * vinCharValue;
+ }
+ unichar checkChar = [vin characterAtIndex:8];
+ if (checkChar == '\0') {
+ return NO;
+ }
+ unichar expectedCheckChar = [self checkChar:sum % 11];
+ return checkChar == expectedCheckChar;
+}
+
+- (int)vinCharValue:(unichar)c {
+ if (c >= 'A' && c <= 'I') {
+ return (c - 'A') + 1;
+ }
+ if (c >= 'J' && c <= 'R') {
+ return (c - 'J') + 1;
+ }
+ if (c >= 'S' && c <= 'Z') {
+ return (c - 'S') + 2;
+ }
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ }
+ return -1;
+}
+
+- (int)vinPositionWeight:(int)position {
+ if (position >= 1 && position <= 7) {
+ return 9 - position;
+ }
+ if (position == 8) {
+ return 10;
+ }
+ if (position == 9) {
+ return 0;
+ }
+ if (position >= 10 && position <= 17) {
+ return 19 - position;
+ }
+ return -1;
+}
+
+- (unichar)checkChar:(int)remainder {
+ if (remainder < 10) {
+ return (unichar) ('0' + remainder);
+ }
+ if (remainder == 10) {
+ return 'X';
+ }
+ return '\0';
+}
+
+- (int)modelYear:(unichar)c {
+ if (c >= 'E' && c <= 'H') {
+ return (c - 'E') + 1984;
+ }
+ if (c >= 'J' && c <= 'N') {
+ return (c - 'J') + 1988;
+ }
+ if (c == 'P') {
+ return 1993;
+ }
+ if (c >= 'R' && c <= 'T') {
+ return (c - 'R') + 1994;
+ }
+ if (c >= 'V' && c <= 'Y') {
+ return (c - 'V') + 1997;
+ }
+ if (c >= '1' && c <= '9') {
+ return (c - '1') + 2001;
+ }
+ if (c >= 'A' && c <= 'D') {
+ return (c - 'A') + 2010;
+ }
+ return -1;
+}
+
+- (NSString *)countryCode:(NSString *)wmi {
+ unichar c1 = [wmi characterAtIndex:0];
+ unichar c2 = [wmi characterAtIndex:1];
+ switch (c1) {
+ case '1':
+ case '4':
+ case '5':
+ return @"US";
+ case '2':
+ return @"CA";
+ case '3':
+ if (c2 >= 'A' && c2 <= 'W') {
+ return @"MX";
+ }
+ break;
+ case '9':
+ if ((c2 >= 'A' && c2 <= 'E') || (c2 >= '3' && c2 <= '9')) {
+ return @"BR";
+ }
+ break;
+ case 'J':
+ if (c2 >= 'A' && c2 <= 'T') {
+ return @"JP";
+ }
+ break;
+ case 'K':
+ if (c2 >= 'L' && c2 <= 'R') {
+ return @"KO";
+ }
+ break;
+ case 'L':
+ return @"CN";
+ case 'M':
+ if (c2 >= 'A' && c2 <= 'E') {
+ return @"IN";
+ }
+ break;
+ case 'S':
+ if (c2 >= 'A' && c2 <= 'M') {
+ return @"UK";
+ }
+ if (c2 >= 'N' && c2 <= 'T') {
+ return @"DE";
+ }
+ break;
+ case 'V':
+ if (c2 >= 'F' && c2 <= 'R') {
+ return @"FR";
+ }
+ if (c2 >= 'S' && c2 <= 'W') {
+ return @"ES";
+ }
+ break;
+ case 'W':
+ return @"DE";
+ case 'X':
+ if (c2 == '0' || (c2 >= '3' && c2 <= '9')) {
+ return @"RU";
+ }
+ break;
+ case 'Z':
+ if (c2 >= 'A' && c2 <= 'R') {
+ return @"IT";
+ }
+ break;
+ }
+ return nil;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/client/result/ZXWifiParsedResult.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXWifiParsedResult.h
new file mode 100644
index 0000000..708a1df
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXWifiParsedResult.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXWifiParsedResult.m
new file mode 100644
index 0000000..cc6e655
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXWifiResultParser.h b/Pods/ZXingObjC/ZXingObjC/client/result/ZXWifiResultParser.h
new file mode 100644
index 0000000..9c85c9a
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/client/result/ZXWifiResultParser.m b/Pods/ZXingObjC/ZXingObjC/client/result/ZXWifiResultParser.m
new file mode 100644
index 0000000..3b70ed2
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/common/ZXBitArray.h b/Pods/ZXingObjC/ZXingObjC/common/ZXBitArray.h
new file mode 100644
index 0000000..0243264
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXBitArray.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 ZXByteArray, ZXIntArray;
+
+/**
+ * A simple, fast array of bits, represented compactly by an array of ints internally.
+ */
+@interface ZXBitArray : NSObject
+
+/**
+ * @return underlying array of ints. The first element holds the first 32 bits, and the least
+ * significant bit is bit 0.
+ */
+@property (nonatomic, assign, readonly) int32_t *bits;
+
+@property (nonatomic, assign, readonly) int size;
+
+- (id)initWithSize:(int)size;
+
+- (int)sizeInBytes;
+
+/**
+ * @param i bit to get
+ * @return true iff bit i is set
+ */
+- (BOOL)get:(int)i;
+
+/**
+ * Sets bit i.
+ *
+ * @param i bit to set
+ */
+- (void)set:(int)i;
+
+/**
+ * Flips bit i.
+ *
+ * @param i bit to set
+ */
+- (void)flip:(int)i;
+
+/**
+ * @param from first bit to check
+ * @return index of first bit that is set, starting from the given index, or size if none are set
+ * at or beyond this given index
+ */
+- (int)nextSet:(int)from;
+
+- (int)nextUnset:(int)from;
+
+/**
+ * Sets a block of 32 bits, starting at bit i.
+ *
+ * @param i first bit to set
+ * @param newBits 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;
+
+/**
+ * Sets a range of bits.
+ *
+ * @param start start of range, inclusive.
+ * @param end end of range, exclusive
+ */
+- (void)setRange:(int)start end:(int)end;
+
+/**
+ * Clears all bits (sets to false).
+ */
+- (void)clear;
+
+/**
+ * Efficient method to check if a range of bits is set, or not set.
+ *
+ * @param start start of range, inclusive.
+ * @param end end of range, exclusive
+ * @param value if true, checks that bits in range are set, otherwise checks that they are not set
+ * @return true iff all bits are set or not set in range, according to value argument
+ * @throws NSInvalidArgumentException if end is less than or equal to start
+ */
+- (BOOL)isRange:(int)start end:(int)end value:(BOOL)value;
+
+- (void)appendBit:(BOOL)bit;
+
+/**
+ * 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;
+
+- (void)appendBitArray:(ZXBitArray *)other;
+
+- (void)xor:(ZXBitArray *)other;
+
+/**
+ *
+ * @param bitOffset first bit to start writing
+ * @param array array to write into. Bytes are written most-significant byte first. This is the opposite
+ * of the internal representation, which is exposed by {@link #getBitArray()}
+ * @param offset position in array to start writing
+ * @param numBytes how many bytes to write
+ */
+- (void)toBytes:(int)bitOffset array:(ZXByteArray *)array offset:(int)offset numBytes:(int)numBytes;
+
+/**
+ * @return underlying array of ints. The first element holds the first 32 bits, and the least
+ * significant bit is bit 0.
+ */
+- (ZXIntArray *)bitArray;
+
+/**
+ * Reverses all bits in the array.
+ */
+- (void)reverse;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXBitArray.m b/Pods/ZXingObjC/ZXingObjC/common/ZXBitArray.m
new file mode 100644
index 0000000..9e415d3
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXBitArray.m
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXByteArray.h"
+#import "ZXIntArray.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 *)calloc(1, sizeof(int32_t));
+ _bitsLength = 1;
+ }
+
+ return self;
+}
+
+// For testing only
+- (id)initWithBits:(ZXIntArray *)bits size:(int)size {
+ if (self = [self initWithSize:size]) {
+ _bits = bits.array;
+ _bits = (int32_t *)malloc(bits.length * sizeof(int32_t));
+ memcpy(_bits, bits.array, bits.length * sizeof(int32_t));
+ _bitsLength = bits.length;
+ }
+
+ return self;
+}
+
+- (id)initWithSize:(int)size {
+ if (self = [super init]) {
+ _size = size;
+ _bitsLength = (size + 31) / 32;
+ _bits = (int32_t *)calloc(_bitsLength, sizeof(int32_t));
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_bits != NULL) {
+ free(_bits);
+ _bits = NULL;
+ }
+}
+
+- (int)sizeInBytes {
+ return (self.size + 7) / 8;
+}
+
+- (void)ensureCapacity:(int)size {
+ if (size > self.bitsLength * 32) {
+ int newBitsLength = (size + 31) / 32;
+ self.bits = realloc(self.bits, newBitsLength * sizeof(int32_t));
+ memset(self.bits + self.bitsLength, 0, (newBitsLength - self.bitsLength) * sizeof(int32_t));
+
+ self.bitsLength = newBitsLength;
+ }
+}
+
+- (BOOL)get:(int)i {
+ return (_bits[i / 32] & (1 << (i & 0x1F))) != 0;
+}
+
+- (void)set:(int)i {
+ _bits[i / 32] |= 1 << (i & 0x1F);
+}
+
+- (void)flip:(int)i {
+ _bits[i / 32] ^= 1 << (i & 0x1F);
+}
+
+- (int)nextSet:(int)from {
+ if (from >= self.size) {
+ return self.size;
+ }
+ int bitsOffset = from / 32;
+ 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 * 32) + [self numberOfTrailingZeros:currentBits];
+ return result > self.size ? self.size : result;
+}
+
+- (int)nextUnset:(int)from {
+ if (from >= self.size) {
+ return self.size;
+ }
+ int bitsOffset = from / 32;
+ 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 * 32) + [self numberOfTrailingZeros:currentBits];
+ return result > self.size ? self.size : result;
+}
+
+- (void)setBulk:(int)i newBits:(int32_t)newBits {
+ _bits[i / 32] = newBits;
+}
+
+- (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 / 32;
+ int lastInt = end / 32;
+ for (int i = firstInt; i <= lastInt; i++) {
+ int firstBit = i > firstInt ? 0 : start & 0x1F;
+ int lastBit = i < lastInt ? 31 : end & 0x1F;
+ int32_t mask;
+ if (lastBit > 31) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Bit-shift operand does not support more than 31 bits" userInfo:nil];
+ }
+ if (firstBit == 0 && lastBit == 31) {
+ mask = -1;
+ } else {
+ mask = 0;
+ for (int j = firstBit; j <= lastBit; j++) {
+ mask |= 1 << j;
+ }
+ }
+ _bits[i] |= mask;
+ }
+}
+
+- (void)clear {
+ memset(self.bits, 0, self.bitsLength * sizeof(int32_t));
+}
+
+- (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; // empty range matches
+ }
+ end--; // will be easier to treat this as the last actually set bit -- inclusive
+ int firstInt = start / 32;
+ int lastInt = end / 32;
+ for (int i = firstInt; i <= lastInt; i++) {
+ int firstBit = i > firstInt ? 0 : start & 0x1F;
+ int lastBit = i < lastInt ? 31 : end & 0x1F;
+ int32_t mask;
+ if (lastBit > 31) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Bit-shift operand does not support more than 31 bits" userInfo:nil];
+ }
+ if (firstBit == 0 && lastBit == 31) {
+ mask = -1;
+ } else {
+ mask = 0;
+ for (int j = firstBit; j <= lastBit; j++) {
+ mask |= 1 << j;
+ }
+ }
+
+ // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
+ // equals the mask, or we're looking for 0s and the masked portion is not all 0s
+ if ((_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 / 32] |= 1 << (self.size & 0x1F);
+ }
+ self.size++;
+}
+
+- (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++) {
+ // The last byte could be incomplete (i.e. not have 8 bits in
+ // it) but there is no problem since 0 XOR 0 == 0.
+ self.bits[i] ^= other.bits[i];
+ }
+}
+
+- (void)toBytes:(int)bitOffset array:(ZXByteArray *)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.array[offset + i] = (int8_t) theByte;
+ }
+}
+
+- (ZXIntArray *)bitArray {
+ ZXIntArray *array = [[ZXIntArray alloc] initWithLength:self.bitsLength];
+ memcpy(array.array, self.bits, array.length * sizeof(int32_t));
+ return array;
+}
+
+- (BOOL)isEqual:(id)o {
+ if (![o isKindOfClass:[ZXBitArray class]]) {
+ return NO;
+ }
+ ZXBitArray *other = (ZXBitArray *)o;
+ return self.size == other.size && memcmp(self.bits, other.bits, self.bitsLength) != 0;
+}
+
+- (NSUInteger)hash {
+ return 31 * self.size;
+}
+
+- (void)reverse {
+ int32_t *newBits = (int32_t *)calloc(self.bitsLength, sizeof(int32_t));
+ int size = self.size;
+
+ // reverse all int's first
+ int len = ((size-1) / 32);
+ int oldBitsLen = len + 1;
+ for (int i = 0; i < oldBitsLen; i++) {
+ long x = (long) self.bits[i];
+ x = ((x >> 1) & 0x55555555L) | ((x & 0x55555555L) << 1);
+ x = ((x >> 2) & 0x33333333L) | ((x & 0x33333333L) << 2);
+ x = ((x >> 4) & 0x0f0f0f0fL) | ((x & 0x0f0f0f0fL) << 4);
+ x = ((x >> 8) & 0x00ff00ffL) | ((x & 0x00ff00ffL) << 8);
+ x = ((x >> 16) & 0x0000ffffL) | ((x & 0x0000ffffL) << 16);
+ newBits[len - i] = (int32_t) x;
+ }
+ // now correct the int's if the bit size isn't a multiple of 32
+ if (size != oldBitsLen * 32) {
+ int leftOffset = oldBitsLen * 32 - size;
+ int mask = 1;
+ for (int i = 0; i < 31 - leftOffset; i++) {
+ mask = (mask << 1) | 1;
+ }
+ int32_t currentInt = (newBits[0] >> leftOffset) & mask;
+ for (int i = 1; i < oldBitsLen; i++) {
+ int32_t nextInt = newBits[i];
+ currentInt |= nextInt << (32 - leftOffset);
+ newBits[i - 1] = currentInt;
+ currentInt = (nextInt >> leftOffset) & mask;
+ }
+ newBits[oldBitsLen - 1] = currentInt;
+ }
+ 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);
+}
+
+- (id)copyWithZone:(NSZone *)zone {
+ ZXBitArray *copy = [[ZXBitArray allocWithZone:zone] initWithSize:self.size];
+ memcpy(copy.bits, self.bits, self.size * sizeof(int32_t));
+ return copy;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXBitMatrix.h b/Pods/ZXingObjC/ZXingObjC/common/ZXBitMatrix.h
new file mode 100644
index 0000000..be65fcf
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXBitMatrix.h
@@ -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.
+ */
+
+@class ZXBitArray, ZXIntArray;
+
+/**
+ * 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.
+ */
+@interface ZXBitMatrix : NSObject
+
+/**
+ * @return The width of the matrix
+ */
+@property (nonatomic, assign, readonly) int width;
+
+/**
+ * @return The height of the matrix
+ */
+@property (nonatomic, assign, readonly) int height;
+
+@property (nonatomic, assign, readonly) int32_t *bits;
+
+/**
+ * @return The row size of the matrix
+ */
+@property (nonatomic, assign, readonly) int rowSize;
+
+// A helper to construct a square matrix.
+- (id)initWithDimension:(int)dimension;
+- (id)initWithWidth:(int)width height:(int)height;
+
++ (ZXBitMatrix *)parse:(NSString *)stringRepresentation
+ setString:(NSString *)setString
+ unsetString:(NSString *)unsetString;
+
+/**
+ * Gets the requested bit, where true means black.
+ *
+ * @param x The horizontal component (i.e. which column)
+ * @param y The vertical component (i.e. which row)
+ * @return value of given bit in matrix
+ */
+- (BOOL)getX:(int)x y:(int)y;
+
+/**
+ * Sets the given bit to true.
+ *
+ * @param x The horizontal component (i.e. which column)
+ * @param y The vertical component (i.e. which row)
+ */
+- (void)setX:(int)x y:(int)y;
+
+- (void)unsetX:(int)x y:(int)y;
+
+/**
+ * Flips the given bit.
+ *
+ * @param x The horizontal component (i.e. which column)
+ * @param y The vertical component (i.e. which row)
+ */
+- (void)flipX:(int)x y:(int)y;
+
+/**
+ * Exclusive-or (XOR): Flip the bit in this ZXBitMatrix if the corresponding
+ * mask bit is set.
+ *
+ * @param mask XOR mask
+ */
+- (void)xor:(ZXBitMatrix *)mask;
+
+/**
+ * Clears all bits (sets to false).
+ */
+- (void)clear;
+
+/**
+ * Sets a square region of the bit matrix to true.
+ *
+ * @param left The horizontal position to begin at (inclusive)
+ * @param top The vertical position to begin at (inclusive)
+ * @param width The width of the region
+ * @param height The height of the region
+ */
+- (void)setRegionAtLeft:(int)left top:(int)top width:(int)width height:(int)height;
+
+/**
+ * A fast method to retrieve one row of data from the matrix as a ZXBitArray.
+ *
+ * @param y The row to retrieve
+ * @param row An optional caller-allocated BitArray, will be allocated if null or too small
+ * @return The resulting BitArray - this reference should always be used even when passing
+ * your own row
+ */
+- (ZXBitArray *)rowAtY:(int)y row:(ZXBitArray *)row;
+
+/**
+ * @param y row to set
+ * @param row ZXBitArray to copy from
+ */
+- (void)setRowAtY:(int)y row:(ZXBitArray *)row;
+
+/**
+ * Modifies this ZXBitMatrix to represent the same but rotated 180 degrees
+ */
+- (void)rotate180;
+
+/**
+ * This is useful in detecting the enclosing rectangle of a 'pure' barcode.
+ *
+ * @return {left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white
+ */
+- (ZXIntArray *)enclosingRectangle;
+
+/**
+ * This is useful in detecting a corner of a 'pure' barcode.
+ *
+ * @return {x,y} coordinate of top-left-most 1 bit, or null if it is all white
+ */
+- (ZXIntArray *)topLeftOnBit;
+
+- (ZXIntArray *)bottomRightOnBit;
+
+- (NSString *)descriptionWithSetString:(NSString *)setString unsetString:(NSString *)unsetString;
+
+/**
+ * @deprecated call descriptionWithSetString:unsetString: only, which uses \n line separator always
+ */
+- (NSString *)descriptionWithSetString:(NSString *)setString unsetString:(NSString *)unsetString
+ lineSeparator:(NSString *)lineSeparator DEPRECATED_ATTRIBUTE;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXBitMatrix.m b/Pods/ZXingObjC/ZXingObjC/common/ZXBitMatrix.m
new file mode 100644
index 0000000..4e03103
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXBitMatrix.m
@@ -0,0 +1,377 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXBoolArray.h"
+#import "ZXIntArray.h"
+
+@interface ZXBitMatrix ()
+
+@property (nonatomic, assign, readonly) int bitsSize;
+
+@end
+
+@implementation ZXBitMatrix
+
+- (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) / 32;
+ _bitsSize = _rowSize * _height;
+ _bits = (int32_t *)malloc(_bitsSize * sizeof(int32_t));
+ [self clear];
+ }
+
+ return self;
+}
+
+- (id)initWithWidth:(int)width height:(int)height rowSize:(int)rowSize bits:(int32_t *)bits {
+ if (self = [super init]) {
+ _width = width;
+ _height = height;
+ _rowSize = rowSize;
+ _bitsSize = _rowSize * _height;
+ _bits = (int32_t *)malloc(_bitsSize * sizeof(int32_t));
+ memcpy(_bits, bits, _bitsSize * sizeof(int32_t));
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_bits != NULL) {
+ free(_bits);
+ _bits = NULL;
+ }
+}
+
++ (ZXBitMatrix *)parse:(NSString *)stringRepresentation
+ setString:(NSString *)setString
+ unsetString:(NSString *)unsetString {
+ if (!stringRepresentation) {
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:@"stringRepresentation is required"
+ userInfo:nil];
+ }
+
+ ZXBoolArray *bits = [[ZXBoolArray alloc] initWithLength:(unsigned int)stringRepresentation.length];
+ int bitsPos = 0;
+ int rowStartPos = 0;
+ int rowLength = -1;
+ int nRows = 0;
+ int pos = 0;
+ while (pos < stringRepresentation.length) {
+ if ([stringRepresentation characterAtIndex:pos] == '\n' ||
+ [stringRepresentation characterAtIndex:pos] == '\r') {
+ if (bitsPos > rowStartPos) {
+ if(rowLength == -1) {
+ rowLength = bitsPos - rowStartPos;
+ } else if (bitsPos - rowStartPos != rowLength) {
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:@"row lengths do not match"
+ userInfo:nil];
+ }
+ rowStartPos = bitsPos;
+ nRows++;
+ }
+ pos++;
+ } else if ([[stringRepresentation substringWithRange:NSMakeRange(pos, setString.length)] isEqualToString:setString]) {
+ pos += setString.length;
+ bits.array[bitsPos] = YES;
+ bitsPos++;
+ } else if ([[stringRepresentation substringWithRange:NSMakeRange(pos, unsetString.length)] isEqualToString:unsetString]) {
+ pos += unsetString.length;
+ bits.array[bitsPos] = NO;
+ bitsPos++;
+ } else {
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:[NSString stringWithFormat:@"illegal character encountered: %@", [stringRepresentation substringFromIndex:pos]]
+ userInfo:nil];
+ }
+ }
+
+ // no EOL at end?
+ if (bitsPos > rowStartPos) {
+ if (rowLength == -1) {
+ rowLength = bitsPos - rowStartPos;
+ } else if (bitsPos - rowStartPos != rowLength) {
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:@"row lengths do not match"
+ userInfo:nil];
+ }
+ nRows++;
+ }
+
+ ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithWidth:rowLength height:nRows];
+ for (int i = 0; i < bitsPos; i++) {
+ if (bits.array[i]) {
+ [matrix setX:i % rowLength y:i / rowLength];
+ }
+ }
+ return matrix;
+}
+
+- (BOOL)getX:(int)x y:(int)y {
+ NSInteger offset = y * self.rowSize + (x / 32);
+ return ((_bits[offset] >> (x & 0x1f)) & 1) != 0;
+}
+
+- (void)setX:(int)x y:(int)y {
+ NSInteger offset = y * self.rowSize + (x / 32);
+ _bits[offset] |= 1 << (x & 0x1f);
+}
+
+- (void)unsetX:(int)x y:(int)y {
+ int offset = y * self.rowSize + (x / 32);
+ _bits[offset] &= ~(1 << (x & 0x1f));
+}
+
+- (void)flipX:(int)x y:(int)y {
+ NSUInteger offset = y * self.rowSize + (x / 32);
+ _bits[offset] ^= 1 << (x & 0x1f);
+}
+
+- (void)xor:(ZXBitMatrix *)mask {
+ if (self.width != mask.width || self.height != mask.height
+ || self.rowSize != mask.rowSize) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"input matrix dimensions do not match"
+ userInfo:nil];
+ }
+ ZXBitArray *rowArray = [[ZXBitArray alloc] initWithSize:self.width];
+ for (int y = 0; y < self.height; y++) {
+ int offset = y * self.rowSize;
+ int32_t *row = [mask rowAtY:y row:rowArray].bits;
+ for (int x = 0; x < self.rowSize; x++) {
+ self.bits[offset + x] ^= row[x];
+ }
+ }
+}
+
+- (void)clear {
+ NSInteger max = self.bitsSize;
+ memset(_bits, 0, max * sizeof(int32_t));
+}
+
+- (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++) {
+ _bits[offset + (x / 32)] |= 1 << (x & 0x1f);
+ }
+ }
+}
+
+- (ZXBitArray *)rowAtY:(int)y row:(ZXBitArray *)row {
+ if (row == nil || [row size] < self.width) {
+ row = [[ZXBitArray alloc] initWithSize:self.width];
+ } else {
+ [row clear];
+ }
+ int offset = y * self.rowSize;
+ for (int x = 0; x < self.rowSize; x++) {
+ [row setBulk:x * 32 newBits:_bits[offset + x]];
+ }
+
+ return row;
+}
+
+- (void)setRowAtY:(int)y row:(ZXBitArray *)row {
+ for (NSUInteger i = 0; i < self.rowSize; i++) {
+ _bits[(y * self.rowSize) + i] = row.bits[i];
+ }
+}
+
+- (void)rotate180 {
+ int width = self.width;
+ int height = self.height;
+ ZXBitArray *topRow = [[ZXBitArray alloc] initWithSize:width];
+ ZXBitArray *bottomRow = [[ZXBitArray alloc] initWithSize:width];
+ for (int i = 0; i < (height+1) / 2; i++) {
+ topRow = [self rowAtY:i row:topRow];
+ bottomRow = [self rowAtY:height - 1 - i row:bottomRow];
+ [topRow reverse];
+ [bottomRow reverse];
+ [self setRowAtY:i row:bottomRow];
+ [self setRowAtY:height - 1 - i row:topRow];
+ }
+}
+
+- (ZXIntArray *)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 = _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 [[ZXIntArray alloc] initWithInts:left, top, width, height, -1];
+}
+
+- (ZXIntArray *)topLeftOnBit {
+ int bitsOffset = 0;
+ while (bitsOffset < self.bitsSize && _bits[bitsOffset] == 0) {
+ bitsOffset++;
+ }
+ if (bitsOffset == self.bitsSize) {
+ return nil;
+ }
+ int y = bitsOffset / self.rowSize;
+ int x = (bitsOffset % self.rowSize) * 32;
+
+ int32_t theBits = _bits[bitsOffset];
+ int32_t bit = 0;
+ while ((theBits << (31 - bit)) == 0) {
+ bit++;
+ }
+ x += bit;
+ return [[ZXIntArray alloc] initWithInts:x, y, -1];
+}
+
+- (ZXIntArray *)bottomRightOnBit {
+ int bitsOffset = self.bitsSize - 1;
+ while (bitsOffset >= 0 && _bits[bitsOffset] == 0) {
+ bitsOffset--;
+ }
+ if (bitsOffset < 0) {
+ return nil;
+ }
+
+ int y = bitsOffset / self.rowSize;
+ int x = (bitsOffset % self.rowSize) * 32;
+
+ int32_t theBits = _bits[bitsOffset];
+ int32_t bit = 31;
+ while ((theBits >> bit) == 0) {
+ bit--;
+ }
+ x += bit;
+
+ return [[ZXIntArray alloc] initWithInts:x, y, -1];
+}
+
+- (BOOL)isEqual:(NSObject *)o {
+ if (!([o isKindOfClass:[ZXBitMatrix class]])) {
+ return NO;
+ }
+ ZXBitMatrix *other = (ZXBitMatrix *)o;
+ for (int i = 0; i < self.bitsSize; i++) {
+ if (_bits[i] != other.bits[i]) {
+ return NO;
+ }
+ }
+ return self.width == other.width && self.height == other.height && self.rowSize == other.rowSize && self.bitsSize == other.bitsSize;
+}
+
+- (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 + _bits[i];
+ }
+ return hash;
+}
+
+- (NSString *)description {
+ return [self descriptionWithSetString:@"X " unsetString:@" "];
+}
+
+- (NSString *)descriptionWithSetString:(NSString *)setString unsetString:(NSString *)unsetString {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ return [self descriptionWithSetString:setString unsetString:unsetString lineSeparator:@"\n"];
+#pragma GCC diagnostic pop
+}
+
+- (NSString *)descriptionWithSetString:(NSString *)setString unsetString:(NSString *)unsetString
+ lineSeparator:(NSString *)lineSeparator {
+ 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] ? setString : unsetString];
+ }
+ [result appendString:lineSeparator];
+ }
+ return result;
+}
+
+- (id)copyWithZone:(NSZone *)zone {
+ return [[ZXBitMatrix allocWithZone:zone] initWithWidth:self.width height:self.height rowSize:self.rowSize bits:self.bits];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXBitSource.h b/Pods/ZXingObjC/ZXingObjC/common/ZXBitSource.h
new file mode 100644
index 0000000..6cc0d5e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXBitSource.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 ZXByteArray;
+
+/**
+ * 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
+
+/**
+ * @return index of next bit in current byte which would be read by the next call to {@link #readBits(int)}.
+ */
+@property (nonatomic, assign, readonly) int bitOffset;
+
+/**
+ * @return index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}.
+ */
+@property (nonatomic, assign, readonly) int byteOffset;
+
+/**
+ * @param bytes 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:(ZXByteArray *)bytes;
+
+/**
+ * @param numBits number of bits to read
+ * @return int representing the bits read. The bits will appear as the least-significant
+ * bits of the int
+ * @throws NSInvalidArgumentException if numBits isn't in [1,32] or more than is available
+ */
+- (int)readBits:(int)numBits;
+
+/**
+ * @return number of bits that can be read successfully
+ */
+- (int)available;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXBitSource.m b/Pods/ZXingObjC/ZXingObjC/common/ZXBitSource.m
new file mode 100644
index 0000000..9453f32
--- /dev/null
+++ b/Pods/ZXingObjC/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"
+#import "ZXByteArray.h"
+
+@interface ZXBitSource ()
+
+@property (nonatomic, strong, readonly) ZXByteArray *bytes;
+@property (nonatomic, assign) int byteOffset;
+@property (nonatomic, assign) int bitOffset;
+
+@end
+
+@implementation ZXBitSource
+
+- (id)initWithBytes:(ZXByteArray *)bytes {
+ if (self = [super init]) {
+ _bytes = bytes;
+ }
+
+ 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;
+
+ // First, read remainder from current byte
+ 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.array[self.byteOffset] & mask) >> bitsToNotRead;
+ numBits -= toRead;
+ self.bitOffset += toRead;
+ if (self.bitOffset == 8) {
+ self.bitOffset = 0;
+ self.byteOffset++;
+ }
+ }
+
+ // Next read whole bytes
+ if (numBits > 0) {
+ while (numBits >= 8) {
+ result = (result << 8) | (self.bytes.array[self.byteOffset] & 0xFF);
+ self.byteOffset++;
+ numBits -= 8;
+ }
+
+ // Finally read a partial byte
+ if (numBits > 0) {
+ int bitsToNotRead = 8 - numBits;
+ int mask = (0xFF >> bitsToNotRead) << bitsToNotRead;
+ result = (result << numBits) | ((self.bytes.array[self.byteOffset] & mask) >> bitsToNotRead);
+ self.bitOffset += numBits;
+ }
+ }
+
+ return result;
+}
+
+- (int)available {
+ return 8 * (self.bytes.length - self.byteOffset) - self.bitOffset;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXBoolArray.h b/Pods/ZXingObjC/ZXingObjC/common/ZXBoolArray.h
new file mode 100644
index 0000000..582d3a3
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXBoolArray.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@interface ZXBoolArray : NSObject
+
+@property (nonatomic, assign, readonly) BOOL *array;
+@property (nonatomic, assign, readonly) unsigned int length;
+
+- (id)initWithLength:(unsigned int)length;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXBoolArray.m b/Pods/ZXingObjC/ZXingObjC/common/ZXBoolArray.m
new file mode 100644
index 0000000..9639f87
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXBoolArray.m
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXBoolArray.h"
+
+@implementation ZXBoolArray
+
+- (id)initWithLength:(unsigned int)length {
+ if (self = [super init]) {
+ _array = (BOOL *)calloc(length, sizeof(BOOL));
+ _length = length;
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_array) {
+ free(_array);
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXByteArray.h b/Pods/ZXingObjC/ZXingObjC/common/ZXByteArray.h
new file mode 100644
index 0000000..e837cc6
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXByteArray.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@interface ZXByteArray : NSObject
+
+@property (nonatomic, assign, readonly) int8_t *array;
+@property (nonatomic, assign, readonly) unsigned int length;
+
+- (id)initWithLength:(unsigned int)length;
+- (id)initWithBytes:(int8_t)byte1, ...;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXByteArray.m b/Pods/ZXingObjC/ZXingObjC/common/ZXByteArray.m
new file mode 100644
index 0000000..8c4ca58
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXByteArray.m
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXByteArray.h"
+
+@implementation ZXByteArray
+
+- (id)initWithLength:(unsigned int)length {
+ if (self = [super init]) {
+ if (length > 0) {
+ _array = (int8_t *)calloc(length, sizeof(int8_t));
+ } else {
+ _array = NULL;
+ }
+ _length = length;
+ }
+
+ return self;
+}
+
+- (id)initWithBytes:(int8_t)byte1, ... {
+ va_list args;
+ va_start(args, byte1);
+ unsigned int length = 0;
+ for (int8_t byte = byte1; byte != -1; byte = va_arg(args, int)) {
+ length++;
+ }
+ va_end(args);
+
+ if ((self = [self initWithLength:length]) && (length > 0)) {
+ va_list args;
+ va_start(args, byte1);
+ int i = 0;
+ for (int8_t byte = byte1; byte != -1; byte = va_arg(args, int)) {
+ _array[i++] = byte;
+ }
+ va_end(args);
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_array) {
+ free(_array);
+ }
+}
+
+- (NSString *)description {
+ NSMutableString *s = [NSMutableString stringWithFormat:@"length=%u, array=(", self.length];
+
+ for (int i = 0; i < self.length; i++) {
+ [s appendFormat:@"%d", self.array[i]];
+ if (i < self.length - 1) {
+ [s appendString:@", "];
+ }
+ }
+
+ [s appendString:@")"];
+ return s;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXCharacterSetECI.h b/Pods/ZXingObjC/ZXingObjC/common/ZXCharacterSetECI.h
new file mode 100644
index 0000000..ea855f2
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXCharacterSetECI.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 a Character Set ECI, according to "Extended Channel Interpretations" 5.3.1.1
+ * of ISO 18004.
+ */
+@interface ZXCharacterSetECI : NSObject
+
+@property (nonatomic, assign, readonly) NSStringEncoding encoding;
+@property (nonatomic, assign, readonly) int value;
+
+/**
+ * @param value character set ECI value
+ * @return CharacterSetECI representing ECI of given value, or nil if it is legal but
+ * unsupported
+ */
++ (ZXCharacterSetECI *)characterSetECIByValue:(int)value;
+
+/**
+ * @param name character set ECI encoding name
+ * @return CharacterSetECI representing ECI for character encoding, or nil if it is legal
+ * but unsupported
+ */
++ (ZXCharacterSetECI *)characterSetECIByEncoding:(NSStringEncoding)encoding;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXCharacterSetECI.m b/Pods/ZXingObjC/ZXingObjC/common/ZXCharacterSetECI.m
new file mode 100644
index 0000000..6d2398f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXCharacterSetECI.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 "ZXCharacterSetECI.h"
+#import "ZXErrors.h"
+
+static NSMutableDictionary *VALUE_TO_ECI = nil;
+static NSMutableDictionary *ENCODING_TO_ECI = nil;
+
+@implementation ZXCharacterSetECI
+
++ (void)initialize {
+ if ([self class] != [ZXCharacterSetECI class]) return;
+
+ 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 init]) {
+ _value = 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/Pods/ZXingObjC/ZXingObjC/common/ZXDecoderResult.h b/Pods/ZXingObjC/ZXingObjC/common/ZXDecoderResult.h
new file mode 100644
index 0000000..4d92c3a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXDecoderResult.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.
+ */
+
+@class ZXByteArray;
+
+/**
+ * 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, strong, readonly) ZXByteArray *rawBytes;
+@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;
+@property (nonatomic, assign, readonly) int structuredAppendParity;
+@property (nonatomic, assign, readonly) int structuredAppendSequenceNumber;
+
+- (id)initWithRawBytes:(ZXByteArray *)rawBytes text:(NSString *)text
+ byteSegments:(NSMutableArray *)byteSegments ecLevel:(NSString *)ecLevel;
+
+- (id)initWithRawBytes:(ZXByteArray *)rawBytes text:(NSString *)text
+ byteSegments:(NSMutableArray *)byteSegments ecLevel:(NSString *)ecLevel
+ saSequence:(int)saSequence saParity:(int)saParity;
+
+- (BOOL)hasStructuredAppend;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXDecoderResult.m b/Pods/ZXingObjC/ZXingObjC/common/ZXDecoderResult.m
new file mode 100644
index 0000000..3e60556
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXDecoderResult.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 "ZXDecoderResult.h"
+
+@implementation ZXDecoderResult
+
+- (id)initWithRawBytes:(ZXByteArray *)rawBytes text:(NSString *)text
+ byteSegments:(NSMutableArray *)byteSegments ecLevel:(NSString *)ecLevel {
+ return [self initWithRawBytes:rawBytes text:text byteSegments:byteSegments ecLevel:ecLevel saSequence:-1 saParity:-1];
+}
+
+- (id)initWithRawBytes:(ZXByteArray *)rawBytes text:(NSString *)text
+ byteSegments:(NSMutableArray *)byteSegments ecLevel:(NSString *)ecLevel
+ saSequence:(int)saSequence saParity:(int)saParity {
+ if (self = [super init]) {
+ _rawBytes = rawBytes;
+ _text = text;
+ _byteSegments = byteSegments;
+ _ecLevel = ecLevel;
+ _structuredAppendParity = saParity;
+ _structuredAppendSequenceNumber = saSequence;
+ }
+
+ return self;
+}
+
+- (BOOL)hasStructuredAppend {
+ return self.structuredAppendParity >= 0 && self.structuredAppendSequenceNumber >= 0;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXDefaultGridSampler.h b/Pods/ZXingObjC/ZXingObjC/common/ZXDefaultGridSampler.h
new file mode 100644
index 0000000..b7776cc
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/common/ZXDefaultGridSampler.m b/Pods/ZXingObjC/ZXingObjC/common/ZXDefaultGridSampler.m
new file mode 100644
index 0000000..c4445c5
--- /dev/null
+++ b/Pods/ZXingObjC/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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithWidth:dimensionX height:dimensionY];
+ int pointsLen = 2 * dimensionX;
+ 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 / 2) + 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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ if ([image getX:xx y:yy]) {
+ [bits setX:x / 2 y:y];
+ }
+ }
+ }
+
+ return bits;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXDetectorResult.h b/Pods/ZXingObjC/ZXingObjC/common/ZXDetectorResult.h
new file mode 100644
index 0000000..91428b1
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXDetectorResult.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 ZXBitMatrix;
+
+/**
+ * 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.
+ */
+@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/Pods/ZXingObjC/ZXingObjC/common/ZXDetectorResult.m b/Pods/ZXingObjC/ZXingObjC/common/ZXDetectorResult.m
new file mode 100644
index 0000000..edd9d25
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/common/ZXGlobalHistogramBinarizer.h b/Pods/ZXingObjC/ZXingObjC/common/ZXGlobalHistogramBinarizer.h
new file mode 100644
index 0000000..8166353
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXGlobalHistogramBinarizer.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 "ZXBinarizer.h"
+
+@class ZXBitArray, ZXBitMatrix, ZXLuminanceSource;
+
+/**
+ * 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.
+ */
+@interface ZXGlobalHistogramBinarizer : ZXBinarizer
+
+// Applies simple sharpening to the row data to improve performance of the 1D Readers.
+- (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error;
+
+// Does not sharpen the data, as this call is intended to only be used by 2D Readers.
+- (ZXBinarizer *)createBinarizer:(ZXLuminanceSource *)source;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXGlobalHistogramBinarizer.m b/Pods/ZXingObjC/ZXingObjC/common/ZXGlobalHistogramBinarizer.m
new file mode 100644
index 0000000..4dc07f8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXGlobalHistogramBinarizer.m
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXByteArray.h"
+#import "ZXErrors.h"
+#import "ZXIntArray.h"
+#import "ZXLuminanceSource.h"
+
+const int ZX_LUMINANCE_BITS = 5;
+const int ZX_LUMINANCE_SHIFT = 8 - ZX_LUMINANCE_BITS;
+const int ZX_LUMINANCE_BUCKETS = 1 << ZX_LUMINANCE_BITS;
+
+@interface ZXGlobalHistogramBinarizer ()
+
+@property (nonatomic, strong) ZXByteArray *luminances;
+@property (nonatomic, strong) ZXIntArray *buckets;
+
+@end
+
+@implementation ZXGlobalHistogramBinarizer
+
+- (id)initWithSource:(ZXLuminanceSource *)source {
+ if (self = [super initWithSource:source]) {
+ _luminances = [[ZXByteArray alloc] initWithLength:0];
+ _buckets = [[ZXIntArray alloc] initWithLength:ZX_LUMINANCE_BUCKETS];
+ }
+
+ return self;
+}
+
+- (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];
+ ZXByteArray *localLuminances = [source rowAtY:y row:self.luminances];
+ ZXIntArray *localBuckets = self.buckets;
+ for (int x = 0; x < width; x++) {
+ int pixel = localLuminances.array[x] & 0xff;
+ localBuckets.array[pixel >> ZX_LUMINANCE_SHIFT]++;
+ }
+ int blackPoint = [self estimateBlackPoint:localBuckets];
+ if (blackPoint == -1) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ int left = localLuminances.array[0] & 0xff;
+ int center = localLuminances.array[1] & 0xff;
+ for (int x = 1; x < width - 1; x++) {
+ int right = localLuminances.array[x + 1] & 0xff;
+ // A simple -1 4 -1 box filter with a weight of 2.
+ int luminance = ((center * 4) - left - right) >> 1;
+ if (luminance < blackPoint) {
+ [row set:x];
+ }
+ left = center;
+ center = right;
+ }
+
+ 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];
+
+ // Quickly calculates the histogram by sampling four rows from the image. This proved to be
+ // more robust on the blackbox tests than sampling a diagonal as we used to do.
+ [self initArrays:width];
+
+ // We delay reading the entire image luminance until the black point estimation succeeds.
+ // Although we end up reading four rows twice, it is consistent with our motto of
+ // "fail quickly" which is necessary for continuous scanning.
+ ZXIntArray *localBuckets = self.buckets;
+ for (int y = 1; y < 5; y++) {
+ int row = height * y / 5;
+ ZXByteArray *localLuminances = [source rowAtY:row row:self.luminances];
+ int right = (width * 4) / 5;
+ for (int x = width / 5; x < right; x++) {
+ int pixel = localLuminances.array[x] & 0xff;
+ localBuckets.array[pixel >> ZX_LUMINANCE_SHIFT]++;
+ }
+ }
+ int blackPoint = [self estimateBlackPoint:localBuckets];
+ if (blackPoint == -1) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ ZXByteArray *localLuminances = source.matrix;
+ for (int y = 0; y < height; y++) {
+ int offset = y * width;
+ for (int x = 0; x < width; x++) {
+ int pixel = localLuminances.array[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.length < luminanceSize) {
+ self.luminances = [[ZXByteArray alloc] initWithLength:luminanceSize];
+ }
+
+ for (int x = 0; x < ZX_LUMINANCE_BUCKETS; x++) {
+ self.buckets.array[x] = 0;
+ }
+}
+
+- (int)estimateBlackPoint:(ZXIntArray *)buckets {
+ // Find the tallest peak in the histogram.
+ int numBuckets = buckets.length;
+ int maxBucketCount = 0;
+ int firstPeak = 0;
+ int firstPeakSize = 0;
+ for (int x = 0; x < numBuckets; x++) {
+ if (buckets.array[x] > firstPeakSize) {
+ firstPeak = x;
+ firstPeakSize = buckets.array[x];
+ }
+ if (buckets.array[x] > maxBucketCount) {
+ maxBucketCount = buckets.array[x];
+ }
+ }
+
+ // Find the second-tallest peak which is somewhat far from the tallest peak.
+ int secondPeak = 0;
+ int secondPeakScore = 0;
+ for (int x = 0; x < numBuckets; x++) {
+ int distanceToBiggest = x - firstPeak;
+ // Encourage more distant second peaks by multiplying by square of distance.
+ int score = buckets.array[x] * distanceToBiggest * distanceToBiggest;
+ if (score > secondPeakScore) {
+ secondPeak = x;
+ secondPeakScore = score;
+ }
+ }
+
+ // Make sure firstPeak corresponds to the black peak.
+ if (firstPeak > secondPeak) {
+ int temp = firstPeak;
+ firstPeak = secondPeak;
+ secondPeak = temp;
+ }
+
+ // If there is too little contrast in the image to pick a meaningful black point, throw rather
+ // than waste time trying to decode the image, and risk false positives.
+ if (secondPeak - firstPeak <= numBuckets / 16) {
+ return -1;
+ }
+
+ // Find a valley between them that is low and closer to the white peak.
+ 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 - buckets.array[x]);
+ if (score > bestValleyScore) {
+ bestValley = x;
+ bestValleyScore = score;
+ }
+ }
+
+ return bestValley << ZX_LUMINANCE_SHIFT;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXGridSampler.h b/Pods/ZXingObjC/ZXingObjC/common/ZXGridSampler.h
new file mode 100644
index 0000000..2ccfd1b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXGridSampler.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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, ZXPerspectiveTransform;
+
+/**
+ * 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.
+ */
+@interface ZXGridSampler : NSObject
+
+/**
+ * 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.
+ *
+ * @param newGridSampler The platform-specific object to install.
+ */
++ (void)setGridSampler:(ZXGridSampler *)newGridSampler;
+
+/**
+ * @return the current implementation of GridSampler
+ */
++ (ZXGridSampler *)instance;
+
+/**
+ * Samples an image for a rectangular matrix of bits of the given dimension.
+ * @param image image to sample
+ * @param dimensionX width of ZXBitMatrix to sample from image
+ * @param dimensionY height of ZXBitMatrix to sample from image
+ * @return ZXBitMatrix representing a grid of points sampled from the image within a region
+ * defined by the "from" parameters or nil if image can't be sampled, for example, if the transformation defined
+ * by the given points is invalid or results in sampling outside the image boundaries
+ */
+- (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;
+
+/**
+ *
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.
+ *
+ * @param image image into which the points should map
+ * @param points actual points in x1,y1,...,xn,yn form
+ * @returns NO if an endpoint is lies outside the image boundaries
+ */
++ (BOOL)checkAndNudgePoints:(ZXBitMatrix *)image points:(float *)points pointsLen:(int)pointsLen error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXGridSampler.m b/Pods/ZXingObjC/ZXingObjC/common/ZXGridSampler.m
new file mode 100644
index 0000000..cf9add8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXGridSampler.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 "ZXBitMatrix.h"
+#import "ZXDefaultGridSampler.h"
+#import "ZXErrors.h"
+#import "ZXGridSampler.h"
+#import "ZXPerspectiveTransform.h"
+
+static ZXGridSampler *gridSampler = nil;
+
+@implementation ZXGridSampler
+
++ (void)setGridSampler:(ZXGridSampler *)newGridSampler {
+ gridSampler = newGridSampler;
+}
+
++ (ZXGridSampler *)instance {
+ if (!gridSampler) {
+ gridSampler = [[ZXDefaultGridSampler alloc] init];
+ }
+
+ return gridSampler;
+}
+
+- (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];
+}
+
++ (BOOL)checkAndNudgePoints:(ZXBitMatrix *)image points:(float *)points pointsLen:(int)pointsLen error:(NSError **)error {
+ int width = image.width;
+ int height = image.height;
+ // Check and nudge points from start until we see some that are OK:
+ 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 = ZXNotFoundErrorInstance();
+ 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;
+ }
+ }
+ // Check and nudge points from end:
+ 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 = ZXNotFoundErrorInstance();
+ 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/Pods/ZXingObjC/ZXingObjC/common/ZXHybridBinarizer.h b/Pods/ZXingObjC/ZXingObjC/common/ZXHybridBinarizer.h
new file mode 100644
index 0000000..bb309ef
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXHybridBinarizer.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 "ZXGlobalHistogramBinarizer.h"
+
+@class ZXBinarizer, ZXBitMatrix, ZXLuminanceSource;
+
+/**
+ * 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.
+ */
+@interface ZXHybridBinarizer : ZXGlobalHistogramBinarizer
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXHybridBinarizer.m b/Pods/ZXingObjC/ZXingObjC/common/ZXHybridBinarizer.m
new file mode 100644
index 0000000..5742cb0
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXByteArray.h"
+#import "ZXHybridBinarizer.h"
+#import "ZXIntArray.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 ZX_BLOCK_SIZE_POWER = 3;
+const int ZX_BLOCK_SIZE = 1 << ZX_BLOCK_SIZE_POWER; // ...0100...00
+const int ZX_BLOCK_SIZE_MASK = ZX_BLOCK_SIZE - 1; // ...0011...11
+const int ZX_MINIMUM_DIMENSION = ZX_BLOCK_SIZE * 5;
+const int ZX_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 >= ZX_MINIMUM_DIMENSION && height >= ZX_MINIMUM_DIMENSION) {
+ ZXByteArray *luminances = source.matrix;
+ int subWidth = width >> ZX_BLOCK_SIZE_POWER;
+ if ((width & ZX_BLOCK_SIZE_MASK) != 0) {
+ subWidth++;
+ }
+ int subHeight = height >> ZX_BLOCK_SIZE_POWER;
+ if ((height & ZX_BLOCK_SIZE_MASK) != 0) {
+ subHeight++;
+ }
+ int **blackPoints = [self calculateBlackPoints:luminances.array subWidth:subWidth subHeight:subHeight width:width height:height];
+
+ ZXBitMatrix *newMatrix = [[ZXBitMatrix alloc] initWithWidth:width height:height];
+ [self calculateThresholdForBlock:luminances.array subWidth:subWidth subHeight:subHeight width:width height:height blackPoints:blackPoints matrix:newMatrix];
+ self.matrix = newMatrix;
+
+ 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 << ZX_BLOCK_SIZE_POWER;
+ int maxYOffset = height - ZX_BLOCK_SIZE;
+ if (yoffset > maxYOffset) {
+ yoffset = maxYOffset;
+ }
+ for (int x = 0; x < subWidth; x++) {
+ int xoffset = x << ZX_BLOCK_SIZE_POWER;
+ int maxXOffset = width - ZX_BLOCK_SIZE;
+ if (xoffset > maxXOffset) {
+ xoffset = maxXOffset;
+ }
+ 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 < ZX_BLOCK_SIZE; y++, offset += stride) {
+ for (int x = 0; x < ZX_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 << ZX_BLOCK_SIZE_POWER;
+ int maxYOffset = height - ZX_BLOCK_SIZE;
+ if (yoffset > maxYOffset) {
+ yoffset = maxYOffset;
+ }
+ for (int x = 0; x < subWidth; x++) {
+ int xoffset = x << ZX_BLOCK_SIZE_POWER;
+ int maxXOffset = width - ZX_BLOCK_SIZE;
+ if (xoffset > maxXOffset) {
+ xoffset = maxXOffset;
+ }
+ int sum = 0;
+ int min = 0xFF;
+ int max = 0;
+ for (int yy = 0, offset = yoffset * width + xoffset; yy < ZX_BLOCK_SIZE; yy++, offset += width) {
+ for (int xx = 0; xx < ZX_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 > ZX_MIN_DYNAMIC_RANGE) {
+ // finish the rest of the rows quickly
+ for (yy++, offset += width; yy < ZX_BLOCK_SIZE; yy++, offset += width) {
+ for (int xx = 0; xx < ZX_BLOCK_SIZE; xx++) {
+ sum += luminances[offset + xx] & 0xFF;
+ }
+ }
+ }
+ }
+
+ // The default estimate is the average of the values in the block.
+ int average = sum >> (ZX_BLOCK_SIZE_POWER * 2);
+ if (max - min <= ZX_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 / 2;
+
+ 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]) / 4;
+ if (min < averageNeighborBlackPoint) {
+ average = averageNeighborBlackPoint;
+ }
+ }
+ }
+ blackPoints[y][x] = average;
+ }
+ }
+ return blackPoints;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXIntArray.h b/Pods/ZXingObjC/ZXingObjC/common/ZXIntArray.h
new file mode 100644
index 0000000..0b45e62
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXIntArray.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@interface ZXIntArray : NSObject
+
+@property (nonatomic, assign, readonly) int32_t *array;
+@property (nonatomic, assign, readonly) unsigned int length;
+
+- (id)initWithLength:(unsigned int)length;
+- (id)initWithInts:(int32_t)int1, ...;
+- (void)clear;
+- (int)sum;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXIntArray.m b/Pods/ZXingObjC/ZXingObjC/common/ZXIntArray.m
new file mode 100644
index 0000000..40221d1
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXIntArray.m
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXIntArray.h"
+
+@implementation ZXIntArray
+
+- (id)initWithLength:(unsigned int)length {
+ if (self = [super init]) {
+ if (length > 0) {
+ _array = (int32_t *)calloc(length, sizeof(int32_t));
+ } else {
+ _array = NULL;
+ }
+ _length = length;
+ }
+
+ return self;
+}
+
+- (id)initWithInts:(int32_t)int1, ... {
+ va_list args;
+ va_start(args, int1);
+ unsigned int length = 0;
+ for (int32_t i = int1; i != -1; i = va_arg(args, int)) {
+ length++;
+ }
+ va_end(args);
+
+ if ((self = [self initWithLength:length]) && (length > 0)) {
+ va_list args;
+ va_start(args, int1);
+ int i = 0;
+ for (int32_t c = int1; c != -1; c = va_arg(args, int)) {
+ _array[i++] = c;
+ }
+ va_end(args);
+ }
+
+ return self;
+}
+
+- (id)copyWithZone:(NSZone *)zone {
+ ZXIntArray *copy = [[ZXIntArray allocWithZone:zone] initWithLength:self.length];
+ memcpy(copy.array, self.array, self.length * sizeof(int32_t));
+ return copy;
+}
+
+- (void)dealloc {
+ if (_array) {
+ free(_array);
+ }
+}
+
+- (void)clear {
+ memset(self.array, 0, self.length * sizeof(int32_t));
+}
+
+- (int)sum {
+ int sum = 0;
+ int32_t *array = self.array;
+ for (int i = 0; i < self.length; i++) {
+ sum += array[i];
+ }
+ return sum;
+}
+
+- (NSString *)description {
+ NSMutableString *s = [NSMutableString stringWithFormat:@"length=%u, array=(", self.length];
+
+ for (int i = 0; i < self.length; i++) {
+ [s appendFormat:@"%d", self.array[i]];
+ if (i < self.length - 1) {
+ [s appendString:@", "];
+ }
+ }
+
+ [s appendString:@")"];
+ return s;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXPerspectiveTransform.h b/Pods/ZXingObjC/ZXingObjC/common/ZXPerspectiveTransform.h
new file mode 100644
index 0000000..ab8cceb
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXPerspectiveTransform.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.
+ */
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/common/ZXPerspectiveTransform.m b/Pods/ZXingObjC/ZXingObjC/common/ZXPerspectiveTransform.m
new file mode 100644
index 0000000..442b5c5
--- /dev/null
+++ b/Pods/ZXingObjC/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, readonly) float a11;
+@property (nonatomic, assign, readonly) float a12;
+@property (nonatomic, assign, readonly) float a13;
+@property (nonatomic, assign, readonly) float a21;
+@property (nonatomic, assign, readonly) float a22;
+@property (nonatomic, assign, readonly) float a23;
+@property (nonatomic, assign, readonly) float a31;
+@property (nonatomic, assign, readonly) float a32;
+@property (nonatomic, assign, readonly) 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/Pods/ZXingObjC/ZXingObjC/common/ZXStringUtils.h b/Pods/ZXingObjC/ZXingObjC/common/ZXStringUtils.h
new file mode 100644
index 0000000..074af7e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXStringUtils.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 ZXByteArray, ZXDecodeHints;
+
+/**
+ * Common string-related functions.
+ */
+@interface ZXStringUtils : NSObject
+
+/**
+ * @param bytes bytes encoding a string, whose encoding should be guessed
+ * @param hints decode hints if applicable
+ * @return name of guessed encoding; at the moment will only guess one of:
+ * NSShiftJISStringEncoding, NSUTF8StringEncoding, NSISOLatin1StringEncoding, or the platform
+ * default encoding if none of these can possibly be correct
+ */
++ (NSStringEncoding)guessEncoding:(ZXByteArray *)bytes hints:(ZXDecodeHints *)hints;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/ZXStringUtils.m b/Pods/ZXingObjC/ZXingObjC/common/ZXStringUtils.m
new file mode 100644
index 0000000..ebd0dff
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/ZXStringUtils.m
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXByteArray.h"
+#import "ZXDecodeHints.h"
+#import "ZXStringUtils.h"
+
+@implementation ZXStringUtils
+
++ (NSStringEncoding)guessEncoding:(ZXByteArray *)bytes hints:(ZXDecodeHints *)hints {
+ NSStringEncoding systemEncoding = CFStringConvertEncodingToNSStringEncoding(CFStringGetSystemEncoding());
+ BOOL assumeShiftJIS = systemEncoding == NSShiftJISStringEncoding || systemEncoding == 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.
+ int length = bytes.length;
+ 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.array[0] == (int8_t) 0xEF &&
+ bytes.array[1] == (int8_t) 0xBB &&
+ bytes.array[2] == (int8_t) 0xBF;
+
+ for (int i = 0;
+ i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8);
+ i++) {
+
+ int value = bytes.array[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 systemEncoding;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMathUtils.h b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMathUtils.h
new file mode 100644
index 0000000..cd38da4
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMathUtils.m b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMathUtils.m
new file mode 100644
index 0000000..3c83ce2
--- /dev/null
+++ b/Pods/ZXingObjC/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 + (d < 0.0f ? -0.5f : 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/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.h b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.h
new file mode 100644
index 0000000..96bd259
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.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.
+ */
+
+@class ZXBitMatrix;
+
+/**
+ * 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.
+ */
+@interface ZXMonochromeRectangleDetector : NSObject
+
+- (id)initWithImage:(ZXBitMatrix *)image;
+
+/**
+ * Detects a rectangular region of black and white -- mostly black -- with a region of mostly
+ * white, in an image.
+ *
+ * @return ZXResultPoint array 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
+ * @return nil if no Data Matrix Code can be found
+ */
+- (NSArray *)detectWithError:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m
new file mode 100644
index 0000000..8549d27
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXMonochromeRectangleDetector.m
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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"
+
+const int ZX_MONOCHROME_MAX_MODULES = 32;
+
+@interface ZXMonochromeRectangleDetector ()
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *image;
+
+@end
+
+@implementation ZXMonochromeRectangleDetector
+
+- (id)initWithImage:(ZXBitMatrix *)image {
+ if (self = [super init]) {
+ _image = image;
+ }
+
+ return self;
+}
+
+- (NSArray *)detectWithError:(NSError **)error {
+ int height = [self.image height];
+ int width = [self.image width];
+ int halfHeight = height / 2;
+ int halfWidth = width / 2;
+ int deltaY = MAX(1, height / (ZX_MONOCHROME_MAX_MODULES * 8) > 1);
+ int deltaX = MAX(1, width / (ZX_MONOCHROME_MAX_MODULES * 8) > 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 / 2];
+ if (!pointA) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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 / 2];
+ if (!pointB) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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 / 2];
+ if (!pointC) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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 / 2];
+ if (!pointD) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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 / 4];
+ if (!pointA) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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.
+ *
+ * @param centerX center's x component (horizontal)
+ * @param deltaX same as deltaY but change in x per step instead
+ * @param left minimum value of x
+ * @param right maximum value of x
+ * @param centerY center's y component (vertical)
+ * @param deltaY change in y per step. If scanning up this is negative; down, positive;
+ * left or right, 0
+ * @param top minimum value of y to search through (meaningless when di == 0)
+ * @param bottom maximum value of y
+ * @param maxWhiteRun maximum run of white pixels that can still be considered to be within
+ * the barcode
+ * @return a {@link com.google.zxing.ResultPoint} encapsulating the corner that was found
+ * or nil if such a point cannot be found
+ */
+- (ZXResultPoint *)findCornerFromCenter:(int)centerX deltaX:(int)deltaX left:(int)left right:(int)right centerY:(int)centerY deltaY:(int)deltaY top:(int)top bottom:(int)bottom maxWhiteRun:(int)maxWhiteRun {
+ 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.
+ *
+ * @param 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
+ * @param maxWhiteRun largest run of white pixels that can still be considered part of the
+ * barcode region
+ * @param minDim minimum pixel location, horizontally or vertically, to consider
+ * @param maxDim maximum pixel location, horizontally or vertically, to consider
+ * @param horizontal if true, we're scanning left-right, instead of up-down
+ * @return int[] with start and end of found range, or nil if no such range is found
+ * (e.g. only white was found)
+ */
+- (NSArray *)blackWhiteRange:(int)fixedDimension maxWhiteRun:(int)maxWhiteRun minDim:(int)minDim maxDim:(int)maxDim horizontal:(BOOL)horizontal {
+ int center = (minDim + maxDim) / 2;
+
+ 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/Pods/ZXingObjC/ZXingObjC/common/detector/ZXWhiteRectangleDetector.h b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXWhiteRectangleDetector.h
new file mode 100644
index 0000000..09dbb46
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXWhiteRectangleDetector.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 "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;
+
+/**
+ * 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.
+ *
+ * @return {@link ResultPoint}[] 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
+ * @return nil if no Data Matrix Code can be found
+ */
+- (NSArray *)detectWithError:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/detector/ZXWhiteRectangleDetector.m b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXWhiteRectangleDetector.m
new file mode 100644
index 0000000..677c873
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/detector/ZXWhiteRectangleDetector.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 "ZXErrors.h"
+#import "ZXMathUtils.h"
+#import "ZXWhiteRectangleDetector.h"
+
+@interface ZXWhiteRectangleDetector ()
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *image;
+@property (nonatomic, assign, readonly) int height;
+@property (nonatomic, assign, readonly) int width;
+@property (nonatomic, assign, readonly) int leftInit;
+@property (nonatomic, assign, readonly) int rightInit;
+@property (nonatomic, assign, readonly) int downInit;
+@property (nonatomic, assign, readonly) int upInit;
+
+@end
+
+const int ZX_INIT_SIZE = 10;
+const int ZX_CORR = 1;
+
+@implementation ZXWhiteRectangleDetector
+
+- (id)initWithImage:(ZXBitMatrix *)image error:(NSError **)error {
+ return [self initWithImage:image initSize:ZX_INIT_SIZE x:image.width / 2 y:image.height / 2 error:error];
+}
+
+- (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 / 2;
+ _leftInit = x - halfsize;
+ _rightInit = x + halfsize;
+ _upInit = y - halfsize;
+ _downInit = y + halfsize;
+ if (_upInit < 0 || _leftInit < 0 || _downInit >= _height || _rightInit >= _width) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ }
+
+ return self;
+}
+
+- (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;
+
+ BOOL atLeastOneBlackPointFoundOnRight = NO;
+ BOOL atLeastOneBlackPointFoundOnBottom = NO;
+ BOOL atLeastOneBlackPointFoundOnLeft = NO;
+ BOOL atLeastOneBlackPointFoundOnTop = NO;
+
+ while (aBlackPointFoundOnBorder) {
+ aBlackPointFoundOnBorder = NO;
+
+ // .....
+ // . |
+ // .....
+ BOOL rightBorderNotWhite = YES;
+ while ((rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < self.width) {
+ rightBorderNotWhite = [self containsBlackPoint:up b:down fixed:right horizontal:NO];
+ if (rightBorderNotWhite) {
+ right++;
+ aBlackPointFoundOnBorder = YES;
+ atLeastOneBlackPointFoundOnRight = YES;
+ } else if (!atLeastOneBlackPointFoundOnRight) {
+ right++;
+ }
+ }
+
+ if (right >= self.width) {
+ sizeExceeded = YES;
+ break;
+ }
+
+ // .....
+ // . .
+ // .___.
+ BOOL bottomBorderNotWhite = YES;
+ while ((bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < self.height) {
+ bottomBorderNotWhite = [self containsBlackPoint:left b:right fixed:down horizontal:YES];
+ if (bottomBorderNotWhite) {
+ down++;
+ aBlackPointFoundOnBorder = YES;
+ atLeastOneBlackPointFoundOnBottom = YES;
+ } else if (!atLeastOneBlackPointFoundOnBottom) {
+ down++;
+ }
+ }
+
+ if (down >= self.height) {
+ sizeExceeded = YES;
+ break;
+ }
+
+ // .....
+ // | .
+ // .....
+ BOOL leftBorderNotWhite = YES;
+ while ((leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0) {
+ leftBorderNotWhite = [self containsBlackPoint:up b:down fixed:left horizontal:NO];
+ if (leftBorderNotWhite) {
+ left--;
+ aBlackPointFoundOnBorder = YES;
+ atLeastOneBlackPointFoundOnLeft = YES;
+ } else if (!atLeastOneBlackPointFoundOnLeft) {
+ left--;
+ }
+ }
+
+ if (left < 0) {
+ sizeExceeded = YES;
+ break;
+ }
+
+ // .___.
+ // . .
+ // .....
+ BOOL topBorderNotWhite = YES;
+ while ((topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0) {
+ topBorderNotWhite = [self containsBlackPoint:left b:right fixed:up horizontal:YES];
+ if (topBorderNotWhite) {
+ up--;
+ aBlackPointFoundOnBorder = YES;
+ atLeastOneBlackPointFoundOnTop = YES;
+ } else if (!atLeastOneBlackPointFoundOnTop) {
+ up--;
+ }
+ }
+
+ 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 = ZXNotFoundErrorInstance();
+ 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 = ZXNotFoundErrorInstance();
+ 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 = ZXNotFoundErrorInstance();
+ 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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ return [self centerEdges:y z:z x:x t:t];
+ } else {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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
+ *
+ * @param y bottom most point
+ * @param z left most point
+ * @param x right most point
+ * @param t top most point
+ * @return ZXResultPoint array 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 - ZX_CORR y:tj + ZX_CORR],
+ [[ZXResultPoint alloc] initWithX:zi + ZX_CORR y:zj + ZX_CORR],
+ [[ZXResultPoint alloc] initWithX:xi - ZX_CORR y:xj - ZX_CORR],
+ [[ZXResultPoint alloc] initWithX:yi + ZX_CORR y:yj - ZX_CORR]];
+ } else {
+ return @[[[ZXResultPoint alloc] initWithX:ti + ZX_CORR y:tj + ZX_CORR],
+ [[ZXResultPoint alloc] initWithX:zi + ZX_CORR y:zj - ZX_CORR],
+ [[ZXResultPoint alloc] initWithX:xi - ZX_CORR y:xj + ZX_CORR],
+ [[ZXResultPoint alloc] initWithX:yi - ZX_CORR y:yj - ZX_CORR]];
+ }
+}
+
+/**
+ * Determines whether a segment contains a black point
+ *
+ * @param a min value of the scanned coordinate
+ * @param b max value of the scanned coordinate
+ * @param fixed value of fixed coordinate
+ * @param horizontal set to true if scan must be horizontal, false if vertical
+ * @return true if a black point has been found, else false.
+ */
+- (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/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGF.h b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGF.h
new file mode 100644
index 0000000..f5d0b62
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGF.h
@@ -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.
+ */
+
+@class ZXGenericGFPoly;
+
+/**
+ * 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).
+ */
+@interface ZXGenericGF : NSObject
+
+@property (nonatomic, strong, readonly) ZXGenericGFPoly *zero;
+@property (nonatomic, strong, readonly) ZXGenericGFPoly *one;
+@property (nonatomic, assign, readonly) int32_t size;
+@property (nonatomic, assign, readonly) int32_t generatorBase;
+
++ (ZXGenericGF *)AztecData12;
++ (ZXGenericGF *)AztecData10;
++ (ZXGenericGF *)AztecData6;
++ (ZXGenericGF *)AztecParam;
++ (ZXGenericGF *)QrCodeField256;
++ (ZXGenericGF *)DataMatrixField256;
++ (ZXGenericGF *)AztecData8;
++ (ZXGenericGF *)MaxiCodeField64;
+
+/**
+ * Create a representation of GF(size) using the given primitive polynomial.
+ *
+ * @param primitive irreducible polynomial whose coefficients are represented by
+ * the bits of an int, where the least-significant bit represents the constant
+ * coefficient
+ * @param size the size of the field
+ * @param b the factor b in the generator polynomial can be 0- or 1-based
+ * (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))).
+ * In most cases it should be 1, but for QR code it is 0.
+ */
+- (id)initWithPrimitive:(int)primitive size:(int)size b:(int)b;
+
+/**
+ * @return the monomial representing coefficient * x^degree
+ */
+- (ZXGenericGFPoly *)buildMonomial:(int)degree coefficient:(int)coefficient;
+
+/**
+ * Implements both addition and subtraction -- they are the same in GF(size).
+ *
+ * @return sum/difference of a and b
+ */
++ (int32_t)addOrSubtract:(int32_t)a b:(int32_t)b;
+
+/**
+ * @return 2 to the power of a in GF(size)
+ */
+- (int32_t)exp:(int)a;
+
+/**
+ * @return base 2 log of a in GF(size)
+ */
+- (int32_t)log:(int)a;
+
+/**
+ * @return multiplicative inverse of a
+ */
+- (int32_t)inverse:(int)a;
+
+/**
+ * @return product of a and b in GF(size)
+ */
+- (int32_t)multiply:(int)a b:(int)b;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGF.m b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGF.m
new file mode 100644
index 0000000..be1eb5d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGF.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 "ZXGenericGF.h"
+#import "ZXGenericGFPoly.h"
+#import "ZXIntArray.h"
+
+@interface ZXGenericGF ()
+
+@property (nonatomic, assign, readonly) int32_t *expTable;
+@property (nonatomic, assign, readonly) int32_t *logTable;
+@property (nonatomic, assign, readonly) int primitive;
+
+@end
+
+@implementation ZXGenericGF {
+ ZXGenericGFPoly *_one;
+ ZXGenericGFPoly *_zero;
+}
+
+- (id)initWithPrimitive:(int)primitive size:(int)size b:(int)b {
+ if (self = [super init]) {
+ _primitive = primitive;
+ _size = size;
+ _generatorBase = b;
+
+ _expTable = (int32_t *)calloc(self.size, sizeof(int32_t));
+ _logTable = (int32_t *)calloc(self.size, sizeof(int32_t));
+ int32_t x = 1;
+ for (int i = 0; i < self.size; i++) {
+ _expTable[i] = x;
+ x <<= 1; // we're assuming the generator alpha is 2
+ if (x >= self.size) {
+ x ^= (int32_t)self.primitive;
+ x &= (int32_t)self.size - 1;
+ }
+ }
+
+ for (int32_t i = 0; i < (int32_t)self.size-1; i++) {
+ _logTable[_expTable[i]] = i;
+ }
+ // logTable[0] == 0 but this should never be used
+ _zero = [[ZXGenericGFPoly alloc] initWithField:self coefficients:[[ZXIntArray alloc] initWithLength:1]];
+
+ _one = [[ZXGenericGFPoly alloc] initWithField:self coefficients:[[ZXIntArray alloc] initWithInts:1, -1]];
+ }
+
+ return self;
+}
+
++ (ZXGenericGF *)AztecData12 {
+ static ZXGenericGF *AztecData12 = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ 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;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ AztecData10 = [[ZXGenericGF alloc] initWithPrimitive:0x409 size:1024 b:1]; // x^10 + x^3 + 1
+ });
+ return AztecData10;
+}
+
++ (ZXGenericGF *)AztecData6 {
+ static ZXGenericGF *AztecData6 = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ AztecData6 = [[ZXGenericGF alloc] initWithPrimitive:0x43 size:64 b:1]; // x^6 + x + 1
+ });
+ return AztecData6;
+}
+
++ (ZXGenericGF *)AztecParam {
+ static ZXGenericGF *AztecParam = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ AztecParam = [[ZXGenericGF alloc] initWithPrimitive:0x13 size:16 b:1]; // x^4 + x + 1
+ });
+ return AztecParam;
+}
+
++ (ZXGenericGF *)QrCodeField256 {
+ static ZXGenericGF *QrCodeField256 = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ 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;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ 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:(int32_t)coefficient {
+ if (degree < 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Degree must be greater than 0."];
+ }
+ if (coefficient == 0) {
+ return self.zero;
+ }
+ ZXIntArray *coefficients = [[ZXIntArray alloc] initWithLength:degree + 1];
+ coefficients.array[0] = coefficient;
+ return [[ZXGenericGFPoly alloc] initWithField:self coefficients:coefficients];
+}
+
++ (int32_t)addOrSubtract:(int32_t)a b:(int32_t)b {
+ return a ^ b;
+}
+
+- (int32_t)exp:(int)a {
+ return _expTable[a];
+}
+
+- (int32_t)log:(int)a {
+ if (a == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Argument must be non-zero."];
+ }
+
+ return _logTable[a];
+}
+
+- (int32_t)inverse:(int)a {
+ if (a == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Argument must be non-zero."];
+ }
+
+ return _expTable[_size - _logTable[a] - 1];
+}
+
+- (int32_t)multiply:(int)a b:(int)b {
+ if (a == 0 || b == 0) {
+ return 0;
+ }
+
+ return _expTable[(_logTable[a] + _logTable[b]) % (_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/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h
new file mode 100644
index 0000000..feae94a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.h
@@ -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.
+ */
+
+@class ZXGenericGF, ZXIntArray;
+
+/**
+ * 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.
+ */
+@interface ZXGenericGFPoly : NSObject
+
+@property (nonatomic, strong, readonly) ZXIntArray *coefficients;
+
+/**
+ * @param field the {@link GenericGF} instance representing the field to use
+ * to perform computations
+ * @param coefficients coefficients as ints representing elements of GF(size), arranged
+ * from most significant (highest-power term) coefficient to least significant
+ */
+- (id)initWithField:(ZXGenericGF *)field coefficients:(ZXIntArray *)coefficients;
+
+/**
+ * @return degree of this polynomial
+ */
+- (int)degree;
+
+/**
+ * @return true iff this polynomial is the monomial "0"
+ */
+- (BOOL)zero;
+
+/**
+ * @return coefficient of x^degree term in this polynomial
+ */
+- (int)coefficient:(int)degree;
+
+/**
+ * @return evaluation of this polynomial at a given point
+ */
+- (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/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m
new file mode 100644
index 0000000..5df43db
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXGenericGFPoly.m
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXIntArray.h"
+
+@interface ZXGenericGFPoly ()
+
+@property (nonatomic, strong, readonly) ZXGenericGF *field;
+
+@end
+
+@implementation ZXGenericGFPoly
+
+- (id)initWithField:(ZXGenericGF *)field coefficients:(ZXIntArray *)coefficients {
+ if (self = [super init]) {
+ if (coefficients.length == 0) {
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:@"coefficients must have at least one element"
+ userInfo:nil];
+ }
+ _field = field;
+ int coefficientsLength = coefficients.length;
+ if (coefficientsLength > 1 && coefficients.array[0] == 0) {
+ // Leading term must be non-zero for anything except the constant polynomial "0"
+ int firstNonZero = 1;
+ while (firstNonZero < coefficientsLength && coefficients.array[firstNonZero] == 0) {
+ firstNonZero++;
+ }
+ if (firstNonZero == coefficientsLength) {
+ _coefficients = [[ZXIntArray alloc] initWithLength:1];
+ } else {
+ _coefficients = [[ZXIntArray alloc] initWithLength:coefficientsLength - firstNonZero];
+ for (int i = 0; i < _coefficients.length; i++) {
+ _coefficients.array[i] = coefficients.array[firstNonZero + i];
+ }
+ }
+ } else {
+ _coefficients = coefficients;
+ }
+ }
+
+ return self;
+}
+
+- (int)degree {
+ return self.coefficients.length - 1;
+}
+
+- (BOOL)zero {
+ return self.coefficients.array[0] == 0;
+}
+
+- (int)coefficient:(int)degree {
+ return self.coefficients.array[self.coefficients.length - 1 - degree];
+}
+
+- (int)evaluateAt:(int)a {
+ if (a == 0) {
+ return [self coefficient:0];
+ }
+ int size = self.coefficients.length;
+ int32_t *coefficients = self.coefficients.array;
+ ZXGenericGF *field = self.field;
+ if (a == 1) {
+ // Just the sum of the coefficients
+ int result = 0;
+ for (int i = 0; i < size; i++) {
+ result = [ZXGenericGF addOrSubtract:result b:coefficients[i]];
+ }
+ return result;
+ }
+ int result = coefficients[0];
+ for (int i = 1; i < size; i++) {
+ result = [ZXGenericGF addOrSubtract:[field multiply:a b:result] b: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;
+ }
+
+ ZXIntArray *smallerCoefficients = self.coefficients;
+ ZXIntArray *largerCoefficients = other.coefficients;
+ if (smallerCoefficients.length > largerCoefficients.length) {
+ ZXIntArray *temp = smallerCoefficients;
+ smallerCoefficients = largerCoefficients;
+ largerCoefficients = temp;
+ }
+ ZXIntArray *sumDiff = [[ZXIntArray alloc] initWithLength:largerCoefficients.length];
+ int lengthDiff = largerCoefficients.length - smallerCoefficients.length;
+ // Copy high-order terms only found in higher-degree polynomial's coefficients
+ memcpy(sumDiff.array, largerCoefficients.array, lengthDiff * sizeof(int32_t));
+
+ for (int i = lengthDiff; i < largerCoefficients.length; i++) {
+ sumDiff.array[i] = [ZXGenericGF addOrSubtract:smallerCoefficients.array[i - lengthDiff] b:largerCoefficients.array[i]];
+ }
+
+ return [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:sumDiff];
+}
+
+- (ZXGenericGFPoly *)multiply:(ZXGenericGFPoly *)other {
+ ZXGenericGF *field = self.field;
+ if (![self.field isEqual:other.field]) {
+ [NSException raise:NSInvalidArgumentException format:@"ZXGenericGFPolys do not have same GenericGF field"];
+ }
+ if (self.zero || other.zero) {
+ return field.zero;
+ }
+ ZXIntArray *aCoefficients = self.coefficients;
+ int aLength = aCoefficients.length;
+ ZXIntArray *bCoefficients = other.coefficients;
+ int bLength = bCoefficients.length;
+ ZXIntArray *product = [[ZXIntArray alloc] initWithLength:aLength + bLength - 1];
+ for (int i = 0; i < aLength; i++) {
+ int aCoeff = aCoefficients.array[i];
+ for (int j = 0; j < bLength; j++) {
+ product.array[i + j] = [ZXGenericGF addOrSubtract:product.array[i + j]
+ b:[field multiply:aCoeff b:bCoefficients.array[j]]];
+ }
+ }
+ return [[ZXGenericGFPoly alloc] initWithField:field coefficients:product];
+}
+
+- (ZXGenericGFPoly *)multiplyScalar:(int)scalar {
+ if (scalar == 0) {
+ return self.field.zero;
+ }
+ if (scalar == 1) {
+ return self;
+ }
+ int size = self.coefficients.length;
+ int32_t *coefficients = self.coefficients.array;
+ ZXIntArray *product = [[ZXIntArray alloc] initWithLength:size];
+ for (int i = 0; i < size; i++) {
+ product.array[i] = [self.field multiply:coefficients[i] b:scalar];
+ }
+ return [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:product];
+}
+
+- (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.coefficients.length;
+ int32_t *coefficients = self.coefficients.array;
+ ZXGenericGF *field = self.field;
+ ZXIntArray *product = [[ZXIntArray alloc] initWithLength:size + degree];
+ for (int i = 0; i < size; i++) {
+ product.array[i] = [field multiply:coefficients[i] b:coefficient];
+ }
+
+ return [[ZXGenericGFPoly alloc] initWithField:field coefficients:product];
+}
+
+- (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];
+
+ ZXGenericGF *field = self.field;
+ while ([remainder degree] >= other.degree && !remainder.zero) {
+ int degreeDifference = remainder.degree - other.degree;
+ int scale = [field multiply:[remainder coefficient:remainder.degree] b:inverseDenominatorLeadingTerm];
+ ZXGenericGFPoly *term = [other multiplyByMonomial:degreeDifference coefficient:scale];
+ ZXGenericGFPoly *iterationQuotient = [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/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.h b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.h
new file mode 100644
index 0000000..62863d2
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.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.
+ */
+
+@class ZXGenericGF, ZXIntArray;
+
+/**
+ * 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.
+ */
+@interface ZXReedSolomonDecoder : NSObject
+
+- (id)initWithField:(ZXGenericGF *)field;
+
+/**
+ * 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.
+ *
+ * @param received data and error-correction codewords
+ * @param twoS number of error-correction codewords available
+ * @return NO if decoding fails for any reason
+ */
+- (BOOL)decode:(ZXIntArray *)received twoS:(int)twoS error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.m b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonDecoder.m
new file mode 100644
index 0000000..3f7b6d8
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXIntArray.h"
+#import "ZXReedSolomonDecoder.h"
+
+@interface ZXReedSolomonDecoder ()
+
+@property (nonatomic, strong, readonly) ZXGenericGF *field;
+
+@end
+
+@implementation ZXReedSolomonDecoder
+
+- (id)initWithField:(ZXGenericGF *)field {
+ if (self = [super init]) {
+ _field = field;
+ }
+
+ return self;
+}
+
+- (BOOL)decode:(ZXIntArray *)received twoS:(int)twoS error:(NSError **)error {
+ ZXGenericGFPoly *poly = [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:received];
+ ZXIntArray *syndromeCoefficients = [[ZXIntArray alloc] initWithLength:twoS];
+ BOOL noError = YES;
+ for (int i = 0; i < twoS; i++) {
+ int eval = [poly evaluateAt:[self.field exp:i + self.field.generatorBase]];
+ syndromeCoefficients.array[syndromeCoefficients.length - 1 - i] = eval;
+ if (eval != 0) {
+ noError = NO;
+ }
+ }
+ if (noError) {
+ return YES;
+ }
+ ZXGenericGFPoly *syndrome = [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:syndromeCoefficients];
+ 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];
+ ZXIntArray *errorLocations = [self findErrorLocations:sigma error:error];
+ if (!errorLocations) {
+ return NO;
+ }
+ ZXIntArray *errorMagnitudes = [self findErrorMagnitudes:omega errorLocations:errorLocations];
+ for (int i = 0; i < errorLocations.length; i++) {
+ int position = received.length - 1 - [self.field log:errorLocations.array[i]];
+ if (position < 0) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Bad error location"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXReedSolomonError userInfo:userInfo];
+ return NO;
+ }
+ received.array[position] = [ZXGenericGF addOrSubtract:received.array[position] b:errorMagnitudes.array[i]];
+ }
+ 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 nil;
+ }
+ 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 nil;
+ }
+
+ int inverse = [self.field inverse:sigmaTildeAtZero];
+ ZXGenericGFPoly *sigma = [t multiplyScalar:inverse];
+ ZXGenericGFPoly *omega = [r multiplyScalar:inverse];
+ return @[sigma, omega];
+}
+
+- (ZXIntArray *)findErrorLocations:(ZXGenericGFPoly *)errorLocator error:(NSError **)error {
+ int numErrors = [errorLocator degree];
+ if (numErrors == 1) {
+ ZXIntArray *array = [[ZXIntArray alloc] initWithLength:1];
+ array.array[0] = [errorLocator coefficient:1];
+ return array;
+ }
+ ZXIntArray *result = [[ZXIntArray alloc] initWithLength:numErrors];
+ int e = 0;
+ for (int i = 1; i < [self.field size] && e < numErrors; i++) {
+ if ([errorLocator evaluateAt:i] == 0) {
+ result.array[e] = [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;
+}
+
+- (ZXIntArray *)findErrorMagnitudes:(ZXGenericGFPoly *)errorEvaluator errorLocations:(ZXIntArray *)errorLocations {
+ int s = errorLocations.length;
+ ZXIntArray *result = [[ZXIntArray alloc] initWithLength:s];
+ ZXGenericGF *field = self.field;
+ for (int i = 0; i < s; i++) {
+ int xiInverse = [field inverse:errorLocations.array[i]];
+ int denominator = 1;
+ for (int j = 0; j < s; j++) {
+ if (i != j) {
+ //denominator = field.multiply(denominator,
+ // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)));
+ // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
+ // Below is a funny-looking workaround from Steven Parkes
+ int term = [field multiply:errorLocations.array[j] b:xiInverse];
+ int termPlus1 = (term & 0x1) == 0 ? term | 1 : term & ~1;
+ denominator = [field multiply:denominator b:termPlus1];
+ }
+ }
+ result.array[i] = [field multiply:[errorEvaluator evaluateAt:xiInverse] b:[field inverse:denominator]];
+ if (field.generatorBase != 0) {
+ result.array[i] = [field multiply:result.array[i] b:xiInverse];
+ }
+ }
+
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.h b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.h
new file mode 100644
index 0000000..af27289
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.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 ZXGenericGF, ZXIntArray;
+
+/**
+ * Implements Reed-Solomon enbcoding, as the name implies.
+ */
+@interface ZXReedSolomonEncoder : NSObject
+
+- (id)initWithField:(ZXGenericGF *)field;
+- (void)encode:(ZXIntArray *)toEncode ecBytes:(int)ecBytes;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.m b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.m
new file mode 100644
index 0000000..2a6ccc4
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/common/reedsolomon/ZXReedSolomonEncoder.m
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXGenericGF.h"
+#import "ZXGenericGFPoly.h"
+#import "ZXIntArray.h"
+#import "ZXReedSolomonEncoder.h"
+
+@interface ZXReedSolomonEncoder ()
+
+@property (nonatomic, strong, readonly) NSMutableArray *cachedGenerators;
+@property (nonatomic, strong, readonly) ZXGenericGF *field;
+
+@end
+
+@implementation ZXReedSolomonEncoder
+
+- (id)initWithField:(ZXGenericGF *)field {
+ if (self = [super init]) {
+ _field = field;
+ ZXIntArray *one = [[ZXIntArray alloc] initWithLength:1];
+ one.array[0] = 1;
+ _cachedGenerators = [NSMutableArray arrayWithObject:[[ZXGenericGFPoly alloc] initWithField:field coefficients:one]];
+ }
+
+ 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++) {
+ ZXIntArray *next = [[ZXIntArray alloc] initWithLength:2];
+ next.array[0] = 1;
+ next.array[1] = [self.field exp:(int)d - 1 + self.field.generatorBase];
+ ZXGenericGFPoly *nextGenerator = [lastGenerator multiply:[[ZXGenericGFPoly alloc] initWithField:self.field coefficients:next]];
+ [self.cachedGenerators addObject:nextGenerator];
+ lastGenerator = nextGenerator;
+ }
+ }
+
+ return (ZXGenericGFPoly *)self.cachedGenerators[degree];
+}
+
+- (void)encode:(ZXIntArray *)toEncode ecBytes:(int)ecBytes {
+ if (ecBytes == 0) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"No error correction bytes"
+ userInfo:nil];
+ }
+ int dataBytes = toEncode.length - ecBytes;
+ if (dataBytes <= 0) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"No data bytes provided"
+ userInfo:nil];
+ }
+ ZXGenericGFPoly *generator = [self buildGenerator:ecBytes];
+ ZXIntArray *infoCoefficients = [[ZXIntArray alloc] initWithLength:dataBytes];
+ for (int i = 0; i < dataBytes; i++) {
+ infoCoefficients.array[i] = toEncode.array[i];
+ }
+ ZXGenericGFPoly *info = [[ZXGenericGFPoly alloc] initWithField:self.field coefficients:infoCoefficients];
+ info = [info multiplyByMonomial:ecBytes coefficient:1];
+ ZXGenericGFPoly *remainder = [info divide:generator][1];
+ ZXIntArray *coefficients = remainder.coefficients;
+ int numZeroCoefficients = ecBytes - coefficients.length;
+ for (int i = 0; i < numZeroCoefficients; i++) {
+ toEncode.array[dataBytes + i] = 0;
+ }
+ for (int i = 0; i < coefficients.length; i++) {
+ toEncode.array[dataBytes + numZeroCoefficients + i] = coefficients.array[i];
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXBarcodeFormat.h b/Pods/ZXingObjC/ZXingObjC/core/ZXBarcodeFormat.h
new file mode 100644
index 0000000..4f74599
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/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/Pods/ZXingObjC/ZXingObjC/core/ZXBinarizer.h b/Pods/ZXingObjC/ZXingObjC/core/ZXBinarizer.h
new file mode 100644
index 0000000..c6fe676
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXBinarizer.h
@@ -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
+#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;
+
+/**
+ * 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.
+ *
+ * @param y The row to fetch, 0 <= y < bitmap height.
+ * @param row An optional preallocated array. If null or too small, it will be ignored.
+ * If used, the Binarizer will call ZXBitArray clear. Always use the returned object.
+ * @return The array of bits for this row (true means black).
+ */
+- (ZXBitArray *)blackRow:(int)y row:(ZXBitArray *)row error:(NSError **)error;
+
+/**
+ * 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 getBlackRow(), so don't mix and match between them.
+ *
+ * @return The 2D array of bits for the image (true means black).
+ */
+- (ZXBitMatrix *)blackMatrixWithError:(NSError **)error;
+
+/**
+ * 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.
+ *
+ * @param source The LuminanceSource this Binarizer will operate on.
+ * @return A new concrete Binarizer implementation object.
+ */
+- (ZXBinarizer *)createBinarizer:(ZXLuminanceSource *)source;
+
+- (CGImageRef)createImage CF_RETURNS_RETAINED;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXBinarizer.m b/Pods/ZXingObjC/ZXingObjC/core/ZXBinarizer.m
new file mode 100644
index 0000000..d87e551
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXBinarizer.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 "ZXBinarizer.h"
+
+#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
+#import
+#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];
+}
+
+- (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];
+}
+
+
+- (ZXBitMatrix *)blackMatrixWithError:(NSError **)error {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+- (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
+
++ (id)hints;
+
+/**
+ * Assume Code 39 codes employ a check digit.
+ */
+@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.
+ */
+@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;
+
+/**
+ * If true, return the start and end digits in a Codabar barcode instead of stripping them. They
+ * are alpha, whereas the rest are numeric. By default, they are stripped, but this causes them
+ * to not be.
+ */
+@property (nonatomic, assign) BOOL returnCodaBarStartEnd;
+
+/**
+ * The caller needs to be notified via callback when a possible ZXResultPoint
+ * is found.
+ */
+@property (nonatomic, strong) id resultPointCallback;
+
+/**
+ * Spend more time to try to find a barcode; optimize for accuracy, not speed.
+ */
+@property (nonatomic, assign) BOOL tryHarder;
+
+/**
+ * Allowed extension lengths for EAN or UPC barcodes. Other formats will ignore this.
+ * Maps to an ZXIntArray of the allowed extension lengths, for example [2], [5], or [2, 5].
+ * If it is optional to have an extension, do not set this hint. If this is set,
+ * and a UPC or EAN barcode is found but an extension is not, then no result will be returned
+ * at all.
+ */
+@property (nonatomic, strong) ZXIntArray *allowedEANExtensions;
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/core/ZXDecodeHints.m b/Pods/ZXingObjC/ZXingObjC/core/ZXDecodeHints.m
new file mode 100644
index 0000000..2c1f5ca
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXDecodeHints.m
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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, readonly) 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.returnCodaBarStartEnd = self.returnCodaBarStartEnd;
+ 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/Pods/ZXingObjC/ZXingObjC/core/ZXDimension.h b/Pods/ZXingObjC/ZXingObjC/core/ZXDimension.h
new file mode 100644
index 0000000..8095847
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXDimension.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.
+ */
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/core/ZXDimension.m b/Pods/ZXingObjC/ZXingObjC/core/ZXDimension.m
new file mode 100644
index 0000000..3eed89a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/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/Pods/ZXingObjC/ZXingObjC/core/ZXEncodeHints.h b/Pods/ZXingObjC/ZXingObjC/core/ZXEncodeHints.h
new file mode 100644
index 0000000..b3571eb
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXEncodeHints.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.
+ */
+typedef enum {
+ ZXDataMatrixSymbolShapeHintForceNone,
+ ZXDataMatrixSymbolShapeHintForceSquare,
+ ZXDataMatrixSymbolShapeHintForceRectangle
+} ZXDataMatrixSymbolShapeHint;
+
+typedef enum {
+ ZXPDF417CompactionAuto,
+ ZXPDF417CompactionText,
+ ZXPDF417CompactionByte,
+ ZXPDF417CompactionNumeric
+} ZXPDF417Compaction;
+
+@class ZXDimension, ZXPDF417Dimensions, ZXQRCodeErrorCorrectionLevel;
+
+/**
+ * These are a set of hints that you may pass to Writers to specify their behavior.
+ */
+@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, assign) ZXDataMatrixSymbolShapeHint dataMatrixShape;
+
+/**
+ * Specifies a minimum barcode size. Only applicable to Data Matrix now.
+ *
+ * @deprecated use width/height params in
+ * ZXDataMatrixWriter encode:format:width:height:error:
+ */
+@property (nonatomic, strong) ZXDimension *minSize DEPRECATED_ATTRIBUTE;
+
+/**
+ * Specifies a maximum barcode size. Only applicable to Data Matrix now.
+ *
+ * @deprecated without replacement
+ */
+@property (nonatomic, strong) ZXDimension *maxSize DEPRECATED_ATTRIBUTE;
+
+/**
+ * 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) ZXQRCodeErrorCorrectionLevel *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) ZXPDF417Compaction pdf417Compaction;
+
+/**
+ * Specifies the minimum and maximum number of rows and columns for PDF417.
+ */
+@property (nonatomic, strong) ZXPDF417Dimensions *pdf417Dimensions;
+
+/**
+ * Specifies the required number of layers for an Aztec code:
+ * a negative number (-1, -2, -3, -4) specifies a compact Aztec code
+ * 0 indicates to use the minimum number of layers (the default)
+ * a positive number (1, 2, .. 32) specifies a normaol (non-compact) Aztec code
+ */
+@property (nonatomic, strong) NSNumber *aztecLayers;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXEncodeHints.m b/Pods/ZXingObjC/ZXingObjC/core/ZXEncodeHints.m
new file mode 100644
index 0000000..539a3ce
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/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/Pods/ZXingObjC/ZXingObjC/core/ZXErrors.h b/Pods/ZXingObjC/ZXingObjC/core/ZXErrors.h
new file mode 100644
index 0000000..20e6e88
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/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 *ZXChecksumErrorInstance(void);
+NSError *ZXFormatErrorInstance(void);
+NSError *ZXNotFoundErrorInstance(void);
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXErrors.m b/Pods/ZXingObjC/ZXingObjC/core/ZXErrors.m
new file mode 100644
index 0000000..08730cf
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/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 *ZXChecksumErrorInstance() {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"This barcode failed its checksum"};
+
+ return [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXChecksumError userInfo:userInfo];
+}
+
+NSError *ZXFormatErrorInstance() {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"This barcode does not confirm to the format's rules"};
+
+ return [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXFormatError userInfo:userInfo];
+}
+
+NSError *ZXNotFoundErrorInstance() {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"A barcode was not found in this image"};
+
+ return [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXNotFoundError userInfo:userInfo];
+}
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXInvertedLuminanceSource.h b/Pods/ZXingObjC/ZXingObjC/core/ZXInvertedLuminanceSource.h
new file mode 100644
index 0000000..7db6f2d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/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/Pods/ZXingObjC/ZXingObjC/core/ZXInvertedLuminanceSource.m b/Pods/ZXingObjC/ZXingObjC/core/ZXInvertedLuminanceSource.m
new file mode 100644
index 0000000..5265f87
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXInvertedLuminanceSource.m
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXByteArray.h"
+#import "ZXInvertedLuminanceSource.h"
+
+@interface ZXInvertedLuminanceSource ()
+
+@property (nonatomic, weak, readonly) ZXLuminanceSource *delegate;
+
+@end
+
+@implementation ZXInvertedLuminanceSource
+
+- (id)initWithDelegate:(ZXLuminanceSource *)delegate {
+ self = [super initWithWidth:delegate.width height:delegate.height];
+ if (self) {
+ _delegate = delegate;
+ }
+
+ return self;
+}
+
+- (ZXByteArray *)rowAtY:(int)y row:(ZXByteArray *)row {
+ row = [self.delegate rowAtY:y row:row];
+ int width = self.width;
+ int8_t *rowArray = row.array;
+ for (int i = 0; i < width; i++) {
+ rowArray[i] = (int8_t) (255 - (rowArray[i] & 0xFF));
+ }
+ return row;
+}
+
+- (ZXByteArray *)matrix {
+ ZXByteArray *matrix = [self.delegate matrix];
+ int length = self.width * self.height;
+ ZXByteArray *invertedMatrix = [[ZXByteArray alloc] initWithLength:length];
+ int8_t *invertedMatrixArray = invertedMatrix.array;
+ int8_t *matrixArray = matrix.array;
+ for (int i = 0; i < length; i++) {
+ invertedMatrixArray[i] = (int8_t) (255 - (matrixArray[i] & 0xFF));
+ }
+ 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;
+}
+
+/**
+ * @return 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/Pods/ZXingObjC/ZXingObjC/core/ZXLuminanceSource.h b/Pods/ZXingObjC/ZXingObjC/core/ZXLuminanceSource.h
new file mode 100644
index 0000000..d279afd
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXLuminanceSource.h
@@ -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.
+ */
+
+@class ZXByteArray;
+
+/**
+ * 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
+
+/**
+ * @return The width of the bitmap.
+ */
+@property (nonatomic, assign, readonly) int width;
+
+/**
+ * @return The height of the bitmap.
+ */
+@property (nonatomic, assign, readonly) int height;
+
+/**
+ * @return Whether this subclass supports cropping.
+ */
+@property (nonatomic, assign, readonly) BOOL cropSupported;
+
+/**
+ * @return Whether this subclass supports counter-clockwise rotation.
+ */
+@property (nonatomic, assign, readonly) BOOL rotateSupported;
+
+- (id)initWithWidth:(int)width height:(int)height;
+
+/**
+ * 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.
+ *
+ * @param y The row to fetch, 0 <= y < getHeight().
+ * @param row An optional preallocated array. If null or too small, it will be ignored.
+ * Always use the returned object, and ignore the .length of the array.
+ * @return An array containing the luminance data.
+ */
+- (ZXByteArray *)rowAtY:(int)y row:(ZXByteArray *)row;
+
+/**
+ * Fetches luminance data for the underlying bitmap. Values should be fetched using:
+ * int luminance = array[y * width + x] & 0xff;
+ *
+ * @return 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.
+ */
+- (ZXByteArray *)matrix;
+
+/**
+ * Returns a new object with cropped image data. Implementations may keep a reference to the
+ * original data rather than a copy. Only callable if isCropSupported() is true.
+ *
+ * @param left The left coordinate, 0 <= left < getWidth().
+ * @param top The top coordinate, 0 <= top <= getHeight().
+ * @param width The width of the rectangle to crop.
+ * @param height The height of the rectangle to crop.
+ * @return A cropped version of this object.
+ */
+- (ZXLuminanceSource *)crop:(int)left top:(int)top width:(int)width height:(int)height;
+
+/**
+ * @return 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;
+
+/**
+ * Returns a new object with rotated image data by 90 degrees counterclockwise.
+ * Only callable if isRotateSupported is true.
+ *
+ * @return A rotated version of this object.
+ */
+- (ZXLuminanceSource *)rotateCounterClockwise;
+
+/**
+ * Returns a new object with rotated image data by 45 degrees counterclockwise.
+ * Only callable if isRotateSupported is true.
+ *
+ * @return A rotated version of this object.
+ */
+- (ZXLuminanceSource *)rotateCounterClockwise45;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXLuminanceSource.m b/Pods/ZXingObjC/ZXingObjC/core/ZXLuminanceSource.m
new file mode 100644
index 0000000..6351d18
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXLuminanceSource.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 "ZXByteArray.h"
+#import "ZXInvertedLuminanceSource.h"
+#import "ZXLuminanceSource.h"
+
+@implementation ZXLuminanceSource
+
+- (id)initWithWidth:(int)width height:(int)height {
+ if (self = [super init]) {
+ _width = width;
+ _height = height;
+ _cropSupported = NO;
+ _rotateSupported = NO;
+ }
+
+ return self;
+}
+
+- (ZXByteArray *)rowAtY:(int)y row:(ZXByteArray *)row {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+- (ZXByteArray *)matrix {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+- (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];
+}
+
+- (ZXLuminanceSource *)invert {
+ return [[ZXInvertedLuminanceSource alloc] initWithDelegate:self];
+}
+
+- (ZXLuminanceSource *)rotateCounterClockwise {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:@"This luminance source does not support rotation by 90 degrees."
+ userInfo:nil];
+}
+
+- (ZXLuminanceSource *)rotateCounterClockwise45 {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:@"This luminance source does not support rotation by 45 degrees."
+ userInfo:nil];
+}
+
+- (NSString *)description {
+ ZXByteArray *row = [[ZXByteArray alloc] initWithLength:self.width];
+ NSMutableString *result = [NSMutableString stringWithCapacity:self.height * (self.width + 1)];
+ for (int y = 0; y < self.height; y++) {
+ row = [self rowAtY:y row:row];
+ for (int x = 0; x < self.width; x++) {
+ int luminance = row.array[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"];
+ }
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXPlanarYUVLuminanceSource.h b/Pods/ZXingObjC/ZXingObjC/core/ZXPlanarYUVLuminanceSource.h
new file mode 100644
index 0000000..e11aa73
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXPlanarYUVLuminanceSource.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.
+ */
+
+#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
+
+/**
+ * @return width of image from renderThumbnail
+ */
+@property (nonatomic, assign, readonly) int thumbnailWidth;
+
+/**
+ * @return height of image from renderThumbnail
+ */
+@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;
+- (int32_t *)renderThumbnail;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXPlanarYUVLuminanceSource.m b/Pods/ZXingObjC/ZXingObjC/core/ZXPlanarYUVLuminanceSource.m
new file mode 100644
index 0000000..8d26033
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXPlanarYUVLuminanceSource.m
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXByteArray.h"
+#import "ZXPlanarYUVLuminanceSource.h"
+
+const int THUMBNAIL_SCALE_FACTOR = 2;
+
+@interface ZXPlanarYUVLuminanceSource ()
+
+@property (nonatomic, strong, readonly) ZXByteArray *yuvData;
+@property (nonatomic, assign, readonly) int dataWidth;
+@property (nonatomic, assign, readonly) int dataHeight;
+@property (nonatomic, assign, readonly) int left;
+@property (nonatomic, assign, readonly) 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."];
+ }
+
+ _yuvData = [[ZXByteArray alloc] initWithLength:yuvDataLen];
+ memcpy(_yuvData.array, yuvData, yuvDataLen * sizeof(int8_t));
+ _dataWidth = dataWidth;
+ _dataHeight = dataHeight;
+ _left = left;
+ _top = top;
+
+ if (reverseHorizontal) {
+ [self reverseHorizontal:width height:height];
+ }
+ }
+
+ return self;
+}
+
+- (ZXByteArray *)rowAtY:(int)y row:(ZXByteArray *)row {
+ if (y < 0 || y >= self.height) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Requested row is outside the image: %d", y];
+ }
+ int width = self.width;
+ if (!row || row.length < width) {
+ row = [[ZXByteArray alloc] initWithLength:width];
+ }
+ int offset = (y + self.top) * self.dataWidth + self.left;
+ memcpy(row.array, self.yuvData.array + offset, self.width * sizeof(int8_t));
+ return row;
+}
+
+- (ZXByteArray *)matrix {
+ int width = self.width;
+ int height = self.height;
+
+ // If the caller asks for the entire underlying image, save the copy and give them the
+ // original data. The docs specifically warn that result.length must be ignored.
+ if (width == self.dataWidth && height == self.dataHeight) {
+ return self.yuvData;
+ }
+
+ int area = self.width * self.height;
+ ZXByteArray *matrix = [[ZXByteArray alloc] initWithLength:area];
+ 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.array, self.yuvData.array + inputOffset, (area - inputOffset) * sizeof(int8_t));
+ return matrix;
+ }
+
+ // Otherwise copy one cropped row at a time.
+ ZXByteArray *yuvData = self.yuvData;
+ for (int y = 0; y < self.height; y++) {
+ int outputOffset = y * self.width;
+ memcpy(matrix.array + outputOffset, yuvData.array + inputOffset, self.width * sizeof(int8_t));
+ 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.array yuvDataLen:self.yuvData.length 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.array[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.array[x1];
+ self.yuvData.array[x1] = self.yuvData.array[x2];
+ self.yuvData.array[x2] = temp;
+ }
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXRGBLuminanceSource.h b/Pods/ZXingObjC/ZXingObjC/core/ZXRGBLuminanceSource.h
new file mode 100644
index 0000000..3944cac
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXRGBLuminanceSource.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 "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:(int32_t *)pixels pixelsLen:(int)pixelsLen;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXRGBLuminanceSource.m b/Pods/ZXingObjC/ZXingObjC/core/ZXRGBLuminanceSource.m
new file mode 100644
index 0000000..91aa197
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXRGBLuminanceSource.m
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXByteArray.h"
+#import "ZXRGBLuminanceSource.h"
+
+@interface ZXRGBLuminanceSource ()
+
+@property (nonatomic, strong, readonly) ZXByteArray *luminances;
+@property (nonatomic, assign, readonly) int dataWidth;
+@property (nonatomic, assign, readonly) int dataHeight;
+@property (nonatomic, assign, readonly) int left;
+@property (nonatomic, assign, readonly) 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.
+ _luminances = [[ZXByteArray alloc] initWithLength:width * height];
+ for (int y = 0; y < height; y++) {
+ int offset = y * width;
+ for (int x = 0; x < width; x++) {
+ int pixel = pixels[offset + x];
+ int r = (pixel >> 16) & 0xff;
+ int g = (pixel >> 8) & 0xff;
+ int b = pixel & 0xff;
+ if (r == g && g == b) {
+ // Image is already greyscale, so pick any channel.
+ _luminances.array[offset + x] = (int8_t) r;
+ } else {
+ // Calculate luminance cheaply, favoring green.
+ _luminances.array[offset + x] = (int8_t) ((r + g + g + b) / 4);
+ }
+ }
+ }
+ }
+
+ return self;
+}
+
+- (id)initWithPixels:(ZXByteArray *)pixels dataWidth:(int)dataWidth dataHeight:(int)dataHeight
+ left:(int)left top:(int)top width:(int)width height:(int)height {
+ if (self = [super initWithWidth:width height:height]) {
+ if (left + self.width > dataWidth || top + self.height > dataHeight) {
+ [NSException raise:NSInvalidArgumentException format:@"Crop rectangle does not fit within image data."];
+ }
+
+ _luminances = pixels;
+ _dataWidth = dataWidth;
+ _dataHeight = dataHeight;
+ _left = left;
+ _top = top;
+ }
+
+ return self;
+}
+
+- (ZXByteArray *)rowAtY:(int)y row:(ZXByteArray *)row {
+ if (y < 0 || y >= self.height) {
+ [NSException raise:NSInvalidArgumentException format:@"Requested row is outside the image: %d", y];
+ }
+ int width = self.width;
+ if (!row || row.length < width) {
+ row = [[ZXByteArray alloc] initWithLength:width];
+ }
+ int offset = (y + self.top) * self.dataWidth + self.left;
+ memcpy(row.array, self.luminances.array + offset, self.width * sizeof(int8_t));
+ return row;
+}
+
+- (ZXByteArray *)matrix {
+ int width = self.width;
+ int height = self.height;
+
+ // If the caller asks for the entire underlying image, save the copy and give them the
+ // original data. The docs specifically warn that result.length must be ignored.
+ if (width == self.dataWidth && height == self.dataHeight) {
+ return self.luminances;
+ }
+
+ int area = self.width * self.height;
+ ZXByteArray *matrix = [[ZXByteArray alloc] initWithLength:area];
+ 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.array, self.luminances.array + inputOffset, (area - inputOffset) * sizeof(int8_t));
+ 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.array + outputOffset, self.luminances.array + inputOffset, self.width * sizeof(int8_t));
+ 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
+ dataWidth:self.dataWidth
+ dataHeight:self.dataHeight
+ left:self.left + left
+ top:self.top + top
+ width:width
+ height:height];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXReader.h b/Pods/ZXingObjC/ZXingObjC/core/ZXReader.h
new file mode 100644
index 0000000..d1a5d86
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXReader.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.
+ */
+
+@class ZXBinaryBitmap, ZXDecodeHints, ZXResult;
+
+/**
+ * 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.
+ */
+@protocol ZXReader
+
+/**
+ * Locates and decodes a barcode in some format within an image.
+ *
+ * @param image image of barcode to decode
+ * @return String which the barcode encodes or nil if
+ * the barcode cannot be located or decoded for any reason
+ */
+- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error;
+
+/**
+ * Locates and decodes a barcode in some format within an image. This method also accepts
+ * hints, each possibly associated to some data, which may help the implementation decode.
+ *
+ * @param image image of barcode to decode
+ * @param hints passed as a {@link java.util.Map} from {@link com.google.zxing.DecodeHintType}
+ * to arbitrary data. The
+ * meaning of the data depends upon the hint type. The implementation may or may not do
+ * anything with these hints.
+ * @return String which the barcode encodes or nil if
+ * the barcode cannot be located or decoded for any reason
+ */
+- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+/**
+ * Resets any internal state the implementation has after a decode, to prepare it
+ * for reuse.
+ */
+- (void)reset;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXResult.h b/Pods/ZXingObjC/ZXingObjC/core/ZXResult.h
new file mode 100644
index 0000000..dab3e97
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXResult.h
@@ -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 "ZXBarcodeFormat.h"
+#import "ZXResultMetadataType.h"
+
+@class ZXByteArray;
+
+/**
+ * Encapsulates the result of decoding a barcode within an image.
+ */
+@interface ZXResult : NSObject
+
+/**
+ * @return raw text encoded by the barcode
+ */
+@property (nonatomic, copy, readonly) NSString *text;
+
+/**
+ * @return raw bytes encoded by the barcode, if applicable, otherwise nil
+ */
+@property (nonatomic, strong, readonly) ZXByteArray *rawBytes;
+
+/**
+ * @return points related to the barcode in the image. These are typically points
+ * identifying finder patterns or the corners of the barcode. The exact meaning is
+ * specific to the type of barcode that was decoded.
+ */
+@property (nonatomic, strong, readonly) NSMutableArray *resultPoints;
+
+/**
+ * @return ZXBarcodeFormat representing the format of the barcode that was decoded
+ */
+@property (nonatomic, assign, readonly) ZXBarcodeFormat barcodeFormat;
+
+/**
+ * @return NSDictionary mapping ZXResultMetadataType keys to values. May be
+ * nil. This contains optional metadata about what was detected about the barcode,
+ * like orientation.
+ */
+@property (nonatomic, strong, readonly) NSMutableDictionary *resultMetadata;
+
+@property (nonatomic, assign, readonly) long timestamp;
+
+- (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format;
+- (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp;
++ (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format;
++ (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes 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/Pods/ZXingObjC/ZXingObjC/core/ZXResult.m b/Pods/ZXingObjC/ZXingObjC/core/ZXResult.m
new file mode 100644
index 0000000..c2ae7cf
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXResult.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 "ZXResult.h"
+
+@interface ZXResult ()
+
+@property (nonatomic, strong) NSMutableDictionary *resultMetadata;
+@property (nonatomic, strong) NSMutableArray *resultPoints;
+
+@end
+
+@implementation ZXResult
+
+- (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format {
+ return [self initWithText:text rawBytes:rawBytes resultPoints:resultPoints format:format timestamp:CFAbsoluteTimeGetCurrent()];
+}
+
+- (id)initWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp {
+ if (self = [super init]) {
+ _text = text;
+ _rawBytes = rawBytes;
+ _resultPoints = [resultPoints mutableCopy];
+ _barcodeFormat = format;
+ _resultMetadata = nil;
+ _timestamp = timestamp;
+ }
+
+ return self;
+}
+
++ (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format {
+ return [[self alloc] initWithText:text rawBytes:rawBytes resultPoints:resultPoints format:format];
+}
+
++ (id)resultWithText:(NSString *)text rawBytes:(ZXByteArray *)rawBytes resultPoints:(NSArray *)resultPoints format:(ZXBarcodeFormat)format timestamp:(long)timestamp {
+ return [[self alloc] initWithText:text rawBytes:rawBytes resultPoints:resultPoints format:format timestamp:timestamp];
+}
+
+- (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/Pods/ZXingObjC/ZXingObjC/core/ZXResultMetadataType.h b/Pods/ZXingObjC/ZXingObjC/core/ZXResultMetadataType.h
new file mode 100644
index 0000000..e466f02
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXResultMetadataType.h
@@ -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.
+ */
+
+/**
+ * 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,
+
+ /**
+ * If the code format supports structured append and the current scanned code is part of one then the
+ * sequence number is given with it.
+ */
+ kResultMetadataTypeStructuredAppendSequence,
+
+ /**
+ * If the code format supports structured append and the current scanned code is part of one then the
+ * parity is given with it.
+ */
+ kResultMetadataTypeStructuredAppendParity
+} ZXResultMetadataType;
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXResultPoint.h b/Pods/ZXingObjC/ZXingObjC/core/ZXResultPoint.h
new file mode 100644
index 0000000..8435c07
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXResultPoint.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.
+ */
+
+/**
+ * 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
+
+@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;
+
+/**
+ * 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;
+
+/**
+ * @return distance between two points
+ */
++ (float)distance:(ZXResultPoint *)pattern1 pattern2:(ZXResultPoint *)pattern2;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXResultPoint.m b/Pods/ZXingObjC/ZXingObjC/core/ZXResultPoint.m
new file mode 100644
index 0000000..038c41a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXResultPoint.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 "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];
+}
+
++ (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;
+}
+
++ (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/Pods/ZXingObjC/ZXingObjC/core/ZXResultPointCallback.h b/Pods/ZXingObjC/ZXingObjC/core/ZXResultPointCallback.h
new file mode 100644
index 0000000..1755e0e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXResultPointCallback.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 ZXResultPoint;
+
+/**
+ * Callback which is invoked when a possible result point (significant
+ * point in the barcode image such as a corner) is found.
+ */
+@protocol ZXResultPointCallback
+
+- (void)foundPossibleResultPoint:(ZXResultPoint *)point;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXWriter.h b/Pods/ZXingObjC/ZXingObjC/core/ZXWriter.h
new file mode 100644
index 0000000..a46850d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXWriter.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.
+ */
+
+#import "ZXBarcodeFormat.h"
+
+@class ZXBitMatrix, ZXEncodeHints;
+
+/**
+ * The base class for all objects which encode/generate a barcode image.
+ */
+@protocol ZXWriter
+
+/**
+ * Encode a barcode using the default settings.
+ *
+ * @param contents The contents to encode in the barcode
+ * @param format The barcode format to generate
+ * @param width The preferred width in pixels
+ * @param height The preferred height in pixels
+ */
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height error:(NSError **)error;
+
+/**
+ *
+ * @param contents The contents to encode in the barcode
+ * @param format The barcode format to generate
+ * @param width The preferred width in pixels
+ * @param height The preferred height in pixels
+ * @param hints Additional parameters to supply to the encoder
+ */
+- (ZXBitMatrix *)encode:(NSString *)contents format:(ZXBarcodeFormat)format width:(int)width height:(int)height hints:(ZXEncodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/core/ZXingObjCCore.h b/Pods/ZXingObjC/ZXingObjC/core/ZXingObjCCore.h
new file mode 100644
index 0000000..7253b03
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/core/ZXingObjCCore.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ZXINGOBJC_CORE_
+
+#define _ZXINGOBJC_CORE_
+
+// Client
+#import "ZXCapture.h"
+#import "ZXCaptureDelegate.h"
+#import "ZXCGImageLuminanceSource.h"
+#import "ZXImage.h"
+
+// Common
+#import "ZXBitArray.h"
+#import "ZXBitMatrix.h"
+#import "ZXBitSource.h"
+#import "ZXBoolArray.h"
+#import "ZXByteArray.h"
+#import "ZXCharacterSetECI.h"
+#import "ZXDecoderResult.h"
+#import "ZXDefaultGridSampler.h"
+#import "ZXDetectorResult.h"
+#import "ZXGenericGF.h"
+#import "ZXGlobalHistogramBinarizer.h"
+#import "ZXGridSampler.h"
+#import "ZXHybridBinarizer.h"
+#import "ZXIntArray.h"
+#import "ZXMathUtils.h"
+#import "ZXMonochromeRectangleDetector.h"
+#import "ZXPerspectiveTransform.h"
+#import "ZXReedSolomonDecoder.h"
+#import "ZXReedSolomonEncoder.h"
+#import "ZXStringUtils.h"
+#import "ZXWhiteRectangleDetector.h"
+
+// Core
+#import "ZXBarcodeFormat.h"
+#import "ZXBinarizer.h"
+#import "ZXBinaryBitmap.h"
+#import "ZXByteMatrix.h"
+#import "ZXDecodeHints.h"
+#import "ZXDimension.h"
+#import "ZXEncodeHints.h"
+#import "ZXErrors.h"
+#import "ZXInvertedLuminanceSource.h"
+#import "ZXLuminanceSource.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"
+
+// Multi
+#import "ZXByQuadrantReader.h"
+#import "ZXGenericMultipleBarcodeReader.h"
+#import "ZXMultiDetector.h"
+#import "ZXMultipleBarcodeReader.h"
+#import "ZXQRCodeMultiReader.h"
+
+#endif
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixReader.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixReader.h
new file mode 100644
index 0000000..7c15883
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixReader.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 Data Matrix codes in an image.
+ */
+@interface ZXDataMatrixReader : NSObject
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixReader.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixReader.m
new file mode 100644
index 0000000..08f4ddc
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixReader.m
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXDataMatrixDetector.h"
+#import "ZXDataMatrixReader.h"
+#import "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXDetectorResult.h"
+#import "ZXErrors.h"
+#import "ZXIntArray.h"
+#import "ZXResult.h"
+
+@interface ZXDataMatrixReader ()
+
+@property (nonatomic, strong, readonly) 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.
+ *
+ * @return a String representing the content encoded by the Data Matrix code
+ */
+- (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 = ZXNotFoundErrorInstance();
+ 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
+ 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 {
+ ZXIntArray *leftTopBlack = image.topLeftOnBit;
+ ZXIntArray *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.array[1];
+ int bottom = rightBottomBlack.array[1];
+ int left = leftTopBlack.array[0];
+ int right = rightBottomBlack.array[0];
+
+ int matrixWidth = (right - left + 1) / moduleSize;
+ int matrixHeight = (bottom - top + 1) / moduleSize;
+ if (matrixWidth <= 0 || matrixHeight <= 0) {
+ return nil;
+ }
+
+ int nudge = moduleSize / 2;
+ 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:(ZXIntArray *)leftTopBlack image:(ZXBitMatrix *)image {
+ int width = image.width;
+ int x = leftTopBlack.array[0];
+ int y = leftTopBlack.array[1];
+ while (x < width && [image getX:x y:y]) {
+ x++;
+ }
+ if (x == width) {
+ return -1;
+ }
+
+ int moduleSize = x - leftTopBlack.array[0];
+ if (moduleSize == 0) {
+ return -1;
+ }
+ return moduleSize;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixWriter.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixWriter.h
new file mode 100644
index 0000000..2b7387d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixWriter.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.
+ */
+
+#import "ZXWriter.h"
+
+/**
+ * This object renders a Data Matrix code as a BitMatrix 2D array of greyscale values.
+ */
+@interface ZXDataMatrixWriter : NSObject
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixWriter.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixWriter.m
new file mode 100644
index 0000000..63f9bb4
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXDataMatrixWriter.m
@@ -0,0 +1,169 @@
+/*
+ * 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 "ZXDataMatrixDefaultPlacement.h"
+#import "ZXDataMatrixErrorCorrection.h"
+#import "ZXDataMatrixHighLevelEncoder.h"
+#import "ZXDataMatrixSymbolInfo.h"
+#import "ZXDataMatrixWriter.h"
+#import "ZXDimension.h"
+#import "ZXEncodeHints.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
+ ZXDataMatrixSymbolShapeHint shape = ZXDataMatrixSymbolShapeHintForceNone;
+ ZXDimension *minSize = [[ZXDimension alloc] initWithWidth:width height:height];
+ ZXDimension *maxSize = nil;
+ if (hints != nil) {
+ shape = hints.dataMatrixShape;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ ZXDimension *requestedMinSize = hints.minSize;
+#pragma GCC diagnostic pop
+ if (requestedMinSize != nil) {
+ minSize = requestedMinSize;
+ }
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ ZXDimension *requestedMaxSize = hints.maxSize;
+#pragma GCC diagnostic pop
+ if (requestedMaxSize != nil) {
+ maxSize = requestedMaxSize;
+ }
+ }
+
+ //1. step: Data encodation
+ NSString *encoded = [ZXDataMatrixHighLevelEncoder encodeHighLevel:contents shape:shape minSize:minSize maxSize:maxSize];
+
+ ZXDataMatrixSymbolInfo *symbolInfo = [ZXDataMatrixSymbolInfo 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
+ ZXDataMatrixDefaultPlacement *placement = [[ZXDataMatrixDefaultPlacement alloc] initWithCodewords:codewords numcols:symbolInfo.symbolDataWidth numrows:symbolInfo.symbolDataHeight];
+ [placement place];
+
+ //4. step: low-level encoding
+ return [self encodeLowLevel:placement symbolInfo:symbolInfo width:width height:height];
+}
+
+/**
+ * Encode the given symbol info to a bit matrix.
+ *
+ * @param placement The DataMatrix placement.
+ * @param symbolInfo The symbol info to encode.
+ * @return The bit matrix generated.
+ */
+- (ZXBitMatrix *)encodeLowLevel:(ZXDataMatrixDefaultPlacement *)placement symbolInfo:(ZXDataMatrixSymbolInfo *)symbolInfo width:(int)width height:(int)height {
+ 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 width:width height:height];
+}
+
+/**
+ * Convert the ZXByteMatrix to ZXBitMatrix.
+ *
+ * @param matrix The input matrix.
+ * @return The output matrix.
+ */
+- (ZXBitMatrix *)convertByteMatrixToBitMatrix:(ZXByteMatrix *)input width:(int)width height:(int)height {
+ int inputWidth = input.width;
+ int inputHeight = input.height;
+ int outputWidth = MAX(width, inputWidth);
+ int outputHeight = MAX(height, inputHeight);
+
+ int multiple = MIN(outputWidth / inputWidth, outputHeight / inputHeight);
+ int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
+ int topPadding = (outputHeight - (inputHeight * multiple)) / 2;
+
+ ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:outputWidth height:outputHeight];
+
+ 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/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXingObjCDataMatrix.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXingObjCDataMatrix.h
new file mode 100644
index 0000000..39bbd4b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/ZXingObjCDataMatrix.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ZXINGOBJC_DATAMATRIX_
+
+#define _ZXINGOBJC_DATAMATRIX_
+
+#import "ZXDataMatrixDecoder.h"
+#import "ZXDataMatrixDefaultPlacement.h"
+#import "ZXDataMatrixDetector.h"
+#import "ZXDataMatrixErrorCorrection.h"
+#import "ZXDataMatrixHighLevelEncoder.h"
+#import "ZXDataMatrixReader.h"
+#import "ZXDataMatrixSymbolInfo.h"
+#import "ZXDataMatrixVersion.h"
+#import "ZXDataMatrixWriter.h"
+
+#endif
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.h
new file mode 100644
index 0000000..b8f1757
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.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.
+ */
+
+@class ZXBitMatrix, ZXByteArray, ZXDataMatrixVersion;
+
+@interface ZXDataMatrixBitMatrixParser : NSObject
+
+@property (nonatomic, strong, readonly) ZXDataMatrixVersion *version;
+
+/**
+ * @param bitMatrix ZXBitMatrix to parse
+ * @return nil if dimension is < 8 or > 144 or not 0 mod 2
+ */
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error;
+
+/**
+ * Reads the bits in the ZXBitMatrix representing the mapping matrix (No alignment patterns)
+ * in the correct order in order to reconstitute the codewords bytes contained within the
+ * Data Matrix Code.
+ *
+ * @return bytes encoded within the Data Matrix Code or nil if the exact number of bytes expected is not read
+ */
+- (ZXByteArray *)readCodewords;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.m
new file mode 100644
index 0000000..af4e921
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixBitMatrixParser.m
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXByteArray.h"
+#import "ZXDataMatrixBitMatrixParser.h"
+#import "ZXDataMatrixVersion.h"
+#import "ZXErrors.h"
+
+@interface ZXDataMatrixBitMatrixParser ()
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *mappingBitMatrix;
+@property (nonatomic, strong, readonly) 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 = ZXFormatErrorInstance();
+ return nil;
+ }
+ _version = [self readVersion:bitMatrix];
+ if (!_version) {
+ if (error) *error = ZXFormatErrorInstance();
+ 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<
+ *
+ * @param bitMatrix Original ZXBitMatrix including alignment patterns
+ * @return ZXDatamatrixVersion encapsulating the Data Matrix Code's "version"
+ * or nil if the dimensions of the mapping matrix are not valid
+ * Data Matrix dimensions.
+ */
+- (ZXDataMatrixVersion *)readVersion:(ZXBitMatrix *)bitMatrix {
+ int numRows = bitMatrix.height;
+ int numColumns = bitMatrix.width;
+ return [ZXDataMatrixVersion versionForDimensions:numRows numColumns:numColumns];
+}
+
+- (ZXByteArray *)readCodewords {
+ ZXByteArray *result = [[ZXByteArray alloc] initWithLength:self.version.totalCodewords];
+ int resultOffset = 0;
+
+ 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.array[resultOffset++] = (int8_t) [self readCorner1:numRows numColumns:numColumns];
+ row -= 2;
+ column += 2;
+ corner1Read = YES;
+ } else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x03) != 0) && !corner2Read) {
+ result.array[resultOffset++] = (int8_t) [self readCorner2:numRows numColumns:numColumns];
+ row -= 2;
+ column += 2;
+ corner2Read = YES;
+ } else if ((row == numRows + 4) && (column == 2) && ((numColumns & 0x07) == 0) && !corner3Read) {
+ result.array[resultOffset++] = (int8_t) [self readCorner3:numRows numColumns:numColumns];
+ row -= 2;
+ column += 2;
+ corner3Read = YES;
+ } else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x07) == 4) && !corner4Read) {
+ result.array[resultOffset++] = (int8_t) [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.array[resultOffset++] = (int8_t) [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.array[resultOffset++] = (int8_t) [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 (resultOffset != self.version.totalCodewords) {
+ return nil;
+ }
+ return result;
+}
+
+/**
+ * Reads a bit of the mapping matrix accounting for boundary wrapping.
+ *
+ * @param row Row to read in the mapping matrix
+ * @param column Column to read in the mapping matrix
+ * @param numRows Number of rows in the mapping matrix
+ * @param numColumns Number of columns in the mapping matrix
+ * @return value of the given bit in the mapping matrix
+ */
+- (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
+ *
+ * @param row Current row in the mapping matrix, anchored at the 8th bit (LSB) of the pattern
+ * @param column Current column in the mapping matrix, anchored at the 8th bit (LSB) of the pattern
+ * @param numRows Number of rows in the mapping matrix
+ * @param numColumns Number of columns in the mapping matrix
+ * @return byte from the utah shape
+ */
+- (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
+ *
+ * @param numRows Number of rows in the mapping matrix
+ * @param numColumns Number of columns in the mapping matrix
+ * @return byte from the Corner condition 1
+ */
+- (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
+ *
+ * @param numRows Number of rows in the mapping matrix
+ * @param numColumns Number of columns in the mapping matrix
+ * @return byte from the Corner condition 2
+ */
+- (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
+ *
+ * @param numRows Number of rows in the mapping matrix
+ * @param numColumns Number of columns in the mapping matrix
+ * @return byte from the Corner condition 3
+ */
+- (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
+ *
+ * @param numRows Number of rows in the mapping matrix
+ * @param numColumns Number of columns in the mapping matrix
+ * @return byte from the Corner condition 4
+ */
+- (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 ZXBitMatrix that contains
+ * alignment patterns.
+ *
+ * @param bitMatrix Original ZXBitMatrix with alignment patterns
+ * @return BitMatrix that has the alignment patterns removed
+ */
+- (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/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.h
new file mode 100644
index 0000000..3894233
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.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.
+ */
+
+@class ZXByteArray, ZXDataMatrixVersion;
+
+/**
+ * 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.
+ */
+@interface ZXDataMatrixDataBlock : NSObject
+
+@property (nonatomic, assign, readonly) int numDataCodewords;
+@property (nonatomic, strong, readonly) ZXByteArray *codewords;
+
+/**
+ * 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.
+ *
+ * @param rawCodewords bytes as read directly from the Data Matrix Code
+ * @param version version of the Data Matrix Code
+ * @return DataBlocks containing original bytes, "de-interleaved" from representation in the
+ * Data Matrix Code
+ */
++ (NSArray *)dataBlocks:(ZXByteArray *)rawCodewords version:(ZXDataMatrixVersion *)version;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.m
new file mode 100644
index 0000000..b26fcf3
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDataBlock.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 "ZXByteArray.h"
+#import "ZXDataMatrixDataBlock.h"
+#import "ZXDataMatrixVersion.h"
+
+@implementation ZXDataMatrixDataBlock
+
+- (id)initWithNumDataCodewords:(int)numDataCodewords codewords:(ZXByteArray *)codewords {
+ if (self = [super init]) {
+ _numDataCodewords = numDataCodewords;
+ _codewords = codewords;
+ }
+
+ return self;
+}
+
++ (NSArray *)dataBlocks:(ZXByteArray *)rawCodewords version:(ZXDataMatrixVersion *)version {
+ // Figure out the number and size of data blocks used by this version
+ ZXDataMatrixECBlocks *ecBlocks = version.ecBlocks;
+
+ // First count the total number of data blocks
+ int totalBlocks = 0;
+ NSArray *ecBlockArray = ecBlocks.ecBlocks;
+ for (ZXDataMatrixECB *ecBlock in ecBlockArray) {
+ totalBlocks += ecBlock.count;
+ }
+
+ // Now establish DataBlocks of the appropriate size and number of data codewords
+ NSMutableArray *result = [NSMutableArray arrayWithCapacity:totalBlocks];
+ for (ZXDataMatrixECB *ecBlock in ecBlockArray) {
+ for (int i = 0; i < ecBlock.count; i++) {
+ int numDataCodewords = ecBlock.dataCodewords;
+ int numBlockCodewords = ecBlocks.ecCodewords + numDataCodewords;
+ [result addObject:[[ZXDataMatrixDataBlock alloc] initWithNumDataCodewords:numDataCodewords codewords:[[ZXByteArray alloc] initWithLength:numBlockCodewords]]];
+ }
+ }
+
+ // All blocks have the same amount of data, except that the last n
+ // (where n may be 0) have 1 less byte. Figure out where these start.
+ // TODO(bbrown): There is only one case where there is a difference for Data Matrix for size 144
+ int longerBlocksTotalCodewords = [[(ZXDataMatrixDataBlock *)result[0] codewords] length];
+ //int shorterBlocksTotalCodewords = longerBlocksTotalCodewords - 1;
+
+ int longerBlocksNumDataCodewords = longerBlocksTotalCodewords - ecBlocks.ecCodewords;
+ int shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1;
+ // The last elements of result may be 1 element shorter for 144 matrix
+ // first fill out as many elements as all of them have minus 1
+ int rawCodewordsOffset = 0;
+ for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {
+ for (ZXDataMatrixDataBlock *block in result) {
+ block.codewords.array[i] = rawCodewords.array[rawCodewordsOffset++];
+ }
+ }
+
+ // Fill out the last data block in the longer ones
+ BOOL specialVersion = version.versionNumber == 24;
+ int numLongerBlocks = specialVersion ? 8 : (int)[result count];
+ for (int j = 0; j < numLongerBlocks; j++) {
+ [(ZXDataMatrixDataBlock *)result[j] codewords].array[longerBlocksNumDataCodewords - 1] = rawCodewords.array[rawCodewordsOffset++];
+ }
+
+ NSUInteger max = [(ZXDataMatrixDataBlock *)result[0] codewords].length;
+ for (int i = longerBlocksNumDataCodewords; i < max; i++) {
+ for (int j = 0; j < [result count]; j++) {
+ int jOffset = specialVersion ? (j + 8) % [result count] : j;
+ int iOffset = specialVersion && jOffset > 7 ? i - 1 : i;
+ [(ZXDataMatrixDataBlock *)result[jOffset] codewords].array[iOffset] = rawCodewords.array[rawCodewordsOffset++];
+ }
+ }
+
+ if (rawCodewordsOffset != rawCodewords.length) {
+ [NSException raise:NSInvalidArgumentException format:@"Codewords size mismatch"];
+ }
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.h
new file mode 100644
index 0000000..115f313
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.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 ZXByteArray, ZXDecoderResult;
+
+/**
+ * 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
+ */
+@interface ZXDataMatrixDecodedBitStreamParser : NSObject
+
++ (ZXDecoderResult *)decode:(ZXByteArray *)bytes error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecodedBitStreamParser.m
new file mode 100644
index 0000000..7c7de50
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXByteArray.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 unichar 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 unichar 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 unichar 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'
+};
+
+// Shift 2 for Text is the same encoding as C40
+static unichar TEXT_SHIFT2_SET_CHARS[40];
+
+const unichar 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', '{', '|', '}', '~', (unichar) 127
+};
+
+enum {
+ PAD_ENCODE = 0, // Not really a mode
+ ASCII_ENCODE,
+ C40_ENCODE,
+ TEXT_ENCODE,
+ ANSIX12_ENCODE,
+ EDIFACT_ENCODE,
+ BASE256_ENCODE
+};
+
+@implementation ZXDataMatrixDecodedBitStreamParser
+
++ (void)initialize {
+ if ([self class] != [ZXDataMatrixDecodedBitStreamParser class]) return;
+
+ memcpy(TEXT_SHIFT2_SET_CHARS, C40_SHIFT2_SET_CHARS, sizeof(C40_SHIFT2_SET_CHARS));
+}
+
++ (ZXDecoderResult *)decode:(ZXByteArray *)bytes error:(NSError **)error {
+ ZXBitSource *bits = [[ZXBitSource alloc] initWithBytes:bytes];
+ 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 = ZXFormatErrorInstance();
+ return nil;
+ }
+ } else {
+ switch (mode) {
+ case C40_ENCODE:
+ if (![self decodeC40Segment:bits result:result]) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ break;
+ case TEXT_ENCODE:
+ if (![self decodeTextSegment:bits result:result]) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ break;
+ case ANSIX12_ENCODE:
+ if (![self decodeAnsiX12Segment:bits result:result]) {
+ if (error) *error = ZXFormatErrorInstance();
+ 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 = ZXFormatErrorInstance();
+ return nil;
+ }
+ break;
+ default:
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ mode = ASCII_ENCODE;
+ }
+ } while (mode != PAD_ENCODE && bits.available > 0);
+ if ([resultTrailer length] > 0) {
+ [result appendString:resultTrailer];
+ }
+ return [[ZXDecoderResult alloc] initWithRawBytes:bytes
+ 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) { // pad 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(TEXT_SHIFT2_SET_CHARS) / sizeof(unichar)) {
+ unichar textChar = TEXT_SHIFT2_SET_CHARS[cValue];
+ if (upperShift) {
+ [result appendFormat:@"%C", (unichar)(textChar + 128)];
+ upperShift = NO;
+ } else {
+ [result appendFormat:@"%C", textChar];
+ }
+ } 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
+ [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;
+ }
+
+ ZXByteArray *bytes = [[ZXByteArray alloc] initWithLength:count];
+ for (int i = 0; i < count; i++) {
+ if ([bits available] < 8) {
+ return NO;
+ }
+ bytes.array[i] = (int8_t)[self unrandomize255State:[bits readBits:8] base256CodewordPosition:codewordPosition++];
+ }
+ [byteSegments addObject:bytes];
+
+ [result appendString:[[NSString alloc] initWithBytes:bytes.array length:bytes.length 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/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.h
new file mode 100644
index 0000000..cf7660a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.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.
+ */
+
+@class ZXBitMatrix, ZXDecoderResult, ZXReedSolomonDecoder;
+
+/**
+ * The main class which implements Data Matrix Code decoding -- as opposed to locating and extracting
+ * the Data Matrix Code from an image.
+ */
+@interface ZXDataMatrixDecoder : NSObject
+
+/**
+ * Convenience method that can decode a Data Matrix Code represented as a 2D array of booleans.
+ * "true" is taken to mean a black module.
+ *
+ * @param image booleans representing white/black Data Matrix Code modules
+ * @return text and bytes encoded within the Data Matrix Code
+ * @return nil if the Data Matrix Code cannot be decoded
+ * @return nil if error correction fails
+ */
+- (ZXDecoderResult *)decode:(NSArray *)image error:(NSError **)error;
+
+/**
+ * Decodes a Data Matrix Code represented as a {@link BitMatrix}. A 1 or "true" is taken
+ * to mean a black module.
+ *
+ * @param bits booleans representing white/black Data Matrix Code modules
+ * @return text and bytes encoded within the Data Matrix Code
+ * @return nil if the Data Matrix Code cannot be decoded
+ * @return nil if error correction fails
+ */
+- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixDecoder.m
new file mode 100644
index 0000000..d2b33fa
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXBoolArray.h"
+#import "ZXByteArray.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 "ZXIntArray.h"
+#import "ZXReedSolomonDecoder.h"
+
+@interface ZXDataMatrixDecoder ()
+
+@property (nonatomic, strong, readonly) ZXReedSolomonDecoder *rsDecoder;
+
+@end
+
+@implementation ZXDataMatrixDecoder
+
+- (id)init {
+ if (self = [super init]) {
+ _rsDecoder = [[ZXReedSolomonDecoder alloc] initWithField:[ZXGenericGF DataMatrixField256]];
+ }
+
+ return self;
+}
+
+- (ZXDecoderResult *)decode:(NSArray *)image error:(NSError **)error {
+ int dimension = (int)[image count];
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithDimension:dimension];
+ for (int i = 0; i < dimension; i++) {
+ ZXBoolArray *b = image[i];
+ for (int j = 0; j < dimension; j++) {
+ if (b.array[j]) {
+ [bits setX:j y:i];
+ }
+ }
+ }
+
+ return [self decodeMatrix:bits error:error];
+}
+
+- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits error:(NSError **)error {
+ ZXDataMatrixBitMatrixParser *parser = [[ZXDataMatrixBitMatrixParser alloc] initWithBitMatrix:bits error:error];
+ if (!parser) {
+ return nil;
+ }
+ ZXDataMatrixVersion *version = [parser version];
+
+ ZXByteArray *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;
+ }
+
+ ZXByteArray *resultBytes = [[ZXByteArray alloc] initWithLength:totalBytes];
+
+ for (int j = 0; j < dataBlocksCount; j++) {
+ ZXDataMatrixDataBlock *dataBlock = dataBlocks[j];
+ ZXByteArray *codewordBytes = dataBlock.codewords;
+ int numDataCodewords = [dataBlock numDataCodewords];
+ if (![self correctErrors:codewordBytes numDataCodewords:numDataCodewords error:error]) {
+ return nil;
+ }
+ for (int i = 0; i < numDataCodewords; i++) {
+ // De-interlace data blocks.
+ resultBytes.array[i * dataBlocksCount + j] = codewordBytes.array[i];
+ }
+ }
+
+ return [ZXDataMatrixDecodedBitStreamParser decode:resultBytes 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.
+ *
+ * @param codewordBytes data and error correction codewords
+ * @param numDataCodewords number of codewords that are data bytes
+ * @return NO if error correction fails
+ */
+- (BOOL)correctErrors:(ZXByteArray *)codewordBytes numDataCodewords:(int)numDataCodewords error:(NSError **)error {
+ int numCodewords = codewordBytes.length;
+ // First read into an array of ints
+ ZXIntArray *codewordsInts = [[ZXIntArray alloc] initWithLength:numCodewords];
+ for (int i = 0; i < numCodewords; i++) {
+ codewordsInts.array[i] = codewordBytes.array[i] & 0xFF;
+ }
+ int numECCodewords = codewordBytes.length - numDataCodewords;
+
+ NSError *decodeError = nil;
+ if (![self.rsDecoder decode:codewordsInts twoS:numECCodewords error:&decodeError]) {
+ if (decodeError.code == ZXReedSolomonError) {
+ if (error) *error = ZXChecksumErrorInstance();
+ return NO;
+ } else {
+ if (error) *error = decodeError;
+ return NO;
+ }
+ }
+
+ for (int i = 0; i < numDataCodewords; i++) {
+ codewordBytes.array[i] = (int8_t) codewordsInts.array[i];
+ }
+ return YES;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h
new file mode 100644
index 0000000..82e01a9
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.h
@@ -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.
+ */
+
+/**
+ * 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;
+
+/**
+ *
Deduces version information from Data Matrix dimensions.
+ *
+ * @param numRows Number of rows in modules
+ * @param numColumns Number of columns in modules
+ * @return Version for a Data Matrix Code of those dimensions or nil
+ * if dimensions do correspond to a valid Data Matrix size
+ */
++ (ZXDataMatrixVersion *)versionForDimensions:(int)numRows numColumns:(int)numColumns;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.m
new file mode 100644
index 0000000..6a3aa82
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/decoder/ZXDataMatrixVersion.m
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+}
+
++ (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 {
+ if ([self class] != [ZXDataMatrixVersion class]) return;
+
+ 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/Pods/ZXingObjC/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.h
new file mode 100644
index 0000000..babf9e1
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.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.
+ */
+
+@class ZXBitMatrix, ZXDetectorResult, ZXWhiteRectangleDetector;
+
+/**
+ * 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.
+ */
+@interface ZXDataMatrixDetector : NSObject
+
+- (id)initWithImage:(ZXBitMatrix *)image error:(NSError **)error;
+
+/**
+ * Detects a Data Matrix Code in an image.
+ *
+ * @return ZXDetectorResult encapsulating results of detecting a Data Matrix Code or nil
+ * if no Data Matrix Code can be found
+ */
+- (ZXDetectorResult *)detectWithError:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m
new file mode 100644
index 0000000..ada6c2f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/detector/ZXDataMatrixDetector.m
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 ZXResultPointsAndTransitions : NSObject
+
+@property (nonatomic, strong, readonly) ZXResultPoint *from;
+@property (nonatomic, strong, readonly) ZXResultPoint *to;
+@property (nonatomic, assign, readonly) int transitions;
+
+@end
+
+@implementation ZXResultPointsAndTransitions
+
+- (id)initWithFrom:(ZXResultPoint *)from to:(ZXResultPoint *)to transitions:(int)transitions {
+ if (self = [super init]) {
+ _from = from;
+ _to = to;
+ _transitions = transitions;
+ }
+
+ return self;
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%@/%@/%d", self.from, self.to, self.transitions];
+}
+
+- (NSComparisonResult)compare:(ZXResultPointsAndTransitions *)otherObject {
+ return [@(self.transitions) compare:@(otherObject.transitions)];
+}
+
+@end
+
+
+@interface ZXDataMatrixDetector ()
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *image;
+@property (nonatomic, strong, readonly) 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;
+}
+
+- (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:)];
+
+ ZXResultPointsAndTransitions *lSideOne = (ZXResultPointsAndTransitions *)transitions[0];
+ ZXResultPointsAndTransitions *lSideTwo = (ZXResultPointsAndTransitions *)transitions[1];
+
+ NSMutableDictionary *pointCount = [NSMutableDictionary dictionary];
+ [self increment:pointCount key:[lSideOne from]];
+ [self increment:pointCount key:[lSideOne to]];
+ [self increment:pointCount key:[lSideTwo from]];
+ [self increment:pointCount key:[lSideTwo to]];
+
+ ZXResultPoint *maybeTopLeft = nil;
+ ZXResultPoint *bottomLeft = nil;
+ ZXResultPoint *maybeBottomRight = nil;
+ for (ZXResultPoint *point in [pointCount allKeys]) {
+ NSNumber *value = pointCount[point];
+ if ([value intValue] == 2) {
+ bottomLeft = point;
+ } else {
+ if (maybeTopLeft == nil) {
+ maybeTopLeft = point;
+ } else {
+ maybeBottomRight = point;
+ }
+ }
+ }
+
+ if (maybeTopLeft == nil || bottomLeft == nil || maybeBottomRight == nil) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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.
+ */
+- (ZXResultPointsAndTransitions *)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 / 2;
+ 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 [[ZXResultPointsAndTransitions alloc] initWithFrom:from to:to transitions:transitions];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixASCIIEncoder.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixASCIIEncoder.h
new file mode 100644
index 0000000..86ab58b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixASCIIEncoder.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 ZXDataMatrixASCIIEncoder : NSObject
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixASCIIEncoder.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixASCIIEncoder.m
new file mode 100644
index 0000000..9673c3f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixASCIIEncoder.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 "ZXDataMatrixASCIIEncoder.h"
+#import "ZXDataMatrixEncoderContext.h"
+#import "ZXDataMatrixHighLevelEncoder.h"
+
+@implementation ZXDataMatrixASCIIEncoder
+
+- (int)encodingMode {
+ return [ZXDataMatrixHighLevelEncoder asciiEncodation];
+}
+
+- (void)encode:(ZXDataMatrixEncoderContext *)context {
+ //step B
+ int n = [ZXDataMatrixHighLevelEncoder 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 = [ZXDataMatrixHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]];
+ if (newMode != [self encodingMode]) {
+ if (newMode == [ZXDataMatrixHighLevelEncoder base256Encodation]) {
+ [context writeCodeword:[ZXDataMatrixHighLevelEncoder latchToBase256]];
+ [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder base256Encodation]];
+ return;
+ } else if (newMode == [ZXDataMatrixHighLevelEncoder c40Encodation]) {
+ [context writeCodeword:[ZXDataMatrixHighLevelEncoder latchToC40]];
+ [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder c40Encodation]];
+ return;
+ } else if (newMode == [ZXDataMatrixHighLevelEncoder x12Encodation]) {
+ [context writeCodeword:[ZXDataMatrixHighLevelEncoder latchToAnsiX12]];
+ [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder x12Encodation]];
+ } else if (newMode == [ZXDataMatrixHighLevelEncoder textEncodation]) {
+ [context writeCodeword:[ZXDataMatrixHighLevelEncoder latchToText]];
+ [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder textEncodation]];
+ } else if (newMode == [ZXDataMatrixHighLevelEncoder edifactEncodation]) {
+ [context writeCodeword:[ZXDataMatrixHighLevelEncoder latchToEdifact]];
+ [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder edifactEncodation]];
+ } else {
+ @throw [NSException exceptionWithName:@"IllegalStateException" reason:@"Illegal mode" userInfo:nil];
+ }
+ } else if ([ZXDataMatrixHighLevelEncoder isExtendedASCII:c]) {
+ [context writeCodeword:[ZXDataMatrixHighLevelEncoder 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 ([ZXDataMatrixHighLevelEncoder isDigit:digit1] && [ZXDataMatrixHighLevelEncoder 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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.h
new file mode 100644
index 0000000..b5f73b3
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.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 ZXDataMatrixBase256Encoder : NSObject
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.m
new file mode 100644
index 0000000..ede8fa9
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixBase256Encoder.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 "ZXDataMatrixBase256Encoder.h"
+#import "ZXDataMatrixEncoderContext.h"
+#import "ZXDataMatrixHighLevelEncoder.h"
+#import "ZXDataMatrixSymbolInfo.h"
+
+@implementation ZXDataMatrixBase256Encoder
+
+- (int)encodingMode {
+ return [ZXDataMatrixHighLevelEncoder base256Encodation];
+}
+
+- (void)encode:(ZXDataMatrixEncoderContext *)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 = [ZXDataMatrixHighLevelEncoder 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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.h
new file mode 100644
index 0000000..edc98ae
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.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 ZXDataMatrixC40Encoder : NSObject
+
+- (int)encodeChar:(unichar)c buffer:(NSMutableString *)sb;
+- (void)writeNextTriplet:(ZXDataMatrixEncoderContext *)context buffer:(NSMutableString *)buffer;
+- (void)handleEOD:(ZXDataMatrixEncoderContext *)context buffer:(NSMutableString *)buffer;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.m
new file mode 100644
index 0000000..4a72603
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixC40Encoder.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 "ZXDataMatrixC40Encoder.h"
+#import "ZXDataMatrixEncoderContext.h"
+#import "ZXDataMatrixHighLevelEncoder.h"
+#import "ZXDataMatrixSymbolInfo.h"
+
+@implementation ZXDataMatrixC40Encoder
+
+- (int)encodingMode {
+ return [ZXDataMatrixHighLevelEncoder c40Encodation];
+}
+
+- (void)encode:(ZXDataMatrixEncoderContext *)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 = [ZXDataMatrixHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]];
+ if (newMode != [self encodingMode]) {
+ [context signalEncoderChange:newMode];
+ break;
+ }
+ }
+ }
+ [self handleEOD:context buffer:buffer];
+}
+
+- (int)backtrackOneCharacter:(ZXDataMatrixEncoderContext *)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:(ZXDataMatrixEncoderContext *)context buffer:(NSMutableString *)buffer {
+ [context writeCodewords:[self encodeToCodewords:buffer startpos:0]];
+ [buffer deleteCharactersInRange:NSMakeRange(0, 3)];
+}
+
+/**
+ * Handle "end of data" situations
+ */
+- (void)handleEOD:(ZXDataMatrixEncoderContext *)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:[ZXDataMatrixHighLevelEncoder c40Unlatch]];
+ }
+ } else if (available == 1 && rest == 1) {
+ while (buffer.length >= 3) {
+ [self writeNextTriplet:context buffer:buffer];
+ }
+ if ([context hasMoreCharacters]) {
+ [context writeCodeword:[ZXDataMatrixHighLevelEncoder 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:[ZXDataMatrixHighLevelEncoder c40Unlatch]];
+ }
+ } else {
+ @throw [NSException exceptionWithName:@"IllegalStateException"
+ reason:@"Unexpected case. Please report!"
+ userInfo:nil];
+ }
+ [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder 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 <= (unichar)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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.h
new file mode 100644
index 0000000..a7e0fc7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.h
@@ -0,0 +1,41 @@
+/*
+ * 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 ZXDataMatrixDefaultPlacement : 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;
+
+/**
+ * Main constructor
+ *
+ * @param codewords the codewords to place
+ * @param numcols the number of columns
+ * @param numrows the number of rows
+ */
+- (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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.m
new file mode 100644
index 0000000..5e1be92
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixDefaultPlacement.m
@@ -0,0 +1,181 @@
+/*
+ * 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 "ZXDataMatrixDefaultPlacement.h"
+
+@implementation ZXDataMatrixDefaultPlacement
+
+- (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.
+ *
+ * @param row the row
+ * @param col the column
+ * @param pos character position
+ */
+- (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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.h
new file mode 100644
index 0000000..20eea46
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.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 ZXDataMatrixEdifactEncoder : NSObject
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.m
new file mode 100644
index 0000000..81c5009
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEdifactEncoder.m
@@ -0,0 +1,142 @@
+/*
+ * 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 "ZXDataMatrixEdifactEncoder.h"
+#import "ZXDataMatrixEncoderContext.h"
+#import "ZXDataMatrixHighLevelEncoder.h"
+#import "ZXDataMatrixSymbolInfo.h"
+
+@implementation ZXDataMatrixEdifactEncoder
+
+- (int)encodingMode {
+ return [ZXDataMatrixHighLevelEncoder edifactEncodation];
+}
+
+- (void)encode:(ZXDataMatrixEncoderContext *)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 = [ZXDataMatrixHighLevelEncoder lookAheadTest:context.message startpos:context.pos currentMode:[self encodingMode]];
+ if (newMode != [self encodingMode]) {
+ [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder asciiEncodation]];
+ break;
+ }
+ }
+ }
+ [buffer appendFormat:@"%C", (unichar) 31]; //Unlatch
+ [self handleEOD:context buffer:buffer];
+}
+
+/**
+ * Handle "end of data" situations
+ *
+ * @param context the encoder context
+ * @param buffer the buffer with the remaining encoded characters
+ */
+- (void)handleEOD:(ZXDataMatrixEncoderContext *)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:[ZXDataMatrixHighLevelEncoder 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 {
+ [ZXDataMatrixHighLevelEncoder 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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoder.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoder.h
new file mode 100644
index 0000000..4d3c63d
--- /dev/null
+++ b/Pods/ZXingObjC/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 ZXDataMatrixEncoderContext;
+
+@protocol ZXDataMatrixEncoder
+
+- (int)encodingMode;
+- (void)encode:(ZXDataMatrixEncoderContext *)context;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoderContext.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoderContext.h
new file mode 100644
index 0000000..719a97d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoderContext.h
@@ -0,0 +1,48 @@
+/*
+ * 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 "ZXEncodeHints.h"
+
+@class ZXDataMatrixSymbolInfo, ZXDimension;
+
+@interface ZXDataMatrixEncoderContext : NSObject
+
+@property (nonatomic, copy, readonly) NSMutableString *codewords;
+@property (nonatomic, copy, readonly) NSString *message;
+@property (nonatomic, assign) int newEncoding;
+@property (nonatomic, assign) int pos;
+@property (nonatomic, assign) int skipAtEnd;
+@property (nonatomic, assign) ZXDataMatrixSymbolShapeHint symbolShape;
+@property (nonatomic, strong) ZXDataMatrixSymbolInfo *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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoderContext.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoderContext.m
new file mode 100644
index 0000000..5e699af
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixEncoderContext.m
@@ -0,0 +1,111 @@
+/*
+ * 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 "ZXDataMatrixEncoderContext.h"
+#import "ZXDataMatrixSymbolInfo.h"
+
+@interface ZXDataMatrixEncoderContext ()
+
+@property (nonatomic, strong) ZXDimension *maxSize;
+@property (nonatomic, strong) ZXDimension *minSize;
+
+@end
+
+@implementation ZXDataMatrixEncoderContext
+
+- (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 = ZXDataMatrixSymbolShapeHintForceNone;
+ _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 = [ZXDataMatrixSymbolInfo lookup:len shape:self.symbolShape minSize:self.minSize maxSize:self.maxSize fail:YES];
+ }
+}
+
+- (void)resetSymbolInfo {
+ self.symbolInfo = nil;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h
new file mode 100644
index 0000000..d93d3fd
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.h
@@ -0,0 +1,33 @@
+/*
+ * 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 ZXDataMatrixSymbolInfo;
+
+/**
+ * Error Correction Code for ECC200.
+ */
+@interface ZXDataMatrixErrorCorrection : NSObject
+
+/**
+ * Creates the ECC200 error correction for an encoded message.
+ *
+ * @param codewords the codewords
+ * @param symbolInfo information about the symbol to be encoded
+ * @return the codewords with interleaved error correction.
+ */
++ (NSString *)encodeECC200:(NSString *)codewords symbolInfo:(ZXDataMatrixSymbolInfo *)symbolInfo;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m
new file mode 100644
index 0000000..6c9f658
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixErrorCorrection.m
@@ -0,0 +1,171 @@
+/*
+ * 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 "ZXDataMatrixSymbolInfo.h"
+
+/**
+ * Lookup table which factors to use for which number of error correction codewords.
+ * See FACTORS.
+ */
+const int ZX_FACTOR_SETS[] = {5, 7, 10, 11, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 62, 68};
+
+/**
+ * Precomputed polynomial factors for ECC 200.
+ */
+const int ZX_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 ZX_MODULO_VALUE = 0x12D;
+
+static int ZX_LOG[256], ZX_ALOG[256];
+
+@implementation ZXDataMatrixErrorCorrection
+
++ (void)initialize {
+ if ([self class] != [ZXDataMatrixErrorCorrection class]) return;
+
+ //Create log and antilog table
+ int p = 1;
+ for (int i = 0; i < 255; i++) {
+ ZX_ALOG[i] = p;
+ ZX_LOG[p] = i;
+ p *= 2;
+ if (p >= 256) {
+ p ^= ZX_MODULO_VALUE;
+ }
+ }
+}
+
++ (NSString *)encodeECC200:(NSString *)codewords symbolInfo:(ZXDataMatrixSymbolInfo *)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)];
+ }
+ while (sb.length < capacity) {
+ [sb appendFormat:@"%C", (unichar)0];
+ }
+ 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 < sizeof(ZX_FACTOR_SETS) / sizeof(int); i++) {
+ if (ZX_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 *)ZX_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] ^ ZX_ALOG[(ZX_LOG[m] + ZX_LOG[poly[k]]) % 255]);
+ } else {
+ ecc[k] = ecc[k - 1];
+ }
+ }
+ if (m != 0 && poly[0] != 0) {
+ ecc[0] = (unichar) ZX_ALOG[(ZX_LOG[m] + ZX_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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.h
new file mode 100644
index 0000000..1273030
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.h
@@ -0,0 +1,135 @@
+/*
+ * 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 "ZXEncodeHints.h"
+
+@class ZXDimension;
+
+/**
+ * DataMatrix ECC 200 data encoder following the algorithm described in ISO/IEC 16022:200(E) in
+ * annex S.
+ */
+@interface ZXDataMatrixHighLevelEncoder : 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
+ *
+ * @param msg the message
+ * @return the byte array of the message
+ */
+
+/*
++ (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).
+ *
+ * @param msg the message
+ * @return the encoded message (the char values range from 0 to 255)
+ */
++ (NSString *)encodeHighLevel:(NSString *)msg;
+
+/**
+ * Performs message encoding of a DataMatrix message using the algorithm described in annex P
+ * of ISO/IEC 16022:2000(E).
+ *
+ * @param msg the message
+ * @param shape requested shape. May be {@code SymbolShapeHint.FORCE_NONE},
+ * {@code SymbolShapeHint.FORCE_SQUARE} or {@code SymbolShapeHint.FORCE_RECTANGLE}.
+ * @param minSize the minimum symbol size constraint or null for no constraint
+ * @param maxSize the maximum symbol size constraint or null for no constraint
+ * @return the encoded message (the char values range from 0 to 255)
+ */
++ (NSString *)encodeHighLevel:(NSString *)msg shape:(ZXDataMatrixSymbolShapeHint)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.
+ *
+ * @param msg the message
+ * @param startpos the start position within the message
+ * @return the requested character count
+ */
++ (int)determineConsecutiveDigitCount:(NSString *)msg startpos:(int)startpos;
+
++ (BOOL)isDigit:(unichar)ch;
++ (BOOL)isExtendedASCII:(unichar)ch;
++ (void)illegalCharacter:(unichar)c;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.m
new file mode 100644
index 0000000..b323d23
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixHighLevelEncoder.m
@@ -0,0 +1,431 @@
+/*
+ * 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 "ZXDataMatrixASCIIEncoder.h"
+#import "ZXDataMatrixBase256Encoder.h"
+#import "ZXDataMatrixC40Encoder.h"
+#import "ZXDataMatrixEdifactEncoder.h"
+#import "ZXDataMatrixEncoderContext.h"
+#import "ZXDataMatrixHighLevelEncoder.h"
+#import "ZXDataMatrixSymbolInfo.h"
+#import "ZXDataMatrixTextEncoder.h"
+#import "ZXDataMatrixX12Encoder.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 ZXDataMatrixHighLevelEncoder
+
++ (void)initialize {
+ if ([self class] != [ZXDataMatrixHighLevelEncoder class]) return;
+
+ 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:ZXDataMatrixSymbolShapeHintForceNone minSize:nil maxSize:nil];
+}
+
++ (NSString *)encodeHighLevel:(NSString *)msg shape:(ZXDataMatrixSymbolShapeHint)shape
+ minSize:(ZXDimension *)minSize maxSize:(ZXDimension *)maxSize {
+ //the codewords 0..255 are encoded as Unicode characters
+ NSArray *encoders = @[[[ZXDataMatrixASCIIEncoder alloc] init],
+ [[ZXDataMatrixC40Encoder alloc] init],
+ [[ZXDataMatrixTextEncoder alloc] init],
+ [[ZXDataMatrixX12Encoder alloc] init],
+ [[ZXDataMatrixEdifactEncoder alloc] init],
+ [[ZXDataMatrixBase256Encoder alloc] init]];
+
+ ZXDataMatrixEncoderContext *context = [[ZXDataMatrixEncoderContext 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 += (int)MACRO_05_HEADER.length;
+ } else if ([msg hasPrefix:MACRO_06_HEADER] && [msg hasSuffix:MACRO_TRAILER]) {
+ [context writeCodeword:[self macro06]];
+ [context setSkipAtEnd:2];
+ context.pos += (int)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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo.h
new file mode 100644
index 0000000..aa85076
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo.h
@@ -0,0 +1,63 @@
+/*
+ * 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 "ZXEncodeHints.h"
+
+@class ZXDimension;
+
+/**
+ * Symbol info table for DataMatrix.
+ */
+@interface ZXDataMatrixSymbolInfo : NSObject
+
+@property (nonatomic, assign, readonly) BOOL rectangular;
+@property (nonatomic, assign, readonly) int errorCodewords;
+@property (nonatomic, assign, readonly) int dataCapacity;
+@property (nonatomic, assign, readonly) int dataRegions;
+@property (nonatomic, assign, readonly) int matrixWidth;
+@property (nonatomic, assign, readonly) int matrixHeight;
+@property (nonatomic, assign, readonly) int rsBlockData;
+@property (nonatomic, assign, readonly) int rsBlockError;
+
+/**
+ * Overrides the symbol info set used by this class. Used for testing purposes.
+ *
+ * @param override the symbol info set to use
+ */
++ (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;
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords;
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords shape:(ZXDataMatrixSymbolShapeHint)shape;
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords allowRectangular:(BOOL)allowRectangular fail:(BOOL)fail;
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords shape:(ZXDataMatrixSymbolShapeHint)shape fail:(BOOL)fail;
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords shape:(ZXDataMatrixSymbolShapeHint)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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo.m
new file mode 100644
index 0000000..45d3c50
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo.m
@@ -0,0 +1,220 @@
+/*
+ * 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 "ZXDataMatrixSymbolInfo.h"
+#import "ZXDataMatrixSymbolInfo144.h"
+#import "ZXDimension.h"
+
+static NSArray *PROD_SYMBOLS = nil;
+static NSArray *symbols = nil;
+
+@implementation ZXDataMatrixSymbolInfo
+
++ (void)initialize {
+ if ([self class] != [ZXDataMatrixSymbolInfo class]) return;
+
+ PROD_SYMBOLS = @[[[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:3 errorCodewords:5 matrixWidth:8 matrixHeight:8 dataRegions:1],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:5 errorCodewords:7 matrixWidth:10 matrixHeight:10 dataRegions:1],
+ /*rect*/[[ZXDataMatrixSymbolInfo alloc] initWithRectangular:YES dataCapacity:5 errorCodewords:7 matrixWidth:16 matrixHeight:6 dataRegions:1],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:8 errorCodewords:10 matrixWidth:12 matrixHeight:12 dataRegions:1],
+ /*rect*/[[ZXDataMatrixSymbolInfo alloc] initWithRectangular:YES dataCapacity:10 errorCodewords:11 matrixWidth:14 matrixHeight:6 dataRegions:2],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:12 errorCodewords:12 matrixWidth:14 matrixHeight:14 dataRegions:1],
+ /*rect*/[[ZXDataMatrixSymbolInfo alloc] initWithRectangular:YES dataCapacity:16 errorCodewords:14 matrixWidth:24 matrixHeight:10 dataRegions:1],
+
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:18 errorCodewords:14 matrixWidth:16 matrixHeight:16 dataRegions:1],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:22 errorCodewords:18 matrixWidth:18 matrixHeight:18 dataRegions:1],
+ /*rect*/[[ZXDataMatrixSymbolInfo alloc] initWithRectangular:YES dataCapacity:22 errorCodewords:18 matrixWidth:16 matrixHeight:10 dataRegions:2],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:30 errorCodewords:20 matrixWidth:20 matrixHeight:20 dataRegions:1],
+ /*rect*/[[ZXDataMatrixSymbolInfo alloc] initWithRectangular:YES dataCapacity:32 errorCodewords:24 matrixWidth:16 matrixHeight:14 dataRegions:2],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:36 errorCodewords:24 matrixWidth:22 matrixHeight:22 dataRegions:1],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:44 errorCodewords:28 matrixWidth:24 matrixHeight:24 dataRegions:1],
+ /*rect*/[[ZXDataMatrixSymbolInfo alloc] initWithRectangular:YES dataCapacity:49 errorCodewords:28 matrixWidth:22 matrixHeight:14 dataRegions:2],
+
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:62 errorCodewords:36 matrixWidth:14 matrixHeight:14 dataRegions:4],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:86 errorCodewords:42 matrixWidth:16 matrixHeight:16 dataRegions:4],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:114 errorCodewords:48 matrixWidth:18 matrixHeight:18 dataRegions:4],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:144 errorCodewords:56 matrixWidth:20 matrixHeight:20 dataRegions:4],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:174 errorCodewords:68 matrixWidth:22 matrixHeight:22 dataRegions:4],
+
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:204 errorCodewords:84 matrixWidth:24 matrixHeight:24 dataRegions:4 rsBlockData:102 rsBlockError:42],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:280 errorCodewords:112 matrixWidth:14 matrixHeight:14 dataRegions:16 rsBlockData:140 rsBlockError:56],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:368 errorCodewords:144 matrixWidth:16 matrixHeight:16 dataRegions:16 rsBlockData:92 rsBlockError:36],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:456 errorCodewords:192 matrixWidth:18 matrixHeight:18 dataRegions:16 rsBlockData:114 rsBlockError:48],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:576 errorCodewords:224 matrixWidth:20 matrixHeight:20 dataRegions:16 rsBlockData:144 rsBlockError:56],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:696 errorCodewords:272 matrixWidth:22 matrixHeight:22 dataRegions:16 rsBlockData:174 rsBlockError:68],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:816 errorCodewords:336 matrixWidth:24 matrixHeight:24 dataRegions:16 rsBlockData:136 rsBlockError:56],
+ [[ZXDataMatrixSymbolInfo alloc] initWithRectangular:NO dataCapacity:1050 errorCodewords:408 matrixWidth:18 matrixHeight:18 dataRegions:36 rsBlockData:175 rsBlockError:68],
+ [[ZXDataMatrixSymbolInfo 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;
+}
+
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords {
+ return [self lookup:dataCodewords shape:ZXDataMatrixSymbolShapeHintForceNone fail:YES];
+}
+
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords shape:(ZXDataMatrixSymbolShapeHint)shape {
+ return [self lookup:dataCodewords shape:shape fail:YES];
+}
+
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords allowRectangular:(BOOL)allowRectangular fail:(BOOL)fail {
+ ZXDataMatrixSymbolShapeHint shape = allowRectangular
+ ? ZXDataMatrixSymbolShapeHintForceNone : ZXDataMatrixSymbolShapeHintForceSquare;
+ return [self lookup:dataCodewords shape:shape fail:fail];
+}
+
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords shape:(ZXDataMatrixSymbolShapeHint)shape fail:(BOOL)fail {
+ return [self lookup:dataCodewords shape:shape minSize:nil maxSize:nil fail:fail];
+}
+
++ (ZXDataMatrixSymbolInfo *)lookup:(int)dataCodewords shape:(ZXDataMatrixSymbolShapeHint)shape minSize:(ZXDimension *)minSize
+ maxSize:(ZXDimension *)maxSize fail:(BOOL)fail {
+ for (ZXDataMatrixSymbolInfo *symbol in symbols) {
+ if (shape == ZXDataMatrixSymbolShapeHintForceSquare && symbol.rectangular) {
+ continue;
+ }
+ if (shape == ZXDataMatrixSymbolShapeHintForceRectangle && !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/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.h
new file mode 100644
index 0000000..e9f82b5
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXDataMatrixSymbolInfo.h"
+
+@interface ZXDataMatrixSymbolInfo144 : ZXDataMatrixSymbolInfo
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.m
new file mode 100644
index 0000000..fa5af67
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixSymbolInfo144.m
@@ -0,0 +1,33 @@
+/*
+ * 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 {
+ return [super initWithRectangular:NO dataCapacity:1558 errorCodewords:620 matrixWidth:22 matrixHeight:22 dataRegions:36 rsBlockData:-1 rsBlockError:62];
+}
+
+- (int)interleavedBlockCount {
+ return 10;
+}
+
+- (int)dataLengthForInterleavedBlock:(int)index {
+ return (index <= 8) ? 156 : 155;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixTextEncoder.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixTextEncoder.h
new file mode 100644
index 0000000..4f82605
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixTextEncoder.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 "ZXDataMatrixC40Encoder.h"
+
+@interface ZXDataMatrixTextEncoder : ZXDataMatrixC40Encoder
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixTextEncoder.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixTextEncoder.m
new file mode 100644
index 0000000..d766c5d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixTextEncoder.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 "ZXDataMatrixHighLevelEncoder.h"
+#import "ZXDataMatrixTextEncoder.h"
+
+@implementation ZXDataMatrixTextEncoder
+
+- (int)encodingMode {
+ return [ZXDataMatrixHighLevelEncoder 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 <= (unichar)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 <= (unichar)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;
+ }
+ [ZXDataMatrixHighLevelEncoder illegalCharacter:c];
+ return -1;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.h b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.h
new file mode 100644
index 0000000..2c5dfea
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.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 "ZXDataMatrixC40Encoder.h"
+
+@interface ZXDataMatrixX12Encoder : ZXDataMatrixC40Encoder
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.m b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.m
new file mode 100644
index 0000000..b377531
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/datamatrix/encoder/ZXDataMatrixX12Encoder.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 "ZXDataMatrixEncoderContext.h"
+#import "ZXDataMatrixHighLevelEncoder.h"
+#import "ZXDataMatrixSymbolInfo.h"
+#import "ZXDataMatrixX12Encoder.h"
+
+@implementation ZXDataMatrixX12Encoder
+
+- (int)encodingMode {
+ return [ZXDataMatrixHighLevelEncoder x12Encodation];
+}
+
+- (void)encode:(ZXDataMatrixEncoderContext *)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 = [ZXDataMatrixHighLevelEncoder 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 {
+ [ZXDataMatrixHighLevelEncoder illegalCharacter:c];
+ }
+ return 1;
+}
+
+- (void)handleEOD:(ZXDataMatrixEncoderContext *)context buffer:(NSMutableString *)buffer {
+ [context updateSymbolInfo];
+ int available = context.symbolInfo.dataCapacity - [context codewordCount];
+ int count = (int)buffer.length;
+ context.pos -= count;
+ if (context.remainingCharacters > 1 || available > 1 ||
+ context.remainingCharacters != available) {
+ [context writeCodeword:[ZXDataMatrixHighLevelEncoder x12Unlatch]];
+ }
+ if (context.newEncoding < 0) {
+ [context signalEncoderChange:[ZXDataMatrixHighLevelEncoder asciiEncodation]];
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/maxicode/ZXMaxiCodeReader.h b/Pods/ZXingObjC/ZXingObjC/maxicode/ZXMaxiCodeReader.h
new file mode 100644
index 0000000..27f42b0
--- /dev/null
+++ b/Pods/ZXingObjC/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
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/maxicode/ZXMaxiCodeReader.m b/Pods/ZXingObjC/ZXingObjC/maxicode/ZXMaxiCodeReader.m
new file mode 100644
index 0000000..9bf2546
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/maxicode/ZXMaxiCodeReader.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 "ZXBinaryBitmap.h"
+#import "ZXBitMatrix.h"
+#import "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXIntArray.h"
+#import "ZXMaxiCodeDecoder.h"
+#import "ZXMaxiCodeReader.h"
+#import "ZXResult.h"
+
+const int ZX_MATRIX_WIDTH = 30;
+const int ZX_MATRIX_HEIGHT = 33;
+
+@interface ZXMaxiCodeReader ()
+
+@property (nonatomic, strong, readonly) ZXMaxiCodeDecoder *decoder;
+
+@end
+
+@implementation ZXMaxiCodeReader
+
+- (id)init {
+ if (self = [super init]) {
+ _decoder = [[ZXMaxiCodeDecoder alloc] init];
+ }
+
+ return self;
+}
+
+/**
+ * Locates and decodes a MaxiCode in an image.
+ *
+ * @return a String representing the content encoded by the MaxiCode
+ * @return nil if a MaxiCode cannot be found
+ * @return nil if a MaxiCode cannot be decoded
+ * @return nil if error correction fails
+ */
+- (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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ decoderResult = [self.decoder decode:bits hints:hints error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ } else {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ NSArray *points = @[];
+ ZXResult *result = [ZXResult resultWithText:decoderResult.text
+ rawBytes:decoderResult.rawBytes
+ 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 {
+ ZXIntArray *enclosingRectangle = image.enclosingRectangle;
+ if (enclosingRectangle == nil) {
+ return nil;
+ }
+
+ int left = enclosingRectangle.array[0];
+ int top = enclosingRectangle.array[1];
+ int width = enclosingRectangle.array[2];
+ int height = enclosingRectangle.array[3];
+
+ // Now just read off the bits
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithWidth:ZX_MATRIX_WIDTH height:ZX_MATRIX_HEIGHT];
+ for (int y = 0; y < ZX_MATRIX_HEIGHT; y++) {
+ int iy = top + (y * height + height / 2) / ZX_MATRIX_HEIGHT;
+ for (int x = 0; x < ZX_MATRIX_WIDTH; x++) {
+ int ix = left + (x * width + width / 2 + (y & 0x01) * width / 2) / ZX_MATRIX_WIDTH;
+ if ([image getX:ix y:iy]) {
+ [bits setX:x y:y];
+ }
+ }
+ }
+
+ return bits;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/maxicode/ZXingObjCMaxiCode.h b/Pods/ZXingObjC/ZXingObjC/maxicode/ZXingObjCMaxiCode.h
new file mode 100644
index 0000000..34b12ce
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/maxicode/ZXingObjCMaxiCode.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ZXINGOBJC_MAXICODE_
+
+#define _ZXINGOBJC_MAXICODE_
+
+#import "ZXMaxiCodeDecoder.h"
+#import "ZXMaxiCodeReader.h"
+
+#endif
diff --git a/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.h b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.h
new file mode 100644
index 0000000..da287f9
--- /dev/null
+++ b/Pods/ZXingObjC/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, ZXByteArray;
+
+@interface ZXMaxiCodeBitMatrixParser : NSObject
+
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error;
+- (ZXByteArray *)readCodewords;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.m b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.m
new file mode 100644
index 0000000..0ec8de9
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeBitMatrixParser.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 "ZXBitMatrix.h"
+#import "ZXByteArray.h"
+#import "ZXErrors.h"
+#import "ZXMaxiCodeBitMatrixParser.h"
+
+const int ZX_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, readonly) ZXBitMatrix *bitMatrix;
+
+@end
+
+@implementation ZXMaxiCodeBitMatrixParser
+
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error {
+ if (self = [super init]) {
+ _bitMatrix = bitMatrix;
+ }
+
+ return self;
+}
+
+- (ZXByteArray *)readCodewords {
+ ZXByteArray *result = [[ZXByteArray alloc] initWithLength:144];
+ int height = self.bitMatrix.height;
+ int width = self.bitMatrix.width;
+ for (int y = 0; y < height; y++) {
+ int *bitnrRow = (int *)ZX_BITNR[y];
+ for (int x = 0; x < width; x++) {
+ int bit = bitnrRow[x];
+ if (bit >= 0 && [self.bitMatrix getX:x y:y]) {
+ result.array[bit / 6] |= (int8_t) (1 << (5 - (bit % 6)));
+ }
+ }
+ }
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.h b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.h
new file mode 100644
index 0000000..6e824b9
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.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 ZXByteArray, ZXDecoderResult;
+
+/**
+ * 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.
+ */
+@interface ZXMaxiCodeDecodedBitStreamParser : NSObject
+
++ (ZXDecoderResult *)decode:(ZXByteArray *)bytes mode:(int)mode;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m
new file mode 100644
index 0000000..d2d95b6
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecodedBitStreamParser.m
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXByteArray.h"
+#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:(ZXByteArray *)bytes mode:(int)mode {
+ NSMutableString *result = [NSMutableString stringWithCapacity:144];
+ switch (mode) {
+ case 2:
+ case 3: {
+ NSString *postcode;
+ if (mode == 2) {
+ int pc = [self postCode2:bytes];
+ postcode = [NSString stringWithFormat:@"%9d", pc];
+ } else {
+ postcode = [self postCode3:bytes];
+ }
+ NSString *country = [NSString stringWithFormat:@"%3d", [self country:bytes]];
+ NSString *service = [NSString stringWithFormat:@"%3d", [self serviceClass:bytes]];
+ [result appendString:[self message:bytes 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 start:1 len:93]];
+ break;
+ case 5:
+ [result appendString:[self message:bytes start:1 len:77]];
+ break;
+ }
+ return [[ZXDecoderResult alloc] initWithRawBytes:bytes
+ text:result
+ byteSegments:nil
+ ecLevel:[NSString stringWithFormat:@"%d", mode]];
+}
+
++ (int)bit:(int)bit bytes:(ZXByteArray *)bytes {
+ bit--;
+ return (bytes.array[bit / 6] & (1 << (5 - (bit % 6)))) == 0 ? 0 : 1;
+}
+
++ (int)integer:(ZXByteArray *)bytes x:(ZXByteArray *)x {
+ int val = 0;
+ for (int i = 0; i < x.length; i++) {
+ val += [self bit:x.array[i] bytes:bytes] << (x.length - i - 1);
+ }
+ return val;
+}
+
++ (int)country:(ZXByteArray *)bytes {
+ return [self integer:bytes x:[[ZXByteArray alloc] initWithBytes:53, 54, 43, 44, 45, 46, 47, 48, 37, 38, -1]];
+}
+
++ (int)serviceClass:(ZXByteArray *)bytes {
+ return [self integer:bytes x:[[ZXByteArray alloc] initWithBytes:55, 56, 57, 58, 59, 60, 49, 50, 51, 52, -1]];
+}
+
++ (int)postCode2Length:(ZXByteArray *)bytes {
+ return [self integer:bytes x:[[ZXByteArray alloc] initWithBytes:39, 40, 41, 42, 31, 32, -1]];
+}
+
++ (int)postCode2:(ZXByteArray *)bytes {
+ return [self integer:bytes x:[[ZXByteArray alloc] initWithBytes: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, -1]];
+}
+
++ (NSString *)postCode3:(ZXByteArray *)bytes {
+ return [NSString stringWithFormat:@"%C%C%C%C%C%C",
+ SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:39, 40, 41, 42, 31, 32, -1]]],
+ SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:33, 34, 35, 36, 25, 26, -1]]],
+ SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:27, 28, 29, 30, 19, 20, -1]]],
+ SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:21, 22, 23, 24, 13, 14, -1]]],
+ SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:15, 16, 17, 18, 7, 8, -1]]],
+ SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes: 9, 10, 11, 12, 1, 2, -1]]]];
+}
+
++ (NSString *)message:(ZXByteArray *)bytes 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.array[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.array[++i] << 24;
+ int nsval2 = bytes.array[++i] << 18;
+ int nsval3 = bytes.array[++i] << 12;
+ int nsval4 = bytes.array[++i] << 6;
+ int nsval5 = bytes.array[++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/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.h b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.h
new file mode 100644
index 0000000..53f1e13
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.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 ZXBitMatrix, ZXDecodeHints, ZXDecoderResult;
+
+/**
+ * The main class which implements MaxiCode decoding -- as opposed to locating and extracting
+ * the MaxiCode from an image.
+ */
+@interface ZXMaxiCodeDecoder : NSObject
+
+- (ZXDecoderResult *)decode:(ZXBitMatrix *)bits error:(NSError **)error;
+- (ZXDecoderResult *)decode:(ZXBitMatrix *)bits hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.m b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.m
new file mode 100644
index 0000000..a74de8c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/maxicode/decoder/ZXMaxiCodeDecoder.m
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXByteArray.h"
+#import "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXGenericGF.h"
+#import "ZXIntArray.h"
+#import "ZXMaxiCodeBitMatrixParser.h"
+#import "ZXMaxiCodeDecodedBitStreamParser.h"
+#import "ZXMaxiCodeDecoder.h"
+#import "ZXReedSolomonDecoder.h"
+
+const int ZX_MAXI_CODE_ALL = 0;
+const int ZX_MAXI_CODE_EVEN = 1;
+const int ZX_MAXI_CODE_ODD = 2;
+
+@interface ZXMaxiCodeDecoder ()
+
+@property (nonatomic, strong, readonly) 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;
+ }
+ ZXByteArray *codewords = [parser readCodewords];
+
+ if (![self correctErrors:codewords start:0 dataCodewords:10 ecCodewords:10 mode:ZX_MAXI_CODE_ALL error:error]) {
+ return nil;
+ }
+ int mode = codewords.array[0] & 0x0F;
+ ZXByteArray *datawords;
+ switch (mode) {
+ case 2:
+ case 3:
+ case 4:
+ if (![self correctErrors:codewords start:20 dataCodewords:84 ecCodewords:40 mode:ZX_MAXI_CODE_EVEN error:error]) {
+ return nil;
+ }
+ if (![self correctErrors:codewords start:20 dataCodewords:84 ecCodewords:40 mode:ZX_MAXI_CODE_ODD error:error]) {
+ return nil;
+ }
+ datawords = [[ZXByteArray alloc] initWithLength:94];
+ break;
+ case 5:
+ if (![self correctErrors:codewords start:20 dataCodewords:68 ecCodewords:56 mode:ZX_MAXI_CODE_EVEN error:error]) {
+ return nil;
+ }
+ if (![self correctErrors:codewords start:20 dataCodewords:68 ecCodewords:56 mode:ZX_MAXI_CODE_ODD error:error]) {
+ return nil;
+ }
+ datawords = [[ZXByteArray alloc] initWithLength:78];
+ break;
+ default:
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ for (int i = 0; i < 10; i++) {
+ datawords.array[i] = codewords.array[i];
+ }
+ for (int i = 20; i < datawords.length + 10; i++) {
+ datawords.array[i - 10] = codewords.array[i];
+ }
+
+ return [ZXMaxiCodeDecodedBitStreamParser decode:datawords mode:mode];
+}
+
+- (BOOL)correctErrors:(ZXByteArray *)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 == ZX_MAXI_CODE_ALL ? 1 : 2;
+
+ // First read into an array of ints
+ ZXIntArray *codewordsInts = [[ZXIntArray alloc] initWithLength:codewords / divisor];
+ for (int i = 0; i < codewords; i++) {
+ if ((mode == ZX_MAXI_CODE_ALL) || (i % 2 == (mode - 1))) {
+ codewordsInts.array[i / divisor] = codewordBytes.array[i + start] & 0xFF;
+ }
+ }
+
+ NSError *decodeError = nil;
+ if (![self.rsDecoder decode:codewordsInts twoS:ecCodewords / divisor error:&decodeError]) {
+ if (decodeError.code == ZXReedSolomonError && error) {
+ *error = ZXChecksumErrorInstance();
+ }
+ 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 == ZX_MAXI_CODE_ALL) || (i % 2 == (mode - 1))) {
+ codewordBytes.array[i + start] = (int8_t) codewordsInts.array[i / divisor];
+ }
+ }
+
+ return YES;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/multi/ZXByQuadrantReader.h b/Pods/ZXingObjC/ZXingObjC/multi/ZXByQuadrantReader.h
new file mode 100644
index 0000000..8de8442
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/multi/ZXByQuadrantReader.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 "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
+
+- (id)initWithDelegate:(id)delegate;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/multi/ZXByQuadrantReader.m b/Pods/ZXingObjC/ZXingObjC/multi/ZXByQuadrantReader.m
new file mode 100644
index 0000000..22f009f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/multi/ZXByQuadrantReader.m
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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"
+#import "ZXResultPoint.h"
+
+@interface ZXByQuadrantReader ()
+
+@property (nonatomic, weak, readonly) id delegate;
+
+@end
+
+@implementation ZXByQuadrantReader
+
+- (id)initWithDelegate:(id)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;
+
+ // No need to call makeAbsolute as results will be relative to original top left here
+ NSError *decodeError = nil;
+ ZXResult *result = [self.delegate decode:[image crop:0 top:0 width:halfWidth height:halfHeight]
+ hints:hints
+ error:&decodeError];
+ if (result) {
+ return result;
+ } else if (decodeError.code != ZXNotFoundError) {
+ if (error) *error = decodeError;
+ return nil;
+ }
+
+ decodeError = nil;
+ result = [self.delegate decode:[image crop:halfWidth top:0 width:halfWidth height:halfHeight]
+ hints:hints
+ error:&decodeError];
+ if (result) {
+ [self makeAbsolute:result.resultPoints leftOffset:halfWidth topOffset:0];
+ return result;
+ } else if (decodeError.code != ZXNotFoundError) {
+ if (error) *error = decodeError;
+ return nil;
+ }
+
+ decodeError = nil;
+ result = [self.delegate decode:[image crop:0 top:halfHeight width:halfWidth height:halfHeight]
+ hints:hints
+ error:&decodeError];
+ if (result) {
+ [self makeAbsolute:result.resultPoints leftOffset:0 topOffset:halfHeight];
+ return result;
+ } else if (decodeError.code != ZXNotFoundError) {
+ if (error) *error = decodeError;
+ return nil;
+ }
+
+ decodeError = nil;
+ result = [self.delegate decode:[image crop:halfWidth top:halfHeight width:halfWidth height:halfHeight]
+ hints:hints
+ error:&decodeError];
+ if (result) {
+ [self makeAbsolute:result.resultPoints leftOffset:halfWidth topOffset:halfHeight];
+ 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];
+ result = [self.delegate decode:center hints:hints error:error];
+ if (result) {
+ [self makeAbsolute:result.resultPoints leftOffset:quarterWidth topOffset:quarterHeight];
+ }
+ return result;
+}
+
+- (void)reset {
+ [self.delegate reset];
+}
+
+- (void)makeAbsolute:(NSMutableArray *)points leftOffset:(int)leftOffset topOffset:(int)topOffset {
+ if (points) {
+ for (int i = 0; i < points.count; i++) {
+ ZXResultPoint *relative = points[i];
+ points[i] = [[ZXResultPoint alloc] initWithX:relative.x + leftOffset y:relative.y + topOffset];
+ }
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.h b/Pods/ZXingObjC/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.h
new file mode 100644
index 0000000..68ed611
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.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 "ZXMultipleBarcodeReader.h"
+
+@protocol ZXReader;
+
+/**
+ * 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].
+ */
+@interface ZXGenericMultipleBarcodeReader : NSObject
+
+- (id)initWithDelegate:(id)delegate;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m b/Pods/ZXingObjC/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m
new file mode 100644
index 0000000..3c2680c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/multi/ZXGenericMultipleBarcodeReader.m
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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"
+
+const int ZX_MIN_DIMENSION_TO_RECUR = 100;
+const int ZX_MAX_DEPTH = 4;
+
+@interface ZXGenericMultipleBarcodeReader ()
+
+@property (nonatomic, weak, readonly) id delegate;
+
+@end
+
+@implementation ZXGenericMultipleBarcodeReader
+
+- (id)initWithDelegate:(id)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 = ZXNotFoundErrorInstance();
+ 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 > ZX_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) {
+ if ((id)point == [NSNull null]) {
+ continue;
+ }
+ 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 > ZX_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 > ZX_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 - ZX_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 - ZX_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) {
+ if ((id)oldPoint != [NSNull null]) {
+ [newResultPoints addObject:[[ZXResultPoint alloc] initWithX:[oldPoint x] + xOffset y:[oldPoint y] + yOffset]];
+ }
+ }
+
+ ZXResult *newResult = [ZXResult resultWithText:result.text rawBytes:result.rawBytes resultPoints:newResultPoints format:result.barcodeFormat];
+ [newResult putAllMetadata:result.resultMetadata];
+ return newResult;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/multi/ZXMultipleBarcodeReader.h b/Pods/ZXingObjC/ZXingObjC/multi/ZXMultipleBarcodeReader.h
new file mode 100644
index 0000000..b7766f3
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/multi/ZXMultipleBarcodeReader.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 "ZXBinaryBitmap.h"
+#import "ZXResult.h"
+
+@class ZXDecodeHints;
+
+/**
+ * Implementation of this interface attempt to read several barcodes from one image.
+ */
+@protocol ZXMultipleBarcodeReader
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error;
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarReader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarReader.h
new file mode 100644
index 0000000..cda00d1
--- /dev/null
+++ b/Pods/ZXingObjC/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 ZX_CODA_ALPHABET_LEN;
+extern const unichar ZX_CODA_ALPHABET[];
+extern const int ZX_CODA_CHARACTER_ENCODINGS[];
+
+@class ZXBitArray, ZXDecodeHints, ZXResult;
+
+/**
+ * Decodes Codabar barcodes.
+ */
+@interface ZXCodaBarReader : ZXOneDReader
+
++ (BOOL)arrayContains:(const unichar *)array length:(unsigned int)length key:(unichar)key;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarReader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarReader.m
new file mode 100644
index 0000000..0c3b001
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarReader.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 "ZXBitArray.h"
+#import "ZXCodaBarReader.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXIntArray.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 float ZX_CODA_MAX_ACCEPTABLE = 2.0f;
+static float ZX_CODA_PADDING = 1.5f;
+
+const unichar ZX_CODA_ALPHABET[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '-', '$', ':', '/', '.', '+', 'A', 'B', 'C', 'D', 'T', 'N'};
+const int ZX_CODA_ALPHABET_LEN = sizeof(ZX_CODA_ALPHABET) / sizeof(unichar);
+
+/**
+ * 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 ZX_CODA_CHARACTER_ENCODINGS[] = {
+ 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 ZX_CODA_MIN_CHARACTER_LENGTH = 3;
+
+// official start and end patterns
+const unichar ZX_CODA_STARTEND_ENCODING[] = {'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, strong) ZXIntArray *counters;
+@property (nonatomic, assign) int counterLength;
+
+@end
+
+@implementation ZXCodaBarReader
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeRowResult = [NSMutableString stringWithCapacity:20];
+ _counters = [[ZXIntArray alloc] initWithLength:80];
+ _counterLength = 0;
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ [self.counters clear];
+
+ if (![self setCountersWithRow:row]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ int startOffset = [self findStartPattern];
+ if (startOffset == -1) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ int nextStart = startOffset;
+
+ self.decodeRowResult = [NSMutableString string];
+ do {
+ int charOffset = [self toNarrowWidePattern:nextStart];
+ if (charOffset == -1) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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:ZX_CODA_STARTEND_ENCODING
+ length:sizeof(ZX_CODA_STARTEND_ENCODING) / sizeof(unichar)
+ key:ZX_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.array[nextStart - 1];
+ int lastPatternSize = 0;
+ for (int i = -8; i < -1; i++) {
+ lastPatternSize += self.counters.array[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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ if (![self validatePattern:startOffset]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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", ZX_CODA_ALPHABET[[self.decodeRowResult characterAtIndex:i]]]];
+ }
+ // Ensure a valid start and end character
+ unichar startchar = [self.decodeRowResult characterAtIndex:0];
+ if (![ZXCodaBarReader arrayContains:ZX_CODA_STARTEND_ENCODING
+ length:sizeof(ZX_CODA_STARTEND_ENCODING) / sizeof(unichar)
+ key:startchar]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ unichar endchar = [self.decodeRowResult characterAtIndex:self.decodeRowResult.length - 1];
+ if (![ZXCodaBarReader arrayContains:ZX_CODA_STARTEND_ENCODING
+ length:sizeof(ZX_CODA_STARTEND_ENCODING) / sizeof(unichar)
+ key:endchar]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ // remove stop/start characters character and check if a long enough string is contained
+ if (self.decodeRowResult.length <= ZX_CODA_MIN_CHARACTER_LENGTH) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ if (!hints.returnCodaBarStartEnd) {
+ [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.array[i];
+ }
+ float left = (float) runningCount;
+ for (int i = startOffset; i < nextStart - 1; i++) {
+ runningCount += self.counters.array[i];
+ }
+ float right = (float) runningCount;
+ return [ZXResult resultWithText:self.decodeRowResult
+ rawBytes:nil
+ 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 = ZX_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.array[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.
+ float maxes[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ float mins[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ // 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.0f; // Accept arbitrarily small "short" stripes.
+ mins[i + 2] = ((float) sizes[i] / counts[i] + (float) sizes[i + 2] / counts[i + 2]) / 2.0f;
+ maxes[i] = mins[i + 2];
+ maxes[i + 2] = (sizes[i + 2] * ZX_CODA_MAX_ACCEPTABLE + ZX_CODA_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 = ZX_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.array[pos + j];
+ 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;
+ while (i < end) {
+ if ([row get:i] ^ isWhite) { // that is, exactly one is true
+ count++;
+ } else {
+ [self counterAppend:count];
+ count = 1;
+ isWhite = !isWhite;
+ }
+ i++;
+ }
+ [self counterAppend:count];
+ return YES;
+}
+
+- (void)counterAppend:(int)e {
+ self.counters.array[self.counterLength] = e;
+ self.counterLength++;
+ if (self.counterLength >= self.counters.length) {
+ ZXIntArray *temp = [[ZXIntArray alloc] initWithLength:self.counterLength * 2];
+ memcpy(temp.array, self.counters.array, self.counters.length * sizeof(int32_t));
+ self.counters = temp;
+ }
+}
+
+- (int)findStartPattern {
+ for (int i = 1; i < self.counterLength; i += 2) {
+ int charOffset = [self toNarrowWidePattern:i];
+ if (charOffset != -1 && [[self class] arrayContains:ZX_CODA_STARTEND_ENCODING
+ length:sizeof(ZX_CODA_STARTEND_ENCODING) / sizeof(unichar)
+ key:ZX_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.array[j];
+ }
+ if (i == 1 || self.counters.array[i-1] >= patternSize / 2) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+
++ (BOOL)arrayContains:(const unichar *)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 {
+ int32_t *array = self.counters.array;
+ 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 = array[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 = array[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 (array[position + i] > threshold) {
+ pattern |= bitmask;
+ }
+ }
+
+ for (int i = 0; i < sizeof(ZX_CODA_CHARACTER_ENCODINGS) / sizeof(int); i++) {
+ if (ZX_CODA_CHARACTER_ENCODINGS[i] == pattern) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarWriter.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarWriter.h
new file mode 100644
index 0000000..c28a007
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarWriter.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 "ZXOneDimensionalCodeWriter.h"
+
+/**
+ * This class renders CodaBar as ZXBoolArray.
+ */
+@interface ZXCodaBarWriter : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarWriter.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarWriter.m
new file mode 100644
index 0000000..20f5d9b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCodaBarWriter.m
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXBoolArray.h"
+#import "ZXCodaBarReader.h"
+#import "ZXCodaBarWriter.h"
+
+const unichar ZX_CODA_START_END_CHARS[] = {'A', 'B', 'C', 'D'};
+const unichar ZX_CODA_ALT_START_END_CHARS[] = {'T', 'N', '*', 'E'};
+const unichar ZX_CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED[] = {'/', ':', '+', '.'};
+static unichar ZX_CODA_DEFAULT_GUARD;
+
+@implementation ZXCodaBarWriter
+
++ (void)initialize {
+ if ([self class] != [ZXCodaBarWriter class]) return;
+
+ ZX_CODA_DEFAULT_GUARD = ZX_CODA_START_END_CHARS[0];
+}
+
+- (ZXBoolArray *)encode:(NSString *)contents {
+ if ([contents length] < 2) {
+ // Can't have a start/end guard, so tentatively add default guards
+ contents = [NSString stringWithFormat:@"%C%@%C", ZX_CODA_DEFAULT_GUARD, contents, ZX_CODA_DEFAULT_GUARD];
+ } else {
+ // Verify input and calculate decoded length.
+ unichar firstChar = [[contents uppercaseString] characterAtIndex:0];
+ unichar lastChar = [[contents uppercaseString] characterAtIndex:contents.length - 1];
+ BOOL startsNormal = [ZXCodaBarReader arrayContains:ZX_CODA_START_END_CHARS length:sizeof(ZX_CODA_START_END_CHARS) / sizeof(unichar) key:firstChar];
+ BOOL endsNormal = [ZXCodaBarReader arrayContains:ZX_CODA_START_END_CHARS length:sizeof(ZX_CODA_START_END_CHARS) / sizeof(unichar) key:lastChar];
+ BOOL startsAlt = [ZXCodaBarReader arrayContains:ZX_CODA_ALT_START_END_CHARS length:sizeof(ZX_CODA_ALT_START_END_CHARS) / sizeof(unichar) key:firstChar];
+ BOOL endsAlt = [ZXCodaBarReader arrayContains:ZX_CODA_ALT_START_END_CHARS length:sizeof(ZX_CODA_ALT_START_END_CHARS) / sizeof(unichar) key:lastChar];
+ if (startsNormal) {
+ if (!endsNormal) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Invalid start/end guards: %@", contents]
+ userInfo:nil];
+ }
+ // else already has valid start/end
+ } else if (startsAlt) {
+ if (!endsAlt) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Invalid start/end guards: %@", contents]
+ userInfo:nil];
+ }
+ // else already has valid start/end
+ } else {
+ // Doesn't start with a guard
+ if (endsNormal || endsAlt) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:[NSString stringWithFormat:@"Invalid start/end guards: %@", contents]
+ userInfo:nil];
+ }
+ // else doesn't end with guard either, so add a default
+ contents = [NSString stringWithFormat:@"%C%@%C", ZX_CODA_DEFAULT_GUARD, contents, ZX_CODA_DEFAULT_GUARD];
+ }
+ }
+
+ // The start character and the end character are decoded to 10 length each.
+ int resultLength = 20;
+ 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:ZX_CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED 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;
+
+ ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:resultLength];
+ int position = 0;
+ for (int index = 0; index < contents.length; index++) {
+ unichar c = [[contents uppercaseString] characterAtIndex:index];
+ if (index == 0 || index == contents.length - 1) {
+ // The start/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 < ZX_CODA_ALPHABET_LEN; i++) {
+ // Found any, because I checked above.
+ if (c == ZX_CODA_ALPHABET[i]) {
+ code = ZX_CODA_CHARACTER_ENCODINGS[i];
+ break;
+ }
+ }
+ BOOL color = YES;
+ int counter = 0;
+ int bit = 0;
+ while (bit < 7) { // A character consists of 7 digit.
+ result.array[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.array[position] = NO;
+ position++;
+ }
+ }
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Reader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Reader.h
new file mode 100644
index 0000000..ff0a0c8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Reader.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 "ZXOneDReader.h"
+
+extern const int ZX_CODE128_CODE_PATTERNS[][7];
+
+extern const int ZX_CODE128_CODE_START_B;
+extern const int ZX_CODE128_CODE_START_C;
+extern const int ZX_CODE128_CODE_CODE_B;
+extern const int ZX_CODE128_CODE_CODE_C;
+extern const int ZX_CODE128_CODE_STOP;
+
+extern const int ZX_CODE128_CODE_FNC_1;
+extern const int ZX_CODE128_CODE_FNC_2;
+extern const int ZX_CODE128_CODE_FNC_3;
+extern const int ZX_CODE128_CODE_FNC_4_A;
+extern const int ZX_CODE128_CODE_FNC_4_B;
+
+@class ZXDecodeHints, ZXResult;
+
+/**
+ * Decodes Code 128 barcodes.
+ */
+@interface ZXCode128Reader : ZXOneDReader
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Reader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Reader.m
new file mode 100644
index 0000000..90d2574
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Reader.m
@@ -0,0 +1,534 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXByteArray.h"
+#import "ZXCode128Reader.h"
+#import "ZXDecodeHints.h"
+#import "ZXErrors.h"
+#import "ZXIntArray.h"
+#import "ZXOneDReader.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+const int ZX_CODE128_CODE_PATTERNS_LEN = 107;
+const int ZX_CODE128_CODE_PATTERNS[ZX_CODE128_CODE_PATTERNS_LEN][7] = {
+ {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 float ZX_CODE128_MAX_AVG_VARIANCE = 0.25f;
+static float ZX_CODE128_MAX_INDIVIDUAL_VARIANCE = 0.7f;
+
+const int ZX_CODE128_CODE_SHIFT = 98;
+const int ZX_CODE128_CODE_CODE_C = 99;
+const int ZX_CODE128_CODE_CODE_B = 100;
+const int ZX_CODE128_CODE_CODE_A = 101;
+const int ZX_CODE128_CODE_FNC_1 = 102;
+const int ZX_CODE128_CODE_FNC_2 = 97;
+const int ZX_CODE128_CODE_FNC_3 = 96;
+const int ZX_CODE128_CODE_FNC_4_A = 101;
+const int ZX_CODE128_CODE_FNC_4_B = 100;
+const int ZX_CODE128_CODE_START_A = 103;
+const int ZX_CODE128_CODE_START_B = 104;
+const int ZX_CODE128_CODE_START_C = 105;
+const int ZX_CODE128_CODE_STOP = 106;
+
+@implementation ZXCode128Reader
+
+- (ZXIntArray *)findStartPattern:(ZXBitArray *)row {
+ int width = row.size;
+ int rowOffset = [row nextSet:0];
+
+ int counterPosition = 0;
+ ZXIntArray *counters = [[ZXIntArray alloc] initWithLength:6];
+ int32_t *array = counters.array;
+ int patternStart = rowOffset;
+ BOOL isWhite = NO;
+ int patternLength = (int)counters.length;
+
+ for (int i = rowOffset; i < width; i++) {
+ if ([row get:i] ^ isWhite) {
+ array[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ float bestVariance = ZX_CODE128_MAX_AVG_VARIANCE;
+ int bestMatch = -1;
+ for (int startCode = ZX_CODE128_CODE_START_A; startCode <= ZX_CODE128_CODE_START_C; startCode++) {
+ float variance = [ZXOneDReader patternMatchVariance:counters pattern:ZX_CODE128_CODE_PATTERNS[startCode] maxIndividualVariance:ZX_CODE128_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 [[ZXIntArray alloc] initWithInts:patternStart, i, bestMatch, -1];
+ }
+ patternStart += array[0] + array[1];
+ for (int y = 2; y < patternLength; y++) {
+ array[y - 2] = array[y];
+ }
+ array[patternLength - 2] = 0;
+ array[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ array[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return nil;
+}
+
+- (int)decodeCode:(ZXBitArray *)row counters:(ZXIntArray *)counters rowOffset:(int)rowOffset {
+ if (![ZXOneDReader recordPattern:row start:rowOffset counters:counters]) {
+ return -1;
+ }
+ float bestVariance = ZX_CODE128_MAX_AVG_VARIANCE;
+ int bestMatch = -1;
+
+ for (int d = 0; d < ZX_CODE128_CODE_PATTERNS_LEN; d++) {
+ float variance = [ZXOneDReader patternMatchVariance:counters pattern:ZX_CODE128_CODE_PATTERNS[d] maxIndividualVariance:ZX_CODE128_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;
+
+ ZXIntArray *startPatternInfo = [self findStartPattern:row];
+ if (!startPatternInfo) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ int startCode = startPatternInfo.array[2];
+ int codeSet;
+
+ NSMutableArray *rawCodes = [NSMutableArray arrayWithObject:@(startCode)];
+
+ switch (startCode) {
+ case ZX_CODE128_CODE_START_A:
+ codeSet = ZX_CODE128_CODE_CODE_A;
+ break;
+ case ZX_CODE128_CODE_START_B:
+ codeSet = ZX_CODE128_CODE_CODE_B;
+ break;
+ case ZX_CODE128_CODE_START_C:
+ codeSet = ZX_CODE128_CODE_CODE_C;
+ break;
+ default:
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+
+ BOOL done = NO;
+ BOOL isNextShifted = NO;
+
+ NSMutableString *result = [NSMutableString stringWithCapacity:20];
+
+ int lastStart = startPatternInfo.array[0];
+ int nextStart = startPatternInfo.array[1];
+ ZXIntArray *counters = [[ZXIntArray alloc] initWithLength:6];
+
+ int lastCode = 0;
+ int code = 0;
+ int checksumTotal = startCode;
+ int multiplier = 0;
+ BOOL lastCharacterWasPrintable = YES;
+ BOOL upperMode = NO;
+ BOOL shiftUpperMode = NO;
+
+ while (!done) {
+ BOOL unshift = isNextShifted;
+ isNextShifted = NO;
+
+ // Save off last code
+ lastCode = code;
+
+ // Decode another code from image
+ code = [self decodeCode:row counters:counters rowOffset:nextStart];
+ if (code == -1) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ [rawCodes addObject:@(code)];
+
+ // Remember whether the last code was printable or not (excluding ZX_CODE128_CODE_STOP)
+ if (code != ZX_CODE128_CODE_STOP) {
+ lastCharacterWasPrintable = YES;
+ }
+
+ // Add to checksum computation (if not ZX_CODE128_CODE_STOP of course)
+ if (code != ZX_CODE128_CODE_STOP) {
+ multiplier++;
+ checksumTotal += multiplier * code;
+ }
+
+ // Advance to where the next code will to start
+ lastStart = nextStart;
+ nextStart += [counters sum];
+
+ // Take care of illegal start codes
+ switch (code) {
+ case ZX_CODE128_CODE_START_A:
+ case ZX_CODE128_CODE_START_B:
+ case ZX_CODE128_CODE_START_C:
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+
+ switch (codeSet) {
+ case ZX_CODE128_CODE_CODE_A:
+ if (code < 64) {
+ if (shiftUpperMode == upperMode) {
+ [result appendFormat:@"%C", (unichar)(' ' + code)];
+ } else {
+ [result appendFormat:@"%C", (unichar)(' ' + code + 128)];
+ }
+ shiftUpperMode = NO;
+ } else if (code < 96) {
+ if (shiftUpperMode == upperMode) {
+ [result appendFormat:@"%C", (unichar)(code - 64)];
+ } else {
+ [result appendFormat:@"%C", (unichar)(code + 64)];
+ }
+ shiftUpperMode = NO;
+ } else {
+ // Don't let CODE_STOP, which always appears, affect whether whether we think the last
+ // code was printable or not.
+ if (code != ZX_CODE128_CODE_STOP) {
+ lastCharacterWasPrintable = NO;
+ }
+
+ switch (code) {
+ case ZX_CODE128_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", (unichar) 29];
+ }
+ }
+ break;
+ case ZX_CODE128_CODE_FNC_2:
+ case ZX_CODE128_CODE_FNC_3:
+ // do nothing?
+ break;
+ case ZX_CODE128_CODE_FNC_4_A:
+ if (!upperMode && shiftUpperMode) {
+ upperMode = YES;
+ shiftUpperMode = NO;
+ } else if (upperMode && shiftUpperMode) {
+ upperMode = NO;
+ shiftUpperMode = NO;
+ } else {
+ shiftUpperMode = YES;
+ }
+ break;
+ case ZX_CODE128_CODE_SHIFT:
+ isNextShifted = YES;
+ codeSet = ZX_CODE128_CODE_CODE_B;
+ break;
+ case ZX_CODE128_CODE_CODE_B:
+ codeSet = ZX_CODE128_CODE_CODE_B;
+ break;
+ case ZX_CODE128_CODE_CODE_C:
+ codeSet = ZX_CODE128_CODE_CODE_C;
+ break;
+ case ZX_CODE128_CODE_STOP:
+ done = YES;
+ break;
+ }
+ }
+ break;
+ case ZX_CODE128_CODE_CODE_B:
+ if (code < 96) {
+ if (shiftUpperMode == upperMode) {
+ [result appendFormat:@"%C", (unichar)(' ' + code)];
+ } else {
+ [result appendFormat:@"%C", (unichar)(' ' + code + 128)];
+ }
+ shiftUpperMode = NO;
+ } else {
+ if (code != ZX_CODE128_CODE_STOP) {
+ lastCharacterWasPrintable = NO;
+ }
+
+ switch (code) {
+ case ZX_CODE128_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", (unichar) 29];
+ }
+ }
+ break;
+ case ZX_CODE128_CODE_FNC_2:
+ case ZX_CODE128_CODE_FNC_3:
+ // do nothing?
+ break;
+ case ZX_CODE128_CODE_FNC_4_B:
+ if (!upperMode && shiftUpperMode) {
+ upperMode = YES;
+ shiftUpperMode = NO;
+ } else if (upperMode && shiftUpperMode) {
+ upperMode = NO;
+ shiftUpperMode = NO;
+ } else {
+ shiftUpperMode = YES;
+ }
+ break;
+ case ZX_CODE128_CODE_SHIFT:
+ isNextShifted = YES;
+ codeSet = ZX_CODE128_CODE_CODE_A;
+ break;
+ case ZX_CODE128_CODE_CODE_A:
+ codeSet = ZX_CODE128_CODE_CODE_A;
+ break;
+ case ZX_CODE128_CODE_CODE_C:
+ codeSet = ZX_CODE128_CODE_CODE_C;
+ break;
+ case ZX_CODE128_CODE_STOP:
+ done = YES;
+ break;
+ }
+ }
+ break;
+ case ZX_CODE128_CODE_CODE_C:
+ if (code < 100) {
+ if (code < 10) {
+ [result appendString:@"0"];
+ }
+ [result appendFormat:@"%d", code];
+ } else {
+ if (code != ZX_CODE128_CODE_STOP) {
+ lastCharacterWasPrintable = NO;
+ }
+
+ switch (code) {
+ case ZX_CODE128_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", (unichar) 29];
+ }
+ }
+ break;
+ case ZX_CODE128_CODE_CODE_A:
+ codeSet = ZX_CODE128_CODE_CODE_A;
+ break;
+ case ZX_CODE128_CODE_CODE_B:
+ codeSet = ZX_CODE128_CODE_CODE_B;
+ break;
+ case ZX_CODE128_CODE_STOP:
+ done = YES;
+ break;
+ }
+ }
+ break;
+ }
+
+ // Unshift back to another code set if we were shifted
+ if (unshift) {
+ codeSet = codeSet == ZX_CODE128_CODE_CODE_A ? ZX_CODE128_CODE_CODE_B : ZX_CODE128_CODE_CODE_A;
+ }
+ }
+
+ int lastPatternSize = nextStart - lastStart;
+
+ // 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 = ZXNotFoundErrorInstance();
+ 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 = ZXChecksumErrorInstance();
+ return nil;
+ }
+
+ // Need to pull out the check digits from string
+ NSUInteger resultLength = [result length];
+ if (resultLength == 0) {
+ // false positive
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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 == ZX_CODE128_CODE_CODE_C) {
+ [result deleteCharactersInRange:NSMakeRange(resultLength - 2, 2)];
+ } else {
+ [result deleteCharactersInRange:NSMakeRange(resultLength - 1, 1)];
+ }
+ }
+
+ float left = (float)(startPatternInfo.array[1] + startPatternInfo.array[0]) / 2.0f;
+ float right = lastStart + lastPatternSize / 2.0f;
+
+ NSUInteger rawCodesSize = [rawCodes count];
+ ZXByteArray *rawBytes = [[ZXByteArray alloc] initWithLength:(unsigned int)rawCodesSize];
+ for (int i = 0; i < rawCodesSize; i++) {
+ rawBytes.array[i] = (int8_t)[rawCodes[i] intValue];
+ }
+
+ return [ZXResult resultWithText:result
+ rawBytes:rawBytes
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
+ format:kBarcodeFormatCode128];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Writer.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Writer.h
new file mode 100644
index 0000000..61a3949
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Writer.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 "ZXOneDimensionalCodeWriter.h"
+
+/**
+ * This object renders a CODE128 code as a ZXBitMatrix.
+ */
+@interface ZXCode128Writer : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Writer.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Writer.m
new file mode 100644
index 0000000..77656c7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode128Writer.m
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXBoolArray.h"
+#import "ZXCode128Reader.h"
+#import "ZXCode128Writer.h"
+
+// Dummy characters used to specify control characters in input
+const unichar ZX_CODE128_ESCAPE_FNC_1 = L'\u00f1';
+const unichar ZX_CODE128_ESCAPE_FNC_2 = L'\u00f2';
+const unichar ZX_CODE128_ESCAPE_FNC_3 = L'\u00f3';
+const unichar ZX_CODE128_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];
+}
+
+- (ZXBoolArray *)encode:(NSString *)contents {
+ 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 ZX_CODE128_ESCAPE_FNC_1:
+ case ZX_CODE128_ESCAPE_FNC_2:
+ case ZX_CODE128_ESCAPE_FNC_3:
+ case ZX_CODE128_ESCAPE_FNC_4:
+ break;
+ default:
+ [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 == ZX_CODE128_CODE_CODE_C ? 2 : 4;
+ int newCodeSet;
+ if ([self isDigits:contents start:position length:requiredDigitCount]) {
+ newCodeSet = ZX_CODE128_CODE_CODE_C;
+ } else {
+ newCodeSet = ZX_CODE128_CODE_CODE_B;
+ }
+
+ //Get the pattern index
+ int patternIndex;
+ if (newCodeSet == codeSet) {
+ // Encode the current character
+ // First handle escapes
+ switch ([contents characterAtIndex:position]) {
+ case ZX_CODE128_ESCAPE_FNC_1:
+ patternIndex = ZX_CODE128_CODE_FNC_1;
+ break;
+ case ZX_CODE128_ESCAPE_FNC_2:
+ patternIndex = ZX_CODE128_CODE_FNC_2;
+ break;
+ case ZX_CODE128_ESCAPE_FNC_3:
+ patternIndex = ZX_CODE128_CODE_FNC_3;
+ break;
+ case ZX_CODE128_ESCAPE_FNC_4:
+ patternIndex = ZX_CODE128_CODE_FNC_4_B; // FIXME if this ever outputs Code A
+ break;
+ default:
+ // Then handle normal characters otherwise
+ if (codeSet == ZX_CODE128_CODE_CODE_B) {
+ patternIndex = [contents characterAtIndex:position] - ' ';
+ } else { // CODE_CODE_C
+ patternIndex = [[contents substringWithRange:NSMakeRange(position, 2)] intValue];
+ position++; // Also incremented below
+ }
+ }
+ position++;
+ } 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 == ZX_CODE128_CODE_CODE_B) {
+ patternIndex = ZX_CODE128_CODE_START_B;
+ } else {
+ // CODE_CODE_C
+ patternIndex = ZX_CODE128_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(ZX_CODE128_CODE_PATTERNS[patternIndex]) / sizeof(int); i++) {
+ [pattern addObject:@(ZX_CODE128_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(ZX_CODE128_CODE_PATTERNS[checkSum]) / sizeof(int); i++) {
+ [pattern addObject:@(ZX_CODE128_CODE_PATTERNS[checkSum][i])];
+ }
+ [patterns addObject:pattern];
+
+ // Append stop code
+ pattern = [NSMutableArray array];
+ for (int i = 0; i < sizeof(ZX_CODE128_CODE_PATTERNS[ZX_CODE128_CODE_STOP]) / sizeof(int); i++) {
+ [pattern addObject:@(ZX_CODE128_CODE_PATTERNS[ZX_CODE128_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
+ ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:codeWidth];
+ 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 += [self appendPattern:result pos:pos pattern:pattern patternLen:patternLen startColor:YES];
+ }
+
+ 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 != ZX_CODE128_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/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Reader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Reader.h
new file mode 100644
index 0000000..d621148
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Reader.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 unichar ZX_CODE39_ALPHABET[];
+extern NSString *ZX_CODE39_ALPHABET_STRING;
+extern const int ZX_CODE39_CHARACTER_ENCODINGS[];
+
+@class ZXDecodeHints, ZXResult;
+
+/**
+ * Decodes Code 39 barcodes. This does not support "Full ASCII Code 39" yet.
+ */
+@interface ZXCode39Reader : ZXOneDReader
+
+/**
+ * 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;
+
+/**
+ * Creates a reader that can be configured to check the last character as a check digit.
+ * It will not decoded "extended Code 39" sequences.
+ *
+ * @param usingCheckDigit if true, treat the last data character as a check digit, not
+ * data, and verify that the checksum passes.
+ */
+- (id)initUsingCheckDigit:(BOOL)usingCheckDigit;
+
+/**
+ * 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.
+ *
+ * @param usingCheckDigit if true, treat the last data character as a check digit, not
+ * data, and verify that the checksum passes.
+ * @param extendedMode if true, will attempt to decode extended Code 39 sequences in the
+ * text.
+ */
+- (id)initUsingCheckDigit:(BOOL)usingCheckDigit extendedMode:(BOOL)extendedMode;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Reader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Reader.m
new file mode 100644
index 0000000..944a390
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Reader.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 "ZXBitArray.h"
+#import "ZXCode39Reader.h"
+#import "ZXErrors.h"
+#import "ZXIntArray.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+unichar ZX_CODE39_ALPHABET[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
+ 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', '-', '.', ' ', '*', '$', '/', '+', '%'};
+NSString *ZX_CODE39_ALPHABET_STRING = nil;
+
+
+/**
+ * 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.
+ */
+const int ZX_CODE39_CHARACTER_ENCODINGS[] = {
+ 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 // $-%
+};
+
+const int ZX_CODE39_ASTERISK_ENCODING = 0x094;
+
+@interface ZXCode39Reader ()
+
+@property (nonatomic, assign, readonly) BOOL extendedMode;
+@property (nonatomic, assign, readonly) BOOL usingCheckDigit;
+@property (nonatomic, strong, readonly) ZXIntArray *counters;
+
+@end
+
+@implementation ZXCode39Reader
+
++ (void)load {
+ ZX_CODE39_ALPHABET_STRING = [[NSString alloc] initWithCharacters:ZX_CODE39_ALPHABET
+ length:sizeof(ZX_CODE39_ALPHABET) / sizeof(unichar)];
+}
+
+- (id)init {
+ return [self initUsingCheckDigit:NO extendedMode:NO];
+}
+
+- (id)initUsingCheckDigit:(BOOL)isUsingCheckDigit {
+ return [self initUsingCheckDigit:isUsingCheckDigit extendedMode:NO];
+}
+
+- (id)initUsingCheckDigit:(BOOL)usingCheckDigit extendedMode:(BOOL)extendedMode {
+ if (self = [super init]) {
+ _usingCheckDigit = usingCheckDigit;
+ _extendedMode = extendedMode;
+ _counters = [[ZXIntArray alloc] initWithLength:9];
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXIntArray *theCounters = self.counters;
+ [theCounters clear];
+ NSMutableString *result = [NSMutableString stringWithCapacity:20];
+
+ ZXIntArray *start = [self findAsteriskPattern:row counters:theCounters];
+ if (!start) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ // Read off white space
+ int nextStart = [row nextSet:start.array[1]];
+ int end = [row size];
+
+ unichar decodedChar;
+ int lastStart;
+ do {
+ if (![ZXOneDReader recordPattern:row start:nextStart counters:theCounters]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ int pattern = [self toNarrowWidePattern:theCounters];
+ if (pattern < 0) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ decodedChar = [self patternToChar:pattern];
+ if (decodedChar == 0) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ [result appendFormat:@"%C", decodedChar];
+ lastStart = nextStart;
+ for (int i = 0; i < theCounters.length; i++) {
+ nextStart += theCounters.array[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 < theCounters.length; i++) {
+ lastPatternSize += theCounters.array[i];
+ }
+ int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
+ if (nextStart != end && (whiteSpaceAfterEnd * 2) < lastPatternSize) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ if (self.usingCheckDigit) {
+ int max = (int)[result length] - 1;
+ int total = 0;
+ for (int i = 0; i < max; i++) {
+ total += [ZX_CODE39_ALPHABET_STRING rangeOfString:[result substringWithRange:NSMakeRange(i, 1)]].location;
+ }
+ if ([result characterAtIndex:max] != ZX_CODE39_ALPHABET[total % 43]) {
+ if (error) *error = ZXChecksumErrorInstance();
+ return nil;
+ }
+ [result deleteCharactersInRange:NSMakeRange(max, 1)];
+ }
+
+ if ([result length] == 0) {
+ // false positive
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ NSString *resultString;
+ if (self.extendedMode) {
+ resultString = [self decodeExtended:result];
+ if (!resultString) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ } else {
+ resultString = result;
+ }
+
+ float left = (float) (start.array[1] + start.array[0]) / 2.0f;
+ float right = (lastStart + lastPatternSize) / 2.0f;
+
+ return [ZXResult resultWithText:resultString
+ rawBytes:nil
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
+ format:kBarcodeFormatCode39];
+}
+
+- (ZXIntArray *)findAsteriskPattern:(ZXBitArray *)row counters:(ZXIntArray *)counters {
+ int width = row.size;
+ int rowOffset = [row nextSet:0];
+
+ int counterPosition = 0;
+ int patternStart = rowOffset;
+ BOOL isWhite = NO;
+ int patternLength = counters.length;
+ int32_t *array = counters.array;
+
+ for (int i = rowOffset; i < width; i++) {
+ if ([row get:i] ^ isWhite) {
+ array[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if ([self toNarrowWidePattern:counters] == ZX_CODE39_ASTERISK_ENCODING &&
+ [row isRange:MAX(0, patternStart - ((i - patternStart) / 2)) end:patternStart value:NO]) {
+ return [[ZXIntArray alloc] initWithInts:patternLength, i, -1];
+ }
+ patternStart += array[0] + array[1];
+ for (int y = 2; y < counters.length; y++) {
+ array[y - 2] = array[y];
+ }
+ array[patternLength - 2] = 0;
+ array[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ array[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return nil;
+}
+
+- (int)toNarrowWidePattern:(ZXIntArray *)counters {
+ int numCounters = counters.length;
+ int maxNarrowCounter = 0;
+ int wideCounters;
+ do {
+ int minCounter = INT_MAX;
+ int32_t *array = counters.array;
+ for (int i = 0; i < numCounters; i++) {
+ int counter = array[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 = array[i];
+ if (array[i] > maxNarrowCounter) {
+ pattern |= 1 << (numCounters - 1 - i);
+ wideCounters++;
+ totalWideCountersWidth += counter;
+ }
+ }
+ if (wideCounters == 3) {
+ for (int i = 0; i < numCounters && wideCounters > 0; i++) {
+ int counter = array[i];
+ if (array[i] > maxNarrowCounter) {
+ wideCounters--;
+ if ((counter * 2) >= totalWideCountersWidth) {
+ return -1;
+ }
+ }
+ }
+ return pattern;
+ }
+ } while (wideCounters > 3);
+ return -1;
+}
+
+- (unichar)patternToChar:(int)pattern {
+ for (int i = 0; i < sizeof(ZX_CODE39_CHARACTER_ENCODINGS) / sizeof(int); i++) {
+ if (ZX_CODE39_CHARACTER_ENCODINGS[i] == pattern) {
+ return ZX_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/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Writer.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Writer.h
new file mode 100644
index 0000000..c7b30d7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Writer.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 "ZXOneDimensionalCodeWriter.h"
+
+/**
+ * This object renders a CODE39 code as a ZXBitMatrix.
+ */
+@interface ZXCode39Writer : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Writer.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Writer.m
new file mode 100644
index 0000000..6a15037
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode39Writer.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 "ZXBitMatrix.h"
+#import "ZXBoolArray.h"
+#import "ZXCode39Reader.h"
+#import "ZXCode39Writer.h"
+#import "ZXIntArray.h"
+
+@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];
+}
+
+- (ZXBoolArray *)encode:(NSString *)contents {
+ int length = (int)[contents length];
+ if (length > 80) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Requested contents should be less than 80 digits long, but got %d", length];
+ }
+
+ ZXIntArray *widths = [[ZXIntArray alloc] initWithLength:9];
+ int codeWidth = 24 + 1 + length;
+ for (int i = 0; i < length; i++) {
+ NSUInteger indexInString = [ZX_CODE39_ALPHABET_STRING rangeOfString:[contents substringWithRange:NSMakeRange(i, 1)]].location;
+ if (indexInString == NSNotFound) {
+ [NSException raise:NSInvalidArgumentException format:@"Bad contents: %@", contents];
+ }
+ [self toIntArray:ZX_CODE39_CHARACTER_ENCODINGS[indexInString] toReturn:widths];
+ codeWidth += [widths sum];
+ }
+ ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:codeWidth];
+ [self toIntArray:ZX_CODE39_CHARACTER_ENCODINGS[39] toReturn:widths];
+ int pos = [self appendPattern:result pos:0 pattern:widths.array patternLen:widths.length startColor:YES];
+ ZXIntArray *narrowWhite = [[ZXIntArray alloc] initWithInts:1, -1];
+ pos += [self appendPattern:result pos:pos pattern:narrowWhite.array patternLen:narrowWhite.length startColor:NO];
+ //append next character to byte matrix
+ for (int i = 0; i < length; i++) {
+ NSUInteger indexInString = [ZX_CODE39_ALPHABET_STRING rangeOfString:[contents substringWithRange:NSMakeRange(i, 1)]].location;
+ [self toIntArray:ZX_CODE39_CHARACTER_ENCODINGS[indexInString] toReturn:widths];
+ pos += [self appendPattern:result pos:pos pattern:widths.array patternLen:widths.length startColor:YES];
+ pos += [self appendPattern:result pos:pos pattern:narrowWhite.array patternLen:narrowWhite.length startColor:NO];
+ }
+
+ [self toIntArray:ZX_CODE39_CHARACTER_ENCODINGS[39] toReturn:widths];
+ [self appendPattern:result pos:pos pattern:widths.array patternLen:widths.length startColor:YES];
+ return result;
+}
+
+- (void)toIntArray:(int)a toReturn:(ZXIntArray *)toReturn {
+ for (int i = 0; i < 9; i++) {
+ int temp = a & (1 << (8 - i));
+ toReturn.array[i] = temp == 0 ? 1 : 2;
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCode93Reader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode93Reader.h
new file mode 100644
index 0000000..e3368f4
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode93Reader.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 "ZXOneDReader.h"
+
+/**
+ * Decodes Code 93 barcodes.
+ */
+@interface ZXCode93Reader : ZXOneDReader
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXCode93Reader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXCode93Reader.m
new file mode 100644
index 0000000..7d8be27
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXIntArray.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+NSString *ZX_CODE93_ALPHABET_STRING = nil;
+const unichar ZX_CODE93_ALPHABET[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
+ 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%', 'a', 'b', 'c', 'd', '*'};
+
+/**
+ * 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 ZX_CODE93_CHARACTER_ENCODINGS[] = {
+ 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 ZX_CODE93_ASTERISK_ENCODING = 0x15E;
+
+@interface ZXCode93Reader ()
+
+@property (nonatomic, strong, readonly) ZXIntArray *counters;
+
+@end
+
+@implementation ZXCode93Reader
+
++ (void)initialize {
+ if ([self class] != [ZXCode93Reader class]) return;
+
+ ZX_CODE93_ALPHABET_STRING = [[NSString alloc] initWithCharacters:ZX_CODE93_ALPHABET
+ length:sizeof(ZX_CODE93_ALPHABET) / sizeof(unichar)];
+}
+
+- (id)init {
+ if (self = [super init]) {
+ _counters = [[ZXIntArray alloc] initWithLength:6];
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXIntArray *start = [self findAsteriskPattern:row];
+ if (!start) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ // Read off white space
+ int nextStart = [row nextSet:start.array[1]];
+ int end = row.size;
+
+ ZXIntArray *theCounters = self.counters;
+ memset(theCounters.array, 0, theCounters.length * sizeof(int32_t));
+ NSMutableString *result = [NSMutableString string];
+
+ unichar decodedChar;
+ int lastStart;
+ do {
+ if (![ZXOneDReader recordPattern:row start:nextStart counters:theCounters]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ int pattern = [self toPattern:theCounters];
+ if (pattern < 0) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ decodedChar = [self patternToChar:pattern];
+ if (decodedChar == 0) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ [result appendFormat:@"%C", decodedChar];
+ lastStart = nextStart;
+ for (int i = 0; i < theCounters.length; i++) {
+ nextStart += theCounters.array[i];
+ }
+ // Read off white space
+ nextStart = [row nextSet:nextStart];
+ } while (decodedChar != '*');
+ [result deleteCharactersInRange:NSMakeRange([result length] - 1, 1)]; // remove asterisk
+
+ int lastPatternSize = [theCounters sum];
+
+ // Should be at least one more black module
+ if (nextStart == end || ![row get:nextStart]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ if ([result length] < 2) {
+ // false positive -- need at least 2 checksum digits
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ if (![self checkChecksums:result error:error]) {
+ return nil;
+ }
+ [result deleteCharactersInRange:NSMakeRange([result length] - 2, 2)];
+
+ NSString *resultString = [self decodeExtended:result];
+ if (!resultString) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+
+ float left = (float) (start.array[1] + start.array[0]) / 2.0f;
+ float right = lastStart + lastPatternSize / 2.0f;
+ return [ZXResult resultWithText:resultString
+ rawBytes:nil
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
+ format:kBarcodeFormatCode93];
+}
+
+- (ZXIntArray *)findAsteriskPattern:(ZXBitArray *)row {
+ int width = row.size;
+ int rowOffset = [row nextSet:0];
+
+ [self.counters clear];
+ ZXIntArray *theCounters = self.counters;
+ int patternStart = rowOffset;
+ BOOL isWhite = NO;
+ int patternLength = theCounters.length;
+
+ int counterPosition = 0;
+ for (int i = rowOffset; i < width; i++) {
+ if ([row get:i] ^ isWhite) {
+ theCounters.array[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if ([self toPattern:theCounters] == ZX_CODE93_ASTERISK_ENCODING) {
+ return [[ZXIntArray alloc] initWithInts:patternStart, i, -1];
+ }
+ patternStart += theCounters.array[0] + theCounters.array[1];
+ for (int y = 2; y < patternLength; y++) {
+ theCounters.array[y - 2] = theCounters.array[y];
+ }
+ theCounters.array[patternLength - 2] = 0;
+ theCounters.array[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ theCounters.array[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return nil;
+}
+
+- (int)toPattern:(ZXIntArray *)counters {
+ int max = counters.length;
+ int sum = [counters sum];
+ int32_t *array = counters.array;
+ int pattern = 0;
+ for (int i = 0; i < max; i++) {
+ int scaled = round(array[i] * 9.0f / sum);
+ if (scaled < 1 || scaled > 4) {
+ return -1;
+ }
+ if ((i & 0x01) == 0) {
+ for (int j = 0; j < scaled; j++) {
+ pattern = (pattern << 1) | 0x01;
+ }
+ } else {
+ pattern <<= scaled;
+ }
+ }
+ return pattern;
+}
+
+- (unichar)patternToChar:(int)pattern {
+ for (int i = 0; i < sizeof(ZX_CODE93_CHARACTER_ENCODINGS) / sizeof(int); i++) {
+ if (ZX_CODE93_CHARACTER_ENCODINGS[i] == pattern) {
+ return ZX_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 * [ZX_CODE93_ALPHABET_STRING rangeOfString:[NSString stringWithFormat:@"%C", [result characterAtIndex:i]]].location;
+ if (++weight > weightMax) {
+ weight = 1;
+ }
+ }
+
+ if ([result characterAtIndex:checkPosition] != ZX_CODE93_ALPHABET[total % 47]) {
+ if (error) *error = ZXChecksumErrorInstance();
+ return NO;
+ }
+ return YES;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Reader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Reader.h
new file mode 100644
index 0000000..f94ecd5
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Reader.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 "ZXUPCEANReader.h"
+
+extern const int ZX_EAN13_FIRST_DIGIT_ENCODINGS[];
+
+/**
+ * Implements decoding of the EAN-13 format.
+ */
+@interface ZXEAN13Reader : ZXUPCEANReader
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Reader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Reader.m
new file mode 100644
index 0000000..fed8b7c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Reader.m
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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"
+#import "ZXIntArray.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
+//
+const int ZX_EAN13_FIRST_DIGIT_ENCODINGS[] = {
+ 0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A
+};
+
+@interface ZXEAN13Reader ()
+
+@property (nonatomic, strong, readonly) ZXIntArray *decodeMiddleCounters;
+
+@end
+
+@implementation ZXEAN13Reader
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeMiddleCounters = [[ZXIntArray alloc] initWithLength:4];
+ }
+ return self;
+}
+
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ ZXIntArray *counters = self.decodeMiddleCounters;
+ [counters clear];
+ 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 rowOffset:rowOffset patternType:ZX_UPC_EAN_PATTERNS_L_AND_G_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch % 10)];
+ rowOffset += [counters sum];
+ if (bestMatch >= 10) {
+ lgPatternFound |= 1 << (5 - x);
+ }
+ }
+
+ if (![self determineFirstDigit:result lgPatternFound:lgPatternFound]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return -1;
+ }
+
+ NSRange middleRange = [[self class] findGuardPattern:row
+ rowOffset:rowOffset
+ whiteFirst:YES
+ pattern:ZX_UPC_EAN_MIDDLE_PATTERN
+ patternLen:ZX_UPC_EAN_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
+ rowOffset:rowOffset
+ patternType:ZX_UPC_EAN_PATTERNS_L_PATTERNS
+ error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch)];
+ rowOffset += [counters sum];
+ }
+
+ 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.
+ *
+ * @param resultString string to insert decoded first digit into
+ * @param lgPatternFound int whose bits indicates the pattern of odd/even L/G patterns used to
+ * encode digits
+ * @return NO if first digit cannot be determined
+ */
+- (BOOL)determineFirstDigit:(NSMutableString *)resultString lgPatternFound:(int)lgPatternFound {
+ for (int d = 0; d < 10; d++) {
+ if (lgPatternFound == ZX_EAN13_FIRST_DIGIT_ENCODINGS[d]) {
+ [resultString insertString:[NSString stringWithFormat:@"%C", (unichar)('0' + d)] atIndex:0];
+ return YES;
+ }
+ }
+ return NO;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Writer.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Writer.h
new file mode 100644
index 0000000..6dc59d8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Writer.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 "ZXUPCEANWriter.h"
+
+/**
+ * This object renders an EAN13 code as a ZXBitMatrix.
+ */
+@interface ZXEAN13Writer : ZXUPCEANWriter
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Writer.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Writer.m
new file mode 100644
index 0000000..b9ad4bd
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN13Writer.m
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXBoolArray.h"
+#import "ZXEAN13Reader.h"
+#import "ZXEAN13Writer.h"
+#import "ZXUPCEANReader.h"
+
+const int ZX_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];
+}
+
+- (ZXBoolArray *)encode:(NSString *)contents {
+ if ([contents length] != 13) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Requested contents should be 13 digits long, but got %d", (int)[contents length]];
+ }
+
+ if (![ZXUPCEANReader checkStandardUPCEANChecksum:contents]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Contents do not pass checksum"];
+ }
+
+ int firstDigit = [[contents substringToIndex:1] intValue];
+ int parities = ZX_EAN13_FIRST_DIGIT_ENCODINGS[firstDigit];
+ ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:ZX_EAN13_CODE_WIDTH];
+ int pos = 0;
+
+ pos += [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_START_END_PATTERN patternLen:ZX_UPC_EAN_START_END_PATTERN_LEN startColor:YES];
+
+ for (int i = 1; i <= 6; i++) {
+ int digit = [[contents substringWithRange:NSMakeRange(i, 1)] intValue];
+ if ((parities >> (6 - i) & 1) == 1) {
+ digit += 10;
+ }
+ pos += [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_L_AND_G_PATTERNS[digit] patternLen:ZX_UPC_EAN_L_PATTERNS_SUB_LEN startColor:FALSE];
+ }
+
+ pos += [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_MIDDLE_PATTERN patternLen:ZX_UPC_EAN_MIDDLE_PATTERN_LEN startColor:FALSE];
+
+ for (int i = 7; i <= 12; i++) {
+ int digit = [[contents substringWithRange:NSMakeRange(i, 1)] intValue];
+ pos += [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_L_PATTERNS[digit] patternLen:ZX_UPC_EAN_L_PATTERNS_SUB_LEN startColor:YES];
+ }
+ [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_START_END_PATTERN patternLen:ZX_UPC_EAN_START_END_PATTERN_LEN startColor:YES];
+
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Reader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Reader.h
new file mode 100644
index 0000000..886ce3b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Reader.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 "ZXUPCEANReader.h"
+
+/**
+ * Implements decoding of the EAN-8 format.
+ */
+@interface ZXEAN8Reader : ZXUPCEANReader
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Reader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Reader.m
new file mode 100644
index 0000000..eb1538a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Reader.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 "ZXBitArray.h"
+#import "ZXEAN8Reader.h"
+#import "ZXIntArray.h"
+
+@interface ZXEAN8Reader ()
+
+@property (nonatomic, strong, readonly) ZXIntArray *decodeMiddleCounters;
+
+@end
+
+@implementation ZXEAN8Reader
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeMiddleCounters = [[ZXIntArray alloc] initWithLength:4];
+ }
+
+ return self;
+}
+
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ ZXIntArray *counters = self.decodeMiddleCounters;
+ [counters clear];
+ 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 rowOffset:rowOffset patternType:ZX_UPC_EAN_PATTERNS_L_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch)];
+ rowOffset += [counters sum];
+ }
+
+ NSRange middleRange = [[self class] findGuardPattern:row rowOffset:rowOffset whiteFirst:YES pattern:ZX_UPC_EAN_MIDDLE_PATTERN patternLen:ZX_UPC_EAN_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 rowOffset:rowOffset patternType:ZX_UPC_EAN_PATTERNS_L_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch)];
+ rowOffset += [counters sum];
+ }
+
+ return rowOffset;
+}
+
+- (ZXBarcodeFormat)barcodeFormat {
+ return kBarcodeFormatEan8;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Writer.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Writer.h
new file mode 100644
index 0000000..5171806
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Writer.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 "ZXUPCEANWriter.h"
+
+/**
+ * This object renders an EAN8 code as a ZXBitMatrix.
+ */
+@interface ZXEAN8Writer : ZXUPCEANWriter
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Writer.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Writer.m
new file mode 100644
index 0000000..7307bd1
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXEAN8Writer.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 "ZXBarcodeFormat.h"
+#import "ZXBoolArray.h"
+#import "ZXEAN8Writer.h"
+#import "ZXUPCEANReader.h"
+
+const int ZX_EAN8_CODE_WIDTH = 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)
+ */
+- (ZXBoolArray *)encode:(NSString *)contents {
+ if ([contents length] != 8) {
+ [NSException raise:NSInvalidArgumentException format:@"Requested contents should be 8 digits long, but got %d", (int)[contents length]];
+ }
+
+ ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:ZX_EAN8_CODE_WIDTH];
+ int pos = 0;
+
+ pos += [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_START_END_PATTERN patternLen:ZX_UPC_EAN_START_END_PATTERN_LEN startColor:YES];
+
+ for (int i = 0; i <= 3; i++) {
+ int digit = [[contents substringWithRange:NSMakeRange(i, 1)] intValue];
+ pos += [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_L_PATTERNS[digit] patternLen:ZX_UPC_EAN_L_PATTERNS_SUB_LEN startColor:FALSE];
+ }
+
+ pos += [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_MIDDLE_PATTERN patternLen:ZX_UPC_EAN_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:ZX_UPC_EAN_L_PATTERNS[digit] patternLen:ZX_UPC_EAN_L_PATTERNS_SUB_LEN startColor:YES];
+ }
+
+ [self appendPattern:result pos:pos pattern:ZX_UPC_EAN_START_END_PATTERN patternLen:ZX_UPC_EAN_START_END_PATTERN_LEN startColor:YES];
+
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXEANManufacturerOrgSupport.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXEANManufacturerOrgSupport.h
new file mode 100644
index 0000000..60b385a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXEANManufacturerOrgSupport.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.
+ */
+
+/**
+ * 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/Pods/ZXingObjC/ZXingObjC/oned/ZXEANManufacturerOrgSupport.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXEANManufacturerOrgSupport.m
new file mode 100644
index 0000000..3bdac20
--- /dev/null
+++ b/Pods/ZXingObjC/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, readonly) NSMutableArray *countryIdentifiers;
+@property (nonatomic, strong, readonly) 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/Pods/ZXingObjC/ZXingObjC/oned/ZXITFReader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXITFReader.h
new file mode 100644
index 0000000..bc145f4
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXITFReader.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 "ZXOneDReader.h"
+
+extern const int ZX_ITF_PATTERNS[][5];
+
+/**
+ * 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.
+ */
+@interface ZXITFReader : ZXOneDReader
+
+- (ZXIntArray *)decodeStart:(ZXBitArray *)row;
+- (ZXIntArray *)decodeEnd:(ZXBitArray *)row;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXITFReader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXITFReader.m
new file mode 100644
index 0000000..c9b41d0
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXITFReader.m
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXIntArray.h"
+#import "ZXITFReader.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+static float ZX_ITF_MAX_AVG_VARIANCE = 0.38f;
+static float ZX_ITF_MAX_INDIVIDUAL_VARIANCE = 0.78f;
+
+static const int ZX_ITF_W = 3; // Pixel width of a wide line
+static const int ZX_ITF_N = 1; // Pixel width of a narrow line
+
+/** Valid ITF lengths. Anything longer than the largest value is also allowed. */
+const int ZX_ITF_DEFAULT_ALLOWED_LENGTHS[] = { 6, 8, 10, 12, 14 };
+
+/**
+ * Start/end guard pattern.
+ *
+ * Note: The end pattern is reversed because the row is reversed before
+ * searching for the END_PATTERN
+ */
+const int ZX_ITF_ITF_START_PATTERN[] = {ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N};
+const int ZX_ITF_END_PATTERN_REVERSED[] = {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W};
+
+/**
+ * Patterns of Wide / Narrow lines to indicate each digit
+ */
+const int ZX_ITF_PATTERNS_LEN = 10;
+const int ZX_ITF_PATTERNS[ZX_ITF_PATTERNS_LEN][5] = {
+ {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W, ZX_ITF_W, ZX_ITF_N}, // 0
+ {ZX_ITF_W, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W}, // 1
+ {ZX_ITF_N, ZX_ITF_W, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W}, // 2
+ {ZX_ITF_W, ZX_ITF_W, ZX_ITF_N, ZX_ITF_N, ZX_ITF_N}, // 3
+ {ZX_ITF_N, ZX_ITF_N, ZX_ITF_W, ZX_ITF_N, ZX_ITF_W}, // 4
+ {ZX_ITF_W, ZX_ITF_N, ZX_ITF_W, ZX_ITF_N, ZX_ITF_N}, // 5
+ {ZX_ITF_N, ZX_ITF_W, ZX_ITF_W, ZX_ITF_N, ZX_ITF_N}, // 6
+ {ZX_ITF_N, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W, ZX_ITF_W}, // 7
+ {ZX_ITF_W, ZX_ITF_N, ZX_ITF_N, ZX_ITF_W, ZX_ITF_N}, // 8
+ {ZX_ITF_N, ZX_ITF_W, ZX_ITF_N, ZX_ITF_W, ZX_ITF_N} // 9
+};
+
+@interface ZXITFReader ()
+
+@property (nonatomic, assign) int narrowLineWidth;
+
+@end
+
+@implementation ZXITFReader
+
+- (id)init {
+ if (self = [super init]) {
+ _narrowLineWidth = -1;
+ }
+
+ return self;
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ // Find out where the Middle section (payload) starts & ends
+ ZXIntArray *startRange = [self decodeStart:row];
+ ZXIntArray *endRange = [self decodeEnd:row];
+ if (!startRange || !endRange) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ NSMutableString *resultString = [NSMutableString stringWithCapacity:20];
+ if (![self decodeMiddle:row payloadStart:startRange.array[1] payloadEnd:endRange.array[0] resultString:resultString]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ NSArray *allowedLengths = nil;
+ if (hints != nil) {
+ allowedLengths = hints.allowedLengths;
+ }
+ if (allowedLengths == nil) {
+ NSMutableArray *temp = [NSMutableArray array];
+ for (int i = 0; i < sizeof(ZX_ITF_DEFAULT_ALLOWED_LENGTHS) / sizeof(int); i++) {
+ [temp addObject:@(ZX_ITF_DEFAULT_ALLOWED_LENGTHS[i])];
+ }
+ allowedLengths = [NSArray arrayWithArray:temp];
+ }
+
+ // To avoid false positives with 2D barcodes (and other patterns), make
+ // an assumption that the decoded string must be a 'standard' length if it's short
+ NSUInteger length = [resultString length];
+ BOOL lengthOK = NO;
+ int maxAllowedLength = 0;
+ for (NSNumber *i in allowedLengths) {
+ int allowedLength = [i intValue];
+ if (length == allowedLength) {
+ lengthOK = YES;
+ break;
+ }
+ if (allowedLength > maxAllowedLength) {
+ maxAllowedLength = allowedLength;
+ }
+ }
+ if (!lengthOK && length > maxAllowedLength) {
+ lengthOK = YES;
+ }
+ if (!lengthOK) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+
+ return [ZXResult resultWithText:resultString
+ rawBytes:nil
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:startRange.array[1] y:(float)rowNumber],
+ [[ZXResultPoint alloc] initWithX:endRange.array[0] y:(float)rowNumber]]
+ format:kBarcodeFormatITF];
+}
+
+/**
+ * @param row row of black/white values to search
+ * @param payloadStart offset of start pattern
+ * @param resultString NSMutableString to append decoded chars to
+ * @return NO if decoding could not complete successfully
+ */
+- (BOOL)decodeMiddle:(ZXBitArray *)row payloadStart:(int)payloadStart payloadEnd:(int)payloadEnd resultString:(NSMutableString *)resultString {
+ // Digits are interleaved in pairs - 5 black lines for one digit, and the
+ // 5
+ // interleaved white lines for the second digit.
+ // Therefore, need to scan 10 lines and then
+ // split these into two arrays
+ ZXIntArray *counterDigitPair = [[ZXIntArray alloc] initWithLength:10];
+ ZXIntArray *counterBlack = [[ZXIntArray alloc] initWithLength:5];
+ ZXIntArray *counterWhite = [[ZXIntArray alloc] initWithLength:5];
+
+ while (payloadStart < payloadEnd) {
+ // Get 10 runs of black/white.
+ if (![ZXOneDReader recordPattern:row start:payloadStart counters:counterDigitPair]) {
+ return NO;
+ }
+ // Split them into each array
+ for (int k = 0; k < 5; k++) {
+ int twoK = 2 * k;
+ counterBlack.array[k] = counterDigitPair.array[twoK];
+ counterWhite.array[k] = counterDigitPair.array[twoK + 1];
+ }
+
+ int bestMatch = [self decodeDigit:counterBlack];
+ if (bestMatch == -1) {
+ return NO;
+ }
+ [resultString appendFormat:@"%C", (unichar)('0' + bestMatch)];
+ bestMatch = [self decodeDigit:counterWhite];
+ if (bestMatch == -1) {
+ return NO;
+ }
+ [resultString appendFormat:@"%C", (unichar)('0' + bestMatch)];
+
+ for (int i = 0; i < counterDigitPair.length; i++) {
+ payloadStart += counterDigitPair.array[i];
+ }
+ }
+ return YES;
+}
+
+/**
+ * Identify where the start of the middle / payload section starts.
+ *
+ * @param row row of black/white values to search
+ * @return Array, containing index of start of 'start block' and end of
+ * 'start block'
+ */
+- (ZXIntArray *)decodeStart:(ZXBitArray *)row {
+ int endStart = [self skipWhiteSpace:row];
+ if (endStart == -1) {
+ return nil;
+ }
+ ZXIntArray *startPattern = [self findGuardPattern:row rowOffset:endStart pattern:ZX_ITF_ITF_START_PATTERN patternLen:sizeof(ZX_ITF_ITF_START_PATTERN)/sizeof(int)];
+ if (!startPattern) {
+ return nil;
+ }
+
+ self.narrowLineWidth = (startPattern.array[1] - startPattern.array[0]) / 4;
+
+ if (![self validateQuietZone:row startPattern:startPattern.array[0]]) {
+ 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
+ *
+ * @param row bit array representing the scanned barcode.
+ * @param startPattern index into row of the start or end pattern.
+ * @return NO if the quiet zone cannot be found, a ReaderException is thrown.
+ */
+- (BOOL)validateQuietZone:(ZXBitArray *)row startPattern:(int)startPattern {
+ int quietCount = self.narrowLineWidth * 10;
+
+ // if there are not so many pixel at all let's try as many as possible
+ quietCount = quietCount < startPattern ? quietCount : startPattern;
+
+ 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.
+ *
+ * @param row row of black/white values to search
+ * @return index of the first black line or -1 if no black lines are found in the row
+ */
+- (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.
+ *
+ * @param row row of black/white values to search
+ * @return Array, containing index of start of 'end block' and end of 'end
+ * block'
+ */
+- (ZXIntArray *)decodeEnd:(ZXBitArray *)row {
+ [row reverse];
+
+ int endStart = [self skipWhiteSpace:row];
+ if (endStart == -1) {
+ [row reverse];
+ return nil;
+ }
+ ZXIntArray *endPattern = [self findGuardPattern:row rowOffset:endStart pattern:ZX_ITF_END_PATTERN_REVERSED patternLen:sizeof(ZX_ITF_END_PATTERN_REVERSED)/sizeof(int)];
+ if (!endPattern) {
+ [row reverse];
+ return nil;
+ }
+ if (![self validateQuietZone:row startPattern:endPattern.array[0]]) {
+ [row reverse];
+ return nil;
+ }
+ int temp = endPattern.array[0];
+ endPattern.array[0] = [row size] - endPattern.array[1];
+ endPattern.array[1] = [row size] - temp;
+ [row reverse];
+ return endPattern;
+}
+
+/**
+ * @param row row of black/white values to search
+ * @param rowOffset position to start search
+ * @param pattern pattern of counts of number of black and white pixels that are
+ * being searched for as a pattern
+ * @return start/end horizontal offset of guard pattern, as an array of two
+ * ints or nil if pattern is not found
+ */
+- (ZXIntArray *)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset pattern:(const int[])pattern patternLen:(int)patternLen {
+ int patternLength = patternLen;
+ ZXIntArray *counters = [[ZXIntArray alloc] initWithLength:patternLength];
+ int32_t *array = counters.array;
+ 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) {
+ array[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if ([ZXOneDReader patternMatchVariance:counters pattern:pattern maxIndividualVariance:ZX_ITF_MAX_INDIVIDUAL_VARIANCE] < ZX_ITF_MAX_AVG_VARIANCE) {
+ return [[ZXIntArray alloc] initWithInts:patternStart, x, -1];
+ }
+ patternStart += array[0] + array[1];
+ for (int y = 2; y < patternLength; y++) {
+ array[y - 2] = array[y];
+ }
+ array[patternLength - 2] = 0;
+ array[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ array[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return nil;
+}
+
+/**
+ * Attempts to decode a sequence of ITF black/white lines into single
+ * digit.
+ *
+ * @param counters the counts of runs of observed black/white/black/... values
+ * @return The decoded digit or -1 if digit cannot be decoded
+ */
+- (int)decodeDigit:(ZXIntArray *)counters {
+ float bestVariance = ZX_ITF_MAX_AVG_VARIANCE; // worst variance we'll accept
+ int bestMatch = -1;
+ int max = ZX_ITF_PATTERNS_LEN;
+ for (int i = 0; i < max; i++) {
+ int pattern[counters.length];
+ for (int ind = 0; ind < counters.length; ind++){
+ pattern[ind] = ZX_ITF_PATTERNS[i][ind];
+ }
+ float variance = [ZXOneDReader patternMatchVariance:counters pattern:pattern maxIndividualVariance:ZX_ITF_MAX_INDIVIDUAL_VARIANCE];
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = i;
+ }
+ }
+ if (bestMatch >= 0) {
+ return bestMatch;
+ } else {
+ return -1;
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXITFWriter.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXITFWriter.h
new file mode 100644
index 0000000..6b02789
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXITFWriter.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 "ZXOneDimensionalCodeWriter.h"
+
+/**
+ * This object renders a ITF code as a ZXBitMatrix.
+ */
+@interface ZXITFWriter : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXITFWriter.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXITFWriter.m
new file mode 100644
index 0000000..5a58048
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXITFWriter.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 "ZXBoolArray.h"
+#import "ZXITFReader.h"
+#import "ZXITFWriter.h"
+
+const int ZX_ITF_WRITER_START_PATTERN[] = {1, 1, 1, 1};
+const int ZX_ITF_WRITER_END_PATTERN[] = {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];
+}
+
+- (ZXBoolArray *)encode:(NSString *)contents {
+ int length = (int)[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 %d", length];
+ }
+
+ ZXBoolArray *result = [[ZXBoolArray alloc] initWithLength:9 + 9 * length];
+ int pos = [self appendPattern:result pos:0 pattern:ZX_ITF_WRITER_START_PATTERN patternLen:sizeof(ZX_ITF_WRITER_START_PATTERN)/sizeof(int) startColor:YES];
+ for (int i = 0; i < length; i += 2) {
+ int one = [[contents substringWithRange:NSMakeRange(i, 1)] intValue];
+ int two = [[contents substringWithRange:NSMakeRange(i + 1, 1)] intValue];
+ const int encodingLen = 18;
+ int encoding[encodingLen];
+ memset(encoding, 0, encodingLen * sizeof(int));
+ for (int j = 0; j < 5; j++) {
+ encoding[2 * j] = ZX_ITF_PATTERNS[one][j];
+ encoding[2 * j + 1] = ZX_ITF_PATTERNS[two][j];
+ }
+ pos += [super appendPattern:result pos:pos pattern:encoding patternLen:encodingLen startColor:YES];
+ }
+ [self appendPattern:result pos:pos pattern:ZX_ITF_WRITER_END_PATTERN patternLen:sizeof(ZX_ITF_WRITER_END_PATTERN)/sizeof(int) startColor:YES];
+
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatOneDReader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatOneDReader.h
new file mode 100644
index 0000000..71a4eb2
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatOneDReader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatOneDReader.m
new file mode 100644
index 0000000..d47e2b2
--- /dev/null
+++ b/Pods/ZXingObjC/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, readonly) 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 = ZXNotFoundErrorInstance();
+ return nil;
+}
+
+- (void)reset {
+ for (id reader in self.readers) {
+ [reader reset];
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatUPCEANReader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatUPCEANReader.h
new file mode 100644
index 0000000..4fcc093
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatUPCEANReader.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 "ZXOneDReader.h"
+
+@class ZXDecodeHints;
+
+/**
+ * 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.
+ */
+@interface ZXMultiFormatUPCEANReader : ZXOneDReader
+
+- (id)initWithHints:(ZXDecodeHints *)hints;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatUPCEANReader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatUPCEANReader.m
new file mode 100644
index 0000000..fbbee67
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXMultiFormatUPCEANReader.m
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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, readonly) 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
+ resultPoints:result.resultPoints
+ format:kBarcodeFormatUPCA];
+ [resultUPCA putAllMetadata:result.resultMetadata];
+ return resultUPCA;
+ }
+ return result;
+ }
+
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+}
+
+- (void)reset {
+ for (id reader in self.readers) {
+ [reader reset];
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDReader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDReader.h
new file mode 100644
index 0000000..9b77421
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDReader.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 "ZXReader.h"
+
+@class ZXBitArray, ZXDecodeHints, ZXIntArray, ZXResult;
+
+/**
+ * Encapsulates functionality and implementation that is common to all families
+ * of one-dimensional barcodes.
+ */
+@interface ZXOneDReader : NSObject
+
++ (BOOL)recordPattern:(ZXBitArray *)row start:(int)start counters:(ZXIntArray *)counters;
++ (BOOL)recordPatternInReverse:(ZXBitArray *)row start:(int)start counters:(ZXIntArray *)counters;
++ (float)patternMatchVariance:(ZXIntArray *)counters pattern:(const int[])pattern maxIndividualVariance:(float)maxIndividualVariance;
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDReader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDReader.m
new file mode 100644
index 0000000..7e4f685
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDReader.m
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXIntArray.h"
+#import "ZXOneDReader.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+
+@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 {
+ // do nothing
+}
+
+/**
+ * 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".
+ *
+ * @param image The image to decode
+ * @param hints Any hints that were requested
+ * @return The contents of the decoded barcode or nil if an error occurs
+ */
+- (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) / 2;
+ 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 = ZXNotFoundErrorInstance();
+ 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.
+ *
+ * @param row row to count from
+ * @param start offset into row to start at
+ * @param counters array into which to record counts or nil if counters cannot be filled entirely
+ * from row before running out of pixels
+ */
++ (BOOL)recordPattern:(ZXBitArray *)row start:(int)start counters:(ZXIntArray *)counters {
+ int numCounters = counters.length;
+ [counters clear];
+ int32_t *array = counters.array;
+ 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) {
+ array[counterPosition]++;
+ } else {
+ counterPosition++;
+ if (counterPosition == numCounters) {
+ break;
+ } else {
+ array[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:(ZXIntArray *)counters {
+ int numTransitionsLeft = counters.length;
+ 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]) {
+ 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.
+ *
+ * @param counters observed counters
+ * @param pattern expected pattern
+ * @param maxIndividualVariance The most any counter can differ before we give up
+ * @return ratio of total variance between counters and pattern compared to total pattern size
+ */
++ (float)patternMatchVariance:(ZXIntArray *)counters pattern:(const int[])pattern maxIndividualVariance:(float)maxIndividualVariance {
+ int numCounters = counters.length;
+ int total = 0;
+ int patternLength = 0;
+
+ int32_t *array = counters.array;
+ for (int i = 0; i < numCounters; i++) {
+ total += array[i];
+ patternLength += pattern[i];
+ }
+
+ if (total < patternLength || patternLength == 0) {
+ return FLT_MAX;
+ }
+ float unitBarWidth = (float) total / patternLength;
+ maxIndividualVariance *= unitBarWidth;
+
+ float totalVariance = 0.0f;
+ for (int x = 0; x < numCounters; x++) {
+ int counter = array[x];
+ float scaledPattern = pattern[x] * unitBarWidth;
+ float variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
+ if (variance > maxIndividualVariance) {
+ return FLT_MAX;
+ }
+ totalVariance += variance;
+ }
+
+ return totalVariance / total;
+}
+
+/**
+ * Attempts to decode a one-dimensional barcode format given a single row of
+ * an image.
+ *
+ * @param rowNumber row number from top of the row
+ * @param row the black/white pixel data of the row
+ * @param hints decode hints
+ * @return ZXResult containing encoded string and start/end of barcode or nil
+ * if an error occurs or barcode cannot be found
+ */
+- (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/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDimensionalCodeWriter.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDimensionalCodeWriter.h
new file mode 100644
index 0000000..170e00d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDimensionalCodeWriter.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 "ZXWriter.h"
+
+@class ZXBoolArray;
+
+/**
+ * Encapsulates functionality and implementation that is common to one-dimensional barcodes.
+ */
+@interface ZXOneDimensionalCodeWriter : NSObject
+
+- (ZXBoolArray *)encode:(NSString *)contents;
+- (int)appendPattern:(ZXBoolArray *)target pos:(int)pos pattern:(const int[])pattern patternLen:(int)patternLen startColor:(BOOL)startColor;
+- (int)defaultMargin;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDimensionalCodeWriter.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDimensionalCodeWriter.m
new file mode 100644
index 0000000..eb69f84
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXOneDimensionalCodeWriter.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 "ZXBitMatrix.h"
+#import "ZXBoolArray.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];
+}
+
+/**
+ * Encode the contents following specified format.
+ * width and height are required size. This method may return bigger size
+ * ZXBitMatrix when specified size is too small. The user can set both {width and
+ * height to zero to get minimum size barcode. If negative value is set to width
+ * or height, IllegalArgumentException is thrown.
+ */
+- (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;
+ }
+
+ ZXBoolArray *code = [self encode:contents];
+ return [self renderResult:code width:width height:height sidesMargin:sidesMargin];
+}
+
+/**
+ * @return a byte array of horizontal pixels (0 = white, 1 = black)
+ */
+- (ZXBitMatrix *)renderResult:(ZXBoolArray *)code width:(int)width height:(int)height sidesMargin:(int)sidesMargin {
+ int inputWidth = code.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 alloc] initWithWidth:outputWidth height:outputHeight];
+ for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
+ if (code.array[inputX]) {
+ [output setRegionAtLeft:outputX top:0 width:multiple height:outputHeight];
+ }
+ }
+ return output;
+}
+
+/**
+ * Appends the given pattern to the target array starting at pos.
+ *
+ * @param startColor starting color - false for white, true for black
+ * @return the number of elements added to target.
+ */
+- (int)appendPattern:(ZXBoolArray *)target pos:(int)pos pattern:(const 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.array[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.
+ *
+ * @return a ZXBoolArray of horizontal pixels (false = white, true = black)
+ */
+- (ZXBoolArray *)encode:(NSString *)contents {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAReader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAReader.h
new file mode 100644
index 0000000..097443c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAReader.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 "ZXUPCEANReader.h"
+
+/**
+ * Implements decoding of the UPC-A format.
+ */
+@interface ZXUPCAReader : ZXUPCEANReader
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAReader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAReader.m
new file mode 100644
index 0000000..659a71e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAReader.m
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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, readonly) 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 = ZXFormatErrorInstance();
+ 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 = ZXFormatErrorInstance();
+ 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 = ZXFormatErrorInstance();
+ 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 = ZXFormatErrorInstance();
+ 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:nil
+ resultPoints:result.resultPoints
+ format:kBarcodeFormatUPCA];
+ } else {
+ return nil;
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAWriter.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAWriter.h
new file mode 100644
index 0000000..0011de8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAWriter.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 "ZXWriter.h"
+
+/**
+ * This object renders a UPC-A code as a ZXBitMatrix.
+ */
+@interface ZXUPCAWriter : NSObject
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAWriter.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAWriter.m
new file mode 100644
index 0000000..6cbc3d1
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCAWriter.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 "ZXEAN13Writer.h"
+#import "ZXUPCAWriter.h"
+
+@implementation ZXUPCAWriter
+
+- (ZXEAN13Writer *)subWriter {
+ static ZXEAN13Writer *subWriter = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ 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/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension2Support.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension2Support.h
new file mode 100644
index 0000000..c185589
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension2Support.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, ZXResult;
+
+/**
+ * @see UPCEANExtension5Support
+ */
+@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/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension2Support.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension2Support.m
new file mode 100644
index 0000000..4188518
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension2Support.m
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXIntArray.h"
+#import "ZXResult.h"
+#import "ZXResultMetadataType.h"
+#import "ZXResultPoint.h"
+#import "ZXUPCEANExtension2Support.h"
+#import "ZXUPCEANReader.h"
+
+@interface ZXUPCEANExtension2Support ()
+
+@property (nonatomic, strong, readonly) ZXIntArray *decodeMiddleCounters;
+
+@end
+
+@implementation ZXUPCEANExtension2Support
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeMiddleCounters = [[ZXIntArray alloc] initWithLength:4];
+ }
+
+ return self;
+}
+
+- (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
+ 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 {
+ ZXIntArray *counters = self.decodeMiddleCounters;
+ [counters clear];
+ 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 rowOffset:rowOffset patternType:ZX_UPC_EAN_PATTERNS_L_AND_G_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch % 10)];
+ rowOffset += [counters sum];
+ 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 = ZXNotFoundErrorInstance();
+ return -1;
+ }
+
+ if ([result intValue] % 4 != checkParity) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return -1;
+ }
+
+ return rowOffset;
+}
+
+/**
+ * @param raw raw content of extension
+ * @return formatted interpretation of raw content as a NSDictionary mapping
+ * one ZXResultMetadataType to appropriate value, or nil if not known
+ */
+- (NSMutableDictionary *)parseExtensionString:(NSString *)raw {
+ if (raw.length != 2) {
+ return nil;
+ }
+ return [NSMutableDictionary dictionaryWithObject:@([raw intValue])
+ forKey:@(kResultMetadataTypeIssueNumber)];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension5Support.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension5Support.h
new file mode 100644
index 0000000..fed1545
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension5Support.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, ZXResult;
+
+/**
+ * @see UPCEANExtension2Support
+ */
+@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/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension5Support.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension5Support.m
new file mode 100644
index 0000000..081372a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtension5Support.m
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXIntArray.h"
+#import "ZXResult.h"
+#import "ZXResultMetadataType.h"
+#import "ZXResultPoint.h"
+#import "ZXUPCEANExtension5Support.h"
+#import "ZXUPCEANReader.h"
+
+const int ZX_UPCEAN_CHECK_DIGIT_ENCODINGS[] = {
+ 0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05
+};
+
+@interface ZXUPCEANExtension5Support ()
+
+@property (nonatomic, strong, readonly) ZXIntArray *decodeMiddleCounters;
+
+@end
+
+@implementation ZXUPCEANExtension5Support
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeMiddleCounters = [[ZXIntArray alloc] initWithLength:4];
+ }
+
+ return self;
+}
+
+- (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
+ 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 {
+ ZXIntArray *counters = self.decodeMiddleCounters;
+ [counters clear];
+
+ 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 rowOffset:rowOffset patternType:ZX_UPC_EAN_PATTERNS_L_AND_G_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch % 10)];
+ rowOffset += [counters sum];
+ if (bestMatch >= 10) {
+ lgPatternFound |= 1 << (4 - x);
+ }
+ if (x != 4) {
+ // Read off separator if not last
+ rowOffset = [row nextSet:rowOffset];
+ rowOffset = [row nextUnset:rowOffset];
+ }
+ }
+
+ if (result.length != 5) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return -1;
+ }
+
+ int checkDigit = [self determineCheckDigit:lgPatternFound];
+ if (checkDigit == -1) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return -1;
+ } else if ([self extensionChecksum:result] != checkDigit) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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 == ZX_UPCEAN_CHECK_DIGIT_ENCODINGS[d]) {
+ return d;
+ }
+ }
+ return -1;
+}
+
+/**
+ * @param raw raw content of extension
+ * @return formatted interpretation of raw content as a NSDictionary mapping
+ * one ZXResultMetadataType to appropriate value, or nil if not known
+ */
+- (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/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtensionSupport.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtensionSupport.h
new file mode 100644
index 0000000..b94101c
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtensionSupport.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtensionSupport.m
new file mode 100644
index 0000000..affe80b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANExtensionSupport.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 "ZXUPCEANExtensionSupport.h"
+#import "ZXUPCEANExtension2Support.h"
+#import "ZXUPCEANExtension5Support.h"
+#import "ZXUPCEANReader.h"
+
+const int ZX_UPCEAN_EXTENSION_START_PATTERN[] = {1,1,2};
+
+@interface ZXUPCEANExtensionSupport ()
+
+@property (nonatomic, strong, readonly) ZXUPCEANExtension2Support *twoSupport;
+@property (nonatomic, strong, readonly) 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:ZX_UPCEAN_EXTENSION_START_PATTERN
+ patternLen:sizeof(ZX_UPCEAN_EXTENSION_START_PATTERN)/sizeof(int)
+ 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/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANReader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANReader.h
new file mode 100644
index 0000000..535640b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANReader.h
@@ -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 "ZXBarcodeFormat.h"
+#import "ZXOneDReader.h"
+
+typedef enum {
+ ZX_UPC_EAN_PATTERNS_L_PATTERNS = 0,
+ ZX_UPC_EAN_PATTERNS_L_AND_G_PATTERNS
+} ZX_UPC_EAN_PATTERNS;
+
+extern const int ZX_UPC_EAN_START_END_PATTERN_LEN;
+extern const int ZX_UPC_EAN_START_END_PATTERN[];
+extern const int ZX_UPC_EAN_MIDDLE_PATTERN_LEN;
+extern const int ZX_UPC_EAN_MIDDLE_PATTERN[];
+extern const int ZX_UPC_EAN_L_PATTERNS_LEN;
+extern const int ZX_UPC_EAN_L_PATTERNS_SUB_LEN;
+extern const int ZX_UPC_EAN_L_PATTERNS[][4];
+extern const int ZX_UPC_EAN_L_AND_G_PATTERNS_LEN;
+extern const int ZX_UPC_EAN_L_AND_G_PATTERNS_SUB_LEN;
+extern const int ZX_UPC_EAN_L_AND_G_PATTERNS[][4];
+
+@class ZXDecodeHints, ZXEANManufacturerOrgSupport, ZXIntArray, ZXResult, ZXUPCEANExtensionSupport;
+
+/**
+ * Encapsulates functionality and implementation that is common to UPC and EAN families
+ * of one-dimensional barcodes.
+ */
+@interface ZXUPCEANReader : ZXOneDReader
+
++ (NSRange)findStartGuardPattern:(ZXBitArray *)row error:(NSError **)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;
+
+/**
+ * @return checkStandardUPCEANChecksum:
+ */
+- (BOOL)checkChecksum:(NSString *)s error:(NSError **)error;
+
+/**
+ * Computes the UPC/EAN checksum on a string of digits, and reports
+ * whether the checksum is correct or not.
+ *
+ * @param s string of digits to check
+ * @return YES iff string of digits passes the UPC/EAN checksum algorithm
+ * @return NO if the string does not contain only digits
+ */
++ (BOOL)checkStandardUPCEANChecksum:(NSString *)s;
+
+- (NSRange)decodeEnd:(ZXBitArray *)row endStart:(int)endStart error:(NSError **)error;
+
++ (NSRange)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset whiteFirst:(BOOL)whiteFirst pattern:(const int[])pattern patternLen:(int)patternLen error:(NSError **)error;
+
+/**
+ * @param row row of black/white values to search
+ * @param rowOffset position to start search
+ * @param whiteFirst if true, indicates that the pattern specifies white/black/white/...
+ * pixel counts, otherwise, it is interpreted as black/white/black/...
+ * @param pattern pattern of counts of number of black and white pixels that are being
+ * searched for as a pattern
+ * @param counters array of counters, as long as pattern, to re-use
+ * @return start/end horizontal offset of guard pattern, as an array of two ints
+ */
++ (NSRange)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset whiteFirst:(BOOL)whiteFirst pattern:(const int[])pattern patternLen:(int)patternLen counters:(ZXIntArray *)counters error:(NSError **)error;
+
+/**
+ * Attempts to decode a single UPC/EAN-encoded digit.
+ *
+ * @param row row of black/white values to decode
+ * @param counters the counts of runs of observed black/white/black/... values
+ * @param rowOffset horizontal offset to start decoding from
+ * @param patterns the set of patterns to use to decode -- sometimes different encodings
+ * for the digits 0-9 are used, and this indicates the encodings for 0 to 9 that should
+ * be used
+ * @return horizontal offset of first pixel beyond the decoded digit
+ * @return -1 if digit cannot be decoded
+ */
++ (int)decodeDigit:(ZXBitArray *)row counters:(ZXIntArray *)counters rowOffset:(int)rowOffset patternType:(ZX_UPC_EAN_PATTERNS)patternType error:(NSError **)error;
+
+/**
+ * Get the format of this decoder.
+ *
+ * @return The 1D format.
+ */
+- (ZXBarcodeFormat)barcodeFormat;
+
+/**
+ * Subclasses override this to decode the portion of a barcode between the start
+ * and end guard patterns.
+ *
+ * @param row row of black/white values to search
+ * @param startRange start/end offset of start guard pattern
+ * @param resultString NSMutableString to append decoded chars to
+ * @return horizontal offset of first pixel after the "middle" that was decoded
+ * @return -1 if decoding could not complete successfully
+ */
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANReader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANReader.m
new file mode 100644
index 0000000..1c6edf0
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANReader.m
@@ -0,0 +1,385 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXIntArray.h"
+#import "ZXResult.h"
+#import "ZXResultPoint.h"
+#import "ZXResultPointCallback.h"
+#import "ZXUPCEANReader.h"
+#import "ZXUPCEANExtensionSupport.h"
+
+static float ZX_UPC_EAN_MAX_AVG_VARIANCE = 0.48f;
+static float ZX_UPC_EAN_MAX_INDIVIDUAL_VARIANCE = 0.7f;
+
+/**
+ * Start/end guard pattern.
+ */
+const int ZX_UPC_EAN_START_END_PATTERN_LEN = 3;
+const int ZX_UPC_EAN_START_END_PATTERN[ZX_UPC_EAN_START_END_PATTERN_LEN] = {1, 1, 1};
+
+/**
+ * Pattern marking the middle of a UPC/EAN pattern, separating the two halves.
+ */
+const int ZX_UPC_EAN_MIDDLE_PATTERN_LEN = 5;
+const int ZX_UPC_EAN_MIDDLE_PATTERN[ZX_UPC_EAN_MIDDLE_PATTERN_LEN] = {1, 1, 1, 1, 1};
+
+/**
+ * "Odd", or "L" patterns used to encode UPC/EAN digits.
+ */
+const int ZX_UPC_EAN_L_PATTERNS_LEN = 10;
+const int ZX_UPC_EAN_L_PATTERNS_SUB_LEN = 4;
+const int ZX_UPC_EAN_L_PATTERNS[ZX_UPC_EAN_L_PATTERNS_LEN][ZX_UPC_EAN_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.
+ */
+const int ZX_UPC_EAN_L_AND_G_PATTERNS_LEN = 20;
+const int ZX_UPC_EAN_L_AND_G_PATTERNS_SUB_LEN = 4;
+const int ZX_UPC_EAN_L_AND_G_PATTERNS[ZX_UPC_EAN_L_AND_G_PATTERNS_LEN][ZX_UPC_EAN_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, readonly) NSMutableString *decodeRowNSMutableString;
+@property (nonatomic, strong, readonly) ZXUPCEANExtensionSupport *extensionReader;
+@property (nonatomic, strong, readonly) 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;
+ ZXIntArray *counters = [[ZXIntArray alloc] initWithLength:ZX_UPC_EAN_START_END_PATTERN_LEN];
+ while (!foundStart) {
+ [counters clear];
+ startRange = [self findGuardPattern:row rowOffset:nextStart
+ whiteFirst:NO
+ pattern:ZX_UPC_EAN_START_END_PATTERN
+ patternLen:ZX_UPC_EAN_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];
+}
+
+- (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row startGuardRange:(NSRange)startGuardRange hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ id 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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ NSString *resultString = [result description];
+ // UPC/EAN should never be less than 8 chars anyway
+ if ([resultString length] < 8) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ if (![self checkChecksum:resultString error:error]) {
+ if (error) *error = ZXChecksumErrorInstance();
+ 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:nil
+ resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber], [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
+ format:format];
+
+ int extensionLength = 0;
+
+ 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]];
+ extensionLength = (int)[extensionResult.text length];
+ }
+
+ ZXIntArray *allowedExtensions = hints == nil ? nil : hints.allowedEANExtensions;
+ if (allowedExtensions != nil) {
+ BOOL valid = NO;
+ for (int i = 0; i < allowedExtensions.length; i++) {
+ if (extensionLength == allowedExtensions.array[i]) {
+ valid = YES;
+ break;
+ }
+ }
+ if (!valid) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ }
+
+ 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 = ZXFormatErrorInstance();
+ return NO;
+ }
+}
+
++ (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:ZX_UPC_EAN_START_END_PATTERN
+ patternLen:ZX_UPC_EAN_START_END_PATTERN_LEN
+ error:error];
+}
+
++ (NSRange)findGuardPattern:(ZXBitArray *)row rowOffset:(int)rowOffset whiteFirst:(BOOL)whiteFirst pattern:(const int[])pattern patternLen:(int)patternLen error:(NSError **)error {
+ ZXIntArray *counters = [[ZXIntArray alloc] initWithLength: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:(const int[])pattern patternLen:(int)patternLen counters:(ZXIntArray *)counters error:(NSError **)error {
+ int patternLength = patternLen;
+ int width = row.size;
+ BOOL isWhite = whiteFirst;
+ rowOffset = whiteFirst ? [row nextUnset:rowOffset] : [row nextSet:rowOffset];
+ int counterPosition = 0;
+ int patternStart = rowOffset;
+ int32_t *array = counters.array;
+ for (int x = rowOffset; x < width; x++) {
+ if ([row get:x] ^ isWhite) {
+ array[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if ([self patternMatchVariance:counters pattern:pattern maxIndividualVariance:ZX_UPC_EAN_MAX_INDIVIDUAL_VARIANCE] < ZX_UPC_EAN_MAX_AVG_VARIANCE) {
+ return NSMakeRange(patternStart, x - patternStart);
+ }
+ patternStart += array[0] + array[1];
+
+ for (int y = 2; y < patternLength; y++) {
+ array[y - 2] = array[y];
+ }
+
+ array[patternLength - 2] = 0;
+ array[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ array[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ if (error) *error = ZXNotFoundErrorInstance();
+ return NSMakeRange(NSNotFound, 0);
+}
+
+/**
+ * Attempts to decode a single UPC/EAN-encoded digit.
+ */
++ (int)decodeDigit:(ZXBitArray *)row counters:(ZXIntArray *)counters rowOffset:(int)rowOffset patternType:(ZX_UPC_EAN_PATTERNS)patternType error:(NSError **)error {
+ if (![self recordPattern:row start:rowOffset counters:counters]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return -1;
+ }
+ float bestVariance = ZX_UPC_EAN_MAX_AVG_VARIANCE;
+ int bestMatch = -1;
+ int max = 0;
+ switch (patternType) {
+ case ZX_UPC_EAN_PATTERNS_L_PATTERNS:
+ max = ZX_UPC_EAN_L_PATTERNS_LEN;
+ for (int i = 0; i < max; i++) {
+ int pattern[counters.length];
+ for (int j = 0; j < counters.length; j++){
+ pattern[j] = ZX_UPC_EAN_L_PATTERNS[i][j];
+ }
+
+ float variance = [self patternMatchVariance:counters pattern:pattern maxIndividualVariance:ZX_UPC_EAN_MAX_INDIVIDUAL_VARIANCE];
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = i;
+ }
+ }
+ break;
+ case ZX_UPC_EAN_PATTERNS_L_AND_G_PATTERNS:
+ max = ZX_UPC_EAN_L_AND_G_PATTERNS_LEN;
+ for (int i = 0; i < max; i++) {
+ int pattern[counters.length];
+ for (int j = 0; j< counters.length; j++){
+ pattern[j] = ZX_UPC_EAN_L_AND_G_PATTERNS[i][j];
+ }
+
+ float variance = [self patternMatchVariance:counters pattern:pattern maxIndividualVariance:ZX_UPC_EAN_MAX_INDIVIDUAL_VARIANCE];
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = i;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (bestMatch >= 0) {
+ return bestMatch;
+ } else {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return -1;
+ }
+}
+
+- (ZXBarcodeFormat)barcodeFormat {
+ @throw [NSException exceptionWithName:NSInternalInconsistencyException
+ reason:[NSString stringWithFormat:@"You must override %@ in a subclass", NSStringFromSelector(_cmd)]
+ userInfo:nil];
+}
+
+- (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/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANWriter.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANWriter.h
new file mode 100644
index 0000000..ce78196
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANWriter.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"
+
+/**
+ * Encapsulates functionality and implementation that is common to UPC and EAN families
+ * of one-dimensional barcodes.
+ */
+@interface ZXUPCEANWriter : ZXOneDimensionalCodeWriter
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANWriter.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEANWriter.m
new file mode 100644
index 0000000..27ba383
--- /dev/null
+++ b/Pods/ZXingObjC/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 ZX_UPC_EAN_START_END_PATTERN_LEN;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEReader.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEReader.h
new file mode 100644
index 0000000..7553319
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEReader.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 "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/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEReader.m b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEReader.m
new file mode 100644
index 0000000..949861b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXUPCEReader.m
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXIntArray.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.
+ */
+const int ZX_UCPE_MIDDLE_END_PATTERN[] = {1, 1, 1, 1, 1, 1};
+
+/**
+ * See ZX_UCPE_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 ZX_UCPE_NUMSYS_AND_CHECK_DIGIT_PATTERNS[][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, strong, readonly) ZXIntArray *decodeMiddleCounters;
+
+@end
+
+@implementation ZXUPCEReader
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeMiddleCounters = [[ZXIntArray alloc] initWithLength:4];
+ }
+
+ return self;
+}
+
+- (int)decodeMiddle:(ZXBitArray *)row startRange:(NSRange)startRange result:(NSMutableString *)result error:(NSError **)error {
+ ZXIntArray *counters = self.decodeMiddleCounters;
+ [counters clear];
+
+ 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 rowOffset:rowOffset patternType:ZX_UPC_EAN_PATTERNS_L_AND_G_PATTERNS error:error];
+ if (bestMatch == -1) {
+ return -1;
+ }
+ [result appendFormat:@"%C", (unichar)('0' + bestMatch % 10)];
+
+ rowOffset += [counters sum];
+
+ if (bestMatch >= 10) {
+ lgPatternFound |= 1 << (5 - x);
+ }
+ }
+
+ if (![self determineNumSysAndCheckDigit:result lgPatternFound:lgPatternFound]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return -1;
+ }
+ return rowOffset;
+}
+
+- (NSRange)decodeEnd:(ZXBitArray *)row endStart:(int)endStart error:(NSError **)error {
+ return [ZXUPCEANReader findGuardPattern:row
+ rowOffset:endStart
+ whiteFirst:YES
+ pattern:ZX_UCPE_MIDDLE_END_PATTERN
+ patternLen:sizeof(ZX_UCPE_MIDDLE_END_PATTERN) / sizeof(int)
+ 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 == ZX_UCPE_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.
+ *
+ * @param upce UPC-E code as string of digits
+ * @return equivalent UPC-A code as string of digits
+ */
++ (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/Pods/ZXingObjC/ZXingObjC/oned/ZXingObjCOneD.h b/Pods/ZXingObjC/ZXingObjC/oned/ZXingObjCOneD.h
new file mode 100644
index 0000000..205b3e1
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/ZXingObjCOneD.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ZXINGOBJC_ONED_
+
+#define _ZXINGOBJC_ONED_
+
+// OneD
+
+#import "ZXAbstractExpandedDecoder.h"
+#import "ZXAbstractRSSReader.h"
+#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 "ZXITFReader.h"
+#import "ZXITFWriter.h"
+#import "ZXMultiFormatOneDReader.h"
+#import "ZXMultiFormatUPCEANReader.h"
+#import "ZXOneDimensionalCodeWriter.h"
+#import "ZXOneDReader.h"
+#import "ZXRSS14Reader.h"
+#import "ZXRSSDataCharacter.h"
+#import "ZXRSSExpandedReader.h"
+#import "ZXRSSFinderPattern.h"
+#import "ZXRSSUtils.h"
+#import "ZXUPCAReader.h"
+#import "ZXUPCAWriter.h"
+#import "ZXUPCEANReader.h"
+#import "ZXUPCEANWriter.h"
+#import "ZXUPCEReader.h"
+
+// Result Parsers
+
+#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 "ZXVINParsedResult.h"
+#import "ZXVINResultParser.h"
+#import "ZXWifiParsedResult.h"
+#import "ZXWifiResultParser.h"
+
+#endif
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXAbstractRSSReader.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXAbstractRSSReader.h
new file mode 100644
index 0000000..4723841
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXAbstractRSSReader.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"
+
+@class ZXIntArray;
+
+typedef enum {
+ ZX_RSS_PATTERNS_RSS14_PATTERNS = 0,
+ ZX_RSS_PATTERNS_RSS_EXPANDED_PATTERNS
+} ZX_RSS_PATTERNS;
+
+@interface ZXAbstractRSSReader : ZXOneDReader
+
+@property (nonatomic, strong, readonly) ZXIntArray *decodeFinderCounters;
+@property (nonatomic, strong, readonly) ZXIntArray *dataCharacterCounters;
+@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, strong, readonly) ZXIntArray *oddCounts;
+@property (nonatomic, strong, readonly) ZXIntArray *evenCounts;
+
++ (int)parseFinderValue:(ZXIntArray *)counters finderPatternType:(ZX_RSS_PATTERNS)finderPatternType;
++ (int)count:(ZXIntArray *)array;
++ (void)increment:(ZXIntArray *)array errors:(float *)errors;
++ (void)decrement:(ZXIntArray *)array errors:(float *)errors;
++ (BOOL)isFinderPattern:(ZXIntArray *)counters;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXAbstractRSSReader.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXAbstractRSSReader.m
new file mode 100644
index 0000000..66bb065
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXAbstractRSSReader.m
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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"
+#import "ZXIntArray.h"
+
+static float ZX_RSS_MAX_AVG_VARIANCE = 0.2f;
+static float ZX_RSS_MAX_INDIVIDUAL_VARIANCE = 0.45f;
+
+float const ZX_RSS_MIN_FINDER_PATTERN_RATIO = 9.5f / 12.0f;
+float const ZX_RSS_MAX_FINDER_PATTERN_RATIO = 12.5f / 14.0f;
+
+#define ZX_RSS14_FINDER_PATTERNS_LEN 9
+#define ZX_RSS14_FINDER_PATTERNS_SUB_LEN 4
+const int ZX_RSS14_FINDER_PATTERNS[ZX_RSS14_FINDER_PATTERNS_LEN][ZX_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 ZX_RSS_EXPANDED_FINDER_PATTERNS_LEN 6
+#define ZX_RSS_EXPANDED_FINDER_PATTERNS_SUB_LEN 4
+const int ZX_RSS_EXPANDED_FINDER_PATTERNS[ZX_RSS_EXPANDED_FINDER_PATTERNS_LEN][ZX_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
+
+- (id)init {
+ if (self = [super init]) {
+ _decodeFinderCounters = [[ZXIntArray alloc] initWithLength:4];
+ _dataCharacterCounters = [[ZXIntArray alloc] initWithLength:8];
+
+ _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));
+
+ _oddCounts = [[ZXIntArray alloc] initWithLength:_dataCharacterCounters.length / 2];
+ _evenCounts = [[ZXIntArray alloc] initWithLength:_dataCharacterCounters.length / 2];
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ if (_oddRoundingErrors != NULL) {
+ free(_oddRoundingErrors);
+ _oddRoundingErrors = NULL;
+ }
+
+ if (_evenRoundingErrors != NULL) {
+ free(_evenRoundingErrors);
+ _evenRoundingErrors = NULL;
+ }
+}
+
++ (int)parseFinderValue:(ZXIntArray *)counters finderPatternType:(ZX_RSS_PATTERNS)finderPatternType {
+ switch (finderPatternType) {
+ case ZX_RSS_PATTERNS_RSS14_PATTERNS:
+ for (int value = 0; value < ZX_RSS14_FINDER_PATTERNS_LEN; value++) {
+ if ([self patternMatchVariance:counters pattern:ZX_RSS14_FINDER_PATTERNS[value] maxIndividualVariance:ZX_RSS_MAX_INDIVIDUAL_VARIANCE] < ZX_RSS_MAX_AVG_VARIANCE) {
+ return value;
+ }
+ }
+ break;
+
+ case ZX_RSS_PATTERNS_RSS_EXPANDED_PATTERNS:
+ for (int value = 0; value < ZX_RSS_EXPANDED_FINDER_PATTERNS_LEN; value++) {
+ if ([self patternMatchVariance:counters pattern:ZX_RSS_EXPANDED_FINDER_PATTERNS[value] maxIndividualVariance:ZX_RSS_MAX_INDIVIDUAL_VARIANCE] < ZX_RSS_MAX_AVG_VARIANCE) {
+ return value;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
++ (int)count:(ZXIntArray *)array {
+ return [array sum];
+}
+
++ (void)increment:(ZXIntArray *)array errors:(float *)errors {
+ int index = 0;
+ float biggestError = errors[0];
+ for (int i = 1; i < array.length; i++) {
+ if (errors[i] > biggestError) {
+ biggestError = errors[i];
+ index = i;
+ }
+ }
+ array.array[index]++;
+}
+
++ (void)decrement:(ZXIntArray *)array errors:(float *)errors {
+ int index = 0;
+ float biggestError = errors[0];
+ for (int i = 1; i < array.length; i++) {
+ if (errors[i] < biggestError) {
+ biggestError = errors[i];
+ index = i;
+ }
+ }
+ array.array[index]--;
+}
+
++ (BOOL)isFinderPattern:(ZXIntArray *)counters {
+ int32_t *array = counters.array;
+ int firstTwoSum = array[0] + array[1];
+ int sum = firstTwoSum + array[2] + array[3];
+ float ratio = (float)firstTwoSum / (float)sum;
+ if (ratio >= ZX_RSS_MIN_FINDER_PATTERN_RATIO && ratio <= ZX_RSS_MAX_FINDER_PATTERN_RATIO) {
+ int minCounter = INT_MAX;
+ int maxCounter = INT_MIN;
+ for (int i = 0; i < counters.length; i++) {
+ int counter = array[i];
+ if (counter > maxCounter) {
+ maxCounter = counter;
+ }
+ if (counter < minCounter) {
+ minCounter = counter;
+ }
+ }
+
+ return maxCounter < 10 * minCounter;
+ }
+ return NO;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSS14Reader.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSS14Reader.h
new file mode 100644
index 0000000..49db392
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSS14Reader.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 "ZXAbstractRSSReader.h"
+
+@class ZXDecodeHints, ZXResult;
+
+/**
+ * Decodes RSS-14, including truncated and stacked variants. See ISO/IEC 24724:2006.
+ */
+@interface ZXRSS14Reader : ZXAbstractRSSReader
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSS14Reader.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSS14Reader.m
new file mode 100644
index 0000000..0653bf3
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSS14Reader.m
@@ -0,0 +1,440 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXIntArray.h"
+#import "ZXResult.h"
+#import "ZXResultPointCallback.h"
+#import "ZXRSS14Reader.h"
+#import "ZXRSSFinderPattern.h"
+#import "ZXRSSPair.h"
+#import "ZXRSSUtils.h"
+
+const int ZX_RSS14_OUTSIDE_EVEN_TOTAL_SUBSET[5] = {1,10,34,70,126};
+const int ZX_RSS14_INSIDE_ODD_TOTAL_SUBSET[4] = {4,20,48,81};
+const int ZX_RSS14_OUTSIDE_GSUM[5] = {0,161,961,2015,2715};
+const int ZX_RSS14_INSIDE_GSUM[4] = {0,336,1036,1516};
+const int ZX_RSS14_OUTSIDE_ODD_WIDEST[5] = {8,6,4,3,1};
+const int ZX_RSS14_INSIDE_ODD_WIDEST[4] = {2,4,6,8};
+
+@interface ZXRSS14Reader ()
+
+@property (nonatomic, strong, readonly) NSMutableArray *possibleLeftPairs;
+@property (nonatomic, strong, readonly) 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 {
+ ZXRSSPair *leftPair = [self decodePair:row right:NO rowNumber:rowNumber hints:hints];
+ [self addOrTally:self.possibleLeftPairs pair:leftPair];
+ [row reverse];
+ ZXRSSPair *rightPair = [self decodePair:row right:YES rowNumber:rowNumber hints:hints];
+ [self addOrTally:self.possibleRightPairs pair:rightPair];
+ [row reverse];
+
+ for (ZXRSSPair *left in self.possibleLeftPairs) {
+ if ([left count] > 1) {
+ for (ZXRSSPair *right in self.possibleRightPairs) {
+ if ([right count] > 1) {
+ if ([self checkChecksum:left rightPair:right]) {
+ return [self constructResult:left rightPair:right];
+ }
+ }
+ }
+ }
+ }
+
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+}
+
+- (void)addOrTally:(NSMutableArray *)possiblePairs pair:(ZXRSSPair *)pair {
+ if (pair == nil) {
+ return;
+ }
+ BOOL found = NO;
+ for (ZXRSSPair *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:(ZXRSSPair *)leftPair rightPair:(ZXRSSPair *)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:nil
+ resultPoints:@[leftPoints[0], leftPoints[1], rightPoints[0], rightPoints[1]]
+ format:kBarcodeFormatRSS14];
+}
+
+- (BOOL)checkChecksum:(ZXRSSPair *)leftPair rightPair:(ZXRSSPair *)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;
+}
+
+- (ZXRSSPair *)decodePair:(ZXBitArray *)row right:(BOOL)right rowNumber:(int)rowNumber hints:(ZXDecodeHints *)hints {
+ ZXIntArray *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 resultPointCallback = hints == nil ? nil : hints.resultPointCallback;
+ if (resultPointCallback != nil) {
+ float center = (startEnd.array[0] + startEnd.array[1]) / 2.0f;
+ if (right) {
+ center = [row size] - 1 - center;
+ }
+ [resultPointCallback foundPossibleResultPoint:[[ZXResultPoint alloc] initWithX:center y:rowNumber]];
+ }
+ ZXRSSDataCharacter *outside = [self decodeDataCharacter:row pattern:pattern outsideChar:YES];
+ ZXRSSDataCharacter *inside = [self decodeDataCharacter:row pattern:pattern outsideChar:NO];
+ if (!outside || !inside) {
+ return nil;
+ }
+ return [[ZXRSSPair alloc] initWithValue:1597 * outside.value + inside.value
+ checksumPortion:outside.checksumPortion + 4 * inside.checksumPortion
+ finderPattern:pattern];
+}
+
+- (ZXRSSDataCharacter *)decodeDataCharacter:(ZXBitArray *)row pattern:(ZXRSSFinderPattern *)pattern outsideChar:(BOOL)outsideChar {
+ ZXIntArray *counters = self.dataCharacterCounters;
+ [counters clear];
+ int32_t *array = counters.array;
+
+ if (outsideChar) {
+ if (![ZXOneDReader recordPatternInReverse:row start:[pattern startEnd].array[0] counters:counters]) {
+ return nil;
+ }
+ } else {
+ if (![ZXOneDReader recordPattern:row start:[pattern startEnd].array[1] counters:counters]) {
+ return nil;
+ }
+
+ for (int i = 0, j = counters.length - 1; i < j; i++, j--) {
+ int temp = array[i];
+ array[i] = array[j];
+ array[j] = temp;
+ }
+ }
+
+ int numModules = outsideChar ? 16 : 15;
+ float elementWidth = (float)[ZXAbstractRSSReader count:counters] / (float)numModules;
+
+ for (int i = 0; i < counters.length; i++) {
+ float value = (float) array[i] / elementWidth;
+ int count = (int)(value + 0.5f);
+ if (count < 1) {
+ count = 1;
+ } else if (count > 8) {
+ count = 8;
+ }
+ int offset = i / 2;
+ if ((i & 0x01) == 0) {
+ self.oddCounts.array[offset] = count;
+ self.oddRoundingErrors[offset] = value - count;
+ } else {
+ self.evenCounts.array[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.oddCounts.length - 1; i >= 0; i--) {
+ oddChecksumPortion *= 9;
+ oddChecksumPortion += self.oddCounts.array[i];
+ oddSum += self.oddCounts.array[i];
+ }
+ int evenChecksumPortion = 0;
+ int evenSum = 0;
+ for (int i = self.evenCounts.length - 1; i >= 0; i--) {
+ evenChecksumPortion *= 9;
+ evenChecksumPortion += self.evenCounts.array[i];
+ evenSum += self.evenCounts.array[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 = ZX_RSS14_OUTSIDE_ODD_WIDEST[group];
+ int evenWidest = 9 - oddWidest;
+ int vOdd = [ZXRSSUtils rssValue:self.oddCounts maxWidth:oddWidest noNarrow:NO];
+ int vEven = [ZXRSSUtils rssValue:self.evenCounts maxWidth:evenWidest noNarrow:YES];
+ int tEven = ZX_RSS14_OUTSIDE_EVEN_TOTAL_SUBSET[group];
+ int gSum = ZX_RSS14_OUTSIDE_GSUM[group];
+ return [[ZXRSSDataCharacter 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 = ZX_RSS14_INSIDE_ODD_WIDEST[group];
+ int evenWidest = 9 - oddWidest;
+ int vOdd = [ZXRSSUtils rssValue:self.oddCounts maxWidth:oddWidest noNarrow:YES];
+ int vEven = [ZXRSSUtils rssValue:self.evenCounts maxWidth:evenWidest noNarrow:NO];
+ int tOdd = ZX_RSS14_INSIDE_ODD_TOTAL_SUBSET[group];
+ int gSum = ZX_RSS14_INSIDE_GSUM[group];
+ return [[ZXRSSDataCharacter alloc] initWithValue:vEven * tOdd + vOdd + gSum checksumPortion:checksumPortion];
+ }
+}
+
+- (ZXIntArray *)findFinderPattern:(ZXBitArray *)row rowOffset:(int)rowOffset rightFinderPattern:(BOOL)rightFinderPattern {
+ ZXIntArray *counters = self.decodeFinderCounters;
+ [counters clear];
+ int32_t *array = counters.array;
+
+ 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) {
+ array[counterPosition]++;
+ } else {
+ if (counterPosition == 3) {
+ if ([ZXAbstractRSSReader isFinderPattern:counters]) {
+ return [[ZXIntArray alloc] initWithInts:patternStart, x, -1];
+ }
+ patternStart += array[0] + array[1];
+ array[0] = array[2];
+ array[1] = array[3];
+ array[2] = 0;
+ array[3] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ array[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+
+ return nil;
+}
+
+- (ZXRSSFinderPattern *)parseFoundFinderPattern:(ZXBitArray *)row rowNumber:(int)rowNumber right:(BOOL)right startEnd:(ZXIntArray *)startEnd {
+ BOOL firstIsBlack = [row get:startEnd.array[0]];
+ int firstElementStart = startEnd.array[0] - 1;
+
+ while (firstElementStart >= 0 && firstIsBlack ^ [row get:firstElementStart]) {
+ firstElementStart--;
+ }
+
+ firstElementStart++;
+ int firstCounter = startEnd.array[0] - firstElementStart;
+
+ ZXIntArray *counters = self.decodeFinderCounters;
+ int32_t *array = counters.array;
+ for (int i = counters.length - 1; i > 0; i--) {
+ array[i] = array[i-1];
+ }
+ array[0] = firstCounter;
+ int value = [ZXAbstractRSSReader parseFinderValue:counters finderPatternType:ZX_RSS_PATTERNS_RSS14_PATTERNS];
+ if (value == -1) {
+ return nil;
+ }
+ int start = firstElementStart;
+ int end = startEnd.array[1];
+ if (right) {
+ start = [row size] - 1 - start;
+ end = [row size] - 1 - end;
+ }
+ return [[ZXRSSFinderPattern alloc] initWithValue:value
+ startEnd:[[ZXIntArray alloc] initWithInts:firstElementStart, startEnd.array[1], -1]
+ start:start
+ end:end
+ rowNumber:rowNumber];
+}
+
+- (BOOL)adjustOddEvenCounts:(BOOL)outsideChar numModules:(int)numModules {
+ int oddSum = [ZXAbstractRSSReader count:self.oddCounts];
+ int evenSum = [ZXAbstractRSSReader count:self.evenCounts];
+ 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 errors:self.oddRoundingErrors];
+ }
+ if (decrementOdd) {
+ [ZXAbstractRSSReader decrement:self.oddCounts errors:self.oddRoundingErrors];
+ }
+ if (incrementEven) {
+ if (decrementEven) {
+ return NO;
+ }
+ [ZXAbstractRSSReader increment:self.evenCounts errors:self.oddRoundingErrors];
+ }
+ if (decrementEven) {
+ [ZXAbstractRSSReader decrement:self.evenCounts errors:self.evenRoundingErrors];
+ }
+ return YES;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSDataCharacter.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSDataCharacter.h
new file mode 100644
index 0000000..78a9901
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSDataCharacter.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 ZXRSSDataCharacter : NSObject
+
+@property (nonatomic, assign, readonly) int value;
+@property (nonatomic, assign, readonly) int checksumPortion;
+
+- (id)initWithValue:(int)value checksumPortion:(int)checksumPortion;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSDataCharacter.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSDataCharacter.m
new file mode 100644
index 0000000..c862338
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSDataCharacter.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 "ZXRSSDataCharacter.h"
+
+@implementation ZXRSSDataCharacter
+
+- (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:[ZXRSSDataCharacter class]]) {
+ return NO;
+ }
+
+ ZXRSSDataCharacter *that = (ZXRSSDataCharacter *)object;
+ return (self.value == that.value) && (self.checksumPortion == that.checksumPortion);
+}
+
+- (NSUInteger)hash {
+ return self.value ^ self.checksumPortion;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSFinderPattern.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSFinderPattern.h
new file mode 100644
index 0000000..f10eb1e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSFinderPattern.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 "ZXResultPoint.h"
+
+@class ZXIntArray;
+
+@interface ZXRSSFinderPattern : NSObject
+
+@property (nonatomic, assign, readonly) int value;
+@property (nonatomic, strong, readonly) ZXIntArray *startEnd;
+@property (nonatomic, strong, readonly) NSMutableArray *resultPoints;
+
+- (id)initWithValue:(int)value startEnd:(ZXIntArray *)startEnd start:(int)start end:(int)end rowNumber:(int)rowNumber;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSFinderPattern.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSFinderPattern.m
new file mode 100644
index 0000000..97af13c
--- /dev/null
+++ b/Pods/ZXingObjC/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:(ZXIntArray *)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/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSPair.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSPair.h
new file mode 100644
index 0000000..2815220
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSPair.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 "ZXRSSDataCharacter.h"
+
+@class ZXRSSFinderPattern;
+
+@interface ZXRSSPair : ZXRSSDataCharacter
+
+@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/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSPair.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSPair.m
new file mode 100644
index 0000000..ee2b8f9
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSPair.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 "ZXRSSPair.h"
+
+@interface ZXRSSPair ()
+
+@property (nonatomic, assign) int count;
+
+@end
+
+@implementation ZXRSSPair
+
+- (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/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSUtils.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSUtils.h
new file mode 100644
index 0000000..03b7105
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSUtils.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 ZXIntArray;
+
+/**
+ * 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:(ZXIntArray *)widths maxWidth:(int)maxWidth noNarrow:(BOOL)noNarrow;
+//+ (NSArray *)elements:(NSArray *)eDist N:(int)N K:(int)K;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSUtils.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSUtils.m
new file mode 100644
index 0000000..aa46919
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/ZXRSSUtils.m
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXIntArray.h"
+#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:(ZXIntArray *)widths maxWidth:(int)maxWidth noNarrow:(BOOL)noNarrow {
+ int elements = widths.length;
+ int n = 0;
+ for (int i = 0; i < elements; i++) {
+ n += widths.array[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.array[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 = 2 * K;
+ [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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.h
new file mode 100644
index 0000000..058b7cb
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXBitArrayBuilder.m
new file mode 100644
index 0000000..c8ff3b0
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXRSSDataCharacter.h"
+#import "ZXRSSExpandedPair.h"
+
+@implementation ZXBitArrayBuilder
+
++ (ZXBitArray *)buildBitArray:(NSArray *)pairs {
+ int charNumber = ((int)[pairs count] * 2) - 1;
+ if ([pairs[pairs.count - 1] rightChar] == nil) {
+ charNumber -= 1;
+ }
+
+ int size = 12 * charNumber;
+
+ ZXBitArray *binary = [[ZXBitArray alloc] initWithSize:size];
+ int accPos = 0;
+
+ ZXRSSExpandedPair *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) {
+ ZXRSSExpandedPair *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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedPair.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedPair.h
new file mode 100644
index 0000000..58c9047
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedPair.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 ZXRSSDataCharacter, ZXRSSFinderPattern;
+
+@interface ZXRSSExpandedPair : NSObject
+
+@property (nonatomic, strong, readonly) ZXRSSDataCharacter *leftChar;
+@property (nonatomic, strong, readonly) ZXRSSDataCharacter *rightChar;
+@property (nonatomic, strong, readonly) ZXRSSFinderPattern *finderPattern;
+@property (nonatomic, assign, readonly) BOOL mayBeLast;
+@property (nonatomic, assign, readonly) BOOL mustBeLast;
+
+- (id)initWithLeftChar:(ZXRSSDataCharacter *)leftChar rightChar:(ZXRSSDataCharacter *)rightChar finderPattern:(ZXRSSFinderPattern *)finderPattern mayBeLast:(BOOL)mayBeLast;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedPair.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedPair.m
new file mode 100644
index 0000000..879abe5
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedPair.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 "ZXRSSDataCharacter.h"
+#import "ZXRSSExpandedPair.h"
+#import "ZXRSSFinderPattern.h"
+
+@implementation ZXRSSExpandedPair
+
+- (id)initWithLeftChar:(ZXRSSDataCharacter *)leftChar rightChar:(ZXRSSDataCharacter *)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:[ZXRSSExpandedPair class]]) {
+ return NO;
+ }
+ ZXRSSExpandedPair *that = (ZXRSSExpandedPair *)object;
+ return [ZXRSSExpandedPair isEqualOrNil:self.leftChar toObject:that.leftChar] &&
+ [ZXRSSExpandedPair isEqualOrNil:self.rightChar toObject:that.rightChar] &&
+ [ZXRSSExpandedPair 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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.h
new file mode 100644
index 0000000..73541f7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.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"
+
+@class ZXRSSDataCharacter, ZXRSSFinderPattern;
+
+@interface ZXRSSExpandedReader : ZXAbstractRSSReader
+
+@property (nonatomic, strong, readonly) NSMutableArray *rows;
+
+- (ZXRSSDataCharacter *)decodeDataCharacter:(ZXBitArray *)row pattern:(ZXRSSFinderPattern *)pattern isOddPattern:(BOOL)isOddPattern leftChar:(BOOL)leftChar;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.m
new file mode 100644
index 0000000..4c680d7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedReader.m
@@ -0,0 +1,742 @@
+ /*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXErrors.h"
+#import "ZXIntArray.h"
+#import "ZXResult.h"
+#import "ZXRSSDataCharacter.h"
+#import "ZXRSSExpandedPair.h"
+#import "ZXRSSExpandedReader.h"
+#import "ZXRSSExpandedRow.h"
+#import "ZXRSSFinderPattern.h"
+#import "ZXRSSUtils.h"
+
+const int ZX_SYMBOL_WIDEST[] = {7, 5, 4, 3, 1};
+const int ZX_EVEN_TOTAL_SUBSET[] = {4, 20, 52, 104, 204};
+const int ZX_GSUM[] = {0, 348, 1388, 2948, 3988};
+
+const int ZX_WEIGHTS[][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 ZX_FINDER_PAT_A = 0;
+const int ZX_FINDER_PAT_B = 1;
+const int ZX_FINDER_PAT_C = 2;
+const int ZX_FINDER_PAT_D = 3;
+const int ZX_FINDER_PAT_E = 4;
+const int ZX_FINDER_PAT_F = 5;
+
+#define ZX_FINDER_PATTERN_SEQUENCES_LEN 10
+#define ZX_FINDER_PATTERN_SEQUENCES_SUBLEN 11
+const int ZX_FINDER_PATTERN_SEQUENCES[ZX_FINDER_PATTERN_SEQUENCES_LEN][ZX_FINDER_PATTERN_SEQUENCES_SUBLEN] = {
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_A },
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_B, ZX_FINDER_PAT_B },
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_C, ZX_FINDER_PAT_B, ZX_FINDER_PAT_D },
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_E, ZX_FINDER_PAT_B, ZX_FINDER_PAT_D, ZX_FINDER_PAT_C },
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_E, ZX_FINDER_PAT_B, ZX_FINDER_PAT_D, ZX_FINDER_PAT_D, ZX_FINDER_PAT_F },
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_E, ZX_FINDER_PAT_B, ZX_FINDER_PAT_D, ZX_FINDER_PAT_E, ZX_FINDER_PAT_F, ZX_FINDER_PAT_F },
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_A, ZX_FINDER_PAT_B, ZX_FINDER_PAT_B, ZX_FINDER_PAT_C, ZX_FINDER_PAT_C, ZX_FINDER_PAT_D, ZX_FINDER_PAT_D },
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_A, ZX_FINDER_PAT_B, ZX_FINDER_PAT_B, ZX_FINDER_PAT_C, ZX_FINDER_PAT_C, ZX_FINDER_PAT_D, ZX_FINDER_PAT_E, ZX_FINDER_PAT_E },
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_A, ZX_FINDER_PAT_B, ZX_FINDER_PAT_B, ZX_FINDER_PAT_C, ZX_FINDER_PAT_C, ZX_FINDER_PAT_D, ZX_FINDER_PAT_E, ZX_FINDER_PAT_F, ZX_FINDER_PAT_F },
+ { ZX_FINDER_PAT_A, ZX_FINDER_PAT_A, ZX_FINDER_PAT_B, ZX_FINDER_PAT_B, ZX_FINDER_PAT_C, ZX_FINDER_PAT_D, ZX_FINDER_PAT_D, ZX_FINDER_PAT_E, ZX_FINDER_PAT_E, ZX_FINDER_PAT_F, ZX_FINDER_PAT_F },
+};
+
+@interface ZXRSSExpandedReader ()
+
+@property (nonatomic, strong, readonly) ZXIntArray *startEnd;
+@property (nonatomic, strong, readonly) NSMutableArray *pairs;
+@property (nonatomic, strong) NSMutableArray *rows;
+@property (nonatomic, assign) BOOL startFromEven;
+
+@end
+
+@implementation ZXRSSExpandedReader
+
+- (id)init {
+ if (self = [super init]) {
+ _pairs = [NSMutableArray array];
+ _rows = [NSMutableArray array];
+ _startFromEven = NO;
+ _startEnd = [[ZXIntArray alloc] initWithLength:2];
+ }
+
+ 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];
+ self.startFromEven = NO;
+ NSMutableArray* pairs = [self decodeRow2pairs:rowNumber row:row error:error];
+ if (pairs) {
+ ZXResult *result = [self constructResult:pairs error:error];
+ if (result) {
+ return result;
+ }
+ }
+
+ [self.pairs removeAllObjects];
+ self.startFromEven = YES;
+ pairs = [self decodeRow2pairs:rowNumber row:row error:error];
+ if (!pairs) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ return [self constructResult:pairs error:error];
+}
+
+- (void)reset {
+ [self.pairs removeAllObjects];
+ [self.rows removeAllObjects];
+}
+
+- (NSMutableArray *)decodeRow2pairs:(int)rowNumber row:(ZXBitArray *)row error:(NSError **)error {
+ while (YES) {
+ ZXRSSExpandedPair *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++) {
+ ZXRSSExpandedRow *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 {
+ int count = (int)[pairs count];
+ for (int i = 0, sz = 2; i < ZX_FINDER_PATTERN_SEQUENCES_LEN; i++, sz++) {
+ if (count > sz) {
+ continue;
+ }
+
+ BOOL stop = YES;
+ for (int j = 0; j < count; j++) {
+ if ([[pairs[j] finderPattern] value] != ZX_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]) {
+ ZXRSSExpandedRow *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:[[ZXRSSExpandedRow 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 (ZXRSSExpandedRow *r in rows) {
+ if ([r.pairs count] == [pairs count]) {
+ continue;
+ }
+ BOOL allFound = YES;
+ for (ZXRSSExpandedPair *p in r.pairs) {
+ BOOL found = NO;
+ for (ZXRSSExpandedPair *pp in pairs) {
+ if ([p isEqual:pp]) {
+ found = YES;
+ break;
+ }
+ }
+ if (!found) {
+ allFound = NO;
+ break;
+ }
+ }
+ if (allFound) {
+ [toRemove addObject:r];
+ }
+ }
+
+ for (ZXRSSExpandedRow *r in toRemove) {
+ [rows removeObject:r];
+ }
+}
+
+- (BOOL)isPartialRow:(NSArray *)pairs of:(NSArray *)rows {
+ for (ZXRSSExpandedRow *r in rows) {
+ BOOL allFound = YES;
+ for (ZXRSSExpandedPair *p in pairs) {
+ BOOL found = NO;
+ for (ZXRSSExpandedPair *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 = [[((ZXRSSExpandedPair *)_pairs[0]) finderPattern] resultPoints];
+ NSArray *lastPoints = [[((ZXRSSExpandedPair *)[_pairs lastObject]) finderPattern] resultPoints];
+
+ return [ZXResult resultWithText:resultingString
+ rawBytes:nil
+ resultPoints:@[firstPoints[0], firstPoints[1], lastPoints[0], lastPoints[1]]
+ format:kBarcodeFormatRSSExpanded];
+}
+
+- (BOOL)checkChecksum {
+ ZXRSSExpandedPair *firstPair = self.pairs[0];
+ ZXRSSDataCharacter *checkCharacter = firstPair.leftChar;
+ ZXRSSDataCharacter *firstCharacter = firstPair.rightChar;
+
+ if (!firstCharacter) {
+ return NO;
+ }
+
+ int checksum = [firstCharacter checksumPortion];
+ int s = 2;
+
+ for (int i = 1; i < self.pairs.count; ++i) {
+ ZXRSSExpandedPair *currentPair = self.pairs[i];
+ checksum += currentPair.leftChar.checksumPortion;
+ s++;
+ ZXRSSDataCharacter *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;
+}
+
+- (ZXRSSExpandedPair *)retrieveNextPair:(ZXBitArray *)row previousPairs:(NSMutableArray *)previousPairs rowNumber:(int)rowNumber {
+ BOOL isOddPattern = [previousPairs count] % 2 == 0;
+ if (self.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:self.startEnd.array[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);
+
+ ZXRSSDataCharacter *leftChar = [self decodeDataCharacter:row pattern:pattern isOddPattern:isOddPattern leftChar:YES];
+ if (!leftChar) {
+ return nil;
+ }
+
+ if (previousPairs.count > 0 && [[previousPairs lastObject] mustBeLast]) {
+ return nil;
+ }
+
+ ZXRSSDataCharacter *rightChar = [self decodeDataCharacter:row pattern:pattern isOddPattern:isOddPattern leftChar:NO];
+ BOOL mayBeLast = YES;
+ return [[ZXRSSExpandedPair alloc] initWithLeftChar:leftChar rightChar:rightChar finderPattern:pattern mayBeLast:mayBeLast];
+}
+
+- (BOOL)findNextPair:(ZXBitArray *)row previousPairs:(NSMutableArray *)previousPairs forcedOffset:(int)forcedOffset {
+ ZXIntArray *counters = self.decodeFinderCounters;
+ [counters clear];
+
+ int width = row.size;
+
+ int rowOffset;
+ if (forcedOffset >= 0) {
+ rowOffset = forcedOffset;
+ } else if ([previousPairs count] == 0) {
+ rowOffset = 0;
+ } else {
+ ZXRSSExpandedPair *lastPair = [previousPairs lastObject];
+ rowOffset = [[lastPair finderPattern] startEnd].array[1];
+ }
+ BOOL searchingEvenPair = [previousPairs count] % 2 != 0;
+ if (self.startFromEven) {
+ searchingEvenPair = !searchingEvenPair;
+ }
+
+ BOOL isWhite = NO;
+ while (rowOffset < width) {
+ isWhite = ![row get:rowOffset];
+ if (!isWhite) {
+ break;
+ }
+ rowOffset++;
+ }
+
+ int counterPosition = 0;
+ int patternStart = rowOffset;
+ int32_t *array = counters.array;
+ for (int x = rowOffset; x < width; x++) {
+ if ([row get:x] ^ isWhite) {
+ array[counterPosition]++;
+ } else {
+ if (counterPosition == 3) {
+ if (searchingEvenPair) {
+ [self reverseCounters:counters];
+ }
+
+ if ([ZXAbstractRSSReader isFinderPattern:counters]) {
+ self.startEnd.array[0] = patternStart;
+ self.startEnd.array[1] = x;
+ return YES;
+ }
+
+ if (searchingEvenPair) {
+ [self reverseCounters:counters];
+ }
+
+ patternStart += array[0] + array[1];
+ array[0] = array[2];
+ array[1] = array[3];
+ array[2] = 0;
+ array[3] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ array[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ return NO;
+}
+
+- (void)reverseCounters:(ZXIntArray *)counters {
+ int length = counters.length;
+ int32_t *array = counters.array;
+ for (int i = 0; i < length / 2; ++i) {
+ int tmp = array[i];
+ array[i] = array[length - i - 1];
+ array[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 = self.startEnd.array[0] - 1;
+ // Locate element 1
+ while (firstElementStart >= 0 && ![row get:firstElementStart]) {
+ firstElementStart--;
+ }
+
+ firstElementStart++;
+ firstCounter = self.startEnd.array[0] - firstElementStart;
+ start = firstElementStart;
+ end = self.startEnd.array[1];
+ } else {
+ // If pattern number is even, the pattern is reversed, so we need to locate element 1 *after *the current block.
+
+ start = self.startEnd.array[0];
+
+ end = [row nextUnset:self.startEnd.array[1] + 1];
+ firstCounter = end - self.startEnd.array[1];
+ }
+
+ // Make 'counters' hold 1-4
+ ZXIntArray *counters = [[ZXIntArray alloc] initWithLength:self.decodeFinderCounters.length];
+ for (int i = 1; i < counters.length; i++) {
+ counters.array[i] = self.decodeFinderCounters.array[i - 1];
+ }
+
+ counters.array[0] = firstCounter;
+ memcpy(self.decodeFinderCounters.array, counters.array, counters.length * sizeof(int32_t));
+
+ int value = [ZXAbstractRSSReader parseFinderValue:counters finderPatternType:ZX_RSS_PATTERNS_RSS_EXPANDED_PATTERNS];
+ if (value == -1) {
+ return nil;
+ }
+ return [[ZXRSSFinderPattern alloc] initWithValue:value startEnd:[[ZXIntArray alloc] initWithInts:start, end, -1] start:start end:end rowNumber:rowNumber];
+}
+
+- (ZXRSSDataCharacter *)decodeDataCharacter:(ZXBitArray *)row pattern:(ZXRSSFinderPattern *)pattern isOddPattern:(BOOL)isOddPattern leftChar:(BOOL)leftChar {
+ ZXIntArray *counters = self.dataCharacterCounters;
+ [counters clear];
+
+ if (leftChar) {
+ if (![ZXOneDReader recordPatternInReverse:row start:[pattern startEnd].array[0] counters:counters]) {
+ return nil;
+ }
+ } else {
+ if (![ZXOneDReader recordPattern:row start:[pattern startEnd].array[1] counters:counters]) {
+ return nil;
+ }
+ // reverse it
+ int32_t *array = counters.array;
+ for (int i = 0, j = counters.length - 1; i < j; i++, j--) {
+ int temp = array[i];
+ array[i] = array[j];
+ array[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] / (float)numModules;
+
+ // Sanity check: element width for pattern and the character should match
+ float expectedElementWidth = (pattern.startEnd.array[1] - pattern.startEnd.array[0]) / 15.0f;
+ if (fabsf(elementWidth - expectedElementWidth) / expectedElementWidth > 0.3f) {
+ return nil;
+ }
+
+ int32_t *array = counters.array;
+ for (int i = 0; i < counters.length; i++) {
+ float value = 1.0f * array[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 / 2;
+ if ((i & 0x01) == 0) {
+ self.oddCounts.array[offset] = count;
+ self.oddRoundingErrors[offset] = value - count;
+ } else {
+ self.evenCounts.array[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.oddCounts.length - 1; i >= 0; i--) {
+ if ([self isNotA1left:pattern isOddPattern:isOddPattern leftChar:leftChar]) {
+ int weight = ZX_WEIGHTS[weightRowNumber][2 * i];
+ oddChecksumPortion += self.oddCounts.array[i] * weight;
+ }
+ oddSum += self.oddCounts.array[i];
+ }
+ int evenChecksumPortion = 0;
+ //int evenSum = 0;
+ for (int i = self.evenCounts.length - 1; i >= 0; i--) {
+ if ([self isNotA1left:pattern isOddPattern:isOddPattern leftChar:leftChar]) {
+ int weight = ZX_WEIGHTS[weightRowNumber][2 * i + 1];
+ evenChecksumPortion += self.evenCounts.array[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 = ZX_SYMBOL_WIDEST[group];
+ int evenWidest = 9 - oddWidest;
+ int vOdd = [ZXRSSUtils rssValue:self.oddCounts maxWidth:oddWidest noNarrow:YES];
+ int vEven = [ZXRSSUtils rssValue:self.evenCounts maxWidth:evenWidest noNarrow:NO];
+ int tEven = ZX_EVEN_TOTAL_SUBSET[group];
+ int gSum = ZX_GSUM[group];
+ int value = vOdd * tEven + vEven + gSum;
+ return [[ZXRSSDataCharacter 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];
+ int evenSum = [ZXAbstractRSSReader count:self.evenCounts];
+ 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 errors:self.oddRoundingErrors];
+ }
+ if (decrementOdd) {
+ [ZXAbstractRSSReader decrement:self.oddCounts errors:self.oddRoundingErrors];
+ }
+ if (incrementEven) {
+ if (decrementEven) {
+ return NO;
+ }
+ [ZXAbstractRSSReader increment:self.evenCounts errors:self.oddRoundingErrors];
+ }
+ if (decrementEven) {
+ [ZXAbstractRSSReader decrement:self.evenCounts errors:self.evenRoundingErrors];
+ }
+ return YES;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.h
new file mode 100644
index 0000000..d693366
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.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.
+ */
+
+/**
+ * One row of an RSS Expanded Stacked symbol, consisting of 1+ expanded pairs.
+ */
+@interface ZXRSSExpandedRow : NSObject
+
+@property (nonatomic, strong, readonly) NSArray *pairs;
+@property (nonatomic, assign, readonly) int rowNumber;
+/** Did this row of the image have to be reversed (mirrored) to recognize the pairs? */
+@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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.m
new file mode 100644
index 0000000..3629849
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/ZXRSSExpandedRow.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 "ZXRSSExpandedRow.h"
+
+@implementation ZXRSSExpandedRow
+
+- (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:[ZXRSSExpandedRow class]]) {
+ return NO;
+ }
+ ZXRSSExpandedRow *that = (ZXRSSExpandedRow *)object;
+ return [self.pairs isEqual:that.pairs] && (self.wasReversed == that.wasReversed);
+}
+
+- (NSUInteger)hash {
+ return self.pairs.hash ^ @(self.wasReversed).hash;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.h
new file mode 100644
index 0000000..c8b40e7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.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 ZXAI013103decoder : ZXAI013x0xDecoder
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013103decoder.m
new file mode 100644
index 0000000..06ce8d0
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.h
new file mode 100644
index 0000000..ea1d339
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01320xDecoder.m
new file mode 100644
index 0000000..714331c
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.h
new file mode 100644
index 0000000..4ae02cc
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01392xDecoder.m
new file mode 100644
index 0000000..6013336
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXErrors.h"
+#import "ZXRSSExpandedDecodedInformation.h"
+#import "ZXRSSExpandedGeneralAppIdDecoder.h"
+
+const int ZX_AI01392x_HEADER_SIZE = 5 + 1 + 2;
+const int ZX_AI01392x_LAST_DIGIT_SIZE = 2;
+
+@implementation ZXAI01392xDecoder
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ if (self.information.size < ZX_AI01392x_HEADER_SIZE + ZX_AI01_GTIN_SIZE) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ NSMutableString *buf = [NSMutableString string];
+ [self encodeCompressedGtin:buf currentPos:ZX_AI01392x_HEADER_SIZE];
+ int lastAIdigit = [self.generalDecoder extractNumericValueFromBitArray:ZX_AI01392x_HEADER_SIZE + ZX_AI01_GTIN_SIZE bits:ZX_AI01392x_LAST_DIGIT_SIZE];
+ [buf appendFormat:@"(392%d)", lastAIdigit];
+ ZXRSSExpandedDecodedInformation *decodedInformation = [self.generalDecoder decodeGeneralPurposeField:ZX_AI01392x_HEADER_SIZE + ZX_AI01_GTIN_SIZE + ZX_AI01392x_LAST_DIGIT_SIZE remaining:nil];
+ [buf appendString:decodedInformation.theNewString];
+ return buf;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.h
new file mode 100644
index 0000000..9fac134
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.m
new file mode 100644
index 0000000..fcde532
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01393xDecoder.m
@@ -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.
+ */
+
+#import "ZXAI01393xDecoder.h"
+#import "ZXBitArray.h"
+#import "ZXErrors.h"
+#import "ZXRSSExpandedDecodedInformation.h"
+#import "ZXRSSExpandedGeneralAppIdDecoder.h"
+
+@implementation ZXAI01393xDecoder
+
+const int ZX_AI01393xDecoder_HEADER_SIZE = 5 + 1 + 2;
+const int ZX_AI01393xDecoder_LAST_DIGIT_SIZE = 2;
+const int ZX_AI01393xDecoder_FIRST_THREE_DIGITS_SIZE = 10;
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ if (self.information.size < ZX_AI01393xDecoder_HEADER_SIZE + ZX_AI01_GTIN_SIZE) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ NSMutableString *buf = [NSMutableString string];
+
+ [self encodeCompressedGtin:buf currentPos:ZX_AI01393xDecoder_HEADER_SIZE];
+
+ int lastAIdigit = [self.generalDecoder extractNumericValueFromBitArray:ZX_AI01393xDecoder_HEADER_SIZE + ZX_AI01_GTIN_SIZE
+ bits:ZX_AI01393xDecoder_LAST_DIGIT_SIZE];
+
+ [buf appendFormat:@"(393%d)", lastAIdigit];
+
+ int firstThreeDigits = [self.generalDecoder extractNumericValueFromBitArray:ZX_AI01393xDecoder_HEADER_SIZE + ZX_AI01_GTIN_SIZE + ZX_AI01393xDecoder_LAST_DIGIT_SIZE
+ bits:ZX_AI01393xDecoder_FIRST_THREE_DIGITS_SIZE];
+ if (firstThreeDigits / 100 == 0) {
+ [buf appendString:@"0"];
+ }
+ if (firstThreeDigits / 10 == 0) {
+ [buf appendString:@"0"];
+ }
+ [buf appendFormat:@"%d", firstThreeDigits];
+
+ ZXRSSExpandedDecodedInformation *generalInformation = [self.generalDecoder decodeGeneralPurposeField:ZX_AI01393xDecoder_HEADER_SIZE + ZX_AI01_GTIN_SIZE + ZX_AI01393xDecoder_LAST_DIGIT_SIZE + ZX_AI01393xDecoder_FIRST_THREE_DIGITS_SIZE
+ remaining:nil];
+ [buf appendString:generalInformation.theNewString];
+
+ return buf;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.h
new file mode 100644
index 0000000..3f2211d
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0x1xDecoder.m
new file mode 100644
index 0000000..41fe6f2
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXRSSExpandedGeneralAppIdDecoder.h"
+
+const int ZX_AI013x0x1x_HEADER_SIZE = 7 + 1;
+const int ZX_AI013x0x1x_WEIGHT_SIZE = 20;
+const int ZX_AI013x0x1x_DATE_SIZE = 16;
+
+@interface ZXAI013x0x1xDecoder ()
+
+@property (nonatomic, copy, readonly) NSString *dateCode;
+@property (nonatomic, copy, readonly) 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 != ZX_AI013x0x1x_HEADER_SIZE + ZX_AI01_GTIN_SIZE + ZX_AI013x0x1x_WEIGHT_SIZE + ZX_AI013x0x1x_DATE_SIZE) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ NSMutableString *buf = [NSMutableString string];
+ [self encodeCompressedGtin:buf currentPos:ZX_AI013x0x1x_HEADER_SIZE];
+ [self encodeCompressedWeight:buf currentPos:ZX_AI013x0x1x_HEADER_SIZE + ZX_AI01_GTIN_SIZE weightSize:ZX_AI013x0x1x_WEIGHT_SIZE];
+ [self encodeCompressedDate:buf currentPos:ZX_AI013x0x1x_HEADER_SIZE + ZX_AI01_GTIN_SIZE + ZX_AI013x0x1x_WEIGHT_SIZE];
+ return buf;
+}
+
+- (void)encodeCompressedDate:(NSMutableString *)buf currentPos:(int)currentPos {
+ int numericDate = [self.generalDecoder extractNumericValueFromBitArray:currentPos bits:ZX_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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.h
new file mode 100644
index 0000000..0f02d6c
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI013x0xDecoder.m
new file mode 100644
index 0000000..6a410c7
--- /dev/null
+++ b/Pods/ZXingObjC/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"
+
+const int ZX_AI013x0x_HEADER_SIZE = 4 + 1;
+const int ZX_AI013x0x_WEIGHT_SIZE = 15;
+
+@implementation ZXAI013x0xDecoder
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ if (self.information.size != ZX_AI013x0x_HEADER_SIZE + ZX_AI01_GTIN_SIZE + ZX_AI013x0x_WEIGHT_SIZE) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ NSMutableString *buf = [NSMutableString string];
+
+ [self encodeCompressedGtin:buf currentPos:ZX_AI013x0x_HEADER_SIZE];
+ [self encodeCompressedWeight:buf currentPos:ZX_AI013x0x_HEADER_SIZE + ZX_AI01_GTIN_SIZE weightSize:ZX_AI013x0x_WEIGHT_SIZE];
+
+ return buf;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.h
new file mode 100644
index 0000000..4299580
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01AndOtherAIs.m
new file mode 100644
index 0000000..3b410af
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXRSSExpandedGeneralAppIdDecoder.h"
+
+const int ZX_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:ZX_AI01_HEADER_SIZE bits:4];
+ [buff appendFormat:@"%d", firstGtinDigit];
+
+ [self encodeCompressedGtinWithoutAI:buff currentPos:ZX_AI01_HEADER_SIZE + 4 initialBufferPosition:initialGtinPosition];
+
+ return [self.generalDecoder decodeAllCodes:buff initialPosition:ZX_AI01_HEADER_SIZE + 44 error:error];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.h
new file mode 100644
index 0000000..49117a7
--- /dev/null
+++ b/Pods/ZXingObjC/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 ZX_AI01_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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01decoder.m
new file mode 100644
index 0000000..8696d1c
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXRSSExpandedGeneralAppIdDecoder.h"
+
+const int ZX_AI01_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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.h
new file mode 100644
index 0000000..670fa44
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.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 "ZXAI01decoder.h"
+
+@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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAI01weightDecoder.m
new file mode 100644
index 0000000..b89bc96
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXRSSExpandedGeneralAppIdDecoder.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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.h
new file mode 100644
index 0000000..f272ca2
--- /dev/null
+++ b/Pods/ZXingObjC/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, ZXRSSExpandedGeneralAppIdDecoder;
+
+@interface ZXAbstractExpandedDecoder : NSObject
+
+@property (nonatomic, strong, readonly) ZXRSSExpandedGeneralAppIdDecoder *generalDecoder;
+@property (nonatomic, strong, readonly) ZXBitArray *information;
+
+- (id)initWithInformation:(ZXBitArray *)information;
+- (NSString *)parseInformationWithError:(NSError **)error;
++ (ZXAbstractExpandedDecoder *)createDecoder:(ZXBitArray *)information;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAbstractExpandedDecoder.m
new file mode 100644
index 0000000..6fe8492
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXRSSExpandedGeneralAppIdDecoder.h"
+
+@implementation ZXAbstractExpandedDecoder
+
+- (id)initWithInformation:(ZXBitArray *)information {
+ if (self = [super init]) {
+ _information = information;
+ _generalDecoder = [[ZXRSSExpandedGeneralAppIdDecoder 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 = [ZXRSSExpandedGeneralAppIdDecoder extractNumericValueFromBitArray:information pos:1 bits:4];
+
+ switch (fourBitEncodationMethod) {
+ case 4:
+ return [[ZXAI013103decoder alloc] initWithInformation:information];
+ case 5:
+ return [[ZXAI01320xDecoder alloc] initWithInformation:information];
+ }
+
+ int fiveBitEncodationMethod = [ZXRSSExpandedGeneralAppIdDecoder extractNumericValueFromBitArray:information pos:1 bits:5];
+ switch (fiveBitEncodationMethod) {
+ case 12:
+ return [[ZXAI01392xDecoder alloc] initWithInformation:information];
+ case 13:
+ return [[ZXAI01393xDecoder alloc] initWithInformation:information];
+ }
+
+ int sevenBitEncodationMethod = [ZXRSSExpandedGeneralAppIdDecoder 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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.h
new file mode 100644
index 0000000..3dfda95
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXAnyAIDecoder.m
new file mode 100644
index 0000000..ec3fdfc
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXRSSExpandedGeneralAppIdDecoder.h"
+
+const int ZX_ANY_AI_HEADER_SIZE = 2 + 1 + 2;
+
+@implementation ZXAnyAIDecoder
+
+- (NSString *)parseInformationWithError:(NSError **)error {
+ NSMutableString *buf = [NSMutableString string];
+ return [self.generalDecoder decodeAllCodes:buf initialPosition:ZX_ANY_AI_HEADER_SIZE error:error];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.h
new file mode 100644
index 0000000..691ebd7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.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 ZXRSSExpandedDecodedInformation;
+
+@interface ZXRSSExpandedBlockParsedResult : NSObject
+
+@property (nonatomic, strong, readonly) ZXRSSExpandedDecodedInformation *decodedInformation;
+@property (nonatomic, assign, readonly) BOOL finished;
+
+- (id)initWithFinished:(BOOL)finished;
+- (id)initWithInformation:(ZXRSSExpandedDecodedInformation *)information finished:(BOOL)finished;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.m
new file mode 100644
index 0000000..0b5c6cd
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedBlockParsedResult.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 "ZXRSSExpandedBlockParsedResult.h"
+#import "ZXRSSExpandedDecodedInformation.h"
+
+@implementation ZXRSSExpandedBlockParsedResult
+
+- (id)initWithFinished:(BOOL)finished {
+ return [self initWithInformation:nil finished:finished];
+}
+
+- (id)initWithInformation:(ZXRSSExpandedDecodedInformation *)information finished:(BOOL)finished {
+ if (self = [super init]) {
+ _decodedInformation = information;
+ _finished = finished;
+ }
+
+ return self;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.h
new file mode 100644
index 0000000..b4c88c8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.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 ZXRSSExpandedCurrentParsingState : NSObject
+
+@property (nonatomic, assign) int position;
+
+- (BOOL)alpha;
+- (BOOL)numeric;
+- (BOOL)isoIec646;
+- (void)setNumeric;
+- (void)setAlpha;
+- (void)setIsoIec646;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.m
new file mode 100644
index 0000000..c21dedf
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedCurrentParsingState.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 "ZXRSSExpandedCurrentParsingState.h"
+
+enum {
+ ZX_NUMERIC_STATE,
+ ZX_ALPHA_STATE,
+ ZX_ISO_IEC_646_STATE
+};
+
+@interface ZXRSSExpandedCurrentParsingState ()
+
+@property (nonatomic, assign) int encoding;
+
+@end
+
+@implementation ZXRSSExpandedCurrentParsingState
+
+- (id)init {
+ if (self = [super init]) {
+ _position = 0;
+ _encoding = ZX_NUMERIC_STATE;
+ }
+ return self;
+}
+
+- (BOOL)alpha {
+ return self.encoding == ZX_ALPHA_STATE;
+}
+
+- (BOOL)numeric {
+ return self.encoding == ZX_NUMERIC_STATE;
+}
+
+- (BOOL)isoIec646 {
+ return self.encoding == ZX_ISO_IEC_646_STATE;
+}
+
+- (void)setNumeric {
+ self.encoding = ZX_NUMERIC_STATE;
+}
+
+- (void)setAlpha {
+ self.encoding = ZX_ALPHA_STATE;
+}
+
+- (void)setIsoIec646 {
+ self.encoding = ZX_ISO_IEC_646_STATE;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedChar.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedChar.h
new file mode 100644
index 0000000..b879132
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedChar.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 "ZXRSSExpandedDecodedObject.h"
+
+extern unichar const ZX_FNC1_CHAR;
+
+@interface ZXRSSExpandedDecodedChar : ZXRSSExpandedDecodedObject
+
+@property (nonatomic, assign, readonly) unichar value;
+
+- (id)initWithNewPosition:(int)newPosition value:(unichar)value;
+- (BOOL)fnc1;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedChar.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedChar.m
new file mode 100644
index 0000000..e5fff1d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedChar.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 "ZXRSSExpandedDecodedChar.h"
+
+unichar const ZX_FNC1_CHAR = '$'; // It's not in Alphanumeric neither in ISO/IEC 646 charset
+
+@implementation ZXRSSExpandedDecodedChar
+
+- (id)initWithNewPosition:(int)newPosition value:(unichar)value {
+ if (self = [super initWithNewPosition:newPosition]) {
+ _value = value;
+ }
+
+ return self;
+}
+
+- (BOOL)fnc1 {
+ return self.value == ZX_FNC1_CHAR;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedInformation.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedInformation.h
new file mode 100644
index 0000000..14ba181
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedInformation.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 "ZXRSSExpandedDecodedObject.h"
+
+@interface ZXRSSExpandedDecodedInformation : ZXRSSExpandedDecodedObject
+
+@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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedInformation.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedInformation.m
new file mode 100644
index 0000000..6111339
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedInformation.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 "ZXRSSExpandedDecodedInformation.h"
+
+@implementation ZXRSSExpandedDecodedInformation
+
+- (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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedNumeric.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedNumeric.h
new file mode 100644
index 0000000..576531c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedNumeric.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 "ZXRSSExpandedDecodedObject.h"
+
+extern const int ZX_FNC1_INT;
+
+@interface ZXRSSExpandedDecodedNumeric : ZXRSSExpandedDecodedObject
+
+@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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedNumeric.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedNumeric.m
new file mode 100644
index 0000000..523c83d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedNumeric.m
@@ -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 "ZXRSSExpandedDecodedNumeric.h"
+
+const int ZX_FNC1_INT = 10;
+
+@implementation ZXRSSExpandedDecodedNumeric
+
+- (id)initWithNewPosition:(int)newPosition firstDigit:(int)firstDigit secondDigit:(int)secondDigit {
+ if (firstDigit < 0 || firstDigit > 10 || secondDigit < 0 || secondDigit > 10) {
+ return nil;
+ }
+
+ if (self = [super initWithNewPosition:newPosition]) {
+ _firstDigit = firstDigit;
+ _secondDigit = secondDigit;
+ }
+
+ return self;
+}
+
+- (int)value {
+ return self.firstDigit * 10 + self.secondDigit;
+}
+
+- (BOOL)firstDigitFNC1 {
+ return self.firstDigit == ZX_FNC1_INT;
+}
+
+- (BOOL)secondDigitFNC1 {
+ return self.secondDigit == ZX_FNC1_INT;
+}
+
+- (BOOL)anyFNC1 {
+ return self.firstDigit == ZX_FNC1_INT || self.secondDigit == ZX_FNC1_INT;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.h
new file mode 100644
index 0000000..5dce8c8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.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 ZXRSSExpandedDecodedObject : NSObject
+
+@property (nonatomic, assign, readonly) int theNewPosition;
+
+- (id)initWithNewPosition:(int)newPosition;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.m
new file mode 100644
index 0000000..ea1793e
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedDecodedObject.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 "ZXRSSExpandedDecodedObject.h"
+
+@implementation ZXRSSExpandedDecodedObject
+
+- (id)initWithNewPosition:(int)newPosition {
+ if (self = [super init]) {
+ _theNewPosition = newPosition;
+ }
+
+ return self;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedFieldParser.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedFieldParser.h
new file mode 100644
index 0000000..767bc23
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedFieldParser.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 ZXRSSExpandedFieldParser : NSObject
+
++ (NSString *)parseFieldsInGeneralPurpose:(NSString *)rawInformation error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedFieldParser.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedFieldParser.m
new file mode 100644
index 0000000..f7299f8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedFieldParser.m
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXRSSExpandedFieldParser.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 ZXRSSExpandedFieldParser
+
++ (void)initialize {
+ if ([self class] != [ZXRSSExpandedFieldParser class]) return;
+
+ 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 = ZXNotFoundErrorInstance();
+ 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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ return result;
+ }
+ }
+
+ if ([rawInformation length] < 3) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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 = ZXNotFoundErrorInstance();
+ 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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ return result;
+ }
+ }
+
+ if ([rawInformation length] < 4) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ return result;
+ }
+ NSString *result = [self processFixedAI:4
+ fieldSize:[FOUR_DIGIT_DATA_LENGTH[i][1] intValue]
+ rawInformation:rawInformation];
+ if (!result) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ return result;
+ }
+ }
+
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedGeneralAppIdDecoder.h b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedGeneralAppIdDecoder.h
new file mode 100644
index 0000000..451766c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedGeneralAppIdDecoder.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, ZXRSSExpandedDecodedInformation;
+
+@interface ZXRSSExpandedGeneralAppIdDecoder : 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;
+- (ZXRSSExpandedDecodedInformation *)decodeGeneralPurposeField:(int)pos remaining:(NSString *)remaining;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedGeneralAppIdDecoder.m b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedGeneralAppIdDecoder.m
new file mode 100644
index 0000000..710086a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/oned/rss/expanded/decoders/ZXRSSExpandedGeneralAppIdDecoder.m
@@ -0,0 +1,517 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXRSSExpandedBlockParsedResult.h"
+#import "ZXRSSExpandedCurrentParsingState.h"
+#import "ZXRSSExpandedDecodedChar.h"
+#import "ZXRSSExpandedDecodedInformation.h"
+#import "ZXRSSExpandedDecodedNumeric.h"
+#import "ZXRSSExpandedFieldParser.h"
+#import "ZXRSSExpandedGeneralAppIdDecoder.h"
+
+@interface ZXRSSExpandedGeneralAppIdDecoder ()
+
+@property (nonatomic, strong, readonly) ZXBitArray *information;
+@property (nonatomic, strong, readonly) ZXRSSExpandedCurrentParsingState *current;
+@property (nonatomic, strong, readonly) NSMutableString *buffer;
+
+@end
+
+@implementation ZXRSSExpandedGeneralAppIdDecoder
+
+- (id)initWithInformation:(ZXBitArray *)information {
+ if (self = [super init]) {
+ _current = [[ZXRSSExpandedCurrentParsingState 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 {
+ ZXRSSExpandedDecodedInformation *info = [self decodeGeneralPurposeField:currentPosition remaining:remaining];
+ if (!info) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ NSString *parsedFields = [ZXRSSExpandedFieldParser 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]) {// No step forward!
+ break;
+ }
+ currentPosition = [info theNewPosition];
+ } while (YES);
+
+ return buff;
+}
+
+- (BOOL)isStillNumeric:(int)pos {
+ // It's numeric if it still has 7 positions
+ // and one of the first 4 bits is "1".
+ 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];
+}
+
+- (ZXRSSExpandedDecodedNumeric *)decodeNumeric:(int)pos {
+ if (pos + 7 > self.information.size) {
+ int numeric = [self extractNumericValueFromBitArray:pos bits:4];
+ if (numeric == 0) {
+ return [[ZXRSSExpandedDecodedNumeric alloc] initWithNewPosition:self.information.size
+ firstDigit:ZX_FNC1_INT
+ secondDigit:ZX_FNC1_INT];
+ }
+ return [[ZXRSSExpandedDecodedNumeric alloc] initWithNewPosition:self.information.size
+ firstDigit:numeric - 1
+ secondDigit:ZX_FNC1_INT];
+ }
+ int numeric = [self extractNumericValueFromBitArray:pos bits:7];
+
+ int digit1 = (numeric - 8) / 11;
+ int digit2 = (numeric - 8) % 11;
+
+ return [[ZXRSSExpandedDecodedNumeric alloc] initWithNewPosition:pos + 7
+ firstDigit:digit1
+ secondDigit:digit2];
+}
+
+- (int)extractNumericValueFromBitArray:(int)pos bits:(int)bits {
+ return [ZXRSSExpandedGeneralAppIdDecoder 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;
+}
+
+- (ZXRSSExpandedDecodedInformation *)decodeGeneralPurposeField:(int)pos remaining:(NSString *)remaining {
+ [self.buffer setString:@""];
+
+ if (remaining != nil) {
+ [self.buffer appendString:remaining];
+ }
+
+ self.current.position = pos;
+
+ NSError *error;
+ ZXRSSExpandedDecodedInformation *lastDecoded = [self parseBlocksWithError:&error];
+ if (error) {
+ return nil;
+ }
+
+ if (lastDecoded != nil && [lastDecoded remaining]) {
+ return [[ZXRSSExpandedDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer
+ remainingValue:lastDecoded.remainingValue];
+ }
+ return [[ZXRSSExpandedDecodedInformation alloc] initWithNewPosition:self.current.position newString:self.buffer];
+}
+
+- (ZXRSSExpandedDecodedInformation *)parseBlocksWithError:(NSError **)error {
+ BOOL isFinished;
+ ZXRSSExpandedBlockParsedResult *result;
+ do {
+ int initialPosition = self.current.position;
+
+ NSError *localError;
+ if (self.current.alpha) {
+ result = [self parseAlphaBlock];
+ isFinished = result.finished;
+ } else if (self.current.isoIec646) {
+ result = [self parseIsoIec646BlockWithError:&localError];
+ isFinished = result.finished;
+ } else {
+ result = [self parseNumericBlockWithError:&localError];
+ isFinished = result.finished;
+ }
+
+ if (localError) {
+ if (error) *error = localError;
+ return nil;
+ }
+
+ BOOL positionChanged = initialPosition != self.current.position;
+ if (!positionChanged && !isFinished) {
+ break;
+ }
+ } while (!isFinished);
+ return result.decodedInformation;
+}
+
+- (ZXRSSExpandedBlockParsedResult *)parseNumericBlockWithError:(NSError **)error {
+ while ([self isStillNumeric:self.current.position]) {
+ ZXRSSExpandedDecodedNumeric *numeric = [self decodeNumeric:self.current.position];
+ if (!numeric) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ self.current.position = numeric.theNewPosition;
+
+ if ([numeric firstDigitFNC1]) {
+ ZXRSSExpandedDecodedInformation *information;
+ if ([numeric secondDigitFNC1]) {
+ information = [[ZXRSSExpandedDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer];
+ } else {
+ information = [[ZXRSSExpandedDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer
+ remainingValue:numeric.secondDigit];
+ }
+ return [[ZXRSSExpandedBlockParsedResult alloc] initWithInformation:information finished:YES];
+ }
+ [self.buffer appendFormat:@"%d", numeric.firstDigit];
+
+ if (numeric.secondDigitFNC1) {
+ ZXRSSExpandedDecodedInformation *information = [[ZXRSSExpandedDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer];
+ return [[ZXRSSExpandedBlockParsedResult 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 [[ZXRSSExpandedBlockParsedResult alloc] initWithFinished:NO];
+}
+
+- (ZXRSSExpandedBlockParsedResult *)parseIsoIec646BlockWithError:(NSError **)error {
+ while ([self isStillIsoIec646:self.current.position]) {
+ ZXRSSExpandedDecodedChar *iso = [self decodeIsoIec646:self.current.position];
+ if (!iso) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ self.current.position = iso.theNewPosition;
+
+ if (iso.fnc1) {
+ ZXRSSExpandedDecodedInformation *information = [[ZXRSSExpandedDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer];
+ return [[ZXRSSExpandedBlockParsedResult 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 [[ZXRSSExpandedBlockParsedResult alloc] initWithFinished:NO];
+}
+
+- (ZXRSSExpandedBlockParsedResult *)parseAlphaBlock {
+ while ([self isStillAlpha:self.current.position]) {
+ ZXRSSExpandedDecodedChar *alpha = [self decodeAlphanumeric:self.current.position];
+ self.current.position = alpha.theNewPosition;
+
+ if (alpha.fnc1) {
+ ZXRSSExpandedDecodedInformation *information = [[ZXRSSExpandedDecodedInformation alloc] initWithNewPosition:self.current.position
+ newString:self.buffer];
+ return [[ZXRSSExpandedBlockParsedResult 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 [[ZXRSSExpandedBlockParsedResult 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;
+}
+
+- (ZXRSSExpandedDecodedChar *)decodeIsoIec646:(int)pos {
+ int fiveBitValue = [self extractNumericValueFromBitArray:pos bits:5];
+ if (fiveBitValue == 15) {
+ return [[ZXRSSExpandedDecodedChar alloc] initWithNewPosition:pos + 5 value:ZX_FNC1_CHAR];
+ }
+
+ if (fiveBitValue >= 5 && fiveBitValue < 15) {
+ return [[ZXRSSExpandedDecodedChar alloc] initWithNewPosition:pos + 5 value:(unichar)('0' + fiveBitValue - 5)];
+ }
+
+ int sevenBitValue = [self extractNumericValueFromBitArray:pos bits:7];
+
+ if (sevenBitValue >= 64 && sevenBitValue < 90) {
+ return [[ZXRSSExpandedDecodedChar alloc] initWithNewPosition:pos + 7 value:(unichar)(sevenBitValue + 1)];
+ }
+
+ if (sevenBitValue >= 90 && sevenBitValue < 116) {
+ return [[ZXRSSExpandedDecodedChar 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:
+ return nil;
+ }
+ return [[ZXRSSExpandedDecodedChar alloc] initWithNewPosition:pos + 8 value:c];
+}
+
+- (BOOL)isStillAlpha:(int)pos {
+ if (pos + 5 > self.information.size) {
+ return NO;
+ }
+
+ // We now check if it's a valid 5-bit value (0..9 and FNC1)
+ 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; // 63 not included
+}
+
+- (ZXRSSExpandedDecodedChar *)decodeAlphanumeric:(int)pos {
+ int fiveBitValue = [self extractNumericValueFromBitArray:pos bits:5];
+ if (fiveBitValue == 15) {
+ return [[ZXRSSExpandedDecodedChar alloc] initWithNewPosition:pos + 5 value:ZX_FNC1_CHAR];
+ }
+
+ if (fiveBitValue >= 5 && fiveBitValue < 15) {
+ return [[ZXRSSExpandedDecodedChar alloc] initWithNewPosition:pos + 5 value:(unichar)('0' + fiveBitValue - 5)];
+ }
+
+ int sixBitValue = [self extractNumericValueFromBitArray:pos bits:6];
+
+ if (sixBitValue >= 32 && sixBitValue < 58) {
+ return [[ZXRSSExpandedDecodedChar 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 [[ZXRSSExpandedDecodedChar 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 {
+ // Next is alphanumeric if there are 3 positions and they are all zeros
+ 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 {
+ // Next is alphanumeric if there are 4 positions and they are all zeros, or
+ // if there is a subset of this just before the end of the symbol
+ 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/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Common.h b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Common.h
new file mode 100644
index 0000000..62efac2
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Common.h
@@ -0,0 +1,42 @@
+/*
+ * 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 ZX_PDF417_SYMBOL_TABLE_LEN 2787
+extern const int ZX_PDF417_SYMBOL_TABLE[];
+
+extern const int ZX_PDF417_NUMBER_OF_CODEWORDS;
+extern const int ZX_PDF417_MIN_ROWS_IN_BARCODE;
+extern const int ZX_PDF417_MAX_ROWS_IN_BARCODE;
+extern const int ZX_PDF417_MAX_CODEWORDS_IN_BARCODE;
+extern const int ZX_PDF417_MODULES_IN_CODEWORD;
+extern const int ZX_PDF417_MODULES_IN_STOP_PATTERN;
+#define ZX_PDF417_BARS_IN_MODULE 8
+
+@class ZXIntArray;
+
+@interface ZXPDF417Common : NSObject
+
++ (int)bitCountSum:(NSArray *)moduleBitCount;
++ (ZXIntArray *)toIntArray:(NSArray *)list;
+
+/**
+ * Translate the symbol into a codeword.
+ *
+ * @return the codeword corresponding to the symbol.
+ */
++ (int)codeword:(int)symbol;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Common.m b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Common.m
new file mode 100644
index 0000000..9e94654
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Common.m
@@ -0,0 +1,468 @@
+/*
+ * 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 "ZXIntArray.h"
+#import "ZXPDF417.h"
+#import "ZXPDF417Common.h"
+
+const int ZX_PDF417_NUMBER_OF_CODEWORDS = 929;
+// Maximum Codewords (Data + Error).
+const int ZX_PDF417_MAX_CODEWORDS_IN_BARCODE = ZX_PDF417_NUMBER_OF_CODEWORDS - 1;
+const int ZX_PDF417_MIN_ROWS_IN_BARCODE = 3;
+const int ZX_PDF417_MAX_ROWS_IN_BARCODE = 90;
+// One left row indication column + max 30 data columns + one right row indicator column
+//const int ZX_PDF417_MAX_CODEWORDS_IN_ROW = 32;
+const int ZX_PDF417_MODULES_IN_CODEWORD = 17;
+const int ZX_PDF417_MODULES_IN_STOP_PATTERN = 18;
+
+const int ZX_PDF417_COMMON_CODEWORD_TABLE[];
+
+@implementation ZXPDF417Common
+
++ (int)bitCountSum:(NSArray *)moduleBitCount {
+ int bitCountSum = 0;
+ for (NSNumber *count in moduleBitCount) {
+ bitCountSum += [count intValue];
+ }
+ return bitCountSum;
+}
+
++ (ZXIntArray *)toIntArray:(NSArray *)list {
+ ZXIntArray *result = [[ZXIntArray alloc] initWithLength:(unsigned int)[list count]];
+ int i = 0;
+ for (NSNumber *integer in list) {
+ result.array[i++] = (int32_t)[integer intValue];
+ }
+ return result;
+}
+
++ (int)codeword:(int)symbol {
+ int i = [self binarySearch:symbol & 0x3FFFF];
+ if (i == -1) {
+ return -1;
+ }
+ return (ZX_PDF417_COMMON_CODEWORD_TABLE[i] - 1) % ZX_PDF417_NUMBER_OF_CODEWORDS;
+}
+
+/**
+ * Use a binary search to find the index of the codeword corresponding to
+ * this symbol.
+ *
+ * @param symbol the symbol from the barcode.
+ * @return the index into the codeword table.
+ */
++ (int)binarySearch:(int)symbol {
+ int first = 0;
+ int upto = ZX_PDF417_SYMBOL_TABLE_LEN;
+ while (first < upto) {
+ int mid = (first + upto) / 2; // Compute mid point.
+ if (symbol < ZX_PDF417_SYMBOL_TABLE[mid]) {
+ upto = mid; // continue search in bottom half.
+ } else if (symbol > ZX_PDF417_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.
+ */
+const int ZX_PDF417_SYMBOL_TABLE[ZX_PDF417_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.
+ */
+const int ZX_PDF417_COMMON_CODEWORD_TABLE[] = {
+ 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/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Reader.h b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Reader.h
new file mode 100644
index 0000000..485b91d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Reader.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 "ZXMultipleBarcodeReader.h"
+#import "ZXReader.h"
+
+@class ZXDecodeHints, ZXResult;
+
+/**
+ * This implementation can detect and decode PDF417 codes in an image.
+ */
+@interface ZXPDF417Reader : NSObject
+
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error;
+- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Reader.m b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Reader.m
new file mode 100644
index 0000000..39d3156
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Reader.m
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.
+ *
+ * @return a String representing the content encoded by the PDF417 code
+ * @return nil if a PDF417 code cannot be found,
+ * @return nil if a PDF417 cannot be decoded
+ */
+- (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 = ZXNotFoundErrorInstance();
+ 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]
+ error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ ZXResult *result = [[ZXResult alloc] initWithText:decoderResult.text
+ rawBytes:decoderResult.rawBytes
+ 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 fabsf(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 fabsf(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]] * ZX_PDF417_MODULES_IN_CODEWORD /
+ ZX_PDF417_MODULES_IN_STOP_PATTERN),
+ MAX([self maxWidth:p[1] p2:p[5]], [self maxWidth:p[7] p2:p[3]] * ZX_PDF417_MODULES_IN_CODEWORD /
+ ZX_PDF417_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]] * ZX_PDF417_MODULES_IN_CODEWORD /
+ ZX_PDF417_MODULES_IN_STOP_PATTERN),
+ MIN([self minWidth:p[1] p2:p[5]], [self minWidth:p[7] p2:p[3]] * ZX_PDF417_MODULES_IN_CODEWORD /
+ ZX_PDF417_MODULES_IN_STOP_PATTERN));
+}
+
+- (void)reset {
+ // nothing needs to be reset
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417ResultMetadata.h b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417ResultMetadata.h
new file mode 100644
index 0000000..1660049
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417ResultMetadata.m b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417ResultMetadata.m
new file mode 100644
index 0000000..c5e2d8a
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Writer.h b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Writer.h
new file mode 100644
index 0000000..eb09e73
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Writer.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 "ZXWriter.h"
+
+@interface ZXPDF417Writer : NSObject
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Writer.m b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Writer.m
new file mode 100644
index 0000000..2f5a022
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXPDF417Writer.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 "ZXByteArray.h"
+#import "ZXEncodeHints.h"
+#import "ZXPDF417.h"
+#import "ZXPDF417BarcodeMatrix.h"
+#import "ZXPDF417Dimensions.h"
+#import "ZXPDF417Writer.h"
+
+/**
+ * default white space (margin) around the code
+ */
+const int ZX_PDF417_WHITE_SPACE = 30;
+
+@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];
+ int margin = ZX_PDF417_WHITE_SPACE;
+
+ if (hints != nil) {
+ encoder.compact = hints.pdf417Compact;
+ encoder.compaction = hints.pdf417Compaction;
+ if (hints.pdf417Dimensions != nil) {
+ ZXPDF417Dimensions *dimensions = hints.pdf417Dimensions;
+ [encoder setDimensionsWithMaxCols:dimensions.maxCols
+ minCols:dimensions.minCols
+ maxRows:dimensions.maxRows
+ minRows:dimensions.minRows];
+ }
+ if (hints.margin) {
+ margin = [hints.margin intValue];
+ }
+ if (hints.encoding > 0) {
+ encoder.encoding = hints.encoding;
+ }
+ }
+
+ return [self bitMatrixFromEncoder:encoder contents:contents width:width height:height margin:margin 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
+ margin:(int)margin
+ error:(NSError **)error {
+ int errorCorrectionLevel = 2;
+ if (![encoder generateBarcodeLogic:contents errorCorrectionLevel:errorCorrectionLevel error:error]) {
+ return nil;
+ }
+
+ int lineThickness = 2;
+ int aspectRatio = 4;
+ NSArray *originalScale = [[encoder barcodeMatrix] scaledMatrixWithXScale:lineThickness yScale:aspectRatio * lineThickness];
+ BOOL rotated = NO;
+ if ((height > width) ^ ([(ZXByteArray *)originalScale[0] length] < [originalScale count])) {
+ originalScale = [self rotateArray:originalScale];
+ rotated = YES;
+ }
+
+ int scaleX = width / [(ZXByteArray *)originalScale[0] length];
+ int scaleY = height / [originalScale count];
+
+ int scale;
+ if (scaleX < scaleY) {
+ scale = scaleX;
+ } else {
+ scale = scaleY;
+ }
+
+ if (scale > 1) {
+ NSArray *scaledMatrix =
+ [[encoder barcodeMatrix] scaledMatrixWithXScale:scale * lineThickness yScale:scale * aspectRatio * lineThickness];
+ if (rotated) {
+ scaledMatrix = [self rotateArray:scaledMatrix];
+ }
+ return [self bitMatrixFrombitArray:scaledMatrix margin:margin];
+ }
+ return [self bitMatrixFrombitArray:originalScale margin:margin];
+}
+
+/**
+ * This takes an array holding the values of the PDF 417
+ *
+ * @param input a byte array of information with 0 is black, and 1 is white
+ * @param margin border around the barcode
+ * @return BitMatrix of the input
+ */
+- (ZXBitMatrix *)bitMatrixFrombitArray:(NSArray *)input margin:(int)margin {
+ // Creates the bitmatrix with extra space for whtespace
+ ZXBitMatrix *output = [[ZXBitMatrix alloc] initWithWidth:[(ZXByteArray *)input[0] length] + 2 * margin height:(int)[input count] + 2 * margin];
+ [output clear];
+ for (int y = 0, yOutput = output.height - margin; y < [input count]; y++, yOutput--) {
+ for (int x = 0; x < [(ZXByteArray *)input[0] length]; x++) {
+ // Zero is white in the bytematrix
+ if ([(ZXByteArray *)input[y] array][x] == 1) {
+ [output setX:x + margin y:yOutput];
+ }
+ }
+ }
+ return output;
+}
+
+/**
+ * Takes and rotates the it 90 degrees
+ */
+- (NSArray *)rotateArray:(NSArray *)bitarray {
+ NSMutableArray *temp = [NSMutableArray array];
+ for (int i = 0; i < [(ZXByteArray *)bitarray[0] length]; i++) {
+ [temp addObject:[[ZXByteArray alloc] initWithLength:(unsigned int)[bitarray count]]];
+ }
+
+ for (int ii = 0; ii < [bitarray count]; ii++) {
+ // This makes the direction consistent on screen when rotating the
+ // screen;
+ int inverseii = (int)[bitarray count] - ii - 1;
+ for (int jj = 0; jj < [(ZXByteArray *)bitarray[0] length]; jj++) {
+ ZXByteArray *b = temp[jj];
+ b.array[inverseii] = [(ZXByteArray *)bitarray[ii] array][jj];
+ }
+ }
+ return temp;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/ZXingObjCPDF417.h b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXingObjCPDF417.h
new file mode 100644
index 0000000..2c77a80
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/ZXingObjCPDF417.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ZXINGOBJC_PDF417_
+
+#define _ZXINGOBJC_PDF417_
+
+#import "ZXModulusGF.h"
+#import "ZXPDF417.h"
+#import "ZXPDF417BarcodeMatrix.h"
+#import "ZXPDF417Common.h"
+#import "ZXPDF417Detector.h"
+#import "ZXPDF417DetectorResult.h"
+#import "ZXPDF417Dimensions.h"
+#import "ZXPDF417ECErrorCorrection.h"
+#import "ZXPDF417Reader.h"
+#import "ZXPDF417ResultMetadata.h"
+#import "ZXPDF417ScanningDecoder.h"
+#import "ZXPDF417Writer.h"
+
+#endif
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.h
new file mode 100644
index 0000000..f2fb7d9
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeMetadata.m
new file mode 100644
index 0000000..1173bbe
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h
new file mode 100644
index 0000000..76147a2
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.h
@@ -0,0 +1,34 @@
+/*
+ * 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 ZXIntArray;
+
+@interface ZXPDF417BarcodeValue : NSObject
+
+/**
+ * Add an occurrence of a value
+ */
+- (void)setValue:(int)value;
+
+/**
+ * Determines the maximum occurrence of a set value and returns all values which were set with this occurrence.
+ * @return an array of int, containing the values with the highest occurrence, or null, if no value was set
+ */
+- (ZXIntArray *)value;
+
+- (NSNumber *)confidence:(int)value;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.m
new file mode 100644
index 0000000..1f3aa03
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BarcodeValue.m
@@ -0,0 +1,67 @@
+/*
+ * 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"
+#import "ZXPDF417Common.h"
+
+@interface ZXPDF417BarcodeValue ()
+
+@property (nonatomic, strong, readonly) 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;
+}
+
+- (ZXIntArray *)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];
+ }
+ }
+ NSArray *array = [[[result sortedArrayUsingSelector:@selector(compare:)] reverseObjectEnumerator] allObjects];
+ return [ZXPDF417Common toIntArray:array];
+}
+
+- (NSNumber *)confidence:(int)value {
+ return self.values[@(value)];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.h
new file mode 100644
index 0000000..da74a78
--- /dev/null
+++ b/Pods/ZXingObjC/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, readonly) ZXResultPoint *topRight;
+@property (nonatomic, strong, readonly) ZXResultPoint *bottomLeft;
+@property (nonatomic, strong, readonly) 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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.m
new file mode 100644
index 0000000..54a2fa7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417BoundingBox.m
@@ -0,0 +1,135 @@
+/*
+ * 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, readonly) 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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.h
new file mode 100644
index 0000000..d64bf47
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417Codeword.m
new file mode 100644
index 0000000..45a624e
--- /dev/null
+++ b/Pods/ZXingObjC/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 ZX_PDF417_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 = ZX_PDF417_BARCODE_ROW_UNKNOWN;
+ }
+
+ return self;
+}
+
+- (BOOL)hasValidRowNumber {
+ return [self isValidRowNumber:self.rowNumber];
+}
+
+- (BOOL)isValidRowNumber:(int)rowNumber {
+ return rowNumber != ZX_PDF417_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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.h
new file mode 100644
index 0000000..a50e347
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m
new file mode 100644
index 0000000..2a3b823
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417CodewordDecoder.m
@@ -0,0 +1,114 @@
+/*
+ * 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 ZX_PDF417_RATIOS_TABLE[ZX_PDF417_SYMBOL_TABLE_LEN][ZX_PDF417_BARS_IN_MODULE];
+
+@implementation ZXPDF417CodewordDecoder
+
++ (void)initialize {
+ if ([self class] != [ZXPDF417CodewordDecoder class]) return;
+
+ // Pre-computes the symbol ratio table.
+ for (int i = 0; i < ZX_PDF417_SYMBOL_TABLE_LEN; i++) {
+ int currentSymbol = ZX_PDF417_SYMBOL_TABLE[i];
+ int currentBit = currentSymbol & 0x1;
+ for (int j = 0; j < ZX_PDF417_BARS_IN_MODULE; j++) {
+ float size = 0.0f;
+ while ((currentSymbol & 0x1) == currentBit) {
+ size += 1.0f;
+ currentSymbol >>= 1;
+ }
+ currentBit = currentSymbol & 0x1;
+ ZX_PDF417_RATIOS_TABLE[i][ZX_PDF417_BARS_IN_MODULE - j - 1] = size / ZX_PDF417_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:ZX_PDF417_BARS_IN_MODULE];
+ for (int i = 0; i < ZX_PDF417_BARS_IN_MODULE; i++) {
+ [result addObject:@0];
+ }
+
+ int bitCountIndex = 0;
+ int sumPreviousBits = 0;
+ for (int i = 0; i < ZX_PDF417_MODULES_IN_CODEWORD; i++) {
+ float sampleIndex =
+ bitCountSum / (2 * ZX_PDF417_MODULES_IN_CODEWORD) +
+ (i * bitCountSum) / ZX_PDF417_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[ZX_PDF417_BARS_IN_MODULE];
+ for (int i = 0; i < ZX_PDF417_BARS_IN_MODULE; i++) {
+ bitCountRatios[i] = [moduleBitCount[i] intValue] / (float) bitCountSum;
+ }
+ float bestMatchError = MAXFLOAT;
+ int bestMatch = -1;
+ for (int j = 0; j < ZX_PDF417_SYMBOL_TABLE_LEN; j++) {
+ float error = 0.0f;
+ float *ratioTableRow = ZX_PDF417_RATIOS_TABLE[j];
+ for (int k = 0; k < ZX_PDF417_BARS_IN_MODULE; k++) {
+ float diff = ratioTableRow[k] - bitCountRatios[k];
+ error += diff * diff;
+ if (error >= bestMatchError) {
+ break;
+ }
+ }
+ if (error < bestMatchError) {
+ bestMatchError = error;
+ bestMatch = ZX_PDF417_SYMBOL_TABLE[j];
+ }
+ }
+ return bestMatch;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.h
new file mode 100644
index 0000000..a90df62
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.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 ZXDecoderResult, ZXIntArray;
+
+/**
+ * This class contains the methods for decoding the PDF417 codewords.
+ */
+@interface ZXPDF417DecodedBitStreamParser : NSObject
+
++ (ZXDecoderResult *)decode:(ZXIntArray *)codewords ecLevel:(NSString *)ecLevel error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m
new file mode 100644
index 0000000..8a8d999
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DecodedBitStreamParser.m
@@ -0,0 +1,643 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXIntArray.h"
+#import "ZXPDF417DecodedBitStreamParser.h"
+#import "ZXPDF417ResultMetadata.h"
+
+typedef enum {
+ ZXPDF417ModeAlpha = 0,
+ ZXPDF417ModeLower,
+ ZXPDF417ModeMixed,
+ ZXPDF417ModePunct,
+ ZXPDF417ModeAlphaShift,
+ ZXPDF417ModePunctShift
+} ZXPDF417Mode;
+
+const int ZX_PDF417_TEXT_COMPACTION_MODE_LATCH = 900;
+const int ZX_PDF417_BYTE_COMPACTION_MODE_LATCH = 901;
+const int ZX_PDF417_NUMERIC_COMPACTION_MODE_LATCH = 902;
+const int ZX_PDF417_BYTE_COMPACTION_MODE_LATCH_6 = 924;
+const int ZX_PDF417_ECI_USER_DEFINED = 925;
+const int ZX_PDF417_ECI_GENERAL_PURPOSE = 926;
+const int ZX_PDF417_ECI_CHARSET = 927;
+const int ZX_PDF417_BEGIN_MACRO_PDF417_CONTROL_BLOCK = 928;
+const int ZX_PDF417_BEGIN_MACRO_PDF417_OPTIONAL_FIELD = 923;
+const int ZX_PDF417_MACRO_PDF417_TERMINATOR = 922;
+const int ZX_PDF417_MODE_SHIFT_TO_BYTE_COMPACTION_MODE = 913;
+const int ZX_PDF417_MAX_NUMERIC_CODEWORDS = 15;
+
+const int ZX_PDF417_PL = 25;
+const int ZX_PDF417_LL = 27;
+const int ZX_PDF417_AS = 27;
+const int ZX_PDF417_ML = 28;
+const int ZX_PDF417_AL = 28;
+const int ZX_PDF417_PS = 29;
+const int ZX_PDF417_PAL = 29;
+
+const unichar ZX_PDF417_PUNCT_CHARS[] = {
+ ';', '<', '>', '@', '[', '\\', ']', '_', '`', '~', '!',
+ '\r', '\t', ',', ':', '\n', '-', '.', '$', '/', '"', '|', '*',
+ '(', ')', '?', '{', '}', '\''};
+
+const unichar ZX_PDF417_MIXED_CHARS[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '&',
+ '\r', '\t', ',', ':', '#', '-', '.', '$', '/', '+', '%', '*',
+ '=', '^'};
+
+const int ZX_PDF417_NUMBER_OF_SEQUENCE_CODEWORDS = 2;
+
+const NSStringEncoding ZX_PDF417_DECODING_DEFAULT_ENCODING = NSISOLatin1StringEncoding;
+
+/**
+ * Table containing values for the exponent of 900.
+ * This is used in the numeric compaction decode algorithm.
+ */
+static NSArray *ZX_PDF417_EXP900 = nil;
+
+@implementation ZXPDF417DecodedBitStreamParser
+
++ (void)initialize {
+ if ([self class] != [ZXPDF417DecodedBitStreamParser class]) return;
+
+ 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]];
+ }
+ ZX_PDF417_EXP900 = [[NSArray alloc] initWithArray:exponents];
+}
+
++ (ZXDecoderResult *)decode:(ZXIntArray *)codewords ecLevel:(NSString *)ecLevel error:(NSError **)error {
+ NSMutableString *result = [NSMutableString stringWithCapacity:codewords.length * 2];
+ NSStringEncoding encoding = ZX_PDF417_DECODING_DEFAULT_ENCODING;
+ // Get compaction mode
+ int codeIndex = 1;
+ int code = codewords.array[codeIndex++];
+ ZXPDF417ResultMetadata *resultMetadata = [[ZXPDF417ResultMetadata alloc] init];
+ while (codeIndex < codewords.array[0]) {
+ switch (code) {
+ case ZX_PDF417_TEXT_COMPACTION_MODE_LATCH:
+ codeIndex = [self textCompaction:codewords codeIndex:codeIndex result:result];
+ break;
+ case ZX_PDF417_BYTE_COMPACTION_MODE_LATCH:
+ case ZX_PDF417_BYTE_COMPACTION_MODE_LATCH_6:
+ codeIndex = [self byteCompaction:code codewords:codewords encoding:encoding codeIndex:codeIndex result:result];
+ break;
+ case ZX_PDF417_MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
+ [result appendFormat:@"%C", (unichar)codewords.array[codeIndex++]];
+ break;
+ case ZX_PDF417_NUMERIC_COMPACTION_MODE_LATCH:
+ codeIndex = [self numericCompaction:codewords codeIndex:codeIndex result:result];
+ if (codeIndex < 0) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ break;
+ case ZX_PDF417_ECI_CHARSET: {
+ ZXCharacterSetECI *charsetECI =
+ [ZXCharacterSetECI characterSetECIByValue:codewords.array[codeIndex++]];
+ encoding = charsetECI.encoding;
+ break;
+ }
+ case ZX_PDF417_ECI_GENERAL_PURPOSE:
+ // Can't do anything with generic ECI; skip its 2 characters
+ codeIndex += 2;
+ break;
+ case ZX_PDF417_ECI_USER_DEFINED:
+ // Can't do anything with user ECI; skip its 1 character
+ codeIndex ++;
+ break;
+ case ZX_PDF417_BEGIN_MACRO_PDF417_CONTROL_BLOCK:
+ codeIndex = [self decodeMacroBlock:codewords codeIndex:codeIndex resultMetadata:resultMetadata];
+ if (codeIndex < 0) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ break;
+ case ZX_PDF417_BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
+ case ZX_PDF417_MACRO_PDF417_TERMINATOR:
+ // Should not see these outside a macro block
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ 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.length) {
+ code = codewords.array[codeIndex++];
+ } else {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ }
+ if ([result length] == 0) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ ZXDecoderResult *decoderResult = [[ZXDecoderResult alloc] initWithRawBytes:nil text:result byteSegments:nil ecLevel:ecLevel];
+ decoderResult.other = resultMetadata;
+ return decoderResult;
+}
+
++ (int)decodeMacroBlock:(ZXIntArray *)codewords codeIndex:(int)codeIndex resultMetadata:(ZXPDF417ResultMetadata *)resultMetadata {
+ if (codeIndex + ZX_PDF417_NUMBER_OF_SEQUENCE_CODEWORDS > codewords.array[0]) {
+ // we must have at least two bytes left for the segment index
+ return -1;
+ }
+ ZXIntArray *segmentIndexArray = [[ZXIntArray alloc] initWithLength:ZX_PDF417_NUMBER_OF_SEQUENCE_CODEWORDS];
+ for (int i = 0; i < ZX_PDF417_NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
+ segmentIndexArray.array[i] = codewords.array[codeIndex];
+ }
+ resultMetadata.segmentIndex = [[self decodeBase900toBase10:segmentIndexArray count:ZX_PDF417_NUMBER_OF_SEQUENCE_CODEWORDS] intValue];
+
+ NSMutableString *fileId = [NSMutableString string];
+ codeIndex = [self textCompaction:codewords codeIndex:codeIndex result:fileId];
+ resultMetadata.fileId = [NSString stringWithString:fileId];
+
+ if (codewords.array[codeIndex] == ZX_PDF417_BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
+ codeIndex++;
+ NSMutableArray *additionalOptionCodeWords = [NSMutableArray array];
+
+ BOOL end = NO;
+ while ((codeIndex < codewords.array[0]) && !end) {
+ int code = codewords.array[codeIndex++];
+ if (code < ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ [additionalOptionCodeWords addObject:@(code)];
+ } else {
+ switch (code) {
+ case ZX_PDF417_MACRO_PDF417_TERMINATOR:
+ resultMetadata.lastSegment = YES;
+ codeIndex++;
+ end = YES;
+ break;
+ default:
+ return -1;
+ }
+ }
+ }
+
+ resultMetadata.optionalData = additionalOptionCodeWords;
+ } else if (codewords.array[codeIndex] == ZX_PDF417_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.
+ *
+ * @param codewords The array of codewords (data + error)
+ * @param codeIndex The current index into the codeword array.
+ * @param result The decoded data is appended to the result.
+ * @return The next index into the codeword array.
+ */
++ (int)textCompaction:(ZXIntArray *)codewords codeIndex:(int)codeIndex result:(NSMutableString *)result {
+ // 2 character per codeword
+ ZXIntArray *textCompactionData = [[ZXIntArray alloc] initWithLength:(codewords.array[0] - codeIndex) * 2];
+ // Used to hold the byte compaction value if there is a mode shift
+ ZXIntArray *byteCompactionData = [[ZXIntArray alloc] initWithLength:(codewords.array[0] - codeIndex) * 2];
+
+ int index = 0;
+ BOOL end = NO;
+ while ((codeIndex < codewords.array[0]) && !end) {
+ int code = codewords.array[codeIndex++];
+ if (code < ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ textCompactionData.array[index] = code / 30;
+ textCompactionData.array[index + 1] = code % 30;
+ index += 2;
+ } else {
+ switch (code) {
+ case ZX_PDF417_TEXT_COMPACTION_MODE_LATCH:
+ // reinitialize text compaction mode to alpha sub mode
+ textCompactionData.array[index++] = ZX_PDF417_TEXT_COMPACTION_MODE_LATCH;
+ break;
+ case ZX_PDF417_BYTE_COMPACTION_MODE_LATCH:
+ case ZX_PDF417_BYTE_COMPACTION_MODE_LATCH_6:
+ case ZX_PDF417_NUMERIC_COMPACTION_MODE_LATCH:
+ case ZX_PDF417_BEGIN_MACRO_PDF417_CONTROL_BLOCK:
+ case ZX_PDF417_BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
+ case ZX_PDF417_MACRO_PDF417_TERMINATOR:
+ codeIndex--;
+ end = YES;
+ break;
+ case ZX_PDF417_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.array[index] = ZX_PDF417_MODE_SHIFT_TO_BYTE_COMPACTION_MODE;
+ code = codewords.array[codeIndex++];
+ byteCompactionData.array[index] = code;
+ index++;
+ 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.
+ *
+ * @param textCompactionData The text compaction data.
+ * @param byteCompactionData The byte compaction data if there
+ * was a mode shift.
+ * @param length The size of the text compaction and byte compaction data.
+ * @param result The decoded data is appended to the result.
+ */
++ (void)decodeTextCompaction:(ZXIntArray *)textCompactionData byteCompactionData:(ZXIntArray *)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.
+ ZXPDF417Mode subMode = ZXPDF417ModeAlpha;
+ ZXPDF417Mode priorToShiftMode = ZXPDF417ModeAlpha;
+ int i = 0;
+ while (i < length) {
+ int subModeCh = textCompactionData.array[i];
+ unichar ch = 0;
+ switch (subMode) {
+ case ZXPDF417ModeAlpha:
+ // Alpha (uppercase alphabetic)
+ if (subModeCh < 26) {
+ // Upper case Alpha Character
+ ch = (unichar)('A' + subModeCh);
+ } else {
+ if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == ZX_PDF417_LL) {
+ subMode = ZXPDF417ModeLower;
+ } else if (subModeCh == ZX_PDF417_ML) {
+ subMode = ZXPDF417ModeMixed;
+ } else if (subModeCh == ZX_PDF417_PS) {
+ // Shift to punctuation
+ priorToShiftMode = subMode;
+ subMode = ZXPDF417ModePunctShift;
+ } else if (subModeCh == ZX_PDF417_MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ // TODO Does this need to use the current character encoding? See other occurrences below
+ [result appendFormat:@"%C", (unichar)byteCompactionData.array[i]];
+ } else if (subModeCh == ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ZXPDF417ModeAlpha;
+ }
+ }
+ break;
+
+ case ZXPDF417ModeLower:
+ // Lower (lowercase alphabetic)
+ if (subModeCh < 26) {
+ ch = (unichar)('a' + subModeCh);
+ } else {
+ if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == ZX_PDF417_AS) {
+ // Shift to alpha
+ priorToShiftMode = subMode;
+ subMode = ZXPDF417ModeAlphaShift;
+ } else if (subModeCh == ZX_PDF417_ML) {
+ subMode = ZXPDF417ModeMixed;
+ } else if (subModeCh == ZX_PDF417_PS) {
+ // Shift to punctuation
+ priorToShiftMode = subMode;
+ subMode = ZXPDF417ModePunctShift;
+ } else if (subModeCh == ZX_PDF417_MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ [result appendFormat:@"%C", (unichar)byteCompactionData.array[i]];
+ } else if (subModeCh == ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ZXPDF417ModeAlpha;
+ }
+ }
+ break;
+
+ case ZXPDF417ModeMixed:
+ // Mixed (numeric and some punctuation)
+ if (subModeCh < ZX_PDF417_PL) {
+ ch = ZX_PDF417_MIXED_CHARS[subModeCh];
+ } else {
+ if (subModeCh == ZX_PDF417_PL) {
+ subMode = ZXPDF417ModePunct;
+ } else if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == ZX_PDF417_LL) {
+ subMode = ZXPDF417ModeLower;
+ } else if (subModeCh == ZX_PDF417_AL) {
+ subMode = ZXPDF417ModeAlpha;
+ } else if (subModeCh == ZX_PDF417_PS) {
+ // Shift to punctuation
+ priorToShiftMode = subMode;
+ subMode = ZXPDF417ModePunctShift;
+ } else if (subModeCh == ZX_PDF417_MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ [result appendFormat:@"%C", (unichar)byteCompactionData.array[i]];
+ } else if (subModeCh == ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ZXPDF417ModeAlpha;
+ }
+ }
+ break;
+
+ case ZXPDF417ModePunct:
+ // Punctuation
+ if (subModeCh < ZX_PDF417_PAL) {
+ ch = ZX_PDF417_PUNCT_CHARS[subModeCh];
+ } else {
+ if (subModeCh == ZX_PDF417_PAL) {
+ subMode = ZXPDF417ModeAlpha;
+ } else if (subModeCh == ZX_PDF417_MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ [result appendFormat:@"%C", (unichar)byteCompactionData.array[i]];
+ } else if (ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ZXPDF417ModeAlpha;
+ }
+ }
+ break;
+
+ case ZXPDF417ModeAlphaShift:
+ // Restore sub-mode
+ subMode = priorToShiftMode;
+ if (subModeCh < 26) {
+ ch = (unichar)('A' + subModeCh);
+ } else {
+ if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ZXPDF417ModeAlpha;
+ }
+ }
+ break;
+
+ case ZXPDF417ModePunctShift:
+ // Restore sub-mode
+ subMode = priorToShiftMode;
+ if (subModeCh < ZX_PDF417_PAL) {
+ ch = ZX_PDF417_PUNCT_CHARS[subModeCh];
+ } else {
+ if (subModeCh == ZX_PDF417_PAL) {
+ subMode = ZXPDF417ModeAlpha;
+ } else if (subModeCh == ZX_PDF417_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.array[i]];
+ } else if (subModeCh == ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ZXPDF417ModeAlpha;
+ }
+ }
+ 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.
+ *
+ * @param mode The byte compaction mode i.e. 901 or 924
+ * @param codewords The array of codewords (data + error)
+ * @param encoding Currently active character encoding
+ * @param codeIndex The current index into the codeword array.
+ * @param result The decoded data is appended to the result.
+ * @return The next index into the codeword array.
+ */
++ (int)byteCompaction:(int)mode
+ codewords:(ZXIntArray *)codewords
+ encoding:(NSStringEncoding)encoding
+ codeIndex:(int)codeIndex
+ result:(NSMutableString *)result {
+ NSMutableData *decodedBytes = [NSMutableData data];
+ if (mode == ZX_PDF417_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;
+ ZXIntArray *byteCompactedCodewords = [[ZXIntArray alloc] initWithLength:6];
+ BOOL end = NO;
+ int nextCode = codewords.array[codeIndex++];
+ while ((codeIndex < codewords.array[0]) && !end) {
+ byteCompactedCodewords.array[count++] = nextCode;
+ // Base 900
+ value = 900 * value + nextCode;
+ nextCode = codewords.array[codeIndex++];
+ // perhaps it should be ok to check only nextCode >= TEXT_COMPACTION_MODE_LATCH
+ if (nextCode == ZX_PDF417_TEXT_COMPACTION_MODE_LATCH ||
+ nextCode == ZX_PDF417_BYTE_COMPACTION_MODE_LATCH ||
+ nextCode == ZX_PDF417_NUMERIC_COMPACTION_MODE_LATCH ||
+ nextCode == ZX_PDF417_BYTE_COMPACTION_MODE_LATCH_6 ||
+ nextCode == ZX_PDF417_BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
+ nextCode == ZX_PDF417_BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
+ nextCode == ZX_PDF417_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) {
+ int8_t byte = (int8_t) (value >> (8 * (5 - j)));
+ [decodedBytes appendBytes:&byte length:1];
+ }
+ value = 0;
+ count = 0;
+ }
+ }
+ }
+
+ // if the end of all codewords is reached the last codeword needs to be added
+ if (codeIndex == codewords.array[0] && nextCode < ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ byteCompactedCodewords.array[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++) {
+ int8_t byte = (int8_t)byteCompactedCodewords.array[i];
+ [decodedBytes appendBytes:&byte length:1];
+ }
+ } else if (mode == ZX_PDF417_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.array[0] && !end) {
+ int code = codewords.array[codeIndex++];
+ if (code < ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ count++;
+ // Base 900
+ value = 900 * value + code;
+ } else {
+ if (code == ZX_PDF417_TEXT_COMPACTION_MODE_LATCH ||
+ code == ZX_PDF417_BYTE_COMPACTION_MODE_LATCH ||
+ code == ZX_PDF417_NUMERIC_COMPACTION_MODE_LATCH ||
+ code == ZX_PDF417_BYTE_COMPACTION_MODE_LATCH_6 ||
+ code == ZX_PDF417_BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
+ code == ZX_PDF417_BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
+ code == ZX_PDF417_MACRO_PDF417_TERMINATOR) {
+ codeIndex--;
+ end = YES;
+ }
+ }
+ if ((count % 5 == 0) && (count > 0)) {
+ // Decode every 5 codewords
+ // Convert to Base 256
+ for (int j = 0; j < 6; ++j) {
+ int8_t byte = (int8_t) (value >> (8 * (5 - j)));
+ [decodedBytes appendBytes:&byte length:1];
+ }
+ value = 0;
+ count = 0;
+ }
+ }
+ }
+ [result appendString:[[NSString alloc] initWithData:decodedBytes encoding:encoding]];
+ return codeIndex;
+}
+
+/**
+ * Numeric Compaction mode (see 5.4.4) permits efficient encoding of numeric data strings.
+ *
+ * @param codewords The array of codewords (data + error)
+ * @param codeIndex The current index into the codeword array.
+ * @param result The decoded data is appended to the result.
+ * @return The next index into the codeword array.
+ */
++ (int)numericCompaction:(ZXIntArray *)codewords codeIndex:(int)codeIndex result:(NSMutableString *)result {
+ int count = 0;
+ BOOL end = NO;
+
+ ZXIntArray *numericCodewords = [[ZXIntArray alloc] initWithLength:ZX_PDF417_MAX_NUMERIC_CODEWORDS];
+
+ while (codeIndex < codewords.array[0] && !end) {
+ int code = codewords.array[codeIndex++];
+ if (codeIndex == codewords.array[0]) {
+ end = YES;
+ }
+ if (code < ZX_PDF417_TEXT_COMPACTION_MODE_LATCH) {
+ numericCodewords.array[count] = code;
+ count++;
+ } else {
+ if (code == ZX_PDF417_TEXT_COMPACTION_MODE_LATCH ||
+ code == ZX_PDF417_BYTE_COMPACTION_MODE_LATCH ||
+ code == ZX_PDF417_BYTE_COMPACTION_MODE_LATCH_6 ||
+ code == ZX_PDF417_BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
+ code == ZX_PDF417_BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
+ code == ZX_PDF417_MACRO_PDF417_TERMINATOR) {
+ codeIndex--;
+ end = YES;
+ }
+ }
+ if (count % ZX_PDF417_MAX_NUMERIC_CODEWORDS == 0 ||
+ code == ZX_PDF417_NUMERIC_COMPACTION_MODE_LATCH ||
+ end) {
+ // Re-invoking Numeric Compaction mode (by using codeword 902
+ // while in Numeric Compaction mode) serves to terminate the
+ // current Numeric Compaction mode grouping as described in 5.4.4.2,
+ // and then to start a new one grouping.
+ if (count > 0) {
+ NSString *s = [self decodeBase900toBase10:numericCodewords count:count];
+ if (s == nil) {
+ return -1;
+ }
+ [result appendString:s];
+ count = 0;
+ }
+ }
+ }
+ return codeIndex;
+}
+
+/**
+ * Convert a list of Numeric Compacted codewords from Base 900 to Base 10.
+ *
+ * @param codewords The array of codewords
+ * @param count The number of codewords
+ * @return The decoded string representing the Numeric data.
+ */
+/*
+ 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:(ZXIntArray *)codewords count:(int)count {
+ NSDecimalNumber *result = [NSDecimalNumber zero];
+ for (int i = 0; i < count; i++) {
+ result = [result decimalNumberByAdding:[ZX_PDF417_EXP900[count - i - 1] decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithDecimal:[@(codewords.array[i]) decimalValue]]]];
+ }
+ NSString *resultString = [result stringValue];
+ if (![resultString hasPrefix:@"1"]) {
+ return nil;
+ }
+ return [resultString substringFromIndex:1];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.h
new file mode 100644
index 0000000..33c9d44
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.m
new file mode 100644
index 0000000..ddf1147
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResult.m
@@ -0,0 +1,303 @@
+/*
+ * 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"
+
+const int ZX_PDF417_ADJUST_ROW_NUMBER_SKIP = 2;
+
+@interface ZXPDF417DetectionResult ()
+
+@property (nonatomic, strong, readonly) ZXPDF417BarcodeMetadata *barcodeMetadata;
+@property (nonatomic, strong, readonly) NSMutableArray *detectionResultColumnsInternal;
+@property (nonatomic, assign, readonly) 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 = ZX_PDF417_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
+/**
+ * @return 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];
+}
+
+- (void)adjustRowNumbersFromBothRI {
+ if (self.detectionResultColumnsInternal[0] == [NSNull null] || self.detectionResultColumnsInternal[self.barcodeColumnCount + 1] == [NSNull null]) {
+ return;
+ }
+ 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];
+ }
+ }
+ }
+ }
+}
+
+- (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 < ZX_PDF417_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 < ZX_PDF417_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)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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.h
new file mode 100644
index 0000000..3a63cd9
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.h
@@ -0,0 +1,30 @@
+/*
+ * 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;
+- (void)setCodeword:(int)imageRow codeword:(ZXPDF417Codeword *)codeword;
+- (ZXPDF417Codeword *)codeword:(int)imageRow;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.m
new file mode 100644
index 0000000..88efbab
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultColumn.m
@@ -0,0 +1,91 @@
+/*
+ * 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"
+
+const int ZX_PDF417_MAX_NEARBY_DISTANCE = 5;
+
+@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 < ZX_PDF417_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;
+}
+
+- (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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.h
new file mode 100644
index 0000000..a20b039
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.h
@@ -0,0 +1,30 @@
+/*
+ * 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 ZXIntArray, ZXPDF417BarcodeMetadata, ZXPDF417BoundingBox;
+
+@interface ZXPDF417DetectionResultRowIndicatorColumn : ZXPDF417DetectionResultColumn
+
+@property (nonatomic, assign, readonly) BOOL isLeft;
+
+- (id)initWithBoundingBox:(ZXPDF417BoundingBox *)boundingBox isLeft:(BOOL)isLeft;
+- (BOOL)getRowHeights:(ZXIntArray **)rowHeights;
+- (int)adjustCompleteIndicatorColumnRowNumbers:(ZXPDF417BarcodeMetadata *)barcodeMetadata;
+- (ZXPDF417BarcodeMetadata *)barcodeMetadata;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m
new file mode 100644
index 0000000..05a5a03
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417DetectionResultRowIndicatorColumn.m
@@ -0,0 +1,265 @@
+/*
+ * 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 "ZXIntArray.h"
+#import "ZXPDF417BarcodeMetadata.h"
+#import "ZXPDF417BarcodeValue.h"
+#import "ZXPDF417BoundingBox.h"
+#import "ZXPDF417Codeword.h"
+#import "ZXPDF417Common.h"
+#import "ZXPDF417DetectionResult.h"
+#import "ZXPDF417DetectionResultRowIndicatorColumn.h"
+#import "ZXResultPoint.h"
+
+@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 ||
+ codeword.rowNumber >= barcodeMetadata.rowCount ||
+ 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);
+}
+
+- (BOOL)getRowHeights:(ZXIntArray **)rowHeights {
+ ZXPDF417BarcodeMetadata *barcodeMetadata = [self barcodeMetadata];
+ if (!barcodeMetadata) {
+ *rowHeights = nil;
+ return YES;
+ }
+ [self adjustIncompleteIndicatorColumnRowNumbers:barcodeMetadata];
+ ZXIntArray *result = [[ZXIntArray alloc] initWithLength:barcodeMetadata.rowCount];
+ for (ZXPDF417Codeword *codeword in [self codewords]) {
+ if ((id)codeword != [NSNull null]) {
+ int rowNumber = codeword.rowNumber;
+ if (rowNumber >= result.length) {
+ *rowHeights = nil;
+ return NO;
+ }
+ result.array[rowNumber]++;
+ } // else throw exception?
+ }
+ *rowHeights = result;
+ return YES;
+}
+
+// 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].length == 0) ||
+ ([barcodeRowCountUpperPart value].length == 0) ||
+ ([barcodeRowCountLowerPart value].length == 0) ||
+ ([barcodeECLevel value].length == 0) ||
+ [barcodeColumnCount value].array[0] < 1 ||
+ [barcodeRowCountUpperPart value].array[0] + [barcodeRowCountLowerPart value].array[0] < ZX_PDF417_MIN_ROWS_IN_BARCODE ||
+ [barcodeRowCountUpperPart value].array[0] + [barcodeRowCountLowerPart value].array[0] > ZX_PDF417_MAX_ROWS_IN_BARCODE) {
+ return nil;
+ }
+ ZXPDF417BarcodeMetadata *barcodeMetadata = [[ZXPDF417BarcodeMetadata alloc] initWithColumnCount:[barcodeColumnCount value].array[0]
+ rowCountUpperPart:[barcodeRowCountUpperPart value].array[0]
+ rowCountLowerPart:[barcodeRowCountLowerPart value].array[0]
+ errorCorrectionLevel:[barcodeECLevel value].array[0]];
+ [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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.h
new file mode 100644
index 0000000..16fad12
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.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 ZXBitMatrix, ZXDecoderResult, ZXResultPoint;
+
+@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
+ error:(NSError **)error;
+- (NSString *)description:(NSArray *)barcodeMatrix;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m
new file mode 100644
index 0000000..43d0831
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ZXPDF417ScanningDecoder.m
@@ -0,0 +1,685 @@
+/*
+ * 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 "ZXErrors.h"
+#import "ZXIntArray.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 ZX_PDF417_CODEWORD_SKEW_SIZE = 2;
+
+const int ZX_PDF417_MAX_ERRORS = 3;
+const int ZX_PDF417_MAX_EC_CODEWORDS = 512;
+static ZXPDF417ECErrorCorrection *errorCorrection;
+
+@implementation ZXPDF417ScanningDecoder
+
++ (void)initialize {
+ if ([self class] != [ZXPDF417ScanningDecoder class]) return;
+
+ 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
+ error:(NSError **)error {
+ 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 error:error];
+ if (!detectionResult) {
+ return nil;
+ }
+ if (i == 0 && detectionResult.boundingBox &&
+ (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 error:error];
+}
+
++ (ZXPDF417DetectionResult *)merge:(ZXPDF417DetectionResultRowIndicatorColumn *)leftRowIndicatorColumn
+ rightRowIndicatorColumn:(ZXPDF417DetectionResultRowIndicatorColumn *)rightRowIndicatorColumn
+ error:(NSError **)error {
+ if (!leftRowIndicatorColumn && !rightRowIndicatorColumn) {
+ return nil;
+ }
+ ZXPDF417BarcodeMetadata *barcodeMetadata = [self barcodeMetadata:leftRowIndicatorColumn rightRowIndicatorColumn:rightRowIndicatorColumn];
+ if (!barcodeMetadata) {
+ return nil;
+ }
+ ZXPDF417BoundingBox *leftBoundingBox, *rightBoundingBox;
+ if (![self adjustBoundingBox:&leftBoundingBox rowIndicatorColumn:leftRowIndicatorColumn error:error]) {
+ return nil;
+ }
+ if (![self adjustBoundingBox:&rightBoundingBox rowIndicatorColumn:rightRowIndicatorColumn error:error]) {
+ return nil;
+ }
+
+ ZXPDF417BoundingBox *boundingBox = [ZXPDF417BoundingBox mergeLeftBox:leftBoundingBox rightBox:rightBoundingBox];
+ if (!boundingBox) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ return [[ZXPDF417DetectionResult alloc] initWithBarcodeMetadata:barcodeMetadata boundingBox:boundingBox];
+}
+
++ (BOOL)adjustBoundingBox:(ZXPDF417BoundingBox **)boundingBox
+ rowIndicatorColumn:(ZXPDF417DetectionResultRowIndicatorColumn *)rowIndicatorColumn
+ error:(NSError **)error {
+ if (!rowIndicatorColumn) {
+ *boundingBox = nil;
+ return YES;
+ }
+ ZXIntArray *rowHeights;
+ if (![rowIndicatorColumn getRowHeights:&rowHeights]) {
+ if (error) *error = ZXFormatErrorInstance();
+ *boundingBox = nil;
+ return NO;
+ }
+ if (!rowHeights) {
+ *boundingBox = nil;
+ return YES;
+ }
+ int maxRowHeight = [self max:rowHeights];
+ int missingStartRows = 0;
+ for (int i = 0; i < rowHeights.length; i++) {
+ int rowHeight = rowHeights.array[i];
+ missingStartRows += maxRowHeight - rowHeight;
+ if (rowHeight > 0) {
+ break;
+ }
+ }
+ NSArray *codewords = rowIndicatorColumn.codewords;
+ for (int row = 0; missingStartRows > 0 && codewords[row] == [NSNull null]; row++) {
+ missingStartRows--;
+ }
+ int missingEndRows = 0;
+ for (int row = rowHeights.length - 1; row >= 0; row--) {
+ missingEndRows += maxRowHeight - rowHeights.array[row];
+ if (rowHeights.array[row] > 0) {
+ break;
+ }
+ }
+ for (int row = (int)[codewords count] - 1; missingEndRows > 0 && codewords[row] == [NSNull null]; row--) {
+ missingEndRows--;
+ }
+ *boundingBox = [rowIndicatorColumn.boundingBox addMissingRows:missingStartRows
+ missingEndRows:missingEndRows
+ isLeft:rowIndicatorColumn.isLeft];
+ return *boundingBox != nil;
+}
+
++ (int)max:(ZXIntArray *)values {
+ int maxValue = -1;
+ for (int i = 0; i < values.length; i++) {
+ int value = values.array[i];
+ maxValue = MAX(maxValue, value);
+ }
+ return maxValue;
+}
+
++ (ZXPDF417BarcodeMetadata *)barcodeMetadata:(ZXPDF417DetectionResultRowIndicatorColumn *)leftRowIndicatorColumn
+ rightRowIndicatorColumn:(ZXPDF417DetectionResultRowIndicatorColumn *)rightRowIndicatorColumn {
+ ZXPDF417BarcodeMetadata *leftBarcodeMetadata;
+ if (!leftRowIndicatorColumn ||
+ !(leftBarcodeMetadata = leftRowIndicatorColumn.barcodeMetadata)) {
+ return rightRowIndicatorColumn ? rightRowIndicatorColumn.barcodeMetadata : nil;
+ }
+ ZXPDF417BarcodeMetadata *rightBarcodeMetadata;
+ if (!rightRowIndicatorColumn ||
+ !(rightBarcodeMetadata = rightRowIndicatorColumn.barcodeMetadata)) {
+ return leftRowIndicatorColumn.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 {
+ ZXIntArray *numberOfCodewords = [(ZXPDF417BarcodeValue *)barcodeMatrix[0][1] value];
+ int calculatedNumberOfCodewords = [detectionResult barcodeColumnCount] * [detectionResult barcodeRowCount];
+ [self numberOfECCodeWords:detectionResult.barcodeECLevel];
+ if (numberOfCodewords.length == 0) {
+ if (calculatedNumberOfCodewords < 1 || calculatedNumberOfCodewords > ZX_PDF417_MAX_CODEWORDS_IN_BARCODE) {
+ return NO;
+ }
+ [(ZXPDF417BarcodeValue *)barcodeMatrix[0][1] setValue:calculatedNumberOfCodewords];
+ } else if (numberOfCodewords.array[0] != 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 error:(NSError **)error {
+ NSArray *barcodeMatrix = [self createBarcodeMatrix:detectionResult];
+ if (!barcodeMatrix) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ if (![self adjustCodewordCount:detectionResult barcodeMatrix:barcodeMatrix]) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ NSMutableArray *erasures = [NSMutableArray array];
+ ZXIntArray *codewords = [[ZXIntArray alloc] initWithLength:detectionResult.barcodeRowCount * detectionResult.barcodeColumnCount];
+ NSMutableArray *ambiguousIndexValuesList = [NSMutableArray array];
+ NSMutableArray *ambiguousIndexesList = [NSMutableArray array];
+ for (int row = 0; row < detectionResult.barcodeRowCount; row++) {
+ for (int column = 0; column < detectionResult.barcodeColumnCount; column++) {
+ ZXIntArray *values = [(ZXPDF417BarcodeValue *)barcodeMatrix[row][column + 1] value];
+ int codewordIndex = row * detectionResult.barcodeColumnCount + column;
+ if (values.length == 0) {
+ [erasures addObject:@(codewordIndex)];
+ } else if (values.length == 1) {
+ codewords.array[codewordIndex] = values.array[0];
+ } else {
+ [ambiguousIndexesList addObject:@(codewordIndex)];
+ [ambiguousIndexValuesList addObject:values];
+ }
+ }
+ }
+ return [self createDecoderResultFromAmbiguousValues:detectionResult.barcodeECLevel
+ codewords:codewords
+ erasureArray:[ZXPDF417Common toIntArray:erasures]
+ ambiguousIndexes:[ZXPDF417Common toIntArray:ambiguousIndexesList]
+ ambiguousIndexValues:ambiguousIndexValuesList
+ error:error];
+}
+
+/**
+ * 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.
+ *
+ * @param erasureArray contains the indexes of erasures
+ * @param ambiguousIndexes array with the indexes that have more than one most likely value
+ * @param ambiguousIndexValues two dimensional array that contains the ambiguous values. The first dimension must
+ * be the same length as the ambiguousIndexes array
+ */
++ (ZXDecoderResult *)createDecoderResultFromAmbiguousValues:(int)ecLevel
+ codewords:(ZXIntArray *)codewords
+ erasureArray:(ZXIntArray *)erasureArray
+ ambiguousIndexes:(ZXIntArray *)ambiguousIndexes
+ ambiguousIndexValues:(NSArray *)ambiguousIndexValues
+ error:(NSError **)error {
+ ZXIntArray *ambiguousIndexCount = [[ZXIntArray alloc] initWithLength:ambiguousIndexes.length];
+
+ int tries = 100;
+ while (tries-- > 0) {
+ for (int i = 0; i < ambiguousIndexCount.length; i++) {
+ ZXIntArray *a = ambiguousIndexValues[i];
+ codewords.array[ambiguousIndexes.array[i]] = a.array[(ambiguousIndexCount.array[i] + 1) % [(ZXIntArray *)ambiguousIndexValues[i] length]];
+ }
+ NSError *e;
+ ZXDecoderResult *result = [self decodeCodewords:codewords ecLevel:ecLevel erasures:erasureArray error:&e];
+ if (result) {
+ return result;
+ } else if (e.code != ZXChecksumError) {
+ if (error) *error = e;
+ return nil;
+ }
+ if (ambiguousIndexCount.length == 0) {
+ if (error) *error = ZXChecksumErrorInstance();
+ return nil;
+ }
+ for (int i = 0; i < ambiguousIndexCount.length; i++) {
+ if (ambiguousIndexCount.array[i] < [(ZXIntArray *)ambiguousIndexValues[i] length] - 1) {
+ ambiguousIndexCount.array[i]++;
+ break;
+ } else {
+ ambiguousIndexCount.array[i] = 0;
+ if (i == ambiguousIndexes.length - 1) {
+ if (error) *error = ZXChecksumErrorInstance();
+ return nil;
+ }
+ }
+ }
+ }
+
+ if (error) *error = ZXChecksumErrorInstance();
+ 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 = 0;
+ for (ZXPDF417DetectionResultColumn *detectionResultColumn in [detectionResult detectionResultColumns]) {
+ if ((id)detectionResultColumn != [NSNull null]) {
+ for (ZXPDF417Codeword *codeword in detectionResultColumn.codewords) {
+ if ((id)codeword != [NSNull null]) {
+ int rowNumber = codeword.rowNumber;
+ if (rowNumber >= 0) {
+ if (rowNumber >= barcodeMatrix.count) {
+ return nil;
+ }
+ [(ZXPDF417BarcodeValue *)barcodeMatrix[rowNumber][column] setValue:codeword.value];
+ }
+ }
+ }
+ }
+ column++;
+ }
+
+ 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] / 2; 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) > ZX_PDF417_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 - ZX_PDF417_CODEWORD_SKEW_SIZE <= codewordSize &&
+ codewordSize <= maxCodewordWidth + ZX_PDF417_CODEWORD_SKEW_SIZE;
+}
+
++ (ZXDecoderResult *)decodeCodewords:(ZXIntArray *)codewords ecLevel:(int)ecLevel erasures:(ZXIntArray *)erasures error:(NSError **)error {
+ if (codewords.length == 0) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+
+ int numECCodewords = 1 << (ecLevel + 1);
+ int correctedErrorsCount = [self correctErrors:codewords erasures:erasures numECCodewords:numECCodewords];
+ if (correctedErrorsCount == -1) {
+ if (error) *error = ZXChecksumErrorInstance();
+ return nil;
+ }
+ if (![self verifyCodewordCount:codewords numECCodewords:numECCodewords]) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+
+ // Decode the codewords
+ ZXDecoderResult *decoderResult = [ZXPDF417DecodedBitStreamParser decode:codewords ecLevel:[@(ecLevel) stringValue] error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ decoderResult.errorsCorrected = @(correctedErrorsCount);
+ decoderResult.erasures = @(erasures.length);
+ return decoderResult;
+}
+
+/**
+ * Given data and error-correction codewords received, possibly corrupted by errors, attempts to
+ * correct the errors in-place.
+ *
+ * @param codewords data and error correction codewords
+ * @param erasures positions of any known erasures
+ * @param numECCodewords number of error correction codewords that are available in codewords
+ * @throws ChecksumException if error correction fails
+ */
++ (int)correctErrors:(ZXIntArray *)codewords erasures:(ZXIntArray *)erasures numECCodewords:(int)numECCodewords {
+ if (erasures &&
+ (erasures.length > numECCodewords / 2 + ZX_PDF417_MAX_ERRORS ||
+ numECCodewords < 0 ||
+ numECCodewords > ZX_PDF417_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:(ZXIntArray *)codewords numECCodewords:(int)numECCodewords {
+ if (codewords.length < 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.array[0];
+ if (numberOfCodewords > codewords.length) {
+ 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.length) {
+ codewords.array[0] = codewords.length - 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 < [(NSArray *)barcodeMatrix[row] count]; column++) {
+ ZXPDF417BarcodeValue *barcodeValue = barcodeMatrix[row][column];
+ if ([barcodeValue value].length == 0) {
+ [result appendString:@" "];
+ } else {
+ [result appendFormat:@"%4d(%2d)", [barcodeValue value].array[0],
+ [[barcodeValue confidence:[barcodeValue value].array[0]] intValue]];
+ }
+ }
+ [result appendString:@"\n"];
+ }
+ return [NSString stringWithString:result];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.h
new file mode 100644
index 0000000..ba295e5
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.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.
+ */
+
+@class ZXModulusPoly;
+
+/**
+ * A field based on powers of a generator integer, modulo some modulus.
+ */
+@interface ZXModulusGF : NSObject
+
+@property (nonatomic, strong, readonly) ZXModulusPoly *one;
+@property (nonatomic, strong, readonly) 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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.m
new file mode 100644
index 0000000..468d6cf
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusGF.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 "ZXIntArray.h"
+#import "ZXModulusGF.h"
+#import "ZXModulusPoly.h"
+#import "ZXPDF417Common.h"
+
+@interface ZXModulusGF ()
+
+@property (nonatomic, assign, readonly) int32_t *expTable;
+@property (nonatomic, assign, readonly) int32_t *logTable;
+@property (nonatomic, assign, readonly) int modulus;
+
+@end
+
+@implementation ZXModulusGF
+
++ (ZXModulusGF *)PDF417_GF {
+ static dispatch_once_t pred = 0;
+ __strong static id _mod = nil;
+ dispatch_once(&pred, ^{
+ @autoreleasepool {
+ _mod = [[ZXModulusGF alloc] initWithModulus:ZX_PDF417_NUMBER_OF_CODEWORDS generator:3];
+ }
+ });
+ return _mod;
+}
+
+- (id)initWithModulus:(int)modulus generator:(int)generator {
+ if (self = [super init]) {
+ _modulus = modulus;
+ _expTable = (int32_t *)calloc(self.modulus, sizeof(int32_t));
+ _logTable = (int32_t *)calloc(self.modulus, sizeof(int32_t));
+ int32_t x = 1;
+ for (int i = 0; i < modulus; i++) {
+ _expTable[i] = x;
+ x = (x * generator) % modulus;
+ }
+ for (int i = 0; i < self.size - 1; i++) {
+ _logTable[_expTable[i]] = i;
+ }
+ // logTable[0] == 0 but this should never be used
+ _zero = [[ZXModulusPoly alloc] initWithField:self coefficients:[[ZXIntArray alloc] initWithLength:1]];
+ _one = [[ZXModulusPoly alloc] initWithField:self coefficients:[[ZXIntArray alloc] initWithInts:1, -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;
+ }
+ ZXIntArray *coefficients = [[ZXIntArray alloc] initWithLength:degree + 1];
+ coefficients.array[0] = coefficient;
+ return [[ZXModulusPoly alloc] initWithField:self coefficients:coefficients];
+}
+
+- (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 _expTable[a];
+}
+
+- (int)log:(int)a {
+ if (a == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Argument must be non-zero."];
+ }
+ return _logTable[a];
+}
+
+- (int)inverse:(int)a {
+ if (a == 0) {
+ [NSException raise:NSInvalidArgumentException format:@"Argument must be non-zero."];
+ }
+
+ return _expTable[_modulus - _logTable[a] - 1];
+}
+
+- (int)multiply:(int)a b:(int)b {
+ if (a == 0 || b == 0) {
+ return 0;
+ }
+
+ return _expTable[(_logTable[a] + _logTable[b]) % (_modulus - 1)];
+}
+
+- (int)size {
+ return self.modulus;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.h
new file mode 100644
index 0000000..103a8e7
--- /dev/null
+++ b/Pods/ZXingObjC/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 ZXIntArray, ZXModulusGF;
+
+@interface ZXModulusPoly : NSObject
+
+- (id)initWithField:(ZXModulusGF *)field coefficients:(ZXIntArray *)coefficients;
+- (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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.m
new file mode 100644
index 0000000..e28af02
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXModulusPoly.m
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXIntArray.h"
+#import "ZXModulusGF.h"
+#import "ZXModulusPoly.h"
+
+@interface ZXModulusPoly ()
+
+@property (nonatomic, strong, readonly) ZXIntArray *coefficients;
+@property (nonatomic, weak, readonly) ZXModulusGF *field;
+
+@end
+
+@implementation ZXModulusPoly
+
+- (id)initWithField:(ZXModulusGF *)field coefficients:(ZXIntArray *)coefficients {
+ if (self = [super init]) {
+ if (coefficients.length == 0) {
+ @throw [NSException exceptionWithName:@"IllegalArgumentException"
+ reason:@"coefficients must have at least one element"
+ userInfo:nil];
+ }
+ _field = field;
+ int coefficientsLength = coefficients.length;
+ if (coefficientsLength > 1 && coefficients.array[0] == 0) {
+ // Leading term must be non-zero for anything except the constant polynomial "0"
+ int firstNonZero = 1;
+ while (firstNonZero < coefficientsLength && coefficients.array[firstNonZero] == 0) {
+ firstNonZero++;
+ }
+ if (firstNonZero == coefficientsLength) {
+ _coefficients = [[ZXIntArray alloc] initWithLength:1];
+ } else {
+ _coefficients = [[ZXIntArray alloc] initWithLength:coefficientsLength - firstNonZero];
+ for (int i = 0; i < _coefficients.length; i++) {
+ _coefficients.array[i] = coefficients.array[firstNonZero + i];
+ }
+ }
+ } else {
+ _coefficients = coefficients;
+ }
+ }
+
+ return self;
+}
+
+/**
+ * @return degree of this polynomial
+ */
+- (int)degree {
+ return self.coefficients.length - 1;
+}
+
+/**
+ * @return true iff this polynomial is the monomial "0"
+ */
+- (BOOL)zero {
+ return self.coefficients.array[0] == 0;
+}
+
+/**
+ * @return coefficient of x^degree term in this polynomial
+ */
+- (int)coefficient:(int)degree {
+ return self.coefficients.array[self.coefficients.length - 1 - degree];
+}
+
+/**
+ * @return evaluation of this polynomial at a given point
+ */
+- (int)evaluateAt:(int)a {
+ if (a == 0) {
+ return [self coefficient:0];
+ }
+ int size = self.coefficients.length;
+ 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.array[i]];
+ }
+ return result;
+ }
+ int result = self.coefficients.array[0];
+ for (int i = 1; i < size; i++) {
+ result = [self.field add:[self.field multiply:a b:result] b:self.coefficients.array[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;
+ }
+
+ ZXIntArray *smallerCoefficients = self.coefficients;
+ ZXIntArray *largerCoefficients = other.coefficients;
+ if (smallerCoefficients.length > largerCoefficients.length) {
+ ZXIntArray *temp = smallerCoefficients;
+ smallerCoefficients = largerCoefficients;
+ largerCoefficients = temp;
+ }
+ ZXIntArray *sumDiff = [[ZXIntArray alloc] initWithLength:largerCoefficients.length];
+ int lengthDiff = largerCoefficients.length - smallerCoefficients.length;
+ // Copy high-order terms only found in higher-degree polynomial's coefficients
+ memcpy(sumDiff.array, largerCoefficients.array, lengthDiff * sizeof(int32_t));
+
+ for (int i = lengthDiff; i < largerCoefficients.length; i++) {
+ sumDiff.array[i] = [self.field add:smallerCoefficients.array[i - lengthDiff] b:largerCoefficients.array[i]];
+ }
+
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:sumDiff];
+}
+
+- (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;
+ }
+ ZXIntArray *aCoefficients = self.coefficients;
+ int aLength = aCoefficients.length;
+ ZXIntArray *bCoefficients = other.coefficients;
+ int bLength = bCoefficients.length;
+ ZXIntArray *product = [[ZXIntArray alloc] initWithLength:aLength + bLength - 1];
+ for (int i = 0; i < aLength; i++) {
+ int aCoeff = aCoefficients.array[i];
+ for (int j = 0; j < bLength; j++) {
+ product.array[i + j] = [self.field add:product.array[i + j]
+ b:[self.field multiply:aCoeff b:bCoefficients.array[j]]];
+ }
+ }
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:product];
+}
+
+- (ZXModulusPoly *)negative {
+ int size = self.coefficients.length;
+ ZXIntArray *negativeCoefficients = [[ZXIntArray alloc] initWithLength:size];
+ for (int i = 0; i < size; i++) {
+ negativeCoefficients.array[i] = [self.field subtract:0 b:self.coefficients.array[i]];
+ }
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:negativeCoefficients];
+}
+
+- (ZXModulusPoly *)multiplyScalar:(int)scalar {
+ if (scalar == 0) {
+ return self.field.zero;
+ }
+ if (scalar == 1) {
+ return self;
+ }
+ int size = self.coefficients.length;
+ ZXIntArray *product = [[ZXIntArray alloc] initWithLength:size];
+ for (int i = 0; i < size; i++) {
+ product.array[i] = [self.field multiply:self.coefficients.array[i] b:scalar];
+ }
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:product];
+}
+
+- (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.coefficients.length;
+ ZXIntArray *product = [[ZXIntArray alloc] initWithLength:size + degree];
+ for (int i = 0; i < size; i++) {
+ product.array[i] = [self.field multiply:self.coefficients.array[i] b:coefficient];
+ }
+
+ return [[ZXModulusPoly alloc] initWithField:self.field coefficients:product];
+}
+
+- (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/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.h
new file mode 100644
index 0000000..3f89cfb
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.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 ZXIntArray;
+
+/**
+ * PDF417 error correction implementation.
+ *
+ * This example
+ * is quite useful in understanding the algorithm.
+ */
+@interface ZXPDF417ECErrorCorrection : NSObject
+
+/**
+ * @return number of errors
+ */
+- (int)decode:(ZXIntArray *)received numECCodewords:(int)numECCodewords erasures:(ZXIntArray *)erasures;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.m b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.m
new file mode 100644
index 0000000..4b8922f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/decoder/ec/ZXPDF417ECErrorCorrection.m
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXIntArray.h"
+#import "ZXModulusGF.h"
+#import "ZXModulusPoly.h"
+#import "ZXPDF417ECErrorCorrection.h"
+
+@interface ZXPDF417ECErrorCorrection ()
+
+@property (nonatomic, strong, readonly) ZXModulusGF *field;
+
+@end
+
+@implementation ZXPDF417ECErrorCorrection
+
+- (id)init {
+ if (self = [super init]) {
+ _field = [ZXModulusGF PDF417_GF];
+ }
+
+ return self;
+}
+
+- (int)decode:(ZXIntArray *)received numECCodewords:(int)numECCodewords erasures:(ZXIntArray *)erasures {
+ ZXModulusPoly *poly = [[ZXModulusPoly alloc] initWithField:self.field coefficients:received];
+ ZXIntArray *S = [[ZXIntArray alloc] initWithLength:numECCodewords];
+ BOOL error = NO;
+ for (int i = numECCodewords; i > 0; i--) {
+ int eval = [poly evaluateAt:[self.field exp:i]];
+ S.array[numECCodewords - i] = eval;
+ if (eval != 0) {
+ error = YES;
+ }
+ }
+
+ if (!error) {
+ return 0;
+ }
+
+ ZXModulusPoly *knownErrors = self.field.one;
+ if (erasures) {
+ for (int i = 0; i < erasures.length; i++) {
+ int erasure = erasures.array[i];
+ int b = [self.field exp:received.length - 1 - erasure];
+ // Add (1 - bx) term:
+ ZXModulusPoly *term = [[ZXModulusPoly alloc] initWithField:self.field coefficients:[[ZXIntArray alloc] initWithInts:[self.field subtract:0 b:b], 1, -1]];
+ knownErrors = [knownErrors multiply:term];
+ }
+ }
+
+ ZXModulusPoly *syndrome = [[ZXModulusPoly alloc] initWithField:self.field coefficients:S];
+ //[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];
+
+ ZXIntArray *errorLocations = [self findErrorLocations:sigma];
+ if (!errorLocations) return -1;
+ ZXIntArray *errorMagnitudes = [self findErrorMagnitudes:omega errorLocator:sigma errorLocations:errorLocations];
+
+ for (int i = 0; i < errorLocations.length; i++) {
+ int position = received.length - 1 - [self.field log:errorLocations.array[i]];
+ if (position < 0) {
+ return -1;
+ }
+ received.array[position] = [self.field subtract:received.array[position] b:errorMagnitudes.array[i]];
+ }
+
+ return errorLocations.length;
+}
+
+- (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];
+}
+
+- (ZXIntArray *)findErrorLocations:(ZXModulusPoly *)errorLocator {
+ // This is a direct application of Chien's search
+ int numErrors = errorLocator.degree;
+ ZXIntArray *result = [[ZXIntArray alloc] initWithLength:numErrors];
+ int e = 0;
+ for (int i = 1; i < self.field.size && e < numErrors; i++) {
+ if ([errorLocator evaluateAt:i] == 0) {
+ result.array[e] = [self.field inverse:i];
+ e++;
+ }
+ }
+ if (e != numErrors) {
+ return nil;
+ }
+ return result;
+}
+
+- (ZXIntArray *)findErrorMagnitudes:(ZXModulusPoly *)errorEvaluator errorLocator:(ZXModulusPoly *)errorLocator errorLocations:(ZXIntArray *)errorLocations {
+ int errorLocatorDegree = errorLocator.degree;
+ ZXIntArray *formalDerivativeCoefficients = [[ZXIntArray alloc] initWithLength:errorLocatorDegree];
+ for (int i = 1; i <= errorLocatorDegree; i++) {
+ formalDerivativeCoefficients.array[errorLocatorDegree - i] =
+ [self.field multiply:i b:[errorLocator coefficient:i]];
+ }
+ ZXModulusPoly *formalDerivative = [[ZXModulusPoly alloc] initWithField:self.field coefficients:formalDerivativeCoefficients];
+
+ // This is directly applying Forney's Formula
+ int s = errorLocations.length;
+ ZXIntArray *result = [[ZXIntArray alloc] initWithLength:s];
+ for (int i = 0; i < s; i++) {
+ int xiInverse = [self.field inverse:errorLocations.array[i]];
+ int numerator = [self.field subtract:0 b:[errorEvaluator evaluateAt:xiInverse]];
+ int denominator = [self.field inverse:[formalDerivative evaluateAt:xiInverse]];
+ result.array[i] = [self.field multiply:numerator b:denominator];
+ }
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417Detector.h b/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417Detector.h
new file mode 100644
index 0000000..2ebaee8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417Detector.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 ZXBinaryBitmap, ZXBitArray, ZXBitMatrix, ZXDecodeHints, ZXPDF417DetectorResult;
+
+/**
+ * Encapsulates logic that can detect a PDF417 Code in an image, even if the
+ * PDF417 Code is rotated or skewed, or partially obscured.
+ */
+@interface ZXPDF417Detector : NSObject
+
+/**
+ * Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations.
+ *
+ * @param hints optional hints to detector
+ * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will
+ * be found and returned
+ * @return ZXPDF417DetectorResult encapsulating results of detecting a PDF417 code or nil
+ * if no PDF417 Code can be found
+ */
++ (ZXPDF417DetectorResult *)detect:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints multiple:(BOOL)multiple error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417Detector.m b/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417Detector.m
new file mode 100644
index 0000000..50333c3
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417Detector.m
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 ZX_PDF417_INDEXES_START_PATTERN[] = {0, 4, 1, 5};
+const int ZX_PDF417_INDEXES_STOP_PATTERN[] = {6, 2, 7, 3};
+const float ZX_PDF417_MAX_AVG_VARIANCE = 0.42f;
+const float ZX_PDF417_MAX_INDIVIDUAL_VARIANCE = 0.8f;
+
+// B S B S B S B S Bar/Space pattern
+// 11111111 0 1 0 1 0 1 000
+const int ZX_PDF417_DETECTOR_START_PATTERN[] = {8, 1, 1, 1, 1, 1, 1, 3};
+
+// 1111111 0 1 000 1 0 1 00 1
+const int ZX_PDF417_DETECTOR_STOP_PATTERN[] = {7, 1, 1, 3, 1, 1, 1, 2, 1};
+const int ZX_PDF417_MAX_PIXEL_DRIFT = 3;
+const int ZX_PDF417_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.
+const int ZX_PDF417_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.
+const int ZX_PDF417_ROW_STEP = 5;
+const int ZX_PDF417_BARCODE_MIN_HEIGHT = 10;
+
+@implementation ZXPDF417Detector
+
++ (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) {
+ bitMatrix = [bitMatrix copy];
+ [bitMatrix rotate180];
+ 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
+ * @param multiple if true, then the image is searched for multiple codes. If false, then at most one code will
+ * be found and returned
+ * @param bitMatrix bit matrix to detect barcodes in
+ * @return List of ResultPoint arrays containing the coordinates of found barcodes
+ */
++ (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 += ZX_PDF417_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;
+}
+
+/**
+ * Locate the vertices and the codewords area of a black blob using the Start
+ * and Stop patterns as locators.
+ *
+ * @param matrix the scanned barcode image.
+ * @return 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:ZX_PDF417_DETECTOR_START_PATTERN
+ patternLen:sizeof(ZX_PDF417_DETECTOR_START_PATTERN) / sizeof(int)]
+ destinationIndexes:ZX_PDF417_INDEXES_START_PATTERN
+ length:sizeof(ZX_PDF417_INDEXES_START_PATTERN) / sizeof(int)];
+
+ 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:ZX_PDF417_DETECTOR_STOP_PATTERN
+ patternLen:sizeof(ZX_PDF417_DETECTOR_STOP_PATTERN) / sizeof(int)]
+ destinationIndexes:ZX_PDF417_INDEXES_STOP_PATTERN
+ length:sizeof(ZX_PDF417_INDEXES_STOP_PATTERN) / sizeof(int)];
+ return result;
+}
+
++ (void)copyToResult:(NSMutableArray *)result tmpResult:(NSMutableArray *)tmpResult destinationIndexes:(const int[])destinationIndexes length:(int)length {
+ for (int i = 0; i < length; i++) {
+ result[destinationIndexes[i]] = tmpResult[i];
+ }
+}
+
++ (NSMutableArray *)findRowsWithPattern:(ZXBitMatrix *)matrix height:(int)height width:(int)width startRow:(int)startRow
+ startColumn:(int)startColumn pattern:(const 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 += ZX_PDF417_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) < ZX_PDF417_MAX_PATTERN_DRIFT &&
+ ABS((int)NSMaxRange(previousRowLoc) - (int)NSMaxRange(loc)) < ZX_PDF417_MAX_PATTERN_DRIFT) {
+ previousRowLoc = loc;
+ skippedRowCount = 0;
+ } else {
+ if (skippedRowCount > ZX_PDF417_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 < ZX_PDF417_BARCODE_MIN_HEIGHT) {
+ for (int i = 0; i < 4; i++) {
+ result[i] = [NSNull null];
+ }
+ }
+ return result;
+}
+
+/**
+ * @param matrix row of black/white values to search
+ * @param column x position to start search
+ * @param row y position to start search
+ * @param width the number of pixels to search on this row
+ * @param pattern pattern of counts of number of black and white pixels that are
+ * being searched for as a pattern
+ * @param counters array of counters, as long as pattern, to re-use
+ * @return start/end horizontal offset of guard pattern, as an array of two ints.
+ */
++ (NSRange)findGuardPattern:(ZXBitMatrix *)matrix
+ column:(int)column
+ row:(int)row
+ width:(int)width
+ whiteFirst:(BOOL)whiteFirst
+ pattern:(const 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 ZX_PDF417_MAX_PIXEL_DRIFT pixels
+ while ([matrix getX:patternStart y:row] && patternStart > 0 && pixelDrift++ < ZX_PDF417_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:ZX_PDF417_MAX_INDIVIDUAL_VARIANCE] < ZX_PDF417_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:ZX_PDF417_MAX_INDIVIDUAL_VARIANCE] < ZX_PDF417_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.
+ *
+ * @param counters observed counters
+ * @param pattern expected pattern
+ * @param maxIndividualVariance The most any counter can differ before we give up
+ * @return ratio of total variance between counters and pattern compared to total pattern size
+ */
++ (float)patternMatchVariance:(int *)counters countersSize:(int)countersSize pattern:(const int[])pattern maxIndividualVariance:(float)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 FLT_MAX;
+ }
+ float unitBarWidth = (float) total / patternLength;
+ maxIndividualVariance *= unitBarWidth;
+
+ float totalVariance = 0.0f;
+ for (int x = 0; x < numCounters; x++) {
+ int counter = counters[x];
+ float scaledPattern = pattern[x] * unitBarWidth;
+ float variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
+ if (variance > maxIndividualVariance) {
+ return FLT_MAX;
+ }
+ totalVariance += variance;
+ }
+
+ return totalVariance / total;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.h b/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.h
new file mode 100644
index 0000000..b7e8c92
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.m b/Pods/ZXingObjC/ZXingObjC/pdf417/detector/ZXPDF417DetectorResult.m
new file mode 100644
index 0000000..47fa823
--- /dev/null
+++ b/Pods/ZXingObjC/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/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417.h b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417.h
new file mode 100644
index 0000000..76a45a1
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417.h
@@ -0,0 +1,55 @@
+/*
+ * 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 "ZXEncodeHints.h"
+
+@class ZXPDF417BarcodeMatrix, ZXIntArray;
+
+/**
+ * Top-level class for the logic part of the PDF417 implementation.
+ */
+@interface ZXPDF417 : NSObject
+
+@property (nonatomic, strong, readonly) ZXPDF417BarcodeMatrix *barcodeMatrix;
+@property (nonatomic, assign) BOOL compact;
+@property (nonatomic, assign) ZXPDF417Compaction compaction;
+@property (nonatomic, assign) NSStringEncoding encoding;
+
+- (id)initWithCompact:(BOOL)compact;
+
+/**
+ * Generates the barcode logic.
+ *
+ * @param msg the message to encode
+ */
+- (BOOL)generateBarcodeLogic:(NSString *)msg errorCorrectionLevel:(int)errorCorrectionLevel error:(NSError **)error;
+
+/**
+ * Determine optimal nr of columns and rows for the specified number of
+ * codewords.
+ *
+ * @param sourceCodeWords number of code words
+ * @param errorCorrectionCodeWords number of error correction code words
+ * @return dimension object containing cols as width and rows as height
+ */
+- (ZXIntArray *)determineDimensions:(int)sourceCodeWords errorCorrectionCodeWords:(int)errorCorrectionCodeWords error:(NSError **)error;
+
+/**
+ * Sets max/min row/col values
+ */
+- (void)setDimensionsWithMaxCols:(int)maxCols minCols:(int)minCols maxRows:(int)maxRows minRows:(int)minRows;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417.m b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417.m
new file mode 100644
index 0000000..fb1e9b7
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417.m
@@ -0,0 +1,733 @@
+/*
+ * 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 "ZXIntArray.h"
+#import "ZXPDF417.h"
+#import "ZXPDF417BarcodeMatrix.h"
+#import "ZXPDF417BarcodeRow.h"
+#import "ZXPDF417ErrorCorrection.h"
+#import "ZXPDF417HighLevelEncoder.h"
+
+/**
+ * The start pattern (17 bits)
+ */
+const int ZX_PDF417_START_PATTERN = 0x1fea8;
+/**
+ * The stop pattern (18 bits)
+ */
+const int ZX_PDF417_STOP_PATTERN = 0x3fa29;
+
+/**
+ * The codeword table from the Annex A of ISO/IEC 15438:2001(E).
+ */
+#define ZX_PDF417_CODEWORD_TABLE_LEN 3
+#define ZX_PDF417_CODEWORD_TABLE_SUB_LEN 929
+const int ZX_PDF417_CODEWORD_TABLE[ZX_PDF417_CODEWORD_TABLE_LEN][ZX_PDF417_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}};
+
+const float ZX_PDF417_PREFERRED_RATIO = 3.0f;
+const float ZX_PDF417_DEFAULT_MODULE_WIDTH = 0.357f; //1px in mm
+const float ZX_PDF417_HEIGHT = 2.0f; //mm
+
+@interface ZXPDF417 ()
+
+@property (nonatomic, strong) ZXPDF417BarcodeMatrix *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 = ZXPDF417CompactionAuto;
+ _encoding = ZX_PDF417_DEFAULT_ENCODING;
+ _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).
+ *
+ * @param m the number of source codewords prior to the additional of the Symbol Length
+ * Descriptor and any pad codewords
+ * @param k the number of error correction codewords
+ * @param c the number of columns in the symbol in the data region (excluding start, stop and
+ * row indicator codewords)
+ * @return the number of rows in the symbol (r)
+ */
+- (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).
+ *
+ * @param m the number of source codewords prior to the additional of the Symbol Length
+ * Descriptor and any pad codewords
+ * @param k the number of error correction codewords
+ * @param c the number of columns in the symbol in the data region (excluding start, stop and
+ * row indicator codewords)
+ * @param r the number of rows in the symbol
+ * @return the number of pad codewords
+ */
+- (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:(ZXPDF417BarcodeRow *)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:(ZXPDF417BarcodeMatrix *)logic {
+ int idx = 0;
+ for (int y = 0; y < r; y++) {
+ int cluster = y % 3;
+ [logic startRow];
+ [self encodeCharPattern:ZX_PDF417_START_PATTERN 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 = ZX_PDF417_CODEWORD_TABLE[cluster][left];
+ [self encodeCharPattern:pattern len:17 logic:logic.currentRow];
+
+ for (int x = 0; x < c; x++) {
+ pattern = ZX_PDF417_CODEWORD_TABLE[cluster][[fullCodewords characterAtIndex:idx]];
+ [self encodeCharPattern:pattern len:17 logic:logic.currentRow];
+ idx++;
+ }
+
+ if (self.compact) {
+ [self encodeCharPattern:ZX_PDF417_STOP_PATTERN len:1 logic:logic.currentRow];
+ } else {
+ pattern = ZX_PDF417_CODEWORD_TABLE[cluster][right];
+ [self encodeCharPattern:pattern len:17 logic:logic.currentRow];
+
+ [self encodeCharPattern:ZX_PDF417_STOP_PATTERN len:18 logic:logic.currentRow];
+ }
+ }
+}
+
+- (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 encoding:self.encoding error:error];
+ if (!highLevel) {
+ return NO;
+ }
+ int sourceCodeWords = (int)highLevel.length;
+
+ ZXIntArray *dimension = [self determineDimensions:sourceCodeWords errorCorrectionCodeWords:errorCorrectionCodeWords error:error];
+ if (!dimension) {
+ return NO;
+ }
+
+ int cols = dimension.array[0];
+ int rows = dimension.array[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 = [[ZXPDF417BarcodeMatrix alloc] initWithHeight:rows width:cols];
+ [self encodeLowLevel:fullCodewords c:cols r:rows errorCorrectionLevel:anErrorCorrectionLevel logic:self.barcodeMatrix];
+
+ return YES;
+}
+
+- (ZXIntArray *)determineDimensions:(int)sourceCodeWords errorCorrectionCodeWords:(int)errorCorrectionCodeWords error:(NSError **)error {
+ float ratio = 0.0f;
+ ZXIntArray *dimension = nil;
+
+ 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) * ZX_PDF417_DEFAULT_MODULE_WIDTH) / (rows * ZX_PDF417_HEIGHT);
+
+ // ignore if previous ratio is closer to preferred ratio
+ if (dimension && fabsf(newRatio - ZX_PDF417_PREFERRED_RATIO) > fabsf(ratio - ZX_PDF417_PREFERRED_RATIO)) {
+ continue;
+ }
+
+ ratio = newRatio;
+ dimension = [[ZXIntArray alloc] initWithInts:cols, rows, -1];
+ }
+
+ // Handle case when min values were larger than necessary
+ if (!dimension) {
+ int rows = [self calculateNumberOfRowsM:sourceCodeWords k:errorCorrectionCodeWords c:self.minCols];
+ if (rows < self.minRows) {
+ dimension = [[ZXIntArray alloc] initWithInts:self.minCols, self.minRows, -1];
+ }
+ }
+
+ if (!dimension) {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Unable to fit message in columns"};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return nil;
+ }
+
+ return dimension;
+}
+
+- (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/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.h b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.h
new file mode 100644
index 0000000..9ff0aed
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.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.
+ */
+
+@class ZXPDF417BarcodeRow;
+
+/**
+ * Holds all of the information for a barcode in a format where it can be easily accessable
+ */
+@interface ZXPDF417BarcodeMatrix : NSObject
+
+@property (nonatomic, assign, readonly) int height;
+@property (nonatomic, assign, readonly) int width;
+
+/**
+ * @param height the height of the matrix (Rows)
+ * @param width the width of the matrix (Cols)
+ */
+- (id)initWithHeight:(int)height width:(int)width;
+- (void)startRow;
+- (ZXPDF417BarcodeRow *)currentRow;
+- (NSArray *)matrix;
+//- (NSArray *)scaledMatrix:(int)scale;
+- (NSArray *)scaledMatrixWithXScale:(int)xScale yScale:(int)yScale;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.m b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.m
new file mode 100644
index 0000000..6e0d452
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeMatrix.m
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXPDF417BarcodeMatrix.h"
+#import "ZXPDF417BarcodeRow.h"
+
+@interface ZXPDF417BarcodeMatrix ()
+
+@property (nonatomic, assign) int currentRowIndex;
+@property (nonatomic, strong, readonly) NSArray *rowMatrix;
+
+@end
+
+@implementation ZXPDF417BarcodeMatrix
+
+- (id)initWithHeight:(int)height width:(int)width {
+ if (self = [super init]) {
+ NSMutableArray *matrix = [NSMutableArray array];
+ for (int i = 0, matrixLength = height; i < matrixLength; i++) {
+ [matrix addObject:[ZXPDF417BarcodeRow barcodeRowWithWidth:(width + 4) * 17 + 1]];
+ }
+ _rowMatrix = matrix;
+ _width = width * 17;
+ _height = height;
+ _currentRowIndex = -1;
+ }
+
+ 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;
+}
+
+- (ZXPDF417BarcodeRow *)currentRow {
+ return self.rowMatrix[self.currentRowIndex];
+}
+
+- (NSArray *)matrix {
+ return [self scaledMatrixWithXScale:1 yScale:1];
+}
+
+/*
+- (NSArray *)scaledMatrix:(int)scale {
+ return [self scaledMatrixWithXScale:scale yScale:scale];
+}
+*/
+
+- (NSArray *)scaledMatrixWithXScale:(int)xScale yScale:(int)yScale {
+ int yMax = self.height * yScale;
+ NSMutableArray *matrixOut = [NSMutableArray array];
+ for (int i = 0; i < yMax; i++) {
+ [matrixOut addObject:[NSNull null]];
+ }
+
+ for (int i = 0; i < yMax; i++) {
+ matrixOut[yMax - i - 1] = [(ZXPDF417BarcodeRow *)self.rowMatrix[i / yScale] scaledRow:xScale];
+ }
+
+ return matrixOut;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeRow.h b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeRow.h
new file mode 100644
index 0000000..a00f7b9
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeRow.h
@@ -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.
+ */
+
+@class ZXByteArray;
+
+@interface ZXPDF417BarcodeRow : NSObject
+
+@property (nonatomic, strong, readonly) ZXByteArray *row;
+
+/**
+ * Creates a Barcode row of the width
+ */
++ (ZXPDF417BarcodeRow *)barcodeRowWithWidth:(int)width;
+
+- (id)initWithWidth:(int)width;
+
+/**
+ * Sets a specific location in the bar
+ *
+ * @param x The location in the bar
+ * @param value Black if true, white if false;
+ */
+- (void)setX:(int)x value:(int8_t)value;
+
+/**
+ * Sets a specific location in the bar
+ *
+ * @param x The location in the bar
+ * @param black Black if true, white if false;
+ */
+- (void)setX:(int)x black:(BOOL)black;
+
+/**
+ * @param black A boolean which is true if the bar black false if it is white
+ * @param width How many spots wide the bar is.
+ */
+- (void)addBar:(BOOL)black width:(int)width;
+
+/**
+ * This function scales the row
+ *
+ * @param scale How much you want the image to be scaled, must be greater than or equal to 1.
+ * @return the scaled row
+ */
+- (ZXByteArray *)scaledRow:(int)scale;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeRow.m b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeRow.m
new file mode 100644
index 0000000..6237bf5
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417BarcodeRow.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 "ZXByteArray.h"
+#import "ZXPDF417BarcodeRow.h"
+
+@interface ZXPDF417BarcodeRow ()
+
+//A tacker for position in the bar
+@property (nonatomic, assign) int currentLocation;
+
+@end
+
+@implementation ZXPDF417BarcodeRow
+
++ (ZXPDF417BarcodeRow *)barcodeRowWithWidth:(int)width {
+ return [[ZXPDF417BarcodeRow alloc] initWithWidth:width];
+}
+
+- (id)initWithWidth:(int)width {
+ if (self = [super init]) {
+ _row = [[ZXByteArray alloc] initWithLength:width];
+ _currentLocation = 0;
+ }
+ return self;
+}
+
+- (void)setX:(int)x value:(int8_t)value {
+ self.row.array[x] = value;
+}
+
+- (void)setX:(int)x black:(BOOL)black {
+ self.row.array[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];
+ }
+}
+
+- (ZXByteArray *)scaledRow:(int)scale {
+ ZXByteArray *output = [[ZXByteArray alloc] initWithLength:self.row.length * scale];
+ for (int i = 0; i < output.length; i++) {
+ output.array[i] = self.row.array[i / scale];
+ }
+ return output;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.h b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.h
new file mode 100644
index 0000000..0e1f155
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.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 ZXPDF417Dimensions : NSObject
+
+@property (nonatomic, assign, readonly) int minCols;
+@property (nonatomic, assign, readonly) int maxCols;
+@property (nonatomic, assign, readonly) int minRows;
+@property (nonatomic, assign, readonly) int maxRows;
+
+- (id)initWithMinCols:(int)minCols maxCols:(int)maxCols minRows:(int)minRows maxRows:(int)maxRows;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.m b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.m
new file mode 100644
index 0000000..33529ab
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417Dimensions.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 "ZXPDF417Dimensions.h"
+
+@implementation ZXPDF417Dimensions
+
+- (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/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.h b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.h
new file mode 100644
index 0000000..de8eb75
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.h
@@ -0,0 +1,51 @@
+/*
+ * 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
+
+/**
+ * Determines the number of error correction codewords for a specified error correction
+ * level.
+ *
+ * @param errorCorrectionLevel the error correction level (0-8)
+ * @return the number of codewords generated for error correction
+ */
+
++ (int)errorCorrectionCodewordCount:(int)errorCorrectionLevel;
+
+/**
+ * Returns the recommended minimum error correction level as described in annex E of
+ * ISO/IEC 15438:2001(E).
+ *
+ * @param n the number of data codewords
+ * @return the recommended minimum error correction level
+ */
++ (int)recommendedMinimumErrorCorrectionLevel:(int)n error:(NSError **)error;
+
+/**
+ * Generates the error correction codewords according to 4.10 in ISO/IEC 15438:2001(E).
+ *
+ * @param dataCodewords the data codewords
+ * @param errorCorrectionLevel the error correction level (0-8)
+ * @return the String representing the error correction codewords
+ */
++ (NSString *)generateErrorCorrection:(NSString *)dataCodewords errorCorrectionLevel:(int)errorCorrectionLevel;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.m b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.m
new file mode 100644
index 0000000..9b88804
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417ErrorCorrection.m
@@ -0,0 +1,176 @@
+/*
+ * 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 ZX_PDF417_EC_COEFFICIENTS[][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
+
++ (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);
+}
+
++ (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;
+}
+
++ (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 * ZX_PDF417_EC_COEFFICIENTS[errorCorrectionLevel][j]) % 929;
+ t3 = 929 - t2;
+ e[j] = (unichar) ((e[j - 1] + t3) % 929);
+ }
+ t2 = (t1 * ZX_PDF417_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/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.h b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.h
new file mode 100644
index 0000000..9ae3deb
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.h
@@ -0,0 +1,37 @@
+/*
+ * 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 "ZXEncodeHints.h"
+
+extern const NSStringEncoding ZX_PDF417_DEFAULT_ENCODING;
+
+/**
+ * PDF417 high-level encoder following the algorithm described in ISO/IEC 15438:2001(E) in
+ * annex P.
+ */
+@interface ZXPDF417HighLevelEncoder : NSObject
+
+/**
+ * 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.
+ *
+ * @param msg the message
+ * @return the encoded message (the char values range from 0 to 928)
+ */
++ (NSString *)encodeHighLevel:(NSString *)msg compaction:(ZXPDF417Compaction)compaction encoding:(NSStringEncoding)encoding error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m
new file mode 100644
index 0000000..ed6198b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/pdf417/encoder/ZXPDF417HighLevelEncoder.m
@@ -0,0 +1,586 @@
+/*
+ * 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 "ZXByteArray.h"
+#import "ZXCharacterSetECI.h"
+#import "ZXErrors.h"
+#import "ZXPDF417HighLevelEncoder.h"
+
+/**
+ * code for Text compaction
+ */
+const int ZX_PDF417_TEXT_COMPACTION = 0;
+
+/**
+ * code for Byte compaction
+ */
+const int ZX_PDF417_BYTE_COMPACTION = 1;
+
+/**
+ * code for Numeric compaction
+ */
+const int ZX_PDF417_NUMERIC_COMPACTION = 2;
+
+/**
+ * Text compaction submode Alpha
+ */
+const int ZX_PDF417_SUBMODE_ALPHA = 0;
+
+/**
+ * Text compaction submode Lower
+ */
+const int ZX_PDF417_SUBMODE_LOWER = 1;
+
+/**
+ * Text compaction submode Mixed
+ */
+const int ZX_PDF417_SUBMODE_MIXED = 2;
+
+/**
+ * Text compaction submode Punctuation
+ */
+const int ZX_PDF417_SUBMODE_PUNCTUATION = 3;
+
+/**
+ * mode latch to Text Compaction mode
+ */
+const int ZX_PDF417_LATCH_TO_TEXT = 900;
+
+/**
+ * mode latch to Byte Compaction mode (number of characters NOT a multiple of 6)
+ */
+const int ZX_PDF417_LATCH_TO_BYTE_PADDED = 901;
+
+/**
+ * mode latch to Numeric Compaction mode
+ */
+const int ZX_PDF417_LATCH_TO_NUMERIC = 902;
+
+/**
+ * mode shift to Byte Compaction mode
+ */
+const int ZX_PDF417_SHIFT_TO_BYTE = 913;
+
+/**
+ * mode latch to Byte Compaction mode (number of characters a multiple of 6)
+ */
+const int ZX_PDF417_LATCH_TO_BYTE = 924;
+
+/**
+ * identifier for a user defined Extended Channel Interpretation (ECI)
+ */
+const int ZX_PDF417_HIGH_LEVEL_ECI_USER_DEFINED = 925;
+
+/**
+ * identifier for a general purpose ECO format
+ */
+const int ZX_PDF417_HIGH_LEVEL_ECI_GENERAL_PURPOSE = 926;
+
+/**
+ * identifier for an ECI of a character set of code page
+ */
+const int ZX_PDF417_HIGH_LEVEL_ECI_CHARSET = 927;
+
+/**
+ * Raw code table for text compaction Mixed sub-mode
+ */
+const int8_t ZX_PDF417_TEXT_MIXED_RAW[] = {
+ 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 int8_t ZX_PDF417_TEXT_PUNCTUATION_RAW[] = {
+ 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 ZX_PDF417_MIXED_TABLE_LEN = 128;
+unichar ZX_PDF417_MIXED_TABLE[ZX_PDF417_MIXED_TABLE_LEN];
+
+const int ZX_PDF417_PUNCTUATION_LEN = 128;
+unichar ZX_PDF417_PUNCTUATION[ZX_PDF417_PUNCTUATION_LEN];
+
+const NSStringEncoding ZX_PDF417_DEFAULT_ENCODING = NSISOLatin1StringEncoding;
+
+@implementation ZXPDF417HighLevelEncoder
+
++ (void)initialize {
+ if ([self class] != [ZXPDF417HighLevelEncoder class]) return;
+
+ //Construct inverse lookups
+ for (int i = 0; i < ZX_PDF417_MIXED_TABLE_LEN; i++) {
+ ZX_PDF417_MIXED_TABLE[i] = 0xFF;
+ }
+ for (int8_t i = 0; i < sizeof(ZX_PDF417_TEXT_MIXED_RAW) / sizeof(int8_t); i++) {
+ int8_t b = ZX_PDF417_TEXT_MIXED_RAW[i];
+ if (b > 0) {
+ ZX_PDF417_MIXED_TABLE[b] = i;
+ }
+ }
+ for (int i = 0; i < ZX_PDF417_PUNCTUATION_LEN; i++) {
+ ZX_PDF417_PUNCTUATION[i] = 0xFF;
+ }
+ for (int8_t i = 0; i < sizeof(ZX_PDF417_TEXT_PUNCTUATION_RAW) / sizeof(int8_t); i++) {
+ int8_t b = ZX_PDF417_TEXT_PUNCTUATION_RAW[i];
+ if (b > 0) {
+ ZX_PDF417_PUNCTUATION[b] = i;
+ }
+ }
+}
+
++ (NSString *)encodeHighLevel:(NSString *)msg compaction:(ZXPDF417Compaction)compaction encoding:(NSStringEncoding)encoding error:(NSError **)error {
+ //the codewords 0..928 are encoded as Unicode characters
+ NSMutableString *sb = [NSMutableString stringWithCapacity:msg.length];
+
+ if (encoding == 0) {
+ encoding = ZX_PDF417_DEFAULT_ENCODING;
+ } else if (ZX_PDF417_DEFAULT_ENCODING != encoding) {
+ ZXCharacterSetECI *eci = [ZXCharacterSetECI characterSetECIByEncoding:encoding];
+ if (![self encodingECI:eci.value sb:sb error:error]) {
+ return nil;
+ }
+ }
+
+ NSUInteger len = msg.length;
+ int p = 0;
+ int textSubMode = ZX_PDF417_SUBMODE_ALPHA;
+
+ // User selected encoding mode
+ ZXByteArray *bytes = nil; //Fill later and only if needed
+ if (compaction == ZXPDF417CompactionText) {
+ [self encodeText:msg startpos:p count:(int)len buffer:sb initialSubmode:textSubMode];
+ } else if (compaction == ZXPDF417CompactionByte) {
+ bytes = [self bytesForMessage:msg encoding:encoding];
+ [self encodeBinary:bytes startpos:p count:(int)msg.length startmode:ZX_PDF417_BYTE_COMPACTION buffer:sb];
+ } else if (compaction == ZXPDF417CompactionNumeric) {
+ [sb appendFormat:@"%C", (unichar) ZX_PDF417_LATCH_TO_NUMERIC];
+ [self encodeNumeric:msg startpos:p count:(int)len buffer:sb];
+ } else {
+ int encodingMode = ZX_PDF417_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) ZX_PDF417_LATCH_TO_NUMERIC];
+ encodingMode = ZX_PDF417_NUMERIC_COMPACTION;
+ textSubMode = ZX_PDF417_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 != ZX_PDF417_TEXT_COMPACTION) {
+ [sb appendFormat:@"%C", (unichar) ZX_PDF417_LATCH_TO_TEXT];
+ encodingMode = ZX_PDF417_TEXT_COMPACTION;
+ textSubMode = ZX_PDF417_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 encoding:encoding];
+ }
+ 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 == ZX_PDF417_TEXT_COMPACTION) {
+ //Switch for one byte (instead of latch)
+ [self encodeBinary:bytes startpos:p count:1 startmode:ZX_PDF417_TEXT_COMPACTION buffer:sb];
+ } else {
+ //Mode latch performed by encodeBinary
+ [self encodeBinary:bytes startpos:p count:b startmode:encodingMode buffer:sb];
+ encodingMode = ZX_PDF417_BYTE_COMPACTION;
+ textSubMode = ZX_PDF417_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.
+ *
+ * @param msg the message
+ * @param startpos the start position within the message
+ * @param count the number of characters to encode
+ * @param sb receives the encoded codewords
+ * @param initialSubmode should normally be SUBMODE_ALPHA
+ * @return the text submode in which this method ends
+ */
++ (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 ZX_PDF417_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 = ZX_PDF417_SUBMODE_LOWER;
+ [tmp appendFormat:@"%C", (unichar) 27]; //ll
+ continue;
+ } else if ([self isMixed:ch]) {
+ submode = ZX_PDF417_SUBMODE_MIXED;
+ [tmp appendFormat:@"%C", (unichar) 28]; //ml
+ continue;
+ } else {
+ [tmp appendFormat:@"%C", (unichar) 29]; //ps
+ [tmp appendFormat:@"%C", ZX_PDF417_PUNCTUATION[ch]];
+ break;
+ }
+ }
+ break;
+ case ZX_PDF417_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 = ZX_PDF417_SUBMODE_MIXED;
+ [tmp appendFormat:@"%C", (unichar) 28]; //ml
+ continue;
+ } else {
+ [tmp appendFormat:@"%C", (unichar) 29]; //ps
+ [tmp appendFormat:@"%C", ZX_PDF417_PUNCTUATION[ch]];
+ break;
+ }
+ }
+ break;
+ case ZX_PDF417_SUBMODE_MIXED:
+ if ([self isMixed:ch]) {
+ [tmp appendFormat:@"%C", ZX_PDF417_MIXED_TABLE[ch]]; //as
+ } else {
+ if ([self isAlphaUpper:ch]) {
+ submode = ZX_PDF417_SUBMODE_ALPHA;
+ [tmp appendFormat:@"%C", (unichar) 28]; //al
+ continue;
+ } else if ([self isAlphaLower:ch]) {
+ submode = ZX_PDF417_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 = ZX_PDF417_SUBMODE_PUNCTUATION;
+ [tmp appendFormat:@"%C", (unichar) 25]; //pl
+ continue;
+ }
+ }
+ [tmp appendFormat:@"%C", (unichar) 29]; //ps
+ [tmp appendFormat:@"%C", ZX_PDF417_PUNCTUATION[ch]];
+ }
+ }
+ break;
+ default: //ZX_PDF417_SUBMODE_PUNCTUATION
+ if ([self isPunctuation:ch]) {
+ [tmp appendFormat:@"%C", ZX_PDF417_PUNCTUATION[ch]];
+ } else {
+ submode = ZX_PDF417_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.
+ *
+ * @param bytes the message converted to a byte array
+ * @param startpos the start position within the message
+ * @param count the number of bytes to encode
+ * @param startmode the mode from which this method starts
+ * @param sb receives the encoded codewords
+ */
++ (void)encodeBinary:(ZXByteArray *)bytes startpos:(int)startpos count:(int)count startmode:(int)startmode buffer:(NSMutableString *)sb {
+ if (count == 1 && startmode == ZX_PDF417_TEXT_COMPACTION) {
+ [sb appendFormat:@"%C", (unichar) ZX_PDF417_SHIFT_TO_BYTE];
+ } else {
+ BOOL sixpack = ((count % 6) == 0);
+ if (sixpack) {
+ [sb appendFormat:@"%C", (unichar) ZX_PDF417_LATCH_TO_BYTE];
+ } else {
+ [sb appendFormat:@"%C", (unichar) ZX_PDF417_LATCH_TO_BYTE_PADDED];
+ }
+ }
+
+ int idx = startpos;
+ // Encode sixpacks
+ if (count >= 6) {
+ 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.array[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)
+ for (int i = idx; i < startpos + count; i++) {
+ int ch = bytes.array[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];
+ NSDecimalNumber *num900 = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInt:900] decimalValue]];
+ NSDecimalNumber *num0 = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInt:0] decimalValue]];
+ while (idx < count) {
+ [tmp setString:@""];
+ int len = MIN(44, count - idx);
+ NSString *part = [@"1" stringByAppendingString:[msg substringWithRange:NSMakeRange(startpos + idx, len)]];
+ NSDecimalNumber *bigint = [NSDecimalNumber decimalNumberWithString:part];
+ do {
+ NSRoundingMode roundingMode = ((bigint.floatValue < 0) ^ (num900.floatValue < 0)) ? NSRoundUp : NSRoundDown;
+ NSDecimalNumber *quotient = [bigint decimalNumberByDividingBy:num900
+ withBehavior:[NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundingMode
+ scale:0
+ raiseOnExactness:NO
+ raiseOnOverflow:NO
+ raiseOnUnderflow:NO
+ raiseOnDivideByZero:NO]];
+
+ NSDecimalNumber *subtractAmount = [quotient decimalNumberByMultiplyingBy:num900];
+ NSDecimalNumber *remainder = [bigint decimalNumberBySubtracting:subtractAmount];
+
+ [tmp appendFormat:@"%C", (unichar)[remainder longValue]];
+ bigint = quotient;
+ } while (![bigint isEqualToNumber:num0]);
+
+ //Reverse temporary string
+ for (int i = (int)tmp.length - 1; i >= 0; i--) {
+ [sb appendFormat:@"%C", [tmp characterAtIndex:i]];
+ }
+ idx += len;
+ }
+}
+
++ (BOOL)isDigit:(unichar)ch {
+ return ch >= '0' && ch <= '9';
+}
+
++ (BOOL)isAlphaUpper:(unichar)ch {
+ return ch == ' ' || (ch >= 'A' && ch <= 'Z');
+}
+
++ (BOOL)isAlphaLower:(unichar)ch {
+ return ch == ' ' || (ch >= 'a' && ch <= 'z');
+}
+
++ (BOOL)isMixed:(unichar)ch {
+ return ZX_PDF417_MIXED_TABLE[ch] != 0xFF;
+}
+
++ (BOOL)isPunctuation:(unichar)ch {
+ return ZX_PDF417_PUNCTUATION[ch] != 0xFF;
+}
+
++ (BOOL)isText:(unichar)ch {
+ return ch == '\t' || ch == '\n' || ch == '\r' || (ch >= 32 && ch <= 126);
+}
+
+/**
+ * Determines the number of consecutive characters that are encodable using numeric compaction.
+ *
+ * @param msg the message
+ * @param startpos the start position within the message
+ * @return the requested character count
+ */
++ (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.
+ *
+ * @param msg the message
+ * @param bytes the message converted to a byte array
+ * @param startpos the start position within the message
+ * @return the requested character count
+ */
++ (int)determineConsecutiveBinaryCount:(NSString *)msg bytes:(ZXByteArray *)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;
+ }
+ ch = [msg characterAtIndex:idx];
+
+ //Check if character is encodable
+ //Sun returns a ASCII 63 (?) for a character that cannot be mapped. Let's hope all
+ //other VMs do the same
+ if (bytes.array[idx] == 63 && ch != '?') {
+ 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;
+}
+
++ (BOOL)encodingECI:(int)eci sb:(NSMutableString *)sb error:(NSError **)error {
+ if (eci >= 0 && eci < 900) {
+ [sb appendFormat:@"%C", (unichar) ZX_PDF417_HIGH_LEVEL_ECI_CHARSET];
+ [sb appendFormat:@"%C", (unichar) eci];
+ } else if (eci < 810900) {
+ [sb appendFormat:@"%C", (unichar) ZX_PDF417_HIGH_LEVEL_ECI_GENERAL_PURPOSE];
+ [sb appendFormat:@"%C", (unichar) (eci / 900 - 1)];
+ [sb appendFormat:@"%C", (unichar) (eci % 900)];
+ } else if (eci < 811800) {
+ [sb appendFormat:@"%C", (unichar) ZX_PDF417_HIGH_LEVEL_ECI_USER_DEFINED];
+ [sb appendFormat:@"%C", (unichar) (810900 - eci)];
+ } else {
+ NSDictionary *userInfo = @{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"ECI number not in valid range from 0..811799, but was %d", eci]};
+
+ if (error) *error = [[NSError alloc] initWithDomain:ZXErrorDomain code:ZXWriterError userInfo:userInfo];
+ return NO;
+ }
+ return YES;
+}
+
++ (ZXByteArray *)bytesForMessage:(NSString *)msg encoding:(NSStringEncoding)encoding {
+ NSData *data = [msg dataUsingEncoding:encoding];
+ int8_t *bytes = (int8_t *)[data bytes];
+ ZXByteArray *byteArray = [[ZXByteArray alloc] initWithLength:(unsigned int)[data length]];
+ memcpy(byteArray.array, bytes, [data length] * sizeof(int8_t));
+ return byteArray;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeReader.h b/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeReader.h
new file mode 100644
index 0000000..cc3c232
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeReader.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 "ZXReader.h"
+
+@class ZXQRCodeDecoder;
+
+/**
+ * This implementation can detect and decode QR Codes in an image.
+ */
+@interface ZXQRCodeReader : NSObject
+
+@property (nonatomic, strong, readonly) ZXQRCodeDecoder *decoder;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeReader.m b/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeReader.m
new file mode 100644
index 0000000..1bb8286
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeReader.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 "ZXBarcodeFormat.h"
+#import "ZXBinaryBitmap.h"
+#import "ZXBitMatrix.h"
+#import "ZXDecodeHints.h"
+#import "ZXDecoderResult.h"
+#import "ZXDetectorResult.h"
+#import "ZXErrors.h"
+#import "ZXIntArray.h"
+#import "ZXQRCodeDecoder.h"
+#import "ZXQRCodeDecoderMetaData.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.
+ *
+ * @return a String representing the content encoded by the QR code
+ * @throws NotFoundException if a QR code cannot be found
+ * @throws FormatException if a QR code cannot be decoded
+ * @throws ChecksumException if error correction fails
+ */
+- (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;
+ NSMutableArray *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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ decoderResult = [self.decoder decodeMatrix:bits hints:hints error:error];
+ if (!decoderResult) {
+ return nil;
+ }
+ points = [NSMutableArray array];
+ } 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] mutableCopy];
+ }
+
+ // If the code was mirrored: swap the bottom-left and the top-right points.
+ if ([decoderResult.other isKindOfClass:[ZXQRCodeDecoderMetaData class]]) {
+ [(ZXQRCodeDecoderMetaData *)decoderResult.other applyMirroredCorrection:points];
+ }
+
+ ZXResult *result = [ZXResult resultWithText:decoderResult.text
+ rawBytes:decoderResult.rawBytes
+ 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];
+ }
+ if ([decoderResult hasStructuredAppend]) {
+ [result putMetadata:kResultMetadataTypeStructuredAppendSequence
+ value:@(decoderResult.structuredAppendSequenceNumber)];
+ [result putMetadata:kResultMetadataTypeStructuredAppendParity
+ value:@(decoderResult.structuredAppendParity)];
+ }
+ 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 {
+ ZXIntArray *leftTopBlack = image.topLeftOnBit;
+ ZXIntArray *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.array[1];
+ int bottom = rightBottomBlack.array[1];
+ int left = leftTopBlack.array[0];
+ int right = rightBottomBlack.array[0];
+
+ // 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
+ // "right" is the farthest-right valid pixel location -- right+1 is not necessarily
+ // This is positive by how much the inner x loop below would be too large
+ int nudgedTooFarRight = left + (int) ((matrixWidth - 1) * moduleSize) - right;
+ if (nudgedTooFarRight > 0) {
+ if (nudgedTooFarRight > nudge) {
+ // Neither way fits; abort
+ return nil;
+ }
+ left -= nudgedTooFarRight;
+ }
+ // See logic above
+ int nudgedTooFarDown = top + (int) ((matrixHeight - 1) * moduleSize) - bottom;
+ if (nudgedTooFarDown > 0) {
+ if (nudgedTooFarDown > nudge) {
+ // Neither way fits; abort
+ return nil;
+ }
+ 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:(ZXIntArray *)leftTopBlack image:(ZXBitMatrix *)image {
+ int height = image.height;
+ int width = image.width;
+ int x = leftTopBlack.array[0];
+ int y = leftTopBlack.array[1];
+ BOOL inBlack = YES;
+ int transitions = 0;
+ while (x < width && y < height) {
+ if (inBlack != [image getX:x y:y]) {
+ if (++transitions == 5) {
+ break;
+ }
+ inBlack = !inBlack;
+ }
+ x++;
+ y++;
+ }
+ if (x == width || y == height) {
+ return -1;
+ }
+
+ return (x - leftTopBlack.array[0]) / 7.0f;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeWriter.h b/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeWriter.h
new file mode 100644
index 0000000..647d9db
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeWriter.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 "ZXWriter.h"
+
+/**
+ * This object renders a QR Code as a BitMatrix 2D array of greyscale values.
+ */
+@interface ZXQRCodeWriter : NSObject
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeWriter.m b/Pods/ZXingObjC/ZXingObjC/qrcode/ZXQRCodeWriter.m
new file mode 100644
index 0000000..575b3d3
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXQRCode.h"
+#import "ZXQRCodeEncoder.h"
+#import "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeWriter.h"
+
+const int ZX_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];
+ }
+
+ ZXQRCodeErrorCorrectionLevel *errorCorrectionLevel = [ZXQRCodeErrorCorrectionLevel errorCorrectionLevelL];
+ int quietZone = ZX_QUIET_ZONE_SIZE;
+ if (hints != nil) {
+ if (hints.errorCorrectionLevel) {
+ errorCorrectionLevel = hints.errorCorrectionLevel;
+ }
+ if (hints.margin) {
+ quietZone = [hints.margin intValue];
+ }
+ }
+
+ ZXQRCode *code = [ZXQRCodeEncoder 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 * 2);
+ int qrHeight = inputHeight + (quietZone * 2);
+ 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/Pods/ZXingObjC/ZXingObjC/qrcode/ZXingObjCQRCode.h b/Pods/ZXingObjC/ZXingObjC/qrcode/ZXingObjCQRCode.h
new file mode 100644
index 0000000..0672a3b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/ZXingObjCQRCode.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXingObjCCore.h"
+
+#ifndef _ZXINGOBJC_QRCODE_
+
+#define _ZXINGOBJC_QRCODE_
+
+#import "ZXQRCode.h"
+#import "ZXQRCodeAlignmentPattern.h"
+#import "ZXQRCodeDecoder.h"
+#import "ZXQRCodeDecoderMetaData.h"
+#import "ZXQRCodeDetector.h"
+#import "ZXQRCodeEncoder.h"
+#import "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeFinderPatternInfo.h"
+#import "ZXQRCodeFinderPattern.h"
+#import "ZXQRCodeFinderPatternFinder.h"
+#import "ZXQRCodeFinderPatternInfo.h"
+#import "ZXQRCodeMode.h"
+#import "ZXQRCodeReader.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXQRCodeWriter.h"
+
+#endif
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.h
new file mode 100644
index 0000000..ca89b37
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.h
@@ -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.
+ */
+
+@class ZXBitMatrix, ZXByteArray, ZXQRCodeFormatInformation, ZXQRCodeVersion;
+
+@interface ZXQRCodeBitMatrixParser : NSObject
+
+/**
+ * @param bitMatrix ZXBitMatrix to parse
+ * @return nil if dimension is not >= 21 and 1 mod 4
+ */
+- (id)initWithBitMatrix:(ZXBitMatrix *)bitMatrix error:(NSError **)error;
+
+/**
+ * Reads format information from one of its two locations within the QR Code.
+ *
+ * @return ZXFormatInformation encapsulating the QR Code's format info
+ * @return nil if both format information locations cannot be parsed as
+ * the valid encoding of format information
+ */
+- (ZXQRCodeFormatInformation *)readFormatInformationWithError:(NSError **)error;
+
+/**
+ * Reads version information from one of its two locations within the QR Code.
+ *
+ * @return ZXQRCodeVersion encapsulating the QR Code's version or nil
+ * if both version information locations cannot be parsed as
+ * the valid encoding of version information
+ */
+- (ZXQRCodeVersion *)readVersionWithError:(NSError **)error;
+
+/**
+ * Reads the bits in the ZXBitMatrix representing the finder pattern in the
+ * correct order in order to reconstruct the codewords bytes contained within the
+ * QR Code.
+ *
+ * @return bytes encoded within the QR Code or nil if the exact number of bytes expected is not read
+ */
+- (ZXByteArray *)readCodewordsWithError:(NSError **)error;
+
+/**
+ * Revert the mask removal done while reading the code words. The bit matrix should revert to its original state.
+ */
+- (void)remask;
+
+/**
+ * Prepare the parser for a mirrored operation.
+ * This flag has effect only on the readFormatInformation and the
+ * readVersion. Before proceeding with readCodewords the
+ * mirror method should be called.
+ *
+ * @param mirror Whether to read version and format information mirrored.
+ */
+- (void)setMirror:(BOOL)mirror;
+
+/** Mirror the bit matrix in order to attempt a second reading. */
+- (void)mirror;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.m
new file mode 100644
index 0000000..0fc1062
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeBitMatrixParser.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 "ZXBitMatrix.h"
+#import "ZXByteArray.h"
+#import "ZXErrors.h"
+#import "ZXQRCodeBitMatrixParser.h"
+#import "ZXQRCodeDataMask.h"
+#import "ZXQRCodeFormatInformation.h"
+#import "ZXQRCodeVersion.h"
+
+@interface ZXQRCodeBitMatrixParser ()
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *bitMatrix;
+@property (nonatomic, assign) BOOL shouldMirror;
+@property (nonatomic, strong) ZXQRCodeFormatInformation *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 = ZXFormatErrorInstance();
+ return nil;
+ }
+
+ if (self = [super init]) {
+ _bitMatrix = bitMatrix;
+ _parsedFormatInfo = nil;
+ _parsedVersion = nil;
+ }
+ return self;
+}
+
+- (ZXQRCodeFormatInformation *)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 = [ZXQRCodeFormatInformation decodeFormatInformation:formatInfoBits1 maskedFormatInfo2:formatInfoBits2];
+ if (self.parsedFormatInfo != nil) {
+ return self.parsedFormatInfo;
+ }
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+}
+
+- (ZXQRCodeVersion *)readVersionWithError:(NSError **)error {
+ if (self.parsedVersion != nil) {
+ return self.parsedVersion;
+ }
+ int dimension = self.bitMatrix.height;
+ int provisionalVersion = (dimension - 17) / 4;
+ 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 = ZXFormatErrorInstance();
+ return nil;
+}
+
+- (int)copyBit:(int)i j:(int)j versionBits:(int)versionBits {
+ BOOL bit = self.shouldMirror ? [self.bitMatrix getX:j y:i] : [self.bitMatrix getX:i y:j];
+ return bit ? (versionBits << 1) | 0x1 : versionBits << 1;
+}
+
+- (ZXByteArray *)readCodewordsWithError:(NSError **)error {
+ ZXQRCodeFormatInformation *formatInfo = [self readFormatInformationWithError:error];
+ if (!formatInfo) {
+ return nil;
+ }
+
+ ZXQRCodeVersion *version = [self readVersionWithError:error];
+ if (!version) {
+ return nil;
+ }
+
+ // Get the data mask for the format used in this QR Code. This will exclude
+ // some bits from reading as we wind through the bit matrix.
+ ZXQRCodeDataMask *dataMask = [ZXQRCodeDataMask forReference:[formatInfo dataMask]];
+ int dimension = self.bitMatrix.height;
+ [dataMask unmaskBitMatrix:self.bitMatrix dimension:dimension];
+
+ ZXBitMatrix *functionPattern = [version buildFunctionPattern];
+
+ BOOL readingUp = YES;
+ ZXByteArray *result = [[ZXByteArray alloc] initWithLength:version.totalCodewords];
+ int resultOffset = 0;
+ int currentByte = 0;
+ int bitsRead = 0;
+ // Read columns in pairs, from right to left
+ for (int j = dimension - 1; j > 0; j -= 2) {
+ if (j == 6) {
+ // Skip whole column with vertical alignment pattern;
+ // saves time and makes the other code proceed more cleanly
+ j--;
+ }
+ // Read alternatingly from bottom to top then top to bottom
+ for (int count = 0; count < dimension; count++) {
+ int i = readingUp ? dimension - 1 - count : count;
+ for (int col = 0; col < 2; col++) {
+ // Ignore bits covered by the function pattern
+ if (![functionPattern getX:j - col y:i]) {
+ // Read a bit
+ bitsRead++;
+ currentByte <<= 1;
+ if ([self.bitMatrix getX:j - col y:i]) {
+ currentByte |= 1;
+ }
+ // If we've made a whole byte, save it off
+ if (bitsRead == 8) {
+ result.array[resultOffset++] = (int8_t) currentByte;
+ bitsRead = 0;
+ currentByte = 0;
+ }
+ }
+ }
+ }
+ readingUp ^= YES; // readingUp = !readingUp; // switch directions
+ }
+ if (resultOffset != [version totalCodewords]) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ return result;
+}
+
+- (void)remask {
+ if (!self.parsedFormatInfo) {
+ return; // We have no format information, and have no data mask
+ }
+ ZXQRCodeDataMask *dataMask = [ZXQRCodeDataMask forReference:self.parsedFormatInfo.dataMask];
+ int dimension = self.bitMatrix.height;
+ [dataMask unmaskBitMatrix:self.bitMatrix dimension:dimension];
+}
+
+- (void)setMirror:(BOOL)mirror {
+ self.parsedVersion = nil;
+ self.parsedFormatInfo = nil;
+ self.shouldMirror = mirror;
+}
+
+- (void)mirror {
+ for (int x = 0; x < self.bitMatrix.width; x++) {
+ for (int y = x + 1; y < self.bitMatrix.height; y++) {
+ if ([self.bitMatrix getX:x y:y] != [self.bitMatrix getX:y y:x]) {
+ [self.bitMatrix flipX:y y:x];
+ [self.bitMatrix flipX:x y:y];
+ }
+ }
+ }
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.h
new file mode 100644
index 0000000..ca5a80c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.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.
+ */
+
+@class ZXByteArray, ZXQRCodeErrorCorrectionLevel, ZXQRCodeVersion;
+
+/**
+ * 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.
+ */
+@interface ZXQRCodeDataBlock : NSObject
+
+@property (nonatomic, strong, readonly) ZXByteArray *codewords;
+@property (nonatomic, assign, readonly) int numDataCodewords;
+
+- (id)initWithNumDataCodewords:(int)numDataCodewords codewords:(ZXByteArray *)codewords;
+
+/**
+ * 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.
+ *
+ * @param rawCodewords bytes as read directly from the QR Code
+ * @param version version of the QR Code
+ * @param ecLevel error-correction level of the QR Code
+ * @return DataBlocks containing original bytes, "de-interleaved" from representation in the
+ * QR Code
+ */
++ (NSArray *)dataBlocks:(ZXByteArray *)rawCodewords version:(ZXQRCodeVersion *)version ecLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.m
new file mode 100644
index 0000000..2b3a1d4
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataBlock.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 "ZXByteArray.h"
+#import "ZXQRCodeDataBlock.h"
+#import "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeVersion.h"
+
+@implementation ZXQRCodeDataBlock
+
+- (id)initWithNumDataCodewords:(int)numDataCodewords codewords:(ZXByteArray *)codewords {
+ if (self = [super init]) {
+ _numDataCodewords = numDataCodewords;
+ _codewords = codewords;
+ }
+
+ return self;
+}
+
++ (NSArray *)dataBlocks:(ZXByteArray *)rawCodewords version:(ZXQRCodeVersion *)version ecLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel {
+ if (rawCodewords.length != version.totalCodewords) {
+ [NSException raise:NSInvalidArgumentException format:@"Invalid codewords count"];
+ }
+
+ // Figure out the number and size of data blocks used by this version and
+ // error correction level
+ ZXQRCodeECBlocks *ecBlocks = [version ecBlocksForLevel:ecLevel];
+
+ // First count the total number of data blocks
+ int totalBlocks = 0;
+ NSArray *ecBlockArray = ecBlocks.ecBlocks;
+ for (ZXQRCodeECB *ecBlock in ecBlockArray) {
+ totalBlocks += ecBlock.count;
+ }
+
+ // Now establish DataBlocks of the appropriate size and number of data codewords
+ 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;
+ [result addObject:[[ZXQRCodeDataBlock alloc] initWithNumDataCodewords:numDataCodewords codewords:[[ZXByteArray alloc] initWithLength:numBlockCodewords]]];
+ }
+ }
+
+ // All blocks have the same amount of data, except that the last n
+ // (where n may be 0) have 1 more byte. Figure out where these start.
+ int shorterBlocksTotalCodewords = [(ZXQRCodeDataBlock *)result[0] codewords].length;
+ int longerBlocksStartAt = (int)[result count] - 1;
+ while (longerBlocksStartAt >= 0) {
+ int numCodewords = [(ZXQRCodeDataBlock *)result[longerBlocksStartAt] codewords].length;
+ if (numCodewords == shorterBlocksTotalCodewords) {
+ break;
+ }
+ longerBlocksStartAt--;
+ }
+ longerBlocksStartAt++;
+
+ int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.ecCodewordsPerBlock;
+ // The last elements of result may be 1 element longer;
+ // first fill out as many elements as all of them have
+ int rawCodewordsOffset = 0;
+ int numResultBlocks = (int)[result count];
+ for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {
+ for (int j = 0; j < numResultBlocks; j++) {
+ [(ZXQRCodeDataBlock *)result[j] codewords].array[i] = rawCodewords.array[rawCodewordsOffset++];
+ }
+ }
+ // Fill out the last data block in the longer ones
+ for (int j = longerBlocksStartAt; j < numResultBlocks; j++) {
+ [(ZXQRCodeDataBlock *)result[j] codewords].array[shorterBlocksNumDataCodewords] = rawCodewords.array[rawCodewordsOffset++];
+ }
+ // Now add in error correction blocks
+ int max = (int)[(ZXQRCodeDataBlock *)result[0] codewords].length;
+ for (int i = shorterBlocksNumDataCodewords; i < max; i++) {
+ for (int j = 0; j < numResultBlocks; j++) {
+ int iOffset = j < longerBlocksStartAt ? i : i + 1;
+ [(ZXQRCodeDataBlock *)result[j] codewords].array[iOffset] = rawCodewords.array[rawCodewordsOffset++];
+ }
+ }
+
+ return result;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.h
new file mode 100644
index 0000000..8ea4d1b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.h
@@ -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.
+ */
+
+@class ZXBitMatrix;
+
+/**
+ * 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.
+ */
+@interface ZXQRCodeDataMask : NSObject
+
+/**
+ * Implementations of this method reverse the data masking process applied to a QR Code and
+ * make its bits ready to read.
+ *
+ * @param bits representation of QR Code bits
+ * @param dimension dimension of QR Code, represented by bits, being unmasked
+ */
+- (void)unmaskBitMatrix:(ZXBitMatrix *)bits dimension:(int)dimension;
+
+- (BOOL)isMasked:(int)i j:(int)j;
+
+/**
+ * @param reference a value between 0 and 7 indicating one of the eight possible
+ * data mask patterns a QR Code may use
+ * @return DataMask encapsulating the data mask pattern
+ */
++ (ZXQRCodeDataMask *)forReference:(int)reference;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.m
new file mode 100644
index 0000000..108bd39
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDataMask.m
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXQRCodeDataMask.h"
+
+/**
+ * 000: mask bits for which (x + y) mod 2 == 0
+ */
+@interface ZXDataMask000 : ZXQRCodeDataMask
+
+@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 : ZXQRCodeDataMask
+
+@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 : ZXQRCodeDataMask
+
+@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 : ZXQRCodeDataMask
+
+@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 : ZXQRCodeDataMask
+
+@end
+
+@implementation ZXDataMask100
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ return (((i / 2) + (j /3)) & 0x01) == 0;
+}
+
+@end
+
+
+/**
+ * 101: mask bits for which xy mod 2 + xy mod 3 == 0
+ */
+@interface ZXDataMask101 : ZXQRCodeDataMask
+
+@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 : ZXQRCodeDataMask
+
+@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 : ZXQRCodeDataMask
+
+@end
+
+@implementation ZXDataMask111
+
+- (BOOL)isMasked:(int)i j:(int)j {
+ return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0;
+}
+
+@end
+
+
+@implementation ZXQRCodeDataMask
+
+/**
+ * See ISO 18004:2006 6.8.1
+ */
+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];
+}
+
+
++ (ZXQRCodeDataMask *)forReference:(int)reference {
+ if (!DATA_MASKS) {
+ 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/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.h
new file mode 100644
index 0000000..d43a639
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.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 ZXByteArray, ZXDecodeHints, ZXDecoderResult, ZXQRCodeErrorCorrectionLevel, ZXQRCodeVersion;
+
+/**
+ * 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
+ */
+@interface ZXQRCodeDecodedBitStreamParser : NSObject
+
++ (ZXDecoderResult *)decode:(ZXByteArray *)bytes
+ version:(ZXQRCodeVersion *)version
+ ecLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel
+ hints:(ZXDecodeHints *)hints
+ error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m
new file mode 100644
index 0000000..b725d47
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecodedBitStreamParser.m
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXByteArray.h"
+#import "ZXCharacterSetECI.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXQRCodeDecodedBitStreamParser.h"
+#import "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeMode.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXStringUtils.h"
+
+/**
+ * See ISO 18004:2006, 6.4.4 Table 5
+ */
+const unichar ZX_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',
+ ' ', '$', '%', '*', '+', '-', '.', '/', ':'
+};
+
+const int ZX_GB2312_SUBSET = 1;
+
+@implementation ZXQRCodeDecodedBitStreamParser
+
++ (ZXDecoderResult *)decode:(ZXByteArray *)bytes
+ version:(ZXQRCodeVersion *)version
+ ecLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel
+ hints:(ZXDecodeHints *)hints
+ error:(NSError **)error {
+ ZXBitSource *bits = [[ZXBitSource alloc] initWithBytes:bytes];
+ NSMutableString *result = [NSMutableString stringWithCapacity:50];
+ NSMutableArray *byteSegments = [NSMutableArray arrayWithCapacity:1];
+ int symbolSequence = -1;
+ int parityData = -1;
+
+ ZXCharacterSetECI *currentCharacterSetECI = nil;
+ ZXQRCodeMode *mode;
+ BOOL fc1InEffect = NO;
+
+ do {
+ // While still another segment to read...
+ if ([bits available] < 4) {
+ // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
+ mode = [ZXQRCodeMode terminatorMode];
+ } else {
+ mode = [ZXQRCodeMode forBits:[bits readBits:4]]; // mode is encoded by 4 bits
+ if (!mode) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ }
+ if (![mode isEqual:[ZXQRCodeMode terminatorMode]]) {
+ if ([mode isEqual:[ZXQRCodeMode fnc1FirstPositionMode]] || [mode isEqual:[ZXQRCodeMode fnc1SecondPositionMode]]) {
+ // We do little with FNC1 except alter the parsed result a bit according to the spec
+ fc1InEffect = YES;
+ } else if ([mode isEqual:[ZXQRCodeMode structuredAppendMode]]) {
+ if (bits.available < 16) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ // sequence number and parity is added later to the result metadata
+ // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
+ symbolSequence = [bits readBits:8];
+ parityData = [bits readBits:8];
+ } else if ([mode isEqual:[ZXQRCodeMode eciMode]]) {
+ // Count doesn't apply to ECI
+ int value = [self parseECIValue:bits];
+ currentCharacterSetECI = [ZXCharacterSetECI characterSetECIByValue:value];
+ if (currentCharacterSetECI == nil) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ } else {
+ // First handle Hanzi mode which does not start with character count
+ if ([mode isEqual:[ZXQRCodeMode hanziMode]]) {
+ //chinese mode contains a sub set indicator right after mode indicator
+ int subset = [bits readBits:4];
+ int countHanzi = [bits readBits:[mode characterCountBits:version]];
+ if (subset == ZX_GB2312_SUBSET) {
+ if (![self decodeHanziSegment:bits result:result count:countHanzi]) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ }
+ } else {
+ // "Normal" QR code modes:
+ // How many characters will follow, encoded in this mode?
+ int count = [bits readBits:[mode characterCountBits:version]];
+ if ([mode isEqual:[ZXQRCodeMode numericMode]]) {
+ if (![self decodeNumericSegment:bits result:result count:count]) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ } else if ([mode isEqual:[ZXQRCodeMode alphanumericMode]]) {
+ if (![self decodeAlphanumericSegment:bits result:result count:count fc1InEffect:fc1InEffect]) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ } else if ([mode isEqual:[ZXQRCodeMode byteMode]]) {
+ if (![self decodeByteSegment:bits result:result count:count currentCharacterSetECI:currentCharacterSetECI byteSegments:byteSegments hints:hints]) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ } else if ([mode isEqual:[ZXQRCodeMode kanjiMode]]) {
+ if (![self decodeKanjiSegment:bits result:result count:count]) {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ } else {
+ if (error) *error = ZXFormatErrorInstance();
+ return nil;
+ }
+ }
+ }
+ }
+ } while (![mode isEqual:[ZXQRCodeMode terminatorMode]]);
+
+ return [[ZXDecoderResult alloc] initWithRawBytes:bytes
+ text:result.description
+ byteSegments:byteSegments.count == 0 ? nil : byteSegments
+ ecLevel:ecLevel == nil ? nil : ecLevel.description
+ saSequence:symbolSequence
+ saParity:parityData];
+}
+
+
+/**
+ * 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;
+ }
+ int8_t bytes[2];
+ bytes[0] = (int8_t)((assembledTwoBytes >> 8) & 0xFF);
+ bytes[1] = (int8_t)(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;
+ }
+ int8_t bytes[2];
+ bytes[0] = (int8_t)(assembledTwoBytes >> 8);
+ bytes[1] = (int8_t)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 (8 * count > bits.available) {
+ return NO;
+ }
+
+ ZXByteArray *readBytes = [[ZXByteArray alloc] initWithLength:count];
+ for (int i = 0; i < count; i++) {
+ readBytes.array[i] = (int8_t)[bits readBits:8];
+ }
+ NSStringEncoding encoding;
+ if (currentCharacterSetECI == nil) {
+ encoding = [ZXStringUtils guessEncoding:readBytes hints:hints];
+ } else {
+ encoding = [currentCharacterSetECI encoding];
+ }
+
+ NSString *string = [[NSString alloc] initWithBytes:readBytes.array length:readBytes.length encoding:encoding];
+ if (string) {
+ [result appendString:string];
+ }
+
+ [byteSegments addObject:readBytes];
+ return YES;
+}
+
++ (unichar)toAlphaNumericChar:(int)value {
+ if (value >= 45) {
+ return -1;
+ }
+ return ZX_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/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h
new file mode 100644
index 0000000..5578557
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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, ZXDecodeHints, ZXDecodeHints, ZXDecoderResult;
+
+/**
+ * The main class which implements QR Code decoding -- as opposed to locating and extracting
+ * the QR Code from an image.
+ */
+@interface ZXQRCodeDecoder : NSObject
+
+/**
+ * Convenience method that can decode a QR Code represented as a 2D array of booleans.
+ * "true" is taken to mean a black module.
+ *
+ * @param image booleans representing white/black QR Code modules
+ * @return text and bytes encoded within the QR Code
+ * @return nil if the QR Code cannot be decoded
+ * @return nil if error correction fails
+ */
+- (ZXDecoderResult *)decode:(NSArray *)image error:(NSError **)error;
+
+/**
+ * Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black module.
+ *
+ * @param bits booleans representing white/black QR Code modules
+ * @return text and bytes encoded within the QR Code
+ * @return nil if the QR Code cannot be decoded
+ * @return nil if error correction fails
+ */
+- (ZXDecoderResult *)decode:(NSArray *)image hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits error:(NSError **)error;
+
+- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits hints:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.m
new file mode 100644
index 0000000..dc3de93
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoder.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 "ZXBitMatrix.h"
+#import "ZXBoolArray.h"
+#import "ZXByteArray.h"
+#import "ZXDecoderResult.h"
+#import "ZXErrors.h"
+#import "ZXGenericGF.h"
+#import "ZXIntArray.h"
+#import "ZXQRCodeBitMatrixParser.h"
+#import "ZXQRCodeDataBlock.h"
+#import "ZXQRCodeDecodedBitStreamParser.h"
+#import "ZXQRCodeDecoder.h"
+#import "ZXQRCodeDecoderMetaData.h"
+#import "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeFormatInformation.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXReedSolomonDecoder.h"
+
+@interface ZXQRCodeDecoder ()
+
+@property (nonatomic, strong, readonly) ZXReedSolomonDecoder *rsDecoder;
+
+@end
+
+@implementation ZXQRCodeDecoder
+
+- (id)init {
+ if (self = [super init]) {
+ _rsDecoder = [[ZXReedSolomonDecoder alloc] initWithField:[ZXGenericGF QrCodeField256]];
+ }
+
+ return self;
+}
+
+- (ZXDecoderResult *)decode:(NSArray *)image error:(NSError **)error {
+ return [self decode:image hints:nil error:error];
+}
+
+- (ZXDecoderResult *)decode:(NSArray *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ int dimension = (int)[image count];
+ ZXBitMatrix *bits = [[ZXBitMatrix alloc] initWithDimension:dimension];
+ for (int i = 0; i < dimension; i++) {
+ ZXBoolArray *b = image[i];
+ for (int j = 0; j < dimension; j++) {
+ if (b.array[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];
+}
+
+- (ZXDecoderResult *)decodeMatrix:(ZXBitMatrix *)bits hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXQRCodeBitMatrixParser *parser = [[ZXQRCodeBitMatrixParser alloc] initWithBitMatrix:bits error:error];
+ if (!parser) {
+ return nil;
+ }
+ ZXDecoderResult *result = [self decodeParser:parser hints:hints error:error];
+ if (result) {
+ return result;
+ }
+
+ // Revert the bit matrix
+ [parser remask];
+
+ // Will be attempting a mirrored reading of the version and format info.
+ [parser setMirror:YES];
+
+ // Preemptively read the version.
+ if (![parser readVersionWithError:error]) {
+ return nil;
+ }
+
+ /*
+ * Since we're here, this means we have successfully detected some kind
+ * of version and format information when mirrored. This is a good sign,
+ * that the QR code may be mirrored, and we should try once more with a
+ * mirrored content.
+ */
+ // Prepare for a mirrored reading.
+ [parser mirror];
+
+ result = [self decodeParser:parser hints:hints error:error];
+ if (!result) {
+ return nil;
+ }
+
+ // Success! Notify the caller that the code was mirrored.
+ result.other = [[ZXQRCodeDecoderMetaData alloc] initWithMirrored:YES];
+
+ return result;
+}
+
+- (ZXDecoderResult *)decodeParser:(ZXQRCodeBitMatrixParser *)parser hints:(ZXDecodeHints *)hints error:(NSError **)error {
+ ZXQRCodeVersion *version = [parser readVersionWithError:error];
+ if (!version) {
+ return nil;
+ }
+ ZXQRCodeFormatInformation *formatInfo = [parser readFormatInformationWithError:error];
+ if (!formatInfo) {
+ return nil;
+ }
+ ZXQRCodeErrorCorrectionLevel *ecLevel = formatInfo.errorCorrectionLevel;
+
+ ZXByteArray *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;
+ }
+
+ ZXByteArray *resultBytes = [[ZXByteArray alloc] initWithLength:totalBytes];
+ int resultOffset = 0;
+
+ for (ZXQRCodeDataBlock *dataBlock in dataBlocks) {
+ ZXByteArray *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.array[resultOffset++] = codewordBytes.array[i];
+ }
+ }
+
+ return [ZXQRCodeDecodedBitStreamParser decode:resultBytes 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.
+ *
+ * @param codewordBytes data and error correction codewords
+ * @param numDataCodewords number of codewords that are data bytes
+ * @return NO if error correction fails
+ */
+- (BOOL)correctErrors:(ZXByteArray *)codewordBytes numDataCodewords:(int)numDataCodewords error:(NSError **)error {
+ int numCodewords = (int)codewordBytes.length;
+ // First read into an array of ints
+ ZXIntArray *codewordsInts = [[ZXIntArray alloc] initWithLength:numCodewords];
+ for (int i = 0; i < numCodewords; i++) {
+ codewordsInts.array[i] = codewordBytes.array[i] & 0xFF;
+ }
+ int numECCodewords = (int)codewordBytes.length - numDataCodewords;
+ NSError *decodeError = nil;
+ if (![self.rsDecoder decode:codewordsInts twoS:numECCodewords error:&decodeError]) {
+ if (decodeError.code == ZXReedSolomonError) {
+ if (error) *error = ZXChecksumErrorInstance();
+ return NO;
+ } else {
+ if (error) *error = decodeError;
+ 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 < numDataCodewords; i++) {
+ codewordBytes.array[i] = (int8_t) codewordsInts.array[i];
+ }
+ return YES;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.h
new file mode 100644
index 0000000..f31f497
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Meta-data container for QR Code decoding. Instances of this class may be used to convey information back to the
+ * decoding caller. Callers are expected to process this.
+ */
+@interface ZXQRCodeDecoderMetaData : NSObject
+
+@property (nonatomic, assign, readonly) BOOL mirrored;
+
+- (id)initWithMirrored:(BOOL)mirrored;
+
+/**
+ * Apply the result points' order correction due to mirroring.
+ *
+ * @param points Array of points to apply mirror correction to.
+ */
+- (void)applyMirroredCorrection:(NSMutableArray *)points;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.m
new file mode 100644
index 0000000..653b760
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeDecoderMetaData.m
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXQRCodeDecoderMetaData.h"
+#import "ZXResultPoint.h"
+
+@implementation ZXQRCodeDecoderMetaData
+
+- (id)initWithMirrored:(BOOL)mirrored {
+ if (self = [super init]) {
+ _mirrored = mirrored;
+ }
+
+ return self;
+}
+
+- (void)applyMirroredCorrection:(NSMutableArray *)points {
+ if (!self.mirrored || [points count] < 3) {
+ return;
+ }
+ ZXResultPoint *bottomLeft = points[0];
+ points[0] = points[2];
+ points[2] = bottomLeft;
+ // No need to 'fix' top-left and alignment pattern.
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.h
new file mode 100644
index 0000000..72230a8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.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.
+ */
+
+/**
+ * See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels
+ * defined by the QR code standard.
+ */
+@interface ZXQRCodeErrorCorrectionLevel : 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;
+
+/**
+ * @param bits int containing the two bits encoding a QR Code's error correction level
+ * @return ErrorCorrectionLevel representing the encoded error correction level
+ */
++ (ZXQRCodeErrorCorrectionLevel *)forBits:(int)bits;
+
+/**
+ * L = ~7% correction
+ */
++ (ZXQRCodeErrorCorrectionLevel *)errorCorrectionLevelL;
+
+/**
+ * M = ~15% correction
+ */
++ (ZXQRCodeErrorCorrectionLevel *)errorCorrectionLevelM;
+
+/**
+ * Q = ~25% correction
+ */
++ (ZXQRCodeErrorCorrectionLevel *)errorCorrectionLevelQ;
+
+/**
+ * H = ~30% correction
+ */
++ (ZXQRCodeErrorCorrectionLevel *)errorCorrectionLevelH;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.m
new file mode 100644
index 0000000..adc913b
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeErrorCorrectionLevel.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 "ZXQRCodeErrorCorrectionLevel.h"
+
+@implementation ZXQRCodeErrorCorrectionLevel
+
+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;
+}
+
++ (ZXQRCodeErrorCorrectionLevel *)forBits:(int)bits {
+ if (!FOR_BITS) {
+ FOR_BITS = @[[ZXQRCodeErrorCorrectionLevel errorCorrectionLevelM], [ZXQRCodeErrorCorrectionLevel errorCorrectionLevelL],
+ [ZXQRCodeErrorCorrectionLevel errorCorrectionLevelH], [ZXQRCodeErrorCorrectionLevel errorCorrectionLevelQ]];
+ }
+
+ if (bits < 0 || bits >= [FOR_BITS count]) {
+ @throw [NSException exceptionWithName:NSInvalidArgumentException
+ reason:@"Invalid bits"
+ userInfo:nil];
+ }
+ return FOR_BITS[bits];
+}
+
++ (ZXQRCodeErrorCorrectionLevel *)errorCorrectionLevelL {
+ static ZXQRCodeErrorCorrectionLevel *thisLevel = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisLevel = [[ZXQRCodeErrorCorrectionLevel alloc] initWithOrdinal:0 bits:0x01 name:@"L"];
+ });
+ return thisLevel;
+}
+
++ (ZXQRCodeErrorCorrectionLevel *)errorCorrectionLevelM {
+ static ZXQRCodeErrorCorrectionLevel *thisLevel = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisLevel = [[ZXQRCodeErrorCorrectionLevel alloc] initWithOrdinal:1 bits:0x00 name:@"M"];
+ });
+ return thisLevel;
+}
+
++ (ZXQRCodeErrorCorrectionLevel *)errorCorrectionLevelQ {
+ static ZXQRCodeErrorCorrectionLevel *thisLevel = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisLevel = [[ZXQRCodeErrorCorrectionLevel alloc] initWithOrdinal:2 bits:0x03 name:@"Q"];
+ });
+ return thisLevel;
+}
+
++ (ZXQRCodeErrorCorrectionLevel *)errorCorrectionLevelH {
+ static ZXQRCodeErrorCorrectionLevel *thisLevel = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisLevel = [[ZXQRCodeErrorCorrectionLevel alloc] initWithOrdinal:3 bits:0x02 name:@"H"];
+ });
+ return thisLevel;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeFormatInformation.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeFormatInformation.h
new file mode 100644
index 0000000..dc7f0ef
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeFormatInformation.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 ZXQRCodeErrorCorrectionLevel;
+
+/**
+ * Encapsulates a QR Code's format information, including the data mask used and
+ * error correction level.
+ */
+@interface ZXQRCodeFormatInformation : NSObject
+
+@property (nonatomic, strong, readonly) ZXQRCodeErrorCorrectionLevel *errorCorrectionLevel;
+@property (nonatomic, assign, readonly) int8_t dataMask;
+
++ (int)numBitsDiffering:(int)a b:(int)b;
+
+/**
+ * @param maskedFormatInfo1 format info indicator, with mask still applied
+ * @param maskedFormatInfo2 second copy of same info; both are checked at the same time
+ * to establish best match
+ * @return information about the format it specifies, or {@code null}
+ * if doesn't seem to match any known pattern
+ */
++ (ZXQRCodeFormatInformation *)decodeFormatInformation:(int)maskedFormatInfo1 maskedFormatInfo2:(int)maskedFormatInfo2;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeFormatInformation.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeFormatInformation.m
new file mode 100644
index 0000000..8fed469
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeFormatInformation.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 "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeFormatInformation.h"
+
+const int ZX_FORMAT_INFO_MASK_QR = 0x5412;
+
+/**
+ * See ISO 18004:2006, Annex C, Table C.1
+ */
+const int ZX_FORMAT_INFO_DECODE_LOOKUP_LEN = 32;
+const int ZX_FORMAT_INFO_DECODE_LOOKUP[ZX_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
+ */
+const int ZX_BITS_SET_IN_HALF_BYTE[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+
+@implementation ZXQRCodeFormatInformation
+
+- (id)initWithFormatInfo:(int)formatInfo {
+ if (self = [super init]) {
+ _errorCorrectionLevel = [ZXQRCodeErrorCorrectionLevel forBits:(formatInfo >> 3) & 0x03];
+ _dataMask = (int8_t)(formatInfo & 0x07);
+ }
+
+ return self;
+}
+
++ (int)numBitsDiffering:(int)a b:(int)b {
+ a ^= b;
+ return ZX_BITS_SET_IN_HALF_BYTE[a & 0x0F] +
+ ZX_BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 4 & 0x0F)] +
+ ZX_BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 8 & 0x0F)] +
+ ZX_BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 12 & 0x0F)] +
+ ZX_BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 16 & 0x0F)] +
+ ZX_BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 20 & 0x0F)] +
+ ZX_BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 24 & 0x0F)] +
+ ZX_BITS_SET_IN_HALF_BYTE[((int)((unsigned int)a) >> 28 & 0x0F)];
+}
+
++ (ZXQRCodeFormatInformation *)decodeFormatInformation:(int)maskedFormatInfo1 maskedFormatInfo2:(int)maskedFormatInfo2 {
+ ZXQRCodeFormatInformation *formatInfo = [self doDecodeFormatInformation:maskedFormatInfo1 maskedFormatInfo2:maskedFormatInfo2];
+ if (formatInfo != nil) {
+ return formatInfo;
+ }
+ return [self doDecodeFormatInformation:maskedFormatInfo1 ^ ZX_FORMAT_INFO_MASK_QR maskedFormatInfo2:maskedFormatInfo2 ^ ZX_FORMAT_INFO_MASK_QR];
+}
+
++ (ZXQRCodeFormatInformation *)doDecodeFormatInformation:(int)maskedFormatInfo1 maskedFormatInfo2:(int)maskedFormatInfo2 {
+ int bestDifference = INT_MAX;
+ int bestFormatInfo = 0;
+
+ for (int i = 0; i < ZX_FORMAT_INFO_DECODE_LOOKUP_LEN; i++) {
+ int targetInfo = ZX_FORMAT_INFO_DECODE_LOOKUP[i][0];
+ if (targetInfo == maskedFormatInfo1 || targetInfo == maskedFormatInfo2) {
+ return [[ZXQRCodeFormatInformation alloc] initWithFormatInfo:ZX_FORMAT_INFO_DECODE_LOOKUP[i][1]];
+ }
+ int bitsDifference = [self numBitsDiffering:maskedFormatInfo1 b:targetInfo];
+ if (bitsDifference < bestDifference) {
+ bestFormatInfo = ZX_FORMAT_INFO_DECODE_LOOKUP[i][1];
+ bestDifference = bitsDifference;
+ }
+ if (maskedFormatInfo1 != maskedFormatInfo2) {
+ bitsDifference = [self numBitsDiffering:maskedFormatInfo2 b:targetInfo];
+ if (bitsDifference < bestDifference) {
+ bestFormatInfo = ZX_FORMAT_INFO_DECODE_LOOKUP[i][1];
+ bestDifference = bitsDifference;
+ }
+ }
+ }
+
+ if (bestDifference <= 3) {
+ return [[ZXQRCodeFormatInformation alloc] initWithFormatInfo:bestFormatInfo];
+ }
+ return nil;
+}
+
+- (NSUInteger)hash {
+ return (self.errorCorrectionLevel.ordinal << 3) | (int)self.dataMask;
+}
+
+- (BOOL)isEqual:(id)o {
+ if (![o isKindOfClass:[ZXQRCodeFormatInformation class]]) {
+ return NO;
+ }
+ ZXQRCodeFormatInformation *other = (ZXQRCodeFormatInformation *)o;
+ return self.errorCorrectionLevel == other.errorCorrectionLevel && self.dataMask == other.dataMask;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeMode.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeMode.h
new file mode 100644
index 0000000..6c41791
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeMode.h
@@ -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.
+ */
+
+@class ZXQRCodeVersion;
+
+/**
+ * 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.
+ */
+@interface ZXQRCodeMode : NSObject
+
+@property (nonatomic, assign, readonly) int bits;
+@property (nonatomic, copy, readonly) NSString *name;
+
+- (id)initWithCharacterCountBitsForVersions:(NSArray *)characterCountBitsForVersions bits:(int)bits name:(NSString *)name;
+
+/**
+ * @param bits four bits encoding a QR Code data mode
+ * @return Mode encoded by these bits or nil if bits do not correspond to a known mode
+ */
++ (ZXQRCodeMode *)forBits:(int)bits;
+
+- (int)characterCountBits:(ZXQRCodeVersion *)version;
+
+/**
+ * @param version version in question
+ * @return number of bits used, in this QR Code symbol {@link Version}, to encode the
+ * count of characters that will follow encoded in this Mode
+ */
++ (ZXQRCodeMode *)terminatorMode; // Not really a mode...
++ (ZXQRCodeMode *)numericMode;
++ (ZXQRCodeMode *)alphanumericMode;
++ (ZXQRCodeMode *)structuredAppendMode; // Not supported
++ (ZXQRCodeMode *)byteMode;
++ (ZXQRCodeMode *)eciMode; // character counts don't apply
++ (ZXQRCodeMode *)kanjiMode;
++ (ZXQRCodeMode *)fnc1FirstPositionMode;
++ (ZXQRCodeMode *)fnc1SecondPositionMode;
+
+/** See GBT 18284-2000; "Hanzi" is a transliteration of this mode name. */
++ (ZXQRCodeMode *)hanziMode;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeMode.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeMode.m
new file mode 100644
index 0000000..e94cd1d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeMode.m
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXQRCodeMode.h"
+#import "ZXQRCodeVersion.h"
+
+@interface ZXQRCodeMode ()
+
+@property (nonatomic, strong, readonly) NSArray *characterCountBitsForVersions;
+
+@end
+
+@implementation ZXQRCodeMode
+
+- (id)initWithCharacterCountBitsForVersions:(NSArray *)characterCountBitsForVersions bits:(int)bits name:(NSString *)name {
+ if (self = [super init]) {
+ _characterCountBitsForVersions = characterCountBitsForVersions;
+ _bits = bits;
+ _name = name;
+ }
+
+ return self;
+}
+
++ (ZXQRCodeMode *)forBits:(int)bits {
+ switch (bits) {
+ case 0x0:
+ return [ZXQRCodeMode terminatorMode];
+ case 0x1:
+ return [ZXQRCodeMode numericMode];
+ case 0x2:
+ return [ZXQRCodeMode alphanumericMode];
+ case 0x3:
+ return [ZXQRCodeMode structuredAppendMode];
+ case 0x4:
+ return [ZXQRCodeMode byteMode];
+ case 0x5:
+ return [ZXQRCodeMode fnc1FirstPositionMode];
+ case 0x7:
+ return [ZXQRCodeMode eciMode];
+ case 0x8:
+ return [ZXQRCodeMode kanjiMode];
+ case 0x9:
+ return [ZXQRCodeMode fnc1SecondPositionMode];
+ case 0xD:
+ return [ZXQRCodeMode 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;
+}
+
++ (ZXQRCodeMode *)terminatorMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x00 name:@"TERMINATOR"];
+ });
+ return thisMode;
+}
+
++ (ZXQRCodeMode *)numericMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@10, @12, @14] bits:0x01 name:@"NUMERIC"];
+ });
+ return thisMode;
+}
+
++ (ZXQRCodeMode *)alphanumericMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@9, @11, @13] bits:0x02 name:@"ALPHANUMERIC"];
+ });
+ return thisMode;
+}
+
++ (ZXQRCodeMode *)structuredAppendMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x03 name:@"STRUCTURED_APPEND"];
+ });
+ return thisMode;
+}
+
++ (ZXQRCodeMode *)byteMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@8, @16, @16] bits:0x04 name:@"BYTE"];
+ });
+ return thisMode;
+}
+
++ (ZXQRCodeMode *)eciMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x07 name:@"ECI"];
+ });
+ return thisMode;
+}
+
++ (ZXQRCodeMode *)kanjiMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@8, @10, @12] bits:0x08 name:@"KANJI"];
+ });
+ return thisMode;
+}
+
++ (ZXQRCodeMode *)fnc1FirstPositionMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x05 name:@"FNC1_FIRST_POSITION"];
+ });
+ return thisMode;
+}
+
++ (ZXQRCodeMode *)fnc1SecondPositionMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@0, @0, @0] bits:0x09 name:@"FNC1_SECOND_POSITION"];
+ });
+ return thisMode;
+}
+
++ (ZXQRCodeMode *)hanziMode {
+ static ZXQRCodeMode *thisMode = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ thisMode = [[ZXQRCodeMode alloc] initWithCharacterCountBitsForVersions:@[@8, @10, @12] bits:0x0D name:@"HANZI"];
+ });
+ return thisMode;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.h b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.h
new file mode 100644
index 0000000..b1d5061
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.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.
+ */
+
+@class ZXBitMatrix, ZXIntArray, ZXQRCodeECB, ZXQRCodeECBlocks, ZXQRCodeErrorCorrectionLevel;
+
+/**
+ * See ISO 18004:2006 Annex D
+ */
+@interface ZXQRCodeVersion : NSObject
+
+@property (nonatomic, assign, readonly) int versionNumber;
+@property (nonatomic, strong, readonly) ZXIntArray *alignmentPatternCenters;
+@property (nonatomic, strong, readonly) NSArray *ecBlocks;
+@property (nonatomic, assign, readonly) int totalCodewords;
+@property (nonatomic, assign, readonly) int dimensionForVersion;
+
+- (ZXQRCodeECBlocks *)ecBlocksForLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel;
++ (ZXQRCodeVersion *)provisionalVersionForDimension:(int)dimension;
++ (ZXQRCodeVersion *)versionForNumber:(int)versionNumber;
++ (ZXQRCodeVersion *)decodeVersionInformation:(int)versionBits;
+- (ZXBitMatrix *)buildFunctionPattern;
+
+@end
+
+/**
+ * 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 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
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.m b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.m
new file mode 100644
index 0000000..a012739
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/decoder/ZXQRCodeVersion.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 "ZXBitMatrix.h"
+#import "ZXIntArray.h"
+#import "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeFormatInformation.h"
+#import "ZXQRCodeVersion.h"
+
+/**
+ * See ISO 18004:2006 Annex D.
+ * Element i represents the raw version bits that specify version i + 7
+ */
+const int ZX_VERSION_DECODE_INFO[] = {
+ 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 *ZX_VERSIONS = nil;
+
+@implementation ZXQRCodeVersion
+
+- (id)initWithVersionNumber:(int)versionNumber alignmentPatternCenters:(ZXIntArray *)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)versionNumber alignmentPatternCenters:(ZXIntArray *)alignmentPatternCenters ecBlocks1:(ZXQRCodeECBlocks *)ecBlocks1 ecBlocks2:(ZXQRCodeECBlocks *)ecBlocks2 ecBlocks3:(ZXQRCodeECBlocks *)ecBlocks3 ecBlocks4:(ZXQRCodeECBlocks *)ecBlocks4 {
+ return [[ZXQRCodeVersion alloc] initWithVersionNumber:versionNumber alignmentPatternCenters:alignmentPatternCenters ecBlocks1:ecBlocks1 ecBlocks2:ecBlocks2 ecBlocks3:ecBlocks3 ecBlocks4:ecBlocks4];
+}
+
+- (int)dimensionForVersion {
+ return 17 + 4 * self.versionNumber;
+}
+
+- (ZXQRCodeECBlocks *)ecBlocksForLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel {
+ return self.ecBlocks[[ecLevel ordinal]];
+}
+
+/**
+ * Deduces version information purely from QR Code dimensions.
+ *
+ * @param dimension dimension in modules
+ * @return Version for a QR Code of that dimension or nil if dimension is not 1 mod 4
+ */
++ (ZXQRCodeVersion *)provisionalVersionForDimension:(int)dimension {
+ if (dimension % 4 != 1) {
+ return nil;
+ }
+
+ return [self versionForNumber:(dimension - 17) / 4];
+}
+
++ (ZXQRCodeVersion *)versionForNumber:(int)versionNumber {
+ if (versionNumber < 1 || versionNumber > 40) {
+ return nil;
+ }
+ return ZX_VERSIONS[versionNumber - 1];
+}
+
++ (ZXQRCodeVersion *)decodeVersionInformation:(int)versionBits {
+ int bestDifference = INT_MAX;
+ int bestVersion = 0;
+
+ for (int i = 0; i < sizeof(ZX_VERSION_DECODE_INFO) / sizeof(int); i++) {
+ int targetVersion = ZX_VERSION_DECODE_INFO[i];
+ if (targetVersion == versionBits) {
+ return [self versionForNumber:i + 7];
+ }
+ int bitsDifference = [ZXQRCodeFormatInformation 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 = self.alignmentPatternCenters.length;
+
+ for (int x = 0; x < max; x++) {
+ int i = self.alignmentPatternCenters.array[x] - 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.array[y] - 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 {
+ if ([self class] != [ZXQRCodeVersion class]) return;
+
+ ZX_VERSIONS = @[[ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:1
+ alignmentPatternCenters:[[ZXIntArray alloc] initWithLength:0]
+ 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:[[ZXIntArray alloc] initWithInts:6, 18, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 22, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 26, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 34, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 22, 38, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 24, 42, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 26, 46, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 28, 50, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 54, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 32, 58, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 34, 62, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 26, 46, 66, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 26, 48, 70, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 26, 50, 74, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 50, 78, -1]
+ ecBlocks1:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:1 dataCodewords:107] ecBlocks2:[ZXQRCodeECB ecbWithCount:5 dataCodewords:108]]
+ ecBlocks2:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:10 dataCodewords:46] ecBlocks2:[ZXQRCodeECB ecbWithCount:1 dataCodewords:47]]
+ ecBlocks3:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:1 dataCodewords:22] ecBlocks2:[ZXQRCodeECB ecbWithCount:15 dataCodewords:23]]
+ ecBlocks4:[ZXQRCodeECBlocks ecBlocksWithEcCodewordsPerBlock:28 ecBlocks1:[ZXQRCodeECB ecbWithCount:2 dataCodewords:14] ecBlocks2:[ZXQRCodeECB ecbWithCount:17 dataCodewords:15]]],
+
+ [ZXQRCodeVersion ZXQRCodeVersionWithVersionNumber:18
+ alignmentPatternCenters:[[ZXIntArray alloc] initWithInts:6, 30, 56, 82, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 58, 86, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 34, 62, 90, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 28, 50, 72, 94, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 26, 50, 72, 98, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 54, 78, 102, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 28, 54, 80, 106, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 32, 58, 84, 110, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 58, 86, 114, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 34, 62, 90, 118, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 26, 50, 74, 98, 122, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 54, 78, 102, 126, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 26, 52, 78, 104, 130, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 56, 82, 108, 134, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 34, 60, 86, 112, 138, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 58, 86, 114, 142, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 34, 62, 90, 118, 146, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 54, 78, 102, 126, 150, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 24, 50, 76, 102, 128, 154, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 28, 54, 80, 106, 132, 158, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 32, 58, 84, 110, 136, 162, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 26, 54, 82, 110, 138, 166, -1]
+ 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:[[ZXIntArray alloc] initWithInts:6, 30, 58, 86, 114, 142, 170, -1]
+ 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
+
+@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
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPattern.h b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPattern.h
new file mode 100644
index 0000000..55f400c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPattern.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 "ZXResultPoint.h"
+
+/**
+ * Encapsulates an alignment pattern, which are the smaller square patterns found in
+ * all but the simplest QR Codes.
+ */
+@interface ZXQRCodeAlignmentPattern : ZXResultPoint
+
+- (id)initWithPosX:(float)posX posY:(float)posY estimatedModuleSize:(float)estimatedModuleSize;
+
+/**
+ * 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;
+
+/**
+ * Combines this object's current estimate of a finder pattern position and module size
+ * with a new estimate. It returns a new {@code FinderPattern} containing an average of the two.
+ */
+- (ZXQRCodeAlignmentPattern *)combineEstimateI:(float)i j:(float)j newModuleSize:(float)newModuleSize;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPattern.m b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPattern.m
new file mode 100644
index 0000000..5c9a9ad
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPattern.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 "ZXQRCodeAlignmentPattern.h"
+
+@interface ZXQRCodeAlignmentPattern ()
+
+@property (nonatomic, assign, readonly) float estimatedModuleSize;
+
+@end
+
+@implementation ZXQRCodeAlignmentPattern
+
+- (id)initWithPosX:(float)posX posY:(float)posY estimatedModuleSize:(float)estimatedModuleSize {
+ if (self = [super initWithX:posX y:posY]) {
+ _estimatedModuleSize = estimatedModuleSize;
+ }
+
+ return self;
+}
+
+- (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;
+}
+
+- (ZXQRCodeAlignmentPattern *)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 [[ZXQRCodeAlignmentPattern alloc] initWithPosX:combinedX posY:combinedY estimatedModuleSize:combinedModuleSize];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.h b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.h
new file mode 100644
index 0000000..6c0af36
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.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.
+ */
+
+@protocol ZXResultPointCallback;
+@class ZXBitMatrix, ZXQRCodeAlignmentPattern;
+
+/**
+ * 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.
+ */
+@interface ZXQRCodeAlignmentPatternFinder : NSObject
+
+/**
+ * Creates a finder that will look in a portion of the whole image.
+ *
+ * @param image image to search
+ * @param startX left column from which to start searching
+ * @param startY top row from which to start searching
+ * @param width width of region to search
+ * @param height height of region to search
+ * @param moduleSize estimated module size so far
+ */
+
+- (id)initWithImage:(ZXBitMatrix *)image startX:(int)startX startY:(int)startY width:(int)width height:(int)height moduleSize:(float)moduleSize resultPointCallback:(id)resultPointCallback;
+
+/**
+ * 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.
+ *
+ * @return ZXAlignmentPattern if found or nil if not found
+ */
+- (ZXQRCodeAlignmentPattern *)findWithError:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.m b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.m
new file mode 100644
index 0000000..e9cde0c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeAlignmentPatternFinder.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 "ZXErrors.h"
+#import "ZXIntArray.h"
+#import "ZXQRCodeAlignmentPattern.h"
+#import "ZXQRCodeAlignmentPatternFinder.h"
+#import "ZXResultPointCallback.h"
+
+@interface ZXQRCodeAlignmentPatternFinder ()
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *image;
+@property (nonatomic, strong, readonly) NSMutableArray *possibleCenters;
+@property (nonatomic, assign, readonly) int startX;
+@property (nonatomic, assign, readonly) int startY;
+@property (nonatomic, assign, readonly) int width;
+@property (nonatomic, assign, readonly) int height;
+@property (nonatomic, assign, readonly) float moduleSize;
+@property (nonatomic, strong, readonly) ZXIntArray *crossCheckStateCount;
+@property (nonatomic, weak, readonly) id resultPointCallback;
+
+@end
+
+@implementation ZXQRCodeAlignmentPatternFinder
+
+- (id)initWithImage:(ZXBitMatrix *)image startX:(int)startX startY:(int)startY width:(int)width height:(int)height moduleSize:(float)moduleSize resultPointCallback:(id)resultPointCallback {
+ if (self = [super init]) {
+ _image = image;
+ _possibleCenters = [NSMutableArray arrayWithCapacity:5];
+ _startX = startX;
+ _startY = startY;
+ _width = width;
+ _height = height;
+ _moduleSize = moduleSize;
+ _crossCheckStateCount = [[ZXIntArray alloc] initWithLength:3];
+ _resultPointCallback = resultPointCallback;
+ }
+
+ return self;
+}
+
+- (ZXQRCodeAlignmentPattern *)findWithError:(NSError **)error {
+ int maxJ = self.startX + self.width;
+ int middleI = self.startY + (self.height / 2);
+ int stateCount[3];
+
+ for (int iGen = 0; iGen < self.height; iGen++) {
+ int i = middleI + ((iGen & 0x01) == 0 ? (iGen + 1) / 2 : -((iGen + 1) / 2));
+ 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]) {
+ ZXQRCodeAlignmentPattern *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]) {
+ ZXQRCodeAlignmentPattern *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 = ZXNotFoundErrorInstance();
+ 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;
+}
+
+/**
+ * @param stateCount count of black/white/black pixels just read
+ * @return true iff the proportions of the counts is close enough to the 1/1/1 ratios
+ * used by alignment patterns to be considered a match
+ */
+- (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.
+ *
+ * @param startI row where an alignment pattern was detected
+ * @param centerJ center of the section that appears to cross an alignment pattern
+ * @param maxCount maximum reasonable number of modules that should be
+ * observed in any reading state, based on the results of the horizontal scan
+ * @return vertical center of alignment pattern, or {@link Float#NaN} if not found
+ */
+- (float)crossCheckVertical:(int)startI centerJ:(int)centerJ maxCount:(int)maxCount originalStateCountTotal:(int)originalStateCountTotal {
+ int maxI = self.image.height;
+ [self.crossCheckStateCount clear];
+ int32_t *stateCount = self.crossCheckStateCount.array;
+
+ 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.
+ *
+ * @param stateCount reading state module counts from horizontal scan
+ * @param i row where alignment pattern may be found
+ * @param j end of possible alignment pattern in row
+ * @return ZXAlignmentPattern if we have found the same pattern twice, or null if not
+ */
+- (ZXQRCodeAlignmentPattern *)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++) {
+ ZXQRCodeAlignmentPattern *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 = [[ZXQRCodeAlignmentPattern 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/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h
new file mode 100644
index 0000000..dcad42d
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeDetector.h
@@ -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.
+ */
+
+@class ZXBitMatrix, ZXDecodeHints, ZXDetectorResult, ZXPerspectiveTransform, ZXQRCodeAlignmentPattern, ZXQRCodeFinderPatternInfo, ZXResultPoint;
+@protocol ZXResultPointCallback;
+
+/**
+ * Encapsulates logic that can detect a QR Code in an image, even if the QR Code
+ * is rotated or skewed, or partially obscured.
+ */
+@interface ZXQRCodeDetector : NSObject
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *image;
+@property (nonatomic, weak, readonly) id resultPointCallback;
+
+- (id)initWithImage:(ZXBitMatrix *)image;
+
+/**
+ * Detects a QR Code in an image, simply.
+ *
+ * @return ZXDetectorResult encapsulating results of detecting a QR Code or nil
+ * if no QR Code can be found
+ */
+- (ZXDetectorResult *)detectWithError:(NSError **)error;
+
+/**
+ * Detects a QR Code in an image, simply.
+ *
+ * @param hints optional hints to detector
+ * @return ZXDetectorResult encapsulating results of detecting a QR Code
+ * @return nil if QR Code cannot be found
+ * @return nil if a QR Code cannot be decoded
+ */
+- (ZXDetectorResult *)detect:(ZXDecodeHints *)hints error:(NSError **)error;
+
+- (ZXDetectorResult *)processFinderPatternInfo:(ZXQRCodeFinderPatternInfo *)info error:(NSError **)error;
+
+/**
+ * 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;
+
+/**
+ * Attempts to locate an alignment pattern in a limited region of the image, which is
+ * guessed to contain it. This method uses ZXAlignmentPattern.
+ *
+ * @param overallEstModuleSize estimated module size so far
+ * @param estAlignmentX x coordinate of center of area probably containing alignment pattern
+ * @param estAlignmentY y coordinate of above
+ * @param allowanceFactor number of pixels in all directions to search from the center
+ * @return ZXAlignmentPattern if found, or nil if an unexpected error occurs during detection
+ */
+- (ZXQRCodeAlignmentPattern *)findAlignmentInRegion:(float)overallEstModuleSize estAlignmentX:(int)estAlignmentX estAlignmentY:(int)estAlignmentY allowanceFactor:(float)allowanceFactor error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeDetector.m b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeDetector.m
new file mode 100644
index 0000000..e6bc99f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeDetector.m
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXDetectorResult.h"
+#import "ZXErrors.h"
+#import "ZXGridSampler.h"
+#import "ZXIntArray.h"
+#import "ZXMathUtils.h"
+#import "ZXPerspectiveTransform.h"
+#import "ZXQRCodeAlignmentPattern.h"
+#import "ZXQRCodeAlignmentPatternFinder.h"
+#import "ZXQRCodeDetector.h"
+#import "ZXQRCodeFinderPattern.h"
+#import "ZXQRCodeFinderPatternFinder.h"
+#import "ZXQRCodeFinderPatternInfo.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXResultPoint.h"
+#import "ZXResultPointCallback.h"
+
+@interface ZXQRCodeDetector ()
+
+@property (nonatomic, weak) id resultPointCallback;
+
+@end
+
+@implementation ZXQRCodeDetector
+
+- (id)initWithImage:(ZXBitMatrix *)image {
+ if (self = [super init]) {
+ _image = image;
+ }
+
+ return self;
+}
+
+- (ZXDetectorResult *)detectWithError:(NSError **)error {
+ return [self detect:nil error:error];
+}
+
+- (ZXDetectorResult *)detect:(ZXDecodeHints *)hints error:(NSError **)error {
+ self.resultPointCallback = hints == nil ? nil : hints.resultPointCallback;
+
+ ZXQRCodeFinderPatternFinder *finder = [[ZXQRCodeFinderPatternFinder alloc] initWithImage:self.image resultPointCallback:self.resultPointCallback];
+ ZXQRCodeFinderPatternInfo *info = [finder find:hints error:error];
+ if (!info) {
+ return nil;
+ }
+
+ return [self processFinderPatternInfo:info error:error];
+}
+
+- (ZXDetectorResult *)processFinderPatternInfo:(ZXQRCodeFinderPatternInfo *)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 = ZXNotFoundErrorInstance();
+ 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 = ZXFormatErrorInstance();
+ return nil;
+ }
+ int modulesBetweenFPCenters = [provisionalVersion dimensionForVersion] - 7;
+
+ ZXQRCodeAlignmentPattern *alignmentPattern = nil;
+ if (provisionalVersion.alignmentPatternCenters.length > 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) / 2) + 7;
+
+ switch (dimension & 0x03) {
+ case 0:
+ dimension++;
+ break;
+ case 2:
+ dimension--;
+ break;
+ case 3:
+ if (error) *error = ZXNotFoundErrorInstance();
+ 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;
+}
+
+/**
+ * Estimates module size based on two finder patterns -- it uses
+ * sizeOfBlackWhiteBlackRunBothWays:fromY:toX:toY: to figure the
+ * width of each, measuring along the axis between their centers.
+ */
+- (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;
+}
+
+/**
+ * See sizeOfBlackWhiteBlackRun:fromY:toX:toY: computes the total width of
+ * a finder pattern by looking for a black-white-black run from the center in the direction
+ * of another point (another finder pattern center), and in the opposite direction too.
+ */
+- (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 / 2;
+ 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;
+}
+
+- (ZXQRCodeAlignmentPattern *)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 = ZXNotFoundErrorInstance();
+ 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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ ZXQRCodeAlignmentPatternFinder *alignmentFinder = [[ZXQRCodeAlignmentPatternFinder 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/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.h b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.h
new file mode 100644
index 0000000..32ea5de
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.h
@@ -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 "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;
+
+/**
+ * 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;
+
+/**
+ * Combines this object's current estimate of a finder pattern position and module size
+ * with a new estimate. It returns a new ZXFinderPattern containing a weighted average
+ * based on count.
+ */
+- (ZXQRCodeFinderPattern *)combineEstimateI:(float)i j:(float)j newModuleSize:(float)newModuleSize;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.m b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.m
new file mode 100644
index 0000000..7a112ce
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPattern.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 "ZXQRCodeFinderPattern.h"
+
+@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++;
+}
+*/
+
+- (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;
+}
+
+- (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/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.h b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.h
new file mode 100644
index 0000000..ada43ad
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.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.
+ */
+
+extern const int ZX_FINDER_PATTERN_MIN_SKIP;
+extern const int ZX_FINDER_PATTERN_MAX_MODULES;
+
+@protocol ZXResultPointCallback;
+@class ZXBitMatrix, ZXDecodeHints, ZXQRCodeFinderPatternInfo;
+
+/**
+ * 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.
+ */
+@interface ZXQRCodeFinderPatternFinder : NSObject
+
+@property (nonatomic, strong, readonly) ZXBitMatrix *image;
+@property (nonatomic, strong, readonly) NSMutableArray *possibleCenters;
+
+/**
+ * Creates a finder that will search the image for three finder patterns.
+ *
+ * @param image image to search
+ */
+- (id)initWithImage:(ZXBitMatrix *)image;
+
+- (id)initWithImage:(ZXBitMatrix *)image resultPointCallback:(id)resultPointCallback;
+
+- (ZXQRCodeFinderPatternInfo *)find:(ZXDecodeHints *)hints error:(NSError **)error;
+
+/**
+ * @param stateCount count of black/white/black/white/black pixels just read
+ * @return true iff the proportions of the counts is close enough to the 1/1/3/1/1 ratios
+ * used by finder patterns to be considered a match
+ */
++ (BOOL)foundPatternCross:(const int[])stateCount;
+
+/**
+ * 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.
+ * And then we cross-cross-cross check with another diagonal scan.
+ *
+ * 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
+ *
+ * @param stateCount reading state module counts from horizontal scan
+ * @param i row where finder pattern may be found
+ * @param j end of possible finder pattern in row
+ * @return true if a finder pattern candidate was found this time
+ */
+- (BOOL)handlePossibleCenter:(const int[])stateCount i:(int)i j:(int)j pureBarcode:(BOOL)pureBarcode;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.m b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.m
new file mode 100644
index 0000000..3a3b7b2
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternFinder.m
@@ -0,0 +1,570 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXQRCodeFinderPattern.h"
+#import "ZXQRCodeFinderPatternInfo.h"
+#import "ZXQRCodeFinderPatternFinder.h"
+#import "ZXResultPoint.h"
+#import "ZXResultPointCallback.h"
+
+const int ZX_CENTER_QUORUM = 2;
+const int ZX_FINDER_PATTERN_MIN_SKIP = 3;
+const int ZX_FINDER_PATTERN_MAX_MODULES = 57;
+
+@interface ZXQRCodeFinderPatternFinder ()
+
+NSInteger centerCompare(id center1, id center2, void *context);
+NSInteger furthestFromAverageCompare(id center1, id center2, void *context);
+
+@property (nonatomic, assign) BOOL hasSkipped;
+@property (nonatomic, weak, readonly) id resultPointCallback;
+@property (nonatomic, strong) NSMutableArray *possibleCenters;
+
+@end
+
+@implementation ZXQRCodeFinderPatternFinder
+
+- (id)initWithImage:(ZXBitMatrix *)image {
+ return [self initWithImage:image resultPointCallback:nil];
+}
+
+- (id)initWithImage:(ZXBitMatrix *)image resultPointCallback:(id)resultPointCallback {
+ if (self = [super init]) {
+ _image = image;
+ _possibleCenters = [NSMutableArray array];
+ _resultPointCallback = resultPointCallback;
+ }
+
+ return self;
+}
+
+- (ZXQRCodeFinderPatternInfo *)find:(ZXDecodeHints *)hints error:(NSError **)error {
+ BOOL tryHarder = hints != nil && hints.tryHarder;
+ BOOL pureBarcode = hints != nil && hints.pureBarcode;
+ int maxI = self.image.height;
+ int maxJ = self.image.width;
+ int iSkip = (3 * maxI) / (4 * ZX_FINDER_PATTERN_MAX_MODULES);
+ if (iSkip < ZX_FINDER_PATTERN_MIN_SKIP || tryHarder) {
+ iSkip = ZX_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 ([ZXQRCodeFinderPatternFinder foundPatternCross:stateCount]) {
+ BOOL confirmed = [self handlePossibleCenter:stateCount i:i j:j pureBarcode:pureBarcode];
+ 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 ([ZXQRCodeFinderPatternFinder foundPatternCross:stateCount]) {
+ BOOL confirmed = [self handlePossibleCenter:stateCount i:i j:maxJ pureBarcode:pureBarcode];
+ if (confirmed) {
+ iSkip = stateCount[0];
+ if (self.hasSkipped) {
+ done = [self haveMultiplyConfirmedCenters];
+ }
+ }
+ }
+ }
+
+ NSMutableArray *patternInfo = [self selectBestPatterns];
+ if (!patternInfo) {
+ if (error) *error = ZXNotFoundErrorInstance();
+ return nil;
+ }
+ [ZXResultPoint orderBestPatterns:patternInfo];
+ return [[ZXQRCodeFinderPatternInfo 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:(const int[])stateCount end:(int)end {
+ return (float)(end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;
+}
+
++ (BOOL)foundPatternCross:(const 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;
+ }
+ float moduleSize = totalModuleSize / 7.0f;
+ float maxVariance = moduleSize / 2.0f;
+ // Allow less than 50% variance from 1-1-3-1-1 proportions
+ return
+ ABS(moduleSize - stateCount[0]) < maxVariance &&
+ ABS(moduleSize - stateCount[1]) < maxVariance &&
+ ABS(3.0f * moduleSize - stateCount[2]) < 3 * maxVariance &&
+ ABS(moduleSize - stateCount[3]) < maxVariance &&
+ ABS(moduleSize - stateCount[4]) < maxVariance;
+}
+
+/**
+ * After a vertical and horizontal scan finds a potential finder pattern, this method
+ * "cross-cross-cross-checks" by scanning down diagonally through the center of the possible
+ * finder pattern to see if the same proportion is detected.
+ *
+ * @param startI row where a finder pattern was detected
+ * @param centerJ center of the section that appears to cross a finder pattern
+ * @param maxCount maximum reasonable number of modules that should be
+ * observed in any reading state, based on the results of the horizontal scan
+ * @param originalStateCountTotal The original state count total.
+ * @return true if proportions are withing expected limits
+ */
+- (BOOL)crossCheckDiagonal:(int)startI centerJ:(int)centerJ maxCount:(int)maxCount originalStateCountTotal:(int)originalStateCountTotal {
+ int stateCount[5] = {0, 0, 0, 0, 0};
+
+ // Start counting up, left from center finding black center mass
+ int i = 0;
+ while (startI >= i && centerJ >= i && [self.image getX:centerJ - i y:startI - i]) {
+ stateCount[2]++;
+ i++;
+ }
+
+ if (startI < i || centerJ < i) {
+ return NO;
+ }
+
+ // Continue up, left finding white space
+ while (startI >= i && centerJ >= i && ![self.image getX:centerJ - i y:startI - i] &&
+ stateCount[1] <= maxCount) {
+ stateCount[1]++;
+ i++;
+ }
+
+ // If already too many modules in this state or ran off the edge:
+ if (startI < i || centerJ < i || stateCount[1] > maxCount) {
+ return NO;
+ }
+
+ // Continue up, left finding black border
+ while (startI >= i && centerJ >= i && [self.image getX:centerJ - i y:startI - i] &&
+ stateCount[0] <= maxCount) {
+ stateCount[0]++;
+ i++;
+ }
+ if (stateCount[0] > maxCount) {
+ return NO;
+ }
+
+ int maxI = self.image.height;
+ int maxJ = self.image.width;
+
+ // Now also count down, right from center
+ i = 1;
+ while (startI + i < maxI && centerJ + i < maxJ && [self.image getX:centerJ + i y:startI + i]) {
+ stateCount[2]++;
+ i++;
+ }
+
+ // Ran off the edge?
+ if (startI + i >= maxI || centerJ + i >= maxJ) {
+ return NO;
+ }
+
+ while (startI + i < maxI && centerJ + i < maxJ && ![self.image getX:centerJ + i y:startI + i] &&
+ stateCount[3] < maxCount) {
+ stateCount[3]++;
+ i++;
+ }
+
+ if (startI + i >= maxI || centerJ + i >= maxJ || stateCount[3] >= maxCount) {
+ return NO;
+ }
+
+ while (startI + i < maxI && centerJ + i < maxJ && [self.image getX:centerJ + i y:startI + i] &&
+ stateCount[4] < maxCount) {
+ stateCount[4]++;
+ i++;
+ }
+
+ if (stateCount[4] >= maxCount) {
+ return NO;
+ }
+
+ // If we found a finder-pattern-like section, but its size is more than 100% different than
+ // the original, assume it's a false positive
+ int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
+ return
+ abs(stateCountTotal - originalStateCountTotal) < 2 * originalStateCountTotal &&
+ [ZXQRCodeFinderPatternFinder foundPatternCross:stateCount];
+}
+
+/**
+ * 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.
+ *
+ * @param startI row where a finder pattern was detected
+ * @param centerJ center of the section that appears to cross a finder pattern
+ * @param maxCount maximum reasonable number of modules that should be
+ * observed in any reading state, based on the results of the horizontal scan
+ * @return vertical center of finder pattern, or {@link Float#NaN} if not found
+ */
+- (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 [ZXQRCodeFinderPatternFinder 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 [ZXQRCodeFinderPatternFinder foundPatternCross:stateCount] ? [self centerFromEnd:stateCount end:j] : NAN;
+}
+
+- (BOOL)handlePossibleCenter:(const int[])stateCount i:(int)i j:(int)j pureBarcode:(BOOL)pureBarcode {
+ int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
+ float centerJ = [self centerFromEnd:stateCount end:j];
+ float centerI = [self crossCheckVertical:i centerJ:(int)centerJ maxCount:stateCount[2] originalStateCountTotal:stateCountTotal];
+ if (!isnan(centerI)) {
+ centerJ = [self crossCheckHorizontal:(int)centerJ centerI:(int)centerI maxCount:stateCount[2] originalStateCountTotal:stateCountTotal];
+ if (!isnan(centerJ) &&
+ (!pureBarcode || [self crossCheckDiagonal:(int)centerI centerJ:(int) centerJ maxCount:stateCount[2] originalStateCountTotal:stateCountTotal])) {
+ 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;
+ }
+ ZXResultPoint *firstConfirmedCenter = nil;
+ for (int i = 0; i < max; i++) {
+ ZXQRCodeFinderPattern *center = self.possibleCenters[i];
+ if ([center count] >= ZX_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;
+}
+
+/**
+ * @return true iff we have found at least 3 finder patterns that have been detected
+ * at least ZX_CENTER_QUORUM times each, and, the estimated module size of the
+ * candidates is "pretty similar"
+ */
+- (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] >= ZX_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;
+}
+
+/**
+ * @return the 3 best ZXFinderPatterns from our list of candidates. The "best" are
+ * those that have been detected at least ZXCENTER_QUORUM times, and whose module
+ * size differs from the average among those patterns the least
+ * @return nil if 3 such finder patterns do not exist
+ */
+- (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/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternInfo.h b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternInfo.h
new file mode 100644
index 0000000..f529186
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternInfo.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 ZXQRCodeFinderPattern;
+
+/**
+ * Encapsulates information about finder patterns in an image, including the location of
+ * the three finder patterns, and their estimated module size.
+ */
+@interface ZXQRCodeFinderPatternInfo : 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/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternInfo.m b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternInfo.m
new file mode 100644
index 0000000..9d63893
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/detector/ZXQRCodeFinderPatternInfo.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 "ZXQRCodeFinderPattern.h"
+#import "ZXQRCodeFinderPatternInfo.h"
+
+@implementation ZXQRCodeFinderPatternInfo
+
+- (id)initWithPatternCenters:(NSArray *)patternCenters {
+ if (self = [super init]) {
+ _bottomLeft = patternCenters[0];
+ _topLeft = patternCenters[1];
+ _topRight = patternCenters[2];
+ }
+
+ return self;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCode.h b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCode.h
new file mode 100644
index 0000000..20ba525
--- /dev/null
+++ b/Pods/ZXingObjC/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 const int ZX_NUM_MASK_PATTERNS;
+
+@class ZXByteMatrix, ZXQRCodeErrorCorrectionLevel, ZXQRCodeMode, ZXQRCodeVersion;
+
+@interface ZXQRCode : NSObject
+
+@property (nonatomic, strong) ZXQRCodeMode *mode;
+@property (nonatomic, strong) ZXQRCodeErrorCorrectionLevel *ecLevel;
+@property (nonatomic, strong) ZXQRCodeVersion *version;
+@property (nonatomic, assign) int maskPattern;
+@property (nonatomic, strong) ZXByteMatrix *matrix;
+
++ (BOOL)isValidMaskPattern:(int)maskPattern;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCode.m b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCode.m
new file mode 100644
index 0000000..3e84654
--- /dev/null
+++ b/Pods/ZXingObjC/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 "ZXQRCode.h"
+#import "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeMode.h"
+
+const int ZX_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 < ZX_NUM_MASK_PATTERNS;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.h b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.h
new file mode 100644
index 0000000..16c6882
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.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 ZXByteArray;
+
+@interface ZXQRCodeBlockPair : NSObject
+
+@property (nonatomic, strong, readonly) ZXByteArray *dataBytes;
+@property (nonatomic, strong, readonly) ZXByteArray *errorCorrectionBytes;
+
+- (id)initWithData:(ZXByteArray *)data errorCorrection:(ZXByteArray *)errorCorrection;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.m b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.m
new file mode 100644
index 0000000..b77fa32
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeBlockPair.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 "ZXQRCodeBlockPair.h"
+
+@implementation ZXQRCodeBlockPair
+
+- (id)initWithData:(ZXByteArray *)data errorCorrection:(ZXByteArray *)errorCorrection {
+ if (self = [super init]) {
+ _dataBytes = data;
+ _errorCorrectionBytes = errorCorrection;
+ }
+
+ return self;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.h b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.h
new file mode 100644
index 0000000..a5cd026
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.h
@@ -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.
+ */
+
+@class ZXBitArray, ZXByteArray, ZXEncodeHints, ZXQRCode, ZXQRCodeErrorCorrectionLevel, ZXQRCodeMode, ZXQRCodeVersion;
+
+extern const NSStringEncoding ZX_DEFAULT_BYTE_MODE_ENCODING;
+
+@interface ZXQRCodeEncoder : NSObject
+
+/**
+ * Encode "bytes" with the error correction level "ecLevel". The encoding mode will be chosen
+ * internally by chooseMode:. On success, store the result in "qrCode".
+ *
+ * We recommend you to use QRCode.EC_LEVEL_L (the lowest level) for
+ * "getECLevel" since our primary use is to show QR code on desktop screens. We don't need very
+ * strong error correction for this purpose.
+ *
+ * Note that there is no way to encode bytes in MODE_KANJI. We might want to add EncodeWithMode()
+ * with which clients can specify the encoding mode. For now, we don't need the functionality.
+ */
++ (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel error:(NSError **)error;
+
++ (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel hints:(ZXEncodeHints *)hints error:(NSError **)error;
+
+/**
+ * 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;
+
+/**
+ * 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;
+
+/**
+ * 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;
+
+/**
+ * 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;
+
++ (ZXByteArray *)generateECBytes:(ZXByteArray *)dataBytes numEcBytesInBlock:(int)numEcBytesInBlock;
+
+/**
+ * Append mode info. On success, store the result in "bits".
+ */
++ (void)appendModeInfo:(ZXQRCodeMode *)mode bits:(ZXBitArray *)bits;
+
+/**
+ * Append length info. On success, store the result in "bits".
+ */
++ (BOOL)appendLengthInfo:(int)numLetters version:(ZXQRCodeVersion *)version mode:(ZXQRCodeMode *)mode bits:(ZXBitArray *)bits error:(NSError **)error;
+
+/**
+ * Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
+ */
++ (BOOL)appendBytes:(NSString *)content mode:(ZXQRCodeMode *)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/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.m b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.m
new file mode 100644
index 0000000..f0d163f
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeEncoder.m
@@ -0,0 +1,563 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXByteArray.h"
+#import "ZXByteMatrix.h"
+#import "ZXCharacterSetECI.h"
+#import "ZXEncodeHints.h"
+#import "ZXErrors.h"
+#import "ZXGenericGF.h"
+#import "ZXIntArray.h"
+#import "ZXQRCode.h"
+#import "ZXQRCodeBlockPair.h"
+#import "ZXQRCodeEncoder.h"
+#import "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeMaskUtil.h"
+#import "ZXQRCodeMatrixUtil.h"
+#import "ZXQRCodeMode.h"
+#import "ZXQRCodeVersion.h"
+#import "ZXReedSolomonEncoder.h"
+
+// The original table is defined in the table 5 of JISX0510:2004 (p.19).
+const int ZX_ALPHANUMERIC_TABLE[] = {
+ -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 ZX_DEFAULT_BYTE_MODE_ENCODING = NSISOLatin1StringEncoding;
+
+@implementation ZXQRCodeEncoder
+
+// The mask penalty calculation is complicated. See Table 21 of JISX0510:2004 (p.45) for details.
+// Basically it applies four rules and summate all penalties.
++ (int)calculateMaskPenalty:(ZXByteMatrix *)matrix {
+ return [ZXQRCodeMaskUtil applyMaskPenaltyRule1:matrix]
+ + [ZXQRCodeMaskUtil applyMaskPenaltyRule2:matrix]
+ + [ZXQRCodeMaskUtil applyMaskPenaltyRule3:matrix]
+ + [ZXQRCodeMaskUtil applyMaskPenaltyRule4:matrix];
+}
+
++ (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXQRCodeErrorCorrectionLevel *)ecLevel error:(NSError **)error {
+ return [self encode:content ecLevel:ecLevel hints:nil error:error];
+}
+
++ (ZXQRCode *)encode:(NSString *)content ecLevel:(ZXQRCodeErrorCorrectionLevel *)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 = ZX_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.
+ ZXQRCodeMode *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:[ZXQRCodeMode byteMode]] && ZX_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:[ZXQRCodeMode 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 (![ZXQRCodeMatrixUtil buildMatrix:finalBits ecLevel:ecLevel version:version maskPattern:maskPattern matrix:matrix error:error]) {
+ return nil;
+ }
+ [qrCode setMatrix:matrix];
+
+ return qrCode;
+}
+
++ (int)alphanumericCode:(int)code {
+ if (code < sizeof(ZX_ALPHANUMERIC_TABLE) / sizeof(int)) {
+ return ZX_ALPHANUMERIC_TABLE[code];
+ }
+ return -1;
+}
+
++ (ZXQRCodeMode *)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}.
+ */
++ (ZXQRCodeMode *)chooseMode:(NSString *)content encoding:(NSStringEncoding)encoding {
+ if (NSShiftJISStringEncoding == encoding) {
+ return [self isOnlyDoubleByteKanji:content] ? [ZXQRCodeMode kanjiMode] : [ZXQRCodeMode 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 [ZXQRCodeMode byteMode];
+ }
+ }
+ if (hasAlphanumeric) {
+ return [ZXQRCodeMode alphanumericMode];
+ }
+ if (hasNumeric) {
+ return [ZXQRCodeMode numericMode];
+ }
+ return [ZXQRCodeMode 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:(ZXQRCodeErrorCorrectionLevel *)ecLevel version:(ZXQRCodeVersion *)version matrix:(ZXByteMatrix *)matrix error:(NSError **)error {
+ int minPenalty = INT_MAX;
+ int bestMaskPattern = -1;
+
+ for (int maskPattern = 0; maskPattern < ZX_NUM_MASK_PATTERNS; maskPattern++) {
+ if (![ZXQRCodeMatrixUtil 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:(ZXQRCodeErrorCorrectionLevel *)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:(ZXQRCodeMode *)mode {
+ int modeInfoBits = 4;
+ int charCountBits = [mode characterCountBits:version];
+ int headerBits = modeInfoBits + charCountBits;
+ int totalBits = numInputBits + headerBits;
+
+ return (totalBits + 7) / 8;
+}
+
++ (BOOL)terminateBits:(int)numDataBytes bits:(ZXBitArray *)bits error:(NSError **)error {
+ int capacity = numDataBytes * 8;
+ 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;
+}
+
++ (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;
+}
+
++ (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];
+ ZXByteArray *dataBytes = [[ZXByteArray alloc] initWithLength:size];
+ [bits toBytes:8 * dataBytesOffset array:dataBytes offset:0 numBytes:size];
+ ZXByteArray *ecBytes = [self generateECBytes:dataBytes numEcBytesInBlock:numEcBytesInBlock[0]];
+ [blocks addObject:[[ZXQRCodeBlockPair alloc] initWithData:dataBytes errorCorrection:ecBytes]];
+
+ maxNumDataBytes = MAX(maxNumDataBytes, size);
+ maxNumEcBytes = MAX(maxNumEcBytes, numEcBytesInBlock[0]);
+ dataBytesOffset += numDataBytesInBlock[0];
+ }
+ 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 (ZXQRCodeBlockPair *block in blocks) {
+ ZXByteArray *dataBytes = block.dataBytes;
+ NSUInteger length = dataBytes.length;
+ if (i < length) {
+ [result appendBits:dataBytes.array[i] numBits:8];
+ }
+ }
+ }
+ // Then, place error correction blocks.
+ for (int i = 0; i < maxNumEcBytes; ++i) {
+ for (ZXQRCodeBlockPair *block in blocks) {
+ ZXByteArray *ecBytes = block.errorCorrectionBytes;
+ int length = ecBytes.length;
+ if (i < length) {
+ [result appendBits:ecBytes.array[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;
+}
+
++ (ZXByteArray *)generateECBytes:(ZXByteArray *)dataBytes numEcBytesInBlock:(int)numEcBytesInBlock {
+ int numDataBytes = dataBytes.length;
+ ZXIntArray *toEncode = [[ZXIntArray alloc] initWithLength:numDataBytes + numEcBytesInBlock];
+ for (int i = 0; i < numDataBytes; i++) {
+ toEncode.array[i] = dataBytes.array[i] & 0xFF;
+ }
+ [[[ZXReedSolomonEncoder alloc] initWithField:[ZXGenericGF QrCodeField256]] encode:toEncode ecBytes:numEcBytesInBlock];
+
+ ZXByteArray *ecBytes = [[ZXByteArray alloc] initWithLength:numEcBytesInBlock];
+ for (int i = 0; i < numEcBytesInBlock; i++) {
+ ecBytes.array[i] = (int8_t) toEncode.array[numDataBytes + i];
+ }
+
+ return ecBytes;
+}
+
++ (void)appendModeInfo:(ZXQRCodeMode *)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:(ZXQRCodeMode *)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;
+}
+
++ (BOOL)appendBytes:(NSString *)content mode:(ZXQRCodeMode *)mode bits:(ZXBitArray *)bits encoding:(NSStringEncoding)encoding error:(NSError **)error {
+ if ([mode isEqual:[ZXQRCodeMode numericMode]]) {
+ [self appendNumericBytes:content bits:bits];
+ } else if ([mode isEqual:[ZXQRCodeMode alphanumericMode]]) {
+ if (![self appendAlphanumericBytes:content bits:bits error:error]) {
+ return NO;
+ }
+ } else if ([mode isEqual:[ZXQRCodeMode byteMode]]) {
+ [self append8BitBytes:content bits:bits encoding:encoding];
+ } else if ([mode isEqual:[ZXQRCodeMode 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:(ZXCharacterSetECI *)eci bits:(ZXBitArray *)bits {
+ [bits appendBits:[[ZXQRCodeMode eciMode] bits] numBits:4];
+ [bits appendBits:[eci value] numBits:8];
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMaskUtil.h b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMaskUtil.h
new file mode 100644
index 0000000..a70a5d8
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMaskUtil.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 ZXQRCodeMaskUtil : NSObject
+
+/**
+ * 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;
+
+/**
+ * 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;
+
+/**
+ * Apply mask penalty rule 3 and return the penalty. Find consecutive runs of 1:1:3:1:1:4
+ * starting with black, or 4:1:1:3:1:1 starting with white, and give penalty to them. If we
+ * find patterns like 000010111010000, we give penalty once.
+ */
++ (int)applyMaskPenaltyRule3:(ZXByteMatrix *)matrix;
+
+/**
+ * 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;
+
+/**
+ * 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;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMaskUtil.m b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMaskUtil.m
new file mode 100644
index 0000000..ba5b443
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMaskUtil.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 "ZXByteMatrix.h"
+#import "ZXQRCode.h"
+#import "ZXQRCodeMaskUtil.h"
+
+// Penalty weights from section 6.8.2.1
+const int ZX_N1 = 3;
+const int ZX_N2 = 3;
+const int ZX_N3 = 40;
+const int ZX_N4 = 10;
+
+@implementation ZXQRCodeMaskUtil
+
++ (int)applyMaskPenaltyRule1:(ZXByteMatrix *)matrix {
+ return [self applyMaskPenaltyRule1Internal:matrix isHorizontal:YES] + [self applyMaskPenaltyRule1Internal:matrix isHorizontal:NO];
+}
+
++ (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 ZX_N2 * penalty;
+}
+
++ (int)applyMaskPenaltyRule3:(ZXByteMatrix *)matrix {
+ int numPenalties = 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++) {
+ int8_t *arrayY = array[y]; // We can at least optimize this access
+ if (x + 6 < width &&
+ arrayY[x] == 1 &&
+ arrayY[x + 1] == 0 &&
+ arrayY[x + 2] == 1 &&
+ arrayY[x + 3] == 1 &&
+ arrayY[x + 4] == 1 &&
+ arrayY[x + 5] == 0 &&
+ arrayY[x + 6] == 1 &&
+ ([self isWhiteHorizontal:arrayY length:width from:x - 4 to:x] || [self isWhiteHorizontal:arrayY length:width from:x + 7 to:x + 11])) {
+ numPenalties++;
+ }
+ 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 &&
+ ([self isWhiteVertical:array length:width col:x from:y - 4 to:y] || [self isWhiteVertical:array length:height col:x from:y + 7 to:y + 11])) {
+ numPenalties++;
+ }
+ }
+ }
+ return numPenalties * ZX_N3;
+}
+
++ (BOOL)isWhiteHorizontal:(int8_t *)rowArray length:(int)length from:(int)from to:(int)to {
+ for (int i = from; i < to; i++) {
+ if (i >= 0 && i < length && rowArray[i] == 1) {
+ return NO;
+ }
+ }
+ return YES;
+}
+
++ (BOOL)isWhiteVertical:(int8_t **)array length:(int)length col:(int)col from:(int)from to:(int)to {
+ for (int i = from; i < to; i++) {
+ if (i >= 0 && i < length && array[i][col] == 1) {
+ return NO;
+ }
+ }
+ return YES;
+}
+
++ (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];
+ int fivePercentVariances = abs(numDarkCells * 2 - numTotalCells) * 10 / numTotalCells;
+ return fivePercentVariances * ZX_N4;
+}
+
++ (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 = ((y / 2) + (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 += ZX_N1 + (numSameBitCells - 5);
+ }
+ numSameBitCells = 1; // Include the cell itself.
+ prevBit = bit;
+ }
+ }
+ if (numSameBitCells >= 5) {
+ penalty += ZX_N1 + (numSameBitCells - 5);
+ }
+ }
+ return penalty;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMatrixUtil.h b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMatrixUtil.h
new file mode 100644
index 0000000..ab89bf4
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMatrixUtil.h
@@ -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.
+ */
+
+@class ZXBitArray, ZXByteMatrix, ZXQRCodeErrorCorrectionLevel, ZXQRCodeVersion;
+
+@interface ZXQRCodeMatrixUtil : NSObject
+
+// Set all cells to -1. -1 means that the cell is empty (not set yet).
++ (void)clearMatrix:(ZXByteMatrix *)matrix;
+
+// 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:(ZXQRCodeErrorCorrectionLevel *)ecLevel version:(ZXQRCodeVersion *)version maskPattern:(int)maskPattern matrix:(ZXByteMatrix *)matrix error:(NSError **)error;
+
+// 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;
+
+// Embed type information. On success, modify the matrix.
++ (BOOL)embedTypeInfo:(ZXQRCodeErrorCorrectionLevel *)ecLevel maskPattern:(int)maskPattern matrix:(ZXByteMatrix *)matrix error:(NSError **)error;
+
+// 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;
+
+// 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;
+
+// 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;
+
+// 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;
+
+// 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:(ZXQRCodeErrorCorrectionLevel *)ecLevel maskPattern:(int)maskPattern bits:(ZXBitArray *)bits error:(NSError **)error;
+
+// 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;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMatrixUtil.m b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMatrixUtil.m
new file mode 100644
index 0000000..422e6cf
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/encoder/ZXQRCodeMatrixUtil.m
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXQRCode.h"
+#import "ZXQRCodeErrorCorrectionLevel.h"
+#import "ZXQRCodeMaskUtil.h"
+#import "ZXQRCodeMatrixUtil.h"
+#import "ZXQRCodeVersion.h"
+
+const int ZX_POSITION_DETECTION_PATTERN[][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},
+};
+
+const int ZX_POSITION_ADJUSTMENT_PATTERN[][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.
+const int ZX_POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[][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.
+const int ZX_TYPE_INFO_COORDINATES[][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)
+const int ZX_VERSION_INFO_POLY = 0x1f25; // 1 1111 0010 0101
+
+// From Appendix C in JISX0510:2004 (p.65).
+const int ZX_TYPE_INFO_POLY = 0x537;
+const int ZX_TYPE_INFO_MASK_PATTERN = 0x5412;
+
+@implementation ZXQRCodeMatrixUtil
+
++ (void)clearMatrix:(ZXByteMatrix *)matrix {
+ [matrix clear:-1];
+}
+
++ (BOOL)buildMatrix:(ZXBitArray *)dataBits ecLevel:(ZXQRCodeErrorCorrectionLevel *)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;
+}
+
++ (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;
+}
+
++ (BOOL)embedTypeInfo:(ZXQRCodeErrorCorrectionLevel *)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 = ZX_TYPE_INFO_COORDINATES[i][0];
+ int y1 = ZX_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;
+}
+
++ (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;
+}
+
++ (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 && [ZXQRCodeMaskUtil 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;
+}
+
++ (int)findMSBSet:(int)value {
+ int numDigits = 0;
+ while (value != 0) {
+ value = (int)((unsigned int)value >> 1);
+ ++numDigits;
+ }
+ return numDigits;
+}
+
++ (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;
+}
+
++ (BOOL)makeTypeInfoBits:(ZXQRCodeErrorCorrectionLevel *)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:ZX_TYPE_INFO_POLY];
+ [bits appendBits:bchCode numBits:10];
+
+ ZXBitArray *maskBits = [[ZXBitArray alloc] init];
+ [maskBits appendBits:ZX_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;
+}
+
++ (BOOL)makeVersionInfoBits:(ZXQRCodeVersion *)version bits:(ZXBitArray *)bits error:(NSError **)error {
+ [bits appendBits:version.versionNumber numBits:6];
+ int bchCode = [self calculateBCHCode:version.versionNumber poly:ZX_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:ZX_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:ZX_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(ZX_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(ZX_POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index]) / sizeof(int);
+ for (int i = 0; i < numCoordinates; ++i) {
+ for (int j = 0; j < numCoordinates; ++j) {
+ int y = ZX_POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][i];
+ int x = ZX_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/Pods/ZXingObjC/ZXingObjC/qrcode/multi/ZXQRCodeMultiReader.h b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/ZXQRCodeMultiReader.h
new file mode 100644
index 0000000..0c2fba9
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/ZXQRCodeMultiReader.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 "ZXMultipleBarcodeReader.h"
+#import "ZXQRCodeReader.h"
+
+/**
+ * This implementation can detect and decode multiple QR Codes in an image.
+ */
+@interface ZXQRCodeMultiReader : ZXQRCodeReader
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/multi/ZXQRCodeMultiReader.m b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/ZXQRCodeMultiReader.m
new file mode 100644
index 0000000..aa4fa6c
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/ZXQRCodeMultiReader.m
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "ZXByteArray.h"
+#import "ZXDecoderResult.h"
+#import "ZXDetectorResult.h"
+#import "ZXMultiDetector.h"
+#import "ZXQRCodeDecoder.h"
+#import "ZXQRCodeDecoderMetaData.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 *detectorResults = [[[ZXMultiDetector alloc] initWithImage:matrix] detectMulti:hints error:error];
+ if (!detectorResults) {
+ return nil;
+ }
+ for (ZXDetectorResult *detectorResult in detectorResults) {
+ ZXDecoderResult *decoderResult = [[self decoder] decodeMatrix:[detectorResult bits] hints:hints error:nil];
+ if (decoderResult) {
+ NSMutableArray *points = [[detectorResult points] mutableCopy];
+ // If the code was mirrored: swap the bottom-left and the top-right points.
+ if ([decoderResult.other isKindOfClass:[ZXQRCodeDecoderMetaData class]]) {
+ [(ZXQRCodeDecoderMetaData *)decoderResult.other applyMirroredCorrection:points];
+ }
+ ZXResult *result = [ZXResult resultWithText:decoderResult.text
+ rawBytes:decoderResult.rawBytes
+ 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];
+ }
+ if ([decoderResult hasStructuredAppend]) {
+ [result putMetadata:kResultMetadataTypeStructuredAppendSequence
+ value:@(decoderResult.structuredAppendSequenceNumber)];
+ [result putMetadata:kResultMetadataTypeStructuredAppendParity
+ value:@(decoderResult.structuredAppendParity)];
+ }
+ [results addObject:result];
+ }
+ }
+
+ results = [self processStructuredAppend:results];
+ return results;
+}
+
+- (NSMutableArray *)processStructuredAppend:(NSMutableArray *)results {
+ BOOL hasSA = NO;
+
+ // first, check, if there is at least on SA result in the list
+ for (ZXResult *result in results) {
+ if (result.resultMetadata[@(kResultMetadataTypeStructuredAppendSequence)]) {
+ hasSA = YES;
+ break;
+ }
+ }
+ if (!hasSA) {
+ return results;
+ }
+
+ // it is, second, split the lists and built a new result list
+ NSMutableArray *newResults = [NSMutableArray array];
+ NSMutableArray *saResults = [NSMutableArray array];
+ for (ZXResult *result in results) {
+ [newResults addObject:result];
+ if (result.resultMetadata[@(kResultMetadataTypeStructuredAppendSequence)]) {
+ [saResults addObject:result];
+ }
+ }
+ // sort and concatenate the SA list items
+ [saResults sortUsingComparator:^NSComparisonResult(ZXResult *a, ZXResult *b) {
+ int aNumber = [a.resultMetadata[@(kResultMetadataTypeStructuredAppendSequence)] intValue];
+ int bNumber = [b.resultMetadata[@(kResultMetadataTypeStructuredAppendSequence)] intValue];
+ if (aNumber < bNumber) {
+ return NSOrderedAscending;
+ }
+ if (aNumber > bNumber) {
+ return NSOrderedDescending;
+ }
+ return NSOrderedSame;
+ }];
+ NSMutableString *concatedText = [NSMutableString string];
+ int rawBytesLen = 0;
+ int byteSegmentLength = 0;
+ for (ZXResult *saResult in saResults) {
+ [concatedText appendString:saResult.text];
+ rawBytesLen += saResult.rawBytes.length;
+ if (saResult.resultMetadata[@(kResultMetadataTypeByteSegments)]) {
+ for (ZXByteArray *segment in saResult.resultMetadata[@(kResultMetadataTypeByteSegments)]) {
+ byteSegmentLength += segment.length;
+ }
+ }
+ }
+ ZXByteArray *newRawBytes = [[ZXByteArray alloc] initWithLength:rawBytesLen];
+ ZXByteArray *newByteSegment = [[ZXByteArray alloc] initWithLength:byteSegmentLength];
+ int newRawBytesIndex = 0;
+ int byteSegmentIndex = 0;
+ for (ZXResult *saResult in saResults) {
+ memcpy(newRawBytes.array, saResult.rawBytes.array, saResult.rawBytes.length * sizeof(int8_t));
+ newRawBytesIndex += saResult.rawBytes.length;
+ if (saResult.resultMetadata[@(kResultMetadataTypeByteSegments)]) {
+ for (ZXByteArray *segment in saResult.resultMetadata[@(kResultMetadataTypeByteSegments)]) {
+ memcpy(newByteSegment.array, segment.array, segment.length * sizeof(int8_t));
+ byteSegmentIndex += segment.length;
+ }
+ }
+ }
+ ZXResult *newResult = [[ZXResult alloc] initWithText:concatedText rawBytes:newRawBytes resultPoints:@[] format:kBarcodeFormatQRCode];
+ if (byteSegmentLength > 0) {
+ NSMutableArray *byteSegmentList = [NSMutableArray array];
+ [byteSegmentList addObject:newByteSegment];
+ [newResult putMetadata:kResultMetadataTypeByteSegments value:byteSegmentList];
+ }
+ [newResults addObject:newResult];
+ return newResults;
+}
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiDetector.h b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiDetector.h
new file mode 100644
index 0000000..348b768
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/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/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiDetector.m b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiDetector.m
new file mode 100644
index 0000000..399d3ad
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/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 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 = ZXNotFoundErrorInstance();
+ 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/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.h b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.h
new file mode 100644
index 0000000..b61025a
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.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 "ZXQRCodeFinderPatternFinder.h"
+
+@class ZXDecodeHints;
+
+/**
+ * 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.
+ */
+@interface ZXMultiFinderPatternFinder : ZXQRCodeFinderPatternFinder
+
+- (NSArray *)findMulti:(ZXDecodeHints *)hints error:(NSError **)error;
+
+@end
diff --git a/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.m b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.m
new file mode 100644
index 0000000..d49f3b4
--- /dev/null
+++ b/Pods/ZXingObjC/ZXingObjC/qrcode/multi/detector/ZXMultiFinderPatternFinder.m
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2012 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "ZXMultiFinderPatternFinder.h"
+#import "ZXQRCodeFinderPattern.h"
+#import "ZXQRCodeFinderPatternInfo.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 ZX_MAX_MODULE_COUNT_PER_EDGE = 180;
+// min. legal count per modules per QR code edge (11)
+float const ZX_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 ZX_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 ZX_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 = ZXNotFoundErrorInstance();
+ return nil;
+ }
+
+ /*
+ * Begin HE modifications to safely detect multiple codes of equal size
+ */
+ if (size == 3) {
+ return @[[@[_possibleCenters[0], _possibleCenters[1], _possibleCenters[2]] mutableCopy]];
+ }
+
+ [_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 > ZX_DIFF_MODSIZE_CUTOFF && vModSize12 >= ZX_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 > ZX_DIFF_MODSIZE_CUTOFF && vModSize23 >= ZX_DIFF_MODSIZE_CUTOFF_PERCENT) {
+ break;
+ }
+
+ NSMutableArray *test = [NSMutableArray arrayWithObjects:p1, p2, p3, nil];
+ [ZXResultPoint orderBestPatterns:test];
+
+ ZXQRCodeFinderPatternInfo *info = [[ZXQRCodeFinderPatternInfo 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 > ZX_MAX_MODULE_COUNT_PER_EDGE || estimatedModuleCount < ZX_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 = ZXNotFoundErrorInstance();
+ return nil;
+}
+
+- (NSArray *)findMulti:(ZXDecodeHints *)hints error:(NSError **)error {
+ BOOL tryHarder = hints != nil && hints.tryHarder;
+ BOOL pureBarcode = hints != nil && hints.pureBarcode;
+ int maxI = self.image.height;
+ int maxJ = self.image.width;
+ // We are looking for black/white/black/white/black modules in
+ // 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 / (ZX_FINDER_PATTERN_MAX_MODULES * 4.0f) * 3);
+ if (iSkip < ZX_FINDER_PATTERN_MIN_SKIP || tryHarder) {
+ iSkip = ZX_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 ([ZXQRCodeFinderPatternFinder foundPatternCross:stateCount] && [self handlePossibleCenter:stateCount i:i j:j pureBarcode:pureBarcode]) {
+ 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 ([ZXQRCodeFinderPatternFinder foundPatternCross:stateCount]) {
+ [self handlePossibleCenter:stateCount i:i j:maxJ pureBarcode:pureBarcode];
+ }
+ }
+ NSArray *patternInfo = [self selectBestPatternsWithError:error];
+ if (!patternInfo) {
+ return nil;
+ }
+ NSMutableArray *result = [NSMutableArray array];
+ for (NSMutableArray *pattern in patternInfo) {
+ [ZXResultPoint orderBestPatterns:pattern];
+ [result addObject:[[ZXQRCodeFinderPatternInfo 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/screenshots/mbp-un_square.png b/screenshots/mbp-un_square.png
new file mode 100644
index 0000000..df352d4
Binary files /dev/null and b/screenshots/mbp-un_square.png differ
diff --git a/screenshots/screenshot1.png b/screenshots/screenshot1.png
new file mode 100644
index 0000000..3d167cb
Binary files /dev/null and b/screenshots/screenshot1.png differ