Compare commits

..

55 Commits

Author SHA1 Message Date
chenliming 79ff5357ac update version 2016-12-21 09:55:42 +08:00
小歪~~~ 2989ffd911 Merge pull request #152 from linyehui/master
using NSMutableArray sortUsingFunction instead of NSArray sortedArray…
2016-12-20 15:58:37 +08:00
linyehui 0510aafead using NSMutableArray sortUsingFunction instead of NSArray sortedArrayUsingFunction
性能优化,同时也会修正多线程下使用LFStreamSocket推流的内存泄漏问题
2016-12-06 15:36:42 +08:00
chenliming f6feec3090 fix audioCapture crash 2016-11-17 10:26:56 +08:00
chenliming b3a8d96787 fix drop bug 2016-11-11 10:31:28 +08:00
chenliming ebc59bc4cf fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/135 2016-11-10 18:19:53 +08:00
chenliming 565453fe9e support swift3 2016-11-09 17:13:19 +08:00
chenliming 3e44e0ebe7 update readme 2016-11-09 14:38:00 +08:00
小歪~~~ f255d10c94 Merge pull request #129 from Zeaa/master
优化更新LFLiveKit中的部分注释错误、添加LFDebug类的description方法
2016-11-09 14:05:16 +08:00
chenliming b683ddacab add carthage 2016-11-08 21:47:13 +08:00
chenliming 4fbf00bfea fix watermark bug 2016-11-08 21:35:50 +08:00
chenliming e64ba9da09 submit source code 2016-11-08 21:16:54 +08:00
ftao a8a160324e 优化更新LFLiveKit中的部分注释错误、添加LFDebug的description方法 2016-10-31 11:33:45 +08:00
chenliming c12a8a7bfa Revert "编译问题"
This reverts commit e1b8812b25.
2016-10-21 14:52:52 +08:00
chenliming e1b8812b25 编译问题 2016-10-21 14:44:53 +08:00
chenliming a130058c5d ... 2016-10-21 14:34:49 +08:00
chenliming 3f804634c5 添加build脚本 2016-10-21 14:26:54 +08:00
chenliming 8b39f68a48 update version 2016-10-20 21:16:49 +08:00
chenliming 1d7b1f7073 添加demo 2016-10-20 21:15:49 +08:00
chenliming 47f35058f3 update version 2016-10-12 20:06:02 +08:00
chenliming a1a7e9aeea fix audioCapture crash 2016-10-12 16:22:49 +08:00
chenliming fabae8ddd8 update version 2016-10-09 10:53:38 +08:00
chenliming 12e1066cae update version 2016-10-08 18:37:42 +08:00
chenliming 05ca0f4f4b update version 2016-10-08 17:05:33 +08:00
chenliming 9e536d2291 add status refresh 2016-10-08 17:02:21 +08:00
chenliming 7bb976d4ae fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/108 2016-10-08 16:09:23 +08:00
chenliming 934d3f29ad changed to async 2016-10-08 14:34:36 +08:00
chenliming 87b3244ba5 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/105 2016-10-08 14:33:02 +08:00
小歪~~~ 23824e2b74 Merge pull request #104 from hannseman/master
Fixes deadlock in #100
2016-10-08 14:24:25 +08:00
Hannes Ljungberg 71d68c3e6e Fix deadlock by not checking for isRunning and stopping unit in callback. 2016-10-03 09:51:53 +02:00
小歪~~~ d9887180c3 Merge pull request #103 from ScottieLee/dev
Reset compression session when encoding error occurs
2016-09-30 11:38:33 +08:00
LiSi 30eac1282c Reset compression session when encoding error occurs 2016-09-30 10:51:36 +08:00
小歪~~~ 77d6a5b85b Merge pull request #92 from kciter/patch-1
Add syntax highlighting
2016-09-21 16:03:16 +08:00
chenliming 73c9adeb71 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/96 2016-09-21 16:00:13 +08:00
Lee Sun-Hyoup 7dcda23bf4 Add syntax highlighting 2016-09-17 16:58:01 +09:00
chenliming aa4f259edc save video to local for mp4 2016-09-14 09:15:55 +08:00
chenliming bc5dcef3b7 修改bug 2016-09-12 15:00:26 +08:00
chenliming 782b0c3c71 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/87 2016-09-12 14:46:33 +08:00
chenliming 34a2fdd3e2 update version 2016-09-07 20:52:23 +08:00
chenliming ae128ab66b modify dealloc bug 2016-09-07 20:51:29 +08:00
chenliming cb164ed1fe fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/78#issuecomment-244348216 2016-09-02 19:43:49 +08:00
chenliming c40b99c19a fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/76 2016-09-02 17:02:20 +08:00
chenliming 2a48333a9a 默认丢帧 2016-09-01 18:44:42 +08:00
chenliming 3c0c2eecb8 fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/75 2016-09-01 14:21:24 +08:00
chenliming 442f04124d fix bug https://github.com/LaiFengiOS/LFLiveKit/issues/74 2016-09-01 14:14:04 +08:00
chenliming c03bd61f37 modify travis 2016-08-31 14:11:25 +08:00
chenliming 161c0acd68 modify readme 2016-08-31 14:10:06 +08:00
chenliming b7be132a30 update 2016-08-31 13:41:39 +08:00
chenliming d30aecc802 fix 编译问题 2016-08-31 13:34:06 +08:00
chenliming b612be76bc update... 2016-08-31 11:52:44 +08:00
chenliming a322e2aa3f fix demo 编译问题 2016-08-31 11:27:55 +08:00
chenliming b0e88e182a remove pili_rtmp 2016-08-31 11:02:47 +08:00
chenliming 3ebd933b6c update version 2016-08-31 11:02:08 +08:00
chenliming db0814ca4c update 2016-08-31 11:00:43 +08:00
chenliming 3a9e0efb73 update 2016-08-31 10:46:14 +08:00
521 changed files with 42253 additions and 4415 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
language: objective-c
osx_image: xcode7
xcode_project: LFLiveKit/LFLiveKit.xcodeproj
xcode_project: FrameWork/LFLiveKit.xcodeproj
xcode_scheme: LFLiveKit
script:
- xctool -project LFLiveKit/LFLiveKit.xcodeproj -scheme 'LFLiveKit' -configuration Release -sdk iphonesimulator -arch i386 build
- xctool -project FrameWork/LFLiveKit.xcodeproj -scheme 'LFLiveKit' -configuration Release -sdk iphonesimulator -arch i386 build
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.2.2.7</string>
<string>2.6</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -14,10 +14,10 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84D8B4251D75778B00752B56"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
BlueprintIdentifier = "84D003751DB8FE1000560583"
BuildableName = "LFLiveKitFramework-universal"
BlueprintName = "LFLiveKitFramework-universal"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -29,15 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84D8B4251D75778B00752B56"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
@@ -51,16 +42,15 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84D8B4251D75778B00752B56"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
BlueprintIdentifier = "84D003751DB8FE1000560583"
BuildableName = "LFLiveKitFramework-universal"
BlueprintName = "LFLiveKitFramework-universal"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
@@ -70,16 +60,15 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "84D8B4251D75778B00752B56"
BuildableName = "LFLiveKitDemo.app"
BlueprintName = "LFLiveKitDemo"
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
BlueprintIdentifier = "84D003751DB8FE1000560583"
BuildableName = "LFLiveKitFramework-universal"
BlueprintName = "LFLiveKitFramework-universal"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8495F66A1DB8F14600542124"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKitFramework"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8495F66A1DB8F14600542124"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKitFramework"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8495F66A1DB8F14600542124"
BuildableName = "LFLiveKit.framework"
BlueprintName = "LFLiveKitFramework"
ReferencedContainer = "container:LFLiveKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.4.3</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
@@ -0,0 +1,26 @@
//
// LFLiveKitFramework.h
// LFLiveKitFramework
//
// Created by admin on 2016/10/20.
// Copyright © 2016年 admin. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for LFLiveKitFramework.
FOUNDATION_EXPORT double LFLiveKitFrameworkVersionNumber;
//! Project version string for LFLiveKitFramework.
FOUNDATION_EXPORT const unsigned char LFLiveKitFrameworkVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <LFLiveKitFramework/PublicHeader.h>
#import <LFLiveKit/LFLiveSession.h>
#import <LFLiveKit/LFLiveAudioConfiguration.h>
#import <LFLiveKit/LFLiveVideoConfiguration.h>
#import <LFLiveKit/LFAudioFrame.h>
#import <LFLiveKit/LFFrame.h>
#import <LFLiveKit/LFLiveStreamInfo.h>
#import <LFLiveKit/LFVideoFrame.h>
#import <LFLiveKit/LFLiveDebug.h>
+2 -5
View File
@@ -2,7 +2,7 @@
Pod::Spec.new do |s|
s.name = "LFLiveKit"
s.version = "2.2.2.7"
s.version = "2.6"
s.summary = "LaiFeng ios Live. LFLiveKit."
s.homepage = "https://github.com/chenliming777"
s.license = { :type => "MIT", :file => "LICENSE" }
@@ -11,13 +11,10 @@ Pod::Spec.new do |s|
s.ios.deployment_target = "7.0"
s.source = { :git => "https://github.com/LaiFengiOS/LFLiveKit.git", :tag => "#{s.version}" }
s.source_files = "LFLiveKit/**/*.{h,m,mm,cpp,c}"
#s.public_header_files = "LFLiveKit/LFLiveKit/**/*.h"
s.public_header_files = ['LFLiveKit/LFLiveKit/*.h', 'LFLiveKit/LFLiveKit/objects/*.h', 'LFLiveKit/LFLiveKit/configuration/*.h']
s.public_header_files = ['LFLiveKit/*.h', 'LFLiveKit/objects/*.h', 'LFLiveKit/configuration/*.h']
s.frameworks = "VideoToolbox", "AudioToolbox","AVFoundation","Foundation","UIKit"
s.libraries = "c++", "z"
s.requires_arc = true
s.ios.vendored_frameworks = 'Vendor/GPUImage.framework','Vendor/pili_rtmp.framework'
end
+22
View File
@@ -0,0 +1,22 @@
//
// LFLiveKit.h
// LFLiveKit
//
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#ifndef LFLiveKit_h
#define LFLiveKit_h
#import "LFLiveSession.h"
#import "LFLiveAudioConfiguration.h"
#import "LFLiveVideoConfiguration.h"
#import "LFAudioFrame.h"
#import "LFFrame.h"
#import "LFLiveStreamInfo.h"
#import "LFVideoFrame.h"
#import "LFLiveDebug.h"
#endif
@@ -1,565 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
84D8B3D21D75753300752B56 /* LFAudioCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B39C1D75753300752B56 /* LFAudioCapture.h */; };
84D8B3D31D75753300752B56 /* LFAudioCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B39D1D75753300752B56 /* LFAudioCapture.m */; };
84D8B3D41D75753300752B56 /* LFVideoCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B39E1D75753300752B56 /* LFVideoCapture.h */; };
84D8B3D51D75753300752B56 /* LFVideoCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B39F1D75753300752B56 /* LFVideoCapture.m */; };
84D8B3D61D75753300752B56 /* LFAVEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3A21D75753300752B56 /* LFAVEncoder.h */; };
84D8B3D71D75753300752B56 /* LFAVEncoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3A31D75753300752B56 /* LFAVEncoder.mm */; };
84D8B3D81D75753300752B56 /* LFMP4Atom.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3A41D75753300752B56 /* LFMP4Atom.h */; };
84D8B3D91D75753300752B56 /* LFMP4Atom.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3A51D75753300752B56 /* LFMP4Atom.m */; };
84D8B3DA1D75753300752B56 /* LFNALUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3A61D75753300752B56 /* LFNALUnit.cpp */; };
84D8B3DB1D75753300752B56 /* LFNALUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3A71D75753300752B56 /* LFNALUnit.h */; };
84D8B3DC1D75753300752B56 /* LFVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3A81D75753300752B56 /* LFVideoEncoder.h */; };
84D8B3DD1D75753300752B56 /* LFVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3A91D75753300752B56 /* LFVideoEncoder.m */; };
84D8B3DE1D75753300752B56 /* LFAudioEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3AA1D75753300752B56 /* LFAudioEncoding.h */; };
84D8B3DF1D75753300752B56 /* LFH264VideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3AB1D75753300752B56 /* LFH264VideoEncoder.h */; };
84D8B3E01D75753300752B56 /* LFH264VideoEncoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3AC1D75753300752B56 /* LFH264VideoEncoder.mm */; };
84D8B3E11D75753300752B56 /* LFHardwareAudioEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3AD1D75753300752B56 /* LFHardwareAudioEncoder.h */; };
84D8B3E21D75753300752B56 /* LFHardwareAudioEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3AE1D75753300752B56 /* LFHardwareAudioEncoder.m */; };
84D8B3E31D75753300752B56 /* LFHardwareVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3AF1D75753300752B56 /* LFHardwareVideoEncoder.h */; };
84D8B3E41D75753300752B56 /* LFHardwareVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3B01D75753300752B56 /* LFHardwareVideoEncoder.m */; };
84D8B3E51D75753300752B56 /* LFVideoEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3B11D75753300752B56 /* LFVideoEncoding.h */; };
84D8B3E61D75753300752B56 /* LFLiveAudioConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3B31D75753300752B56 /* LFLiveAudioConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B3E71D75753300752B56 /* LFLiveAudioConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3B41D75753300752B56 /* LFLiveAudioConfiguration.m */; };
84D8B3E81D75753300752B56 /* LFLiveVideoConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3B51D75753300752B56 /* LFLiveVideoConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B3E91D75753300752B56 /* LFLiveVideoConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3B61D75753300752B56 /* LFLiveVideoConfiguration.m */; };
84D8B3EA1D75753300752B56 /* LFGPUImageBeautyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3B81D75753300752B56 /* LFGPUImageBeautyFilter.h */; };
84D8B3EB1D75753300752B56 /* LFGPUImageBeautyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3B91D75753300752B56 /* LFGPUImageBeautyFilter.m */; };
84D8B3EC1D75753300752B56 /* LFGPUImageEmptyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3BA1D75753300752B56 /* LFGPUImageEmptyFilter.h */; };
84D8B3ED1D75753300752B56 /* LFGPUImageEmptyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3BB1D75753300752B56 /* LFGPUImageEmptyFilter.m */; };
84D8B3EE1D75753300752B56 /* LFLiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3BC1D75753300752B56 /* LFLiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B3EF1D75753300752B56 /* LFLiveSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3BD1D75753300752B56 /* LFLiveSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B3F01D75753300752B56 /* LFLiveSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3BE1D75753300752B56 /* LFLiveSession.m */; };
84D8B3F11D75753300752B56 /* LFAudioFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3C01D75753300752B56 /* LFAudioFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B3F21D75753300752B56 /* LFAudioFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3C11D75753300752B56 /* LFAudioFrame.m */; };
84D8B3F31D75753300752B56 /* LFFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3C21D75753300752B56 /* LFFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B3F41D75753300752B56 /* LFFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3C31D75753300752B56 /* LFFrame.m */; };
84D8B3F51D75753300752B56 /* LFLiveDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3C41D75753300752B56 /* LFLiveDebug.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B3F61D75753300752B56 /* LFLiveDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3C51D75753300752B56 /* LFLiveDebug.m */; };
84D8B3F71D75753300752B56 /* LFLiveStreamInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3C61D75753300752B56 /* LFLiveStreamInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B3F81D75753300752B56 /* LFLiveStreamInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3C71D75753300752B56 /* LFLiveStreamInfo.m */; };
84D8B3F91D75753300752B56 /* LFVideoFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3C81D75753300752B56 /* LFVideoFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
84D8B3FA1D75753300752B56 /* LFVideoFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3C91D75753300752B56 /* LFVideoFrame.m */; };
84D8B3FB1D75753300752B56 /* LFStreamingBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3CB1D75753300752B56 /* LFStreamingBuffer.h */; };
84D8B3FC1D75753300752B56 /* LFStreamingBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3CC1D75753300752B56 /* LFStreamingBuffer.m */; };
84D8B3FD1D75753300752B56 /* LFStreamRTMPSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3CD1D75753300752B56 /* LFStreamRTMPSocket.h */; };
84D8B3FE1D75753300752B56 /* LFStreamRtmpSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3CE1D75753300752B56 /* LFStreamRtmpSocket.m */; };
84D8B3FF1D75753300752B56 /* LFStreamSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3CF1D75753300752B56 /* LFStreamSocket.h */; };
84D8B4001D75753300752B56 /* NSMutableArray+LFAdd.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B3D01D75753300752B56 /* NSMutableArray+LFAdd.h */; };
84D8B4011D75753300752B56 /* NSMutableArray+LFAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B3D11D75753300752B56 /* NSMutableArray+LFAdd.m */; };
84D8B4BF1D757EB800752B56 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4BE1D757EB800752B56 /* VideoToolbox.framework */; };
84D8B4C11D757EBE00752B56 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4C01D757EBE00752B56 /* AudioToolbox.framework */; };
84D8B4C31D757EC400752B56 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4C21D757EC400752B56 /* AVFoundation.framework */; };
84D8B4C51D757EC800752B56 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4C41D757EC800752B56 /* Foundation.framework */; };
84D8B4C71D757ECC00752B56 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84D8B4C61D757ECC00752B56 /* UIKit.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
84D8B3901D7574D600752B56 /* LFLiveKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LFLiveKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
84D8B39C1D75753300752B56 /* LFAudioCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioCapture.h; sourceTree = "<group>"; };
84D8B39D1D75753300752B56 /* LFAudioCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFAudioCapture.m; sourceTree = "<group>"; };
84D8B39E1D75753300752B56 /* LFVideoCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoCapture.h; sourceTree = "<group>"; };
84D8B39F1D75753300752B56 /* LFVideoCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoCapture.m; sourceTree = "<group>"; };
84D8B3A21D75753300752B56 /* LFAVEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAVEncoder.h; sourceTree = "<group>"; };
84D8B3A31D75753300752B56 /* LFAVEncoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LFAVEncoder.mm; sourceTree = "<group>"; };
84D8B3A41D75753300752B56 /* LFMP4Atom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFMP4Atom.h; sourceTree = "<group>"; };
84D8B3A51D75753300752B56 /* LFMP4Atom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFMP4Atom.m; sourceTree = "<group>"; };
84D8B3A61D75753300752B56 /* LFNALUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LFNALUnit.cpp; sourceTree = "<group>"; };
84D8B3A71D75753300752B56 /* LFNALUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFNALUnit.h; sourceTree = "<group>"; };
84D8B3A81D75753300752B56 /* LFVideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoEncoder.h; sourceTree = "<group>"; };
84D8B3A91D75753300752B56 /* LFVideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoEncoder.m; sourceTree = "<group>"; };
84D8B3AA1D75753300752B56 /* LFAudioEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioEncoding.h; sourceTree = "<group>"; };
84D8B3AB1D75753300752B56 /* LFH264VideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFH264VideoEncoder.h; sourceTree = "<group>"; };
84D8B3AC1D75753300752B56 /* LFH264VideoEncoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LFH264VideoEncoder.mm; sourceTree = "<group>"; };
84D8B3AD1D75753300752B56 /* LFHardwareAudioEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFHardwareAudioEncoder.h; sourceTree = "<group>"; };
84D8B3AE1D75753300752B56 /* LFHardwareAudioEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFHardwareAudioEncoder.m; sourceTree = "<group>"; };
84D8B3AF1D75753300752B56 /* LFHardwareVideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFHardwareVideoEncoder.h; sourceTree = "<group>"; };
84D8B3B01D75753300752B56 /* LFHardwareVideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFHardwareVideoEncoder.m; sourceTree = "<group>"; };
84D8B3B11D75753300752B56 /* LFVideoEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoEncoding.h; sourceTree = "<group>"; };
84D8B3B31D75753300752B56 /* LFLiveAudioConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveAudioConfiguration.h; sourceTree = "<group>"; };
84D8B3B41D75753300752B56 /* LFLiveAudioConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveAudioConfiguration.m; sourceTree = "<group>"; };
84D8B3B51D75753300752B56 /* LFLiveVideoConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveVideoConfiguration.h; sourceTree = "<group>"; };
84D8B3B61D75753300752B56 /* LFLiveVideoConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveVideoConfiguration.m; sourceTree = "<group>"; };
84D8B3B81D75753300752B56 /* LFGPUImageBeautyFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFGPUImageBeautyFilter.h; sourceTree = "<group>"; };
84D8B3B91D75753300752B56 /* LFGPUImageBeautyFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFGPUImageBeautyFilter.m; sourceTree = "<group>"; };
84D8B3BA1D75753300752B56 /* LFGPUImageEmptyFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFGPUImageEmptyFilter.h; sourceTree = "<group>"; };
84D8B3BB1D75753300752B56 /* LFGPUImageEmptyFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFGPUImageEmptyFilter.m; sourceTree = "<group>"; };
84D8B3BC1D75753300752B56 /* LFLiveKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveKit.h; sourceTree = "<group>"; };
84D8B3BD1D75753300752B56 /* LFLiveSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveSession.h; sourceTree = "<group>"; };
84D8B3BE1D75753300752B56 /* LFLiveSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveSession.m; sourceTree = "<group>"; };
84D8B3C01D75753300752B56 /* LFAudioFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioFrame.h; sourceTree = "<group>"; };
84D8B3C11D75753300752B56 /* LFAudioFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFAudioFrame.m; sourceTree = "<group>"; };
84D8B3C21D75753300752B56 /* LFFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFFrame.h; sourceTree = "<group>"; };
84D8B3C31D75753300752B56 /* LFFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFFrame.m; sourceTree = "<group>"; };
84D8B3C41D75753300752B56 /* LFLiveDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveDebug.h; sourceTree = "<group>"; };
84D8B3C51D75753300752B56 /* LFLiveDebug.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveDebug.m; sourceTree = "<group>"; };
84D8B3C61D75753300752B56 /* LFLiveStreamInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveStreamInfo.h; sourceTree = "<group>"; };
84D8B3C71D75753300752B56 /* LFLiveStreamInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveStreamInfo.m; sourceTree = "<group>"; };
84D8B3C81D75753300752B56 /* LFVideoFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoFrame.h; sourceTree = "<group>"; };
84D8B3C91D75753300752B56 /* LFVideoFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoFrame.m; sourceTree = "<group>"; };
84D8B3CB1D75753300752B56 /* LFStreamingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFStreamingBuffer.h; sourceTree = "<group>"; };
84D8B3CC1D75753300752B56 /* LFStreamingBuffer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFStreamingBuffer.m; sourceTree = "<group>"; };
84D8B3CD1D75753300752B56 /* LFStreamRTMPSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFStreamRTMPSocket.h; sourceTree = "<group>"; };
84D8B3CE1D75753300752B56 /* LFStreamRtmpSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFStreamRtmpSocket.m; sourceTree = "<group>"; };
84D8B3CF1D75753300752B56 /* LFStreamSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFStreamSocket.h; sourceTree = "<group>"; };
84D8B3D01D75753300752B56 /* NSMutableArray+LFAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+LFAdd.h"; sourceTree = "<group>"; };
84D8B3D11D75753300752B56 /* NSMutableArray+LFAdd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+LFAdd.m"; sourceTree = "<group>"; };
84D8B4BE1D757EB800752B56 /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
84D8B4C01D757EBE00752B56 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
84D8B4C21D757EC400752B56 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
84D8B4C41D757EC800752B56 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
84D8B4C61D757ECC00752B56 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
84D8B4C81D757ED100752B56 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
84D8B4CA1D757ED600752B56 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
84D8B38C1D7574D600752B56 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84D8B4C71D757ECC00752B56 /* UIKit.framework in Frameworks */,
84D8B4C51D757EC800752B56 /* Foundation.framework in Frameworks */,
84D8B4C31D757EC400752B56 /* AVFoundation.framework in Frameworks */,
84D8B4C11D757EBE00752B56 /* AudioToolbox.framework in Frameworks */,
84D8B4BF1D757EB800752B56 /* VideoToolbox.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
84D8B3861D7574D600752B56 = {
isa = PBXGroup;
children = (
84D8B4CA1D757ED600752B56 /* libz.tbd */,
84D8B4C81D757ED100752B56 /* libstdc++.tbd */,
84D8B4C61D757ECC00752B56 /* UIKit.framework */,
84D8B4C41D757EC800752B56 /* Foundation.framework */,
84D8B4C21D757EC400752B56 /* AVFoundation.framework */,
84D8B4C01D757EBE00752B56 /* AudioToolbox.framework */,
84D8B4BE1D757EB800752B56 /* VideoToolbox.framework */,
84D8B3921D7574D600752B56 /* LFLiveKit */,
84D8B3911D7574D600752B56 /* Products */,
);
sourceTree = "<group>";
};
84D8B3911D7574D600752B56 /* Products */ = {
isa = PBXGroup;
children = (
84D8B3901D7574D600752B56 /* LFLiveKit.framework */,
);
name = Products;
sourceTree = "<group>";
};
84D8B3921D7574D600752B56 /* LFLiveKit */ = {
isa = PBXGroup;
children = (
84D8B39B1D75753300752B56 /* capture */,
84D8B3A01D75753300752B56 /* coder */,
84D8B3B21D75753300752B56 /* configuration */,
84D8B3B71D75753300752B56 /* filter */,
84D8B3BC1D75753300752B56 /* LFLiveKit.h */,
84D8B3BD1D75753300752B56 /* LFLiveSession.h */,
84D8B3BE1D75753300752B56 /* LFLiveSession.m */,
84D8B3BF1D75753300752B56 /* objects */,
84D8B3CA1D75753300752B56 /* publish */,
);
path = LFLiveKit;
sourceTree = "<group>";
};
84D8B39B1D75753300752B56 /* capture */ = {
isa = PBXGroup;
children = (
84D8B39C1D75753300752B56 /* LFAudioCapture.h */,
84D8B39D1D75753300752B56 /* LFAudioCapture.m */,
84D8B39E1D75753300752B56 /* LFVideoCapture.h */,
84D8B39F1D75753300752B56 /* LFVideoCapture.m */,
);
path = capture;
sourceTree = "<group>";
};
84D8B3A01D75753300752B56 /* coder */ = {
isa = PBXGroup;
children = (
84D8B3A11D75753300752B56 /* H264 */,
84D8B3AA1D75753300752B56 /* LFAudioEncoding.h */,
84D8B3AB1D75753300752B56 /* LFH264VideoEncoder.h */,
84D8B3AC1D75753300752B56 /* LFH264VideoEncoder.mm */,
84D8B3AD1D75753300752B56 /* LFHardwareAudioEncoder.h */,
84D8B3AE1D75753300752B56 /* LFHardwareAudioEncoder.m */,
84D8B3AF1D75753300752B56 /* LFHardwareVideoEncoder.h */,
84D8B3B01D75753300752B56 /* LFHardwareVideoEncoder.m */,
84D8B3B11D75753300752B56 /* LFVideoEncoding.h */,
);
path = coder;
sourceTree = "<group>";
};
84D8B3A11D75753300752B56 /* H264 */ = {
isa = PBXGroup;
children = (
84D8B3A21D75753300752B56 /* LFAVEncoder.h */,
84D8B3A31D75753300752B56 /* LFAVEncoder.mm */,
84D8B3A41D75753300752B56 /* LFMP4Atom.h */,
84D8B3A51D75753300752B56 /* LFMP4Atom.m */,
84D8B3A61D75753300752B56 /* LFNALUnit.cpp */,
84D8B3A71D75753300752B56 /* LFNALUnit.h */,
84D8B3A81D75753300752B56 /* LFVideoEncoder.h */,
84D8B3A91D75753300752B56 /* LFVideoEncoder.m */,
);
path = H264;
sourceTree = "<group>";
};
84D8B3B21D75753300752B56 /* configuration */ = {
isa = PBXGroup;
children = (
84D8B3B31D75753300752B56 /* LFLiveAudioConfiguration.h */,
84D8B3B41D75753300752B56 /* LFLiveAudioConfiguration.m */,
84D8B3B51D75753300752B56 /* LFLiveVideoConfiguration.h */,
84D8B3B61D75753300752B56 /* LFLiveVideoConfiguration.m */,
);
path = configuration;
sourceTree = "<group>";
};
84D8B3B71D75753300752B56 /* filter */ = {
isa = PBXGroup;
children = (
84D8B3B81D75753300752B56 /* LFGPUImageBeautyFilter.h */,
84D8B3B91D75753300752B56 /* LFGPUImageBeautyFilter.m */,
84D8B3BA1D75753300752B56 /* LFGPUImageEmptyFilter.h */,
84D8B3BB1D75753300752B56 /* LFGPUImageEmptyFilter.m */,
);
path = filter;
sourceTree = "<group>";
};
84D8B3BF1D75753300752B56 /* objects */ = {
isa = PBXGroup;
children = (
84D8B3C01D75753300752B56 /* LFAudioFrame.h */,
84D8B3C11D75753300752B56 /* LFAudioFrame.m */,
84D8B3C21D75753300752B56 /* LFFrame.h */,
84D8B3C31D75753300752B56 /* LFFrame.m */,
84D8B3C41D75753300752B56 /* LFLiveDebug.h */,
84D8B3C51D75753300752B56 /* LFLiveDebug.m */,
84D8B3C61D75753300752B56 /* LFLiveStreamInfo.h */,
84D8B3C71D75753300752B56 /* LFLiveStreamInfo.m */,
84D8B3C81D75753300752B56 /* LFVideoFrame.h */,
84D8B3C91D75753300752B56 /* LFVideoFrame.m */,
);
path = objects;
sourceTree = "<group>";
};
84D8B3CA1D75753300752B56 /* publish */ = {
isa = PBXGroup;
children = (
84D8B3CB1D75753300752B56 /* LFStreamingBuffer.h */,
84D8B3CC1D75753300752B56 /* LFStreamingBuffer.m */,
84D8B3CD1D75753300752B56 /* LFStreamRTMPSocket.h */,
84D8B3CE1D75753300752B56 /* LFStreamRtmpSocket.m */,
84D8B3CF1D75753300752B56 /* LFStreamSocket.h */,
84D8B3D01D75753300752B56 /* NSMutableArray+LFAdd.h */,
84D8B3D11D75753300752B56 /* NSMutableArray+LFAdd.m */,
);
path = publish;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
84D8B38D1D7574D600752B56 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
84D8B3F51D75753300752B56 /* LFLiveDebug.h in Headers */,
84D8B3E61D75753300752B56 /* LFLiveAudioConfiguration.h in Headers */,
84D8B3F11D75753300752B56 /* LFAudioFrame.h in Headers */,
84D8B3F71D75753300752B56 /* LFLiveStreamInfo.h in Headers */,
84D8B3E81D75753300752B56 /* LFLiveVideoConfiguration.h in Headers */,
84D8B3F31D75753300752B56 /* LFFrame.h in Headers */,
84D8B3EE1D75753300752B56 /* LFLiveKit.h in Headers */,
84D8B3EF1D75753300752B56 /* LFLiveSession.h in Headers */,
84D8B3F91D75753300752B56 /* LFVideoFrame.h in Headers */,
84D8B3D21D75753300752B56 /* LFAudioCapture.h in Headers */,
84D8B3FD1D75753300752B56 /* LFStreamRTMPSocket.h in Headers */,
84D8B3D81D75753300752B56 /* LFMP4Atom.h in Headers */,
84D8B3EA1D75753300752B56 /* LFGPUImageBeautyFilter.h in Headers */,
84D8B3D61D75753300752B56 /* LFAVEncoder.h in Headers */,
84D8B3DC1D75753300752B56 /* LFVideoEncoder.h in Headers */,
84D8B3EC1D75753300752B56 /* LFGPUImageEmptyFilter.h in Headers */,
84D8B3DE1D75753300752B56 /* LFAudioEncoding.h in Headers */,
84D8B4001D75753300752B56 /* NSMutableArray+LFAdd.h in Headers */,
84D8B3E31D75753300752B56 /* LFHardwareVideoEncoder.h in Headers */,
84D8B3D41D75753300752B56 /* LFVideoCapture.h in Headers */,
84D8B3FF1D75753300752B56 /* LFStreamSocket.h in Headers */,
84D8B3DB1D75753300752B56 /* LFNALUnit.h in Headers */,
84D8B3E11D75753300752B56 /* LFHardwareAudioEncoder.h in Headers */,
84D8B3E51D75753300752B56 /* LFVideoEncoding.h in Headers */,
84D8B3FB1D75753300752B56 /* LFStreamingBuffer.h in Headers */,
84D8B3DF1D75753300752B56 /* LFH264VideoEncoder.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
84D8B38F1D7574D600752B56 /* LFLiveKit */ = {
isa = PBXNativeTarget;
buildConfigurationList = 84D8B3981D7574D600752B56 /* Build configuration list for PBXNativeTarget "LFLiveKit" */;
buildPhases = (
84D8B38B1D7574D600752B56 /* Sources */,
84D8B38C1D7574D600752B56 /* Frameworks */,
84D8B38D1D7574D600752B56 /* Headers */,
84D8B38E1D7574D600752B56 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = LFLiveKit;
productName = LFLiveKit;
productReference = 84D8B3901D7574D600752B56 /* LFLiveKit.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
84D8B3871D7574D600752B56 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = admin;
TargetAttributes = {
84D8B38F1D7574D600752B56 = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = 84D8B38A1D7574D600752B56 /* Build configuration list for PBXProject "LFLiveKit" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 84D8B3861D7574D600752B56;
productRefGroup = 84D8B3911D7574D600752B56 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
84D8B38F1D7574D600752B56 /* LFLiveKit */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
84D8B38E1D7574D600752B56 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
84D8B38B1D7574D600752B56 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
84D8B3EB1D75753300752B56 /* LFGPUImageBeautyFilter.m in Sources */,
84D8B3F41D75753300752B56 /* LFFrame.m in Sources */,
84D8B3F61D75753300752B56 /* LFLiveDebug.m in Sources */,
84D8B3D51D75753300752B56 /* LFVideoCapture.m in Sources */,
84D8B3F21D75753300752B56 /* LFAudioFrame.m in Sources */,
84D8B3F81D75753300752B56 /* LFLiveStreamInfo.m in Sources */,
84D8B3DA1D75753300752B56 /* LFNALUnit.cpp in Sources */,
84D8B3D71D75753300752B56 /* LFAVEncoder.mm in Sources */,
84D8B3D91D75753300752B56 /* LFMP4Atom.m in Sources */,
84D8B3E91D75753300752B56 /* LFLiveVideoConfiguration.m in Sources */,
84D8B3DD1D75753300752B56 /* LFVideoEncoder.m in Sources */,
84D8B3ED1D75753300752B56 /* LFGPUImageEmptyFilter.m in Sources */,
84D8B3F01D75753300752B56 /* LFLiveSession.m in Sources */,
84D8B3FE1D75753300752B56 /* LFStreamRtmpSocket.m in Sources */,
84D8B3E71D75753300752B56 /* LFLiveAudioConfiguration.m in Sources */,
84D8B3E21D75753300752B56 /* LFHardwareAudioEncoder.m in Sources */,
84D8B3E01D75753300752B56 /* LFH264VideoEncoder.mm in Sources */,
84D8B3FC1D75753300752B56 /* LFStreamingBuffer.m in Sources */,
84D8B3E41D75753300752B56 /* LFHardwareVideoEncoder.m in Sources */,
84D8B3FA1D75753300752B56 /* LFVideoFrame.m in Sources */,
84D8B3D31D75753300752B56 /* LFAudioCapture.m in Sources */,
84D8B4011D75753300752B56 /* NSMutableArray+LFAdd.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
84D8B3961D7574D600752B56 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
84D8B3971D7574D600752B56 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
84D8B3991D7574D600752B56 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../Vendor/GPUImage.framework/Headers\"",
"\"$(SRCROOT)/../Vendor/pili_rtmp.framework/Headers\"",
);
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
84D8B39A1D7574D600752B56 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../Vendor/GPUImage.framework/Headers\"",
"\"$(SRCROOT)/../Vendor/pili_rtmp.framework/Headers\"",
);
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.youku.LFLiveKit;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
84D8B38A1D7574D600752B56 /* Build configuration list for PBXProject "LFLiveKit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84D8B3961D7574D600752B56 /* Debug */,
84D8B3971D7574D600752B56 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
84D8B3981D7574D600752B56 /* Build configuration list for PBXNativeTarget "LFLiveKit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84D8B3991D7574D600752B56 /* Debug */,
84D8B39A1D7574D600752B56 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 84D8B3871D7574D600752B56 /* Project object */;
}
-25
View File
@@ -1,25 +0,0 @@
//
// LFLiveKit.h
// LFLiveKit
//
// Created by admin on 16/5/24.
// Copyright © 2016年 admin. All rights reserved.
//
#import "LFLiveSession.h"
#import "LFLiveAudioConfiguration.h"
#import "LFLiveVideoConfiguration.h"
#import "LFAudioFrame.h"
#import "LFFrame.h"
#import "LFLiveStreamInfo.h"
#import "LFVideoFrame.h"
#import "LFLiveDebug.h"
//#import <LFLiveKit/LFLiveSession.h>
//#import <LFLiveKit/LFLiveAudioConfiguration.h>
//#import <LFLiveKit/LFLiveVideoConfiguration.h>
//#import <LFLiveKit/LFAudioFrame.h>
//#import <LFLiveKit/LFFrame.h>
//#import <LFLiveKit/LFLiveStreamInfo.h>
//#import <LFLiveKit/LFVideoFrame.h>
//#import <LFLiveKit/LFLiveDebug.h>
@@ -1,13 +0,0 @@
#if __has_include(<GPUImage/GPUImage.h>)
#import <GPUImage/GPUImage.h>
#elif __has_include("GPUImage/GPUImage.h")
#import "GPUImage/GPUImage.h"
#else
#import "GPUImage.h"
#endif
@interface LFGPUImageEmptyFilter : GPUImageFilter
{
}
@end
-14
View File
@@ -1,14 +0,0 @@
//
// LFLiveDebug.m
// LaiFeng
//
// Created by admin on 16/5/19.
// Copyright © 2016年 live Interactive. All rights reserved.
//
#import "LFLiveDebug.h"
@implementation LFLiveDebug
@end
@@ -2,8 +2,9 @@
// LFLiveSession.h
// LFLiveKit
//
// Created by 倾慕 on 16/5/2.
// Copyright © 2016年 倾慕. All rights reserved.
//
// Created by LaiFeng on 16/5/20.
// Copyright © 2016年 LaiFeng All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -15,6 +16,8 @@
#import "LFLiveVideoConfiguration.h"
#import "LFLiveDebug.h"
typedef NS_ENUM(NSInteger,LFLiveCaptureType) {
LFLiveCaptureAudio, //< capture only audio
LFLiveCaptureVideo, //< capture onlt video
@@ -115,7 +118,15 @@ typedef NS_ENUM(NSInteger,LFLiveCaptureTypeMask) {
*.*/
@property (nonatomic, strong, nullable) UIView *warterMarkView;
/* The currentImage is videoCapture shot */
@property (nonatomic, strong,readonly ,nullable) UIImage *currentImage;
/* The saveLocalVideo is save the local video */
@property (nonatomic, assign) BOOL saveLocalVideo;
/* The saveLocalVideoPath is save the local video path */
@property (nonatomic, strong, nullable) NSURL *saveLocalVideoPath;
#pragma mark - Initializer
///=============================================================================
/// @name Initializer
@@ -2,8 +2,8 @@
// LFLiveSession.m
// LFLiveKit
//
// Created by on 16/5/2.
// Copyright © 2016 . All rights reserved.
// Created by LaiFeng on 16/5/20.
// Copyright © 2016 LaiFeng All rights reserved.
//
#import "LFLiveSession.h"
@@ -90,8 +90,8 @@
}
- (void)dealloc {
self.videoCaptureSource.running = NO;
self.audioCaptureSource.running = NO;
_videoCaptureSource.running = NO;
_audioCaptureSource.running = NO;
}
#pragma mark -- CustomMethod
@@ -100,7 +100,6 @@
_streamInfo = streamInfo;
_streamInfo.videoConfiguration = _videoConfiguration;
_streamInfo.audioConfiguration = _audioConfiguration;
_streamInfo.needDropFrame = (self.captureType & LFLiveCaptureMaskVideo || self.captureType & LFLiveInputMaskVideo) ? YES : NO;//<
[self.socket start];
}
@@ -110,15 +109,6 @@
self.socket = nil;
}
#pragma mark -- PrivateMethod
- (void)pushSendBuffer:(LFFrame*)frame{
if(self.relativeTimestamps == 0){
self.relativeTimestamps = frame.timestamp;
}
frame.timestamp = [self uploadTimestamp:frame.timestamp];
[self.socket sendFrame:frame];
}
- (void)pushVideo:(nullable CVPixelBufferRef)pixelBuffer{
if(self.captureType & LFLiveInputMaskVideo){
if (self.uploading) [self.videoEncoder encodeVideoData:pixelBuffer timeStamp:NOW];
@@ -131,6 +121,15 @@
}
}
#pragma mark -- PrivateMethod
- (void)pushSendBuffer:(LFFrame*)frame{
if(self.relativeTimestamps == 0){
self.relativeTimestamps = frame.timestamp;
}
frame.timestamp = [self uploadTimestamp:frame.timestamp];
[self.socket sendFrame:frame];
}
#pragma mark -- CaptureDelegate
- (void)captureOutput:(nullable LFAudioCapture *)capture audioData:(nullable NSData*)audioData {
if (self.uploading) [self.audioEncoder encodeAudioData:audioData timeStamp:NOW];
@@ -252,6 +251,23 @@
[self didChangeValueForKey:@"beautyFace"];
}
- (BOOL)saveLocalVideo{
return self.videoCaptureSource.saveLocalVideo;
}
- (void)setSaveLocalVideo:(BOOL)saveLocalVideo{
[self.videoCaptureSource setSaveLocalVideo:saveLocalVideo];
}
- (NSURL*)saveLocalVideoPath{
return self.videoCaptureSource.saveLocalVideoPath;
}
- (void)setSaveLocalVideoPath:(NSURL*)saveLocalVideoPath{
[self.videoCaptureSource setSaveLocalVideoPath:saveLocalVideoPath];
}
- (BOOL)beautyFace {
return self.videoCaptureSource.beautyFace;
}
+236
View File
@@ -0,0 +1,236 @@
// This is Jeff LaMarche's GLProgram OpenGL shader wrapper class from his OpenGL ES 2.0 book.
// A description of this can be found at his page on the topic:
// http://iphonedevelopment.blogspot.com/2010/11/opengl-es-20-for-ios-chapter-4.html
#import "GLProgram.h"
// START:typedefs
#pragma mark Function Pointer Definitions
typedef void (*GLInfoFunction)(GLuint program, GLenum pname, GLint* params);
typedef void (*GLLogFunction) (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
// END:typedefs
#pragma mark -
#pragma mark Private Extension Method Declaration
// START:extension
@interface GLProgram()
- (BOOL)compileShader:(GLuint *)shader
type:(GLenum)type
string:(NSString *)shaderString;
@end
// END:extension
#pragma mark -
@implementation GLProgram
// START:init
@synthesize initialized = _initialized;
- (id)initWithVertexShaderString:(NSString *)vShaderString
fragmentShaderString:(NSString *)fShaderString;
{
if ((self = [super init]))
{
_initialized = NO;
attributes = [[NSMutableArray alloc] init];
uniforms = [[NSMutableArray alloc] init];
program = glCreateProgram();
if (![self compileShader:&vertShader
type:GL_VERTEX_SHADER
string:vShaderString])
{
NSLog(@"Failed to compile vertex shader");
}
// Create and compile fragment shader
if (![self compileShader:&fragShader
type:GL_FRAGMENT_SHADER
string:fShaderString])
{
NSLog(@"Failed to compile fragment shader");
}
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
}
return self;
}
- (id)initWithVertexShaderString:(NSString *)vShaderString
fragmentShaderFilename:(NSString *)fShaderFilename;
{
NSString *fragShaderPathname = [[NSBundle mainBundle] pathForResource:fShaderFilename ofType:@"fsh"];
NSString *fragmentShaderString = [NSString stringWithContentsOfFile:fragShaderPathname encoding:NSUTF8StringEncoding error:nil];
if ((self = [self initWithVertexShaderString:vShaderString fragmentShaderString:fragmentShaderString]))
{
}
return self;
}
- (id)initWithVertexShaderFilename:(NSString *)vShaderFilename
fragmentShaderFilename:(NSString *)fShaderFilename;
{
NSString *vertShaderPathname = [[NSBundle mainBundle] pathForResource:vShaderFilename ofType:@"vsh"];
NSString *vertexShaderString = [NSString stringWithContentsOfFile:vertShaderPathname encoding:NSUTF8StringEncoding error:nil];
NSString *fragShaderPathname = [[NSBundle mainBundle] pathForResource:fShaderFilename ofType:@"fsh"];
NSString *fragmentShaderString = [NSString stringWithContentsOfFile:fragShaderPathname encoding:NSUTF8StringEncoding error:nil];
if ((self = [self initWithVertexShaderString:vertexShaderString fragmentShaderString:fragmentShaderString]))
{
}
return self;
}
// END:init
// START:compile
- (BOOL)compileShader:(GLuint *)shader
type:(GLenum)type
string:(NSString *)shaderString
{
// CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
GLint status;
const GLchar *source;
source =
(GLchar *)[shaderString UTF8String];
if (!source)
{
NSLog(@"Failed to load vertex shader");
return NO;
}
*shader = glCreateShader(type);
glShaderSource(*shader, 1, &source, NULL);
glCompileShader(*shader);
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE)
{
GLint logLength;
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0)
{
GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(*shader, logLength, &logLength, log);
if (shader == &vertShader)
{
self.vertexShaderLog = [NSString stringWithFormat:@"%s", log];
}
else
{
self.fragmentShaderLog = [NSString stringWithFormat:@"%s", log];
}
free(log);
}
}
// CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
// NSLog(@"Compiled in %f ms", linkTime * 1000.0);
return status == GL_TRUE;
}
// END:compile
#pragma mark -
// START:addattribute
- (void)addAttribute:(NSString *)attributeName
{
if (![attributes containsObject:attributeName])
{
[attributes addObject:attributeName];
glBindAttribLocation(program,
(GLuint)[attributes indexOfObject:attributeName],
[attributeName UTF8String]);
}
}
// END:addattribute
// START:indexmethods
- (GLuint)attributeIndex:(NSString *)attributeName
{
return (GLuint)[attributes indexOfObject:attributeName];
}
- (GLuint)uniformIndex:(NSString *)uniformName
{
return glGetUniformLocation(program, [uniformName UTF8String]);
}
// END:indexmethods
#pragma mark -
// START:link
- (BOOL)link
{
// CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
GLint status;
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
return NO;
if (vertShader)
{
glDeleteShader(vertShader);
vertShader = 0;
}
if (fragShader)
{
glDeleteShader(fragShader);
fragShader = 0;
}
self.initialized = YES;
// CFAbsoluteTime linkTime = (CFAbsoluteTimeGetCurrent() - startTime);
// NSLog(@"Linked in %f ms", linkTime * 1000.0);
return YES;
}
// END:link
// START:use
- (void)use
{
glUseProgram(program);
}
// END:use
#pragma mark -
- (void)validate;
{
GLint logLength;
glValidateProgram(program);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0)
{
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(program, logLength, &logLength, log);
self.programLog = [NSString stringWithFormat:@"%s", log];
free(log);
}
}
#pragma mark -
// START:dealloc
- (void)dealloc
{
if (vertShader)
glDeleteShader(vertShader);
if (fragShader)
glDeleteShader(fragShader);
if (program)
glDeleteProgram(program);
}
// END:dealloc
@end
+128
View File
@@ -0,0 +1,128 @@
#import "GPUImage3x3ConvolutionFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImage3x3ConvolutionFragmentShaderString = SHADER_STRING
(
precision highp float;
uniform sampler2D inputImageTexture;
uniform mediump mat3 convolutionMatrix;
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
void main()
{
mediump vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;
mediump vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;
mediump vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;
mediump vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);
mediump vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;
mediump vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;
mediump vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;
mediump vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;
mediump vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;
mediump vec3 resultColor = topLeftColor * convolutionMatrix[0][0] + topColor * convolutionMatrix[0][1] + topRightColor * convolutionMatrix[0][2];
resultColor += leftColor * convolutionMatrix[1][0] + centerColor.rgb * convolutionMatrix[1][1] + rightColor * convolutionMatrix[1][2];
resultColor += bottomLeftColor * convolutionMatrix[2][0] + bottomColor * convolutionMatrix[2][1] + bottomRightColor * convolutionMatrix[2][2];
gl_FragColor = vec4(resultColor, centerColor.a);
}
);
#else
NSString *const kGPUImage3x3ConvolutionFragmentShaderString = SHADER_STRING
(
uniform sampler2D inputImageTexture;
uniform mat3 convolutionMatrix;
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
void main()
{
vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;
vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;
vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;
vec4 centerColor = texture2D(inputImageTexture, textureCoordinate);
vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;
vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;
vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;
vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;
vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;
vec3 resultColor = topLeftColor * convolutionMatrix[0][0] + topColor * convolutionMatrix[0][1] + topRightColor * convolutionMatrix[0][2];
resultColor += leftColor * convolutionMatrix[1][0] + centerColor.rgb * convolutionMatrix[1][1] + rightColor * convolutionMatrix[1][2];
resultColor += bottomLeftColor * convolutionMatrix[2][0] + bottomColor * convolutionMatrix[2][1] + bottomRightColor * convolutionMatrix[2][2];
gl_FragColor = vec4(resultColor, centerColor.a);
}
);
#endif
@implementation GPUImage3x3ConvolutionFilter
@synthesize convolutionKernel = _convolutionKernel;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [self initWithFragmentShaderFromString:kGPUImage3x3ConvolutionFragmentShaderString]))
{
return nil;
}
self.convolutionKernel = (GPUMatrix3x3){
{0.f, 0.f, 0.f},
{0.f, 1.f, 0.f},
{0.f, 0.f, 0.f}
};
return self;
}
- (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString;
{
if (!(self = [super initWithFragmentShaderFromString:fragmentShaderString]))
{
return nil;
}
convolutionMatrixUniform = [filterProgram uniformIndex:@"convolutionMatrix"];
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setConvolutionKernel:(GPUMatrix3x3)newValue;
{
_convolutionKernel = newValue;
[self setMatrix3f:_convolutionKernel forUniform:convolutionMatrixUniform program:filterProgram];
}
@end
@@ -0,0 +1,121 @@
#import "GPUImage3x3TextureSamplingFilter.h"
// Override vertex shader to remove dependent texture reads
NSString *const kGPUImageNearbyTexelSamplingVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
uniform float texelWidth;
uniform float texelHeight;
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
void main()
{
gl_Position = position;
vec2 widthStep = vec2(texelWidth, 0.0);
vec2 heightStep = vec2(0.0, texelHeight);
vec2 widthHeightStep = vec2(texelWidth, texelHeight);
vec2 widthNegativeHeightStep = vec2(texelWidth, -texelHeight);
textureCoordinate = inputTextureCoordinate.xy;
leftTextureCoordinate = inputTextureCoordinate.xy - widthStep;
rightTextureCoordinate = inputTextureCoordinate.xy + widthStep;
topTextureCoordinate = inputTextureCoordinate.xy - heightStep;
topLeftTextureCoordinate = inputTextureCoordinate.xy - widthHeightStep;
topRightTextureCoordinate = inputTextureCoordinate.xy + widthNegativeHeightStep;
bottomTextureCoordinate = inputTextureCoordinate.xy + heightStep;
bottomLeftTextureCoordinate = inputTextureCoordinate.xy - widthNegativeHeightStep;
bottomRightTextureCoordinate = inputTextureCoordinate.xy + widthHeightStep;
}
);
@implementation GPUImage3x3TextureSamplingFilter
@synthesize texelWidth = _texelWidth;
@synthesize texelHeight = _texelHeight;
#pragma mark -
#pragma mark Initialization and teardown
- (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShaderFromString:(NSString *)fragmentShaderString;
{
if (!(self = [super initWithVertexShaderFromString:vertexShaderString fragmentShaderFromString:fragmentShaderString]))
{
return nil;
}
texelWidthUniform = [filterProgram uniformIndex:@"texelWidth"];
texelHeightUniform = [filterProgram uniformIndex:@"texelHeight"];
return self;
}
- (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString;
{
if (!(self = [self initWithVertexShaderFromString:kGPUImageNearbyTexelSamplingVertexShaderString fragmentShaderFromString:fragmentShaderString]))
{
return nil;
}
return self;
}
- (void)setupFilterForSize:(CGSize)filterFrameSize;
{
if (!hasOverriddenImageSizeFactor)
{
_texelWidth = 1.0 / filterFrameSize.width;
_texelHeight = 1.0 / filterFrameSize.height;
runSynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext setActiveShaderProgram:filterProgram];
if (GPUImageRotationSwapsWidthAndHeight(inputRotation))
{
glUniform1f(texelWidthUniform, _texelHeight);
glUniform1f(texelHeightUniform, _texelWidth);
}
else
{
glUniform1f(texelWidthUniform, _texelWidth);
glUniform1f(texelHeightUniform, _texelHeight);
}
});
}
}
#pragma mark -
#pragma mark Accessors
- (void)setTexelWidth:(CGFloat)newValue;
{
hasOverriddenImageSizeFactor = YES;
_texelWidth = newValue;
[self setFloat:_texelWidth forUniform:texelWidthUniform program:filterProgram];
}
- (void)setTexelHeight:(CGFloat)newValue;
{
hasOverriddenImageSizeFactor = YES;
_texelHeight = newValue;
[self setFloat:_texelHeight forUniform:texelHeightUniform program:filterProgram];
}
@end
+100
View File
@@ -0,0 +1,100 @@
#import "GPUImageAdaptiveThresholdFilter.h"
#import "GPUImageFilter.h"
#import "GPUImageTwoInputFilter.h"
#import "GPUImageGrayscaleFilter.h"
#import "GPUImageBoxBlurFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageAdaptiveThresholdFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
highp float blurredInput = texture2D(inputImageTexture, textureCoordinate).r;
highp float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r;
highp float thresholdResult = step(blurredInput - 0.05, localLuminance);
gl_FragColor = vec4(vec3(thresholdResult), 1.0);
}
);
#else
NSString *const kGPUImageAdaptiveThresholdFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
float blurredInput = texture2D(inputImageTexture, textureCoordinate).r;
float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r;
float thresholdResult = step(blurredInput - 0.05, localLuminance);
gl_FragColor = vec4(vec3(thresholdResult), 1.0);
}
);
#endif
@interface GPUImageAdaptiveThresholdFilter()
{
GPUImageBoxBlurFilter *boxBlurFilter;
}
@end
@implementation GPUImageAdaptiveThresholdFilter
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super init]))
{
return nil;
}
// First pass: reduce to luminance
GPUImageGrayscaleFilter *luminanceFilter = [[GPUImageGrayscaleFilter alloc] init];
[self addFilter:luminanceFilter];
// Second pass: perform a box blur
boxBlurFilter = [[GPUImageBoxBlurFilter alloc] init];
[self addFilter:boxBlurFilter];
// Third pass: compare the blurred background luminance to the local value
GPUImageFilter *adaptiveThresholdFilter = [[GPUImageTwoInputFilter alloc] initWithFragmentShaderFromString:kGPUImageAdaptiveThresholdFragmentShaderString];
[self addFilter:adaptiveThresholdFilter];
[luminanceFilter addTarget:boxBlurFilter];
[boxBlurFilter addTarget:adaptiveThresholdFilter];
// To prevent double updating of this filter, disable updates from the sharp luminance image side
[luminanceFilter addTarget:adaptiveThresholdFilter];
self.initialFilters = [NSArray arrayWithObject:luminanceFilter];
self.terminalFilter = adaptiveThresholdFilter;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setBlurRadiusInPixels:(CGFloat)newValue;
{
boxBlurFilter.blurRadiusInPixels = newValue;
}
- (CGFloat)blurRadiusInPixels;
{
return boxBlurFilter.blurRadiusInPixels;
}
@end
+100
View File
@@ -0,0 +1,100 @@
#import "GPUImageAddBlendFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageAddBlendFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);
mediump float r;
if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) {
r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);
} else {
r = overlay.r + base.r;
}
mediump float g;
if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) {
g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);
} else {
g = overlay.g + base.g;
}
mediump float b;
if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) {
b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);
} else {
b = overlay.b + base.b;
}
mediump float a = overlay.a + base.a - overlay.a * base.a;
gl_FragColor = vec4(r, g, b, a);
}
);
#else
NSString *const kGPUImageAddBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 base = texture2D(inputImageTexture, textureCoordinate);
vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);
float r;
if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) {
r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);
} else {
r = overlay.r + base.r;
}
float g;
if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) {
g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);
} else {
g = overlay.g + base.g;
}
float b;
if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) {
b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);
} else {
b = overlay.b + base.b;
}
float a = overlay.a + base.a - overlay.a * base.a;
gl_FragColor = vec4(r, g, b, a);
}
);
#endif
@implementation GPUImageAddBlendFilter
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageAddBlendFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+72
View File
@@ -0,0 +1,72 @@
#import "GPUImageAlphaBlendFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageAlphaBlendFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform lowp float mixturePercent;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a);
}
);
#else
NSString *const kGPUImageAlphaBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform float mixturePercent;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a);
}
);
#endif
@implementation GPUImageAlphaBlendFilter
@synthesize mix = _mix;
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageAlphaBlendFragmentShaderString]))
{
return nil;
}
mixUniform = [filterProgram uniformIndex:@"mixturePercent"];
self.mix = 0.5;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setMix:(CGFloat)newValue;
{
_mix = newValue;
[self setFloat:_mix forUniform:mixUniform program:filterProgram];
}
@end
+38
View File
@@ -0,0 +1,38 @@
#import "GPUImageAmatorkaFilter.h"
#import "GPUImagePicture.h"
#import "GPUImageLookupFilter.h"
@implementation GPUImageAmatorkaFilter
- (id)init;
{
if (!(self = [super init]))
{
return nil;
}
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
UIImage *image = [UIImage imageNamed:@"lookup_amatorka.png"];
#else
NSImage *image = [NSImage imageNamed:@"lookup_amatorka.png"];
#endif
NSAssert(image, @"To use GPUImageAmatorkaFilter you need to add lookup_amatorka.png from GPUImage/framework/Resources to your application bundle.");
lookupImageSource = [[GPUImagePicture alloc] initWithImage:image];
GPUImageLookupFilter *lookupFilter = [[GPUImageLookupFilter alloc] init];
[self addFilter:lookupFilter];
[lookupImageSource addTarget:lookupFilter atTextureLocation:1];
[lookupImageSource processImage];
self.initialFilters = [NSArray arrayWithObjects:lookupFilter, nil];
self.terminalFilter = lookupFilter;
return self;
}
#pragma mark -
#pragma mark Accessors
@end
+204
View File
@@ -0,0 +1,204 @@
#import "GPUImageAverageColor.h"
NSString *const kGPUImageColorAveragingVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
uniform float texelWidth;
uniform float texelHeight;
varying vec2 upperLeftInputTextureCoordinate;
varying vec2 upperRightInputTextureCoordinate;
varying vec2 lowerLeftInputTextureCoordinate;
varying vec2 lowerRightInputTextureCoordinate;
void main()
{
gl_Position = position;
upperLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, -texelHeight);
upperRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, -texelHeight);
lowerLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, texelHeight);
lowerRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, texelHeight);
}
);
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageColorAveragingFragmentShaderString = SHADER_STRING
(
precision highp float;
uniform sampler2D inputImageTexture;
varying highp vec2 outputTextureCoordinate;
varying highp vec2 upperLeftInputTextureCoordinate;
varying highp vec2 upperRightInputTextureCoordinate;
varying highp vec2 lowerLeftInputTextureCoordinate;
varying highp vec2 lowerRightInputTextureCoordinate;
void main()
{
highp vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate);
highp vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate);
highp vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate);
highp vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate);
gl_FragColor = 0.25 * (upperLeftColor + upperRightColor + lowerLeftColor + lowerRightColor);
}
);
#else
NSString *const kGPUImageColorAveragingFragmentShaderString = SHADER_STRING
(
uniform sampler2D inputImageTexture;
varying vec2 outputTextureCoordinate;
varying vec2 upperLeftInputTextureCoordinate;
varying vec2 upperRightInputTextureCoordinate;
varying vec2 lowerLeftInputTextureCoordinate;
varying vec2 lowerRightInputTextureCoordinate;
void main()
{
vec4 upperLeftColor = texture2D(inputImageTexture, upperLeftInputTextureCoordinate);
vec4 upperRightColor = texture2D(inputImageTexture, upperRightInputTextureCoordinate);
vec4 lowerLeftColor = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate);
vec4 lowerRightColor = texture2D(inputImageTexture, lowerRightInputTextureCoordinate);
gl_FragColor = 0.25 * (upperLeftColor + upperRightColor + lowerLeftColor + lowerRightColor);
}
);
#endif
@implementation GPUImageAverageColor
@synthesize colorAverageProcessingFinishedBlock = _colorAverageProcessingFinishedBlock;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithVertexShaderFromString:kGPUImageColorAveragingVertexShaderString fragmentShaderFromString:kGPUImageColorAveragingFragmentShaderString]))
{
return nil;
}
texelWidthUniform = [filterProgram uniformIndex:@"texelWidth"];
texelHeightUniform = [filterProgram uniformIndex:@"texelHeight"];
finalStageSize = CGSizeMake(1.0, 1.0);
__unsafe_unretained GPUImageAverageColor *weakSelf = self;
[self setFrameProcessingCompletionBlock:^(GPUImageOutput *filter, CMTime frameTime) {
[weakSelf extractAverageColorAtFrameTime:frameTime];
}];
return self;
}
- (void)dealloc;
{
if (rawImagePixels != NULL)
{
free(rawImagePixels);
}
}
#pragma mark -
#pragma mark Managing the display FBOs
- (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates;
{
if (self.preventRendering)
{
[firstInputFramebuffer unlock];
return;
}
outputFramebuffer = nil;
[GPUImageContext setActiveShaderProgram:filterProgram];
glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, vertices);
glVertexAttribPointer(filterTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, textureCoordinates);
GLuint currentTexture = [firstInputFramebuffer texture];
NSUInteger numberOfReductionsInX = floor(log(inputTextureSize.width) / log(4.0));
NSUInteger numberOfReductionsInY = floor(log(inputTextureSize.height) / log(4.0));
NSUInteger reductionsToHitSideLimit = MIN(numberOfReductionsInX, numberOfReductionsInY);
for (NSUInteger currentReduction = 0; currentReduction < reductionsToHitSideLimit; currentReduction++)
{
CGSize currentStageSize = CGSizeMake(floor(inputTextureSize.width / pow(4.0, currentReduction + 1.0)), floor(inputTextureSize.height / pow(4.0, currentReduction + 1.0)));
[outputFramebuffer unlock];
outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:currentStageSize textureOptions:self.outputTextureOptions onlyTexture:NO];
[outputFramebuffer activateFramebuffer];
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, currentTexture);
glUniform1i(filterInputTextureUniform, 2);
glUniform1f(texelWidthUniform, 0.25 / currentStageSize.width);
glUniform1f(texelHeightUniform, 0.25 / currentStageSize.height);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
currentTexture = [outputFramebuffer texture];
finalStageSize = currentStageSize;
}
[firstInputFramebuffer unlock];
}
- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;
{
inputRotation = kGPUImageNoRotation;
}
- (void)extractAverageColorAtFrameTime:(CMTime)frameTime;
{
runSynchronouslyOnVideoProcessingQueue(^{
// we need a normal color texture for averaging the color values
NSAssert(self.outputTextureOptions.internalFormat == GL_RGBA, @"The output texture internal format for this filter must be GL_RGBA.");
NSAssert(self.outputTextureOptions.type == GL_UNSIGNED_BYTE, @"The type of the output texture of this filter must be GL_UNSIGNED_BYTE.");
NSUInteger totalNumberOfPixels = round(finalStageSize.width * finalStageSize.height);
if (rawImagePixels == NULL)
{
rawImagePixels = (GLubyte *)malloc(totalNumberOfPixels * 4);
}
[GPUImageContext useImageProcessingContext];
[outputFramebuffer activateFramebuffer];
glReadPixels(0, 0, (int)finalStageSize.width, (int)finalStageSize.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels);
NSUInteger redTotal = 0, greenTotal = 0, blueTotal = 0, alphaTotal = 0;
NSUInteger byteIndex = 0;
for (NSUInteger currentPixel = 0; currentPixel < totalNumberOfPixels; currentPixel++)
{
redTotal += rawImagePixels[byteIndex++];
greenTotal += rawImagePixels[byteIndex++];
blueTotal += rawImagePixels[byteIndex++];
alphaTotal += rawImagePixels[byteIndex++];
}
CGFloat normalizedRedTotal = (CGFloat)redTotal / (CGFloat)totalNumberOfPixels / 255.0;
CGFloat normalizedGreenTotal = (CGFloat)greenTotal / (CGFloat)totalNumberOfPixels / 255.0;
CGFloat normalizedBlueTotal = (CGFloat)blueTotal / (CGFloat)totalNumberOfPixels / 255.0;
CGFloat normalizedAlphaTotal = (CGFloat)alphaTotal / (CGFloat)totalNumberOfPixels / 255.0;
if (_colorAverageProcessingFinishedBlock != NULL)
{
_colorAverageProcessingFinishedBlock(normalizedRedTotal, normalizedGreenTotal, normalizedBlueTotal, normalizedAlphaTotal, frameTime);
}
});
}
@end
@@ -0,0 +1,47 @@
#import "GPUImageAverageLuminanceThresholdFilter.h"
#import "GPUImageLuminosity.h"
#import "GPUImageLuminanceThresholdFilter.h"
@interface GPUImageAverageLuminanceThresholdFilter()
{
GPUImageLuminosity *luminosityFilter;
GPUImageLuminanceThresholdFilter *luminanceThresholdFilter;
}
@end
@implementation GPUImageAverageLuminanceThresholdFilter
@synthesize thresholdMultiplier = _thresholdMultiplier;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super init]))
{
return nil;
}
self.thresholdMultiplier = 1.0;
luminosityFilter = [[GPUImageLuminosity alloc] init];
[self addFilter:luminosityFilter];
luminanceThresholdFilter = [[GPUImageLuminanceThresholdFilter alloc] init];
[self addFilter:luminanceThresholdFilter];
__unsafe_unretained GPUImageAverageLuminanceThresholdFilter *weakSelf = self;
__unsafe_unretained GPUImageLuminanceThresholdFilter *weakThreshold = luminanceThresholdFilter;
[luminosityFilter setLuminosityProcessingFinishedBlock:^(CGFloat luminosity, CMTime frameTime) {
weakThreshold.threshold = luminosity * weakSelf.thresholdMultiplier;
}];
self.initialFilters = [NSArray arrayWithObjects:luminosityFilter, luminanceThresholdFilter, nil];
self.terminalFilter = luminanceThresholdFilter;
return self;
}
@end
+231
View File
@@ -0,0 +1,231 @@
#import "GPUImageBilateralFilter.h"
NSString *const kGPUImageBilateralBlurVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
const int GAUSSIAN_SAMPLES = 9;
uniform float texelWidthOffset;
uniform float texelHeightOffset;
varying vec2 textureCoordinate;
varying vec2 blurCoordinates[GAUSSIAN_SAMPLES];
void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
// Calculate the positions for the blur
int multiplier = 0;
vec2 blurStep;
vec2 singleStepOffset = vec2(texelWidthOffset, texelHeightOffset);
for (int i = 0; i < GAUSSIAN_SAMPLES; i++)
{
multiplier = (i - ((GAUSSIAN_SAMPLES - 1) / 2));
// Blur in x (horizontal)
blurStep = float(multiplier) * singleStepOffset;
blurCoordinates[i] = inputTextureCoordinate.xy + blurStep;
}
}
);
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageBilateralFilterFragmentShaderString = SHADER_STRING
(
uniform sampler2D inputImageTexture;
const lowp int GAUSSIAN_SAMPLES = 9;
varying highp vec2 textureCoordinate;
varying highp vec2 blurCoordinates[GAUSSIAN_SAMPLES];
uniform mediump float distanceNormalizationFactor;
void main()
{
lowp vec4 centralColor;
lowp float gaussianWeightTotal;
lowp vec4 sum;
lowp vec4 sampleColor;
lowp float distanceFromCentralColor;
lowp float gaussianWeight;
centralColor = texture2D(inputImageTexture, blurCoordinates[4]);
gaussianWeightTotal = 0.18;
sum = centralColor * 0.18;
sampleColor = texture2D(inputImageTexture, blurCoordinates[0]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[1]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[2]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[3]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[5]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[6]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[7]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[8]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
gl_FragColor = sum / gaussianWeightTotal;
}
);
#else
NSString *const kGPUImageBilateralFilterFragmentShaderString = SHADER_STRING
(
uniform sampler2D inputImageTexture;
const int GAUSSIAN_SAMPLES = 9;
varying vec2 textureCoordinate;
varying vec2 blurCoordinates[GAUSSIAN_SAMPLES];
uniform float distanceNormalizationFactor;
void main()
{
vec4 centralColor;
float gaussianWeightTotal;
vec4 sum;
vec4 sampleColor;
float distanceFromCentralColor;
float gaussianWeight;
centralColor = texture2D(inputImageTexture, blurCoordinates[4]);
gaussianWeightTotal = 0.18;
sum = centralColor * 0.18;
sampleColor = texture2D(inputImageTexture, blurCoordinates[0]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[1]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[2]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[3]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[5]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.15 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[6]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.12 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[7]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.09 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
sampleColor = texture2D(inputImageTexture, blurCoordinates[8]);
distanceFromCentralColor = min(distance(centralColor, sampleColor) * distanceNormalizationFactor, 1.0);
gaussianWeight = 0.05 * (1.0 - distanceFromCentralColor);
gaussianWeightTotal += gaussianWeight;
sum += sampleColor * gaussianWeight;
gl_FragColor = sum / gaussianWeightTotal;
}
);
#endif
@implementation GPUImageBilateralFilter
@synthesize distanceNormalizationFactor = _distanceNormalizationFactor;
- (id)init;
{
if (!(self = [super initWithFirstStageVertexShaderFromString:kGPUImageBilateralBlurVertexShaderString
firstStageFragmentShaderFromString:kGPUImageBilateralFilterFragmentShaderString
secondStageVertexShaderFromString:kGPUImageBilateralBlurVertexShaderString
secondStageFragmentShaderFromString:kGPUImageBilateralFilterFragmentShaderString])) {
return nil;
}
firstDistanceNormalizationFactorUniform = [filterProgram uniformIndex:@"distanceNormalizationFactor"];
secondDistanceNormalizationFactorUniform = [filterProgram uniformIndex:@"distanceNormalizationFactor"];
self.texelSpacingMultiplier = 4.0;
self.distanceNormalizationFactor = 8.0;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setDistanceNormalizationFactor:(CGFloat)newValue
{
_distanceNormalizationFactor = newValue;
[self setFloat:newValue
forUniform:firstDistanceNormalizationFactorUniform
program:filterProgram];
[self setFloat:newValue
forUniform:secondDistanceNormalizationFactorUniform
program:secondFilterProgram];
}
@end
+178
View File
@@ -0,0 +1,178 @@
#import "GPUImageBoxBlurFilter.h"
@implementation GPUImageBoxBlurFilter
+ (NSString *)vertexShaderForOptimizedBlurOfRadius:(NSUInteger)blurRadius sigma:(CGFloat)sigma;
{
if (blurRadius < 1)
{
return kGPUImageVertexShaderString;
}
// From these weights we calculate the offsets to read interpolated values from
NSUInteger numberOfOptimizedOffsets = MIN(blurRadius / 2 + (blurRadius % 2), 7);
NSMutableString *shaderString = [[NSMutableString alloc] init];
// Header
[shaderString appendFormat:@"\
attribute vec4 position;\n\
attribute vec4 inputTextureCoordinate;\n\
\n\
uniform float texelWidthOffset;\n\
uniform float texelHeightOffset;\n\
\n\
varying vec2 blurCoordinates[%lu];\n\
\n\
void main()\n\
{\n\
gl_Position = position;\n\
\n\
vec2 singleStepOffset = vec2(texelWidthOffset, texelHeightOffset);\n", (unsigned long)(1 + (numberOfOptimizedOffsets * 2))];
// Inner offset loop
[shaderString appendString:@"blurCoordinates[0] = inputTextureCoordinate.xy;\n"];
for (NSUInteger currentOptimizedOffset = 0; currentOptimizedOffset < numberOfOptimizedOffsets; currentOptimizedOffset++)
{
GLfloat optimizedOffset = (GLfloat)(currentOptimizedOffset * 2) + 1.5;
[shaderString appendFormat:@"\
blurCoordinates[%lu] = inputTextureCoordinate.xy + singleStepOffset * %f;\n\
blurCoordinates[%lu] = inputTextureCoordinate.xy - singleStepOffset * %f;\n", (unsigned long)((currentOptimizedOffset * 2) + 1), optimizedOffset, (unsigned long)((currentOptimizedOffset * 2) + 2), optimizedOffset];
}
// Footer
[shaderString appendString:@"}\n"];
return shaderString;
}
+ (NSString *)fragmentShaderForOptimizedBlurOfRadius:(NSUInteger)blurRadius sigma:(CGFloat)sigma;
{
if (blurRadius < 1)
{
return kGPUImagePassthroughFragmentShaderString;
}
NSUInteger numberOfOptimizedOffsets = MIN(blurRadius / 2 + (blurRadius % 2), 7);
NSUInteger trueNumberOfOptimizedOffsets = blurRadius / 2 + (blurRadius % 2);
NSMutableString *shaderString = [[NSMutableString alloc] init];
// Header
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
[shaderString appendFormat:@"\
uniform sampler2D inputImageTexture;\n\
uniform highp float texelWidthOffset;\n\
uniform highp float texelHeightOffset;\n\
\n\
varying highp vec2 blurCoordinates[%lu];\n\
\n\
void main()\n\
{\n\
lowp vec4 sum = vec4(0.0);\n", (unsigned long)(1 + (numberOfOptimizedOffsets * 2)) ];
#else
[shaderString appendFormat:@"\
uniform sampler2D inputImageTexture;\n\
uniform float texelWidthOffset;\n\
uniform float texelHeightOffset;\n\
\n\
varying vec2 blurCoordinates[%lu];\n\
\n\
void main()\n\
{\n\
vec4 sum = vec4(0.0);\n", 1 + (numberOfOptimizedOffsets * 2) ];
#endif
GLfloat boxWeight = 1.0 / (GLfloat)((blurRadius * 2) + 1);
// Inner texture loop
[shaderString appendFormat:@"sum += texture2D(inputImageTexture, blurCoordinates[0]) * %f;\n", boxWeight];
for (NSUInteger currentBlurCoordinateIndex = 0; currentBlurCoordinateIndex < numberOfOptimizedOffsets; currentBlurCoordinateIndex++)
{
[shaderString appendFormat:@"sum += texture2D(inputImageTexture, blurCoordinates[%lu]) * %f;\n", (unsigned long)((currentBlurCoordinateIndex * 2) + 1), boxWeight * 2.0];
[shaderString appendFormat:@"sum += texture2D(inputImageTexture, blurCoordinates[%lu]) * %f;\n", (unsigned long)((currentBlurCoordinateIndex * 2) + 2), boxWeight * 2.0];
}
// If the number of required samples exceeds the amount we can pass in via varyings, we have to do dependent texture reads in the fragment shader
if (trueNumberOfOptimizedOffsets > numberOfOptimizedOffsets)
{
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
[shaderString appendString:@"highp vec2 singleStepOffset = vec2(texelWidthOffset, texelHeightOffset);\n"];
#else
[shaderString appendString:@"vec2 singleStepOffset = vec2(texelWidthOffset, texelHeightOffset);\n"];
#endif
for (NSUInteger currentOverlowTextureRead = numberOfOptimizedOffsets; currentOverlowTextureRead < trueNumberOfOptimizedOffsets; currentOverlowTextureRead++)
{
GLfloat optimizedOffset = (GLfloat)(currentOverlowTextureRead * 2) + 1.5;
[shaderString appendFormat:@"sum += texture2D(inputImageTexture, blurCoordinates[0] + singleStepOffset * %f) * %f;\n", optimizedOffset, boxWeight * 2.0];
[shaderString appendFormat:@"sum += texture2D(inputImageTexture, blurCoordinates[0] - singleStepOffset * %f) * %f;\n", optimizedOffset, boxWeight * 2.0];
}
}
// Footer
[shaderString appendString:@"\
gl_FragColor = sum;\n\
}\n"];
return shaderString;
}
- (void)setupFilterForSize:(CGSize)filterFrameSize;
{
[super setupFilterForSize:filterFrameSize];
if (shouldResizeBlurRadiusWithImageSize == YES)
{
}
}
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
// NSString *currentGaussianBlurVertexShader = [GPUImageGaussianBlurFilter vertexShaderForStandardGaussianOfRadius:4 sigma:2.0];
// NSString *currentGaussianBlurFragmentShader = [GPUImageGaussianBlurFilter fragmentShaderForStandardGaussianOfRadius:4 sigma:2.0];
NSString *currentBoxBlurVertexShader = [[self class] vertexShaderForOptimizedBlurOfRadius:4 sigma:0.0];
NSString *currentBoxBlurFragmentShader = [[self class] fragmentShaderForOptimizedBlurOfRadius:4 sigma:0.0];
if (!(self = [super initWithFirstStageVertexShaderFromString:currentBoxBlurVertexShader firstStageFragmentShaderFromString:currentBoxBlurFragmentShader secondStageVertexShaderFromString:currentBoxBlurVertexShader secondStageFragmentShaderFromString:currentBoxBlurFragmentShader]))
{
return nil;
}
_blurRadiusInPixels = 4.0;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setBlurRadiusInPixels:(CGFloat)newValue;
{
CGFloat newBlurRadius = round(round(newValue / 2.0) * 2.0); // For now, only do even radii
if (newBlurRadius != _blurRadiusInPixels)
{
_blurRadiusInPixels = newBlurRadius;
NSString *newGaussianBlurVertexShader = [[self class] vertexShaderForOptimizedBlurOfRadius:_blurRadiusInPixels sigma:0.0];
NSString *newGaussianBlurFragmentShader = [[self class] fragmentShaderForOptimizedBlurOfRadius:_blurRadiusInPixels sigma:0.0];
// NSLog(@"Optimized vertex shader: \n%@", newGaussianBlurVertexShader);
// NSLog(@"Optimized fragment shader: \n%@", newGaussianBlurFragmentShader);
//
[self switchToVertexShader:newGaussianBlurVertexShader fragmentShader:newGaussianBlurFragmentShader];
}
shouldResizeBlurRadiusWithImageSize = NO;
}
@end
+66
View File
@@ -0,0 +1,66 @@
#import "GPUImageBrightnessFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageBrightnessFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform lowp float brightness;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);
}
);
#else
NSString *const kGPUImageBrightnessFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform float brightness;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
gl_FragColor = vec4((textureColor.rgb + vec3(brightness)), textureColor.w);
}
);
#endif
@implementation GPUImageBrightnessFilter
@synthesize brightness = _brightness;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageBrightnessFragmentShaderString]))
{
return nil;
}
brightnessUniform = [filterProgram uniformIndex:@"brightness"];
self.brightness = 0.0;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setBrightness:(CGFloat)newValue;
{
_brightness = newValue;
[self setFloat:_brightness forUniform:brightnessUniform program:filterProgram];
}
@end
+112
View File
@@ -0,0 +1,112 @@
#import "GPUImageBuffer.h"
@interface GPUImageBuffer()
@end
@implementation GPUImageBuffer
@synthesize bufferSize = _bufferSize;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [self initWithFragmentShaderFromString:kGPUImagePassthroughFragmentShaderString]))
{
return nil;
}
bufferedFramebuffers = [[NSMutableArray alloc] init];
// [bufferedTextures addObject:[NSNumber numberWithInt:outputTexture]];
_bufferSize = 1;
return self;
}
- (void)dealloc
{
for (GPUImageFramebuffer *currentFramebuffer in bufferedFramebuffers)
{
[currentFramebuffer unlock];
}
}
#pragma mark -
#pragma mark GPUImageInput
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
{
if ([bufferedFramebuffers count] >= _bufferSize)
{
outputFramebuffer = [bufferedFramebuffers objectAtIndex:0];
[bufferedFramebuffers removeObjectAtIndex:0];
}
else
{
// Nothing yet in the buffer, so don't process further until the buffer is full
outputFramebuffer = firstInputFramebuffer;
[firstInputFramebuffer lock];
}
[bufferedFramebuffers addObject:firstInputFramebuffer];
// Need to pass along rotation information, as we're just holding on to buffered framebuffers and not rotating them ourselves
for (id<GPUImageInput> currentTarget in targets)
{
if (currentTarget != self.targetToIgnoreForUpdates)
{
NSInteger indexOfObject = [targets indexOfObject:currentTarget];
NSInteger textureIndex = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue];
[currentTarget setInputRotation:inputRotation atIndex:textureIndex];
}
}
// Let the downstream video elements see the previous frame from the buffer before rendering a new one into place
[self informTargetsAboutNewFrameAtTime:frameTime];
// [self renderToTextureWithVertices:imageVertices textureCoordinates:[[self class] textureCoordinatesForRotation:inputRotation]];
}
- (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates;
{
// No need to render to another texture anymore, since we'll be hanging on to the textures in our buffer
}
#pragma mark -
#pragma mark Accessors
- (void)setBufferSize:(NSUInteger)newValue;
{
if ( (newValue == _bufferSize) || (newValue < 1) )
{
return;
}
if (newValue > _bufferSize)
{
NSUInteger texturesToAdd = newValue - _bufferSize;
for (NSUInteger currentTextureIndex = 0; currentTextureIndex < texturesToAdd; currentTextureIndex++)
{
// TODO: Deal with the growth of the size of the buffer by rotating framebuffers, no textures
}
}
else
{
NSUInteger texturesToRemove = _bufferSize - newValue;
for (NSUInteger currentTextureIndex = 0; currentTextureIndex < texturesToRemove; currentTextureIndex++)
{
GPUImageFramebuffer *lastFramebuffer = [bufferedFramebuffers lastObject];
[bufferedFramebuffers removeObjectAtIndex:([bufferedFramebuffers count] - 1)];
[lastFramebuffer unlock];
lastFramebuffer = nil;
}
}
_bufferSize = newValue;
}
@end
+174
View File
@@ -0,0 +1,174 @@
#import "GPUImageBulgeDistortionFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageBulgeDistortionFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp float aspectRatio;
uniform highp vec2 center;
uniform highp float radius;
uniform highp float scale;
void main()
{
highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, ((textureCoordinate.y - center.y) * aspectRatio) + center.y);
highp float dist = distance(center, textureCoordinateToUse);
textureCoordinateToUse = textureCoordinate;
if (dist < radius)
{
textureCoordinateToUse -= center;
highp float percent = 1.0 - ((radius - dist) / radius) * scale;
percent = percent * percent;
textureCoordinateToUse = textureCoordinateToUse * percent;
textureCoordinateToUse += center;
}
gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );
}
);
#else
NSString *const kGPUImageBulgeDistortionFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform float aspectRatio;
uniform vec2 center;
uniform float radius;
uniform float scale;
void main()
{
vec2 textureCoordinateToUse = vec2(textureCoordinate.x, ((textureCoordinate.y - center.y) * aspectRatio) + center.y);
float dist = distance(center, textureCoordinateToUse);
textureCoordinateToUse = textureCoordinate;
if (dist < radius)
{
textureCoordinateToUse -= center;
float percent = 1.0 - ((radius - dist) / radius) * scale;
percent = percent * percent;
textureCoordinateToUse = textureCoordinateToUse * percent;
textureCoordinateToUse += center;
}
gl_FragColor = texture2D(inputImageTexture, textureCoordinateToUse );
}
);
#endif
@interface GPUImageBulgeDistortionFilter ()
- (void)adjustAspectRatio;
@property (readwrite, nonatomic) CGFloat aspectRatio;
@end
@implementation GPUImageBulgeDistortionFilter
@synthesize aspectRatio = _aspectRatio;
@synthesize center = _center;
@synthesize radius = _radius;
@synthesize scale = _scale;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageBulgeDistortionFragmentShaderString]))
{
return nil;
}
aspectRatioUniform = [filterProgram uniformIndex:@"aspectRatio"];
radiusUniform = [filterProgram uniformIndex:@"radius"];
scaleUniform = [filterProgram uniformIndex:@"scale"];
centerUniform = [filterProgram uniformIndex:@"center"];
self.radius = 0.25;
self.scale = 0.5;
self.center = CGPointMake(0.5, 0.5);
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)adjustAspectRatio;
{
if (GPUImageRotationSwapsWidthAndHeight(inputRotation))
{
[self setAspectRatio:(inputTextureSize.width / inputTextureSize.height)];
}
else
{
[self setAspectRatio:(inputTextureSize.height / inputTextureSize.width)];
}
}
- (void)forceProcessingAtSize:(CGSize)frameSize;
{
[super forceProcessingAtSize:frameSize];
[self adjustAspectRatio];
}
- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;
{
CGSize oldInputSize = inputTextureSize;
[super setInputSize:newSize atIndex:textureIndex];
if ( (!CGSizeEqualToSize(oldInputSize, inputTextureSize)) && (!CGSizeEqualToSize(newSize, CGSizeZero)) )
{
[self adjustAspectRatio];
}
}
- (void)setAspectRatio:(CGFloat)newValue;
{
_aspectRatio = newValue;
[self setFloat:_aspectRatio forUniform:aspectRatioUniform program:filterProgram];
}
- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;
{
[super setInputRotation:newInputRotation atIndex:textureIndex];
[self setCenter:self.center];
[self adjustAspectRatio];
}
- (void)setRadius:(CGFloat)newValue;
{
_radius = newValue;
[self setFloat:_radius forUniform:radiusUniform program:filterProgram];
}
- (void)setScale:(CGFloat)newValue;
{
_scale = newValue;
[self setFloat:_scale forUniform:scaleUniform program:filterProgram];
}
- (void)setCenter:(CGPoint)newValue;
{
_center = newValue;
CGPoint rotatedPoint = [self rotatedPoint:_center forRotation:inputRotation];
[self setPoint:rotatedPoint forUniform:centerUniform program:filterProgram];
}
@end
+113
View File
@@ -0,0 +1,113 @@
//
// GPUImageCGAColorspaceFilter.m
//
#import "GPUImageCGAColorspaceFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageCGAColorspaceFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
highp vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0);
//highp vec4 colorDivisor = vec4(colorDepth);
highp vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor);
highp vec4 color = texture2D(inputImageTexture, samplePos );
//gl_FragColor = texture2D(inputImageTexture, samplePos );
mediump vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0);
mediump vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0);
mediump vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0);
mediump vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0);
mediump vec4 endColor;
highp float blackDistance = distance(color, colorBlack);
highp float whiteDistance = distance(color, colorWhite);
highp float magentaDistance = distance(color, colorMagenta);
highp float cyanDistance = distance(color, colorCyan);
mediump vec4 finalColor;
highp float colorDistance = min(magentaDistance, cyanDistance);
colorDistance = min(colorDistance, whiteDistance);
colorDistance = min(colorDistance, blackDistance);
if (colorDistance == blackDistance) {
finalColor = colorBlack;
} else if (colorDistance == whiteDistance) {
finalColor = colorWhite;
} else if (colorDistance == cyanDistance) {
finalColor = colorCyan;
} else {
finalColor = colorMagenta;
}
gl_FragColor = finalColor;
}
);
#else
NSString *const kGPUImageCGAColorspaceFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
vec2 sampleDivisor = vec2(1.0 / 200.0, 1.0 / 320.0);
//highp vec4 colorDivisor = vec4(colorDepth);
vec2 samplePos = textureCoordinate - mod(textureCoordinate, sampleDivisor);
vec4 color = texture2D(inputImageTexture, samplePos );
//gl_FragColor = texture2D(inputImageTexture, samplePos );
vec4 colorCyan = vec4(85.0 / 255.0, 1.0, 1.0, 1.0);
vec4 colorMagenta = vec4(1.0, 85.0 / 255.0, 1.0, 1.0);
vec4 colorWhite = vec4(1.0, 1.0, 1.0, 1.0);
vec4 colorBlack = vec4(0.0, 0.0, 0.0, 1.0);
vec4 endColor;
float blackDistance = distance(color, colorBlack);
float whiteDistance = distance(color, colorWhite);
float magentaDistance = distance(color, colorMagenta);
float cyanDistance = distance(color, colorCyan);
vec4 finalColor;
float colorDistance = min(magentaDistance, cyanDistance);
colorDistance = min(colorDistance, whiteDistance);
colorDistance = min(colorDistance, blackDistance);
if (colorDistance == blackDistance) {
finalColor = colorBlack;
} else if (colorDistance == whiteDistance) {
finalColor = colorWhite;
} else if (colorDistance == cyanDistance) {
finalColor = colorCyan;
} else {
finalColor = colorMagenta;
}
gl_FragColor = finalColor;
}
);
#endif
@implementation GPUImageCGAColorspaceFilter
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageCGAColorspaceFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+125
View File
@@ -0,0 +1,125 @@
#import "GPUImageCannyEdgeDetectionFilter.h"
#import "GPUImageGrayscaleFilter.h"
#import "GPUImageDirectionalSobelEdgeDetectionFilter.h"
#import "GPUImageDirectionalNonMaximumSuppressionFilter.h"
#import "GPUImageWeakPixelInclusionFilter.h"
#import "GPUImageSingleComponentGaussianBlurFilter.h"
@implementation GPUImageCannyEdgeDetectionFilter
@synthesize upperThreshold;
@synthesize lowerThreshold;
@synthesize blurRadiusInPixels;
@synthesize blurTexelSpacingMultiplier;
@synthesize texelWidth;
@synthesize texelHeight;
- (id)init;
{
if (!(self = [super init]))
{
return nil;
}
// First pass: convert image to luminance
luminanceFilter = [[GPUImageGrayscaleFilter alloc] init];
[self addFilter:luminanceFilter];
// Second pass: apply a variable Gaussian blur
blurFilter = [[GPUImageSingleComponentGaussianBlurFilter alloc] init];
[self addFilter:blurFilter];
// Third pass: run the Sobel edge detection, with calculated gradient directions, on this blurred image
edgeDetectionFilter = [[GPUImageDirectionalSobelEdgeDetectionFilter alloc] init];
[self addFilter:edgeDetectionFilter];
// Fourth pass: apply non-maximum suppression
nonMaximumSuppressionFilter = [[GPUImageDirectionalNonMaximumSuppressionFilter alloc] init];
[self addFilter:nonMaximumSuppressionFilter];
// Fifth pass: include weak pixels to complete edges
weakPixelInclusionFilter = [[GPUImageWeakPixelInclusionFilter alloc] init];
[self addFilter:weakPixelInclusionFilter];
[luminanceFilter addTarget:blurFilter];
[blurFilter addTarget:edgeDetectionFilter];
[edgeDetectionFilter addTarget:nonMaximumSuppressionFilter];
[nonMaximumSuppressionFilter addTarget:weakPixelInclusionFilter];
self.initialFilters = [NSArray arrayWithObject:luminanceFilter];
// self.terminalFilter = nonMaximumSuppressionFilter;
self.terminalFilter = weakPixelInclusionFilter;
self.blurRadiusInPixels = 2.0;
self.blurTexelSpacingMultiplier = 1.0;
self.upperThreshold = 0.4;
self.lowerThreshold = 0.1;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setBlurRadiusInPixels:(CGFloat)newValue;
{
blurFilter.blurRadiusInPixels = newValue;
}
- (CGFloat)blurRadiusInPixels;
{
return blurFilter.blurRadiusInPixels;
}
- (void)setBlurTexelSpacingMultiplier:(CGFloat)newValue;
{
blurFilter.texelSpacingMultiplier = newValue;
}
- (CGFloat)blurTexelSpacingMultiplier;
{
return blurFilter.texelSpacingMultiplier;
}
- (void)setTexelWidth:(CGFloat)newValue;
{
edgeDetectionFilter.texelWidth = newValue;
}
- (CGFloat)texelWidth;
{
return edgeDetectionFilter.texelWidth;
}
- (void)setTexelHeight:(CGFloat)newValue;
{
edgeDetectionFilter.texelHeight = newValue;
}
- (CGFloat)texelHeight;
{
return edgeDetectionFilter.texelHeight;
}
- (void)setUpperThreshold:(CGFloat)newValue;
{
nonMaximumSuppressionFilter.upperThreshold = newValue;
}
- (CGFloat)upperThreshold;
{
return nonMaximumSuppressionFilter.upperThreshold;
}
- (void)setLowerThreshold:(CGFloat)newValue;
{
nonMaximumSuppressionFilter.lowerThreshold = newValue;
}
- (CGFloat)lowerThreshold;
{
return nonMaximumSuppressionFilter.lowerThreshold;
}
@end
+117
View File
@@ -0,0 +1,117 @@
#import "GPUImageChromaKeyBlendFilter.h"
// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageChromaKeyBlendFragmentShaderString = SHADER_STRING
(
precision highp float;
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform float thresholdSensitivity;
uniform float smoothing;
uniform vec3 colorToReplace;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b;
float maskCr = 0.7132 * (colorToReplace.r - maskY);
float maskCb = 0.5647 * (colorToReplace.b - maskY);
float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;
float Cr = 0.7132 * (textureColor.r - Y);
float Cb = 0.5647 * (textureColor.b - Y);
// float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb));
float blendValue = 1.0 - smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));
gl_FragColor = mix(textureColor, textureColor2, blendValue);
}
);
#else
NSString *const kGPUImageChromaKeyBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform float thresholdSensitivity;
uniform float smoothing;
uniform vec3 colorToReplace;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b;
float maskCr = 0.7132 * (colorToReplace.r - maskY);
float maskCb = 0.5647 * (colorToReplace.b - maskY);
float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;
float Cr = 0.7132 * (textureColor.r - Y);
float Cb = 0.5647 * (textureColor.b - Y);
// float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb));
float blendValue = 1.0 - smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));
gl_FragColor = mix(textureColor, textureColor2, blendValue);
}
);
#endif
@implementation GPUImageChromaKeyBlendFilter
@synthesize thresholdSensitivity = _thresholdSensitivity;
@synthesize smoothing = _smoothing;
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageChromaKeyBlendFragmentShaderString]))
{
return nil;
}
thresholdSensitivityUniform = [filterProgram uniformIndex:@"thresholdSensitivity"];
smoothingUniform = [filterProgram uniformIndex:@"smoothing"];
colorToReplaceUniform = [filterProgram uniformIndex:@"colorToReplace"];
self.thresholdSensitivity = 0.4;
self.smoothing = 0.1;
[self setColorToReplaceRed:0.0 green:1.0 blue:0.0];
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setColorToReplaceRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
{
GPUVector3 colorToReplace = {redComponent, greenComponent, blueComponent};
[self setVec3:colorToReplace forUniform:colorToReplaceUniform program:filterProgram];
}
- (void)setThresholdSensitivity:(CGFloat)newValue;
{
_thresholdSensitivity = newValue;
[self setFloat:(GLfloat)_thresholdSensitivity forUniform:thresholdSensitivityUniform program:filterProgram];
}
- (void)setSmoothing:(CGFloat)newValue;
{
_smoothing = newValue;
[self setFloat:(GLfloat)_smoothing forUniform:smoothingUniform program:filterProgram];
}
@end
+113
View File
@@ -0,0 +1,113 @@
#import "GPUImageChromaKeyFilter.h"
// Shader code based on Apple's CIChromaKeyFilter example: https://developer.apple.com/library/mac/#samplecode/CIChromaKeyFilter/Introduction/Intro.html
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageChromaKeyFragmentShaderString = SHADER_STRING
(
precision highp float;
varying highp vec2 textureCoordinate;
uniform float thresholdSensitivity;
uniform float smoothing;
uniform vec3 colorToReplace;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b;
float maskCr = 0.7132 * (colorToReplace.r - maskY);
float maskCb = 0.5647 * (colorToReplace.b - maskY);
float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;
float Cr = 0.7132 * (textureColor.r - Y);
float Cb = 0.5647 * (textureColor.b - Y);
// float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb));
float blendValue = smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));
gl_FragColor = vec4(textureColor.rgb, textureColor.a * blendValue);
}
);
#else
NSString *const kGPUImageChromaKeyFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform float thresholdSensitivity;
uniform float smoothing;
uniform vec3 colorToReplace;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
float maskY = 0.2989 * colorToReplace.r + 0.5866 * colorToReplace.g + 0.1145 * colorToReplace.b;
float maskCr = 0.7132 * (colorToReplace.r - maskY);
float maskCb = 0.5647 * (colorToReplace.b - maskY);
float Y = 0.2989 * textureColor.r + 0.5866 * textureColor.g + 0.1145 * textureColor.b;
float Cr = 0.7132 * (textureColor.r - Y);
float Cb = 0.5647 * (textureColor.b - Y);
// float blendValue = 1.0 - smoothstep(thresholdSensitivity - smoothing, thresholdSensitivity , abs(Cr - maskCr) + abs(Cb - maskCb));
float blendValue = smoothstep(thresholdSensitivity, thresholdSensitivity + smoothing, distance(vec2(Cr, Cb), vec2(maskCr, maskCb)));
gl_FragColor = vec4(textureColor.rgb, textureColor.a * blendValue);
}
);
#endif
@implementation GPUImageChromaKeyFilter
@synthesize thresholdSensitivity = _thresholdSensitivity;
@synthesize smoothing = _smoothing;
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageChromaKeyFragmentShaderString]))
{
return nil;
}
thresholdSensitivityUniform = [filterProgram uniformIndex:@"thresholdSensitivity"];
smoothingUniform = [filterProgram uniformIndex:@"smoothing"];
colorToReplaceUniform = [filterProgram uniformIndex:@"colorToReplace"];
self.thresholdSensitivity = 0.4;
self.smoothing = 0.1;
[self setColorToReplaceRed:0.0 green:1.0 blue:0.0];
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setColorToReplaceRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
{
GPUVector3 colorToReplace = {redComponent, greenComponent, blueComponent};
[self setVec3:colorToReplace forUniform:colorToReplaceUniform program:filterProgram];
}
- (void)setThresholdSensitivity:(CGFloat)newValue;
{
_thresholdSensitivity = newValue;
[self setFloat:(GLfloat)_thresholdSensitivity forUniform:thresholdSensitivityUniform program:filterProgram];
}
- (void)setSmoothing:(CGFloat)newValue;
{
_smoothing = newValue;
[self setFloat:(GLfloat)_smoothing forUniform:smoothingUniform program:filterProgram];
}
@end
+57
View File
@@ -0,0 +1,57 @@
#import "GPUImageClosingFilter.h"
#import "GPUImageErosionFilter.h"
#import "GPUImageDilationFilter.h"
@implementation GPUImageClosingFilter
@synthesize verticalTexelSpacing = _verticalTexelSpacing;
@synthesize horizontalTexelSpacing = _horizontalTexelSpacing;
- (id)init;
{
if (!(self = [self initWithRadius:1]))
{
return nil;
}
return self;
}
- (id)initWithRadius:(NSUInteger)radius;
{
if (!(self = [super init]))
{
return nil;
}
// First pass: dilation
dilationFilter = [[GPUImageDilationFilter alloc] initWithRadius:radius];
[self addFilter:dilationFilter];
// Second pass: erosion
erosionFilter = [[GPUImageErosionFilter alloc] initWithRadius:radius];
[self addFilter:erosionFilter];
[dilationFilter addTarget:erosionFilter];
self.initialFilters = [NSArray arrayWithObjects:dilationFilter, nil];
self.terminalFilter = erosionFilter;
return self;
}
- (void)setVerticalTexelSpacing:(CGFloat)newValue;
{
_verticalTexelSpacing = newValue;
erosionFilter.verticalTexelSpacing = newValue;
dilationFilter.verticalTexelSpacing = newValue;
}
- (void)setHorizontalTexelSpacing:(CGFloat)newValue;
{
_horizontalTexelSpacing = newValue;
erosionFilter.horizontalTexelSpacing = newValue;
dilationFilter.horizontalTexelSpacing = newValue;
}
@end
+113
View File
@@ -0,0 +1,113 @@
#import "GPUImageColorBlendFilter.h"
/**
* Color blend mode based upon pseudo code from the PDF specification.
*/
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageColorBlendFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
highp float lum(lowp vec3 c) {
return dot(c, vec3(0.3, 0.59, 0.11));
}
lowp vec3 clipcolor(lowp vec3 c) {
highp float l = lum(c);
lowp float n = min(min(c.r, c.g), c.b);
lowp float x = max(max(c.r, c.g), c.b);
if (n < 0.0) {
c.r = l + ((c.r - l) * l) / (l - n);
c.g = l + ((c.g - l) * l) / (l - n);
c.b = l + ((c.b - l) * l) / (l - n);
}
if (x > 1.0) {
c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);
c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);
c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);
}
return c;
}
lowp vec3 setlum(lowp vec3 c, highp float l) {
highp float d = l - lum(c);
c = c + vec3(d);
return clipcolor(c);
}
void main()
{
highp vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);
highp vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(overlayColor.rgb, lum(baseColor.rgb)) * overlayColor.a, baseColor.a);
}
);
#else
NSString *const kGPUImageColorBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
float lum(vec3 c) {
return dot(c, vec3(0.3, 0.59, 0.11));
}
vec3 clipcolor(vec3 c) {
float l = lum(c);
float n = min(min(c.r, c.g), c.b);
float x = max(max(c.r, c.g), c.b);
if (n < 0.0) {
c.r = l + ((c.r - l) * l) / (l - n);
c.g = l + ((c.g - l) * l) / (l - n);
c.b = l + ((c.b - l) * l) / (l - n);
}
if (x > 1.0) {
c.r = l + ((c.r - l) * (1.0 - l)) / (x - l);
c.g = l + ((c.g - l) * (1.0 - l)) / (x - l);
c.b = l + ((c.b - l) * (1.0 - l)) / (x - l);
}
return c;
}
vec3 setlum(vec3 c, float l) {
float d = l - lum(c);
c = c + vec3(d);
return clipcolor(c);
}
void main()
{
vec4 baseColor = texture2D(inputImageTexture, textureCoordinate);
vec4 overlayColor = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4(baseColor.rgb * (1.0 - overlayColor.a) + setlum(overlayColor.rgb, lum(baseColor.rgb)) * overlayColor.a, baseColor.a);
}
);
#endif
@implementation GPUImageColorBlendFilter
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageColorBlendFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+52
View File
@@ -0,0 +1,52 @@
#import "GPUImageColorBurnBlendFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageColorBurnBlendFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
mediump vec4 whiteColor = vec4(1.0);
gl_FragColor = whiteColor - (whiteColor - textureColor) / textureColor2;
}
);
#else
NSString *const kGPUImageColorBurnBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
vec4 whiteColor = vec4(1.0);
gl_FragColor = whiteColor - (whiteColor - textureColor) / textureColor2;
}
);
#endif
@implementation GPUImageColorBurnBlendFilter
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageColorBurnBlendFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+159
View File
@@ -0,0 +1,159 @@
#import "GPUImageFilter.h"
// Color Conversion Constants (YUV to RGB) including adjustment from 16-235/16-240 (video range)
// BT.601, which is the standard for SDTV.
GLfloat kColorConversion601Default[] = {
1.164, 1.164, 1.164,
0.0, -0.392, 2.017,
1.596, -0.813, 0.0,
};
// BT.601 full range (ref: http://www.equasys.de/colorconversion.html)
GLfloat kColorConversion601FullRangeDefault[] = {
1.0, 1.0, 1.0,
0.0, -0.343, 1.765,
1.4, -0.711, 0.0,
};
// BT.709, which is the standard for HDTV.
GLfloat kColorConversion709Default[] = {
1.164, 1.164, 1.164,
0.0, -0.213, 2.112,
1.793, -0.533, 0.0,
};
GLfloat *kColorConversion601 = kColorConversion601Default;
GLfloat *kColorConversion601FullRange = kColorConversion601FullRangeDefault;
GLfloat *kColorConversion709 = kColorConversion709Default;
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageYUVVideoRangeConversionForRGFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D luminanceTexture;
uniform sampler2D chrominanceTexture;
uniform mediump mat3 colorConversionMatrix;
void main()
{
mediump vec3 yuv;
lowp vec3 rgb;
yuv.x = texture2D(luminanceTexture, textureCoordinate).r;
yuv.yz = texture2D(chrominanceTexture, textureCoordinate).rg - vec2(0.5, 0.5);
rgb = colorConversionMatrix * yuv;
gl_FragColor = vec4(rgb, 1);
}
);
#else
NSString *const kGPUImageYUVVideoRangeConversionForRGFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D luminanceTexture;
uniform sampler2D chrominanceTexture;
void main()
{
vec3 yuv;
vec3 rgb;
yuv.x = texture2D(luminanceTexture, textureCoordinate).r;
yuv.yz = texture2D(chrominanceTexture, textureCoordinate).rg - vec2(0.5, 0.5);
// BT.601, which is the standard for SDTV is provided as a reference
/*
rgb = mat3( 1, 1, 1,
0, -.39465, 2.03211,
1.13983, -.58060, 0) * yuv;
*/
// Using BT.709 which is the standard for HDTV
rgb = mat3( 1, 1, 1,
0, -.21482, 2.12798,
1.28033, -.38059, 0) * yuv;
gl_FragColor = vec4(rgb, 1);
}
);
#endif
NSString *const kGPUImageYUVFullRangeConversionForLAFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D luminanceTexture;
uniform sampler2D chrominanceTexture;
uniform mediump mat3 colorConversionMatrix;
void main()
{
mediump vec3 yuv;
lowp vec3 rgb;
yuv.x = texture2D(luminanceTexture, textureCoordinate).r;
yuv.yz = texture2D(chrominanceTexture, textureCoordinate).ra - vec2(0.5, 0.5);
rgb = colorConversionMatrix * yuv;
gl_FragColor = vec4(rgb, 1);
}
);
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D luminanceTexture;
uniform sampler2D chrominanceTexture;
uniform mediump mat3 colorConversionMatrix;
void main()
{
mediump vec3 yuv;
lowp vec3 rgb;
yuv.x = texture2D(luminanceTexture, textureCoordinate).r - (16.0/255.0);
yuv.yz = texture2D(chrominanceTexture, textureCoordinate).ra - vec2(0.5, 0.5);
rgb = colorConversionMatrix * yuv;
gl_FragColor = vec4(rgb, 1);
}
);
#else
NSString *const kGPUImageYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D luminanceTexture;
uniform sampler2D chrominanceTexture;
void main()
{
vec3 yuv;
vec3 rgb;
yuv.x = texture2D(luminanceTexture, textureCoordinate).r;
yuv.yz = texture2D(chrominanceTexture, textureCoordinate).ra - vec2(0.5, 0.5);
// BT.601, which is the standard for SDTV is provided as a reference
/*
rgb = mat3( 1, 1, 1,
0, -.39465, 2.03211,
1.13983, -.58060, 0) * yuv;
*/
// Using BT.709 which is the standard for HDTV
rgb = mat3( 1, 1, 1,
0, -.21482, 2.12798,
1.28033, -.38059, 0) * yuv;
gl_FragColor = vec4(rgb, 1);
}
);
#endif
+75
View File
@@ -0,0 +1,75 @@
#import "GPUImageColorDodgeBlendFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageColorDodgeBlendFragmentShaderString = SHADER_STRING
(
precision mediump float;
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 base = texture2D(inputImageTexture, textureCoordinate);
vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);
vec3 baseOverlayAlphaProduct = vec3(overlay.a * base.a);
vec3 rightHandProduct = overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a);
vec3 firstBlendColor = baseOverlayAlphaProduct + rightHandProduct;
vec3 overlayRGB = clamp((overlay.rgb / clamp(overlay.a, 0.01, 1.0)) * step(0.0, overlay.a), 0.0, 0.99);
vec3 secondBlendColor = (base.rgb * overlay.a) / (1.0 - overlayRGB) + rightHandProduct;
vec3 colorChoice = step((overlay.rgb * base.a + base.rgb * overlay.a), baseOverlayAlphaProduct);
gl_FragColor = vec4(mix(firstBlendColor, secondBlendColor, colorChoice), 1.0);
}
);
#else
NSString *const kGPUImageColorDodgeBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 base = texture2D(inputImageTexture, textureCoordinate);
vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);
vec3 baseOverlayAlphaProduct = vec3(overlay.a * base.a);
vec3 rightHandProduct = overlay.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlay.a);
vec3 firstBlendColor = baseOverlayAlphaProduct + rightHandProduct;
vec3 overlayRGB = clamp((overlay.rgb / clamp(overlay.a, 0.01, 1.0)) * step(0.0, overlay.a), 0.0, 0.99);
vec3 secondBlendColor = (base.rgb * overlay.a) / (1.0 - overlayRGB) + rightHandProduct;
vec3 colorChoice = step((overlay.rgb * base.a + base.rgb * overlay.a), baseOverlayAlphaProduct);
gl_FragColor = vec4(mix(firstBlendColor, secondBlendColor, colorChoice), 1.0);
}
);
#endif
@implementation GPUImageColorDodgeBlendFilter
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageColorDodgeBlendFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+46
View File
@@ -0,0 +1,46 @@
#import "GPUImageColorInvertFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageInvertFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w);
}
);
#else
NSString *const kGPUImageInvertFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
gl_FragColor = vec4((1.0 - textureColor.rgb), textureColor.w);
}
);
#endif
@implementation GPUImageColorInvertFilter
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageInvertFragmentShaderString]))
{
return nil;
}
return self;
}
@end
@@ -0,0 +1,159 @@
#import "GPUImageColorLocalBinaryPatternFilter.h"
// This is based on "Accelerating image recognition on mobile devices using GPGPU" by Miguel Bordallo Lopez, Henri Nykanen, Jari Hannuksela, Olli Silven and Markku Vehvilainen
// http://www.ee.oulu.fi/~jhannuks/publications/SPIE2011a.pdf
// Right pixel is the most significant bit, traveling clockwise to get to the upper right, which is the least significant
// If the external pixel is greater than or equal to the center, set to 1, otherwise 0
//
// 2 1 0
// 3 7
// 4 5 6
// 01101101
// 76543210
@implementation GPUImageColorLocalBinaryPatternFilter
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageColorLocalBinaryPatternFragmentShaderString = SHADER_STRING
(
precision highp float;
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
lowp vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb;
lowp vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;
lowp vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;
lowp vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;
lowp vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;
lowp vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;
lowp vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;
lowp vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;
lowp vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;
lowp float redByteTally = 1.0 / 255.0 * step(centerColor.r, topRightColor.r);
redByteTally += 2.0 / 255.0 * step(centerColor.r, topColor.r);
redByteTally += 4.0 / 255.0 * step(centerColor.r, topLeftColor.r);
redByteTally += 8.0 / 255.0 * step(centerColor.r, leftColor.r);
redByteTally += 16.0 / 255.0 * step(centerColor.r, bottomLeftColor.r);
redByteTally += 32.0 / 255.0 * step(centerColor.r, bottomColor.r);
redByteTally += 64.0 / 255.0 * step(centerColor.r, bottomRightColor.r);
redByteTally += 128.0 / 255.0 * step(centerColor.r, rightColor.r);
lowp float blueByteTally = 1.0 / 255.0 * step(centerColor.b, topRightColor.b);
blueByteTally += 2.0 / 255.0 * step(centerColor.b, topColor.b);
blueByteTally += 4.0 / 255.0 * step(centerColor.b, topLeftColor.b);
blueByteTally += 8.0 / 255.0 * step(centerColor.b, leftColor.b);
blueByteTally += 16.0 / 255.0 * step(centerColor.b, bottomLeftColor.b);
blueByteTally += 32.0 / 255.0 * step(centerColor.b, bottomColor.b);
blueByteTally += 64.0 / 255.0 * step(centerColor.b, bottomRightColor.b);
blueByteTally += 128.0 / 255.0 * step(centerColor.b, rightColor.b);
lowp float greenByteTally = 1.0 / 255.0 * step(centerColor.g, topRightColor.g);
greenByteTally += 2.0 / 255.0 * step(centerColor.g, topColor.g);
greenByteTally += 4.0 / 255.0 * step(centerColor.g, topLeftColor.g);
greenByteTally += 8.0 / 255.0 * step(centerColor.g, leftColor.g);
greenByteTally += 16.0 / 255.0 * step(centerColor.g, bottomLeftColor.g);
greenByteTally += 32.0 / 255.0 * step(centerColor.g, bottomColor.g);
greenByteTally += 64.0 / 255.0 * step(centerColor.g, bottomRightColor.g);
greenByteTally += 128.0 / 255.0 * step(centerColor.g, rightColor.g);
// TODO: Replace the above with a dot product and two vec4s
// TODO: Apply step to a matrix, rather than individually
gl_FragColor = vec4(redByteTally, blueByteTally, greenByteTally, 1.0);
}
);
#else
NSString *const kGPUImageColorLocalBinaryPatternFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb;
vec3 bottomLeftColor = texture2D(inputImageTexture, bottomLeftTextureCoordinate).rgb;
vec3 topRightColor = texture2D(inputImageTexture, topRightTextureCoordinate).rgb;
vec3 topLeftColor = texture2D(inputImageTexture, topLeftTextureCoordinate).rgb;
vec3 bottomRightColor = texture2D(inputImageTexture, bottomRightTextureCoordinate).rgb;
vec3 leftColor = texture2D(inputImageTexture, leftTextureCoordinate).rgb;
vec3 rightColor = texture2D(inputImageTexture, rightTextureCoordinate).rgb;
vec3 bottomColor = texture2D(inputImageTexture, bottomTextureCoordinate).rgb;
vec3 topColor = texture2D(inputImageTexture, topTextureCoordinate).rgb;
float redByteTally = 1.0 / 255.0 * step(centerColor.r, topRightColor.r);
redByteTally += 2.0 / 255.0 * step(centerColor.r, topColor.r);
redByteTally += 4.0 / 255.0 * step(centerColor.r, topLeftColor.r);
redByteTally += 8.0 / 255.0 * step(centerColor.r, leftColor.r);
redByteTally += 16.0 / 255.0 * step(centerColor.r, bottomLeftColor.r);
redByteTally += 32.0 / 255.0 * step(centerColor.r, bottomColor.r);
redByteTally += 64.0 / 255.0 * step(centerColor.r, bottomRightColor.r);
redByteTally += 128.0 / 255.0 * step(centerColor.r, rightColor.r);
float blueByteTally = 1.0 / 255.0 * step(centerColor.b, topRightColor.b);
blueByteTally += 2.0 / 255.0 * step(centerColor.b, topColor.b);
blueByteTally += 4.0 / 255.0 * step(centerColor.b, topLeftColor.b);
blueByteTally += 8.0 / 255.0 * step(centerColor.b, leftColor.b);
blueByteTally += 16.0 / 255.0 * step(centerColor.b, bottomLeftColor.b);
blueByteTally += 32.0 / 255.0 * step(centerColor.b, bottomColor.b);
blueByteTally += 64.0 / 255.0 * step(centerColor.b, bottomRightColor.b);
blueByteTally += 128.0 / 255.0 * step(centerColor.b, rightColor.b);
float greenByteTally = 1.0 / 255.0 * step(centerColor.g, topRightColor.g);
greenByteTally += 2.0 / 255.0 * step(centerColor.g, topColor.g);
greenByteTally += 4.0 / 255.0 * step(centerColor.g, topLeftColor.g);
greenByteTally += 8.0 / 255.0 * step(centerColor.g, leftColor.g);
greenByteTally += 16.0 / 255.0 * step(centerColor.g, bottomLeftColor.g);
greenByteTally += 32.0 / 255.0 * step(centerColor.g, bottomColor.g);
greenByteTally += 64.0 / 255.0 * step(centerColor.g, bottomRightColor.g);
greenByteTally += 128.0 / 255.0 * step(centerColor.g, rightColor.g);
// TODO: Replace the above with a dot product and two vec4s
// TODO: Apply step to a matrix, rather than individually
gl_FragColor = vec4(redByteTally, blueByteTally, greenByteTally, 1.0);
}
);
#endif
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageColorLocalBinaryPatternFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+87
View File
@@ -0,0 +1,87 @@
#import "GPUImageColorMatrixFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageColorMatrixFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform lowp mat4 colorMatrix;
uniform lowp float intensity;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 outputColor = textureColor * colorMatrix;
gl_FragColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor);
}
);
#else
NSString *const kGPUImageColorMatrixFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform mat4 colorMatrix;
uniform float intensity;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
vec4 outputColor = textureColor * colorMatrix;
gl_FragColor = (intensity * outputColor) + ((1.0 - intensity) * textureColor);
}
);
#endif
@implementation GPUImageColorMatrixFilter
@synthesize intensity = _intensity;
@synthesize colorMatrix = _colorMatrix;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageColorMatrixFragmentShaderString]))
{
return nil;
}
colorMatrixUniform = [filterProgram uniformIndex:@"colorMatrix"];
intensityUniform = [filterProgram uniformIndex:@"intensity"];
self.intensity = 1.f;
self.colorMatrix = (GPUMatrix4x4){
{1.f, 0.f, 0.f, 0.f},
{0.f, 1.f, 0.f, 0.f},
{0.f, 0.f, 1.f, 0.f},
{0.f, 0.f, 0.f, 1.f}
};
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setIntensity:(CGFloat)newIntensity;
{
_intensity = newIntensity;
[self setFloat:_intensity forUniform:intensityUniform program:filterProgram];
}
- (void)setColorMatrix:(GPUMatrix4x4)newColorMatrix;
{
_colorMatrix = newColorMatrix;
[self setMatrix4f:_colorMatrix forUniform:colorMatrixUniform program:filterProgram];
}
@end
+139
View File
@@ -0,0 +1,139 @@
#import "GPUImageColorPackingFilter.h"
NSString *const kGPUImageColorPackingVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
uniform float texelWidth;
uniform float texelHeight;
varying vec2 upperLeftInputTextureCoordinate;
varying vec2 upperRightInputTextureCoordinate;
varying vec2 lowerLeftInputTextureCoordinate;
varying vec2 lowerRightInputTextureCoordinate;
void main()
{
gl_Position = position;
upperLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, -texelHeight);
upperRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, -texelHeight);
lowerLeftInputTextureCoordinate = inputTextureCoordinate.xy + vec2(-texelWidth, texelHeight);
lowerRightInputTextureCoordinate = inputTextureCoordinate.xy + vec2(texelWidth, texelHeight);
}
);
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageColorPackingFragmentShaderString = SHADER_STRING
(
precision lowp float;
uniform sampler2D inputImageTexture;
uniform mediump mat3 convolutionMatrix;
varying highp vec2 outputTextureCoordinate;
varying highp vec2 upperLeftInputTextureCoordinate;
varying highp vec2 upperRightInputTextureCoordinate;
varying highp vec2 lowerLeftInputTextureCoordinate;
varying highp vec2 lowerRightInputTextureCoordinate;
void main()
{
float upperLeftIntensity = texture2D(inputImageTexture, upperLeftInputTextureCoordinate).r;
float upperRightIntensity = texture2D(inputImageTexture, upperRightInputTextureCoordinate).r;
float lowerLeftIntensity = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate).r;
float lowerRightIntensity = texture2D(inputImageTexture, lowerRightInputTextureCoordinate).r;
gl_FragColor = vec4(upperLeftIntensity, upperRightIntensity, lowerLeftIntensity, lowerRightIntensity);
}
);
#else
NSString *const kGPUImageColorPackingFragmentShaderString = SHADER_STRING
(
uniform sampler2D inputImageTexture;
uniform mat3 convolutionMatrix;
varying vec2 outputTextureCoordinate;
varying vec2 upperLeftInputTextureCoordinate;
varying vec2 upperRightInputTextureCoordinate;
varying vec2 lowerLeftInputTextureCoordinate;
varying vec2 lowerRightInputTextureCoordinate;
void main()
{
float upperLeftIntensity = texture2D(inputImageTexture, upperLeftInputTextureCoordinate).r;
float upperRightIntensity = texture2D(inputImageTexture, upperRightInputTextureCoordinate).r;
float lowerLeftIntensity = texture2D(inputImageTexture, lowerLeftInputTextureCoordinate).r;
float lowerRightIntensity = texture2D(inputImageTexture, lowerRightInputTextureCoordinate).r;
gl_FragColor = vec4(upperLeftIntensity, upperRightIntensity, lowerLeftIntensity, lowerRightIntensity);
}
);
#endif
@implementation GPUImageColorPackingFilter
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithVertexShaderFromString:kGPUImageColorPackingVertexShaderString fragmentShaderFromString:kGPUImageColorPackingFragmentShaderString]))
{
return nil;
}
texelWidthUniform = [filterProgram uniformIndex:@"texelWidth"];
texelHeightUniform = [filterProgram uniformIndex:@"texelHeight"];
return self;
}
- (void)setupFilterForSize:(CGSize)filterFrameSize;
{
texelWidth = 0.5 / inputTextureSize.width;
texelHeight = 0.5 / inputTextureSize.height;
runSynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext setActiveShaderProgram:filterProgram];
glUniform1f(texelWidthUniform, texelWidth);
glUniform1f(texelHeightUniform, texelHeight);
});
}
#pragma mark -
#pragma mark Managing the display FBOs
- (CGSize)sizeOfFBO;
{
CGSize outputSize = [self maximumOutputSize];
if ( (CGSizeEqualToSize(outputSize, CGSizeZero)) || (inputTextureSize.width < outputSize.width) )
{
CGSize quarterSize;
quarterSize.width = inputTextureSize.width / 2.0;
quarterSize.height = inputTextureSize.height / 2.0;
return quarterSize;
}
else
{
return outputSize;
}
}
#pragma mark -
#pragma mark Rendering
- (CGSize)outputFrameSize;
{
CGSize quarterSize;
quarterSize.width = inputTextureSize.width / 2.0;
quarterSize.height = inputTextureSize.height / 2.0;
return quarterSize;
}
@end
+48
View File
@@ -0,0 +1,48 @@
#import "GPUImageColourFASTFeatureDetector.h"
#import "GPUImageColourFASTSamplingOperation.h"
#import "GPUImageBoxBlurFilter.h"
@implementation GPUImageColourFASTFeatureDetector
@synthesize blurRadiusInPixels;
- (id)init;
{
if (!(self = [super init]))
{
return nil;
}
// First pass: apply a variable Gaussian blur
blurFilter = [[GPUImageBoxBlurFilter alloc] init];
[self addFilter:blurFilter];
// Second pass: combine the blurred image with the original sharp one
colourFASTSamplingOperation = [[GPUImageColourFASTSamplingOperation alloc] init];
[self addFilter:colourFASTSamplingOperation];
// Texture location 0 needs to be the sharp image for both the blur and the second stage processing
[blurFilter addTarget:colourFASTSamplingOperation atTextureLocation:1];
self.initialFilters = [NSArray arrayWithObjects:blurFilter, colourFASTSamplingOperation, nil];
self.terminalFilter = colourFASTSamplingOperation;
self.blurRadiusInPixels = 3.0;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setBlurRadiusInPixels:(CGFloat)newValue;
{
blurFilter.blurRadiusInPixels = newValue;
}
- (CGFloat)blurRadiusInPixels;
{
return blurFilter.blurRadiusInPixels;
}
@end
+204
View File
@@ -0,0 +1,204 @@
#import "GPUImageColourFASTSamplingOperation.h"
NSString *const kGPUImageColourFASTSamplingVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec4 inputTextureCoordinate;
attribute vec4 inputTextureCoordinate2;
uniform float texelWidth;
uniform float texelHeight;
varying vec2 textureCoordinate;
varying vec2 pointATextureCoordinate;
varying vec2 pointBTextureCoordinate;
varying vec2 pointCTextureCoordinate;
varying vec2 pointDTextureCoordinate;
varying vec2 pointETextureCoordinate;
varying vec2 pointFTextureCoordinate;
varying vec2 pointGTextureCoordinate;
varying vec2 pointHTextureCoordinate;
void main()
{
gl_Position = position;
float tripleTexelWidth = 3.0 * texelWidth;
float tripleTexelHeight = 3.0 * texelHeight;
textureCoordinate = inputTextureCoordinate.xy;
pointATextureCoordinate = vec2(textureCoordinate.x + tripleTexelWidth, textureCoordinate.y + texelHeight);
pointBTextureCoordinate = vec2(textureCoordinate.x + texelWidth, textureCoordinate.y + tripleTexelHeight);
pointCTextureCoordinate = vec2(textureCoordinate.x - texelWidth, textureCoordinate.y + tripleTexelHeight);
pointDTextureCoordinate = vec2(textureCoordinate.x - tripleTexelWidth, textureCoordinate.y + texelHeight);
pointETextureCoordinate = vec2(textureCoordinate.x - tripleTexelWidth, textureCoordinate.y - texelHeight);
pointFTextureCoordinate = vec2(textureCoordinate.x - texelWidth, textureCoordinate.y - tripleTexelHeight);
pointGTextureCoordinate = vec2(textureCoordinate.x + texelWidth, textureCoordinate.y - tripleTexelHeight);
pointHTextureCoordinate = vec2(textureCoordinate.x + tripleTexelWidth, textureCoordinate.y - texelHeight);
}
);
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageColourFASTSamplingFragmentShaderString = SHADER_STRING
(
precision highp float;
varying vec2 textureCoordinate;
varying vec2 pointATextureCoordinate;
varying vec2 pointBTextureCoordinate;
varying vec2 pointCTextureCoordinate;
varying vec2 pointDTextureCoordinate;
varying vec2 pointETextureCoordinate;
varying vec2 pointFTextureCoordinate;
varying vec2 pointGTextureCoordinate;
varying vec2 pointHTextureCoordinate;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
const float PITwo = 6.2832;
const float PI = 3.1416;
void main()
{
vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb;
vec3 pointAColor = texture2D(inputImageTexture, pointATextureCoordinate).rgb;
vec3 pointBColor = texture2D(inputImageTexture, pointBTextureCoordinate).rgb;
vec3 pointCColor = texture2D(inputImageTexture, pointCTextureCoordinate).rgb;
vec3 pointDColor = texture2D(inputImageTexture, pointDTextureCoordinate).rgb;
vec3 pointEColor = texture2D(inputImageTexture, pointETextureCoordinate).rgb;
vec3 pointFColor = texture2D(inputImageTexture, pointFTextureCoordinate).rgb;
vec3 pointGColor = texture2D(inputImageTexture, pointGTextureCoordinate).rgb;
vec3 pointHColor = texture2D(inputImageTexture, pointHTextureCoordinate).rgb;
vec3 colorComparison = ((pointAColor + pointBColor + pointCColor + pointDColor + pointEColor + pointFColor + pointGColor + pointHColor) * 0.125) - centerColor;
// Direction calculation drawn from Appendix B of Seth Hall's Ph.D. thesis
vec3 dirX = (pointAColor*0.94868) + (pointBColor*0.316227) - (pointCColor*0.316227) - (pointDColor*0.94868) - (pointEColor*0.94868) - (pointFColor*0.316227) + (pointGColor*0.316227) + (pointHColor*0.94868);
vec3 dirY = (pointAColor*0.316227) + (pointBColor*0.94868) + (pointCColor*0.94868) + (pointDColor*0.316227) - (pointEColor*0.316227) - (pointFColor*0.94868) - (pointGColor*0.94868) - (pointHColor*0.316227);
vec3 absoluteDifference = abs(colorComparison);
float componentLength = length(colorComparison);
float avgX = dot(absoluteDifference, dirX) / componentLength;
float avgY = dot(absoluteDifference, dirY) / componentLength;
float angle = atan(avgY, avgX);
vec3 normalizedColorComparison = (colorComparison + 1.0) * 0.5;
gl_FragColor = vec4(normalizedColorComparison, (angle+PI)/PITwo);
}
);
#else
NSString *const kGPUImageColourFASTSamplingFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 pointATextureCoordinate;
varying vec2 pointBTextureCoordinate;
varying vec2 pointCTextureCoordinate;
varying vec2 pointDTextureCoordinate;
varying vec2 pointETextureCoordinate;
varying vec2 pointFTextureCoordinate;
varying vec2 pointGTextureCoordinate;
varying vec2 pointHTextureCoordinate;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
const float PITwo = 6.2832;
const float PI = 3.1416;
void main()
{
vec3 centerColor = texture2D(inputImageTexture, textureCoordinate).rgb;
vec3 pointAColor = texture2D(inputImageTexture, pointATextureCoordinate).rgb;
vec3 pointBColor = texture2D(inputImageTexture, pointBTextureCoordinate).rgb;
vec3 pointCColor = texture2D(inputImageTexture, pointCTextureCoordinate).rgb;
vec3 pointDColor = texture2D(inputImageTexture, pointDTextureCoordinate).rgb;
vec3 pointEColor = texture2D(inputImageTexture, pointETextureCoordinate).rgb;
vec3 pointFColor = texture2D(inputImageTexture, pointFTextureCoordinate).rgb;
vec3 pointGColor = texture2D(inputImageTexture, pointGTextureCoordinate).rgb;
vec3 pointHColor = texture2D(inputImageTexture, pointHTextureCoordinate).rgb;
vec3 colorComparison = ((pointAColor + pointBColor + pointCColor + pointDColor + pointEColor + pointFColor + pointGColor + pointHColor) * 0.125) - centerColor;
// Direction calculation drawn from Appendix B of Seth Hall's Ph.D. thesis
vec3 dirX = (pointAColor*0.94868) + (pointBColor*0.316227) - (pointCColor*0.316227) - (pointDColor*0.94868) - (pointEColor*0.94868) - (pointFColor*0.316227) + (pointGColor*0.316227) + (pointHColor*0.94868);
vec3 dirY = (pointAColor*0.316227) + (pointBColor*0.94868) + (pointCColor*0.94868) + (pointDColor*0.316227) - (pointEColor*0.316227) - (pointFColor*0.94868) - (pointGColor*0.94868) - (pointHColor*0.316227);
vec3 absoluteDifference = abs(colorComparison);
float componentLength = length(colorComparison);
float avgX = dot(absoluteDifference, dirX) / componentLength;
float avgY = dot(absoluteDifference, dirY) / componentLength;
float angle = atan(avgY, avgX);
vec3 normalizedColorComparison = (colorComparison + 1.0) * 0.5;
gl_FragColor = vec4(normalizedColorComparison, (angle+PI)/PITwo);
}
);
#endif
@implementation GPUImageColourFASTSamplingOperation
@synthesize texelWidth = _texelWidth;
@synthesize texelHeight = _texelHeight;
#pragma mark -
#pragma mark Initialization and teardown
- (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString;
{
if (!(self = [super initWithVertexShaderFromString:kGPUImageColourFASTSamplingVertexShaderString fragmentShaderFromString:kGPUImageColourFASTSamplingFragmentShaderString]))
{
return nil;
}
texelWidthUniform = [filterProgram uniformIndex:@"texelWidth"];
texelHeightUniform = [filterProgram uniformIndex:@"texelHeight"];
return self;
}
- (void)setupFilterForSize:(CGSize)filterFrameSize;
{
if (!hasOverriddenImageSizeFactor)
{
_texelWidth = 1.0 / filterFrameSize.width;
_texelHeight = 1.0 / filterFrameSize.height;
runSynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext setActiveShaderProgram:filterProgram];
if (GPUImageRotationSwapsWidthAndHeight(inputRotation))
{
glUniform1f(texelWidthUniform, _texelHeight);
glUniform1f(texelHeightUniform, _texelWidth);
}
else
{
glUniform1f(texelWidthUniform, _texelWidth);
glUniform1f(texelHeightUniform, _texelHeight);
}
});
}
}
#pragma mark -
#pragma mark Accessors
- (void)setTexelWidth:(CGFloat)newValue;
{
hasOverriddenImageSizeFactor = YES;
_texelWidth = newValue;
[self setFloat:_texelWidth forUniform:texelWidthUniform program:filterProgram];
}
- (void)setTexelHeight:(CGFloat)newValue;
{
hasOverriddenImageSizeFactor = YES;
_texelHeight = newValue;
[self setFloat:_texelHeight forUniform:texelHeightUniform program:filterProgram];
}
@end
+66
View File
@@ -0,0 +1,66 @@
#import "GPUImageContrastFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageContrastFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform lowp float contrast;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);
}
);
#else
NSString *const kGPUImageContrastFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform float contrast;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
gl_FragColor = vec4(((textureColor.rgb - vec3(0.5)) * contrast + vec3(0.5)), textureColor.w);
}
);
#endif
@implementation GPUImageContrastFilter
@synthesize contrast = _contrast;
#pragma mark -
#pragma mark Initialization
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageContrastFragmentShaderString]))
{
return nil;
}
contrastUniform = [filterProgram uniformIndex:@"contrast"];
self.contrast = 1.0;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setContrast:(CGFloat)newValue;
{
_contrast = newValue;
[self setFloat:_contrast forUniform:contrastUniform program:filterProgram];
}
@end
+274
View File
@@ -0,0 +1,274 @@
#import "GPUImageCropFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageCropFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
gl_FragColor = texture2D(inputImageTexture, textureCoordinate);
}
);
#else
NSString *const kGPUImageCropFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
gl_FragColor = texture2D(inputImageTexture, textureCoordinate);
}
);
#endif
@interface GPUImageCropFilter ()
- (void)calculateCropTextureCoordinates;
@end
@interface GPUImageCropFilter()
{
CGSize originallySuppliedInputSize;
}
@end
@implementation GPUImageCropFilter
@synthesize cropRegion = _cropRegion;
#pragma mark -
#pragma mark Initialization and teardown
- (id)initWithCropRegion:(CGRect)newCropRegion;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageCropFragmentShaderString]))
{
return nil;
}
self.cropRegion = newCropRegion;
return self;
}
- (id)init;
{
if (!(self = [self initWithCropRegion:CGRectMake(0.0, 0.0, 1.0, 1.0)]))
{
return nil;
}
return self;
}
#pragma mark -
#pragma mark Rendering
- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;
{
if (self.preventRendering)
{
return;
}
// if (overrideInputSize)
// {
// if (CGSizeEqualToSize(forcedMaximumSize, CGSizeZero))
// {
// return;
// }
// else
// {
// CGRect insetRect = AVMakeRectWithAspectRatioInsideRect(newSize, CGRectMake(0.0, 0.0, forcedMaximumSize.width, forcedMaximumSize.height));
// inputTextureSize = insetRect.size;
// return;
// }
// }
CGSize rotatedSize = [self rotatedSize:newSize forIndex:textureIndex];
originallySuppliedInputSize = rotatedSize;
CGSize scaledSize;
scaledSize.width = rotatedSize.width * _cropRegion.size.width;
scaledSize.height = rotatedSize.height * _cropRegion.size.height;
if (CGSizeEqualToSize(scaledSize, CGSizeZero))
{
inputTextureSize = scaledSize;
}
else if (!CGSizeEqualToSize(inputTextureSize, scaledSize))
{
inputTextureSize = scaledSize;
}
}
#pragma mark -
#pragma mark GPUImageInput
- (void)calculateCropTextureCoordinates;
{
CGFloat minX = _cropRegion.origin.x;
CGFloat minY = _cropRegion.origin.y;
CGFloat maxX = CGRectGetMaxX(_cropRegion);
CGFloat maxY = CGRectGetMaxY(_cropRegion);
switch(inputRotation)
{
case kGPUImageNoRotation: // Works
{
cropTextureCoordinates[0] = minX; // 0,0
cropTextureCoordinates[1] = minY;
cropTextureCoordinates[2] = maxX; // 1,0
cropTextureCoordinates[3] = minY;
cropTextureCoordinates[4] = minX; // 0,1
cropTextureCoordinates[5] = maxY;
cropTextureCoordinates[6] = maxX; // 1,1
cropTextureCoordinates[7] = maxY;
}; break;
case kGPUImageRotateLeft: // Fixed
{
cropTextureCoordinates[0] = maxY; // 1,0
cropTextureCoordinates[1] = 1.0 - maxX;
cropTextureCoordinates[2] = maxY; // 1,1
cropTextureCoordinates[3] = 1.0 - minX;
cropTextureCoordinates[4] = minY; // 0,0
cropTextureCoordinates[5] = 1.0 - maxX;
cropTextureCoordinates[6] = minY; // 0,1
cropTextureCoordinates[7] = 1.0 - minX;
}; break;
case kGPUImageRotateRight: // Fixed
{
cropTextureCoordinates[0] = minY; // 0,1
cropTextureCoordinates[1] = 1.0 - minX;
cropTextureCoordinates[2] = minY; // 0,0
cropTextureCoordinates[3] = 1.0 - maxX;
cropTextureCoordinates[4] = maxY; // 1,1
cropTextureCoordinates[5] = 1.0 - minX;
cropTextureCoordinates[6] = maxY; // 1,0
cropTextureCoordinates[7] = 1.0 - maxX;
}; break;
case kGPUImageFlipVertical: // Works for me
{
cropTextureCoordinates[0] = minX; // 0,1
cropTextureCoordinates[1] = maxY;
cropTextureCoordinates[2] = maxX; // 1,1
cropTextureCoordinates[3] = maxY;
cropTextureCoordinates[4] = minX; // 0,0
cropTextureCoordinates[5] = minY;
cropTextureCoordinates[6] = maxX; // 1,0
cropTextureCoordinates[7] = minY;
}; break;
case kGPUImageFlipHorizonal: // Works for me
{
cropTextureCoordinates[0] = maxX; // 1,0
cropTextureCoordinates[1] = minY;
cropTextureCoordinates[2] = minX; // 0,0
cropTextureCoordinates[3] = minY;
cropTextureCoordinates[4] = maxX; // 1,1
cropTextureCoordinates[5] = maxY;
cropTextureCoordinates[6] = minX; // 0,1
cropTextureCoordinates[7] = maxY;
}; break;
case kGPUImageRotate180: // Fixed
{
cropTextureCoordinates[0] = maxX; // 1,1
cropTextureCoordinates[1] = maxY;
cropTextureCoordinates[2] = minX; // 0,1
cropTextureCoordinates[3] = maxY;
cropTextureCoordinates[4] = maxX; // 1,0
cropTextureCoordinates[5] = minY;
cropTextureCoordinates[6] = minX; // 0,0
cropTextureCoordinates[7] = minY;
}; break;
case kGPUImageRotateRightFlipVertical: // Fixed
{
cropTextureCoordinates[0] = minY; // 0,0
cropTextureCoordinates[1] = 1.0 - maxX;
cropTextureCoordinates[2] = minY; // 0,1
cropTextureCoordinates[3] = 1.0 - minX;
cropTextureCoordinates[4] = maxY; // 1,0
cropTextureCoordinates[5] = 1.0 - maxX;
cropTextureCoordinates[6] = maxY; // 1,1
cropTextureCoordinates[7] = 1.0 - minX;
}; break;
case kGPUImageRotateRightFlipHorizontal: // Fixed
{
cropTextureCoordinates[0] = maxY; // 1,1
cropTextureCoordinates[1] = 1.0 - minX;
cropTextureCoordinates[2] = maxY; // 1,0
cropTextureCoordinates[3] = 1.0 - maxX;
cropTextureCoordinates[4] = minY; // 0,1
cropTextureCoordinates[5] = 1.0 - minX;
cropTextureCoordinates[6] = minY; // 0,0
cropTextureCoordinates[7] = 1.0 - maxX;
}; break;
}
}
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
{
static const GLfloat cropSquareVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
[self renderToTextureWithVertices:cropSquareVertices textureCoordinates:cropTextureCoordinates];
[self informTargetsAboutNewFrameAtTime:frameTime];
}
#pragma mark -
#pragma mark Accessors
- (void)setCropRegion:(CGRect)newValue;
{
NSParameterAssert(newValue.origin.x >= 0 && newValue.origin.x <= 1 &&
newValue.origin.y >= 0 && newValue.origin.y <= 1 &&
newValue.size.width >= 0 && newValue.size.width <= 1 &&
newValue.size.height >= 0 && newValue.size.height <= 1);
_cropRegion = newValue;
[self calculateCropTextureCoordinates];
}
- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;
{
[super setInputRotation:newInputRotation atIndex:textureIndex];
[self calculateCropTextureCoordinates];
}
@end
+139
View File
@@ -0,0 +1,139 @@
#import "GPUImageCrosshairGenerator.h"
NSString *const kGPUImageCrosshairVertexShaderString = SHADER_STRING
(
attribute vec4 position;
uniform float crosshairWidth;
varying vec2 centerLocation;
varying float pointSpacing;
void main()
{
gl_Position = vec4(((position.xy * 2.0) - 1.0), 0.0, 1.0);
gl_PointSize = crosshairWidth + 1.0;
pointSpacing = 1.0 / crosshairWidth;
centerLocation = vec2(pointSpacing * ceil(crosshairWidth / 2.0), pointSpacing * ceil(crosshairWidth / 2.0));
}
);
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageCrosshairFragmentShaderString = SHADER_STRING
(
uniform lowp vec3 crosshairColor;
varying highp vec2 centerLocation;
varying highp float pointSpacing;
void main()
{
lowp vec2 distanceFromCenter = abs(centerLocation - gl_PointCoord.xy);
lowp float axisTest = step(pointSpacing, gl_PointCoord.y) * step(distanceFromCenter.x, 0.09) + step(pointSpacing, gl_PointCoord.x) * step(distanceFromCenter.y, 0.09);
gl_FragColor = vec4(crosshairColor * axisTest, axisTest);
// gl_FragColor = vec4(distanceFromCenterInX, distanceFromCenterInY, 0.0, 1.0);
}
);
#else
NSString *const kGPUImageCrosshairFragmentShaderString = SHADER_STRING
(
GPUImageEscapedHashIdentifier(version 120)\n
uniform vec3 crosshairColor;
varying vec2 centerLocation;
varying float pointSpacing;
void main()
{
vec2 distanceFromCenter = abs(centerLocation - gl_PointCoord.xy);
float axisTest = step(pointSpacing, gl_PointCoord.y) * step(distanceFromCenter.x, 0.09) + step(pointSpacing, gl_PointCoord.x) * step(distanceFromCenter.y, 0.09);
gl_FragColor = vec4(crosshairColor * axisTest, axisTest);
// gl_FragColor = vec4(distanceFromCenterInX, distanceFromCenterInY, 0.0, 1.0);
}
);
#endif
@implementation GPUImageCrosshairGenerator
@synthesize crosshairWidth = _crosshairWidth;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithVertexShaderFromString:kGPUImageCrosshairVertexShaderString fragmentShaderFromString:kGPUImageCrosshairFragmentShaderString]))
{
return nil;
}
runSynchronouslyOnVideoProcessingQueue(^{
crosshairWidthUniform = [filterProgram uniformIndex:@"crosshairWidth"];
crosshairColorUniform = [filterProgram uniformIndex:@"crosshairColor"];
self.crosshairWidth = 5.0;
[self setCrosshairColorRed:0.0 green:1.0 blue:0.0];
});
return self;
}
#pragma mark -
#pragma mark Rendering
- (void)renderCrosshairsFromArray:(GLfloat *)crosshairCoordinates count:(NSUInteger)numberOfCrosshairs frameTime:(CMTime)frameTime;
{
if (self.preventRendering)
{
return;
}
runSynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext setActiveShaderProgram:filterProgram];
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
#else
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO];
[outputFramebuffer activateFramebuffer];
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, crosshairCoordinates);
glDrawArrays(GL_POINTS, 0, (GLsizei)numberOfCrosshairs);
[self informTargetsAboutNewFrameAtTime:frameTime];
});
}
- (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates;
{
// Prevent rendering of the frame by normal means
}
#pragma mark -
#pragma mark Accessors
- (void)setCrosshairWidth:(CGFloat)newValue;
{
_crosshairWidth = newValue;
[self setFloat:_crosshairWidth forUniform:crosshairWidthUniform program:filterProgram];
}
- (void)setCrosshairColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
{
GPUVector3 crosshairColor = {redComponent, greenComponent, blueComponent};
[self setVec3:crosshairColor forUniform:crosshairColorUniform program:filterProgram];
}
@end
+163
View File
@@ -0,0 +1,163 @@
#import "GPUImageCrosshatchFilter.h"
// Shader code based on http://machinesdontcare.wordpress.com/
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageCrosshatchFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp float crossHatchSpacing;
uniform highp float lineWidth;
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main()
{
highp float luminance = dot(texture2D(inputImageTexture, textureCoordinate).rgb, W);
lowp vec4 colorToDisplay = vec4(1.0, 1.0, 1.0, 1.0);
if (luminance < 1.00)
{
if (mod(textureCoordinate.x + textureCoordinate.y, crossHatchSpacing) <= lineWidth)
{
colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);
}
}
if (luminance < 0.75)
{
if (mod(textureCoordinate.x - textureCoordinate.y, crossHatchSpacing) <= lineWidth)
{
colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);
}
}
if (luminance < 0.50)
{
if (mod(textureCoordinate.x + textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth)
{
colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);
}
}
if (luminance < 0.3)
{
if (mod(textureCoordinate.x - textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth)
{
colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);
}
}
gl_FragColor = colorToDisplay;
}
);
#else
NSString *const kGPUImageCrosshatchFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform float crossHatchSpacing;
uniform float lineWidth;
const vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main()
{
float luminance = dot(texture2D(inputImageTexture, textureCoordinate).rgb, W);
vec4 colorToDisplay = vec4(1.0, 1.0, 1.0, 1.0);
if (luminance < 1.00)
{
if (mod(textureCoordinate.x + textureCoordinate.y, crossHatchSpacing) <= lineWidth)
{
colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);
}
}
if (luminance < 0.75)
{
if (mod(textureCoordinate.x - textureCoordinate.y, crossHatchSpacing) <= lineWidth)
{
colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);
}
}
if (luminance < 0.50)
{
if (mod(textureCoordinate.x + textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth)
{
colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);
}
}
if (luminance < 0.3)
{
if (mod(textureCoordinate.x - textureCoordinate.y - (crossHatchSpacing / 2.0), crossHatchSpacing) <= lineWidth)
{
colorToDisplay = vec4(0.0, 0.0, 0.0, 1.0);
}
}
gl_FragColor = colorToDisplay;
}
);
#endif
@implementation GPUImageCrosshatchFilter
@synthesize crossHatchSpacing = _crossHatchSpacing;
@synthesize lineWidth = _lineWidth;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageCrosshatchFragmentShaderString]))
{
return nil;
}
crossHatchSpacingUniform = [filterProgram uniformIndex:@"crossHatchSpacing"];
lineWidthUniform = [filterProgram uniformIndex:@"lineWidth"];
self.crossHatchSpacing = 0.03;
self.lineWidth = 0.003;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setCrossHatchSpacing:(CGFloat)newValue;
{
CGFloat singlePixelSpacing;
if (inputTextureSize.width != 0.0)
{
singlePixelSpacing = 1.0 / inputTextureSize.width;
}
else
{
singlePixelSpacing = 1.0 / 2048.0;
}
if (newValue < singlePixelSpacing)
{
_crossHatchSpacing = singlePixelSpacing;
}
else
{
_crossHatchSpacing = newValue;
}
[self setFloat:_crossHatchSpacing forUniform:crossHatchSpacingUniform program:filterProgram];
}
- (void)setLineWidth:(CGFloat)newValue;
{
_lineWidth = newValue;
[self setFloat:_lineWidth forUniform:lineWidthUniform program:filterProgram];
}
@end
+52
View File
@@ -0,0 +1,52 @@
#import "GPUImageDarkenBlendFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageDarkenBlendFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4(min(overlayer.rgb * base.a, base.rgb * overlayer.a) + overlayer.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlayer.a), 1.0);
}
);
#else
NSString *const kGPUImageDarkenBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 base = texture2D(inputImageTexture, textureCoordinate);
vec4 overlayer = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4(min(overlayer.rgb * base.a, base.rgb * overlayer.a) + overlayer.rgb * (1.0 - base.a) + base.rgb * (1.0 - overlayer.a), 1.0);
}
);
#endif
@implementation GPUImageDarkenBlendFilter
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageDarkenBlendFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+50
View File
@@ -0,0 +1,50 @@
#import "GPUImageDifferenceBlendFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageDifferenceBlendFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4(abs(textureColor2.rgb - textureColor.rgb), textureColor.a);
}
);
#else
NSString *const kGPUImageDifferenceBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4(abs(textureColor2.rgb - textureColor.rgb), textureColor.a);
}
);
#endif
@implementation GPUImageDifferenceBlendFilter
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageDifferenceBlendFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+431
View File
@@ -0,0 +1,431 @@
#import "GPUImageDilationFilter.h"
@implementation GPUImageDilationFilter
NSString *const kGPUImageDilationRadiusOneVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec2 inputTextureCoordinate;
uniform float texelWidthOffset;
uniform float texelHeightOffset;
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
void main()
{
gl_Position = position;
vec2 offset = vec2(texelWidthOffset, texelHeightOffset);
centerTextureCoordinate = inputTextureCoordinate;
oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;
oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;
}
);
NSString *const kGPUImageDilationRadiusTwoVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec2 inputTextureCoordinate;
uniform float texelWidthOffset;
uniform float texelHeightOffset;
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
varying vec2 twoStepsPositiveTextureCoordinate;
varying vec2 twoStepsNegativeTextureCoordinate;
void main()
{
gl_Position = position;
vec2 offset = vec2(texelWidthOffset, texelHeightOffset);
centerTextureCoordinate = inputTextureCoordinate;
oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;
oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;
twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);
twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);
}
);
NSString *const kGPUImageDilationRadiusThreeVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec2 inputTextureCoordinate;
uniform float texelWidthOffset;
uniform float texelHeightOffset;
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
varying vec2 twoStepsPositiveTextureCoordinate;
varying vec2 twoStepsNegativeTextureCoordinate;
varying vec2 threeStepsPositiveTextureCoordinate;
varying vec2 threeStepsNegativeTextureCoordinate;
void main()
{
gl_Position = position;
vec2 offset = vec2(texelWidthOffset, texelHeightOffset);
centerTextureCoordinate = inputTextureCoordinate;
oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;
oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;
twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);
twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);
threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);
threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);
}
);
NSString *const kGPUImageDilationRadiusFourVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec2 inputTextureCoordinate;
uniform float texelWidthOffset;
uniform float texelHeightOffset;
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
varying vec2 twoStepsPositiveTextureCoordinate;
varying vec2 twoStepsNegativeTextureCoordinate;
varying vec2 threeStepsPositiveTextureCoordinate;
varying vec2 threeStepsNegativeTextureCoordinate;
varying vec2 fourStepsPositiveTextureCoordinate;
varying vec2 fourStepsNegativeTextureCoordinate;
void main()
{
gl_Position = position;
vec2 offset = vec2(texelWidthOffset, texelHeightOffset);
centerTextureCoordinate = inputTextureCoordinate;
oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;
oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;
twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);
twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);
threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);
threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);
fourStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 4.0);
fourStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 4.0);
}
);
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageDilationRadiusOneFragmentShaderString = SHADER_STRING
(
precision lowp float;
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
lowp float maxValue = max(centerIntensity, oneStepPositiveIntensity);
maxValue = max(maxValue, oneStepNegativeIntensity);
gl_FragColor = vec4(vec3(maxValue), 1.0);
}
);
NSString *const kGPUImageDilationRadiusTwoFragmentShaderString = SHADER_STRING
(
precision lowp float;
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
varying vec2 twoStepsPositiveTextureCoordinate;
varying vec2 twoStepsNegativeTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
lowp float maxValue = max(centerIntensity, oneStepPositiveIntensity);
maxValue = max(maxValue, oneStepNegativeIntensity);
maxValue = max(maxValue, twoStepsPositiveIntensity);
maxValue = max(maxValue, twoStepsNegativeIntensity);
gl_FragColor = vec4(vec3(maxValue), 1.0);
}
);
NSString *const kGPUImageDilationRadiusThreeFragmentShaderString = SHADER_STRING
(
precision lowp float;
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
varying vec2 twoStepsPositiveTextureCoordinate;
varying vec2 twoStepsNegativeTextureCoordinate;
varying vec2 threeStepsPositiveTextureCoordinate;
varying vec2 threeStepsNegativeTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
float threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate).r;
float threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate).r;
lowp float maxValue = max(centerIntensity, oneStepPositiveIntensity);
maxValue = max(maxValue, oneStepNegativeIntensity);
maxValue = max(maxValue, twoStepsPositiveIntensity);
maxValue = max(maxValue, twoStepsNegativeIntensity);
maxValue = max(maxValue, threeStepsPositiveIntensity);
maxValue = max(maxValue, threeStepsNegativeIntensity);
gl_FragColor = vec4(vec3(maxValue), 1.0);
}
);
NSString *const kGPUImageDilationRadiusFourFragmentShaderString = SHADER_STRING
(
precision lowp float;
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
varying vec2 twoStepsPositiveTextureCoordinate;
varying vec2 twoStepsNegativeTextureCoordinate;
varying vec2 threeStepsPositiveTextureCoordinate;
varying vec2 threeStepsNegativeTextureCoordinate;
varying vec2 fourStepsPositiveTextureCoordinate;
varying vec2 fourStepsNegativeTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
float threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate).r;
float threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate).r;
float fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate).r;
float fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate).r;
lowp float maxValue = max(centerIntensity, oneStepPositiveIntensity);
maxValue = max(maxValue, oneStepNegativeIntensity);
maxValue = max(maxValue, twoStepsPositiveIntensity);
maxValue = max(maxValue, twoStepsNegativeIntensity);
maxValue = max(maxValue, threeStepsPositiveIntensity);
maxValue = max(maxValue, threeStepsNegativeIntensity);
maxValue = max(maxValue, fourStepsPositiveIntensity);
maxValue = max(maxValue, fourStepsNegativeIntensity);
gl_FragColor = vec4(vec3(maxValue), 1.0);
}
);
#else
NSString *const kGPUImageDilationRadiusOneFragmentShaderString = SHADER_STRING
(
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
float maxValue = max(centerIntensity, oneStepPositiveIntensity);
maxValue = max(maxValue, oneStepNegativeIntensity);
gl_FragColor = vec4(vec3(maxValue), 1.0);
}
);
NSString *const kGPUImageDilationRadiusTwoFragmentShaderString = SHADER_STRING
(
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
varying vec2 twoStepsPositiveTextureCoordinate;
varying vec2 twoStepsNegativeTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
float maxValue = max(centerIntensity, oneStepPositiveIntensity);
maxValue = max(maxValue, oneStepNegativeIntensity);
maxValue = max(maxValue, twoStepsPositiveIntensity);
maxValue = max(maxValue, twoStepsNegativeIntensity);
gl_FragColor = vec4(vec3(maxValue), 1.0);
}
);
NSString *const kGPUImageDilationRadiusThreeFragmentShaderString = SHADER_STRING
(
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
varying vec2 twoStepsPositiveTextureCoordinate;
varying vec2 twoStepsNegativeTextureCoordinate;
varying vec2 threeStepsPositiveTextureCoordinate;
varying vec2 threeStepsNegativeTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
float threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate).r;
float threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate).r;
float maxValue = max(centerIntensity, oneStepPositiveIntensity);
maxValue = max(maxValue, oneStepNegativeIntensity);
maxValue = max(maxValue, twoStepsPositiveIntensity);
maxValue = max(maxValue, twoStepsNegativeIntensity);
maxValue = max(maxValue, threeStepsPositiveIntensity);
maxValue = max(maxValue, threeStepsNegativeIntensity);
gl_FragColor = vec4(vec3(maxValue), 1.0);
}
);
NSString *const kGPUImageDilationRadiusFourFragmentShaderString = SHADER_STRING
(
varying vec2 centerTextureCoordinate;
varying vec2 oneStepPositiveTextureCoordinate;
varying vec2 oneStepNegativeTextureCoordinate;
varying vec2 twoStepsPositiveTextureCoordinate;
varying vec2 twoStepsNegativeTextureCoordinate;
varying vec2 threeStepsPositiveTextureCoordinate;
varying vec2 threeStepsNegativeTextureCoordinate;
varying vec2 fourStepsPositiveTextureCoordinate;
varying vec2 fourStepsNegativeTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate).r;
float oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate).r;
float oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate).r;
float twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate).r;
float twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate).r;
float threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate).r;
float threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate).r;
float fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate).r;
float fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate).r;
float maxValue = max(centerIntensity, oneStepPositiveIntensity);
maxValue = max(maxValue, oneStepNegativeIntensity);
maxValue = max(maxValue, twoStepsPositiveIntensity);
maxValue = max(maxValue, twoStepsNegativeIntensity);
maxValue = max(maxValue, threeStepsPositiveIntensity);
maxValue = max(maxValue, threeStepsNegativeIntensity);
maxValue = max(maxValue, fourStepsPositiveIntensity);
maxValue = max(maxValue, fourStepsNegativeIntensity);
gl_FragColor = vec4(vec3(maxValue), 1.0);
}
);
#endif
#pragma mark -
#pragma mark Initialization and teardown
- (id)initWithRadius:(NSUInteger)dilationRadius;
{
NSString *fragmentShaderForThisRadius = nil;
NSString *vertexShaderForThisRadius = nil;
switch (dilationRadius)
{
case 0:
case 1:
{
vertexShaderForThisRadius = kGPUImageDilationRadiusOneVertexShaderString;
fragmentShaderForThisRadius = kGPUImageDilationRadiusOneFragmentShaderString;
}; break;
case 2:
{
vertexShaderForThisRadius = kGPUImageDilationRadiusTwoVertexShaderString;
fragmentShaderForThisRadius = kGPUImageDilationRadiusTwoFragmentShaderString;
}; break;
case 3:
{
vertexShaderForThisRadius = kGPUImageDilationRadiusThreeVertexShaderString;
fragmentShaderForThisRadius = kGPUImageDilationRadiusThreeFragmentShaderString;
}; break;
case 4:
{
vertexShaderForThisRadius = kGPUImageDilationRadiusFourVertexShaderString;
fragmentShaderForThisRadius = kGPUImageDilationRadiusFourFragmentShaderString;
}; break;
default:
{
vertexShaderForThisRadius = kGPUImageDilationRadiusFourVertexShaderString;
fragmentShaderForThisRadius = kGPUImageDilationRadiusFourFragmentShaderString;
}; break;
}
if (!(self = [super initWithFirstStageVertexShaderFromString:vertexShaderForThisRadius firstStageFragmentShaderFromString:fragmentShaderForThisRadius secondStageVertexShaderFromString:vertexShaderForThisRadius secondStageFragmentShaderFromString:fragmentShaderForThisRadius]))
{
return nil;
}
return self;
}
- (id)init;
{
if (!(self = [self initWithRadius:1]))
{
return nil;
}
return self;
}
@end
@@ -0,0 +1,141 @@
#import "GPUImageDirectionalNonMaximumSuppressionFilter.h"
@implementation GPUImageDirectionalNonMaximumSuppressionFilter
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageDirectionalNonmaximumSuppressionFragmentShaderString = SHADER_STRING
(
precision mediump float;
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp float texelWidth;
uniform highp float texelHeight;
uniform mediump float upperThreshold;
uniform mediump float lowerThreshold;
void main()
{
vec3 currentGradientAndDirection = texture2D(inputImageTexture, textureCoordinate).rgb;
vec2 gradientDirection = ((currentGradientAndDirection.gb * 2.0) - 1.0) * vec2(texelWidth, texelHeight);
float firstSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate + gradientDirection).r;
float secondSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate - gradientDirection).r;
float multiplier = step(firstSampledGradientMagnitude, currentGradientAndDirection.r);
multiplier = multiplier * step(secondSampledGradientMagnitude, currentGradientAndDirection.r);
float thresholdCompliance = smoothstep(lowerThreshold, upperThreshold, currentGradientAndDirection.r);
multiplier = multiplier * thresholdCompliance;
gl_FragColor = vec4(multiplier, multiplier, multiplier, 1.0);
}
);
#else
NSString *const kGPUImageDirectionalNonmaximumSuppressionFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform float texelWidth;
uniform float texelHeight;
uniform float upperThreshold;
uniform float lowerThreshold;
void main()
{
vec3 currentGradientAndDirection = texture2D(inputImageTexture, textureCoordinate).rgb;
vec2 gradientDirection = ((currentGradientAndDirection.gb * 2.0) - 1.0) * vec2(texelWidth, texelHeight);
float firstSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate + gradientDirection).r;
float secondSampledGradientMagnitude = texture2D(inputImageTexture, textureCoordinate - gradientDirection).r;
float multiplier = step(firstSampledGradientMagnitude, currentGradientAndDirection.r);
multiplier = multiplier * step(secondSampledGradientMagnitude, currentGradientAndDirection.r);
float thresholdCompliance = smoothstep(lowerThreshold, upperThreshold, currentGradientAndDirection.r);
multiplier = multiplier * thresholdCompliance;
gl_FragColor = vec4(multiplier, multiplier, multiplier, 1.0);
}
);
#endif
@synthesize texelWidth = _texelWidth;
@synthesize texelHeight = _texelHeight;
@synthesize upperThreshold = _upperThreshold;
@synthesize lowerThreshold = _lowerThreshold;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageDirectionalNonmaximumSuppressionFragmentShaderString]))
{
return nil;
}
texelWidthUniform = [filterProgram uniformIndex:@"texelWidth"];
texelHeightUniform = [filterProgram uniformIndex:@"texelHeight"];
upperThresholdUniform = [filterProgram uniformIndex:@"upperThreshold"];
lowerThresholdUniform = [filterProgram uniformIndex:@"lowerThreshold"];
self.upperThreshold = 0.5;
self.lowerThreshold = 0.1;
return self;
}
- (void)setupFilterForSize:(CGSize)filterFrameSize;
{
if (!hasOverriddenImageSizeFactor)
{
_texelWidth = 1.0 / filterFrameSize.width;
_texelHeight = 1.0 / filterFrameSize.height;
runSynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext setActiveShaderProgram:filterProgram];
glUniform1f(texelWidthUniform, _texelWidth);
glUniform1f(texelHeightUniform, _texelHeight);
});
}
}
#pragma mark -
#pragma mark Accessors
- (void)setTexelWidth:(CGFloat)newValue;
{
hasOverriddenImageSizeFactor = YES;
_texelWidth = newValue;
[self setFloat:_texelWidth forUniform:texelWidthUniform program:filterProgram];
}
- (void)setTexelHeight:(CGFloat)newValue;
{
hasOverriddenImageSizeFactor = YES;
_texelHeight = newValue;
[self setFloat:_texelHeight forUniform:texelHeightUniform program:filterProgram];
}
- (void)setLowerThreshold:(CGFloat)newValue;
{
_lowerThreshold = newValue;
[self setFloat:_lowerThreshold forUniform:lowerThresholdUniform program:filterProgram];
}
- (void)setUpperThreshold:(CGFloat)newValue;
{
_upperThreshold = newValue;
[self setFloat:_upperThreshold forUniform:upperThresholdUniform program:filterProgram];
}
@end
@@ -0,0 +1,103 @@
#import "GPUImageDirectionalSobelEdgeDetectionFilter.h"
@implementation GPUImageDirectionalSobelEdgeDetectionFilter
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageDirectionalSobelEdgeDetectionFragmentShaderString = SHADER_STRING
(
precision mediump float;
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;
float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;
float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;
float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;
float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;
float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;
float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;
float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;
vec2 gradientDirection;
gradientDirection.x = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;
gradientDirection.y = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;
float gradientMagnitude = length(gradientDirection);
vec2 normalizedDirection = normalize(gradientDirection);
normalizedDirection = sign(normalizedDirection) * floor(abs(normalizedDirection) + 0.617316); // Offset by 1-sin(pi/8) to set to 0 if near axis, 1 if away
normalizedDirection = (normalizedDirection + 1.0) * 0.5; // Place -1.0 - 1.0 within 0 - 1.0
gl_FragColor = vec4(gradientMagnitude, normalizedDirection.x, normalizedDirection.y, 1.0);
}
);
#else
NSString *const kGPUImageDirectionalSobelEdgeDetectionFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 leftTextureCoordinate;
varying vec2 rightTextureCoordinate;
varying vec2 topTextureCoordinate;
varying vec2 topLeftTextureCoordinate;
varying vec2 topRightTextureCoordinate;
varying vec2 bottomTextureCoordinate;
varying vec2 bottomLeftTextureCoordinate;
varying vec2 bottomRightTextureCoordinate;
uniform sampler2D inputImageTexture;
void main()
{
float bottomLeftIntensity = texture2D(inputImageTexture, bottomLeftTextureCoordinate).r;
float topRightIntensity = texture2D(inputImageTexture, topRightTextureCoordinate).r;
float topLeftIntensity = texture2D(inputImageTexture, topLeftTextureCoordinate).r;
float bottomRightIntensity = texture2D(inputImageTexture, bottomRightTextureCoordinate).r;
float leftIntensity = texture2D(inputImageTexture, leftTextureCoordinate).r;
float rightIntensity = texture2D(inputImageTexture, rightTextureCoordinate).r;
float bottomIntensity = texture2D(inputImageTexture, bottomTextureCoordinate).r;
float topIntensity = texture2D(inputImageTexture, topTextureCoordinate).r;
vec2 gradientDirection;
gradientDirection.x = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity;
gradientDirection.y = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity;
float gradientMagnitude = length(gradientDirection);
vec2 normalizedDirection = normalize(gradientDirection);
normalizedDirection = sign(normalizedDirection) * floor(abs(normalizedDirection) + 0.617316); // Offset by 1-sin(pi/8) to set to 0 if near axis, 1 if away
normalizedDirection = (normalizedDirection + 1.0) * 0.5; // Place -1.0 - 1.0 within 0 - 1.0
gl_FragColor = vec4(gradientMagnitude, normalizedDirection.x, normalizedDirection.y, 1.0);
}
);
#endif
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageDirectionalSobelEdgeDetectionFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+72
View File
@@ -0,0 +1,72 @@
#import "GPUImageDissolveBlendFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageDissolveBlendFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform lowp float mixturePercent;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = mix(textureColor, textureColor2, mixturePercent);
}
);
#else
NSString *const kGPUImageDissolveBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform float mixturePercent;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = mix(textureColor, textureColor2, mixturePercent);
}
);
#endif
@implementation GPUImageDissolveBlendFilter
@synthesize mix = _mix;
#pragma mark -
#pragma mark Initialization and teardown
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageDissolveBlendFragmentShaderString]))
{
return nil;
}
mixUniform = [filterProgram uniformIndex:@"mixturePercent"];
self.mix = 0.5;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setMix:(CGFloat)newValue;
{
_mix = newValue;
[self setFloat:_mix forUniform:mixUniform program:filterProgram];
}
@end
+96
View File
@@ -0,0 +1,96 @@
#import "GPUImageDivideBlendFilter.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kGPUImageDivideBlendFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);
mediump vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);
mediump float ra;
if (overlay.a == 0.0 || ((base.r / overlay.r) > (base.a / overlay.a)))
ra = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);
else
ra = (base.r * overlay.a * overlay.a) / overlay.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);
mediump float ga;
if (overlay.a == 0.0 || ((base.g / overlay.g) > (base.a / overlay.a)))
ga = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);
else
ga = (base.g * overlay.a * overlay.a) / overlay.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);
mediump float ba;
if (overlay.a == 0.0 || ((base.b / overlay.b) > (base.a / overlay.a)))
ba = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);
else
ba = (base.b * overlay.a * overlay.a) / overlay.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);
mediump float a = overlay.a + base.a - overlay.a * base.a;
gl_FragColor = vec4(ra, ga, ba, a);
}
);
#else
NSString *const kGPUImageDivideBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
vec4 base = texture2D(inputImageTexture, textureCoordinate);
vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);
float ra;
if (overlay.a == 0.0 || ((base.r / overlay.r) > (base.a / overlay.a)))
ra = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);
else
ra = (base.r * overlay.a * overlay.a) / overlay.r + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);
float ga;
if (overlay.a == 0.0 || ((base.g / overlay.g) > (base.a / overlay.a)))
ga = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);
else
ga = (base.g * overlay.a * overlay.a) / overlay.g + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);
float ba;
if (overlay.a == 0.0 || ((base.b / overlay.b) > (base.a / overlay.a)))
ba = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);
else
ba = (base.b * overlay.a * overlay.a) / overlay.b + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);
float a = overlay.a + base.a - overlay.a * base.a;
gl_FragColor = vec4(ra, ga, ba, a);
}
);
#endif
@implementation GPUImageDivideBlendFilter
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kGPUImageDivideBlendFragmentShaderString]))
{
return nil;
}
return self;
}
@end
+49
View File
@@ -0,0 +1,49 @@
#import "GPUImageEmbossFilter.h"
@implementation GPUImageEmbossFilter
@synthesize intensity = _intensity;
- (id)init;
{
if (!(self = [super init]))
{
return nil;
}
self.intensity = 1.0;
return self;
}
#pragma mark -
#pragma mark Accessors
- (void)setIntensity:(CGFloat)newValue;
{
// [(GPUImage3x3ConvolutionFilter *)filter setConvolutionMatrix:(GPUMatrix3x3){
// {-2.0f, -1.0f, 0.0f},
// {-1.0f, 1.0f, 1.0f},
// { 0.0f, 1.0f, 2.0f}
// }];
_intensity = newValue;
GPUMatrix3x3 newConvolutionMatrix;
newConvolutionMatrix.one.one = _intensity * (-2.0);
newConvolutionMatrix.one.two = -_intensity;
newConvolutionMatrix.one.three = 0.0f;
newConvolutionMatrix.two.one = -_intensity;
newConvolutionMatrix.two.two = 1.0;
newConvolutionMatrix.two.three = _intensity;
newConvolutionMatrix.three.one = 0.0f;
newConvolutionMatrix.three.two = _intensity;
newConvolutionMatrix.three.three = _intensity * 2.0;
self.convolutionKernel = newConvolutionMatrix;
}
@end

Some files were not shown because too many files have changed in this diff Show More