diff --git a/English.lproj/InfoPlist.strings b/English.lproj/InfoPlist.strings new file mode 100644 index 0000000..ede88f9 Binary files /dev/null and b/English.lproj/InfoPlist.strings differ diff --git a/Info.plist b/Info.plist new file mode 100644 index 0000000..c1922af --- /dev/null +++ b/Info.plist @@ -0,0 +1,59 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDocumentTypes + + + CFBundleTypeRole + QLGenerator + LSItemContentTypes + + dyn.ah62d4rv4ge80c65f + + + + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleName + ${PRODUCT_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.studioavante.quicklookase + CFBundleInfoDictionaryVersion + 6.0 + CFBundleVersion + 1.0 + CFPlugInDynamicRegisterFunction + + CFPlugInDynamicRegistration + NO + CFPlugInFactories + + 660EBE04-BCB7-46E1-B107-88FBB16EE5AF + QuickLookGeneratorPluginFactory + + CFPlugInTypes + + 5E2D9680-5022-40FA-B806-43349622E5B9 + + 660EBE04-BCB7-46E1-B107-88FBB16EE5AF + + + CFPlugInUnloadFunction + + QLThumbnailMinimumSize + 17 + QLPreviewWidth + 600 + QLPreviewHeight + 800 + QLSupportsConcurrentRequests + + QLNeedsToBeRunInMainThread + + + diff --git a/QuickLookASE.xcodeproj/project.pbxproj b/QuickLookASE.xcodeproj/project.pbxproj new file mode 100644 index 0000000..2016041 --- /dev/null +++ b/QuickLookASE.xcodeproj/project.pbxproj @@ -0,0 +1,320 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 440BBDE80B0537AC0075B7E5 /* QuickLookASE.qlgenerator in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8D576316048677EA00EA77CD /* QuickLookASE.qlgenerator */; }; + 627414860B4EEC0B0069E3AD /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 627414850B4EEC0B0069E3AD /* ApplicationServices.framework */; }; + 6274148C0B4EED590069E3AD /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6274148B0B4EED590069E3AD /* CoreServices.framework */; }; + 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; }; + DBAD62E41D3C63B9005EA523 /* DataReader.h in Headers */ = {isa = PBXBuildFile; fileRef = DBAD62DD1D3C63B9005EA523 /* DataReader.h */; }; + DBAD62E51D3C63B9005EA523 /* DataReader.m in Sources */ = {isa = PBXBuildFile; fileRef = DBAD62DE1D3C63B9005EA523 /* DataReader.m */; }; + DBAD62E61D3C63B9005EA523 /* GeneratePreviewForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = DBAD62DF1D3C63B9005EA523 /* GeneratePreviewForURL.m */; }; + DBAD62E71D3C63B9005EA523 /* GenerateThumbnailForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = DBAD62E01D3C63B9005EA523 /* GenerateThumbnailForURL.m */; }; + DBAD62E81D3C63B9005EA523 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = DBAD62E11D3C63B9005EA523 /* main.c */; }; + DBAD62E91D3C63B9005EA523 /* SwatchDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = DBAD62E21D3C63B9005EA523 /* SwatchDocument.h */; }; + DBAD62EA1D3C63B9005EA523 /* SwatchDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = DBAD62E31D3C63B9005EA523 /* SwatchDocument.m */; }; + F23287A00A761867004F5233 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F232879F0A761867004F5233 /* Cocoa.framework */; }; + F28CFC030A3EC0C6000ABFF5 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F28CFC020A3EC0C6000ABFF5 /* QuickLook.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 440BBDFA0B0537B10075B7E5 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "~/Library/QuickLook"; + dstSubfolderSpec = 0; + files = ( + 440BBDE80B0537AC0075B7E5 /* QuickLookASE.qlgenerator in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 622150340BBDD60C00126F4B /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 627414850B4EEC0B0069E3AD /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = ""; }; + 6274148B0B4EED590069E3AD /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; + 8D576316048677EA00EA77CD /* QuickLookASE.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QuickLookASE.qlgenerator; sourceTree = BUILT_PRODUCTS_DIR; }; + DB57D0DB1D0DB18600490A66 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + DBAD62DD1D3C63B9005EA523 /* DataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DataReader.h; path = src/DataReader.h; sourceTree = ""; }; + DBAD62DE1D3C63B9005EA523 /* DataReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DataReader.m; path = src/DataReader.m; sourceTree = ""; }; + DBAD62DF1D3C63B9005EA523 /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GeneratePreviewForURL.m; path = src/GeneratePreviewForURL.m; sourceTree = ""; }; + DBAD62E01D3C63B9005EA523 /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GenerateThumbnailForURL.m; path = src/GenerateThumbnailForURL.m; sourceTree = ""; }; + DBAD62E11D3C63B9005EA523 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = main.c; path = src/main.c; sourceTree = ""; }; + DBAD62E21D3C63B9005EA523 /* SwatchDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SwatchDocument.h; path = src/SwatchDocument.h; sourceTree = ""; }; + DBAD62E31D3C63B9005EA523 /* SwatchDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SwatchDocument.m; path = src/SwatchDocument.m; sourceTree = ""; }; + F232879F0A761867004F5233 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + F28CFC020A3EC0C6000ABFF5 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = /System/Library/Frameworks/QuickLook.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D576313048677EA00EA77CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F28CFC030A3EC0C6000ABFF5 /* QuickLook.framework in Frameworks */, + F23287A00A761867004F5233 /* Cocoa.framework in Frameworks */, + 627414860B4EEC0B0069E3AD /* ApplicationServices.framework in Frameworks */, + 6274148C0B4EED590069E3AD /* CoreServices.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* QuickLookSketch */ = { + isa = PBXGroup; + children = ( + 08FB77AFFE84173DC02AAC07 /* Quick Look Generator */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, + 19C28FB6FE9D52B211CA2CBB /* Products */, + ); + name = QuickLookSketch; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 6274148B0B4EED590069E3AD /* CoreServices.framework */, + F232879F0A761867004F5233 /* Cocoa.framework */, + F28CFC020A3EC0C6000ABFF5 /* QuickLook.framework */, + 627414850B4EEC0B0069E3AD /* ApplicationServices.framework */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + DB57D0DB1D0DB18600490A66 /* README.md */, + 622150340BBDD60C00126F4B /* Info.plist */, + 8D5B49A704867FD3000E48DA /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77AFFE84173DC02AAC07 /* Quick Look Generator */ = { + isa = PBXGroup; + children = ( + DBAD62E11D3C63B9005EA523 /* main.c */, + DBAD62DF1D3C63B9005EA523 /* GeneratePreviewForURL.m */, + DBAD62E01D3C63B9005EA523 /* GenerateThumbnailForURL.m */, + DBAD62E21D3C63B9005EA523 /* SwatchDocument.h */, + DBAD62E31D3C63B9005EA523 /* SwatchDocument.m */, + DBAD62DD1D3C63B9005EA523 /* DataReader.h */, + DBAD62DE1D3C63B9005EA523 /* DataReader.m */, + ); + name = "Quick Look Generator"; + sourceTree = ""; + }; + 19C28FB6FE9D52B211CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D576316048677EA00EA77CD /* QuickLookASE.qlgenerator */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D57630E048677EA00EA77CD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DBAD62E41D3C63B9005EA523 /* DataReader.h in Headers */, + DBAD62E91D3C63B9005EA523 /* SwatchDocument.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 8D57630D048677EA00EA77CD /* QuickLookASE */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2CA3261E0896AD4900168862 /* Build configuration list for PBXNativeTarget "QuickLookASE" */; + buildPhases = ( + 8D57630E048677EA00EA77CD /* Headers */, + 8D57630F048677EA00EA77CD /* Resources */, + 8D576311048677EA00EA77CD /* Sources */, + 8D576313048677EA00EA77CD /* Frameworks */, + 8D576315048677EA00EA77CD /* Rez */, + 440BBDFA0B0537B10075B7E5 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = QuickLookASE; + productInstallPath = /Library/Spotlight; + productName = QuickLookSketch; + productReference = 8D576316048677EA00EA77CD /* QuickLookASE.qlgenerator */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + attributes = { + }; + buildConfigurationList = 2CA326220896AD4900168862 /* Build configuration list for PBXProject "QuickLookASE" */; + compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + en, + ); + mainGroup = 089C166AFE841209C02AAC07 /* QuickLookSketch */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D57630D048677EA00EA77CD /* QuickLookASE */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D57630F048677EA00EA77CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 8D576315048677EA00EA77CD /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D576311048677EA00EA77CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DBAD62E51D3C63B9005EA523 /* DataReader.m in Sources */, + DBAD62E81D3C63B9005EA523 /* main.c in Sources */, + DBAD62E71D3C63B9005EA523 /* GenerateThumbnailForURL.m in Sources */, + DBAD62EA1D3C63B9005EA523 /* SwatchDocument.m in Sources */, + DBAD62E61D3C63B9005EA523 /* GeneratePreviewForURL.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 8D5B49A704867FD3000E48DA /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C167EFE841241C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 2CA3261F0896AD4900168862 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Library/QuickLook; + LIBRARY_STYLE = Bundle; + PRODUCT_NAME = QuickLookASE; + WRAPPER_EXTENSION = qlgenerator; + ZERO_LINK = YES; + }; + name = Debug; + }; + 2CA326200896AD4900168862 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SYSTEM_LIBRARY_DIR)/Frameworks\""; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = NO; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = /Library/QuickLook; + LIBRARY_STYLE = Bundle; + PRODUCT_NAME = QuickLookASE; + WRAPPER_EXTENSION = qlgenerator; + }; + name = Release; + }; + 2CA326230896AD4900168862 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + PREBINDING = NO; + }; + name = Debug; + }; + 2CA326240896AD4900168862 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + PREBINDING = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2CA3261E0896AD4900168862 /* Build configuration list for PBXNativeTarget "QuickLookASE" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2CA3261F0896AD4900168862 /* Debug */, + 2CA326200896AD4900168862 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2CA326220896AD4900168862 /* Build configuration list for PBXProject "QuickLookASE" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2CA326230896AD4900168862 /* Debug */, + 2CA326240896AD4900168862 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/QuickLookASE.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/QuickLookASE.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..fbfadc0 --- /dev/null +++ b/QuickLookASE.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/README.md b/README.md index 8708dc9..3335848 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ # QuickLookASE Mac quicklook for ASE files (Adobe Swatch Exchange) + + +How to find Adobe ASE UTI: +mdls -name kMDItemContentType MySwatch.ase + diff --git a/src/DataReader.h b/src/DataReader.h new file mode 100644 index 0000000..0c1321d --- /dev/null +++ b/src/DataReader.h @@ -0,0 +1,75 @@ +/* + + File: SKTDrawDocument.h + + Abstract: Part of the Sketch Sample Code + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Computer, Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Computer, + Inc. may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2007 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface DataReader : NSObject { + @private + + NSData * _fileData; + unsigned char * _buffer; + int _length; + int _position; + +} + +- (int)remaining; +- (int)length; + +- (BOOL)readFromURL:(NSURL *)url; +//- (unsigned char *)GetChunk:(int)size; +- (unsigned char *)GetBytes:(int)size; +- (NSString*)GetString:(int)size; +- (int)GetInt; +- (int)GetIntOfSize:(int)size; +- (float)GetFloat; +- (float)GetFloatOfSize:(int)size; + +@end diff --git a/src/DataReader.m b/src/DataReader.m new file mode 100644 index 0000000..96057b4 --- /dev/null +++ b/src/DataReader.m @@ -0,0 +1,179 @@ +/* + + File: SwatchDocument.m + + Abstract: Part of the Sketch Sample Code + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Computer, Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Computer, + Inc. may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2007 Apple Inc. All Rights Reserved. + + */ + + +#import +#import "DataReader.h" + +@implementation DataReader + +- (BOOL)readFromURL:(NSURL *)url { + + _fileData = [[NSData alloc] initWithContentsOfURL:(NSURL*)url]; + if (_fileData == NULL) + return false; + + _buffer = (unsigned char*)[_fileData bytes]; + _length = [_fileData length]; + _position = 0; + + return true; +} + +- (int)length { + return _length; +} + +- (int)remaining { + return (_length - _position); +} + +- (unsigned char *)GetChunk:(int)size +{ + if (size <= 0 || size > [self remaining]) + return NULL; + unsigned char * chunk = &(_buffer[_position]); + _position += size; + return chunk; +} +- (unsigned char *)GetBytes:(int)size +{ + unsigned char * chunk = [self GetChunk:size]; + if (chunk == NULL) + { + NSLog(@"SwatchPalette.Reader.GetBytes(): Invalid chunk size [%d] remaining [%d]",size,[self remaining]); + return NULL; + } + return chunk; +} +- (NSString*)GetString:(int)size +{ + unsigned char * chunk = [self GetChunk:size]; + if (chunk == NULL) + { + NSLog(@"SwatchPalette.Reader.GetString(): Invalid chunk size [%d] remaining [%d]",size,[self remaining]); + return NULL; + } + NSString *s = [[NSString alloc] initWithBytes:chunk + length:size + encoding:NSUTF8StringEncoding]; + return s; +} +- (int)GetInt +{ + return [self GetIntOfSize:4]; +} +- (int)GetIntOfSize:(int)size +{ + if (size > 4) + { + NSLog(@"SwatchPalette.Reader.GetInt(): Invalid int size [%d], expecting <= 4",size); + return -1; + } + unsigned char * chunk = [self GetChunk:size]; + if (chunk == NULL) + { + NSLog(@"SwatchPalette.Reader.GetInt(): Invalid chunk size [%d] remaining [%d]",size,[self remaining]); + return -1; + } + unsigned int res; + NSString *hex = [self ChunkToHex:chunk size:size]; + NSScanner* scanner = [NSScanner scannerWithString:hex]; + [scanner scanHexInt:&res]; + return (int)res; +} +- (float)GetFloat +{ + return [self GetFloatOfSize:4]; +} +- (float)GetFloatOfSize:(int)size +{ + if (size > 4) + { + NSLog(@"SwatchPalette.Reader.GetFloat(): Invalid int size [%d], expecting <= 4",size); + return -1; + } + unsigned char * chunk = [self GetChunk:size]; + if (chunk == NULL) + { + NSLog(@"SwatchPalette.Reader.GetFloat(): Invalid chunk size [%d] remaining [%d]",size,[self remaining]); + return -1; + } + union { + float f; + unsigned int i; + } res; + NSString *hex = [self ChunkToHex:chunk size:size]; + NSScanner* scanner = [NSScanner scannerWithString:hex]; + [scanner scanHexInt:&res.i]; + return res.f; +} + +- (NSString*) ChunkToHex:(unsigned char *)chunk size:(int)size +{ + NSMutableString * result = [[NSMutableString alloc] init]; + for (int i=0; i +#include +#include +#import +#import "SwatchDocument.h" + + +/* ----------------------------------------------------------------------------- + Generate a preview for file + + This function's job is to create preview for designated file + ----------------------------------------------------------------------------- */ + +OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + SwatchDocument* document = [[SwatchDocument alloc] init]; + + if(![document readFromURL:(NSURL *)url]) { + [document release]; + [pool release]; + return noErr; + } + + NSSize canvasSize = [document canvasSize]; + + // Preview will be drawn in a vectorized context + // Here we create a graphics context to draw the Quick Look Preview in + CGContextRef cgContext = QLPreviewRequestCreateContext(preview, *(CGSize *)&canvasSize, false, NULL); + if(cgContext) { + NSGraphicsContext* context = [NSGraphicsContext graphicsContextWithGraphicsPort:(void *)cgContext flipped:YES]; + if(context) { + //These two lines of code are just good safe programming... + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:context]; + + [document drawDocumentInContext:context]; + + //This line sets the context back to what it was when we're done + [NSGraphicsContext restoreGraphicsState]; + } + + // When we are done with our drawing code QLPreviewRequestFlushContext() is called to flush the context + QLPreviewRequestFlushContext(preview, cgContext); + + CFRelease(cgContext); + } + + [pool release]; + return noErr; +} + +void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview) +{ + // implement only if supported +} + diff --git a/src/GenerateThumbnailForURL.m b/src/GenerateThumbnailForURL.m new file mode 100644 index 0000000..29c0a6f --- /dev/null +++ b/src/GenerateThumbnailForURL.m @@ -0,0 +1,103 @@ +/* + + File: GenerateThumbnailForURL.m + + Abstract: This is the code to generate Quick Look thumbnails for Sketch documents + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by + Apple Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. + may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2009 Apple Inc. All Rights Reserved. + */ + +#include +#include +#include +#import +#import "SwatchDocument.h" + +OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + SwatchDocument* document = [[SwatchDocument alloc] init]; + + if(![document readFromURL:(NSURL *)url]) { + [document release]; + [pool release]; + return noErr; + } + + NSSize canvasSize = [document canvasSize]; + + // Thumbnail will be drawn with maximum resolution for desired thumbnail request + // Here we create a graphics context to draw the Quick Look Thumbnail in. + CGContextRef cgContext = QLThumbnailRequestCreateContext(thumbnail, *(CGSize *)&canvasSize, false, NULL); + if(cgContext) { + NSGraphicsContext* context = [NSGraphicsContext graphicsContextWithGraphicsPort:(void *)cgContext flipped:YES]; + if(context) { + //These two lines of code are just good safe programming... + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:context]; + + //Normally you'd want to do something much more lightweight for a thumbnail, + //like load an pre-generated image embedded in the document or something + //but for a quick and dirty sample, we'll just render the document here + [document drawDocumentInContext:context]; + + //This line sets the context back to what it was when we're done + [NSGraphicsContext restoreGraphicsState]; + } + + // When we are done with our drawing code QLThumbnailRequestFlushContext() is called to flush the context + QLThumbnailRequestFlushContext(thumbnail, cgContext); + + CFRelease(cgContext); + } + + [pool release]; + return noErr; +} + +void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail) +{ + // implement only if supported +} + diff --git a/src/SwatchDocument.h b/src/SwatchDocument.h new file mode 100644 index 0000000..f13b997 --- /dev/null +++ b/src/SwatchDocument.h @@ -0,0 +1,68 @@ +/* + + File: SKTDrawDocument.h + + Abstract: Part of the Sketch Sample Code + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Computer, Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Computer, + Inc. may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2007 Apple Inc. All Rights Reserved. + + */ + +#import + +@interface SwatchDocument : NSObject { + @private + + NSMutableArray *colors; + +} + +// Return the current value of the property. +- (NSSize)canvasSize; + +// Added for Quick Look generator +- (void)drawDocumentInContext:(NSGraphicsContext *)context; +- (BOOL)readFromURL:(NSURL *)url; + + +@end diff --git a/src/SwatchDocument.m b/src/SwatchDocument.m new file mode 100644 index 0000000..be08324 --- /dev/null +++ b/src/SwatchDocument.m @@ -0,0 +1,278 @@ +/* + + File: SwatchDocument.m + + Abstract: Part of the Sketch Sample Code + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple + Computer, Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Computer, + Inc. may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2007 Apple Inc. All Rights Reserved. + + */ + + +#import +#import "SwatchDocument.h" +#import "DataReader.h" + +#define HEIGHT 600 +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +const int BLOCK_GROUP_START = 0xc001; +const int BLOCK_GROUP_END = 0xc002; +const int BLOCK_COLOR = 0x0001; + +enum ColorMode +{ + ColorModeUndefined = -1, + ColorModeCMYK, + ColorModeRGB, + ColorModeLAB, + ColorModeGray +}; + +enum ColorType +{ + ColorTypeUndefined = -1, + ColorTypeGlobal, + ColorTypeSpot, + ColorTypeNormal +}; + +struct SwatchColor +{ + NSString * name; + NSString * group; + enum ColorMode mode; + enum ColorType type; + NSColor * color; + float rawValues[4]; + int rawValuesCount; +}; + +@implementation SwatchDocument + +- (BOOL)readFromURL:(NSURL *)url { +// [self redirectConsoleLogToDocumentFolder]; + + // Create colors array + colors = [[NSMutableArray alloc]init]; + + // Open data reader + DataReader* reader = [[DataReader alloc] init]; + [reader readFromURL:url]; + NSLog(@"SwatchPalette: File size [%d]",[reader length]); + if ([reader length] < 12) + { + NSLog(@"SwatchPalette: Invalid asset size [%d]",[reader length]); + return false; + } + + // Get Header + NSString * signature = [reader GetString:4]; + int v1 = [reader GetIntOfSize:2]; + int v2 = [reader GetIntOfSize:2]; + NSLog(@"SwatchPalette: signature [%@] version [%d.%d]",signature,v1,v2); + if (![signature isEqualToString:@"ASEF"]) + { + NSLog(@"SwatchPalette: Wrong signature [%@]. Must be [ASEF].",signature); + return false; + } + + // Get blocks + NSString * groupName = @""; + int blockCount = [reader GetInt]; + NSLog(@"SwatchPalette: Block count [%d]",blockCount); + for (int b = 0 ; b < blockCount ; b++) + { + int type = [reader GetIntOfSize:2]; + int blockSize = [reader GetInt]; + NSLog(@"SwatchPalette: Block [%d] type [%d] size [%d]",b,type,blockSize); + + struct SwatchColor color; + + // Color + if (type == BLOCK_GROUP_START || type == BLOCK_COLOR) + { + // Group/Colro name + int nameSize = [reader GetIntOfSize:2]; + NSLog(@"SwatchPalette: nameSize [%d]",nameSize); + if (nameSize > 0) + { + // 0-terminated string of length (uint16) double-byte characters + unsigned char * bs = [reader GetBytes:nameSize*2]; + color.name = @""; + for (int i = 0 ; i < nameSize-1 ; i++) + { + NSString *ch = [NSString stringWithFormat:@"%c", bs[(i*2)+1]]; + color.name = [color.name stringByAppendingString:ch]; + } + NSLog(@"SwatchPalette: Name (%d) [%@]",nameSize,color.name); + } + + if (type == BLOCK_GROUP_START) + { + groupName = color.name; + NSLog(@"SwatchPalette: Group Start [%@]",groupName); + } + else //if (type == BLOCK_COLOR) + { + color.group = groupName; + + NSString * colorMode = [reader GetString:4]; + NSLog(@"SwatchPalette: Color mode [%@]",colorMode); + if ([colorMode isEqualToString:@"CMYK"]) + { + color.mode = ColorModeCMYK; + color.rawValuesCount = 4; + float C = color.rawValues[0] = [reader GetFloat]; + float M = color.rawValues[1] = [reader GetFloat]; + float Y = color.rawValues[2] = [reader GetFloat]; + float K = color.rawValues[3] = [reader GetFloat]; + float R = (1-C) * (1-K); + float G = (1-M) * (1-K); + float B = (1-Y) * (1-K); + color.color = [NSColor colorWithRed:R green:G blue:B alpha:1]; + [colors addObject:color.color]; +// palette.Add(color); + } + else if ([colorMode isEqualToString:@"RGB "]) + { + color.mode = ColorModeRGB; + color.rawValuesCount = 3; + float R = color.rawValues[0] = [reader GetFloat]; + float G = color.rawValues[1] = [reader GetFloat]; + float B = color.rawValues[2] = [reader GetFloat]; + color.color = [NSColor colorWithRed:R green:G blue:B alpha:1]; + [colors addObject:color.color]; +// palette.Add(color); + } + + else if ([colorMode isEqualToString:@"LAB "]) + { + color.mode = ColorModeLAB; + color.rawValuesCount = 3; + float L = color.rawValues[0] = [reader GetFloat]; + float A = color.rawValues[1] = [reader GetFloat]; + float B = color.rawValues[2] = [reader GetFloat]; +// color.color = [NSColor colorWithRed:R green:G blue:B alpha:1]; +// [colors addObject:color.color]; +// palette.Add(color); + // No idea what LAB is !!! + NSLog(@"SwatchPalette: LAB color not supportted (%.3f,%.3f,%.3f)",L,A,B); + } + else if ([colorMode isEqualToString:@"Gray"]) + { + color.mode = ColorModeGray; + color.rawValuesCount = 1; + float G = color.rawValues[0] = [reader GetFloat]; + color.color = [NSColor colorWithWhite:G alpha:1]; + [colors addObject:color.color]; +// palette.Add(color); + } + + // Color type + color.type = [reader GetIntOfSize:2]; + } + } + else if (type == BLOCK_GROUP_END) + { + NSLog(@"SwatchPalette: Group End"); + } + else + { + NSLog(@"SwatchPalette: Invalid type [%d]",type); + } + } + + return ([colors count] > 0); +} + +- (void) dealloc +{ + if (colors) + [colors dealloc]; + [super dealloc]; +} + + +- (NSSize)canvasSize { + NSSize size = { CLAMP(colors.count, 2, 4)*(HEIGHT/2), HEIGHT }; + return size; +} + + +// Added for Quick Look generator +- (void)drawDocumentInContext:(NSGraphicsContext *)context +{ + // Init + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:context]; + [context saveGraphicsState]; + + // Draw! + { + NSSize size = [self canvasSize]; + + int w = size.width / colors.count; + for (int i = 0 ; i < colors.count ; ++i) + { + [colors[i] setFill]; + NSRect aRect = NSMakeRect(w*i, 0.0, w, size.height); + NSRectFill(aRect); + } + } + + // Finalize + [context restoreGraphicsState]; + [NSGraphicsContext restoreGraphicsState]; +} + +- (void) redirectConsoleLogToDocumentFolder +{ + NSString *logPath = [NSHomeDirectory() stringByAppendingPathComponent:@"console.txt"]; + freopen([logPath fileSystemRepresentation],"a+",stderr); +} + + +@end + + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..74b0433 --- /dev/null +++ b/src/main.c @@ -0,0 +1,266 @@ +/* + + File: main.c + + Abstract: This is the CFPlug-in boilerplate code for a Quick Look preview generator + + Version: 1.0 + + Disclaimer: IMPORTANT: This Apple software is supplied to you by + Apple Inc. ("Apple") in consideration of your agreement to the + following terms, and your use, installation, modification or + redistribution of this Apple software constitutes acceptance of these + terms. If you do not agree with these terms, please do not use, + install, modify or redistribute this Apple software. + + In consideration of your agreement to abide by the following terms, and + subject to these terms, Apple grants you a personal, non-exclusive + license, under Apple's copyrights in this original Apple software (the + "Apple Software"), to use, reproduce, modify and redistribute the Apple + Software, with or without modifications, in source and/or binary forms; + provided that if you redistribute the Apple Software in its entirety and + without modifications, you must retain this notice and the following + text and disclaimers in all such redistributions of the Apple Software. + Neither the name, trademarks, service marks or logos of Apple Inc. + may be used to endorse or promote products derived from the Apple + Software without specific prior written permission from Apple. Except + as expressly stated in this notice, no other rights or licenses, express + or implied, are granted by Apple herein, including but not limited to + any patent rights that may be infringed by your derivative works or by + other works in which the Apple Software may be incorporated. + + The Apple Software is provided by Apple on an "AS IS" basis. APPLE + MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION + THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND + OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. + + IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, + MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED + AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), + STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + Copyright (C) 2007 Apple Inc. All Rights Reserved. + */ + +//============================================================================== +// +// DO NO MODIFY THE CONTENT OF THIS FILE +// +// This file contains the generic CFPlug-in code necessary for your generator +// To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c +// +//============================================================================== + + + + + + +#include +#include +#include +#include + +// ----------------------------------------------------------------------------- +// constants +// ----------------------------------------------------------------------------- + +// Don't modify this line +#define PLUGIN_ID "660EBE04-BCB7-46E1-B107-88FBB16EE5AF" + +// +// Below is the generic glue code for all plug-ins. +// +// You should not have to modify this code aside from changing +// names if you decide to change the names defined in the Info.plist +// + + +// ----------------------------------------------------------------------------- +// typedefs +// ----------------------------------------------------------------------------- + +// The thumbnail generation function to be implemented in GenerateThumbnailForURL.c +OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize); +void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail); + +// The preview generation function to be implemented in GeneratePreviewForURL.c +OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); +void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); + +// The layout for an instance of QuickLookGeneratorPlugIn +typedef struct __QuickLookGeneratorPluginType +{ + void *conduitInterface; + CFUUIDRef factoryID; + UInt32 refCount; +} QuickLookGeneratorPluginType; + +// ----------------------------------------------------------------------------- +// prototypes +// ----------------------------------------------------------------------------- +// Forward declaration for the IUnknown implementation. +// + +QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID); +void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance); +HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv); +void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID); +ULONG QuickLookGeneratorPluginAddRef(void *thisInstance); +ULONG QuickLookGeneratorPluginRelease(void *thisInstance); + +// ----------------------------------------------------------------------------- +// myInterfaceFtbl definition +// ----------------------------------------------------------------------------- +// The QLGeneratorInterfaceStruct function table. +// +static QLGeneratorInterfaceStruct myInterfaceFtbl = { + NULL, + QuickLookGeneratorQueryInterface, + QuickLookGeneratorPluginAddRef, + QuickLookGeneratorPluginRelease, + NULL, + NULL, + NULL, + NULL +}; + + +// ----------------------------------------------------------------------------- +// AllocQuickLookGeneratorPluginType +// ----------------------------------------------------------------------------- +// Utility function that allocates a new instance. +// You can do some initial setup for the generator here if you wish +// like allocating globals etc... +// +QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID) +{ + QuickLookGeneratorPluginType *theNewInstance; + + theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType)); + memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType)); + + /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */ + theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct)); + memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct)); + + /* Retain and keep an open instance refcount for each factory. */ + theNewInstance->factoryID = CFRetain(inFactoryID); + CFPlugInAddInstanceForFactory(inFactoryID); + + /* This function returns the IUnknown interface so set the refCount to one. */ + theNewInstance->refCount = 1; + return theNewInstance; +} + +// ----------------------------------------------------------------------------- +// DeallocQuickLookGeneratorPluginType +// ----------------------------------------------------------------------------- +// Utility function that deallocates the instance when +// the refCount goes to zero. +// In the current implementation generator interfaces are never deallocated +// but implement this as this might change in the future +// +void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance) +{ + CFUUIDRef theFactoryID; + + theFactoryID = thisInstance->factoryID; + /* Free the conduitInterface table up */ + free(thisInstance->conduitInterface); + + /* Free the instance structure */ + free(thisInstance); + if (theFactoryID){ + CFPlugInRemoveInstanceForFactory(theFactoryID); + CFRelease(theFactoryID); + } +} + +// ----------------------------------------------------------------------------- +// QuickLookGeneratorQueryInterface +// ----------------------------------------------------------------------------- +// Implementation of the IUnknown QueryInterface function. +// +HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv) +{ + CFUUIDRef interfaceID; + + interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid); + + if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){ + /* If the Right interface was requested, bump the ref count, + * set the ppv parameter equal to the instance, and + * return good status. + */ + ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL; + ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration; + ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL; + ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration; + ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance); + *ppv = thisInstance; + CFRelease(interfaceID); + return S_OK; + }else{ + /* Requested interface unknown, bail with error. */ + *ppv = NULL; + CFRelease(interfaceID); + return E_NOINTERFACE; + } +} + +// ----------------------------------------------------------------------------- +// QuickLookGeneratorPluginAddRef +// ----------------------------------------------------------------------------- +// Implementation of reference counting for this type. Whenever an interface +// is requested, bump the refCount for the instance. NOTE: returning the +// refcount is a convention but is not required so don't rely on it. +// +ULONG QuickLookGeneratorPluginAddRef(void *thisInstance) +{ + ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1; + return ((QuickLookGeneratorPluginType*) thisInstance)->refCount; +} + +// ----------------------------------------------------------------------------- +// QuickLookGeneratorPluginRelease +// ----------------------------------------------------------------------------- +// When an interface is released, decrement the refCount. +// If the refCount goes to zero, deallocate the instance. +// +ULONG QuickLookGeneratorPluginRelease(void *thisInstance) +{ + ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1; + if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){ + DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance ); + return 0; + }else{ + return ((QuickLookGeneratorPluginType*) thisInstance )->refCount; + } +} + +// ----------------------------------------------------------------------------- +// QuickLookGeneratorPluginFactory +// ----------------------------------------------------------------------------- +void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID) +{ + QuickLookGeneratorPluginType *result; + CFUUIDRef uuid; + + /* If correct type is being requested, allocate an + * instance of kQLGeneratorTypeID and return the IUnknown interface. + */ + if (CFEqual(typeID,kQLGeneratorTypeID)){ + uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID)); + result = AllocQuickLookGeneratorPluginType(uuid); + CFRelease(uuid); + return result; + } + /* If the requested type is incorrect, return NULL. */ + return NULL; +}