in ios/SpectrumKit/SpectrumKitInstrumentationTestsHelpers/FSPSSIMCalculator.m [76:136]
static FSPImageData FSPMakeImageDataFromImage(CGImageRef image)
{
// Inspired from https://developer.apple.com/library/content/qa/qa1509/_index.html
const size_t imageHeight = CGImageGetHeight(image);
const size_t imageWidth = CGImageGetWidth(image);
// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
const NSInteger bitmapBytesPerRow = imageWidth * FSPImageSimilaritySSIMChannelsCount;
const CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
NSCAssert(colorSpace != NULL, @"Unable to get color space");
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
void *bitmapData = malloc(bitmapBytesPerRow * imageHeight);
if (bitmapData == NULL) {
CGColorSpaceRelease(colorSpace);
NSCAssert(false, @"Unable to alloc bitmap data");
}
// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
CGContextRef context = CGBitmapContextCreate(bitmapData,
imageWidth,
imageHeight,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace);
if (context == NULL) {
free(bitmapData);
NSCAssert(false, @"Unable to create context");
}
// Draw the image to the bitmap context. Once we draw, the memory
// allocated for the context for rendering will then contain the
// raw image data in the specified color space.
CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image);
// Now we can get a pointer to the image data associated with the bitmap
// context.
uint8_t const *const bytes = (uint8_t const *const)CGBitmapContextGetData(context);
NSCAssert(bytes != NULL, @"Unable to get bitmap bytes");
FSPImageData data;
data.bytes = bytes;
data.context = context;
return data;
}