Skip to content
This repository was archived by the owner on Jan 12, 2019. It is now read-only.

Experiments with bisector models #11

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b2f7d60
more experiments with bisector models (disappointing!)
Feb 17, 2015
299be2c
update dmz
Feb 19, 2015
83830e4
update dmz (prevent random expiry results when !SCAN_EXPIRY)
Feb 24, 2015
5e83722
5.0.2: update release notes, podspec
Feb 24, 2015
1b86e81
update dmz
Feb 26, 2015
aa76592
simplify hseg/vseg-passing from dmz layer
Feb 27, 2015
b863b8f
update to Xcode 6.2
Mar 12, 2015
c8c6e29
eliminate visible stutter on canceling the scan
Mar 12, 2015
a41ca93
reset to default focus range restriction when done
Mar 17, 2015
a701ea2
5.0.3: update release notes, podspec
Mar 17, 2015
7d37398
update dmz
Mar 20, 2015
ceb248f
check video permissions before presenting camera view
Mar 28, 2015
206dfc3
add compiler flag to theoretically improve performance
Apr 7, 2015
5e095d7
update to latest dmz
Apr 14, 2015
16c854a
format incoming expiry strings a teensy bit more robustly
Apr 14, 2015
ff60f08
restrict expiry year manual input to 2 digits
Apr 14, 2015
1cf602c
5.0.4: update release notes, podspec
Apr 14, 2015
af3f64e
tweak storyboard for Swift sample app
Apr 15, 2015
64c573e
update to Xcode 6.3
Apr 16, 2015
a92752c
prevent compiler warnings for arm64 (re NEON flags)
Apr 16, 2015
c553a85
update dmz
Apr 24, 2015
3872076
first draft of some expiry documentation
Apr 24, 2015
5b7a3c1
expiry doc: several edits
Apr 24, 2015
eae8781
expiry doc: new illustrations
Apr 27, 2015
da570a4
expiry doc: a few tweaks
Apr 27, 2015
dabc2b7
expiry doc: another tweak
Apr 27, 2015
71f533e
expiry docs: move into dmz submodule
Apr 27, 2015
7f9cc78
IplImage -> UIImage: minor fix
Apr 27, 2015
dee7e51
update to latest dmz
Apr 27, 2015
96f769f
more experiments with bisector models (disappointing!)
Feb 17, 2015
d4f3e68
Merge branch 'feature/bisector-models' of github.com:card-io/card.io-…
Apr 27, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 10 additions & 19 deletions Classes/CardIOCardScanner.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ @interface CardIOCardScanner ()
@property(assign, readwrite) ScannerState scannerState;
@property(strong, readwrite) CardIOReadCardInfo *cardInfoCache;
@property(assign, readwrite) BOOL cardInfoCacheDirty;
@property(strong, readwrite) NSArray *xOffsets;
@property(assign, readwrite) uint16_t yOffset;
@property(assign, readwrite) BOOL lastFrameWasUsable;
@property(assign, readwrite) BOOL lastFrameWasUpsideDown;
@property(assign, readwrite) BOOL scanIsComplete;
Expand Down Expand Up @@ -67,7 +65,6 @@ - (void)addFrame:(CardIOIplImage *)y
}

FrameScanResult result;
bool collectCardNumber = (_scannerState.timeOfCardNumberCompletionInMilliseconds == 0);

// A little bit of a hack, but we prepopulate focusScore and brightness information
result.focus_score = focusScore;
Expand All @@ -79,20 +76,8 @@ - (void)addFrame:(CardIOIplImage *)y
result.flipped = flipped;
scanner_add_frame_with_expiry(&_scannerState, y.image, scanExpiry, &result);
self.lastFrameWasUsable = result.usable;
if (collectCardNumber) {
if(result.usable) {
NSMutableArray *x = [NSMutableArray arrayWithCapacity:result.hseg.n_offsets];
for(uint8_t i = 0; i < result.hseg.n_offsets; i++) {
NSNumber *xOffset = [NSNumber numberWithUnsignedShort:result.hseg.offsets[i]];
[x addObject:xOffset];
}
self.xOffsets = x;
self.yOffset = result.vseg.y_offset;
} else {
self.lastFrameWasUpsideDown = result.upside_down;
self.xOffsets = nil;
self.yOffset = 0;
}
if(!result.usable) {
self.lastFrameWasUpsideDown = result.upside_down;
}
[self markCachesDirty];
}
Expand Down Expand Up @@ -156,9 +141,15 @@ - (CardIOReadCardInfo *)cardInfo {
}
#endif

NSMutableArray *xOffsets = [NSMutableArray arrayWithCapacity:result.hseg.n_offsets];
for(uint8_t i = 0; i < result.hseg.n_offsets; i++) {
NSNumber *xOffset = [NSNumber numberWithUnsignedShort:result.hseg.offsets[i]];
[xOffsets addObject:xOffset];
}

