/*
 * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "WebIconDatabaseInternal.h"

#import "WebIconDatabaseClient.h"
#import "WebIconDatabaseDelegate.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
#import "WebNSNotificationCenterExtras.h"
#import "WebNSURLExtras.h"
#import "WebPreferences.h"
#import "WebTypesInternal.h"
#import <WebCore/FoundationExtras.h>
#import <WebCore/IconDatabase.h>
#import <WebCore/Image.h>
#import <WebCore/IntSize.h>
#import <WebCore/ThreadCheck.h>

using namespace WebCore;

NSString * const WebIconDatabaseVersionKey =    @"WebIconDatabaseVersion";
NSString * const WebURLToIconURLKey =           @"WebSiteURLToIconURLKey";

NSString *WebIconDatabaseDidAddIconNotification =          @"WebIconDatabaseDidAddIconNotification";
NSString *WebIconNotificationUserInfoURLKey =              @"WebIconNotificationUserInfoURLKey";
NSString *WebIconDatabaseDidRemoveAllIconsNotification =   @"WebIconDatabaseDidRemoveAllIconsNotification";

NSString *WebIconDatabaseDirectoryDefaultsKey = @"WebIconDatabaseDirectoryDefaultsKey";
NSString *WebIconDatabaseImportDirectoryDefaultsKey = @"WebIconDatabaseImportDirectoryDefaultsKey";
NSString *WebIconDatabaseEnabledDefaultsKey =   @"WebIconDatabaseEnabled";

NSString *WebIconDatabasePath = @"~/Library/Icons";

NSSize WebIconSmallSize = {16, 16};
NSSize WebIconMediumSize = {32, 32};
NSSize WebIconLargeSize = {128, 128};

#define UniqueFilePathSize (34)

static WebIconDatabaseClient* defaultClient()
{
    static WebIconDatabaseClient* defaultClient = new WebIconDatabaseClient();
    return defaultClient;
}

@interface WebIconDatabase (WebReallyInternal)
- (BOOL)_isEnabled;
- (void)_sendNotificationForURL:(NSString *)URL;
- (void)_sendDidRemoveAllIconsNotification;
- (NSImage *)_iconForFileURL:(NSString *)fileURL withSize:(NSSize)size;
- (void)_resetCachedWebPreferences:(NSNotification *)notification;
- (NSImage *)_largestIconFromDictionary:(NSMutableDictionary *)icons;
- (NSMutableDictionary *)_iconsBySplittingRepresentationsOfIcon:(NSImage *)icon;
- (NSImage *)_iconFromDictionary:(NSMutableDictionary *)icons forSize:(NSSize)size cache:(BOOL)cache;
- (void)_scaleIcon:(NSImage *)icon toSize:(NSSize)size;
- (NSString *)_databaseDirectory;
@end

@implementation WebIconDatabase

+ (WebIconDatabase *)sharedIconDatabase
{
    static WebIconDatabase *database = nil;
    if (!database)
        database = [[WebIconDatabase alloc] init];
    return database;
}

- init
{
    [super init];
    WebCoreThreadViolationCheck();
        
    _private = [[WebIconDatabasePrivate alloc] init];
    
    // Check the user defaults and see if the icon database should even be enabled.
    // Inform the bridge and, if we're disabled, bail from init right here
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    // <rdar://problem/4741419> - IconDatabase should be disabled by default
    NSDictionary *initialDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:YES], WebIconDatabaseEnabledDefaultsKey, nil];
    [defaults registerDefaults:initialDefaults];
    [initialDefaults release];
    BOOL enabled = [defaults boolForKey:WebIconDatabaseEnabledDefaultsKey];
    iconDatabase()->setEnabled(enabled);
    if (!enabled)
        return self;
    iconDatabase()->setClient(defaultClient());
    
    // Figure out the directory we should be using for the icon.db
    NSString *databaseDirectory = [self _databaseDirectory];
    
    // Rename legacy icon database files to the new icon database name
    BOOL isDirectory = NO;
    NSString *legacyDB = [databaseDirectory stringByAppendingPathComponent:@"icon.db"];
    NSFileManager *defaultManager = [NSFileManager defaultManager];
    if ([defaultManager fileExistsAtPath:legacyDB isDirectory:&isDirectory] && !isDirectory) {
        NSString *newDB = [databaseDirectory stringByAppendingPathComponent:iconDatabase()->defaultDatabaseFilename()];
        if (![defaultManager fileExistsAtPath:newDB])
            rename([legacyDB fileSystemRepresentation], [newDB fileSystemRepresentation]);
    }
    
    // Set the private browsing pref then open the WebCore icon database
    iconDatabase()->setPrivateBrowsingEnabled([[WebPreferences standardPreferences] privateBrowsingEnabled]);
    if (!iconDatabase()->open(databaseDirectory))
        LOG_ERROR("Unable to open icon database");
    
    // Register for important notifications
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(_applicationWillTerminate:)
                                                 name:NSApplicationWillTerminateNotification
                                               object:NSApp];
    [[NSNotificationCenter defaultCenter] 
            addObserver:self selector:@selector(_resetCachedWebPreferences:) 
                   name:WebPreferencesChangedNotification object:nil];

    return self;
}

- (NSImage *)iconForURL:(NSString *)URL withSize:(NSSize)size cache:(BOOL)cache
{
    ASSERT_MAIN_THREAD();
    ASSERT(size.width);
    ASSERT(size.height);

    if (!URL || ![self _isEnabled])
        return [self defaultIconForURL:URL withSize:size];

    // FIXME - <rdar://problem/4697934> - Move the handling of FileURLs to WebCore and implement in ObjC++
    if ([URL _webkit_isFileURL])
        return [self _iconForFileURL:URL withSize:size];
      
    if (Image* image = iconDatabase()->iconForPageURL(URL, IntSize(size)))
        if (NSImage *icon = webGetNSImage(image, size))
            return icon;
    return [self defaultIconForURL:URL withSize:size];
}

- (NSImage *)iconForURL:(NSString *)URL withSize:(NSSize)size
{
    return [self iconForURL:URL withSize:size cache:YES];
}

- (NSString *)iconURLForURL:(NSString *)URL
{
    if (![self _isEnabled])
        return nil;
    ASSERT_MAIN_THREAD();

    return iconDatabase()->iconURLForPageURL(URL);
}

- (NSImage *)defaultIconWithSize:(NSSize)size
{
    ASSERT_MAIN_THREAD();
    ASSERT(size.width);
    ASSERT(size.height);
    
    Image* image = iconDatabase()->defaultIcon(IntSize(size));
    return image ? image->getNSImage() : nil;
}

- (NSImage *)defaultIconForURL:(NSString *)URL withSize:(NSSize)size
{
    if (_private->delegateImplementsDefaultIconForURL)
        return [_private->delegate webIconDatabase:self defaultIconForURL:URL withSize:size];
    return [self defaultIconWithSize:size];
}

- (void)retainIconForURL:(NSString *)URL
{
    ASSERT_MAIN_THREAD();
    ASSERT(URL);
    if (![self _isEnabled])
        return;

    iconDatabase()->retainIconForPageURL(URL);
}

- (void)releaseIconForURL:(NSString *)pageURL
{
    ASSERT_MAIN_THREAD();
    ASSERT(pageURL);
    if (![self _isEnabled])
        return;

    iconDatabase()->releaseIconForPageURL(pageURL);
}

+ (void)delayDatabaseCleanup
{
    ASSERT_MAIN_THREAD();

    IconDatabase::delayDatabaseCleanup();
}

+ (void)allowDatabaseCleanup
{
    ASSERT_MAIN_THREAD();

    IconDatabase::allowDatabaseCleanup();
}

- (void)setDelegate:(id)delegate
{
    _private->delegate = delegate;
    _private->delegateImplementsDefaultIconForURL = [delegate respondsToSelector:@selector(webIconDatabase:defaultIconForURL:withSize:)];
}

- (id)delegate
{
    return _private->delegate;
}

@end


@implementation WebIconDatabase (WebPendingPublic)

- (void)removeAllIcons
{
    ASSERT_MAIN_THREAD();
    if (![self _isEnabled])
        return;

    // Via the IconDatabaseClient interface, removeAllIcons() will send the WebIconDatabaseDidRemoveAllIconsNotification
    iconDatabase()->removeAllIcons();
}

@end

@implementation WebIconDatabase (WebPrivate)

+ (void)_checkIntegrityBeforeOpening
{
    iconDatabase()->checkIntegrityBeforeOpening();
}

@end

@implementation WebIconDatabase (WebInternal)

- (BOOL)_isEnabled
{
    return iconDatabase()->isEnabled();
}

- (void)_sendNotificationForURL:(NSString *)URL
{
    ASSERT(URL);
    
    NSDictionary *userInfo = [NSDictionary dictionaryWithObject:URL
                                                         forKey:WebIconNotificationUserInfoURLKey];
                                                         
    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:WebIconDatabaseDidAddIconNotification
                                                        object:self
                                                      userInfo:userInfo];
}

- (void)_sendDidRemoveAllIconsNotification
{
    [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:WebIconDatabaseDidRemoveAllIconsNotification
                                                        object:self
                                                      userInfo:nil];
}

- (void)_applicationWillTerminate:(NSNotification *)notification
{
    iconDatabase()->close();
}

- (NSImage *)_iconForFileURL:(NSString *)file withSize:(NSSize)size
{
    ASSERT_MAIN_THREAD();
    ASSERT(size.width);
    ASSERT(size.height);

    NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
    NSString *path = [[NSURL _web_URLWithDataAsString:file] path];
    NSString *suffix = [path pathExtension];
    NSImage *icon = nil;
    
    if ([suffix _webkit_isCaseInsensitiveEqualToString:@"htm"] || [suffix _webkit_isCaseInsensitiveEqualToString:@"html"]) {
        if (!_private->htmlIcons) {
            icon = [workspace iconForFileType:@"html"];
            _private->htmlIcons = [[self _iconsBySplittingRepresentationsOfIcon:icon] retain];
        }
        icon = [self _iconFromDictionary:_private->htmlIcons forSize:size cache:YES];
    } else {
        if (!path || ![path isAbsolutePath]) {
            // Return the generic icon when there is no path.
            icon = [workspace iconForFileType:NSFileTypeForHFSTypeCode(kGenericDocumentIcon)];
        } else {
            icon = [workspace iconForFile:path];
        }
        [self _scaleIcon:icon toSize:size];
    }

    return icon;
}

- (void)_resetCachedWebPreferences:(NSNotification *)notification
{
    BOOL privateBrowsingEnabledNow = [[WebPreferences standardPreferences] privateBrowsingEnabled];
    iconDatabase()->setPrivateBrowsingEnabled(privateBrowsingEnabledNow);
}

- (NSImage *)_largestIconFromDictionary:(NSMutableDictionary *)icons
{
    ASSERT(icons);
    
    NSEnumerator *enumerator = [icons keyEnumerator];
    NSValue *currentSize, *largestSize=nil;
    float largestSizeArea=0;

    while ((currentSize = [enumerator nextObject]) != nil) {
        NSSize currentSizeSize = [currentSize sizeValue];
        float currentSizeArea = currentSizeSize.width * currentSizeSize.height;
        if(!largestSizeArea || (currentSizeArea > largestSizeArea)){
            largestSize = currentSize;
            largestSizeArea = currentSizeArea;
        }
    }

    return [icons objectForKey:largestSize];
}

- (NSMutableDictionary *)_iconsBySplittingRepresentationsOfIcon:(NSImage *)icon
{
    ASSERT(icon);

    NSMutableDictionary *icons = [NSMutableDictionary dictionary];
    NSEnumerator *enumerator = [[icon representations] objectEnumerator];
    NSImageRep *rep;

    while ((rep = [enumerator nextObject]) != nil) {
        NSSize size = [rep size];
        NSImage *subIcon = [[NSImage alloc] initWithSize:size];
        [subIcon addRepresentation:rep];
        [icons setObject:subIcon forKey:[NSValue valueWithSize:size]];
        [subIcon release];
    }

    if([icons count] > 0)
        return icons;

    LOG_ERROR("icon has no representations");
    
    return nil;
}

- (NSImage *)_iconFromDictionary:(NSMutableDictionary *)icons forSize:(NSSize)size cache:(BOOL)cache
{
    ASSERT(size.width);
    ASSERT(size.height);

    NSImage *icon = [icons objectForKey:[NSValue valueWithSize:size]];

    if(!icon){
        icon = [[[self _largestIconFromDictionary:icons] copy] autorelease];
        [self _scaleIcon:icon toSize:size];

        if(cache){
            [icons setObject:icon forKey:[NSValue valueWithSize:size]];
        }
    }

    return icon;
}

- (void)_scaleIcon:(NSImage *)icon toSize:(NSSize)size
{
    ASSERT(size.width);
    ASSERT(size.height);
    
#if !LOG_DISABLED        
    double start = CFAbsoluteTimeGetCurrent();
#endif
    
    [icon setScalesWhenResized:YES];
    [icon setSize:size];
    
#if !LOG_DISABLED
    double duration = CFAbsoluteTimeGetCurrent() - start;
    LOG(Timing, "scaling icon took %f seconds.", duration);
#endif
}

// This hashing String->filename algorithm came from WebFileDatabase.m and is what was used in the 
// WebKit Icon Database
static void legacyIconDatabaseFilePathForKey(id key, char *buffer)
{
    const char *s;
    UInt32 hash1;
    UInt32 hash2;
    CFIndex len;
    CFIndex cnt;
    
    s = [[[[key description] lowercaseString] stringByStandardizingPath] UTF8String];
    len = strlen(s);

    // compute first hash    
    hash1 = len;
    for (cnt = 0; cnt < len; cnt++) {
        hash1 += (hash1 << 8) + s[cnt];
    }
    hash1 += (hash1 << (len & 31));

    // compute second hash    
    hash2 = len;
    for (cnt = 0; cnt < len; cnt++) {
        hash2 = (37 * hash2) ^ s[cnt];
    }

#ifdef __LP64__
    snprintf(buffer, UniqueFilePathSize, "%.2u/%.2u/%.10u-%.10u.cache", ((hash1 & 0xff) >> 4), ((hash2 & 0xff) >> 4), hash1, hash2);
#else
    snprintf(buffer, UniqueFilePathSize, "%.2lu/%.2lu/%.10lu-%.10lu.cache", ((hash1 & 0xff) >> 4), ((hash2 & 0xff) >> 4), hash1, hash2);
#endif
}

// This method of getting an object from the filesystem is taken from the old 
// WebKit Icon Database
static id objectFromPathForKey(NSString *databasePath, id key)
{
    ASSERT(key);
    id result = nil;

    // Use the key->filename hashing the old WebKit IconDatabase used
    char uniqueKey[UniqueFilePathSize];    
    legacyIconDatabaseFilePathForKey(key, uniqueKey);
    
    // Get the data from this file and setup for the un-archiving
    NSString *filePath = [[NSString alloc] initWithFormat:@"%@/%s", databasePath, uniqueKey];
    NSData *data = [[NSData alloc] initWithContentsOfFile:filePath];
    NSUnarchiver *unarchiver = nil;
    
    @try {
        if (data) {
            unarchiver = [[NSUnarchiver alloc] initForReadingWithData:data];
            if (unarchiver) {
                id fileKey = [unarchiver decodeObject];
                if ([fileKey isEqual:key]) {
                    id object = [unarchiver decodeObject];
                    if (object) {
                        // Decoded objects go away when the unarchiver does, so we need to
                        // retain this so we can return it to our caller.
                        result = [[object retain] autorelease];
                        LOG(IconDatabase, "read disk cache file - %@", key);
                    }
                }
            }
        }
    } @catch (NSException *localException) {
        LOG(IconDatabase, "cannot unarchive cache file - %@", key);
        result = nil;
    }

    [unarchiver release];
    [data release];
    [filePath release];
    
    return result;
}

static NSData* iconDataFromPathForIconURL(NSString *databasePath, NSString *iconURLString)
{
    ASSERT(iconURLString);
    ASSERT(databasePath);
    
    NSData *iconData = objectFromPathForKey(databasePath, iconURLString);
    
    if ((id)iconData == (id)[NSNull null]) 
        return nil;
        
    return iconData;
}

- (NSString *)_databaseDirectory
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    // Figure out the directory we should be using for the icon.db
    NSString *databaseDirectory = [defaults objectForKey:WebIconDatabaseDirectoryDefaultsKey];
    if (!databaseDirectory) {
        databaseDirectory = WebIconDatabasePath;
        [defaults setObject:databaseDirectory forKey:WebIconDatabaseDirectoryDefaultsKey];
    }
    
    return [[databaseDirectory stringByExpandingTildeInPath] stringByStandardizingPath];
}

@end

@implementation WebIconDatabasePrivate
@end

@interface ThreadEnabler : NSObject {
}
+ (void)enableThreading;

- (void)threadEnablingSelector:(id)arg;
@end

@implementation ThreadEnabler

- (void)threadEnablingSelector:(id)arg
{
    return;
}

+ (void)enableThreading
{
    ThreadEnabler *enabler = [[ThreadEnabler alloc] init];
    [NSThread detachNewThreadSelector:@selector(threadEnablingSelector:) toTarget:enabler withObject:nil];
    [enabler release];
}

@end

bool importToWebCoreFormat()
{
    // Since this is running on a secondary POSIX thread and Cocoa cannot be used multithreaded unless an NSThread has been detached,
    // make sure that happens here for all WebKit clients
    if (![NSThread isMultiThreaded])
        [ThreadEnabler enableThreading];
    ASSERT([NSThread isMultiThreaded]);    
    
#ifndef BUILDING_ON_TIGER 
    // Tell backup software (i.e., Time Machine) to never back up the icon database, because  
    // it's a large file that changes frequently, thus using a lot of backup disk space, and 
    // it's unlikely that many users would be upset about it not being backed up. We do this 
    // here because this code is only executed once for each icon database instance. We could 
    // make this configurable on a per-client basis someday if that seemed useful. 
    // See <rdar://problem/5320208>.
    CFStringRef databasePath = iconDatabase()->databasePath().createCFString();
    if (databasePath) {
        CFURLRef databasePathURL = CFURLCreateWithFileSystemPath(0, databasePath, kCFURLPOSIXPathStyle, FALSE); 
        CFRelease(databasePath);
        CSBackupSetItemExcluded(databasePathURL, true, true); 
        CFRelease(databasePathURL);
    }
#endif 

    // Get the directory the old icon database *should* be in
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *databaseDirectory = [defaults objectForKey:WebIconDatabaseImportDirectoryDefaultsKey];
    
    if (!databaseDirectory)
        databaseDirectory = [defaults objectForKey:WebIconDatabaseDirectoryDefaultsKey];
        
    if (!databaseDirectory) {
        databaseDirectory = WebIconDatabasePath;
        [defaults setObject:databaseDirectory forKey:WebIconDatabaseDirectoryDefaultsKey];
    }
    databaseDirectory = [databaseDirectory stringByExpandingTildeInPath];

    // With this directory, get the PageURLToIconURL map that was saved to disk
    NSMutableDictionary *pageURLToIconURL = objectFromPathForKey(databaseDirectory, WebURLToIconURLKey);

    // If the retrieved object was not a valid NSMutableDictionary, then we have no valid
    // icons to import
    if (![pageURLToIconURL isKindOfClass:[NSMutableDictionary class]])
        pageURLToIconURL = nil;
    
    NSEnumerator *enumerator = [pageURLToIconURL keyEnumerator];
    NSString *url, *iconURL;
    
    // First, we'll iterate through the PageURL->IconURL map
    while ((url = [enumerator nextObject]) != nil) {
        iconURL = [pageURLToIconURL objectForKey:url];
        if (!iconURL)
            continue;
        iconDatabase()->importIconURLForPageURL(iconURL, url);
        if (iconDatabase()->shouldStopThreadActivity())
            return false;
    }    

    // Second, we'll get a list of the unique IconURLs we have
    NSMutableSet *iconsOnDiskWithURLs = [NSMutableSet setWithArray:[pageURLToIconURL allValues]];
    enumerator = [iconsOnDiskWithURLs objectEnumerator];
    NSData *iconData;
    
    // And iterate through them, adding the icon data to the new icon database
    while ((url = [enumerator nextObject]) != nil) {
        iconData = iconDataFromPathForIconURL(databaseDirectory, url);
        if (iconData)
            iconDatabase()->importIconDataForIconURL(SharedBuffer::wrapNSData(iconData), url);
        else {
            // This really *shouldn't* happen, so it'd be good to track down why it might happen in a debug build
            // however, we do know how to handle it gracefully in release
            LOG_ERROR("%@ is marked as having an icon on disk, but we couldn't get the data for it", url);
            iconDatabase()->importIconDataForIconURL(0, url);
        }
        if (iconDatabase()->shouldStopThreadActivity())
            return false;
    }
    
    // After we're done importing old style icons over to webcore icons, we delete the entire directory hierarchy 
    // for the old icon DB (skipping the new iconDB if it is in the same directory)
    NSFileManager *fileManager = [NSFileManager defaultManager];
    enumerator = [[fileManager directoryContentsAtPath:databaseDirectory] objectEnumerator];
    
    NSString *databaseFilename = iconDatabase()->defaultDatabaseFilename();

    BOOL foundIconDB = NO;
    NSString *file;
    while ((file = [enumerator nextObject]) != nil) {
        if ([file caseInsensitiveCompare:databaseFilename] == NSOrderedSame) {
            foundIconDB = YES;
            continue;
        }
        NSString *filePath = [databaseDirectory stringByAppendingPathComponent:file];
        if (![fileManager removeFileAtPath:filePath handler:nil])
            LOG_ERROR("Failed to delete %@ from old icon directory", filePath);
    }
    
    // If the new iconDB wasn't in that directory, we can delete the directory itself
    if (!foundIconDB)
        rmdir([databaseDirectory fileSystemRepresentation]);
    
    return true;
}

NSImage *webGetNSImage(Image* image, NSSize size)
{
    ASSERT_MAIN_THREAD();
    ASSERT(size.width);
    ASSERT(size.height);

    // FIXME: We're doing the resize here for now because WebCore::Image doesn't yet support resizing/multiple representations
    // This makes it so there's effectively only one size of a particular icon in the system at a time. We should move this
    // to WebCore::Image at some point.
    if (!image)
        return nil;
    NSImage* nsImage = image->getNSImage();
    if (!nsImage)
        return nil;
    if (!NSEqualSizes([nsImage size], size)) {
        [nsImage setScalesWhenResized:YES];
        [nsImage setSize:size];
    }
    return nsImage;
}
