diff --git a/.gitignore b/.gitignore index 122cfe2..45b25d9 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,7 @@ Carthage/Build # `pod install` in .travis.yml # Example/Pods + +# SwiftPM +.swiftpm +.build diff --git a/.gitmodules b/.gitmodules index 9a8927b..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "Vendors/libheif"] - path = Vendors/libheif - url = https://github.com/strukturag/libheif.git diff --git a/.travis.yml b/.travis.yml index dd124d7..88efac2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode9.4 +osx_image: xcode11.2 env: global: @@ -15,10 +15,9 @@ notifications: before_install: - env - locale - - gem install cocoapods --no-rdoc --no-ri --no-document --quiet - - gem install xcpretty --no-rdoc --no-ri --no-document --quiet + - gem install cocoapods --no-document --quiet + - gem install xcpretty --no-document --quiet - pod --version - - pod setup --silent > /dev/null - pod repo update --silent - xcpretty --version - xcodebuild -version @@ -28,8 +27,22 @@ script: - set -o pipefail - echo Check if the library described by the podspec can be built - - pod lib lint --use-libraries --allow-warnings + # Run full subspecs linting consuming too much of build time because CocoaPods use source code of Pods + # Since`libx265` && `libde265` is Pod and have their own linting, don't waste time to lint full subspecs combination + - pod lib lint --use-libraries --allow-warnings --no-subspecs --fail-fast - echo Build example - pod install --project-directory=Example - - xcodebuild build -workspace Example/SDWebImageHEIFCoder.xcworkspace -scheme SDWebImageHEIFCoder-Example -sdk iphonesimulator -destination 'name=iPhone 8' -configuration Debug | xcpretty -c \ No newline at end of file + - xcodebuild build -workspace Example/SDWebImageHEIFCoder.xcworkspace -scheme 'SDWebImageHEIFCoder-Example' -destination 'name=iPhone 11 Pro' -configuration Debug | xcpretty -c + - xcodebuild build -workspace Example/SDWebImageHEIFCoder.xcworkspace -scheme 'SDWebImageHEIFCoder-Example macOS' -destination 'platform=macOS,arch=x86_64' -configuration Debug | xcpretty -c + + - echo Clean DerivedData + - rm -rf ~/Library/Developer/Xcode/DerivedData/ + - mkdir DerivedData + + - echo Run the tests + - xcodebuild clean test -workspace Example/SDWebImageHEIFCoder.xcworkspace -scheme 'SDWebImageHEIFCoder_Tests' -sdk iphonesimulator -destination 'name=iPhone 11 Pro' -configuration Debug | xcpretty -c + - mv ~/Library/Developer/Xcode/DerivedData/ ./DerivedData/iOS + +after_success: + - bash <(curl -s https://codecov.io/bash) -D './DerivedData/iOS' -J '^SDWebImageHEIFCoder$' -X gcov -F ios diff --git a/Cartfile b/Cartfile index a48af35..7853948 100644 --- a/Cartfile +++ b/Cartfile @@ -1,2 +1,2 @@ -github "SDWebImage/SDWebImage" -github "SDWebImage/libheif-Xcode" \ No newline at end of file +github "SDWebImage/SDWebImage" ~> 5.10 +github "SDWebImage/libheif-Xcode" >= 1.6.0 \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index 4b39f95..abfe185 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,3 +1,3 @@ -github "SDWebImage/SDWebImage" "4.4.3" -github "SDWebImage/libde265-Xcode" "1.0.3" -github "SDWebImage/libheif-Xcode" "1.3.2" +github "SDWebImage/SDWebImage" "5.5.2" +github "SDWebImage/libde265-Xcode" "1.0.5" +github "SDWebImage/libheif-Xcode" "1.6.1" diff --git a/Example/Podfile b/Example/Podfile index 73248a6..129f7b3 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -2,6 +2,7 @@ use_frameworks! inhibit_all_warnings! target 'SDWebImageHEIFCoder_Example' do + platform :ios, '9.0' pod 'SDWebImageHEIFCoder', :path => '../', :subspecs => [ 'libde265', 'libx265' @@ -9,18 +10,15 @@ target 'SDWebImageHEIFCoder_Example' do target 'SDWebImageHEIFCoder_Tests' do inherit! :search_paths - + pod 'Expecta' end end -post_install do |installer| - - installer.pods_project.targets.each do |target| - if target.name == "SDWebImageHEIFCoder" - target.build_configurations.each do |config| - config.build_settings['HEADER_SEARCH_PATHS'] ||= ['$(inherited)', '${SRCROOT}/../../Vendors/include'] - end - end - end +target 'SDWebImageHEIFCoder_Example macOS' do + platform :osx, '10.11' + pod 'SDWebImageHEIFCoder', :path => '../', :subspecs => [ + 'libde265', + 'libx265' + ] end \ No newline at end of file diff --git a/Example/Podfile.lock b/Example/Podfile.lock index f4f2b54..159c939 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,20 +1,59 @@ PODS: - - SDWebImage/Core (4.4.3) - - SDWebImageHEIFCoder/libde265 (0.1.2): - - SDWebImage/Core (~> 4.2) + - Expecta (1.0.6) + - libde265 (1.0.7) + - libheif/libde265 (1.9.0): + - libde265 + - libheif/libheif + - libheif/libheif (1.9.0) + - libheif/libx265 (1.9.0): + - libheif/libheif + - libx265 + - libx265 (3.0): + - libx265/common (= 3.0) + - libx265/core (= 3.0) + - libx265/encoder (= 3.0) + - libx265/input (= 3.0) + - libx265/output (= 3.0) + - libx265/x265 (= 3.0) + - libx265/common (3.0): + - libx265/core + - libx265/core (3.0) + - libx265/encoder (3.0): + - libx265/output + - libx265/input (3.0): + - libx265/common + - libx265/output (3.0): + - libx265/input + - libx265/x265 (3.0): + - libx265/common + - libx265/core + - libx265/encoder + - libx265/input + - libx265/output + - SDWebImage/Core (5.10.4) + - SDWebImageHEIFCoder/libde265 (0.10.1): + - libheif/libde265 + - SDWebImage/Core (~> 5.10) - SDWebImageHEIFCoder/libheif - - SDWebImageHEIFCoder/libheif (0.1.2): - - SDWebImage/Core (~> 4.2) - - SDWebImageHEIFCoder/libx265 (0.1.2): - - SDWebImage/Core (~> 4.2) + - SDWebImageHEIFCoder/libheif (0.10.1): + - libheif/libheif (>= 1.6.0) + - SDWebImage/Core (~> 5.10) + - SDWebImageHEIFCoder/libx265 (0.10.1): + - libheif/libx265 + - SDWebImage/Core (~> 5.10) - SDWebImageHEIFCoder/libheif DEPENDENCIES: + - Expecta - SDWebImageHEIFCoder/libde265 (from `../`) - SDWebImageHEIFCoder/libx265 (from `../`) SPEC REPOS: - https://github.com/cocoapods/specs.git: + trunk: + - Expecta + - libde265 + - libheif + - libx265 - SDWebImage EXTERNAL SOURCES: @@ -22,9 +61,13 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - SDWebImage: c5594f1a19c48d526d321e548902b56b479cd508 - SDWebImageHEIFCoder: fa5516639b2a7e14430ffa6a74826407778b2ce7 + Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5 + libde265: f0a422ba8f35519aeab5999608eb8f6d8ea60c93 + libheif: 7cf34d3cc53a49c4607ee755ff09592c4a5b26d2 + libx265: 23ab716aae3eff1e6b68b3db6ace8883867691c4 + SDWebImage: c666b97e1fa9c64b4909816a903322018f0a9c84 + SDWebImageHEIFCoder: 7743027f7a7a0437806abf3b0e1fda0915832daa -PODFILE CHECKSUM: 6f0273ee2365d3edb08042f707a55bcbb5085458 +PODFILE CHECKSUM: 201e723f3263aa614a21c7e7e46f82956584f083 -COCOAPODS: 1.5.3 +COCOAPODS: 1.8.4 diff --git a/Example/SDWebImageHEIFCoder.xcodeproj/project.pbxproj b/Example/SDWebImageHEIFCoder.xcodeproj/project.pbxproj index 21001c7..0327764 100644 --- a/Example/SDWebImageHEIFCoder.xcodeproj/project.pbxproj +++ b/Example/SDWebImageHEIFCoder.xcodeproj/project.pbxproj @@ -7,7 +7,15 @@ objects = { /* Begin PBXBuildFile section */ - 0B7E1D1B3369C67B9AC58749 /* Pods_SDWebImageHEIFCoder_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C56612731812E8C66FD75D78 /* Pods_SDWebImageHEIFCoder_Tests.framework */; }; + 02611B7015E8FA9225C7A277 /* Pods_SDWebImageHEIFCoder_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C56612731812E8C66FD75D78 /* Pods_SDWebImageHEIFCoder_Tests.framework */; }; + 327C6B97246E4C3600AB0AA4 /* TestImage.heic in Resources */ = {isa = PBXBuildFile; fileRef = 327C6B96246E4C3600AB0AA4 /* TestImage.heic */; }; + 32B50E1D244841DD0078E964 /* TestImageAnimated.heic in Resources */ = {isa = PBXBuildFile; fileRef = 32B50E1B244841DD0078E964 /* TestImageAnimated.heic */; }; + 32B50E1E244841DD0078E964 /* TestImageStatic.heic in Resources */ = {isa = PBXBuildFile; fileRef = 32B50E1C244841DD0078E964 /* TestImageStatic.heic */; }; + 32DE7FAC2261EA5400CF1A88 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 32DE7FAB2261EA5400CF1A88 /* AppDelegate.m */; }; + 32DE7FAF2261EA5400CF1A88 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32DE7FAE2261EA5400CF1A88 /* ViewController.m */; }; + 32DE7FB12261EA5400CF1A88 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 32DE7FB02261EA5400CF1A88 /* Assets.xcassets */; }; + 32DE7FB42261EA5400CF1A88 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32DE7FB22261EA5400CF1A88 /* Main.storyboard */; }; + 32DE7FB72261EA5400CF1A88 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 32DE7FB62261EA5400CF1A88 /* main.m */; }; 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; }; 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; @@ -20,10 +28,11 @@ 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; - 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; }; + 6003F5BC195388D20070C39A /* SDWebImageHEIFCoderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* SDWebImageHEIFCoderTests.m */; }; 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; }; 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; C8FC400702982DCE3137FF1E /* Pods_SDWebImageHEIFCoder_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAB362D312C46B9817266DAB /* Pods_SDWebImageHEIFCoder_Example.framework */; }; + EF9F662659DA33FEAF30A93A /* Pods_SDWebImageHEIFCoder_Example_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2AF860EE1234E07BC0DB72D /* Pods_SDWebImageHEIFCoder_Example_macOS.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -37,9 +46,21 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 08649579C6FF2CB2561035C5 /* Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Tests/Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig"; sourceTree = ""; }; + 327C6B96246E4C3600AB0AA4 /* TestImage.heic */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImage.heic; sourceTree = ""; }; + 32B50E1B244841DD0078E964 /* TestImageAnimated.heic */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageAnimated.heic; sourceTree = ""; }; + 32B50E1C244841DD0078E964 /* TestImageStatic.heic */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageStatic.heic; sourceTree = ""; }; + 32DE7FA82261EA5300CF1A88 /* SDWebImageHEIFCoder_Example macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SDWebImageHEIFCoder_Example macOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 32DE7FAA2261EA5300CF1A88 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 32DE7FAB2261EA5400CF1A88 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 32DE7FAD2261EA5400CF1A88 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; + 32DE7FAE2261EA5400CF1A88 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 32DE7FB02261EA5400CF1A88 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 32DE7FB32261EA5400CF1A88 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 32DE7FB52261EA5400CF1A88 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 32DE7FB62261EA5400CF1A88 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 32DE7FB82261EA5400CF1A88 /* SDWebImageHEIFCoder_Example_macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SDWebImageHEIFCoder_Example_macOS.entitlements; sourceTree = ""; }; + 32DE7FBC2261EACA00CF1A88 /* SDWebImageHEIFCoder_Example macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "SDWebImageHEIFCoder_Example macOS.entitlements"; sourceTree = ""; }; 47B0A23AD5FD8BCF7F72BD4C /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; - 5772A51CA49AB3C04A24B8CE /* Pods-SDWebImageHEIFCoder_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageHEIFCoder_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Tests/Pods-SDWebImageHEIFCoder_Tests.release.xcconfig"; sourceTree = ""; }; 6003F58A195388D20070C39A /* SDWebImageHEIFCoder_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SDWebImageHEIFCoder_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -57,19 +78,32 @@ 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; }; 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; }; + 6003F5BB195388D20070C39A /* SDWebImageHEIFCoderTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageHEIFCoderTests.m; sourceTree = ""; }; 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; }; 71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 7B8FAB679E1472168E8617DA /* SDWebImageHEIFCoder.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = SDWebImageHEIFCoder.podspec; path = ../SDWebImageHEIFCoder.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 8AE65D38B3BF6E4CCAFAF73D /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; A1EC1B641EF75BEA2475590E /* Pods-SDWebImageHEIFCoder_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageHEIFCoder_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Example/Pods-SDWebImageHEIFCoder_Example.release.xcconfig"; sourceTree = ""; }; + A67B84CEC3645A0A997486A2 /* Pods-SDWebImageHEIFCoder_Example macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageHEIFCoder_Example macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Example macOS/Pods-SDWebImageHEIFCoder_Example macOS.debug.xcconfig"; sourceTree = ""; }; AAB362D312C46B9817266DAB /* Pods_SDWebImageHEIFCoder_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImageHEIFCoder_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AB0B536057FCDF0347F3135D /* Pods-SDWebImageHEIFCoder_Example macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageHEIFCoder_Example macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Example macOS/Pods-SDWebImageHEIFCoder_Example macOS.release.xcconfig"; sourceTree = ""; }; + AD1FAB2DFC3830F2A4ADBB8B /* Pods-SDWebImageHEIFCoder_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageHEIFCoder_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Tests/Pods-SDWebImageHEIFCoder_Tests.release.xcconfig"; sourceTree = ""; }; + B2AF860EE1234E07BC0DB72D /* Pods_SDWebImageHEIFCoder_Example_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImageHEIFCoder_Example_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C56612731812E8C66FD75D78 /* Pods_SDWebImageHEIFCoder_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImageHEIFCoder_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E246A920ED516D3F3B26DB31 /* Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Tests/Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig"; sourceTree = ""; }; EDAAE4F3946D0D53727C85E0 /* Pods-SDWebImageHEIFCoder_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageHEIFCoder_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Example/Pods-SDWebImageHEIFCoder_Example.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 32DE7FA52261EA5300CF1A88 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EF9F662659DA33FEAF30A93A /* Pods_SDWebImageHEIFCoder_Example_macOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6003F587195388D20070C39A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -88,19 +122,47 @@ 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */, 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */, 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */, - 0B7E1D1B3369C67B9AC58749 /* Pods_SDWebImageHEIFCoder_Tests.framework in Frameworks */, + 02611B7015E8FA9225C7A277 /* Pods_SDWebImageHEIFCoder_Tests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 32B50E1A244841310078E964 /* Images */ = { + isa = PBXGroup; + children = ( + 32B50E1B244841DD0078E964 /* TestImageAnimated.heic */, + 32B50E1C244841DD0078E964 /* TestImageStatic.heic */, + 327C6B96246E4C3600AB0AA4 /* TestImage.heic */, + ); + path = Images; + sourceTree = ""; + }; + 32DE7FA92261EA5300CF1A88 /* SDWebImageHEIFCoder_Example macOS */ = { + isa = PBXGroup; + children = ( + 32DE7FBC2261EACA00CF1A88 /* SDWebImageHEIFCoder_Example macOS.entitlements */, + 32DE7FAA2261EA5300CF1A88 /* AppDelegate.h */, + 32DE7FAB2261EA5400CF1A88 /* AppDelegate.m */, + 32DE7FAD2261EA5400CF1A88 /* ViewController.h */, + 32DE7FAE2261EA5400CF1A88 /* ViewController.m */, + 32DE7FB02261EA5400CF1A88 /* Assets.xcassets */, + 32DE7FB22261EA5400CF1A88 /* Main.storyboard */, + 32DE7FB52261EA5400CF1A88 /* Info.plist */, + 32DE7FB62261EA5400CF1A88 /* main.m */, + 32DE7FB82261EA5400CF1A88 /* SDWebImageHEIFCoder_Example_macOS.entitlements */, + ); + path = "SDWebImageHEIFCoder_Example macOS"; + sourceTree = ""; + }; 6003F581195388D10070C39A = { isa = PBXGroup; children = ( 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */, 6003F593195388D20070C39A /* Example for SDWebImageHEIFCoder */, 6003F5B5195388D20070C39A /* Tests */, + 32DE7FA92261EA5300CF1A88 /* SDWebImageHEIFCoder_Example macOS */, 6003F58C195388D20070C39A /* Frameworks */, 6003F58B195388D20070C39A /* Products */, 76AEA6AD201F42CB609AC8F6 /* Pods */, @@ -112,6 +174,7 @@ children = ( 6003F58A195388D20070C39A /* SDWebImageHEIFCoder_Example.app */, 6003F5AE195388D20070C39A /* SDWebImageHEIFCoder_Tests.xctest */, + 32DE7FA82261EA5300CF1A88 /* SDWebImageHEIFCoder_Example macOS.app */, ); name = Products; sourceTree = ""; @@ -125,6 +188,7 @@ 6003F5AF195388D20070C39A /* XCTest.framework */, AAB362D312C46B9817266DAB /* Pods_SDWebImageHEIFCoder_Example.framework */, C56612731812E8C66FD75D78 /* Pods_SDWebImageHEIFCoder_Tests.framework */, + B2AF860EE1234E07BC0DB72D /* Pods_SDWebImageHEIFCoder_Example_macOS.framework */, ); name = Frameworks; sourceTree = ""; @@ -159,10 +223,12 @@ 6003F5B5195388D20070C39A /* Tests */ = { isa = PBXGroup; children = ( - 6003F5BB195388D20070C39A /* Tests.m */, + 32B50E1A244841310078E964 /* Images */, + 6003F5BB195388D20070C39A /* SDWebImageHEIFCoderTests.m */, 6003F5B6195388D20070C39A /* Supporting Files */, ); - path = Tests; + name = Tests; + path = ../Tests; sourceTree = ""; }; 6003F5B6195388D20070C39A /* Supporting Files */ = { @@ -190,8 +256,10 @@ children = ( EDAAE4F3946D0D53727C85E0 /* Pods-SDWebImageHEIFCoder_Example.debug.xcconfig */, A1EC1B641EF75BEA2475590E /* Pods-SDWebImageHEIFCoder_Example.release.xcconfig */, - 08649579C6FF2CB2561035C5 /* Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig */, - 5772A51CA49AB3C04A24B8CE /* Pods-SDWebImageHEIFCoder_Tests.release.xcconfig */, + A67B84CEC3645A0A997486A2 /* Pods-SDWebImageHEIFCoder_Example macOS.debug.xcconfig */, + AB0B536057FCDF0347F3135D /* Pods-SDWebImageHEIFCoder_Example macOS.release.xcconfig */, + E246A920ED516D3F3B26DB31 /* Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig */, + AD1FAB2DFC3830F2A4ADBB8B /* Pods-SDWebImageHEIFCoder_Tests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -199,6 +267,25 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 32DE7FA72261EA5300CF1A88 /* SDWebImageHEIFCoder_Example macOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 32DE7FBB2261EA5400CF1A88 /* Build configuration list for PBXNativeTarget "SDWebImageHEIFCoder_Example macOS" */; + buildPhases = ( + A2C66F452A1B40946E468D96 /* [CP] Check Pods Manifest.lock */, + 32DE7FA42261EA5300CF1A88 /* Sources */, + 32DE7FA52261EA5300CF1A88 /* Frameworks */, + 32DE7FA62261EA5300CF1A88 /* Resources */, + 96669B7112262C063F62EA79 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SDWebImageHEIFCoder_Example macOS"; + productName = "SDWebImageHEIFCoder_Example macOS"; + productReference = 32DE7FA82261EA5300CF1A88 /* SDWebImageHEIFCoder_Example macOS.app */; + productType = "com.apple.product-type.application"; + }; 6003F589195388D20070C39A /* SDWebImageHEIFCoder_Example */ = { isa = PBXNativeTarget; buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "SDWebImageHEIFCoder_Example" */; @@ -222,10 +309,11 @@ isa = PBXNativeTarget; buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "SDWebImageHEIFCoder_Tests" */; buildPhases = ( - A22717D99CCC232FB7A60F34 /* [CP] Check Pods Manifest.lock */, + AC57DECD759D1FC135D8AF3F /* [CP] Check Pods Manifest.lock */, 6003F5AA195388D20070C39A /* Sources */, 6003F5AB195388D20070C39A /* Frameworks */, 6003F5AC195388D20070C39A /* Resources */, + 027BFE092DEF3CDEB1FF8404 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -247,8 +335,14 @@ LastUpgradeCheck = 0920; ORGANIZATIONNAME = DreamPiggy; TargetAttributes = { - 6003F589195388D20070C39A = { - DevelopmentTeam = H7W77QXGX2; + 32DE7FA72261EA5300CF1A88 = { + CreatedOnToolsVersion = 10.2; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 0; + }; + }; }; 6003F5AD195388D20070C39A = { TestTargetID = 6003F589195388D20070C39A; @@ -260,6 +354,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -270,11 +365,21 @@ targets = ( 6003F589195388D20070C39A /* SDWebImageHEIFCoder_Example */, 6003F5AD195388D20070C39A /* SDWebImageHEIFCoder_Tests */, + 32DE7FA72261EA5300CF1A88 /* SDWebImageHEIFCoder_Example macOS */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 32DE7FA62261EA5300CF1A88 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 32DE7FB12261EA5400CF1A88 /* Assets.xcassets in Resources */, + 32DE7FB42261EA5400CF1A88 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6003F588195388D20070C39A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -290,23 +395,96 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 327C6B97246E4C3600AB0AA4 /* TestImage.heic in Resources */, 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */, + 32B50E1D244841DD0078E964 /* TestImageAnimated.heic in Resources */, + 32B50E1E244841DD0078E964 /* TestImageStatic.heic in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - A22717D99CCC232FB7A60F34 /* [CP] Check Pods Manifest.lock */ = { + 027BFE092DEF3CDEB1FF8404 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-SDWebImageHEIFCoder_Tests/Pods-SDWebImageHEIFCoder_Tests-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Expecta/Expecta.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImageHEIFCoder_Tests/Pods-SDWebImageHEIFCoder_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 96669B7112262C063F62EA79 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-SDWebImageHEIFCoder_Example macOS/Pods-SDWebImageHEIFCoder_Example macOS-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/SDWebImage-macOS/SDWebImage.framework", + "${BUILT_PRODUCTS_DIR}/SDWebImageHEIFCoder-macOS/SDWebImageHEIFCoder.framework", + "${BUILT_PRODUCTS_DIR}/libde265-macOS/libde265.framework", + "${BUILT_PRODUCTS_DIR}/libheif-macOS/libheif.framework", + "${BUILT_PRODUCTS_DIR}/libx265-macOS/libx265.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageHEIFCoder.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libde265.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libheif.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libx265.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImageHEIFCoder_Example macOS/Pods-SDWebImageHEIFCoder_Example macOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A2C66F452A1B40946E468D96 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-SDWebImageHEIFCoder_Example macOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + AC57DECD759D1FC135D8AF3F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-SDWebImageHEIFCoder_Tests-checkManifestLockResult.txt", ); @@ -338,28 +516,40 @@ buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Example/Pods-SDWebImageHEIFCoder_Example-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework", - "${BUILT_PRODUCTS_DIR}/SDWebImageHEIFCoder/SDWebImageHEIFCoder.framework", + "${PODS_ROOT}/Target Support Files/Pods-SDWebImageHEIFCoder_Example/Pods-SDWebImageHEIFCoder_Example-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/SDWebImage-iOS/SDWebImage.framework", + "${BUILT_PRODUCTS_DIR}/SDWebImageHEIFCoder-iOS/SDWebImageHEIFCoder.framework", + "${BUILT_PRODUCTS_DIR}/libde265-iOS/libde265.framework", + "${BUILT_PRODUCTS_DIR}/libheif-iOS/libheif.framework", + "${BUILT_PRODUCTS_DIR}/libx265-iOS/libx265.framework", ); name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - ); outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageHEIFCoder.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libde265.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libheif.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libx265.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SDWebImageHEIFCoder_Example/Pods-SDWebImageHEIFCoder_Example-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImageHEIFCoder_Example/Pods-SDWebImageHEIFCoder_Example-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 32DE7FA42261EA5300CF1A88 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 32DE7FAF2261EA5400CF1A88 /* ViewController.m in Sources */, + 32DE7FB72261EA5400CF1A88 /* main.m in Sources */, + 32DE7FAC2261EA5400CF1A88 /* AppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6003F586195388D20070C39A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -374,7 +564,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6003F5BC195388D20070C39A /* Tests.m in Sources */, + 6003F5BC195388D20070C39A /* SDWebImageHEIFCoderTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -389,6 +579,14 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 32DE7FB22261EA5400CF1A88 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 32DE7FB32261EA5400CF1A88 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; 6003F596195388D20070C39A /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -416,6 +614,65 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 32DE7FB92261EA5400CF1A88 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A67B84CEC3645A0A997486A2 /* Pods-SDWebImageHEIFCoder_Example macOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = "SDWebImageHEIFCoder_Example macOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "org.SDWebImage.SDWebImageHEIFCoder-Example-macOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Debug; + }; + 32DE7FBA2261EA5400CF1A88 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AB0B536057FCDF0347F3135D /* Pods-SDWebImageHEIFCoder_Example macOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = "SDWebImageHEIFCoder_Example macOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "org.SDWebImage.SDWebImageHEIFCoder-Example-macOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Release; + }; 6003F5BD195388D20070C39A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -516,7 +773,6 @@ baseConfigurationReference = EDAAE4F3946D0D53727C85E0 /* Pods-SDWebImageHEIFCoder_Example.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = H7W77QXGX2; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SDWebImageHEIFCoder/SDWebImageHEIFCoder-Prefix.pch"; INFOPLIST_FILE = "SDWebImageHEIFCoder/SDWebImageHEIFCoder-Info.plist"; @@ -532,7 +788,6 @@ baseConfigurationReference = A1EC1B641EF75BEA2475590E /* Pods-SDWebImageHEIFCoder_Example.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = H7W77QXGX2; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SDWebImageHEIFCoder/SDWebImageHEIFCoder-Prefix.pch"; INFOPLIST_FILE = "SDWebImageHEIFCoder/SDWebImageHEIFCoder-Info.plist"; @@ -545,21 +800,20 @@ }; 6003F5C3195388D20070C39A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 08649579C6FF2CB2561035C5 /* Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig */; + baseConfigurationReference = E246A920ED516D3F3B26DB31 /* Pods-SDWebImageHEIFCoder_Tests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; + GCC_PREFIX_HEADER = "../Tests/Tests-Prefix.pch"; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); - INFOPLIST_FILE = "Tests/Tests-Info.plist"; + INFOPLIST_FILE = "../Tests/Tests-Info.plist"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SDWebImageHEIFCoder_Example.app/SDWebImageHEIFCoder_Example"; @@ -569,17 +823,16 @@ }; 6003F5C4195388D20070C39A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5772A51CA49AB3C04A24B8CE /* Pods-SDWebImageHEIFCoder_Tests.release.xcconfig */; + baseConfigurationReference = AD1FAB2DFC3830F2A4ADBB8B /* Pods-SDWebImageHEIFCoder_Tests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; - INFOPLIST_FILE = "Tests/Tests-Info.plist"; + GCC_PREFIX_HEADER = "../Tests/Tests-Prefix.pch"; + INFOPLIST_FILE = "../Tests/Tests-Info.plist"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SDWebImageHEIFCoder_Example.app/SDWebImageHEIFCoder_Example"; @@ -590,6 +843,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 32DE7FBB2261EA5400CF1A88 /* Build configuration list for PBXNativeTarget "SDWebImageHEIFCoder_Example macOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 32DE7FB92261EA5400CF1A88 /* Debug */, + 32DE7FBA2261EA5400CF1A88 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 6003F585195388D10070C39A /* Build configuration list for PBXProject "SDWebImageHEIFCoder" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Example/SDWebImageHEIFCoder.xcodeproj/xcshareddata/xcschemes/SDWebImageHEIFCoder-Example macOS.xcscheme b/Example/SDWebImageHEIFCoder.xcodeproj/xcshareddata/xcschemes/SDWebImageHEIFCoder-Example macOS.xcscheme new file mode 100644 index 0000000..d14e5cb --- /dev/null +++ b/Example/SDWebImageHEIFCoder.xcodeproj/xcshareddata/xcschemes/SDWebImageHEIFCoder-Example macOS.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/SDWebImageHEIFCoder.xcodeproj/xcshareddata/xcschemes/SDWebImageHEIFCoder-Example.xcscheme b/Example/SDWebImageHEIFCoder.xcodeproj/xcshareddata/xcschemes/SDWebImageHEIFCoder-Example.xcscheme index a3dc245..7c5ff20 100644 --- a/Example/SDWebImageHEIFCoder.xcodeproj/xcshareddata/xcschemes/SDWebImageHEIFCoder-Example.xcscheme +++ b/Example/SDWebImageHEIFCoder.xcodeproj/xcshareddata/xcschemes/SDWebImageHEIFCoder-Example.xcscheme @@ -1,6 +1,6 @@ + + + + @@ -40,23 +48,11 @@ - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/SDWebImageHEIFCoder/SDAppDelegate.m b/Example/SDWebImageHEIFCoder/SDAppDelegate.m index d48140b..844207d 100644 --- a/Example/SDWebImageHEIFCoder/SDAppDelegate.m +++ b/Example/SDWebImageHEIFCoder/SDAppDelegate.m @@ -7,12 +7,15 @@ // #import "SDAppDelegate.h" +#import @implementation SDAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. + SDImageHEIFCoder *HEIFCoder = [SDImageHEIFCoder sharedCoder]; + [[SDImageCodersManager sharedManager] addCoder:HEIFCoder]; return YES; } diff --git a/Example/SDWebImageHEIFCoder/SDViewController.m b/Example/SDWebImageHEIFCoder/SDViewController.m index 302d235..40b6f37 100644 --- a/Example/SDWebImageHEIFCoder/SDViewController.m +++ b/Example/SDWebImageHEIFCoder/SDViewController.m @@ -7,9 +7,8 @@ // #import "SDViewController.h" +#import #import -#import -#import @interface SDViewController () @@ -21,10 +20,8 @@ - (void)viewDidLoad { [super viewDidLoad]; - SDWebImageHEIFCoder *HEIFCoder = [SDWebImageHEIFCoder sharedCoder]; - [[SDWebImageCodersManager sharedInstance] addCoder:HEIFCoder]; NSURL *singleHEICURL = [NSURL URLWithString:@"http://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"]; - NSURL *stillHEICURL = [NSURL URLWithString:@"http://nokiatech.github.io/heif/content/images/autumn_1440x960.heic"]; + NSURL *animatedHEICURL = [NSURL URLWithString:@"http://nokiatech.github.io/heif/content/image_sequences/starfield_animation.heic"]; CGSize screenSize = [UIScreen mainScreen].bounds.size; @@ -34,18 +31,21 @@ - (void)viewDidLoad [self.view addSubview:imageView1]; [self.view addSubview:imageView2]; - [imageView1 sd_setImageWithURL:singleHEICURL placeholderImage:nil options:0 completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + [imageView1 sd_setImageWithURL:singleHEICURL placeholderImage:nil options:0 context:@{SDWebImageContextImageThumbnailPixelSize : @(CGSizeMake(500, 500))} progress:nil completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { if (image) { NSLog(@"Single HEIC load success"); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - NSData *data = [[SDWebImageHEIFCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatHEIC]; + NSData *data = [[SDImageHEIFCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatHEIC options:@{SDImageCoderEncodeMaxPixelSize : @(CGSizeMake(100, 100))}]; NSAssert(data, @"HEIC encoding failed"); + UIImage *thumbnailImage = [[SDImageHEIFCoder sharedCoder] decodedImageWithData:data options:@{SDImageCoderDecodeThumbnailPixelSize : @(CGSizeMake(100, 100))}]; + NSAssert(thumbnailImage.size.width == 100, @"HEIC thumbnail encoding and then thumbnail decoding"); NSLog(@"HEIC encoding success"); }); } }]; - [imageView2 sd_setImageWithURL:stillHEICURL completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { - if (image.images) { + [imageView2 sd_setImageWithURL:animatedHEICURL completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + // libheif currently does not supports animation + if (image) { NSLog(@"Still HEIF load success"); } }]; diff --git a/Example/SDWebImageHEIFCoder_Example macOS/AppDelegate.h b/Example/SDWebImageHEIFCoder_Example macOS/AppDelegate.h new file mode 100644 index 0000000..1ba8b00 --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// SDWebImageHEIFCoder_Example macOS +// +// Created by lizhuoli on 2019/4/13. +// Copyright © 2019 DreamPiggy. All rights reserved. +// + +#import + +@interface AppDelegate : NSObject + + +@end + diff --git a/Example/SDWebImageHEIFCoder_Example macOS/AppDelegate.m b/Example/SDWebImageHEIFCoder_Example macOS/AppDelegate.m new file mode 100644 index 0000000..c4dc9b1 --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/AppDelegate.m @@ -0,0 +1,30 @@ +// +// AppDelegate.m +// SDWebImageHEIFCoder_Example macOS +// +// Created by lizhuoli on 2019/4/13. +// Copyright © 2019 DreamPiggy. All rights reserved. +// + +#import "AppDelegate.h" +#import + +@interface AppDelegate () + +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application + SDImageHEIFCoder *HEIFCoder = [SDImageHEIFCoder sharedCoder]; + [[SDImageCodersManager sharedManager] addCoder:HEIFCoder]; +} + + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + + +@end diff --git a/Example/SDWebImageHEIFCoder_Example macOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/SDWebImageHEIFCoder_Example macOS/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2db2b1c --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/SDWebImageHEIFCoder_Example macOS/Assets.xcassets/Contents.json b/Example/SDWebImageHEIFCoder_Example macOS/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Example/SDWebImageHEIFCoder_Example macOS/Base.lproj/Main.storyboard b/Example/SDWebImageHEIFCoder_Example macOS/Base.lproj/Main.storyboard new file mode 100644 index 0000000..6eacd2a --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/Base.lproj/Main.storyboard @@ -0,0 +1,717 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/SDWebImageHEIFCoder_Example macOS/Info.plist b/Example/SDWebImageHEIFCoder_Example macOS/Info.plist new file mode 100644 index 0000000..5023627 --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/Info.plist @@ -0,0 +1,37 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2019 DreamPiggy. All rights reserved. + NSMainStoryboardFile + Main + NSPrincipalClass + NSApplication + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + + diff --git a/Example/SDWebImageHEIFCoder_Example macOS/SDWebImageHEIFCoder_Example macOS.entitlements b/Example/SDWebImageHEIFCoder_Example macOS/SDWebImageHEIFCoder_Example macOS.entitlements new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/SDWebImageHEIFCoder_Example macOS.entitlements @@ -0,0 +1,5 @@ + + + + + diff --git a/Example/SDWebImageHEIFCoder_Example macOS/SDWebImageHEIFCoder_Example_macOS.entitlements b/Example/SDWebImageHEIFCoder_Example macOS/SDWebImageHEIFCoder_Example_macOS.entitlements new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/SDWebImageHEIFCoder_Example_macOS.entitlements @@ -0,0 +1,5 @@ + + + + + diff --git a/Example/SDWebImageHEIFCoder_Example macOS/ViewController.h b/Example/SDWebImageHEIFCoder_Example macOS/ViewController.h new file mode 100644 index 0000000..6d07795 --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/ViewController.h @@ -0,0 +1,15 @@ +// +// ViewController.h +// SDWebImageHEIFCoder_Example macOS +// +// Created by lizhuoli on 2019/4/13. +// Copyright © 2019 DreamPiggy. All rights reserved. +// + +#import + +@interface ViewController : NSViewController + + +@end + diff --git a/Example/SDWebImageHEIFCoder_Example macOS/ViewController.m b/Example/SDWebImageHEIFCoder_Example macOS/ViewController.m new file mode 100644 index 0000000..dd747a3 --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/ViewController.m @@ -0,0 +1,65 @@ +// +// ViewController.m +// SDWebImageHEIFCoder-Example macOS +// +// Created by lizhuoli on 2019/4/13. +// Copyright © 2019 DreamPiggy. All rights reserved. +// + +#import "ViewController.h" +#import +#import + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + NSURL *staticHEIFURL = [NSURL URLWithString:@"http://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"]; + NSURL *animatedHEIFURL = [NSURL URLWithString:@"http://nokiatech.github.io/heif/content/image_sequences/starfield_animation.heic"]; + + CGSize screenSize = self.view.bounds.size; + + UIImageView *imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, screenSize.width / 2, screenSize.height)]; + imageView1.imageScaling = NSImageScaleProportionallyUpOrDown; + + UIImageView *imageView2 = [[UIImageView alloc] initWithFrame:CGRectMake(screenSize.width / 2, 0, screenSize.width / 2, screenSize.height)]; + imageView2.imageScaling = NSImageScaleProportionallyUpOrDown; + + [self.view addSubview:imageView1]; + [self.view addSubview:imageView2]; + + [imageView1 sd_setImageWithURL:staticHEIFURL completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + if (image) { + NSLog(@"Static HEIF load success"); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSData *HEIFData = [SDImageHEIFCoder.sharedCoder encodedDataWithImage:image format:SDImageFormatHEIF options:nil]; + if (HEIFData) { + NSLog(@"Static HEIF encode success"); + } + }); + } + }]; + [imageView2 sd_setImageWithURL:animatedHEIFURL completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + if (image.sd_isAnimated) { + NSLog(@"Animated HEIF load success"); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + // Animated HEIF encoding is really slow, specify the lowest quality with fast speed + NSData *HEIFData = [SDImageHEIFCoder.sharedCoder encodedDataWithImage:image format:SDImageFormatHEIF options:@{SDImageCoderEncodeCompressionQuality : @(0)}]; + if (HEIFData) { + NSLog(@"Animated HEIF encode success"); + } + }); + } + }]; +} + + +- (void)setRepresentedObject:(id)representedObject { + [super setRepresentedObject:representedObject]; + + // Update the view, if already loaded. +} + + +@end diff --git a/Example/SDWebImageHEIFCoder_Example macOS/main.m b/Example/SDWebImageHEIFCoder_Example macOS/main.m new file mode 100644 index 0000000..353a9c9 --- /dev/null +++ b/Example/SDWebImageHEIFCoder_Example macOS/main.m @@ -0,0 +1,13 @@ +// +// main.m +// SDWebImageHEIFCoder_Example macOS +// +// Created by lizhuoli on 2019/4/13. +// Copyright © 2019 DreamPiggy. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/Example/Screenshot/HEIFDemo-macOS.png b/Example/Screenshot/HEIFDemo-macOS.png new file mode 100644 index 0000000..402716a Binary files /dev/null and b/Example/Screenshot/HEIFDemo-macOS.png differ diff --git a/Example/Tests/Tests.m b/Example/Tests/Tests.m deleted file mode 100644 index b20359a..0000000 --- a/Example/Tests/Tests.m +++ /dev/null @@ -1,35 +0,0 @@ -// -// SDWebImageHEIFCoderTests.m -// SDWebImageHEIFCoderTests -// -// Created by DreamPiggy on 05/08/2018. -// Copyright (c) 2018 DreamPiggy. All rights reserved. -// - -@import XCTest; - -@interface Tests : XCTestCase - -@end - -@implementation Tests - -- (void)setUp -{ - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown -{ - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - -- (void)testExample -{ - XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); -} - -@end - diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..804d68e --- /dev/null +++ b/Package.resolved @@ -0,0 +1,34 @@ +{ + "object": { + "pins": [ + { + "package": "libde265", + "repositoryURL": "https://github.com/SDWebImage/libde265-Xcode.git", + "state": { + "branch": null, + "revision": "39b0430c631669dba8e578a2ececae3a05dbb935", + "version": "1.0.4" + } + }, + { + "package": "libheif", + "repositoryURL": "https://github.com/SDWebImage/libheif-Xcode.git", + "state": { + "branch": null, + "revision": "e78f3a9bf4f45f857032029a519adae46170978f", + "version": "1.6.1" + } + }, + { + "package": "SDWebImage", + "repositoryURL": "https://github.com/SDWebImage/SDWebImage.git", + "state": { + "branch": null, + "revision": "247f74a5d191e9c6bd601d292c99cf9fe1658930", + "version": "5.4.1" + } + } + ] + }, + "version": 1 +} diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..9855abb --- /dev/null +++ b/Package.swift @@ -0,0 +1,35 @@ +// swift-tools-version:5.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SDWebImageHEIFCoder", + platforms: [ + .macOS(.v10_11), .iOS(.v9), .tvOS(.v9), .watchOS(.v2) + ], + products: [ + // Products define the executables and libraries produced by a package, and make them visible to other packages. + .library( + name: "SDWebImageHEIFCoder", + targets: ["SDWebImageHEIFCoder"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + .package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.10.0"), + .package(url: "https://github.com/SDWebImage/libheif-Xcode.git", from: "1.6.1") + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target( + name: "SDWebImageHEIFCoder", + dependencies: ["SDWebImage", "libheif"], + path: ".", + sources: ["SDWebImageHEIFCoder/Classes"], + publicHeadersPath: "SDWebImageHEIFCoder/Classes", + cSettings: [.define("HAVE_LIBDE265")] + ) + ] +) diff --git a/README.md b/README.md index bc7ffc3..6632226 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,42 @@ # SDWebImageHEIFCoder -[![CI Status](https://img.shields.io/travis/DreamPiggy/SDWebImageHEIFCoder.svg?style=flat)](https://travis-ci.org/DreamPiggy/SDWebImageHEIFCoder) +[![CI Status](https://img.shields.io/travis/SDWebImage/SDWebImageHEIFCoder.svg?style=flat)](https://travis-ci.org/SDWebImage/SDWebImageHEIFCoder) [![Version](https://img.shields.io/cocoapods/v/SDWebImageHEIFCoder.svg?style=flat)](https://cocoapods.org/pods/SDWebImageHEIFCoder) [![License](https://img.shields.io/cocoapods/l/SDWebImageHEIFCoder.svg?style=flat)](https://cocoapods.org/pods/SDWebImageHEIFCoder) [![Platform](https://img.shields.io/cocoapods/p/SDWebImageHEIFCoder.svg?style=flat)](https://cocoapods.org/pods/SDWebImageHEIFCoder) +[![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg?style=flat)](https://swift.org/package-manager/) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/SDWebImage/SDWebImageHEIFCoder) +[![codecov](https://codecov.io/gh/SDWebImage/SDWebImageHEIFCoder/branch/master/graph/badge.svg)](https://codecov.io/gh/SDWebImage/SDWebImageHEIFCoder) -## Example +## 4.x compatibility + +SDWebImage 5.x change the custom image coder API. This `master` branch follow the `5.x` branch of SDWebImage. For 4.x compatibility HEIF coder support, checkout `4.x` branch. -To run the example project, clone the repo, and run `pod install` from the Example directory first. +## What's for This is a [SDWebImage](https://github.com/rs/SDWebImage) coder plugin to add [High Efficiency Image File Format (HEIF)](http://nokiatech.github.io/heif/index.html) support. Which is built based on the open-sourced [libheif](https://github.com/strukturag/libheif) codec. This HEIF coder plugin currently support HEIF single/still image **decoding** as well as HEIC image **encoding**. -It support iOS 8+/macOS 10.9+ device without the dependency of Apple's Image/IO framework. +The decoding supports [HDR](https://en.wikipedia.org/wiki/High-dynamic-range_imaging) HEIF image with 10/12 bit depth (larger than normal 8 bit) as well. + +It support iOS 9+/macOS 10.11+ device without the dependency of Apple's Image/IO framework. -However, for better performance and hardware accelerate for iOS 11+ device, it's really recommended to use Image/IO instead. +For iOS 8+/macOS 10.10+, use version lower than 0.10.0. + +## Performance + +Apple's Image/IO framework supports Hardware-Accelerated HEIF decoding (A9+ chip) and encoding on (A10+ chip). And provide a backup Software decoding and encoding on all iOS 11+/macOS 10.13+ devices. + +This coder is used for backward-compatible solution. And the codec only do Software decoding / encoding, which is slower than Image/IO. So if possible, choose to use Image/IO (SDWebImage's built-in coder) firstly. ## Requirements -+ iOS 8 ++ iOS 9.0 + tvOS 9.0 -+ macOS 10.9 ++ macOS 10.11 + watchOS 2.0 ++ Xcode 11.0 ## Installation @@ -35,7 +48,7 @@ it, simply add the following line to your Podfile: pod 'SDWebImageHEIFCoder' ``` -SDWebImageHEIFCoder contains 2 subspec `libde265` & `libx265`. Which integrate the codec plugin for libheif to support HEIF image decoding/encoding. +SDWebImageHEIFCoder contains subspecs `libde265` & `libx265`. Which integrate the codec plugin for libheif to support HEIF image decoding/encoding. To enable HEIF decoding, you should add `libde265` subspec: @@ -61,23 +74,164 @@ Carthage does not support like CocoaPods' subspec, since most of user use HEIF d github "SDWebImage/SDWebImageHEIFCoder" ``` +#### Swift Package Manager (Xcode 11+) + +SDWebImageHEIFCoder is available through [Swift Package Manager](https://swift.org/package-manager). + +The framework through SwiftPM only supports libde265 for HEIF decoding. + +```swift +let package = Package( + dependencies: [ + .package(url: "https://github.com/SDWebImage/SDWebImageHEIFCoder.git", from: "0.6") + ] +) +``` + ## Usage +### Add Coder + +To use HEIF coder, you should firstly add the `SDImageHEIFCoder.sharedCoder` to the coders manager. You can also detect the target platform compatibility for HEIF and choose add coder. + ++ Objective-C + +```objective-c +if (@available(iOS 11.0, macOS 10.13, tvOS 11.0, *)) { + // These version supports Image/IO built-in decoding +} else { + // Don't support HEIF decoding, add coder + SDImageHEIFCoder *HEIFCoder = [SDImageHEIFCoder sharedCoder]; + [[SDImageCodersManager sharedManager] addCoder:HEIFCoder]; +} +``` + ++ Swift + +```swift +if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) { + // These version supports Image/IO built-in decoding +} else { + // Don't support HEIF decoding, add coder + let HEIFCoder = SDImageHEIFCoder.shared + SDImageCodersManager.shared.addCoder(HEIFCoder) +} +``` + +### Loading + +Then you can call the View Category method to start load HEIF images. + ++ Objective-C + ```objective-c -SDWebImageAPNGCoder *HEIFCoder = [SDWebImageHEIFCoder sharedCoder]; -[[SDImageCodersManager sharedInstance] addCoder:HEIFCoder]; UIImageView *imageView; -NSURL *HEIFURL; -[imageView sd_setImageWithURL:HEIFURL]; +[imageView sd_setImageWithURL:url]; ``` -## 4.x compatibility ++ Swift -SDWebImage 5.x change the custom image coder API. This `master` branch follow the `5.x` branch of SDWebImage. For 4.x compatibility HEIF coder support, checkout `4.x` branch. +```swift +let imageView: UIImageView +imageView.sd_setImage(with: url) +``` + +### Decoding + +`SDImageHEIFCoder` currently supports decode the static HEIF images. + +Note HEIF sequence images(.heics) is not supported currently, only supported in built-in coder from SDWebImage for iOS 13+/macOS 10.15+, also supported by [Safari and WebKit](https://bugs.webkit.org/show_bug.cgi?id=197384). + ++ Objective-C + +```objective-c +// HEIF image decoding +NSData *heifData; +UIImage *image = [[SDImageHEIFCoder sharedCoder] decodedImageWithData:heifData options:nil]; +``` + ++ Swift + +```swift +// HEIF image decoding +let heifData: Data +let image = SDImageHEIFCoder.shared.decodedImage(with: data, options: nil) +``` + +### Thumbnail Decoding (0.7.0+) + +HEIF image container supports embed thumbnail image. If we can found a suitable thumbnail image, we pick that instead for quickly display, else we will decode full pixel image and scale down. + ++ Objective-C + +```objective-c +// HEIF thumbnail image decoding +NSData *heifData; +CGSize thumbnailSize = CGSizeMake(300, 300); +UIImage *thumbnailImage = [[SDImageHEIFCoder sharedCoder] decodedImageWithData:heifData options:@{SDImageCoderDecodeThumbnailPixelSize : @(thumbnailSize}]; +``` + ++ Swift + +```swift +// HEIF thumbnail image decoding +let heifData: Data +let thumbnailSize = CGSize(width: 300, height: 300) +let image = SDImageHEIFCoder.shared.decodedImage(with: data, options: [.decodeThumbnailPixelSize: thumbnailSize]) +``` + +### Encoding + +`SDWebImageHEIFCoder` also support HEIF encoding (need x265 subspec). You can encode `UIImage` to HEIF compressed image data. + ++ Objective-C + +```objectivec +UIImage *image; +NSData *imageData = [image sd_imageDataAsFormat:SDImageFormatHEIF]; +// Encode Quality +NSData *lossyData = [[SDImageHEIFCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatHEIF options:@{SDImageCoderEncodeCompressionQuality : @(0.1)}]; // [0, 1] compression quality +NSData *limitedData = [[SDImageHEIFCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatHEIF options:@{SDImageCoderEncodeMaxFileSize : @(1024 * 10)}]; // v0.8.0 feature, limit output file size <= 10KB +``` + ++ Swift + +```swift +let image; +let imageData = image.sd_imageData(as: .HEIF) +// Encode Quality +let lossyData = SDImageHEIFCoder.shared.encodedData(with: image, format: .heif, options: [.encodeCompressionQuality: 0.1]) // [0, 1] compression quality +let limitedData = SDImageHEIFCoder.shared.encodedData(with: image, format: .heif, options: [.encodeMaxFileSize: 1024 * 10]) // v0.8.0 feature, limit output file size <= 10KB +``` + +### Thumbnail Encoding (0.8.0+) + ++ Objective-C + +```objective-c +// HEIF image thumbnail encoding +UIImage *image; +NSData *thumbnailData = [[SDImageHEIFCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatHEIF options:@{SDImageCoderEncodeMaxPixelSize : @(CGSizeMake(200, 200)}, SDImageCoderEncodeEmbedThumbnail : @(YES)]; +// v0.8.0 feature, encoding max pixel size +// v0.9.0 feature, control whether to embed thumbnail (max 320x320 pixels) +``` + ++ Swift + +```swift +// HEIF image thumbnail encoding +let image: UIImage +let thumbnailData = SDImageHEIFCoder.shared.encodedData(with: image, format: .heif, options: [.encodeMaxPixelSize: CGSize(width: 200, height: 200), .encodeEmbedThumbnail : true]) +// v0.8.0 feature, encoding max pixel size +// v0.9.0 feature, control whether to embed thumbnail (max 320x320 pixels) +``` + +See more documentation in [SDWebImage Wiki - Coders](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-coder-420) ## Screenshot - + + The images are from [HEIF official site example](http://nokiatech.github.io/heif/examples.html) diff --git a/SDWebImageHEIFCoder.podspec b/SDWebImageHEIFCoder.podspec index 00bc3f2..604ffb3 100644 --- a/SDWebImageHEIFCoder.podspec +++ b/SDWebImageHEIFCoder.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'SDWebImageHEIFCoder' - s.version = '0.1.4' + s.version = '0.10.1' s.summary = 'A SDWebImage coder plugin to support HEIF image' s.description = <<-DESC @@ -21,57 +21,37 @@ Which is built based on the open-sourced libheif codec. s.author = { 'DreamPiggy' => 'lizhuoli1126@126.com' } s.source = { :git => 'https://github.com/SDWebImage/SDWebImageHEIFCoder.git', :tag => s.version.to_s, :submodules => true } - s.osx.deployment_target = '10.9' - s.ios.deployment_target = '8.0' + s.osx.deployment_target = '10.11' + s.ios.deployment_target = '9.0' s.tvos.deployment_target = '9.0' s.watchos.deployment_target = '2.0' - s.default_subspecs = 'libheif', 'libde265' + s.module_map = 'SDWebImageHEIFCoder/Module/SDWebImageHEIFCoder.modulemap' + s.default_subspec = 'libde265' # HEIF core dependency s.subspec 'libheif' do |ss| - ss.source_files = 'Vendors/libheif/libheif/*.{h,c,cc}', 'Vendors/include/libheif/*.h', 'SDWebImageHEIFCoder/Classes/**/*' - ss.exclude_files = 'Vendors/libheif/libheif/*fuzzer.{h,c,cc}', 'Vendors/libheif/libheif/heif.h', 'Vendors/libheif/libheif/heif_decoder_libde265.{h,c,cc}', 'Vendors/libheif/libheif/heif_encoder_x265.{h,c,cc}' - ss.public_header_files = 'Vendors/include/libheif/*.h', 'SDWebImageHEIFCoder/Classes/**/*.h' - ss.preserve_path = 'Vendors/include' - ss.xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) HAVE_UNISTD_H=1', - 'HEADER_SEARCH_PATHS' => '$(inherited) ${PODS_ROOT}/SDWebImageHEIFCoder/Vendors/include ${PODS_ROOT}/SDWebImageHEIFCoder/Vendors/include/libx265 ${PODS_TARGET_SRCROOT}/Vendors/include ${PODS_TARGET_SRCROOT}/Vendors/include/libx265' - } - ss.libraries = 'c++' + ss.dependency 'libheif/libheif', '>= 1.6.0' + ss.source_files = 'SDWebImageHEIFCoder/Classes/**/*', 'SDWebImageHEIFCoder/Module/SDWebImageHEIFCoder.h' end # HEIF Decoding need libde265 s.subspec 'libde265' do |ss| + ss.dependency 'libheif/libde265' ss.dependency 'SDWebImageHEIFCoder/libheif' - ss.source_files = 'Vendors/include/libde265/*.{h}', 'Vendors/libheif/libheif/heif_decoder_libde265.{h,c,cc}' - ss.public_header_files = 'Vendors/include/libde265/*.{h}' - ss.osx.vendored_libraries = 'Vendors/libde265/macOS/libde265.a' - ss.ios.vendored_libraries = 'Vendors/libde265/iOS/libde265.a' - ss.tvos.vendored_libraries = 'Vendors/libde265/tvOS/libde265.a' - ss.watchos.vendored_libraries = 'Vendors/libde265/watchOS/libde265.a' - ss.preserve_path = 'Vendors/include' ss.xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) HAVE_LIBDE265=1', - 'HEADER_SEARCH_PATHS' => '$(inherited) ${PODS_ROOT}/SDWebImageHEIFCoder/Vendors/include' + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) HAVE_LIBDE265=1' } end # HEIF Encoding need libx265 s.subspec 'libx265' do |ss| + ss.dependency 'libheif/libx265' ss.dependency 'SDWebImageHEIFCoder/libheif' - ss.source_files = 'Vendors/include/libx265/*.{h}', 'Vendors/libheif/libheif/heif_encoder_x265.{h,c,cc}' - ss.public_header_files = 'Vendors/include/libx265/*.{h}' - ss.osx.vendored_libraries = 'Vendors/libx265/macOS/libx265.a' - ss.ios.vendored_libraries = 'Vendors/libx265/iOS/libx265.a' - ss.tvos.vendored_libraries = 'Vendors/libx265/tvOS/libx265.a' - ss.watchos.vendored_libraries = 'Vendors/libx265/watchOS/libx265.a' - ss.preserve_path = 'Vendors/include' ss.xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) HAVE_X265=1', - 'HEADER_SEARCH_PATHS' => '$(inherited) ${PODS_ROOT}/SDWebImageHEIFCoder/Vendors/include' + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) HAVE_X265=1' } end - s.dependency 'SDWebImage/Core', '~> 4.2' + s.dependency 'SDWebImage/Core', '~> 5.10' end diff --git a/SDWebImageHEIFCoder.xcodeproj/project.pbxproj b/SDWebImageHEIFCoder.xcodeproj/project.pbxproj index 1515ec4..58e8eb3 100644 --- a/SDWebImageHEIFCoder.xcodeproj/project.pbxproj +++ b/SDWebImageHEIFCoder.xcodeproj/project.pbxproj @@ -7,14 +7,21 @@ objects = { /* Begin PBXBuildFile section */ - 326D0EDD21CE36B200EBA412 /* SDWebImageHEIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 326D0EDB21CE36B200EBA412 /* SDWebImageHEIFCoder.m */; }; - 326D0EDE21CE36B200EBA412 /* SDWebImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 326D0EDC21CE36B200EBA412 /* SDWebImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 323CCB1321CE5F1700F77FB1 /* SDImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 323CCB0D21CE5F1700F77FB1 /* SDImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 323CCB1421CE5F1700F77FB1 /* SDImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 323CCB0D21CE5F1700F77FB1 /* SDImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 323CCB1521CE5F1700F77FB1 /* SDImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 323CCB0D21CE5F1700F77FB1 /* SDImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 323CCB1621CE5F1700F77FB1 /* SDImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 323CCB0D21CE5F1700F77FB1 /* SDImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 323CCB1721CE5F1700F77FB1 /* SDImageHEIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 323CCB0E21CE5F1700F77FB1 /* SDImageHEIFCoder.m */; }; + 323CCB1821CE5F1700F77FB1 /* SDImageHEIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 323CCB0E21CE5F1700F77FB1 /* SDImageHEIFCoder.m */; }; + 323CCB1921CE5F1700F77FB1 /* SDImageHEIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 323CCB0E21CE5F1700F77FB1 /* SDImageHEIFCoder.m */; }; + 323CCB1A21CE5F1700F77FB1 /* SDImageHEIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 323CCB0E21CE5F1700F77FB1 /* SDImageHEIFCoder.m */; }; + 323CCB2121CE5F4400F77FB1 /* SDWebImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 323CCB2021CE5F4300F77FB1 /* SDWebImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 323CCB2221CE5F4400F77FB1 /* SDWebImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 323CCB2021CE5F4300F77FB1 /* SDWebImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 323CCB2321CE5F4400F77FB1 /* SDWebImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 323CCB2021CE5F4300F77FB1 /* SDWebImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 323CCB2421CE5F4400F77FB1 /* SDWebImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 323CCB2021CE5F4300F77FB1 /* SDWebImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 326D0EE121CE394100EBA412 /* SDWebImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 326D0EE021CE394100EBA412 /* SDWebImage.framework */; }; 326D0EE321CE394A00EBA412 /* libheif.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 326D0EE221CE394A00EBA412 /* libheif.framework */; }; 326D0EE521CE395300EBA412 /* libde265.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 326D0EE421CE395300EBA412 /* libde265.framework */; }; - 326D0F0D21CE3EBA00EBA412 /* SDWebImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 326D0EDC21CE36B200EBA412 /* SDWebImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 326D0F0E21CE3EBB00EBA412 /* SDWebImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 326D0EDC21CE36B200EBA412 /* SDWebImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 326D0F0F21CE3EBB00EBA412 /* SDWebImageHEIFCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 326D0EDC21CE36B200EBA412 /* SDWebImageHEIFCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 326D0F1121CE3EE200EBA412 /* SDWebImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 326D0F1021CE3EE200EBA412 /* SDWebImage.framework */; }; 326D0F1321CE3EEC00EBA412 /* libheif.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 326D0F1221CE3EEC00EBA412 /* libheif.framework */; }; 326D0F1621CE3F0300EBA412 /* libde265.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 326D0F1521CE3F0300EBA412 /* libde265.framework */; }; @@ -24,16 +31,14 @@ 326D0F2021CE3F2300EBA412 /* SDWebImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 326D0F1D21CE3F2300EBA412 /* SDWebImage.framework */; }; 326D0F2121CE3F2300EBA412 /* libheif.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 326D0F1E21CE3F2300EBA412 /* libheif.framework */; }; 326D0F2221CE3F2300EBA412 /* libde265.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 326D0F1F21CE3F2300EBA412 /* libde265.framework */; }; - 326D0F2321CE3F7A00EBA412 /* SDWebImageHEIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 326D0EDB21CE36B200EBA412 /* SDWebImageHEIFCoder.m */; }; - 326D0F2421CE3F7A00EBA412 /* SDWebImageHEIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 326D0EDB21CE36B200EBA412 /* SDWebImageHEIFCoder.m */; }; - 326D0F2521CE3F7B00EBA412 /* SDWebImageHEIFCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 326D0EDB21CE36B200EBA412 /* SDWebImageHEIFCoder.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 323CCB0D21CE5F1700F77FB1 /* SDImageHEIFCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDImageHEIFCoder.h; sourceTree = ""; }; + 323CCB0E21CE5F1700F77FB1 /* SDImageHEIFCoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImageHEIFCoder.m; sourceTree = ""; }; + 323CCB2021CE5F4300F77FB1 /* SDWebImageHEIFCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDWebImageHEIFCoder.h; path = Module/SDWebImageHEIFCoder.h; sourceTree = ""; }; 326D0EC321CE359400EBA412 /* SDWebImageHEIFCoder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImageHEIFCoder.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 326D0ED921CE36AA00EBA412 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Module/Info.plist; sourceTree = ""; }; - 326D0EDB21CE36B200EBA412 /* SDWebImageHEIFCoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDWebImageHEIFCoder.m; path = Classes/SDWebImageHEIFCoder.m; sourceTree = ""; }; - 326D0EDC21CE36B200EBA412 /* SDWebImageHEIFCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDWebImageHEIFCoder.h; path = Classes/SDWebImageHEIFCoder.h; sourceTree = ""; }; 326D0EE021CE394100EBA412 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/iOS/SDWebImage.framework; sourceTree = ""; }; 326D0EE221CE394A00EBA412 /* libheif.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libheif.framework; path = Carthage/Build/iOS/libheif.framework; sourceTree = ""; }; 326D0EE421CE395300EBA412 /* libde265.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = libde265.framework; path = Carthage/Build/iOS/libde265.framework; sourceTree = ""; }; @@ -95,6 +100,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 323CCB0B21CE5F1700F77FB1 /* Classes */ = { + isa = PBXGroup; + children = ( + 323CCB0D21CE5F1700F77FB1 /* SDImageHEIFCoder.h */, + 323CCB0E21CE5F1700F77FB1 /* SDImageHEIFCoder.m */, + ); + path = Classes; + sourceTree = ""; + }; 326D0EB921CE359400EBA412 = { isa = PBXGroup; children = ( @@ -118,8 +132,8 @@ 326D0EC521CE359400EBA412 /* SDWebImageHEIFCoder */ = { isa = PBXGroup; children = ( - 326D0EDC21CE36B200EBA412 /* SDWebImageHEIFCoder.h */, - 326D0EDB21CE36B200EBA412 /* SDWebImageHEIFCoder.m */, + 323CCB0B21CE5F1700F77FB1 /* Classes */, + 323CCB2021CE5F4300F77FB1 /* SDWebImageHEIFCoder.h */, 326D0ED921CE36AA00EBA412 /* Info.plist */, ); path = SDWebImageHEIFCoder; @@ -151,7 +165,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 326D0EDE21CE36B200EBA412 /* SDWebImageHEIFCoder.h in Headers */, + 323CCB2121CE5F4400F77FB1 /* SDWebImageHEIFCoder.h in Headers */, + 323CCB1321CE5F1700F77FB1 /* SDImageHEIFCoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -159,7 +174,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 326D0F0D21CE3EBA00EBA412 /* SDWebImageHEIFCoder.h in Headers */, + 323CCB2221CE5F4400F77FB1 /* SDWebImageHEIFCoder.h in Headers */, + 323CCB1421CE5F1700F77FB1 /* SDImageHEIFCoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -167,7 +183,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 326D0F0E21CE3EBB00EBA412 /* SDWebImageHEIFCoder.h in Headers */, + 323CCB2321CE5F4400F77FB1 /* SDWebImageHEIFCoder.h in Headers */, + 323CCB1521CE5F1700F77FB1 /* SDImageHEIFCoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -175,7 +192,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 326D0F0F21CE3EBB00EBA412 /* SDWebImageHEIFCoder.h in Headers */, + 323CCB2421CE5F4400F77FB1 /* SDWebImageHEIFCoder.h in Headers */, + 323CCB1621CE5F1700F77FB1 /* SDImageHEIFCoder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -332,7 +350,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 326D0EDD21CE36B200EBA412 /* SDWebImageHEIFCoder.m in Sources */, + 323CCB1721CE5F1700F77FB1 /* SDImageHEIFCoder.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -340,7 +358,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 326D0F2321CE3F7A00EBA412 /* SDWebImageHEIFCoder.m in Sources */, + 323CCB1821CE5F1700F77FB1 /* SDImageHEIFCoder.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -348,7 +366,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 326D0F2421CE3F7A00EBA412 /* SDWebImageHEIFCoder.m in Sources */, + 323CCB1921CE5F1700F77FB1 /* SDImageHEIFCoder.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -356,7 +374,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 326D0F2521CE3F7B00EBA412 /* SDWebImageHEIFCoder.m in Sources */, + 323CCB1A21CE5F1700F77FB1 /* SDImageHEIFCoder.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -415,13 +433,16 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; + TVOS_DEPLOYMENT_TARGET = 9.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; }; @@ -471,13 +492,16 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; + TVOS_DEPLOYMENT_TARGET = 9.0; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; }; @@ -501,7 +525,6 @@ ); INFOPLIST_FILE = "$(SRCROOT)/SDWebImageHEIFCoder/Module/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -530,7 +553,6 @@ GCC_PREPROCESSOR_DEFINITIONS = HAVE_LIBDE265; INFOPLIST_FILE = "$(SRCROOT)/SDWebImageHEIFCoder/Module/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -571,7 +593,6 @@ "@executable_path/../Frameworks", "@loader_path/Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.9; PRODUCT_BUNDLE_IDENTIFIER = "com.SDWebImage.SDWebImageHEIFCoder-macOS"; PRODUCT_MODULE_NAME = SDWebImageHEIFCoder; PRODUCT_NAME = SDWebImageHEIFCoder; @@ -604,7 +625,6 @@ "@executable_path/../Frameworks", "@loader_path/Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.9; PRODUCT_BUNDLE_IDENTIFIER = "com.SDWebImage.SDWebImageHEIFCoder-macOS"; PRODUCT_MODULE_NAME = SDWebImageHEIFCoder; PRODUCT_NAME = SDWebImageHEIFCoder; @@ -644,7 +664,6 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Debug; }; @@ -675,7 +694,6 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Release; }; @@ -711,7 +729,6 @@ SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; }; @@ -743,7 +760,6 @@ SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; }; diff --git a/SDWebImageHEIFCoder/Classes/SDImageHEIFCoder.h b/SDWebImageHEIFCoder/Classes/SDImageHEIFCoder.h new file mode 100644 index 0000000..582797e --- /dev/null +++ b/SDWebImageHEIFCoder/Classes/SDImageHEIFCoder.h @@ -0,0 +1,18 @@ +// +// SDImageHEIFCoder.h +// SDWebImageHEIFCoder +// +// Created by lizhuoli on 2018/5/8. +// + +#if __has_include() +#import +#else +@import SDWebImage; +#endif + +@interface SDImageHEIFCoder : NSObject + +@property (nonatomic, class, readonly, nonnull) SDImageHEIFCoder *sharedCoder; + +@end diff --git a/SDWebImageHEIFCoder/Classes/SDImageHEIFCoder.m b/SDWebImageHEIFCoder/Classes/SDImageHEIFCoder.m new file mode 100644 index 0000000..dc262fc --- /dev/null +++ b/SDWebImageHEIFCoder/Classes/SDImageHEIFCoder.m @@ -0,0 +1,616 @@ +// +// SDImageHEIFCoder.m +// SDWebImageHEIFCoder +// +// Created by lizhuoli on 2018/5/8. +// + +#import "SDImageHEIFCoder.h" +#if __has_include() +#import +#else +#import "heif.h" +#endif +#import + +typedef struct heif_context heif_context; +typedef struct heif_image_handle heif_image_handle; +typedef struct heif_image heif_image; +typedef struct heif_encoder heif_encoder; +typedef struct heif_writer heif_writer; +typedef struct heif_error heif_error; +typedef enum heif_chroma heif_chroma; +typedef enum heif_channel heif_channel; +typedef enum heif_colorspace heif_colorspace; +typedef enum heif_color_profile_type heif_color_profile_type; + +static int HEIFMaxThumbnailPixelSize = 320; // Max Limit to thumbnail. This value is from Image/IO decompile result, which is also hardcoded :) +//static const char kMetadataTypeExif[] = "Exif"; + +static heif_error WriteImageData(heif_context * ctx, const void * data, size_t size, void * userdata) { + NSMutableData *imageData = (__bridge NSMutableData *)userdata; + NSCParameterAssert(imageData); + NSCParameterAssert(data); + + [imageData appendBytes:data length:size]; + + // OK + heif_error error; + error.code = heif_error_Ok; + error.subcode = heif_suberror_Unspecified; + error.message = "Success"; + return error; +} + +static void FreeImageData(void *info, const void *data, size_t size) { + heif_image *img = (heif_image *)info; + heif_image_release(img); // `heif_image_release` will free the bitmap buffer. We do not call `free` +} + +//static uint8_t *GetExifMetaData(const heif_image_handle* handle, size_t* size) { +// // Sample code from: https://github.com/strukturag/libheif/blob/v1.11.0/examples/encoder.cc +// heif_item_id metadata_id; +// int count = heif_image_handle_get_list_of_metadata_block_IDs(handle, kMetadataTypeExif, +// &metadata_id, 1); +// +// for (int i = 0; i < count; i++) { +// size_t datasize = heif_image_handle_get_metadata_size(handle, metadata_id); +// uint8_t* data = malloc(datasize); +// if (!data) { +// continue; +// } +// +// heif_error error = heif_image_handle_get_metadata(handle, metadata_id, data); +// if (error.code != heif_error_Ok) { +// free(data); +// continue; +// } +// +// *size = datasize; +// return data; +// } +// +// return NULL; +//} + +/// Calculate the actual thumnail pixel size +static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio, CGSize thumbnailSize) { + CGFloat width = fullSize.width; + CGFloat height = fullSize.height; + CGFloat resultWidth; + CGFloat resultHeight; + + if (width == 0 || height == 0 || thumbnailSize.width == 0 || thumbnailSize.height == 0 || (width <= thumbnailSize.width && height <= thumbnailSize.height)) { + // Full Pixel + resultWidth = width; + resultHeight = height; + } else { + // Thumbnail + if (preserveAspectRatio) { + CGFloat pixelRatio = width / height; + CGFloat thumbnailRatio = thumbnailSize.width / thumbnailSize.height; + if (pixelRatio > thumbnailRatio) { + resultWidth = thumbnailSize.width; + resultHeight = ceil(thumbnailSize.width / pixelRatio); + } else { + resultHeight = thumbnailSize.height; + resultWidth = ceil(thumbnailSize.height * pixelRatio); + } + } else { + resultWidth = thumbnailSize.width; + resultHeight = thumbnailSize.height; + } + } + + return CGSizeMake(resultWidth, resultHeight); +} + +@implementation SDImageHEIFCoder + ++ (instancetype)sharedCoder { + static SDImageHEIFCoder *coder; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + coder = [[SDImageHEIFCoder alloc] init]; + }); + return coder; +} + +- (BOOL)canDecodeFromData:(NSData *)data { +#if HAVE_LIBDE265 + return [[self class] isHEIFFormatForData:data]; +#else + return NO; +#endif +} + +- (UIImage *)decodedImageWithData:(NSData *)data options:(SDImageCoderOptions *)options { + if (!data) { + return nil; + } + CGFloat scale = 1; + if ([options valueForKey:SDImageCoderDecodeScaleFactor]) { + scale = [[options valueForKey:SDImageCoderDecodeScaleFactor] doubleValue]; + if (scale < 1) { + scale = 1; + } + } + + CGSize thumbnailSize = CGSizeZero; + NSValue *thumbnailSizeValue = options[SDImageCoderDecodeThumbnailPixelSize]; + if (thumbnailSizeValue != nil) { +#if SD_MAC + thumbnailSize = thumbnailSizeValue.sizeValue; +#else + thumbnailSize = thumbnailSizeValue.CGSizeValue; +#endif + } + + BOOL preserveAspectRatio = YES; + NSNumber *preserveAspectRatioValue = options[SDImageCoderDecodePreserveAspectRatio]; + if (preserveAspectRatioValue != nil) { + preserveAspectRatio = preserveAspectRatioValue.boolValue; + } + + // Currently only support primary image :) + CGImageRef imageRef = [self sd_createHEIFImageWithData:data thumbnailSize:thumbnailSize preserveAspectRatio:preserveAspectRatio]; + if (!imageRef) { + return nil; + } + +#if SD_MAC + UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:kCGImagePropertyOrientationUp]; +#else + UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp]; +#endif + CGImageRelease(imageRef); + + return image; +} + +// Only decode the primary image (HEIF also support tied-image and animated image) +- (nullable CGImageRef)sd_createHEIFImageWithData:(nonnull NSData *)data thumbnailSize:(CGSize)thumbnailSize preserveAspectRatio:(BOOL)preserveAspectRatio CF_RETURNS_RETAINED { + heif_context* ctx = heif_context_alloc(); + if (!ctx) { + return nil; + } + + const void *bytes = data.bytes; + const size_t size = data.length; + heif_error error = heif_context_read_from_memory(ctx, bytes, size, NULL); + if (error.code != heif_error_Ok) { + heif_context_free(ctx); + return nil; + } + + // get a handle to the primary image + heif_image_handle* handle; + error = heif_context_get_primary_image_handle(ctx, &handle); + if (error.code != heif_error_Ok) { + heif_context_free(ctx); + return nil; + } + + // check thumbnail firstly + if (thumbnailSize.width > 0 && thumbnailSize.height > 0) { + heif_item_id thumbnailID; + int thumbnailCount = heif_image_handle_get_list_of_thumbnail_IDs(handle, &thumbnailID, 1); + if (thumbnailCount > 0) { + heif_image_handle *thumbnailHandle; + error = heif_image_handle_get_thumbnail(handle, thumbnailID, &thumbnailHandle); + if (error.code != heif_error_Ok) { + heif_image_handle_release(handle); + heif_context_free(ctx); + return nil; + } + + int handleWidth = heif_image_handle_get_width(thumbnailHandle); + int handleHeight = heif_image_handle_get_height(thumbnailHandle); + if (handleWidth < thumbnailSize.width && handleHeight < thumbnailSize.height) { + // use full image to scale down if pixel size is smaller than thumbnail size + heif_image_handle_release(thumbnailHandle); + } else { + // else, the thumbnail is large enough to directly use + heif_image_handle_release(handle); + handle = thumbnailHandle; + } + } + } + + CGImageRef imageRef = [self sd_createFrameWithImageHandle:handle thumbnailSize:thumbnailSize preserveAspectRatio:preserveAspectRatio]; + + // clean up + heif_image_handle_release(handle); + heif_context_free(ctx); + + return imageRef; +} + +- (nullable CGImageRef)sd_createFrameWithImageHandle:(heif_image_handle *)handle thumbnailSize:(CGSize)thumbnailSize preserveAspectRatio:(BOOL)preserveAspectRatio CF_RETURNS_RETAINED { + heif_error error; + + // check alpha channel + BOOL hasAlpha = heif_image_handle_has_alpha_channel(handle); + int depth = heif_image_handle_get_chroma_bits_per_pixel(handle); + BOOL hasHighDepth = depth > 8; + heif_chroma chroma; + if (hasAlpha) { + if (hasHighDepth) { + chroma = heif_chroma_interleaved_RRGGBB_BE; + } else { + chroma = heif_chroma_interleaved_RGBA; + } + } else { + if (hasHighDepth) { + chroma = heif_chroma_interleaved_RRGGBBAA_BE; + } else { + chroma = heif_chroma_interleaved_RGB; + } + } + + // decode the image and convert colorspace to RGB/RGBA, saved as 24bit/32bit interleaved + heif_image* img; + error = heif_decode_image(handle, &img, heif_colorspace_RGB, chroma, NULL); + if (error.code != heif_error_Ok) { + return nil; + } + + int handleWidth = heif_image_handle_get_width(handle); + int handleHeight = heif_image_handle_get_height(handle); + CGSize scaledSize = SDCalculateThumbnailSize(CGSizeMake(handleWidth, handleHeight), preserveAspectRatio, thumbnailSize); + // use scaling for thumbnail + if (scaledSize.width > 0 && scaledSize.height > 0 && scaledSize.width != handleWidth && scaledSize.height != handleHeight) { + heif_image *scaled_img; + error = heif_image_scale_image(img, &scaled_img, scaledSize.width, scaledSize.height, NULL); + heif_image_release(img); + if (error.code != heif_error_Ok) { + return nil; + } + img = scaled_img; + } + + int width, height, stride, bitsPerPixel, bitsPerComponent; + width = heif_image_get_width(img, heif_channel_interleaved); + height = heif_image_get_height(img, heif_channel_interleaved); + bitsPerPixel = heif_image_get_bits_per_pixel(img, heif_channel_interleaved); + bitsPerComponent = hasHighDepth ? 16 : 8; + CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; + bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNone; + + const uint8_t *rgba = heif_image_get_plane_readonly(img, heif_channel_interleaved, &stride); + if (!rgba) { + heif_image_release(img); + return nil; + } + CGDataProviderRef provider = + CGDataProviderCreateWithData(img, rgba, stride * height, FreeImageData); + + CGColorSpaceRef colorSpaceRef = [self sd_createColorSpaceWithImageHandle:handle]; + CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; + CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, stride, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); + + // clean up + CGDataProviderRelease(provider); + CGColorSpaceRelease(colorSpaceRef); + + return imageRef; +} + +// Create and return the correct colorspace by checking the ICC Profile +- (nonnull CGColorSpaceRef)sd_createColorSpaceWithImageHandle:(heif_image_handle *)handle CF_RETURNS_RETAINED { + CGColorSpaceRef colorSpaceRef = NULL; + + heif_error error; + size_t profile_size = 0; + uint8_t profile_buffer = NULL; + heif_color_profile_type profileType = heif_image_handle_get_color_profile_type(handle); + + if (profileType != heif_color_profile_type_not_present) { + error = heif_image_get_raw_color_profile(handle, &profile_buffer); + if (error.code == heif_error_Ok) { + profile_size = heif_image_handle_get_raw_color_profile_size(handle); + } else { + profile_buffer = NULL; + } + } + + if (profile_buffer) { + NSData *profileData = [NSData dataWithBytes:profile_buffer length:profile_size]; + if (@available(iOS 10, tvOS 10, macOS 10.12, watchOS 3, *)) { + colorSpaceRef = CGColorSpaceCreateWithICCData((__bridge CFDataRef)profileData); + } else { + colorSpaceRef = CGColorSpaceCreateWithICCProfile((__bridge CFDataRef)profileData); + } + if (colorSpaceRef) { + // We use RGB color model to decode HEIF images currently, so we must filter out other colorSpace + CGColorSpaceModel model = CGColorSpaceGetModel(colorSpaceRef); + if (model != kCGColorSpaceModelRGB) { + CGColorSpaceRelease(colorSpaceRef); + colorSpaceRef = NULL; + } + } + } + + if (!colorSpaceRef) { + colorSpaceRef = [SDImageCoderHelper colorSpaceGetDeviceRGB]; + CGColorSpaceRetain(colorSpaceRef); + } + + return colorSpaceRef; +} + +// libheif contains initilial encoding support using libx265, but currently is not fully support +- (BOOL)canEncodeToFormat:(SDImageFormat)format { + if (format == SDImageFormatHEIC || format == SDImageFormatHEIF) { +#if HAVE_X265 + return YES; +#else + return NO; +#endif + } + return NO; +} + +- (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(SDImageCoderOptions *)options { + if (!image) { + return nil; + } + + NSData *data; + + double compressionQuality = 1; + if ([options valueForKey:SDImageCoderEncodeCompressionQuality]) { + compressionQuality = [[options valueForKey:SDImageCoderEncodeCompressionQuality] doubleValue]; + } + CGSize maxPixelSize = CGSizeZero; + NSValue *maxPixelSizeValue = options[SDImageCoderEncodeMaxPixelSize]; + if (maxPixelSizeValue != nil) { +#if SD_MAC + maxPixelSize = maxPixelSizeValue.sizeValue; +#else + maxPixelSize = maxPixelSizeValue.CGSizeValue; +#endif + } + NSUInteger maxFileSize = 0; + if (options[SDImageCoderEncodeMaxFileSize]) { + maxFileSize = [options[SDImageCoderEncodeMaxFileSize] unsignedIntegerValue]; + } + BOOL embedThumbnail = NO; + if (options[SDImageCoderEncodeEmbedThumbnail]) { + embedThumbnail = options[SDImageCoderEncodeEmbedThumbnail]; + } + + data = [self sd_encodedHEIFDataWithImage:image quality:compressionQuality maxPixelSize:maxPixelSize maxFileSize:maxFileSize embedThumbnail:embedThumbnail]; + + return data; +} + +- (nullable NSData *)sd_encodedHEIFDataWithImage:(nonnull UIImage *)image quality:(double)quality maxPixelSize:(CGSize)maxPixelSize maxFileSize:(NSUInteger)maxFileSize embedThumbnail:(BOOL)embedThumbnail { + CGImageRef imageRef = image.CGImage; + if (!imageRef) { + return nil; + } + + size_t width = CGImageGetWidth(imageRef); + size_t height = CGImageGetHeight(imageRef); + CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); + CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask; + CGBitmapInfo byteOrderInfo = bitmapInfo & kCGBitmapByteOrderMask; + BOOL hasAlpha = !(alphaInfo == kCGImageAlphaNone || + alphaInfo == kCGImageAlphaNoneSkipFirst || + alphaInfo == kCGImageAlphaNoneSkipLast); + BOOL byteOrderNormal = NO; + switch (byteOrderInfo) { + case kCGBitmapByteOrderDefault: { + byteOrderNormal = YES; + } break; + case kCGBitmapByteOrder32Little: { + } break; + case kCGBitmapByteOrder32Big: { + byteOrderNormal = YES; + } break; + default: break; + } + + heif_context* ctx = heif_context_alloc(); + if (!ctx) { + return nil; + } + heif_error error; + + // get the default encoder + heif_encoder* encoder; + error = heif_context_get_encoder_for_format(ctx, heif_compression_HEVC, &encoder); + if (error.code != heif_error_Ok) { + heif_context_free(ctx); + return nil; + } + + // set the encoder parameters + if (maxFileSize > 0) { + // if we want to actually the limit bytes, use ABR to limit bitrate + // I'm not professional in x265 video encoding, learn more: https://slhck.info/video/2017/03/01/rate-control.html + unsigned long bitrate = maxFileSize * 8 / 1000; // kbps, 1 second + size_t length = snprintf(NULL, 0, "%d", bitrate); + char *bitrate_str = malloc(length + 1); + snprintf(bitrate_str, length + 1, "%d", bitrate); + heif_encoder_set_parameter(encoder, "x265:bitrate", bitrate_str); + heif_encoder_set_parameter(encoder, "x265:vbv-maxrate", bitrate_str); + heif_encoder_set_parameter(encoder, "x265:vbv-bufsize", bitrate_str); + free(bitrate_str); + } else { + // else use the CRF quality (libheif's default quality params) + heif_encoder_set_lossy_quality(encoder, quality * 100); + } + + // libheif supports RGB888/RGBA8888 color mode, convert all to this + vImageConverterRef convertor = NULL; + vImage_Error v_error = kvImageNoError; + + size_t bitsPerPixel = hasAlpha ? 32 : 24; + size_t bytesPerRow = (width * bitsPerPixel + 7) / 8; + // use 16 byte alignment, see libheif's source code heif_image.cc :) + int alignment = 16; // must be power of two + bytesPerRow = (bytesPerRow+alignment-1) & ~(alignment-1); + + vImage_CGImageFormat srcFormat = { + .bitsPerComponent = (uint32_t)CGImageGetBitsPerComponent(imageRef), + .bitsPerPixel = (uint32_t)CGImageGetBitsPerPixel(imageRef), + .colorSpace = CGImageGetColorSpace(imageRef), + .bitmapInfo = bitmapInfo, + .renderingIntent = CGImageGetRenderingIntent(imageRef) + }; + vImage_CGImageFormat destFormat = { + .bitsPerComponent = 8, + .bitsPerPixel = bitsPerPixel, + .colorSpace = [SDImageCoderHelper colorSpaceGetDeviceRGB], + .bitmapInfo = hasAlpha ? kCGImageAlphaLast | kCGBitmapByteOrderDefault : kCGImageAlphaNone | kCGBitmapByteOrderDefault // RGB888/RGBA8888 (Non-premultiplied to works for libheif) + }; + + convertor = vImageConverter_CreateWithCGImageFormat(&srcFormat, &destFormat, NULL, kvImageNoFlags, &v_error); + if (v_error != kvImageNoError) { + heif_context_free(ctx); + return nil; + } + + vImage_Buffer src; + v_error = vImageBuffer_InitWithCGImage(&src, &srcFormat, NULL, imageRef, kvImageNoFlags); + if (v_error != kvImageNoError) { + heif_context_free(ctx); + return nil; + } + vImage_Buffer dest = { + .width = width, + .height = height, + .rowBytes = bytesPerRow, + .data = malloc(height * bytesPerRow) // It seems that libheif does not keep 32/64 byte alignment, however, vImage's `vImageBuffer_Init` does. So manually alloc buffer + }; + if (!dest.data) { + free(src.data); + vImageConverter_Release(convertor); + heif_context_free(ctx); + return nil; + } + + // Convert input color mode to RGB888/RGBA8888 + v_error = vImageConvert_AnyToAny(convertor, &src, &dest, NULL, kvImageNoFlags); + vImageConverter_Release(convertor); + if (v_error != kvImageNoError) { + free(src.data); + free(dest.data); + heif_context_free(ctx); + return nil; + } + + free(src.data); + void * rgba = dest.data; // Converted buffer + + // code to fill in the image + heif_chroma chroma = hasAlpha ? heif_chroma_interleaved_RGBA : heif_chroma_interleaved_RGB; + heif_colorspace colorspace = heif_colorspace_RGB; + heif_image* img; + error = heif_image_create((int)width, (int)height, colorspace, chroma, &img); + if (error.code != heif_error_Ok) { + free(rgba); + heif_encoder_release(encoder); + heif_context_free(ctx); + return nil; + } + + // add the plane + heif_channel channel = heif_channel_interleaved; + error = heif_image_add_plane(img, channel, (int)width, (int)height, (int)bitsPerPixel); + if (error.code != heif_error_Ok) { + free(rgba); + heif_encoder_release(encoder); + heif_context_free(ctx); + return nil; + } + + // fill the plane + int stride; + uint8_t *planar = heif_image_get_plane(img, channel, &stride); + planar = rgba; + + // check thumbnail encoding + int ctuSize = 64; + // x265 cannot encode images smaller than one CTU size + // https://bitbucket.org/multicoreware/x265/issues/475/x265-does-not-allow-image-sizes-smaller + // -> use smaller CTU sizes for very small images + if (maxPixelSize.width > 0 && maxPixelSize.height > 0 && width >= ctuSize && height >= ctuSize) { + CGSize scaledSize = SDCalculateThumbnailSize(CGSizeMake(width, height), YES, maxPixelSize); + heif_image *thumbnail_img; + error = heif_image_scale_image(img, &thumbnail_img, (int)scaledSize.width, (int)scaledSize.height, NULL); + if (error.code != heif_error_Ok) { + free(rgba); + heif_image_release(img); + heif_encoder_release(encoder); + heif_context_free(ctx); + return nil; + } + heif_image_release(img); + img = thumbnail_img; + } + + // encode the image + heif_image_handle *handle; + error = heif_context_encode_image(ctx, img, encoder, NULL, &handle); + if (error.code != heif_error_Ok) { + free(rgba); + heif_image_release(img); + heif_encoder_release(encoder); + heif_context_free(ctx); + return nil; + } + + // support embed thumbnail image + if (embedThumbnail) { + heif_image *thumbnail_img = img; + CGSize scaledSize = SDCalculateThumbnailSize(CGSizeMake(width, height), YES, maxPixelSize); + int maxSize = HEIFMaxThumbnailPixelSize; + if (scaledSize.width > maxSize || scaledSize.height > maxSize) { + scaledSize = CGSizeMake(maxSize, maxSize); + } + error = heif_context_encode_thumbnail(ctx, img, handle, encoder, NULL, (int)MAX(scaledSize.width, scaledSize.height), NULL); + } + + NSMutableData *mutableData = [NSMutableData data]; + heif_writer writer; + writer.writer_api_version = 1; + writer.write = WriteImageData; // This is a function pointer + + error = heif_context_write(ctx, &writer, (__bridge void *)(mutableData)); + + // clean up + free(rgba); + heif_image_release(img); + heif_encoder_release(encoder); + heif_image_handle_release(handle); + heif_context_free(ctx); + + return [mutableData copy]; +} + +#pragma mark - Helper ++ (BOOL)isHEIFFormatForData:(NSData *)data +{ + if (!data) { + return NO; + } + if (data.length >= 12) { + //....ftypmif1 ....ftypmsf1 ....ftypheic ....ftypheix ....ftyphevc ....ftyphevx + NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding]; + if ([testString isEqualToString:@"ftypmif1"] + || [testString isEqualToString:@"ftypmsf1"] + || [testString isEqualToString:@"ftypheic"] + || [testString isEqualToString:@"ftypheix"] + || [testString isEqualToString:@"ftyphevc"] + || [testString isEqualToString:@"ftyphevx"]) { + return YES; + } + } + + return NO; +} + +@end diff --git a/SDWebImageHEIFCoder/Classes/SDWebImageHEIFCoder.h b/SDWebImageHEIFCoder/Classes/SDWebImageHEIFCoder.h deleted file mode 100644 index 8884ddf..0000000 --- a/SDWebImageHEIFCoder/Classes/SDWebImageHEIFCoder.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// SDWebImageHEIFCoder.h -// SDWebImageHEIFCoder -// -// Created by lizhuoli on 2018/5/8. -// - -#import - -@interface SDWebImageHEIFCoder : NSObject - -@property (nonatomic, class, readonly, nonnull) SDWebImageHEIFCoder *sharedCoder; - -@end diff --git a/SDWebImageHEIFCoder/Classes/SDWebImageHEIFCoder.m b/SDWebImageHEIFCoder/Classes/SDWebImageHEIFCoder.m deleted file mode 100644 index 2454114..0000000 --- a/SDWebImageHEIFCoder/Classes/SDWebImageHEIFCoder.m +++ /dev/null @@ -1,362 +0,0 @@ -// -// SDWebImageHEIFCoder.m -// SDWebImageHEIFCoder -// -// Created by lizhuoli on 2018/5/8. -// - -#import "SDWebImageHEIFCoder.h" -#if __has_include() -#import -#else -#import "heif.h" -#endif -#if SD_MAC -#import -#endif -#import - -typedef struct heif_context heif_context; -typedef struct heif_image_handle heif_image_handle; -typedef struct heif_image heif_image; -typedef struct heif_encoder heif_encoder; -typedef struct heif_writer heif_writer; -typedef struct heif_error heif_error; -typedef enum heif_chroma heif_chroma; -typedef enum heif_channel heif_channel; -typedef enum heif_colorspace heif_colorspace; - -static heif_error WriteImageData(heif_context * ctx, const void * data, size_t size, void * userdata) { - NSMutableData *imageData = (__bridge NSMutableData *)userdata; - NSCParameterAssert(imageData); - NSCParameterAssert(data); - - [imageData appendBytes:data length:size]; - - // OK - heif_error error; - error.code = heif_error_Ok; - error.subcode = heif_suberror_Unspecified; - error.message = "Success"; - return error; -} - -@implementation SDWebImageHEIFCoder - -+ (instancetype)sharedCoder { - static SDWebImageHEIFCoder *coder; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - coder = [[SDWebImageHEIFCoder alloc] init]; - }); - return coder; -} - -- (BOOL)canDecodeFromData:(NSData *)data { -#if HAVE_LIBDE265 - return [[self class] isHEIFFormatForData:data]; -#else - return NO; -#endif -} - -- (UIImage *)decodedImageWithData:(NSData *)data { - UIImage *image = nil; - if (!data) { - return nil; - } - - // Currently only support primary image :) - CGImageRef imageRef = [self sd_createHEIFImageWithData:data]; - if (!imageRef) { - return nil; - } - -#if SD_UIKIT || SD_WATCH - image = [[UIImage alloc] initWithCGImage:imageRef]; -#else - image = [[UIImage alloc] initWithCGImage:imageRef size:NSZeroSize]; -#endif - CGImageRelease(imageRef); - - return image; -} - -// Only decode the primary image (HEIF also support tied-image and still image) -- (nullable CGImageRef)sd_createHEIFImageWithData:(nonnull NSData *)data CF_RETURNS_RETAINED { - heif_context* ctx = heif_context_alloc(); - if (!ctx) { - return nil; - } - - const void *bytes = data.bytes; - const size_t size = data.length; - heif_error error = heif_context_read_from_memory(ctx, bytes, size, NULL); - if (error.code != heif_error_Ok) { - heif_context_free(ctx); - return nil; - } - - // get a handle to the primary image - heif_image_handle* handle; - error = heif_context_get_primary_image_handle(ctx, &handle); - if (error.code != heif_error_Ok) { - heif_context_free(ctx); - return nil; - } - - // check alpha channel - bool hasAlpha = heif_image_handle_has_alpha_channel(handle); - heif_chroma chroma = hasAlpha ? heif_chroma_interleaved_32bit : heif_chroma_interleaved_24bit; - - // decode the image and convert colorspace to RGB/RGBA, saved as 24bit/32bit interleaved - heif_image* img; - error = heif_decode_image(handle, &img, heif_colorspace_RGB, chroma, NULL); - if (error.code != heif_error_Ok) { - heif_image_handle_release(handle); - heif_context_free(ctx); - return nil; - } - - int width, height, stride, bitsPerPixel, bitsPerComponent; - width = heif_image_get_width(img, heif_channel_interleaved); - height = heif_image_get_height(img, heif_channel_interleaved); - bitsPerPixel = heif_image_get_bits_per_pixel(img, heif_channel_interleaved); - bitsPerComponent = 8; - CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; - bitmapInfo |= hasAlpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNone; - - const uint8_t *rgba = heif_image_get_plane_readonly(img, heif_channel_interleaved, &stride); - if (!rgba) { - heif_image_release(img); - heif_image_handle_release(handle); - heif_context_free(ctx); - return nil; - } - CGDataProviderRef provider = - CGDataProviderCreateWithData(NULL, rgba, stride * height, NULL); - - CGColorSpaceRef colorSpaceRef = SDCGColorSpaceGetDeviceRGB(); - CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; - CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, stride, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); - - // clean up - CGDataProviderRelease(provider); - heif_image_release(img); - heif_image_handle_release(handle); - heif_context_free(ctx); - - return imageRef; -} - -- (UIImage *)decompressedImageWithImage:(UIImage *)image data:(NSData *__autoreleasing _Nullable *)data options:(NSDictionary *)optionsDict { - return image; -} - -// libheif contains initilial encoding support using libx265, but currently is not fully support -- (BOOL)canEncodeToFormat:(SDImageFormat)format { - if (format == SDImageFormatHEIC) { -#if HAVE_X265 - return YES; -#else - return NO; -#endif - } - return NO; -} - -- (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format { - if (!image) { - return nil; - } - - NSData *data; - - double compressionQuality = 1; - - data = [self sd_encodedHEIFDataWithImage:image quality:compressionQuality]; - - return data; -} - -- (nullable NSData *)sd_encodedHEIFDataWithImage:(nonnull UIImage *)image quality:(double)quality { - CGImageRef imageRef = image.CGImage; - if (!imageRef) { - return nil; - } - - size_t width = CGImageGetWidth(imageRef); - size_t height = CGImageGetHeight(imageRef); - size_t bytesPerRow = CGImageGetBytesPerRow(imageRef); - size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef); - CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); - CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask; - CGBitmapInfo byteOrderInfo = bitmapInfo & kCGBitmapByteOrderMask; - BOOL hasAlpha = !(alphaInfo == kCGImageAlphaNone || - alphaInfo == kCGImageAlphaNoneSkipFirst || - alphaInfo == kCGImageAlphaNoneSkipLast); - BOOL byteOrderNormal = NO; - switch (byteOrderInfo) { - case kCGBitmapByteOrderDefault: { - byteOrderNormal = YES; - } break; - case kCGBitmapByteOrder32Little: { - } break; - case kCGBitmapByteOrder32Big: { - byteOrderNormal = YES; - } break; - default: break; - } - - heif_context* ctx = heif_context_alloc(); - if (!ctx) { - return nil; - } - heif_error error; - - // get the default encoder - heif_encoder* encoder; - error = heif_context_get_encoder_for_format(ctx, heif_compression_HEVC, &encoder); - if (error.code != heif_error_Ok) { - heif_context_free(ctx); - return nil; - } - - // set the encoder parameters - heif_encoder_set_lossy_quality(encoder, quality * 100); - - // libheif supports RGB888/RGBA8888 color mode, convert all to this - vImageConverterRef convertor = NULL; - vImage_Error v_error = kvImageNoError; - - vImage_CGImageFormat srcFormat = { - .bitsPerComponent = (uint32_t)CGImageGetBitsPerComponent(imageRef), - .bitsPerPixel = (uint32_t)CGImageGetBitsPerPixel(imageRef), - .colorSpace = CGImageGetColorSpace(imageRef), - .bitmapInfo = bitmapInfo - }; - vImage_CGImageFormat destFormat = { - .bitsPerComponent = 8, - .bitsPerPixel = hasAlpha ? 32 : 24, - .colorSpace = SDCGColorSpaceGetDeviceRGB(), - .bitmapInfo = hasAlpha ? kCGImageAlphaLast | kCGBitmapByteOrderDefault : kCGImageAlphaNone | kCGBitmapByteOrderDefault // RGB888/RGBA8888 (Non-premultiplied to works for libwebp) - }; - - convertor = vImageConverter_CreateWithCGImageFormat(&srcFormat, &destFormat, NULL, kvImageNoFlags, &v_error); - if (v_error != kvImageNoError) { - heif_context_free(ctx); - return nil; - } - - vImage_Buffer src; - v_error = vImageBuffer_InitWithCGImage(&src, &srcFormat, NULL, imageRef, kvImageNoFlags); - if (v_error != kvImageNoError) { - heif_context_free(ctx); - return nil; - } - vImage_Buffer dest = { - .width = width, - .height = height, - .rowBytes = bytesPerRow, - .data = malloc(height * bytesPerRow) // It seems that libheif does not keep 32/64 byte alignment, however, vImage's `vImageBuffer_Init` does. So manually alloc buffer - }; - if (!dest.data) { - free(src.data); - vImageConverter_Release(convertor); - heif_context_free(ctx); - return nil; - } - - // Convert input color mode to RGB888/RGBA8888 - v_error = vImageConvert_AnyToAny(convertor, &src, &dest, NULL, kvImageNoFlags); - vImageConverter_Release(convertor); - if (v_error != kvImageNoError) { - free(src.data); - free(dest.data); - heif_context_free(ctx); - return nil; - } - - free(src.data); - void * rgba = dest.data; // Converted buffer - - // code to fill in the image - heif_chroma chroma = hasAlpha ? heif_chroma_interleaved_RGBA : heif_chroma_interleaved_RGB; - heif_colorspace colorspace = heif_colorspace_RGB; - heif_image* img; - error = heif_image_create((int)width, (int)height, colorspace, chroma, &img); - if (error.code != heif_error_Ok) { - free(rgba); - heif_encoder_release(encoder); - heif_context_free(ctx); - return nil; - } - - // add the plane - heif_channel channel = heif_channel_interleaved; - error = heif_image_add_plane(img, channel, (int)width, (int)height, (int)bitsPerPixel); - if (error.code != heif_error_Ok) { - free(rgba); - heif_encoder_release(encoder); - heif_context_free(ctx); - return nil; - } - - // fill the plane - int stride; - uint8_t *planar = heif_image_get_plane(img, channel, &stride); - size_t bytes_per_pixel = (bitsPerPixel + 7) / 8; - for (int y = 0 ; y < height ; y++) { - memcpy(planar + y * stride, rgba + y * stride, width * bytes_per_pixel); - } - - // free the rgba buffer - free(rgba); - - // encode the image - error = heif_context_encode_image(ctx, img, encoder, NULL, NULL); - if (error.code != heif_error_Ok) { - heif_image_release(img); - heif_encoder_release(encoder); - heif_context_free(ctx); - return nil; - } - - NSMutableData *mutableData = [NSMutableData data]; - heif_writer writer; - writer.writer_api_version = 1; - writer.write = WriteImageData; // This is a function pointer - - error = heif_context_write(ctx, &writer, (__bridge void *)(mutableData)); - - // clean up - heif_image_release(img); - heif_encoder_release(encoder); - heif_context_free(ctx); - - return [mutableData copy]; -} - -#pragma mark - Helper -+ (BOOL)isHEIFFormatForData:(NSData *)data -{ - if (!data) { - return NO; - } - if (data.length >= 12) { - //....ftypmif1 ....ftypmsf1 ....ftypheic ....ftypheix ....ftyphevc ....ftyphevx - NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding]; - if ([testString isEqualToString:@"ftypmif1"] - || [testString isEqualToString:@"ftypmsf1"] - || [testString isEqualToString:@"ftypheic"] - || [testString isEqualToString:@"ftypheix"] - || [testString isEqualToString:@"ftyphevc"] - || [testString isEqualToString:@"ftyphevx"]) { - return YES; - } - } - - return NO; -} - -@end diff --git a/SDWebImageHEIFCoder/Module/Info.plist b/SDWebImageHEIFCoder/Module/Info.plist index 5b54d0c..479b075 100644 --- a/SDWebImageHEIFCoder/Module/Info.plist +++ b/SDWebImageHEIFCoder/Module/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.1.4 + 0.10.1 CFBundleVersion - 0.1.4 + 0.10.1 diff --git a/SDWebImageHEIFCoder/Module/SDWebImageHEIFCoder.h b/SDWebImageHEIFCoder/Module/SDWebImageHEIFCoder.h new file mode 100644 index 0000000..4d19362 --- /dev/null +++ b/SDWebImageHEIFCoder/Module/SDWebImageHEIFCoder.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import + +FOUNDATION_EXPORT double SDWebImageHEIFCoderVersionNumber; +FOUNDATION_EXPORT const unsigned char SDWebImageHEIFCoderVersionString[]; + diff --git a/SDWebImageHEIFCoder/Module/SDWebImageHEIFCoder.modulemap b/SDWebImageHEIFCoder/Module/SDWebImageHEIFCoder.modulemap new file mode 100644 index 0000000..a21ae6f --- /dev/null +++ b/SDWebImageHEIFCoder/Module/SDWebImageHEIFCoder.modulemap @@ -0,0 +1,6 @@ +framework module SDWebImageHEIFCoder { + umbrella header "SDWebImageHEIFCoder.h" + + export * + module * { export * } +} diff --git a/Tests/Images/TestImage.heic b/Tests/Images/TestImage.heic new file mode 100644 index 0000000..f0bfa22 Binary files /dev/null and b/Tests/Images/TestImage.heic differ diff --git a/Tests/Images/TestImageAnimated.heic b/Tests/Images/TestImageAnimated.heic new file mode 100644 index 0000000..0dd3180 Binary files /dev/null and b/Tests/Images/TestImageAnimated.heic differ diff --git a/Tests/Images/TestImageStatic.heic b/Tests/Images/TestImageStatic.heic new file mode 100644 index 0000000..b16f92b Binary files /dev/null and b/Tests/Images/TestImageStatic.heic differ diff --git a/Tests/SDWebImageHEIFCoderTests.m b/Tests/SDWebImageHEIFCoderTests.m new file mode 100644 index 0000000..c94b4e3 --- /dev/null +++ b/Tests/SDWebImageHEIFCoderTests.m @@ -0,0 +1,292 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +@import Foundation; +@import XCTest; +#import +#import +#import +#import + +const int64_t kAsyncTestTimeout = 5; + +typedef struct heif_context heif_context; +typedef struct heif_image_handle heif_image_handle; +typedef struct heif_image heif_image; +typedef struct heif_encoder heif_encoder; +typedef struct heif_writer heif_writer; +typedef struct heif_error heif_error; +typedef enum heif_chroma heif_chroma; +typedef enum heif_channel heif_channel; +typedef enum heif_colorspace heif_colorspace; + +@interface SDWebImageHEIFCoderTests : XCTestCase +@end + +@interface SDHEIFCoderFrame : NSObject +@property (nonatomic, assign) NSUInteger index; // Frame index (zero based) +@property (nonatomic, assign) NSUInteger blendFromIndex; // The nearest previous frame index which blend mode is HEIF_MUX_BLEND +@end + +@implementation SDWebImageHEIFCoderTests + ++ (void)setUp { + [SDImageCache.sharedImageCache clearMemory]; + [SDImageCache.sharedImageCache clearDiskOnCompletion:nil]; + [[SDImageCodersManager sharedManager] addCoder:[SDImageHEIFCoder sharedCoder]]; +} + ++ (void)tearDown { + [[SDImageCodersManager sharedManager] removeCoder:[SDImageHEIFCoder sharedCoder]]; +} + +- (void)test01ThatHEIFWorks { + XCTestExpectation *expectation = [self expectationWithDescription:@"HEIF download"]; + NSURL *imageURL = [NSURL URLWithString:@"http://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"]; + [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) { + if (image && data && !error && finished) { + [expectation fulfill]; + } else { + XCTFail(@"Something went wrong"); + } + }]; + [self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:nil]; +} + +- (void)test02ThatProgressiveHEIFWorks { + XCTestExpectation *expectation = [self expectationWithDescription:@"Progressive HEIF download"]; + NSURL *imageURL = [NSURL URLWithString:@"http://nokiatech.github.io/heif/content/image_sequences/starfield_animation.heic"]; + [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:imageURL options:SDWebImageDownloaderProgressiveLoad progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) { + if (image && data && !error && finished) { + [expectation fulfill]; + } else if (finished) { + XCTFail(@"Something went wrong"); + } else { + // progressive updates + } + }]; + [self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:nil]; +} + +- (void)test11ThatStaticHEIFCoderWorks { + NSURL *staticHEIFURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImageStatic" withExtension:@"heic"]; + [self verifyCoder:[SDImageHEIFCoder sharedCoder] + withLocalImageURL:staticHEIFURL + supportsEncoding:YES + isAnimatedImage:NO]; +} + +- (void)test12ThatAnimatedHEIFCoderWorks { + NSURL *animatedHEIFURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImageAnimated" withExtension:@"heic"]; + // libheif does not support Animated Image currently + [self verifyCoder:[SDImageHEIFCoder sharedCoder] + withLocalImageURL:animatedHEIFURL + supportsEncoding:NO + isAnimatedImage:NO]; +} + +- (void)test45HEIFEncodingMaxFileSize { + NSURL *staticHEIFURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImageStatic" withExtension:@"heic"]; + NSData *data = [NSData dataWithContentsOfURL:staticHEIFURL]; + UIImage *image = [UIImage sd_imageWithData:data]; + NSData *dataWithNoLimit = [SDImageHEIFCoder.sharedCoder encodedDataWithImage:image format:SDImageFormatHEIC options:nil]; + XCTAssertNotNil(dataWithNoLimit); + NSUInteger maxFileSize = 1024 * 50; + NSData *dataWithLimit = [SDImageHEIFCoder.sharedCoder encodedDataWithImage:image format:SDImageFormatHEIC options:@{SDImageCoderEncodeMaxFileSize : @(maxFileSize)}]; + XCTAssertNotNil(dataWithLimit); + XCTAssertGreaterThan(dataWithNoLimit.length, dataWithLimit.length); + XCTAssertGreaterThan(dataWithNoLimit.length, maxFileSize); + XCTAssertLessThanOrEqual(dataWithLimit.length, maxFileSize); +} + +- (void)test19ThatEmbedThumbnailHEICWorks { + // The input HEIC does not contains any embed thumbnail + NSURL *heicURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImage" withExtension:@"heic"]; + NSData *heicData = [NSData dataWithContentsOfURL:heicURL]; + NSArray *thumbnailImages = [self thumbnailImagesFromData:heicData]; + expect(thumbnailImages.count).equal(0); + + UIImage *image = [SDImageHEIFCoder.sharedCoder decodedImageWithData:heicData options:nil]; + // Encode with embed thumbnail + NSData *encodedData = [SDImageHEIFCoder.sharedCoder encodedDataWithImage:image format:SDImageFormatHEIC options:@{SDImageCoderEncodeEmbedThumbnail : @(YES)}]; + + [encodedData writeToFile:@"/tmp/1.heic" atomically:YES]; + + // The new HEIC contains one embed thumbnail + NSArray *thumbnailImages2 = [self thumbnailImagesFromData:encodedData]; + expect(thumbnailImages2.count).equal(1); + + // Cuurent we use 320x320 for thubmnail (keep aspect ratio), check the behavior :) + NSDictionary *thumbnailImageInfo = thumbnailImages2.firstObject; + NSUInteger thumbnailWidth = [thumbnailImageInfo[@"width"] unsignedIntegerValue]; + NSUInteger thumbnailHeight = [thumbnailImageInfo[@"height"] unsignedIntegerValue]; + expect(thumbnailWidth).equal(320); + expect(thumbnailHeight).equal(212); +} + +- (void)verifyCoder:(id)coder + withLocalImageURL:(NSURL *)imageUrl + supportsEncoding:(BOOL)supportsEncoding + isAnimatedImage:(BOOL)isAnimated { + SDImageFormat encodingFormat = SDImageFormatHEIC; + + NSData *inputImageData = [NSData dataWithContentsOfURL:imageUrl]; + expect(inputImageData).toNot.beNil(); + SDImageFormat inputImageFormat = [NSData sd_imageFormatForImageData:inputImageData]; + expect(inputImageFormat).toNot.equal(SDImageFormatUndefined); + + // 1 - check if we can decode - should be true + expect([coder canDecodeFromData:inputImageData]).to.beTruthy(); + + // 2 - decode from NSData to UIImage and check it + UIImage *inputImage = [coder decodedImageWithData:inputImageData options:nil]; + expect(inputImage).toNot.beNil(); + + if (isAnimated) { + // 2a - check images count > 0 (only for animated images) + expect(inputImage.sd_isAnimated).to.beTruthy(); + + // 2b - check image size and scale for each frameImage (only for animated images) +#if SD_UIKIT + CGSize imageSize = inputImage.size; + CGFloat imageScale = inputImage.scale; + [inputImage.images enumerateObjectsUsingBlock:^(UIImage * frameImage, NSUInteger idx, BOOL * stop) { + expect(imageSize).to.equal(frameImage.size); + expect(imageScale).to.equal(frameImage.scale); + }]; +#endif + } + + // 3 - check thumbnail decoding + CGFloat pixelWidth = inputImage.size.width; + CGFloat pixelHeight = inputImage.size.height; + expect(pixelWidth).beGreaterThan(0); + expect(pixelHeight).beGreaterThan(0); + // check thumnail with scratch + CGFloat thumbnailWidth = 50; + CGFloat thumbnailHeight = 50; + UIImage *thumbImage = [coder decodedImageWithData:inputImageData options:@{ + SDImageCoderDecodeThumbnailPixelSize : @(CGSizeMake(thumbnailWidth, thumbnailHeight)), + SDImageCoderDecodePreserveAspectRatio : @(NO) + }]; + expect(thumbImage).toNot.beNil(); + expect(thumbImage.size).equal(CGSizeMake(thumbnailWidth, thumbnailHeight)); + // check thumnail with aspect ratio limit + thumbImage = [coder decodedImageWithData:inputImageData options:@{ + SDImageCoderDecodeThumbnailPixelSize : @(CGSizeMake(thumbnailWidth, thumbnailHeight)), + SDImageCoderDecodePreserveAspectRatio : @(YES) + }]; + expect(thumbImage).toNot.beNil(); + CGFloat ratio = pixelWidth / pixelHeight; + CGFloat thumbnailRatio = thumbnailWidth / thumbnailHeight; + CGSize thumbnailPixelSize; + if (ratio > thumbnailRatio) { + thumbnailPixelSize = CGSizeMake(thumbnailWidth, round(thumbnailWidth / ratio)); + } else { + thumbnailPixelSize = CGSizeMake(round(thumbnailHeight * ratio), thumbnailHeight); + } + // Image/IO's thumbnail API does not always use round to preserve precision, we check ABS <= 1 + expect(ABS(thumbImage.size.width - thumbnailPixelSize.width)).beLessThanOrEqualTo(1); + expect(ABS(thumbImage.size.height - thumbnailPixelSize.height)).beLessThanOrEqualTo(1); + + + if (supportsEncoding) { + // 4 - check if we can encode to the original format + if (encodingFormat == SDImageFormatUndefined) { + encodingFormat = inputImageFormat; + } + expect([coder canEncodeToFormat:encodingFormat]).to.beTruthy(); + + // 5 - encode from UIImage to NSData using the inputImageFormat and check it + NSData *outputImageData = [coder encodedDataWithImage:inputImage format:encodingFormat options:nil]; + expect(outputImageData).toNot.beNil(); + UIImage *outputImage = [coder decodedImageWithData:outputImageData options:nil]; + expect(outputImage.size).to.equal(inputImage.size); + expect(outputImage.scale).to.equal(inputImage.scale); +#if SD_UIKIT + expect(outputImage.images.count).to.equal(inputImage.images.count); +#endif + + // check max pixel size encoding with scratch + CGFloat maxWidth = 100; + CGFloat maxHeight = 100; + CGFloat maxRatio = maxWidth / maxHeight; + CGSize maxPixelSize; + if (ratio > maxRatio) { + maxPixelSize = CGSizeMake(maxWidth, round(maxWidth / ratio)); + } else { + maxPixelSize = CGSizeMake(round(maxHeight * ratio), maxHeight); + } + NSData *outputMaxImageData = [coder encodedDataWithImage:inputImage format:encodingFormat options:@{SDImageCoderEncodeMaxPixelSize : @(CGSizeMake(maxWidth, maxHeight))}]; + expect(outputMaxImageData).toNot.beNil(); + UIImage *outputMaxImage = [coder decodedImageWithData:outputMaxImageData options:nil]; + // Image/IO's thumbnail API does not always use round to preserve precision, we check ABS <= 1 + expect(ABS(outputMaxImage.size.width - maxPixelSize.width)).beLessThanOrEqualTo(1); + expect(ABS(outputMaxImage.size.height - maxPixelSize.height)).beLessThanOrEqualTo(1); +#if SD_UIKIT + expect(outputMaxImage.images.count).to.equal(inputImage.images.count); +#endif + } +} + +- (NSArray *)thumbnailImagesFromData:(NSData *)data { + heif_context* ctx = heif_context_alloc(); + if (!ctx) { + return nil; + } + + const void *bytes = data.bytes; + const size_t size = data.length; + heif_error error = heif_context_read_from_memory(ctx, bytes, size, NULL); + if (error.code != heif_error_Ok) { + heif_context_free(ctx); + return nil; + } + + // get a handle to the primary image + heif_image_handle* handle; + error = heif_context_get_primary_image_handle(ctx, &handle); + if (error.code != heif_error_Ok) { + heif_context_free(ctx); + return nil; + } + + // check thumbnail count + int thumbnailCount = heif_image_handle_get_number_of_thumbnails(handle); + + // check thumbnail size + heif_item_id *thumbnailIDs = calloc(thumbnailCount, sizeof(heif_item_id)); + thumbnailCount = heif_image_handle_get_list_of_thumbnail_IDs(handle, thumbnailIDs, thumbnailCount); + + NSMutableArray *thumbnailImages = [NSMutableArray arrayWithCapacity:thumbnailCount]; + for (int i = 0; i < thumbnailCount; i++) { + heif_image_handle *thumbnailHandle; + error = heif_image_handle_get_thumbnail(handle, thumbnailIDs[i], &thumbnailHandle); + if (error.code != heif_error_Ok) { + heif_image_handle_release(handle); + heif_context_free(ctx); + free(thumbnailIDs); + return nil; + } + + int handleWidth = heif_image_handle_get_width(thumbnailHandle); + int handleHeight = heif_image_handle_get_height(thumbnailHandle); + heif_image_handle_release(thumbnailHandle); + + NSDictionary *thumbnailImage = @{@"width": @(handleWidth), @"height": @(handleHeight)}; + [thumbnailImages addObject:thumbnailImage]; + } + + free(thumbnailIDs); + heif_image_handle_release(handle); + heif_context_free(ctx); + + return [thumbnailImages copy]; +} + +@end diff --git a/Example/Tests/Tests-Info.plist b/Tests/Tests-Info.plist similarity index 100% rename from Example/Tests/Tests-Info.plist rename to Tests/Tests-Info.plist diff --git a/Example/Tests/Tests-Prefix.pch b/Tests/Tests-Prefix.pch similarity index 100% rename from Example/Tests/Tests-Prefix.pch rename to Tests/Tests-Prefix.pch diff --git a/Example/Tests/en.lproj/InfoPlist.strings b/Tests/en.lproj/InfoPlist.strings similarity index 100% rename from Example/Tests/en.lproj/InfoPlist.strings rename to Tests/en.lproj/InfoPlist.strings diff --git a/Vendors/include/libde265/de265-version.h b/Vendors/include/libde265/de265-version.h deleted file mode 100644 index 054daa7..0000000 --- a/Vendors/include/libde265/de265-version.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * H.265 video codec. - * Copyright (c) 2013-2014 struktur AG, Dirk Farin - * - * This file is part of libde265. - * - * libde265 is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * libde265 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libde265. If not, see . - */ - -/* de265-version.h - * - * This file was generated by autoconf when libde265 was built. - * - * DO NOT EDIT THIS FILE. - */ -#ifndef LIBDE265_VERSION_H -#define LIBDE265_VERSION_H - -/* Numeric representation of the version */ -#define LIBDE265_NUMERIC_VERSION 0x01000300 - -/* Version string */ -#define LIBDE265_VERSION "1.0.3" - -#endif diff --git a/Vendors/include/libde265/de265.h b/Vendors/include/libde265/de265.h deleted file mode 100644 index 393d1ee..0000000 --- a/Vendors/include/libde265/de265.h +++ /dev/null @@ -1,437 +0,0 @@ -/* - * H.265 video codec. - * Copyright (c) 2013-2014 struktur AG, Dirk Farin - * - * This file is part of libde265. - * - * libde265 is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * libde265 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libde265. If not, see . -*/ - - -#ifndef DE265_H -#define DE265_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "de265-version.h" - -//#define inline static __inline - - -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif -#include - -#if defined(_MSC_VER) && !defined(LIBDE265_STATIC_BUILD) - #ifdef LIBDE265_EXPORTS - #define LIBDE265_API __declspec(dllexport) - #else - #define LIBDE265_API __declspec(dllimport) - #endif -#elif HAVE_VISIBILITY - #ifdef LIBDE265_EXPORTS - #define LIBDE265_API __attribute__((__visibility__("default"))) - #else - #define LIBDE265_API - #endif -#else - #define LIBDE265_API -#endif - -#if __GNUC__ -#define LIBDE265_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define LIBDE265_DEPRECATED __declspec(deprecated) -#else -#define LIBDE265_DEPRECATED -#endif - -#if defined(_MSC_VER) -#define LIBDE265_INLINE __inline -#else -#define LIBDE265_INLINE inline -#endif - -/* === version numbers === */ - -// version of linked libde265 library -LIBDE265_API const char *de265_get_version(void); -LIBDE265_API uint32_t de265_get_version_number(void); - -LIBDE265_API int de265_get_version_number_major(void); -LIBDE265_API int de265_get_version_number_minor(void); -LIBDE265_API int de265_get_version_number_maintenance(void); - - -/* === error codes === */ - -typedef enum { - DE265_OK = 0, - DE265_ERROR_NO_SUCH_FILE=1, - //DE265_ERROR_NO_STARTCODE=2, obsolet - //DE265_ERROR_EOF=3, - DE265_ERROR_COEFFICIENT_OUT_OF_IMAGE_BOUNDS=4, - DE265_ERROR_CHECKSUM_MISMATCH=5, - DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA=6, - DE265_ERROR_OUT_OF_MEMORY=7, - DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE=8, - DE265_ERROR_IMAGE_BUFFER_FULL=9, - DE265_ERROR_CANNOT_START_THREADPOOL=10, - DE265_ERROR_LIBRARY_INITIALIZATION_FAILED=11, - DE265_ERROR_LIBRARY_NOT_INITIALIZED=12, - DE265_ERROR_WAITING_FOR_INPUT_DATA=13, - DE265_ERROR_CANNOT_PROCESS_SEI=14, - DE265_ERROR_PARAMETER_PARSING=15, - DE265_ERROR_NO_INITIAL_SLICE_HEADER=16, - DE265_ERROR_PREMATURE_END_OF_SLICE=17, - DE265_ERROR_UNSPECIFIED_DECODING_ERROR=18, - - // --- errors that should become obsolete in later libde265 versions --- - - //DE265_ERROR_MAX_THREAD_CONTEXTS_EXCEEDED = 500, obsolet - //DE265_ERROR_MAX_NUMBER_OF_SLICES_EXCEEDED = 501, obsolet - DE265_ERROR_NOT_IMPLEMENTED_YET = 502, - //DE265_ERROR_SCALING_LIST_NOT_IMPLEMENTED = 502, obsolet - - // --- warnings --- - - DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING = 1000, - DE265_WARNING_WARNING_BUFFER_FULL=1001, - DE265_WARNING_PREMATURE_END_OF_SLICE_SEGMENT=1002, - DE265_WARNING_INCORRECT_ENTRY_POINT_OFFSET=1003, - DE265_WARNING_CTB_OUTSIDE_IMAGE_AREA=1004, - DE265_WARNING_SPS_HEADER_INVALID=1005, - DE265_WARNING_PPS_HEADER_INVALID=1006, - DE265_WARNING_SLICEHEADER_INVALID=1007, - DE265_WARNING_INCORRECT_MOTION_VECTOR_SCALING=1008, - DE265_WARNING_NONEXISTING_PPS_REFERENCED=1009, - DE265_WARNING_NONEXISTING_SPS_REFERENCED=1010, - DE265_WARNING_BOTH_PREDFLAGS_ZERO=1011, - DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED=1012, - DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ=1013, - DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE=1014, - DE265_WARNING_SHORT_TERM_REF_PIC_SET_OUT_OF_RANGE=1015, - DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST=1016, - DE265_WARNING_EOSS_BIT_NOT_SET=1017, - DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED=1018, - DE265_WARNING_INVALID_CHROMA_FORMAT=1019, - DE265_WARNING_SLICE_SEGMENT_ADDRESS_INVALID=1020, - DE265_WARNING_DEPENDENT_SLICE_WITH_ADDRESS_ZERO=1021, - DE265_WARNING_NUMBER_OF_THREADS_LIMITED_TO_MAXIMUM=1022, - DE265_NON_EXISTING_LT_REFERENCE_CANDIDATE_IN_SLICE_HEADER=1023, - DE265_WARNING_CANNOT_APPLY_SAO_OUT_OF_MEMORY=1024, - DE265_WARNING_SPS_MISSING_CANNOT_DECODE_SEI=1025, - DE265_WARNING_COLLOCATED_MOTION_VECTOR_OUTSIDE_IMAGE_AREA=1026 -} de265_error; - -LIBDE265_API const char* de265_get_error_text(de265_error err); - -/* Returns true, if 'err' is DE265_OK or a warning. - */ -LIBDE265_API int de265_isOK(de265_error err); - -LIBDE265_API void de265_disable_logging(); // DEPRECATED -LIBDE265_API void de265_set_verbosity(int level); - - -/* === image === */ - -/* The image is currently always 3-channel YCbCr, with 4:2:0 chroma. - But you may want to check the chroma format anyway for future compatibility. - */ - -struct de265_image; - -enum de265_chroma { - de265_chroma_mono=0, - de265_chroma_420=1, - de265_chroma_422=2, - de265_chroma_444=3 -}; - -typedef int64_t de265_PTS; - - -LIBDE265_API int de265_get_image_width(const struct de265_image*,int channel); -LIBDE265_API int de265_get_image_height(const struct de265_image*,int channel); -LIBDE265_API enum de265_chroma de265_get_chroma_format(const struct de265_image*); -LIBDE265_API int de265_get_bits_per_pixel(const struct de265_image*,int channel); -/* The |out_stride| is returned as "bytes per line" if a non-NULL parameter is given. */ -LIBDE265_API const uint8_t* de265_get_image_plane(const struct de265_image*, int channel, int* out_stride); -LIBDE265_API void* de265_get_image_plane_user_data(const struct de265_image*, int channel); -LIBDE265_API de265_PTS de265_get_image_PTS(const struct de265_image*); -LIBDE265_API void* de265_get_image_user_data(const struct de265_image*); -LIBDE265_API void de265_set_image_user_data(struct de265_image*, void *user_data); - -/* Get NAL-header information of this frame. You can pass in NULL pointers if you - do not need this piece of information. - */ -LIBDE265_API void de265_get_image_NAL_header(const struct de265_image*, - int* nal_unit_type, - const char** nal_unit_name, // textual description of 'nal_unit_type' - int* nuh_layer_id, - int* nuh_temporal_id); - - -/* === decoder === */ - -typedef void de265_decoder_context; // private structure - - - -/* Get a new decoder context. Must be freed with de265_free_decoder(). */ -LIBDE265_API de265_decoder_context* de265_new_decoder(void); - -/* Initialize background decoding threads. If this function is not called, - all decoding is done in the main thread (no multi-threading). */ -LIBDE265_API de265_error de265_start_worker_threads(de265_decoder_context*, int number_of_threads); - -/* Free decoder context. May only be called once on a context. */ -LIBDE265_API de265_error de265_free_decoder(de265_decoder_context*); - -#ifndef LIBDE265_DISABLE_DEPRECATED -/* Push more data into the decoder, must be raw h265. - All complete images in the data will be decoded, hence, do not push - too much data at once to prevent image buffer overflows. - The end of a picture can only be detected when the succeeding start-code - is read from the data. - If you want to flush the data and force decoding of the data so far - (e.g. at the end of a file), call de265_decode_data() with 'length' zero. - - NOTE: This method is deprecated and will be removed in a future version. - You should use "de265_push_data" or "de265_push_NAL" and "de265_decode" - instead. -*/ -LIBDE265_API LIBDE265_DEPRECATED de265_error de265_decode_data(de265_decoder_context*, const void* data, int length); -#endif - -/* Push more data into the decoder, must be a raw h265 bytestream with startcodes. - The PTS is assigned to all NALs whose start-code 0x000001 is contained in the data. - The bytestream must contain all stuffing-bytes. - This function only pushes data into the decoder, nothing will be decoded. -*/ -LIBDE265_API de265_error de265_push_data(de265_decoder_context*, const void* data, int length, - de265_PTS pts, void* user_data); - -/* Indicate that de265_push_data has just received data until the end of a NAL. - The remaining pending input data is put into a NAL package and forwarded to the decoder. -*/ -LIBDE265_API void de265_push_end_of_NAL(de265_decoder_context*); - -/* Indicate that de265_push_data has just received data until the end of a frame. - All data pending at the decoder input will be pushed into the decoder and - the decoded picture is pushed to the output queue. -*/ -LIBDE265_API void de265_push_end_of_frame(de265_decoder_context*); - -/* Push a complete NAL unit without startcode into the decoder. The data must still - contain all stuffing-bytes. - This function only pushes data into the decoder, nothing will be decoded. -*/ -LIBDE265_API de265_error de265_push_NAL(de265_decoder_context*, const void* data, int length, - de265_PTS pts, void* user_data); - -/* Indicate the end-of-stream. All data pending at the decoder input will be - pushed into the decoder and the decoded picture queue will be completely emptied. - */ -LIBDE265_API de265_error de265_flush_data(de265_decoder_context*); - -/* Return number of bytes pending at the decoder input. - Can be used to avoid overflowing the decoder with too much data. - */ -LIBDE265_API int de265_get_number_of_input_bytes_pending(de265_decoder_context*); - -/* Return number of NAL units pending at the decoder input. - Can be used to avoid overflowing the decoder with too much data. - */ -LIBDE265_API int de265_get_number_of_NAL_units_pending(de265_decoder_context*); - -/* Do some decoding. Returns status whether it did perform some decoding or - why it could not do so. If 'more' is non-null, indicates whether de265_decode() - should be called again (possibly after resolving the indicated problem). - DE265_OK - decoding ok - DE265_ERROR_IMAGE_BUFFER_FULL - DPB full, extract some images before continuing - DE265_ERROR_WAITING_FOR_INPUT_DATA - insert more data before continuing - - You have to consider these cases: - - decoding successful -> err = DE265_OK, more=true - - decoding stalled -> err != DE265_OK, more=true - - decoding finished -> err = DE265_OK, more=false - - unresolvable error -> err != DE265_OK, more=false - */ -LIBDE265_API de265_error de265_decode(de265_decoder_context*, int* more); - -/* Clear decoder state. Call this when skipping in the stream. - */ -LIBDE265_API void de265_reset(de265_decoder_context*); - -/* Return next decoded picture, if there is any. If no complete picture has been - decoded yet, NULL is returned. You should call de265_release_next_picture() to - advance to the next picture. */ -LIBDE265_API const struct de265_image* de265_peek_next_picture(de265_decoder_context*); // may return NULL - -/* Get next decoded picture and remove this picture from the decoder output queue. - Returns NULL is there is no decoded picture ready. - You can use the picture only until you call any other de265_* function. */ -LIBDE265_API const struct de265_image* de265_get_next_picture(de265_decoder_context*); // may return NULL - -/* Release the current decoded picture for reuse in the decoder. You should not - use the data anymore after calling this function. */ -LIBDE265_API void de265_release_next_picture(de265_decoder_context*); - - -LIBDE265_API de265_error de265_get_warning(de265_decoder_context*); - - -enum de265_image_format { - de265_image_format_mono8 = 1, - de265_image_format_YUV420P8 = 2, - de265_image_format_YUV422P8 = 3, - de265_image_format_YUV444P8 = 4 -}; - -struct de265_image_spec -{ - enum de265_image_format format; - int width; - int height; - int alignment; - - // conformance window - - int crop_left; - int crop_right; - int crop_top; - int crop_bottom; - - int visible_width; // convenience, width - crop_left - crop_right - int visible_height; // convenience, height - crop_top - crop_bottom -}; - -struct de265_image_allocation -{ - int (*get_buffer)(de265_decoder_context* ctx, // first parameter deprecated - struct de265_image_spec* spec, - struct de265_image* img, - void* userdata); - void (*release_buffer)(de265_decoder_context* ctx, // first parameter deprecated - struct de265_image* img, - void* userdata); -}; - -/* The user data pointer will be given to the get_buffer() and release_buffer() functions - in de265_image_allocation. */ -LIBDE265_API void de265_set_image_allocation_functions(de265_decoder_context*, - struct de265_image_allocation*, - void* userdata); -LIBDE265_API const struct de265_image_allocation *de265_get_default_image_allocation_functions(void); - -LIBDE265_API void de265_set_image_plane(struct de265_image* img, int cIdx, void* mem, int stride, void *userdata); - - -/* --- frame dropping API --- - - To limit decoding to a maximum temporal layer (TID), use de265_set_limit_TID(). - The maximum layer ID in the stream can be queried with de265_get_highest_TID(). - Note that the maximum layer ID can change throughout the stream. - - For a fine-grained selection of the frame-rate, use de265_set_framerate_ratio(). - A percentage of 100% will decode all frames in all temporal layers. A lower percentage - will drop approximately as many frames. Note that this only accurate if the frames - are distributed evenly among the layers. Otherwise, the mapping is non-linear. - - The limit_TID has a higher precedence than framerate_ratio. Hence, setting a higher - framerate-ratio will decode at limit_TID without dropping. - - With change_framerate(), the output frame-rate can be increased/decreased to some - discrete preferable values. Currently, these are non-dropped decoding at various - TID layers. -*/ - -LIBDE265_API int de265_get_highest_TID(de265_decoder_context*); // highest temporal substream to decode -LIBDE265_API int de265_get_current_TID(de265_decoder_context*); // currently decoded temporal substream - -LIBDE265_API void de265_set_limit_TID(de265_decoder_context*,int max_tid); // highest temporal substream to decode -LIBDE265_API void de265_set_framerate_ratio(de265_decoder_context*,int percent); // percentage of frames to decode (approx) -LIBDE265_API int de265_change_framerate(de265_decoder_context*,int more_vs_less); // 1: more, -1: less, returns corresponding framerate_ratio - - -/* --- decoding parameters --- */ - -enum de265_param { - DE265_DECODER_PARAM_BOOL_SEI_CHECK_HASH=0, // (bool) Perform SEI hash check on decoded pictures. - DE265_DECODER_PARAM_DUMP_SPS_HEADERS=1, // (int) Dump headers to specified file-descriptor. - DE265_DECODER_PARAM_DUMP_VPS_HEADERS=2, - DE265_DECODER_PARAM_DUMP_PPS_HEADERS=3, - DE265_DECODER_PARAM_DUMP_SLICE_HEADERS=4, - DE265_DECODER_PARAM_ACCELERATION_CODE=5, // (int) enum de265_acceleration, default: AUTO - DE265_DECODER_PARAM_SUPPRESS_FAULTY_PICTURES=6, // (bool) do not output frames with decoding errors, default: no (output all images) - - DE265_DECODER_PARAM_DISABLE_DEBLOCKING=7, // (bool) disable deblocking - DE265_DECODER_PARAM_DISABLE_SAO=8 // (bool) disable SAO filter - //DE265_DECODER_PARAM_DISABLE_MC_RESIDUAL_IDCT=9, // (bool) disable decoding of IDCT residuals in MC blocks - //DE265_DECODER_PARAM_DISABLE_INTRA_RESIDUAL_IDCT=10 // (bool) disable decoding of IDCT residuals in MC blocks -}; - -// sorted such that a large ID includes all optimizations from lower IDs -enum de265_acceleration { - de265_acceleration_SCALAR = 0, // only fallback implementation - de265_acceleration_MMX = 10, - de265_acceleration_SSE = 20, - de265_acceleration_SSE2 = 30, - de265_acceleration_SSE4 = 40, - de265_acceleration_AVX = 50, // not implemented yet - de265_acceleration_AVX2 = 60, // not implemented yet - de265_acceleration_ARM = 70, - de265_acceleration_NEON = 80, - de265_acceleration_AUTO = 10000 -}; - - -/* Set decoding parameters. */ -LIBDE265_API void de265_set_parameter_bool(de265_decoder_context*, enum de265_param param, int value); - -LIBDE265_API void de265_set_parameter_int(de265_decoder_context*, enum de265_param param, int value); - -/* Get decoding parameters. */ -LIBDE265_API int de265_get_parameter_bool(de265_decoder_context*, enum de265_param param); - - - -/* --- optional library initialization --- */ - -/* Static library initialization. Must be paired with de265_free(). - Initialization is optional, since it will be done implicitly in de265_new_decoder(). - Return value is false if initialization failed. - Only call de265_free() when initialization was successful. - Multiple calls to 'init' are allowed, but must be matched with an equal number of 'free' calls. -*/ -LIBDE265_API de265_error de265_init(void); - -/* Free global library data. - An implicit free call is made in de265_free_decoder(). - Returns false if library was not initialized before, or if 'free' was called - more often than 'init'. - */ -LIBDE265_API de265_error de265_free(void); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Vendors/include/libheif/heif.h b/Vendors/include/libheif/heif.h deleted file mode 100644 index 6dffd95..0000000 --- a/Vendors/include/libheif/heif.h +++ /dev/null @@ -1,996 +0,0 @@ -/* - * HEIF codec. - * Copyright (c) 2017 struktur AG, Dirk Farin - * - * This file is part of libheif. - * - * libheif is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * libheif is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libheif. If not, see . - */ - -#ifndef LIBHEIF_HEIF_H -#define LIBHEIF_HEIF_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include "heif_version.h" - - -// API versions table -// -// release depth.rep dec.options enc.options heif_reader heif_writer -// ------------------------------------------------------------------------------ -// 1.0 1 1 N/A N/A N/A -// 1.1 1 1 N/A N/A 1 -// 1.3 1 1 1 1 1 - - -#if defined(_MSC_VER) && !defined(LIBHEIF_STATIC_BUILD) - #ifdef LIBHEIF_EXPORTS - #define LIBHEIF_API __declspec(dllexport) - #else - #define LIBHEIF_API __declspec(dllimport) - #endif -#elif defined(HAVE_VISIBILITY) && HAVE_VISIBILITY - #ifdef LIBHEIF_EXPORTS - #define LIBHEIF_API __attribute__((__visibility__("default"))) - #else - #define LIBHEIF_API - #endif -#else - #define LIBHEIF_API -#endif - -/* === version numbers === */ - -// Version string of linked libheif library. -LIBHEIF_API const char *heif_get_version(void); -// Numeric version of linked libheif library, encoded as 0xHHMMLL00 = HH.MM.LL. -LIBHEIF_API uint32_t heif_get_version_number(void); - -// Numeric part "HH" from above. -LIBHEIF_API int heif_get_version_number_major(void); -// Numeric part "MM" from above. -LIBHEIF_API int heif_get_version_number_minor(void); -// Numeric part "LL" from above. -LIBHEIF_API int heif_get_version_number_maintenance(void); - -// Helper macros to check for given versions of libheif at compile time. -#define LIBHEIF_MAKE_VERSION(h, m, l) ((h) << 24 | (m) << 16 | (l) << 8) -#define LIBHEIF_HAVE_VERSION(h, m, l) (LIBHEIF_NUMERIC_VERSION >= LIBHEIF_MAKE_VERSION(h, m, l)) - -struct heif_context; -struct heif_image_handle; -struct heif_image; - - -enum heif_error_code { - // Everything ok, no error occurred. - heif_error_Ok = 0, - - // Input file does not exist. - heif_error_Input_does_not_exist = 1, - - // Error in input file. Corrupted or invalid content. - heif_error_Invalid_input = 2, - - // Input file type is not supported. - heif_error_Unsupported_filetype = 3, - - // Image requires an unsupported decoder feature. - heif_error_Unsupported_feature = 4, - - // Library API has been used in an invalid way. - heif_error_Usage_error = 5, - - // Could not allocate enough memory. - heif_error_Memory_allocation_error = 6, - - // The decoder plugin generated an error - heif_error_Decoder_plugin_error = 7, - - // The decoder plugin generated an error - heif_error_Encoder_plugin_error = 8, - - // Error during encoding or when writing to the output - heif_error_Encoding_error = 9 -}; - - -enum heif_suberror_code { - // no further information available - heif_suberror_Unspecified = 0, - - // --- Invalid_input --- - - // End of data reached unexpectedly. - heif_suberror_End_of_data = 100, - - // Size of box (defined in header) is wrong - heif_suberror_Invalid_box_size = 101, - - // Mandatory 'ftyp' box is missing - heif_suberror_No_ftyp_box = 102, - - heif_suberror_No_idat_box = 103, - - heif_suberror_No_meta_box = 104, - - heif_suberror_No_hdlr_box = 105, - - heif_suberror_No_hvcC_box = 106, - - heif_suberror_No_pitm_box = 107, - - heif_suberror_No_ipco_box = 108, - - heif_suberror_No_ipma_box = 109, - - heif_suberror_No_iloc_box = 110, - - heif_suberror_No_iinf_box = 111, - - heif_suberror_No_iprp_box = 112, - - heif_suberror_No_iref_box = 113, - - heif_suberror_No_pict_handler = 114, - - // An item property referenced in the 'ipma' box is not existing in the 'ipco' container. - heif_suberror_Ipma_box_references_nonexisting_property = 115, - - // No properties have been assigned to an item. - heif_suberror_No_properties_assigned_to_item = 116, - - // Image has no (compressed) data - heif_suberror_No_item_data = 117, - - // Invalid specification of image grid (tiled image) - heif_suberror_Invalid_grid_data = 118, - - // Tile-images in a grid image are missing - heif_suberror_Missing_grid_images = 119, - - heif_suberror_Invalid_clean_aperture = 120, - - // Invalid specification of overlay image - heif_suberror_Invalid_overlay_data = 121, - - // Overlay image completely outside of visible canvas area - heif_suberror_Overlay_image_outside_of_canvas = 122, - - heif_suberror_Auxiliary_image_type_unspecified = 123, - - heif_suberror_No_or_invalid_primary_item = 124, - - heif_suberror_No_infe_box = 125, - - - // --- Memory_allocation_error --- - - // A security limit preventing unreasonable memory allocations was exceeded by the input file. - // Please check whether the file is valid. If it is, contact us so that we could increase the - // security limits further. - heif_suberror_Security_limit_exceeded = 1000, - - - // --- Usage_error --- - - // An item ID was used that is not present in the file. - heif_suberror_Nonexisting_item_referenced = 2000, // also used for Invalid_input - - // An API argument was given a NULL pointer, which is not allowed for that function. - heif_suberror_Null_pointer_argument = 2001, - - // Image channel referenced that does not exist in the image - heif_suberror_Nonexisting_image_channel_referenced = 2002, - - // The version of the passed plugin is not supported. - heif_suberror_Unsupported_plugin_version = 2003, - - // The version of the passed writer is not supported. - heif_suberror_Unsupported_writer_version = 2004, - - // The given (encoder) parameter name does not exist. - heif_suberror_Unsupported_parameter = 2005, - - // The value for the given parameter is not in the valid range. - heif_suberror_Invalid_parameter_value = 2006, - - - // --- Unsupported_feature --- - - // Image was coded with an unsupported compression method. - heif_suberror_Unsupported_codec = 3000, - - // Image is specified in an unknown way, e.g. as tiled grid image (which is supported) - heif_suberror_Unsupported_image_type = 3001, - - heif_suberror_Unsupported_data_version = 3002, - - // The conversion of the source image to the requested chroma / colorspace is not supported. - heif_suberror_Unsupported_color_conversion = 3003, - - heif_suberror_Unsupported_item_construction_method = 3004, - - - // --- Encoder_plugin_error --- - - - // --- Encoding_error --- - - heif_suberror_Cannot_write_output_data = 5000, -}; - - - -struct heif_error -{ - // main error category - enum heif_error_code code; - - // more detailed error code - enum heif_suberror_code subcode; - - // textual error message (is always defined, you do not have to check for NULL) - const char* message; -}; - - -typedef uint32_t heif_item_id; - - -// ========================= heif_context ========================= -// A heif_context represents a HEIF file that has been read. -// In the future, you will also be able to add pictures to a heif_context -// and write it into a file again. - - -// Allocate a new context for reading HEIF files. -// Has to be freed again with heif_context_free(). -LIBHEIF_API -struct heif_context* heif_context_alloc(void); - -// Free a previously allocated HEIF context. You should not free a context twice. -LIBHEIF_API -void heif_context_free(struct heif_context*); - - -struct heif_reading_options; - -enum heif_reader_grow_status { - heif_reader_grow_status_size_reached, // requested size has been reached, we can read until this point - heif_reader_grow_status_timeout, // size has not been reached yet, but it may still grow further - heif_reader_grow_status_size_beyond_eof // size has not been reached and never will. The file has grown to its full size -}; - -struct heif_reader { - // API version supported by this reader - int reader_api_version; - - // --- version 1 functions --- - int64_t (*get_position)(void* userdata); - - // The functions read(), and seek() return 0 on success. - // Generally, libheif will make sure that we do not read past the file size. - int (*read)(void* data, - size_t size, - void* userdata); - int (*seek)(int64_t position, - void* userdata); - - // When calling this function, libheif wants to make sure that it can read the file - // up to 'target_size'. This is useful when the file is currently downloaded and may - // grow with time. You may, for example, extract the image sizes even before the actual - // compressed image data has been completely downloaded. - // - // Even if your input files will not grow, you will have to implement at least - // detection whether the target_size is above the (fixed) file length - // (in this case, return 'size_beyond_eof'). - enum heif_reader_grow_status (*wait_for_file_size)(int64_t target_size, void* userdata); -}; - - -// Read a HEIF file from a named disk file. -// The heif_reading_options should currently be set to NULL. -LIBHEIF_API -struct heif_error heif_context_read_from_file(struct heif_context*, const char* filename, - const struct heif_reading_options*); - -// Read a HEIF file stored completely in memory. -// The heif_reading_options should currently be set to NULL. -// DEPRECATED: use heif_context_read_from_memory_without_copy() instead. -LIBHEIF_API -struct heif_error heif_context_read_from_memory(struct heif_context*, - const void* mem, size_t size, - const struct heif_reading_options*); - -// Same as heif_context_read_from_memory() except that the provided memory is not copied. -// That means, you will have to keep the memory area alive as long as you use the heif_context. -LIBHEIF_API -struct heif_error heif_context_read_from_memory_without_copy(struct heif_context*, - const void* mem, size_t size, - const struct heif_reading_options*); - -LIBHEIF_API -struct heif_error heif_context_read_from_reader(struct heif_context*, - const struct heif_reader* reader, - void* userdata, - const struct heif_reading_options*); - -// Number of top-level images in the HEIF file. This does not include the thumbnails or the -// tile images that are composed to an image grid. You can get access to the thumbnails via -// the main image handle. -LIBHEIF_API -int heif_context_get_number_of_top_level_images(struct heif_context* ctx); - -LIBHEIF_API -int heif_context_is_top_level_image_ID(struct heif_context* ctx, heif_item_id id); - -// Fills in image IDs into the user-supplied int-array 'ID_array', preallocated with 'count' entries. -// Function returns the total number of IDs filled into the array. -LIBHEIF_API -int heif_context_get_list_of_top_level_image_IDs(struct heif_context* ctx, - heif_item_id* ID_array, - int count); - -LIBHEIF_API -struct heif_error heif_context_get_primary_image_ID(struct heif_context* ctx, heif_item_id* id); - -// Get a handle to the primary image of the HEIF file. -// This is the image that should be displayed primarily when there are several images in the file. -LIBHEIF_API -struct heif_error heif_context_get_primary_image_handle(struct heif_context* ctx, - struct heif_image_handle**); - -// Get the handle for a specific top-level image from an image ID. -LIBHEIF_API -struct heif_error heif_context_get_image_handle(struct heif_context* ctx, - heif_item_id id, - struct heif_image_handle**); - -// Print information about the boxes of a HEIF file to file descriptor. -// This is for debugging and informational purposes only. You should not rely on -// the output having a specific format. At best, you should not use this at all. -LIBHEIF_API -void heif_context_debug_dump_boxes_to_file(struct heif_context* ctx, int fd); - - -// ========================= heif_image_handle ========================= - -// An heif_image_handle is a handle to a logical image in the HEIF file. -// To get the actual pixel data, you have to decode the handle to an heif_image. -// An heif_image_handle also gives you access to the thumbnails and Exif data -// associated with an image. - -// Once you obtained an heif_image_handle, you can already release the heif_context, -// since it is internally ref-counted. - -// Release image handle. -LIBHEIF_API -void heif_image_handle_release(const struct heif_image_handle*); - -// Check whether the given image_handle is the primary image of the file. -LIBHEIF_API -int heif_image_handle_is_primary_image(const struct heif_image_handle* handle); - -// Get the resolution of an image. -LIBHEIF_API -int heif_image_handle_get_width(const struct heif_image_handle* handle); - -LIBHEIF_API -int heif_image_handle_get_height(const struct heif_image_handle* handle); - -LIBHEIF_API -int heif_image_handle_has_alpha_channel(const struct heif_image_handle*); - - -// ------------------------- depth images ------------------------- - -LIBHEIF_API -int heif_image_handle_has_depth_image(const struct heif_image_handle*); - -LIBHEIF_API -int heif_image_handle_get_number_of_depth_images(const struct heif_image_handle* handle); - -LIBHEIF_API -int heif_image_handle_get_list_of_depth_image_IDs(const struct heif_image_handle* handle, - heif_item_id* ids, int count); - -LIBHEIF_API -struct heif_error heif_image_handle_get_depth_image_handle(const struct heif_image_handle* handle, - heif_item_id depth_image_id, - struct heif_image_handle** out_depth_handle); - - -enum heif_depth_representation_type { - heif_depth_representation_type_uniform_inverse_Z = 0, - heif_depth_representation_type_uniform_disparity = 1, - heif_depth_representation_type_uniform_Z = 2, - heif_depth_representation_type_nonuniform_disparity = 3 -}; - -struct heif_depth_representation_info { - uint8_t version; - - // version 1 fields - - uint8_t has_z_near; - uint8_t has_z_far; - uint8_t has_d_min; - uint8_t has_d_max; - - double z_near; - double z_far; - double d_min; - double d_max; - - enum heif_depth_representation_type depth_representation_type; - uint32_t disparity_reference_view; - - uint32_t depth_nonlinear_representation_model_size; - uint8_t* depth_nonlinear_representation_model; - - // version 2 fields below -}; - - -LIBHEIF_API -void heif_depth_representation_info_free(const struct heif_depth_representation_info* info); - -// Returns true when there is depth_representation_info available -LIBHEIF_API -int heif_image_handle_get_depth_image_representation_info(const struct heif_image_handle* handle, - heif_item_id depth_image_id, - const struct heif_depth_representation_info** out); - - - -// ------------------------- thumbnails ------------------------- - -// List the number of thumbnails assigned to this image handle. Usually 0 or 1. -LIBHEIF_API -int heif_image_handle_get_number_of_thumbnails(const struct heif_image_handle* handle); - -LIBHEIF_API -int heif_image_handle_get_list_of_thumbnail_IDs(const struct heif_image_handle* handle, - heif_item_id* ids, int count); - -// Get the image handle of a thumbnail image. -LIBHEIF_API -struct heif_error heif_image_handle_get_thumbnail(const struct heif_image_handle* main_image_handle, - heif_item_id thumbnail_id, - struct heif_image_handle** out_thumbnail_handle); - - -// ------------------------- metadata (Exif / XMP) ------------------------- - -// How many metadata blocks are attached to an image. Usually, the only metadata is -// an "Exif" block. -LIBHEIF_API -int heif_image_handle_get_number_of_metadata_blocks(const struct heif_image_handle* handle, - const char* type_filter); - -// 'type_filter' can be used to get only metadata of specific types, like "Exif". -// If 'type_filter' is NULL, it will return all types of metadata IDs. -LIBHEIF_API -int heif_image_handle_get_list_of_metadata_block_IDs(const struct heif_image_handle* handle, - const char* type_filter, - heif_item_id* ids, int count); - -// Return a string indicating the type of the metadata, as specified in the HEIF file. -// Exif data will have the type string "Exif". -// This string will be valid until the next call to a libheif function. -// You do not have to free this string. -LIBHEIF_API -const char* heif_image_handle_get_metadata_type(const struct heif_image_handle* handle, - heif_item_id metadata_id); - -LIBHEIF_API -const char* heif_image_handle_get_metadata_content_type(const struct heif_image_handle* handle, - heif_item_id metadata_id); - -// Get the size of the raw metadata, as stored in the HEIF file. -LIBHEIF_API -size_t heif_image_handle_get_metadata_size(const struct heif_image_handle* handle, - heif_item_id metadata_id); - -// 'out_data' must point to a memory area of the size reported by heif_image_handle_get_metadata_size(). -// The data is returned exactly as stored in the HEIF file. -// For Exif data, you probably have to skip the first four bytes of the data, since they -// indicate the offset to the start of the TIFF header of the Exif data. -LIBHEIF_API -struct heif_error heif_image_handle_get_metadata(const struct heif_image_handle* handle, - heif_item_id metadata_id, - void* out_data); - - -// ========================= heif_image ========================= - -// An heif_image contains a decoded pixel image in various colorspaces, chroma formats, -// and bit depths. - -// Note: when converting images to colorspace_RGB/chroma_interleaved_24bit, the resulting -// image contains only a single channel of type channel_interleaved with 3 bytes per pixel, -// containing the interleaved R,G,B values. - -enum heif_compression_format { - heif_compression_undefined = 0, - heif_compression_HEVC = 1, - heif_compression_AVC = 2, - heif_compression_JPEG = 3 -}; - -enum heif_chroma { - heif_chroma_undefined=99, - heif_chroma_monochrome=0, - heif_chroma_420=1, - heif_chroma_422=2, - heif_chroma_444=3, - heif_chroma_interleaved_RGB =10, - heif_chroma_interleaved_RGBA=11 -}; - -// DEPRECTATED ENUM NAMES -#define heif_chroma_interleaved_24bit heif_chroma_interleaved_RGB -#define heif_chroma_interleaved_32bit heif_chroma_interleaved_RGBA - - -enum heif_colorspace { - heif_colorspace_undefined=99, - heif_colorspace_YCbCr=0, - heif_colorspace_RGB =1, - heif_colorspace_monochrome=2 -}; - -enum heif_channel { - heif_channel_Y = 0, - heif_channel_Cb = 1, - heif_channel_Cr = 2, - heif_channel_R = 3, - heif_channel_G = 4, - heif_channel_B = 5, - heif_channel_Alpha = 6, - heif_channel_interleaved = 10 -}; - - -enum heif_progress_step { - heif_progress_step_total = 0, - heif_progress_step_load_tile = 1 -}; - - -struct heif_decoding_options -{ - uint8_t version; - - // version 1 options - - // Ignore geometric transformations like cropping, rotation, mirroring. - // Default: false (do not ignore). - uint8_t ignore_transformations; - - void (*start_progress)(enum heif_progress_step step, int max_progress, void* progress_user_data); - void (*on_progress)(enum heif_progress_step step, int progress, void* progress_user_data); - void (*end_progress)(enum heif_progress_step step, void* progress_user_data); - void* progress_user_data; -}; - - -// Allocate decoding options and fill with default values. -// Note: you should always get the decoding options through this function since the -// option structure may grow in size in future versions. -LIBHEIF_API -struct heif_decoding_options* heif_decoding_options_alloc(); - -LIBHEIF_API -void heif_decoding_options_free(struct heif_decoding_options*); - -// Decode an heif_image_handle into the actual pixel image and also carry out -// all geometric transformations specified in the HEIF file (rotation, cropping, mirroring). -// -// If colorspace or chroma is set to heif_colorspace_undefined or heif_chroma_undefined, -// respectively, the original colorspace is taken. -// Decoding options may be NULL. If you want to supply options, always use -// heif_decoding_options_alloc() to get the structure. -LIBHEIF_API -struct heif_error heif_decode_image(const struct heif_image_handle* in_handle, - struct heif_image** out_img, - enum heif_colorspace colorspace, - enum heif_chroma chroma, - const struct heif_decoding_options* options); - -// Get the colorspace format of the image. -LIBHEIF_API -enum heif_colorspace heif_image_get_colorspace(const struct heif_image*); - -// Get the chroma format of the image. -LIBHEIF_API -enum heif_chroma heif_image_get_chroma_format(const struct heif_image*); - -// Get width of the given image channel in pixels. Returns -1 if a non-existing -// channel was given. -LIBHEIF_API -int heif_image_get_width(const struct heif_image*,enum heif_channel channel); - -// Get height of the given image channel in pixels. Returns -1 if a non-existing -// channel was given. -LIBHEIF_API -int heif_image_get_height(const struct heif_image*,enum heif_channel channel); - -// Get the number of bits per pixel in the given image channel. Returns -1 if -// a non-existing channel was given. -// Note that the number of bits per pixel may be different for each color channel. -LIBHEIF_API -int heif_image_get_bits_per_pixel(const struct heif_image*,enum heif_channel channel); - -LIBHEIF_API -int heif_image_has_channel(const struct heif_image*, enum heif_channel channel); - -// Get a pointer to the actual pixel data. -// The 'out_stride' is returned as "bytes per line". -// When out_stride is NULL, no value will be written. -// Returns NULL if a non-existing channel was given. -LIBHEIF_API -const uint8_t* heif_image_get_plane_readonly(const struct heif_image*, - enum heif_channel channel, - int* out_stride); - -LIBHEIF_API -uint8_t* heif_image_get_plane(struct heif_image*, - enum heif_channel channel, - int* out_stride); - - -struct heif_scaling_options; - -// Currently, heif_scaling_options is not defined yet. Pass a NULL pointer. -LIBHEIF_API -struct heif_error heif_image_scale_image(const struct heif_image* input, - struct heif_image** output, - int width, int height, - const struct heif_scaling_options* options); - -// Release heif_image. -LIBHEIF_API -void heif_image_release(const struct heif_image*); - - -// ==================================================================================================== -// Encoding API - -LIBHEIF_API -struct heif_error heif_context_write_to_file(struct heif_context*, - const char* filename); - -struct heif_writer { - // API version supported by this writer - int writer_api_version; - - // --- version 1 functions --- - struct heif_error (*write)(struct heif_context* ctx, // TODO: why do we need this parameter? - const void* data, - size_t size, - void* userdata); -}; - -LIBHEIF_API -struct heif_error heif_context_write(struct heif_context*, - struct heif_writer* writer, - void* userdata); - - -// ----- encoder ----- - -// The encoder used for actually encoding an image. -struct heif_encoder; - -// A description of the encoder's capabilities and name. -struct heif_encoder_descriptor; - -// A configuration parameter of the encoder. Each encoder implementation may have a different -// set of parameters. For the most common settings (e.q. quality), special functions to set -// the parameters are provided. -struct heif_encoder_parameter; - - -// Get a list of available encoders. You can filter the encoders by compression format and name. -// Use format_filter==heif_compression_undefined and name_filter==NULL as wildcards. -// The returned list of encoders is sorted by their priority (which is a plugin property). -// Note: to get the actual encoder from the descriptors returned here, use heif_context_get_encoder(). -LIBHEIF_API -int heif_context_get_encoder_descriptors(struct heif_context*, // TODO: why do we need this parameter? - enum heif_compression_format format_filter, - const char* name_filter, - const struct heif_encoder_descriptor** out_encoders, - int count); - -// Return a long, descriptive name of the encoder (including version information). -LIBHEIF_API -const char* heif_encoder_descriptor_get_name(const struct heif_encoder_descriptor*); - -// Return a short, symbolic name for identifying the encoder. -// This name should stay constant over different encoder versions. -LIBHEIF_API -const char* heif_encoder_descriptor_get_id_name(const struct heif_encoder_descriptor*); - -LIBHEIF_API -enum heif_compression_format -heif_encoder_descriptor_get_compression_format(const struct heif_encoder_descriptor*); - -LIBHEIF_API -int heif_encoder_descriptor_supportes_lossy_compression(const struct heif_encoder_descriptor*); - -LIBHEIF_API -int heif_encoder_descriptor_supportes_lossless_compression(const struct heif_encoder_descriptor*); - - -// Get an encoder instance that can be used to actually encode images from a descriptor. -// TODO: why do we need the context here? I think we should remove this. You may pass a NULL context. -LIBHEIF_API -struct heif_error heif_context_get_encoder(struct heif_context* context, - const struct heif_encoder_descriptor*, - struct heif_encoder** out_encoder); - -// Quick check whether there is a decoder available for the given format. -// Note that the decoder still may not be able to decode all variants of that format. -// You will have to query that further (todo) or just try to decode and check the returned error. -LIBHEIF_API -int heif_have_decoder_for_format(enum heif_compression_format format); - -// Quick check whether there is an enoder available for the given format. -// Note that the encoder may be limited to a certain subset of features (e.g. only 8 bit, only lossy). -// You will have to query the specific capabilities further. -LIBHEIF_API -int heif_have_encoder_for_format(enum heif_compression_format format); - -// Get an encoder for the given compression format. If there are several encoder plugins -// for this format, the encoder with the highest plugin priority will be returned. -// TODO: why do we need the context here? I think we should remove this. You may pass a NULL context. -LIBHEIF_API -struct heif_error heif_context_get_encoder_for_format(struct heif_context* context, - enum heif_compression_format format, - struct heif_encoder**); - -// You have to release the encoder after use. -LIBHEIF_API -void heif_encoder_release(struct heif_encoder*); - -// Get the encoder name from the encoder itself. -LIBHEIF_API -const char* heif_encoder_get_name(const struct heif_encoder*); - - -// --- Encoder Parameters --- - -// Libheif supports settings parameters through specialized functions and through -// generic functions by parameter name. Sometimes, the same parameter can be set -// in both ways. -// We consider it best practice to use the generic parameter functions only in -// dynamically generated user interfaces, as no guarantees are made that some specific -// parameter names are supported by all plugins. - - -// Set a 'quality' factor (0-100). How this is mapped to actual encoding parameters is -// encoder dependent. -LIBHEIF_API -struct heif_error heif_encoder_set_lossy_quality(struct heif_encoder*, int quality); - -LIBHEIF_API -struct heif_error heif_encoder_set_lossless(struct heif_encoder*, int enable); - -// level should be between 0 (= none) to 4 (= full) -LIBHEIF_API -struct heif_error heif_encoder_set_logging_level(struct heif_encoder*, int level); - -// Get a generic list of encoder parameters. -// Each encoder may define its own, additional set of parameters. -// You do not have to free the returned list. -LIBHEIF_API -const struct heif_encoder_parameter*const* heif_encoder_list_parameters(struct heif_encoder*); - -// Return the parameter name. -LIBHEIF_API -const char* heif_encoder_parameter_get_name(const struct heif_encoder_parameter*); - - -enum heif_encoder_parameter_type { - heif_encoder_parameter_type_integer = 1, - heif_encoder_parameter_type_boolean = 2, - heif_encoder_parameter_type_string = 3 -}; - -// Return the parameter type. -LIBHEIF_API -enum heif_encoder_parameter_type heif_encoder_parameter_get_type(const struct heif_encoder_parameter*); - -LIBHEIF_API -struct heif_error heif_encoder_parameter_get_valid_integer_range(const struct heif_encoder_parameter*, - int* have_minimum_maximum, - int* minimum, int* maximum); - -LIBHEIF_API -struct heif_error heif_encoder_parameter_get_valid_string_values(const struct heif_encoder_parameter*, - const char*const** out_stringarray); - - -LIBHEIF_API -struct heif_error heif_encoder_set_parameter_integer(struct heif_encoder*, - const char* parameter_name, - int value); - -LIBHEIF_API -struct heif_error heif_encoder_get_parameter_integer(struct heif_encoder*, - const char* parameter_name, - int* value); - -// TODO: name should be changed to heif_encoder_get_valid_integer_parameter_range -LIBHEIF_API // DEPRECATED. -struct heif_error heif_encoder_parameter_integer_valid_range(struct heif_encoder*, - const char* parameter_name, - int* have_minimum_maximum, - int* minimum, int* maximum); - -LIBHEIF_API -struct heif_error heif_encoder_set_parameter_boolean(struct heif_encoder*, - const char* parameter_name, - int value); - -LIBHEIF_API -struct heif_error heif_encoder_get_parameter_boolean(struct heif_encoder*, - const char* parameter_name, - int* value); - -LIBHEIF_API -struct heif_error heif_encoder_set_parameter_string(struct heif_encoder*, - const char* parameter_name, - const char* value); - -LIBHEIF_API -struct heif_error heif_encoder_get_parameter_string(struct heif_encoder*, - const char* parameter_name, - char* value, int value_size); - -// returns a NULL-terminated list of valid strings or NULL if all values are allowed -LIBHEIF_API -struct heif_error heif_encoder_parameter_string_valid_values(struct heif_encoder*, - const char* parameter_name, - const char*const** out_stringarray); - -// Set a parameter of any type to the string value. -// Integer values are parsed from the string. -// Boolean values can be "true"/"false"/"1"/"0" -LIBHEIF_API -struct heif_error heif_encoder_set_parameter(struct heif_encoder*, - const char* parameter_name, - const char* value); - -// Get the current value of a parameter of any type as a human readable string. -// The returned string is compatible with heif_encoder_set_parameter(). -LIBHEIF_API -struct heif_error heif_encoder_get_parameter(struct heif_encoder*, - const char* parameter_name, - char* value_ptr, int value_size); - - -struct heif_encoding_options { - uint8_t version; - - // version 1 options - - uint8_t save_alpha_channel; // default: true -}; - -LIBHEIF_API -struct heif_encoding_options* heif_encoding_options_alloc(); - -LIBHEIF_API -void heif_encoding_options_free(struct heif_encoding_options*); - - -// Compress the input image. -// Returns a handle to the coded image in 'out_image_handle' unless out_image_handle = NULL. -// 'options' should be NULL for now. -// The first image added to the context is also automatically set the primary image, but -// you can change the primary image later with heif_context_set_primary_image(). -LIBHEIF_API -struct heif_error heif_context_encode_image(struct heif_context*, - const struct heif_image* image, - struct heif_encoder* encoder, - const struct heif_encoding_options* options, - struct heif_image_handle** out_image_handle); - -LIBHEIF_API -struct heif_error heif_context_set_primary_image(struct heif_context*, - struct heif_image_handle* image_handle); - -// Encode the 'image' as a scaled down thumbnail image. -// The image is scaled down to fit into a square area of width 'bbox_size'. -// If the input image is already so small that it fits into this bounding box, no thumbnail -// image is encoded and NULL is returned in 'out_thumb_image_handle'. -// No error is returned in this case. -// The encoded thumbnail is automatically assigned to the 'master_image_handle'. Hence, you -// do not have to call heif_context_assign_thumbnail(). -LIBHEIF_API -struct heif_error heif_context_encode_thumbnail(struct heif_context*, - const struct heif_image* image, - const struct heif_image_handle* master_image_handle, - struct heif_encoder* encoder, - const struct heif_encoding_options* options, - int bbox_size, - struct heif_image_handle** out_thumb_image_handle); - -// Assign 'thumbnail_image' as the thumbnail image of 'master_image'. -LIBHEIF_API -struct heif_error heif_context_assign_thumbnail(struct heif_context*, - const struct heif_image_handle* thumbnail_image, - const struct heif_image_handle* master_image); - -// Add EXIF metadata to an image. The raw EXIF metadata shall begin with the TIFF header. -LIBHEIF_API -struct heif_error heif_context_add_exif_metadata(struct heif_context*, - const struct heif_image_handle* image_handle, - const void* data, int size); - -// Add XMP metadata to an image. -LIBHEIF_API -struct heif_error heif_context_add_XMP_metadata(struct heif_context*, - const struct heif_image_handle* image_handle, - const void* data, int size); - - -// --- heif_image allocation - -// Create a new image of the specified resolution and colorspace. -// Note: no memory for the actual image data is reserved yet. You have to use -// heif_image_add_plane() to add the image planes required by your colorspace/chroma. -LIBHEIF_API -struct heif_error heif_image_create(int width, int height, - enum heif_colorspace colorspace, - enum heif_chroma chroma, - struct heif_image** out_image); - -LIBHEIF_API -struct heif_error heif_image_add_plane(struct heif_image* image, - enum heif_channel channel, - int width, int height, int bit_depth); - - - - -// --- register plugins - -struct heif_decoder_plugin; -struct heif_encoder_plugin; - -// DEPRECATED. Use heif_register_decoder_plugin(const struct heif_decoder_plugin*) instead. -LIBHEIF_API -struct heif_error heif_register_decoder(struct heif_context* heif, const struct heif_decoder_plugin*); - -LIBHEIF_API -struct heif_error heif_register_decoder_plugin(const struct heif_decoder_plugin*); - -LIBHEIF_API -struct heif_error heif_register_encoder_plugin(const struct heif_encoder_plugin*); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Vendors/include/libheif/heif_version.h b/Vendors/include/libheif/heif_version.h deleted file mode 100644 index 2f4ac45..0000000 --- a/Vendors/include/libheif/heif_version.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * HEIF codec. - * Copyright (c) 2017 struktur AG, Dirk Farin - * - * This file is part of libheif. - * - * libheif is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * libheif is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libheif. If not, see . - */ - -/* heif-version.h - * - * This file was generated by autoconf when libheif was built. - * - * DO NOT EDIT THIS FILE. - */ -#ifndef LIBHEIF_HEIF_VERSION_H -#define LIBHEIF_HEIF_VERSION_H - -/* Numeric representation of the version */ -#define LIBHEIF_NUMERIC_VERSION 0x01030200 - -/* Version string */ -#define LIBHEIF_VERSION "1.3.2" - -#endif // LIBHEIF_HEIF_VERSION_H diff --git a/Vendors/include/libx265/x265.h b/Vendors/include/libx265/x265.h deleted file mode 100644 index 6d783dc..0000000 --- a/Vendors/include/libx265/x265.h +++ /dev/null @@ -1,1908 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2013-2017 MulticoreWare, Inc - * - * Authors: Steve Borho - * Min Chen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. - * - * This program is also available under a commercial proprietary license. - * For more information, contact us at license @ x265.com. - *****************************************************************************/ - -#ifndef X265_H -#define X265_H -#include -#include -#include "x265_config.h" -#ifdef __cplusplus -extern "C" { -#endif - -/* x265_encoder: - * opaque handler for encoder */ -typedef struct x265_encoder x265_encoder; - -/* x265_picyuv: - * opaque handler for PicYuv */ -typedef struct x265_picyuv x265_picyuv; - -/* Application developers planning to link against a shared library version of - * libx265 from a Microsoft Visual Studio or similar development environment - * will need to define X265_API_IMPORTS before including this header. - * This clause does not apply to MinGW, similar development environments, or non - * Windows platforms. */ -#ifdef X265_API_IMPORTS -#define X265_API __declspec(dllimport) -#else -#define X265_API -#endif - -typedef enum -{ - NAL_UNIT_CODED_SLICE_TRAIL_N = 0, - NAL_UNIT_CODED_SLICE_TRAIL_R, - NAL_UNIT_CODED_SLICE_TSA_N, - NAL_UNIT_CODED_SLICE_TLA_R, - NAL_UNIT_CODED_SLICE_STSA_N, - NAL_UNIT_CODED_SLICE_STSA_R, - NAL_UNIT_CODED_SLICE_RADL_N, - NAL_UNIT_CODED_SLICE_RADL_R, - NAL_UNIT_CODED_SLICE_RASL_N, - NAL_UNIT_CODED_SLICE_RASL_R, - NAL_UNIT_CODED_SLICE_BLA_W_LP = 16, - NAL_UNIT_CODED_SLICE_BLA_W_RADL, - NAL_UNIT_CODED_SLICE_BLA_N_LP, - NAL_UNIT_CODED_SLICE_IDR_W_RADL, - NAL_UNIT_CODED_SLICE_IDR_N_LP, - NAL_UNIT_CODED_SLICE_CRA, - NAL_UNIT_VPS = 32, - NAL_UNIT_SPS, - NAL_UNIT_PPS, - NAL_UNIT_ACCESS_UNIT_DELIMITER, - NAL_UNIT_EOS, - NAL_UNIT_EOB, - NAL_UNIT_FILLER_DATA, - NAL_UNIT_PREFIX_SEI, - NAL_UNIT_SUFFIX_SEI, - NAL_UNIT_INVALID = 64, -} NalUnitType; - -/* The data within the payload is already NAL-encapsulated; the type is merely - * in the struct for easy access by the calling application. All data returned - * in an x265_nal, including the data in payload, is no longer valid after the - * next call to x265_encoder_encode. Thus it must be used or copied before - * calling x265_encoder_encode again. */ -typedef struct x265_nal -{ - uint32_t type; /* NalUnitType */ - uint32_t sizeBytes; /* size in bytes */ - uint8_t* payload; -} x265_nal; - -#define X265_LOOKAHEAD_MAX 250 - -typedef struct x265_lookahead_data -{ - int64_t plannedSatd[X265_LOOKAHEAD_MAX + 1]; - uint32_t *vbvCost; - uint32_t *intraVbvCost; - uint32_t *satdForVbv; - uint32_t *intraSatdForVbv; - int keyframe; - int lastMiniGopBFrame; - int plannedType[X265_LOOKAHEAD_MAX + 1]; - int64_t dts; -} x265_lookahead_data; - -/* Stores all analysis data for a single frame */ -typedef struct x265_analysis_data -{ - int64_t satdCost; - uint32_t frameRecordSize; - uint32_t poc; - uint32_t sliceType; - uint32_t numCUsInFrame; - uint32_t numPartitions; - uint32_t depthBytes; - int bScenecut; - void* wt; - void* interData; - void* intraData; - uint32_t numCuInHeight; - x265_lookahead_data lookahead; - uint8_t* modeFlag[2]; -} x265_analysis_data; - -/* cu statistics */ -typedef struct x265_cu_stats -{ - double percentSkipCu[4]; // Percentage of skip cu in all depths - double percentMergeCu[4]; // Percentage of merge cu in all depths - double percentIntraDistribution[4][3]; // Percentage of DC, Planar, Angular intra modes in all depths - double percentInterDistribution[4][3]; // Percentage of 2Nx2N inter, rect and amp in all depths - double percentIntraNxN; // Percentage of 4x4 cu - - /* All the above values will add up to 100%. */ -} x265_cu_stats; - - -/* pu statistics */ -typedef struct x265_pu_stats -{ - double percentSkipPu[4]; // Percentage of skip cu in all depths - double percentIntraPu[4]; // Percentage of intra modes in all depths - double percentAmpPu[4]; // Percentage of amp modes in all depths - double percentInterPu[4][3]; // Percentage of inter 2nx2n, 2nxn and nx2n in all depths - double percentMergePu[4][3]; // Percentage of merge 2nx2n, 2nxn and nx2n in all depth - double percentNxN; - - /* All the above values will add up to 100%. */ -} x265_pu_stats; - - -typedef struct x265_analysis_2Pass -{ - uint32_t poc; - uint32_t frameRecordSize; - void* analysisFramedata; -}x265_analysis_2Pass; - -/* Frame level statistics */ -typedef struct x265_frame_stats -{ - double qp; - double rateFactor; - double psnrY; - double psnrU; - double psnrV; - double psnr; - double ssim; - double decideWaitTime; - double row0WaitTime; - double wallTime; - double refWaitWallTime; - double totalCTUTime; - double stallTime; - double avgWPP; - double avgLumaDistortion; - double avgChromaDistortion; - double avgPsyEnergy; - double avgResEnergy; - double avgLumaLevel; - double bufferFill; - uint64_t bits; - int encoderOrder; - int poc; - int countRowBlocks; - int list0POC[16]; - int list1POC[16]; - uint16_t maxLumaLevel; - uint16_t minLumaLevel; - - uint16_t maxChromaULevel; - uint16_t minChromaULevel; - double avgChromaULevel; - - - uint16_t maxChromaVLevel; - uint16_t minChromaVLevel; - double avgChromaVLevel; - - char sliceType; - int bScenecut; - double ipCostRatio; - int frameLatency; - x265_cu_stats cuStats; - x265_pu_stats puStats; - double totalFrameTime; -} x265_frame_stats; - -typedef struct x265_ctu_info_t -{ - int32_t ctuAddress; - int32_t ctuPartitions[64]; - void* ctuInfo; -} x265_ctu_info_t; - -typedef enum -{ - NO_CTU_INFO = 0, - HAS_CTU_INFO = 1, - CTU_INFO_CHANGE = 2, -}CTUInfo; - -typedef enum -{ - NO_INFO = 0, - AVC_INFO = 1, -}MVRefineType; - -/* Arbitrary User SEI - * Payload size is in bytes and the payload pointer must be non-NULL. - * Payload types and syntax can be found in Annex D of the H.265 Specification. - * SEI Payload Alignment bits as described in Annex D must be included at the - * end of the payload if needed. The payload should not be NAL-encapsulated. - * Payloads are written in the order of input */ - -typedef enum -{ - BUFFERING_PERIOD = 0, - PICTURE_TIMING = 1, - PAN_SCAN_RECT = 2, - FILLER_PAYLOAD = 3, - USER_DATA_REGISTERED_ITU_T_T35 = 4, - USER_DATA_UNREGISTERED = 5, - RECOVERY_POINT = 6, - SCENE_INFO = 9, - FULL_FRAME_SNAPSHOT = 15, - PROGRESSIVE_REFINEMENT_SEGMENT_START = 16, - PROGRESSIVE_REFINEMENT_SEGMENT_END = 17, - FILM_GRAIN_CHARACTERISTICS = 19, - POST_FILTER_HINT = 22, - TONE_MAPPING_INFO = 23, - FRAME_PACKING = 45, - DISPLAY_ORIENTATION = 47, - SOP_DESCRIPTION = 128, - ACTIVE_PARAMETER_SETS = 129, - DECODING_UNIT_INFO = 130, - TEMPORAL_LEVEL0_INDEX = 131, - DECODED_PICTURE_HASH = 132, - SCALABLE_NESTING = 133, - REGION_REFRESH_INFO = 134, - MASTERING_DISPLAY_INFO = 137, - CONTENT_LIGHT_LEVEL_INFO = 144, -} SEIPayloadType; - -typedef struct x265_sei_payload -{ - int payloadSize; - SEIPayloadType payloadType; - uint8_t* payload; -} x265_sei_payload; - -typedef struct x265_sei -{ - int numPayloads; - x265_sei_payload *payloads; -} x265_sei; - -/* Used to pass pictures into the encoder, and to get picture data back out of - * the encoder. The input and output semantics are different */ -typedef struct x265_picture -{ - /* presentation time stamp: user-specified, returned on output */ - int64_t pts; - - /* display time stamp: ignored on input, copied from reordered pts. Returned - * on output */ - int64_t dts; - - /* force quantizer for != X265_QP_AUTO */ - /* The value provided on input is returned with the same picture (POC) on - * output */ - void* userData; - - /* Must be specified on input pictures, the number of planes is determined - * by the colorSpace value */ - void* planes[3]; - - /* Stride is the number of bytes between row starts */ - int stride[3]; - - /* Must be specified on input pictures. x265_picture_init() will set it to - * the encoder's internal bit depth, but this field must describe the depth - * of the input pictures. Must be between 8 and 16. Values larger than 8 - * imply 16bits per input sample. If input bit depth is larger than the - * internal bit depth, the encoder will down-shift pixels. Input samples - * larger than 8bits will be masked to internal bit depth. On output the - * bitDepth will be the internal encoder bit depth */ - int bitDepth; - - /* Must be specified on input pictures: X265_TYPE_AUTO or other. - * x265_picture_init() sets this to auto, returned on output */ - int sliceType; - - /* Ignored on input, set to picture count, returned on output */ - int poc; - - /* Must be specified on input pictures: X265_CSP_I420 or other. It must - * match the internal color space of the encoder. x265_picture_init() will - * initialize this value to the internal color space */ - int colorSpace; - - /* Force the slice base QP for this picture within the encoder. Set to 0 - * to allow the encoder to determine base QP */ - int forceqp; - - /* If param.analysisLoad and param.analysisSave are disabled, this field is - * ignored on input and output. Else the user must call x265_alloc_analysis_data() - * to allocate analysis buffers for every picture passed to the encoder. - * - * On input when param.analysisLoad is enabled and analysisData - * member pointers are valid, the encoder will use the data stored here to - * reduce encoder work. - * - * On output when param.analysisSave is enabled and analysisData - * member pointers are valid, the encoder will write output analysis into - * this data structure */ - x265_analysis_data analysisData; - - /* An array of quantizer offsets to be applied to this image during encoding. - * These are added on top of the decisions made by rateControl. - * Adaptive quantization must be enabled to use this feature. These quantizer - * offsets should be given for each 16x16 block (8x8 block, when qg-size is 8). - * Behavior if quant offsets differ between encoding passes is undefined. */ - float *quantOffsets; - - /* Frame level statistics */ - x265_frame_stats frameData; - - /* User defined SEI */ - x265_sei userSEI; - - /* Ratecontrol statistics for collecting the ratecontrol information. - * It is not used for collecting the last pass ratecontrol data in - * multi pass ratecontrol mode. */ - void* rcData; - - uint64_t framesize; - - int height; - - x265_analysis_2Pass analysis2Pass; -} x265_picture; - -typedef enum -{ - X265_DIA_SEARCH, - X265_HEX_SEARCH, - X265_UMH_SEARCH, - X265_STAR_SEARCH, - X265_SEA, - X265_FULL_SEARCH -} X265_ME_METHODS; - -/* CPU flags */ - -/* x86 */ -#define X265_CPU_CMOV 0x0000001 -#define X265_CPU_MMX 0x0000002 -#define X265_CPU_MMX2 0x0000004 /* MMX2 aka MMXEXT aka ISSE */ -#define X265_CPU_MMXEXT X265_CPU_MMX2 -#define X265_CPU_SSE 0x0000008 -#define X265_CPU_SSE2 0x0000010 -#define X265_CPU_SSE3 0x0000020 -#define X265_CPU_SSSE3 0x0000040 -#define X265_CPU_SSE4 0x0000080 /* SSE4.1 */ -#define X265_CPU_SSE42 0x0000100 /* SSE4.2 */ -#define X265_CPU_LZCNT 0x0000200 /* Phenom support for "leading zero count" instruction. */ -#define X265_CPU_AVX 0x0000400 /* AVX support: requires OS support even if YMM registers aren't used. */ -#define X265_CPU_XOP 0x0000800 /* AMD XOP */ -#define X265_CPU_FMA4 0x0001000 /* AMD FMA4 */ -#define X265_CPU_AVX2 0x0002000 /* AVX2 */ -#define X265_CPU_FMA3 0x0004000 /* Intel FMA3 */ -#define X265_CPU_BMI1 0x0008000 /* BMI1 */ -#define X265_CPU_BMI2 0x0010000 /* BMI2 */ -/* x86 modifiers */ -#define X265_CPU_CACHELINE_32 0x0020000 /* avoid memory loads that span the border between two cachelines */ -#define X265_CPU_CACHELINE_64 0x0040000 /* 32/64 is the size of a cacheline in bytes */ -#define X265_CPU_SSE2_IS_SLOW 0x0080000 /* avoid most SSE2 functions on Athlon64 */ -#define X265_CPU_SSE2_IS_FAST 0x0100000 /* a few functions are only faster on Core2 and Phenom */ -#define X265_CPU_SLOW_SHUFFLE 0x0200000 /* The Conroe has a slow shuffle unit (relative to overall SSE performance) */ -#define X265_CPU_STACK_MOD4 0x0400000 /* if stack is only mod4 and not mod16 */ -#define X265_CPU_SLOW_CTZ 0x0800000 /* BSR/BSF x86 instructions are really slow on some CPUs */ -#define X265_CPU_SLOW_ATOM 0x1000000 /* The Atom is terrible: slow SSE unaligned loads, slow - * SIMD multiplies, slow SIMD variable shifts, slow pshufb, - * cacheline split penalties -- gather everything here that - * isn't shared by other CPUs to avoid making half a dozen - * new SLOW flags. */ -#define X265_CPU_SLOW_PSHUFB 0x2000000 /* such as on the Intel Atom */ -#define X265_CPU_SLOW_PALIGNR 0x4000000 /* such as on the AMD Bobcat */ - -/* ARM */ -#define X265_CPU_ARMV6 0x0000001 -#define X265_CPU_NEON 0x0000002 /* ARM NEON */ -#define X265_CPU_FAST_NEON_MRC 0x0000004 /* Transfer from NEON to ARM register is fast (Cortex-A9) */ - -/* IBM Power8 */ -#define X265_CPU_ALTIVEC 0x0000001 - -#define X265_MAX_SUBPEL_LEVEL 7 - -/* Log level */ -#define X265_LOG_NONE (-1) -#define X265_LOG_ERROR 0 -#define X265_LOG_WARNING 1 -#define X265_LOG_INFO 2 -#define X265_LOG_DEBUG 3 -#define X265_LOG_FULL 4 - -#define X265_B_ADAPT_NONE 0 -#define X265_B_ADAPT_FAST 1 -#define X265_B_ADAPT_TRELLIS 2 - -#define X265_REF_LIMIT_DEPTH 1 -#define X265_REF_LIMIT_CU 2 - -#define X265_TU_LIMIT_BFS 1 -#define X265_TU_LIMIT_DFS 2 -#define X265_TU_LIMIT_NEIGH 4 - -#define X265_BFRAME_MAX 16 -#define X265_MAX_FRAME_THREADS 16 - -#define X265_TYPE_AUTO 0x0000 /* Let x265 choose the right type */ -#define X265_TYPE_IDR 0x0001 -#define X265_TYPE_I 0x0002 -#define X265_TYPE_P 0x0003 -#define X265_TYPE_BREF 0x0004 /* Non-disposable B-frame */ -#define X265_TYPE_B 0x0005 -#define IS_X265_TYPE_I(x) ((x) == X265_TYPE_I || (x) == X265_TYPE_IDR) -#define IS_X265_TYPE_B(x) ((x) == X265_TYPE_B || (x) == X265_TYPE_BREF) - -#define X265_QP_AUTO 0 - -#define X265_AQ_NONE 0 -#define X265_AQ_VARIANCE 1 -#define X265_AQ_AUTO_VARIANCE 2 -#define X265_AQ_AUTO_VARIANCE_BIASED 3 - -#define x265_ADAPT_RD_STRENGTH 4 - -/* NOTE! For this release only X265_CSP_I420 and X265_CSP_I444 are supported */ - -/* Supported internal color space types (according to semantics of chroma_format_idc) */ -#define X265_CSP_I400 0 /* yuv 4:0:0 planar */ -#define X265_CSP_I420 1 /* yuv 4:2:0 planar */ -#define X265_CSP_I422 2 /* yuv 4:2:2 planar */ -#define X265_CSP_I444 3 /* yuv 4:4:4 planar */ -#define X265_CSP_COUNT 4 /* Number of supported internal color spaces */ - -/* These color spaces will eventually be supported as input pictures. The pictures will - * be converted to the appropriate planar color spaces at ingest */ -#define X265_CSP_NV12 4 /* yuv 4:2:0, with one y plane and one packed u+v */ -#define X265_CSP_NV16 5 /* yuv 4:2:2, with one y plane and one packed u+v */ - -/* Interleaved color-spaces may eventually be supported as input pictures */ -#define X265_CSP_BGR 6 /* packed bgr 24bits */ -#define X265_CSP_BGRA 7 /* packed bgr 32bits */ -#define X265_CSP_RGB 8 /* packed rgb 24bits */ -#define X265_CSP_MAX 9 /* end of list */ -#define X265_EXTENDED_SAR 255 /* aspect ratio explicitly specified as width:height */ -/* Analysis options */ -#define X265_ANALYSIS_OFF 0 -#define X265_ANALYSIS_SAVE 1 -#define X265_ANALYSIS_LOAD 2 - -typedef struct x265_cli_csp -{ - int planes; - int width[3]; - int height[3]; -} x265_cli_csp; - -static const x265_cli_csp x265_cli_csps[] = -{ - { 1, { 0, 0, 0 }, { 0, 0, 0 } }, /* i400 */ - { 3, { 0, 1, 1 }, { 0, 1, 1 } }, /* i420 */ - { 3, { 0, 1, 1 }, { 0, 0, 0 } }, /* i422 */ - { 3, { 0, 0, 0 }, { 0, 0, 0 } }, /* i444 */ - { 2, { 0, 0 }, { 0, 1 } }, /* nv12 */ - { 2, { 0, 0 }, { 0, 0 } }, /* nv16 */ -}; - -/* rate tolerance method */ -typedef enum -{ - X265_RC_ABR, - X265_RC_CQP, - X265_RC_CRF -} X265_RC_METHODS; - -/* slice type statistics */ -typedef struct x265_sliceType_stats -{ - double avgQp; - double bitrate; - double psnrY; - double psnrU; - double psnrV; - double ssim; - uint32_t numPics; -} x265_sliceType_stats; - -/* Output statistics from encoder */ -typedef struct x265_stats -{ - double globalPsnrY; - double globalPsnrU; - double globalPsnrV; - double globalPsnr; - double globalSsim; - double elapsedEncodeTime; /* wall time since encoder was opened */ - double elapsedVideoTime; /* encoded picture count / frame rate */ - double bitrate; /* accBits / elapsed video time */ - uint64_t accBits; /* total bits output thus far */ - uint32_t encodedPictureCount; /* number of output pictures thus far */ - uint32_t totalWPFrames; /* number of uni-directional weighted frames used */ - x265_sliceType_stats statsI; /* statistics of I slice */ - x265_sliceType_stats statsP; /* statistics of P slice */ - x265_sliceType_stats statsB; /* statistics of B slice */ - uint16_t maxCLL; /* maximum content light level */ - uint16_t maxFALL; /* maximum frame average light level */ -} x265_stats; - -/* String values accepted by x265_param_parse() (and CLI) for various parameters */ -static const char * const x265_motion_est_names[] = { "dia", "hex", "umh", "star", "sea", "full", 0 }; -static const char * const x265_source_csp_names[] = { "i400", "i420", "i422", "i444", "nv12", "nv16", 0 }; -static const char * const x265_video_format_names[] = { "component", "pal", "ntsc", "secam", "mac", "unknown", 0 }; -static const char * const x265_fullrange_names[] = { "limited", "full", 0 }; -static const char * const x265_colorprim_names[] = { "reserved", "bt709", "unknown", "reserved", "bt470m", "bt470bg", "smpte170m", "smpte240m", "film", "bt2020", "smpte428", "smpte431", "smpte432", 0 }; -static const char * const x265_transfer_names[] = { "reserved", "bt709", "unknown", "reserved", "bt470m", "bt470bg", "smpte170m", "smpte240m", "linear", "log100", - "log316", "iec61966-2-4", "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", - "smpte2084", "smpte428", "arib-std-b67", 0 }; -static const char * const x265_colmatrix_names[] = { "gbr", "bt709", "unknown", "", "fcc", "bt470bg", "smpte170m", "smpte240m", - "ycgco", "bt2020nc", "bt2020c", "smpte2085", "chroma-derived-nc", "chroma-derived-c", "ictcp", 0 }; -static const char * const x265_sar_names[] = { "unknown", "1:1", "12:11", "10:11", "16:11", "40:33", "24:11", "20:11", - "32:11", "80:33", "18:11", "15:11", "64:33", "160:99", "4:3", "3:2", "2:1", 0 }; -static const char * const x265_interlace_names[] = { "prog", "tff", "bff", 0 }; -static const char * const x265_analysis_names[] = { "off", "save", "load", 0 }; - -/* Zones: override ratecontrol for specific sections of the video. - * If zones overlap, whichever comes later in the list takes precedence. */ -typedef struct x265_zone -{ - int startFrame, endFrame; /* range of frame numbers */ - int bForceQp; /* whether to use qp vs bitrate factor */ - int qp; - float bitrateFactor; -} x265_zone; - -/* x265 input parameters - * - * For version safety you may use x265_param_alloc/free() to manage the - * allocation of x265_param instances, and x265_param_parse() to assign values - * by name. By never dereferencing param fields in your own code you can treat - * x265_param as an opaque data structure */ -typedef struct x265_param -{ - /* x265_param_default() will auto-detect this cpu capability bitmap. it is - * recommended to not change this value unless you know the cpu detection is - * somehow flawed on your target hardware. The asm function tables are - * process global, the first encoder configures them for all encoders */ - int cpuid; - - /*== Parallelism Features ==*/ - - /* Number of concurrently encoded frames between 1 and X265_MAX_FRAME_THREADS - * or 0 for auto-detection. By default x265 will use a number of frame - * threads empirically determined to be optimal for your CPU core count, - * between 2 and 6. Using more than one frame thread causes motion search - * in the down direction to be clamped but otherwise encode behavior is - * unaffected. With CQP rate control the output bitstream is deterministic - * for all values of frameNumThreads greater than 1. All other forms of - * rate-control can be negatively impacted by increases to the number of - * frame threads because the extra concurrency adds uncertainty to the - * bitrate estimations. Frame parallelism is generally limited by the the - * is generally limited by the the number of CU rows - * - * When thread pools are used, each frame thread is assigned to a single - * pool and the frame thread itself is given the node affinity of its pool. - * But when no thread pools are used no node affinity is assigned. */ - int frameNumThreads; - - /* Comma seperated list of threads per NUMA node. If "none", then no worker - * pools are created and only frame parallelism is possible. If NULL or "" - * (default) x265 will use all available threads on each NUMA node. - * - * '+' is a special value indicating all cores detected on the node - * '*' is a special value indicating all cores detected on the node and all - * remaining nodes. - * '-' is a special value indicating no cores on the node, same as '0' - * - * example strings for a 4-node system: - * "" - default, unspecified, all numa nodes are used for thread pools - * "*" - same as default - * "none" - no thread pools are created, only frame parallelism possible - * "-" - same as "none" - * "10" - allocate one pool, using up to 10 cores on node 0 - * "-,+" - allocate one pool, using all cores on node 1 - * "+,-,+" - allocate two pools, using all cores on nodes 0 and 2 - * "+,-,+,-" - allocate two pools, using all cores on nodes 0 and 2 - * "-,*" - allocate three pools, using all cores on nodes 1, 2 and 3 - * "8,8,8,8" - allocate four pools with up to 8 threads in each pool - * - * The total number of threads will be determined by the number of threads - * assigned to all nodes. The worker threads will each be given affinity for - * their node, they will not be allowed to migrate between nodes, but they - * will be allowed to move between CPU cores within their node. - * - * If the three pool features: bEnableWavefront, bDistributeModeAnalysis and - * bDistributeMotionEstimation are all disabled, then numaPools is ignored - * and no thread pools are created. - * - * If "none" is specified, then all three of the thread pool features are - * implicitly disabled. - * - * Multiple thread pools will be allocated for any NUMA node with more than - * 64 logical CPU cores. But any given thread pool will always use at most - * one NUMA node. - * - * Frame encoders are distributed between the available thread pools, and - * the encoder will never generate more thread pools than frameNumThreads */ - const char* numaPools; - - /* Enable wavefront parallel processing, greatly increases parallelism for - * less than 1% compression efficiency loss. Requires a thread pool, enabled - * by default */ - int bEnableWavefront; - - /* Use multiple threads to measure CU mode costs. Recommended for many core - * CPUs. On RD levels less than 5, it may not offload enough work to warrant - * the overhead. It is useful with the slow preset since it has the - * rectangular predictions enabled. At RD level 5 and 6 (preset slower and - * below), this feature should be an unambiguous win if you have CPU - * cores available for work. Default disabled */ - int bDistributeModeAnalysis; - - /* Use multiple threads to perform motion estimation to (ME to one reference - * per thread). Recommended for many core CPUs. The more references the more - * motion searches there will be to distribute. This option is often not a - * win, particularly in video sequences with low motion. Default disabled */ - int bDistributeMotionEstimation; - - /*== Logging Features ==*/ - - /* Enable analysis and logging distribution of CUs. Now deprecated */ - int bLogCuStats; - - /* Enable the measurement and reporting of PSNR. Default is enabled */ - int bEnablePsnr; - - /* Enable the measurement and reporting of SSIM. Default is disabled */ - int bEnableSsim; - - /* The level of logging detail emitted by the encoder. X265_LOG_NONE to - * X265_LOG_FULL, default is X265_LOG_INFO */ - int logLevel; - - /* Level of csv logging. 0 is summary, 1 is frame level logging, - * 2 is frame level logging with performance statistics */ - int csvLogLevel; - - /* filename of CSV log. If csvLogLevel is non-zero, the encoder will emit - * per-slice statistics to this log file in encode order. Otherwise the - * encoder will emit per-stream statistics into the log file when - * x265_encoder_log is called (presumably at the end of the encode) */ - const char* csvfn; - - /*== Internal Picture Specification ==*/ - - /* Internal encoder bit depth. If x265 was compiled to use 8bit pixels - * (HIGH_BIT_DEPTH=0), this field must be 8, else this field must be 10. - * Future builds may support 12bit pixels. */ - int internalBitDepth; - - /* Color space of internal pictures, must match color space of input - * pictures */ - int internalCsp; - - /* Numerator and denominator of frame rate */ - uint32_t fpsNum; - uint32_t fpsDenom; - - /* Width (in pixels) of the source pictures. If this width is not an even - * multiple of 4, the encoder will pad the pictures internally to meet this - * minimum requirement. All valid HEVC widths are supported */ - int sourceWidth; - - /* Height (in pixels) of the source pictures. If this height is not an even - * multiple of 4, the encoder will pad the pictures internally to meet this - * minimum requirement. All valid HEVC heights are supported */ - int sourceHeight; - - /* Interlace type of source pictures. 0 - progressive pictures (default). - * 1 - top field first, 2 - bottom field first. HEVC encodes interlaced - * content as fields, they must be provided to the encoder in the correct - * temporal order */ - int interlaceMode; - - /* Total Number of frames to be encoded, calculated from the user input - * (--frames) and (--seek). In case, the input is read from a pipe, this can - * remain as 0. It is later used in 2 pass RateControl, hence storing the - * value in param */ - int totalFrames; - - /*== Profile / Tier / Level ==*/ - - /* Note: the profile is specified by x265_param_apply_profile() */ - - /* Minimum decoder requirement level. Defaults to 0, which implies auto- - * detection by the encoder. If specified, the encoder will attempt to bring - * the encode specifications within that specified level. If the encoder is - * unable to reach the level it issues a warning and emits the actual - * decoder requirement. If the requested requirement level is higher than - * the actual level, the actual requirement level is signaled. The value is - * an specified as an integer with the level times 10, for example level - * "5.1" is specified as 51, and level "5.0" is specified as 50. */ - int levelIdc; - - /* if levelIdc is specified (non-zero) this flag will differentiate between - * Main (0) and High (1) tier. Default is Main tier (0) */ - int bHighTier; - - /* Enable UHD Blu-ray compatibility support. If specified, the encoder will - * attempt to modify/set the encode specifications. If the encoder is unable - * to do so, this option will be turned OFF. */ - int uhdBluray; - - /* The maximum number of L0 references a P or B slice may use. This - * influences the size of the decoded picture buffer. The higher this - * number, the more reference frames there will be available for motion - * search, improving compression efficiency of most video at a cost of - * performance. Value must be between 1 and 16, default is 3 */ - int maxNumReferences; - - /* Allow libx265 to emit HEVC bitstreams which do not meet strict level - * requirements. Defaults to false */ - int bAllowNonConformance; - - /*== Bitstream Options ==*/ - - /* Flag indicating whether VPS, SPS and PPS headers should be output with - * each keyframe. Default false */ - int bRepeatHeaders; - - /* Flag indicating whether the encoder should generate start codes (Annex B - * format) or length (file format) before NAL units. Default true, Annex B. - * Muxers should set this to the correct value */ - int bAnnexB; - - /* Flag indicating whether the encoder should emit an Access Unit Delimiter - * NAL at the start of every access unit. Default false */ - int bEnableAccessUnitDelimiters; - - /* Enables the buffering period SEI and picture timing SEI to signal the HRD - * parameters. Default is disabled */ - int bEmitHRDSEI; - - /* Enables the emission of a user data SEI with the stream headers which - * describes the encoder version, build info, and parameters. This is - * very helpful for debugging, but may interfere with regression tests. - * Default enabled */ - int bEmitInfoSEI; - - /* Enable the generation of SEI messages for each encoded frame containing - * the hashes of the three reconstructed picture planes. Most decoders will - * validate those hashes against the reconstructed images it generates and - * report any mismatches. This is essentially a debugging feature. Hash - * types are MD5(1), CRC(2), Checksum(3). Default is 0, none */ - int decodedPictureHashSEI; - - /* Enable Temporal Sub Layers while encoding, signals NAL units of coded - * slices with their temporalId. Output bitstreams can be extracted either - * at the base temporal layer (layer 0) with roughly half the frame rate or - * at a higher temporal layer (layer 1) that decodes all the frames in the - * sequence. */ - int bEnableTemporalSubLayers; - - /*== GOP structure and slice type decisions (lookahead) ==*/ - - /* Enable open GOP - meaning I slices are not necessarily IDR and thus frames - * encoded after an I slice may reference frames encoded prior to the I - * frame which have remained in the decoded picture buffer. Open GOP - * generally has better compression efficiency and negligible encoder - * performance impact, but the use case may preclude it. Default true */ - int bOpenGOP; - - /* Scene cuts closer together than this are coded as I, not IDR. */ - int keyframeMin; - - /* Maximum keyframe distance or intra period in number of frames. If 0 or 1, - * all frames are I frames. A negative value is casted to MAX_INT internally - * which effectively makes frame 0 the only I frame. Default is 250 */ - int keyframeMax; - - /* Maximum consecutive B frames that can be emitted by the lookahead. When - * b-adapt is 0 and keyframMax is greater than bframes, the lookahead emits - * a fixed pattern of `bframes` B frames between each P. With b-adapt 1 the - * lookahead ignores the value of bframes for the most part. With b-adapt 2 - * the value of bframes determines the search (POC) distance performed in - * both directions, quadratically increasing the compute load of the - * lookahead. The higher the value, the more B frames the lookahead may - * possibly use consecutively, usually improving compression. Default is 3, - * maximum is 16 */ - int bframes; - - /* Sets the operating mode of the lookahead. With b-adapt 0, the GOP - * structure is fixed based on the values of keyframeMax and bframes. - * With b-adapt 1 a light lookahead is used to chose B frame placement. - * With b-adapt 2 (trellis) a viterbi B path selection is performed */ - int bFrameAdaptive; - - /* When enabled, the encoder will use the B frame in the middle of each - * mini-GOP larger than 2 B frames as a motion reference for the surrounding - * B frames. This improves compression efficiency for a small performance - * penalty. Referenced B frames are treated somewhere between a B and a P - * frame by rate control. Default is enabled. */ - int bBPyramid; - - /* A value which is added to the cost estimate of B frames in the lookahead. - * It may be a positive value (making B frames appear less expensive, which - * biases the lookahead to choose more B frames) or negative, which makes the - * lookahead choose more P frames. Default is 0, there are no limits */ - int bFrameBias; - - /* The number of frames that must be queued in the lookahead before it may - * make slice decisions. Increasing this value directly increases the encode - * latency. The longer the queue the more optimally the lookahead may make - * slice decisions, particularly with b-adapt 2. When cu-tree is enabled, - * the length of the queue linearly increases the effectiveness of the - * cu-tree analysis. Default is 40 frames, maximum is 250 */ - int lookaheadDepth; - - /* Use multiple worker threads to measure the estimated cost of each frame - * within the lookahead. When bFrameAdaptive is 2, most frame cost estimates - * will be performed in batch mode, many cost estimates at the same time, - * and lookaheadSlices is ignored for batched estimates. The effect on - * performance can be quite small. The higher this parameter, the less - * accurate the frame costs will be (since context is lost across slice - * boundaries) which will result in less accurate B-frame and scene-cut - * decisions. Default is 0 - disabled. 1 is the same as 0. Max 16 */ - int lookaheadSlices; - - /* An arbitrary threshold which determines how aggressively the lookahead - * should detect scene cuts. The default (40) is recommended. */ - int scenecutThreshold; - - /* Replace keyframes by using a column of intra blocks that move across the video - * from one side to the other, thereby "refreshing" the image. In effect, instead of a - * big keyframe, the keyframe is "spread" over many frames. */ - int bIntraRefresh; - - /*== Coding Unit (CU) definitions ==*/ - - /* Maximum CU width and height in pixels. The size must be 64, 32, or 16. - * The higher the size, the more efficiently x265 can encode areas of low - * complexity, greatly improving compression efficiency at large - * resolutions. The smaller the size, the more effective wavefront and - * frame parallelism will become because of the increase in rows. default 64 - * All encoders within the same process must use the same maxCUSize, until - * all encoders are closed and x265_cleanup() is called to reset the value. */ - uint32_t maxCUSize; - - /* Minimum CU width and height in pixels. The size must be 64, 32, 16, or - * 8. Default 8. All encoders within the same process must use the same - * minCUSize. */ - uint32_t minCUSize; - - /* Enable rectangular motion prediction partitions (vertical and - * horizontal), available at all CU depths from 64x64 to 8x8. Default is - * disabled */ - int bEnableRectInter; - - /* Enable asymmetrical motion predictions. At CU depths 64, 32, and 16, it - * is possible to use 25%/75% split partitions in the up, down, right, left - * directions. For some material this can improve compression efficiency at - * the cost of extra analysis. bEnableRectInter must be enabled for this - * feature to be used. Default disabled */ - int bEnableAMP; - - /*== Residual Quadtree Transform Unit (TU) definitions ==*/ - - /* Maximum TU width and height in pixels. The size must be 32, 16, 8 or 4. - * The larger the size the more efficiently the residual can be compressed - * by the DCT transforms, at the expense of more computation */ - uint32_t maxTUSize; - - /* The additional depth the residual quad-tree is allowed to recurse beyond - * the coding quad-tree, for inter coded blocks. This must be between 1 and - * 4. The higher the value the more efficiently the residual can be - * compressed by the DCT transforms, at the expense of much more compute */ - uint32_t tuQTMaxInterDepth; - - /* The additional depth the residual quad-tree is allowed to recurse beyond - * the coding quad-tree, for intra coded blocks. This must be between 1 and - * 4. The higher the value the more efficiently the residual can be - * compressed by the DCT transforms, at the expense of much more compute */ - uint32_t tuQTMaxIntraDepth; - - /* Enable early exit decisions for inter coded blocks to avoid recursing to - * higher TU depths. Default: 0 */ - uint32_t limitTU; - - /* Set the amount of rate-distortion analysis to use within quant. 0 implies - * no rate-distortion optimization. At level 1 rate-distortion cost is used to - * find optimal rounding values for each level (and allows psy-rdoq to be - * enabled). At level 2 rate-distortion cost is used to make decimate decisions - * on each 4x4 coding group (including the cost of signaling the group within - * the group bitmap). Psy-rdoq is less effective at preserving energy when - * RDOQ is at level 2. Default: 0 */ - int rdoqLevel; - - /* Enable the implicit signaling of the sign bit of the last coefficient of - * each transform unit. This saves one bit per TU at the expense of figuring - * out which coefficient can be toggled with the least distortion. - * Default is enabled */ - int bEnableSignHiding; - - /* Allow intra coded blocks to be encoded directly as residual without the - * DCT transform, when this improves efficiency. Checking whether the block - * will benefit from this option incurs a performance penalty. Default is - * disabled */ - int bEnableTransformSkip; - - /* An integer value in range of 0 to 2000, which denotes strength of noise - * reduction in intra CUs. 0 means disabled */ - int noiseReductionIntra; - - /* An integer value in range of 0 to 2000, which denotes strength of noise - * reduction in inter CUs. 0 means disabled */ - int noiseReductionInter; - - /* Quantization scaling lists. HEVC supports 6 quantization scaling lists to - * be defined; one each for Y, Cb, Cr for intra prediction and one each for - * inter prediction. - * - * - NULL and "off" will disable quant scaling (default) - * - "default" will enable the HEVC default scaling lists, which - * do not need to be signaled since they are specified - * - all other strings indicate a filename containing custom scaling lists - * in the HM format. The encode will fail if the file is not parsed - * correctly. Custom lists must be signaled in the SPS. */ - const char *scalingLists; - - /*== Intra Coding Tools ==*/ - - /* Enable constrained intra prediction. This causes intra prediction to - * input samples that were inter predicted. For some use cases this is - * believed to me more robust to stream errors, but it has a compression - * penalty on P and (particularly) B slices. Defaults to disabled */ - int bEnableConstrainedIntra; - - /* Enable strong intra smoothing for 32x32 blocks where the reference - * samples are flat. It may or may not improve compression efficiency, - * depending on your source material. Defaults to disabled */ - int bEnableStrongIntraSmoothing; - - /*== Inter Coding Tools ==*/ - - /* The maximum number of merge candidates that are considered during inter - * analysis. This number (between 1 and 5) is signaled in the stream - * headers and determines the number of bits required to signal a merge so - * it can have significant trade-offs. The smaller this number the higher - * the performance but the less compression efficiency. Default is 3 */ - uint32_t maxNumMergeCand; - - /* Limit the motion references used for each search based on the results of - * previous motion searches already performed for the same CU: If 0 all - * references are always searched. If X265_REF_LIMIT_CU all motion searches - * will restrict themselves to the references selected by the 2Nx2N search - * at the same depth. If X265_REF_LIMIT_DEPTH the 2Nx2N motion search will - * only use references that were selected by the best motion searches of the - * 4 split CUs at the next lower CU depth. The two flags may be combined */ - uint32_t limitReferences; - - /* Limit modes analyzed for each CU using cost metrics from the 4 sub-CUs */ - uint32_t limitModes; - - /* ME search method (DIA, HEX, UMH, STAR, SEA, FULL). The search patterns - * (methods) are sorted in increasing complexity, with diamond being the - * simplest and fastest and full being the slowest. DIA, HEX, UMH and SEA were - * adapted from x264 directly. STAR is an adaption of the HEVC reference - * encoder's three step search, while full is a naive exhaustive search. The - * default is the star search, it has a good balance of performance and - * compression efficiency */ - int searchMethod; - - /* A value between 0 and X265_MAX_SUBPEL_LEVEL which adjusts the amount of - * effort performed during sub-pel refine. Default is 5 */ - int subpelRefine; - - /* The maximum distance from the motion prediction that the full pel motion - * search is allowed to progress before terminating. This value can have an - * effect on frame parallelism, as referenced frames must be at least this - * many rows of reconstructed pixels ahead of the referencee at all times. - * (When considering reference lag, the motion prediction must be ignored - * because it cannot be known ahead of time). Default is 60, which is the - * default max CU size (64) minus the luma HPEL half-filter length (4). If a - * smaller CU size is used, the search range should be similarly reduced */ - int searchRange; - - /* Enable availability of temporal motion vector for AMVP, default is enabled */ - int bEnableTemporalMvp; - - /* Enable weighted prediction in P slices. This enables weighting analysis - * in the lookahead, which influences slice decisions, and enables weighting - * analysis in the main encoder which allows P reference samples to have a - * weight function applied to them prior to using them for motion - * compensation. In video which has lighting changes, it can give a large - * improvement in compression efficiency. Default is enabled */ - int bEnableWeightedPred; - - /* Enable weighted prediction in B slices. Default is disabled */ - int bEnableWeightedBiPred; - /* Enable source pixels in motion estimation. Default is disabled */ - int bSourceReferenceEstimation; - /*== Loop Filters ==*/ - /* Enable the deblocking loop filter, which improves visual quality by - * reducing blocking effects at block edges, particularly at lower bitrates - * or higher QP. When enabled it adds another CU row of reference lag, - * reducing frame parallelism effectiveness. Default is enabled */ - int bEnableLoopFilter; - - /* deblocking filter tC offset [-6, 6] -6 light filter, 6 strong. - * This is the coded div2 value, actual offset is doubled at use */ - int deblockingFilterTCOffset; - - /* deblocking filter Beta offset [-6, 6] -6 light filter, 6 strong - * This is the coded div2 value, actual offset is doubled at use */ - int deblockingFilterBetaOffset; - - /* Enable the Sample Adaptive Offset loop filter, which reduces distortion - * effects by adjusting reconstructed sample values based on histogram - * analysis to better approximate the original samples. When enabled it adds - * a CU row of reference lag, reducing frame parallelism effectiveness. - * Default is enabled */ - int bEnableSAO; - - /* Note: when deblocking and SAO are both enabled, the loop filter CU lag is - * only one row, as they operate in series on the same row. */ - - /* Select the method in which SAO deals with deblocking boundary pixels. If - * disabled the right and bottom boundary areas are skipped. If enabled, - * non-deblocked pixels are used entirely. Default is disabled */ - int bSaoNonDeblocked; - - /*== Analysis tools ==*/ - - /* A value between 1 and 6 (both inclusive) which determines the level of - * rate distortion optimizations to perform during mode and depth decisions. - * The more RDO the better the compression efficiency at a major cost of - * performance. Default is 3 */ - int rdLevel; - - /* Enable early skip decisions to avoid analysing additional modes in likely - * skip blocks. Default is disabled */ - int bEnableEarlySkip; - - /* Enable early CU size decisions to avoid recursing to higher depths. - * Default is enabled */ - int bEnableRecursionSkip; - - /* Use a faster search method to find the best intra mode. Default is 0 */ - int bEnableFastIntra; - - /* Enable a faster determination of whether skipping the DCT transform will - * be beneficial. Slight performance gain for some compression loss. Default - * is enabled */ - int bEnableTSkipFast; - - /* The CU Lossless flag, when enabled, compares the rate-distortion costs - * for normal and lossless encoding, and chooses the best mode for each CU. - * If lossless mode is chosen, the cu-transquant-bypass flag is set for that - * CU */ - int bCULossless; - - /* Specify whether to attempt to encode intra modes in B frames. By default - * enabled, but only applicable for the presets which use rdLevel 5 or 6 - * (veryslow and placebo). All other presets will not try intra in B frames - * regardless of this setting */ - int bIntraInBFrames; - - /* Apply an optional penalty to the estimated cost of 32x32 intra blocks in - * non-intra slices. 0 is disabled, 1 enables a small penalty, and 2 enables - * a full penalty. This favors inter-coding and its low bitrate over - * potential increases in distortion, but usually improves performance. - * Default is 0 */ - int rdPenalty; - - /* Psycho-visual rate-distortion strength. Only has an effect in presets - * which use RDO. It makes mode decision favor options which preserve the - * energy of the source, at the cost of lost compression. The value must - * be between 0 and 5.0, 1.0 is typical. Default 2.0 */ - double psyRd; - - /* Strength of psycho-visual optimizations in quantization. Only has an - * effect when RDOQ is enabled (presets slow, slower and veryslow). The - * value must be between 0 and 50, 1.0 is typical. Default 0 */ - double psyRdoq; - - /* Perform quantisation parameter based RD refinement. RD cost is calculated - * on the best CU partitions, chosen after the CU analysis, for a range of QPs - * to find the optimal rounding effect. Only effective at rd-levels 5 and 6. - * Default disabled */ - int bEnableRdRefine; - - /* If save, write per-frame analysis information into analysis buffers. - * If load, read analysis information into analysis buffer and use this - * analysis information to reduce the amount of work the encoder must perform. - * Default disabled. Now deprecated*/ - int analysisReuseMode; - - /* Filename for multi-pass-opt-analysis/distortion. Default name is "x265_analysis.dat" */ - const char* analysisReuseFileName; - - /*== Rate Control ==*/ - - /* The lossless flag enables true lossless coding, bypassing scaling, - * transform, quantization and in-loop filter processes. This is used for - * ultra-high bitrates with zero loss of quality. It implies no rate control */ - int bLossless; - - /* Generally a small signed integer which offsets the QP used to quantize - * the Cb chroma residual (delta from luma QP specified by rate-control). - * Default is 0, which is recommended */ - int cbQpOffset; - - /* Generally a small signed integer which offsets the QP used to quantize - * the Cr chroma residual (delta from luma QP specified by rate-control). - * Default is 0, which is recommended */ - int crQpOffset; - - struct - { - /* Explicit mode of rate-control, necessary for API users. It must - * be one of the X265_RC_METHODS enum values. */ - int rateControlMode; - - /* Base QP to use for Constant QP rate control. Adaptive QP may alter - * the QP used for each block. If a QP is specified on the command line - * CQP rate control is implied. Default: 32 */ - int qp; - - /* target bitrate for Average BitRate (ABR) rate control. If a non- zero - * bitrate is specified on the command line, ABR is implied. Default 0 */ - int bitrate; - - /* qComp sets the quantizer curve compression factor. It weights the frame - * quantizer based on the complexity of residual (measured by lookahead). - * Default value is 0.6. Increasing it to 1 will effectively generate CQP */ - double qCompress; - - /* QP offset between I/P and P/B frames. Default ipfactor: 1.4 - * Default pbFactor: 1.3 */ - double ipFactor; - double pbFactor; - - /* Ratefactor constant: targets a certain constant "quality". - * Acceptable values between 0 and 51. Default value: 28 */ - double rfConstant; - - /* Max QP difference between frames. Default: 4 */ - int qpStep; - - /* Enable adaptive quantization. This mode distributes available bits between all - * CTUs of a frame, assigning more bits to low complexity areas. Turning - * this ON will usually affect PSNR negatively, however SSIM and visual quality - * generally improves. Default: X265_AQ_VARIANCE */ - int aqMode; - - /* Sets the strength of AQ bias towards low detail CTUs. Valid only if - * AQ is enabled. Default value: 1.0. Acceptable values between 0.0 and 3.0 */ - double aqStrength; - - /* Sets the maximum rate the VBV buffer should be assumed to refill at - * Default is zero */ - int vbvMaxBitrate; - - /* Sets the size of the VBV buffer in kilobits. Default is zero */ - int vbvBufferSize; - - /* Sets how full the VBV buffer must be before playback starts. If it is less than - * 1, then the initial fill is vbv-init * vbvBufferSize. Otherwise, it is - * interpreted as the initial fill in kbits. Default is 0.9 */ - double vbvBufferInit; - - /* Enable CUTree rate-control. This keeps track of the CUs that propagate temporally - * across frames and assigns more bits to these CUs. Improves encode efficiency. - * Default: enabled */ - int cuTree; - - /* In CRF mode, maximum CRF as caused by VBV. 0 implies no limit */ - double rfConstantMax; - - /* In CRF mode, minimum CRF as caused by VBV */ - double rfConstantMin; - - /* Multi-pass encoding */ - /* Enable writing the stats in a multi-pass encode to the stat output file */ - int bStatWrite; - - /* Enable loading data from the stat input file in a multi pass encode */ - int bStatRead; - - /* Filename of the 2pass output/input stats file, if unspecified the - * encoder will default to using x265_2pass.log */ - const char* statFileName; - - /* temporally blur quants */ - double qblur; - - /* temporally blur complexity */ - double complexityBlur; - - /* Enable slow and a more detailed first pass encode in multi pass rate control */ - int bEnableSlowFirstPass; - - /* rate-control overrides */ - int zoneCount; - x265_zone* zones; - - /* specify a text file which contains MAX_MAX_QP + 1 floating point - * values to be copied into x265_lambda_tab and a second set of - * MAX_MAX_QP + 1 floating point values for x265_lambda2_tab. All values - * are separated by comma, space or newline. Text after a hash (#) is - * ignored. The lambda tables are process-global, so these new lambda - * values will affect all encoders in the same process */ - const char* lambdaFileName; - - /* Enable stricter conditions to check bitrate deviations in CBR mode. May compromise - * quality to maintain bitrate adherence */ - int bStrictCbr; - - /* Enable adaptive quantization at CU granularity. This parameter specifies - * the minimum CU size at which QP can be adjusted, i.e. Quantization Group - * (QG) size. Allowed values are 64, 32, 16, 8 provided it falls within the - * inclusuve range [maxCUSize, minCUSize]. Experimental, default: maxCUSize */ - uint32_t qgSize; - - /* internally enable if tune grain is set */ - int bEnableGrain; - - /* sets a hard upper limit on QP */ - int qpMax; - - /* sets a hard lower limit on QP */ - int qpMin; - - /* internally enable if tune grain is set */ - int bEnableConstVbv; - - } rc; - - /*== Video Usability Information ==*/ - struct - { - /* Aspect ratio idc to be added to the VUI. The default is 0 indicating - * the apsect ratio is unspecified. If set to X265_EXTENDED_SAR then - * sarWidth and sarHeight must also be set */ - int aspectRatioIdc; - - /* Sample Aspect Ratio width in arbitrary units to be added to the VUI - * only if aspectRatioIdc is set to X265_EXTENDED_SAR. This is the width - * of an individual pixel. If this is set then sarHeight must also be set */ - int sarWidth; - - /* Sample Aspect Ratio height in arbitrary units to be added to the VUI. - * only if aspectRatioIdc is set to X265_EXTENDED_SAR. This is the width - * of an individual pixel. If this is set then sarWidth must also be set */ - int sarHeight; - - /* Enable overscan info present flag in the VUI. If this is set then - * bEnabledOverscanAppropriateFlag will be added to the VUI. The default - * is false */ - int bEnableOverscanInfoPresentFlag; - - /* Enable overscan appropriate flag. The status of this flag is added - * to the VUI only if bEnableOverscanInfoPresentFlag is set. If this - * flag is set then cropped decoded pictures may be output for display. - * The default is false */ - int bEnableOverscanAppropriateFlag; - - /* Video signal type present flag of the VUI. If this is set then - * videoFormat, bEnableVideoFullRangeFlag and - * bEnableColorDescriptionPresentFlag will be added to the VUI. The - * default is false */ - int bEnableVideoSignalTypePresentFlag; - - /* Video format of the source video. 0 = component, 1 = PAL, 2 = NTSC, - * 3 = SECAM, 4 = MAC, 5 = unspecified video format is the default */ - int videoFormat; - - /* Video full range flag indicates the black level and range of the luma - * and chroma signals as derived from E′Y, E′PB, and E′PR or E′R, E′G, - * and E′B real-valued component signals. The default is false */ - int bEnableVideoFullRangeFlag; - - /* Color description present flag in the VUI. If this is set then - * color_primaries, transfer_characteristics and matrix_coeffs are to be - * added to the VUI. The default is false */ - int bEnableColorDescriptionPresentFlag; - - /* Color primaries holds the chromacity coordinates of the source - * primaries. The default is 2 */ - int colorPrimaries; - - /* Transfer characteristics indicates the opto-electronic transfer - * characteristic of the source picture. The default is 2 */ - int transferCharacteristics; - - /* Matrix coefficients used to derive the luma and chroma signals from - * the red, blue and green primaries. The default is 2 */ - int matrixCoeffs; - - /* Chroma location info present flag adds chroma_sample_loc_type_top_field and - * chroma_sample_loc_type_bottom_field to the VUI. The default is false */ - int bEnableChromaLocInfoPresentFlag; - - /* Chroma sample location type top field holds the chroma location in - * the top field. The default is 0 */ - int chromaSampleLocTypeTopField; - - /* Chroma sample location type bottom field holds the chroma location in - * the bottom field. The default is 0 */ - int chromaSampleLocTypeBottomField; - - /* Default display window flag adds def_disp_win_left_offset, - * def_disp_win_right_offset, def_disp_win_top_offset and - * def_disp_win_bottom_offset to the VUI. The default is false */ - int bEnableDefaultDisplayWindowFlag; - - /* Default display window left offset holds the left offset with the - * conformance cropping window to further crop the displayed window */ - int defDispWinLeftOffset; - - /* Default display window right offset holds the right offset with the - * conformance cropping window to further crop the displayed window */ - int defDispWinRightOffset; - - /* Default display window top offset holds the top offset with the - * conformance cropping window to further crop the displayed window */ - int defDispWinTopOffset; - - /* Default display window bottom offset holds the bottom offset with the - * conformance cropping window to further crop the displayed window */ - int defDispWinBottomOffset; - } vui; - - /* SMPTE ST 2086 mastering display color volume SEI info, specified as a - * string which is parsed when the stream header SEI are emitted. The string - * format is "G(%hu,%hu)B(%hu,%hu)R(%hu,%hu)WP(%hu,%hu)L(%u,%u)" where %hu - * are unsigned 16bit integers and %u are unsigned 32bit integers. The SEI - * includes X,Y display primaries for RGB channels, white point X,Y and - * max,min luminance values. */ - const char* masteringDisplayColorVolume; - - /* Maximum Content light level(MaxCLL), specified as integer that indicates the - * maximum pixel intensity level in units of 1 candela per square metre of the - * bitstream. x265 will also calculate MaxCLL programmatically from the input - * pixel values and set in the Content light level info SEI */ - uint16_t maxCLL; - - /* Maximum Frame Average Light Level(MaxFALL), specified as integer that indicates - * the maximum frame average intensity level in units of 1 candela per square - * metre of the bitstream. x265 will also calculate MaxFALL programmatically - * from the input pixel values and set in the Content light level info SEI */ - uint16_t maxFALL; - - /* Minimum luma level of input source picture, specified as a integer which - * would automatically increase any luma values below the specified --min-luma - * value to that value. */ - uint16_t minLuma; - - /* Maximum luma level of input source picture, specified as a integer which - * would automatically decrease any luma values above the specified --max-luma - * value to that value. */ - uint16_t maxLuma; - - /* Maximum of the picture order count */ - int log2MaxPocLsb; - - /* Emit VUI Timing info, an optional VUI field */ - int bEmitVUITimingInfo; - - /* Emit HRD Timing info */ - int bEmitVUIHRDInfo; - - /* Maximum count of Slices of picture, the value range is [1, maximum rows] */ - unsigned int maxSlices; - - /* Optimize QP in PPS based on statistics from prevvious GOP*/ - int bOptQpPPS; - - /* Opitmize ref list length in PPS based on stats from previous GOP*/ - int bOptRefListLengthPPS; - - /* Enable storing commonly RPS in SPS in multi pass mode */ - int bMultiPassOptRPS; - /* This value represents the percentage difference between the inter cost and - * intra cost of a frame used in scenecut detection. Default 5. */ - double scenecutBias; - /* Use multiple worker threads dedicated to doing only lookahead instead of sharing - * the worker threads with Frame Encoders. A dedicated lookahead threadpool is created with the - * specified number of worker threads. This can range from 0 upto half the - * hardware threads available for encoding. Using too many threads for lookahead can starve - * resources for frame Encoder and can harm performance. Default is 0 - disabled. */ - int lookaheadThreads; - /* Optimize CU level QPs to signal consistent deltaQPs in frame for rd level > 4 */ - int bOptCUDeltaQP; - /* Refine analysis in multipass ratecontrol based on analysis information stored */ - int analysisMultiPassRefine; - /* Refine analysis in multipass ratecontrol based on distortion data stored */ - int analysisMultiPassDistortion; - /* Adaptive Quantization based on relative motion */ - int bAQMotion; - /* SSIM based RDO, based on residual divisive normalization scheme. Used for mode - * selection during analysis of CTUs, can achieve significant gain in terms of - * objective quality metrics SSIM and PSNR */ - int bSsimRd; - - /* Increase RD at points where bitrate drops due to vbv. Default 0 */ - double dynamicRd; - - /* Enables the emitting of HDR SEI packets which contains HDR-specific params. - * Auto-enabled when max-cll, max-fall, or mastering display info is specified. - * Default is disabled */ - int bEmitHDRSEI; - - /* Enable luma and chroma offsets for HDR/WCG content. - * Default is disabled */ - int bHDROpt; - - /* A value between 1 and 10 (both inclusive) determines the level of - * information stored/reused in analysis save/load. Higher the refine - * level higher the information stored/reused. Default is 5 */ - int analysisReuseLevel; - - /* Limit Sample Adaptive Offset filter computation by early terminating SAO - * process based on inter prediction mode, CTU spatial-domain correlations, - * and relations between luma and chroma */ - int bLimitSAO; - - /* File containing the tone mapping information */ - const char* toneMapFile; - - /* Insert tone mapping information only for IDR frames and when the - * tone mapping information changes. */ - int bDhdr10opt; - - /* Determine how x265 react to the content information recieved through the API */ - int bCTUInfo; - - /* Use ratecontrol statistics from pic_in, if available*/ - int bUseRcStats; - - /* Factor by which input video is scaled down for analysis save mode. Default is 0 */ - int scaleFactor; - - /* Enable intra refinement in load mode*/ - int intraRefine; - - /* Enable inter refinement in load mode*/ - int interRefine; - - /* Enable motion vector refinement in load mode*/ - int mvRefine; - - /* Log of maximum CTU size */ - uint32_t maxLog2CUSize; - - /* Actual CU depth with respect to config depth */ - uint32_t maxCUDepth; - - /* CU depth with respect to maximum transform size */ - uint32_t unitSizeDepth; - - /* Number of 4x4 units in maximum CU size */ - uint32_t num4x4Partitions; - - /* Specify if analysis mode uses file for data reuse */ - int bUseAnalysisFile; - - /* File pointer for csv log */ - FILE* csvfpt; - - /* Force flushing the frames from encoder */ - int forceFlush; - - /* Enable skipping split RD analysis when sum of split CU rdCost larger than none split CU rdCost for Intra CU */ - int bEnableSplitRdSkip; - - /* Disable lookahead */ - int bDisableLookahead; - - /* Use low-pass subband dct approximation - * This DCT approximation is less computational intensive and gives results close to standard DCT */ - int bLowPassDct; - - /* Sets the portion of the decode buffer that must be available after all the - * specified frames have been inserted into the decode buffer. If it is less - * than 1, then the final buffer available is vbv-end * vbvBufferSize. Otherwise, - * it is interpreted as the final buffer available in kbits. Default 0 (disabled) */ - double vbvBufferEnd; - - /* Frame from which qp has to be adjusted to hit final decode buffer emptiness. - * Specified as a fraction of the total frames. Default 0 */ - double vbvEndFrameAdjust; - - /* Reuse MV information obtained through API */ - int bMVType; - /* Allow the encoder to have a copy of the planes of x265_picture in Frame */ - int bCopyPicToFrame; - - /*Number of frames for GOP boundary decision lookahead.If a scenecut frame is found - * within this from the gop boundary set by keyint, the GOP will be extented until such a point, - * otherwise the GOP will be terminated as set by keyint*/ - int gopLookahead; - - /*Write per-frame analysis information into analysis buffers. Default disabled. */ - const char* analysisSave; - - /* Read analysis information into analysis buffer and use this analysis information - * to reduce the amount of work the encoder must perform. Default disabled. */ - const char* analysisLoad; - - /*Number of RADL pictures allowed in front of IDR*/ - int radl; -} x265_param; - -/* x265_param_alloc: - * Allocates an x265_param instance. The returned param structure is not - * special in any way, but using this method together with x265_param_free() - * and x265_param_parse() to set values by name allows the application to treat - * x265_param as an opaque data struct for version safety */ -x265_param *x265_param_alloc(void); - -/* x265_param_free: - * Use x265_param_free() to release storage for an x265_param instance - * allocated by x265_param_alloc() */ -void x265_param_free(x265_param *); - -/* x265_param_default: - * Initialize an x265_param structure to default values */ -void x265_param_default(x265_param *param); - -/* x265_param_parse: - * set one parameter by name. - * returns 0 on success, or returns one of the following errors. - * note: BAD_VALUE occurs only if it can't even parse the value, - * numerical range is not checked until x265_encoder_open(). - * value=NULL means "true" for boolean options, but is a BAD_VALUE for non-booleans. */ -#define X265_PARAM_BAD_NAME (-1) -#define X265_PARAM_BAD_VALUE (-2) -int x265_param_parse(x265_param *p, const char *name, const char *value); - -static const char * const x265_profile_names[] = { - /* HEVC v1 */ - "main", "main10", "mainstillpicture", /* alias */ "msp", - - /* HEVC v2 (Range Extensions) */ - "main-intra", "main10-intra", - "main444-8", "main444-intra", "main444-stillpicture", - - "main422-10", "main422-10-intra", - "main444-10", "main444-10-intra", - - "main12", "main12-intra", - "main422-12", "main422-12-intra", - "main444-12", "main444-12-intra", - - "main444-16-intra", "main444-16-stillpicture", /* Not Supported! */ - 0 -}; - -/* x265_param_apply_profile: - * Applies the restrictions of the given profile. (one of x265_profile_names) - * (can be NULL, in which case the function will do nothing) - * Note: the detected profile can be lower than the one specified to this - * function. This function will force the encoder parameters to fit within - * the specified profile, or fail if that is impossible. - * returns 0 on success, negative on failure (e.g. invalid profile name). */ -int x265_param_apply_profile(x265_param *, const char *profile); - -/* x265_param_default_preset: - * The same as x265_param_default, but also use the passed preset and tune - * to modify the default settings. - * (either can be NULL, which implies no preset or no tune, respectively) - * - * Currently available presets are, ordered from fastest to slowest: */ -static const char * const x265_preset_names[] = { "ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 }; - -/* The presets can also be indexed numerically, as in: - * x265_param_default_preset( ¶m, "3", ... ) - * with ultrafast mapping to "0" and placebo mapping to "9". This mapping may - * of course change if new presets are added in between, but will always be - * ordered from fastest to slowest. - * - * Warning: the speed of these presets scales dramatically. Ultrafast is a full - * 100 times faster than placebo! - * - * Currently available tunings are: */ -static const char * const x265_tune_names[] = { "psnr", "ssim", "grain", "zerolatency", "fastdecode", 0 }; - -/* returns 0 on success, negative on failure (e.g. invalid preset/tune name). */ -int x265_param_default_preset(x265_param *, const char *preset, const char *tune); - -/* x265_picture_alloc: - * Allocates an x265_picture instance. The returned picture structure is not - * special in any way, but using this method together with x265_picture_free() - * and x265_picture_init() allows some version safety. New picture fields will - * always be added to the end of x265_picture */ -x265_picture *x265_picture_alloc(void); - -/* x265_picture_free: - * Use x265_picture_free() to release storage for an x265_picture instance - * allocated by x265_picture_alloc() */ -void x265_picture_free(x265_picture *); - -/* x265_picture_init: - * Initialize an x265_picture structure to default values. It sets the pixel - * depth and color space to the encoder's internal values and sets the slice - * type to auto - so the lookahead will determine slice type. */ -void x265_picture_init(x265_param *param, x265_picture *pic); - -/* x265_max_bit_depth: - * Specifies the numer of bits per pixel that x265 uses internally to - * represent a pixel, and the bit depth of the output bitstream. - * param->internalBitDepth must be set to this value. x265_max_bit_depth - * will be 8 for default builds, 10 for HIGH_BIT_DEPTH builds. */ -X265_API extern const int x265_max_bit_depth; - -/* x265_version_str: - * A static string containing the version of this compiled x265 library */ -X265_API extern const char *x265_version_str; - -/* x265_build_info: - * A static string describing the compiler and target architecture */ -X265_API extern const char *x265_build_info_str; - -/* Force a link error in the case of linking against an incompatible API version. - * Glue #defines exist to force correct macro expansion; the final output of the macro - * is x265_encoder_open_##X265_BUILD (for purposes of dlopen). */ -#define x265_encoder_glue1(x, y) x ## y -#define x265_encoder_glue2(x, y) x265_encoder_glue1(x, y) -#define x265_encoder_open x265_encoder_glue2(x265_encoder_open_, X265_BUILD) - -/* x265_encoder_open: - * create a new encoder handler, all parameters from x265_param are copied */ -x265_encoder* x265_encoder_open(x265_param *); - -/* x265_encoder_parameters: - * copies the current internal set of parameters to the pointer provided - * by the caller. useful when the calling application needs to know - * how x265_encoder_open has changed the parameters. - * note that the data accessible through pointers in the returned param struct - * (e.g. filenames) should not be modified by the calling application. */ -void x265_encoder_parameters(x265_encoder *, x265_param *); - -/* x265_encoder_headers: - * return the SPS and PPS that will be used for the whole stream. - * *pi_nal is the number of NAL units outputted in pp_nal. - * returns negative on error, total byte size of payload data on success - * the payloads of all output NALs are guaranteed to be sequential in memory. */ -int x265_encoder_headers(x265_encoder *, x265_nal **pp_nal, uint32_t *pi_nal); - -/* x265_encoder_encode: - * encode one picture. - * *pi_nal is the number of NAL units outputted in pp_nal. - * returns negative on error, 1 if a picture and access unit were output, - * or zero if the encoder pipeline is still filling or is empty after flushing. - * the payloads of all output NALs are guaranteed to be sequential in memory. - * To flush the encoder and retrieve delayed output pictures, pass pic_in as NULL. - * Once flushing has begun, all subsequent calls must pass pic_in as NULL. */ -int x265_encoder_encode(x265_encoder *encoder, x265_nal **pp_nal, uint32_t *pi_nal, x265_picture *pic_in, x265_picture *pic_out); - -/* x265_encoder_reconfig: - * various parameters from x265_param are copied. - * this takes effect immediately, on whichever frame is encoded next; - * returns 0 on success, negative on parameter validation error. - * - * not all parameters can be changed; see the actual function for a - * detailed breakdown. since not all parameters can be changed, moving - * from preset to preset may not always fully copy all relevant parameters, - * but should still work usably in practice. however, more so than for - * other presets, many of the speed shortcuts used in ultrafast cannot be - * switched out of; using reconfig to switch between ultrafast and other - * presets is not recommended without a more fine-grained breakdown of - * parameters to take this into account. */ -int x265_encoder_reconfig(x265_encoder *, x265_param *); - -/* x265_encoder_get_stats: - * returns encoder statistics */ -void x265_encoder_get_stats(x265_encoder *encoder, x265_stats *, uint32_t statsSizeBytes); - -/* x265_encoder_log: - * write a line to the configured CSV file. If a CSV filename was not - * configured, or file open failed, this function will perform no write. */ -void x265_encoder_log(x265_encoder *encoder, int argc, char **argv); - -/* x265_encoder_close: - * close an encoder handler */ -void x265_encoder_close(x265_encoder *); - -/* x265_encoder_intra_refresh: - * If an intra refresh is not in progress, begin one with the next P-frame. - * If an intra refresh is in progress, begin one as soon as the current one finishes. - * Requires bIntraRefresh to be set. - * - * Useful for interactive streaming where the client can tell the server that packet loss has - * occurred. In this case, keyint can be set to an extremely high value so that intra refreshes - * occur only when calling x265_encoder_intra_refresh. - * - * In multi-pass encoding, if x265_encoder_intra_refresh is called differently in each pass, - * behavior is undefined. - * - * Should not be called during an x265_encoder_encode. */ - -int x265_encoder_intra_refresh(x265_encoder *); - -/* x265_encoder_ctu_info: - * Copy CTU information such as ctu address and ctu partition structure of all - * CTUs in each frame. The function is invoked only if "--ctu-info" is enabled and - * the encoder will wait for this copy to complete if enabled. - */ -int x265_encoder_ctu_info(x265_encoder *, int poc, x265_ctu_info_t** ctu); - -/* x265_get_slicetype_poc_and_scenecut: - * get the slice type, poc and scene cut information for the current frame, - * returns negative on error, 0 when access unit were output. - * This API must be called after(poc >= lookaheadDepth + bframes + 2) condition check */ -int x265_get_slicetype_poc_and_scenecut(x265_encoder *encoder, int *slicetype, int *poc, int* sceneCut); - -/* x265_get_ref_frame_list: - * returns negative on error, 0 when access unit were output. - * This API must be called after(poc >= lookaheadDepth + bframes + 2) condition check */ -int x265_get_ref_frame_list(x265_encoder *encoder, x265_picyuv**, x265_picyuv**, int, int, int*, int*); - -/* x265_set_analysis_data: - * set the analysis data. The incoming analysis_data structure is assumed to be AVC-sized blocks. - * returns negative on error, 0 access unit were output. */ -int x265_set_analysis_data(x265_encoder *encoder, x265_analysis_data *analysis_data, int poc, uint32_t cuBytes); - -/* x265_cleanup: - * release library static allocations, reset configured CTU size */ -void x265_cleanup(void); - -/* Open a CSV log file. On success it returns a file handle which must be passed - * to x265_csvlog_frame() and/or x265_csvlog_encode(). The file handle must be - * closed by the caller using fclose(). If csv-loglevel is 0, then no frame logging - * header is written to the file. This function will return NULL if it is unable - * to open the file for write or if it detects a structure size skew */ -FILE* x265_csvlog_open(const x265_param *); - -/* Log frame statistics to the CSV file handle. csv-loglevel should have been non-zero - * in the call to x265_csvlog_open() if this function is called. */ -void x265_csvlog_frame(const x265_param *, const x265_picture *); - -/* Log final encode statistics to the CSV file handle. 'argc' and 'argv' are - * intended to be command line arguments passed to the encoder. padx and pady are - * padding offsets for conformance and can be given from sps settings. Encode - * statistics should be queried from the encoder just prior to closing it. */ -void x265_csvlog_encode(const x265_param*, const x265_stats *, int padx, int pady, int argc, char** argv); - -/* In-place downshift from a bit-depth greater than 8 to a bit-depth of 8, using - * the residual bits to dither each row. */ -void x265_dither_image(x265_picture *, int picWidth, int picHeight, int16_t *errorBuf, int bitDepth); - -#define X265_MAJOR_VERSION 1 - -/* === Multi-lib API === - * By using this method to gain access to the libx265 interfaces, you allow run- - * time selection between various available libx265 libraries based on the - * encoder parameters. The most likely use case is to choose between Main and - * Main10 builds of libx265. */ - -typedef struct x265_api -{ - int api_major_version; /* X265_MAJOR_VERSION */ - int api_build_number; /* X265_BUILD (soname) */ - int sizeof_param; /* sizeof(x265_param) */ - int sizeof_picture; /* sizeof(x265_picture) */ - int sizeof_analysis_data; /* sizeof(x265_analysis_data) */ - int sizeof_zone; /* sizeof(x265_zone) */ - int sizeof_stats; /* sizeof(x265_stats) */ - - int bit_depth; - const char* version_str; - const char* build_info_str; - - /* libx265 public API functions, documented above with x265_ prefixes */ - x265_param* (*param_alloc)(void); - void (*param_free)(x265_param*); - void (*param_default)(x265_param*); - int (*param_parse)(x265_param*, const char*, const char*); - int (*param_apply_profile)(x265_param*, const char*); - int (*param_default_preset)(x265_param*, const char*, const char *); - x265_picture* (*picture_alloc)(void); - void (*picture_free)(x265_picture*); - void (*picture_init)(x265_param*, x265_picture*); - x265_encoder* (*encoder_open)(x265_param*); - void (*encoder_parameters)(x265_encoder*, x265_param*); - int (*encoder_reconfig)(x265_encoder*, x265_param*); - int (*encoder_headers)(x265_encoder*, x265_nal**, uint32_t*); - int (*encoder_encode)(x265_encoder*, x265_nal**, uint32_t*, x265_picture*, x265_picture*); - void (*encoder_get_stats)(x265_encoder*, x265_stats*, uint32_t); - void (*encoder_log)(x265_encoder*, int, char**); - void (*encoder_close)(x265_encoder*); - void (*cleanup)(void); - - int sizeof_frame_stats; /* sizeof(x265_frame_stats) */ - int (*encoder_intra_refresh)(x265_encoder*); - int (*encoder_ctu_info)(x265_encoder*, int, x265_ctu_info_t**); - int (*get_slicetype_poc_and_scenecut)(x265_encoder*, int*, int*, int*); - int (*get_ref_frame_list)(x265_encoder*, x265_picyuv**, x265_picyuv**, int, int, int*, int*); - FILE* (*csvlog_open)(const x265_param*); - void (*csvlog_frame)(const x265_param*, const x265_picture*); - void (*csvlog_encode)(const x265_param*, const x265_stats *, int, int, int, char**); - void (*dither_image)(x265_picture*, int, int, int16_t*, int); - int (*set_analysis_data)(x265_encoder *encoder, x265_analysis_data *analysis_data, int poc, uint32_t cuBytes); - /* add new pointers to the end, or increment X265_MAJOR_VERSION */ -} x265_api; - -/* Force a link error in the case of linking against an incompatible API version. - * Glue #defines exist to force correct macro expansion; the final output of the macro - * is x265_api_get_##X265_BUILD (for purposes of dlopen). */ -#define x265_api_glue1(x, y) x ## y -#define x265_api_glue2(x, y) x265_api_glue1(x, y) -#define x265_api_get x265_api_glue2(x265_api_get_, X265_BUILD) - -/* x265_api_get: - * Retrieve the programming interface for a linked x265 library. - * May return NULL if no library is available that supports the - * requested bit depth. If bitDepth is 0 the function is guarunteed - * to return a non-NULL x265_api pointer, from the linked libx265. - * - * If the requested bitDepth is not supported by the linked libx265, - * it will attempt to dynamically bind x265_api_get() from a shared - * library with an appropriate name: - * 8bit: libx265_main.so - * 10bit: libx265_main10.so - * Obviously the shared library file extension is platform specific */ -const x265_api* x265_api_get(int bitDepth); - -/* x265_api_query: - * Retrieve the programming interface for a linked x265 library, like - * x265_api_get(), except this function accepts X265_BUILD as the second - * argument rather than using the build number as part of the function name. - * Applications which dynamically link to libx265 can use this interface to - * query the library API and achieve a relative amount of version skew - * flexibility. The function may return NULL if the library determines that - * the apiVersion that your application was compiled against is not compatible - * with the library you have linked with. - * - * api_major_version will be incremented any time non-backward compatible - * changes are made to any public structures or functions. If - * api_major_version does not match X265_MAJOR_VERSION from the x265.h your - * application compiled against, your application must not use the returned - * x265_api pointer. - * - * Users of this API *must* also validate the sizes of any structures which - * are not treated as opaque in application code. For instance, if your - * application dereferences a x265_param pointer, then it must check that - * api->sizeof_param matches the sizeof(x265_param) that your application - * compiled with. */ -const x265_api* x265_api_query(int bitDepth, int apiVersion, int* err); - -#define X265_API_QUERY_ERR_NONE 0 /* returned API pointer is non-NULL */ -#define X265_API_QUERY_ERR_VER_REFUSED 1 /* incompatible version skew */ -#define X265_API_QUERY_ERR_LIB_NOT_FOUND 2 /* libx265_main10 not found, for ex */ -#define X265_API_QUERY_ERR_FUNC_NOT_FOUND 3 /* unable to bind x265_api_query */ -#define X265_API_QUERY_ERR_WRONG_BITDEPTH 4 /* libx265_main10 not 10bit, for ex */ - -static const char * const x265_api_query_errnames[] = { - "api queried from libx265", - "libx265 version is not compatible with this application", - "unable to bind a libx265 with requested bit depth", - "unable to bind x265_api_query from libx265", - "libx265 has an invalid bitdepth" -}; - -#ifdef __cplusplus -} -#endif - -#endif // X265_H diff --git a/Vendors/include/libx265/x265_config.h b/Vendors/include/libx265/x265_config.h deleted file mode 100644 index a4d6c68..0000000 --- a/Vendors/include/libx265/x265_config.h +++ /dev/null @@ -1,34 +0,0 @@ -/***************************************************************************** - * Copyright (C) 2013-2017 MulticoreWare, Inc - * - * Authors: Steve Borho - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. - * - * This program is also available under a commercial proprietary license. - * For more information, contact us at license @ x265.com. - *****************************************************************************/ - -#ifndef X265_CONFIG_H -#define X265_CONFIG_H - -/* Defines generated at build time */ - -/* Incremented each time public API is changed, X265_BUILD is used as - * the shared library SONAME on platforms which support it. It also - * prevents linking against a different version of the static lib */ -#define X265_BUILD 151 - -#endif diff --git a/Vendors/libde265/iOS/libde265.a b/Vendors/libde265/iOS/libde265.a deleted file mode 100644 index 20b553f..0000000 Binary files a/Vendors/libde265/iOS/libde265.a and /dev/null differ diff --git a/Vendors/libde265/macOS/libde265.a b/Vendors/libde265/macOS/libde265.a deleted file mode 100644 index 101730c..0000000 Binary files a/Vendors/libde265/macOS/libde265.a and /dev/null differ diff --git a/Vendors/libde265/tvOS/libde265.a b/Vendors/libde265/tvOS/libde265.a deleted file mode 100644 index 551e02c..0000000 Binary files a/Vendors/libde265/tvOS/libde265.a and /dev/null differ diff --git a/Vendors/libde265/watchOS/libde265.a b/Vendors/libde265/watchOS/libde265.a deleted file mode 100644 index d477be1..0000000 Binary files a/Vendors/libde265/watchOS/libde265.a and /dev/null differ diff --git a/Vendors/libheif b/Vendors/libheif deleted file mode 160000 index 2706077..0000000 --- a/Vendors/libheif +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2706077d0fe4019e4555bebb46e98ff57b850e63 diff --git a/Vendors/libx265/iOS/libx265.a b/Vendors/libx265/iOS/libx265.a deleted file mode 100644 index d4f70c2..0000000 Binary files a/Vendors/libx265/iOS/libx265.a and /dev/null differ diff --git a/Vendors/libx265/macOS/libx265.a b/Vendors/libx265/macOS/libx265.a deleted file mode 100644 index 4d18436..0000000 Binary files a/Vendors/libx265/macOS/libx265.a and /dev/null differ diff --git a/Vendors/libx265/tvOS/libx265.a b/Vendors/libx265/tvOS/libx265.a deleted file mode 100644 index b00b409..0000000 Binary files a/Vendors/libx265/tvOS/libx265.a and /dev/null differ diff --git a/Vendors/libx265/watchOS/libx265.a b/Vendors/libx265/watchOS/libx265.a deleted file mode 100644 index 74b4f8d..0000000 Binary files a/Vendors/libx265/watchOS/libx265.a and /dev/null differ diff --git a/_Pods.xcodeproj b/_Pods.xcodeproj deleted file mode 120000 index 3c5a8e7..0000000 --- a/_Pods.xcodeproj +++ /dev/null @@ -1 +0,0 @@ -Example/Pods/Pods.xcodeproj \ No newline at end of file diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..c628436 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,9 @@ +coverage: + ignore: + - "Example" + - "Tests" + status: + project: + default: off + ios: + flags: ios