self.cardInfoCache = [CardIOReadCardInfo cardInfoWithNumber:cardNumber
xOffsets:self.xOffsets
yOffset:self.yOffset
xOffsets:xOffsets
yOffset:result.vseg.y_offset
expiryMonth:result.expiry_month
expiryYear:result.expiry_year
#if CARDIO_DEBUG
Expand Down
7 changes: 4 additions & 3 deletions Classes/CardIOCreditCardExpiryFormatter.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#import "CardIOCreditCardExpiryFormatter.h"
#import "CardIOCreditCardInfo.h"
#import "CardIOCreditCardNumber.h"

@implementation CardIOCreditCardExpiryFormatter

Expand All @@ -16,12 +17,12 @@ - (BOOL)getObjectValue:(id __autoreleasing *)obj forString:(NSString *)string er
NSInteger year = 0;

if (values.count > 0) {
month = [[values[0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] integerValue];
month = [[CardIOCreditCardNumber stringByRemovingNonNumbers:values[0]] integerValue];
}
if (values.count > 1) {
year = [[values[1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] integerValue];
year = [[CardIOCreditCardNumber stringByRemovingNonNumbers:values[1]] integerValue];
if (year < 2000) {
year += 2000;
year = 2000 + (year % 100);
}
}

Expand Down
5 changes: 3 additions & 2 deletions Classes/CardIOExpiryTextFieldDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRang

NSString *numericNewText = [CardIOCreditCardNumber stringByRemovingNonNumbers:newText];
NSString *updatedText = [textField.text stringByReplacingCharactersInRange:range withString:numericNewText];
if(updatedText.length > 9) {
if(updatedText.length > 7) {
// 7 characters: "MM_/_YY"
[CardIOConfigurableTextFieldDelegate vibrate];
return NO;
}
Expand All @@ -104,7 +105,7 @@ - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRang
NSString *monthStr = [updatedNumberText substringToIndex:MIN(2, updatedNumberText.length)];
if(monthStr.length > 0) {
NSInteger month = [monthStr integerValue];
if(month < 0 || 12 < month) {
if(month < 0 || month > 12) {
[CardIOConfigurableTextFieldDelegate vibrate];
return NO;
}
Expand Down
5 changes: 3 additions & 2 deletions Classes/CardIOIplImage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,13 @@ - (UIImage *)UIImage {
} else if(self.image->nChannels == 3) {
colorSpace = CGColorSpaceCreateDeviceRGB();
}
int depth = self.image->depth & ~IPL_DEPTH_SIGN;
NSData *data = [NSData dataWithBytes:self.image->imageData length:self.image->imageSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
CGImageRef imageRef = CGImageCreate(self.image->width,
self.image->height,
self.image->depth,
self.image->depth * self.image->nChannels,
depth,
depth * self.image->nChannels,
self.image->widthStep,
colorSpace,
kCGImageAlphaNone | kCGBitmapByteOrderDefault,
Expand Down
27 changes: 27 additions & 0 deletions Classes/CardIOUtilities.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
#import "CardIOGPUGaussianBlurFilter.h"
#import "CardIOIccVersion.h"
#import "CardIOLocalizer.h"
#import "CardIOMacros.h"
#import "CardIOView.h"

#import <AVFoundation/AVFoundation.h>

@implementation CardIOUtilities

#pragma mark - Library version, for bug reporting etc.
Expand Down Expand Up @@ -70,6 +73,30 @@ + (BOOL)canReadCardWithCamera {
cachedScanAvailabilityStatus = ScanAvailabilityNever;
return NO;
}

if (iOS_7_PLUS) {
// Check for video permission.
// But don't set cachedScanAvailabilityStatus here, as the user can change this permission at any time.
// (Actually, should the user go to Settings and change this permission for this app, apparently the system
// will immediately SIGKILL (force restart) this app. But let's not depend on this semi-documented behavior.)
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authStatus == AVAuthorizationStatusDenied || authStatus == AVAuthorizationStatusRestricted){
return NO;
}
else {
// Either the user has already granted permission, or else the user has not yet been asked.
//
// For the latter case, while we could ask now, unfortunately the necessary
// [AVCaptureDevice requestAccessForMediaType:completionHandler:] method returns the user's choice
// to us asynchronously, which doesn't mix well with canReadCardWithCamera being synchronous.
//
// Rather than making a backward-incompatible change to canReadCardWithCamera, let's simply allow things
// to proceed. When the camera view is finally presented, then the user will be prompted to authorize
// or deny the video permission. If they choose "deny", then they'll probably understand why they're
// looking at a black screen.
return YES;
}
}
#endif

cachedScanAvailabilityStatus = ScanAvailabilityAlways;
Expand Down
15 changes: 15 additions & 0 deletions Classes/CardIOVideoStream.mm
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,21 @@ - (void)startSession {

- (void)stopSession {
if (self.running) {
#if USE_CAMERA
[self changeCameraConfiguration:^{
// restore default focus range
if ([self.camera respondsToSelector:@selector(isAutoFocusRangeRestrictionSupported)]) {
if(self.camera.autoFocusRangeRestrictionSupported) {
self.camera.autoFocusRangeRestriction = AVCaptureAutoFocusRangeRestrictionNone;
}
}
}
#if CARDIO_DEBUG
withErrorMessage:@"CardIO couldn't lock for configuration within stopSession"
#endif
];
#endif

dispatch_semaphore_wait(self.cameraConfigurationSemaphore, DISPATCH_TIME_FOREVER);

#if USE_CAMERA
Expand Down
4 changes: 4 additions & 0 deletions Classes/CardIOViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,10 @@ - (void)manualEntry:(id)sender {

- (void)cancel:(id)sender {
[self.context.scanReport reportEventWithLabel:@"scan_cancel" withScanner:self.cardIOView.scanner];

// Hiding the CardIOView causes it to call its stopSession method, thus eliminating a visible stutter.
// See https://github.com/card-io/card.io-iOS-SDK/issues/97
self.cardIOView.hidden = YES;

[self.navigationController setNavigationBarHidden:NO animated:YES]; // to restore the color of the status bar!

Expand Down
2 changes: 1 addition & 1 deletion Release/CardIO.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = 'CardIO'
spec.version = '5.0.1'
spec.version = '5.0.4'
spec.license = { type: 'MIT', file: 'LICENSE.md' }
spec.homepage = 'https://www.card.io'
spec.authors = { 'CardIO' => '[email protected]' }
Expand Down
22 changes: 15 additions & 7 deletions Release/SampleApp-Swift/SampleApp-Swift/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6751" systemVersion="13F1077" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6736"/>
</dependencies>
<scenes>
<!--View Controller-->
Expand All @@ -23,11 +23,11 @@
<constraint firstAttribute="width" constant="300" id="saB-lV-1Ja"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6wu-dt-vfp">
<rect key="frame" x="264" y="50" width="73" height="30"/>
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6wu-dt-vfp">
<rect key="frame" x="264" y="75" width="73" height="25"/>
<state key="normal" title="Scan Card">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
Expand All @@ -39,10 +39,18 @@
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="centerX" secondItem="RN3-ZX-uyW" secondAttribute="centerX" id="9NV-Wg-jNb"/>
<constraint firstItem="RN3-ZX-uyW" firstAttribute="top" secondItem="6wu-dt-vfp" secondAttribute="bottom" constant="8" symbolic="YES" id="Gc5-Cp-AzK"/>
<constraint firstAttribute="centerY" secondItem="RN3-ZX-uyW" secondAttribute="centerY" constant="74" id="IpO-6t-Ids"/>
<constraint firstAttribute="centerX" secondItem="6wu-dt-vfp" secondAttribute="centerX" id="Vpq-hA-5Ve"/>
<constraint firstItem="RN3-ZX-uyW" firstAttribute="top" secondItem="6wu-dt-vfp" secondAttribute="bottom" constant="8" id="opr-g8-aEN"/>
<constraint firstAttribute="centerX" secondItem="6wu-dt-vfp" secondAttribute="centerX" id="QG3-P9-yf4"/>
<constraint firstItem="6wu-dt-vfp" firstAttribute="centerX" secondItem="RN3-ZX-uyW" secondAttribute="centerX" id="Uh4-u3-RjP"/>
<constraint firstItem="6wu-dt-vfp" firstAttribute="top" secondItem="8bC-Xf-vdC" secondAttribute="top" constant="75" id="u8l-Wq-ERk"/>
</constraints>
<variation key="default">
<mask key="constraints">
<exclude reference="Gc5-Cp-AzK"/>
<exclude reference="Uh4-u3-RjP"/>
</mask>
</variation>
</view>
<connections>
<outlet property="resultLabel" destination="RN3-ZX-uyW" id="jVY-aE-csY"/>
Expand Down
24 changes: 24 additions & 0 deletions Release/release_notes.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
card.io iOS SDK release notes
=============================

5.0.4 (Tue 4/14/2015)

* Check existing video permissions before presenting camera view.
(https://github.com/card-io/card.io-iOS-SDK/issues/99)
* Restrict expiry year manual input to 2 digits in all cases.
(https://github.com/card-io/card.io-iOS-SDK/issues/104)

--

5.0.3 (Tue 3/17/2015)

* On scan cancelation, eliminate a visual stutter.
(https://github.com/card-io/card.io-iOS-SDK/issues/97)
* On scan completion, reset camera focus range to nonrestricted.
(https://github.com/card-io/card.io-iOS-source/issues/17)

--

5.0.2 (Mon 2/23/2015)

* Re-enable expiry-scanning for 32-bit devices (e.g., iPhone 4S).

--

5.0.1 (Tue 2/10/2015)

* Simplify expiry-scanning code to improve accuracy and also decrease library size a bit.
Expand Down
2 changes: 1 addition & 1 deletion dmz
Submodule dmz updated 277 files
Loading