Blame macosx/quicklookdjvu/GeneratePreviewForURL.m

Packit df99a1
#include <CoreFoundation/CoreFoundation.h>
Packit df99a1
#include <CoreServices/CoreServices.h>
Packit df99a1
#include <QuickLook/QuickLook.h>
Packit df99a1
#import <Cocoa/Cocoa.h>
Packit df99a1
Packit df99a1
#include "ddjvuRef.h"
Packit df99a1
Packit df99a1
/* -----------------------------------------------------------------------------
Packit df99a1
   Generate a preview for file
Packit df99a1
Packit df99a1
   This function's job is to create preview for designated file
Packit df99a1
   ----------------------------------------------------------------------------- */
Packit df99a1
Packit df99a1
OSStatus
Packit df99a1
GeneratePreviewForURL(void *thisInterface,
Packit df99a1
					  QLPreviewRequestRef preview,
Packit df99a1
					  CFURLRef url,
Packit df99a1
					  CFStringRef contentTypeUTI,
Packit df99a1
					  CFDictionaryRef options)
Packit df99a1
{
Packit df99a1
	CFBundleRef bundle = QLPreviewRequestGetGeneratorBundle(preview);
Packit df99a1
	char *ddjvu = ddjvuPath(bundle);
Packit df99a1
	if (ddjvu != NULL) {
Packit df99a1
		NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];		
Packit df99a1
		NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
Packit df99a1
		NSDictionary *domain = [defaults persistentDomainForName:@"org.djvu.qlgenerator"];
Packit df99a1
		CFUUIDRef uuid = NULL;
Packit df99a1
		CFStringRef uuidString;
Packit df99a1
		BOOL debug = FALSE;
Packit df99a1
		NSString *tmpPath = nil;
Packit df99a1
		
Packit df99a1
		if (domain && [domain objectForKey:@"previewpages"])
Packit df99a1
			if ([[domain objectForKey:@"previewpages"] intValue] == 0)
Packit df99a1
				goto poppool;
Packit df99a1
Packit df99a1
		if (domain && [domain objectForKey:@"debug"]) {
Packit df99a1
			debug = [[domain objectForKey:@"debug"] boolValue];
Packit df99a1
		}
Packit df99a1
		
Packit df99a1
		uuid = CFUUIDCreate(kCFAllocatorDefault);
Packit df99a1
		if (uuid) {
Packit df99a1
			uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuid);
Packit df99a1
			if (uuidString) {
Packit df99a1
				tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:
Packit df99a1
						   [NSString stringWithFormat:@"djvuql-%@", uuidString]];
Packit df99a1
				CFRelease(uuidString);
Packit df99a1
			}
Packit df99a1
			CFRelease(uuid);
Packit df99a1
		}
