1eafa96e0SStanisław Chmiela// Copyright 2016-present 650 Industries. All rights reserved. 2eafa96e0SStanisław Chmiela 3fb647b1dSTomasz Sapeta#import <UIKit/UIKit.h> 4eafa96e0SStanisław Chmiela#import <AVFoundation/AVFoundation.h> 5*6185d13dSKudo Chien#import <ZXingObjC/ZXingObjCCore.h> 6eafa96e0SStanisław Chmiela#import <EXBarCodeScanner/EXBarCodeScannerUtils.h> 7eafa96e0SStanisław Chmiela 8eafa96e0SStanisław Chmiela@implementation EXBarCodeScannerUtils 9eafa96e0SStanisław Chmiela 10eafa96e0SStanisław Chmiela+ (NSDictionary *)validBarCodeTypes 11eafa96e0SStanisław Chmiela{ 125a06ec9aSUrata Daiki NSMutableDictionary *validTypes = [@{ 13eafa96e0SStanisław Chmiela @"upc_e" : AVMetadataObjectTypeUPCECode, 14eafa96e0SStanisław Chmiela @"code39" : AVMetadataObjectTypeCode39Code, 15eafa96e0SStanisław Chmiela @"code39mod43" : AVMetadataObjectTypeCode39Mod43Code, 16eafa96e0SStanisław Chmiela @"ean13" : AVMetadataObjectTypeEAN13Code, 17eafa96e0SStanisław Chmiela @"ean8" : AVMetadataObjectTypeEAN8Code, 18eafa96e0SStanisław Chmiela @"code93" : AVMetadataObjectTypeCode93Code, 19e9fe1169SCharlie Cruzan @"code128" : AVMetadataObjectTypeCode128Code, 20eafa96e0SStanisław Chmiela @"pdf417" : AVMetadataObjectTypePDF417Code, 21eafa96e0SStanisław Chmiela @"qr" : AVMetadataObjectTypeQRCode, 22eafa96e0SStanisław Chmiela @"aztec" : AVMetadataObjectTypeAztecCode, 23eafa96e0SStanisław Chmiela @"interleaved2of5" : AVMetadataObjectTypeInterleaved2of5Code, 24eafa96e0SStanisław Chmiela @"itf14" : AVMetadataObjectTypeITF14Code, 25eafa96e0SStanisław Chmiela @"datamatrix" : AVMetadataObjectTypeDataMatrixCode, 265a06ec9aSUrata Daiki } mutableCopy]; 277e5da4d1SBartłomiej Bukowski#ifdef __IPHONE_15_4 285a06ec9aSUrata Daiki if (@available(iOS 15.4, *)) { 295a06ec9aSUrata Daiki validTypes[@"codabar"] = AVMetadataObjectTypeCodabarCode; 305a06ec9aSUrata Daiki } 317e5da4d1SBartłomiej Bukowski#endif 325a06ec9aSUrata Daiki return validTypes; 33eafa96e0SStanisław Chmiela} 34eafa96e0SStanisław Chmiela 35eafa96e0SStanisław Chmiela+ (AVCaptureVideoOrientation)videoOrientationForInterfaceOrientation:(UIInterfaceOrientation)orientation 36eafa96e0SStanisław Chmiela{ 37eafa96e0SStanisław Chmiela switch (orientation) { 38eafa96e0SStanisław Chmiela case UIInterfaceOrientationPortrait: 39eafa96e0SStanisław Chmiela return AVCaptureVideoOrientationPortrait; 40eafa96e0SStanisław Chmiela case UIInterfaceOrientationPortraitUpsideDown: 41eafa96e0SStanisław Chmiela return AVCaptureVideoOrientationPortraitUpsideDown; 42eafa96e0SStanisław Chmiela case UIInterfaceOrientationLandscapeRight: 43eafa96e0SStanisław Chmiela return AVCaptureVideoOrientationLandscapeRight; 44eafa96e0SStanisław Chmiela case UIInterfaceOrientationLandscapeLeft: 45eafa96e0SStanisław Chmiela return AVCaptureVideoOrientationLandscapeLeft; 46eafa96e0SStanisław Chmiela default: 47eafa96e0SStanisław Chmiela return 0; 48eafa96e0SStanisław Chmiela } 49eafa96e0SStanisław Chmiela} 50eafa96e0SStanisław Chmiela 51eafa96e0SStanisław Chmiela+ (AVCaptureDevice *)deviceWithMediaType:(AVMediaType)mediaType 52eafa96e0SStanisław Chmiela preferringPosition:(AVCaptureDevicePosition)position 53eafa96e0SStanisław Chmiela{ 546a392fcaSStanisław Chmiela return [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:mediaType position:position]; 55eafa96e0SStanisław Chmiela} 56eafa96e0SStanisław Chmiela 57bd4c8242SŁukasz Kosmaty+ (NSDictionary *)ciQRCodeFeatureToDicitionary:(CIQRCodeFeature *)barCodeScannerResult barCodeType:(NSString *)type 58bd4c8242SŁukasz Kosmaty{ 59bd4c8242SŁukasz Kosmaty NSMutableDictionary *result = [NSMutableDictionary new]; 60bd4c8242SŁukasz Kosmaty result[@"type"] = type; 61bd4c8242SŁukasz Kosmaty result[@"data"] = barCodeScannerResult.messageString; 62bd4c8242SŁukasz Kosmaty 63bd4c8242SŁukasz Kosmaty if (!CGRectIsEmpty(barCodeScannerResult.bounds)) { 64bd4c8242SŁukasz Kosmaty NSMutableArray<NSDictionary *> *cornerPointsResult = [NSMutableArray new]; 65bd4c8242SŁukasz Kosmaty for (NSValue *nsPoint in @[ 66bd4c8242SŁukasz Kosmaty [NSValue valueWithCGPoint:barCodeScannerResult.topLeft], 67bd4c8242SŁukasz Kosmaty [NSValue valueWithCGPoint:barCodeScannerResult.topRight], 68bd4c8242SŁukasz Kosmaty [NSValue valueWithCGPoint:barCodeScannerResult.bottomRight], 69bd4c8242SŁukasz Kosmaty [NSValue valueWithCGPoint:barCodeScannerResult.bottomLeft] 70bd4c8242SŁukasz Kosmaty ]) { 71bd4c8242SŁukasz Kosmaty CGPoint point = [nsPoint CGPointValue]; 72bd4c8242SŁukasz Kosmaty [cornerPointsResult addObject:@{ 73bd4c8242SŁukasz Kosmaty @"x": @(point.x), 74bd4c8242SŁukasz Kosmaty @"y": @(point.y) 75bd4c8242SŁukasz Kosmaty }]; 76bd4c8242SŁukasz Kosmaty } 77bd4c8242SŁukasz Kosmaty 78bd4c8242SŁukasz Kosmaty result[@"cornerPoints"] = cornerPointsResult; 79bd4c8242SŁukasz Kosmaty result[@"bounds"] = @{ 80bd4c8242SŁukasz Kosmaty @"origin": @{ 81bd4c8242SŁukasz Kosmaty @"x": @(barCodeScannerResult.bounds.origin.x), 82bd4c8242SŁukasz Kosmaty @"y": @(barCodeScannerResult.bounds.origin.y), 83bd4c8242SŁukasz Kosmaty }, 84bd4c8242SŁukasz Kosmaty @"size": @{ 85bd4c8242SŁukasz Kosmaty @"width": @(barCodeScannerResult.bounds.size.width), 86bd4c8242SŁukasz Kosmaty @"height": @(barCodeScannerResult.bounds.size.height), 87bd4c8242SŁukasz Kosmaty } 88bd4c8242SŁukasz Kosmaty }; 89d0d8198eSŁukasz Kosmaty } else { 90d0d8198eSŁukasz Kosmaty [EXBarCodeScannerUtils addEmptyCornerPoints:result]; 91bd4c8242SŁukasz Kosmaty } 92bd4c8242SŁukasz Kosmaty 93bd4c8242SŁukasz Kosmaty return result; 94bd4c8242SŁukasz Kosmaty} 95bd4c8242SŁukasz Kosmaty 96bd4c8242SŁukasz Kosmaty+ (NSDictionary *)avMetadataCodeObjectToDicitionary:(AVMetadataMachineReadableCodeObject *)barCodeScannerResult 97bd4c8242SŁukasz Kosmaty{ 98bd4c8242SŁukasz Kosmaty NSMutableDictionary *result = [NSMutableDictionary new]; 99bd4c8242SŁukasz Kosmaty result[@"type"] = barCodeScannerResult.type; 100bd4c8242SŁukasz Kosmaty result[@"data"] = barCodeScannerResult.stringValue; 101bd4c8242SŁukasz Kosmaty 102bd4c8242SŁukasz Kosmaty if (barCodeScannerResult.corners.count) { 103bd4c8242SŁukasz Kosmaty NSMutableArray<NSDictionary *> *cornerPointsResult = [NSMutableArray new]; 104bd4c8242SŁukasz Kosmaty for (NSDictionary *point in barCodeScannerResult.corners) { 105bd4c8242SŁukasz Kosmaty [cornerPointsResult addObject:@{ 106bd4c8242SŁukasz Kosmaty @"x": point[@"X"], 107bd4c8242SŁukasz Kosmaty @"y": point[@"Y"] 108bd4c8242SŁukasz Kosmaty }]; 109bd4c8242SŁukasz Kosmaty } 110bd4c8242SŁukasz Kosmaty result[@"cornerPoints"] = cornerPointsResult; 111bd4c8242SŁukasz Kosmaty result[@"bounds"] = @{ 112bd4c8242SŁukasz Kosmaty @"origin": @{ 113bd4c8242SŁukasz Kosmaty @"x": @(barCodeScannerResult.bounds.origin.x), 114bd4c8242SŁukasz Kosmaty @"y": @(barCodeScannerResult.bounds.origin.y), 115bd4c8242SŁukasz Kosmaty }, 116bd4c8242SŁukasz Kosmaty @"size": @{ 117bd4c8242SŁukasz Kosmaty @"width": @(barCodeScannerResult.bounds.size.width), 118bd4c8242SŁukasz Kosmaty @"height": @(barCodeScannerResult.bounds.size.height), 119bd4c8242SŁukasz Kosmaty } 120bd4c8242SŁukasz Kosmaty }; 121d0d8198eSŁukasz Kosmaty } else { 122d0d8198eSŁukasz Kosmaty [EXBarCodeScannerUtils addEmptyCornerPoints:result]; 123bd4c8242SŁukasz Kosmaty } 124bd4c8242SŁukasz Kosmaty return result; 125bd4c8242SŁukasz Kosmaty} 126bd4c8242SŁukasz Kosmaty 127bd4c8242SŁukasz Kosmaty+ (NSDictionary *)zxResultToDicitionary:(ZXResult *)barCodeScannerResult 128bd4c8242SŁukasz Kosmaty{ 129bd4c8242SŁukasz Kosmaty NSMutableDictionary *result = [NSMutableDictionary new]; 130bd4c8242SŁukasz Kosmaty result[@"type"] = [EXBarCodeScannerUtils zxingFormatToString:barCodeScannerResult.barcodeFormat]; 131bd4c8242SŁukasz Kosmaty 132bd4c8242SŁukasz Kosmaty // text contains characteres u'\0' (null character) that malforme resulting string, so we get rid of them 133bd4c8242SŁukasz Kosmaty NSMutableString* data = [NSMutableString new]; 134bd4c8242SŁukasz Kosmaty for (int i = 0; i < [barCodeScannerResult.text length]; i++) { 135bd4c8242SŁukasz Kosmaty if ([barCodeScannerResult.text characterAtIndex:i] != u'\0') { 136bd4c8242SŁukasz Kosmaty [data appendFormat:@"%c", [barCodeScannerResult.text characterAtIndex:i]]; 137bd4c8242SŁukasz Kosmaty } 138bd4c8242SŁukasz Kosmaty } 139bd4c8242SŁukasz Kosmaty result[@"data"] = data; 140bd4c8242SŁukasz Kosmaty 141bd4c8242SŁukasz Kosmaty return result; 142bd4c8242SŁukasz Kosmaty} 143bd4c8242SŁukasz Kosmaty 144bd4c8242SŁukasz Kosmaty+ (NSString *)zxingFormatToString:(ZXBarcodeFormat)format 145bd4c8242SŁukasz Kosmaty{ 146bd4c8242SŁukasz Kosmaty switch (format) { 147bd4c8242SŁukasz Kosmaty case kBarcodeFormatPDF417: 148bd4c8242SŁukasz Kosmaty return AVMetadataObjectTypePDF417Code; 149bd4c8242SŁukasz Kosmaty case kBarcodeFormatCode39: 150bd4c8242SŁukasz Kosmaty return AVMetadataObjectTypeCode39Code; 1515a06ec9aSUrata Daiki case kBarcodeFormatCodabar: 1527e5da4d1SBartłomiej Bukowski#ifdef __IPHONE_15_4 1535a06ec9aSUrata Daiki if (@available(iOS 15.4, *)) { 1545a06ec9aSUrata Daiki return AVMetadataObjectTypeCodabarCode; 1555a06ec9aSUrata Daiki } 1567e5da4d1SBartłomiej Bukowski#endif 1577e5da4d1SBartłomiej Bukowski return @"unknown"; 158bd4c8242SŁukasz Kosmaty default: 159bd4c8242SŁukasz Kosmaty return @"unknown"; 160bd4c8242SŁukasz Kosmaty } 161bd4c8242SŁukasz Kosmaty} 162bd4c8242SŁukasz Kosmaty 163d0d8198eSŁukasz Kosmaty+ (void)addEmptyCornerPoints:(NSMutableDictionary *)result 164d0d8198eSŁukasz Kosmaty{ 165d0d8198eSŁukasz Kosmaty result[@"cornerPoints"] = @[]; 166d0d8198eSŁukasz Kosmaty result[@"bounds"] = @{ 167d0d8198eSŁukasz Kosmaty @"origin": @{ 168d0d8198eSŁukasz Kosmaty @"x": @(0), 169d0d8198eSŁukasz Kosmaty @"y": @(0), 170d0d8198eSŁukasz Kosmaty }, 171d0d8198eSŁukasz Kosmaty @"size": @{ 172d0d8198eSŁukasz Kosmaty @"width": @(0), 173d0d8198eSŁukasz Kosmaty @"height": @(0), 174d0d8198eSŁukasz Kosmaty } 175d0d8198eSŁukasz Kosmaty }; 176d0d8198eSŁukasz Kosmaty} 177d0d8198eSŁukasz Kosmaty 178eafa96e0SStanisław Chmiela@end 179