123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- /*
- * Copyright 2012 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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
|