-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathGenerateThumbnailForURL.m
More file actions
131 lines (115 loc) · 5.06 KB
/
GenerateThumbnailForURL.m
File metadata and controls
131 lines (115 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <QuickLook/QuickLook.h>
#import <Cocoa/Cocoa.h>
#import "GNJUnZip.h"
#import "NSString+Additions.h"
/* -----------------------------------------------------------------------------
Generate a thumbnail for file
This function's job is to create thumbnail for designated file as fast as possible
----------------------------------------------------------------------------- */
OSStatus GenerateThumbnailForURL(void *thisInterface,
QLThumbnailRequestRef thumbnail,
CFURLRef url,
CFStringRef contentTypeUTI,
CFDictionaryRef options,
CGSize maxSize)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *path = [(NSURL *)url path];
GNJUnZip *unzip = [[GNJUnZip alloc] initWithZipFile:path];
NSCharacterSet *setForTrim = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSData *xmlData = [unzip dataWithContentsOfFile:@"META-INF/container.xml"];
if(!xmlData) {
[unzip release];
[pool release];
return noErr;
}
NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithData:xmlData
options:NSXMLDocumentTidyXML
error:NULL];
if(!xmlDoc) {
[unzip release];
[pool release];
return noErr;
}
NSString *xpath = @"/container/rootfiles/rootfile/@full-path";
NSArray *nodes = [xmlDoc nodesForXPath:xpath error:NULL];
if(![nodes count]) {
[xmlDoc release];
[unzip release];
[pool release];
return noErr;
}
NSString *fullPathValue = [[nodes objectAtIndex:0] stringValue];
NSString *opfFilePath = [fullPathValue stringByTrimmingCharactersInSet:setForTrim];
opfFilePath = [opfFilePath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[xmlDoc release];
xmlData = [unzip dataWithContentsOfFile:opfFilePath];
if(!xmlData) {
[unzip release];
[pool release];
return noErr;
}
xmlDoc = [[NSXMLDocument alloc] initWithData:xmlData
options:NSXMLDocumentTidyXML
error:NULL];
if(!xmlDoc) {
[unzip release];
[pool release];
return noErr;
}
NSString *coverImagePath = nil;
xpath = @"/package/manifest/item[contains(concat(' ', normalize-space(@properties), ' '), ' cover-image ')]/@href";
nodes = [xmlDoc nodesForXPath:xpath error:NULL];
if([nodes count]) coverImagePath = [[nodes objectAtIndex:0] stringValue];
else {
xpath = @"/package/metadata/meta[@name='cover']/@content";
nodes = [xmlDoc nodesForXPath:xpath error:NULL];
if([nodes count]) {
NSString *coverImageId = [[[nodes objectAtIndex:0] stringValue] stringByTrimmingCharactersInSet:setForTrim];
xpath = [NSString stringWithFormat:@"/package/manifest/item[@id='%@']/@href",
coverImageId];
NSArray *coverImageItemHrefs = [xmlDoc nodesForXPath:xpath error:NULL];
if([coverImageItemHrefs count]) {
coverImagePath = [[coverImageItemHrefs objectAtIndex:0] stringValue];
}
}
}
if([coverImagePath length]) {
coverImagePath = [coverImagePath stringByTrimmingCharactersInSet:setForTrim];
coverImagePath = [coverImagePath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if([coverImagePath isAbsolutePath]) coverImagePath = [coverImagePath substringFromIndex:1];
else {
NSString *opfBasePath = [opfFilePath stringByDeletingLastPathComponent];
coverImagePath = [opfBasePath stringByAppendingPathComponent:coverImagePath];
}
coverImagePath = [coverImagePath stringByForciblyResolvingSymlinksInPath];
NSData *coverImageData = [unzip dataWithContentsOfFile:coverImagePath];
NSImage *coverImage = [[[NSImage alloc] initWithData:coverImageData] autorelease];
if([coverImage isValid]) {
CGSize maximumSize = QLThumbnailRequestGetMaximumSize(thumbnail);
NSSize imageSize = [coverImage size];
CGFloat scale = maximumSize.width / ((imageSize.width > imageSize.height) ? imageSize.width : imageSize.height);
NSSize newSize = NSMakeSize(imageSize.width * scale, imageSize.height * scale);
NSImage *resizedImage = [[[NSImage alloc] initWithSize:newSize] autorelease];
[resizedImage lockFocus];
[coverImage drawInRect:NSMakeRect(0.0, 0.0, newSize.width, newSize.height)
fromRect:NSMakeRect(0.0, 0.0, imageSize.width, imageSize.height)
operation:NSCompositeSourceOver
fraction:1.0];
[resizedImage unlockFocus];
NSData *resizedImageData = [resizedImage TIFFRepresentation];
QLThumbnailRequestSetImageWithData(thumbnail, (CFDataRef)resizedImageData, NULL);
}
}
[xmlDoc release];
[unzip release];
[pool release];
return noErr;
}
void CancelThumbnailGeneration(void* thisInterface,
QLThumbnailRequestRef thumbnail)
{
// implement only if supported
}