static FSPImageData FSPMakeImageDataFromImage()

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;
}