├── .gitattributes ├── .github └── workflows │ └── release.yml ├── .gitignore ├── Example ├── WebPImage Example.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── WebPImage Example.xcscheme └── WebPImage Example │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json │ ├── LaunchScreen.storyboard │ ├── WebPImage Example-Info.plist │ ├── WebPImage Example-Prefix.pch │ ├── en.lproj │ └── InfoPlist.strings │ ├── image.png │ ├── image.webp │ └── main.m ├── LICENSE ├── README.md ├── WebP.framework ├── Headers │ ├── decode.h │ ├── encode.h │ └── types.h └── WebP ├── WebPImageSerialization.podspec ├── WebPImageSerialization.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist └── WebPImageSerialization ├── WebPImageSerialization.h └── WebPImageSerialization.m /.gitattributes: -------------------------------------------------------------------------------- 1 | WebP.framework/* linguist-vendored 2 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | 8 | jobs: 9 | cocoapods: 10 | runs-on: macos-latest 11 | 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v1 15 | 16 | - name: Install CocoaPods 17 | run: gem install cocoapods 18 | 19 | - name: Deploy to CocoaPods 20 | run: | 21 | set -eo pipefail 22 | pod lib lint --allow-warnings 23 | pod trunk push --allow-warnings 24 | env: 25 | COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | # CocoaPods 34 | # 35 | # We recommend against adding the Pods directory to your .gitignore. However 36 | # you should judge for yourself, the pros and cons are mentioned at: 37 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 38 | # 39 | # Pods/ 40 | # 41 | # Add this line if you want to avoid checking in source code from the Xcode workspace 42 | # *.xcworkspace 43 | 44 | # Carthage 45 | # 46 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 47 | # Carthage/Checkouts 48 | 49 | Carthage/Build/ 50 | 51 | # fastlane 52 | # 53 | # It is recommended to not store the screenshots in the git repo. 54 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 55 | # For more information about the recommended setup visit: 56 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 57 | 58 | fastlane/report.xml 59 | fastlane/Preview.html 60 | fastlane/screenshots/**/*.png 61 | fastlane/test_output 62 | 63 | # Code Injection 64 | # 65 | # After new code Injection tools there's a generated folder /iOSInjectionProject 66 | # https://github.com/johnno1962/injectionforxcode 67 | 68 | iOSInjectionProject/ 69 | .DS_Store 70 | -------------------------------------------------------------------------------- /Example/WebPImage Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 22E7604E23EE9C8B00051B96 /* WebP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22E7604D23EE9C8B00051B96 /* WebP.framework */; }; 11 | 22E7605023EE9D5000051B96 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 22E7604F23EE9D5000051B96 /* LaunchScreen.storyboard */; }; 12 | F82E75AF18ABDC4E002D596E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F82E75AE18ABDC4E002D596E /* Foundation.framework */; }; 13 | F82E75B118ABDC4E002D596E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F82E75B018ABDC4E002D596E /* CoreGraphics.framework */; }; 14 | F82E75B318ABDC4E002D596E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F82E75B218ABDC4E002D596E /* UIKit.framework */; }; 15 | F82E75B918ABDC4E002D596E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F82E75B718ABDC4E002D596E /* InfoPlist.strings */; }; 16 | F82E75BB18ABDC4E002D596E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F82E75BA18ABDC4E002D596E /* main.m */; }; 17 | F82E75BF18ABDC4E002D596E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F82E75BE18ABDC4E002D596E /* AppDelegate.m */; }; 18 | F82E75C118ABDC4E002D596E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F82E75C018ABDC4E002D596E /* Images.xcassets */; }; 19 | F8B725EB18BE915200C12AFC /* image.webp in Resources */ = {isa = PBXBuildFile; fileRef = F8B725EA18BE915200C12AFC /* image.webp */; }; 20 | F8B7264718BEAB1000C12AFC /* WebPImageSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = F8B7264618BEAB1000C12AFC /* WebPImageSerialization.m */; }; 21 | F8B7264B18BEC00A00C12AFC /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = F8B7264A18BEC00A00C12AFC /* image.png */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 22E7604D23EE9C8B00051B96 /* WebP.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebP.framework; path = ../WebP.framework; sourceTree = ""; }; 26 | 22E7604F23EE9D5000051B96 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 27 | F82E75AB18ABDC4E002D596E /* WebPImage Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WebPImage Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | F82E75AE18ABDC4E002D596E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 29 | F82E75B018ABDC4E002D596E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 30 | F82E75B218ABDC4E002D596E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 31 | F82E75B618ABDC4E002D596E /* WebPImage Example-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "WebPImage Example-Info.plist"; sourceTree = ""; }; 32 | F82E75B818ABDC4E002D596E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 33 | F82E75BA18ABDC4E002D596E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 34 | F82E75BC18ABDC4E002D596E /* WebPImage Example-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WebPImage Example-Prefix.pch"; sourceTree = ""; }; 35 | F82E75BD18ABDC4E002D596E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 36 | F82E75BE18ABDC4E002D596E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 37 | F82E75C018ABDC4E002D596E /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 38 | F82E75C718ABDC4E002D596E /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 39 | F8B725EA18BE915200C12AFC /* image.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = image.webp; sourceTree = ""; }; 40 | F8B7264518BEAB1000C12AFC /* WebPImageSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPImageSerialization.h; sourceTree = ""; }; 41 | F8B7264618BEAB1000C12AFC /* WebPImageSerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebPImageSerialization.m; sourceTree = ""; }; 42 | F8B7264A18BEC00A00C12AFC /* image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = image.png; sourceTree = ""; }; 43 | /* End PBXFileReference section */ 44 | 45 | /* Begin PBXFrameworksBuildPhase section */ 46 | F82E75A818ABDC4E002D596E /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | 22E7604E23EE9C8B00051B96 /* WebP.framework in Frameworks */, 51 | F82E75B118ABDC4E002D596E /* CoreGraphics.framework in Frameworks */, 52 | F82E75B318ABDC4E002D596E /* UIKit.framework in Frameworks */, 53 | F82E75AF18ABDC4E002D596E /* Foundation.framework in Frameworks */, 54 | ); 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | /* End PBXFrameworksBuildPhase section */ 58 | 59 | /* Begin PBXGroup section */ 60 | F82E75A218ABDC4E002D596E = { 61 | isa = PBXGroup; 62 | children = ( 63 | F82E75B418ABDC4E002D596E /* WebPImage Example */, 64 | F82E75AD18ABDC4E002D596E /* Frameworks */, 65 | F82E75AC18ABDC4E002D596E /* Products */, 66 | F82E75DD18ABDC57002D596E /* Vendor */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | F82E75AC18ABDC4E002D596E /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | F82E75AB18ABDC4E002D596E /* WebPImage Example.app */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | F82E75AD18ABDC4E002D596E /* Frameworks */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 22E7604D23EE9C8B00051B96 /* WebP.framework */, 82 | F82E75AE18ABDC4E002D596E /* Foundation.framework */, 83 | F82E75B018ABDC4E002D596E /* CoreGraphics.framework */, 84 | F82E75B218ABDC4E002D596E /* UIKit.framework */, 85 | F82E75C718ABDC4E002D596E /* XCTest.framework */, 86 | ); 87 | name = Frameworks; 88 | sourceTree = ""; 89 | }; 90 | F82E75B418ABDC4E002D596E /* WebPImage Example */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | F82E75BD18ABDC4E002D596E /* AppDelegate.h */, 94 | F82E75BE18ABDC4E002D596E /* AppDelegate.m */, 95 | F82E75C018ABDC4E002D596E /* Images.xcassets */, 96 | F82E75B518ABDC4E002D596E /* Supporting Files */, 97 | ); 98 | path = "WebPImage Example"; 99 | sourceTree = ""; 100 | }; 101 | F82E75B518ABDC4E002D596E /* Supporting Files */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | F8B7264A18BEC00A00C12AFC /* image.png */, 105 | F8B725EA18BE915200C12AFC /* image.webp */, 106 | F82E75B618ABDC4E002D596E /* WebPImage Example-Info.plist */, 107 | F82E75B718ABDC4E002D596E /* InfoPlist.strings */, 108 | F82E75BA18ABDC4E002D596E /* main.m */, 109 | F82E75BC18ABDC4E002D596E /* WebPImage Example-Prefix.pch */, 110 | 22E7604F23EE9D5000051B96 /* LaunchScreen.storyboard */, 111 | ); 112 | name = "Supporting Files"; 113 | sourceTree = ""; 114 | }; 115 | F82E75DD18ABDC57002D596E /* Vendor */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | F8B7261A18BEAB1000C12AFC /* WebPImageSerialization */, 119 | ); 120 | name = Vendor; 121 | path = ../WebPImageSerialization; 122 | sourceTree = ""; 123 | }; 124 | F8B7261A18BEAB1000C12AFC /* WebPImageSerialization */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | F8B7264518BEAB1000C12AFC /* WebPImageSerialization.h */, 128 | F8B7264618BEAB1000C12AFC /* WebPImageSerialization.m */, 129 | ); 130 | name = WebPImageSerialization; 131 | sourceTree = ""; 132 | }; 133 | /* End PBXGroup section */ 134 | 135 | /* Begin PBXNativeTarget section */ 136 | F82E75AA18ABDC4E002D596E /* WebPImage Example */ = { 137 | isa = PBXNativeTarget; 138 | buildConfigurationList = F82E75D718ABDC4E002D596E /* Build configuration list for PBXNativeTarget "WebPImage Example" */; 139 | buildPhases = ( 140 | F82E75A718ABDC4E002D596E /* Sources */, 141 | F82E75A818ABDC4E002D596E /* Frameworks */, 142 | F82E75A918ABDC4E002D596E /* Resources */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | ); 148 | name = "WebPImage Example"; 149 | productName = "WebPImage Example"; 150 | productReference = F82E75AB18ABDC4E002D596E /* WebPImage Example.app */; 151 | productType = "com.apple.product-type.application"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | F82E75A318ABDC4E002D596E /* Project object */ = { 157 | isa = PBXProject; 158 | attributes = { 159 | LastUpgradeCheck = 1020; 160 | ORGANIZATIONNAME = "Mattt Thompson"; 161 | }; 162 | buildConfigurationList = F82E75A618ABDC4E002D596E /* Build configuration list for PBXProject "WebPImage Example" */; 163 | compatibilityVersion = "Xcode 3.2"; 164 | developmentRegion = en; 165 | hasScannedForEncodings = 0; 166 | knownRegions = ( 167 | en, 168 | Base, 169 | ); 170 | mainGroup = F82E75A218ABDC4E002D596E; 171 | productRefGroup = F82E75AC18ABDC4E002D596E /* Products */; 172 | projectDirPath = ""; 173 | projectRoot = ""; 174 | targets = ( 175 | F82E75AA18ABDC4E002D596E /* WebPImage Example */, 176 | ); 177 | }; 178 | /* End PBXProject section */ 179 | 180 | /* Begin PBXResourcesBuildPhase section */ 181 | F82E75A918ABDC4E002D596E /* Resources */ = { 182 | isa = PBXResourcesBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | F8B725EB18BE915200C12AFC /* image.webp in Resources */, 186 | F82E75B918ABDC4E002D596E /* InfoPlist.strings in Resources */, 187 | F82E75C118ABDC4E002D596E /* Images.xcassets in Resources */, 188 | 22E7605023EE9D5000051B96 /* LaunchScreen.storyboard in Resources */, 189 | F8B7264B18BEC00A00C12AFC /* image.png in Resources */, 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | /* End PBXResourcesBuildPhase section */ 194 | 195 | /* Begin PBXSourcesBuildPhase section */ 196 | F82E75A718ABDC4E002D596E /* Sources */ = { 197 | isa = PBXSourcesBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | F8B7264718BEAB1000C12AFC /* WebPImageSerialization.m in Sources */, 201 | F82E75BF18ABDC4E002D596E /* AppDelegate.m in Sources */, 202 | F82E75BB18ABDC4E002D596E /* main.m in Sources */, 203 | ); 204 | runOnlyForDeploymentPostprocessing = 0; 205 | }; 206 | /* End PBXSourcesBuildPhase section */ 207 | 208 | /* Begin PBXVariantGroup section */ 209 | F82E75B718ABDC4E002D596E /* InfoPlist.strings */ = { 210 | isa = PBXVariantGroup; 211 | children = ( 212 | F82E75B818ABDC4E002D596E /* en */, 213 | ); 214 | name = InfoPlist.strings; 215 | sourceTree = ""; 216 | }; 217 | /* End PBXVariantGroup section */ 218 | 219 | /* Begin XCBuildConfiguration section */ 220 | F82E75D518ABDC4E002D596E /* Debug */ = { 221 | isa = XCBuildConfiguration; 222 | buildSettings = { 223 | ALWAYS_SEARCH_USER_PATHS = NO; 224 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 225 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 226 | CLANG_CXX_LIBRARY = "libc++"; 227 | CLANG_ENABLE_MODULES = YES; 228 | CLANG_ENABLE_OBJC_ARC = YES; 229 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 230 | CLANG_WARN_BOOL_CONVERSION = YES; 231 | CLANG_WARN_COMMA = YES; 232 | CLANG_WARN_CONSTANT_CONVERSION = YES; 233 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 234 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 235 | CLANG_WARN_EMPTY_BODY = YES; 236 | CLANG_WARN_ENUM_CONVERSION = YES; 237 | CLANG_WARN_INFINITE_RECURSION = YES; 238 | CLANG_WARN_INT_CONVERSION = YES; 239 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 240 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 241 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 242 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 243 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 244 | CLANG_WARN_STRICT_PROTOTYPES = YES; 245 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 246 | CLANG_WARN_UNREACHABLE_CODE = YES; 247 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 248 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 249 | COPY_PHASE_STRIP = NO; 250 | ENABLE_STRICT_OBJC_MSGSEND = YES; 251 | ENABLE_TESTABILITY = YES; 252 | GCC_C_LANGUAGE_STANDARD = gnu99; 253 | GCC_DYNAMIC_NO_PIC = NO; 254 | GCC_NO_COMMON_BLOCKS = YES; 255 | GCC_OPTIMIZATION_LEVEL = 0; 256 | GCC_PREPROCESSOR_DEFINITIONS = ( 257 | "DEBUG=1", 258 | "$(inherited)", 259 | ); 260 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 261 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 262 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 263 | GCC_WARN_UNDECLARED_SELECTOR = YES; 264 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 265 | GCC_WARN_UNUSED_FUNCTION = YES; 266 | GCC_WARN_UNUSED_VARIABLE = YES; 267 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 268 | ONLY_ACTIVE_ARCH = YES; 269 | SDKROOT = iphoneos; 270 | }; 271 | name = Debug; 272 | }; 273 | F82E75D618ABDC4E002D596E /* Release */ = { 274 | isa = XCBuildConfiguration; 275 | buildSettings = { 276 | ALWAYS_SEARCH_USER_PATHS = NO; 277 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 278 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 279 | CLANG_CXX_LIBRARY = "libc++"; 280 | CLANG_ENABLE_MODULES = YES; 281 | CLANG_ENABLE_OBJC_ARC = YES; 282 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 283 | CLANG_WARN_BOOL_CONVERSION = YES; 284 | CLANG_WARN_COMMA = YES; 285 | CLANG_WARN_CONSTANT_CONVERSION = YES; 286 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 287 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 288 | CLANG_WARN_EMPTY_BODY = YES; 289 | CLANG_WARN_ENUM_CONVERSION = YES; 290 | CLANG_WARN_INFINITE_RECURSION = YES; 291 | CLANG_WARN_INT_CONVERSION = YES; 292 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 293 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 294 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 295 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 296 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 297 | CLANG_WARN_STRICT_PROTOTYPES = YES; 298 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 299 | CLANG_WARN_UNREACHABLE_CODE = YES; 300 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 301 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 302 | COPY_PHASE_STRIP = YES; 303 | ENABLE_NS_ASSERTIONS = NO; 304 | ENABLE_STRICT_OBJC_MSGSEND = YES; 305 | GCC_C_LANGUAGE_STANDARD = gnu99; 306 | GCC_NO_COMMON_BLOCKS = YES; 307 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 308 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 309 | GCC_WARN_UNDECLARED_SELECTOR = YES; 310 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 311 | GCC_WARN_UNUSED_FUNCTION = YES; 312 | GCC_WARN_UNUSED_VARIABLE = YES; 313 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 314 | SDKROOT = iphoneos; 315 | VALIDATE_PRODUCT = YES; 316 | }; 317 | name = Release; 318 | }; 319 | F82E75D818ABDC4E002D596E /* Debug */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 323 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 324 | DEVELOPMENT_TEAM = ""; 325 | FRAMEWORK_SEARCH_PATHS = ( 326 | "$(inherited)", 327 | "$(SRCROOT)/../**", 328 | "$(SRCROOT)/**", 329 | ); 330 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 331 | GCC_PREFIX_HEADER = "WebPImage Example/WebPImage Example-Prefix.pch"; 332 | INFOPLIST_FILE = "WebPImage Example/WebPImage Example-Info.plist"; 333 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 334 | PRODUCT_BUNDLE_IDENTIFIER = "com.mattt.${PRODUCT_NAME:rfc1034identifier}"; 335 | PRODUCT_NAME = "$(TARGET_NAME)"; 336 | TARGETED_DEVICE_FAMILY = "1,2"; 337 | WARNING_CFLAGS = "-Weverything"; 338 | WRAPPER_EXTENSION = app; 339 | }; 340 | name = Debug; 341 | }; 342 | F82E75D918ABDC4E002D596E /* Release */ = { 343 | isa = XCBuildConfiguration; 344 | buildSettings = { 345 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 346 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 347 | DEVELOPMENT_TEAM = ""; 348 | FRAMEWORK_SEARCH_PATHS = ( 349 | "$(inherited)", 350 | "$(SRCROOT)/../**", 351 | "$(SRCROOT)/**", 352 | ); 353 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 354 | GCC_PREFIX_HEADER = "WebPImage Example/WebPImage Example-Prefix.pch"; 355 | INFOPLIST_FILE = "WebPImage Example/WebPImage Example-Info.plist"; 356 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 357 | PRODUCT_BUNDLE_IDENTIFIER = "com.mattt.${PRODUCT_NAME:rfc1034identifier}"; 358 | PRODUCT_NAME = "$(TARGET_NAME)"; 359 | TARGETED_DEVICE_FAMILY = "1,2"; 360 | WARNING_CFLAGS = "-Weverything"; 361 | WRAPPER_EXTENSION = app; 362 | }; 363 | name = Release; 364 | }; 365 | /* End XCBuildConfiguration section */ 366 | 367 | /* Begin XCConfigurationList section */ 368 | F82E75A618ABDC4E002D596E /* Build configuration list for PBXProject "WebPImage Example" */ = { 369 | isa = XCConfigurationList; 370 | buildConfigurations = ( 371 | F82E75D518ABDC4E002D596E /* Debug */, 372 | F82E75D618ABDC4E002D596E /* Release */, 373 | ); 374 | defaultConfigurationIsVisible = 0; 375 | defaultConfigurationName = Release; 376 | }; 377 | F82E75D718ABDC4E002D596E /* Build configuration list for PBXNativeTarget "WebPImage Example" */ = { 378 | isa = XCConfigurationList; 379 | buildConfigurations = ( 380 | F82E75D818ABDC4E002D596E /* Debug */, 381 | F82E75D918ABDC4E002D596E /* Release */, 382 | ); 383 | defaultConfigurationIsVisible = 0; 384 | defaultConfigurationName = Release; 385 | }; 386 | /* End XCConfigurationList section */ 387 | }; 388 | rootObject = F82E75A318ABDC4E002D596E /* Project object */; 389 | } 390 | -------------------------------------------------------------------------------- /Example/WebPImage Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/WebPImage Example.xcodeproj/xcshareddata/xcschemes/WebPImage Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Example/WebPImage Example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // AppDelegate.h 2 | // 3 | // Copyright (c) 2014 – 2020 Mattt (http://mat.tt/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import UIKit; 24 | 25 | @interface AppDelegate : UIResponder 26 | 27 | @property (strong, nonatomic) UIWindow *window; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Example/WebPImage Example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // AppDelegate.m 2 | // 3 | // Copyright (c) 2014 – 2020 Mattt (http://mat.tt/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "AppDelegate.h" 24 | 25 | #import "WebPImageSerialization.h" 26 | 27 | @implementation AppDelegate 28 | @synthesize window; 29 | 30 | - (BOOL)application:(__unused UIApplication *)application 31 | didFinishLaunchingWithOptions:(__unused NSDictionary *)launchOptions 32 | { 33 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 34 | 35 | UIViewController *viewController = [[UIViewController alloc] init]; 36 | self.window.rootViewController = viewController; 37 | 38 | UIImage *image = [UIImage imageNamed:@"image.webp"]; 39 | 40 | UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 41 | imageView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | 42 | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; 43 | imageView.contentMode = UIViewContentModeScaleAspectFit; 44 | 45 | CGSize viewSize = viewController.view.frame.size; 46 | CGSize imageSize = imageView.frame.size; 47 | if (imageSize.width > viewSize.width || imageSize.height > viewSize.height) { 48 | CGFloat minimumSize = viewSize.width < viewSize.height ? viewSize.width : viewSize.height; 49 | imageView.frame = (CGRect){CGPointZero, (CGSize){minimumSize, minimumSize}}; 50 | imageView.frame = CGRectInset(imageView.frame, 20.0, 20.0); 51 | } 52 | 53 | imageView.center = viewController.view.center; 54 | [viewController.view addSubview:imageView]; 55 | 56 | self.window.backgroundColor = [UIColor whiteColor]; 57 | [self.window makeKeyAndVisible]; 58 | 59 | return YES; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Example/WebPImage Example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/WebPImage Example/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WebPImage Example/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Example/WebPImage Example/WebPImage Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationPortraitUpsideDown 35 | UIInterfaceOrientationLandscapeLeft 36 | UIInterfaceOrientationLandscapeRight 37 | 38 | UIUserInterfaceStyle 39 | Light 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/WebPImage Example/WebPImage Example-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | @import Darwin.Availability; 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | @import UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/WebPImage Example/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/WebPImage Example/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattt/WebPImageSerialization/a77a48e87c54c626ad16b8e60acc7f3bab40ab55/Example/WebPImage Example/image.png -------------------------------------------------------------------------------- /Example/WebPImage Example/image.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattt/WebPImageSerialization/a77a48e87c54c626ad16b8e60acc7f3bab40ab55/Example/WebPImage Example/image.webp -------------------------------------------------------------------------------- /Example/WebPImage Example/main.m: -------------------------------------------------------------------------------- 1 | // main.m 2 | // 3 | // Copyright (c) 2014 – 2020 Mattt (http://mat.tt/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import UIKit; 24 | 25 | #import "AppDelegate.h" 26 | 27 | int main(int argc, char * argv[]) { 28 | @autoreleasepool { 29 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 – 2021 Mattt (https://mat.tt/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebPImageSerialization 2 | 3 | `WebPImageSerialization` encodes and decodes between `UIImage` 4 | and [WebP](https://developers.google.com/speed/webp/) images, 5 | following the API conventions of Foundation's `NSJSONSerialization` class. 6 | 7 | By default, `UIImage` initializers can't decode animated images from GIF files. 8 | This library uses swizzling to provide this functionality for you. 9 | To opt out of this behavior, 10 | set `WEBP_NO_UIIMAGE_INITIALIZER_SWIZZLING` in your build environment. 11 | If you're using CocoaPods, 12 | you can add this build setting to your `Podfile`: 13 | 14 | ```ruby 15 | post_install do |r| 16 | r.pods_project.targets.each do |target| 17 | if target.name == 'WebPImageSerialization' then 18 | target.build_configurations.each do |config| 19 | config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= 20 | ['$(inherited)', 'WEBP_NO_UIIMAGE_INITIALIZER_SWIZZLING=1'] 21 | end 22 | end 23 | end 24 | end 25 | ``` 26 | 27 | ## Usage 28 | 29 | ### Decoding 30 | 31 | ```objective-c 32 | UIImageView *imageView = ...; 33 | imageView.image = [UIImage imageNamed:@"image.webp"]; 34 | ``` 35 | 36 | ### Encoding 37 | 38 | ```objective-c 39 | NSData *data = UIImageWebPRepresentation(imageView.image); 40 | ``` 41 | 42 | --- 43 | 44 | ## Contact 45 | 46 | Mattt ([@mattt](https://twitter.com/mattt)) 47 | 48 | ## License 49 | 50 | WebPImageSerialization is available under the MIT license. See the LICENSE file for more info. 51 | -------------------------------------------------------------------------------- /WebP.framework/Headers/decode.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Main decoding functions for WebP images. 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_WEBP_DECODE_H_ 15 | #define WEBP_WEBP_DECODE_H_ 16 | 17 | #include "./types.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #define WEBP_DECODER_ABI_VERSION 0x0208 // MAJOR(8b) + MINOR(8b) 24 | 25 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 26 | // the types are left here for reference. 27 | // typedef enum VP8StatusCode VP8StatusCode; 28 | // typedef enum WEBP_CSP_MODE WEBP_CSP_MODE; 29 | typedef struct WebPRGBABuffer WebPRGBABuffer; 30 | typedef struct WebPYUVABuffer WebPYUVABuffer; 31 | typedef struct WebPDecBuffer WebPDecBuffer; 32 | typedef struct WebPIDecoder WebPIDecoder; 33 | typedef struct WebPBitstreamFeatures WebPBitstreamFeatures; 34 | typedef struct WebPDecoderOptions WebPDecoderOptions; 35 | typedef struct WebPDecoderConfig WebPDecoderConfig; 36 | 37 | // Return the decoder's version number, packed in hexadecimal using 8bits for 38 | // each of major/minor/revision. E.g: v2.5.7 is 0x020507. 39 | WEBP_EXTERN int WebPGetDecoderVersion(void); 40 | 41 | // Retrieve basic header information: width, height. 42 | // This function will also validate the header, returning true on success, 43 | // false otherwise. '*width' and '*height' are only valid on successful return. 44 | // Pointers 'width' and 'height' can be passed NULL if deemed irrelevant. 45 | // Note: The following chunk sequences (before the raw VP8/VP8L data) are 46 | // considered valid by this function: 47 | // RIFF + VP8(L) 48 | // RIFF + VP8X + (optional chunks) + VP8(L) 49 | // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose. 50 | // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose. 51 | WEBP_EXTERN int WebPGetInfo(const uint8_t* data, size_t data_size, 52 | int* width, int* height); 53 | 54 | // Decodes WebP images pointed to by 'data' and returns RGBA samples, along 55 | // with the dimensions in *width and *height. The ordering of samples in 56 | // memory is R, G, B, A, R, G, B, A... in scan order (endian-independent). 57 | // The returned pointer should be deleted calling WebPFree(). 58 | // Returns NULL in case of error. 59 | WEBP_EXTERN uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size, 60 | int* width, int* height); 61 | 62 | // Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data. 63 | WEBP_EXTERN uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size, 64 | int* width, int* height); 65 | 66 | // Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data. 67 | WEBP_EXTERN uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size, 68 | int* width, int* height); 69 | 70 | // Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data. 71 | // If the bitstream contains transparency, it is ignored. 72 | WEBP_EXTERN uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, 73 | int* width, int* height); 74 | 75 | // Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data. 76 | WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size, 77 | int* width, int* height); 78 | 79 | 80 | // Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer 81 | // returned is the Y samples buffer. Upon return, *u and *v will point to 82 | // the U and V chroma data. These U and V buffers need NOT be passed to 83 | // WebPFree(), unlike the returned Y luma one. The dimension of the U and V 84 | // planes are both (*width + 1) / 2 and (*height + 1)/ 2. 85 | // Upon return, the Y buffer has a stride returned as '*stride', while U and V 86 | // have a common stride returned as '*uv_stride'. 87 | // Return NULL in case of error. 88 | // (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr 89 | WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size, 90 | int* width, int* height, 91 | uint8_t** u, uint8_t** v, 92 | int* stride, int* uv_stride); 93 | 94 | // Releases memory returned by the WebPDecode*() functions above. 95 | WEBP_EXTERN void WebPFree(void* ptr); 96 | 97 | // These five functions are variants of the above ones, that decode the image 98 | // directly into a pre-allocated buffer 'output_buffer'. The maximum storage 99 | // available in this buffer is indicated by 'output_buffer_size'. If this 100 | // storage is not sufficient (or an error occurred), NULL is returned. 101 | // Otherwise, output_buffer is returned, for convenience. 102 | // The parameter 'output_stride' specifies the distance (in bytes) 103 | // between scanlines. Hence, output_buffer_size is expected to be at least 104 | // output_stride x picture-height. 105 | WEBP_EXTERN uint8_t* WebPDecodeRGBAInto( 106 | const uint8_t* data, size_t data_size, 107 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 108 | WEBP_EXTERN uint8_t* WebPDecodeARGBInto( 109 | const uint8_t* data, size_t data_size, 110 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 111 | WEBP_EXTERN uint8_t* WebPDecodeBGRAInto( 112 | const uint8_t* data, size_t data_size, 113 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 114 | 115 | // RGB and BGR variants. Here too the transparency information, if present, 116 | // will be dropped and ignored. 117 | WEBP_EXTERN uint8_t* WebPDecodeRGBInto( 118 | const uint8_t* data, size_t data_size, 119 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 120 | WEBP_EXTERN uint8_t* WebPDecodeBGRInto( 121 | const uint8_t* data, size_t data_size, 122 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 123 | 124 | // WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly 125 | // into pre-allocated luma/chroma plane buffers. This function requires the 126 | // strides to be passed: one for the luma plane and one for each of the 127 | // chroma ones. The size of each plane buffer is passed as 'luma_size', 128 | // 'u_size' and 'v_size' respectively. 129 | // Pointer to the luma plane ('*luma') is returned or NULL if an error occurred 130 | // during decoding (or because some buffers were found to be too small). 131 | WEBP_EXTERN uint8_t* WebPDecodeYUVInto( 132 | const uint8_t* data, size_t data_size, 133 | uint8_t* luma, size_t luma_size, int luma_stride, 134 | uint8_t* u, size_t u_size, int u_stride, 135 | uint8_t* v, size_t v_size, int v_stride); 136 | 137 | //------------------------------------------------------------------------------ 138 | // Output colorspaces and buffer 139 | 140 | // Colorspaces 141 | // Note: the naming describes the byte-ordering of packed samples in memory. 142 | // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,... 143 | // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels. 144 | // RGBA-4444 and RGB-565 colorspaces are represented by following byte-order: 145 | // RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ... 146 | // RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ... 147 | // In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for 148 | // these two modes: 149 | // RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ... 150 | // RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ... 151 | 152 | typedef enum WEBP_CSP_MODE { 153 | MODE_RGB = 0, MODE_RGBA = 1, 154 | MODE_BGR = 2, MODE_BGRA = 3, 155 | MODE_ARGB = 4, MODE_RGBA_4444 = 5, 156 | MODE_RGB_565 = 6, 157 | // RGB-premultiplied transparent modes (alpha value is preserved) 158 | MODE_rgbA = 7, 159 | MODE_bgrA = 8, 160 | MODE_Argb = 9, 161 | MODE_rgbA_4444 = 10, 162 | // YUV modes must come after RGB ones. 163 | MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0 164 | MODE_LAST = 13 165 | } WEBP_CSP_MODE; 166 | 167 | // Some useful macros: 168 | static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) { 169 | return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb || 170 | mode == MODE_rgbA_4444); 171 | } 172 | 173 | static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) { 174 | return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB || 175 | mode == MODE_RGBA_4444 || mode == MODE_YUVA || 176 | WebPIsPremultipliedMode(mode)); 177 | } 178 | 179 | static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) { 180 | return (mode < MODE_YUV); 181 | } 182 | 183 | //------------------------------------------------------------------------------ 184 | // WebPDecBuffer: Generic structure for describing the output sample buffer. 185 | 186 | struct WebPRGBABuffer { // view as RGBA 187 | uint8_t* rgba; // pointer to RGBA samples 188 | int stride; // stride in bytes from one scanline to the next. 189 | size_t size; // total size of the *rgba buffer. 190 | }; 191 | 192 | struct WebPYUVABuffer { // view as YUVA 193 | uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples 194 | int y_stride; // luma stride 195 | int u_stride, v_stride; // chroma strides 196 | int a_stride; // alpha stride 197 | size_t y_size; // luma plane size 198 | size_t u_size, v_size; // chroma planes size 199 | size_t a_size; // alpha-plane size 200 | }; 201 | 202 | // Output buffer 203 | struct WebPDecBuffer { 204 | WEBP_CSP_MODE colorspace; // Colorspace. 205 | int width, height; // Dimensions. 206 | int is_external_memory; // If non-zero, 'internal_memory' pointer is not 207 | // used. If value is '2' or more, the external 208 | // memory is considered 'slow' and multiple 209 | // read/write will be avoided. 210 | union { 211 | WebPRGBABuffer RGBA; 212 | WebPYUVABuffer YUVA; 213 | } u; // Nameless union of buffer parameters. 214 | uint32_t pad[4]; // padding for later use 215 | 216 | uint8_t* private_memory; // Internally allocated memory (only when 217 | // is_external_memory is 0). Should not be used 218 | // externally, but accessed via the buffer union. 219 | }; 220 | 221 | // Internal, version-checked, entry point 222 | WEBP_EXTERN int WebPInitDecBufferInternal(WebPDecBuffer*, int); 223 | 224 | // Initialize the structure as empty. Must be called before any other use. 225 | // Returns false in case of version mismatch 226 | static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) { 227 | return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION); 228 | } 229 | 230 | // Free any memory associated with the buffer. Must always be called last. 231 | // Note: doesn't free the 'buffer' structure itself. 232 | WEBP_EXTERN void WebPFreeDecBuffer(WebPDecBuffer* buffer); 233 | 234 | //------------------------------------------------------------------------------ 235 | // Enumeration of the status codes 236 | 237 | typedef enum VP8StatusCode { 238 | VP8_STATUS_OK = 0, 239 | VP8_STATUS_OUT_OF_MEMORY, 240 | VP8_STATUS_INVALID_PARAM, 241 | VP8_STATUS_BITSTREAM_ERROR, 242 | VP8_STATUS_UNSUPPORTED_FEATURE, 243 | VP8_STATUS_SUSPENDED, 244 | VP8_STATUS_USER_ABORT, 245 | VP8_STATUS_NOT_ENOUGH_DATA 246 | } VP8StatusCode; 247 | 248 | //------------------------------------------------------------------------------ 249 | // Incremental decoding 250 | // 251 | // This API allows streamlined decoding of partial data. 252 | // Picture can be incrementally decoded as data become available thanks to the 253 | // WebPIDecoder object. This object can be left in a SUSPENDED state if the 254 | // picture is only partially decoded, pending additional input. 255 | // Code example: 256 | // 257 | // WebPInitDecBuffer(&output_buffer); 258 | // output_buffer.colorspace = mode; 259 | // ... 260 | // WebPIDecoder* idec = WebPINewDecoder(&output_buffer); 261 | // while (additional_data_is_available) { 262 | // // ... (get additional data in some new_data[] buffer) 263 | // status = WebPIAppend(idec, new_data, new_data_size); 264 | // if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { 265 | // break; // an error occurred. 266 | // } 267 | // 268 | // // The above call decodes the current available buffer. 269 | // // Part of the image can now be refreshed by calling 270 | // // WebPIDecGetRGB()/WebPIDecGetYUVA() etc. 271 | // } 272 | // WebPIDelete(idec); 273 | 274 | // Creates a new incremental decoder with the supplied buffer parameter. 275 | // This output_buffer can be passed NULL, in which case a default output buffer 276 | // is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer' 277 | // is kept, which means that the lifespan of 'output_buffer' must be larger than 278 | // that of the returned WebPIDecoder object. 279 | // The supplied 'output_buffer' content MUST NOT be changed between calls to 280 | // WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is 281 | // not set to 0. In such a case, it is allowed to modify the pointers, size and 282 | // stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain 283 | // within valid bounds. 284 | // All other fields of WebPDecBuffer MUST remain constant between calls. 285 | // Returns NULL if the allocation failed. 286 | WEBP_EXTERN WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer); 287 | 288 | // This function allocates and initializes an incremental-decoder object, which 289 | // will output the RGB/A samples specified by 'csp' into a preallocated 290 | // buffer 'output_buffer'. The size of this buffer is at least 291 | // 'output_buffer_size' and the stride (distance in bytes between two scanlines) 292 | // is specified by 'output_stride'. 293 | // Additionally, output_buffer can be passed NULL in which case the output 294 | // buffer will be allocated automatically when the decoding starts. The 295 | // colorspace 'csp' is taken into account for allocating this buffer. All other 296 | // parameters are ignored. 297 | // Returns NULL if the allocation failed, or if some parameters are invalid. 298 | WEBP_EXTERN WebPIDecoder* WebPINewRGB( 299 | WEBP_CSP_MODE csp, 300 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 301 | 302 | // This function allocates and initializes an incremental-decoder object, which 303 | // will output the raw luma/chroma samples into a preallocated planes if 304 | // supplied. The luma plane is specified by its pointer 'luma', its size 305 | // 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane 306 | // is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v 307 | // plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer 308 | // can be pass NULL in case one is not interested in the transparency plane. 309 | // Conversely, 'luma' can be passed NULL if no preallocated planes are supplied. 310 | // In this case, the output buffer will be automatically allocated (using 311 | // MODE_YUVA) when decoding starts. All parameters are then ignored. 312 | // Returns NULL if the allocation failed or if a parameter is invalid. 313 | WEBP_EXTERN WebPIDecoder* WebPINewYUVA( 314 | uint8_t* luma, size_t luma_size, int luma_stride, 315 | uint8_t* u, size_t u_size, int u_stride, 316 | uint8_t* v, size_t v_size, int v_stride, 317 | uint8_t* a, size_t a_size, int a_stride); 318 | 319 | // Deprecated version of the above, without the alpha plane. 320 | // Kept for backward compatibility. 321 | WEBP_EXTERN WebPIDecoder* WebPINewYUV( 322 | uint8_t* luma, size_t luma_size, int luma_stride, 323 | uint8_t* u, size_t u_size, int u_stride, 324 | uint8_t* v, size_t v_size, int v_stride); 325 | 326 | // Deletes the WebPIDecoder object and associated memory. Must always be called 327 | // if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded. 328 | WEBP_EXTERN void WebPIDelete(WebPIDecoder* idec); 329 | 330 | // Copies and decodes the next available data. Returns VP8_STATUS_OK when 331 | // the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more 332 | // data is expected. Returns error in other cases. 333 | WEBP_EXTERN VP8StatusCode WebPIAppend( 334 | WebPIDecoder* idec, const uint8_t* data, size_t data_size); 335 | 336 | // A variant of the above function to be used when data buffer contains 337 | // partial data from the beginning. In this case data buffer is not copied 338 | // to the internal memory. 339 | // Note that the value of the 'data' pointer can change between calls to 340 | // WebPIUpdate, for instance when the data buffer is resized to fit larger data. 341 | WEBP_EXTERN VP8StatusCode WebPIUpdate( 342 | WebPIDecoder* idec, const uint8_t* data, size_t data_size); 343 | 344 | // Returns the RGB/A image decoded so far. Returns NULL if output params 345 | // are not initialized yet. The RGB/A output type corresponds to the colorspace 346 | // specified during call to WebPINewDecoder() or WebPINewRGB(). 347 | // *last_y is the index of last decoded row in raster scan order. Some pointers 348 | // (*last_y, *width etc.) can be NULL if corresponding information is not 349 | // needed. The values in these pointers are only valid on successful (non-NULL) 350 | // return. 351 | WEBP_EXTERN uint8_t* WebPIDecGetRGB( 352 | const WebPIDecoder* idec, int* last_y, 353 | int* width, int* height, int* stride); 354 | 355 | // Same as above function to get a YUVA image. Returns pointer to the luma 356 | // plane or NULL in case of error. If there is no alpha information 357 | // the alpha pointer '*a' will be returned NULL. 358 | WEBP_EXTERN uint8_t* WebPIDecGetYUVA( 359 | const WebPIDecoder* idec, int* last_y, 360 | uint8_t** u, uint8_t** v, uint8_t** a, 361 | int* width, int* height, int* stride, int* uv_stride, int* a_stride); 362 | 363 | // Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the 364 | // alpha information (if present). Kept for backward compatibility. 365 | static WEBP_INLINE uint8_t* WebPIDecGetYUV( 366 | const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, 367 | int* width, int* height, int* stride, int* uv_stride) { 368 | return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height, 369 | stride, uv_stride, NULL); 370 | } 371 | 372 | // Generic call to retrieve information about the displayable area. 373 | // If non NULL, the left/right/width/height pointers are filled with the visible 374 | // rectangular area so far. 375 | // Returns NULL in case the incremental decoder object is in an invalid state. 376 | // Otherwise returns the pointer to the internal representation. This structure 377 | // is read-only, tied to WebPIDecoder's lifespan and should not be modified. 378 | WEBP_EXTERN const WebPDecBuffer* WebPIDecodedArea( 379 | const WebPIDecoder* idec, int* left, int* top, int* width, int* height); 380 | 381 | //------------------------------------------------------------------------------ 382 | // Advanced decoding parametrization 383 | // 384 | // Code sample for using the advanced decoding API 385 | /* 386 | // A) Init a configuration object 387 | WebPDecoderConfig config; 388 | CHECK(WebPInitDecoderConfig(&config)); 389 | 390 | // B) optional: retrieve the bitstream's features. 391 | CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK); 392 | 393 | // C) Adjust 'config', if needed 394 | config.no_fancy_upsampling = 1; 395 | config.output.colorspace = MODE_BGRA; 396 | // etc. 397 | 398 | // Note that you can also make config.output point to an externally 399 | // supplied memory buffer, provided it's big enough to store the decoded 400 | // picture. Otherwise, config.output will just be used to allocate memory 401 | // and store the decoded picture. 402 | 403 | // D) Decode! 404 | CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK); 405 | 406 | // E) Decoded image is now in config.output (and config.output.u.RGBA) 407 | 408 | // F) Reclaim memory allocated in config's object. It's safe to call 409 | // this function even if the memory is external and wasn't allocated 410 | // by WebPDecode(). 411 | WebPFreeDecBuffer(&config.output); 412 | */ 413 | 414 | // Features gathered from the bitstream 415 | struct WebPBitstreamFeatures { 416 | int width; // Width in pixels, as read from the bitstream. 417 | int height; // Height in pixels, as read from the bitstream. 418 | int has_alpha; // True if the bitstream contains an alpha channel. 419 | int has_animation; // True if the bitstream is an animation. 420 | int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless 421 | 422 | uint32_t pad[5]; // padding for later use 423 | }; 424 | 425 | // Internal, version-checked, entry point 426 | WEBP_EXTERN VP8StatusCode WebPGetFeaturesInternal( 427 | const uint8_t*, size_t, WebPBitstreamFeatures*, int); 428 | 429 | // Retrieve features from the bitstream. The *features structure is filled 430 | // with information gathered from the bitstream. 431 | // Returns VP8_STATUS_OK when the features are successfully retrieved. Returns 432 | // VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the 433 | // features from headers. Returns error in other cases. 434 | // Note: The following chunk sequences (before the raw VP8/VP8L data) are 435 | // considered valid by this function: 436 | // RIFF + VP8(L) 437 | // RIFF + VP8X + (optional chunks) + VP8(L) 438 | // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose. 439 | // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose. 440 | static WEBP_INLINE VP8StatusCode WebPGetFeatures( 441 | const uint8_t* data, size_t data_size, 442 | WebPBitstreamFeatures* features) { 443 | return WebPGetFeaturesInternal(data, data_size, features, 444 | WEBP_DECODER_ABI_VERSION); 445 | } 446 | 447 | // Decoding options 448 | struct WebPDecoderOptions { 449 | int bypass_filtering; // if true, skip the in-loop filtering 450 | int no_fancy_upsampling; // if true, use faster pointwise upsampler 451 | int use_cropping; // if true, cropping is applied _first_ 452 | int crop_left, crop_top; // top-left position for cropping. 453 | // Will be snapped to even values. 454 | int crop_width, crop_height; // dimension of the cropping area 455 | int use_scaling; // if true, scaling is applied _afterward_ 456 | int scaled_width, scaled_height; // final resolution 457 | int use_threads; // if true, use multi-threaded decoding 458 | int dithering_strength; // dithering strength (0=Off, 100=full) 459 | int flip; // flip output vertically 460 | int alpha_dithering_strength; // alpha dithering strength in [0..100] 461 | 462 | uint32_t pad[5]; // padding for later use 463 | }; 464 | 465 | // Main object storing the configuration for advanced decoding. 466 | struct WebPDecoderConfig { 467 | WebPBitstreamFeatures input; // Immutable bitstream features (optional) 468 | WebPDecBuffer output; // Output buffer (can point to external mem) 469 | WebPDecoderOptions options; // Decoding options 470 | }; 471 | 472 | // Internal, version-checked, entry point 473 | WEBP_EXTERN int WebPInitDecoderConfigInternal(WebPDecoderConfig*, int); 474 | 475 | // Initialize the configuration as empty. This function must always be 476 | // called first, unless WebPGetFeatures() is to be called. 477 | // Returns false in case of mismatched version. 478 | static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) { 479 | return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION); 480 | } 481 | 482 | // Instantiate a new incremental decoder object with the requested 483 | // configuration. The bitstream can be passed using 'data' and 'data_size' 484 | // parameter, in which case the features will be parsed and stored into 485 | // config->input. Otherwise, 'data' can be NULL and no parsing will occur. 486 | // Note that 'config' can be NULL too, in which case a default configuration 487 | // is used. If 'config' is not NULL, it must outlive the WebPIDecoder object 488 | // as some references to its fields will be used. No internal copy of 'config' 489 | // is made. 490 | // The return WebPIDecoder object must always be deleted calling WebPIDelete(). 491 | // Returns NULL in case of error (and config->status will then reflect 492 | // the error condition, if available). 493 | WEBP_EXTERN WebPIDecoder* WebPIDecode(const uint8_t* data, size_t data_size, 494 | WebPDecoderConfig* config); 495 | 496 | // Non-incremental version. This version decodes the full data at once, taking 497 | // 'config' into account. Returns decoding status (which should be VP8_STATUS_OK 498 | // if the decoding was successful). Note that 'config' cannot be NULL. 499 | WEBP_EXTERN VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size, 500 | WebPDecoderConfig* config); 501 | 502 | #ifdef __cplusplus 503 | } // extern "C" 504 | #endif 505 | 506 | #endif // WEBP_WEBP_DECODE_H_ 507 | -------------------------------------------------------------------------------- /WebP.framework/Headers/encode.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // WebP encoder: main interface 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_WEBP_ENCODE_H_ 15 | #define WEBP_WEBP_ENCODE_H_ 16 | 17 | #include "./types.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #define WEBP_ENCODER_ABI_VERSION 0x020e // MAJOR(8b) + MINOR(8b) 24 | 25 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 26 | // the types are left here for reference. 27 | // typedef enum WebPImageHint WebPImageHint; 28 | // typedef enum WebPEncCSP WebPEncCSP; 29 | // typedef enum WebPPreset WebPPreset; 30 | // typedef enum WebPEncodingError WebPEncodingError; 31 | typedef struct WebPConfig WebPConfig; 32 | typedef struct WebPPicture WebPPicture; // main structure for I/O 33 | typedef struct WebPAuxStats WebPAuxStats; 34 | typedef struct WebPMemoryWriter WebPMemoryWriter; 35 | 36 | // Return the encoder's version number, packed in hexadecimal using 8bits for 37 | // each of major/minor/revision. E.g: v2.5.7 is 0x020507. 38 | WEBP_EXTERN int WebPGetEncoderVersion(void); 39 | 40 | //------------------------------------------------------------------------------ 41 | // One-stop-shop call! No questions asked: 42 | 43 | // Returns the size of the compressed data (pointed to by *output), or 0 if 44 | // an error occurred. The compressed data must be released by the caller 45 | // using the call 'WebPFree(*output)'. 46 | // These functions compress using the lossy format, and the quality_factor 47 | // can go from 0 (smaller output, lower quality) to 100 (best quality, 48 | // larger output). 49 | WEBP_EXTERN size_t WebPEncodeRGB(const uint8_t* rgb, 50 | int width, int height, int stride, 51 | float quality_factor, uint8_t** output); 52 | WEBP_EXTERN size_t WebPEncodeBGR(const uint8_t* bgr, 53 | int width, int height, int stride, 54 | float quality_factor, uint8_t** output); 55 | WEBP_EXTERN size_t WebPEncodeRGBA(const uint8_t* rgba, 56 | int width, int height, int stride, 57 | float quality_factor, uint8_t** output); 58 | WEBP_EXTERN size_t WebPEncodeBGRA(const uint8_t* bgra, 59 | int width, int height, int stride, 60 | float quality_factor, uint8_t** output); 61 | 62 | // These functions are the equivalent of the above, but compressing in a 63 | // lossless manner. Files are usually larger than lossy format, but will 64 | // not suffer any compression loss. 65 | // Note these functions, like the lossy versions, use the library's default 66 | // settings. For lossless this means 'exact' is disabled. RGB values in 67 | // transparent areas will be modified to improve compression. To avoid this, 68 | // use WebPEncode() and set WebPConfig::exact to 1. 69 | WEBP_EXTERN size_t WebPEncodeLosslessRGB(const uint8_t* rgb, 70 | int width, int height, int stride, 71 | uint8_t** output); 72 | WEBP_EXTERN size_t WebPEncodeLosslessBGR(const uint8_t* bgr, 73 | int width, int height, int stride, 74 | uint8_t** output); 75 | WEBP_EXTERN size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, 76 | int width, int height, int stride, 77 | uint8_t** output); 78 | WEBP_EXTERN size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, 79 | int width, int height, int stride, 80 | uint8_t** output); 81 | 82 | // Releases memory returned by the WebPEncode*() functions above. 83 | WEBP_EXTERN void WebPFree(void* ptr); 84 | 85 | //------------------------------------------------------------------------------ 86 | // Coding parameters 87 | 88 | // Image characteristics hint for the underlying encoder. 89 | typedef enum WebPImageHint { 90 | WEBP_HINT_DEFAULT = 0, // default preset. 91 | WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot 92 | WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting 93 | WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc). 94 | WEBP_HINT_LAST 95 | } WebPImageHint; 96 | 97 | // Compression parameters. 98 | struct WebPConfig { 99 | int lossless; // Lossless encoding (0=lossy(default), 1=lossless). 100 | float quality; // between 0 and 100. For lossy, 0 gives the smallest 101 | // size and 100 the largest. For lossless, this 102 | // parameter is the amount of effort put into the 103 | // compression: 0 is the fastest but gives larger 104 | // files compared to the slowest, but best, 100. 105 | int method; // quality/speed trade-off (0=fast, 6=slower-better) 106 | 107 | WebPImageHint image_hint; // Hint for image type (lossless only for now). 108 | 109 | int target_size; // if non-zero, set the desired target size in bytes. 110 | // Takes precedence over the 'compression' parameter. 111 | float target_PSNR; // if non-zero, specifies the minimal distortion to 112 | // try to achieve. Takes precedence over target_size. 113 | int segments; // maximum number of segments to use, in [1..4] 114 | int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum. 115 | int filter_strength; // range: [0 = off .. 100 = strongest] 116 | int filter_sharpness; // range: [0 = off .. 7 = least sharp] 117 | int filter_type; // filtering type: 0 = simple, 1 = strong (only used 118 | // if filter_strength > 0 or autofilter > 0) 119 | int autofilter; // Auto adjust filter's strength [0 = off, 1 = on] 120 | int alpha_compression; // Algorithm for encoding the alpha plane (0 = none, 121 | // 1 = compressed with WebP lossless). Default is 1. 122 | int alpha_filtering; // Predictive filtering method for alpha plane. 123 | // 0: none, 1: fast, 2: best. Default if 1. 124 | int alpha_quality; // Between 0 (smallest size) and 100 (lossless). 125 | // Default is 100. 126 | int pass; // number of entropy-analysis passes (in [1..10]). 127 | 128 | int show_compressed; // if true, export the compressed picture back. 129 | // In-loop filtering is not applied. 130 | int preprocessing; // preprocessing filter: 131 | // 0=none, 1=segment-smooth, 2=pseudo-random dithering 132 | int partitions; // log2(number of token partitions) in [0..3]. Default 133 | // is set to 0 for easier progressive decoding. 134 | int partition_limit; // quality degradation allowed to fit the 512k limit 135 | // on prediction modes coding (0: no degradation, 136 | // 100: maximum possible degradation). 137 | int emulate_jpeg_size; // If true, compression parameters will be remapped 138 | // to better match the expected output size from 139 | // JPEG compression. Generally, the output size will 140 | // be similar but the degradation will be lower. 141 | int thread_level; // If non-zero, try and use multi-threaded encoding. 142 | int low_memory; // If set, reduce memory usage (but increase CPU use). 143 | 144 | int near_lossless; // Near lossless encoding [0 = max loss .. 100 = off 145 | // (default)]. 146 | int exact; // if non-zero, preserve the exact RGB values under 147 | // transparent area. Otherwise, discard this invisible 148 | // RGB information for better compression. The default 149 | // value is 0. 150 | 151 | int use_delta_palette; // reserved for future lossless feature 152 | int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion 153 | 154 | uint32_t pad[2]; // padding for later use 155 | }; 156 | 157 | // Enumerate some predefined settings for WebPConfig, depending on the type 158 | // of source picture. These presets are used when calling WebPConfigPreset(). 159 | typedef enum WebPPreset { 160 | WEBP_PRESET_DEFAULT = 0, // default preset. 161 | WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot 162 | WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting 163 | WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details 164 | WEBP_PRESET_ICON, // small-sized colorful images 165 | WEBP_PRESET_TEXT // text-like 166 | } WebPPreset; 167 | 168 | // Internal, version-checked, entry point 169 | WEBP_EXTERN int WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int); 170 | 171 | // Should always be called, to initialize a fresh WebPConfig structure before 172 | // modification. Returns false in case of version mismatch. WebPConfigInit() 173 | // must have succeeded before using the 'config' object. 174 | // Note that the default values are lossless=0 and quality=75. 175 | static WEBP_INLINE int WebPConfigInit(WebPConfig* config) { 176 | return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f, 177 | WEBP_ENCODER_ABI_VERSION); 178 | } 179 | 180 | // This function will initialize the configuration according to a predefined 181 | // set of parameters (referred to by 'preset') and a given quality factor. 182 | // This function can be called as a replacement to WebPConfigInit(). Will 183 | // return false in case of error. 184 | static WEBP_INLINE int WebPConfigPreset(WebPConfig* config, 185 | WebPPreset preset, float quality) { 186 | return WebPConfigInitInternal(config, preset, quality, 187 | WEBP_ENCODER_ABI_VERSION); 188 | } 189 | 190 | // Activate the lossless compression mode with the desired efficiency level 191 | // between 0 (fastest, lowest compression) and 9 (slower, best compression). 192 | // A good default level is '6', providing a fair tradeoff between compression 193 | // speed and final compressed size. 194 | // This function will overwrite several fields from config: 'method', 'quality' 195 | // and 'lossless'. Returns false in case of parameter error. 196 | WEBP_EXTERN int WebPConfigLosslessPreset(WebPConfig* config, int level); 197 | 198 | // Returns true if 'config' is non-NULL and all configuration parameters are 199 | // within their valid ranges. 200 | WEBP_EXTERN int WebPValidateConfig(const WebPConfig* config); 201 | 202 | //------------------------------------------------------------------------------ 203 | // Input / Output 204 | // Structure for storing auxiliary statistics. 205 | 206 | struct WebPAuxStats { 207 | int coded_size; // final size 208 | 209 | float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha 210 | int block_count[3]; // number of intra4/intra16/skipped macroblocks 211 | int header_bytes[2]; // approximate number of bytes spent for header 212 | // and mode-partition #0 213 | int residual_bytes[3][4]; // approximate number of bytes spent for 214 | // DC/AC/uv coefficients for each (0..3) segments. 215 | int segment_size[4]; // number of macroblocks in each segments 216 | int segment_quant[4]; // quantizer values for each segments 217 | int segment_level[4]; // filtering strength for each segments [0..63] 218 | 219 | int alpha_data_size; // size of the transparency data 220 | int layer_data_size; // size of the enhancement layer data 221 | 222 | // lossless encoder statistics 223 | uint32_t lossless_features; // bit0:predictor bit1:cross-color transform 224 | // bit2:subtract-green bit3:color indexing 225 | int histogram_bits; // number of precision bits of histogram 226 | int transform_bits; // precision bits for transform 227 | int cache_bits; // number of bits for color cache lookup 228 | int palette_size; // number of color in palette, if used 229 | int lossless_size; // final lossless size 230 | int lossless_hdr_size; // lossless header (transform, huffman etc) size 231 | int lossless_data_size; // lossless image data size 232 | 233 | uint32_t pad[2]; // padding for later use 234 | }; 235 | 236 | // Signature for output function. Should return true if writing was successful. 237 | // data/data_size is the segment of data to write, and 'picture' is for 238 | // reference (and so one can make use of picture->custom_ptr). 239 | typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size, 240 | const WebPPicture* picture); 241 | 242 | // WebPMemoryWrite: a special WebPWriterFunction that writes to memory using 243 | // the following WebPMemoryWriter object (to be set as a custom_ptr). 244 | struct WebPMemoryWriter { 245 | uint8_t* mem; // final buffer (of size 'max_size', larger than 'size'). 246 | size_t size; // final size 247 | size_t max_size; // total capacity 248 | uint32_t pad[1]; // padding for later use 249 | }; 250 | 251 | // The following must be called first before any use. 252 | WEBP_EXTERN void WebPMemoryWriterInit(WebPMemoryWriter* writer); 253 | 254 | // The following must be called to deallocate writer->mem memory. The 'writer' 255 | // object itself is not deallocated. 256 | WEBP_EXTERN void WebPMemoryWriterClear(WebPMemoryWriter* writer); 257 | // The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon 258 | // completion, writer.mem and writer.size will hold the coded data. 259 | // writer.mem must be freed by calling WebPMemoryWriterClear. 260 | WEBP_EXTERN int WebPMemoryWrite(const uint8_t* data, size_t data_size, 261 | const WebPPicture* picture); 262 | 263 | // Progress hook, called from time to time to report progress. It can return 264 | // false to request an abort of the encoding process, or true otherwise if 265 | // everything is OK. 266 | typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture); 267 | 268 | // Color spaces. 269 | typedef enum WebPEncCSP { 270 | // chroma sampling 271 | WEBP_YUV420 = 0, // 4:2:0 272 | WEBP_YUV420A = 4, // alpha channel variant 273 | WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors 274 | WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present 275 | } WebPEncCSP; 276 | 277 | // Encoding error conditions. 278 | typedef enum WebPEncodingError { 279 | VP8_ENC_OK = 0, 280 | VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects 281 | VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits 282 | VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL 283 | VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid 284 | VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height 285 | VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k 286 | VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M 287 | VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes 288 | VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G 289 | VP8_ENC_ERROR_USER_ABORT, // abort request by user 290 | VP8_ENC_ERROR_LAST // list terminator. always last. 291 | } WebPEncodingError; 292 | 293 | // maximum width/height allowed (inclusive), in pixels 294 | #define WEBP_MAX_DIMENSION 16383 295 | 296 | // Main exchange structure (input samples, output bytes, statistics) 297 | struct WebPPicture { 298 | // INPUT 299 | ////////////// 300 | // Main flag for encoder selecting between ARGB or YUV input. 301 | // It is recommended to use ARGB input (*argb, argb_stride) for lossless 302 | // compression, and YUV input (*y, *u, *v, etc.) for lossy compression 303 | // since these are the respective native colorspace for these formats. 304 | int use_argb; 305 | 306 | // YUV input (mostly used for input to lossy compression) 307 | WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr). 308 | int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION) 309 | uint8_t *y, *u, *v; // pointers to luma/chroma planes. 310 | int y_stride, uv_stride; // luma/chroma strides. 311 | uint8_t* a; // pointer to the alpha plane 312 | int a_stride; // stride of the alpha plane 313 | uint32_t pad1[2]; // padding for later use 314 | 315 | // ARGB input (mostly used for input to lossless compression) 316 | uint32_t* argb; // Pointer to argb (32 bit) plane. 317 | int argb_stride; // This is stride in pixels units, not bytes. 318 | uint32_t pad2[3]; // padding for later use 319 | 320 | // OUTPUT 321 | /////////////// 322 | // Byte-emission hook, to store compressed bytes as they are ready. 323 | WebPWriterFunction writer; // can be NULL 324 | void* custom_ptr; // can be used by the writer. 325 | 326 | // map for extra information (only for lossy compression mode) 327 | int extra_info_type; // 1: intra type, 2: segment, 3: quant 328 | // 4: intra-16 prediction mode, 329 | // 5: chroma prediction mode, 330 | // 6: bit cost, 7: distortion 331 | uint8_t* extra_info; // if not NULL, points to an array of size 332 | // ((width + 15) / 16) * ((height + 15) / 16) that 333 | // will be filled with a macroblock map, depending 334 | // on extra_info_type. 335 | 336 | // STATS AND REPORTS 337 | /////////////////////////// 338 | // Pointer to side statistics (updated only if not NULL) 339 | WebPAuxStats* stats; 340 | 341 | // Error code for the latest error encountered during encoding 342 | WebPEncodingError error_code; 343 | 344 | // If not NULL, report progress during encoding. 345 | WebPProgressHook progress_hook; 346 | 347 | void* user_data; // this field is free to be set to any value and 348 | // used during callbacks (like progress-report e.g.). 349 | 350 | uint32_t pad3[3]; // padding for later use 351 | 352 | // Unused for now 353 | uint8_t *pad4, *pad5; 354 | uint32_t pad6[8]; // padding for later use 355 | 356 | // PRIVATE FIELDS 357 | //////////////////// 358 | void* memory_; // row chunk of memory for yuva planes 359 | void* memory_argb_; // and for argb too. 360 | void* pad7[2]; // padding for later use 361 | }; 362 | 363 | // Internal, version-checked, entry point 364 | WEBP_EXTERN int WebPPictureInitInternal(WebPPicture*, int); 365 | 366 | // Should always be called, to initialize the structure. Returns false in case 367 | // of version mismatch. WebPPictureInit() must have succeeded before using the 368 | // 'picture' object. 369 | // Note that, by default, use_argb is false and colorspace is WEBP_YUV420. 370 | static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) { 371 | return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION); 372 | } 373 | 374 | //------------------------------------------------------------------------------ 375 | // WebPPicture utils 376 | 377 | // Convenience allocation / deallocation based on picture->width/height: 378 | // Allocate y/u/v buffers as per colorspace/width/height specification. 379 | // Note! This function will free the previous buffer if needed. 380 | // Returns false in case of memory error. 381 | WEBP_EXTERN int WebPPictureAlloc(WebPPicture* picture); 382 | 383 | // Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*(). 384 | // Note that this function does _not_ free the memory used by the 'picture' 385 | // object itself. 386 | // Besides memory (which is reclaimed) all other fields of 'picture' are 387 | // preserved. 388 | WEBP_EXTERN void WebPPictureFree(WebPPicture* picture); 389 | 390 | // Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst 391 | // will fully own the copied pixels (this is not a view). The 'dst' picture need 392 | // not be initialized as its content is overwritten. 393 | // Returns false in case of memory allocation error. 394 | WEBP_EXTERN int WebPPictureCopy(const WebPPicture* src, WebPPicture* dst); 395 | 396 | // Compute the single distortion for packed planes of samples. 397 | // 'src' will be compared to 'ref', and the raw distortion stored into 398 | // '*distortion'. The refined metric (log(MSE), log(1 - ssim),...' will be 399 | // stored in '*result'. 400 | // 'x_step' is the horizontal stride (in bytes) between samples. 401 | // 'src/ref_stride' is the byte distance between rows. 402 | // Returns false in case of error (bad parameter, memory allocation error, ...). 403 | WEBP_EXTERN int WebPPlaneDistortion(const uint8_t* src, size_t src_stride, 404 | const uint8_t* ref, size_t ref_stride, 405 | int width, int height, 406 | size_t x_step, 407 | int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM 408 | float* distortion, float* result); 409 | 410 | // Compute PSNR, SSIM or LSIM distortion metric between two pictures. Results 411 | // are in dB, stored in result[] in the B/G/R/A/All order. The distortion is 412 | // always performed using ARGB samples. Hence if the input is YUV(A), the 413 | // picture will be internally converted to ARGB (just for the measurement). 414 | // Warning: this function is rather CPU-intensive. 415 | WEBP_EXTERN int WebPPictureDistortion( 416 | const WebPPicture* src, const WebPPicture* ref, 417 | int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM 418 | float result[5]); 419 | 420 | // self-crops a picture to the rectangle defined by top/left/width/height. 421 | // Returns false in case of memory allocation error, or if the rectangle is 422 | // outside of the source picture. 423 | // The rectangle for the view is defined by the top-left corner pixel 424 | // coordinates (left, top) as well as its width and height. This rectangle 425 | // must be fully be comprised inside the 'src' source picture. If the source 426 | // picture uses the YUV420 colorspace, the top and left coordinates will be 427 | // snapped to even values. 428 | WEBP_EXTERN int WebPPictureCrop(WebPPicture* picture, 429 | int left, int top, int width, int height); 430 | 431 | // Extracts a view from 'src' picture into 'dst'. The rectangle for the view 432 | // is defined by the top-left corner pixel coordinates (left, top) as well 433 | // as its width and height. This rectangle must be fully be comprised inside 434 | // the 'src' source picture. If the source picture uses the YUV420 colorspace, 435 | // the top and left coordinates will be snapped to even values. 436 | // Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed 437 | // ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so, 438 | // the original dimension will be lost). Picture 'dst' need not be initialized 439 | // with WebPPictureInit() if it is different from 'src', since its content will 440 | // be overwritten. 441 | // Returns false in case of memory allocation error or invalid parameters. 442 | WEBP_EXTERN int WebPPictureView(const WebPPicture* src, 443 | int left, int top, int width, int height, 444 | WebPPicture* dst); 445 | 446 | // Returns true if the 'picture' is actually a view and therefore does 447 | // not own the memory for pixels. 448 | WEBP_EXTERN int WebPPictureIsView(const WebPPicture* picture); 449 | 450 | // Rescale a picture to new dimension width x height. 451 | // If either 'width' or 'height' (but not both) is 0 the corresponding 452 | // dimension will be calculated preserving the aspect ratio. 453 | // No gamma correction is applied. 454 | // Returns false in case of error (invalid parameter or insufficient memory). 455 | WEBP_EXTERN int WebPPictureRescale(WebPPicture* pic, int width, int height); 456 | 457 | // Colorspace conversion function to import RGB samples. 458 | // Previous buffer will be free'd, if any. 459 | // *rgb buffer should have a size of at least height * rgb_stride. 460 | // Returns false in case of memory error. 461 | WEBP_EXTERN int WebPPictureImportRGB( 462 | WebPPicture* picture, const uint8_t* rgb, int rgb_stride); 463 | // Same, but for RGBA buffer. 464 | WEBP_EXTERN int WebPPictureImportRGBA( 465 | WebPPicture* picture, const uint8_t* rgba, int rgba_stride); 466 | // Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format 467 | // input buffer ignoring the alpha channel. Avoids needing to copy the data 468 | // to a temporary 24-bit RGB buffer to import the RGB only. 469 | WEBP_EXTERN int WebPPictureImportRGBX( 470 | WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride); 471 | 472 | // Variants of the above, but taking BGR(A|X) input. 473 | WEBP_EXTERN int WebPPictureImportBGR( 474 | WebPPicture* picture, const uint8_t* bgr, int bgr_stride); 475 | WEBP_EXTERN int WebPPictureImportBGRA( 476 | WebPPicture* picture, const uint8_t* bgra, int bgra_stride); 477 | WEBP_EXTERN int WebPPictureImportBGRX( 478 | WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride); 479 | 480 | // Converts picture->argb data to the YUV420A format. The 'colorspace' 481 | // parameter is deprecated and should be equal to WEBP_YUV420. 482 | // Upon return, picture->use_argb is set to false. The presence of real 483 | // non-opaque transparent values is detected, and 'colorspace' will be 484 | // adjusted accordingly. Note that this method is lossy. 485 | // Returns false in case of error. 486 | WEBP_EXTERN int WebPPictureARGBToYUVA(WebPPicture* picture, 487 | WebPEncCSP /*colorspace = WEBP_YUV420*/); 488 | 489 | // Same as WebPPictureARGBToYUVA(), but the conversion is done using 490 | // pseudo-random dithering with a strength 'dithering' between 491 | // 0.0 (no dithering) and 1.0 (maximum dithering). This is useful 492 | // for photographic picture. 493 | WEBP_EXTERN int WebPPictureARGBToYUVADithered( 494 | WebPPicture* picture, WebPEncCSP colorspace, float dithering); 495 | 496 | // Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion. 497 | // Downsampling is handled with extra care in case of color clipping. This 498 | // method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better 499 | // and sharper YUV representation. 500 | // Returns false in case of error. 501 | WEBP_EXTERN int WebPPictureSharpARGBToYUVA(WebPPicture* picture); 502 | // kept for backward compatibility: 503 | WEBP_EXTERN int WebPPictureSmartARGBToYUVA(WebPPicture* picture); 504 | 505 | // Converts picture->yuv to picture->argb and sets picture->use_argb to true. 506 | // The input format must be YUV_420 or YUV_420A. The conversion from YUV420 to 507 | // ARGB incurs a small loss too. 508 | // Note that the use of this colorspace is discouraged if one has access to the 509 | // raw ARGB samples, since using YUV420 is comparatively lossy. 510 | // Returns false in case of error. 511 | WEBP_EXTERN int WebPPictureYUVAToARGB(WebPPicture* picture); 512 | 513 | // Helper function: given a width x height plane of RGBA or YUV(A) samples 514 | // clean-up or smoothen the YUV or RGB samples under fully transparent area, 515 | // to help compressibility (no guarantee, though). 516 | WEBP_EXTERN void WebPCleanupTransparentArea(WebPPicture* picture); 517 | 518 | // Scan the picture 'picture' for the presence of non fully opaque alpha values. 519 | // Returns true in such case. Otherwise returns false (indicating that the 520 | // alpha plane can be ignored altogether e.g.). 521 | WEBP_EXTERN int WebPPictureHasTransparency(const WebPPicture* picture); 522 | 523 | // Remove the transparency information (if present) by blending the color with 524 | // the background color 'background_rgb' (specified as 24bit RGB triplet). 525 | // After this call, all alpha values are reset to 0xff. 526 | WEBP_EXTERN void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb); 527 | 528 | //------------------------------------------------------------------------------ 529 | // Main call 530 | 531 | // Main encoding call, after config and picture have been initialized. 532 | // 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION), 533 | // and the 'config' object must be a valid one. 534 | // Returns false in case of error, true otherwise. 535 | // In case of error, picture->error_code is updated accordingly. 536 | // 'picture' can hold the source samples in both YUV(A) or ARGB input, depending 537 | // on the value of 'picture->use_argb'. It is highly recommended to use 538 | // the former for lossy encoding, and the latter for lossless encoding 539 | // (when config.lossless is true). Automatic conversion from one format to 540 | // another is provided but they both incur some loss. 541 | WEBP_EXTERN int WebPEncode(const WebPConfig* config, WebPPicture* picture); 542 | 543 | //------------------------------------------------------------------------------ 544 | 545 | #ifdef __cplusplus 546 | } // extern "C" 547 | #endif 548 | 549 | #endif // WEBP_WEBP_ENCODE_H_ 550 | -------------------------------------------------------------------------------- /WebP.framework/Headers/types.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Common types 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_WEBP_TYPES_H_ 15 | #define WEBP_WEBP_TYPES_H_ 16 | 17 | #include // for size_t 18 | 19 | #ifndef _MSC_VER 20 | #include 21 | #if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \ 22 | (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) 23 | #define WEBP_INLINE inline 24 | #else 25 | #define WEBP_INLINE 26 | #endif 27 | #else 28 | typedef signed char int8_t; 29 | typedef unsigned char uint8_t; 30 | typedef signed short int16_t; 31 | typedef unsigned short uint16_t; 32 | typedef signed int int32_t; 33 | typedef unsigned int uint32_t; 34 | typedef unsigned long long int uint64_t; 35 | typedef long long int int64_t; 36 | #define WEBP_INLINE __forceinline 37 | #endif /* _MSC_VER */ 38 | 39 | #ifndef WEBP_EXTERN 40 | // This explicitly marks library functions and allows for changing the 41 | // signature for e.g., Windows DLL builds. 42 | # if defined(__GNUC__) && __GNUC__ >= 4 43 | # define WEBP_EXTERN extern __attribute__ ((visibility ("default"))) 44 | # else 45 | # define WEBP_EXTERN extern 46 | # endif /* __GNUC__ >= 4 */ 47 | #endif /* WEBP_EXTERN */ 48 | 49 | // Macro to check ABI compatibility (same major revision number) 50 | #define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8)) 51 | 52 | #endif // WEBP_WEBP_TYPES_H_ 53 | -------------------------------------------------------------------------------- /WebP.framework/WebP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattt/WebPImageSerialization/a77a48e87c54c626ad16b8e60acc7f3bab40ab55/WebP.framework/WebP -------------------------------------------------------------------------------- /WebPImageSerialization.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'WebPImageSerialization' 3 | s.version = '0.2.1' 4 | s.license = 'MIT' 5 | s.summary = 'Encodes and decodes between UIImage and WebP image data.' 6 | s.homepage = 'https://github.com/mattt/WebPImageSerialization' 7 | s.social_media_url = 'https://twitter.com/mattt' 8 | s.authors = { 'Mattt' => 'mattt@me.com' } 9 | s.source = { git: 'https://github.com/mattt/WebPImageSerialization.git', tag: s.version } 10 | s.source_files = 'WebPImageSerialization', 'WebP.framework' 11 | s.preserve_paths = 'WebPImageSerialization', 'WebP.framework' 12 | s.vendored_frameworks = 'WebP.framework' 13 | s.requires_arc = true 14 | 15 | s.ios.frameworks = 'CoreGraphics' 16 | s.ios.deployment_target = '5.0' 17 | end 18 | -------------------------------------------------------------------------------- /WebPImageSerialization.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 9 | 10 | 12 | 13 | 14 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /WebPImageSerialization.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WebPImageSerialization/WebPImageSerialization.h: -------------------------------------------------------------------------------- 1 | // WebPImageSerialization.h 2 | // 3 | // Copyright (c) 2014 – 2020 Mattt (http://mat.tt/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | @import Foundation; 24 | 25 | #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 26 | 27 | @import UIKit; 28 | 29 | NS_ASSUME_NONNULL_BEGIN 30 | 31 | /// Decoding WebP Image Data 32 | 33 | /** 34 | 35 | */ 36 | extern __attribute__((overloadable)) UIImage * _Nullable UIImageWithWebPData(NSData *data); 37 | 38 | /** 39 | 40 | */ 41 | extern __attribute__((overloadable)) UIImage * _Nullable UIImageWithWebPData(NSData *data, CGFloat scale, NSError * __autoreleasing *error); 42 | 43 | /** 44 | 45 | */ 46 | extern __attribute__((overloadable)) UIImage * _Nullable UIImageWithWebPData(NSData *data, CGFloat scale, CGSize fittingSize, NSError * __autoreleasing *error); 47 | 48 | /// Encoding WebP Image Data 49 | 50 | /** 51 | 52 | */ 53 | typedef NS_ENUM(NSUInteger, WebPImagePreset) { 54 | WebPImageDefaultPreset, 55 | WebPImagePicturePreset, 56 | WebPImagePhotoPreset, 57 | WebPImageDrawingPreset, 58 | WebPImageIconPreset, 59 | WebPImageTextPreset, 60 | }; 61 | 62 | /** 63 | 64 | */ 65 | extern __attribute__((overloadable)) NSData * _Nullable UIImageWebPRepresentation(UIImage *image); 66 | 67 | /** 68 | 69 | */ 70 | extern __attribute__((overloadable)) NSData * _Nullable UIImageWebPRepresentation(UIImage *image, WebPImagePreset preset, CGFloat quality, NSError * __autoreleasing *error); 71 | 72 | #pragma mark - 73 | 74 | /** 75 | 76 | */ 77 | @interface WebPImageSerialization : NSObject 78 | 79 | /// Creating a WebPImage 80 | 81 | /** 82 | 83 | */ 84 | + (UIImage * _Nullable)imageWithData:(NSData *)data 85 | error:(NSError * __autoreleasing *)error; 86 | 87 | /** 88 | 89 | */ 90 | + (UIImage * _Nullable)imageWithData:(NSData *)data 91 | scale:(CGFloat)scale 92 | error:(NSError * __autoreleasing *)error; 93 | 94 | /** 95 | 96 | */ 97 | + (UIImage * _Nullable)imageWithData:(NSData *)data 98 | scale:(CGFloat)scale 99 | fittingSize:(CGSize)fittingSize 100 | error:(NSError * __autoreleasing *)error; 101 | 102 | /// Creating WebPImage Data 103 | 104 | /** 105 | 106 | */ 107 | + (NSData * _Nullable)dataWithImage:(UIImage *)image 108 | error:(NSError * __autoreleasing *)error; 109 | 110 | /** 111 | 112 | */ 113 | + (NSData * _Nullable)dataWithImage:(UIImage *)image 114 | preset:(WebPImagePreset)preset 115 | quality:(CGFloat)quality 116 | error:(NSError * __autoreleasing *)error; 117 | 118 | @end 119 | 120 | /** 121 | 122 | */ 123 | extern NSString * const WebPImageErrorDomain; 124 | 125 | NS_ASSUME_NONNULL_END 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /WebPImageSerialization/WebPImageSerialization.m: -------------------------------------------------------------------------------- 1 | // WebPImageSerialization.m 2 | // 3 | // Copyright (c) 2014 – 2020 Mattt (http://mat.tt/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "WebPImageSerialization.h" 24 | 25 | #pragma clang diagnostic push 26 | #pragma clang diagnostic ignored "-Weverything" 27 | #import 28 | #import 29 | #pragma clang diagnostic pop 30 | 31 | NS_ASSUME_NONNULL_BEGIN 32 | 33 | NSString * const WebPImageErrorDomain = @"com.webp.image.error"; 34 | 35 | #pragma clang diagnostic push 36 | #pragma clang diagnostic ignored "-Wunused-macros" 37 | #define WebPImageDefaultPreset WEBP_PRESET_DEFAULT 38 | #define WebPImagePicturePreset WEBP_PRESET_PICTURE 39 | #define WebPImagePhotoPreset WEBP_PRESET_PHOTO 40 | #define WebPImageDrawingPreset WEBP_PRESET_DRAWING 41 | #define WebPImageIconPreset WEBP_PRESET_ICON 42 | #define WebPImageTextPreset WEBP_PRESET_TEXT 43 | #pragma clang diagnostic pop 44 | 45 | static inline BOOL WebPDataIsValid(NSData *data) { 46 | if (data && data.length > 0) { 47 | int width = 0, height = 0; 48 | return WebPGetInfo(data.bytes, data.length, &width, &height) && width > 0 && height > 0; 49 | } 50 | 51 | return NO; 52 | } 53 | 54 | static NSString * WebPLocalizedDescriptionForVP8StatusCode(VP8StatusCode status) { 55 | switch (status) { 56 | case VP8_STATUS_OUT_OF_MEMORY: 57 | return NSLocalizedStringFromTable(@"VP8 out of memory", @"WebPImageSerialization", nil); 58 | case VP8_STATUS_INVALID_PARAM: 59 | return NSLocalizedStringFromTable(@"VP8 invalid parameter", @"WebPImageSerialization", nil); 60 | case VP8_STATUS_BITSTREAM_ERROR: 61 | return NSLocalizedStringFromTable(@"VP8 bitstream error", @"WebPImageSerialization", nil); 62 | case VP8_STATUS_UNSUPPORTED_FEATURE: 63 | return NSLocalizedStringFromTable(@"VP8 unsupported feature", @"WebPImageSerialization", nil); 64 | case VP8_STATUS_SUSPENDED: 65 | return NSLocalizedStringFromTable(@"VP8 suspended", @"WebPImageSerialization", nil); 66 | case VP8_STATUS_USER_ABORT: 67 | return NSLocalizedStringFromTable(@"VP8 user Abort", @"WebPImageSerialization", nil); 68 | case VP8_STATUS_NOT_ENOUGH_DATA: 69 | return NSLocalizedStringFromTable(@"VP8 not enough data", @"WebPImageSerialization", nil); 70 | case VP8_STATUS_OK: 71 | return NSLocalizedStringFromTable(@"VP8 unknown error", @"WebPImageSerialization", nil); 72 | } 73 | } 74 | 75 | static void WebPFreeImageData(void *info, const void *data, size_t size) { 76 | #pragma clang diagnostic push 77 | #pragma clang diagnostic ignored "-Wcast-qual" 78 | free((void *)data); 79 | #pragma clang diagnostic pop 80 | } 81 | 82 | __attribute__((overloadable)) UIImage * _Nullable UIImageWithWebPData(NSData *data) { 83 | return UIImageWithWebPData(data, 1.0, nil); 84 | } 85 | 86 | __attribute__((overloadable)) UIImage * _Nullable UIImageWithWebPData(NSData *data, CGFloat scale, NSError * __autoreleasing *error) { 87 | return UIImageWithWebPData(data, scale, CGSizeZero, error); 88 | } 89 | 90 | __attribute__((overloadable)) UIImage * _Nullable UIImageWithWebPData(NSData *data, CGFloat scale, CGSize fittingSize, NSError * __autoreleasing *error) { 91 | NSDictionary *userInfo = nil; 92 | { 93 | WebPDecoderConfig config; 94 | int width = 0, height = 0; 95 | 96 | if(!WebPGetInfo([data bytes], [data length], &width, &height)) { 97 | userInfo = @{ 98 | NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"WebP header formatting error", @"WebPImageSerialization", nil) 99 | }; 100 | goto _error; 101 | } 102 | 103 | if(!WebPInitDecoderConfig(&config)) { 104 | userInfo = @{ 105 | NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"WebP image failed to initialize structure", @"WebPImageSerialization", nil) 106 | }; 107 | goto _error; 108 | } 109 | 110 | config.output.colorspace = MODE_RGBA; 111 | config.options.bypass_filtering = true; 112 | config.options.no_fancy_upsampling = true; 113 | config.options.use_threads = true; 114 | 115 | if (fittingSize.width > 0.0 && fittingSize.height > 0.0) { 116 | #pragma clang diagnostic push 117 | #pragma clang diagnostic ignored "-Wgnu" 118 | CGFloat sizeScale = MIN(fittingSize.width / (CGFloat)width, fittingSize.height / (CGFloat)height); 119 | #pragma clang diagnostic pop 120 | 121 | config.options.use_scaling = true; 122 | config.options.scaled_width = (int)(width * sizeScale); 123 | config.options.scaled_height = (int)(height * sizeScale); 124 | } 125 | 126 | VP8StatusCode status = WebPDecode([data bytes], [data length], &config); 127 | if (status != VP8_STATUS_OK) { 128 | userInfo = @{ 129 | NSLocalizedDescriptionKey: WebPLocalizedDescriptionForVP8StatusCode(status) 130 | }; 131 | goto _error; 132 | } 133 | 134 | size_t bitsPerComponent = 8; 135 | size_t bitsPerPixel = 32; 136 | size_t bytesPerRow = 4; 137 | CGDataProviderRef provider = CGDataProviderCreateWithData(&config, config.output.u.RGBA.rgba, config.output.width * config.output.height * bytesPerRow, WebPFreeImageData); 138 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 139 | CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaLast; 140 | CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 141 | BOOL shouldInterpolate = YES; 142 | 143 | CGImageRef imageRef = CGImageCreate((size_t)config.output.width, (size_t)config.output.height, bitsPerComponent, bitsPerPixel, bytesPerRow * config.output.width, colorSpace, bitmapInfo, provider, NULL, shouldInterpolate, renderingIntent); 144 | 145 | UIImage *image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp]; 146 | 147 | CGImageRelease(imageRef); 148 | CGColorSpaceRelease(colorSpace); 149 | CGDataProviderRelease(provider); 150 | 151 | return image; 152 | } 153 | _error: { 154 | if (error) { 155 | *error = [[NSError alloc] initWithDomain:WebPImageErrorDomain code:-1 userInfo:userInfo]; 156 | } 157 | 158 | return nil; 159 | } 160 | } 161 | 162 | extern __attribute__((overloadable)) NSData * _Nullable UIImageWebPRepresentation(UIImage *image) { 163 | return UIImageWebPRepresentation(image, (WebPImagePreset)WebPImageDefaultPreset, 75.0, nil); 164 | } 165 | 166 | __attribute__((overloadable)) NSData * _Nullable UIImageWebPRepresentation(UIImage *image, WebPImagePreset preset, CGFloat quality, NSError * __autoreleasing *error) { 167 | NSCParameterAssert(quality >= 0.0 && quality <= 100.0); 168 | 169 | CGImageRef imageRef = image.CGImage; 170 | NSDictionary *userInfo = nil; 171 | { 172 | CGDataProviderRef dataProvider = CGImageGetDataProvider(imageRef); 173 | CFDataRef dataRef = CGDataProviderCopyData(dataProvider); 174 | 175 | WebPConfig config; 176 | WebPPicture picture; 177 | 178 | if (!WebPConfigPreset(&config, (WebPPreset)preset, quality)) { 179 | userInfo = @{NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"WebP image configuration preset initialization failed.", @"WebPImageSerialization", nil)}; 180 | goto _error; 181 | } 182 | 183 | if (!WebPValidateConfig(&config)) { 184 | userInfo = @{NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"WebP image invalid configuration.", @"WebPImageSerialization", nil)}; 185 | goto _error; 186 | } 187 | 188 | if (!WebPPictureInit(&picture)) { 189 | userInfo = @{NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"WebP image failed to initialize structure.", @"WebPImageSerialization", nil)}; 190 | goto _error; 191 | } 192 | 193 | size_t bytesPerRow = CGImageGetBytesPerRow(imageRef); 194 | size_t width = CGImageGetWidth(imageRef); 195 | size_t height = CGImageGetHeight(imageRef); 196 | 197 | picture.colorspace = WEBP_YUV420; 198 | picture.width = (int)width; 199 | picture.height = (int)height; 200 | 201 | WebPPictureImportRGBA(&picture, (const uint8_t *)CFDataGetBytePtr(dataRef), (int)bytesPerRow); 202 | WebPPictureARGBToYUVA(&picture, picture.colorspace); 203 | WebPCleanupTransparentArea(&picture); 204 | 205 | CFRelease(dataRef); 206 | 207 | WebPMemoryWriter writer; 208 | WebPMemoryWriterInit(&writer); 209 | picture.writer = WebPMemoryWrite; 210 | picture.custom_ptr = &writer; 211 | WebPEncode(&config, &picture); 212 | 213 | NSData *data = [NSData dataWithBytes:writer.mem length:writer.size]; 214 | 215 | WebPPictureFree(&picture); 216 | 217 | return data; 218 | } 219 | _error: { 220 | if (error) { 221 | *error = [[NSError alloc] initWithDomain:WebPImageErrorDomain code:-1 userInfo:userInfo]; 222 | } 223 | 224 | CFRelease(imageRef); 225 | 226 | return nil; 227 | } 228 | } 229 | 230 | @implementation WebPImageSerialization 231 | 232 | + (UIImage * _Nullable)imageWithData:(NSData *)data 233 | error:(NSError * __autoreleasing *)error 234 | { 235 | return [self imageWithData:data scale:1.0 error:error]; 236 | } 237 | 238 | + (UIImage * _Nullable)imageWithData:(NSData *)data 239 | scale:(CGFloat)scale 240 | error:(NSError * __autoreleasing *)error 241 | { 242 | return UIImageWithWebPData(data, scale, error); 243 | } 244 | 245 | + (UIImage * _Nullable)imageWithData:(NSData *)data 246 | scale:(CGFloat)scale 247 | fittingSize:(CGSize)fittingSize 248 | error:(NSError * __autoreleasing *)error 249 | { 250 | return UIImageWithWebPData(data, scale, fittingSize, error); 251 | } 252 | 253 | #pragma mark - 254 | 255 | + (NSData * _Nullable)dataWithImage:(UIImage *)image 256 | error:(NSError * __autoreleasing *)error 257 | { 258 | return [self dataWithImage:image preset:(WebPImagePreset)WebPImageDefaultPreset quality:1.0 error:error]; 259 | } 260 | 261 | + (NSData * _Nullable )dataWithImage:(UIImage *)image 262 | preset:(WebPImagePreset)preset 263 | quality:(CGFloat)quality 264 | error:(NSError * __autoreleasing *)error 265 | { 266 | return UIImageWebPRepresentation(image, preset, quality, error); 267 | } 268 | 269 | @end 270 | 271 | NS_ASSUME_NONNULL_END 272 | 273 | #pragma mark - 274 | 275 | #ifndef WEBP_NO_UIIMAGE_INITIALIZER_SWIZZLING 276 | @import ObjectiveC.runtime; 277 | 278 | static inline void webp_swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) { 279 | Method originalMethod = class_getInstanceMethod(class, originalSelector); 280 | Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); 281 | if (class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) { 282 | class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); 283 | } else { 284 | method_exchangeImplementations(originalMethod, swizzledMethod); 285 | } 286 | } 287 | 288 | @interface UIImage (_WebPImageSerialization) 289 | @end 290 | 291 | @implementation UIImage (_WebPImageSerialization) 292 | 293 | + (void)load { 294 | static dispatch_once_t onceToken; 295 | dispatch_once(&onceToken, ^{ 296 | @autoreleasepool { 297 | webp_swizzleSelector(self, @selector(initWithData:scale:), @selector(webp_initWithData:scale:)); 298 | webp_swizzleSelector(self, @selector(initWithData:), @selector(webp_initWithData:)); 299 | webp_swizzleSelector(self, @selector(initWithContentsOfFile:), @selector(webp_initWithContentsOfFile:)); 300 | webp_swizzleSelector(object_getClass((id)self), @selector(imageNamed:), @selector(webp_imageNamed:)); 301 | } 302 | }); 303 | } 304 | 305 | NS_ASSUME_NONNULL_BEGIN 306 | 307 | + (UIImage *)webp_imageNamed:(NSString *)name __attribute__((objc_method_family(new))){ 308 | CGFloat scale = [[UIScreen mainScreen] scale]; 309 | 310 | NSString *scaleSuffix = @""; 311 | if (scale >= 3) { 312 | scaleSuffix = @"@3x"; 313 | } else if (scale >= 2) { 314 | scaleSuffix = @"@2x"; 315 | } 316 | 317 | NSString * _Nullable path = nil; 318 | 319 | if (!path) { 320 | // e.g. image@2x.webp 321 | NSString *nameWithRatio = [[[name stringByDeletingPathExtension] stringByAppendingString:scaleSuffix] stringByAppendingPathExtension:[name pathExtension]]; 322 | path = [[NSBundle mainBundle] pathForResource:nameWithRatio ofType:[name pathExtension]]; 323 | } 324 | 325 | if (!path) { 326 | // e.g. image.webp 327 | path = [[NSBundle mainBundle] pathForResource:[name stringByDeletingPathExtension] ofType:[name pathExtension]]; 328 | } 329 | 330 | if (path) { 331 | NSData *data = [NSData dataWithContentsOfFile:(NSString * _Nonnull)path]; 332 | if (WebPDataIsValid(data)) { 333 | return [WebPImageSerialization imageWithData:data error:nil]; 334 | } 335 | } 336 | 337 | return [self webp_imageNamed:name]; 338 | } 339 | 340 | - (id)webp_initWithData:(NSData *)data __attribute__((objc_method_family(init))) { 341 | if (WebPDataIsValid(data)) { 342 | return UIImageWithWebPData(data, 1.0, nil); 343 | } 344 | 345 | return [self webp_initWithData:data]; 346 | } 347 | 348 | - (id)webp_initWithData:(NSData *)data 349 | scale:(CGFloat)scale __attribute__((objc_method_family(init))) 350 | { 351 | if (WebPDataIsValid(data)) { 352 | return UIImageWithWebPData(data, scale, nil); 353 | } 354 | 355 | return [self webp_initWithData:data scale:scale]; 356 | } 357 | 358 | - (id)webp_initWithContentsOfFile:(NSString *)path __attribute__((objc_method_family(init))) { 359 | NSData *data = [NSData dataWithContentsOfFile:path]; 360 | if (WebPDataIsValid(data)) { 361 | return UIImageWithWebPData(data, 1.0, nil); 362 | } 363 | 364 | return [self webp_initWithContentsOfFile:path]; 365 | } 366 | 367 | @end 368 | 369 | NS_ASSUME_NONNULL_END 370 | 371 | #endif 372 | --------------------------------------------------------------------------------