Packit df99a1
		if (tmpPath) {
Packit df99a1
			const char *cmd = NULL;
Packit df99a1
			CFStringRef cmdRef;
Packit df99a1
			int page = 0;
Packit df99a1
			int pages = 1;
Packit df99a1
			int maxpages = 5;
Packit df99a1
			int width = 612;	// default 8.5x11 in points
Packit df99a1
			int height = 792;
Packit df99a1
			CGSize size;
Packit df99a1
			MDItemRef mditem = NULL;
Packit df99a1
			NSString *source = (NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
Packit df99a1
			NSString *dest = nil;
Packit df99a1
			NSFileManager *fmgr = [NSFileManager defaultManager];
Packit df99a1
			[fmgr createDirectoryAtPath:tmpPath attributes:nil];
Packit df99a1
			
Packit df99a1
			mditem = MDItemCreate(kCFAllocatorDefault, (CFStringRef)source);
Packit df99a1
			if (mditem) {
Packit df99a1
				CFTypeRef ref = NULL;
Packit df99a1
				ref = MDItemCopyAttribute(mditem, kMDItemNumberOfPages);
Packit df99a1
				if (ref) {
Packit df99a1
					CFNumberGetValue(ref, kCFNumberIntType, &pages);
Packit df99a1
					CFRelease(ref);
Packit df99a1
				}
Packit df99a1
				ref = MDItemCopyAttribute(mditem, kMDItemPageWidth);
Packit df99a1
				if (ref) {
Packit df99a1
					CFNumberGetValue(ref, kCFNumberIntType, &width);
Packit df99a1
					CFRelease(ref);
Packit df99a1
				}
Packit df99a1
				ref = MDItemCopyAttribute(mditem, kMDItemPageHeight);
Packit df99a1
				if (ref) {
Packit df99a1
					CFNumberGetValue(ref, kCFNumberIntType, &height);
Packit df99a1
					CFRelease(ref);
Packit df99a1
				}
Packit df99a1
				CFRelease(mditem);				
Packit df99a1
			}
Packit df99a1
			
Packit df99a1
			if (domain && [domain objectForKey:@"previewpages"])
Packit df99a1
				maxpages = [[domain objectForKey:@"previewpages"] intValue];
Packit df99a1
			
Packit df99a1
			if (debug) {
Packit df99a1
				NSLog(@"metadata: pages=%d, width=%d, height=%d", pages, width, height);
Packit df99a1
				NSLog(@"maxpages=%d", maxpages);				
Packit df99a1
			}
Packit df99a1
						
Packit df99a1
			CGRect rect = CGRectMake(0, 0, width, height);
Packit df99a1
			CGContextRef c;
Packit df99a1
			c = QLPreviewRequestCreatePDFContext(preview, &rect, NULL, NULL);
Packit df99a1
			
Packit df99a1
			page = 0;
Packit df99a1
			do {
Packit df99a1
				page++;
Packit df99a1
				dest = [tmpPath stringByAppendingPathComponent:[[source lastPathComponent] stringByAppendingFormat:@"_t_p%04d.tiff", page]];
Packit df99a1
				size = CGSizeMake(width, height);
Packit df99a1
				cmdRef = CFStringCreateWithFormat(NULL, NULL, CFSTR("\"%s\" -format=tiff -page=%d -size=%dx%d \"%s\" \"%s\""), ddjvu, page, width, height, [source fileSystemRepresentation], [dest fileSystemRepresentation]);
Packit df99a1
				cmd = CFStringGetCStringPtr(cmdRef, CFStringGetSystemEncoding());
Packit df99a1
				if (cmd != NULL) {
Packit df99a1
					if (debug)
Packit df99a1
						NSLog(@"%s", cmd);
Packit df99a1
					if ((system(cmd) == 0) && ([fmgr fileExistsAtPath:dest])) {
Packit df99a1
						NSURL *durl = [NSURL fileURLWithPath:dest];
Packit df99a1
						CGImageSourceRef  sourceRef;
Packit df99a1
						
Packit df99a1
						sourceRef = CGImageSourceCreateWithURL((CFURLRef)durl, NULL);
Packit df99a1
						if(sourceRef) {
Packit df99a1
							CGImageRef imageRef = NULL;
Packit df99a1
							imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL);
Packit df99a1
							if (imageRef) {
Packit df99a1
								CGFloat offset = height * (page-1);
Packit df99a1
								CGRectOffset(rect, 0.0, offset);
Packit df99a1
								CGPDFContextBeginPage(c, NULL);
Packit df99a1
								CGContextSaveGState(c);
Packit df99a1
								CGContextDrawImage(c, rect, imageRef);
Packit df99a1
								if (page == maxpages && maxpages < pages) {
Packit df99a1
									CGAffineTransform m;
Packit df99a1
									CFURLRef more = CFBundleCopyResourceURL(bundle, CFSTR("more_pages"), CFSTR("pdf"), NULL);
Packit df99a1
									CGPDFDocumentRef doc = CGPDFDocumentCreateWithURL(more);
Packit df99a1
									CGPDFPageRef pdf = CGPDFDocumentGetPage(doc, 1);
Packit df99a1
									CGFloat offset = height * page;
Packit df99a1
									CGRectOffset(rect, 0.0, offset);
Packit df99a1
									CGContextSaveGState(c);
Packit df99a1
									m = CGPDFPageGetDrawingTransform(pdf, kCGPDFMediaBox, rect, 0, true);
Packit df99a1
									CGContextConcatCTM(c, m);
Packit df99a1
									CGContextDrawPDFPage(c, pdf);
Packit df99a1
									CGContextRestoreGState(c);
Packit df99a1
									CFRelease(doc);
Packit df99a1
								}
Packit df99a1
								CGContextRestoreGState(c);
Packit df99a1
								CGPDFContextEndPage(c);
Packit df99a1
								CFRelease(imageRef);
Packit df99a1
							}
Packit df99a1
							CFRelease(sourceRef);
Packit df99a1
						}
Packit df99a1
					}
Packit df99a1
				}
Packit df99a1
				CFRelease(cmdRef);
Packit df99a1
			} while (page < pages && page < maxpages);
Packit df99a1
Packit df99a1
			CGPDFContextClose(c);
Packit df99a1
			QLPreviewRequestFlushContext(preview, c);
Packit df99a1
			CFRelease(c);
Packit df99a1
			[fmgr removeFileAtPath:tmpPath handler:nil];
Packit df99a1
			[source release];
Packit df99a1
		}
Packit df99a1
	poppool:
Packit df99a1
		[pool release];
Packit df99a1
	}
Packit df99a1
    return noErr;
Packit df99a1
}
Packit df99a1
Packit df99a1
void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview)
Packit df99a1
{
Packit df99a1
    // implement only if supported
Packit df99a1
}