├── .gitignore ├── English.lproj └── InfoPlist.strings ├── GeneratePreviewForURL.m ├── GenerateThumbnailForURL.m ├── Info.plist ├── LICENSE ├── README.md ├── WebP.xcodeproj └── project.pbxproj ├── WebPImage.h ├── WebPImage.m ├── include └── webp │ ├── decode.h │ ├── decode_vp8.h │ ├── encode.h │ ├── format_constants.h │ ├── mux.h │ └── types.h ├── lib └── libwebp-static.a └── main.c /.gitignore: -------------------------------------------------------------------------------- 1 | Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | 17 | -------------------------------------------------------------------------------- /English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/webp-quicklook/e9c9a66959037f140996e90e031ed0cdca831921/English.lproj/InfoPlist.strings -------------------------------------------------------------------------------- /GeneratePreviewForURL.m: -------------------------------------------------------------------------------- 1 | #import 2 | #include 3 | #include 4 | #include 5 | #import "WebPImage.h" 6 | 7 | /* ----------------------------------------------------------------------------- 8 | Generate a preview for file 9 | 10 | This function's job is to create preview for designated file 11 | ----------------------------------------------------------------------------- */ 12 | 13 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) 14 | { 15 | CGImageRef image = CreateImageForURL(url); 16 | if (image == NULL) { 17 | return -1; 18 | } 19 | CGFloat width = CGImageGetWidth(image); 20 | CGFloat height = CGImageGetHeight(image); 21 | 22 | @autoreleasepool { 23 | NSDictionary *newOpt = [NSDictionary dictionaryWithObjectsAndKeys:(NSString *)[(NSDictionary *)options objectForKey:(NSString *)kQLPreviewPropertyDisplayNameKey], kQLPreviewPropertyDisplayNameKey, [NSNumber numberWithFloat:width], kQLPreviewPropertyWidthKey, [NSNumber numberWithFloat:height], kQLPreviewPropertyHeightKey, nil]; 24 | CGContextRef ctx = QLPreviewRequestCreateContext(preview, CGSizeMake(width, height), YES, (CFDictionaryRef)newOpt); 25 | CGContextDrawImage(ctx, CGRectMake(0,0,width,height), image); 26 | QLPreviewRequestFlushContext(preview, ctx); 27 | CGImageRelease(image); 28 | CGContextRelease(ctx); 29 | } 30 | return noErr; 31 | } 32 | 33 | void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview) 34 | { 35 | // implement only if supported 36 | } 37 | -------------------------------------------------------------------------------- /GenerateThumbnailForURL.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import 6 | #import "WebPImage.h" 7 | 8 | /* ----------------------------------------------------------------------------- 9 | Generate a thumbnail for file 10 | 11 | This function's job is to create thumbnail for designated file as fast as possible 12 | ----------------------------------------------------------------------------- */ 13 | 14 | 15 | 16 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize) 17 | { 18 | CGImageRef image = CreateImageForURL(url); 19 | if (image == NULL) { 20 | return -1; 21 | } 22 | QLThumbnailRequestSetImage(thumbnail, image, nil); 23 | CGImageRelease(image); 24 | return noErr; 25 | } 26 | 27 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail) 28 | { 29 | // implement only if supported 30 | } 31 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeRole 11 | QLGenerator 12 | LSItemContentTypes 13 | 14 | com.google.webp 15 | 16 | 17 | 18 | CFBundleTypeRole 19 | QLGenerator 20 | LSItemContentTypes 21 | 22 | public.webp 23 | 24 | 25 | 26 | CFBundleExecutable 27 | ${EXECUTABLE_NAME} 28 | CFBundleIconFile 29 | 30 | CFBundleIdentifier 31 | com.codingrobots.qlgenerator.${PRODUCT_NAME:identifier} 32 | CFBundleInfoDictionaryVersion 33 | 6.0 34 | CFBundleName 35 | ${PRODUCT_NAME} 36 | CFBundleShortVersionString 37 | 3 38 | CFBundleVersion 39 | 2.2 40 | CFPlugInDynamicRegisterFunction 41 | 42 | CFPlugInDynamicRegistration 43 | NO 44 | CFPlugInFactories 45 | 46 | 9751E920-D39F-4881-969A-03BCE5B273E7 47 | QuickLookGeneratorPluginFactory 48 | 49 | CFPlugInTypes 50 | 51 | 5E2D9680-5022-40FA-B806-43349622E5B9 52 | 53 | 9751E920-D39F-4881-969A-03BCE5B273E7 54 | 55 | 56 | CFPlugInUnloadFunction 57 | 58 | QLNeedsToBeRunInMainThread 59 | 60 | QLPreviewHeight 61 | 600 62 | QLPreviewWidth 63 | 800 64 | QLSupportsConcurrentRequests 65 | 66 | QLThumbnailMinimumSize 67 | 17 68 | UTImportedTypeDeclarations 69 | 70 | 71 | UTTypeConformsTo 72 | 73 | public.image 74 | 75 | UTTypeDescription 76 | WebP image 77 | UTTypeIdentifier 78 | com.google.webp 79 | UTTypeReferenceURL 80 | http://code.google.com/speed/webp/ 81 | UTTypeTagSpecification 82 | 83 | public.filename-extension 84 | 85 | webp 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011, 2012 Dmitry Chestnykh 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WebP QuickLook Plugin 2 | ===================== 3 | 4 | This is an open-source QuickLook plugin to generate thumbnails and previews for [WebP images](http://code.google.com/speed/webp/). Requires Mac OS X 10.7 or later (but tested on 10.8). 5 | 6 | New version supports WebP lossy, lossless, and alpha channels. 7 | 8 | 9 | Installation 10 | ------------ 11 | 12 | Click [Releases](https://github.com/dchest/webp-quicklook/releases) and download the latest version. Unzip it, and put `WebP.qlgenerator` into `~/Library/QuickLook` (or `/Library/QuickLook`). You may need to reboot to enable it (or open Terminal and run `qlmanage -r`). 13 | 14 | 15 | Development Notes 16 | ----------------- 17 | 18 | The plugin uses the precompiled `libwebp.a` (i386, x86\_64; git rev. 2afee60a7) located in `lib`. I build it manually, and haven't yet created a script to build it from sources; patches welcome. 19 | -------------------------------------------------------------------------------- /WebP.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0AE4DF3E136F6C2500079D1E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AE4DF3D136F6C2500079D1E /* Foundation.framework */; }; 11 | 0AE4DF5B136F718C00079D1E /* libwebp-static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AE4DF5A136F718C00079D1E /* libwebp-static.a */; }; 12 | 0AE4DF7A136F758200079D1E /* WebPImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0AE4DF78136F758200079D1E /* WebPImage.h */; }; 13 | 0AE4DF7B136F758200079D1E /* WebPImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AE4DF79136F758200079D1E /* WebPImage.m */; }; 14 | 2C05A19C06CAA52B00D84F6F /* GeneratePreviewForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C05A19B06CAA52B00D84F6F /* GeneratePreviewForURL.m */; }; 15 | 61E3BCFB0870B4F2002186A0 /* GenerateThumbnailForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 61E3BCFA0870B4F2002186A0 /* GenerateThumbnailForURL.m */; }; 16 | 8D576312048677EA00EA77CD /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB77B6FE84183AC02AAC07 /* main.c */; settings = {ATTRIBUTES = (); }; }; 17 | 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; }; 18 | 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; }; 19 | C86B05270671AA6E00DD9006 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C86B05260671AA6E00DD9006 /* CoreServices.framework */; }; 20 | F28CFBFD0A3EC0AF000ABFF5 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F28CFBFC0A3EC0AF000ABFF5 /* ApplicationServices.framework */; }; 21 | F28CFC030A3EC0C6000ABFF5 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F28CFC020A3EC0C6000ABFF5 /* QuickLook.framework */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; 26 | 08FB77B6FE84183AC02AAC07 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 27 | 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 28 | 0AE4DF3D136F6C2500079D1E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 29 | 0AE4DF5A136F718C00079D1E /* libwebp-static.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libwebp-static.a"; path = "lib/libwebp-static.a"; sourceTree = ""; }; 30 | 0AE4DF78136F758200079D1E /* WebPImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPImage.h; sourceTree = ""; }; 31 | 0AE4DF79136F758200079D1E /* WebPImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebPImage.m; sourceTree = ""; }; 32 | 2C05A19B06CAA52B00D84F6F /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratePreviewForURL.m; sourceTree = ""; }; 33 | 61E3BCFA0870B4F2002186A0 /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = GenerateThumbnailForURL.m; sourceTree = ""; }; 34 | 8D576316048677EA00EA77CD /* WebP.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WebP.qlgenerator; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | 8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 36 | C86B05260671AA6E00DD9006 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; 37 | F28CFBFC0A3EC0AF000ABFF5 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = ""; }; 38 | F28CFC020A3EC0C6000ABFF5 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = /System/Library/Frameworks/QuickLook.framework; sourceTree = ""; }; 39 | /* End PBXFileReference section */ 40 | 41 | /* Begin PBXFrameworksBuildPhase section */ 42 | 8D576313048677EA00EA77CD /* Frameworks */ = { 43 | isa = PBXFrameworksBuildPhase; 44 | buildActionMask = 2147483647; 45 | files = ( 46 | 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */, 47 | C86B05270671AA6E00DD9006 /* CoreServices.framework in Frameworks */, 48 | F28CFBFD0A3EC0AF000ABFF5 /* ApplicationServices.framework in Frameworks */, 49 | F28CFC030A3EC0C6000ABFF5 /* QuickLook.framework in Frameworks */, 50 | 0AE4DF3E136F6C2500079D1E /* Foundation.framework in Frameworks */, 51 | 0AE4DF5B136F718C00079D1E /* libwebp-static.a in Frameworks */, 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 089C166AFE841209C02AAC07 /* WebP */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 08FB77AFFE84173DC02AAC07 /* Source */, 62 | 089C167CFE841241C02AAC07 /* Resources */, 63 | 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, 64 | 19C28FB6FE9D52B211CA2CBB /* Products */, 65 | ); 66 | name = WebP; 67 | sourceTree = ""; 68 | }; 69 | 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 0AE4DF5A136F718C00079D1E /* libwebp-static.a */, 73 | F28CFC020A3EC0C6000ABFF5 /* QuickLook.framework */, 74 | F28CFBFC0A3EC0AF000ABFF5 /* ApplicationServices.framework */, 75 | C86B05260671AA6E00DD9006 /* CoreServices.framework */, 76 | 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */, 77 | 0AE4DF3D136F6C2500079D1E /* Foundation.framework */, 78 | ); 79 | name = "External Frameworks and Libraries"; 80 | sourceTree = ""; 81 | }; 82 | 089C167CFE841241C02AAC07 /* Resources */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 8D576317048677EA00EA77CD /* Info.plist */, 86 | 8D5B49A704867FD3000E48DA /* InfoPlist.strings */, 87 | ); 88 | name = Resources; 89 | sourceTree = ""; 90 | }; 91 | 08FB77AFFE84173DC02AAC07 /* Source */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 61E3BCFA0870B4F2002186A0 /* GenerateThumbnailForURL.m */, 95 | 2C05A19B06CAA52B00D84F6F /* GeneratePreviewForURL.m */, 96 | 08FB77B6FE84183AC02AAC07 /* main.c */, 97 | 0AE4DF78136F758200079D1E /* WebPImage.h */, 98 | 0AE4DF79136F758200079D1E /* WebPImage.m */, 99 | ); 100 | name = Source; 101 | sourceTree = ""; 102 | }; 103 | 19C28FB6FE9D52B211CA2CBB /* Products */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 8D576316048677EA00EA77CD /* WebP.qlgenerator */, 107 | ); 108 | name = Products; 109 | sourceTree = ""; 110 | }; 111 | /* End PBXGroup section */ 112 | 113 | /* Begin PBXHeadersBuildPhase section */ 114 | 8D57630E048677EA00EA77CD /* Headers */ = { 115 | isa = PBXHeadersBuildPhase; 116 | buildActionMask = 2147483647; 117 | files = ( 118 | 0AE4DF7A136F758200079D1E /* WebPImage.h in Headers */, 119 | ); 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | /* End PBXHeadersBuildPhase section */ 123 | 124 | /* Begin PBXNativeTarget section */ 125 | 8D57630D048677EA00EA77CD /* WebP */ = { 126 | isa = PBXNativeTarget; 127 | buildConfigurationList = 2CA3261E0896AD4900168862 /* Build configuration list for PBXNativeTarget "WebP" */; 128 | buildPhases = ( 129 | 8D57630E048677EA00EA77CD /* Headers */, 130 | 8D57630F048677EA00EA77CD /* Resources */, 131 | 8D576311048677EA00EA77CD /* Sources */, 132 | 8D576313048677EA00EA77CD /* Frameworks */, 133 | 8D576315048677EA00EA77CD /* Rez */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = WebP; 140 | productInstallPath = /Library/QuickLook; 141 | productName = WebP; 142 | productReference = 8D576316048677EA00EA77CD /* WebP.qlgenerator */; 143 | productType = "com.apple.product-type.bundle"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | 089C1669FE841209C02AAC07 /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastUpgradeCheck = 0600; 152 | }; 153 | buildConfigurationList = 2CA326220896AD4900168862 /* Build configuration list for PBXProject "WebP" */; 154 | compatibilityVersion = "Xcode 3.2"; 155 | developmentRegion = English; 156 | hasScannedForEncodings = 1; 157 | knownRegions = ( 158 | English, 159 | Japanese, 160 | French, 161 | German, 162 | ); 163 | mainGroup = 089C166AFE841209C02AAC07 /* WebP */; 164 | projectDirPath = ""; 165 | projectRoot = ""; 166 | targets = ( 167 | 8D57630D048677EA00EA77CD /* WebP */, 168 | ); 169 | }; 170 | /* End PBXProject section */ 171 | 172 | /* Begin PBXResourcesBuildPhase section */ 173 | 8D57630F048677EA00EA77CD /* Resources */ = { 174 | isa = PBXResourcesBuildPhase; 175 | buildActionMask = 2147483647; 176 | files = ( 177 | 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */, 178 | ); 179 | runOnlyForDeploymentPostprocessing = 0; 180 | }; 181 | /* End PBXResourcesBuildPhase section */ 182 | 183 | /* Begin PBXRezBuildPhase section */ 184 | 8D576315048677EA00EA77CD /* Rez */ = { 185 | isa = PBXRezBuildPhase; 186 | buildActionMask = 2147483647; 187 | files = ( 188 | ); 189 | runOnlyForDeploymentPostprocessing = 0; 190 | }; 191 | /* End PBXRezBuildPhase section */ 192 | 193 | /* Begin PBXSourcesBuildPhase section */ 194 | 8D576311048677EA00EA77CD /* Sources */ = { 195 | isa = PBXSourcesBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | 8D576312048677EA00EA77CD /* main.c in Sources */, 199 | 2C05A19C06CAA52B00D84F6F /* GeneratePreviewForURL.m in Sources */, 200 | 61E3BCFB0870B4F2002186A0 /* GenerateThumbnailForURL.m in Sources */, 201 | 0AE4DF7B136F758200079D1E /* WebPImage.m in Sources */, 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | }; 205 | /* End PBXSourcesBuildPhase section */ 206 | 207 | /* Begin PBXVariantGroup section */ 208 | 8D5B49A704867FD3000E48DA /* InfoPlist.strings */ = { 209 | isa = PBXVariantGroup; 210 | children = ( 211 | 089C167EFE841241C02AAC07 /* English */, 212 | ); 213 | name = InfoPlist.strings; 214 | sourceTree = ""; 215 | }; 216 | /* End PBXVariantGroup section */ 217 | 218 | /* Begin XCBuildConfiguration section */ 219 | 2CA3261F0896AD4900168862 /* Debug */ = { 220 | isa = XCBuildConfiguration; 221 | buildSettings = { 222 | CODE_SIGN_IDENTITY = "Developer ID Application: Dmitry Chestnykh"; 223 | COMBINE_HIDPI_IMAGES = YES; 224 | COPY_PHASE_STRIP = NO; 225 | GCC_DYNAMIC_NO_PIC = NO; 226 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 227 | GCC_MODEL_TUNING = G5; 228 | GCC_OPTIMIZATION_LEVEL = 0; 229 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 230 | INFOPLIST_FILE = Info.plist; 231 | INSTALL_PATH = /Library/QuickLook; 232 | LIBRARY_SEARCH_PATHS = ( 233 | "$(inherited)", 234 | "\"$(SRCROOT)/lib\"", 235 | ); 236 | PRODUCT_NAME = WebP; 237 | PROVISIONING_PROFILE = ""; 238 | WRAPPER_EXTENSION = qlgenerator; 239 | }; 240 | name = Debug; 241 | }; 242 | 2CA326200896AD4900168862 /* Release */ = { 243 | isa = XCBuildConfiguration; 244 | buildSettings = { 245 | CODE_SIGN_IDENTITY = "Developer ID Application: Dmitry Chestnykh"; 246 | COMBINE_HIDPI_IMAGES = YES; 247 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 248 | GCC_MODEL_TUNING = G5; 249 | GCC_OPTIMIZATION_LEVEL = 3; 250 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 251 | INFOPLIST_FILE = Info.plist; 252 | INSTALL_PATH = /Library/QuickLook; 253 | LIBRARY_SEARCH_PATHS = ( 254 | "$(inherited)", 255 | "\"$(SRCROOT)/lib\"", 256 | ); 257 | PRODUCT_NAME = WebP; 258 | PROVISIONING_PROFILE = ""; 259 | WRAPPER_EXTENSION = qlgenerator; 260 | }; 261 | name = Release; 262 | }; 263 | 2CA326230896AD4900168862 /* Debug */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | GCC_C_LANGUAGE_STANDARD = gnu99; 267 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 268 | GCC_WARN_UNUSED_VARIABLE = YES; 269 | HEADER_SEARCH_PATHS = ./include; 270 | ONLY_ACTIVE_ARCH = YES; 271 | PREBINDING = NO; 272 | SDKROOT = macosx; 273 | }; 274 | name = Debug; 275 | }; 276 | 2CA326240896AD4900168862 /* Release */ = { 277 | isa = XCBuildConfiguration; 278 | buildSettings = { 279 | GCC_C_LANGUAGE_STANDARD = gnu99; 280 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 281 | GCC_WARN_UNUSED_VARIABLE = YES; 282 | HEADER_SEARCH_PATHS = ./include; 283 | PREBINDING = NO; 284 | SDKROOT = macosx; 285 | VALID_ARCHS = "i386 x86_64"; 286 | }; 287 | name = Release; 288 | }; 289 | /* End XCBuildConfiguration section */ 290 | 291 | /* Begin XCConfigurationList section */ 292 | 2CA3261E0896AD4900168862 /* Build configuration list for PBXNativeTarget "WebP" */ = { 293 | isa = XCConfigurationList; 294 | buildConfigurations = ( 295 | 2CA3261F0896AD4900168862 /* Debug */, 296 | 2CA326200896AD4900168862 /* Release */, 297 | ); 298 | defaultConfigurationIsVisible = 0; 299 | defaultConfigurationName = Release; 300 | }; 301 | 2CA326220896AD4900168862 /* Build configuration list for PBXProject "WebP" */ = { 302 | isa = XCConfigurationList; 303 | buildConfigurations = ( 304 | 2CA326230896AD4900168862 /* Debug */, 305 | 2CA326240896AD4900168862 /* Release */, 306 | ); 307 | defaultConfigurationIsVisible = 0; 308 | defaultConfigurationName = Release; 309 | }; 310 | /* End XCConfigurationList section */ 311 | }; 312 | rootObject = 089C1669FE841209C02AAC07 /* Project object */; 313 | } 314 | -------------------------------------------------------------------------------- /WebPImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // WebPImage.h 3 | // WebP 4 | // 5 | // Created by Dmitry Chestnykh on 5/3/11. 6 | // Copyright 2011 Coding Robots. All rights reserved. 7 | // 8 | #import 9 | 10 | 11 | CGImageRef CreateImageForURL(CFURLRef url); 12 | -------------------------------------------------------------------------------- /WebPImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // WebPImage.m 3 | // WebP 4 | // 5 | // Created by Dmitry Chestnykh on 5/3/11. 6 | // Copyright 2011 Coding Robots. All rights reserved. 7 | // 8 | 9 | #import "WebPImage.h" 10 | #import "webp/decode.h" 11 | 12 | CGImageRef CreateImageForURL(CFURLRef url) 13 | { 14 | NSData *fileData = [[NSData alloc] initWithContentsOfURL:(NSURL*)url]; 15 | 16 | WebPDecoderConfig config; 17 | if (!WebPInitDecoderConfig(&config)) { 18 | NSLog(@"(WebPInitDecoderConfig) cannot get WebP image data for %@", url); 19 | [fileData release]; 20 | return NULL; 21 | } 22 | 23 | if (WebPGetFeatures([fileData bytes], [fileData length], &config.input) != VP8_STATUS_OK) { 24 | NSLog(@"(WebPGetFeatures) cannot get WebP image data for %@", url); 25 | [fileData release]; 26 | return NULL; 27 | } 28 | 29 | config.output.colorspace = MODE_rgbA; // premultiplied alpha 30 | 31 | if (WebPDecode([fileData bytes], [fileData length], &config) != VP8_STATUS_OK) { 32 | NSLog(@"(WebPDecode) cannot get WebP image data for %@", url); 33 | [fileData release]; 34 | return NULL; 35 | } 36 | 37 | CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 38 | CGContextRef bitmapContext = CGBitmapContextCreate( 39 | config.output.u.RGBA.rgba, 40 | config.input.width, 41 | config.input.height, 42 | 8, // bitsPerComponent 43 | 4*config.input.width, // bytesPerRow 44 | colorSpace, 45 | kCGImageAlphaPremultipliedLast); 46 | WebPFreeDecBuffer(&config.output); 47 | CGColorSpaceRelease(colorSpace); 48 | [fileData release]; 49 | CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext); 50 | CGContextRelease(bitmapContext); 51 | return cgImage; 52 | } 53 | -------------------------------------------------------------------------------- /include/webp/decode.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Google Inc. All Rights Reserved. 2 | // 3 | // This code is licensed under the same terms as WebM: 4 | // Software License Agreement: http://www.webmproject.org/license/software/ 5 | // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 6 | // ----------------------------------------------------------------------------- 7 | // 8 | // Main decoding functions for WebP images. 9 | // 10 | // Author: Skal (pascal.massimino@gmail.com) 11 | 12 | #ifndef WEBP_WEBP_DECODE_H_ 13 | #define WEBP_WEBP_DECODE_H_ 14 | 15 | #include "./types.h" 16 | 17 | #if defined(__cplusplus) || defined(c_plusplus) 18 | extern "C" { 19 | #endif 20 | 21 | #define WEBP_DECODER_ABI_VERSION 0x0200 // MAJOR(8b) + MINOR(8b) 22 | 23 | // Return the decoder's version number, packed in hexadecimal using 8bits for 24 | // each of major/minor/revision. E.g: v2.5.7 is 0x020507. 25 | WEBP_EXTERN(int) WebPGetDecoderVersion(void); 26 | 27 | // Retrieve basic header information: width, height. 28 | // This function will also validate the header and return 0 in 29 | // case of formatting error. 30 | // Pointers 'width' and 'height' can be passed NULL if deemed irrelevant. 31 | WEBP_EXTERN(int) WebPGetInfo(const uint8_t* data, size_t data_size, 32 | int* width, int* height); 33 | 34 | // Decodes WebP images pointed to by 'data' and returns RGBA samples, along 35 | // with the dimensions in *width and *height. The ordering of samples in 36 | // memory is R, G, B, A, R, G, B, A... in scan order (endian-independent). 37 | // The returned pointer should be deleted calling free(). 38 | // Returns NULL in case of error. 39 | WEBP_EXTERN(uint8_t*) WebPDecodeRGBA(const uint8_t* data, size_t data_size, 40 | int* width, int* height); 41 | 42 | // Same as WebPDecodeRGBA, but returning A, R, G, B, A, R, G, B... ordered data. 43 | WEBP_EXTERN(uint8_t*) WebPDecodeARGB(const uint8_t* data, size_t data_size, 44 | int* width, int* height); 45 | 46 | // Same as WebPDecodeRGBA, but returning B, G, R, A, B, G, R, A... ordered data. 47 | WEBP_EXTERN(uint8_t*) WebPDecodeBGRA(const uint8_t* data, size_t data_size, 48 | int* width, int* height); 49 | 50 | // Same as WebPDecodeRGBA, but returning R, G, B, R, G, B... ordered data. 51 | // If the bitstream contains transparency, it is ignored. 52 | WEBP_EXTERN(uint8_t*) WebPDecodeRGB(const uint8_t* data, size_t data_size, 53 | int* width, int* height); 54 | 55 | // Same as WebPDecodeRGB, but returning B, G, R, B, G, R... ordered data. 56 | WEBP_EXTERN(uint8_t*) WebPDecodeBGR(const uint8_t* data, size_t data_size, 57 | int* width, int* height); 58 | 59 | 60 | // Decode WebP images pointed to by 'data' to Y'UV format(*). The pointer 61 | // returned is the Y samples buffer. Upon return, *u and *v will point to 62 | // the U and V chroma data. These U and V buffers need NOT be free()'d, 63 | // unlike the returned Y luma one. The dimension of the U and V planes 64 | // are both (*width + 1) / 2 and (*height + 1)/ 2. 65 | // Upon return, the Y buffer has a stride returned as '*stride', while U and V 66 | // have a common stride returned as '*uv_stride'. 67 | // Return NULL in case of error. 68 | // (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr 69 | WEBP_EXTERN(uint8_t*) WebPDecodeYUV(const uint8_t* data, size_t data_size, 70 | int* width, int* height, 71 | uint8_t** u, uint8_t** v, 72 | int* stride, int* uv_stride); 73 | 74 | // These five functions are variants of the above ones, that decode the image 75 | // directly into a pre-allocated buffer 'output_buffer'. The maximum storage 76 | // available in this buffer is indicated by 'output_buffer_size'. If this 77 | // storage is not sufficient (or an error occurred), NULL is returned. 78 | // Otherwise, output_buffer is returned, for convenience. 79 | // The parameter 'output_stride' specifies the distance (in bytes) 80 | // between scanlines. Hence, output_buffer_size is expected to be at least 81 | // output_stride x picture-height. 82 | WEBP_EXTERN(uint8_t*) WebPDecodeRGBAInto( 83 | const uint8_t* data, size_t data_size, 84 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 85 | WEBP_EXTERN(uint8_t*) WebPDecodeARGBInto( 86 | const uint8_t* data, size_t data_size, 87 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 88 | WEBP_EXTERN(uint8_t*) WebPDecodeBGRAInto( 89 | const uint8_t* data, size_t data_size, 90 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 91 | 92 | // RGB and BGR variants. Here too the transparency information, if present, 93 | // will be dropped and ignored. 94 | WEBP_EXTERN(uint8_t*) WebPDecodeRGBInto( 95 | const uint8_t* data, size_t data_size, 96 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 97 | WEBP_EXTERN(uint8_t*) WebPDecodeBGRInto( 98 | const uint8_t* data, size_t data_size, 99 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 100 | 101 | // WebPDecodeYUVInto() is a variant of WebPDecodeYUV() that operates directly 102 | // into pre-allocated luma/chroma plane buffers. This function requires the 103 | // strides to be passed: one for the luma plane and one for each of the 104 | // chroma ones. The size of each plane buffer is passed as 'luma_size', 105 | // 'u_size' and 'v_size' respectively. 106 | // Pointer to the luma plane ('*luma') is returned or NULL if an error occurred 107 | // during decoding (or because some buffers were found to be too small). 108 | WEBP_EXTERN(uint8_t*) WebPDecodeYUVInto( 109 | const uint8_t* data, size_t data_size, 110 | uint8_t* luma, size_t luma_size, int luma_stride, 111 | uint8_t* u, size_t u_size, int u_stride, 112 | uint8_t* v, size_t v_size, int v_stride); 113 | 114 | //------------------------------------------------------------------------------ 115 | // Output colorspaces and buffer 116 | 117 | // Colorspaces 118 | // Note: the naming describes the byte-ordering of packed samples in memory. 119 | // For instance, MODE_BGRA relates to samples ordered as B,G,R,A,B,G,R,A,... 120 | // Non-capital names (e.g.:MODE_Argb) relates to pre-multiplied RGB channels. 121 | // RGB-565 and RGBA-4444 are also endian-agnostic and byte-oriented. 122 | typedef enum { MODE_RGB = 0, MODE_RGBA = 1, 123 | MODE_BGR = 2, MODE_BGRA = 3, 124 | MODE_ARGB = 4, MODE_RGBA_4444 = 5, 125 | MODE_RGB_565 = 6, 126 | // RGB-premultiplied transparent modes (alpha value is preserved) 127 | MODE_rgbA = 7, 128 | MODE_bgrA = 8, 129 | MODE_Argb = 9, 130 | MODE_rgbA_4444 = 10, 131 | // YUV modes must come after RGB ones. 132 | MODE_YUV = 11, MODE_YUVA = 12, // yuv 4:2:0 133 | MODE_LAST = 13 134 | } WEBP_CSP_MODE; 135 | 136 | // Some useful macros: 137 | static WEBP_INLINE int WebPIsPremultipliedMode(WEBP_CSP_MODE mode) { 138 | return (mode == MODE_rgbA || mode == MODE_bgrA || mode == MODE_Argb || 139 | mode == MODE_rgbA_4444); 140 | } 141 | 142 | static WEBP_INLINE int WebPIsAlphaMode(WEBP_CSP_MODE mode) { 143 | return (mode == MODE_RGBA || mode == MODE_BGRA || mode == MODE_ARGB || 144 | mode == MODE_RGBA_4444 || mode == MODE_YUVA || 145 | WebPIsPremultipliedMode(mode)); 146 | } 147 | 148 | static WEBP_INLINE int WebPIsRGBMode(WEBP_CSP_MODE mode) { 149 | return (mode < MODE_YUV); 150 | } 151 | 152 | //------------------------------------------------------------------------------ 153 | // WebPDecBuffer: Generic structure for describing the output sample buffer. 154 | 155 | typedef struct { // view as RGBA 156 | uint8_t* rgba; // pointer to RGBA samples 157 | int stride; // stride in bytes from one scanline to the next. 158 | size_t size; // total size of the *rgba buffer. 159 | } WebPRGBABuffer; 160 | 161 | typedef struct { // view as YUVA 162 | uint8_t* y, *u, *v, *a; // pointer to luma, chroma U/V, alpha samples 163 | int y_stride; // luma stride 164 | int u_stride, v_stride; // chroma strides 165 | int a_stride; // alpha stride 166 | size_t y_size; // luma plane size 167 | size_t u_size, v_size; // chroma planes size 168 | size_t a_size; // alpha-plane size 169 | } WebPYUVABuffer; 170 | 171 | // Output buffer 172 | typedef struct { 173 | WEBP_CSP_MODE colorspace; // Colorspace. 174 | int width, height; // Dimensions. 175 | int is_external_memory; // If true, 'internal_memory' pointer is not used. 176 | union { 177 | WebPRGBABuffer RGBA; 178 | WebPYUVABuffer YUVA; 179 | } u; // Nameless union of buffer parameters. 180 | uint32_t pad[4]; // padding for later use 181 | 182 | uint8_t* private_memory; // Internally allocated memory (only when 183 | // is_external_memory is false). Should not be used 184 | // externally, but accessed via the buffer union. 185 | } WebPDecBuffer; 186 | 187 | // Internal, version-checked, entry point 188 | WEBP_EXTERN(int) WebPInitDecBufferInternal(WebPDecBuffer*, int); 189 | 190 | // Initialize the structure as empty. Must be called before any other use. 191 | // Returns false in case of version mismatch 192 | static WEBP_INLINE int WebPInitDecBuffer(WebPDecBuffer* buffer) { 193 | return WebPInitDecBufferInternal(buffer, WEBP_DECODER_ABI_VERSION); 194 | } 195 | 196 | // Free any memory associated with the buffer. Must always be called last. 197 | // Note: doesn't free the 'buffer' structure itself. 198 | WEBP_EXTERN(void) WebPFreeDecBuffer(WebPDecBuffer* buffer); 199 | 200 | //------------------------------------------------------------------------------ 201 | // Enumeration of the status codes 202 | 203 | typedef enum { 204 | VP8_STATUS_OK = 0, 205 | VP8_STATUS_OUT_OF_MEMORY, 206 | VP8_STATUS_INVALID_PARAM, 207 | VP8_STATUS_BITSTREAM_ERROR, 208 | VP8_STATUS_UNSUPPORTED_FEATURE, 209 | VP8_STATUS_SUSPENDED, 210 | VP8_STATUS_USER_ABORT, 211 | VP8_STATUS_NOT_ENOUGH_DATA 212 | } VP8StatusCode; 213 | 214 | //------------------------------------------------------------------------------ 215 | // Incremental decoding 216 | // 217 | // This API allows streamlined decoding of partial data. 218 | // Picture can be incrementally decoded as data become available thanks to the 219 | // WebPIDecoder object. This object can be left in a SUSPENDED state if the 220 | // picture is only partially decoded, pending additional input. 221 | // Code example: 222 | // 223 | // WebPInitDecBuffer(&buffer); 224 | // buffer.colorspace = mode; 225 | // ... 226 | // WebPIDecoder* idec = WebPINewDecoder(&buffer); 227 | // while (has_more_data) { 228 | // // ... (get additional data) 229 | // status = WebPIAppend(idec, new_data, new_data_size); 230 | // if (status != VP8_STATUS_SUSPENDED || 231 | // break; 232 | // } 233 | // 234 | // // The above call decodes the current available buffer. 235 | // // Part of the image can now be refreshed by calling to 236 | // // WebPIDecGetRGB()/WebPIDecGetYUVA() etc. 237 | // } 238 | // WebPIDelete(idec); 239 | 240 | typedef struct WebPIDecoder WebPIDecoder; 241 | 242 | // Creates a new incremental decoder with the supplied buffer parameter. 243 | // This output_buffer can be passed NULL, in which case a default output buffer 244 | // is used (with MODE_RGB). Otherwise, an internal reference to 'output_buffer' 245 | // is kept, which means that the lifespan of 'output_buffer' must be larger than 246 | // that of the returned WebPIDecoder object. 247 | // Returns NULL if the allocation failed. 248 | WEBP_EXTERN(WebPIDecoder*) WebPINewDecoder(WebPDecBuffer* output_buffer); 249 | 250 | // This function allocates and initializes an incremental-decoder object, which 251 | // will output the RGB/A samples specified by 'csp' into a preallocated 252 | // buffer 'output_buffer'. The size of this buffer is at least 253 | // 'output_buffer_size' and the stride (distance in bytes between two scanlines) 254 | // is specified by 'output_stride'. Returns NULL if the allocation failed. 255 | WEBP_EXTERN(WebPIDecoder*) WebPINewRGB( 256 | WEBP_CSP_MODE csp, 257 | uint8_t* output_buffer, size_t output_buffer_size, int output_stride); 258 | 259 | // This function allocates and initializes an incremental-decoder object, which 260 | // will output the raw luma/chroma samples into a preallocated planes. The luma 261 | // plane is specified by its pointer 'luma', its size 'luma_size' and its stride 262 | // 'luma_stride'. Similarly, the chroma-u plane is specified by the 'u', 263 | // 'u_size' and 'u_stride' parameters, and the chroma-v plane by 'v' 264 | // and 'v_size'. And same for the alpha-plane. The 'a' pointer can be pass 265 | // NULL in case one is not interested in the transparency plane. 266 | // Returns NULL if the allocation failed. 267 | WEBP_EXTERN(WebPIDecoder*) WebPINewYUVA( 268 | uint8_t* luma, size_t luma_size, int luma_stride, 269 | uint8_t* u, size_t u_size, int u_stride, 270 | uint8_t* v, size_t v_size, int v_stride, 271 | uint8_t* a, size_t a_size, int a_stride); 272 | 273 | // Deprecated version of the above, without the alpha plane. 274 | // Kept for backward compatibility. 275 | WEBP_EXTERN(WebPIDecoder*) WebPINewYUV( 276 | uint8_t* luma, size_t luma_size, int luma_stride, 277 | uint8_t* u, size_t u_size, int u_stride, 278 | uint8_t* v, size_t v_size, int v_stride); 279 | 280 | // Deletes the WebPIDecoder object and associated memory. Must always be called 281 | // if WebPINewDecoder, WebPINewRGB or WebPINewYUV succeeded. 282 | WEBP_EXTERN(void) WebPIDelete(WebPIDecoder* idec); 283 | 284 | // Copies and decodes the next available data. Returns VP8_STATUS_OK when 285 | // the image is successfully decoded. Returns VP8_STATUS_SUSPENDED when more 286 | // data is expected. Returns error in other cases. 287 | WEBP_EXTERN(VP8StatusCode) WebPIAppend( 288 | WebPIDecoder* idec, const uint8_t* data, size_t data_size); 289 | 290 | // A variant of the above function to be used when data buffer contains 291 | // partial data from the beginning. In this case data buffer is not copied 292 | // to the internal memory. 293 | // Note that the value of the 'data' pointer can change between calls to 294 | // WebPIUpdate, for instance when the data buffer is resized to fit larger data. 295 | WEBP_EXTERN(VP8StatusCode) WebPIUpdate( 296 | WebPIDecoder* idec, const uint8_t* data, size_t data_size); 297 | 298 | // Returns the RGB/A image decoded so far. Returns NULL if output params 299 | // are not initialized yet. The RGB/A output type corresponds to the colorspace 300 | // specified during call to WebPINewDecoder() or WebPINewRGB(). 301 | // *last_y is the index of last decoded row in raster scan order. Some pointers 302 | // (*last_y, *width etc.) can be NULL if corresponding information is not 303 | // needed. 304 | WEBP_EXTERN(uint8_t*) WebPIDecGetRGB( 305 | const WebPIDecoder* idec, int* last_y, 306 | int* width, int* height, int* stride); 307 | 308 | // Same as above function to get a YUVA image. Returns pointer to the luma 309 | // plane or NULL in case of error. If there is no alpha information 310 | // the alpha pointer '*a' will be returned NULL. 311 | WEBP_EXTERN(uint8_t*) WebPIDecGetYUVA( 312 | const WebPIDecoder* idec, int* last_y, 313 | uint8_t** u, uint8_t** v, uint8_t** a, 314 | int* width, int* height, int* stride, int* uv_stride, int* a_stride); 315 | 316 | // Deprecated alpha-less version of WebPIDecGetYUVA(): it will ignore the 317 | // alpha information (if present). Kept for backward compatibility. 318 | static WEBP_INLINE uint8_t* WebPIDecGetYUV( 319 | const WebPIDecoder* idec, int* last_y, uint8_t** u, uint8_t** v, 320 | int* width, int* height, int* stride, int* uv_stride) { 321 | return WebPIDecGetYUVA(idec, last_y, u, v, NULL, width, height, 322 | stride, uv_stride, NULL); 323 | } 324 | 325 | // Generic call to retrieve information about the displayable area. 326 | // If non NULL, the left/right/width/height pointers are filled with the visible 327 | // rectangular area so far. 328 | // Returns NULL in case the incremental decoder object is in an invalid state. 329 | // Otherwise returns the pointer to the internal representation. This structure 330 | // is read-only, tied to WebPIDecoder's lifespan and should not be modified. 331 | WEBP_EXTERN(const WebPDecBuffer*) WebPIDecodedArea( 332 | const WebPIDecoder* idec, int* left, int* top, int* width, int* height); 333 | 334 | //------------------------------------------------------------------------------ 335 | // Advanced decoding parametrization 336 | // 337 | // Code sample for using the advanced decoding API 338 | /* 339 | // A) Init a configuration object 340 | WebPDecoderConfig config; 341 | CHECK(WebPInitDecoderConfig(&config)); 342 | 343 | // B) optional: retrieve the bitstream's features. 344 | CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK); 345 | 346 | // C) Adjust 'config', if needed 347 | config.no_fancy = 1; 348 | config.output.colorspace = MODE_BGRA; 349 | // etc. 350 | 351 | // Note that you can also make config.output point to an externally 352 | // supplied memory buffer, provided it's big enough to store the decoded 353 | // picture. Otherwise, config.output will just be used to allocate memory 354 | // and store the decoded picture. 355 | 356 | // D) Decode! 357 | CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK); 358 | 359 | // E) Decoded image is now in config.output (and config.output.u.RGBA) 360 | 361 | // F) Reclaim memory allocated in config's object. It's safe to call 362 | // this function even if the memory is external and wasn't allocated 363 | // by WebPDecode(). 364 | WebPFreeDecBuffer(&config.output); 365 | */ 366 | 367 | // Features gathered from the bitstream 368 | typedef struct { 369 | int width; // Width in pixels, as read from the bitstream. 370 | int height; // Height in pixels, as read from the bitstream. 371 | int has_alpha; // True if the bitstream contains an alpha channel. 372 | 373 | // Unused for now: 374 | int bitstream_version; // should be 0 for now. TODO(later) 375 | int no_incremental_decoding; // if true, using incremental decoding is not 376 | // recommended. 377 | int rotate; // TODO(later) 378 | int uv_sampling; // should be 0 for now. TODO(later) 379 | uint32_t pad[3]; // padding for later use 380 | } WebPBitstreamFeatures; 381 | 382 | // Internal, version-checked, entry point 383 | WEBP_EXTERN(VP8StatusCode) WebPGetFeaturesInternal( 384 | const uint8_t*, size_t, WebPBitstreamFeatures*, int); 385 | 386 | // Retrieve features from the bitstream. The *features structure is filled 387 | // with information gathered from the bitstream. 388 | // Returns false in case of error or version mismatch. 389 | // In case of error, features->bitstream_status will reflect the error code. 390 | static WEBP_INLINE VP8StatusCode WebPGetFeatures( 391 | const uint8_t* data, size_t data_size, 392 | WebPBitstreamFeatures* features) { 393 | return WebPGetFeaturesInternal(data, data_size, features, 394 | WEBP_DECODER_ABI_VERSION); 395 | } 396 | 397 | // Decoding options 398 | typedef struct { 399 | int bypass_filtering; // if true, skip the in-loop filtering 400 | int no_fancy_upsampling; // if true, use faster pointwise upsampler 401 | int use_cropping; // if true, cropping is applied _first_ 402 | int crop_left, crop_top; // top-left position for cropping. 403 | // Will be snapped to even values. 404 | int crop_width, crop_height; // dimension of the cropping area 405 | int use_scaling; // if true, scaling is applied _afterward_ 406 | int scaled_width, scaled_height; // final resolution 407 | int use_threads; // if true, use multi-threaded decoding 408 | 409 | // Unused for now: 410 | int force_rotation; // forced rotation (to be applied _last_) 411 | int no_enhancement; // if true, discard enhancement layer 412 | uint32_t pad[6]; // padding for later use 413 | } WebPDecoderOptions; 414 | 415 | // Main object storing the configuration for advanced decoding. 416 | typedef struct { 417 | WebPBitstreamFeatures input; // Immutable bitstream features (optional) 418 | WebPDecBuffer output; // Output buffer (can point to external mem) 419 | WebPDecoderOptions options; // Decoding options 420 | } WebPDecoderConfig; 421 | 422 | // Internal, version-checked, entry point 423 | WEBP_EXTERN(int) WebPInitDecoderConfigInternal(WebPDecoderConfig*, int); 424 | 425 | // Initialize the configuration as empty. This function must always be 426 | // called first, unless WebPGetFeatures() is to be called. 427 | // Returns false in case of mismatched version. 428 | static WEBP_INLINE int WebPInitDecoderConfig(WebPDecoderConfig* config) { 429 | return WebPInitDecoderConfigInternal(config, WEBP_DECODER_ABI_VERSION); 430 | } 431 | 432 | // Instantiate a new incremental decoder object with the requested 433 | // configuration. The bitstream can be passed using 'data' and 'data_size' 434 | // parameter, in which case the features will be parsed and stored into 435 | // config->input. Otherwise, 'data' can be NULL and no parsing will occur. 436 | // Note that 'config' can be NULL too, in which case a default configuration 437 | // is used. 438 | // The return WebPIDecoder object must always be deleted calling WebPIDelete(). 439 | // Returns NULL in case of error (and config->status will then reflect 440 | // the error condition). 441 | WEBP_EXTERN(WebPIDecoder*) WebPIDecode(const uint8_t* data, size_t data_size, 442 | WebPDecoderConfig* config); 443 | 444 | // Non-incremental version. This version decodes the full data at once, taking 445 | // 'config' into account. Returns decoding status (which should be VP8_STATUS_OK 446 | // if the decoding was successful). 447 | WEBP_EXTERN(VP8StatusCode) WebPDecode(const uint8_t* data, size_t data_size, 448 | WebPDecoderConfig* config); 449 | 450 | #if defined(__cplusplus) || defined(c_plusplus) 451 | } // extern "C" 452 | #endif 453 | 454 | #endif /* WEBP_WEBP_DECODE_H_ */ 455 | -------------------------------------------------------------------------------- /include/webp/decode_vp8.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Google Inc. 2 | // 3 | // This code is licensed under the same terms as WebM: 4 | // Software License Agreement: http://www.webmproject.org/license/software/ 5 | // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 6 | // ----------------------------------------------------------------------------- 7 | // 8 | // Low-level API for VP8 decoder 9 | // 10 | // Author: Skal (pascal.massimino@gmail.com) 11 | 12 | #ifndef WEBP_WEBP_DECODE_VP8_H_ 13 | #define WEBP_WEBP_DECODE_VP8_H_ 14 | 15 | #include "webp/decode.h" 16 | 17 | #if defined(__cplusplus) || defined(c_plusplus) 18 | extern "C" { 19 | #endif 20 | 21 | #define WEBP_DECODER_ABI_VERSION 0x0002 22 | 23 | //----------------------------------------------------------------------------- 24 | // Lower-level API 25 | // 26 | // Thes functions provide fine-grained control of the decoding process. 27 | // The call flow should resemble: 28 | // 29 | // VP8Io io; 30 | // VP8InitIo(&io); 31 | // io.data = data; 32 | // io.data_size = size; 33 | // /* customize io's functions (setup()/put()/teardown()) if needed. */ 34 | // 35 | // VP8Decoder* dec = VP8New(); 36 | // bool ok = VP8Decode(dec); 37 | // if (!ok) printf("Error: %s\n", VP8StatusMessage(dec)); 38 | // VP8Delete(dec); 39 | // return ok; 40 | 41 | // Input / Output 42 | typedef struct VP8Io VP8Io; 43 | struct VP8Io { 44 | // set by VP8GetHeaders() 45 | int width, height; // picture dimensions, in pixels 46 | 47 | // set before calling put() 48 | int mb_y; // position of the current rows (in pixels) 49 | int mb_h; // number of rows in the sample 50 | const uint8_t *y, *u, *v; // rows to copy (in yuv420 format) 51 | int y_stride; // row stride for luma 52 | int uv_stride; // row stride for chroma 53 | 54 | void* opaque; // user data 55 | 56 | // called when fresh samples are available. Currently, samples are in 57 | // YUV420 format, and can be up to width x 24 in size (depending on the 58 | // in-loop filtering level, e.g.). Should return false in case of error 59 | // or abort request. 60 | int (*put)(const VP8Io* io); 61 | 62 | // called just before starting to decode the blocks. 63 | // Should returns 0 in case of error. 64 | int (*setup)(VP8Io* io); 65 | 66 | // called just after block decoding is finished (or when an error occurred). 67 | void (*teardown)(const VP8Io* io); 68 | 69 | // this is a recommendation for the user-side yuv->rgb converter. This flag 70 | // is set when calling setup() hook and can be overwritten by it. It then 71 | // can be taken into consideration during the put() method. 72 | int fancy_upscaling; 73 | 74 | // Input buffer. 75 | uint32_t data_size; 76 | const uint8_t* data; 77 | 78 | // If true, in-loop filtering will not be performed even if present in the 79 | // bitstream. Switching off filtering may speed up decoding at the expense 80 | // of more visible blocking. Note that output will also be non-compliant 81 | // with the VP8 specifications. 82 | int bypass_filtering; 83 | 84 | // pointer to the alpha data (if present) corresponding to the rows 85 | const uint8_t* a; 86 | }; 87 | 88 | // Internal, version-checked, entry point 89 | int VP8InitIoInternal(VP8Io* const, int); 90 | 91 | // Main decoding object. This is an opaque structure. 92 | typedef struct VP8Decoder VP8Decoder; 93 | 94 | // Create a new decoder object. 95 | VP8Decoder* VP8New(void); 96 | 97 | // Must be called to make sure 'io' is initialized properly. 98 | // Returns false in case of version mismatch. Upon such failure, no other 99 | // decoding function should be called (VP8Decode, VP8GetHeaders, ...) 100 | static inline int VP8InitIo(VP8Io* const io) { 101 | return VP8InitIoInternal(io, WEBP_DECODER_ABI_VERSION); 102 | } 103 | 104 | // Start decoding a new picture. Returns true if ok. 105 | int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io); 106 | 107 | // Decode a picture. Will call VP8GetHeaders() if it wasn't done already. 108 | // Returns false in case of error. 109 | int VP8Decode(VP8Decoder* const dec, VP8Io* const io); 110 | 111 | // Return current status of the decoder: 112 | VP8StatusCode VP8Status(VP8Decoder* const dec); 113 | 114 | // return readable string corresponding to the last status. 115 | const char* VP8StatusMessage(VP8Decoder* const dec); 116 | 117 | // Resets the decoder in its initial state, reclaiming memory. 118 | // Not a mandatory call between calls to VP8Decode(). 119 | void VP8Clear(VP8Decoder* const dec); 120 | 121 | // Destroy the decoder object. 122 | void VP8Delete(VP8Decoder* const dec); 123 | 124 | //----------------------------------------------------------------------------- 125 | 126 | #if defined(__cplusplus) || defined(c_plusplus) 127 | } // extern "C" 128 | #endif 129 | 130 | #endif /* WEBP_WEBP_DECODE_VP8_H_ */ 131 | -------------------------------------------------------------------------------- /include/webp/encode.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // This code is licensed under the same terms as WebM: 4 | // Software License Agreement: http://www.webmproject.org/license/software/ 5 | // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 6 | // ----------------------------------------------------------------------------- 7 | // 8 | // WebP encoder: main interface 9 | // 10 | // Author: Skal (pascal.massimino@gmail.com) 11 | 12 | #ifndef WEBP_WEBP_ENCODE_H_ 13 | #define WEBP_WEBP_ENCODE_H_ 14 | 15 | #include "./types.h" 16 | 17 | #if defined(__cplusplus) || defined(c_plusplus) 18 | extern "C" { 19 | #endif 20 | 21 | #define WEBP_ENCODER_ABI_VERSION 0x0200 // MAJOR(8b) + MINOR(8b) 22 | 23 | // Return the encoder's version number, packed in hexadecimal using 8bits for 24 | // each of major/minor/revision. E.g: v2.5.7 is 0x020507. 25 | WEBP_EXTERN(int) WebPGetEncoderVersion(void); 26 | 27 | //------------------------------------------------------------------------------ 28 | // One-stop-shop call! No questions asked: 29 | 30 | // Returns the size of the compressed data (pointed to by *output), or 0 if 31 | // an error occurred. The compressed data must be released by the caller 32 | // using the call 'free(*output)'. 33 | // These functions compress using the lossy format, and the quality_factor 34 | // can go from 0 (smaller output, lower quality) to 100 (best quality, 35 | // larger output). 36 | WEBP_EXTERN(size_t) WebPEncodeRGB(const uint8_t* rgb, 37 | int width, int height, int stride, 38 | float quality_factor, uint8_t** output); 39 | WEBP_EXTERN(size_t) WebPEncodeBGR(const uint8_t* bgr, 40 | int width, int height, int stride, 41 | float quality_factor, uint8_t** output); 42 | WEBP_EXTERN(size_t) WebPEncodeRGBA(const uint8_t* rgba, 43 | int width, int height, int stride, 44 | float quality_factor, uint8_t** output); 45 | WEBP_EXTERN(size_t) WebPEncodeBGRA(const uint8_t* bgra, 46 | int width, int height, int stride, 47 | float quality_factor, uint8_t** output); 48 | 49 | // These functions are the equivalent of the above, but compressing in a 50 | // lossless manner. Files are usually larger than lossy format, but will 51 | // not suffer any compression loss. 52 | WEBP_EXTERN(size_t) WebPEncodeLosslessRGB(const uint8_t* rgb, 53 | int width, int height, int stride, 54 | uint8_t** output); 55 | WEBP_EXTERN(size_t) WebPEncodeLosslessBGR(const uint8_t* bgr, 56 | int width, int height, int stride, 57 | uint8_t** output); 58 | WEBP_EXTERN(size_t) WebPEncodeLosslessRGBA(const uint8_t* rgba, 59 | int width, int height, int stride, 60 | uint8_t** output); 61 | WEBP_EXTERN(size_t) WebPEncodeLosslessBGRA(const uint8_t* bgra, 62 | int width, int height, int stride, 63 | uint8_t** output); 64 | 65 | //------------------------------------------------------------------------------ 66 | // Coding parameters 67 | 68 | // Image characteristics hint for the underlying encoder. 69 | typedef enum { 70 | WEBP_HINT_DEFAULT = 0, // default preset. 71 | WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot 72 | WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting 73 | WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc). 74 | WEBP_HINT_LAST 75 | } WebPImageHint; 76 | 77 | typedef struct { 78 | int lossless; // Lossless encoding (0=lossy(default), 1=lossless). 79 | float quality; // between 0 (smallest file) and 100 (biggest) 80 | int method; // quality/speed trade-off (0=fast, 6=slower-better) 81 | 82 | WebPImageHint image_hint; // Hint for image type (lossless only for now). 83 | 84 | // Parameters related to lossy compression only: 85 | int target_size; // if non-zero, set the desired target size in bytes. 86 | // Takes precedence over the 'compression' parameter. 87 | float target_PSNR; // if non-zero, specifies the minimal distortion to 88 | // try to achieve. Takes precedence over target_size. 89 | int segments; // maximum number of segments to use, in [1..4] 90 | int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum. 91 | int filter_strength; // range: [0 = off .. 100 = strongest] 92 | int filter_sharpness; // range: [0 = off .. 7 = least sharp] 93 | int filter_type; // filtering type: 0 = simple, 1 = strong (only used 94 | // if filter_strength > 0 or autofilter > 0) 95 | int autofilter; // Auto adjust filter's strength [0 = off, 1 = on] 96 | int alpha_compression; // Algorithm for encoding the alpha plane (0 = none, 97 | // 1 = compressed with WebP lossless). Default is 1. 98 | int alpha_filtering; // Predictive filtering method for alpha plane. 99 | // 0: none, 1: fast, 2: best. Default if 1. 100 | int alpha_quality; // Between 0 (smallest size) and 100 (lossless). 101 | // Default is 100. 102 | int pass; // number of entropy-analysis passes (in [1..10]). 103 | 104 | int show_compressed; // if true, export the compressed picture back. 105 | // In-loop filtering is not applied. 106 | int preprocessing; // preprocessing filter (0=none, 1=segment-smooth) 107 | int partitions; // log2(number of token partitions) in [0..3]. Default 108 | // is set to 0 for easier progressive decoding. 109 | int partition_limit; // quality degradation allowed to fit the 512k limit 110 | // on prediction modes coding (0: no degradation, 111 | // 100: maximum possible degradation). 112 | 113 | uint32_t pad[8]; // padding for later use 114 | } WebPConfig; 115 | 116 | // Enumerate some predefined settings for WebPConfig, depending on the type 117 | // of source picture. These presets are used when calling WebPConfigPreset(). 118 | typedef enum { 119 | WEBP_PRESET_DEFAULT = 0, // default preset. 120 | WEBP_PRESET_PICTURE, // digital picture, like portrait, inner shot 121 | WEBP_PRESET_PHOTO, // outdoor photograph, with natural lighting 122 | WEBP_PRESET_DRAWING, // hand or line drawing, with high-contrast details 123 | WEBP_PRESET_ICON, // small-sized colorful images 124 | WEBP_PRESET_TEXT // text-like 125 | } WebPPreset; 126 | 127 | // Internal, version-checked, entry point 128 | WEBP_EXTERN(int) WebPConfigInitInternal(WebPConfig*, WebPPreset, float, int); 129 | 130 | // Should always be called, to initialize a fresh WebPConfig structure before 131 | // modification. Returns false in case of version mismatch. WebPConfigInit() 132 | // must have succeeded before using the 'config' object. 133 | // Note that the default values are lossless=0 and quality=75. 134 | static WEBP_INLINE int WebPConfigInit(WebPConfig* config) { 135 | return WebPConfigInitInternal(config, WEBP_PRESET_DEFAULT, 75.f, 136 | WEBP_ENCODER_ABI_VERSION); 137 | } 138 | 139 | // This function will initialize the configuration according to a predefined 140 | // set of parameters (referred to by 'preset') and a given quality factor. 141 | // This function can be called as a replacement to WebPConfigInit(). Will 142 | // return false in case of error. 143 | static WEBP_INLINE int WebPConfigPreset(WebPConfig* config, 144 | WebPPreset preset, float quality) { 145 | return WebPConfigInitInternal(config, preset, quality, 146 | WEBP_ENCODER_ABI_VERSION); 147 | } 148 | 149 | // Returns true if 'config' is non-NULL and all configuration parameters are 150 | // within their valid ranges. 151 | WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* config); 152 | 153 | //------------------------------------------------------------------------------ 154 | // Input / Output 155 | 156 | typedef struct WebPPicture WebPPicture; // main structure for I/O 157 | 158 | // Structure for storing auxiliary statistics (mostly for lossy encoding). 159 | typedef struct { 160 | int coded_size; // final size 161 | 162 | float PSNR[5]; // peak-signal-to-noise ratio for Y/U/V/All/Alpha 163 | int block_count[3]; // number of intra4/intra16/skipped macroblocks 164 | int header_bytes[2]; // approximate number of bytes spent for header 165 | // and mode-partition #0 166 | int residual_bytes[3][4]; // approximate number of bytes spent for 167 | // DC/AC/uv coefficients for each (0..3) segments. 168 | int segment_size[4]; // number of macroblocks in each segments 169 | int segment_quant[4]; // quantizer values for each segments 170 | int segment_level[4]; // filtering strength for each segments [0..63] 171 | 172 | int alpha_data_size; // size of the transparency data 173 | int layer_data_size; // size of the enhancement layer data 174 | 175 | // lossless encoder statistics 176 | uint32_t lossless_features; // bit0:predictor bit1:cross-color transform 177 | // bit2:subtract-green bit3:color indexing 178 | int histogram_bits; // number of precision bits of histogram 179 | int transform_bits; // precision bits for transform 180 | int cache_bits; // number of bits for color cache lookup 181 | int palette_size; // number of color in palette, if used 182 | int lossless_size; // final lossless size 183 | 184 | uint32_t pad[4]; // padding for later use 185 | } WebPAuxStats; 186 | 187 | // Signature for output function. Should return true if writing was successful. 188 | // data/data_size is the segment of data to write, and 'picture' is for 189 | // reference (and so one can make use of picture->custom_ptr). 190 | typedef int (*WebPWriterFunction)(const uint8_t* data, size_t data_size, 191 | const WebPPicture* picture); 192 | 193 | // WebPMemoryWrite: a special WebPWriterFunction that writes to memory using 194 | // the following WebPMemoryWriter object (to be set as a custom_ptr). 195 | typedef struct { 196 | uint8_t* mem; // final buffer (of size 'max_size', larger than 'size'). 197 | size_t size; // final size 198 | size_t max_size; // total capacity 199 | uint32_t pad[1]; // padding for later use 200 | } WebPMemoryWriter; 201 | 202 | // The following must be called first before any use. 203 | WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer); 204 | 205 | // The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon 206 | // completion, writer.mem and writer.size will hold the coded data. 207 | WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size, 208 | const WebPPicture* picture); 209 | 210 | // Progress hook, called from time to time to report progress. It can return 211 | // false to request an abort of the encoding process, or true otherwise if 212 | // everything is OK. 213 | typedef int (*WebPProgressHook)(int percent, const WebPPicture* picture); 214 | 215 | typedef enum { 216 | // chroma sampling 217 | WEBP_YUV420 = 0, // 4:2:0 218 | WEBP_YUV422 = 1, // 4:2:2 219 | WEBP_YUV444 = 2, // 4:4:4 220 | WEBP_YUV400 = 3, // grayscale 221 | WEBP_CSP_UV_MASK = 3, // bit-mask to get the UV sampling factors 222 | // alpha channel variants 223 | WEBP_YUV420A = 4, 224 | WEBP_YUV422A = 5, 225 | WEBP_YUV444A = 6, 226 | WEBP_YUV400A = 7, // grayscale + alpha 227 | WEBP_CSP_ALPHA_BIT = 4 // bit that is set if alpha is present 228 | } WebPEncCSP; 229 | 230 | // Encoding error conditions. 231 | typedef enum { 232 | VP8_ENC_OK = 0, 233 | VP8_ENC_ERROR_OUT_OF_MEMORY, // memory error allocating objects 234 | VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY, // memory error while flushing bits 235 | VP8_ENC_ERROR_NULL_PARAMETER, // a pointer parameter is NULL 236 | VP8_ENC_ERROR_INVALID_CONFIGURATION, // configuration is invalid 237 | VP8_ENC_ERROR_BAD_DIMENSION, // picture has invalid width/height 238 | VP8_ENC_ERROR_PARTITION0_OVERFLOW, // partition is bigger than 512k 239 | VP8_ENC_ERROR_PARTITION_OVERFLOW, // partition is bigger than 16M 240 | VP8_ENC_ERROR_BAD_WRITE, // error while flushing bytes 241 | VP8_ENC_ERROR_FILE_TOO_BIG, // file is bigger than 4G 242 | VP8_ENC_ERROR_USER_ABORT, // abort request by user 243 | VP8_ENC_ERROR_LAST // list terminator. always last. 244 | } WebPEncodingError; 245 | 246 | // maximum width/height allowed (inclusive), in pixels 247 | #define WEBP_MAX_DIMENSION 16383 248 | 249 | // Main exchange structure (input samples, output bytes, statistics) 250 | struct WebPPicture { 251 | 252 | // INPUT 253 | ////////////// 254 | // Main flag for encoder selecting between ARGB or YUV input. 255 | // It is recommended to use ARGB input (*argb, argb_stride) for lossless 256 | // compression, and YUV input (*y, *u, *v, etc.) for lossy compression 257 | // since these are the respective native colorspace for these formats. 258 | int use_argb; 259 | 260 | // YUV input (mostly used for input to lossy compression) 261 | WebPEncCSP colorspace; // colorspace: should be YUV420 for now (=Y'CbCr). 262 | int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION) 263 | uint8_t *y, *u, *v; // pointers to luma/chroma planes. 264 | int y_stride, uv_stride; // luma/chroma strides. 265 | uint8_t* a; // pointer to the alpha plane 266 | int a_stride; // stride of the alpha plane 267 | uint32_t pad1[2]; // padding for later use 268 | 269 | // ARGB input (mostly used for input to lossless compression) 270 | uint32_t* argb; // Pointer to argb (32 bit) plane. 271 | int argb_stride; // This is stride in pixels units, not bytes. 272 | uint32_t pad2[3]; // padding for later use 273 | 274 | // OUTPUT 275 | /////////////// 276 | // Byte-emission hook, to store compressed bytes as they are ready. 277 | WebPWriterFunction writer; // can be NULL 278 | void* custom_ptr; // can be used by the writer. 279 | 280 | // map for extra information (only for lossy compression mode) 281 | int extra_info_type; // 1: intra type, 2: segment, 3: quant 282 | // 4: intra-16 prediction mode, 283 | // 5: chroma prediction mode, 284 | // 6: bit cost, 7: distortion 285 | uint8_t* extra_info; // if not NULL, points to an array of size 286 | // ((width + 15) / 16) * ((height + 15) / 16) that 287 | // will be filled with a macroblock map, depending 288 | // on extra_info_type. 289 | 290 | // STATS AND REPORTS 291 | /////////////////////////// 292 | // Pointer to side statistics (updated only if not NULL) 293 | WebPAuxStats* stats; 294 | 295 | // Error code for the latest error encountered during encoding 296 | WebPEncodingError error_code; 297 | 298 | // If not NULL, report progress during encoding. 299 | WebPProgressHook progress_hook; 300 | 301 | void* user_data; // this field is free to be set to any value and 302 | // used during callbacks (like progress-report e.g.). 303 | 304 | uint32_t pad3[3]; // padding for later use 305 | 306 | // Unused for now: original samples (for non-YUV420 modes) 307 | uint8_t *u0, *v0; 308 | int uv0_stride; 309 | 310 | uint32_t pad4[7]; // padding for later use 311 | 312 | // PRIVATE FIELDS 313 | //////////////////// 314 | void* memory_; // row chunk of memory for yuva planes 315 | void* memory_argb_; // and for argb too. 316 | void* pad5[2]; // padding for later use 317 | }; 318 | 319 | // Internal, version-checked, entry point 320 | WEBP_EXTERN(int) WebPPictureInitInternal(WebPPicture*, int); 321 | 322 | // Should always be called, to initialize the structure. Returns false in case 323 | // of version mismatch. WebPPictureInit() must have succeeded before using the 324 | // 'picture' object. 325 | // Note that, by default, use_argb is false and colorspace is WEBP_YUV420. 326 | static WEBP_INLINE int WebPPictureInit(WebPPicture* picture) { 327 | return WebPPictureInitInternal(picture, WEBP_ENCODER_ABI_VERSION); 328 | } 329 | 330 | //------------------------------------------------------------------------------ 331 | // WebPPicture utils 332 | 333 | // Convenience allocation / deallocation based on picture->width/height: 334 | // Allocate y/u/v buffers as per colorspace/width/height specification. 335 | // Note! This function will free the previous buffer if needed. 336 | // Returns false in case of memory error. 337 | WEBP_EXTERN(int) WebPPictureAlloc(WebPPicture* picture); 338 | 339 | // Release the memory allocated by WebPPictureAlloc() or WebPPictureImport*(). 340 | // Note that this function does _not_ free the memory used by the 'picture' 341 | // object itself. 342 | // Besides memory (which is reclaimed) all other fields of 'picture' are 343 | // preserved. 344 | WEBP_EXTERN(void) WebPPictureFree(WebPPicture* picture); 345 | 346 | // Copy the pixels of *src into *dst, using WebPPictureAlloc. Upon return, 347 | // *dst will fully own the copied pixels (this is not a view). 348 | // Returns false in case of memory allocation error. 349 | WEBP_EXTERN(int) WebPPictureCopy(const WebPPicture* src, WebPPicture* dst); 350 | 351 | // Compute PSNR or SSIM distortion between two pictures. 352 | // Result is in dB, stores in result[] in the Y/U/V/Alpha/All order. 353 | // Returns false in case of error (pic1 and pic2 don't have same dimension, ...) 354 | // Warning: this function is rather CPU-intensive. 355 | WEBP_EXTERN(int) WebPPictureDistortion( 356 | const WebPPicture* pic1, const WebPPicture* pic2, 357 | int metric_type, // 0 = PSNR, 1 = SSIM 358 | float result[5]); 359 | 360 | // self-crops a picture to the rectangle defined by top/left/width/height. 361 | // Returns false in case of memory allocation error, or if the rectangle is 362 | // outside of the source picture. 363 | // The rectangle for the view is defined by the top-left corner pixel 364 | // coordinates (left, top) as well as its width and height. This rectangle 365 | // must be fully be comprised inside the 'src' source picture. If the source 366 | // picture uses the YUV420 colorspace, the top and left coordinates will be 367 | // snapped to even values. 368 | WEBP_EXTERN(int) WebPPictureCrop(WebPPicture* picture, 369 | int left, int top, int width, int height); 370 | 371 | // Extracts a view from 'src' picture into 'dst'. The rectangle for the view 372 | // is defined by the top-left corner pixel coordinates (left, top) as well 373 | // as its width and height. This rectangle must be fully be comprised inside 374 | // the 'src' source picture. If the source picture uses the YUV420 colorspace, 375 | // the top and left coordinates will be snapped to even values. 376 | // Picture 'src' must out-live 'dst' picture. Self-extraction of view is allowed 377 | // ('src' equal to 'dst') as a mean of fast-cropping (but note that doing so, 378 | // the original dimension will be lost). 379 | // Returns false in case of memory allocation error or invalid parameters. 380 | WEBP_EXTERN(int) WebPPictureView(const WebPPicture* src, 381 | int left, int top, int width, int height, 382 | WebPPicture* dst); 383 | 384 | // Returns true if the 'picture' is actually a view and therefore does 385 | // not own the memory for pixels. 386 | WEBP_EXTERN(int) WebPPictureIsView(const WebPPicture* picture); 387 | 388 | // Rescale a picture to new dimension width x height. 389 | // Now gamma correction is applied. 390 | // Returns false in case of error (invalid parameter or insufficient memory). 391 | WEBP_EXTERN(int) WebPPictureRescale(WebPPicture* pic, int width, int height); 392 | 393 | // Colorspace conversion function to import RGB samples. 394 | // Previous buffer will be free'd, if any. 395 | // *rgb buffer should have a size of at least height * rgb_stride. 396 | // Returns false in case of memory error. 397 | WEBP_EXTERN(int) WebPPictureImportRGB( 398 | WebPPicture* picture, const uint8_t* rgb, int rgb_stride); 399 | // Same, but for RGBA buffer. 400 | WEBP_EXTERN(int) WebPPictureImportRGBA( 401 | WebPPicture* picture, const uint8_t* rgba, int rgba_stride); 402 | // Same, but for RGBA buffer. Imports the RGB direct from the 32-bit format 403 | // input buffer ignoring the alpha channel. Avoids needing to copy the data 404 | // to a temporary 24-bit RGB buffer to import the RGB only. 405 | WEBP_EXTERN(int) WebPPictureImportRGBX( 406 | WebPPicture* picture, const uint8_t* rgbx, int rgbx_stride); 407 | 408 | // Variants of the above, but taking BGR(A|X) input. 409 | WEBP_EXTERN(int) WebPPictureImportBGR( 410 | WebPPicture* picture, const uint8_t* bgr, int bgr_stride); 411 | WEBP_EXTERN(int) WebPPictureImportBGRA( 412 | WebPPicture* picture, const uint8_t* bgra, int bgra_stride); 413 | WEBP_EXTERN(int) WebPPictureImportBGRX( 414 | WebPPicture* picture, const uint8_t* bgrx, int bgrx_stride); 415 | 416 | // Converts picture->argb data to the YUVA format specified by 'colorspace'. 417 | // Upon return, picture->use_argb is set to false. The presence of real 418 | // non-opaque transparent values is detected, and 'colorspace' will be 419 | // adjusted accordingly. Note that this method is lossy. 420 | // Returns false in case of error. 421 | WEBP_EXTERN(int) WebPPictureARGBToYUVA(WebPPicture* picture, 422 | WebPEncCSP colorspace); 423 | 424 | // Converts picture->yuv to picture->argb and sets picture->use_argb to true. 425 | // The input format must be YUV_420 or YUV_420A. 426 | // Note that the use of this method is discouraged if one has access to the 427 | // raw ARGB samples, since using YUV420 is comparatively lossy. Also, the 428 | // conversion from YUV420 to ARGB incurs a small loss too. 429 | // Returns false in case of error. 430 | WEBP_EXTERN(int) WebPPictureYUVAToARGB(WebPPicture* picture); 431 | 432 | // Helper function: given a width x height plane of YUV(A) samples 433 | // (with stride 'stride'), clean-up the YUV samples under fully transparent 434 | // area, to help compressibility (no guarantee, though). 435 | WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* picture); 436 | 437 | // Scan the picture 'picture' for the presence of non fully opaque alpha values. 438 | // Returns true in such case. Otherwise returns false (indicating that the 439 | // alpha plane can be ignored altogether e.g.). 440 | WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* picture); 441 | 442 | //------------------------------------------------------------------------------ 443 | // Main call 444 | 445 | // Main encoding call, after config and picture have been initialized. 446 | // 'picture' must be less than 16384x16384 in dimension (cf WEBP_MAX_DIMENSION), 447 | // and the 'config' object must be a valid one. 448 | // Returns false in case of error, true otherwise. 449 | // In case of error, picture->error_code is updated accordingly. 450 | // 'picture' can hold the source samples in both YUV(A) or ARGB input, depending 451 | // on the value of 'picture->use_argb'. It is highly recommended to use 452 | // the former for lossy encoding, and the latter for lossless encoding 453 | // (when config.lossless is true). Automatic conversion from one format to 454 | // another is provided but they both incur some loss. 455 | WEBP_EXTERN(int) WebPEncode(const WebPConfig* config, WebPPicture* picture); 456 | 457 | //------------------------------------------------------------------------------ 458 | 459 | #if defined(__cplusplus) || defined(c_plusplus) 460 | } // extern "C" 461 | #endif 462 | 463 | #endif /* WEBP_WEBP_ENCODE_H_ */ 464 | -------------------------------------------------------------------------------- /include/webp/format_constants.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // This code is licensed under the same terms as WebM: 4 | // Software License Agreement: http://www.webmproject.org/license/software/ 5 | // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 6 | // ----------------------------------------------------------------------------- 7 | // 8 | // Internal header for constants related to WebP file format. 9 | // 10 | // Author: Urvang (urvang@google.com) 11 | 12 | #ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_ 13 | #define WEBP_WEBP_FORMAT_CONSTANTS_H_ 14 | 15 | // VP8 related constants. 16 | #define VP8_SIGNATURE 0x9d012a // Signature in VP8 data. 17 | #define VP8_MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition 18 | #define VP8_MAX_PARTITION_SIZE (1 << 24) // max size for token partition 19 | #define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data. 20 | 21 | // VP8L related constants. 22 | #define VP8L_SIGNATURE_SIZE 1 // VP8L signature size. 23 | #define VP8L_MAGIC_BYTE 0x2f // VP8L signature byte. 24 | #define VP8L_IMAGE_SIZE_BITS 14 // Number of bits used to store 25 | // width and height. 26 | #define VP8L_VERSION_BITS 3 // 3 bits reserved for version. 27 | #define VP8L_VERSION 0 // version 0 28 | #define VP8L_FRAME_HEADER_SIZE 5 // Size of the VP8L frame header. 29 | 30 | #define MAX_PALETTE_SIZE 256 31 | #define MAX_CACHE_BITS 11 32 | #define HUFFMAN_CODES_PER_META_CODE 5 33 | #define ARGB_BLACK 0xff000000 34 | 35 | #define DEFAULT_CODE_LENGTH 8 36 | #define MAX_ALLOWED_CODE_LENGTH 15 37 | 38 | #define NUM_LITERAL_CODES 256 39 | #define NUM_LENGTH_CODES 24 40 | #define NUM_DISTANCE_CODES 40 41 | #define CODE_LENGTH_CODES 19 42 | 43 | #define MIN_HUFFMAN_BITS 2 // min number of Huffman bits 44 | #define MAX_HUFFMAN_BITS 9 // max number of Huffman bits 45 | 46 | #define TRANSFORM_PRESENT 1 // The bit to be written when next data 47 | // to be read is a transform. 48 | #define NUM_TRANSFORMS 4 // Maximum number of allowed transform 49 | // in a bitstream. 50 | typedef enum { 51 | PREDICTOR_TRANSFORM = 0, 52 | CROSS_COLOR_TRANSFORM = 1, 53 | SUBTRACT_GREEN = 2, 54 | COLOR_INDEXING_TRANSFORM = 3 55 | } VP8LImageTransformType; 56 | 57 | // Alpha related constants. 58 | #define ALPHA_HEADER_LEN 1 59 | #define ALPHA_NO_COMPRESSION 0 60 | #define ALPHA_LOSSLESS_COMPRESSION 1 61 | #define ALPHA_PREPROCESSED_LEVELS 1 62 | 63 | // Mux related constants. 64 | #define TAG_SIZE 4 // Size of a chunk tag (e.g. "VP8L"). 65 | #define CHUNK_SIZE_BYTES 4 // Size needed to store chunk's size. 66 | #define CHUNK_HEADER_SIZE 8 // Size of a chunk header. 67 | #define RIFF_HEADER_SIZE 12 // Size of the RIFF header ("RIFFnnnnWEBP"). 68 | #define FRAME_CHUNK_SIZE 15 // Size of a FRM chunk. 69 | #define LOOP_CHUNK_SIZE 2 // Size of a LOOP chunk. 70 | #define TILE_CHUNK_SIZE 6 // Size of a TILE chunk. 71 | #define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk. 72 | 73 | #define TILING_FLAG_BIT 0x01 // Set if tiles are possibly used. 74 | #define ANIMATION_FLAG_BIT 0x02 // Set if some animation is expected 75 | #define ICC_FLAG_BIT 0x04 // Whether ICC is present or not. 76 | #define METADATA_FLAG_BIT 0x08 // Set if some META chunk is possibly present. 77 | #define ALPHA_FLAG_BIT 0x10 // Should be same as the ALPHA_FLAG in mux.h 78 | #define ROTATION_FLAG_BITS 0xe0 // all 3 bits for rotation + symmetry 79 | 80 | #define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height. 81 | #define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height. 82 | #define MAX_LOOP_COUNT (1 << 16) // maximum value for loop-count 83 | #define MAX_DURATION (1 << 24) // maximum duration 84 | #define MAX_POSITION_OFFSET (1 << 24) // maximum frame/tile x/y offset 85 | 86 | // Maximum chunk payload is such that adding the header and padding won't 87 | // overflow a uint32_t. 88 | #define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1) 89 | 90 | #endif /* WEBP_WEBP_FORMAT_CONSTANTS_H_ */ 91 | -------------------------------------------------------------------------------- /include/webp/mux.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // This code is licensed under the same terms as WebM: 4 | // Software License Agreement: http://www.webmproject.org/license/software/ 5 | // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 6 | // ----------------------------------------------------------------------------- 7 | // 8 | // RIFF container manipulation for WEBP images. 9 | // 10 | // Authors: Urvang (urvang@google.com) 11 | // Vikas (vikasa@google.com) 12 | 13 | // This API allows manipulation of WebP container images containing features 14 | // like Color profile, XMP metadata, Animation and Tiling. 15 | // 16 | // Code Example#1: Creating a MUX with image data, color profile and XMP 17 | // metadata. 18 | // 19 | // int copy_data = 0; 20 | // WebPMux* mux = WebPMuxNew(); 21 | // // ... (Prepare image data). 22 | // WebPMuxSetImage(mux, &image, copy_data); 23 | // // ... (Prepare ICCP color profile data). 24 | // WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data); 25 | // // ... (Prepare XMP metadata). 26 | // WebPMuxSetChunk(mux, "META", &xmp, copy_data); 27 | // // Get data from mux in WebP RIFF format. 28 | // WebPMuxAssemble(mux, &output_data); 29 | // WebPMuxDelete(mux); 30 | // // ... (Consume output_data; e.g. write output_data.bytes_ to file). 31 | // WebPDataClear(&output_data); 32 | // 33 | // Code Example#2: Get image and color profile data from a WebP file. 34 | // 35 | // int copy_data = 0; 36 | // // ... (Read data from file). 37 | // WebPMux* mux = WebPMuxCreate(&data, copy_data); 38 | // WebPMuxGetImage(mux, &image); 39 | // // ... (Consume image; e.g. call WebPDecode() to decode the data). 40 | // WebPMuxGetChunk(mux, "ICCP", &icc_profile); 41 | // // ... (Consume icc_data). 42 | // WebPMuxDelete(mux); 43 | // free(data); 44 | 45 | #ifndef WEBP_WEBP_MUX_H_ 46 | #define WEBP_WEBP_MUX_H_ 47 | 48 | #include "./types.h" 49 | 50 | #if defined(__cplusplus) || defined(c_plusplus) 51 | extern "C" { 52 | #endif 53 | 54 | #define WEBP_MUX_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b) 55 | 56 | // Error codes 57 | typedef enum { 58 | WEBP_MUX_OK = 1, 59 | WEBP_MUX_NOT_FOUND = 0, 60 | WEBP_MUX_INVALID_ARGUMENT = -1, 61 | WEBP_MUX_BAD_DATA = -2, 62 | WEBP_MUX_MEMORY_ERROR = -3, 63 | WEBP_MUX_NOT_ENOUGH_DATA = -4 64 | } WebPMuxError; 65 | 66 | // Flag values for different features used in VP8X chunk. 67 | typedef enum { 68 | TILE_FLAG = 0x00000001, 69 | ANIMATION_FLAG = 0x00000002, 70 | ICCP_FLAG = 0x00000004, 71 | META_FLAG = 0x00000008, 72 | ALPHA_FLAG = 0x00000010 73 | } WebPFeatureFlags; 74 | 75 | // IDs for different types of chunks. 76 | typedef enum { 77 | WEBP_CHUNK_VP8X, // VP8X 78 | WEBP_CHUNK_ICCP, // ICCP 79 | WEBP_CHUNK_LOOP, // LOOP 80 | WEBP_CHUNK_FRAME, // FRM 81 | WEBP_CHUNK_TILE, // TILE 82 | WEBP_CHUNK_ALPHA, // ALPH 83 | WEBP_CHUNK_IMAGE, // VP8/VP8L 84 | WEBP_CHUNK_META, // META 85 | WEBP_CHUNK_UNKNOWN, // Other chunks. 86 | WEBP_CHUNK_NIL 87 | } WebPChunkId; 88 | 89 | typedef struct WebPMux WebPMux; // main opaque object. 90 | 91 | // Data type used to describe 'raw' data, e.g., chunk data 92 | // (ICC profile, metadata) and WebP compressed image data. 93 | typedef struct { 94 | const uint8_t* bytes_; 95 | size_t size_; 96 | } WebPData; 97 | 98 | //------------------------------------------------------------------------------ 99 | // Manipulation of a WebPData object. 100 | 101 | // Initializes the contents of the 'webp_data' object with default values. 102 | WEBP_EXTERN(void) WebPDataInit(WebPData* webp_data); 103 | 104 | // Clears the contents of the 'webp_data' object by calling free(). Does not 105 | // deallocate the object itself. 106 | WEBP_EXTERN(void) WebPDataClear(WebPData* webp_data); 107 | 108 | // Allocates necessary storage for 'dst' and copies the contents of 'src'. 109 | // Returns true on success. 110 | WEBP_EXTERN(int) WebPDataCopy(const WebPData* src, WebPData* dst); 111 | 112 | //------------------------------------------------------------------------------ 113 | // Life of a Mux object 114 | 115 | // Internal, version-checked, entry point 116 | WEBP_EXTERN(WebPMux*) WebPNewInternal(int); 117 | 118 | // Creates an empty mux object. 119 | // Returns: 120 | // A pointer to the newly created empty mux object. 121 | static WEBP_INLINE WebPMux* WebPMuxNew(void) { 122 | return WebPNewInternal(WEBP_MUX_ABI_VERSION); 123 | } 124 | 125 | // Deletes the mux object. 126 | // Parameters: 127 | // mux - (in/out) object to be deleted 128 | WEBP_EXTERN(void) WebPMuxDelete(WebPMux* mux); 129 | 130 | //------------------------------------------------------------------------------ 131 | // Mux creation. 132 | 133 | // Internal, version-checked, entry point 134 | WEBP_EXTERN(WebPMux*) WebPMuxCreateInternal(const WebPData*, int, int); 135 | 136 | // Creates a mux object from raw data given in WebP RIFF format. 137 | // Parameters: 138 | // bitstream - (in) the bitstream data in WebP RIFF format 139 | // copy_data - (in) value 1 indicates given data WILL copied to the mux, and 140 | // value 0 indicates data will NOT be copied. 141 | // Returns: 142 | // A pointer to the mux object created from given data - on success. 143 | // NULL - In case of invalid data or memory error. 144 | static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* bitstream, 145 | int copy_data) { 146 | return WebPMuxCreateInternal(bitstream, copy_data, WEBP_MUX_ABI_VERSION); 147 | } 148 | 149 | //------------------------------------------------------------------------------ 150 | // Single Image. 151 | 152 | // Sets the image in the mux object. Any existing images (including frame/tile) 153 | // will be removed. 154 | // Parameters: 155 | // mux - (in/out) object in which the image is to be set 156 | // bitstream - (in) can either be a raw VP8/VP8L bitstream or a single-image 157 | // WebP file (non-animated and non-tiled) 158 | // copy_data - (in) value 1 indicates given data WILL copied to the mux, and 159 | // value 0 indicates data will NOT be copied. 160 | // Returns: 161 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or bitstream is NULL. 162 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 163 | // WEBP_MUX_OK - on success. 164 | WEBP_EXTERN(WebPMuxError) WebPMuxSetImage(WebPMux* mux, 165 | const WebPData* bitstream, 166 | int copy_data); 167 | 168 | // Gets image data from the mux object. 169 | // The content of 'bitstream' is allocated using malloc(), and NOT 170 | // owned by the 'mux' object. It MUST be deallocated by the caller by calling 171 | // WebPDataClear(). 172 | // Parameters: 173 | // mux - (in) object from which the image is to be fetched 174 | // bitstream - (out) the image data 175 | // Returns: 176 | // WEBP_MUX_INVALID_ARGUMENT - if either mux or bitstream is NULL 177 | // or if mux contains animation/tiling. 178 | // WEBP_MUX_NOT_FOUND - if image is not present in mux object. 179 | // WEBP_MUX_OK - on success. 180 | WEBP_EXTERN(WebPMuxError) WebPMuxGetImage(const WebPMux* mux, 181 | WebPData* bitstream); 182 | 183 | // Deletes the image in the mux object. 184 | // Parameters: 185 | // mux - (in/out) object from which the image is to be deleted 186 | // Returns: 187 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL 188 | // or if mux contains animation/tiling. 189 | // WEBP_MUX_NOT_FOUND - if image is not present in mux object. 190 | // WEBP_MUX_OK - on success. 191 | WEBP_EXTERN(WebPMuxError) WebPMuxDeleteImage(WebPMux* mux); 192 | 193 | //------------------------------------------------------------------------------ 194 | // Chunks. 195 | 196 | // Note: Only non-image related chunks should be managed through chunk APIs. 197 | // (Image related chunks are: "FRM ", "TILE", "VP8 ", "VP8L" and "ALPH"). 198 | 199 | // Adds a chunk with id 'fourcc' and data 'chunk_data' in the mux object. 200 | // Any existing chunk(s) with the same id will be removed. 201 | // Parameters: 202 | // mux - (in/out) object to which the chunk is to be added 203 | // fourcc - (in) a character array containing the fourcc of the given chunk; 204 | // e.g., "ICCP", "META" etc. 205 | // chunk_data - (in) the chunk data to be added 206 | // copy_data - (in) value 1 indicates given data WILL copied to the mux, and 207 | // value 0 indicates data will NOT be copied. 208 | // Returns: 209 | // WEBP_MUX_INVALID_ARGUMENT - if mux or chunk_data is NULL 210 | // or if fourcc corresponds to an image chunk. 211 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 212 | // WEBP_MUX_OK - on success. 213 | WEBP_EXTERN(WebPMuxError) WebPMuxSetChunk( 214 | WebPMux* mux, const char fourcc[4], const WebPData* chunk_data, 215 | int copy_data); 216 | 217 | // Gets a reference to the data of the chunk with id 'fourcc' in the mux object. 218 | // The caller should NOT free the returned data. 219 | // Parameters: 220 | // mux - (in) object from which the chunk data is to be fetched 221 | // fourcc - (in) a character array containing the fourcc of the chunk; 222 | // e.g., "ICCP", "META" etc. 223 | // chunk_data - (out) returned chunk data 224 | // Returns: 225 | // WEBP_MUX_INVALID_ARGUMENT - if either mux or chunk_data is NULL 226 | // or if fourcc corresponds to an image chunk. 227 | // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given id. 228 | // WEBP_MUX_OK - on success. 229 | WEBP_EXTERN(WebPMuxError) WebPMuxGetChunk( 230 | const WebPMux* mux, const char fourcc[4], WebPData* chunk_data); 231 | 232 | // Deletes the chunk with the given 'fourcc' from the mux object. 233 | // Parameters: 234 | // mux - (in/out) object from which the chunk is to be deleted 235 | // fourcc - (in) a character array containing the fourcc of the chunk; 236 | // e.g., "ICCP", "META" etc. 237 | // Returns: 238 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL 239 | // or if fourcc corresponds to an image chunk. 240 | // WEBP_MUX_NOT_FOUND - If mux does not contain a chunk with the given fourcc. 241 | // WEBP_MUX_OK - on success. 242 | WEBP_EXTERN(WebPMuxError) WebPMuxDeleteChunk( 243 | WebPMux* mux, const char fourcc[4]); 244 | 245 | //------------------------------------------------------------------------------ 246 | // Animation. 247 | 248 | // Encapsulates data about a single frame/tile. 249 | typedef struct { 250 | WebPData bitstream_; // image data: can either be a raw VP8/VP8L bitstream 251 | // or a single-image WebP file. 252 | int x_offset_; // x-offset of the frame. 253 | int y_offset_; // y-offset of the frame. 254 | int duration_; // duration of the frame (in milliseconds). 255 | uint32_t pad[3]; // padding for later use 256 | } WebPMuxFrameInfo; 257 | 258 | // Adds an animation frame at the end of the mux object. 259 | // Note: as WebP only supports even offsets, any odd offset will be snapped to 260 | // an even location using: offset &= ~1 261 | // Parameters: 262 | // mux - (in/out) object to which an animation frame is to be added 263 | // frame - (in) frame data. 264 | // copy_data - (in) value 1 indicates given data WILL copied to the mux, and 265 | // value 0 indicates data will NOT be copied. 266 | // Returns: 267 | // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL 268 | // or if content of 'frame' is invalid. 269 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 270 | // WEBP_MUX_OK - on success. 271 | WEBP_EXTERN(WebPMuxError) WebPMuxPushFrame( 272 | WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data); 273 | 274 | // Gets the nth animation frame from the mux object. 275 | // The content of 'frame->bitstream_' is allocated using malloc(), and NOT 276 | // owned by the 'mux' object. It MUST be deallocated by the caller by calling 277 | // WebPDataClear(). 278 | // nth=0 has a special meaning - last position. 279 | // Parameters: 280 | // mux - (in) object from which the info is to be fetched 281 | // nth - (in) index of the frame in the mux object 282 | // frame - (out) data of the returned frame 283 | // Returns: 284 | // WEBP_MUX_INVALID_ARGUMENT - if mux or frame is NULL 285 | // WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object. 286 | // WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid. 287 | // WEBP_MUX_OK - on success. 288 | WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame( 289 | const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* frame); 290 | 291 | // Deletes an animation frame from the mux object. 292 | // nth=0 has a special meaning - last position. 293 | // Parameters: 294 | // mux - (in/out) object from which a frame is to be deleted 295 | // nth - (in) The position from which the frame is to be deleted 296 | // Returns: 297 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL 298 | // WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object 299 | // before deletion. 300 | // WEBP_MUX_OK - on success. 301 | WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* mux, uint32_t nth); 302 | 303 | // Sets the animation loop count in the mux object. Any existing loop count 304 | // value(s) will be removed. 305 | // Parameters: 306 | // mux - (in/out) object in which loop chunk is to be set/added 307 | // loop_count - (in) animation loop count value. 308 | // Note that loop_count of zero denotes infinite loop. 309 | // Returns: 310 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL 311 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 312 | // WEBP_MUX_OK - on success. 313 | WEBP_EXTERN(WebPMuxError) WebPMuxSetLoopCount(WebPMux* mux, int loop_count); 314 | 315 | // Gets the animation loop count from the mux object. 316 | // Parameters: 317 | // mux - (in) object from which the loop count is to be fetched 318 | // loop_count - (out) the loop_count value present in the LOOP chunk 319 | // Returns: 320 | // WEBP_MUX_INVALID_ARGUMENT - if either of mux or loop_count is NULL 321 | // WEBP_MUX_NOT_FOUND - if loop chunk is not present in mux object. 322 | // WEBP_MUX_OK - on success. 323 | WEBP_EXTERN(WebPMuxError) WebPMuxGetLoopCount(const WebPMux* mux, 324 | int* loop_count); 325 | 326 | //------------------------------------------------------------------------------ 327 | // Tiling. 328 | 329 | // Adds a tile at the end of the mux object. 330 | // Note: as WebP only supports even offsets, any odd offset will be snapped to 331 | // an even location using: offset &= ~1 332 | // Parameters: 333 | // mux - (in/out) object to which a tile is to be added. 334 | // tile - (in) tile data. 335 | // copy_data - (in) value 1 indicates given data WILL copied to the mux, and 336 | // value 0 indicates data will NOT be copied. 337 | // Returns: 338 | // WEBP_MUX_INVALID_ARGUMENT - if mux or tile is NULL 339 | // or if content of 'tile' is invalid. 340 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 341 | // WEBP_MUX_OK - on success. 342 | WEBP_EXTERN(WebPMuxError) WebPMuxPushTile( 343 | WebPMux* mux, const WebPMuxFrameInfo* tile, int copy_data); 344 | 345 | // Gets the nth tile from the mux object. 346 | // The content of 'tile->bitstream_' is allocated using malloc(), and NOT 347 | // owned by the 'mux' object. It MUST be deallocated by the caller by calling 348 | // WebPDataClear(). 349 | // nth=0 has a special meaning - last position. 350 | // Parameters: 351 | // mux - (in) object from which the info is to be fetched 352 | // nth - (in) index of the tile in the mux object 353 | // tile - (out) data of the returned tile 354 | // Returns: 355 | // WEBP_MUX_INVALID_ARGUMENT - if either mux or tile is NULL 356 | // WEBP_MUX_NOT_FOUND - if there are less than nth tiles in the mux object. 357 | // WEBP_MUX_BAD_DATA - if nth tile chunk in mux is invalid. 358 | // WEBP_MUX_OK - on success. 359 | WEBP_EXTERN(WebPMuxError) WebPMuxGetTile( 360 | const WebPMux* mux, uint32_t nth, WebPMuxFrameInfo* tile); 361 | 362 | // Deletes a tile from the mux object. 363 | // nth=0 has a special meaning - last position 364 | // Parameters: 365 | // mux - (in/out) object from which a tile is to be deleted 366 | // nth - (in) The position from which the tile is to be deleted 367 | // Returns: 368 | // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL 369 | // WEBP_MUX_NOT_FOUND - If there are less than nth tiles in the mux object 370 | // before deletion. 371 | // WEBP_MUX_OK - on success. 372 | WEBP_EXTERN(WebPMuxError) WebPMuxDeleteTile(WebPMux* mux, uint32_t nth); 373 | 374 | //------------------------------------------------------------------------------ 375 | // Misc Utilities. 376 | 377 | // Gets the feature flags from the mux object. 378 | // Parameters: 379 | // mux - (in) object from which the features are to be fetched 380 | // flags - (out) the flags specifying which features are present in the 381 | // mux object. This will be an OR of various flag values. 382 | // Enum 'WebPFeatureFlags' can be used to test individual flag values. 383 | // Returns: 384 | // WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL 385 | // WEBP_MUX_NOT_FOUND - if VP8X chunk is not present in mux object. 386 | // WEBP_MUX_BAD_DATA - if VP8X chunk in mux is invalid. 387 | // WEBP_MUX_OK - on success. 388 | WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux, 389 | uint32_t* flags); 390 | 391 | // Gets number of chunks having tag value tag in the mux object. 392 | // Parameters: 393 | // mux - (in) object from which the info is to be fetched 394 | // id - (in) chunk id specifying the type of chunk 395 | // num_elements - (out) number of chunks with the given chunk id 396 | // Returns: 397 | // WEBP_MUX_INVALID_ARGUMENT - if either mux, or num_elements is NULL 398 | // WEBP_MUX_OK - on success. 399 | WEBP_EXTERN(WebPMuxError) WebPMuxNumChunks(const WebPMux* mux, 400 | WebPChunkId id, int* num_elements); 401 | 402 | // Assembles all chunks in WebP RIFF format and returns in 'assembled_data'. 403 | // This function also validates the mux object. 404 | // Note: The content of 'assembled_data' will be ignored and overwritten. 405 | // Also, the content of 'assembled_data' is allocated using malloc(), and NOT 406 | // owned by the 'mux' object. It MUST be deallocated by the caller by calling 407 | // WebPDataClear(). 408 | // Parameters: 409 | // mux - (in/out) object whose chunks are to be assembled 410 | // assembled_data - (out) assembled WebP data 411 | // Returns: 412 | // WEBP_MUX_BAD_DATA - if mux object is invalid. 413 | // WEBP_MUX_INVALID_ARGUMENT - if either mux, output_data or output_size is 414 | // NULL. 415 | // WEBP_MUX_MEMORY_ERROR - on memory allocation error. 416 | // WEBP_MUX_OK - on success 417 | WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* mux, 418 | WebPData* assembled_data); 419 | 420 | //------------------------------------------------------------------------------ 421 | // Demux API. 422 | // Enables extraction of image and extended format data from WebP files. 423 | 424 | #define WEBP_DEMUX_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b) 425 | 426 | typedef struct WebPDemuxer WebPDemuxer; 427 | 428 | typedef enum { 429 | WEBP_DEMUX_PARSING_HEADER, // Not enough data to parse full header. 430 | WEBP_DEMUX_PARSED_HEADER, // Header parsing complete, data may be available. 431 | WEBP_DEMUX_DONE // Entire file has been parsed. 432 | } WebPDemuxState; 433 | 434 | //------------------------------------------------------------------------------ 435 | // Life of a Demux object 436 | 437 | // Internal, version-checked, entry point 438 | WEBP_EXTERN(WebPDemuxer*) WebPDemuxInternal( 439 | const WebPData*, int, WebPDemuxState*, int); 440 | 441 | // Parses the WebP file given by 'data'. 442 | // A complete WebP file must be present in 'data' for the function to succeed. 443 | // Returns a WebPDemuxer object on successful parse, NULL otherwise. 444 | static WEBP_INLINE WebPDemuxer* WebPDemux(const WebPData* data) { 445 | return WebPDemuxInternal(data, 0, NULL, WEBP_DEMUX_ABI_VERSION); 446 | } 447 | 448 | // Parses the WebP file given by 'data'. 449 | // If 'state' is non-NULL it will be set to indicate the status of the demuxer. 450 | // Returns a WebPDemuxer object on successful parse, NULL otherwise. 451 | static WEBP_INLINE WebPDemuxer* WebPDemuxPartial( 452 | const WebPData* data, WebPDemuxState* state) { 453 | return WebPDemuxInternal(data, 1, state, WEBP_DEMUX_ABI_VERSION); 454 | } 455 | 456 | // Frees memory associated with 'dmux'. 457 | WEBP_EXTERN(void) WebPDemuxDelete(WebPDemuxer* dmux); 458 | 459 | //------------------------------------------------------------------------------ 460 | // Data/information extraction. 461 | 462 | typedef enum { 463 | WEBP_FF_FORMAT_FLAGS, // Extended format flags present in the 'VP8X' chunk. 464 | WEBP_FF_CANVAS_WIDTH, 465 | WEBP_FF_CANVAS_HEIGHT, 466 | WEBP_FF_LOOP_COUNT 467 | } WebPFormatFeature; 468 | 469 | // Get the 'feature' value from the 'dmux'. 470 | // NOTE: values are only valid if WebPDemux() was used or WebPDemuxPartial() 471 | // returned a state > WEBP_DEMUX_PARSING_HEADER. 472 | WEBP_EXTERN(uint32_t) WebPDemuxGetI( 473 | const WebPDemuxer* dmux, WebPFormatFeature feature); 474 | 475 | //------------------------------------------------------------------------------ 476 | // Frame iteration. 477 | 478 | typedef struct { 479 | int frame_num_; 480 | int num_frames_; 481 | int tile_num_; 482 | int num_tiles_; 483 | int x_offset_, y_offset_; // offset relative to the canvas. 484 | int width_, height_; // dimensions of this frame or tile. 485 | int duration_; // display duration in milliseconds. 486 | int complete_; // true if 'tile_' contains a full frame. partial images may 487 | // still be decoded with the WebP incremental decoder. 488 | WebPData tile_; // The frame or tile given by 'frame_num_' and 'tile_num_'. 489 | 490 | uint32_t pad[4]; // padding for later use 491 | void* private_; 492 | } WebPIterator; 493 | 494 | // Retrieves frame 'frame_number' from 'dmux'. 495 | // 'iter->tile_' points to the first tile on return from this function. 496 | // Individual tiles may be extracted using WebPDemuxSetTile(). 497 | // Setting 'frame_number' equal to 0 will return the last frame of the image. 498 | // Returns false if 'dmux' is NULL or frame 'frame_number' is not present. 499 | // Call WebPDemuxReleaseIterator() when use of the iterator is complete. 500 | // NOTE: 'dmux' must persist for the lifetime of 'iter'. 501 | WEBP_EXTERN(int) WebPDemuxGetFrame( 502 | const WebPDemuxer* dmux, int frame_number, WebPIterator* iter); 503 | 504 | // Sets 'iter->tile_' to point to the next ('iter->frame_num_' + 1) or previous 505 | // ('iter->frame_num_' - 1) frame. These functions do not loop. 506 | // Returns true on success, false otherwise. 507 | WEBP_EXTERN(int) WebPDemuxNextFrame(WebPIterator* iter); 508 | WEBP_EXTERN(int) WebPDemuxPrevFrame(WebPIterator* iter); 509 | 510 | // Sets 'iter->tile_' to reflect tile number 'tile_number'. 511 | // Returns true if tile 'tile_number' is present, false otherwise. 512 | WEBP_EXTERN(int) WebPDemuxSelectTile(WebPIterator* iter, int tile_number); 513 | 514 | // Releases any memory associated with 'iter'. 515 | // Must be called before destroying the associated WebPDemuxer with 516 | // WebPDemuxDelete(). 517 | WEBP_EXTERN(void) WebPDemuxReleaseIterator(WebPIterator* iter); 518 | 519 | //------------------------------------------------------------------------------ 520 | // Chunk iteration. 521 | 522 | typedef struct { 523 | // The current and total number of chunks with the fourcc given to 524 | // WebPDemuxGetChunk(). 525 | int chunk_num_; 526 | int num_chunks_; 527 | WebPData chunk_; // The payload of the chunk. 528 | 529 | uint32_t pad[6]; // padding for later use 530 | void* private_; 531 | } WebPChunkIterator; 532 | 533 | // Retrieves the 'chunk_number' instance of the chunk with id 'fourcc' from 534 | // 'dmux'. 535 | // 'fourcc' is a character array containing the fourcc of the chunk to return, 536 | // e.g., "ICCP", "META", "EXIF", etc. 537 | // Setting 'chunk_number' equal to 0 will return the last chunk in a set. 538 | // Returns true if the chunk is found, false otherwise. Image related chunk 539 | // payloads are accessed through WebPDemuxGetFrame() and related functions. 540 | // Call WebPDemuxReleaseChunkIterator() when use of the iterator is complete. 541 | // NOTE: 'dmux' must persist for the lifetime of the iterator. 542 | WEBP_EXTERN(int) WebPDemuxGetChunk(const WebPDemuxer* dmux, 543 | const char fourcc[4], int chunk_number, 544 | WebPChunkIterator* iter); 545 | 546 | // Sets 'iter->chunk_' to point to the next ('iter->chunk_num_' + 1) or previous 547 | // ('iter->chunk_num_' - 1) chunk. These functions do not loop. 548 | // Returns true on success, false otherwise. 549 | WEBP_EXTERN(int) WebPDemuxNextChunk(WebPChunkIterator* iter); 550 | WEBP_EXTERN(int) WebPDemuxPrevChunk(WebPChunkIterator* iter); 551 | 552 | // Releases any memory associated with 'iter'. 553 | // Must be called before destroying the associated WebPDemuxer with 554 | // WebPDemuxDelete(). 555 | WEBP_EXTERN(void) WebPDemuxReleaseChunkIterator(WebPChunkIterator* iter); 556 | 557 | //------------------------------------------------------------------------------ 558 | 559 | #if defined(__cplusplus) || defined(c_plusplus) 560 | } // extern "C" 561 | #endif 562 | 563 | #endif /* WEBP_WEBP_MUX_H_ */ 564 | -------------------------------------------------------------------------------- /include/webp/types.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Google Inc. All Rights Reserved. 2 | // 3 | // This code is licensed under the same terms as WebM: 4 | // Software License Agreement: http://www.webmproject.org/license/software/ 5 | // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 6 | // ----------------------------------------------------------------------------- 7 | // 8 | // Common types 9 | // 10 | // Author: Skal (pascal.massimino@gmail.com) 11 | 12 | #ifndef WEBP_WEBP_TYPES_H_ 13 | #define WEBP_WEBP_TYPES_H_ 14 | 15 | #include // for size_t 16 | 17 | #ifndef _MSC_VER 18 | #include 19 | #ifdef __STRICT_ANSI__ 20 | #define WEBP_INLINE 21 | #else /* __STRICT_ANSI__ */ 22 | #define WEBP_INLINE inline 23 | #endif 24 | #else 25 | typedef signed char int8_t; 26 | typedef unsigned char uint8_t; 27 | typedef signed short int16_t; 28 | typedef unsigned short uint16_t; 29 | typedef signed int int32_t; 30 | typedef unsigned int uint32_t; 31 | typedef unsigned long long int uint64_t; 32 | typedef long long int int64_t; 33 | #define WEBP_INLINE __forceinline 34 | #endif /* _MSC_VER */ 35 | 36 | #ifndef WEBP_EXTERN 37 | // This explicitly marks library functions and allows for changing the 38 | // signature for e.g., Windows DLL builds. 39 | #define WEBP_EXTERN(type) extern type 40 | #endif /* WEBP_EXTERN */ 41 | 42 | // Macro to check ABI compatibility (same major revision number) 43 | #define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8)) 44 | 45 | #endif /* WEBP_WEBP_TYPES_H_ */ 46 | -------------------------------------------------------------------------------- /lib/libwebp-static.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dchest/webp-quicklook/e9c9a66959037f140996e90e031ed0cdca831921/lib/libwebp-static.a -------------------------------------------------------------------------------- /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 "9751E920-D39F-4881-969A-03BCE5B273E7" 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 | --------------------------------------------------------------------------------