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