Repository: SDWebImage/SDWebImage
File: SDWebImage/NSImage+Additions.m (Objective-C)

Code before:
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#import "NSImage+Additions.h"

#if SD_MAC

@implementation NSImage (Additions)

- (CGImageRef)CGImage {
    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
    CGImageRef cgImage = [self CGImageForProposedRect:&imageRect context:nil hints:nil];
    return cgImage;
}

- (CGFloat)scale {
    CGFloat scale = 1;
    CGFloat width = self.size.width;
    if (width > 0) {
        // Use CGImage to get pixel width, NSImageRep.pixelsWide may be double on Retina screen
        NSUInteger pixelWidth = CGImageGetWidth(self.CGImage);
        scale = pixelWidth / width;
    }
    return scale;
}

- (instancetype)initWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale {
    if (scale < 1) {
        scale = 1;
    }
    NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage scale:scale];
    NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
    self = [self initWithSize:size];
    if (self) {
        [self addRepresentation:imageRep];
    }
    return self;
}

- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale {
    if (scale < 1) {
        scale = 1;
    }
    NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:data scale:scale];
    if (!imageRep) {
        return nil;

Review comment (suggestion):
This may cause unnecessary cost if the `NSImage` it's not bitmap image based. (Such as PDF image, which is vector based image and scale does not work). We'd better only care about bitmap image rep.

Code after:
/*
 * This file is part of the SDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#import "NSImage+Additions.h"

#if SD_MAC

#import "SDWebImageCoderHelper.h"

@implementation NSImage (Additions)

- (CGImageRef)CGImage {
    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
    CGImageRef cgImage = [self CGImageForProposedRect:&imageRect context:nil hints:nil];
    return cgImage;
}

- (CGFloat)scale {
    CGFloat scale = 1;
    NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
    NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];
    CGFloat width = imageRep.size.width;
    CGFloat height = imageRep.size.height;
    NSUInteger pixelWidth = imageRep.pixelsWide;
    NSUInteger pixelHeight = imageRep.pixelsHigh;
    if (width > 0 && height > 0) {
        CGFloat widthScale = pixelWidth / width;
        CGFloat heightScale = pixelHeight / height;
        if (widthScale == heightScale && widthScale >= 1) {
            // Protect because there may be `NSImageRepMatchesDevice` (0)
            scale = widthScale;
        }
    }
    
    return scale;
}

- (instancetype)initWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation {
    if (scale < 1) {
        scale = 1;
    }
    CGFloat pixelWidth = CGImageGetWidth(cgImage);
    CGFloat pixelHeight = CGImageGetHeight(cgImage);
    NSSize size = NSMakeSize(pixelWidth / scale, pixelHeight / scale);
    if (orientation != kCGImagePropertyOrientationUp) {
        // AppKit design is different from UIKit. Where CGImage based image rep does not respect to any orientation. Only data based image rep which contains the EXIF metadata can automatically detect orientation.