Issue 479
authorsmparkes@smparkes.net <smparkes@smparkes.net@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Tue, 17 Aug 2010 21:18:56 +0000 (21:18 +0000)
committersmparkes@smparkes.net <smparkes@smparkes.net@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Tue, 17 Aug 2010 21:18:56 +0000 (21:18 +0000)
Note, the audio no longer plays. I'm pretty sure this is because the widget is dismissed immediately
and the sound is released before it is played. I'm thinkng audio feedback should be done by the caller.

git-svn-id: http://zxing.googlecode.com/svn/trunk@1546 59b500cc-1b3d-0410-9834-0bbf25fbcc57

14 files changed:
iphone/ScanTest/Classes/RootViewController.h
iphone/ScanTest/Classes/RootViewController.mm
iphone/ScanTest/ScanTest.xcodeproj/project.pbxproj
iphone/ZXingWidget/Classes/Decoder.h
iphone/ZXingWidget/Classes/Decoder.mm
iphone/ZXingWidget/Classes/DecoderDelegate.h
iphone/ZXingWidget/Classes/FormatReader.h
iphone/ZXingWidget/Classes/FormatReader.mm
iphone/ZXingWidget/Classes/OverlayView.h
iphone/ZXingWidget/Classes/OverlayView.m
iphone/ZXingWidget/Classes/ZXingWidgetController.h
iphone/ZXingWidget/Classes/ZXingWidgetController.m
iphone/ZXingWidget/Classes/resultParsers/ResultParser.h
iphone/ZXingWidget/ZXingWidget.xcodeproj/project.pbxproj

index 4da7839..ff2c434 100644 (file)
 #import "ZXingWidgetController.h"
 
 @interface RootViewController : UIViewController <ZXingDelegate> {
-       IBOutlet UITextView *resultsView;
+  IBOutlet UITextView *resultsView;
   NSString *resultsToDisplay;
 }
 @property (nonatomic, retain) IBOutlet UITextView *resultsView;
-@property (nonatomic, retain) NSString *resultsToDisplay;
+@property (nonatomic, copy) NSString *resultsToDisplay;
 
 - (IBAction)scanPressed:(id)sender;
 @end
index a0c3b60..52ce404 100644 (file)
@@ -23,7 +23,8 @@
 
 - (void)viewDidLoad {
   [super viewDidLoad];
-       [self setTitle:@"ZXing"];
+  [self setTitle:@"ZXing"];
+  [resultsView setText:resultsToDisplay];
 }
 
 - (IBAction)scanPressed:(id)sender {
   widController.readers = readers;
   [readers release];
   NSBundle *mainBundle = [NSBundle mainBundle];
-       [widController setSoundToPlay:[[NSURL fileURLWithPath:[mainBundle pathForResource:@"beep-beep" ofType:@"aiff"] isDirectory:NO] retain]];
-  [self presentModalViewController:widController
-                          animated:YES];
+  widController.soundToPlay =
+      [NSURL fileURLWithPath:[mainBundle pathForResource:@"beep-beep" ofType:@"aiff"] isDirectory:NO];
+  [self presentModalViewController:widController animated:YES];
   [widController release];
 }
 
-
-- (void)viewWillAppear:(BOOL)animated {
-  [super viewWillAppear:animated];
-  if (resultsToDisplay)
-  {
-    [resultsView setText:resultsToDisplay];
-    [resultsView setNeedsDisplay];
-  }
-}
-
-/*
- - (void)viewDidAppear:(BOOL)animated {
- [super viewDidAppear:animated];
- }
- */
-/*
- - (void)viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
- }
- */
-/*
- - (void)viewDidDisappear:(BOOL)animated {
- [super viewDidDisappear:animated];
- }
- */
-
-/*
- // Override to allow orientations other than the default portrait orientation.
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
- // Return YES for supported orientations.
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
- }
- */
-
 #pragma mark -
 #pragma mark ZXingDelegateMethods
 
 - (void)zxingController:(ZXingWidgetController*)controller didScanResult:(NSString *)result {
-  [self dismissModalViewControllerAnimated:NO];
   self.resultsToDisplay = result;
+  if (self.isViewLoaded) {
+    [resultsView setText:resultsToDisplay];
+    [resultsView setNeedsDisplay];
+  }
+  [self dismissModalViewControllerAnimated:NO];
 }
 
 - (void)zxingControllerDidCancel:(ZXingWidgetController*)controller {
   [self dismissModalViewControllerAnimated:YES];
 }
 
-
-#pragma mark -
-#pragma mark Memory management
-
-- (void)didReceiveMemoryWarning {
-  // Releases the view if it doesn't have a superview.
-  [super didReceiveMemoryWarning];
-  
-  // Relinquish ownership any cached data, images, etc that aren't in use.
-}
-
 - (void)viewDidUnload {
-  // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
-  // For example: self.myOutlet = nil;
+  self.resultsView = nil;
 }
 
-
 - (void)dealloc {
   [resultsView release];
   [resultsToDisplay release];
index 22c5d1e..378ad05 100755 (executable)
@@ -17,6 +17,9 @@
                28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD735F0D9D9599002E5188 /* MainWindow.xib */; };
                28C286E10D94DF7D0034E888 /* RootViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.mm */; };
                28F335F11007B36200424DE2 /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28F335F01007B36200424DE2 /* RootViewController.xib */; };
+               3BCED5C8120F84C900131FA0 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BCED5C7120F84C900131FA0 /* AVFoundation.framework */; };
+               3BCED5CE120F84E000131FA0 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BCED5CD120F84E000131FA0 /* CoreVideo.framework */; };
+               3BCED5EB120F885C00131FA0 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BCED5EA120F885C00131FA0 /* CoreMedia.framework */; };
                E5345BF11198D81A000CB77F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E5345BF01198D81A000CB77F /* AudioToolbox.framework */; };
                E548755C119C62B9001CC0F8 /* beep-beep.aiff in Resources */ = {isa = PBXBuildFile; fileRef = E548755B119C62B9001CC0F8 /* beep-beep.aiff */; };
 /* End PBXBuildFile section */
@@ -53,6 +56,9 @@
                28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = "<group>"; };
                28C286E00D94DF7D0034E888 /* RootViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RootViewController.mm; sourceTree = "<group>"; };
                28F335F01007B36200424DE2 /* RootViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RootViewController.xib; sourceTree = "<group>"; };
+               3BCED5C7120F84C900131FA0 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
+               3BCED5CD120F84E000131FA0 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
+               3BCED5EA120F885C00131FA0 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
                8D1107310486CEB800E47090 /* ScanTest-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ScanTest-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
                E5345BF01198D81A000CB77F /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
                E5345FD6119B27D2000CB77F /* libZXingWidget.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libZXingWidget.a; path = "build/Debug-iphoneos/libZXingWidget.a"; sourceTree = "<group>"; };
@@ -70,6 +76,9 @@
                                E5345BF11198D81A000CB77F /* AudioToolbox.framework in Frameworks */,
                                1F027F7F11A7BADA006B06DE /* libZXingWidget.a in Frameworks */,
                                1F027F8511A7BB77006B06DE /* libiconv.dylib in Frameworks */,
+                               3BCED5C8120F84C900131FA0 /* AVFoundation.framework in Frameworks */,
+                               3BCED5CE120F84E000131FA0 /* CoreVideo.framework in Frameworks */,
+                               3BCED5EB120F885C00131FA0 /* CoreMedia.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */,
                                E5345BF01198D81A000CB77F /* AudioToolbox.framework */,
                                1F027F8411A7BB77006B06DE /* libiconv.dylib */,
