├── .gitignore ├── LICENSE ├── QLImageset.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── QLImageset ├── GeneratePreviewForURL.m ├── GenerateThumbnailForURL.m ├── Info.plist ├── QLImageset.h ├── QLImageset.m └── main.c ├── README.md └── dump └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | 28 | ignore/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 QFish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /QLImageset.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E9735DC21AB15771001D3617 /* GenerateThumbnailForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = E9735DC11AB15771001D3617 /* GenerateThumbnailForURL.m */; }; 11 | E9735DC41AB15771001D3617 /* GeneratePreviewForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = E9735DC31AB15771001D3617 /* GeneratePreviewForURL.m */; }; 12 | E9735DC61AB15771001D3617 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = E9735DC51AB15771001D3617 /* main.c */; }; 13 | E9735DCE1AB15839001D3617 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9735DCD1AB15839001D3617 /* AppKit.framework */; }; 14 | E9735DD01AB1599F001D3617 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9735DCF1AB1599F001D3617 /* CoreFoundation.framework */; }; 15 | E9735DD21AB159A8001D3617 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9735DD11AB159A8001D3617 /* CoreServices.framework */; }; 16 | E9735DD41AB159B1001D3617 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9735DD31AB159B1001D3617 /* Cocoa.framework */; }; 17 | E9735DD61AB159B5001D3617 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9735DD51AB159B5001D3617 /* QuickLook.framework */; }; 18 | E992AABA1AB426BE00EB2E7B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E992AAB91AB426BE00EB2E7B /* main.m */; }; 19 | E992AABE1AB4276500EB2E7B /* QLImageset.m in Sources */ = {isa = PBXBuildFile; fileRef = E9A2BE4C1AB1B07C0066636B /* QLImageset.m */; }; 20 | E9A2BE4D1AB1B07C0066636B /* QLImageset.h in Headers */ = {isa = PBXBuildFile; fileRef = E9A2BE4B1AB1B07C0066636B /* QLImageset.h */; }; 21 | E9A2BE4E1AB1B07C0066636B /* QLImageset.m in Sources */ = {isa = PBXBuildFile; fileRef = E9A2BE4C1AB1B07C0066636B /* QLImageset.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXCopyFilesBuildPhase section */ 25 | E992AAB51AB426BE00EB2E7B /* CopyFiles */ = { 26 | isa = PBXCopyFilesBuildPhase; 27 | buildActionMask = 2147483647; 28 | dstPath = /usr/share/man/man1/; 29 | dstSubfolderSpec = 0; 30 | files = ( 31 | ); 32 | runOnlyForDeploymentPostprocessing = 1; 33 | }; 34 | /* End PBXCopyFilesBuildPhase section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | E9735DBC1AB15771001D3617 /* QLImageset.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QLImageset.qlgenerator; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | E9735DC01AB15771001D3617 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | E9735DC11AB15771001D3617 /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GenerateThumbnailForURL.m; sourceTree = ""; }; 40 | E9735DC31AB15771001D3617 /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GeneratePreviewForURL.m; sourceTree = ""; }; 41 | E9735DC51AB15771001D3617 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 42 | E9735DCD1AB15839001D3617 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 43 | E9735DCF1AB1599F001D3617 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 44 | E9735DD11AB159A8001D3617 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; 45 | E9735DD31AB159B1001D3617 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 46 | E9735DD51AB159B5001D3617 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = System/Library/Frameworks/QuickLook.framework; sourceTree = SDKROOT; }; 47 | E992AAB71AB426BE00EB2E7B /* dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dump; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | E992AAB91AB426BE00EB2E7B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 49 | E9A2BE4B1AB1B07C0066636B /* QLImageset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QLImageset.h; sourceTree = ""; }; 50 | E9A2BE4C1AB1B07C0066636B /* QLImageset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QLImageset.m; sourceTree = ""; }; 51 | /* End PBXFileReference section */ 52 | 53 | /* Begin PBXFrameworksBuildPhase section */ 54 | E9735DB81AB15771001D3617 /* Frameworks */ = { 55 | isa = PBXFrameworksBuildPhase; 56 | buildActionMask = 2147483647; 57 | files = ( 58 | E9735DD61AB159B5001D3617 /* QuickLook.framework in Frameworks */, 59 | E9735DD41AB159B1001D3617 /* Cocoa.framework in Frameworks */, 60 | E9735DD21AB159A8001D3617 /* CoreServices.framework in Frameworks */, 61 | E9735DD01AB1599F001D3617 /* CoreFoundation.framework in Frameworks */, 62 | E9735DCE1AB15839001D3617 /* AppKit.framework in Frameworks */, 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | E992AAB41AB426BE00EB2E7B /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | E9735DB21AB15771001D3617 = { 77 | isa = PBXGroup; 78 | children = ( 79 | E9735DBE1AB15771001D3617 /* QLImageset */, 80 | E9735DCC1AB15823001D3617 /* External Frameworks and Libraries */, 81 | E992AAB81AB426BE00EB2E7B /* dump */, 82 | E9735DBD1AB15771001D3617 /* Products */, 83 | ); 84 | sourceTree = ""; 85 | }; 86 | E9735DBD1AB15771001D3617 /* Products */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | E9735DBC1AB15771001D3617 /* QLImageset.qlgenerator */, 90 | E992AAB71AB426BE00EB2E7B /* dump */, 91 | ); 92 | name = Products; 93 | sourceTree = ""; 94 | }; 95 | E9735DBE1AB15771001D3617 /* QLImageset */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | E9735DC11AB15771001D3617 /* GenerateThumbnailForURL.m */, 99 | E9735DC31AB15771001D3617 /* GeneratePreviewForURL.m */, 100 | E9A2BE4B1AB1B07C0066636B /* QLImageset.h */, 101 | E9A2BE4C1AB1B07C0066636B /* QLImageset.m */, 102 | E9735DC51AB15771001D3617 /* main.c */, 103 | E9735DBF1AB15771001D3617 /* Supporting Files */, 104 | ); 105 | path = QLImageset; 106 | sourceTree = ""; 107 | }; 108 | E9735DBF1AB15771001D3617 /* Supporting Files */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | E9735DC01AB15771001D3617 /* Info.plist */, 112 | ); 113 | name = "Supporting Files"; 114 | sourceTree = ""; 115 | }; 116 | E9735DCC1AB15823001D3617 /* External Frameworks and Libraries */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | E9735DD51AB159B5001D3617 /* QuickLook.framework */, 120 | E9735DD31AB159B1001D3617 /* Cocoa.framework */, 121 | E9735DD11AB159A8001D3617 /* CoreServices.framework */, 122 | E9735DCF1AB1599F001D3617 /* CoreFoundation.framework */, 123 | E9735DCD1AB15839001D3617 /* AppKit.framework */, 124 | ); 125 | name = "External Frameworks and Libraries"; 126 | path = QLImageset; 127 | sourceTree = ""; 128 | }; 129 | E992AAB81AB426BE00EB2E7B /* dump */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | E992AAB91AB426BE00EB2E7B /* main.m */, 133 | ); 134 | path = dump; 135 | sourceTree = ""; 136 | }; 137 | /* End PBXGroup section */ 138 | 139 | /* Begin PBXHeadersBuildPhase section */ 140 | E9735DB91AB15771001D3617 /* Headers */ = { 141 | isa = PBXHeadersBuildPhase; 142 | buildActionMask = 2147483647; 143 | files = ( 144 | E9A2BE4D1AB1B07C0066636B /* QLImageset.h in Headers */, 145 | ); 146 | runOnlyForDeploymentPostprocessing = 0; 147 | }; 148 | /* End PBXHeadersBuildPhase section */ 149 | 150 | /* Begin PBXNativeTarget section */ 151 | E9735DBB1AB15771001D3617 /* QLImageset */ = { 152 | isa = PBXNativeTarget; 153 | buildConfigurationList = E9735DC91AB15771001D3617 /* Build configuration list for PBXNativeTarget "QLImageset" */; 154 | buildPhases = ( 155 | E9735DB71AB15771001D3617 /* Sources */, 156 | E9735DB81AB15771001D3617 /* Frameworks */, 157 | E9735DB91AB15771001D3617 /* Headers */, 158 | E9735DBA1AB15771001D3617 /* Resources */, 159 | ); 160 | buildRules = ( 161 | ); 162 | dependencies = ( 163 | ); 164 | name = QLImageset; 165 | productName = QLImageset; 166 | productReference = E9735DBC1AB15771001D3617 /* QLImageset.qlgenerator */; 167 | productType = "com.apple.product-type.bundle"; 168 | }; 169 | E992AAB61AB426BE00EB2E7B /* dump */ = { 170 | isa = PBXNativeTarget; 171 | buildConfigurationList = E992AABD1AB426BE00EB2E7B /* Build configuration list for PBXNativeTarget "dump" */; 172 | buildPhases = ( 173 | E992AAB31AB426BE00EB2E7B /* Sources */, 174 | E992AAB41AB426BE00EB2E7B /* Frameworks */, 175 | E992AAB51AB426BE00EB2E7B /* CopyFiles */, 176 | ); 177 | buildRules = ( 178 | ); 179 | dependencies = ( 180 | ); 181 | name = dump; 182 | productName = dump; 183 | productReference = E992AAB71AB426BE00EB2E7B /* dump */; 184 | productType = "com.apple.product-type.tool"; 185 | }; 186 | /* End PBXNativeTarget section */ 187 | 188 | /* Begin PBXProject section */ 189 | E9735DB31AB15771001D3617 /* Project object */ = { 190 | isa = PBXProject; 191 | attributes = { 192 | LastUpgradeCheck = 0610; 193 | ORGANIZATIONNAME = QFish; 194 | TargetAttributes = { 195 | E9735DBB1AB15771001D3617 = { 196 | CreatedOnToolsVersion = 6.1.1; 197 | }; 198 | E992AAB61AB426BE00EB2E7B = { 199 | CreatedOnToolsVersion = 6.1.1; 200 | }; 201 | }; 202 | }; 203 | buildConfigurationList = E9735DB61AB15771001D3617 /* Build configuration list for PBXProject "QLImageset" */; 204 | compatibilityVersion = "Xcode 3.2"; 205 | developmentRegion = English; 206 | hasScannedForEncodings = 0; 207 | knownRegions = ( 208 | en, 209 | ); 210 | mainGroup = E9735DB21AB15771001D3617; 211 | productRefGroup = E9735DBD1AB15771001D3617 /* Products */; 212 | projectDirPath = ""; 213 | projectRoot = ""; 214 | targets = ( 215 | E9735DBB1AB15771001D3617 /* QLImageset */, 216 | E992AAB61AB426BE00EB2E7B /* dump */, 217 | ); 218 | }; 219 | /* End PBXProject section */ 220 | 221 | /* Begin PBXResourcesBuildPhase section */ 222 | E9735DBA1AB15771001D3617 /* Resources */ = { 223 | isa = PBXResourcesBuildPhase; 224 | buildActionMask = 2147483647; 225 | files = ( 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | }; 229 | /* End PBXResourcesBuildPhase section */ 230 | 231 | /* Begin PBXSourcesBuildPhase section */ 232 | E9735DB71AB15771001D3617 /* Sources */ = { 233 | isa = PBXSourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | E9735DC21AB15771001D3617 /* GenerateThumbnailForURL.m in Sources */, 237 | E9735DC41AB15771001D3617 /* GeneratePreviewForURL.m in Sources */, 238 | E9735DC61AB15771001D3617 /* main.c in Sources */, 239 | E9A2BE4E1AB1B07C0066636B /* QLImageset.m in Sources */, 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | E992AAB31AB426BE00EB2E7B /* Sources */ = { 244 | isa = PBXSourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | E992AABE1AB4276500EB2E7B /* QLImageset.m in Sources */, 248 | E992AABA1AB426BE00EB2E7B /* main.m in Sources */, 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | /* End PBXSourcesBuildPhase section */ 253 | 254 | /* Begin XCBuildConfiguration section */ 255 | E9735DC71AB15771001D3617 /* Debug */ = { 256 | isa = XCBuildConfiguration; 257 | buildSettings = { 258 | ALWAYS_SEARCH_USER_PATHS = NO; 259 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 260 | CLANG_CXX_LIBRARY = "libc++"; 261 | CLANG_ENABLE_MODULES = YES; 262 | CLANG_ENABLE_OBJC_ARC = YES; 263 | CLANG_WARN_BOOL_CONVERSION = YES; 264 | CLANG_WARN_CONSTANT_CONVERSION = YES; 265 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 266 | CLANG_WARN_EMPTY_BODY = YES; 267 | CLANG_WARN_ENUM_CONVERSION = YES; 268 | CLANG_WARN_INT_CONVERSION = YES; 269 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 270 | CLANG_WARN_UNREACHABLE_CODE = YES; 271 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 272 | COPY_PHASE_STRIP = NO; 273 | ENABLE_STRICT_OBJC_MSGSEND = YES; 274 | GCC_C_LANGUAGE_STANDARD = gnu99; 275 | GCC_DYNAMIC_NO_PIC = NO; 276 | GCC_OPTIMIZATION_LEVEL = 0; 277 | GCC_PREPROCESSOR_DEFINITIONS = ( 278 | "DEBUG=1", 279 | "$(inherited)", 280 | ); 281 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 283 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 284 | GCC_WARN_UNDECLARED_SELECTOR = YES; 285 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 286 | GCC_WARN_UNUSED_FUNCTION = YES; 287 | GCC_WARN_UNUSED_VARIABLE = YES; 288 | MACOSX_DEPLOYMENT_TARGET = 10.10; 289 | MTL_ENABLE_DEBUG_INFO = YES; 290 | ONLY_ACTIVE_ARCH = YES; 291 | SDKROOT = macosx; 292 | }; 293 | name = Debug; 294 | }; 295 | E9735DC81AB15771001D3617 /* Release */ = { 296 | isa = XCBuildConfiguration; 297 | buildSettings = { 298 | ALWAYS_SEARCH_USER_PATHS = NO; 299 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 300 | CLANG_CXX_LIBRARY = "libc++"; 301 | CLANG_ENABLE_MODULES = YES; 302 | CLANG_ENABLE_OBJC_ARC = YES; 303 | CLANG_WARN_BOOL_CONVERSION = YES; 304 | CLANG_WARN_CONSTANT_CONVERSION = YES; 305 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 306 | CLANG_WARN_EMPTY_BODY = YES; 307 | CLANG_WARN_ENUM_CONVERSION = YES; 308 | CLANG_WARN_INT_CONVERSION = YES; 309 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 310 | CLANG_WARN_UNREACHABLE_CODE = YES; 311 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 312 | COPY_PHASE_STRIP = YES; 313 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 314 | ENABLE_NS_ASSERTIONS = NO; 315 | ENABLE_STRICT_OBJC_MSGSEND = YES; 316 | GCC_C_LANGUAGE_STANDARD = gnu99; 317 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 318 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 319 | GCC_WARN_UNDECLARED_SELECTOR = YES; 320 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 321 | GCC_WARN_UNUSED_FUNCTION = YES; 322 | GCC_WARN_UNUSED_VARIABLE = YES; 323 | MACOSX_DEPLOYMENT_TARGET = 10.10; 324 | MTL_ENABLE_DEBUG_INFO = NO; 325 | SDKROOT = macosx; 326 | }; 327 | name = Release; 328 | }; 329 | E9735DCA1AB15771001D3617 /* Debug */ = { 330 | isa = XCBuildConfiguration; 331 | buildSettings = { 332 | COMBINE_HIDPI_IMAGES = YES; 333 | INFOPLIST_FILE = QLImageset/Info.plist; 334 | INSTALL_PATH = /Library/QuickLook; 335 | PRODUCT_NAME = "$(TARGET_NAME)"; 336 | WRAPPER_EXTENSION = qlgenerator; 337 | }; 338 | name = Debug; 339 | }; 340 | E9735DCB1AB15771001D3617 /* Release */ = { 341 | isa = XCBuildConfiguration; 342 | buildSettings = { 343 | COMBINE_HIDPI_IMAGES = YES; 344 | INFOPLIST_FILE = QLImageset/Info.plist; 345 | INSTALL_PATH = /Library/QuickLook; 346 | PRODUCT_NAME = "$(TARGET_NAME)"; 347 | WRAPPER_EXTENSION = qlgenerator; 348 | }; 349 | name = Release; 350 | }; 351 | E992AABB1AB426BE00EB2E7B /* Debug */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | GCC_PREPROCESSOR_DEFINITIONS = ( 355 | "DEBUG=1", 356 | "$(inherited)", 357 | ); 358 | PRODUCT_NAME = "$(TARGET_NAME)"; 359 | }; 360 | name = Debug; 361 | }; 362 | E992AABC1AB426BE00EB2E7B /* Release */ = { 363 | isa = XCBuildConfiguration; 364 | buildSettings = { 365 | PRODUCT_NAME = "$(TARGET_NAME)"; 366 | }; 367 | name = Release; 368 | }; 369 | /* End XCBuildConfiguration section */ 370 | 371 | /* Begin XCConfigurationList section */ 372 | E9735DB61AB15771001D3617 /* Build configuration list for PBXProject "QLImageset" */ = { 373 | isa = XCConfigurationList; 374 | buildConfigurations = ( 375 | E9735DC71AB15771001D3617 /* Debug */, 376 | E9735DC81AB15771001D3617 /* Release */, 377 | ); 378 | defaultConfigurationIsVisible = 0; 379 | defaultConfigurationName = Release; 380 | }; 381 | E9735DC91AB15771001D3617 /* Build configuration list for PBXNativeTarget "QLImageset" */ = { 382 | isa = XCConfigurationList; 383 | buildConfigurations = ( 384 | E9735DCA1AB15771001D3617 /* Debug */, 385 | E9735DCB1AB15771001D3617 /* Release */, 386 | ); 387 | defaultConfigurationIsVisible = 0; 388 | defaultConfigurationName = Release; 389 | }; 390 | E992AABD1AB426BE00EB2E7B /* Build configuration list for PBXNativeTarget "dump" */ = { 391 | isa = XCConfigurationList; 392 | buildConfigurations = ( 393 | E992AABB1AB426BE00EB2E7B /* Debug */, 394 | E992AABC1AB426BE00EB2E7B /* Release */, 395 | ); 396 | defaultConfigurationIsVisible = 0; 397 | defaultConfigurationName = Release; 398 | }; 399 | /* End XCConfigurationList section */ 400 | }; 401 | rootObject = E9735DB31AB15771001D3617 /* Project object */; 402 | } 403 | -------------------------------------------------------------------------------- /QLImageset.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /QLImageset/GeneratePreviewForURL.m: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 QFish 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifdef __OBJC__ 26 | #include 27 | #include 28 | #endif 29 | 30 | #include 31 | #include 32 | #include 33 | #import "QLImageset.h" 34 | 35 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); 36 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); 37 | 38 | /* ----------------------------------------------------------------------------- 39 | Generate a preview for file 40 | 41 | This function's job is to create preview for designated file 42 | ----------------------------------------------------------------------------- */ 43 | 44 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) 45 | { 46 | NSString * dir = ((__bridge NSURL *)(url)).path; 47 | NSString * file = QLImagesetGetFileForPath(dir); 48 | NSString * name = [[dir lastPathComponent] stringByDeletingPathExtension]; 49 | NSImage * image = [[NSImage alloc] initWithContentsOfFile:file]; 50 | 51 | NSString * displayName = [NSString stringWithFormat:@"%.1f x %.1f - %@", 52 | image.size.width, 53 | image.size.height, 54 | name]; 55 | 56 | CFDictionaryRef props = (__bridge CFDictionaryRef) 57 | @{(__bridge NSString*)kQLPreviewPropertyDisplayNameKey: displayName }; 58 | 59 | QLPreviewRequestSetURLRepresentation(preview, (__bridge CFURLRef)[NSURL fileURLWithPath:file], kUTTypePNG, props); 60 | 61 | return noErr; 62 | } 63 | 64 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview) 65 | { 66 | // Implement only if supported 67 | } 68 | -------------------------------------------------------------------------------- /QLImageset/GenerateThumbnailForURL.m: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 QFish 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifdef __OBJC__ 26 | #include 27 | #include 28 | #endif 29 | 30 | #include 31 | #include 32 | #include 33 | #import "QLImageset.h" 34 | 35 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); 36 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail); 37 | 38 | /* ----------------------------------------------------------------------------- 39 | Generate a thumbnail for file 40 | 41 | This function's job is to create thumbnail for designated file as fast as possible 42 | ----------------------------------------------------------------------------- */ 43 | 44 | #if QLIMAGESET_USE_DEFAULT 45 | 46 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize) 47 | { 48 | NSString * dir = ((__bridge NSURL *)(url)).path; 49 | NSString * file = QLImagesetGetFileForPath(dir); 50 | 51 | CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:file], NULL); 52 | CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, NULL); 53 | CFRelease(source); 54 | 55 | QLThumbnailRequestSetImage(thumbnail, image, NULL); 56 | CFRelease(image); 57 | 58 | return noErr; 59 | } 60 | 61 | #else // #if QLIMAGESET_USE_DEFAULT 62 | 63 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize) 64 | { 65 | NSSize thumbSize = NSMakeSize((maxSize.width * (600.0/800.0)), maxSize.height); 66 | 67 | NSString * dir = ((__bridge NSURL *)(url)).path; 68 | NSString * file = QLImagesetGetFileForPath(dir); 69 | 70 | CGContextRef context = 71 | QLThumbnailRequestCreateContext(thumbnail, thumbSize, false, NULL); 72 | 73 | if (context) { 74 | QLImagesetDrawImageInContentWithURL(context, (__bridge CFURLRef)[NSURL fileURLWithPath:file], thumbSize); 75 | QLThumbnailRequestFlushContext(thumbnail, context); 76 | CFRelease(context); 77 | } 78 | 79 | return noErr; 80 | } 81 | 82 | #endif // #if QLIMAGESET_USE_DEFAULT 83 | 84 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail) 85 | { 86 | // Implement only if supported 87 | } 88 | -------------------------------------------------------------------------------- /QLImageset/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDocumentTypes 8 | 9 | 10 | CFBundleTypeRole 11 | QLGenerator 12 | LSItemContentTypes 13 | 14 | qfi.sh.imageset 15 | 16 | 17 | 18 | CFBundleExecutable 19 | $(EXECUTABLE_NAME) 20 | CFBundleIdentifier 21 | qfi.sh.$(PRODUCT_NAME:rfc1034identifier) 22 | CFBundleInfoDictionaryVersion 23 | 6.0 24 | CFBundleName 25 | $(PRODUCT_NAME) 26 | CFBundleShortVersionString 27 | 1.0 28 | CFBundleSignature 29 | ???? 30 | CFBundleVersion 31 | 1 32 | CFPlugInDynamicRegisterFunction 33 | 34 | CFPlugInDynamicRegistration 35 | NO 36 | CFPlugInFactories 37 | 38 | 62713591-4A2F-4FA9-B15C-C4F605BC6B8D 39 | QuickLookGeneratorPluginFactory 40 | 41 | CFPlugInTypes 42 | 43 | 5E2D9680-5022-40FA-B806-43349622E5B9 44 | 45 | 62713591-4A2F-4FA9-B15C-C4F605BC6B8D 46 | 47 | 48 | CFPlugInUnloadFunction 49 | 50 | NSHumanReadableCopyright 51 | Copyright © 2015 QFish. All rights reserved. 52 | QLNeedsToBeRunInMainThread 53 | 54 | QLPreviewHeight 55 | 600 56 | QLPreviewWidth 57 | 800 58 | QLSupportsConcurrentRequests 59 | 60 | QLThumbnailMinimumSize 61 | 17 62 | UTImportedTypeDeclarations 63 | 64 | 65 | UTTypeConformsTo 66 | 67 | public.directory 68 | public.package 69 | 70 | UTTypeDescription 71 | Imageset Package 72 | UTTypeIconFile 73 | public.image 74 | UTTypeIdentifier 75 | qfi.sh.imageset 76 | UTTypeTagSpecification 77 | 78 | public.filename-extension 79 | 80 | imageset 81 | launchimage 82 | appiconset 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /QLImageset/QLImageset.h: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 QFish 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #import 26 | 27 | /** 28 | * You can see logs in the ·Console.app· with prefix ·【QLImageset 1.0】:· 29 | */ 30 | #define QLImagesetVer @"1.0" 31 | #define QLImagesetLog(...) NSLog(@"【QLImageset "QLImagesetVer"】:"__VA_ARGS__) 32 | 33 | #undef QLIMAGESET_USE_DEFAULT 34 | #define QLIMAGESET_USE_DEFAULT 1 35 | 36 | /*! 37 | * @function QLImagesetGetFileForPath 38 | * @abstract Get the appropriate size image under the target dir, the default 39 | order is .png > @2x.png > @3x.png > jpg. 40 | * @param path The path of thae target directory. 41 | * @discussion Currently used any png file to be the target file. 42 | */ 43 | NSString * QLImagesetGetFileForPath(NSString * path); 44 | #if !QLIMAGESET_USE_DEFAULT 45 | void QLImagesetDrawImageInContentWithURL(CGContextRef context, CFURLRef url, CGSize size) 46 | ; 47 | #endif // #if QLIMAGESET_USE_DEFAULT -------------------------------------------------------------------------------- /QLImageset/QLImageset.m: -------------------------------------------------------------------------------- 1 | /** 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2015 QFish 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #import "QLImageset.h" 26 | 27 | NSString * QLImagesetGetFileForPath(NSString * path) 28 | { 29 | BOOL isDirectory = NO; 30 | BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]; 31 | if ( !exists ) 32 | return nil; 33 | 34 | NSError * error; 35 | NSArray * contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error]; 36 | 37 | if ( error ) { 38 | QLImagesetLog(@"%@", error); 39 | return nil; 40 | } 41 | 42 | if ( !contents.count ) { 43 | QLImagesetLog(@"no contents in %@", path); 44 | return nil; 45 | } 46 | 47 | static NSArray * filters = nil; 48 | 49 | if ( !filters ) { 50 | filters = @[@"png", @"@2x.png", @"@3x.png", @"jpg"]; 51 | } 52 | 53 | NSString * content = nil; 54 | 55 | for ( int i = 0; i < filters.count; i++ ) { 56 | NSArray * matches = [contents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF ENDSWITH %@", filters[i]]]; 57 | if ( matches.count ) { 58 | content = matches.firstObject; 59 | break; 60 | } 61 | } 62 | 63 | if ( content ) 64 | return [path stringByAppendingPathComponent:content]; 65 | return nil; 66 | 67 | } 68 | 69 | #if !QLIMAGESET_USE_DEFAULT 70 | 71 | void QLImagesetDrawImageInContentWithURL(CGContextRef context, CFURLRef url, CGSize canvasSize) 72 | { 73 | CGImageSourceRef source = CGImageSourceCreateWithURL(url, NULL); 74 | CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, NULL); 75 | CFRelease(source); 76 | 77 | CGFloat width = CGImageGetWidth(image); 78 | CGFloat height = CGImageGetWidth(image); 79 | QLImagesetLog(@"%f %f, %f %f", canvasSize.width, canvasSize.height, width, height); 80 | CGContextDrawImage(context, CGRectMake(0, 0, width, height), image); 81 | CGContextFlush(context); 82 | CGImageRelease(image); 83 | } 84 | 85 | #endif // #if QLIMAGESET_USE_DEFAULT 86 | -------------------------------------------------------------------------------- /QLImageset/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 "62713591-4A2F-4FA9-B15C-C4F605BC6B8D" 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QLImageset 2 | 3 | QLImageset is a quicklook plugin that lets you preview package or directory with extension likes **`imageset`**, **`appiconset`** and **`launchimage`**. 4 | 5 | It also displays **the dimensions** using point coordinates of the image in the quicklook title bar. 6 | 7 | ## Installation 8 | 9 | 1. Download this package [QLImageset.qlgenerator.zip](http://const.qiniudn.com/repo/qlimageset/QLImageset.qlgenerator.zip) 10 | 11 | 2. Unpack it, copy or move the `QLImageset.qlgenerator` to the following path: 12 | 13 | ``` 14 | /Library/QuickLook 15 | ``` 16 | 17 | Tips: To quickly go to Finder, type `Shift + Cmd + G`. 18 | 19 | ## Usage 20 | 21 | **Selecte** the package or directory, then **Press** the **`SPACE`** key. 22 | 23 | ![preview](http://const.qiniudn.com/repo/qlimageset/preview.gif) 24 | 25 | ## TODO 26 | - [x] Support generating thumbnails. 27 | 28 | ## Uninstallation 29 | 30 | Find and delete the following path: 31 | 32 | ``` 33 | /Library/QuickLook/QLImageset.qlgenerator 34 | ``` 35 | 36 | ## Want to help 37 | * [How to write a QuickLook plugin](https://github.com/qfish/QLImageset/wiki/How-to-write-a-Quicklook-plugin) 38 | * [Star this repository](https://github.com/qfish/QLImageset/) 39 | * [Bugs Report & Advice](https://github.com/qfish/QLImageset/issues) 40 | * [Fork & Pull Request](https://github.com/qfish/QLImageset/pulls) 41 | 42 | ## Contributor 43 | * [@qiaoxueshi](https://github.com/qiaoxueshi) Reviews the code. 44 | 45 | ## Trouble-Shooting 46 | 47 | * Run `qlmanage -r` in the Terminal. (This will restart QuickLook, which reloads all plugins.) 48 | * Type `Alt + Cmd + Esc`, relaunch the Finder. (This will restart Finder.) 49 | 50 | ## Special thanks to 51 | 52 | * [![Geek-Zoo](http://geek-zoo.com/img/images/logo_2.png)](http://www.geek-zoo.com) 53 | 54 | They provide awesome design and development works continues to help the open-source community even better. 55 | 56 | 57 | * [BeeFramework](https://github.com/gavinkwoe/BeeFramework) 58 | 59 | BeeFramework is a new generation of development framework which makes faster and easier app development, Build your app by geek's way. 60 | -------------------------------------------------------------------------------- /dump/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // dump 4 | // 5 | // Created by QFish on 3/14/15. 6 | // Copyright (c) 2015 QFish. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "QLImageset.h" 11 | 12 | // Dump for debug 13 | 14 | int main(int argc, const char * argv[]) { 15 | @autoreleasepool { 16 | 17 | if (argc != 2) { 18 | printf("Usage: dump .\n"); 19 | exit(EXIT_FAILURE); 20 | } 21 | 22 | const char* filename = argv[1]; 23 | 24 | // const char* filename = "~/Desktop/QFish.imageset"; 25 | 26 | NSLog( @"%@", QLImagesetGetFileForPath([NSString stringWithUTF8String:filename]) ); 27 | } 28 | return 0; 29 | } 30 | --------------------------------------------------------------------------------