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