+                               3BCED5C7120F84C900131FA0 /* AVFoundation.framework */,
+                               3BCED5CD120F84E000131FA0 /* CoreVideo.framework */,
+                               3BCED5EA120F885C00131FA0 /* CoreMedia.framework */,
                        );
                        name = Frameworks;
                        sourceTree = "<group>";
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Romain Pechayre (2CQ4EGKG4S)";
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                GCC_C_LANGUAGE_STANDARD = c99;
                                GCC_VERSION = "";
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                        ../../cpp/core/src,
                                        "../ZXingWidget/Classes/**",
                                );
-                               IPHONEOS_DEPLOYMENT_TARGET = 3.1.3;
+                               IPHONEOS_DEPLOYMENT_TARGET = 4.0;
                                PREBINDING = NO;
-                               "PROVISIONING_PROFILE[sdk=iphoneos*]" = "4969F794-AB05-4D6F-909C-99C93009AC70";
                                SDKROOT = iphoneos4.0;
                        };
                        name = Debug;
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Romain Pechayre (2CQ4EGKG4S)";
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                                GCC_C_LANGUAGE_STANDARD = c99;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
                                        ../../cpp/core/src,
                                        "../ZXingWidget/Classes/**",
                                );
-                               IPHONEOS_DEPLOYMENT_TARGET = 3.1.3;
+                               IPHONEOS_DEPLOYMENT_TARGET = 4.0;
                                OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
                                PREBINDING = NO;
-                               "PROVISIONING_PROFILE[sdk=iphoneos*]" = "4969F794-AB05-4D6F-909C-99C93009AC70";
                                SDKROOT = iphoneos4.0;
                        };
                        name = Release;
index 7b0da30..ee1745c 100644 (file)
 #import "DecoderDelegate.h"
 
 @interface Decoder : NSObject {
-       NSSet *readers;
+  NSSet *readers;
   UIImage *image;
-       CGRect cropRect;
+  CGRect cropRect;
   UIImage *subsetImage;
   unsigned char *subsetData;
   size_t subsetWidth;
   size_t subsetHeight;
   size_t subsetBytesPerRow;
-       id<DecoderDelegate> delegate;
-  NSOperationQueue *operationQueue;
+  id<DecoderDelegate> delegate;
 }
 
 @property(nonatomic, retain) UIImage *image;
@@ -45,9 +44,9 @@
 @property(assign) size_t subsetHeight;
 @property(assign) size_t subsetBytesPerRow;
 @property(nonatomic, assign) id<DecoderDelegate> delegate;
-@property (nonatomic, retain) NSOperationQueue *operationQueue;
 
-- (void) decodeImage:(UIImage *)image;
-- (void) decodeImage:(UIImage *)image cropRect:(CGRect)cropRect;
+- (BOOL) decodeImage:(UIImage *)image;
+- (BOOL) decodeImage:(UIImage *)image cropRect:(CGRect)cropRect;
+- (void) resultPointCallback:(CGPoint)point;
 
 @end
index 13d9439..7510588 100644 (file)
 #include <zxing/BinaryBitmap.h>
 #include <zxing/ReaderException.h>
 #include <zxing/common/IllegalArgumentException.h>
-#include <zxing/common/GlobalHistogramBinarizer.h>
+#include <zxing/common/HybridBinarizer.h>
 #include <zxing/common/GreyscaleLuminanceSource.h>
 
 using namespace zxing;
 
+class ZXingWidgetControllerCallback : public zxing::ResultPointCallback {
+private:
+  Decoder* decoder;
+public:
+  ZXingWidgetControllerCallback(Decoder* _decoder) : decoder(_decoder) {}
+  void foundPossibleResultPoint(ResultPoint const& result) {
+    CGPoint point;
+    point.x = result.getX();
+    point.y = result.getY();
+    [decoder resultPointCallback:point];
+  }
+};
+
 @implementation Decoder
 
 @synthesize image;
@@ -42,32 +55,16 @@ using namespace zxing;
 @synthesize subsetHeight;
 @synthesize subsetBytesPerRow;
 @synthesize delegate;
-@synthesize operationQueue;
 @synthesize readers;
 
 
-- (id)init {
-  if (self = [super init]) {
-    NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
-    self.operationQueue = opQueue;
-    [opQueue release];
-  }
-  return self;
-}
 - (void)willDecodeImage {
   if ([self.delegate respondsToSelector:@selector(decoder:willDecodeImage:usingSubset:)]) {
     [self.delegate decoder:self willDecodeImage:self.image usingSubset:self.subsetImage];
   }
 }
 
-- (void)progressDecodingImage:(NSString *)progress {
-  if ([self.delegate respondsToSelector:@selector(decoder:decodingImage:usingSubset:progress:)]) {
-    [self.delegate decoder:self decodingImage:self.image usingSubset:self.subsetImage progress:progress];
-  }
-}
-
 - (void)didDecodeImage:(TwoDDecoderResult *)result {
-
   if ([self.delegate respondsToSelector:@selector(decoder:didDecodeImage:usingSubset:withResult:)]) {
     [self.delegate decoder:self didDecodeImage:self.image usingSubset:self.subsetImage withResult:result];
   }
@@ -76,13 +73,18 @@ using namespace zxing;
 }
 
 - (void)failedToDecodeImage:(NSString *)reason {
-
   if ([self.delegate respondsToSelector:@selector(decoder:failedToDecodeImage:usingSubset:reason:)]) {
     [self.delegate decoder:self failedToDecodeImage:self.image usingSubset:self.subsetImage reason:reason];
   }
 }
 
-#define SUBSET_SIZE 320.0
+- (void)resultPointCallback:(CGPoint)point {
+  if ([self.delegate respondsToSelector:@selector(decoder:foundPossibleResultPoint:)]) {
+    [self.delegate decoder:self foundPossibleResultPoint:point];
+  }
+}
+
+#define SUBSET_SIZE 360
 - (void) prepareSubset {
   CGSize size = [image size];
 #ifdef DEBUG
@@ -155,22 +157,26 @@ using namespace zxing;
 #endif
 }  
 
