diff --git a/README.md b/README.md index 51e29bbaf..488401aa6 100755 --- a/README.md +++ b/README.md @@ -208,7 +208,6 @@ Documentation is generated from header comments using appledoc. To build the doc - *threshold*: Any edge above this threshold will be black, and anything below white. Ranges from 0.0 to 1.0, with 0.5 as the default - **GPUImageSketchFilter**: Converts video to look like a sketch. This is just the Sobel edge detection filter with the colors inverted - - *intensity*: The degree to which the original image colors are replaced by the detected edges (0.0 - 1.0, with 1.0 as the default) - *texelWidth*: - *texelHeight*: These parameters affect the visibility of the detected edges diff --git a/examples/ColorObjectTracking/ColorObjectTracking/ColorTrackingViewController.h b/examples/ColorObjectTracking/ColorObjectTracking/ColorTrackingViewController.h index 51712b23e..db25b6aaa 100755 --- a/examples/ColorObjectTracking/ColorObjectTracking/ColorTrackingViewController.h +++ b/examples/ColorObjectTracking/ColorObjectTracking/ColorTrackingViewController.h @@ -3,13 +3,13 @@ typedef enum { PASSTHROUGH_VIDEO, SIMPLE_THRESHOLDING, POSITION_THRESHOLDING, OBJECT_TRACKING} ColorTrackingDisplayMode; -@interface ColorTrackingViewController : UIViewController +@interface ColorTrackingViewController : UIViewController { CALayer *trackingDot; GPUImageVideoCamera *videoCamera; GPUImageFilter *thresholdFilter, *positionFilter; - GPUImageRawData *positionRawData, *videoRawData; + GPUImageRawDataOutput *positionRawData, *videoRawData; GPUImageView *filteredVideoView; ColorTrackingDisplayMode displayMode; diff --git a/examples/ColorObjectTracking/ColorObjectTracking/ColorTrackingViewController.m b/examples/ColorObjectTracking/ColorObjectTracking/ColorTrackingViewController.m index e0a0dcec4..2c5f87bb8 100755 --- a/examples/ColorObjectTracking/ColorObjectTracking/ColorTrackingViewController.m +++ b/examples/ColorObjectTracking/ColorObjectTracking/ColorTrackingViewController.m @@ -66,11 +66,45 @@ - (void)configureVideoFiltering; CGSize videoPixelSize = CGSizeMake(480.0, 640.0); - positionRawData = [[GPUImageRawData alloc] initWithImageSize:videoPixelSize]; - positionRawData.delegate = self; + positionRawData = [[GPUImageRawDataOutput alloc] initWithImageSize:videoPixelSize]; + __unsafe_unretained ColorTrackingViewController *weakSelf = self; + [positionRawData setNewFrameAvailableBlock:^{ + GLubyte *bytesForPositionData = positionRawData.rawBytesForImage; + CGPoint currentTrackingLocation = [weakSelf centroidFromTexture:bytesForPositionData ofSize:[positionRawData maximumOutputSize]]; + CGSize currentViewSize = weakSelf.view.bounds.size; + trackingDot.position = CGPointMake(currentTrackingLocation.x * currentViewSize.width, currentTrackingLocation.y * currentViewSize.height); + }]; - videoRawData = [[GPUImageRawData alloc] initWithImageSize:videoPixelSize]; - videoRawData.delegate = self; + videoRawData = [[GPUImageRawDataOutput alloc] initWithImageSize:videoPixelSize]; + [videoRawData setNewFrameAvailableBlock:^{ + if (shouldReplaceThresholdColor) + { + CGSize currentViewSize = self.view.bounds.size; + CGSize rawPixelsSize = [videoRawData maximumOutputSize]; + + + CGPoint scaledTouchPoint; + scaledTouchPoint.x = (currentTouchPoint.x / currentViewSize.width) * rawPixelsSize.width; + scaledTouchPoint.y = (currentTouchPoint.y / currentViewSize.height) * rawPixelsSize.height; + + GPUByteColorVector colorAtTouchPoint = [videoRawData colorAtLocation:scaledTouchPoint]; + + thresholdColor[0] = (float)colorAtTouchPoint.red / 255.0; + thresholdColor[1] = (float)colorAtTouchPoint.green / 255.0; + thresholdColor[2] = (float)colorAtTouchPoint.blue / 255.0; + + // NSLog(@"Color at touch point: %d, %d, %d, %d", colorAtTouchPoint.red, colorAtTouchPoint.green, colorAtTouchPoint.blue, colorAtTouchPoint.alpha); + + [[NSUserDefaults standardUserDefaults] setFloat:thresholdColor[0] forKey:@"thresholdColorR"]; + [[NSUserDefaults standardUserDefaults] setFloat:thresholdColor[1] forKey:@"thresholdColorG"]; + [[NSUserDefaults standardUserDefaults] setFloat:thresholdColor[2] forKey:@"thresholdColorB"]; + + [thresholdFilter setFloatVec3:thresholdColor forUniform:@"inputColor"]; + [positionFilter setFloatVec3:thresholdColor forUniform:@"inputColor"]; + + shouldReplaceThresholdColor = NO; + } + }]; [videoCamera addTarget:filteredVideoView]; [videoCamera addTarget:videoRawData]; @@ -200,52 +234,7 @@ - (CGPoint)centroidFromTexture:(GLubyte *)pixels ofSize:(CGSize)textureSize; } } - return CGPointMake(currentXTotal / currentPixelTotal, currentYTotal / currentPixelTotal); -} - -#pragma mark - -#pragma mark GPUImageRawDataProcessor protocol - -- (void)newImageFrameAvailableFromDataSource:(GPUImageRawData *)rawDataSource; -{ - if (rawDataSource == positionRawData) - { - GLubyte *bytesForPositionData = rawDataSource.rawBytesForImage; - CGPoint currentTrackingLocation = [self centroidFromTexture:bytesForPositionData ofSize:[rawDataSource maximumOutputSize]]; - CGSize currentViewSize = self.view.bounds.size; - trackingDot.position = CGPointMake(currentTrackingLocation.x * currentViewSize.width, currentTrackingLocation.y * currentViewSize.height); - } - else - { - if (shouldReplaceThresholdColor) - { - CGSize currentViewSize = self.view.bounds.size; - CGSize rawPixelsSize = [rawDataSource maximumOutputSize]; - - - CGPoint scaledTouchPoint; - scaledTouchPoint.x = (currentTouchPoint.x / currentViewSize.width) * rawPixelsSize.width; - scaledTouchPoint.y = (currentTouchPoint.y / currentViewSize.height) * rawPixelsSize.height; - - GPUByteColorVector colorAtTouchPoint = [rawDataSource colorAtLocation:scaledTouchPoint]; - - thresholdColor[0] = (float)colorAtTouchPoint.red / 255.0; - thresholdColor[1] = (float)colorAtTouchPoint.green / 255.0; - thresholdColor[2] = (float)colorAtTouchPoint.blue / 255.0; - -// NSLog(@"Color at touch point: %d, %d, %d, %d", colorAtTouchPoint.red, colorAtTouchPoint.green, colorAtTouchPoint.blue, colorAtTouchPoint.alpha); - - [[NSUserDefaults standardUserDefaults] setFloat:thresholdColor[0] forKey:@"thresholdColorR"]; - [[NSUserDefaults standardUserDefaults] setFloat:thresholdColor[1] forKey:@"thresholdColorG"]; - [[NSUserDefaults standardUserDefaults] setFloat:thresholdColor[2] forKey:@"thresholdColorB"]; - - [thresholdFilter setFloatVec3:thresholdColor forUniform:@"inputColor"]; - [positionFilter setFloatVec3:thresholdColor forUniform:@"inputColor"]; - - shouldReplaceThresholdColor = NO; - } - } - + return CGPointMake((1.0 - currentYTotal / currentPixelTotal), currentXTotal / currentPixelTotal); } #pragma mark - diff --git a/examples/RawDataTest/RawDataTest.xcodeproj/project.pbxproj b/examples/RawDataTest/RawDataTest.xcodeproj/project.pbxproj index 177072ce3..f75b7a294 100644 --- a/examples/RawDataTest/RawDataTest.xcodeproj/project.pbxproj +++ b/examples/RawDataTest/RawDataTest.xcodeproj/project.pbxproj @@ -7,25 +7,63 @@ objects = { /* Begin PBXBuildFile section */ + BC18E03D156B352E00AB8026 /* libGPUImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BCF1E62F1569D454006B155F /* libGPUImage.a */; }; + BC18E03F156B354000AB8026 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC18E03E156B354000AB8026 /* CoreMedia.framework */; }; BCF1E6071569D372006B155F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCF1E6061569D372006B155F /* UIKit.framework */; }; BCF1E6091569D372006B155F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCF1E6081569D372006B155F /* Foundation.framework */; }; BCF1E60B1569D372006B155F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCF1E60A1569D372006B155F /* CoreGraphics.framework */; }; BCF1E6111569D372006B155F /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = BCF1E60F1569D372006B155F /* InfoPlist.strings */; }; BCF1E6131569D372006B155F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF1E6121569D372006B155F /* main.m */; }; BCF1E6171569D372006B155F /* RawDataTestAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF1E6161569D372006B155F /* RawDataTestAppDelegate.m */; }; + BCF1E61E1569D3F8006B155F /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCF1E61D1569D3F8006B155F /* CoreVideo.framework */; }; + BCF1E6201569D408006B155F /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCF1E61F1569D408006B155F /* AVFoundation.framework */; }; + BCF1E6231569D42A006B155F /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCF1E6211569D42A006B155F /* OpenGLES.framework */; }; + BCF1E6241569D42A006B155F /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCF1E6221569D42A006B155F /* QuartzCore.framework */; }; + BCF1E63F156AAB4E006B155F /* CalculationShader.fsh in Resources */ = {isa = PBXBuildFile; fileRef = BCF1E63E156AAB4E006B155F /* CalculationShader.fsh */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + BCF1E62E1569D454006B155F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BCF1E6251569D453006B155F /* GPUImage.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BCF1A33414DDB1EC00852800; + remoteInfo = GPUImage; + }; + BCF1E6301569D454006B155F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BCF1E6251569D453006B155F /* GPUImage.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BCF1A34414DDB1EC00852800; + remoteInfo = GPUImageTests; + }; + BCF1E6371569D565006B155F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BCF1E6251569D453006B155F /* GPUImage.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BCF1A33314DDB1EC00852800; + remoteInfo = GPUImage; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ + BC18E03E156B354000AB8026 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; BCF1E6021569D372006B155F /* RawDataTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RawDataTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; BCF1E6061569D372006B155F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; BCF1E6081569D372006B155F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; BCF1E60A1569D372006B155F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - BCF1E60E1569D372006B155F /* RawDataTest-Info.plist */ = {isa = PBXFileReference; path = "RawDataTest-Info.plist"; sourceTree = ""; }; + BCF1E60E1569D372006B155F /* RawDataTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RawDataTest-Info.plist"; sourceTree = ""; }; BCF1E6101569D372006B155F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; BCF1E6121569D372006B155F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - BCF1E6141569D372006B155F /* RawDataTest-Prefix.pch */ = {isa = PBXFileReference; path = "RawDataTest-Prefix.pch"; sourceTree = ""; }; - BCF1E6151569D372006B155F /* RawDataTestAppDelegate.h */ = {isa = PBXFileReference; path = RawDataTestAppDelegate.h; sourceTree = ""; }; + BCF1E6141569D372006B155F /* RawDataTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RawDataTest-Prefix.pch"; sourceTree = ""; }; + BCF1E6151569D372006B155F /* RawDataTestAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RawDataTestAppDelegate.h; sourceTree = ""; }; BCF1E6161569D372006B155F /* RawDataTestAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RawDataTestAppDelegate.m; sourceTree = ""; }; + BCF1E61D1569D3F8006B155F /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; + BCF1E61F1569D408006B155F /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + BCF1E6211569D42A006B155F /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + BCF1E6221569D42A006B155F /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + BCF1E6251569D453006B155F /* GPUImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GPUImage.xcodeproj; path = ../../framework/GPUImage.xcodeproj; sourceTree = ""; }; + BCF1E63E156AAB4E006B155F /* CalculationShader.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = CalculationShader.fsh; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -33,6 +71,12 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + BC18E03F156B354000AB8026 /* CoreMedia.framework in Frameworks */, + BC18E03D156B352E00AB8026 /* libGPUImage.a in Frameworks */, + BCF1E6231569D42A006B155F /* OpenGLES.framework in Frameworks */, + BCF1E6241569D42A006B155F /* QuartzCore.framework in Frameworks */, + BCF1E6201569D408006B155F /* AVFoundation.framework in Frameworks */, + BCF1E61E1569D3F8006B155F /* CoreVideo.framework in Frameworks */, BCF1E6071569D372006B155F /* UIKit.framework in Frameworks */, BCF1E6091569D372006B155F /* Foundation.framework in Frameworks */, BCF1E60B1569D372006B155F /* CoreGraphics.framework in Frameworks */, @@ -45,6 +89,7 @@ BCF1E5F71569D372006B155F = { isa = PBXGroup; children = ( + BC18E03E156B354000AB8026 /* CoreMedia.framework */, BCF1E60C1569D372006B155F /* RawDataTest */, BCF1E6051569D372006B155F /* Frameworks */, BCF1E6031569D372006B155F /* Products */, @@ -62,6 +107,11 @@ BCF1E6051569D372006B155F /* Frameworks */ = { isa = PBXGroup; children = ( + BCF1E6251569D453006B155F /* GPUImage.xcodeproj */, + BCF1E6211569D42A006B155F /* OpenGLES.framework */, + BCF1E6221569D42A006B155F /* QuartzCore.framework */, + BCF1E61F1569D408006B155F /* AVFoundation.framework */, + BCF1E61D1569D3F8006B155F /* CoreVideo.framework */, BCF1E6061569D372006B155F /* UIKit.framework */, BCF1E6081569D372006B155F /* Foundation.framework */, BCF1E60A1569D372006B155F /* CoreGraphics.framework */, @@ -74,6 +124,7 @@ children = ( BCF1E6151569D372006B155F /* RawDataTestAppDelegate.h */, BCF1E6161569D372006B155F /* RawDataTestAppDelegate.m */, + BCF1E63E156AAB4E006B155F /* CalculationShader.fsh */, BCF1E60D1569D372006B155F /* Supporting Files */, ); path = RawDataTest; @@ -90,6 +141,15 @@ name = "Supporting Files"; sourceTree = ""; }; + BCF1E6261569D453006B155F /* Products */ = { + isa = PBXGroup; + children = ( + BCF1E62F1569D454006B155F /* libGPUImage.a */, + BCF1E6311569D454006B155F /* GPUImageTests.octest */, + ); + name = Products; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -104,6 +164,7 @@ buildRules = ( ); dependencies = ( + BCF1E6381569D565006B155F /* PBXTargetDependency */, ); name = RawDataTest; productName = RawDataTest; @@ -130,6 +191,12 @@ mainGroup = BCF1E5F71569D372006B155F; productRefGroup = BCF1E6031569D372006B155F /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = BCF1E6261569D453006B155F /* Products */; + ProjectRef = BCF1E6251569D453006B155F /* GPUImage.xcodeproj */; + }, + ); projectRoot = ""; targets = ( BCF1E6011569D372006B155F /* RawDataTest */, @@ -137,12 +204,30 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + BCF1E62F1569D454006B155F /* libGPUImage.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libGPUImage.a; + remoteRef = BCF1E62E1569D454006B155F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + BCF1E6311569D454006B155F /* GPUImageTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = GPUImageTests.octest; + remoteRef = BCF1E6301569D454006B155F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ BCF1E6001569D372006B155F /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( BCF1E6111569D372006B155F /* InfoPlist.strings in Resources */, + BCF1E63F156AAB4E006B155F /* CalculationShader.fsh in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -160,6 +245,14 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + BCF1E6381569D565006B155F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GPUImage; + targetProxy = BCF1E6371569D565006B155F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ BCF1E60F1569D372006B155F /* InfoPlist.strings */ = { isa = PBXVariantGroup; @@ -180,6 +273,7 @@ CLANG_ENABLE_OBJC_ARC = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = "../../framework/**"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -192,6 +286,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "../../framework/**"; IPHONEOS_DEPLOYMENT_TARGET = 5.1; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -206,11 +301,13 @@ CLANG_ENABLE_OBJC_ARC = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = "../../framework/**"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = "../../framework/**"; IPHONEOS_DEPLOYMENT_TARGET = 5.1; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; @@ -260,6 +357,7 @@ BCF1E61C1569D372006B155F /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/examples/RawDataTest/RawDataTest/CalculationShader.fsh b/examples/RawDataTest/RawDataTest/CalculationShader.fsh index e69de29bb..35855c289 100644 --- a/examples/RawDataTest/RawDataTest/CalculationShader.fsh +++ b/examples/RawDataTest/RawDataTest/CalculationShader.fsh @@ -0,0 +1,11 @@ +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform lowp float gamma; + +void main() +{ + lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + + gl_FragColor = textureColor; +} diff --git a/examples/RawDataTest/RawDataTest/RawDataTestAppDelegate.h b/examples/RawDataTest/RawDataTest/RawDataTestAppDelegate.h index 5cdc818ed..37497e5ff 100644 --- a/examples/RawDataTest/RawDataTest/RawDataTestAppDelegate.h +++ b/examples/RawDataTest/RawDataTest/RawDataTestAppDelegate.h @@ -1,11 +1,4 @@ -// -// RawDataTestAppDelegate.h -// RawDataTest -// -// Created by Brad Larson on 5/20/2012. -// Copyright (c) 2012 Cell Phone. All rights reserved. -// - +#import "GPUImage.h" #import @interface RawDataTestAppDelegate : UIResponder diff --git a/examples/RawDataTest/RawDataTest/RawDataTestAppDelegate.m b/examples/RawDataTest/RawDataTest/RawDataTestAppDelegate.m index 1194faf6b..1e9b6bcd2 100644 --- a/examples/RawDataTest/RawDataTest/RawDataTestAppDelegate.m +++ b/examples/RawDataTest/RawDataTest/RawDataTestAppDelegate.m @@ -1,11 +1,3 @@ -// -// RawDataTestAppDelegate.m -// RawDataTest -// -// Created by Brad Larson on 5/20/2012. -// Copyright (c) 2012 Cell Phone. All rights reserved. -// - #import "RawDataTestAppDelegate.h" @implementation RawDataTestAppDelegate @@ -18,34 +10,42 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; - return YES; -} - -- (void)applicationWillResignActive:(UIApplication *)application -{ - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication *)application -{ - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} + + GLubyte *rawDataBytes = calloc(10 * 10 * 4, sizeof(GLubyte)); + for (unsigned int yIndex = 0; yIndex < 10; yIndex++) + { + for (unsigned int xIndex = 0; xIndex < 10; xIndex++) + { + rawDataBytes[yIndex * 10 * 4 + xIndex * 4] = xIndex; + rawDataBytes[yIndex * 10 * 4 + xIndex * 4 + 1] = yIndex; + rawDataBytes[yIndex * 10 * 4 + xIndex * 4 + 2] = 255; + rawDataBytes[yIndex * 10 * 4 + xIndex * 4 + 3] = 0; + } + } + + GPUImageRawDataInput *rawDataInput = [[GPUImageRawDataInput alloc] initWithBytes:rawDataBytes size:CGSizeMake(10.0, 10.0)]; + GPUImageFilter *customFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CalculationShader"]; + GPUImageRawDataOutput *rawDataOutput = [[GPUImageRawDataOutput alloc] initWithImageSize:CGSizeMake(10.0, 10.0)]; + + [rawDataInput addTarget:customFilter]; + [customFilter addTarget:rawDataOutput]; + + [rawDataOutput setNewFrameAvailableBlock:^{ + GLubyte *outputBytes = [rawDataOutput rawBytesForImage]; + NSInteger bytesPerRow = [rawDataOutput bytesPerRowInOutput]; + NSLog(@"Bytes per row: %d", bytesPerRow); + for (unsigned int yIndex = 0; yIndex < 10; yIndex++) + { + for (unsigned int xIndex = 0; xIndex < 10; xIndex++) + { + NSLog(@"Byte at (%d, %d): %d, %d, %d, %d", xIndex, yIndex, outputBytes[yIndex * bytesPerRow + xIndex * 4], outputBytes[yIndex * bytesPerRow + xIndex * 4 + 1], outputBytes[yIndex * bytesPerRow + xIndex * 4 + 2], outputBytes[yIndex * bytesPerRow + xIndex * 4 + 3]); + } + } + }]; + + [rawDataInput processData]; -- (void)applicationWillEnterForeground:(UIApplication *)application -{ - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication *)application -{ - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication *)application -{ - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + return YES; } @end diff --git a/examples/RawDataTest/RawDataTest/main.m b/examples/RawDataTest/RawDataTest/main.m index 9ee49214f..f42977efc 100644 --- a/examples/RawDataTest/RawDataTest/main.m +++ b/examples/RawDataTest/RawDataTest/main.m @@ -1,11 +1,3 @@ -// -// main.m -// RawDataTest -// -// Created by Brad Larson on 5/20/2012. -// Copyright (c) 2012 Cell Phone. All rights reserved. -// - #import #import "RawDataTestAppDelegate.h" diff --git a/framework/GPUImage.xcodeproj/project.pbxproj b/framework/GPUImage.xcodeproj/project.pbxproj index 51857e38d..b7217cecf 100644 --- a/framework/GPUImage.xcodeproj/project.pbxproj +++ b/framework/GPUImage.xcodeproj/project.pbxproj @@ -41,8 +41,8 @@ BC114899155AF65400F107AF /* GPUImageTwoInputFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC114897155AF65400F107AF /* GPUImageTwoInputFilter.m */; }; BC1A47F514FC759D00D552E8 /* GPUImageGaussianBlurFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D04CB7B14FB2A29001D6733 /* GPUImageGaussianBlurFilter.m */; }; BC1A483E14FD1EF900D552E8 /* GPUImageGaussianBlurFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D04CB7A14FB2A29001D6733 /* GPUImageGaussianBlurFilter.h */; }; - BC1B715714F49DAA00ACA2AB /* GPUImageRawData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1B715514F49DAA00ACA2AB /* GPUImageRawData.h */; }; - BC1B715814F49DAA00ACA2AB /* GPUImageRawData.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1B715614F49DAA00ACA2AB /* GPUImageRawData.m */; }; + BC1B715714F49DAA00ACA2AB /* GPUImageRawDataOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1B715514F49DAA00ACA2AB /* GPUImageRawDataOutput.h */; }; + BC1B715814F49DAA00ACA2AB /* GPUImageRawDataOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1B715614F49DAA00ACA2AB /* GPUImageRawDataOutput.m */; }; BC1B717C14F566E200ACA2AB /* GPUImageSketchFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1B717A14F566E200ACA2AB /* GPUImageSketchFilter.h */; }; BC1B717D14F566E200ACA2AB /* GPUImageSketchFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC1B717B14F566E200ACA2AB /* GPUImageSketchFilter.m */; }; BC1B718E14F56C1D00ACA2AB /* GPUImageSwirlFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC1B718C14F56C1D00ACA2AB /* GPUImageSwirlFilter.h */; }; @@ -196,6 +196,8 @@ BCF1E54515669907006B155F /* GPUImageVoroniConsumerFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF1E53F15669907006B155F /* GPUImageVoroniConsumerFilter.m */; }; BCF1E57B15673599006B155F /* GPUImageToneCurveFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF1E57915673599006B155F /* GPUImageToneCurveFilter.h */; }; BCF1E57C15673599006B155F /* GPUImageToneCurveFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF1E57A15673599006B155F /* GPUImageToneCurveFilter.m */; }; + BCF1E642156AB332006B155F /* GPUImageRawDataInput.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF1E640156AB332006B155F /* GPUImageRawDataInput.h */; }; + BCF1E643156AB332006B155F /* GPUImageRawDataInput.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF1E641156AB332006B155F /* GPUImageRawDataInput.m */; }; BCF3D68B153CC124009A1FE5 /* GPUImageTextureInput.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF3D689153CC124009A1FE5 /* GPUImageTextureInput.h */; }; BCF3D68C153CC124009A1FE5 /* GPUImageTextureInput.m in Sources */ = {isa = PBXBuildFile; fileRef = BCF3D68A153CC124009A1FE5 /* GPUImageTextureInput.m */; }; BCF3D6DD153CFF61009A1FE5 /* GPUImageTiltShiftFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCF3D6DB153CFF61009A1FE5 /* GPUImageTiltShiftFilter.h */; }; @@ -249,8 +251,8 @@ BC01E831155CA5E1004C75C3 /* GPUImage3x3TextureSamplingFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImage3x3TextureSamplingFilter.m; path = Source/GPUImage3x3TextureSamplingFilter.m; sourceTree = SOURCE_ROOT; }; BC114896155AF65400F107AF /* GPUImageTwoInputFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageTwoInputFilter.h; path = Source/GPUImageTwoInputFilter.h; sourceTree = SOURCE_ROOT; }; BC114897155AF65400F107AF /* GPUImageTwoInputFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageTwoInputFilter.m; path = Source/GPUImageTwoInputFilter.m; sourceTree = SOURCE_ROOT; }; - BC1B715514F49DAA00ACA2AB /* GPUImageRawData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageRawData.h; path = Source/GPUImageRawData.h; sourceTree = SOURCE_ROOT; }; - BC1B715614F49DAA00ACA2AB /* GPUImageRawData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageRawData.m; path = Source/GPUImageRawData.m; sourceTree = SOURCE_ROOT; }; + BC1B715514F49DAA00ACA2AB /* GPUImageRawDataOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageRawDataOutput.h; path = Source/GPUImageRawDataOutput.h; sourceTree = SOURCE_ROOT; }; + BC1B715614F49DAA00ACA2AB /* GPUImageRawDataOutput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageRawDataOutput.m; path = Source/GPUImageRawDataOutput.m; sourceTree = SOURCE_ROOT; }; BC1B717A14F566E200ACA2AB /* GPUImageSketchFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageSketchFilter.h; path = Source/GPUImageSketchFilter.h; sourceTree = SOURCE_ROOT; }; BC1B717B14F566E200ACA2AB /* GPUImageSketchFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageSketchFilter.m; path = Source/GPUImageSketchFilter.m; sourceTree = SOURCE_ROOT; }; BC1B718C14F56C1D00ACA2AB /* GPUImageSwirlFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageSwirlFilter.h; path = Source/GPUImageSwirlFilter.h; sourceTree = SOURCE_ROOT; }; @@ -403,6 +405,8 @@ BCF1E53F15669907006B155F /* GPUImageVoroniConsumerFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageVoroniConsumerFilter.m; path = Source/GPUImageVoroniConsumerFilter.m; sourceTree = SOURCE_ROOT; }; BCF1E57915673599006B155F /* GPUImageToneCurveFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageToneCurveFilter.h; path = Source/GPUImageToneCurveFilter.h; sourceTree = SOURCE_ROOT; }; BCF1E57A15673599006B155F /* GPUImageToneCurveFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageToneCurveFilter.m; path = Source/GPUImageToneCurveFilter.m; sourceTree = SOURCE_ROOT; }; + BCF1E640156AB332006B155F /* GPUImageRawDataInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageRawDataInput.h; path = Source/GPUImageRawDataInput.h; sourceTree = SOURCE_ROOT; }; + BCF1E641156AB332006B155F /* GPUImageRawDataInput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageRawDataInput.m; path = Source/GPUImageRawDataInput.m; sourceTree = SOURCE_ROOT; }; BCF3D689153CC124009A1FE5 /* GPUImageTextureInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageTextureInput.h; path = Source/GPUImageTextureInput.h; sourceTree = SOURCE_ROOT; }; BCF3D68A153CC124009A1FE5 /* GPUImageTextureInput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageTextureInput.m; path = Source/GPUImageTextureInput.m; sourceTree = SOURCE_ROOT; }; BCF3D6DB153CFF61009A1FE5 /* GPUImageTiltShiftFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageTiltShiftFilter.h; path = Source/GPUImageTiltShiftFilter.h; sourceTree = SOURCE_ROOT; }; @@ -619,6 +623,8 @@ BC982C6B14F33C2A0001FF6F /* GPUImageMovie.m */, BCF3D689153CC124009A1FE5 /* GPUImageTextureInput.h */, BCF3D68A153CC124009A1FE5 /* GPUImageTextureInput.m */, + BCF1E640156AB332006B155F /* GPUImageRawDataInput.h */, + BCF1E641156AB332006B155F /* GPUImageRawDataInput.m */, ); name = Sources; sourceTree = ""; @@ -628,12 +634,12 @@ children = ( BCB5E75A14E2086300701302 /* GPUImageView.h */, BCB5E75B14E2086300701302 /* GPUImageView.m */, - BC1B715514F49DAA00ACA2AB /* GPUImageRawData.h */, - BC1B715614F49DAA00ACA2AB /* GPUImageRawData.m */, BC1B727F14FB16AF00ACA2AB /* GPUImageMovieWriter.h */, BC1B728014FB16AF00ACA2AB /* GPUImageMovieWriter.m */, BCB6B8B91505BF940041703B /* GPUImageTextureOutput.h */, BCB6B8BA1505BF940041703B /* GPUImageTextureOutput.m */, + BC1B715514F49DAA00ACA2AB /* GPUImageRawDataOutput.h */, + BC1B715614F49DAA00ACA2AB /* GPUImageRawDataOutput.m */, ); name = Outputs; sourceTree = ""; @@ -793,7 +799,7 @@ BC982C8114F34F0C0001FF6F /* GPUImageDarkenBlendFilter.h in Headers */, BC982C8314F34F0C0001FF6F /* GPUImageLightenBlendFilter.h in Headers */, BC982C9F14F35C2D0001FF6F /* GPUImageToonFilter.h in Headers */, - BC1B715714F49DAA00ACA2AB /* GPUImageRawData.h in Headers */, + BC1B715714F49DAA00ACA2AB /* GPUImageRawDataOutput.h in Headers */, BC1B717C14F566E200ACA2AB /* GPUImageSketchFilter.h in Headers */, BC1B718E14F56C1D00ACA2AB /* GPUImageSwirlFilter.h in Headers */, 0DF3FA2B14FA00C9006AF7D9 /* GPUImageVignetteFilter.h in Headers */, @@ -858,6 +864,7 @@ BCF1E54215669907006B155F /* GPUImageMosaicFilter.h in Headers */, BCF1E54415669907006B155F /* GPUImageVoroniConsumerFilter.h in Headers */, BCF1E57B15673599006B155F /* GPUImageToneCurveFilter.h in Headers */, + BCF1E642156AB332006B155F /* GPUImageRawDataInput.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -997,7 +1004,7 @@ BC982C8214F34F0C0001FF6F /* GPUImageDarkenBlendFilter.m in Sources */, BC982C8414F34F0C0001FF6F /* GPUImageLightenBlendFilter.m in Sources */, BC982CA014F35C2D0001FF6F /* GPUImageToonFilter.m in Sources */, - BC1B715814F49DAA00ACA2AB /* GPUImageRawData.m in Sources */, + BC1B715814F49DAA00ACA2AB /* GPUImageRawDataOutput.m in Sources */, BC1B717D14F566E200ACA2AB /* GPUImageSketchFilter.m in Sources */, BC1B718F14F56C1D00ACA2AB /* GPUImageSwirlFilter.m in Sources */, 0DF3FA2C14FA00C9006AF7D9 /* GPUImageVignetteFilter.m in Sources */, @@ -1062,6 +1069,7 @@ BCF1E54315669907006B155F /* GPUImageMosaicFilter.m in Sources */, BCF1E54515669907006B155F /* GPUImageVoroniConsumerFilter.m in Sources */, BCF1E57C15673599006B155F /* GPUImageToneCurveFilter.m in Sources */, + BCF1E643156AB332006B155F /* GPUImageRawDataInput.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/framework/Source/GPUImage.h b/framework/Source/GPUImage.h index ec4d44a6a..f448efa04 100755 --- a/framework/Source/GPUImage.h +++ b/framework/Source/GPUImage.h @@ -8,7 +8,8 @@ #import "GPUImageStillCamera.h" #import "GPUImageMovie.h" #import "GPUImagePicture.h" -#import "GPUImageRawData.h" +#import "GPUImageRawDataInput.h" +#import "GPUImageRawDataOutput.h" #import "GPUImageMovieWriter.h" #import "GPUImageFilterPipeline.h" #import "GPUImageTextureOutput.h" diff --git a/framework/Source/GPUImageHarrisCornerDetectionFilter.h b/framework/Source/GPUImageHarrisCornerDetectionFilter.h index 3b3616089..e2d7e37f4 100755 --- a/framework/Source/GPUImageHarrisCornerDetectionFilter.h +++ b/framework/Source/GPUImageHarrisCornerDetectionFilter.h @@ -42,4 +42,7 @@ // This block is called on the detection of new corner points, usually on every processed frame. A C array containing normalized coordinates in X, Y pairs is passed in, along with a count of the number of corners detected @property(nonatomic, copy) void(^cornersDetectedBlock)(GLfloat* cornerArray, NSUInteger cornersDetected); +// Initialization and teardown +- (id)initWithCornerDetectionFragmentShader:(NSString *)cornerDetectionFragmentShader; + @end diff --git a/framework/Source/GPUImageHarrisCornerDetectionFilter.m b/framework/Source/GPUImageHarrisCornerDetectionFilter.m index 99dd81f03..716826de9 100755 --- a/framework/Source/GPUImageHarrisCornerDetectionFilter.m +++ b/framework/Source/GPUImageHarrisCornerDetectionFilter.m @@ -33,10 +33,12 @@ void main() mediump float derivativeSum = derivativeElements.x + derivativeElements.y; // This is the Noble variant on the Harris detector, from - // Alison Noble, "Descriptions of Image Surfaces", PhD thesis, Department of Engineering Science, Oxford University 1989, p45. + // Alison Noble, "Descriptions of Image Surfaces", PhD thesis, Department of Engineering Science, Oxford University 1989, p45. + // R = (Ix^2 * Iy^2 - Ixy * Ixy) / (Ix^2 + Iy^2) mediump float harrisIntensity = (derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z)) / (derivativeSum); // Original Harris detector + // R = Ix^2 * Iy^2 - Ixy * Ixy - k * (Ix^2 + Iy^2)^2 // highp float harrisIntensity = derivativeElements.x * derivativeElements.y - (derivativeElements.z * derivativeElements.z) - harrisConstant * derivativeSum * derivativeSum; // gl_FragColor = vec4(vec3(harrisIntensity * 7.0), 1.0); @@ -66,9 +68,20 @@ void main() @synthesize sensitivity = _sensitivity; @synthesize threshold = _threshold; -//@synthesize intensity = _intensity; +#pragma mark - +#pragma mark Initialization and teardown - (id)init; +{ + if (!(self = [self initWithCornerDetectionFragmentShader:kGPUImageHarrisCornerDetectionFragmentShaderString])) + { + return nil; + } + + return self; +} + +- (id)initWithCornerDetectionFragmentShader:(NSString *)cornerDetectionFragmentShader; { if (!(self = [super init])) { @@ -87,7 +100,7 @@ - (id)init; [self addFilter:blurFilter]; // Third pass: apply the Harris corner detection calculation - harrisCornerDetectionFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromString:kGPUImageHarrisCornerDetectionFragmentShaderString]; + harrisCornerDetectionFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromString:cornerDetectionFragmentShader]; [self addFilter:harrisCornerDetectionFilter]; // Fourth pass: apply non-maximum suppression to find the local maxima diff --git a/framework/Source/GPUImageRawDataInput.h b/framework/Source/GPUImageRawDataInput.h index ced4b4df7..e97c70a1e 100644 --- a/framework/Source/GPUImageRawDataInput.h +++ b/framework/Source/GPUImageRawDataInput.h @@ -1,13 +1,19 @@ -// -// GPUImageRawDataInput.h -// GPUImage -// -// Created by Brad Larson on 5/21/2012. -// Copyright (c) 2012 Brad Larson. All rights reserved. -// - #import "GPUImageOutput.h" +// The bytes passed into this input are not copied or retained, but you are free to deallocate them after they are used by this filter. +// The bytes are uploaded and stored within a texture, so nothing is kept locally. +// Input bytes are assumed to be in BGRA format. + @interface GPUImageRawDataInput : GPUImageOutput +{ + CGSize uploadedImageSize; +} + +// Initialization and teardown +- (id)initWithBytes:(GLubyte *)bytesToUpload size:(CGSize)imageSize; + +// Image rendering +- (void)updateDataFromBytes:(GLubyte *)bytesToUpload size:(CGSize)imageSize; +- (void)processData; @end diff --git a/framework/Source/GPUImageRawDataInput.m b/framework/Source/GPUImageRawDataInput.m index 9c56a0b52..fd257aa03 100644 --- a/framework/Source/GPUImageRawDataInput.m +++ b/framework/Source/GPUImageRawDataInput.m @@ -1,13 +1,63 @@ -// -// GPUImageRawDataInput.m -// GPUImage -// -// Created by Brad Larson on 5/21/2012. -// Copyright (c) 2012 Brad Larson. All rights reserved. -// - #import "GPUImageRawDataInput.h" +@interface GPUImageRawDataInput() +- (void)uploadBytes:(GLubyte *)bytesToUpload; +@end + @implementation GPUImageRawDataInput +#pragma mark - +#pragma mark Initialization and teardown + +- (id)initWithBytes:(GLubyte *)bytesToUpload size:(CGSize)imageSize; +{ + if (!(self = [super init])) + { + return nil; + } + + uploadedImageSize = imageSize; + + [self uploadBytes:bytesToUpload]; + + return self; +} + +#pragma mark - +#pragma mark Image rendering + +- (void)uploadBytes:(GLubyte *)bytesToUpload; +{ + [GPUImageOpenGLESContext useImageProcessingContext]; + + glBindTexture(GL_TEXTURE_2D, outputTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)uploadedImageSize.width, (int)uploadedImageSize.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, bytesToUpload); +} + +- (void)updateDataFromBytes:(GLubyte *)bytesToUpload size:(CGSize)imageSize; +{ + uploadedImageSize = imageSize; + + [self uploadBytes:bytesToUpload]; +} + +- (void)processData; +{ + CGSize pixelSizeOfImage = [self outputImageSize]; + + for (id currentTarget in targets) + { + NSInteger indexOfObject = [targets indexOfObject:currentTarget]; + NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue]; + + [currentTarget setInputSize:pixelSizeOfImage atIndex:textureIndexOfTarget]; + [currentTarget newFrameReadyAtTime:kCMTimeInvalid]; + } +} + +- (CGSize)outputImageSize; +{ + return uploadedImageSize; +} + @end diff --git a/framework/Source/GPUImageRawDataOutput.h b/framework/Source/GPUImageRawDataOutput.h index d8eb8ca66..8f492c3be 100755 --- a/framework/Source/GPUImageRawDataOutput.h +++ b/framework/Source/GPUImageRawDataOutput.h @@ -11,24 +11,21 @@ typedef struct GPUByteColorVector GPUByteColorVector; @protocol GPUImageRawDataProcessor; -@interface GPUImageRawData : NSObject { +@interface GPUImageRawDataOutput : NSObject { CGSize imageSize; CVOpenGLESTextureCacheRef rawDataTextureCache; CVPixelBufferRef renderTarget; GPUImageRotationMode inputRotation; } -@property(readwrite, unsafe_unretained, nonatomic) id delegate; @property(readonly) GLubyte *rawBytesForImage; +@property(nonatomic, copy) void(^newFrameAvailableBlock)(void); // Initialization and teardown - (id)initWithImageSize:(CGSize)newImageSize; // Data access - (GPUByteColorVector)colorAtLocation:(CGPoint)locationInImage; +- (NSUInteger)bytesPerRowInOutput; -@end - -@protocol GPUImageRawDataProcessor -- (void)newImageFrameAvailableFromDataSource:(GPUImageRawData *)rawDataSource; @end \ No newline at end of file diff --git a/framework/Source/GPUImageRawDataOutput.m b/framework/Source/GPUImageRawDataOutput.m index 6e38a4429..93cf916ed 100755 --- a/framework/Source/GPUImageRawDataOutput.m +++ b/framework/Source/GPUImageRawDataOutput.m @@ -1,10 +1,10 @@ -#import "GPUImageRawData.h" +#import "GPUImageRawDataOutput.h" #import "GPUImageOpenGLESContext.h" #import "GLProgram.h" #import "GPUImageFilter.h" -@interface GPUImageRawData () +@interface GPUImageRawDataOutput () { BOOL hasReadFromTheCurrentFrame; @@ -29,10 +29,10 @@ - (void)renderAtInternalSize; @end -@implementation GPUImageRawData +@implementation GPUImageRawDataOutput @synthesize rawBytesForImage = _rawBytesForImage; -@synthesize delegate = _delegate; +@synthesize newFrameAvailableBlock = _newFrameAvailableBlock; #pragma mark - #pragma mark Initialization and teardown @@ -82,7 +82,7 @@ - (void)dealloc { [self destroyDataFBO]; - if (_rawBytesForImage != NULL) + if (_rawBytesForImage != NULL && (![GPUImageOpenGLESContext supportsFastTextureUpload])) { free(_rawBytesForImage); _rawBytesForImage = NULL; @@ -218,10 +218,10 @@ - (void)renderAtInternalSize; }; static const GLfloat textureCoordinates[] = { - 0.0f, 1.0f, - 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, + 1.0f, 1.0f, }; glActiveTexture(GL_TEXTURE4); @@ -278,7 +278,11 @@ - (GPUByteColorVector)colorAtLocation:(CGPoint)locationInImage; - (void)newFrameReadyAtTime:(CMTime)frameTime; { hasReadFromTheCurrentFrame = NO; - [self.delegate newImageFrameAvailableFromDataSource:self]; + + if (_newFrameAvailableBlock != NULL) + { + _newFrameAvailableBlock(); + } } - (NSInteger)nextAvailableTextureIndex; @@ -344,6 +348,7 @@ - (GLubyte *)rawBytesForImage; if ([GPUImageOpenGLESContext supportsFastTextureUpload]) { + glFinish(); CVPixelBufferLockBaseAddress(renderTarget, 0); _rawBytesForImage = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget); } @@ -354,7 +359,18 @@ - (GLubyte *)rawBytesForImage; return _rawBytesForImage; } - +} + +- (NSUInteger)bytesPerRowInOutput; +{ + if ([GPUImageOpenGLESContext supportsFastTextureUpload]) + { + return CVPixelBufferGetBytesPerRow(renderTarget); + } + else + { + return imageSize.width; + } } @end diff --git a/framework/Source/GPUImageXYDerivativeFilter.m b/framework/Source/GPUImageXYDerivativeFilter.m index fdbcae913..3ff679b1a 100755 --- a/framework/Source/GPUImageXYDerivativeFilter.m +++ b/framework/Source/GPUImageXYDerivativeFilter.m @@ -36,8 +36,8 @@ void main() // float verticalDerivative = abs(-topLeftIntensity - topIntensity - topRightIntensity + bottomLeftIntensity + bottomIntensity + bottomRightIntensity); // float horizontalDerivative = abs(-bottomLeftIntensity - leftIntensity - topLeftIntensity + bottomRightIntensity + rightIntensity + topRightIntensity); - float verticalDerivative = abs(-topIntensity + bottomIntensity); - float horizontalDerivative = abs(-leftIntensity + rightIntensity); + float verticalDerivative = -topIntensity + bottomIntensity; + float horizontalDerivative = -leftIntensity + rightIntensity; gl_FragColor = vec4(horizontalDerivative * horizontalDerivative, verticalDerivative * verticalDerivative, verticalDerivative * horizontalDerivative, 1.0); }