Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 47f35058f3 | |||
| a1a7e9aeea | |||
| fabae8ddd8 | |||
| 12e1066cae | |||
| 05ca0f4f4b | |||
| 9e536d2291 | |||
| 7bb976d4ae | |||
| 934d3f29ad | |||
| 87b3244ba5 | |||
| 23824e2b74 | |||
| 71d68c3e6e | |||
| d9887180c3 | |||
| 30eac1282c | |||
| 77d6a5b85b | |||
| 73c9adeb71 | |||
| 7dcda23bf4 | |||
| aa4f259edc | |||
| bc5dcef3b7 | |||
| 782b0c3c71 | |||
| 34a2fdd3e2 | |||
| ae128ab66b | |||
| cb164ed1fe | |||
| c40b99c19a | |||
| 2a48333a9a | |||
| 3c0c2eecb8 | |||
| 442f04124d | |||
| c03bd61f37 | |||
| 161c0acd68 | |||
| b7be132a30 | |||
| d30aecc802 | |||
| b612be76bc | |||
| a322e2aa3f | |||
| b0e88e182a | |||
| 3ebd933b6c | |||
| db0814ca4c | |||
| 3a9e0efb73 | |||
| 7bcc82a03e | |||
| 293e021cf6 | |||
| 340ab086d2 | |||
| f025f807f4 | |||
| 90b086c7a3 | |||
| cf56d72598 | |||
| b22f61c4e2 | |||
| 7d1311311c | |||
| a508cecc32 | |||
| 7657d27854 | |||
| 7c3aae8003 | |||
| 8c2596c23e | |||
| 681b1cd107 | |||
| 13094108e3 | |||
| abd55c5511 | |||
| fc52abe7bd | |||
| fa10e28281 | |||
| c624fbe78c | |||
| 19a355e697 | |||
| 7799f0f613 | |||
| ecf3b557cf | |||
| 58d83ed0dc | |||
| b167bda396 | |||
| 336a6e2432 | |||
| 8acddcda90 | |||
| cf2fc51fea | |||
| 2b236b2a35 | |||
| e59699b7fd | |||
| e9f3c66a3b | |||
| dc1dc18824 | |||
| 014e73f44c | |||
| ee7c25727b | |||
| 79f0ba930b | |||
| c5edbfba8e | |||
| 91c689a41f |
+2
-2
@@ -1,7 +1,7 @@
|
||||
language: objective-c
|
||||
osx_image: xcode7
|
||||
xcode_project: LFLiveKit.xcodeproj
|
||||
xcode_project: FrameWork/LFLiveKit.xcodeproj
|
||||
xcode_scheme: LFLiveKit
|
||||
|
||||
script:
|
||||
- xctool -project 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.1</string>
|
||||
<string>2.4.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
@@ -0,0 +1,623 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1F3858C76FA5230BD4B34FEF /* libPods-LFLiveKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D9E53AEC8F2938295308B625 /* libPods-LFLiveKit.a */; };
|
||||
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 */; };
|
||||
84D8B5BB1D768B6E00752B56 /* LFAudioCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5851D768B6E00752B56 /* LFAudioCapture.h */; };
|
||||
84D8B5BC1D768B6E00752B56 /* LFAudioCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5861D768B6E00752B56 /* LFAudioCapture.m */; };
|
||||
84D8B5BD1D768B6E00752B56 /* LFVideoCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5871D768B6E00752B56 /* LFVideoCapture.h */; };
|
||||
84D8B5BE1D768B6E00752B56 /* LFVideoCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5881D768B6E00752B56 /* LFVideoCapture.m */; };
|
||||
84D8B5BF1D768B6E00752B56 /* LFAVEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B58B1D768B6E00752B56 /* LFAVEncoder.h */; };
|
||||
84D8B5C01D768B6E00752B56 /* LFAVEncoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B58C1D768B6E00752B56 /* LFAVEncoder.mm */; };
|
||||
84D8B5C11D768B6E00752B56 /* LFMP4Atom.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B58D1D768B6E00752B56 /* LFMP4Atom.h */; };
|
||||
84D8B5C21D768B6E00752B56 /* LFMP4Atom.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B58E1D768B6E00752B56 /* LFMP4Atom.m */; };
|
||||
84D8B5C31D768B6E00752B56 /* LFNALUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B58F1D768B6E00752B56 /* LFNALUnit.cpp */; };
|
||||
84D8B5C41D768B6E00752B56 /* LFNALUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5901D768B6E00752B56 /* LFNALUnit.h */; };
|
||||
84D8B5C51D768B6E00752B56 /* LFVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5911D768B6E00752B56 /* LFVideoEncoder.h */; };
|
||||
84D8B5C61D768B6E00752B56 /* LFVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5921D768B6E00752B56 /* LFVideoEncoder.m */; };
|
||||
84D8B5C71D768B6E00752B56 /* LFAudioEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5931D768B6E00752B56 /* LFAudioEncoding.h */; };
|
||||
84D8B5C81D768B6E00752B56 /* LFH264VideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5941D768B6E00752B56 /* LFH264VideoEncoder.h */; };
|
||||
84D8B5C91D768B6E00752B56 /* LFH264VideoEncoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5951D768B6E00752B56 /* LFH264VideoEncoder.mm */; };
|
||||
84D8B5CA1D768B6E00752B56 /* LFHardwareAudioEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5961D768B6E00752B56 /* LFHardwareAudioEncoder.h */; };
|
||||
84D8B5CB1D768B6E00752B56 /* LFHardwareAudioEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5971D768B6E00752B56 /* LFHardwareAudioEncoder.m */; };
|
||||
84D8B5CC1D768B6E00752B56 /* LFHardwareVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5981D768B6E00752B56 /* LFHardwareVideoEncoder.h */; };
|
||||
84D8B5CD1D768B6E00752B56 /* LFHardwareVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5991D768B6E00752B56 /* LFHardwareVideoEncoder.m */; };
|
||||
84D8B5CE1D768B6E00752B56 /* LFVideoEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B59A1D768B6E00752B56 /* LFVideoEncoding.h */; };
|
||||
84D8B5CF1D768B6E00752B56 /* LFLiveAudioConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B59C1D768B6E00752B56 /* LFLiveAudioConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84D8B5D01D768B6E00752B56 /* LFLiveAudioConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B59D1D768B6E00752B56 /* LFLiveAudioConfiguration.m */; };
|
||||
84D8B5D11D768B6E00752B56 /* LFLiveVideoConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B59E1D768B6E00752B56 /* LFLiveVideoConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84D8B5D21D768B6E00752B56 /* LFLiveVideoConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B59F1D768B6E00752B56 /* LFLiveVideoConfiguration.m */; };
|
||||
84D8B5D31D768B6E00752B56 /* LFGPUImageBeautyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A11D768B6E00752B56 /* LFGPUImageBeautyFilter.h */; };
|
||||
84D8B5D41D768B6E00752B56 /* LFGPUImageBeautyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5A21D768B6E00752B56 /* LFGPUImageBeautyFilter.m */; };
|
||||
84D8B5D51D768B6E00752B56 /* LFGPUImageEmptyFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A31D768B6E00752B56 /* LFGPUImageEmptyFilter.h */; };
|
||||
84D8B5D61D768B6E00752B56 /* LFGPUImageEmptyFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5A41D768B6E00752B56 /* LFGPUImageEmptyFilter.m */; };
|
||||
84D8B5D71D768B6E00752B56 /* LFLiveKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A51D768B6E00752B56 /* LFLiveKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84D8B5D81D768B6E00752B56 /* LFLiveSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A61D768B6E00752B56 /* LFLiveSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84D8B5D91D768B6E00752B56 /* LFLiveSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5A71D768B6E00752B56 /* LFLiveSession.m */; };
|
||||
84D8B5DA1D768B6E00752B56 /* LFAudioFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5A91D768B6E00752B56 /* LFAudioFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84D8B5DB1D768B6E00752B56 /* LFAudioFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5AA1D768B6E00752B56 /* LFAudioFrame.m */; };
|
||||
84D8B5DC1D768B6E00752B56 /* LFFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5AB1D768B6E00752B56 /* LFFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84D8B5DD1D768B6E00752B56 /* LFFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5AC1D768B6E00752B56 /* LFFrame.m */; };
|
||||
84D8B5DE1D768B6E00752B56 /* LFLiveDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5AD1D768B6E00752B56 /* LFLiveDebug.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84D8B5DF1D768B6E00752B56 /* LFLiveDebug.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5AE1D768B6E00752B56 /* LFLiveDebug.m */; };
|
||||
84D8B5E01D768B6E00752B56 /* LFLiveStreamInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5AF1D768B6E00752B56 /* LFLiveStreamInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84D8B5E11D768B6E00752B56 /* LFLiveStreamInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B01D768B6E00752B56 /* LFLiveStreamInfo.m */; };
|
||||
84D8B5E21D768B6E00752B56 /* LFVideoFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B11D768B6E00752B56 /* LFVideoFrame.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
84D8B5E31D768B6E00752B56 /* LFVideoFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B21D768B6E00752B56 /* LFVideoFrame.m */; };
|
||||
84D8B5E41D768B6E00752B56 /* LFStreamingBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B41D768B6E00752B56 /* LFStreamingBuffer.h */; };
|
||||
84D8B5E51D768B6E00752B56 /* LFStreamingBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B51D768B6E00752B56 /* LFStreamingBuffer.m */; };
|
||||
84D8B5E61D768B6E00752B56 /* LFStreamRTMPSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B61D768B6E00752B56 /* LFStreamRTMPSocket.h */; };
|
||||
84D8B5E71D768B6E00752B56 /* LFStreamRtmpSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5B71D768B6E00752B56 /* LFStreamRtmpSocket.m */; };
|
||||
84D8B5E81D768B6E00752B56 /* LFStreamSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B81D768B6E00752B56 /* LFStreamSocket.h */; };
|
||||
84D8B5E91D768B6E00752B56 /* NSMutableArray+LFAdd.h in Headers */ = {isa = PBXBuildFile; fileRef = 84D8B5B91D768B6E00752B56 /* NSMutableArray+LFAdd.h */; };
|
||||
84D8B5EA1D768B6E00752B56 /* NSMutableArray+LFAdd.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D8B5BA1D768B6E00752B56 /* NSMutableArray+LFAdd.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
7F7E051931BABE0B14FE6A57 /* Pods-LFLiveKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKit/Pods-LFLiveKit.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
84D8B3901D7574D600752B56 /* LFLiveKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LFLiveKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
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; };
|
||||
84D8B5851D768B6E00752B56 /* LFAudioCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioCapture.h; sourceTree = "<group>"; };
|
||||
84D8B5861D768B6E00752B56 /* LFAudioCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFAudioCapture.m; sourceTree = "<group>"; };
|
||||
84D8B5871D768B6E00752B56 /* LFVideoCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoCapture.h; sourceTree = "<group>"; };
|
||||
84D8B5881D768B6E00752B56 /* LFVideoCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoCapture.m; sourceTree = "<group>"; };
|
||||
84D8B58B1D768B6E00752B56 /* LFAVEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAVEncoder.h; sourceTree = "<group>"; };
|
||||
84D8B58C1D768B6E00752B56 /* LFAVEncoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LFAVEncoder.mm; sourceTree = "<group>"; };
|
||||
84D8B58D1D768B6E00752B56 /* LFMP4Atom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFMP4Atom.h; sourceTree = "<group>"; };
|
||||
84D8B58E1D768B6E00752B56 /* LFMP4Atom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFMP4Atom.m; sourceTree = "<group>"; };
|
||||
84D8B58F1D768B6E00752B56 /* LFNALUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LFNALUnit.cpp; sourceTree = "<group>"; };
|
||||
84D8B5901D768B6E00752B56 /* LFNALUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFNALUnit.h; sourceTree = "<group>"; };
|
||||
84D8B5911D768B6E00752B56 /* LFVideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoEncoder.h; sourceTree = "<group>"; };
|
||||
84D8B5921D768B6E00752B56 /* LFVideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoEncoder.m; sourceTree = "<group>"; };
|
||||
84D8B5931D768B6E00752B56 /* LFAudioEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioEncoding.h; sourceTree = "<group>"; };
|
||||
84D8B5941D768B6E00752B56 /* LFH264VideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFH264VideoEncoder.h; sourceTree = "<group>"; };
|
||||
84D8B5951D768B6E00752B56 /* LFH264VideoEncoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = LFH264VideoEncoder.mm; sourceTree = "<group>"; };
|
||||
84D8B5961D768B6E00752B56 /* LFHardwareAudioEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFHardwareAudioEncoder.h; sourceTree = "<group>"; };
|
||||
84D8B5971D768B6E00752B56 /* LFHardwareAudioEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFHardwareAudioEncoder.m; sourceTree = "<group>"; };
|
||||
84D8B5981D768B6E00752B56 /* LFHardwareVideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFHardwareVideoEncoder.h; sourceTree = "<group>"; };
|
||||
84D8B5991D768B6E00752B56 /* LFHardwareVideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFHardwareVideoEncoder.m; sourceTree = "<group>"; };
|
||||
84D8B59A1D768B6E00752B56 /* LFVideoEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoEncoding.h; sourceTree = "<group>"; };
|
||||
84D8B59C1D768B6E00752B56 /* LFLiveAudioConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveAudioConfiguration.h; sourceTree = "<group>"; };
|
||||
84D8B59D1D768B6E00752B56 /* LFLiveAudioConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveAudioConfiguration.m; sourceTree = "<group>"; };
|
||||
84D8B59E1D768B6E00752B56 /* LFLiveVideoConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveVideoConfiguration.h; sourceTree = "<group>"; };
|
||||
84D8B59F1D768B6E00752B56 /* LFLiveVideoConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveVideoConfiguration.m; sourceTree = "<group>"; };
|
||||
84D8B5A11D768B6E00752B56 /* LFGPUImageBeautyFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFGPUImageBeautyFilter.h; sourceTree = "<group>"; };
|
||||
84D8B5A21D768B6E00752B56 /* LFGPUImageBeautyFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFGPUImageBeautyFilter.m; sourceTree = "<group>"; };
|
||||
84D8B5A31D768B6E00752B56 /* LFGPUImageEmptyFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFGPUImageEmptyFilter.h; sourceTree = "<group>"; };
|
||||
84D8B5A41D768B6E00752B56 /* LFGPUImageEmptyFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFGPUImageEmptyFilter.m; sourceTree = "<group>"; };
|
||||
84D8B5A51D768B6E00752B56 /* LFLiveKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveKit.h; sourceTree = "<group>"; };
|
||||
84D8B5A61D768B6E00752B56 /* LFLiveSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveSession.h; sourceTree = "<group>"; };
|
||||
84D8B5A71D768B6E00752B56 /* LFLiveSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveSession.m; sourceTree = "<group>"; };
|
||||
84D8B5A91D768B6E00752B56 /* LFAudioFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFAudioFrame.h; sourceTree = "<group>"; };
|
||||
84D8B5AA1D768B6E00752B56 /* LFAudioFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFAudioFrame.m; sourceTree = "<group>"; };
|
||||
84D8B5AB1D768B6E00752B56 /* LFFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFFrame.h; sourceTree = "<group>"; };
|
||||
84D8B5AC1D768B6E00752B56 /* LFFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFFrame.m; sourceTree = "<group>"; };
|
||||
84D8B5AD1D768B6E00752B56 /* LFLiveDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveDebug.h; sourceTree = "<group>"; };
|
||||
84D8B5AE1D768B6E00752B56 /* LFLiveDebug.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveDebug.m; sourceTree = "<group>"; };
|
||||
84D8B5AF1D768B6E00752B56 /* LFLiveStreamInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFLiveStreamInfo.h; sourceTree = "<group>"; };
|
||||
84D8B5B01D768B6E00752B56 /* LFLiveStreamInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFLiveStreamInfo.m; sourceTree = "<group>"; };
|
||||
84D8B5B11D768B6E00752B56 /* LFVideoFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFVideoFrame.h; sourceTree = "<group>"; };
|
||||
84D8B5B21D768B6E00752B56 /* LFVideoFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFVideoFrame.m; sourceTree = "<group>"; };
|
||||
84D8B5B41D768B6E00752B56 /* LFStreamingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFStreamingBuffer.h; sourceTree = "<group>"; };
|
||||
84D8B5B51D768B6E00752B56 /* LFStreamingBuffer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFStreamingBuffer.m; sourceTree = "<group>"; };
|
||||
84D8B5B61D768B6E00752B56 /* LFStreamRTMPSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFStreamRTMPSocket.h; sourceTree = "<group>"; };
|
||||
84D8B5B71D768B6E00752B56 /* LFStreamRtmpSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFStreamRtmpSocket.m; sourceTree = "<group>"; };
|
||||
84D8B5B81D768B6E00752B56 /* LFStreamSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFStreamSocket.h; sourceTree = "<group>"; };
|
||||
84D8B5B91D768B6E00752B56 /* NSMutableArray+LFAdd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+LFAdd.h"; sourceTree = "<group>"; };
|
||||
84D8B5BA1D768B6E00752B56 /* NSMutableArray+LFAdd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+LFAdd.m"; sourceTree = "<group>"; };
|
||||
BF1D108D206BBD2267CDB4FB /* Pods-LFLiveKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LFLiveKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-LFLiveKit/Pods-LFLiveKit.release.xcconfig"; sourceTree = "<group>"; };
|
||||
D9E53AEC8F2938295308B625 /* libPods-LFLiveKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LFLiveKit.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* 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 */,
|
||||
1F3858C76FA5230BD4B34FEF /* libPods-LFLiveKit.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
84D8B3861D7574D600752B56 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B5831D768B6E00752B56 /* LFLiveKit */,
|
||||
84D8B4CA1D757ED600752B56 /* libz.tbd */,
|
||||
84D8B4C81D757ED100752B56 /* libstdc++.tbd */,
|
||||
84D8B4C61D757ECC00752B56 /* UIKit.framework */,
|
||||
84D8B4C41D757EC800752B56 /* Foundation.framework */,
|
||||
84D8B4C21D757EC400752B56 /* AVFoundation.framework */,
|
||||
84D8B4C01D757EBE00752B56 /* AudioToolbox.framework */,
|
||||
84D8B4BE1D757EB800752B56 /* VideoToolbox.framework */,
|
||||
84D8B3911D7574D600752B56 /* Products */,
|
||||
D77470616157694EC6FD0A0D /* Pods */,
|
||||
9ABACAFFC334034AA0115426 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84D8B3911D7574D600752B56 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B3901D7574D600752B56 /* LFLiveKit.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84D8B5831D768B6E00752B56 /* LFLiveKit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B5841D768B6E00752B56 /* capture */,
|
||||
84D8B5891D768B6E00752B56 /* coder */,
|
||||
84D8B59B1D768B6E00752B56 /* configuration */,
|
||||
84D8B5A01D768B6E00752B56 /* filter */,
|
||||
84D8B5A51D768B6E00752B56 /* LFLiveKit.h */,
|
||||
84D8B5A61D768B6E00752B56 /* LFLiveSession.h */,
|
||||
84D8B5A71D768B6E00752B56 /* LFLiveSession.m */,
|
||||
84D8B5A81D768B6E00752B56 /* objects */,
|
||||
84D8B5B31D768B6E00752B56 /* publish */,
|
||||
);
|
||||
name = LFLiveKit;
|
||||
path = ../LFLiveKit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84D8B5841D768B6E00752B56 /* capture */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B5851D768B6E00752B56 /* LFAudioCapture.h */,
|
||||
84D8B5861D768B6E00752B56 /* LFAudioCapture.m */,
|
||||
84D8B5871D768B6E00752B56 /* LFVideoCapture.h */,
|
||||
84D8B5881D768B6E00752B56 /* LFVideoCapture.m */,
|
||||
);
|
||||
path = capture;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84D8B5891D768B6E00752B56 /* coder */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B58A1D768B6E00752B56 /* H264 */,
|
||||
84D8B5931D768B6E00752B56 /* LFAudioEncoding.h */,
|
||||
84D8B5941D768B6E00752B56 /* LFH264VideoEncoder.h */,
|
||||
84D8B5951D768B6E00752B56 /* LFH264VideoEncoder.mm */,
|
||||
84D8B5961D768B6E00752B56 /* LFHardwareAudioEncoder.h */,
|
||||
84D8B5971D768B6E00752B56 /* LFHardwareAudioEncoder.m */,
|
||||
84D8B5981D768B6E00752B56 /* LFHardwareVideoEncoder.h */,
|
||||
84D8B5991D768B6E00752B56 /* LFHardwareVideoEncoder.m */,
|
||||
84D8B59A1D768B6E00752B56 /* LFVideoEncoding.h */,
|
||||
);
|
||||
path = coder;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84D8B58A1D768B6E00752B56 /* H264 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B58B1D768B6E00752B56 /* LFAVEncoder.h */,
|
||||
84D8B58C1D768B6E00752B56 /* LFAVEncoder.mm */,
|
||||
84D8B58D1D768B6E00752B56 /* LFMP4Atom.h */,
|
||||
84D8B58E1D768B6E00752B56 /* LFMP4Atom.m */,
|
||||
84D8B58F1D768B6E00752B56 /* LFNALUnit.cpp */,
|
||||
84D8B5901D768B6E00752B56 /* LFNALUnit.h */,
|
||||
84D8B5911D768B6E00752B56 /* LFVideoEncoder.h */,
|
||||
84D8B5921D768B6E00752B56 /* LFVideoEncoder.m */,
|
||||
);
|
||||
path = H264;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84D8B59B1D768B6E00752B56 /* configuration */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B59C1D768B6E00752B56 /* LFLiveAudioConfiguration.h */,
|
||||
84D8B59D1D768B6E00752B56 /* LFLiveAudioConfiguration.m */,
|
||||
84D8B59E1D768B6E00752B56 /* LFLiveVideoConfiguration.h */,
|
||||
84D8B59F1D768B6E00752B56 /* LFLiveVideoConfiguration.m */,
|
||||
);
|
||||
path = configuration;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84D8B5A01D768B6E00752B56 /* filter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B5A11D768B6E00752B56 /* LFGPUImageBeautyFilter.h */,
|
||||
84D8B5A21D768B6E00752B56 /* LFGPUImageBeautyFilter.m */,
|
||||
84D8B5A31D768B6E00752B56 /* LFGPUImageEmptyFilter.h */,
|
||||
84D8B5A41D768B6E00752B56 /* LFGPUImageEmptyFilter.m */,
|
||||
);
|
||||
path = filter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84D8B5A81D768B6E00752B56 /* objects */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B5A91D768B6E00752B56 /* LFAudioFrame.h */,
|
||||
84D8B5AA1D768B6E00752B56 /* LFAudioFrame.m */,
|
||||
84D8B5AB1D768B6E00752B56 /* LFFrame.h */,
|
||||
84D8B5AC1D768B6E00752B56 /* LFFrame.m */,
|
||||
84D8B5AD1D768B6E00752B56 /* LFLiveDebug.h */,
|
||||
84D8B5AE1D768B6E00752B56 /* LFLiveDebug.m */,
|
||||
84D8B5AF1D768B6E00752B56 /* LFLiveStreamInfo.h */,
|
||||
84D8B5B01D768B6E00752B56 /* LFLiveStreamInfo.m */,
|
||||
84D8B5B11D768B6E00752B56 /* LFVideoFrame.h */,
|
||||
84D8B5B21D768B6E00752B56 /* LFVideoFrame.m */,
|
||||
);
|
||||
path = objects;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
84D8B5B31D768B6E00752B56 /* publish */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84D8B5B41D768B6E00752B56 /* LFStreamingBuffer.h */,
|
||||
84D8B5B51D768B6E00752B56 /* LFStreamingBuffer.m */,
|
||||
84D8B5B61D768B6E00752B56 /* LFStreamRTMPSocket.h */,
|
||||
84D8B5B71D768B6E00752B56 /* LFStreamRtmpSocket.m */,
|
||||
84D8B5B81D768B6E00752B56 /* LFStreamSocket.h */,
|
||||
84D8B5B91D768B6E00752B56 /* NSMutableArray+LFAdd.h */,
|
||||
84D8B5BA1D768B6E00752B56 /* NSMutableArray+LFAdd.m */,
|
||||
);
|
||||
path = publish;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9ABACAFFC334034AA0115426 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D9E53AEC8F2938295308B625 /* libPods-LFLiveKit.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D77470616157694EC6FD0A0D /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7F7E051931BABE0B14FE6A57 /* Pods-LFLiveKit.debug.xcconfig */,
|
||||
BF1D108D206BBD2267CDB4FB /* Pods-LFLiveKit.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
84D8B38D1D7574D600752B56 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
84D8B5DE1D768B6E00752B56 /* LFLiveDebug.h in Headers */,
|
||||
84D8B5CF1D768B6E00752B56 /* LFLiveAudioConfiguration.h in Headers */,
|
||||
84D8B5DA1D768B6E00752B56 /* LFAudioFrame.h in Headers */,
|
||||
84D8B5E01D768B6E00752B56 /* LFLiveStreamInfo.h in Headers */,
|
||||
84D8B5D11D768B6E00752B56 /* LFLiveVideoConfiguration.h in Headers */,
|
||||
84D8B5DC1D768B6E00752B56 /* LFFrame.h in Headers */,
|
||||
84D8B5D71D768B6E00752B56 /* LFLiveKit.h in Headers */,
|
||||
84D8B5D81D768B6E00752B56 /* LFLiveSession.h in Headers */,
|
||||
84D8B5E21D768B6E00752B56 /* LFVideoFrame.h in Headers */,
|
||||
84D8B5BB1D768B6E00752B56 /* LFAudioCapture.h in Headers */,
|
||||
84D8B5E61D768B6E00752B56 /* LFStreamRTMPSocket.h in Headers */,
|
||||
84D8B5C11D768B6E00752B56 /* LFMP4Atom.h in Headers */,
|
||||
84D8B5D31D768B6E00752B56 /* LFGPUImageBeautyFilter.h in Headers */,
|
||||
84D8B5BF1D768B6E00752B56 /* LFAVEncoder.h in Headers */,
|
||||
84D8B5C51D768B6E00752B56 /* LFVideoEncoder.h in Headers */,
|
||||
84D8B5D51D768B6E00752B56 /* LFGPUImageEmptyFilter.h in Headers */,
|
||||
84D8B5C71D768B6E00752B56 /* LFAudioEncoding.h in Headers */,
|
||||
84D8B5E91D768B6E00752B56 /* NSMutableArray+LFAdd.h in Headers */,
|
||||
84D8B5CC1D768B6E00752B56 /* LFHardwareVideoEncoder.h in Headers */,
|
||||
84D8B5BD1D768B6E00752B56 /* LFVideoCapture.h in Headers */,
|
||||
84D8B5E81D768B6E00752B56 /* LFStreamSocket.h in Headers */,
|
||||
84D8B5C41D768B6E00752B56 /* LFNALUnit.h in Headers */,
|
||||
84D8B5CA1D768B6E00752B56 /* LFHardwareAudioEncoder.h in Headers */,
|
||||
84D8B5CE1D768B6E00752B56 /* LFVideoEncoding.h in Headers */,
|
||||
84D8B5E41D768B6E00752B56 /* LFStreamingBuffer.h in Headers */,
|
||||
84D8B5C81D768B6E00752B56 /* 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 = (
|
||||
2833F857062C89FFF3975A1B /* 📦 Check Pods Manifest.lock */,
|
||||
84D8B38B1D7574D600752B56 /* Sources */,
|
||||
84D8B38C1D7574D600752B56 /* Frameworks */,
|
||||
84D8B38D1D7574D600752B56 /* Headers */,
|
||||
84D8B38E1D7574D600752B56 /* Resources */,
|
||||
D64BB080ABC44A32A8D6E2CF /* 📦 Copy Pods 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 PBXShellScriptBuildPhase section */
|
||||
2833F857062C89FFF3975A1B /* 📦 Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "📦 Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
D64BB080ABC44A32A8D6E2CF /* 📦 Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "📦 Copy Pods Resources";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-LFLiveKit/Pods-LFLiveKit-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
84D8B38B1D7574D600752B56 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
84D8B5D41D768B6E00752B56 /* LFGPUImageBeautyFilter.m in Sources */,
|
||||
84D8B5DD1D768B6E00752B56 /* LFFrame.m in Sources */,
|
||||
84D8B5DF1D768B6E00752B56 /* LFLiveDebug.m in Sources */,
|
||||
84D8B5BE1D768B6E00752B56 /* LFVideoCapture.m in Sources */,
|
||||
84D8B5DB1D768B6E00752B56 /* LFAudioFrame.m in Sources */,
|
||||
84D8B5E11D768B6E00752B56 /* LFLiveStreamInfo.m in Sources */,
|
||||
84D8B5C31D768B6E00752B56 /* LFNALUnit.cpp in Sources */,
|
||||
84D8B5C01D768B6E00752B56 /* LFAVEncoder.mm in Sources */,
|
||||
84D8B5C21D768B6E00752B56 /* LFMP4Atom.m in Sources */,
|
||||
84D8B5D21D768B6E00752B56 /* LFLiveVideoConfiguration.m in Sources */,
|
||||
84D8B5C61D768B6E00752B56 /* LFVideoEncoder.m in Sources */,
|
||||
84D8B5D61D768B6E00752B56 /* LFGPUImageEmptyFilter.m in Sources */,
|
||||
84D8B5D91D768B6E00752B56 /* LFLiveSession.m in Sources */,
|
||||
84D8B5E71D768B6E00752B56 /* LFStreamRtmpSocket.m in Sources */,
|
||||
84D8B5D01D768B6E00752B56 /* LFLiveAudioConfiguration.m in Sources */,
|
||||
84D8B5CB1D768B6E00752B56 /* LFHardwareAudioEncoder.m in Sources */,
|
||||
84D8B5C91D768B6E00752B56 /* LFH264VideoEncoder.mm in Sources */,
|
||||
84D8B5E51D768B6E00752B56 /* LFStreamingBuffer.m in Sources */,
|
||||
84D8B5CD1D768B6E00752B56 /* LFHardwareVideoEncoder.m in Sources */,
|
||||
84D8B5E31D768B6E00752B56 /* LFVideoFrame.m in Sources */,
|
||||
84D8B5BC1D768B6E00752B56 /* LFAudioCapture.m in Sources */,
|
||||
84D8B5EA1D768B6E00752B56 /* 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;
|
||||
baseConfigurationReference = 7F7E051931BABE0B14FE6A57 /* Pods-LFLiveKit.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
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";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
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;
|
||||
baseConfigurationReference = BF1D108D206BBD2267CDB4FB /* Pods-LFLiveKit.release.xcconfig */;
|
||||
buildSettings = {
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
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";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
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 */;
|
||||
}
|
||||
+17
-28
@@ -14,10 +14,10 @@
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B2D23E791D348F3D00B34CA8"
|
||||
BuildableName = "LFLiveKitDemo.app"
|
||||
BlueprintName = "LFLiveKitDemo"
|
||||
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
|
||||
BlueprintIdentifier = "84D8B38F1D7574D600752B56"
|
||||
BuildableName = "LFLiveKit.framework"
|
||||
BlueprintName = "LFLiveKit"
|
||||
ReferencedContainer = "container:LFLiveKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
@@ -29,20 +29,11 @@
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B2D23E791D348F3D00B34CA8"
|
||||
BuildableName = "LFLiveKitDemo.app"
|
||||
BlueprintName = "LFLiveKitDemo"
|
||||
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
@@ -51,16 +42,15 @@
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "B2D23E791D348F3D00B34CA8"
|
||||
BuildableName = "LFLiveKitDemo.app"
|
||||
BlueprintName = "LFLiveKitDemo"
|
||||
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
|
||||
BlueprintIdentifier = "84D8B38F1D7574D600752B56"
|
||||
BuildableName = "LFLiveKit.framework"
|
||||
BlueprintName = "LFLiveKit"
|
||||
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 = "B2D23E791D348F3D00B34CA8"
|
||||
BuildableName = "LFLiveKitDemo.app"
|
||||
BlueprintName = "LFLiveKitDemo"
|
||||
ReferencedContainer = "container:LFLiveKitDemo.xcodeproj">
|
||||
BlueprintIdentifier = "84D8B38F1D7574D600752B56"
|
||||
BuildableName = "LFLiveKit.framework"
|
||||
BlueprintName = "LFLiveKit"
|
||||
ReferencedContainer = "container:LFLiveKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
@@ -0,0 +1,7 @@
|
||||
source 'https://github.com/CocoaPods/Specs.git'
|
||||
platform :ios,'7.0'
|
||||
|
||||
target “LFLiveKit” do
|
||||
pod 'pili-librtmp', '~> 1.0.3.1'
|
||||
pod 'LMGPUImage'
|
||||
end
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
Pod::Spec.new do |s|
|
||||
|
||||
s.name = "LFLiveKit"
|
||||
s.version = "2.1"
|
||||
s.version = "2.4.2"
|
||||
s.summary = "LaiFeng ios Live. LFLiveKit."
|
||||
s.homepage = "https://github.com/chenliming777"
|
||||
s.license = { :type => "MIT", :file => "LICENSE" }
|
||||
@@ -11,12 +11,12 @@ 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/**/*.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.dependency 'LMGPUImage'
|
||||
s.dependency 'pili-librtmp', '1.0.3.1'
|
||||
end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:LFLiveKit.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
Generated
BIN
Binary file not shown.
Generated
BIN
Binary file not shown.
@@ -1,155 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "48F687CDE9990BD471D7883061F7E5D4"
|
||||
BuildableName = "libCocoaAsyncSocket.a"
|
||||
BlueprintName = "CocoaAsyncSocket"
|
||||
ReferencedContainer = "container:Pods/Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "6610362E50A6DE8BACCA1F2885CD9157"
|
||||
BuildableName = "libGPUImage.a"
|
||||
BlueprintName = "GPUImage"
|
||||
ReferencedContainer = "container:Pods/Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7C2BDDF89D4243C7BCA44592D146DEED"
|
||||
BuildableName = "libPods-LFLiveKit.a"
|
||||
BlueprintName = "Pods-LFLiveKit"
|
||||
ReferencedContainer = "container:Pods/Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "84001F891D0015D10026C63F"
|
||||
BuildableName = "LFLiveKit.framework"
|
||||
BlueprintName = "LFLiveKit"
|
||||
ReferencedContainer = "container:LFLiveKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "84001F931D0015D10026C63F"
|
||||
BuildableName = "LFLiveKitTests.xctest"
|
||||
BlueprintName = "LFLiveKitTests"
|
||||
ReferencedContainer = "container:LFLiveKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "84001F931D0015D10026C63F"
|
||||
BuildableName = "LFLiveKitTests.xctest"
|
||||
BlueprintName = "LFLiveKitTests"
|
||||
ReferencedContainer = "container:LFLiveKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "84001F891D0015D10026C63F"
|
||||
BuildableName = "LFLiveKit.framework"
|
||||
BlueprintName = "LFLiveKit"
|
||||
ReferencedContainer = "container:LFLiveKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<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 = "84001F891D0015D10026C63F"
|
||||
BuildableName = "LFLiveKit.framework"
|
||||
BlueprintName = "LFLiveKit"
|
||||
ReferencedContainer = "container:LFLiveKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "84001F891D0015D10026C63F"
|
||||
BuildableName = "LFLiveKit.framework"
|
||||
BlueprintName = "LFLiveKit"
|
||||
ReferencedContainer = "container:LFLiveKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,27 +0,0 @@
|
||||
<?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>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>LFLiveKit.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>84001F891D0015D10026C63F</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>84001F931D0015D10026C63F</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?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>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>84001F891D0015D10026C63F</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>84001F931D0015D10026C63F</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
+15
-2
@@ -2,10 +2,20 @@
|
||||
// LFLiveKit.h
|
||||
// LFLiveKit
|
||||
//
|
||||
// Created by admin on 16/5/24.
|
||||
// Copyright © 2016年 admin. All rights reserved.
|
||||
// Created by LaiFeng on 16/5/20.
|
||||
// Copyright © 2016年 LaiFeng All rights reserved.
|
||||
//
|
||||
|
||||
#if __has_include(<LFLiveKit/LFLiveKit.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>
|
||||
#else
|
||||
#import "LFLiveSession.h"
|
||||
#import "LFLiveAudioConfiguration.h"
|
||||
#import "LFLiveVideoConfiguration.h"
|
||||
@@ -13,3 +23,6 @@
|
||||
#import "LFFrame.h"
|
||||
#import "LFLiveStreamInfo.h"
|
||||
#import "LFVideoFrame.h"
|
||||
#import "LFLiveDebug.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,12 +2,21 @@
|
||||
// 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>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#if __has_include(<LFLiveKit/LFLiveKit.h>)
|
||||
#import <LFLiveKit/LFLiveStreamInfo.h>
|
||||
#import <LFLiveKit/LFAudioFrame.h>
|
||||
#import <LFLiveKit/LFVideoFrame.h>
|
||||
#import <LFLiveKit/LFLiveAudioConfiguration.h>
|
||||
#import <LFLiveKit/LFLiveVideoConfiguration.h>
|
||||
#import <LFLiveKit/LFLiveDebug.h>
|
||||
#else
|
||||
#import "LFLiveStreamInfo.h"
|
||||
#import "LFAudioFrame.h"
|
||||
#import "LFVideoFrame.h"
|
||||
@@ -15,6 +24,10 @@
|
||||
#import "LFLiveVideoConfiguration.h"
|
||||
#import "LFLiveDebug.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef NS_ENUM(NSInteger,LFLiveCaptureType) {
|
||||
LFLiveCaptureAudio, //< capture only audio
|
||||
LFLiveCaptureVideo, //< capture onlt video
|
||||
@@ -113,7 +126,16 @@ typedef NS_ENUM(NSInteger,LFLiveCaptureTypeMask) {
|
||||
/*** The warterMarkView control whether the watermark is displayed or not ,if set ni,will remove watermark,otherwise add.
|
||||
set alpha represent mix.Position relative to outVideoSize.
|
||||
*.*/
|
||||
@property (nonatomic, strong) UIView *warterMarkView;
|
||||
@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
|
||||
///=============================================================================
|
||||
@@ -126,7 +148,7 @@ typedef NS_ENUM(NSInteger,LFLiveCaptureTypeMask) {
|
||||
The designated initializer. Multiple instances with the same configuration will make the
|
||||
capture unstable.
|
||||
*/
|
||||
- (nullable instancetype)initWithAudioConfiguration:(nullable LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(nullable LFLiveVideoConfiguration *)videoConfiguration NS_DESIGNATED_INITIALIZER;
|
||||
- (nullable instancetype)initWithAudioConfiguration:(nullable LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(nullable LFLiveVideoConfiguration *)videoConfiguration;
|
||||
|
||||
/**
|
||||
The designated initializer. Multiple instances with the same configuration will make the
|
||||
@@ -141,10 +163,10 @@ typedef NS_ENUM(NSInteger,LFLiveCaptureTypeMask) {
|
||||
- (void)stopLive;
|
||||
|
||||
/** support outer input yuv or rgb video(set LFLiveCaptureTypeMask) .*/
|
||||
- (void)pushVideo:(CVPixelBufferRef)pixelBuffer;
|
||||
- (void)pushVideo:(nullable CVPixelBufferRef)pixelBuffer;
|
||||
|
||||
/** support outer input pcm audio(set LFLiveCaptureTypeMask) .*/
|
||||
- (void)pushAudio:(AudioBufferList)audioBufferList;
|
||||
- (void)pushAudio:(nullable NSData*)audioData;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
+79
-31
@@ -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"
|
||||
@@ -47,10 +47,10 @@
|
||||
@property (nonatomic, assign, readwrite) LFLiveState state;
|
||||
/// 当前直播type
|
||||
@property (nonatomic, assign, readwrite) LFLiveCaptureTypeMask captureType;
|
||||
|
||||
/// 时间戳锁
|
||||
@property (nonatomic, strong) dispatch_semaphore_t lock;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
/** 时间戳 */
|
||||
@@ -59,16 +59,21 @@
|
||||
|
||||
@interface LFLiveSession ()
|
||||
|
||||
@property (nonatomic, assign) uint64_t timestamp;
|
||||
@property (nonatomic, assign) BOOL isFirstFrame;
|
||||
@property (nonatomic, assign) uint64_t currentTimestamp;
|
||||
/// 上传相对时间戳
|
||||
@property (nonatomic, assign) uint64_t relativeTimestamps;
|
||||
/// 音视频是否对齐
|
||||
@property (nonatomic, assign) BOOL AVAlignment;
|
||||
/// 当前是否采集到了音频
|
||||
@property (nonatomic, assign) BOOL hasCaptureAudio;
|
||||
/// 当前是否采集到了关键帧
|
||||
@property (nonatomic, assign) BOOL hasKeyFrameVideo;
|
||||
|
||||
@end
|
||||
|
||||
@implementation LFLiveSession
|
||||
|
||||
#pragma mark -- LifeCycle
|
||||
- (instancetype)initWithAudioConfiguration:(LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(LFLiveVideoConfiguration *)videoConfiguration {
|
||||
- (instancetype)initWithAudioConfiguration:(nullable LFLiveAudioConfiguration *)audioConfiguration videoConfiguration:(nullable LFLiveVideoConfiguration *)videoConfiguration {
|
||||
return [self initWithAudioConfiguration:audioConfiguration videoConfiguration:videoConfiguration captureType:LFLiveCaptureDefaultMask];
|
||||
}
|
||||
|
||||
@@ -79,15 +84,14 @@
|
||||
_audioConfiguration = audioConfiguration;
|
||||
_videoConfiguration = videoConfiguration;
|
||||
_adaptiveBitrate = NO;
|
||||
_isFirstFrame = YES;
|
||||
_captureType = captureType;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
self.videoCaptureSource.running = NO;
|
||||
self.audioCaptureSource.running = NO;
|
||||
_videoCaptureSource.running = NO;
|
||||
_audioCaptureSource.running = NO;
|
||||
}
|
||||
|
||||
#pragma mark -- CustomMethod
|
||||
@@ -96,7 +100,6 @@
|
||||
_streamInfo = streamInfo;
|
||||
_streamInfo.videoConfiguration = _videoConfiguration;
|
||||
_streamInfo.audioConfiguration = _audioConfiguration;
|
||||
_streamInfo.needDropFrame = (self.captureType & LFLiveCaptureMaskVideo || self.captureType & LFLiveInputMaskVideo) ? YES : NO;//< 有视频执行丢帧算法
|
||||
[self.socket start];
|
||||
}
|
||||
|
||||
@@ -106,42 +109,61 @@
|
||||
self.socket = nil;
|
||||
}
|
||||
|
||||
- (void)pushVideo:(CVPixelBufferRef)pixelBuffer{
|
||||
- (void)pushVideo:(nullable CVPixelBufferRef)pixelBuffer{
|
||||
if(self.captureType & LFLiveInputMaskVideo){
|
||||
if (self.uploading) [self.videoEncoder encodeVideoData:pixelBuffer timeStamp:self.currentTimestamp];
|
||||
if (self.uploading) [self.videoEncoder encodeVideoData:pixelBuffer timeStamp:NOW];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pushAudio:(AudioBufferList)audioBufferList{
|
||||
- (void)pushAudio:(nullable NSData*)audioData{
|
||||
if(self.captureType & LFLiveInputMaskAudio){
|
||||
if (self.uploading) [self.audioEncoder encodeAudioData:audioBufferList timeStamp:self.currentTimestamp];
|
||||
if (self.uploading) [self.audioEncoder encodeAudioData:audioData timeStamp:NOW];
|
||||
}
|
||||
}
|
||||
|
||||
#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 audioBuffer:(AudioBufferList)inBufferList {
|
||||
if (self.uploading) [self.audioEncoder encodeAudioData:inBufferList timeStamp:self.currentTimestamp];
|
||||
- (void)captureOutput:(nullable LFAudioCapture *)capture audioData:(nullable NSData*)audioData {
|
||||
if (self.uploading) [self.audioEncoder encodeAudioData:audioData timeStamp:NOW];
|
||||
}
|
||||
|
||||
- (void)captureOutput:(nullable LFVideoCapture *)capture pixelBuffer:(nullable CVPixelBufferRef)pixelBuffer {
|
||||
if (self.uploading) [self.videoEncoder encodeVideoData:pixelBuffer timeStamp:self.currentTimestamp];
|
||||
if (self.uploading) [self.videoEncoder encodeVideoData:pixelBuffer timeStamp:NOW];
|
||||
}
|
||||
|
||||
#pragma mark -- EncoderDelegate
|
||||
- (void)audioEncoder:(nullable id<LFAudioEncoding>)encoder audioFrame:(nullable LFAudioFrame *)frame {
|
||||
if (self.uploading) [self.socket sendFrame:frame]; //<上传
|
||||
//<上传 时间戳对齐
|
||||
if (self.uploading){
|
||||
self.hasCaptureAudio = YES;
|
||||
if(self.AVAlignment) [self pushSendBuffer:frame];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)videoEncoder:(nullable id<LFVideoEncoding>)encoder videoFrame:(nullable LFVideoFrame *)frame {
|
||||
if (self.uploading) [self.socket sendFrame:frame]; //<上传
|
||||
//<上传 时间戳对齐
|
||||
if (self.uploading){
|
||||
if(frame.isKeyFrame && self.hasCaptureAudio) self.hasKeyFrameVideo = YES;
|
||||
if(self.AVAlignment) [self pushSendBuffer:frame];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -- LFStreamTcpSocketDelegate
|
||||
- (void)socketStatus:(nullable id<LFStreamSocket>)socket status:(LFLiveState)status {
|
||||
if (status == LFLiveStart) {
|
||||
if (!self.uploading) {
|
||||
self.timestamp = 0;
|
||||
self.isFirstFrame = YES;
|
||||
self.AVAlignment = NO;
|
||||
self.hasCaptureAudio = NO;
|
||||
self.hasKeyFrameVideo = NO;
|
||||
self.relativeTimestamps = 0;
|
||||
self.uploading = YES;
|
||||
}
|
||||
} else if(status == LFLiveStop || status == LFLiveError){
|
||||
@@ -229,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;
|
||||
}
|
||||
@@ -297,10 +336,14 @@
|
||||
[self.videoCaptureSource setWarterMarkView:warterMarkView];
|
||||
}
|
||||
|
||||
- (UIView*)warterMarkView{
|
||||
- (nullable UIView*)warterMarkView{
|
||||
return self.videoCaptureSource.warterMarkView;
|
||||
}
|
||||
|
||||
- (nullable UIImage *)currentImage{
|
||||
return self.videoCaptureSource.currentImage;
|
||||
}
|
||||
|
||||
- (LFAudioCapture *)audioCaptureSource {
|
||||
if (!_audioCaptureSource) {
|
||||
if(self.captureType & LFLiveCaptureMaskAudio){
|
||||
@@ -363,18 +406,23 @@
|
||||
return _lock;
|
||||
}
|
||||
|
||||
- (uint64_t)currentTimestamp {
|
||||
- (uint64_t)uploadTimestamp:(uint64_t)captureTimestamp{
|
||||
dispatch_semaphore_wait(self.lock, DISPATCH_TIME_FOREVER);
|
||||
uint64_t currentts = 0;
|
||||
if (_isFirstFrame) {
|
||||
_timestamp = NOW;
|
||||
_isFirstFrame = NO;
|
||||
currentts = 0;
|
||||
} else {
|
||||
currentts = NOW - _timestamp;
|
||||
}
|
||||
currentts = captureTimestamp - self.relativeTimestamps;
|
||||
dispatch_semaphore_signal(self.lock);
|
||||
return currentts;
|
||||
}
|
||||
|
||||
- (BOOL)AVAlignment{
|
||||
if((self.captureType & LFLiveCaptureMaskAudio || self.captureType & LFLiveInputMaskAudio) &&
|
||||
(self.captureType & LFLiveCaptureMaskVideo || self.captureType & LFLiveInputMaskVideo)
|
||||
){
|
||||
if(self.hasCaptureAudio && self.hasKeyFrameVideo) return YES;
|
||||
else return NO;
|
||||
}else{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
// 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
|
||||
// I've extended this to be able to take programs as NSStrings in addition to files, for baked-in shaders
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
|
||||
#import <OpenGLES/ES2/gl.h>
|
||||
#import <OpenGLES/ES2/glext.h>
|
||||
#else
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import <OpenGL/gl.h>
|
||||
#endif
|
||||
|
||||
@interface GLProgram : NSObject
|
||||
{
|
||||
NSMutableArray *attributes;
|
||||
NSMutableArray *uniforms;
|
||||
GLuint program,
|
||||
vertShader,
|
||||
fragShader;
|
||||
}
|
||||
|
||||
@property(readwrite, nonatomic) BOOL initialized;
|
||||
@property(readwrite, copy, nonatomic) NSString *vertexShaderLog;
|
||||
@property(readwrite, copy, nonatomic) NSString *fragmentShaderLog;
|
||||
@property(readwrite, copy, nonatomic) NSString *programLog;
|
||||
|
||||
- (id)initWithVertexShaderString:(NSString *)vShaderString
|
||||
fragmentShaderString:(NSString *)fShaderString;
|
||||
- (id)initWithVertexShaderString:(NSString *)vShaderString
|
||||
fragmentShaderFilename:(NSString *)fShaderFilename;
|
||||
- (id)initWithVertexShaderFilename:(NSString *)vShaderFilename
|
||||
fragmentShaderFilename:(NSString *)fShaderFilename;
|
||||
- (void)addAttribute:(NSString *)attributeName;
|
||||
- (GLuint)attributeIndex:(NSString *)attributeName;
|
||||
- (GLuint)uniformIndex:(NSString *)uniformName;
|
||||
- (BOOL)link;
|
||||
- (void)use;
|
||||
- (void)validate;
|
||||
@end
|
||||
-236
@@ -1,236 +0,0 @@
|
||||
// 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
|
||||
Vendored
-170
@@ -1,170 +0,0 @@
|
||||
#import "GLProgram.h"
|
||||
|
||||
// Base classes
|
||||
#import "GPUImageContext.h"
|
||||
#import "GPUImageOutput.h"
|
||||
#import "GPUImageView.h"
|
||||
#import "GPUImageVideoCamera.h"
|
||||
#import "GPUImageStillCamera.h"
|
||||
#import "GPUImageMovie.h"
|
||||
#import "GPUImagePicture.h"
|
||||
#import "GPUImageRawDataInput.h"
|
||||
#import "GPUImageRawDataOutput.h"
|
||||
#import "GPUImageMovieWriter.h"
|
||||
#import "GPUImageFilterPipeline.h"
|
||||
#import "GPUImageTextureOutput.h"
|
||||
#import "GPUImageFilterGroup.h"
|
||||
#import "GPUImageTextureInput.h"
|
||||
#import "GPUImageUIElement.h"
|
||||
#import "GPUImageBuffer.h"
|
||||
#import "GPUImageFramebuffer.h"
|
||||
#import "GPUImageFramebufferCache.h"
|
||||
|
||||
// Filters
|
||||
#import "GPUImageFilter.h"
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
#import "GPUImagePixellateFilter.h"
|
||||
#import "GPUImagePixellatePositionFilter.h"
|
||||
#import "GPUImageSepiaFilter.h"
|
||||
#import "GPUImageColorInvertFilter.h"
|
||||
#import "GPUImageSaturationFilter.h"
|
||||
#import "GPUImageContrastFilter.h"
|
||||
#import "GPUImageExposureFilter.h"
|
||||
#import "GPUImageBrightnessFilter.h"
|
||||
#import "GPUImageLevelsFilter.h"
|
||||
#import "GPUImageSharpenFilter.h"
|
||||
#import "GPUImageGammaFilter.h"
|
||||
#import "GPUImageSobelEdgeDetectionFilter.h"
|
||||
#import "GPUImageSketchFilter.h"
|
||||
#import "GPUImageToonFilter.h"
|
||||
#import "GPUImageSmoothToonFilter.h"
|
||||
#import "GPUImageMultiplyBlendFilter.h"
|
||||
#import "GPUImageDissolveBlendFilter.h"
|
||||
#import "GPUImageKuwaharaFilter.h"
|
||||
#import "GPUImageKuwaharaRadius3Filter.h"
|
||||
#import "GPUImageVignetteFilter.h"
|
||||
#import "GPUImageGaussianBlurFilter.h"
|
||||
#import "GPUImageGaussianBlurPositionFilter.h"
|
||||
#import "GPUImageGaussianSelectiveBlurFilter.h"
|
||||
#import "GPUImageOverlayBlendFilter.h"
|
||||
#import "GPUImageDarkenBlendFilter.h"
|
||||
#import "GPUImageLightenBlendFilter.h"
|
||||
#import "GPUImageSwirlFilter.h"
|
||||
#import "GPUImageSourceOverBlendFilter.h"
|
||||
#import "GPUImageColorBurnBlendFilter.h"
|
||||
#import "GPUImageColorDodgeBlendFilter.h"
|
||||
#import "GPUImageScreenBlendFilter.h"
|
||||
#import "GPUImageExclusionBlendFilter.h"
|
||||
#import "GPUImageDifferenceBlendFilter.h"
|
||||
#import "GPUImageSubtractBlendFilter.h"
|
||||
#import "GPUImageHardLightBlendFilter.h"
|
||||
#import "GPUImageSoftLightBlendFilter.h"
|
||||
#import "GPUImageColorBlendFilter.h"
|
||||
#import "GPUImageHueBlendFilter.h"
|
||||
#import "GPUImageSaturationBlendFilter.h"
|
||||
#import "GPUImageLuminosityBlendFilter.h"
|
||||
#import "GPUImageCropFilter.h"
|
||||
#import "GPUImageGrayscaleFilter.h"
|
||||
#import "GPUImageTransformFilter.h"
|
||||
#import "GPUImageChromaKeyBlendFilter.h"
|
||||
#import "GPUImageHazeFilter.h"
|
||||
#import "GPUImageLuminanceThresholdFilter.h"
|
||||
#import "GPUImagePosterizeFilter.h"
|
||||
#import "GPUImageBoxBlurFilter.h"
|
||||
#import "GPUImageAdaptiveThresholdFilter.h"
|
||||
#import "GPUImageSolarizeFilter.h"
|
||||
#import "GPUImageUnsharpMaskFilter.h"
|
||||
#import "GPUImageBulgeDistortionFilter.h"
|
||||
#import "GPUImagePinchDistortionFilter.h"
|
||||
#import "GPUImageCrosshatchFilter.h"
|
||||
#import "GPUImageCGAColorspaceFilter.h"
|
||||
#import "GPUImagePolarPixellateFilter.h"
|
||||
#import "GPUImageStretchDistortionFilter.h"
|
||||
#import "GPUImagePerlinNoiseFilter.h"
|
||||
#import "GPUImageJFAVoronoiFilter.h"
|
||||
#import "GPUImageVoronoiConsumerFilter.h"
|
||||
#import "GPUImageMosaicFilter.h"
|
||||
#import "GPUImageTiltShiftFilter.h"
|
||||
#import "GPUImage3x3ConvolutionFilter.h"
|
||||
#import "GPUImageEmbossFilter.h"
|
||||
#import "GPUImageCannyEdgeDetectionFilter.h"
|
||||
#import "GPUImageThresholdEdgeDetectionFilter.h"
|
||||
#import "GPUImageMaskFilter.h"
|
||||
#import "GPUImageHistogramFilter.h"
|
||||
#import "GPUImageHistogramGenerator.h"
|
||||
#import "GPUImageHistogramEqualizationFilter.h"
|
||||
#import "GPUImagePrewittEdgeDetectionFilter.h"
|
||||
#import "GPUImageXYDerivativeFilter.h"
|
||||
#import "GPUImageHarrisCornerDetectionFilter.h"
|
||||
#import "GPUImageAlphaBlendFilter.h"
|
||||
#import "GPUImageNormalBlendFilter.h"
|
||||
#import "GPUImageNonMaximumSuppressionFilter.h"
|
||||
#import "GPUImageRGBFilter.h"
|
||||
#import "GPUImageMedianFilter.h"
|
||||
#import "GPUImageBilateralFilter.h"
|
||||
#import "GPUImageCrosshairGenerator.h"
|
||||
#import "GPUImageToneCurveFilter.h"
|
||||
#import "GPUImageNobleCornerDetectionFilter.h"
|
||||
#import "GPUImageShiTomasiFeatureDetectionFilter.h"
|
||||
#import "GPUImageErosionFilter.h"
|
||||
#import "GPUImageRGBErosionFilter.h"
|
||||
#import "GPUImageDilationFilter.h"
|
||||
#import "GPUImageRGBDilationFilter.h"
|
||||
#import "GPUImageOpeningFilter.h"
|
||||
#import "GPUImageRGBOpeningFilter.h"
|
||||
#import "GPUImageClosingFilter.h"
|
||||
#import "GPUImageRGBClosingFilter.h"
|
||||
#import "GPUImageColorPackingFilter.h"
|
||||
#import "GPUImageSphereRefractionFilter.h"
|
||||
#import "GPUImageMonochromeFilter.h"
|
||||
#import "GPUImageOpacityFilter.h"
|
||||
#import "GPUImageHighlightShadowFilter.h"
|
||||
#import "GPUImageFalseColorFilter.h"
|
||||
#import "GPUImageHSBFilter.h"
|
||||
#import "GPUImageHueFilter.h"
|
||||
#import "GPUImageGlassSphereFilter.h"
|
||||
#import "GPUImageLookupFilter.h"
|
||||
#import "GPUImageAmatorkaFilter.h"
|
||||
#import "GPUImageMissEtikateFilter.h"
|
||||
#import "GPUImageSoftEleganceFilter.h"
|
||||
#import "GPUImageAddBlendFilter.h"
|
||||
#import "GPUImageDivideBlendFilter.h"
|
||||
#import "GPUImagePolkaDotFilter.h"
|
||||
#import "GPUImageLocalBinaryPatternFilter.h"
|
||||
#import "GPUImageColorLocalBinaryPatternFilter.h"
|
||||
#import "GPUImageLanczosResamplingFilter.h"
|
||||
#import "GPUImageAverageColor.h"
|
||||
#import "GPUImageSolidColorGenerator.h"
|
||||
#import "GPUImageLuminosity.h"
|
||||
#import "GPUImageAverageLuminanceThresholdFilter.h"
|
||||
#import "GPUImageWhiteBalanceFilter.h"
|
||||
#import "GPUImageChromaKeyFilter.h"
|
||||
#import "GPUImageLowPassFilter.h"
|
||||
#import "GPUImageHighPassFilter.h"
|
||||
#import "GPUImageMotionDetector.h"
|
||||
#import "GPUImageHalftoneFilter.h"
|
||||
#import "GPUImageThresholdedNonMaximumSuppressionFilter.h"
|
||||
#import "GPUImageHoughTransformLineDetector.h"
|
||||
#import "GPUImageParallelCoordinateLineTransformFilter.h"
|
||||
#import "GPUImageThresholdSketchFilter.h"
|
||||
#import "GPUImageLineGenerator.h"
|
||||
#import "GPUImageLinearBurnBlendFilter.h"
|
||||
#import "GPUImageGaussianBlurPositionFilter.h"
|
||||
#import "GPUImagePixellatePositionFilter.h"
|
||||
#import "GPUImageTwoInputCrossTextureSamplingFilter.h"
|
||||
#import "GPUImagePoissonBlendFilter.h"
|
||||
#import "GPUImageMotionBlurFilter.h"
|
||||
#import "GPUImageZoomBlurFilter.h"
|
||||
#import "GPUImageLaplacianFilter.h"
|
||||
#import "GPUImageiOSBlurFilter.h"
|
||||
#import "GPUImageLuminanceRangeFilter.h"
|
||||
#import "GPUImageDirectionalNonMaximumSuppressionFilter.h"
|
||||
#import "GPUImageDirectionalSobelEdgeDetectionFilter.h"
|
||||
#import "GPUImageSingleComponentGaussianBlurFilter.h"
|
||||
#import "GPUImageThreeInputFilter.h"
|
||||
#import "GPUImageFourInputFilter.h"
|
||||
#import "GPUImageWeakPixelInclusionFilter.h"
|
||||
#import "GPUImageColorConversion.h"
|
||||
#import "GPUImageColourFASTFeatureDetector.h"
|
||||
#import "GPUImageColourFASTSamplingOperation.h"
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#import "GPUImage3x3TextureSamplingFilter.h"
|
||||
|
||||
/** Runs a 3x3 convolution kernel against the image
|
||||
*/
|
||||
@interface GPUImage3x3ConvolutionFilter : GPUImage3x3TextureSamplingFilter
|
||||
{
|
||||
GLint convolutionMatrixUniform;
|
||||
}
|
||||
|
||||
/** Convolution kernel to run against the image
|
||||
|
||||
The convolution kernel is a 3x3 matrix of values to apply to the pixel and its 8 surrounding pixels.
|
||||
The matrix is specified in row-major order, with the top left pixel being one.one and the bottom right three.three
|
||||
If the values in the matrix don't add up to 1.0, the image could be brightened or darkened.
|
||||
*/
|
||||
@property(readwrite, nonatomic) GPUMatrix3x3 convolutionKernel;
|
||||
|
||||
@end
|
||||
@@ -1,128 +0,0 @@
|
||||
#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
|
||||
@@ -1,18 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
extern NSString *const kGPUImageNearbyTexelSamplingVertexShaderString;
|
||||
|
||||
@interface GPUImage3x3TextureSamplingFilter : GPUImageFilter
|
||||
{
|
||||
GLint texelWidthUniform, texelHeightUniform;
|
||||
|
||||
CGFloat texelWidth, texelHeight;
|
||||
BOOL hasOverriddenImageSizeFactor;
|
||||
}
|
||||
|
||||
// The texel width and height determines how far out to sample from this texel. By default, this is the normalized width of a pixel, but this can be overridden for different effects.
|
||||
@property(readwrite, nonatomic) CGFloat texelWidth;
|
||||
@property(readwrite, nonatomic) CGFloat texelHeight;
|
||||
|
||||
|
||||
@end
|
||||
@@ -1,121 +0,0 @@
|
||||
#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
|
||||
@@ -1,9 +0,0 @@
|
||||
#import "GPUImageFilterGroup.h"
|
||||
|
||||
@interface GPUImageAdaptiveThresholdFilter : GPUImageFilterGroup
|
||||
|
||||
/** A multiplier for the background averaging blur radius in pixels, with a default of 4
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat blurRadiusInPixels;
|
||||
|
||||
@end
|
||||
@@ -1,100 +0,0 @@
|
||||
#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
|
||||
@@ -1,5 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
@interface GPUImageAddBlendFilter : GPUImageTwoInputFilter
|
||||
|
||||
@end
|
||||
-100
@@ -1,100 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
@interface GPUImageAlphaBlendFilter : GPUImageTwoInputFilter
|
||||
{
|
||||
GLint mixUniform;
|
||||
}
|
||||
|
||||
// Mix ranges from 0.0 (only image 1) to 1.0 (only image 2), with 1.0 as the normal level
|
||||
@property(readwrite, nonatomic) CGFloat mix;
|
||||
|
||||
@end
|
||||
@@ -1,72 +0,0 @@
|
||||
#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
|
||||
@@ -1,17 +0,0 @@
|
||||
#import "GPUImageFilterGroup.h"
|
||||
|
||||
@class GPUImagePicture;
|
||||
|
||||
/** A photo filter based on Photoshop action by Amatorka
|
||||
http://amatorka.deviantart.com/art/Amatorka-Action-2-121069631
|
||||
*/
|
||||
|
||||
// Note: If you want to use this effect you have to add lookup_amatorka.png
|
||||
// from Resources folder to your application bundle.
|
||||
|
||||
@interface GPUImageAmatorkaFilter : GPUImageFilterGroup
|
||||
{
|
||||
GPUImagePicture *lookupImageSource;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,38 +0,0 @@
|
||||
#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
|
||||
@@ -1,20 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
extern NSString *const kGPUImageColorAveragingVertexShaderString;
|
||||
|
||||
@interface GPUImageAverageColor : GPUImageFilter
|
||||
{
|
||||
GLint texelWidthUniform, texelHeightUniform;
|
||||
|
||||
NSUInteger numberOfStages;
|
||||
|
||||
GLubyte *rawImagePixels;
|
||||
CGSize finalStageSize;
|
||||
}
|
||||
|
||||
// This block is called on the completion of color averaging for a frame
|
||||
@property(nonatomic, copy) void(^colorAverageProcessingFinishedBlock)(CGFloat redComponent, CGFloat greenComponent, CGFloat blueComponent, CGFloat alphaComponent, CMTime frameTime);
|
||||
|
||||
- (void)extractAverageColorAtFrameTime:(CMTime)frameTime;
|
||||
|
||||
@end
|
||||
-204
@@ -1,204 +0,0 @@
|
||||
#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
|
||||
@@ -1,8 +0,0 @@
|
||||
#import "GPUImageFilterGroup.h"
|
||||
|
||||
@interface GPUImageAverageLuminanceThresholdFilter : GPUImageFilterGroup
|
||||
|
||||
// This is multiplied by the continually calculated average image luminosity to arrive at the final threshold. Default is 1.0.
|
||||
@property(readwrite, nonatomic) CGFloat thresholdMultiplier;
|
||||
|
||||
@end
|
||||
@@ -1,47 +0,0 @@
|
||||
#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
|
||||
@@ -1,10 +0,0 @@
|
||||
#import "GPUImageGaussianBlurFilter.h"
|
||||
|
||||
@interface GPUImageBilateralFilter : GPUImageGaussianBlurFilter
|
||||
{
|
||||
CGFloat firstDistanceNormalizationFactorUniform;
|
||||
CGFloat secondDistanceNormalizationFactorUniform;
|
||||
}
|
||||
// A normalization factor for the distance between central color and sample color.
|
||||
@property(nonatomic, readwrite) CGFloat distanceNormalizationFactor;
|
||||
@end
|
||||
-231
@@ -1,231 +0,0 @@
|
||||
#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
|
||||
@@ -1,7 +0,0 @@
|
||||
#import "GPUImageGaussianBlurFilter.h"
|
||||
|
||||
/** A hardware-accelerated box blur of an image
|
||||
*/
|
||||
@interface GPUImageBoxBlurFilter : GPUImageGaussianBlurFilter
|
||||
|
||||
@end
|
||||
-178
@@ -1,178 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageBrightnessFilter : GPUImageFilter
|
||||
{
|
||||
GLint brightnessUniform;
|
||||
}
|
||||
|
||||
// Brightness ranges from -1.0 to 1.0, with 0.0 as the normal level
|
||||
@property(readwrite, nonatomic) CGFloat brightness;
|
||||
|
||||
@end
|
||||
@@ -1,66 +0,0 @@
|
||||
#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
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageBuffer : GPUImageFilter
|
||||
{
|
||||
NSMutableArray *bufferedFramebuffers;
|
||||
}
|
||||
|
||||
@property(readwrite, nonatomic) NSUInteger bufferSize;
|
||||
|
||||
@end
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
#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
|
||||
@@ -1,16 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
/// Creates a bulge distortion on the image
|
||||
@interface GPUImageBulgeDistortionFilter : GPUImageFilter
|
||||
{
|
||||
GLint aspectRatioUniform, radiusUniform, centerUniform, scaleUniform;
|
||||
}
|
||||
|
||||
/// The center about which to apply the distortion, with a default of (0.5, 0.5)
|
||||
@property(readwrite, nonatomic) CGPoint center;
|
||||
/// The radius of the distortion, ranging from 0.0 to 1.0, with a default of 0.25
|
||||
@property(readwrite, nonatomic) CGFloat radius;
|
||||
/// The amount of distortion to apply, from -1.0 to 1.0, with a default of 0.5
|
||||
@property(readwrite, nonatomic) CGFloat scale;
|
||||
|
||||
@end
|
||||
@@ -1,174 +0,0 @@
|
||||
#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
|
||||
@@ -1,5 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageCGAColorspaceFilter : GPUImageFilter
|
||||
|
||||
@end
|
||||
@@ -1,113 +0,0 @@
|
||||
//
|
||||
// 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
|
||||
@@ -1,62 +0,0 @@
|
||||
#import "GPUImageFilterGroup.h"
|
||||
|
||||
@class GPUImageGrayscaleFilter;
|
||||
@class GPUImageSingleComponentGaussianBlurFilter;
|
||||
@class GPUImageDirectionalSobelEdgeDetectionFilter;
|
||||
@class GPUImageDirectionalNonMaximumSuppressionFilter;
|
||||
@class GPUImageWeakPixelInclusionFilter;
|
||||
|
||||
/** This applies the edge detection process described by John Canny in
|
||||
|
||||
Canny, J., A Computational Approach To Edge Detection, IEEE Trans. Pattern Analysis and Machine Intelligence, 8(6):679–698, 1986.
|
||||
|
||||
and implemented in OpenGL ES by
|
||||
|
||||
A. Ensor, S. Hall. GPU-based Image Analysis on Mobile Devices. Proceedings of Image and Vision Computing New Zealand 2011.
|
||||
|
||||
It starts with a conversion to luminance, followed by an accelerated 9-hit Gaussian blur. A Sobel operator is applied to obtain the overall
|
||||
gradient strength in the blurred image, as well as the direction (in texture sampling steps) of the gradient. A non-maximum suppression filter
|
||||
acts along the direction of the gradient, highlighting strong edges that pass the threshold and completely removing those that fail the lower
|
||||
threshold. Finally, pixels from in-between these thresholds are either included in edges or rejected based on neighboring pixels.
|
||||
*/
|
||||
@interface GPUImageCannyEdgeDetectionFilter : GPUImageFilterGroup
|
||||
{
|
||||
GPUImageGrayscaleFilter *luminanceFilter;
|
||||
GPUImageSingleComponentGaussianBlurFilter *blurFilter;
|
||||
GPUImageDirectionalSobelEdgeDetectionFilter *edgeDetectionFilter;
|
||||
GPUImageDirectionalNonMaximumSuppressionFilter *nonMaximumSuppressionFilter;
|
||||
GPUImageWeakPixelInclusionFilter *weakPixelInclusionFilter;
|
||||
}
|
||||
|
||||
/** The image width and height factors tweak the appearance of the edges.
|
||||
|
||||
These parameters affect the visibility of the detected edges
|
||||
|
||||
By default, they match the inverse of the filter size in pixels
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat texelWidth;
|
||||
/** The image width and height factors tweak the appearance of the edges.
|
||||
|
||||
These parameters affect the visibility of the detected edges
|
||||
|
||||
By default, they match the inverse of the filter size in pixels
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat texelHeight;
|
||||
|
||||
/** The underlying blur radius for the Gaussian blur. Default is 2.0.
|
||||
*/
|
||||
@property (readwrite, nonatomic) CGFloat blurRadiusInPixels;
|
||||
|
||||
/** The underlying blur texel spacing multiplier. Default is 1.0.
|
||||
*/
|
||||
@property (readwrite, nonatomic) CGFloat blurTexelSpacingMultiplier;
|
||||
|
||||
/** Any edge with a gradient magnitude above this threshold will pass and show up in the final result.
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat upperThreshold;
|
||||
|
||||
/** Any edge with a gradient magnitude below this threshold will fail and be removed from the final result.
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat lowerThreshold;
|
||||
|
||||
@end
|
||||
@@ -1,125 +0,0 @@
|
||||
#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
|
||||
@@ -1,32 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
/** Selectively replaces a color in the first image with the second image
|
||||
*/
|
||||
@interface GPUImageChromaKeyBlendFilter : GPUImageTwoInputFilter
|
||||
{
|
||||
GLint colorToReplaceUniform, thresholdSensitivityUniform, smoothingUniform;
|
||||
}
|
||||
|
||||
/** The threshold sensitivity controls how similar pixels need to be colored to be replaced
|
||||
|
||||
The default value is 0.3
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat thresholdSensitivity;
|
||||
|
||||
/** The degree of smoothing controls how gradually similar colors are replaced in the image
|
||||
|
||||
The default value is 0.1
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat smoothing;
|
||||
|
||||
/** The color to be replaced is specified using individual red, green, and blue components (normalized to 1.0).
|
||||
|
||||
The default is green: (0.0, 1.0, 0.0).
|
||||
|
||||
@param redComponent Red component of color to be replaced
|
||||
@param greenComponent Green component of color to be replaced
|
||||
@param blueComponent Blue component of color to be replaced
|
||||
*/
|
||||
- (void)setColorToReplaceRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
|
||||
|
||||
@end
|
||||
@@ -1,117 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageChromaKeyFilter : GPUImageFilter
|
||||
{
|
||||
GLint colorToReplaceUniform, thresholdSensitivityUniform, smoothingUniform;
|
||||
}
|
||||
|
||||
/** The threshold sensitivity controls how similar pixels need to be colored to be replaced
|
||||
|
||||
The default value is 0.3
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat thresholdSensitivity;
|
||||
|
||||
/** The degree of smoothing controls how gradually similar colors are replaced in the image
|
||||
|
||||
The default value is 0.1
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat smoothing;
|
||||
|
||||
/** The color to be replaced is specified using individual red, green, and blue components (normalized to 1.0).
|
||||
|
||||
The default is green: (0.0, 1.0, 0.0).
|
||||
|
||||
@param redComponent Red component of color to be replaced
|
||||
@param greenComponent Green component of color to be replaced
|
||||
@param blueComponent Blue component of color to be replaced
|
||||
*/
|
||||
- (void)setColorToReplaceRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
|
||||
|
||||
@end
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
#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
|
||||
@@ -1,19 +0,0 @@
|
||||
#import "GPUImageFilterGroup.h"
|
||||
|
||||
@class GPUImageErosionFilter;
|
||||
@class GPUImageDilationFilter;
|
||||
|
||||
// A filter that first performs a dilation on the red channel of an image, followed by an erosion of the same radius.
|
||||
// This helps to filter out smaller dark elements.
|
||||
|
||||
@interface GPUImageClosingFilter : GPUImageFilterGroup
|
||||
{
|
||||
GPUImageErosionFilter *erosionFilter;
|
||||
GPUImageDilationFilter *dilationFilter;
|
||||
}
|
||||
|
||||
@property(readwrite, nonatomic) CGFloat verticalTexelSpacing, horizontalTexelSpacing;
|
||||
|
||||
- (id)initWithRadius:(NSUInteger)radius;
|
||||
|
||||
@end
|
||||
@@ -1,57 +0,0 @@
|
||||
#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
|
||||
@@ -1,5 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
@interface GPUImageColorBlendFilter : GPUImageTwoInputFilter
|
||||
|
||||
@end
|
||||
@@ -1,113 +0,0 @@
|
||||
#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
|
||||
@@ -1,9 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
/** Applies a color burn blend of two images
|
||||
*/
|
||||
@interface GPUImageColorBurnBlendFilter : GPUImageTwoInputFilter
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,52 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef GPUImageColorConversion_h
|
||||
#define GPUImageColorConversion_h
|
||||
|
||||
extern GLfloat *kColorConversion601;
|
||||
extern GLfloat *kColorConversion601FullRange;
|
||||
extern GLfloat *kColorConversion709;
|
||||
extern NSString *const kGPUImageYUVVideoRangeConversionForRGFragmentShaderString;
|
||||
extern NSString *const kGPUImageYUVFullRangeConversionForLAFragmentShaderString;
|
||||
extern NSString *const kGPUImageYUVVideoRangeConversionForLAFragmentShaderString;
|
||||
|
||||
|
||||
#endif /* GPUImageColorConversion_h */
|
||||
-159
@@ -1,159 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
/** Applies a color dodge blend of two images
|
||||
*/
|
||||
@interface GPUImageColorDodgeBlendFilter : GPUImageTwoInputFilter
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,75 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageColorInvertFilter : GPUImageFilter
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,46 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#import "GPUImage3x3TextureSamplingFilter.h"
|
||||
|
||||
@interface GPUImageColorLocalBinaryPatternFilter : GPUImage3x3TextureSamplingFilter
|
||||
|
||||
@end
|
||||
@@ -1,159 +0,0 @@
|
||||
#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
|
||||
@@ -1,19 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
/** Transforms the colors of an image by applying a matrix to them
|
||||
*/
|
||||
@interface GPUImageColorMatrixFilter : GPUImageFilter
|
||||
{
|
||||
GLint colorMatrixUniform;
|
||||
GLint intensityUniform;
|
||||
}
|
||||
|
||||
/** A 4x4 matrix used to transform each color in an image
|
||||
*/
|
||||
@property(readwrite, nonatomic) GPUMatrix4x4 colorMatrix;
|
||||
|
||||
/** The degree to which the new transformed color replaces the original color for each pixel
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat intensity;
|
||||
|
||||
@end
|
||||
@@ -1,87 +0,0 @@
|
||||
#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
|
||||
@@ -1,10 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageColorPackingFilter : GPUImageFilter
|
||||
{
|
||||
GLint texelWidthUniform, texelHeightUniform;
|
||||
|
||||
CGFloat texelWidth, texelHeight;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,139 +0,0 @@
|
||||
#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
|
||||
@@ -1,21 +0,0 @@
|
||||
#import "GPUImageFilterGroup.h"
|
||||
|
||||
// This generates image-wide feature descriptors using the ColourFAST process, as developed and described in
|
||||
//
|
||||
// A. Ensor and S. Hall. ColourFAST: GPU-based feature point detection and tracking on mobile devices. 28th International Conference of Image and Vision Computing, New Zealand, 2013, p. 124-129.
|
||||
//
|
||||
// Seth Hall, "GPU accelerated feature algorithms for mobile devices", PhD thesis, School of Computing and Mathematical Sciences, Auckland University of Technology 2014.
|
||||
// http://aut.researchgateway.ac.nz/handle/10292/7991
|
||||
|
||||
@class GPUImageColourFASTSamplingOperation;
|
||||
@class GPUImageBoxBlurFilter;
|
||||
|
||||
@interface GPUImageColourFASTFeatureDetector : GPUImageFilterGroup
|
||||
{
|
||||
GPUImageBoxBlurFilter *blurFilter;
|
||||
GPUImageColourFASTSamplingOperation *colourFASTSamplingOperation;
|
||||
}
|
||||
// The blur radius of the underlying box blur. The default is 3.0.
|
||||
@property (readwrite, nonatomic) CGFloat blurRadiusInPixels;
|
||||
|
||||
@end
|
||||
@@ -1,48 +0,0 @@
|
||||
#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
|
||||
@@ -1,22 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
// This is the feature extraction phase of the ColourFAST feature detector, as described in:
|
||||
//
|
||||
// A. Ensor and S. Hall. ColourFAST: GPU-based feature point detection and tracking on mobile devices. 28th International Conference of Image and Vision Computing, New Zealand, 2013, p. 124-129.
|
||||
//
|
||||
// Seth Hall, "GPU accelerated feature algorithms for mobile devices", PhD thesis, School of Computing and Mathematical Sciences, Auckland University of Technology 2014.
|
||||
// http://aut.researchgateway.ac.nz/handle/10292/7991
|
||||
|
||||
@interface GPUImageColourFASTSamplingOperation : GPUImageTwoInputFilter
|
||||
{
|
||||
GLint texelWidthUniform, texelHeightUniform;
|
||||
|
||||
CGFloat texelWidth, texelHeight;
|
||||
BOOL hasOverriddenImageSizeFactor;
|
||||
}
|
||||
|
||||
// The texel width and height determines how far out to sample from this texel. By default, this is the normalized width of a pixel, but this can be overridden for different effects.
|
||||
@property(readwrite, nonatomic) CGFloat texelWidth;
|
||||
@property(readwrite, nonatomic) CGFloat texelHeight;
|
||||
|
||||
@end
|
||||
@@ -1,204 +0,0 @@
|
||||
#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
|
||||
@@ -1,14 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
/** Adjusts the contrast of the image
|
||||
*/
|
||||
@interface GPUImageContrastFilter : GPUImageFilter
|
||||
{
|
||||
GLint contrastUniform;
|
||||
}
|
||||
|
||||
/** Contrast ranges from 0.0 to 4.0 (max contrast), with 1.0 as the normal level
|
||||
*/
|
||||
@property(readwrite, nonatomic) CGFloat contrast;
|
||||
|
||||
@end
|
||||
@@ -1,66 +0,0 @@
|
||||
#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
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageCropFilter : GPUImageFilter
|
||||
{
|
||||
GLfloat cropTextureCoordinates[8];
|
||||
}
|
||||
|
||||
// The crop region is the rectangle within the image to crop. It is normalized to a coordinate space from 0.0 to 1.0, with 0.0, 0.0 being the upper left corner of the image
|
||||
@property(readwrite, nonatomic) CGRect cropRegion;
|
||||
|
||||
// Initialization and teardown
|
||||
- (id)initWithCropRegion:(CGRect)newCropRegion;
|
||||
|
||||
@end
|
||||
-274
@@ -1,274 +0,0 @@
|
||||
#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
|
||||
@@ -1,17 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageCrosshairGenerator : GPUImageFilter
|
||||
{
|
||||
GLint crosshairWidthUniform, crosshairColorUniform;
|
||||
}
|
||||
|
||||
// The width of the displayed crosshairs, in pixels. Currently this only works well for odd widths. The default is 5.
|
||||
@property(readwrite, nonatomic) CGFloat crosshairWidth;
|
||||
|
||||
// The color of the crosshairs is specified using individual red, green, and blue components (normalized to 1.0). The default is green: (0.0, 1.0, 0.0).
|
||||
- (void)setCrosshairColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
|
||||
|
||||
// Rendering
|
||||
- (void)renderCrosshairsFromArray:(GLfloat *)crosshairCoordinates count:(NSUInteger)numberOfCrosshairs frameTime:(CMTime)frameTime;
|
||||
|
||||
@end
|
||||
@@ -1,139 +0,0 @@
|
||||
#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
|
||||
@@ -1,13 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageCrosshatchFilter : GPUImageFilter
|
||||
{
|
||||
GLint crossHatchSpacingUniform, lineWidthUniform;
|
||||
}
|
||||
// The fractional width of the image to use as the spacing for the crosshatch. The default is 0.03.
|
||||
@property(readwrite, nonatomic) CGFloat crossHatchSpacing;
|
||||
|
||||
// A relative width for the crosshatch lines. The default is 0.003.
|
||||
@property(readwrite, nonatomic) CGFloat lineWidth;
|
||||
|
||||
@end
|
||||
@@ -1,163 +0,0 @@
|
||||
#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
|
||||
@@ -1,7 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
@interface GPUImageDarkenBlendFilter : GPUImageTwoInputFilter
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,52 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
@interface GPUImageDifferenceBlendFilter : GPUImageTwoInputFilter
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,50 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#import "GPUImageTwoPassTextureSamplingFilter.h"
|
||||
|
||||
// For each pixel, this sets it to the maximum value of the red channel in a rectangular neighborhood extending out dilationRadius pixels from the center.
|
||||
// This extends out bright features, and is most commonly used with black-and-white thresholded images.
|
||||
|
||||
extern NSString *const kGPUImageDilationRadiusOneVertexShaderString;
|
||||
extern NSString *const kGPUImageDilationRadiusTwoVertexShaderString;
|
||||
extern NSString *const kGPUImageDilationRadiusThreeVertexShaderString;
|
||||
extern NSString *const kGPUImageDilationRadiusFourVertexShaderString;
|
||||
|
||||
@interface GPUImageDilationFilter : GPUImageTwoPassTextureSamplingFilter
|
||||
|
||||
// Acceptable values for dilationRadius, which sets the distance in pixels to sample out from the center, are 1, 2, 3, and 4.
|
||||
- (id)initWithRadius:(NSUInteger)dilationRadius;
|
||||
|
||||
@end
|
||||
-431
@@ -1,431 +0,0 @@
|
||||
#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
|
||||
@@ -1,19 +0,0 @@
|
||||
#import "GPUImageFilter.h"
|
||||
|
||||
@interface GPUImageDirectionalNonMaximumSuppressionFilter : GPUImageFilter
|
||||
{
|
||||
GLint texelWidthUniform, texelHeightUniform;
|
||||
GLint upperThresholdUniform, lowerThresholdUniform;
|
||||
|
||||
BOOL hasOverriddenImageSizeFactor;
|
||||
}
|
||||
|
||||
// The texel width and height determines how far out to sample from this texel. By default, this is the normalized width of a pixel, but this can be overridden for different effects.
|
||||
@property(readwrite, nonatomic) CGFloat texelWidth;
|
||||
@property(readwrite, nonatomic) CGFloat texelHeight;
|
||||
|
||||
// These thresholds set cutoffs for the intensities that definitely get registered (upper threshold) and those that definitely don't (lower threshold)
|
||||
@property(readwrite, nonatomic) CGFloat upperThreshold;
|
||||
@property(readwrite, nonatomic) CGFloat lowerThreshold;
|
||||
|
||||
@end
|
||||
@@ -1,141 +0,0 @@
|
||||
#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
|
||||
@@ -1,5 +0,0 @@
|
||||
#import "GPUImage3x3TextureSamplingFilter.h"
|
||||
|
||||
@interface GPUImageDirectionalSobelEdgeDetectionFilter : GPUImage3x3TextureSamplingFilter
|
||||
|
||||
@end
|
||||
@@ -1,103 +0,0 @@
|
||||
#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
|
||||
@@ -1,11 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
@interface GPUImageDissolveBlendFilter : GPUImageTwoInputFilter
|
||||
{
|
||||
GLint mixUniform;
|
||||
}
|
||||
|
||||
// Mix ranges from 0.0 (only image 1) to 1.0 (only image 2), with 0.5 (half of either) as the normal level
|
||||
@property(readwrite, nonatomic) CGFloat mix;
|
||||
|
||||
@end
|
||||
@@ -1,72 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#import "GPUImageTwoInputFilter.h"
|
||||
|
||||
@interface GPUImageDivideBlendFilter : GPUImageTwoInputFilter
|
||||
|
||||
@end
|
||||
@@ -1,96 +0,0 @@
|
||||
#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
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#import "GPUImage3x3ConvolutionFilter.h"
|
||||
|
||||
@interface GPUImageEmbossFilter : GPUImage3x3ConvolutionFilter
|
||||
|
||||
// The strength of the embossing, from 0.0 to 4.0, with 1.0 as the normal level
|
||||
@property(readwrite, nonatomic) CGFloat intensity;
|
||||
|
||||
@end
|
||||
@@ -1,49 +0,0 @@
|
||||
#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
|
||||
@@ -1,11 +0,0 @@
|
||||
#import "GPUImageTwoPassTextureSamplingFilter.h"
|
||||
|
||||
// For each pixel, this sets it to the minimum value of the red channel in a rectangular neighborhood extending out dilationRadius pixels from the center.
|
||||
// This extends out dark features, and is most commonly used with black-and-white thresholded images.
|
||||
|
||||
@interface GPUImageErosionFilter : GPUImageTwoPassTextureSamplingFilter
|
||||
|
||||
// Acceptable values for erosionRadius, which sets the distance in pixels to sample out from the center, are 1, 2, 3, and 4.
|
||||
- (id)initWithRadius:(NSUInteger)erosionRadius;
|
||||
|
||||
@end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user