-- (void)decode:(id)arg {
+- (BOOL)decode {
   NSAutoreleasePool* mainpool = [[NSAutoreleasePool alloc] init];
+  TwoDDecoderResult *decoderResult = nil;
+    
   { 
     //NSSet *formatReaders = [FormatReader formatReaders];
     NSSet *formatReaders = self.readers;
     Ref<LuminanceSource> source 
-           (new GreyscaleLuminanceSource(subsetData, subsetBytesPerRow, subsetHeight, 0, 0, subsetWidth, subsetHeight));
-    Ref<Binarizer> binarizer (new GlobalHistogramBinarizer(source));
+        (new GreyscaleLuminanceSource(subsetData, subsetBytesPerRow, subsetHeight, 0, 0, subsetWidth, subsetHeight));
+
+    Ref<Binarizer> binarizer (new HybridBinarizer(source));
+    source = 0;
     Ref<BinaryBitmap> grayImage (new BinaryBitmap(binarizer));
+    binarizer = 0;
 #ifdef DEBUG
-    NSLog(@"created GreyscaleLuminanceSource", subsetWidth, subsetHeight);
+    NSLog(@"created GreyscaleLuminanceSource(%p,%d,%d,%d,%d,%d,%d)",
+          subsetData, subsetBytesPerRow, subsetHeight, 0, 0, subsetWidth, subsetHeight);
     NSLog(@"grayImage count = %d", grayImage->count());
 #endif
     
-    TwoDDecoderResult *decoderResult = nil;
-    
 #ifdef TRY_ROTATIONS
     for (int i = 0; !decoderResult && i < 4; i++) {
 #endif
@@ -180,7 +186,9 @@ using namespace zxing;
   #ifdef DEBUG
           NSLog(@"decoding gray image");
   #endif  
-          Ref<Result> result([reader decode:grayImage]);
+          ResultPointCallback* callback_pointer(new ZXingWidgetControllerCallback(self));
+          Ref<ResultPointCallback> callback(callback_pointer);
+          Ref<Result> result([reader decode:grayImage andCallback:callback]);
   #ifdef DEBUG
           NSLog(@"gray image decoded");
   #endif
@@ -198,10 +206,9 @@ using namespace zxing;
           }
           
           NSString *resultString = [NSString stringWithCString:cString
-                                encoding:NSUTF8StringEncoding];
-          
-          decoderResult = [[TwoDDecoderResult resultWithText:resultString
-                                                     points:points] retain];
+                                                        encoding:NSUTF8StringEncoding];
+
+          decoderResult = [[TwoDDecoderResult resultWithText:resultString points:points] retain];
           [points release];
         } catch (ReaderException &rex) {
           NSLog(@"failed to decode, caught ReaderException '%s'",
@@ -231,6 +238,11 @@ using namespace zxing;
        free(subsetData);
        self.subsetData = NULL;
          
+        // DONT COMMIT
+        // [decoderResult release];
+        // decoderResult = nil;
+        
+
     if (decoderResult) {
       [self performSelectorOnMainThread:@selector(didDecodeImage:)
                    withObject:decoderResult
@@ -247,41 +259,26 @@ using namespace zxing;
   NSLog(@"finished decoding.");
 #endif
   [mainpool release];
-}
 
-- (void) decodeImage:(UIImage *)i {
-  [self decodeImage:i cropRect:CGRectMake(0.0f, 0.0f, i.size.width, i.size.height)];
+  return decoderResult == nil ? NO : YES;
 }
 
-
-- (void) asyncDecodeImage {
-  [self prepareSubset];
-  [self willDecodeImage];
-  [self performSelectorOnMainThread:@selector(willDecodeImage) 
-                         withObject:nil 
-                      waitUntilDone:NO];
-  [self performSelectorOnMainThread:@selector(progressDecodingImage:)
-                         withObject:NSLocalizedString(@"Decoder MessageWhileDecoding", @"Decoding ...")
-                      waitUntilDone:NO];
-/*  NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(decode:) object:nil];
-  [operationQueue addOperation:op];
-  [op release];*/
-  [self decode:nil];
+- (BOOL) decodeImage:(UIImage *)i {
+  return [self decodeImage:i cropRect:CGRectMake(0.0f, 0.0f, i.size.width, i.size.height)];
 }
-- (void) decodeImage:(UIImage *)i cropRect:(CGRect)cr {
+
+- (BOOL) decodeImage:(UIImage *)i cropRect:(CGRect)cr {
   self.image = i;
   self.cropRect = cr;
-  NSInvocationOperation *op = [[NSInvocationOperation  alloc] initWithTarget:self selector:@selector(asyncDecodeImage) object:nil];
-  [operationQueue addOperation:op];
-  [op release];
+  [self prepareSubset];
+  [self willDecodeImage];
+  return [self decode];
 }
 
 - (void) dealloc {
-
   [image release];
   [subsetImage release];
-  if (subsetData) free(subsetData);
-  [operationQueue release];
+  free(subsetData);
   [readers release];
   [super dealloc];
 }
index 5a78203..1d735c5 100644 (file)
@@ -27,8 +27,8 @@
 @protocol DecoderDelegate<NSObject>
 @optional
 - (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset;
-- (void)decoder:(Decoder *)decoder decodingImage:(UIImage *)image usingSubset:(UIImage *)subset progress:(NSString *)message;
 - (void)decoder:(Decoder *)decoder didDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset withResult:(TwoDDecoderResult *)result;
 - (void)decoder:(Decoder *)decoder failedToDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset reason:(NSString *)reason;
+- (void)decoder:(Decoder *)decoder foundPossibleResultPoint:(CGPoint)point;
 
 @end
index 58c406d..1061c4c 100644 (file)
@@ -23,6 +23,7 @@
 #import <zxing/Result.h>
 #import <zxing/BinaryBitmap.h>
 #import <zxing/Reader.h>
+#import <zxing/ResultPointCallback.h>
 
 @interface FormatReader : NSObject {
   zxing::Reader *reader_;
@@ -33,5 +34,6 @@
 
 - (id)initWithReader:(zxing::Reader *)reader;
 - (zxing::Ref<zxing::Result>)decode:(zxing::Ref<zxing::BinaryBitmap>)grayImage;
+- (zxing::Ref<zxing::Result>)decode:(zxing::Ref<zxing::BinaryBitmap>)grayImage andCallback:(zxing::Ref<zxing::ResultPointCallback>)callback;
 
 @end
index 474413b..885ec78 100644 (file)
@@ -62,4 +62,10 @@ static NSMutableSet *sFormatReaders = nil;
   return reader_->decode(grayImage);
 }
 
+- (zxing::Ref<zxing::Result>)decode:(zxing::Ref<zxing::BinaryBitmap>)grayImage andCallback:(zxing::Ref<zxing::ResultPointCallback>)callback {
+    zxing::DecodeHints hints;
+    hints.setResultPointCallback(callback);
+    return reader_->decode(grayImage, hints);
+}
+
 @end
index d9f6d35..e77d131 100755 (executable)
 
 @interface OverlayView : UIView {
        UIImageView *imageView;
-       NSArray *_points;
+       NSMutableArray *_points;
        UIButton *cancelButton;
        id<CancelDelegate> delegate;
        BOOL oneDMode;
+        CGRect cropRect;
 }
 
-@property (nonatomic, retain) NSArray*  points;
+@property (nonatomic, retain) NSMutableArray*  points;
 @property (nonatomic, assign) id<CancelDelegate> delegate;
 @property (nonatomic, assign) BOOL oneDMode;
+@property (nonatomic, assign) CGRect cropRect;
 
 - (id)initWithFrame:(CGRect)theFrame cancelEnabled:(BOOL)isCancelEnabled oneDMode:(BOOL)isOneDModeEnabled;
 
-- (CGRect)cropRect;
+- (void)setPoint:(CGPoint)point;
 
 @end
 
 @protocol CancelDelegate
 - (void)cancelled;
-@end
\ No newline at end of file
+@end
index eb6a6e9..2093bff 100755 (executable)
@@ -28,11 +28,21 @@ static const CGFloat kPadding = 10;
 @synthesize delegate, oneDMode;
 @synthesize points = _points;
 @synthesize cancelButton;
+@synthesize cropRect;
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 - (id) initWithFrame:(CGRect)theFrame cancelEnabled:(BOOL)isCancelEnabled oneDMode:(BOOL)isOneDModeEnabled {
-       if( self = [super initWithFrame:theFrame] ) {
-               self.backgroundColor = [UIColor clearColor];
+  if( self = [super initWithFrame:theFrame] ) {
+
+    CGFloat rectSize = self.frame.size.width - kPadding * 2;
+    if (!oneDMode) {
+      cropRect = CGRectMake(kPadding, (self.frame.size.height - rectSize) / 2, rectSize, rectSize);
+    } else {
+      CGFloat rectSize2 = self.frame.size.height - kPadding * 2;
+      cropRect = CGRectMake(kPadding, kPadding, rectSize, rectSize2);          
+    }
+
+    self.backgroundColor = [UIColor clearColor];
     self.oneDMode = isOneDModeEnabled;
     if (isCancelEnabled) {
       UIButton *butt = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
@@ -51,7 +61,7 @@ static const CGFloat kPadding = 10;
       [self addSubview:imageView];
     }
   }
-       return self;
+  return self;
 }
 
 - (void)cancel:(id)sender {
@@ -64,9 +74,7 @@ static const CGFloat kPadding = 10;
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 - (void) dealloc {
        [imageView release];
-       imageView = nil;
        [_points release];
-       _points = nil;
        [super dealloc];
 }
 
@@ -81,14 +89,41 @@ static const CGFloat kPadding = 10;
        CGContextStrokePath(context);
 }
 
+- (CGPoint)map:(CGPoint)point {
+    CGPoint center;
+    center.x = cropRect.size.width/2;
+    center.y = cropRect.size.height/2;
+    float x = point.x - center.x;
+    float y = point.y - center.y;
+    int rotation = 90;
+    switch(rotation) {
+    case 0:
+        point.x = x;
+        point.y = y;
+        break;
+    case 90:
+        point.x = -y;
+        point.y = x;
+        break;
+    case 180:
+        point.x = -x;
+        point.y = -y;
+        break;
+    case 270:
+        point.x = y;
+        point.y = -x;
+        break;
+    }
+    point.x = point.x + center.x;
+    point.y = point.y + center.y;
+    return point;
+}
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 - (void)drawRect:(CGRect)rect {
        [super drawRect:rect];
        CGContextRef c = UIGraphicsGetCurrentContext();
   
-       CGRect cropRect = [self cropRect];
-       
        if (nil != _points) {
     //         [imageView.image drawAtPoint:cropRect.origin];
        }
@@ -135,8 +170,8 @@ static const CGFloat kPadding = 10;
                CGContextSetStrokeColor(c, blue);
                CGContextSetFillColor(c, blue);
                if (oneDMode) {
-                       CGPoint val1 = [[_points objectAtIndex:0] CGPointValue];
-                       CGPoint val2 = [[_points objectAtIndex:1] CGPointValue];
+                       CGPoint val1 = [self map:[[_points objectAtIndex:0] CGPointValue]];
+                       CGPoint val2 = [self map:[[_points objectAtIndex:1] CGPointValue]];
                        CGContextMoveToPoint(c, offset, val1.x);
                        CGContextAddLineToPoint(c, offset, val2.x);
                        CGContextStrokePath(c);
@@ -144,7 +179,7 @@ static const CGFloat kPadding = 10;
                else {
                        CGRect smallSquare = CGRectMake(0, 0, 10, 10);
                        for( NSValue* value in _points ) {
-                               CGPoint point = [value CGPointValue];
+                               CGPoint point = [self map:[value CGPointValue]];
                                smallSquare.origin = CGPointMake(
                                          cropRect.origin.x + point.x - smallSquare.size.width / 2,
                                          cropRect.origin.y + point.y - smallSquare.size.height / 2);
@@ -185,36 +220,26 @@ static const CGFloat kPadding = 10;
 
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
-- (CGRect) cropRect {
-       CGFloat rectSize = self.frame.size.width - kPadding * 2;
-       if (!oneDMode) {
-               return CGRectMake(kPadding, (self.frame.size.height - rectSize) / 2, rectSize, rectSize);
-       }
-       else {
-               CGFloat rectSize2 = self.frame.size.height - kPadding * 2;
-               return CGRectMake(kPadding, kPadding, rectSize, rectSize2);             
-       }
-}
-
-/*
-- (void)viewDidLoad {
-  self.imageView = [[UIImageView alloc] init];
-  self.imageView.frame = CGRectMake(0, 0, 100, 100);
-  [self addSubview:self.imageView];
+- (void) setPoints:(NSMutableArray*)pnts {
+    [pnts retain];
+    [_points release];
+    _points = pnts;
        
+    if (pnts != nil) {
+        self.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.25];
+    }
+    [self setNeedsDisplay];
 }
-*/
 
-////////////////////////////////////////////////////////////////////////////////////////////////////
-- (void) setPoints:(NSArray*)pnts {
-       [pnts retain];
-       [_points release];
-       _points = pnts;
-       
-       if (pnts != nil) {
-               self.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.25];
-       }
-       [self setNeedsDisplay];
+- (void) setPoint:(CGPoint)point {
+    if (!_points) {
+        _points = [[NSMutableArray alloc] init];
+    }
+    if (_points.count > 3) {
+        [_points removeObjectAtIndex:0];
+    }
+    [_points addObject:[NSValue valueWithCGPoint:point]];
+    [self setNeedsDisplay];
 }
 
 
index 03a7f89..7a52a97 100755 (executable)
 
 #include <UIKit/UIKit.h>
 #include <AudioToolbox/AudioToolbox.h>
+#import <AVFoundation/AVFoundation.h>
 #include "Decoder.h"
-#include "ParsedResult.h"
+#include "parsedResults/ParsedResult.h"
 #include "OverlayView.h"
 
 @protocol ZXingDelegate;
 
-//@interface ZXingWidgetController : UIImagePickerController <DecoderDelegate, CancelDelegate> {
-@interface ZXingWidgetController : UIViewController<DecoderDelegate, CancelDelegate, UIImagePickerControllerDelegate,UINavigationControllerDelegate> {
+#if !TARGET_IPHONE_SIMULATOR
+#define HAS_AVFF 1
+#endif
+
+@interface ZXingWidgetController : UIViewController<DecoderDelegate,
+                                                    CancelDelegate,
+                                                    UINavigationControllerDelegate
+#if HAS_AVFF
+                                                    , AVCaptureVideoDataOutputSampleBufferDelegate
+#endif
+                                                    > {
   NSSet *readers;
   ParsedResult *result;
-  UIImagePickerController *imagePicker;
-  NSArray *actions;       
   OverlayView *overlayView;
   SystemSoundID beepSound;
   BOOL showCancel;
   id<ZXingDelegate> delegate;
   BOOL wasCancelled;
   BOOL oneDMode;
+#if HAS_AVFF
+  AVCaptureSession *captureSession;
+  AVCaptureVideoPreviewLayer *prevLayer;
+#endif
+  BOOL decoding;
 }
 
+#if HAS_AVFF
+@property (nonatomic, retain) AVCaptureSession *captureSession;
+@property (nonatomic, retain) AVCaptureVideoPreviewLayer *prevLayer;
+#endif
 @property (nonatomic, retain ) NSSet *readers;
 @property (nonatomic, assign) id<ZXingDelegate> delegate;
-@property (nonatomic, assign) NSURL *soundToPlay;
+@property (nonatomic, retain) NSURL *soundToPlay;
 @property (nonatomic, retain) ParsedResult *result;
-@property (nonatomic, retain) NSArray *actions;
 @property (nonatomic, retain) OverlayView *overlayView;
 
 - (id)initWithDelegate:(id<ZXingDelegate>)delegate showCancel:(BOOL)shouldShowCancel OneDMode:(BOOL)shouldUseoOneDMode;
 
 - (BOOL)fixedFocus;
-- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;
 @end
 
 @protocol ZXingDelegate
 - (void)zxingController:(ZXingWidgetController*)controller didScanResult:(NSString *)result;
 - (void)zxingControllerDidCancel:(ZXingWidgetController*)controller;
-@end
\ No newline at end of file
+@end
index 3ea90e5..4599e3e 100755 (executable)
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
+#import <AVFoundation/AVFoundation.h>
+
 #define CAMERA_SCALAR 1.12412 // scalar = (480 / (2048 / 480))
 #define FIRST_TAKE_DELAY 1.0
 #define ONE_D_BAND_HEIGHT 10.0
 
-CGImageRef UIGetScreenImage(void);
-
 @interface ZXingWidgetController ()
 
 @property BOOL showCancel;
 @property BOOL oneDMode;
 
-@property (nonatomic, retain) UIImagePickerController* imagePicker;
+- (void)initCapture;
+- (void)stopCapture;
 
 @end
 
-
-
-
-
 @implementation ZXingWidgetController
-@synthesize result, actions, delegate, soundToPlay;
+
+#if HAS_AVFF
+@synthesize captureSession;
+@synthesize prevLayer;
+#endif
+@synthesize result, delegate, soundToPlay;
 @synthesize overlayView;
 @synthesize oneDMode, showCancel;
-@synthesize imagePicker;
 @synthesize readers;
 
 
--(void)loadImagePicker {
-  if (self.imagePicker)
-  {
-    [imagePicker release];
-    imagePicker = nil;
-  }
-  UIImagePickerController* imController = [[UIImagePickerController alloc] init];
-  self.imagePicker = imController;
-  imagePicker.delegate = self;
-  [imController release];
-  imagePicker.wantsFullScreenLayout = YES;
-  if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
-    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
-  float zoomFactor = CAMERA_SCALAR;
-  if ([self fixedFocus]) {
-    zoomFactor *= 2.0;
-  }
-  if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
-    imagePicker.cameraViewTransform = CGAffineTransformScale(
-                                                             imagePicker.cameraViewTransform, zoomFactor, zoomFactor);
-  if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
-  {
-    imagePicker.showsCameraControls = NO;
-    imagePicker.cameraOverlayView = overlayView;
-    imagePicker.allowsEditing = NO;
-  }
-}
-
-- (void)unloadImagePicker {
-  if (self.imagePicker)
-  {
-    [imagePicker release];
-    imagePicker = nil;
-  }
-}
-
 - (id)initWithDelegate:(id<ZXingDelegate>)scanDelegate showCancel:(BOOL)shouldShowCancel OneDMode:(BOOL)shouldUseoOneDMode {
   if (self = [super init]) {
     [self setDelegate:scanDelegate];
@@ -93,6 +58,7 @@ CGImageRef UIGetScreenImage(void);
     self.showCancel = shouldShowCancel;
     self.wantsFullScreenLayout = YES;
     beepSound = -1;
+    decoding = NO;
     OverlayView *theOverLayView = [[OverlayView alloc] initWithFrame:[UIScreen mainScreen].bounds 
                                                        cancelEnabled:showCancel 
                                                             oneDMode:oneDMode];
@@ -108,14 +74,17 @@ CGImageRef UIGetScreenImage(void);
   if (beepSound != -1) {
     AudioServicesDisposeSystemSoundID(beepSound);
   }
-  imagePicker.cameraOverlayView = nil;
-  [imagePicker release];
+  
+  [self stopCapture];
+
+  [soundToPlay release];
   [overlayView release];
   [readers release];
   [super dealloc];
 }
 
 - (void)cancelled {
+  [self stopCapture];
   [[UIApplication sharedApplication] setStatusBarHidden:NO];
   wasCancelled = YES;
   if (delegate != nil) {
@@ -153,32 +122,28 @@ CGImageRef UIGetScreenImage(void);
 }
 
 - (void)viewDidAppear:(BOOL)animated {
-  NSLog(@"View did appear");
   [super viewDidAppear:animated];
   [[UIApplication sharedApplication] setStatusBarHidden:YES];
   //self.wantsFullScreenLayout = YES;
-  [self loadImagePicker];
-  self.view = imagePicker.view;
+
+  decoding = YES;
+
+  [self initCapture];
+  [self.view addSubview:overlayView];
+  // [self loadImagePicker];
+  // self.view = imagePicker.view;
   
   [overlayView setPoints:nil];
   wasCancelled = NO;
-  if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
-
-    [NSTimer scheduledTimerWithTimeInterval: FIRST_TAKE_DELAY
-                                     target: self
-                                   selector: @selector(takePicture:)
-                                   userInfo: nil
-                                    repeats: NO];
-  }
 }
 
-- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
-  //self.wantsFullScreenLayout = NO;
-  [UIApplication sharedApplication].statusBarHidden = NO;
-  [self cancelled];
+- (void)viewDidDisappear:(BOOL)animated {
+  [super viewDidDisappear:animated];
+  [[UIApplication sharedApplication] setStatusBarHidden:NO];
+  [self.overlayView removeFromSuperview];
+  [self stopCapture];
 }
 
-
 - (CGImageRef)CGImageRotated90:(CGImageRef)imgRef
 {
   CGFloat angleInRadians = -90 * (M_PI / 180);
@@ -254,41 +219,6 @@ CGImageRef UIGetScreenImage(void);
   return rotatedImage;
 }
 
-- (void)takePicture:(NSTimer*)theTimer {
-  CGImageRef capture = UIGetScreenImage();
-  static int cpt = 0;
-  if (cpt%10 == 0)
-    UIImageWriteToSavedPhotosAlbum([UIImage imageWithCGImage:capture], nil, nil,nil);
-  CGRect cropRect = [overlayView cropRect];
-  if (oneDMode) {
-    // let's just give the decoder a vertical band right above the red line
-    cropRect.origin.x = cropRect.origin.x + (cropRect.size.width / 2) - (ONE_D_BAND_HEIGHT + 1);
-    cropRect.size.width = ONE_D_BAND_HEIGHT;
-    // do a rotate
-    CGImageRef croppedImg = CGImageCreateWithImageInRect(capture, cropRect);
-    capture = [self CGImageRotated90:croppedImg];
-    capture = [self CGImageRotated180:capture];
-    //              UIImageWriteToSavedPhotosAlbum([UIImage imageWithCGImage:capture], nil, nil, nil);
-    CGImageRelease(croppedImg);
-    cropRect.origin.x = 0.0;
-    cropRect.origin.y = 0.0;
-    cropRect.size.width = CGImageGetWidth(capture);
-    cropRect.size.height = CGImageGetHeight(capture);
-  }
-  CGImageRef newImage = CGImageCreateWithImageInRect(capture, cropRect);
-  CGImageRelease(capture);
-  //UIImage *scrn = [UIImage imageWithCGImage:newImage];
-  UIImage *scrn = [[UIImage alloc] initWithCGImage:newImage];
-  CGImageRelease(newImage);
-  Decoder *d = [[Decoder alloc] init];
-  d.readers = readers;
-  d.delegate = self;
-  cropRect.origin.x = 0.0;
-  cropRect.origin.y = 0.0;
-  [d decodeImage:scrn cropRect:cropRect];
-  [scrn release];
-}
-
 // DecoderDelegate methods
 
 - (void)decoder:(Decoder *)decoder willDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset{
@@ -299,24 +229,20 @@ CGImageRef UIGetScreenImage(void);
 
 - (void)decoder:(Decoder *)decoder
   decodingImage:(UIImage *)image
-    usingSubset:(UIImage *)subset
-       progress:(NSString *)message {
+     usingSubset:(UIImage *)subset {
 }
 
 - (void)presentResultForString:(NSString *)resultString {
   self.result = [ResultParser parsedResultForString:resultString];
-  
   if (beepSound != -1) {
     AudioServicesPlaySystemSound(beepSound);
   }
 #ifdef DEBUG
   NSLog(@"result string = %@", resultString);
-  NSLog(@"result has %d actions", actions ? 0 : actions.count);
 #endif
-  //      [self updateToolbar];
 }
 
-- (void)presentResultPoints:(NSArray *)resultPoints
+- (void)presentResultPoints:(NSMutableArray *)resultPoints
                    forImage:(UIImage *)image
                 usingSubset:(UIImage *)subset {
   // simply add the points to the image view
@@ -327,9 +253,8 @@ CGImageRef UIGetScreenImage(void);
   [self presentResultForString:[twoDResult text]];
   [self presentResultPoints:[twoDResult points] forImage:image usingSubset:subset];
   // now, in a selector, call the delegate to give this overlay time to show the points
-  [self performSelector:@selector(alertDelegate:) withObject:[[twoDResult text] copy] afterDelay:1.0];
+  [self performSelector:@selector(alertDelegate:) withObject:[[twoDResult text] copy] afterDelay:0.0];
   decoder.delegate = nil;
-  [decoder release];
 }
 
 - (void)alertDelegate:(id)text {        
@@ -337,16 +262,212 @@ CGImageRef UIGetScreenImage(void);
   if (delegate != nil) {
     [delegate zxingController:self didScanResult:text];
   }
+  [text release];
 }
 
 - (void)decoder:(Decoder *)decoder failedToDecodeImage:(UIImage *)image usingSubset:(UIImage *)subset reason:(NSString *)reason {
   decoder.delegate = nil;
-  [decoder release];
   [overlayView setPoints:nil];
-  if (!wasCancelled) {
-    [self takePicture:nil];
+}
+
+- (void)decoder:(Decoder *)decoder foundPossibleResultPoint:(CGPoint)point {
+  [overlayView setPoint:point];
+}
+
+/*
+- (void)stopPreview:(NSNotification*)notification {
+  // NSLog(@"stop preview");
+}
+
+- (void)notification:(NSNotification*)notification {
+  // NSLog(@"notification %@", notification.name);
+}
+*/
+
+- (void)initCapture {
+#if HAS_AVFF
+  AVCaptureDeviceInput *captureInput =
+    [AVCaptureDeviceInput deviceInputWithDevice:
+            [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] 
+                                          error:nil];
+  AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
+  captureOutput.alwaysDiscardsLateVideoFrames = YES; 
+  [captureOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
+  NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
+  NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 
+  NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
+  [captureOutput setVideoSettings:videoSettings]; 
+  self.captureSession = [[AVCaptureSession alloc] init];
+  [self.captureSession release];
+  self.captureSession.sessionPreset = AVCaptureSessionPresetMedium; // 480x360 on a 4
+
+  [self.captureSession addInput:captureInput];
+  [self.captureSession addOutput:captureOutput];
+
+  [captureOutput release];
+
+/*
+  [[NSNotificationCenter defaultCenter]
+      addObserver:self
+         selector:@selector(stopPreview:)
+             name:AVCaptureSessionDidStopRunningNotification
+           object:self.captureSession];
+
+  [[NSNotificationCenter defaultCenter]
+      addObserver:self
+         selector:@selector(notification:)
+             name:AVCaptureSessionDidStopRunningNotification
+           object:self.captureSession];
+
+  [[NSNotificationCenter defaultCenter]
+      addObserver:self
+         selector:@selector(notification:)
+             name:AVCaptureSessionRuntimeErrorNotification
+           object:self.captureSession];
+
+  [[NSNotificationCenter defaultCenter]
+      addObserver:self
+         selector:@selector(notification:)
+             name:AVCaptureSessionDidStartRunningNotification
+           object:self.captureSession];
+
+  [[NSNotificationCenter defaultCenter]
+      addObserver:self
+         selector:@selector(notification:)
+             name:AVCaptureSessionWasInterruptedNotification
+           object:self.captureSession];
+
+  [[NSNotificationCenter defaultCenter]
+      addObserver:self
+         selector:@selector(notification:)
+             name:AVCaptureSessionInterruptionEndedNotification
+           object:self.captureSession];
+*/
+
+  [self.captureSession startRunning];
+
+  if (!self.prevLayer) {
+    self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
   }
-  //[self updateToolbar];
+  // NSLog(@"prev %p %@", self.prevLayer, self.prevLayer);
+  self.prevLayer.frame = self.view.bounds;
+  self.prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
+  [self.view.layer addSublayer: self.prevLayer];
+#endif
+}
+
+#if HAS_AVFF
+- (void)captureOutput:(AVCaptureOutput *)captureOutput 
+didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
+       fromConnection:(AVCaptureConnection *)connection 
+{ 
+  if (!decoding) {
+    return;
+  }
+  CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
+  /*Lock the image buffer*/
+  CVPixelBufferLockBaseAddress(imageBuffer,0); 
+  /*Get information about the image*/
+  size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
+  size_t width = CVPixelBufferGetWidth(imageBuffer); 
+  size_t height = CVPixelBufferGetHeight(imageBuffer); 
+    
+  uint8_t* baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 
+  void* free_me = 0;
+  if (true) { // iOS bug?
+    uint8_t* tmp = baseAddress;
+    int bytes = bytesPerRow*height;
+    free_me = baseAddress = (uint8_t*)malloc(bytes);
+    baseAddress[0] = 0xdb;
+    memcpy(baseAddress,tmp,bytes);
+  }
+
+  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
+  CGContextRef newContext =
+    CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace,
+                          kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst); 
+
+  CGImageRef capture = CGBitmapContextCreateImage(newContext); 
+  CVPixelBufferUnlockBaseAddress(imageBuffer,0);
+  free(free_me);
+
+  CGContextRelease(newContext); 
+  CGColorSpaceRelease(colorSpace);
+
+  CGRect cropRect = [overlayView cropRect];
+  if (oneDMode) {
+    // let's just give the decoder a vertical band right above the red line
+    cropRect.origin.x = cropRect.origin.x + (cropRect.size.width / 2) - (ONE_D_BAND_HEIGHT + 1);
+    cropRect.size.width = ONE_D_BAND_HEIGHT;
+    // do a rotate
+    CGImageRef croppedImg = CGImageCreateWithImageInRect(capture, cropRect);
+    capture = [self CGImageRotated90:croppedImg];
+    capture = [self CGImageRotated180:capture];
+    //              UIImageWriteToSavedPhotosAlbum([UIImage imageWithCGImage:capture], nil, nil, nil);
+    CGImageRelease(croppedImg);
+    cropRect.origin.x = 0.0;
+    cropRect.origin.y = 0.0;
+    cropRect.size.width = CGImageGetWidth(capture);
+    cropRect.size.height = CGImageGetHeight(capture);
+  }
+
+  // Won't work if the overlay becomes uncentered ...
+  // iOS always takes videos in landscape
+  // images are always 4x3; device is not
+  // iOS uses virtual pixels for non-image stuff
+
+  {
+    float height = CGImageGetHeight(capture);
+    float width = CGImageGetWidth(capture);
+
+    CGRect screen = UIScreen.mainScreen.bounds;
+    float tmp = screen.size.width;
+    screen.size.width = screen.size.height;;
+    screen.size.height = tmp;
+
+    cropRect.origin.x = (width-cropRect.size.width)/2;
+    cropRect.origin.y = (height-cropRect.size.height)/2;
+  }
+  CGImageRef newImage = CGImageCreateWithImageInRect(capture, cropRect);
+  CGImageRelease(capture);
+  UIImage *scrn = [[UIImage alloc] initWithCGImage:newImage];
+  CGImageRelease(newImage);
+  Decoder *d = [[Decoder alloc] init];
+  d.readers = readers;
+  d.delegate = self;
+  cropRect.origin.x = 0.0;
+  cropRect.origin.y = 0.0;
+  decoding = [d decodeImage:scrn cropRect:cropRect] == YES ? NO : YES;
+  [d release];
+  [scrn release];
+} 
+#endif
+
+- (void)stopCapture {
+  decoding = NO;
+#if HAS_AVFF
+  [captureSession stopRunning];
+  AVCaptureInput* input = [captureSession.inputs objectAtIndex:0];
+  [captureSession removeInput:input];
+  AVCaptureVideoDataOutput* output = (AVCaptureVideoDataOutput*)[captureSession.outputs objectAtIndex:0];
+  [captureSession removeOutput:output];
+  [self.prevLayer removeFromSuperlayer];
+
+/*
+  // heebee jeebees here ... is iOS still writing into the layer?
+  if (self.prevLayer) {
+    layer.session = nil;
+    AVCaptureVideoPreviewLayer* layer = prevLayer;
+    [self.prevLayer retain];
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 12000000000), dispatch_get_main_queue(), ^{
+        [layer release];
+    });
+  }
+*/
+
+  self.prevLayer = nil;
+  self.captureSession = nil;
+#endif
 }
 
 @end
index 6651f73..d6283ef 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 #import <UIKit/UIKit.h>
-#import "ParsedResult.h"
+#import "../parsedResults/ParsedResult.h"
 
 @interface ResultParser : NSObject {
 
index 93e2a54..ee6e2b8 100644 (file)
                1F3DB0FE11C61080009C581B /* MultiFormatOneDReader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F3DB0F811C61080009C581B /* MultiFormatOneDReader.mm */; };
                1F3DB0FF11C61080009C581B /* MultiFormatUPCEANReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F3DB0F911C61080009C581B /* MultiFormatUPCEANReader.h */; };
                1F3DB10011C61080009C581B /* MultiFormatUPCEANReader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F3DB0FA11C61080009C581B /* MultiFormatUPCEANReader.mm */; };
-               1F56ECA612094AB400DFA8DD /* GreyscaleLuminanceSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F56ECA212094AB400DFA8DD /* GreyscaleLuminanceSource.cpp */; };
-               1F56ECA712094AB400DFA8DD /* GreyscaleLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F56ECA312094AB400DFA8DD /* GreyscaleLuminanceSource.h */; };
-               1F56ECA812094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F56ECA412094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.cpp */; };
-               1F56ECA912094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F56ECA512094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.h */; };
-               1F56ED0012094D6400DFA8DD /* DecodeHints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F56ECFF12094D6400DFA8DD /* DecodeHints.cpp */; };
-               1FCC1295120FBD12002C7978 /* HybridBinarizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FCC1293120FBD12002C7978 /* HybridBinarizer.cpp */; };
-               1FCC1296120FBD12002C7978 /* HybridBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCC1294120FBD12002C7978 /* HybridBinarizer.h */; };
+               3B72D96F12130EF6007CEF32 /* ResultPointCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B72D96D12130EF6007CEF32 /* ResultPointCallback.cpp */; };
+               3B72D97012130EF6007CEF32 /* ResultPointCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B72D96E12130EF6007CEF32 /* ResultPointCallback.h */; };
+               3B81AAC5120F07E40022E5D4 /* DecodeHints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B81AAC3120F07E40022E5D4 /* DecodeHints.cpp */; };
+               3B81AAC6120F07E40022E5D4 /* DecodeHints.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B81AAC4120F07E40022E5D4 /* DecodeHints.h */; };
+               3B81AAC9120F080D0022E5D4 /* GreyscaleLuminanceSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B81AAC7120F080D0022E5D4 /* GreyscaleLuminanceSource.cpp */; };
+               3B81AACA120F080D0022E5D4 /* GreyscaleLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B81AAC8120F080D0022E5D4 /* GreyscaleLuminanceSource.h */; };
+               3B81AACD120F08170022E5D4 /* HybridBinarizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B81AACB120F08170022E5D4 /* HybridBinarizer.cpp */; };
+               3B81AACE120F08170022E5D4 /* HybridBinarizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B81AACC120F08170022E5D4 /* HybridBinarizer.h */; };
+               3B81AAF8120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3B81AAF6120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.cpp */; };
+               3B81AAF9120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B81AAF7120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.h */; };
                AA747D9F0F9514B9006C5449 /* ZXingWidget_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* ZXingWidget_Prefix.pch */; };
                AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };
                E534594311987396000CB77F /* BarcodeFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E53458B511987396000CB77F /* BarcodeFormat.cpp */; };
                1F3DB0F811C61080009C581B /* MultiFormatOneDReader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MultiFormatOneDReader.mm; path = Classes/MultiFormatOneDReader.mm; sourceTree = "<group>"; };
                1F3DB0F911C61080009C581B /* MultiFormatUPCEANReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MultiFormatUPCEANReader.h; path = Classes/MultiFormatUPCEANReader.h; sourceTree = "<group>"; };
                1F3DB0FA11C61080009C581B /* MultiFormatUPCEANReader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MultiFormatUPCEANReader.mm; path = Classes/MultiFormatUPCEANReader.mm; sourceTree = "<group>"; };
-               1F56ECA212094AB400DFA8DD /* GreyscaleLuminanceSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GreyscaleLuminanceSource.cpp; sourceTree = "<group>"; };
-               1F56ECA312094AB400DFA8DD /* GreyscaleLuminanceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GreyscaleLuminanceSource.h; sourceTree = "<group>"; };
-               1F56ECA412094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GreyscaleRotatedLuminanceSource.cpp; sourceTree = "<group>"; };
-               1F56ECA512094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GreyscaleRotatedLuminanceSource.h; sourceTree = "<group>"; };
-               1F56ECFF12094D6400DFA8DD /* DecodeHints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DecodeHints.cpp; sourceTree = "<group>"; };
-               1FCC1293120FBD12002C7978 /* HybridBinarizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HybridBinarizer.cpp; sourceTree = "<group>"; };
-               1FCC1294120FBD12002C7978 /* HybridBinarizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HybridBinarizer.h; sourceTree = "<group>"; };
+               3B72D96D12130EF6007CEF32 /* ResultPointCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResultPointCallback.cpp; sourceTree = "<group>"; };
+               3B72D96E12130EF6007CEF32 /* ResultPointCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultPointCallback.h; sourceTree = "<group>"; };
+               3B81AAC3120F07E40022E5D4 /* DecodeHints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DecodeHints.cpp; sourceTree = "<group>"; };
+               3B81AAC4120F07E40022E5D4 /* DecodeHints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecodeHints.h; sourceTree = "<group>"; };
+               3B81AAC7120F080D0022E5D4 /* GreyscaleLuminanceSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GreyscaleLuminanceSource.cpp; sourceTree = "<group>"; };
+               3B81AAC8120F080D0022E5D4 /* GreyscaleLuminanceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GreyscaleLuminanceSource.h; sourceTree = "<group>"; };
+               3B81AACB120F08170022E5D4 /* HybridBinarizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HybridBinarizer.cpp; sourceTree = "<group>"; };
+               3B81AACC120F08170022E5D4 /* HybridBinarizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HybridBinarizer.h; sourceTree = "<group>"; };
+               3B81AAF6120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GreyscaleRotatedLuminanceSource.cpp; sourceTree = "<group>"; };
+               3B81AAF7120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GreyscaleRotatedLuminanceSource.h; sourceTree = "<group>"; };
                AA747D9E0F9514B9006C5449 /* ZXingWidget_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZXingWidget_Prefix.pch; sourceTree = SOURCE_ROOT; };
                AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
                D2AAC07E0554694100DB518D /* libZXingWidget.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libZXingWidget.a; sourceTree = BUILT_PRODUCTS_DIR; };
                E53458B411987396000CB77F /* zxing */ = {
                        isa = PBXGroup;
                        children = (
-                               1F56ECFF12094D6400DFA8DD /* DecodeHints.cpp */,
+                               3B72D96D12130EF6007CEF32 /* ResultPointCallback.cpp */,
+                               3B72D96E12130EF6007CEF32 /* ResultPointCallback.h */,
+                               3B81AAC3120F07E40022E5D4 /* DecodeHints.cpp */,
+                               3B81AAC4120F07E40022E5D4 /* DecodeHints.h */,
                                E53458B511987396000CB77F /* BarcodeFormat.cpp */,
                                E53458B611987396000CB77F /* BarcodeFormat.h */,
                                E53458B711987396000CB77F /* Binarizer.cpp */,
                E53458BB11987396000CB77F /* common */ = {
                        isa = PBXGroup;
                        children = (
-                               1FCC1293120FBD12002C7978 /* HybridBinarizer.cpp */,
-                               1FCC1294120FBD12002C7978 /* HybridBinarizer.h */,
-                               1F56ECA212094AB400DFA8DD /* GreyscaleLuminanceSource.cpp */,
-                               1F56ECA312094AB400DFA8DD /* GreyscaleLuminanceSource.h */,
-                               1F56ECA412094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.cpp */,
-                               1F56ECA512094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.h */,
+                               3B81AAF6120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.cpp */,
+                               3B81AAF7120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.h */,
+                               3B81AACB120F08170022E5D4 /* HybridBinarizer.cpp */,
+                               3B81AACC120F08170022E5D4 /* HybridBinarizer.h */,
+                               3B81AAC7120F080D0022E5D4 /* GreyscaleLuminanceSource.cpp */,
+                               3B81AAC8120F080D0022E5D4 /* GreyscaleLuminanceSource.h */,
                                E53458BC11987396000CB77F /* Array.cpp */,
                                E53458BD11987396000CB77F /* Array.h */,
                                E53458BE11987396000CB77F /* BitArray.cpp */,
                                1F3DB0FB11C61080009C581B /* DataMatrixReader.h in Headers */,
                                1F3DB0FD11C61080009C581B /* MultiFormatOneDReader.h in Headers */,
                                1F3DB0FF11C61080009C581B /* MultiFormatUPCEANReader.h in Headers */,
-                               1F56ECA712094AB400DFA8DD /* GreyscaleLuminanceSource.h in Headers */,
-                               1F56ECA912094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.h in Headers */,
-                               1FCC1296120FBD12002C7978 /* HybridBinarizer.h in Headers */,
+                               3B81AAC6120F07E40022E5D4 /* DecodeHints.h in Headers */,
+                               3B81AACA120F080D0022E5D4 /* GreyscaleLuminanceSource.h in Headers */,
+                               3B81AACE120F08170022E5D4 /* HybridBinarizer.h in Headers */,
+                               3B81AAF9120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.h in Headers */,
+                               3B72D97012130EF6007CEF32 /* ResultPointCallback.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                1F3DB0FC11C61080009C581B /* DataMatrixReader.mm in Sources */,
                                1F3DB0FE11C61080009C581B /* MultiFormatOneDReader.mm in Sources */,
                                1F3DB10011C61080009C581B /* MultiFormatUPCEANReader.mm in Sources */,
-                               1F56ECA612094AB400DFA8DD /* GreyscaleLuminanceSource.cpp in Sources */,
-                               1F56ECA812094AB400DFA8DD /* GreyscaleRotatedLuminanceSource.cpp in Sources */,
-                               1F56ED0012094D6400DFA8DD /* DecodeHints.cpp in Sources */,
-                               1FCC1295120FBD12002C7978 /* HybridBinarizer.cpp in Sources */,
+                               3B81AAC5120F07E40022E5D4 /* DecodeHints.cpp in Sources */,
+                               3B81AAC9120F080D0022E5D4 /* GreyscaleLuminanceSource.cpp in Sources */,
+                               3B81AACD120F08170022E5D4 /* HybridBinarizer.cpp in Sources */,
+                               3B81AAF8120F0A7E0022E5D4 /* GreyscaleRotatedLuminanceSource.cpp in Sources */,
+                               3B72D96F12130EF6007CEF32 /* ResultPointCallback.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = YES;
-                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
                                COPY_PHASE_STRIP = NO;
                                DEAD_CODE_STRIPPING = YES;
-                               DSTROOT = /tmp/ZXingWidget.dst;
                                EXPORTED_SYMBOLS_FILE = exportList;
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_ENABLE_FIX_AND_CONTINUE = YES;
                                GCC_SYMBOLS_PRIVATE_EXTERN = NO;
                                HEADER_SEARCH_PATHS = ../../cpp/core/src;
                                INSTALL_PATH = /usr/local/lib;
-                               IPHONEOS_DEPLOYMENT_TARGET = 3.1.3;
                                LD_GENERATE_MAP_FILE = YES;
                                LD_OPENMP_FLAGS = "-fopenmp";
                                MACH_O_TYPE = staticlib;
                                );
                                PRESERVE_DEAD_CODE_INITS_AND_TERMS = NO;
                                PRODUCT_NAME = ZXingWidget;
-                               SDKROOT = iphoneos4.0;
                                SEPARATE_STRIP = NO;
                                SKIP_INSTALL = YES;
-                               STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = dynamic;
                        };
                        name = Debug;
                };
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ALWAYS_SEARCH_USER_PATHS = NO;
-                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-                               DSTROOT = /tmp/ZXingWidget.dst;
                                GCC_MODEL_TUNING = G5;
                                GCC_PRECOMPILE_PREFIX_HEADER = YES;
                                GCC_PREFIX_HEADER = ZXingWidget_Prefix.pch;
                                GCC_SYMBOLS_PRIVATE_EXTERN = NO;
                                HEADER_SEARCH_PATHS = ../../cpp/core/src;
                                INSTALL_PATH = /usr/local/lib;
-                               IPHONEOS_DEPLOYMENT_TARGET = 3.1.3;
                                PRODUCT_NAME = ZXingWidget;
-                               SDKROOT = iphoneos4.0;
                        };
                        name = Release;
                };
                                GCC_VERSION = "";
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               IPHONEOS_DEPLOYMENT_TARGET = 3.1.3;
+                               IPHONEOS_DEPLOYMENT_TARGET = 4.0;
                                OTHER_LDFLAGS = "-ObjC";
                                PREBINDING = NO;
                                SDKROOT = iphoneos4.0;
+                               WARNING_CFLAGS = "-Werror";
                        };
                        name = Debug;
                };
                                GCC_VERSION = "";
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
-                               IPHONEOS_DEPLOYMENT_TARGET = 3.1.3;
+                               IPHONEOS_DEPLOYMENT_TARGET = 4.0;
                                OTHER_LDFLAGS = "-ObjC";
                                PREBINDING = NO;
                                SDKROOT = iphoneos4.0;
+                               WARNING_CFLAGS = "-Werror";
                        };
                        name = Release;
                };