1// Copyright 2016-present 650 Industries. All rights reserved.
2
3#import <UIKit/UIKit.h>
4#import <AVFoundation/AVFoundation.h>
5#import <EXBarCodeScanner/EXBarCodeScannerUtils.h>
6
7@implementation EXBarCodeScannerUtils
8
9+ (NSDictionary *)validBarCodeTypes
10{
11  return @{
12           @"upc_e" : AVMetadataObjectTypeUPCECode,
13           @"code39" : AVMetadataObjectTypeCode39Code,
14           @"code39mod43" : AVMetadataObjectTypeCode39Mod43Code,
15           @"ean13" : AVMetadataObjectTypeEAN13Code,
16           @"ean8" : AVMetadataObjectTypeEAN8Code,
17           @"code93" : AVMetadataObjectTypeCode93Code,
18           @"code128" : AVMetadataObjectTypeCode128Code,
19           @"pdf417" : AVMetadataObjectTypePDF417Code,
20           @"qr" : AVMetadataObjectTypeQRCode,
21           @"aztec" : AVMetadataObjectTypeAztecCode,
22           @"interleaved2of5" : AVMetadataObjectTypeInterleaved2of5Code,
23           @"itf14" : AVMetadataObjectTypeITF14Code,
24           @"datamatrix" : AVMetadataObjectTypeDataMatrixCode,
25           };
26}
27
28+ (AVCaptureVideoOrientation)videoOrientationForInterfaceOrientation:(UIInterfaceOrientation)orientation
29{
30  switch (orientation) {
31    case UIInterfaceOrientationPortrait:
32      return AVCaptureVideoOrientationPortrait;
33    case UIInterfaceOrientationPortraitUpsideDown:
34      return AVCaptureVideoOrientationPortraitUpsideDown;
35    case UIInterfaceOrientationLandscapeRight:
36      return AVCaptureVideoOrientationLandscapeRight;
37    case UIInterfaceOrientationLandscapeLeft:
38      return AVCaptureVideoOrientationLandscapeLeft;
39    default:
40      return 0;
41  }
42}
43
44+ (AVCaptureDevice *)deviceWithMediaType:(AVMediaType)mediaType
45                      preferringPosition:(AVCaptureDevicePosition)position
46{
47  return [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:mediaType position:position];
48}
49
50+ (NSDictionary *)ciQRCodeFeatureToDicitionary:(CIQRCodeFeature *)barCodeScannerResult barCodeType:(NSString *)type
51{
52  NSMutableDictionary *result = [NSMutableDictionary new];
53  result[@"type"] = type;
54  result[@"data"] = barCodeScannerResult.messageString;
55
56  if (!CGRectIsEmpty(barCodeScannerResult.bounds)) {
57    NSMutableArray<NSDictionary *> *cornerPointsResult = [NSMutableArray new];
58    for (NSValue *nsPoint in @[
59      [NSValue valueWithCGPoint:barCodeScannerResult.topLeft],
60      [NSValue valueWithCGPoint:barCodeScannerResult.topRight],
61      [NSValue valueWithCGPoint:barCodeScannerResult.bottomRight],
62      [NSValue valueWithCGPoint:barCodeScannerResult.bottomLeft]
63    ]) {
64      CGPoint point = [nsPoint CGPointValue];
65      [cornerPointsResult addObject:@{
66        @"x": @(point.x),
67        @"y": @(point.y)
68      }];
69    }
70
71    result[@"cornerPoints"] = cornerPointsResult;
72    result[@"bounds"] = @{
73      @"origin": @{
74          @"x": @(barCodeScannerResult.bounds.origin.x),
75          @"y": @(barCodeScannerResult.bounds.origin.y),
76      },
77      @"size": @{
78          @"width": @(barCodeScannerResult.bounds.size.width),
79          @"height": @(barCodeScannerResult.bounds.size.height),
80      }
81    };
82  }
83
84  return result;
85}
86
87+ (NSDictionary *)avMetadataCodeObjectToDicitionary:(AVMetadataMachineReadableCodeObject *)barCodeScannerResult
88{
89  NSMutableDictionary *result = [NSMutableDictionary new];
90  result[@"type"] = barCodeScannerResult.type;
91  result[@"data"] = barCodeScannerResult.stringValue;
92
93  if (barCodeScannerResult.corners.count) {
94    NSMutableArray<NSDictionary *> *cornerPointsResult = [NSMutableArray new];
95    for (NSDictionary *point in barCodeScannerResult.corners) {
96      [cornerPointsResult addObject:@{
97        @"x": point[@"X"],
98        @"y": point[@"Y"]
99      }];
100    }
101    result[@"cornerPoints"] = cornerPointsResult;
102    result[@"bounds"] = @{
103      @"origin": @{
104          @"x": @(barCodeScannerResult.bounds.origin.x),
105          @"y": @(barCodeScannerResult.bounds.origin.y),
106      },
107      @"size": @{
108          @"width": @(barCodeScannerResult.bounds.size.width),
109          @"height": @(barCodeScannerResult.bounds.size.height),
110      }
111    };
112  }
113  return result;
114}
115
116+ (NSDictionary *)zxResultToDicitionary:(ZXResult *)barCodeScannerResult
117{
118  NSMutableDictionary *result = [NSMutableDictionary new];
119  result[@"type"] = [EXBarCodeScannerUtils zxingFormatToString:barCodeScannerResult.barcodeFormat];
120
121  // text contains characteres u'\0' (null character) that malforme resulting string, so we get rid of them
122  NSMutableString* data = [NSMutableString new];
123  for (int i = 0; i < [barCodeScannerResult.text length]; i++) {
124    if ([barCodeScannerResult.text characterAtIndex:i] != u'\0') {
125      [data appendFormat:@"%c", [barCodeScannerResult.text characterAtIndex:i]];
126    }
127  }
128  result[@"data"] = data;
129
130  return result;
131}
132
133+ (NSString *)zxingFormatToString:(ZXBarcodeFormat)format
134{
135  switch (format) {
136    case kBarcodeFormatPDF417:
137      return AVMetadataObjectTypePDF417Code;
138    case kBarcodeFormatCode39:
139      return AVMetadataObjectTypeCode39Code;
140    default:
141      return @"unknown";
142  }
143}
144
145@end
146