├── .gitignore ├── README.md ├── WebpQuickLook.tar.gz ├── WebpQuickLook.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── WebpQuickLook.xccheckout │ └── xcuserdata │ │ └── emin.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── emin.xcuserdatad │ ├── xcdebugger │ └── Breakpoints.xcbkptlist │ └── xcschemes │ ├── WebpQuickLook.xcscheme │ └── xcschememanagement.plist ├── WebpQuickLook ├── GeneratePreviewForURL.c ├── GenerateThumbnailForURL.c ├── WebpQuickLook-Info.plist ├── WebpQuickLook-Prefix.pch ├── en.lproj │ └── InfoPlist.strings ├── libwebp.a ├── libwebpdemux.a ├── main.c └── webp │ ├── .DS_Store │ ├── decode.h │ ├── demux.h │ ├── encode.h │ ├── format_constants.h │ ├── mux.h │ ├── mux_types.h │ └── types.h ├── install-all.sh ├── install.sh └── screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.xcuserdatad 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Quick Look Plugin for WebP Files 2 | ================================ 3 | 4 | ### What is this? 5 | 6 | Quick Look is a part of Mac OS X. It provides you a quick way 7 | to look at your content without open it in an application. 8 | In Finder, choose a file or folder and push the space button, then QuickLook 9 | mechanism quickly show the preview of the content. And also it is responsible 10 | for the thumbnail creation. 11 | 12 | Most people know this mechanism. By default, OS X doesn't provide preview and 13 | thumbnail for all file types. [WebP](https://developers.google.com/speed/webp/) is Google's new image format and OS X 14 | doesn't recognize the .webp files. This plugin will give you an ability to 15 | see previews and thumbnails of WebP images. 16 | 17 | ### How does it look like? 18 | 19 | Just like an ordinary image file: 20 | 21 | ![quicklook webp](https://raw.github.com/emin/WebPQuickLook/master/screenshot.png 'WebP') 22 | 23 | 24 | ### How can I install it? 25 | 26 | This is simple for those of you who are familiar with terminal 27 | (console). 28 | 29 | Open your terminal app (or whatever you use) and copy paste the below 30 | command: 31 | 32 | curl -L https://raw.github.com/emin/WebPQuickLook/master/install.sh | sh 33 | 34 | 35 | That's it. You just installed it. Enjoy your WebP files just like ordinary 36 | image files. 37 | 38 | 39 | If you use [homebrew](https://brew.sh/) you can do: 40 | 41 | brew install --cask WebPQuickLook 42 | 43 | ### The other users can't use it. What can I do? 44 | 45 | You can do it same operations by logining their account. But if you want 46 | to install for all users, that's simple and similar the above commands. 47 | Just use this installation script, 48 | 49 | curl -L https://raw.github.com/emin/WebPQuickLook/master/install-all.sh | sh 50 | 51 | 52 | This requires an administrator account, if you are not administrator you 53 | can't install it. It'll ask for password then you're done. 54 | 55 | 56 | -------------------------------------------------------------------------------- /WebpQuickLook.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emin/WebPQuickLook/4221460f0cf9b1e850586f72ced301340adc70a4/WebpQuickLook.tar.gz -------------------------------------------------------------------------------- /WebpQuickLook.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 237E363517A257280033EC8D /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 237E363417A257280033EC8D /* QuickLook.framework */; }; 11 | 237E363717A257280033EC8D /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 237E363617A257280033EC8D /* ApplicationServices.framework */; }; 12 | 237E363917A257280033EC8D /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 237E363817A257280033EC8D /* CoreServices.framework */; }; 13 | 237E363B17A257280033EC8D /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 237E363A17A257280033EC8D /* CoreFoundation.framework */; }; 14 | 237E364117A257280033EC8D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 237E363F17A257280033EC8D /* InfoPlist.strings */; }; 15 | 237E364317A257280033EC8D /* GenerateThumbnailForURL.c in Sources */ = {isa = PBXBuildFile; fileRef = 237E364217A257280033EC8D /* GenerateThumbnailForURL.c */; }; 16 | 237E364517A257280033EC8D /* GeneratePreviewForURL.c in Sources */ = {isa = PBXBuildFile; fileRef = 237E364417A257280033EC8D /* GeneratePreviewForURL.c */; }; 17 | 237E364717A257280033EC8D /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 237E364617A257280033EC8D /* main.c */; }; 18 | 23866DAD18A838C40009A7A8 /* decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 23866DA718A838C40009A7A8 /* decode.h */; }; 19 | 23866DAE18A838C40009A7A8 /* demux.h in Headers */ = {isa = PBXBuildFile; fileRef = 23866DA818A838C40009A7A8 /* demux.h */; }; 20 | 23866DAF18A838C40009A7A8 /* encode.h in Headers */ = {isa = PBXBuildFile; fileRef = 23866DA918A838C40009A7A8 /* encode.h */; }; 21 | 23866DB018A838C40009A7A8 /* mux.h in Headers */ = {isa = PBXBuildFile; fileRef = 23866DAA18A838C40009A7A8 /* mux.h */; }; 22 | 23866DB118A838C40009A7A8 /* mux_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 23866DAB18A838C40009A7A8 /* mux_types.h */; }; 23 | 23866DB218A838C40009A7A8 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 23866DAC18A838C40009A7A8 /* types.h */; }; 24 | EF468D502046047400DCBA9A /* libwebp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EF468D4C2046046200DCBA9A /* libwebp.a */; }; 25 | EF468D512046047700DCBA9A /* libwebpdemux.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EF468D4D2046046200DCBA9A /* libwebpdemux.a */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 237E363117A257280033EC8D /* WebpQuickLook.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WebpQuickLook.qlgenerator; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 237E363417A257280033EC8D /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = System/Library/Frameworks/QuickLook.framework; sourceTree = SDKROOT; }; 31 | 237E363617A257280033EC8D /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; }; 32 | 237E363817A257280033EC8D /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; 33 | 237E363A17A257280033EC8D /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 34 | 237E363E17A257280033EC8D /* WebpQuickLook-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "WebpQuickLook-Info.plist"; sourceTree = ""; }; 35 | 237E364017A257280033EC8D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 36 | 237E364217A257280033EC8D /* GenerateThumbnailForURL.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = GenerateThumbnailForURL.c; sourceTree = ""; }; 37 | 237E364417A257280033EC8D /* GeneratePreviewForURL.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = GeneratePreviewForURL.c; sourceTree = ""; }; 38 | 237E364617A257280033EC8D /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 39 | 237E364817A257280033EC8D /* WebpQuickLook-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WebpQuickLook-Prefix.pch"; sourceTree = ""; }; 40 | 237E365D17A28C310033EC8D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 41 | 23866DA718A838C40009A7A8 /* decode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decode.h; sourceTree = ""; }; 42 | 23866DA818A838C40009A7A8 /* demux.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = demux.h; sourceTree = ""; }; 43 | 23866DA918A838C40009A7A8 /* encode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = encode.h; sourceTree = ""; }; 44 | 23866DAA18A838C40009A7A8 /* mux.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mux.h; sourceTree = ""; }; 45 | 23866DAB18A838C40009A7A8 /* mux_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mux_types.h; sourceTree = ""; }; 46 | 23866DAC18A838C40009A7A8 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = ""; }; 47 | EF468D4C2046046200DCBA9A /* libwebp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libwebp.a; sourceTree = ""; }; 48 | EF468D4D2046046200DCBA9A /* libwebpdemux.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libwebpdemux.a; sourceTree = ""; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | 237E362C17A257280033EC8D /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | EF468D512046047700DCBA9A /* libwebpdemux.a in Frameworks */, 57 | EF468D502046047400DCBA9A /* libwebp.a in Frameworks */, 58 | 237E363517A257280033EC8D /* QuickLook.framework in Frameworks */, 59 | 237E363717A257280033EC8D /* ApplicationServices.framework in Frameworks */, 60 | 237E363917A257280033EC8D /* CoreServices.framework in Frameworks */, 61 | 237E363B17A257280033EC8D /* CoreFoundation.framework in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | 237E362617A257280033EC8D = { 69 | isa = PBXGroup; 70 | children = ( 71 | 237E365D17A28C310033EC8D /* Cocoa.framework */, 72 | 237E363C17A257280033EC8D /* WebpQuickLook */, 73 | 237E363317A257280033EC8D /* Frameworks */, 74 | 237E363217A257280033EC8D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 237E363217A257280033EC8D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 237E363117A257280033EC8D /* WebpQuickLook.qlgenerator */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 237E363317A257280033EC8D /* Frameworks */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 237E363417A257280033EC8D /* QuickLook.framework */, 90 | 237E363617A257280033EC8D /* ApplicationServices.framework */, 91 | 237E363817A257280033EC8D /* CoreServices.framework */, 92 | 237E363A17A257280033EC8D /* CoreFoundation.framework */, 93 | ); 94 | name = Frameworks; 95 | sourceTree = ""; 96 | }; 97 | 237E363C17A257280033EC8D /* WebpQuickLook */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | EF468D4C2046046200DCBA9A /* libwebp.a */, 101 | EF468D4D2046046200DCBA9A /* libwebpdemux.a */, 102 | 23866DA618A838C40009A7A8 /* webp */, 103 | 237E364217A257280033EC8D /* GenerateThumbnailForURL.c */, 104 | 237E364417A257280033EC8D /* GeneratePreviewForURL.c */, 105 | 237E364617A257280033EC8D /* main.c */, 106 | 237E363D17A257280033EC8D /* Supporting Files */, 107 | ); 108 | path = WebpQuickLook; 109 | sourceTree = ""; 110 | }; 111 | 237E363D17A257280033EC8D /* Supporting Files */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 237E363E17A257280033EC8D /* WebpQuickLook-Info.plist */, 115 | 237E363F17A257280033EC8D /* InfoPlist.strings */, 116 | 237E364817A257280033EC8D /* WebpQuickLook-Prefix.pch */, 117 | ); 118 | name = "Supporting Files"; 119 | sourceTree = ""; 120 | }; 121 | 23866DA618A838C40009A7A8 /* webp */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 23866DA718A838C40009A7A8 /* decode.h */, 125 | 23866DA818A838C40009A7A8 /* demux.h */, 126 | 23866DA918A838C40009A7A8 /* encode.h */, 127 | 23866DAA18A838C40009A7A8 /* mux.h */, 128 | 23866DAB18A838C40009A7A8 /* mux_types.h */, 129 | 23866DAC18A838C40009A7A8 /* types.h */, 130 | ); 131 | path = webp; 132 | sourceTree = ""; 133 | }; 134 | /* End PBXGroup section */ 135 | 136 | /* Begin PBXHeadersBuildPhase section */ 137 | 237E362D17A257280033EC8D /* Headers */ = { 138 | isa = PBXHeadersBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | 23866DB218A838C40009A7A8 /* types.h in Headers */, 142 | 23866DAE18A838C40009A7A8 /* demux.h in Headers */, 143 | 23866DB018A838C40009A7A8 /* mux.h in Headers */, 144 | 23866DB118A838C40009A7A8 /* mux_types.h in Headers */, 145 | 23866DAD18A838C40009A7A8 /* decode.h in Headers */, 146 | 23866DAF18A838C40009A7A8 /* encode.h in Headers */, 147 | ); 148 | runOnlyForDeploymentPostprocessing = 0; 149 | }; 150 | /* End PBXHeadersBuildPhase section */ 151 | 152 | /* Begin PBXNativeTarget section */ 153 | 237E363017A257280033EC8D /* WebpQuickLook */ = { 154 | isa = PBXNativeTarget; 155 | buildConfigurationList = 237E364B17A257280033EC8D /* Build configuration list for PBXNativeTarget "WebpQuickLook" */; 156 | buildPhases = ( 157 | 237E362B17A257280033EC8D /* Sources */, 158 | 237E362C17A257280033EC8D /* Frameworks */, 159 | 237E362D17A257280033EC8D /* Headers */, 160 | 237E362E17A257280033EC8D /* Resources */, 161 | 237E362F17A257280033EC8D /* Rez */, 162 | ); 163 | buildRules = ( 164 | ); 165 | dependencies = ( 166 | ); 167 | name = WebpQuickLook; 168 | productName = WebpQuickLook; 169 | productReference = 237E363117A257280033EC8D /* WebpQuickLook.qlgenerator */; 170 | productType = "com.apple.product-type.bundle"; 171 | }; 172 | /* End PBXNativeTarget section */ 173 | 174 | /* Begin PBXProject section */ 175 | 237E362717A257280033EC8D /* Project object */ = { 176 | isa = PBXProject; 177 | attributes = { 178 | LastUpgradeCheck = 0910; 179 | ORGANIZATIONNAME = "Emin Kura"; 180 | }; 181 | buildConfigurationList = 237E362A17A257280033EC8D /* Build configuration list for PBXProject "WebpQuickLook" */; 182 | compatibilityVersion = "Xcode 3.2"; 183 | developmentRegion = English; 184 | hasScannedForEncodings = 0; 185 | knownRegions = ( 186 | en, 187 | ); 188 | mainGroup = 237E362617A257280033EC8D; 189 | productRefGroup = 237E363217A257280033EC8D /* Products */; 190 | projectDirPath = ""; 191 | projectRoot = ""; 192 | targets = ( 193 | 237E363017A257280033EC8D /* WebpQuickLook */, 194 | ); 195 | }; 196 | /* End PBXProject section */ 197 | 198 | /* Begin PBXResourcesBuildPhase section */ 199 | 237E362E17A257280033EC8D /* Resources */ = { 200 | isa = PBXResourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 237E364117A257280033EC8D /* InfoPlist.strings in Resources */, 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXResourcesBuildPhase section */ 208 | 209 | /* Begin PBXRezBuildPhase section */ 210 | 237E362F17A257280033EC8D /* Rez */ = { 211 | isa = PBXRezBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | }; 217 | /* End PBXRezBuildPhase section */ 218 | 219 | /* Begin PBXSourcesBuildPhase section */ 220 | 237E362B17A257280033EC8D /* Sources */ = { 221 | isa = PBXSourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | 237E364317A257280033EC8D /* GenerateThumbnailForURL.c in Sources */, 225 | 237E364517A257280033EC8D /* GeneratePreviewForURL.c in Sources */, 226 | 237E364717A257280033EC8D /* main.c in Sources */, 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | /* End PBXSourcesBuildPhase section */ 231 | 232 | /* Begin PBXVariantGroup section */ 233 | 237E363F17A257280033EC8D /* InfoPlist.strings */ = { 234 | isa = PBXVariantGroup; 235 | children = ( 236 | 237E364017A257280033EC8D /* en */, 237 | ); 238 | name = InfoPlist.strings; 239 | sourceTree = ""; 240 | }; 241 | /* End PBXVariantGroup section */ 242 | 243 | /* Begin XCBuildConfiguration section */ 244 | 237E364917A257280033EC8D /* Debug */ = { 245 | isa = XCBuildConfiguration; 246 | buildSettings = { 247 | ALWAYS_SEARCH_USER_PATHS = NO; 248 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 249 | CLANG_CXX_LIBRARY = "libc++"; 250 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 251 | CLANG_WARN_BOOL_CONVERSION = YES; 252 | CLANG_WARN_COMMA = YES; 253 | CLANG_WARN_CONSTANT_CONVERSION = YES; 254 | CLANG_WARN_EMPTY_BODY = YES; 255 | CLANG_WARN_ENUM_CONVERSION = YES; 256 | CLANG_WARN_INFINITE_RECURSION = YES; 257 | CLANG_WARN_INT_CONVERSION = YES; 258 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 259 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 260 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 261 | CLANG_WARN_STRICT_PROTOTYPES = YES; 262 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 263 | CLANG_WARN_UNREACHABLE_CODE = YES; 264 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 265 | COPY_PHASE_STRIP = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | ENABLE_TESTABILITY = YES; 268 | GCC_C_LANGUAGE_STANDARD = gnu99; 269 | GCC_DYNAMIC_NO_PIC = NO; 270 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 271 | GCC_NO_COMMON_BLOCKS = YES; 272 | GCC_OPTIMIZATION_LEVEL = 0; 273 | GCC_PREPROCESSOR_DEFINITIONS = ( 274 | "DEBUG=1", 275 | "$(inherited)", 276 | ); 277 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 278 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 279 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 280 | GCC_WARN_UNDECLARED_SELECTOR = YES; 281 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 282 | GCC_WARN_UNUSED_FUNCTION = YES; 283 | GCC_WARN_UNUSED_VARIABLE = YES; 284 | MACOSX_DEPLOYMENT_TARGET = 10.9; 285 | ONLY_ACTIVE_ARCH = YES; 286 | SDKROOT = macosx; 287 | }; 288 | name = Debug; 289 | }; 290 | 237E364A17A257280033EC8D /* Release */ = { 291 | isa = XCBuildConfiguration; 292 | buildSettings = { 293 | ALWAYS_SEARCH_USER_PATHS = NO; 294 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 295 | CLANG_CXX_LIBRARY = "libc++"; 296 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 297 | CLANG_WARN_BOOL_CONVERSION = YES; 298 | CLANG_WARN_COMMA = YES; 299 | CLANG_WARN_CONSTANT_CONVERSION = YES; 300 | CLANG_WARN_EMPTY_BODY = YES; 301 | CLANG_WARN_ENUM_CONVERSION = YES; 302 | CLANG_WARN_INFINITE_RECURSION = YES; 303 | CLANG_WARN_INT_CONVERSION = YES; 304 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 305 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 306 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 307 | CLANG_WARN_STRICT_PROTOTYPES = YES; 308 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 309 | CLANG_WARN_UNREACHABLE_CODE = YES; 310 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 311 | COPY_PHASE_STRIP = YES; 312 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 313 | ENABLE_STRICT_OBJC_MSGSEND = YES; 314 | GCC_C_LANGUAGE_STANDARD = gnu99; 315 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 316 | GCC_NO_COMMON_BLOCKS = YES; 317 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 318 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 319 | GCC_WARN_UNDECLARED_SELECTOR = YES; 320 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 321 | GCC_WARN_UNUSED_FUNCTION = YES; 322 | GCC_WARN_UNUSED_VARIABLE = YES; 323 | MACOSX_DEPLOYMENT_TARGET = 10.9; 324 | ONLY_ACTIVE_ARCH = YES; 325 | SDKROOT = macosx; 326 | }; 327 | name = Release; 328 | }; 329 | 237E364C17A257280033EC8D /* Debug */ = { 330 | isa = XCBuildConfiguration; 331 | buildSettings = { 332 | COMBINE_HIDPI_IMAGES = YES; 333 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 334 | GCC_PREFIX_HEADER = "WebpQuickLook/WebpQuickLook-Prefix.pch"; 335 | INFOPLIST_FILE = "WebpQuickLook/WebpQuickLook-Info.plist"; 336 | INSTALL_PATH = /Library/QuickLook; 337 | LIBRARY_SEARCH_PATHS = ( 338 | "$(inherited)", 339 | "$(SRCROOT)/WebpQuickLook", 340 | "$(PROJECT_DIR)/WebpQuickLook", 341 | ); 342 | ONLY_ACTIVE_ARCH = NO; 343 | PRODUCT_BUNDLE_IDENTIFIER = "com.eminkura.${PRODUCT_NAME:rfc1034identifier}"; 344 | PRODUCT_NAME = "$(TARGET_NAME)"; 345 | WRAPPER_EXTENSION = qlgenerator; 346 | }; 347 | name = Debug; 348 | }; 349 | 237E364D17A257280033EC8D /* Release */ = { 350 | isa = XCBuildConfiguration; 351 | buildSettings = { 352 | COMBINE_HIDPI_IMAGES = YES; 353 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 354 | GCC_PREFIX_HEADER = "WebpQuickLook/WebpQuickLook-Prefix.pch"; 355 | INFOPLIST_FILE = "WebpQuickLook/WebpQuickLook-Info.plist"; 356 | INSTALL_PATH = /Library/QuickLook; 357 | LIBRARY_SEARCH_PATHS = ( 358 | "$(inherited)", 359 | "$(SRCROOT)/WebpQuickLook", 360 | "$(PROJECT_DIR)/WebpQuickLook", 361 | ); 362 | ONLY_ACTIVE_ARCH = YES; 363 | PRODUCT_BUNDLE_IDENTIFIER = "com.eminkura.${PRODUCT_NAME:rfc1034identifier}"; 364 | PRODUCT_NAME = "$(TARGET_NAME)"; 365 | WRAPPER_EXTENSION = qlgenerator; 366 | }; 367 | name = Release; 368 | }; 369 | /* End XCBuildConfiguration section */ 370 | 371 | /* Begin XCConfigurationList section */ 372 | 237E362A17A257280033EC8D /* Build configuration list for PBXProject "WebpQuickLook" */ = { 373 | isa = XCConfigurationList; 374 | buildConfigurations = ( 375 | 237E364917A257280033EC8D /* Debug */, 376 | 237E364A17A257280033EC8D /* Release */, 377 | ); 378 | defaultConfigurationIsVisible = 0; 379 | defaultConfigurationName = Release; 380 | }; 381 | 237E364B17A257280033EC8D /* Build configuration list for PBXNativeTarget "WebpQuickLook" */ = { 382 | isa = XCConfigurationList; 383 | buildConfigurations = ( 384 | 237E364C17A257280033EC8D /* Debug */, 385 | 237E364D17A257280033EC8D /* Release */, 386 | ); 387 | defaultConfigurationIsVisible = 0; 388 | defaultConfigurationName = Release; 389 | }; 390 | /* End XCConfigurationList section */ 391 | }; 392 | rootObject = 237E362717A257280033EC8D /* Project object */; 393 | } 394 | -------------------------------------------------------------------------------- /WebpQuickLook.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WebpQuickLook.xcodeproj/project.xcworkspace/xcshareddata/WebpQuickLook.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | A0F5937C-CE11-46D0-85E6-65804267D499 9 | IDESourceControlProjectName 10 | WebpQuickLook 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | EE99BFB2-76CF-4AC6-BB75-506D5A9BABAA 14 | https://github.com/emin/WebPQuickLook 15 | 16 | IDESourceControlProjectPath 17 | WebpQuickLook.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | EE99BFB2-76CF-4AC6-BB75-506D5A9BABAA 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/emin/WebPQuickLook 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | EE99BFB2-76CF-4AC6-BB75-506D5A9BABAA 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | EE99BFB2-76CF-4AC6-BB75-506D5A9BABAA 36 | IDESourceControlWCCName 37 | WebPQuickLook 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WebpQuickLook.xcodeproj/project.xcworkspace/xcuserdata/emin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emin/WebPQuickLook/4221460f0cf9b1e850586f72ced301340adc70a4/WebpQuickLook.xcodeproj/project.xcworkspace/xcuserdata/emin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WebpQuickLook.xcodeproj/xcuserdata/emin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WebpQuickLook.xcodeproj/xcuserdata/emin.xcuserdatad/xcschemes/WebpQuickLook.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 42 | 43 | 44 | 45 | 51 | 52 | 54 | 55 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /WebpQuickLook.xcodeproj/xcuserdata/emin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WebpQuickLook.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 237E363017A257280033EC8D 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /WebpQuickLook/GeneratePreviewForURL.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "webp/decode.h" 5 | #include "webp/demux.h" 6 | 7 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); 8 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); 9 | 10 | /* ----------------------------------------------------------------------------- 11 | Generate a preview for file 12 | 13 | This function's job is to create preview for designated file 14 | ----------------------------------------------------------------------------- */ 15 | 16 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) 17 | { 18 | // To complete your generator please implement the function GeneratePreviewForURL in GeneratePreviewForURL.c 19 | 20 | // get posix path and convert it to C string then we can get data from file with simple C operation. 21 | // Sometimes CoreFoundation is pain in the ass. I don't want to use it to get byte data 22 | 23 | CFStringRef path = CFURLCopyPath(url); 24 | path = CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, path, CFSTR("")); 25 | CFIndex length = CFStringGetLength(path); 26 | CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); 27 | 28 | char* c_path = (char*)malloc(maxSize); 29 | CFStringGetCString(path, c_path, maxSize, kCFStringEncodingUTF8); 30 | 31 | // let 's do the reading and decoding with libwebp 32 | 33 | FILE *file = fopen(c_path, "r"); 34 | 35 | if (file != NULL) { 36 | 37 | fseek(file, 0, SEEK_END); 38 | long int size = ftell(file); 39 | fseek(file, 0, SEEK_SET); 40 | 41 | const uint8_t data[size]; 42 | 43 | fread((void*)&data[0], sizeof(uint8_t), size, file); 44 | 45 | fclose(file); 46 | 47 | WebPBitstreamFeatures features; 48 | 49 | WebPGetFeatures(&data[0], size, &features); 50 | 51 | 52 | int width = 0; 53 | int height = 0; 54 | 55 | uint8_t *rgbData = NULL; 56 | 57 | int samples = 3; 58 | CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; 59 | 60 | if ( features.has_animation ) { 61 | 62 | // it has animation we need to use demux 63 | WebPData webpData; 64 | webpData.bytes = data; 65 | webpData.size = size; 66 | 67 | WebPDemuxer *demux = WebPDemux(&webpData); 68 | 69 | // uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); 70 | // uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); 71 | // // ... (Get information about the features present in the WebP file). 72 | // uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); 73 | 74 | 75 | // ... (Iterate over all frames). 76 | WebPIterator iter; 77 | if (WebPDemuxGetFrame(demux, 1, &iter)) { 78 | 79 | do { 80 | 81 | if( features.has_alpha ){ 82 | 83 | rgbData = WebPDecodeRGBA(iter.fragment.bytes, size, &width, &height); 84 | samples = 4; 85 | bitmapInfo = kCGImageAlphaLast; 86 | 87 | }else{ 88 | rgbData = WebPDecodeRGB(iter.fragment.bytes, size, &width, &height); 89 | samples = 3; 90 | bitmapInfo = kCGBitmapByteOrderDefault; 91 | } 92 | 93 | // for now break it, it only show first frame 94 | break; 95 | 96 | // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), 97 | // ... and get other frame properties like width, height, offsets etc. 98 | // ... see 'struct WebPIterator' below for more info). 99 | } while (WebPDemuxNextFrame(&iter)); 100 | WebPDemuxReleaseIterator(&iter); 101 | } 102 | 103 | } 104 | else 105 | { 106 | 107 | 108 | if( features.has_alpha ){ 109 | rgbData = WebPDecodeRGBA(&data[0], size, &width, &height); 110 | samples = 4; 111 | bitmapInfo = kCGImageAlphaLast; 112 | }else{ 113 | rgbData = WebPDecodeRGB(&data[0], size, &width, &height); 114 | } 115 | 116 | } 117 | 118 | CGSize imageSize = CGSizeMake(width, height); 119 | 120 | CGContextRef ctx = QLPreviewRequestCreateContext(preview, imageSize, true, options); 121 | 122 | CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, rgbData, width*height*samples, NULL); 123 | 124 | CGImageRef image = CGImageCreate(width, height, 8, 8 * samples, width * samples, CGColorSpaceCreateDeviceRGB(), bitmapInfo, provider, NULL, false, kCGRenderingIntentDefault); 125 | 126 | 127 | CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), image); 128 | 129 | CGContextFlush(ctx); 130 | 131 | QLPreviewRequestFlushContext(preview, ctx); 132 | CFRelease(ctx); 133 | 134 | free(rgbData); 135 | } 136 | 137 | 138 | return noErr; 139 | } 140 | 141 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview) 142 | { 143 | // Implement only if supported 144 | } 145 | -------------------------------------------------------------------------------- /WebpQuickLook/GenerateThumbnailForURL.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "webp/decode.h" 5 | #include "webp/demux.h" 6 | 7 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); 8 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail); 9 | 10 | /* ----------------------------------------------------------------------------- 11 | Generate a thumbnail for file 12 | 13 | This function's job is to create thumbnail for designated file as fast as possible 14 | ----------------------------------------------------------------------------- */ 15 | 16 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize) 17 | { 18 | 19 | // get posix path and convert it to C string then we can get data from file with simple C operation. 20 | // Sometimes CoreFoundation is pain in the ass. I don't want to use it to get byte data 21 | 22 | CFStringRef path = CFURLCopyPath(url); 23 | path = CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, path, CFSTR("")); 24 | CFIndex length = CFStringGetLength(path); 25 | CFIndex max = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); 26 | 27 | char* c_path = (char*)malloc(max); 28 | CFStringGetCString(path, c_path, max, kCFStringEncodingUTF8); 29 | 30 | // let 's do the reading and decoding with libwebp 31 | 32 | FILE *file = fopen(c_path, "r"); 33 | 34 | if (file != NULL) { 35 | 36 | fseek(file, 0, SEEK_END); 37 | long int size = ftell(file); 38 | fseek(file, 0, SEEK_SET); 39 | 40 | const uint8_t data[size]; 41 | 42 | fread((void*)(&data[0]), sizeof(uint8_t), size, file); 43 | 44 | fclose(file); 45 | 46 | 47 | WebPBitstreamFeatures features; 48 | WebPGetFeatures(&data[0], size, &features); 49 | 50 | int width = (int)maxSize.width; 51 | int height = (int)maxSize.height; 52 | int image_w, image_h; 53 | 54 | WebPGetInfo(&data[0], size, &image_w, &image_h); 55 | 56 | 57 | if( image_w > image_h ) 58 | { 59 | width = (int)maxSize.width; 60 | height = (int)( width * image_h/image_w ); 61 | } 62 | else 63 | { 64 | height = (int)maxSize.height; 65 | width = (int)( height * image_w/image_h ); 66 | } 67 | 68 | // for scaled size decoding 69 | 70 | WebPDecoderConfig config; 71 | WebPInitDecoderConfig(&config); 72 | 73 | config.options.use_scaling = 1; 74 | config.options.scaled_width = width; 75 | config.options.scaled_height = height; 76 | 77 | config.output.colorspace = MODE_RGBA; 78 | 79 | 80 | 81 | 82 | if ( features.has_animation ) { 83 | 84 | // it has animation we need to use demux 85 | WebPData webpData; 86 | webpData.bytes = data; 87 | webpData.size = size; 88 | 89 | WebPDemuxer *demux = WebPDemux(&webpData); 90 | 91 | // uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); 92 | // uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); 93 | // // ... (Get information about the features present in the WebP file). 94 | // uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); 95 | 96 | 97 | // ... (Iterate over all frames). 98 | WebPIterator iter; 99 | if (WebPDemuxGetFrame(demux, 1, &iter)) { 100 | 101 | do { 102 | 103 | WebPDecode(iter.fragment.bytes, size, &config); 104 | 105 | // for now break it, it only show first frame 106 | break; 107 | 108 | // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), 109 | // ... and get other frame properties like width, height, offsets etc. 110 | // ... see 'struct WebPIterator' below for more info). 111 | } while (WebPDemuxNextFrame(&iter)); 112 | WebPDemuxReleaseIterator(&iter); 113 | } 114 | 115 | } 116 | else 117 | { 118 | WebPDecode(&data[0], size, &config); 119 | } 120 | 121 | 122 | 123 | uint8_t *rgbData = config.output.u.RGBA.rgba; //WebPDecodeRGB( &data[0], size, &width, &height); 124 | 125 | CGSize imageSize = CGSizeMake(width, height); 126 | 127 | CGContextRef ctx = QLThumbnailRequestCreateContext(thumbnail, imageSize, true, options); 128 | 129 | CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, rgbData, width*height*4, NULL); 130 | 131 | CGImageRef image = CGImageCreate(width, height, 8, 32, width * 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaLast, provider, NULL, false, kCGRenderingIntentDefault); 132 | 133 | 134 | CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), image); 135 | 136 | CGContextFlush(ctx); 137 | 138 | QLThumbnailRequestFlushContext(thumbnail, ctx); 139 | CFRelease(ctx); 140 | 141 | WebPFreeDecBuffer(&config.output); 142 | } 143 | 144 | 145 | 146 | 147 | 148 | 149 | return noErr; 150 | } 151 | 152 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail) 153 | { 154 | // Implement only if supported 155 | } 156 | -------------------------------------------------------------------------------- /WebpQuickLook/WebpQuickLook-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeRole 11 | QLGenerator 12 | LSItemContentTypes 13 | 14 | public.webp 15 | 16 | 17 | 18 | CFBundleExecutable 19 | ${EXECUTABLE_NAME} 20 | CFBundleIconFile 21 | 22 | CFBundleIdentifier 23 | $(PRODUCT_BUNDLE_IDENTIFIER) 24 | CFBundleInfoDictionaryVersion 25 | 6.0 26 | CFBundleName 27 | ${PRODUCT_NAME} 28 | CFBundleShortVersionString 29 | 1 30 | CFBundleVersion 31 | 1.0 32 | CFPlugInDynamicRegisterFunction 33 | 34 | CFPlugInDynamicRegistration 35 | NO 36 | CFPlugInFactories 37 | 38 | 232C6209-F9AB-4981-8920-76E1B3F859DB 39 | QuickLookGeneratorPluginFactory 40 | 41 | CFPlugInTypes 42 | 43 | 5E2D9680-5022-40FA-B806-43349622E5B9 44 | 45 | 232C6209-F9AB-4981-8920-76E1B3F859DB 46 | 47 | 48 | CFPlugInUnloadFunction 49 | 50 | NSHumanReadableCopyright 51 | Copyright © 2013 Emin Kura. All rights reserved. 52 | QLNeedsToBeRunInMainThread 53 | 54 | QLPreviewHeight 55 | 600 56 | QLPreviewWidth 57 | 800 58 | QLSupportsConcurrentRequests 59 | 60 | UTExportedTypeDeclarations 61 | 62 | 63 | UTTypeConformsTo 64 | 65 | public.data 66 | public.image 67 | 68 | UTTypeIdentifier 69 | public.webp 70 | UTTypeTagSpecification 71 | 72 | com.apple.ostype 73 | JPEG 74 | public.filename-extension 75 | 76 | webp 77 | 78 | public.mime-type 79 | image/webp 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /WebpQuickLook/WebpQuickLook-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'WebpQuickLook' target in the 'WebpQuickLook' project 3 | // 4 | 5 | -------------------------------------------------------------------------------- /WebpQuickLook/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /WebpQuickLook/libwebp.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emin/WebPQuickLook/4221460f0cf9b1e850586f72ced301340adc70a4/WebpQuickLook/libwebp.a -------------------------------------------------------------------------------- /WebpQuickLook/libwebpdemux.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emin/WebPQuickLook/4221460f0cf9b1e850586f72ced301340adc70a4/WebpQuickLook/libwebpdemux.a -------------------------------------------------------------------------------- /WebpQuickLook/main.c: -------------------------------------------------------------------------------- 1 | //============================================================================== 2 | // 3 | // DO NO MODIFY THE CONTENT OF THIS FILE 4 | // 5 | // This file contains the generic CFPlug-in code necessary for your generator 6 | // To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c 7 | // 8 | //============================================================================== 9 | 10 | 11 | 12 | 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | // ----------------------------------------------------------------------------- 21 | // constants 22 | // ----------------------------------------------------------------------------- 23 | 24 | // Don't modify this line 25 | #define PLUGIN_ID "232C6209-F9AB-4981-8920-76E1B3F859DB" 26 | 27 | // 28 | // Below is the generic glue code for all plug-ins. 29 | // 30 | // You should not have to modify this code aside from changing 31 | // names if you decide to change the names defined in the Info.plist 32 | // 33 | 34 | 35 | // ----------------------------------------------------------------------------- 36 | // typedefs 37 | // ----------------------------------------------------------------------------- 38 | 39 | // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c 40 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); 41 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail); 42 | 43 | // The preview generation function to be implemented in GeneratePreviewForURL.c 44 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); 45 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); 46 | 47 | // The layout for an instance of QuickLookGeneratorPlugIn 48 | typedef struct __QuickLookGeneratorPluginType 49 | { 50 | void *conduitInterface; 51 | CFUUIDRef factoryID; 52 | UInt32 refCount; 53 | } QuickLookGeneratorPluginType; 54 | 55 | // ----------------------------------------------------------------------------- 56 | // prototypes 57 | // ----------------------------------------------------------------------------- 58 | // Forward declaration for the IUnknown implementation. 59 | // 60 | 61 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID); 62 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance); 63 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); 64 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); 65 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance); 66 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance); 67 | 68 | // ----------------------------------------------------------------------------- 69 | // myInterfaceFtbl definition 70 | // ----------------------------------------------------------------------------- 71 | // The QLGeneratorInterfaceStruct function table. 72 | // 73 | static QLGeneratorInterfaceStruct myInterfaceFtbl = { 74 | NULL, 75 | QuickLookGeneratorQueryInterface, 76 | QuickLookGeneratorPluginAddRef, 77 | QuickLookGeneratorPluginRelease, 78 | NULL, 79 | NULL, 80 | NULL, 81 | NULL 82 | }; 83 | 84 | 85 | // ----------------------------------------------------------------------------- 86 | // AllocQuickLookGeneratorPluginType 87 | // ----------------------------------------------------------------------------- 88 | // Utility function that allocates a new instance. 89 | // You can do some initial setup for the generator here if you wish 90 | // like allocating globals etc... 91 | // 92 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID) 93 | { 94 | QuickLookGeneratorPluginType *theNewInstance; 95 | 96 | theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType)); 97 | memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType)); 98 | 99 | /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */ 100 | theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct)); 101 | memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct)); 102 | 103 | /* Retain and keep an open instance refcount for each factory. */ 104 | theNewInstance->factoryID = CFRetain(inFactoryID); 105 | CFPlugInAddInstanceForFactory(inFactoryID); 106 | 107 | /* This function returns the IUnknown interface so set the refCount to one. */ 108 | theNewInstance->refCount = 1; 109 | return theNewInstance; 110 | } 111 | 112 | // ----------------------------------------------------------------------------- 113 | // DeallocQuickLookGeneratorPluginType 114 | // ----------------------------------------------------------------------------- 115 | // Utility function that deallocates the instance when 116 | // the refCount goes to zero. 117 | // In the current implementation generator interfaces are never deallocated 118 | // but implement this as this might change in the future 119 | // 120 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance) 121 | { 122 | CFUUIDRef theFactoryID; 123 | 124 | theFactoryID = thisInstance->factoryID; 125 | /* Free the conduitInterface table up */ 126 | free(thisInstance->conduitInterface); 127 | 128 | /* Free the instance structure */ 129 | free(thisInstance); 130 | if (theFactoryID){ 131 | CFPlugInRemoveInstanceForFactory(theFactoryID); 132 | CFRelease(theFactoryID); 133 | } 134 | } 135 | 136 | // ----------------------------------------------------------------------------- 137 | // QuickLookGeneratorQueryInterface 138 | // ----------------------------------------------------------------------------- 139 | // Implementation of the IUnknown QueryInterface function. 140 | // 141 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) 142 | { 143 | CFUUIDRef interfaceID; 144 | 145 | interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); 146 | 147 | if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){ 148 | /* If the Right interface was requested, bump the ref count, 149 | * set the ppv parameter equal to the instance, and 150 | * return good status. 151 | */ 152 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL; 153 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration; 154 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL; 155 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration; 156 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance); 157 | *ppv = thisInstance; 158 | CFRelease(interfaceID); 159 | return S_OK; 160 | }else{ 161 | /* Requested interface unknown, bail with error. */ 162 | *ppv = NULL; 163 | CFRelease(interfaceID); 164 | return E_NOINTERFACE; 165 | } 166 | } 167 | 168 | // ----------------------------------------------------------------------------- 169 | // QuickLookGeneratorPluginAddRef 170 | // ----------------------------------------------------------------------------- 171 | // Implementation of reference counting for this type. Whenever an interface 172 | // is requested, bump the refCount for the instance. NOTE: returning the 173 | // refcount is a convention but is not required so don't rely on it. 174 | // 175 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance) 176 | { 177 | ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1; 178 | return ((QuickLookGeneratorPluginType*) thisInstance)->refCount; 179 | } 180 | 181 | // ----------------------------------------------------------------------------- 182 | // QuickLookGeneratorPluginRelease 183 | // ----------------------------------------------------------------------------- 184 | // When an interface is released, decrement the refCount. 185 | // If the refCount goes to zero, deallocate the instance. 186 | // 187 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance) 188 | { 189 | ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1; 190 | if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){ 191 | DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance ); 192 | return 0; 193 | }else{ 194 | return ((QuickLookGeneratorPluginType*) thisInstance )->refCount; 195 | } 196 | } 197 | 198 | // ----------------------------------------------------------------------------- 199 | // QuickLookGeneratorPluginFactory 200 | // ----------------------------------------------------------------------------- 201 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) 202 | { 203 | QuickLookGeneratorPluginType *result; 204 | CFUUIDRef uuid; 205 | 206 | /* If correct type is being requested, allocate an 207 | * instance of kQLGeneratorTypeID and return the IUnknown interface. 208 | */ 209 | if (CFEqual(typeID,kQLGeneratorTypeID)){ 210 | uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); 211 | result = AllocQuickLookGeneratorPluginType(uuid); 212 | CFRelease(uuid); 213 | return result; 214 | } 215 | /* If the requested type is incorrect, return NULL. */ 216 | return NULL; 217 | } 218 | 219 | -------------------------------------------------------------------------------- /WebpQuickLook/webp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emin/WebPQuickLook/4221460f0cf9b1e850586f72ced301340adc70a4/WebpQuickLook/webp/.DS_Store -------------------------------------------------------------------------------- /WebpQuickLook/webp/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 | WEBP_EXTERN(int) WebPGetInfo(const uint8_t* data, size_t data_size, 46 | int* width, int* height); 47 | 48 | // Decodes WebP images pointed to by 'data' and returns RGBA samples, along 49 | // with the dimensions in *width and *height. The ordering of samples in 50 | // memory is R, G, B, A, R, G, B, A... in scan order (endian-independent). 51 | // The returned pointer should be deleted calling WebPFree(). 52 | // Returns NULL in case of error. 53 | WEBP_EXTERN(uint8_t*) WebPDecodeRGBA(const uint8_t* data, size_t data_size, 54 | int* width, int* height); 55 | 56 | // Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data. 57 | WEBP_EXTERN(uint8_t*) WebPDecodeARGB(const uint8_t* data, size_t data_size, 58 | int* width, int* height); 59 | 60 | // Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data. 61 | WEBP_EXTERN(uint8_t*) WebPDecodeBGRA(const uint8_t* data, size_t data_size, 62 | int* width, int* height); 63 | 64 | // Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data. 65 | // If the bitstream contains transparency, it is ignored. 66 | WEBP_EXTERN(uint8_t*) WebPDecodeRGB(const uint8_t* data, size_t data_size, 67 | int* width, int* height); 68 | 69 | // Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data. 70 | WEBP_EXTERN(uint8_t*) WebPDecodeBGR(const uint8_t* data, size_t data_size, 71 | int* width, int* height); 72 | 73 | 74 | // Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer 75 | // returned is the Y samples buffer. Upon return, *u and *v will point to 76 | // the U and V chroma data. These U and V buffers need NOT be passed to 77 | // WebPFree(), unlike the returned Y luma one. The dimension of the U and V 78 | // planes are both (*width + 1) / 2 and (*height + 1)/ 2. 79 | // Upon return, the Y buffer has a stride returned as '*stride', while U and V 80 | // have a common stride returned as '*uv_stride'. 81 | // Return NULL in case of error. 82 | // (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr 83 | WEBP_EXTERN(uint8_t*) WebPDecodeYUV(const uint8_t* data, size_t data_size, 84 | int* width, int* height, 85 | uint8_t** u, uint8_t** v, 86 | int* stride, int* uv_stride); 87 | 88 | // Releases memory returned by the WebPDecode*() functions above. 89 | WEBP_EXTERN(void) WebPFree(void* ptr); 90 | 91 | // These five functions are variants of the above ones, that decode the image 92 | // directly into a pre-allocated buffer 'output_buffer'. The maximum storage 93 | // available in this buffer is indicated by 'output_buffer_size'. If this 94 | // storage is not sufficient (or an error occurred), NULL is returned. 95 | // Otherwise, output_buffer is returned, for convenience. 96 | // The parameter 'output_stride' specifies the distance (in bytes) 97 | // between scanlines. Hence, output_buffer_size is expected to be at least 98 | // output_stride x picture-height. 99 | WEBP_EXTERN(uint8_t*) WebPDecodeRGBAInto( 100 | const uint8_t* data, size_t data_size, 101 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 102 | WEBP_EXTERN(uint8_t*) WebPDecodeARGBInto( 103 | const uint8_t* data, size_t data_size, 104 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 105 | WEBP_EXTERN(uint8_t*) WebPDecodeBGRAInto( 106 | const uint8_t* data, size_t data_size, 107 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 108 | 109 | // RGB and BGR variants. Here too the transparency information, if present, 110 | // will be dropped and ignored. 111 | WEBP_EXTERN(uint8_t*) WebPDecodeRGBInto( 112 | const uint8_t* data, size_t data_size, 113 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 114 | WEBP_EXTERN(uint8_t*) WebPDecodeBGRInto( 115 | const uint8_t* data, size_t data_size, 116 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 117 | 118 | // WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly 119 | // into pre-allocated luma/chroma plane buffers. This function requires the 120 | // strides to be passed: one for the luma plane and one for each of the 121 | // chroma ones. The size of each plane buffer is passed as 'luma_size', 122 | // 'u_size' and 'v_size' respectively. 123 | // Pointer to the luma plane ('*luma') is returned or NULL if an error occurred 124 | // during decoding (or because some buffers were found to be too small). 125 | WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto( 126 | const uint8_t* data, size_t data_size, 127 | uint8_t* luma, size_t luma_size, int luma_stride, 128 | uint8_t* u, size_t u_size, int u_stride, 129 | uint8_t* v, size_t v_size, int v_stride); 130 | 131 | //------------------------------------------------------------------------------ 132 | // Output colorspaces and buffer 133 | 134 | // Colorspaces 135 | // Note: the naming describes the byte-ordering of packed samples in memory. 136 | // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,... 137 | // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels. 138 | // RGBA-4444 and RGB-565 colorspaces are represented by following byte-order: 139 | // RGBA-4444: [r3 r2 r1 r0 g3 g2 g1 g0], [b3 b2 b1 b0 a3 a2 a1 a0], ... 140 | // RGB-565: [r4 r3 r2 r1 r0 g5 g4 g3], [g2 g1 g0 b4 b3 b2 b1 b0], ... 141 | // In the case WEBP_SWAP_16BITS_CSP is defined, the bytes are swapped for 142 | // these two modes: 143 | // RGBA-4444: [b3 b2 b1 b0 a3 a2 a1 a0], [r3 r2 r1 r0 g3 g2 g1 g0], ... 144 | // RGB-565: [g2 g1 g0 b4 b3 b2 b1 b0], [r4 r3 r2 r1 r0 g5 g4 g3], ... 145 | 146 | typedef enum WEBP_CSP_MODE { 147 | MODE_RGB = 0, MODE_RGBA = 1, 148 | MODE_BGR = 2, MODE_BGRA = 3, 149 | MODE_ARGB = 4, MODE_RGBA_4444 = 5, 150 | MODE_RGB_565 = 6, 151 | // RGB-premultiplied transparent modes (alpha value is preserved) 152 | MODE_rgbA = 7, 153 | MODE_bgrA = 8, 154 | MODE_Argb = 9, 155 | MODE_rgbA_4444 = 10, 156 | // YUV modes must come after RGB ones. 157 | MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0 158 | MODE_LAST = 13 159 | } WEBP_CSP_MODE; 160 | 161 | // Some useful macros: 162 | static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) { 163 | return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb || 164 | mode == MODE_rgbA_4444); 165 | } 166 | 167 | static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) { 168 | return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB || 169 | mode == MODE_RGBA_4444 || mode == MODE_YUVA || 170 | WebPIsPremultipliedMode(mode)); 171 | } 172 | 173 | static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) { 174 | return (mode < MODE_YUV); 175 | } 176 | 177 | //------------------------------------------------------------------------------ 178 | // WebPDecBuffer: Generic structure for describing the output sample buffer. 179 | 180 | struct WebPRGBABuffer { // view as RGBA 181 | uint8_t* rgba; // pointer to RGBA samples 182 | int stride; // stride in bytes from one scanline to the next. 183 | size_t size; // total size of the *rgba buffer. 184 | }; 185 | 186 | struct WebPYUVABuffer { // view as YUVA 187 | uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples 188 | int y_stride; // luma stride 189 | int u_stride, v_stride; // chroma strides 190 | int a_stride; // alpha stride 191 | size_t y_size; // luma plane size 192 | size_t u_size, v_size; // chroma planes size 193 | size_t a_size; // alpha-plane size 194 | }; 195 | 196 | // Output buffer 197 | struct WebPDecBuffer { 198 | WEBP_CSP_MODE colorspace; // Colorspace. 199 | int width, height; // Dimensions. 200 | int is_external_memory; // If non-zero, 'internal_memory' pointer is not 201 | // used. If value is '2' or more, the external 202 | // memory is considered 'slow' and multiple 203 | // read/write will be avoided. 204 | union { 205 | WebPRGBABuffer RGBA; 206 | WebPYUVABuffer YUVA; 207 | } u; // Nameless union of buffer parameters. 208 | uint32_t pad[4]; // padding for later use 209 | 210 | uint8_t* private_memory; // Internally allocated memory (only when 211 | // is_external_memory is 0). Should not be used 212 | // externally, but accessed via the buffer union. 213 | }; 214 | 215 | // Internal, version-checked, entry point 216 | WEBP_EXTERN(int) WebPInitDecBufferInternal(WebPDecBuffer*, int); 217 | 218 | // Initialize the structure as empty. Must be called before any other use. 219 | // Returns false in case of version mismatch 220 | static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) { 221 | return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION); 222 | } 223 | 224 | // Free any memory associated with the buffer. Must always be called last. 225 | // Note: doesn't free the 'buffer' structure itself. 226 | WEBP_EXTERN(void) WebPFreeDecBuffer(WebPDecBuffer* buffer); 227 | 228 | //------------------------------------------------------------------------------ 229 | // Enumeration of the status codes 230 | 231 | typedef enum VP8StatusCode { 232 | VP8_STATUS_OK = 0, 233 | VP8_STATUS_OUT_OF_MEMORY, 234 | VP8_STATUS_INVALID_PARAM, 235 | VP8_STATUS_BITSTREAM_ERROR, 236 | VP8_STATUS_UNSUPPORTED_FEATURE, 237 | VP8_STATUS_SUSPENDED, 238 | VP8_STATUS_USER_ABORT, 239 | VP8_STATUS_NOT_ENOUGH_DATA 240 | } VP8StatusCode; 241 | 242 | //------------------------------------------------------------------------------ 243 | // Incremental decoding 244 | // 245 | // This API allows streamlined decoding of partial data. 246 | // Picture can be incrementally decoded as data become available thanks to the 247 | // WebPIDecoder object. This object can be left in a SUSPENDED state if the 248 | // picture is only partially decoded, pending additional input. 249 | // Code example: 250 | // 251 | // WebPInitDecBuffer(&output_buffer); 252 | // output_buffer.colorspace = mode; 253 | // ... 254 | // WebPIDecoder* idec = WebPINewDecoder(&output_buffer); 255 | // while (additional_data_is_available) { 256 | // // ... (get additional data in some new_data[] buffer) 257 | // status = WebPIAppend(idec, new_data, new_data_size); 258 | // if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) { 259 | // break; // an error occurred. 260 | // } 261 | // 262 | // // The above call decodes the current available buffer. 263 | // // Part of the image can now be refreshed by calling 264 | // // WebPIDecGetRGB()/WebPIDecGetYUVA() etc. 265 | // } 266 | // WebPIDelete(idec); 267 | 268 | // Creates a new incremental decoder with the supplied buffer parameter. 269 | // This output_buffer can be passed NULL, in which case a default output buffer 270 | // is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer' 271 | // is kept, which means that the lifespan of 'output_buffer' must be larger than 272 | // that of the returned WebPIDecoder object. 273 | // The supplied 'output_buffer' content MUST NOT be changed between calls to 274 | // WebPIAppend() or WebPIUpdate() unless 'output_buffer.is_external_memory' is 275 | // not set to 0. In such a case, it is allowed to modify the pointers, size and 276 | // stride of output_buffer.u.RGBA or output_buffer.u.YUVA, provided they remain 277 | // within valid bounds. 278 | // All other fields of WebPDecBuffer MUST remain constant between calls. 279 | // Returns NULL if the allocation failed. 280 | WEBP_EXTERN(WebPIDecoder*) WebPINewDecoder(WebPDecBuffer* output_buffer); 281 | 282 | // This function allocates and initializes an incremental-decoder object, which 283 | // will output the RGB/A samples specified by 'csp' into a preallocated 284 | // buffer 'output_buffer'. The size of this buffer is at least 285 | // 'output_buffer_size' and the stride (distance in bytes between two scanlines) 286 | // is specified by 'output_stride'. 287 | // Additionally, output_buffer can be passed NULL in which case the output 288 | // buffer will be allocated automatically when the decoding starts. The 289 | // colorspace 'csp' is taken into account for allocating this buffer. All other 290 | // parameters are ignored. 291 | // Returns NULL if the allocation failed, or if some parameters are invalid. 292 | WEBP_EXTERN(WebPIDecoder*) WebPINewRGB( 293 | WEBP_CSP_MODE csp, 294 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 295 | 296 | // This function allocates and initializes an incremental-decoder object, which 297 | // will output the raw luma/chroma samples into a preallocated planes if 298 | // supplied. The luma plane is specified by its pointer 'luma', its size 299 | // 'luma_size' and its stride 'luma_stride'. Similarly, the chroma-u plane 300 | // is specified by the 'u', 'u_size' and 'u_stride' parameters, and the chroma-v 301 | // plane by 'v' and 'v_size'. And same for the alpha-plane. The 'a' pointer 302 | // can be pass NULL in case one is not interested in the transparency plane. 303 | // Conversely, 'luma' can be passed NULL if no preallocated planes are supplied. 304 | // In this case, the output buffer will be automatically allocated (using 305 | // MODE_YUVA) when decoding starts. All parameters are then ignored. 306 | // Returns NULL if the allocation failed or if a parameter is invalid. 307 | WEBP_EXTERN(WebPIDecoder*) WebPINewYUVA( 308 | uint8_t* luma, size_t luma_size, int luma_stride, 309 | uint8_t* u, size_t u_size, int u_stride, 310 | uint8_t* v, size_t v_size, int v_stride, 311 | uint8_t* a, size_t a_size, int a_stride); 312 | 313 | // Deprecated version of the above, without the alpha plane. 314 | // Kept for backward compatibility. 315 | WEBP_EXTERN(WebPIDecoder*) WebPINewYUV( 316 | uint8_t* luma, size_t luma_size, int luma_stride, 317 | uint8_t* u, size_t u_size, int u_stride, 318 | uint8_t* v, size_t v_size, int v_stride); 319 | 320 | // Deletes the WebPIDecoder object and associated memory. Must always be called 321 | // if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded. 322 | WEBP_EXTERN(void) WebPIDelete(WebPIDecoder* idec); 323 | 324 | // Copies and decodes the next available data. Returns VP8_STATUS_OK when 325 | // the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more 326 | // data is expected. Returns error in other cases. 327 | WEBP_EXTERN(VP8StatusCode) WebPIAppend( 328 | WebPIDecoder* idec, const uint8_t* data, size_t data_size); 329 | 330 | // A variant of the above function to be used when data buffer contains 331 | // partial data from the beginning. In this case data buffer is not copied 332 | // to the internal memory. 333 | // Note that the value of the 'data' pointer can change between calls to 334 | // WebPIUpdate, for instance when the data buffer is resized to fit larger data. 335 | WEBP_EXTERN(VP8StatusCode) WebPIUpdate( 336 | WebPIDecoder* idec, const uint8_t* data, size_t data_size); 337 | 338 | // Returns the RGB/A image decoded so far. Returns NULL if output params 339 | // are not initialized yet. The RGB/A output type corresponds to the colorspace 340 | // specified during call to WebPINewDecoder() or WebPINewRGB(). 341 | // *last_y is the index of last decoded row in raster scan order. Some pointers 342 | // (*last_y, *width etc.) can be NULL if corresponding information is not 343 | // needed. 344 | WEBP_EXTERN(uint8_t*) WebPIDecGetRGB( 345 | const WebPIDecoder* idec, int* last_y, 346 | int* width, int* height, int* stride); 347 | 348 | // Same as above function to get a YUVA image. Returns pointer to the luma 349 | // plane or NULL in case of error. If there is no alpha information 350 | // the alpha pointer '*a' will be returned NULL. 351 | WEBP_EXTERN(uint8_t*) WebPIDecGetYUVA( 352 | const WebPIDecoder* idec, int* last_y, 353 | uint8_t** u, uint8_t** v, uint8_t** a, 354 | int* width, int* height, int* stride, int* uv_stride, int* a_stride); 355 | 356 | // Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the 357 | // alpha information (if present). Kept for backward compatibility. 358 | static WEBP_INLINE uint8_t* WebPIDecGetYUV( 359 | const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, 360 | int* width, int* height, int* stride, int* uv_stride) { 361 | return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height, 362 | stride, uv_stride, NULL); 363 | } 364 | 365 | // Generic call to retrieve information about the displayable area. 366 | // If non NULL, the left/right/width/height pointers are filled with the visible 367 | // rectangular area so far. 368 | // Returns NULL in case the incremental decoder object is in an invalid state. 369 | // Otherwise returns the pointer to the internal representation. This structure 370 | // is read-only, tied to WebPIDecoder's lifespan and should not be modified. 371 | WEBP_EXTERN(const WebPDecBuffer*) WebPIDecodedArea( 372 | const WebPIDecoder* idec, int* left, int* top, int* width, int* height); 373 | 374 | //------------------------------------------------------------------------------ 375 | // Advanced decoding parametrization 376 | // 377 | // Code sample for using the advanced decoding API 378 | /* 379 | // A) Init a configuration object 380 | WebPDecoderConfig config; 381 | CHECK(WebPInitDecoderConfig(&config)); 382 | 383 | // B) optional: retrieve the bitstream's features. 384 | CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK); 385 | 386 | // C) Adjust 'config', if needed 387 | config.no_fancy_upsampling = 1; 388 | config.output.colorspace = MODE_BGRA; 389 | // etc. 390 | 391 | // Note that you can also make config.output point to an externally 392 | // supplied memory buffer, provided it's big enough to store the decoded 393 | // picture. Otherwise, config.output will just be used to allocate memory 394 | // and store the decoded picture. 395 | 396 | // D) Decode! 397 | CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK); 398 | 399 | // E) Decoded image is now in config.output (and config.output.u.RGBA) 400 | 401 | // F) Reclaim memory allocated in config's object. It's safe to call 402 | // this function even if the memory is external and wasn't allocated 403 | // by WebPDecode(). 404 | WebPFreeDecBuffer(&config.output); 405 | */ 406 | 407 | // Features gathered from the bitstream 408 | struct WebPBitstreamFeatures { 409 | int width; // Width in pixels, as read from the bitstream. 410 | int height; // Height in pixels, as read from the bitstream. 411 | int has_alpha; // True if the bitstream contains an alpha channel. 412 | int has_animation; // True if the bitstream is an animation. 413 | int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless 414 | 415 | uint32_t pad[5]; // padding for later use 416 | }; 417 | 418 | // Internal, version-checked, entry point 419 | WEBP_EXTERN(VP8StatusCode) WebPGetFeaturesInternal( 420 | const uint8_t*, size_t, WebPBitstreamFeatures*, int); 421 | 422 | // Retrieve features from the bitstream. The *features structure is filled 423 | // with information gathered from the bitstream. 424 | // Returns VP8_STATUS_OK when the features are successfully retrieved. Returns 425 | // VP8_STATUS_NOT_ENOUGH_DATA when more data is needed to retrieve the 426 | // features from headers. Returns error in other cases. 427 | static WEBP_INLINE VP8StatusCode WebPGetFeatures( 428 | const uint8_t* data, size_t data_size, 429 | WebPBitstreamFeatures* features) { 430 | return WebPGetFeaturesInternal(data, data_size, features, 431 | WEBP_DECODER_ABI_VERSION); 432 | } 433 | 434 | // Decoding options 435 | struct WebPDecoderOptions { 436 | int bypass_filtering; // if true, skip the in-loop filtering 437 | int no_fancy_upsampling; // if true, use faster pointwise upsampler 438 | int use_cropping; // if true, cropping is applied _first_ 439 | int crop_left, crop_top; // top-left position for cropping. 440 | // Will be snapped to even values. 441 | int crop_width, crop_height; // dimension of the cropping area 442 | int use_scaling; // if true, scaling is applied _afterward_ 443 | int scaled_width, scaled_height; // final resolution 444 | int use_threads; // if true, use multi-threaded decoding 445 | int dithering_strength; // dithering strength (0=Off, 100=full) 446 | int flip; // flip output vertically 447 | int alpha_dithering_strength; // alpha dithering strength in [0..100] 448 | 449 | uint32_t pad[5]; // padding for later use 450 | }; 451 | 452 | // Main object storing the configuration for advanced decoding. 453 | struct WebPDecoderConfig { 454 | WebPBitstreamFeatures input; // Immutable bitstream features (optional) 455 | WebPDecBuffer output; // Output buffer (can point to external mem) 456 | WebPDecoderOptions options; // Decoding options 457 | }; 458 | 459 | // Internal, version-checked, entry point 460 | WEBP_EXTERN(int) WebPInitDecoderConfigInternal(WebPDecoderConfig*, int); 461 | 462 | // Initialize the configuration as empty. This function must always be 463 | // called first, unless WebPGetFeatures() is to be called. 464 | // Returns false in case of mismatched version. 465 | static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) { 466 | return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION); 467 | } 468 | 469 | // Instantiate a new incremental decoder object with the requested 470 | // configuration. The bitstream can be passed using 'data' and 'data_size' 471 | // parameter, in which case the features will be parsed and stored into 472 | // config->input. Otherwise, 'data' can be NULL and no parsing will occur. 473 | // Note that 'config' can be NULL too, in which case a default configuration 474 | // is used. If 'config' is not NULL, it must outlive the WebPIDecoder object 475 | // as some references to its fields will be used. No internal copy of 'config' 476 | // is made. 477 | // The return WebPIDecoder object must always be deleted calling WebPIDelete(). 478 | // Returns NULL in case of error (and config->status will then reflect 479 | // the error condition, if available). 480 | WEBP_EXTERN(WebPIDecoder*) WebPIDecode(const uint8_t* data, size_t data_size, 481 | WebPDecoderConfig* config); 482 | 483 | // Non-incremental version. This version decodes the full data at once, taking 484 | // 'config' into account. Returns decoding status (which should be VP8_STATUS_OK 485 | // if the decoding was successful). Note that 'config' cannot be NULL. 486 | WEBP_EXTERN(VP8StatusCode) WebPDecode(const uint8_t* data, size_t data_size, 487 | WebPDecoderConfig* config); 488 | 489 | #ifdef __cplusplus 490 | } // extern "C" 491 | #endif 492 | 493 | #endif /* WEBP_WEBP_DECODE_H_ */ 494 | -------------------------------------------------------------------------------- /WebpQuickLook/webp/demux.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 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 | // Demux API. 11 | // Enables extraction of image and extended format data from WebP files. 12 | 13 | // Code Example: Demuxing WebP data to extract all the frames, ICC profile 14 | // and EXIF/XMP metadata. 15 | /* 16 | WebPDemuxer* demux = WebPDemux(&webp_data); 17 | 18 | uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); 19 | uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); 20 | // ... (Get information about the features present in the WebP file). 21 | uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); 22 | 23 | // ... (Iterate over all frames). 24 | WebPIterator iter; 25 | if (WebPDemuxGetFrame(demux, 1, &iter)) { 26 | do { 27 | // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), 28 | // ... and get other frame properties like width, height, offsets etc. 29 | // ... see 'struct WebPIterator' below for more info). 30 | } while (WebPDemuxNextFrame(&iter)); 31 | WebPDemuxReleaseIterator(&iter); 32 | } 33 | 34 | // ... (Extract metadata). 35 | WebPChunkIterator chunk_iter; 36 | if (flags & ICCP_FLAG) WebPDemuxGetChunk(demux, "ICCP", 1, &chunk_iter); 37 | // ... (Consume the ICC profile in 'chunk_iter.chunk'). 38 | WebPDemuxReleaseChunkIterator(&chunk_iter); 39 | if (flags & EXIF_FLAG) WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter); 40 | // ... (Consume the EXIF metadata in 'chunk_iter.chunk'). 41 | WebPDemuxReleaseChunkIterator(&chunk_iter); 42 | if (flags & XMP_FLAG) WebPDemuxGetChunk(demux, "XMP ", 1, &chunk_iter); 43 | // ... (Consume the XMP metadata in 'chunk_iter.chunk'). 44 | WebPDemuxReleaseChunkIterator(&chunk_iter); 45 | WebPDemuxDelete(demux); 46 | */ 47 | 48 | #ifndef WEBP_WEBP_DEMUX_H_ 49 | #define WEBP_WEBP_DEMUX_H_ 50 | 51 | #include "./decode.h" // for WEBP_CSP_MODE 52 | #include "./mux_types.h" 53 | 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | #define WEBP_DEMUX_ABI_VERSION 0x0107 // MAJOR(8b) + MINOR(8b) 59 | 60 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 61 | // the types are left here for reference. 62 | // typedef enum WebPDemuxState WebPDemuxState; 63 | // typedef enum WebPFormatFeature WebPFormatFeature; 64 | typedef struct WebPDemuxer WebPDemuxer; 65 | typedef struct WebPIterator WebPIterator; 66 | typedef struct WebPChunkIterator WebPChunkIterator; 67 | typedef struct WebPAnimInfo WebPAnimInfo; 68 | typedef struct WebPAnimDecoderOptions WebPAnimDecoderOptions; 69 | 70 | //------------------------------------------------------------------------------ 71 | 72 | // Returns the version number of the demux library, packed in hexadecimal using 73 | // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. 74 | WEBP_EXTERN(int) WebPGetDemuxVersion(void); 75 | 76 | //------------------------------------------------------------------------------ 77 | // Life of a Demux object 78 | 79 | typedef enum WebPDemuxState { 80 | WEBP_DEMUX_PARSE_ERROR = -1, // An error occurred while parsing. 81 | WEBP_DEMUX_PARSING_HEADER = 0, // Not enough data to parse full header. 82 | WEBP_DEMUX_PARSED_HEADER = 1, // Header parsing complete, 83 | // data may be available. 84 | WEBP_DEMUX_DONE = 2 // Entire file has been parsed. 85 | } WebPDemuxState; 86 | 87 | // Internal, version-checked, entry point 88 | WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal( 89 | const WebPData*, int, WebPDemuxState*, int); 90 | 91 | // Parses the full WebP file given by 'data'. For single images the WebP file 92 | // header alone or the file header and the chunk header may be absent. 93 | // Returns a WebPDemuxer object on successful parse, NULL otherwise. 94 | static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) { 95 | return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION); 96 | } 97 | 98 | // Parses the possibly incomplete WebP file given by 'data'. 99 | // If 'state' is non-NULL it will be set to indicate the status of the demuxer. 100 | // Returns NULL in case of error or if there isn't enough data to start parsing; 101 | // and a WebPDemuxer object on successful parse. 102 | // Note that WebPDemuxer keeps internal pointers to 'data' memory segment. 103 | // If this data is volatile, the demuxer object should be deleted (by calling 104 | // WebPDemuxDelete()) and WebPDemuxPartial() called again on the new data. 105 | // This is usually an inexpensive operation. 106 | static WEBP_INLINE WebPDemuxer* WebPDemuxPartial( 107 | const WebPData* data, WebPDemuxState* state) { 108 | return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION); 109 | } 110 | 111 | // Frees memory associated with 'dmux'. 112 | WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* dmux); 113 | 114 | //------------------------------------------------------------------------------ 115 | // Data/information extraction. 116 | 117 | typedef enum WebPFormatFeature { 118 | WEBP_FF_FORMAT_FLAGS, // Extended format flags present in the 'VP8X' chunk. 119 | WEBP_FF_CANVAS_WIDTH, 120 | WEBP_FF_CANVAS_HEIGHT, 121 | WEBP_FF_LOOP_COUNT, 122 | WEBP_FF_BACKGROUND_COLOR, 123 | WEBP_FF_FRAME_COUNT // Number of frames present in the demux object. 124 | // In case of a partial demux, this is the number of 125 | // frames seen so far, with the last frame possibly 126 | // being partial. 127 | } WebPFormatFeature; 128 | 129 | // Get the 'feature' value from the 'dmux'. 130 | // NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial() 131 | // returned a state > WEBP_DEMUX_PARSING_HEADER. 132 | WEBP_EXTERN(uint32_t) WebPDemuxGetI( 133 | const WebPDemuxer* dmux, WebPFormatFeature feature); 134 | 135 | //------------------------------------------------------------------------------ 136 | // Frame iteration. 137 | 138 | struct WebPIterator { 139 | int frame_num; 140 | int num_frames; // equivalent to WEBP_FF_FRAME_COUNT. 141 | int x_offset, y_offset; // offset relative to the canvas. 142 | int width, height; // dimensions of this frame. 143 | int duration; // display duration in milliseconds. 144 | WebPMuxAnimDispose dispose_method; // dispose method for the frame. 145 | int complete; // true if 'fragment' contains a full frame. partial images 146 | // may still be decoded with the WebP incremental decoder. 147 | WebPData fragment; // The frame given by 'frame_num'. Note for historical 148 | // reasons this is called a fragment. 149 | int has_alpha; // True if the frame contains transparency. 150 | WebPMuxAnimBlend blend_method; // Blend operation for the frame. 151 | 152 | uint32_t pad[2]; // padding for later use. 153 | void* private_; // for internal use only. 154 | }; 155 | 156 | // Retrieves frame 'frame_number' from 'dmux'. 157 | // 'iter->fragment' points to the frame on return from this function. 158 | // Setting 'frame_number' equal to 0 will return the last frame of the image. 159 | // Returns false if 'dmux' is NULL or frame 'frame_number' is not present. 160 | // Call WebPDemuxReleaseIterator() when use of the iterator is complete. 161 | // NOTE: 'dmux' must persist for the lifetime of 'iter'. 162 | WEBP_EXTERN(int) WebPDemuxGetFrame( 163 | const WebPDemuxer* dmux, int frame_number, WebPIterator* iter); 164 | 165 | // Sets 'iter->fragment' to point to the next ('iter->frame_num' + 1) or 166 | // previous ('iter->frame_num' - 1) frame. These functions do not loop. 167 | // Returns true on success, false otherwise. 168 | WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter); 169 | WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter); 170 | 171 | // Releases any memory associated with 'iter'. 172 | // Must be called before any subsequent calls to WebPDemuxGetChunk() on the same 173 | // iter. Also, must be called before destroying the associated WebPDemuxer with 174 | // WebPDemuxDelete(). 175 | WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* iter); 176 | 177 | //------------------------------------------------------------------------------ 178 | // Chunk iteration. 179 | 180 | struct WebPChunkIterator { 181 | // The current and total number of chunks with the fourcc given to 182 | // WebPDemuxGetChunk(). 183 | int chunk_num; 184 | int num_chunks; 185 | WebPData chunk; // The payload of the chunk. 186 | 187 | uint32_t pad[6]; // padding for later use 188 | void* private_; 189 | }; 190 | 191 | // Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from 192 | // 'dmux'. 193 | // 'fourcc' is a character array containing the fourcc of the chunk to return, 194 | // e.g., "ICCP", "XMP ", "EXIF", etc. 195 | // Setting 'chunk_number' equal to 0 will return the last chunk in a set. 196 | // Returns true if the chunk is found, false otherwise. Image related chunk 197 | // payloads are accessed through WebPDemuxGetFrame() and related functions. 198 | // Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete. 199 | // NOTE: 'dmux' must persist for the lifetime of the iterator. 200 | WEBP_EXTERN(int) WebPDemuxGetChunk(const WebPDemuxer* dmux, 201 | const char fourcc[4], int chunk_number, 202 | WebPChunkIterator* iter); 203 | 204 | // Sets 'iter->chunk' to point to the next ('iter->chunk_num' + 1) or previous 205 | // ('iter->chunk_num' - 1) chunk. These functions do not loop. 206 | // Returns true on success, false otherwise. 207 | WEBP_EXTERN(int) WebPDemuxNextChunk(WebPChunkIterator* iter); 208 | WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* iter); 209 | 210 | // Releases any memory associated with 'iter'. 211 | // Must be called before destroying the associated WebPDemuxer with 212 | // WebPDemuxDelete(). 213 | WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter); 214 | 215 | //------------------------------------------------------------------------------ 216 | // WebPAnimDecoder API 217 | // 218 | // This API allows decoding (possibly) animated WebP images. 219 | // 220 | // Code Example: 221 | /* 222 | WebPAnimDecoderOptions dec_options; 223 | WebPAnimDecoderOptionsInit(&dec_options); 224 | // Tune 'dec_options' as needed. 225 | WebPAnimDecoder* dec = WebPAnimDecoderNew(webp_data, &dec_options); 226 | WebPAnimInfo anim_info; 227 | WebPAnimDecoderGetInfo(dec, &anim_info); 228 | for (uint32_t i = 0; i < anim_info.loop_count; ++i) { 229 | while (WebPAnimDecoderHasMoreFrames(dec)) { 230 | uint8_t* buf; 231 | int timestamp; 232 | WebPAnimDecoderGetNext(dec, &buf, ×tamp); 233 | // ... (Render 'buf' based on 'timestamp'). 234 | // ... (Do NOT free 'buf', as it is owned by 'dec'). 235 | } 236 | WebPAnimDecoderReset(dec); 237 | } 238 | const WebPDemuxer* demuxer = WebPAnimDecoderGetDemuxer(dec); 239 | // ... (Do something using 'demuxer'; e.g. get EXIF/XMP/ICC data). 240 | WebPAnimDecoderDelete(dec); 241 | */ 242 | 243 | typedef struct WebPAnimDecoder WebPAnimDecoder; // Main opaque object. 244 | 245 | // Global options. 246 | struct WebPAnimDecoderOptions { 247 | // Output colorspace. Only the following modes are supported: 248 | // MODE_RGBA, MODE_BGRA, MODE_rgbA and MODE_bgrA. 249 | WEBP_CSP_MODE color_mode; 250 | int use_threads; // If true, use multi-threaded decoding. 251 | uint32_t padding[7]; // Padding for later use. 252 | }; 253 | 254 | // Internal, version-checked, entry point. 255 | WEBP_EXTERN(int) WebPAnimDecoderOptionsInitInternal( 256 | WebPAnimDecoderOptions*, int); 257 | 258 | // Should always be called, to initialize a fresh WebPAnimDecoderOptions 259 | // structure before modification. Returns false in case of version mismatch. 260 | // WebPAnimDecoderOptionsInit() must have succeeded before using the 261 | // 'dec_options' object. 262 | static WEBP_INLINE int WebPAnimDecoderOptionsInit( 263 | WebPAnimDecoderOptions* dec_options) { 264 | return WebPAnimDecoderOptionsInitInternal(dec_options, 265 | WEBP_DEMUX_ABI_VERSION); 266 | } 267 | 268 | // Internal, version-checked, entry point. 269 | WEBP_EXTERN(WebPAnimDecoder*) WebPAnimDecoderNewInternal( 270 | const WebPData*, const WebPAnimDecoderOptions*, int); 271 | 272 | // Creates and initializes a WebPAnimDecoder object. 273 | // Parameters: 274 | // webp_data - (in) WebP bitstream. This should remain unchanged during the 275 | // lifetime of the output WebPAnimDecoder object. 276 | // dec_options - (in) decoding options. Can be passed NULL to choose 277 | // reasonable defaults (in particular, color mode MODE_RGBA 278 | // will be picked). 279 | // Returns: 280 | // A pointer to the newly created WebPAnimDecoder object, or NULL in case of 281 | // parsing error, invalid option or memory error. 282 | static WEBP_INLINE WebPAnimDecoder* WebPAnimDecoderNew( 283 | const WebPData* webp_data, const WebPAnimDecoderOptions* dec_options) { 284 | return WebPAnimDecoderNewInternal(webp_data, dec_options, 285 | WEBP_DEMUX_ABI_VERSION); 286 | } 287 | 288 | // Global information about the animation.. 289 | struct WebPAnimInfo { 290 | uint32_t canvas_width; 291 | uint32_t canvas_height; 292 | uint32_t loop_count; 293 | uint32_t bgcolor; 294 | uint32_t frame_count; 295 | uint32_t pad[4]; // padding for later use 296 | }; 297 | 298 | // Get global information about the animation. 299 | // Parameters: 300 | // dec - (in) decoder instance to get information from. 301 | // info - (out) global information fetched from the animation. 302 | // Returns: 303 | // True on success. 304 | WEBP_EXTERN(int) WebPAnimDecoderGetInfo(const WebPAnimDecoder* dec, 305 | WebPAnimInfo* info); 306 | 307 | // Fetch the next frame from 'dec' based on options supplied to 308 | // WebPAnimDecoderNew(). This will be a fully reconstructed canvas of size 309 | // 'canvas_width * 4 * canvas_height', and not just the frame sub-rectangle. The 310 | // returned buffer 'buf' is valid only until the next call to 311 | // WebPAnimDecoderGetNext(), WebPAnimDecoderReset() or WebPAnimDecoderDelete(). 312 | // Parameters: 313 | // dec - (in/out) decoder instance from which the next frame is to be fetched. 314 | // buf - (out) decoded frame. 315 | // timestamp - (out) timestamp of the frame in milliseconds. 316 | // Returns: 317 | // False if any of the arguments are NULL, or if there is a parsing or 318 | // decoding error, or if there are no more frames. Otherwise, returns true. 319 | WEBP_EXTERN(int) WebPAnimDecoderGetNext(WebPAnimDecoder* dec, 320 | uint8_t** buf, int* timestamp); 321 | 322 | // Check if there are more frames left to decode. 323 | // Parameters: 324 | // dec - (in) decoder instance to be checked. 325 | // Returns: 326 | // True if 'dec' is not NULL and some frames are yet to be decoded. 327 | // Otherwise, returns false. 328 | WEBP_EXTERN(int) WebPAnimDecoderHasMoreFrames(const WebPAnimDecoder* dec); 329 | 330 | // Resets the WebPAnimDecoder object, so that next call to 331 | // WebPAnimDecoderGetNext() will restart decoding from 1st frame. This would be 332 | // helpful when all frames need to be decoded multiple times (e.g. 333 | // info.loop_count times) without destroying and recreating the 'dec' object. 334 | // Parameters: 335 | // dec - (in/out) decoder instance to be reset 336 | WEBP_EXTERN(void) WebPAnimDecoderReset(WebPAnimDecoder* dec); 337 | 338 | // Grab the internal demuxer object. 339 | // Getting the demuxer object can be useful if one wants to use operations only 340 | // available through demuxer; e.g. to get XMP/EXIF/ICC metadata. The returned 341 | // demuxer object is owned by 'dec' and is valid only until the next call to 342 | // WebPAnimDecoderDelete(). 343 | // 344 | // Parameters: 345 | // dec - (in) decoder instance from which the demuxer object is to be fetched. 346 | WEBP_EXTERN(const WebPDemuxer*) WebPAnimDecoderGetDemuxer( 347 | const WebPAnimDecoder* dec); 348 | 349 | // Deletes the WebPAnimDecoder object. 350 | // Parameters: 351 | // dec - (in/out) decoder instance to be deleted 352 | WEBP_EXTERN(void) WebPAnimDecoderDelete(WebPAnimDecoder* dec); 353 | 354 | #ifdef __cplusplus 355 | } // extern "C" 356 | #endif 357 | 358 | #endif /* WEBP_WEBP_DEMUX_H_ */ 359 | -------------------------------------------------------------------------------- /WebpQuickLook/webp/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 | WEBP_EXTERN(size_t) WebPEncodeLosslessRGB(const uint8_t* rgb, 66 | int width, int height, int stride, 67 | uint8_t** output); 68 | WEBP_EXTERN(size_t) WebPEncodeLosslessBGR(const uint8_t* bgr, 69 | int width, int height, int stride, 70 | uint8_t** output); 71 | WEBP_EXTERN(size_t) WebPEncodeLosslessRGBA(const uint8_t* rgba, 72 | int width, int height, int stride, 73 | uint8_t** output); 74 | WEBP_EXTERN(size_t) WebPEncodeLosslessBGRA(const uint8_t* bgra, 75 | int width, int height, int stride, 76 | uint8_t** output); 77 | 78 | // Releases memory returned by the WebPEncode*() functions above. 79 | WEBP_EXTERN(void) WebPFree(void* ptr); 80 | 81 | //------------------------------------------------------------------------------ 82 | // Coding parameters 83 | 84 | // Image characteristics hint for the underlying encoder. 85 | typedef enum WebPImageHint { 86 | WEBP_HINT_DEFAULT = 0, // default preset. 87 | WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot 88 | WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting 89 | WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc). 90 | WEBP_HINT_LAST 91 | } WebPImageHint; 92 | 93 | // Compression parameters. 94 | struct WebPConfig { 95 | int lossless; // Lossless encoding (0=lossy(default), 1=lossless). 96 | float quality; // between 0 and 100. For lossy, 0 gives the smallest 97 | // size and 100 the largest. For lossless, this 98 | // parameter is the amount of effort put into the 99 | // compression: 0 is the fastest but gives larger 100 | // files compared to the slowest, but best, 100. 101 | int method; // quality/speed trade-off (0=fast, 6=slower-better) 102 | 103 | WebPImageHint image_hint; // Hint for image type (lossless only for now). 104 | 105 | // Parameters related to lossy compression only: 106 | int target_size; // if non-zero, set the desired target size in bytes. 107 | // Takes precedence over the 'compression' parameter. 108 | float target_PSNR; // if non-zero, specifies the minimal distortion to 109 | // try to achieve. Takes precedence over target_size. 110 | int segments; // maximum number of segments to use, in [1..4] 111 | int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum. 112 | int filter_strength; // range: [0 = off .. 100 = strongest] 113 | int filter_sharpness; // range: [0 = off .. 7 = least sharp] 114 | int filter_type; // filtering type: 0 = simple, 1 = strong (only used 115 | // if filter_strength > 0 or autofilter > 0) 116 | int autofilter; // Auto adjust filter's strength [0 = off, 1 = on] 117 | int alpha_compression; // Algorithm for encoding the alpha plane (0 = none, 118 | // 1 = compressed with WebP lossless). Default is 1. 119 | int alpha_filtering; // Predictive filtering method for alpha plane. 120 | // 0: none, 1: fast, 2: best. Default if 1. 121 | int alpha_quality; // Between 0 (smallest size) and 100 (lossless). 122 | // Default is 100. 123 | int pass; // number of entropy-analysis passes (in [1..10]). 124 | 125 | int show_compressed; // if true, export the compressed picture back. 126 | // In-loop filtering is not applied. 127 | int preprocessing; // preprocessing filter: 128 | // 0=none, 1=segment-smooth, 2=pseudo-random dithering 129 | int partitions; // log2(number of token partitions) in [0..3]. Default 130 | // is set to 0 for easier progressive decoding. 131 | int partition_limit; // quality degradation allowed to fit the 512k limit 132 | // on prediction modes coding (0: no degradation, 133 | // 100: maximum possible degradation). 134 | int emulate_jpeg_size; // If true, compression parameters will be remapped 135 | // to better match the expected output size from 136 | // JPEG compression. Generally, the output size will 137 | // be similar but the degradation will be lower. 138 | int thread_level; // If non-zero, try and use multi-threaded encoding. 139 | int low_memory; // If set, reduce memory usage (but increase CPU use). 140 | 141 | int near_lossless; // Near lossless encoding [0 = max loss .. 100 = off 142 | // (default)]. 143 | int exact; // if non-zero, preserve the exact RGB values under 144 | // transparent area. Otherwise, discard this invisible 145 | // RGB information for better compression. The default 146 | // value is 0. 147 | 148 | int use_delta_palette; // reserved for future lossless feature 149 | int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion 150 | 151 | uint32_t pad[2]; // padding for later use 152 | }; 153 | 154 | // Enumerate some predefined settings for WebPConfig, depending on the type 155 | // of source picture. These presets are used when calling WebPConfigPreset(). 156 | typedef enum WebPPreset { 157 | WEBP_PRESET_DEFAULT = 0, // default preset. 158 | WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot 159 | WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting 160 | WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details 161 | WEBP_PRESET_ICON, // small-sized colorful images 162 | WEBP_PRESET_TEXT // text-like 163 | } WebPPreset; 164 | 165 | // Internal, version-checked, entry point 166 | WEBP_EXTERN(int) WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int); 167 | 168 | // Should always be called, to initialize a fresh WebPConfig structure before 169 | // modification. Returns false in case of version mismatch. WebPConfigInit() 170 | // must have succeeded before using the 'config' object. 171 | // Note that the default values are lossless=0 and quality=75. 172 | static WEBP_INLINE int WebPConfigInit(WebPConfig* config) { 173 | return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f, 174 | WEBP_ENCODER_ABI_VERSION); 175 | } 176 | 177 | // This function will initialize the configuration according to a predefined 178 | // set of parameters (referred to by 'preset') and a given quality factor. 179 | // This function can be called as a replacement to WebPConfigInit(). Will 180 | // return false in case of error. 181 | static WEBP_INLINE int WebPConfigPreset(WebPConfig* config, 182 | WebPPreset preset, float quality) { 183 | return WebPConfigInitInternal(config, preset, quality, 184 | WEBP_ENCODER_ABI_VERSION); 185 | } 186 | 187 | // Activate the lossless compression mode with the desired efficiency level 188 | // between 0 (fastest, lowest compression) and 9 (slower, best compression). 189 | // A good default level is '6', providing a fair tradeoff between compression 190 | // speed and final compressed size. 191 | // This function will overwrite several fields from config: 'method', 'quality' 192 | // and 'lossless'. Returns false in case of parameter error. 193 | WEBP_EXTERN(int) WebPConfigLosslessPreset(WebPConfig* config, int level); 194 | 195 | // Returns true if 'config' is non-NULL and all configuration parameters are 196 | // within their valid ranges. 197 | WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* config); 198 | 199 | //------------------------------------------------------------------------------ 200 | // Input / Output 201 | // Structure for storing auxiliary statistics (mostly for lossy encoding). 202 | 203 | struct WebPAuxStats { 204 | int coded_size; // final size 205 | 206 | float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha 207 | int block_count[3]; // number of intra4/intra16/skipped macroblocks 208 | int header_bytes[2]; // approximate number of bytes spent for header 209 | // and mode-partition #0 210 | int residual_bytes[3][4]; // approximate number of bytes spent for 211 | // DC/AC/uv coefficients for each (0..3) segments. 212 | int segment_size[4]; // number of macroblocks in each segments 213 | int segment_quant[4]; // quantizer values for each segments 214 | int segment_level[4]; // filtering strength for each segments [0..63] 215 | 216 | int alpha_data_size; // size of the transparency data 217 | int layer_data_size; // size of the enhancement layer data 218 | 219 | // lossless encoder statistics 220 | uint32_t lossless_features; // bit0:predictor bit1:cross-color transform 221 | // bit2:subtract-green bit3:color indexing 222 | int histogram_bits; // number of precision bits of histogram 223 | int transform_bits; // precision bits for transform 224 | int cache_bits; // number of bits for color cache lookup 225 | int palette_size; // number of color in palette, if used 226 | int lossless_size; // final lossless size 227 | int lossless_hdr_size; // lossless header (transform, huffman etc) size 228 | int lossless_data_size; // lossless image data size 229 | 230 | uint32_t pad[2]; // padding for later use 231 | }; 232 | 233 | // Signature for output function. Should return true if writing was successful. 234 | // data/data_size is the segment of data to write, and 'picture' is for 235 | // reference (and so one can make use of picture->custom_ptr). 236 | typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size, 237 | const WebPPicture* picture); 238 | 239 | // WebPMemoryWrite: a special WebPWriterFunction that writes to memory using 240 | // the following WebPMemoryWriter object (to be set as a custom_ptr). 241 | struct WebPMemoryWriter { 242 | uint8_t* mem; // final buffer (of size 'max_size', larger than 'size'). 243 | size_t size; // final size 244 | size_t max_size; // total capacity 245 | uint32_t pad[1]; // padding for later use 246 | }; 247 | 248 | // The following must be called first before any use. 249 | WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer); 250 | 251 | // The following must be called to deallocate writer->mem memory. The 'writer' 252 | // object itself is not deallocated. 253 | WEBP_EXTERN(void) WebPMemoryWriterClear(WebPMemoryWriter* writer); 254 | // The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon 255 | // completion, writer.mem and writer.size will hold the coded data. 256 | // writer.mem must be freed by calling WebPMemoryWriterClear. 257 | WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size, 258 | const WebPPicture* picture); 259 | 260 | // Progress hook, called from time to time to report progress. It can return 261 | // false to request an abort of the encoding process, or true otherwise if 262 | // everything is OK. 263 | typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture); 264 | 265 | // Color spaces. 266 | typedef enum WebPEncCSP { 267 | // chroma sampling 268 | WEBP_YUV420 = 0, // 4:2:0 269 | WEBP_YUV420A = 4, // alpha channel variant 270 | WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors 271 | WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present 272 | } WebPEncCSP; 273 | 274 | // Encoding error conditions. 275 | typedef enum WebPEncodingError { 276 | VP8_ENC_OK = 0, 277 | VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects 278 | VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits 279 | VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL 280 | VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid 281 | VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height 282 | VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k 283 | VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M 284 | VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes 285 | VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G 286 | VP8_ENC_ERROR_USER_ABORT, // abort request by user 287 | VP8_ENC_ERROR_LAST // list terminator. always last. 288 | } WebPEncodingError; 289 | 290 | // maximum width/height allowed (inclusive), in pixels 291 | #define WEBP_MAX_DIMENSION 16383 292 | 293 | // Main exchange structure (input samples, output bytes, statistics) 294 | struct WebPPicture { 295 | // INPUT 296 | ////////////// 297 | // Main flag for encoder selecting between ARGB or YUV input. 298 | // It is recommended to use ARGB input (*argb, argb_stride) for lossless 299 | // compression, and YUV input (*y, *u, *v, etc.) for lossy compression 300 | // since these are the respective native colorspace for these formats. 301 | int use_argb; 302 | 303 | // YUV input (mostly used for input to lossy compression) 304 | WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr). 305 | int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION) 306 | uint8_t *y, *u, *v; // pointers to luma/chroma planes. 307 | int y_stride, uv_stride; // luma/chroma strides. 308 | uint8_t* a; // pointer to the alpha plane 309 | int a_stride; // stride of the alpha plane 310 | uint32_t pad1[2]; // padding for later use 311 | 312 | // ARGB input (mostly used for input to lossless compression) 313 | uint32_t* argb; // Pointer to argb (32 bit) plane. 314 | int argb_stride; // This is stride in pixels units, not bytes. 315 | uint32_t pad2[3]; // padding for later use 316 | 317 | // OUTPUT 318 | /////////////// 319 | // Byte-emission hook, to store compressed bytes as they are ready. 320 | WebPWriterFunction writer; // can be NULL 321 | void* custom_ptr; // can be used by the writer. 322 | 323 | // map for extra information (only for lossy compression mode) 324 | int extra_info_type; // 1: intra type, 2: segment, 3: quant 325 | // 4: intra-16 prediction mode, 326 | // 5: chroma prediction mode, 327 | // 6: bit cost, 7: distortion 328 | uint8_t* extra_info; // if not NULL, points to an array of size 329 | // ((width + 15) / 16) * ((height + 15) / 16) that 330 | // will be filled with a macroblock map, depending 331 | // on extra_info_type. 332 | 333 | // STATS AND REPORTS 334 | /////////////////////////// 335 | // Pointer to side statistics (updated only if not NULL) 336 | WebPAuxStats* stats; 337 | 338 | // Error code for the latest error encountered during encoding 339 | WebPEncodingError error_code; 340 | 341 | // If not NULL, report progress during encoding. 342 | WebPProgressHook progress_hook; 343 | 344 | void* user_data; // this field is free to be set to any value and 345 | // used during callbacks (like progress-report e.g.). 346 | 347 | uint32_t pad3[3]; // padding for later use 348 | 349 | // Unused for now 350 | uint8_t *pad4, *pad5; 351 | uint32_t pad6[8]; // padding for later use 352 | 353 | // PRIVATE FIELDS 354 | //////////////////// 355 | void* memory_; // row chunk of memory for yuva planes 356 | void* memory_argb_; // and for argb too. 357 | void* pad7[2]; // padding for later use 358 | }; 359 | 360 | // Internal, version-checked, entry point 361 | WEBP_EXTERN(int) WebPPictureInitInternal(WebPPicture*, int); 362 | 363 | // Should always be called, to initialize the structure. Returns false in case 364 | // of version mismatch. WebPPictureInit() must have succeeded before using the 365 | // 'picture' object. 366 | // Note that, by default, use_argb is false and colorspace is WEBP_YUV420. 367 | static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) { 368 | return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION); 369 | } 370 | 371 | //------------------------------------------------------------------------------ 372 | // WebPPicture utils 373 | 374 | // Convenience allocation / deallocation based on picture->width/height: 375 | // Allocate y/u/v buffers as per colorspace/width/height specification. 376 | // Note! This function will free the previous buffer if needed. 377 | // Returns false in case of memory error. 378 | WEBP_EXTERN(int) WebPPictureAlloc(WebPPicture* picture); 379 | 380 | // Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*(). 381 | // Note that this function does _not_ free the memory used by the 'picture' 382 | // object itself. 383 | // Besides memory (which is reclaimed) all other fields of 'picture' are 384 | // preserved. 385 | WEBP_EXTERN(void) WebPPictureFree(WebPPicture* picture); 386 | 387 | // Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, *dst 388 | // will fully own the copied pixels (this is not a view). The 'dst' picture need 389 | // not be initialized as its content is overwritten. 390 | // Returns false in case of memory allocation error. 391 | WEBP_EXTERN(int) WebPPictureCopy(const WebPPicture* src, WebPPicture* dst); 392 | 393 | // Compute the single distortion for packed planes of samples. 394 | // 'src' will be compared to 'ref', and the raw distortion stored into 395 | // '*distortion'. The refined metric (log(MSE), log(1 - ssim),...' will be 396 | // stored in '*result'. 397 | // 'x_step' is the horizontal stride (in bytes) between samples. 398 | // 'src/ref_stride' is the byte distance between rows. 399 | // Returns false in case of error (bad parameter, memory allocation error, ...). 400 | WEBP_EXTERN(int) WebPPlaneDistortion(const uint8_t* src, size_t src_stride, 401 | const uint8_t* ref, size_t ref_stride, 402 | int width, int height, 403 | size_t x_step, 404 | int type, // 0 = PSNR, 1 = SSIM, 2 = LSIM 405 | float* distortion, float* result); 406 | 407 | // Compute PSNR, SSIM or LSIM distortion metric between two pictures. Results 408 | // are in dB, stored in result[] in the B/G/R/A/All order. The distortion is 409 | // always performed using ARGB samples. Hence if the input is YUV(A), the 410 | // picture will be internally converted to ARGB (just for the measurement). 411 | // Warning: this function is rather CPU-intensive. 412 | WEBP_EXTERN(int) WebPPictureDistortion( 413 | const WebPPicture* src, const WebPPicture* ref, 414 | int metric_type, // 0 = PSNR, 1 = SSIM, 2 = LSIM 415 | float result[5]); 416 | 417 | // self-crops a picture to the rectangle defined by top/left/width/height. 418 | // Returns false in case of memory allocation error, or if the rectangle is 419 | // outside of the source picture. 420 | // The rectangle for the view is defined by the top-left corner pixel 421 | // coordinates (left, top) as well as its width and height. This rectangle 422 | // must be fully be comprised inside the 'src' source picture. If the source 423 | // picture uses the YUV420 colorspace, the top and left coordinates will be 424 | // snapped to even values. 425 | WEBP_EXTERN(int) WebPPictureCrop(WebPPicture* picture, 426 | int left, int top, int width, int height); 427 | 428 | // Extracts a view from 'src' picture into 'dst'. The rectangle for the view 429 | // is defined by the top-left corner pixel coordinates (left, top) as well 430 | // as its width and height. This rectangle must be fully be comprised inside 431 | // the 'src' source picture. If the source picture uses the YUV420 colorspace, 432 | // the top and left coordinates will be snapped to even values. 433 | // Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed 434 | // ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so, 435 | // the original dimension will be lost). Picture 'dst' need not be initialized 436 | // with WebPPictureInit() if it is different from 'src', since its content will 437 | // be overwritten. 438 | // Returns false in case of memory allocation error or invalid parameters. 439 | WEBP_EXTERN(int) WebPPictureView(const WebPPicture* src, 440 | int left, int top, int width, int height, 441 | WebPPicture* dst); 442 | 443 | // Returns true if the 'picture' is actually a view and therefore does 444 | // not own the memory for pixels. 445 | WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* picture); 446 | 447 | // Rescale a picture to new dimension width x height. 448 | // If either 'width' or 'height' (but not both) is 0 the corresponding 449 | // dimension will be calculated preserving the aspect ratio. 450 | // No gamma correction is applied. 451 | // Returns false in case of error (invalid parameter or insufficient memory). 452 | WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* pic, int width, int height); 453 | 454 | // Colorspace conversion function to import RGB samples. 455 | // Previous buffer will be free'd, if any. 456 | // *rgb buffer should have a size of at least height * rgb_stride. 457 | // Returns false in case of memory error. 458 | WEBP_EXTERN(int) WebPPictureImportRGB( 459 | WebPPicture* picture, const uint8_t* rgb, int rgb_stride); 460 | // Same, but for RGBA buffer. 461 | WEBP_EXTERN(int) WebPPictureImportRGBA( 462 | WebPPicture* picture, const uint8_t* rgba, int rgba_stride); 463 | // Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format 464 | // input buffer ignoring the alpha channel. Avoids needing to copy the data 465 | // to a temporary 24-bit RGB buffer to import the RGB only. 466 | WEBP_EXTERN(int) WebPPictureImportRGBX( 467 | WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride); 468 | 469 | // Variants of the above, but taking BGR(A|X) input. 470 | WEBP_EXTERN(int) WebPPictureImportBGR( 471 | WebPPicture* picture, const uint8_t* bgr, int bgr_stride); 472 | WEBP_EXTERN(int) WebPPictureImportBGRA( 473 | WebPPicture* picture, const uint8_t* bgra, int bgra_stride); 474 | WEBP_EXTERN(int) WebPPictureImportBGRX( 475 | WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride); 476 | 477 | // Converts picture->argb data to the YUV420A format. The 'colorspace' 478 | // parameter is deprecated and should be equal to WEBP_YUV420. 479 | // Upon return, picture->use_argb is set to false. The presence of real 480 | // non-opaque transparent values is detected, and 'colorspace' will be 481 | // adjusted accordingly. Note that this method is lossy. 482 | // Returns false in case of error. 483 | WEBP_EXTERN(int) WebPPictureARGBToYUVA(WebPPicture* picture, 484 | WebPEncCSP /*colorspace = WEBP_YUV420*/); 485 | 486 | // Same as WebPPictureARGBToYUVA(), but the conversion is done using 487 | // pseudo-random dithering with a strength 'dithering' between 488 | // 0.0 (no dithering) and 1.0 (maximum dithering). This is useful 489 | // for photographic picture. 490 | WEBP_EXTERN(int) WebPPictureARGBToYUVADithered( 491 | WebPPicture* picture, WebPEncCSP colorspace, float dithering); 492 | 493 | // Performs 'sharp' RGBA->YUVA420 downsampling and colorspace conversion. 494 | // Downsampling is handled with extra care in case of color clipping. This 495 | // method is roughly 2x slower than WebPPictureARGBToYUVA() but produces better 496 | // and sharper YUV representation. 497 | // Returns false in case of error. 498 | WEBP_EXTERN(int) WebPPictureSharpARGBToYUVA(WebPPicture* picture); 499 | // kept for backward compatibility: 500 | WEBP_EXTERN(int) WebPPictureSmartARGBToYUVA(WebPPicture* picture); 501 | 502 | // Converts picture->yuv to picture->argb and sets picture->use_argb to true. 503 | // The input format must be YUV_420 or YUV_420A. The conversion from YUV420 to 504 | // ARGB incurs a small loss too. 505 | // Note that the use of this colorspace is discouraged if one has access to the 506 | // raw ARGB samples, since using YUV420 is comparatively lossy. 507 | // Returns false in case of error. 508 | WEBP_EXTERN(int) WebPPictureYUVAToARGB(WebPPicture* picture); 509 | 510 | // Helper function: given a width x height plane of RGBA or YUV(A) samples 511 | // clean-up the YUV or RGB samples under fully transparent area, to help 512 | // compressibility (no guarantee, though). 513 | WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* picture); 514 | 515 | // Scan the picture 'picture' for the presence of non fully opaque alpha values. 516 | // Returns true in such case. Otherwise returns false (indicating that the 517 | // alpha plane can be ignored altogether e.g.). 518 | WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* picture); 519 | 520 | // Remove the transparency information (if present) by blending the color with 521 | // the background color 'background_rgb' (specified as 24bit RGB triplet). 522 | // After this call, all alpha values are reset to 0xff. 523 | WEBP_EXTERN(void) WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb); 524 | 525 | //------------------------------------------------------------------------------ 526 | // Main call 527 | 528 | // Main encoding call, after config and picture have been initialized. 529 | // 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION), 530 | // and the 'config' object must be a valid one. 531 | // Returns false in case of error, true otherwise. 532 | // In case of error, picture->error_code is updated accordingly. 533 | // 'picture' can hold the source samples in both YUV(A) or ARGB input, depending 534 | // on the value of 'picture->use_argb'. It is highly recommended to use 535 | // the former for lossy encoding, and the latter for lossless encoding 536 | // (when config.lossless is true). Automatic conversion from one format to 537 | // another is provided but they both incur some loss. 538 | WEBP_EXTERN(int) WebPEncode(const WebPConfig* config, WebPPicture* picture); 539 | 540 | //------------------------------------------------------------------------------ 541 | 542 | #ifdef __cplusplus 543 | } // extern "C" 544 | #endif 545 | 546 | #endif /* WEBP_WEBP_ENCODE_H_ */ 547 | -------------------------------------------------------------------------------- /WebpQuickLook/webp/format_constants.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 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 | // Internal header for constants related to WebP file format. 11 | // 12 | // Author: Urvang (urvang@google.com) 13 | 14 | #ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_ 15 | #define WEBP_WEBP_FORMAT_CONSTANTS_H_ 16 | 17 | // Create fourcc of the chunk from the chunk tag characters. 18 | #define MKFOURCC(a, b, c, d) ((a) | (b) << 8 | (c) << 16 | (uint32_t)(d) << 24) 19 | 20 | // VP8 related constants. 21 | #define VP8_SIGNATURE 0x9d012a // Signature in VP8 data. 22 | #define VP8_MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition 23 | #define VP8_MAX_PARTITION_SIZE (1 << 24) // max size for token partition 24 | #define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data. 25 | 26 | // VP8L related constants. 27 | #define VP8L_SIGNATURE_SIZE 1 // VP8L signature size. 28 | #define VP8L_MAGIC_BYTE 0x2f // VP8L signature byte. 29 | #define VP8L_IMAGE_SIZE_BITS 14 // Number of bits used to store 30 | // width and height. 31 | #define VP8L_VERSION_BITS 3 // 3 bits reserved for version. 32 | #define VP8L_VERSION 0 // version 0 33 | #define VP8L_FRAME_HEADER_SIZE 5 // Size of the VP8L frame header. 34 | 35 | #define MAX_PALETTE_SIZE 256 36 | #define MAX_CACHE_BITS 11 37 | #define HUFFMAN_CODES_PER_META_CODE 5 38 | #define ARGB_BLACK 0xff000000 39 | 40 | #define DEFAULT_CODE_LENGTH 8 41 | #define MAX_ALLOWED_CODE_LENGTH 15 42 | 43 | #define NUM_LITERAL_CODES 256 44 | #define NUM_LENGTH_CODES 24 45 | #define NUM_DISTANCE_CODES 40 46 | #define CODE_LENGTH_CODES 19 47 | 48 | #define MIN_HUFFMAN_BITS 2 // min number of Huffman bits 49 | #define MAX_HUFFMAN_BITS 9 // max number of Huffman bits 50 | 51 | #define TRANSFORM_PRESENT 1 // The bit to be written when next data 52 | // to be read is a transform. 53 | #define NUM_TRANSFORMS 4 // Maximum number of allowed transform 54 | // in a bitstream. 55 | typedef enum { 56 | PREDICTOR_TRANSFORM = 0, 57 | CROSS_COLOR_TRANSFORM = 1, 58 | SUBTRACT_GREEN = 2, 59 | COLOR_INDEXING_TRANSFORM = 3 60 | } VP8LImageTransformType; 61 | 62 | // Alpha related constants. 63 | #define ALPHA_HEADER_LEN 1 64 | #define ALPHA_NO_COMPRESSION 0 65 | #define ALPHA_LOSSLESS_COMPRESSION 1 66 | #define ALPHA_PREPROCESSED_LEVELS 1 67 | 68 | // Mux related constants. 69 | #define TAG_SIZE 4 // Size of a chunk tag (e.g. "VP8L"). 70 | #define CHUNK_SIZE_BYTES 4 // Size needed to store chunk's size. 71 | #define CHUNK_HEADER_SIZE 8 // Size of a chunk header. 72 | #define RIFF_HEADER_SIZE 12 // Size of the RIFF header ("RIFFnnnnWEBP"). 73 | #define ANMF_CHUNK_SIZE 16 // Size of an ANMF chunk. 74 | #define ANIM_CHUNK_SIZE 6 // Size of an ANIM chunk. 75 | #define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk. 76 | 77 | #define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height. 78 | #define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height. 79 | #define MAX_LOOP_COUNT (1 << 16) // maximum value for loop-count 80 | #define MAX_DURATION (1 << 24) // maximum duration 81 | #define MAX_POSITION_OFFSET (1 << 24) // maximum frame x/y offset 82 | 83 | // Maximum chunk payload is such that adding the header and padding won't 84 | // overflow a uint32_t. 85 | #define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1) 86 | 87 | #endif /* WEBP_WEBP_FORMAT_CONSTANTS_H_ */ 88 | -------------------------------------------------------------------------------- /WebpQuickLook/webp/mux.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 | // RIFF container manipulation and encoding for WebP images. 11 | // 12 | // Authors: Urvang (urvang@google.com) 13 | // Vikas (vikasa@google.com) 14 | 15 | #ifndef WEBP_WEBP_MUX_H_ 16 | #define WEBP_WEBP_MUX_H_ 17 | 18 | #include "./mux_types.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #define WEBP_MUX_ABI_VERSION 0x0108 // MAJOR(8b) + MINOR(8b) 25 | 26 | //------------------------------------------------------------------------------ 27 | // Mux API 28 | // 29 | // This API allows manipulation of WebP container images containing features 30 | // like color profile, metadata, animation. 31 | // 32 | // Code Example#1: Create a WebPMux object with image data, color profile and 33 | // XMP metadata. 34 | /* 35 | int copy_data = 0; 36 | WebPMux* mux = WebPMuxNew(); 37 | // ... (Prepare image data). 38 | WebPMuxSetImage(mux, &image, copy_data); 39 | // ... (Prepare ICCP color profile data). 40 | WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data); 41 | // ... (Prepare XMP metadata). 42 | WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data); 43 | // Get data from mux in WebP RIFF format. 44 | WebPMuxAssemble(mux, &output_data); 45 | WebPMuxDelete(mux); 46 | // ... (Consume output_data; e.g. write output_data.bytes to file). 47 | WebPDataClear(&output_data); 48 | */ 49 | 50 | // Code Example#2: Get image and color profile data from a WebP file. 51 | /* 52 | int copy_data = 0; 53 | // ... (Read data from file). 54 | WebPMux* mux = WebPMuxCreate(&data, copy_data); 55 | WebPMuxGetFrame(mux, 1, &image); 56 | // ... (Consume image; e.g. call WebPDecode() to decode the data). 57 | WebPMuxGetChunk(mux, "ICCP", &icc_profile); 58 | // ... (Consume icc_data). 59 | WebPMuxDelete(mux); 60 | free(data); 61 | */ 62 | 63 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 64 | // the types are left here for reference. 65 | // typedef enum WebPMuxError WebPMuxError; 66 | // typedef enum WebPChunkId WebPChunkId; 67 | typedef struct WebPMux WebPMux; // main opaque object. 68 | typedef struct WebPMuxFrameInfo WebPMuxFrameInfo; 69 | typedef struct WebPMuxAnimParams WebPMuxAnimParams; 70 | typedef struct WebPAnimEncoderOptions WebPAnimEncoderOptions; 71 | 72 | // Error codes 73 | typedef enum WebPMuxError { 74 | WEBP_MUX_OK = 1, 75 | WEBP_MUX_NOT_FOUND = 0, 76 | WEBP_MUX_INVALID_ARGUMENT = -1, 77 | WEBP_MUX_BAD_DATA = -2, 78 | WEBP_MUX_MEMORY_ERROR = -3, 79 | WEBP_MUX_NOT_ENOUGH_DATA = -4 80 | } WebPMuxError; 81 | 82 | // IDs for different types of chunks. 83 | typedef enum WebPChunkId { 84 | WEBP_CHUNK_VP8X, // VP8X 85 | WEBP_CHUNK_ICCP, // ICCP 86 | WEBP_CHUNK_ANIM, // ANIM 87 | WEBP_CHUNK_ANMF, // ANMF 88 | WEBP_CHUNK_DEPRECATED, // (deprecated from FRGM) 89 | WEBP_CHUNK_ALPHA, // ALPH 90 | WEBP_CHUNK_IMAGE, // VP8/VP8L 91 | WEBP_CHUNK_EXIF, // EXIF 92 | WEBP_CHUNK_XMP, // XMP 93 | WEBP_CHUNK_UNKNOWN, // Other chunks. 94 | WEBP_CHUNK_NIL 95 | } WebPChunkId; 96 | 97 | //------------------------------------------------------------------------------ 98 | 99 | // Returns the version number of the mux library, packed in hexadecimal using 100 | // 8bits for each of major/minor/revision. E.g: v2.5.7 is 0x020507. 101 | WEBP_EXTERN(int) WebPGetMuxVersion(void); 102 | 103 | //------------------------------------------------------------------------------ 104 | // Life of a Mux object 105 | 106 | // Internal, version-checked, entry point 107 | WEBP_EXTERN(WebPMux*) WebPNewInternal(int); 108 | 109 | // Creates an empty mux object. 110 | // Returns: 111 | // A pointer to the newly created empty mux object. 112 | // Or NULL in case of memory error. 113 | static WEBP_INLINE WebPMux* WebPMuxNew(void) { 114 | return WebPNewInternal(WEBP_MUX_ABI_VERSION); 115 | } 116 | 117 | // Deletes the mux object. 118 | // Parameters: 119 | // mux - (in/out) object to be deleted 120 | WEBP_EXTERN(void) WebPMuxDelete(WebPMux* mux); 121 | 122 | //------------------------------------------------------------------------------ 123 | // Mux creation. 124 | 125 | // Internal, version-checked, entry point 126 | WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData*, int, int); 127 | 128 | // Creates a mux object from raw data given in WebP RIFF format. 129 | // Parameters: 130 | // bitstream - (in) the bitstream data in WebP RIFF format 131 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux 132 | // object and value 0 indicates data will NOT be copied. 133 | // Returns: 134 | // A pointer to the mux object created from given data - on success. 135 | // NULL - In case of invalid data or memory error. 136 | static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream, 137 | int copy_data) { 138 | return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION); 139 | } 140 | 141 | //------------------------------------------------------------------------------ 142 | // Non-image chunks. 143 | 144 | // Note: Only non-image related chunks should be managed through chunk APIs. 145 | // (Image related chunks are: "ANMF", "VP8 ", "VP8L" and "ALPH"). 146 | // To add, get and delete images, use WebPMuxSetImage(), WebPMuxPushFrame(), 147 | // WebPMuxGetFrame() and WebPMuxDeleteFrame(). 148 | 149 | // Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object. 150 | // Any existing chunk(s) with the same id will be removed. 151 | // Parameters: 152 | // mux - (in/out) object to which the chunk is to be added 153 | // fourcc - (in) a character array containing the fourcc of the given chunk; 154 | // e.g., "ICCP", "XMP ", "EXIF" etc. 155 | // chunk_data - (in) the chunk data to be added 156 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux 157 | // object and value 0 indicates data will NOT be copied. 158 | // Returns: 159 | // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL 160 | // or if fourcc corresponds to an image chunk. 161 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 162 | // WEBP_MUX_OK - on success. 163 | WEBP_EXTERN(WebPMuxError) WebPMuxSetChunk( 164 | WebPMux* mux, const char fourcc[4], const WebPData* chunk_data, 165 | int copy_data); 166 | 167 | // Gets a reference to the data of the chunk with id 'fourcc' in the mux object. 168 | // The caller should NOT free the returned data. 169 | // Parameters: 170 | // mux - (in) object from which the chunk data is to be fetched 171 | // fourcc - (in) a character array containing the fourcc of the chunk; 172 | // e.g., "ICCP", "XMP ", "EXIF" etc. 173 | // chunk_data - (out) returned chunk data 174 | // Returns: 175 | // WEBP_MUX_INVALID_ARGUMENT - if mux, fourcc or chunk_data is NULL 176 | // or if fourcc corresponds to an image chunk. 177 | // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id. 178 | // WEBP_MUX_OK - on success. 179 | WEBP_EXTERN(WebPMuxError) WebPMuxGetChunk( 180 | const WebPMux* mux, const char fourcc[4], WebPData* chunk_data); 181 | 182 | // Deletes the chunk with the given 'fourcc' from the mux object. 183 | // Parameters: 184 | // mux - (in/out) object from which the chunk is to be deleted 185 | // fourcc - (in) a character array containing the fourcc of the chunk; 186 | // e.g., "ICCP", "XMP ", "EXIF" etc. 187 | // Returns: 188 | // WEBP_MUX_INVALID_ARGUMENT - if mux or fourcc is NULL 189 | // or if fourcc corresponds to an image chunk. 190 | // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc. 191 | // WEBP_MUX_OK - on success. 192 | WEBP_EXTERN(WebPMuxError) WebPMuxDeleteChunk( 193 | WebPMux* mux, const char fourcc[4]); 194 | 195 | //------------------------------------------------------------------------------ 196 | // Images. 197 | 198 | // Encapsulates data about a single frame. 199 | struct WebPMuxFrameInfo { 200 | WebPData bitstream; // image data: can be a raw VP8/VP8L bitstream 201 | // or a single-image WebP file. 202 | int x_offset; // x-offset of the frame. 203 | int y_offset; // y-offset of the frame. 204 | int duration; // duration of the frame (in milliseconds). 205 | 206 | WebPChunkId id; // frame type: should be one of WEBP_CHUNK_ANMF 207 | // or WEBP_CHUNK_IMAGE 208 | WebPMuxAnimDispose dispose_method; // Disposal method for the frame. 209 | WebPMuxAnimBlend blend_method; // Blend operation for the frame. 210 | uint32_t pad[1]; // padding for later use 211 | }; 212 | 213 | // Sets the (non-animated) image in the mux object. 214 | // Note: Any existing images (including frames) will be removed. 215 | // Parameters: 216 | // mux - (in/out) object in which the image is to be set 217 | // bitstream - (in) can be a raw VP8/VP8L bitstream or a single-image 218 | // WebP file (non-animated) 219 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux 220 | // object and value 0 indicates data will NOT be copied. 221 | // Returns: 222 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL. 223 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 224 | // WEBP_MUX_OK - on success. 225 | WEBP_EXTERN(WebPMuxError) WebPMuxSetImage( 226 | WebPMux* mux, const WebPData* bitstream, int copy_data); 227 | 228 | // Adds a frame at the end of the mux object. 229 | // Notes: (1) frame.id should be WEBP_CHUNK_ANMF 230 | // (2) For setting a non-animated image, use WebPMuxSetImage() instead. 231 | // (3) Type of frame being pushed must be same as the frames in mux. 232 | // (4) As WebP only supports even offsets, any odd offset will be snapped 233 | // to an even location using: offset &= ~1 234 | // Parameters: 235 | // mux - (in/out) object to which the frame is to be added 236 | // frame - (in) frame data. 237 | // copy_data - (in) value 1 indicates given data WILL be copied to the mux 238 | // object and value 0 indicates data will NOT be copied. 239 | // Returns: 240 | // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL 241 | // or if content of 'frame' is invalid. 242 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 243 | // WEBP_MUX_OK - on success. 244 | WEBP_EXTERN(WebPMuxError) WebPMuxPushFrame( 245 | WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data); 246 | 247 | // Gets the nth frame from the mux object. 248 | // The content of 'frame->bitstream' is allocated using malloc(), and NOT 249 | // owned by the 'mux' object. It MUST be deallocated by the caller by calling 250 | // WebPDataClear(). 251 | // nth=0 has a special meaning - last position. 252 | // Parameters: 253 | // mux - (in) object from which the info is to be fetched 254 | // nth - (in) index of the frame in the mux object 255 | // frame - (out) data of the returned frame 256 | // Returns: 257 | // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL. 258 | // WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object. 259 | // WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid. 260 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 261 | // WEBP_MUX_OK - on success. 262 | WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame( 263 | const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame); 264 | 265 | // Deletes a frame from the mux object. 266 | // nth=0 has a special meaning - last position. 267 | // Parameters: 268 | // mux - (in/out) object from which a frame is to be deleted 269 | // nth - (in) The position from which the frame is to be deleted 270 | // Returns: 271 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL. 272 | // WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object 273 | // before deletion. 274 | // WEBP_MUX_OK - on success. 275 | WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth); 276 | 277 | //------------------------------------------------------------------------------ 278 | // Animation. 279 | 280 | // Animation parameters. 281 | struct WebPMuxAnimParams { 282 | uint32_t bgcolor; // Background color of the canvas stored (in MSB order) as: 283 | // Bits 00 to 07: Alpha. 284 | // Bits 08 to 15: Red. 285 | // Bits 16 to 23: Green. 286 | // Bits 24 to 31: Blue. 287 | int loop_count; // Number of times to repeat the animation [0 = infinite]. 288 | }; 289 | 290 | // Sets the animation parameters in the mux object. Any existing ANIM chunks 291 | // will be removed. 292 | // Parameters: 293 | // mux - (in/out) object in which ANIM chunk is to be set/added 294 | // params - (in) animation parameters. 295 | // Returns: 296 | // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL. 297 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 298 | // WEBP_MUX_OK - on success. 299 | WEBP_EXTERN(WebPMuxError) WebPMuxSetAnimationParams( 300 | WebPMux* mux, const WebPMuxAnimParams* params); 301 | 302 | // Gets the animation parameters from the mux object. 303 | // Parameters: 304 | // mux - (in) object from which the animation parameters to be fetched 305 | // params - (out) animation parameters extracted from the ANIM chunk 306 | // Returns: 307 | // WEBP_MUX_INVALID_ARGUMENT - if mux or params is NULL. 308 | // WEBP_MUX_NOT_FOUND - if ANIM chunk is not present in mux object. 309 | // WEBP_MUX_OK - on success. 310 | WEBP_EXTERN(WebPMuxError) WebPMuxGetAnimationParams( 311 | const WebPMux* mux, WebPMuxAnimParams* params); 312 | 313 | //------------------------------------------------------------------------------ 314 | // Misc Utilities. 315 | 316 | // Sets the canvas size for the mux object. The width and height can be 317 | // specified explicitly or left as zero (0, 0). 318 | // * When width and height are specified explicitly, then this frame bound is 319 | // enforced during subsequent calls to WebPMuxAssemble() and an error is 320 | // reported if any animated frame does not completely fit within the canvas. 321 | // * When unspecified (0, 0), the constructed canvas will get the frame bounds 322 | // from the bounding-box over all frames after calling WebPMuxAssemble(). 323 | // Parameters: 324 | // mux - (in) object to which the canvas size is to be set 325 | // width - (in) canvas width 326 | // height - (in) canvas height 327 | // Returns: 328 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL; or 329 | // width or height are invalid or out of bounds 330 | // WEBP_MUX_OK - on success. 331 | WEBP_EXTERN(WebPMuxError) WebPMuxSetCanvasSize(WebPMux* mux, 332 | int width, int height); 333 | 334 | // Gets the canvas size from the mux object. 335 | // Note: This method assumes that the VP8X chunk, if present, is up-to-date. 336 | // That is, the mux object hasn't been modified since the last call to 337 | // WebPMuxAssemble() or WebPMuxCreate(). 338 | // Parameters: 339 | // mux - (in) object from which the canvas size is to be fetched 340 | // width - (out) canvas width 341 | // height - (out) canvas height 342 | // Returns: 343 | // WEBP_MUX_INVALID_ARGUMENT - if mux, width or height is NULL. 344 | // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid. 345 | // WEBP_MUX_OK - on success. 346 | WEBP_EXTERN(WebPMuxError) WebPMuxGetCanvasSize(const WebPMux* mux, 347 | int* width, int* height); 348 | 349 | // Gets the feature flags from the mux object. 350 | // Note: This method assumes that the VP8X chunk, if present, is up-to-date. 351 | // That is, the mux object hasn't been modified since the last call to 352 | // WebPMuxAssemble() or WebPMuxCreate(). 353 | // Parameters: 354 | // mux - (in) object from which the features are to be fetched 355 | // flags - (out) the flags specifying which features are present in the 356 | // mux object. This will be an OR of various flag values. 357 | // Enum 'WebPFeatureFlags' can be used to test individual flag values. 358 | // Returns: 359 | // WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL. 360 | // WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid. 361 | // WEBP_MUX_OK - on success. 362 | WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux, 363 | uint32_t* flags); 364 | 365 | // Gets number of chunks with the given 'id' in the mux object. 366 | // Parameters: 367 | // mux - (in) object from which the info is to be fetched 368 | // id - (in) chunk id specifying the type of chunk 369 | // num_elements - (out) number of chunks with the given chunk id 370 | // Returns: 371 | // WEBP_MUX_INVALID_ARGUMENT - if mux, or num_elements is NULL. 372 | // WEBP_MUX_OK - on success. 373 | WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* mux, 374 | WebPChunkId id, int* num_elements); 375 | 376 | // Assembles all chunks in WebP RIFF format and returns in 'assembled_data'. 377 | // This function also validates the mux object. 378 | // Note: The content of 'assembled_data' will be ignored and overwritten. 379 | // Also, the content of 'assembled_data' is allocated using malloc(), and NOT 380 | // owned by the 'mux' object. It MUST be deallocated by the caller by calling 381 | // WebPDataClear(). It's always safe to call WebPDataClear() upon return, 382 | // even in case of error. 383 | // Parameters: 384 | // mux - (in/out) object whose chunks are to be assembled 385 | // assembled_data - (out) assembled WebP data 386 | // Returns: 387 | // WEBP_MUX_BAD_DATA - if mux object is invalid. 388 | // WEBP_MUX_INVALID_ARGUMENT - if mux or assembled_data is NULL. 389 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 390 | // WEBP_MUX_OK - on success. 391 | WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* mux, 392 | WebPData* assembled_data); 393 | 394 | //------------------------------------------------------------------------------ 395 | // WebPAnimEncoder API 396 | // 397 | // This API allows encoding (possibly) animated WebP images. 398 | // 399 | // Code Example: 400 | /* 401 | WebPAnimEncoderOptions enc_options; 402 | WebPAnimEncoderOptionsInit(&enc_options); 403 | // Tune 'enc_options' as needed. 404 | WebPAnimEncoder* enc = WebPAnimEncoderNew(width, height, &enc_options); 405 | while() { 406 | WebPConfig config; 407 | WebPConfigInit(&config); 408 | // Tune 'config' as needed. 409 | WebPAnimEncoderAdd(enc, frame, timestamp_ms, &config); 410 | } 411 | WebPAnimEncoderAdd(enc, NULL, timestamp_ms, NULL); 412 | WebPAnimEncoderAssemble(enc, webp_data); 413 | WebPAnimEncoderDelete(enc); 414 | // Write the 'webp_data' to a file, or re-mux it further. 415 | */ 416 | 417 | typedef struct WebPAnimEncoder WebPAnimEncoder; // Main opaque object. 418 | 419 | // Forward declarations. Defined in encode.h. 420 | struct WebPPicture; 421 | struct WebPConfig; 422 | 423 | // Global options. 424 | struct WebPAnimEncoderOptions { 425 | WebPMuxAnimParams anim_params; // Animation parameters. 426 | int minimize_size; // If true, minimize the output size (slow). Implicitly 427 | // disables key-frame insertion. 428 | int kmin; 429 | int kmax; // Minimum and maximum distance between consecutive key 430 | // frames in the output. The library may insert some key 431 | // frames as needed to satisfy this criteria. 432 | // Note that these conditions should hold: kmax > kmin 433 | // and kmin >= kmax / 2 + 1. Also, if kmax <= 0, then 434 | // key-frame insertion is disabled; and if kmax == 1, 435 | // then all frames will be key-frames (kmin value does 436 | // not matter for these special cases). 437 | int allow_mixed; // If true, use mixed compression mode; may choose 438 | // either lossy and lossless for each frame. 439 | int verbose; // If true, print info and warning messages to stderr. 440 | 441 | uint32_t padding[4]; // Padding for later use. 442 | }; 443 | 444 | // Internal, version-checked, entry point. 445 | WEBP_EXTERN(int) WebPAnimEncoderOptionsInitInternal( 446 | WebPAnimEncoderOptions*, int); 447 | 448 | // Should always be called, to initialize a fresh WebPAnimEncoderOptions 449 | // structure before modification. Returns false in case of version mismatch. 450 | // WebPAnimEncoderOptionsInit() must have succeeded before using the 451 | // 'enc_options' object. 452 | static WEBP_INLINE int WebPAnimEncoderOptionsInit( 453 | WebPAnimEncoderOptions* enc_options) { 454 | return WebPAnimEncoderOptionsInitInternal(enc_options, WEBP_MUX_ABI_VERSION); 455 | } 456 | 457 | // Internal, version-checked, entry point. 458 | WEBP_EXTERN(WebPAnimEncoder*) WebPAnimEncoderNewInternal( 459 | int, int, const WebPAnimEncoderOptions*, int); 460 | 461 | // Creates and initializes a WebPAnimEncoder object. 462 | // Parameters: 463 | // width/height - (in) canvas width and height of the animation. 464 | // enc_options - (in) encoding options; can be passed NULL to pick 465 | // reasonable defaults. 466 | // Returns: 467 | // A pointer to the newly created WebPAnimEncoder object. 468 | // Or NULL in case of memory error. 469 | static WEBP_INLINE WebPAnimEncoder* WebPAnimEncoderNew( 470 | int width, int height, const WebPAnimEncoderOptions* enc_options) { 471 | return WebPAnimEncoderNewInternal(width, height, enc_options, 472 | WEBP_MUX_ABI_VERSION); 473 | } 474 | 475 | // Optimize the given frame for WebP, encode it and add it to the 476 | // WebPAnimEncoder object. 477 | // The last call to 'WebPAnimEncoderAdd' should be with frame = NULL, which 478 | // indicates that no more frames are to be added. This call is also used to 479 | // determine the duration of the last frame. 480 | // Parameters: 481 | // enc - (in/out) object to which the frame is to be added. 482 | // frame - (in/out) frame data in ARGB or YUV(A) format. If it is in YUV(A) 483 | // format, it will be converted to ARGB, which incurs a small loss. 484 | // timestamp_ms - (in) timestamp of this frame in milliseconds. 485 | // Duration of a frame would be calculated as 486 | // "timestamp of next frame - timestamp of this frame". 487 | // Hence, timestamps should be in non-decreasing order. 488 | // config - (in) encoding options; can be passed NULL to pick 489 | // reasonable defaults. 490 | // Returns: 491 | // On error, returns false and frame->error_code is set appropriately. 492 | // Otherwise, returns true. 493 | WEBP_EXTERN(int) WebPAnimEncoderAdd( 494 | WebPAnimEncoder* enc, struct WebPPicture* frame, int timestamp_ms, 495 | const struct WebPConfig* config); 496 | 497 | // Assemble all frames added so far into a WebP bitstream. 498 | // This call should be preceded by a call to 'WebPAnimEncoderAdd' with 499 | // frame = NULL; if not, the duration of the last frame will be internally 500 | // estimated. 501 | // Parameters: 502 | // enc - (in/out) object from which the frames are to be assembled. 503 | // webp_data - (out) generated WebP bitstream. 504 | // Returns: 505 | // True on success. 506 | WEBP_EXTERN(int) WebPAnimEncoderAssemble(WebPAnimEncoder* enc, 507 | WebPData* webp_data); 508 | 509 | // Get error string corresponding to the most recent call using 'enc'. The 510 | // returned string is owned by 'enc' and is valid only until the next call to 511 | // WebPAnimEncoderAdd() or WebPAnimEncoderAssemble() or WebPAnimEncoderDelete(). 512 | // Parameters: 513 | // enc - (in/out) object from which the error string is to be fetched. 514 | // Returns: 515 | // NULL if 'enc' is NULL. Otherwise, returns the error string if the last call 516 | // to 'enc' had an error, or an empty string if the last call was a success. 517 | WEBP_EXTERN(const char*) WebPAnimEncoderGetError(WebPAnimEncoder* enc); 518 | 519 | // Deletes the WebPAnimEncoder object. 520 | // Parameters: 521 | // enc - (in/out) object to be deleted 522 | WEBP_EXTERN(void) WebPAnimEncoderDelete(WebPAnimEncoder* enc); 523 | 524 | //------------------------------------------------------------------------------ 525 | 526 | #ifdef __cplusplus 527 | } // extern "C" 528 | #endif 529 | 530 | #endif /* WEBP_WEBP_MUX_H_ */ 531 | -------------------------------------------------------------------------------- /WebpQuickLook/webp/mux_types.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 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 | // Data-types common to the mux and demux libraries. 11 | // 12 | // Author: Urvang (urvang@google.com) 13 | 14 | #ifndef WEBP_WEBP_MUX_TYPES_H_ 15 | #define WEBP_WEBP_MUX_TYPES_H_ 16 | 17 | #include // free() 18 | #include // memset() 19 | #include "./types.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 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 WebPFeatureFlags WebPFeatureFlags; 28 | // typedef enum WebPMuxAnimDispose WebPMuxAnimDispose; 29 | // typedef enum WebPMuxAnimBlend WebPMuxAnimBlend; 30 | typedef struct WebPData WebPData; 31 | 32 | // VP8X Feature Flags. 33 | typedef enum WebPFeatureFlags { 34 | ANIMATION_FLAG = 0x00000002, 35 | XMP_FLAG = 0x00000004, 36 | EXIF_FLAG = 0x00000008, 37 | ALPHA_FLAG = 0x00000010, 38 | ICCP_FLAG = 0x00000020, 39 | 40 | ALL_VALID_FLAGS = 0x0000003e 41 | } WebPFeatureFlags; 42 | 43 | // Dispose method (animation only). Indicates how the area used by the current 44 | // frame is to be treated before rendering the next frame on the canvas. 45 | typedef enum WebPMuxAnimDispose { 46 | WEBP_MUX_DISPOSE_NONE, // Do not dispose. 47 | WEBP_MUX_DISPOSE_BACKGROUND // Dispose to background color. 48 | } WebPMuxAnimDispose; 49 | 50 | // Blend operation (animation only). Indicates how transparent pixels of the 51 | // current frame are blended with those of the previous canvas. 52 | typedef enum WebPMuxAnimBlend { 53 | WEBP_MUX_BLEND, // Blend. 54 | WEBP_MUX_NO_BLEND // Do not blend. 55 | } WebPMuxAnimBlend; 56 | 57 | // Data type used to describe 'raw' data, e.g., chunk data 58 | // (ICC profile, metadata) and WebP compressed image data. 59 | struct WebPData { 60 | const uint8_t* bytes; 61 | size_t size; 62 | }; 63 | 64 | // Initializes the contents of the 'webp_data' object with default values. 65 | static WEBP_INLINE void WebPDataInit(WebPData* webp_data) { 66 | if (webp_data != NULL) { 67 | memset(webp_data, 0, sizeof(*webp_data)); 68 | } 69 | } 70 | 71 | // Clears the contents of the 'webp_data' object by calling free(). Does not 72 | // deallocate the object itself. 73 | static WEBP_INLINE void WebPDataClear(WebPData* webp_data) { 74 | if (webp_data != NULL) { 75 | free((void*)webp_data->bytes); 76 | WebPDataInit(webp_data); 77 | } 78 | } 79 | 80 | // Allocates necessary storage for 'dst' and copies the contents of 'src'. 81 | // Returns true on success. 82 | static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) { 83 | if (src == NULL || dst == NULL) return 0; 84 | WebPDataInit(dst); 85 | if (src->bytes != NULL && src->size != 0) { 86 | dst->bytes = (uint8_t*)malloc(src->size); 87 | if (dst->bytes == NULL) return 0; 88 | memcpy((void*)dst->bytes, src->bytes, src->size); 89 | dst->size = src->size; 90 | } 91 | return 1; 92 | } 93 | 94 | #ifdef __cplusplus 95 | } // extern "C" 96 | #endif 97 | 98 | #endif /* WEBP_WEBP_MUX_TYPES_H_ */ 99 | -------------------------------------------------------------------------------- /WebpQuickLook/webp/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(type) extern __attribute__ ((visibility ("default"))) type 44 | # else 45 | # define WEBP_EXTERN(type) extern type 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 | -------------------------------------------------------------------------------- /install-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | curl -L https://raw.github.com/emin/WebPQuickLook/master/WebpQuickLook.tar.gz | tar -xvz 3 | sudo mkdir -p /Library/QuickLook/ 4 | sudo mv WebpQuickLook.qlgenerator /Library/QuickLook/ 5 | qlmanage -r 6 | 7 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | curl -L https://raw.github.com/emin/WebPQuickLook/master/WebpQuickLook.tar.gz | tar -xvz 3 | mkdir -p ~/Library/QuickLook/ 4 | mv WebpQuickLook.qlgenerator ~/Library/QuickLook/ 5 | qlmanage -r 6 | 7 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emin/WebPQuickLook/4221460f0cf9b1e850586f72ced301340adc70a4/screenshot.png --------------------------------------------------------------------------------