blob: df191b3f1746c32678175bdbc44956b636e53821 [file] [log] [blame]
/*
* Copyright 2012 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "ZXBarcodeFormat.h"
#import "ZXBinaryBitmap.h"
#import "ZXBitMatrix.h"
#import "ZXDecodeHints.h"
#import "ZXDecoderResult.h"
#import "ZXDetectorResult.h"
#import "ZXErrors.h"
#import "ZXPDF417Common.h"
#import "ZXPDF417Detector.h"
#import "ZXPDF417DetectorResult.h"
#import "ZXPDF417Reader.h"
#import "ZXPDF417ResultMetadata.h"
#import "ZXPDF417ScanningDecoder.h"
#import "ZXResult.h"
#import "ZXResultPoint.h"
@implementation ZXPDF417Reader
/**
* Locates and decodes a PDF417 code in an image.
*/
- (ZXResult *)decode:(ZXBinaryBitmap *)image error:(NSError **)error {
return [self decode:image hints:nil error:error];
}
- (ZXResult *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
NSArray *result = [self decode:image hints:hints multiple:NO error:error];
if (!result || result.count == 0 || !result[0]) {
if (error) *error = NotFoundErrorInstance();
return nil;
}
return result[0];
}
- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image error:(NSError **)error {
return [self decodeMultiple:image hints:nil error:error];
}
- (NSArray *)decodeMultiple:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints error:(NSError **)error {
return [self decode:image hints:hints multiple:YES error:error];
}
- (NSArray *)decode:(ZXBinaryBitmap *)image hints:(ZXDecodeHints *)hints multiple:(BOOL)multiple error:(NSError **)error {
NSMutableArray *results = [NSMutableArray array];
ZXPDF417DetectorResult *detectorResult = [ZXPDF417Detector detect:image hints:hints multiple:multiple error:error];
if (!detectorResult) {
return nil;
}
for (NSArray *points in detectorResult.points) {
ZXResultPoint *imageTopLeft = points[4] == [NSNull null] ? nil : points[4];
ZXResultPoint *imageBottomLeft = points[5] == [NSNull null] ? nil : points[5];
ZXResultPoint *imageTopRight = points[6] == [NSNull null] ? nil : points[6];
ZXResultPoint *imageBottomRight = points[7] == [NSNull null] ? nil : points[7];
ZXDecoderResult *decoderResult = [ZXPDF417ScanningDecoder decode:detectorResult.bits
imageTopLeft:imageTopLeft
imageBottomLeft:imageBottomLeft
imageTopRight:imageTopRight
imageBottomRight:imageBottomRight
minCodewordWidth:[self minCodewordWidth:points]
maxCodewordWidth:[self maxCodewordWidth:points]];
if (!decoderResult) {
return nil;
}
ZXResult *result = [[ZXResult alloc] initWithText:decoderResult.text rawBytes:decoderResult.rawBytes
length:decoderResult.length resultPoints:points format:kBarcodeFormatPDF417];
[result putMetadata:kResultMetadataTypeErrorCorrectionLevel value:decoderResult.ecLevel];
ZXPDF417ResultMetadata *pdf417ResultMetadata = decoderResult.other;
if (pdf417ResultMetadata) {
[result putMetadata:kResultMetadataTypePDF417ExtraMetadata value:pdf417ResultMetadata];
}
[results addObject:result];
}
return [NSArray arrayWithArray:results];
}
- (int)maxWidth:(ZXResultPoint *)p1 p2:(ZXResultPoint *)p2 {
if (!p1 || !p2 || (id)p1 == [NSNull null] || p2 == (id)[NSNull null]) {
return 0;
}
return abs(p1.x - p2.x);
}
- (int)minWidth:(ZXResultPoint *)p1 p2:(ZXResultPoint *)p2 {
if (!p1 || !p2 || (id)p1 == [NSNull null] || p2 == (id)[NSNull null]) {
return INT_MAX;
}
return abs(p1.x - p2.x);
}
- (int)maxCodewordWidth:(NSArray *)p {
return MAX(
MAX([self maxWidth:p[0] p2:p[4]], [self maxWidth:p[6] p2:p[2]] * ZXPDF417_MODULES_IN_CODEWORD /
ZXPDF417_MODULES_IN_STOP_PATTERN),
MAX([self maxWidth:p[1] p2:p[5]], [self maxWidth:p[7] p2:p[3]] * ZXPDF417_MODULES_IN_CODEWORD /
ZXPDF417_MODULES_IN_STOP_PATTERN));
}
- (int)minCodewordWidth:(NSArray *)p {
return MIN(
MIN([self minWidth:p[0] p2:p[4]], [self minWidth:p[6] p2:p[2]] * ZXPDF417_MODULES_IN_CODEWORD /
ZXPDF417_MODULES_IN_STOP_PATTERN),
MIN([self minWidth:p[1] p2:p[5]], [self minWidth:p[7] p2:p[3]] * ZXPDF417_MODULES_IN_CODEWORD /
ZXPDF417_MODULES_IN_STOP_PATTERN));
}
- (void)reset {
// nothing needs to be reset
}
@end