CGFloat FSPComputeSSIMFactorBetween()

in ios/SpectrumKit/SpectrumKitInstrumentationTestsHelpers/FSPSSIMCalculator.m [148:187]


CGFloat FSPComputeSSIMFactorBetween(UIImage *left, UIImage *right)
{
  NSCParameterAssert(left != nil);
  NSCParameterAssert(right != nil);
  NSCParameterAssert(CGSizeEqualToSize(left.size, right.size));
  NSCAssert1(left.size.width >= FSPImageSimilaritySSIMWindowSize, @"Image width must be >= than %d", FSPImageSimilaritySSIMWindowSize);
  NSCAssert1(left.size.height >= FSPImageSimilaritySSIMWindowSize, @"Image height must be >= than %d", FSPImageSimilaritySSIMWindowSize);

  FSPImageData leftImageData = FSPMakeImageDataFromImage(left.CGImage);
  FSPImageData rightImageData = FSPMakeImageDataFromImage(right.CGImage);
  int leftChannels[FSPImageSimilaritySSIMWindowArea];
  int otherChannels[FSPImageSimilaritySSIMWindowArea];

  CGFloat ssimSum = 0;
  NSUInteger ssimCount = 0;

  for (NSUInteger x = 0; x < left.size.width - FSPImageSimilaritySSIMWindowSize; x += FSPImageSimilaritySSIMWindowStep) {
    for (NSUInteger y = 0; y < left.size.height - FSPImageSimilaritySSIMWindowSize; y += FSPImageSimilaritySSIMWindowStep) {

      for (NSUInteger channel = 0; channel < FSPImageSimilaritySSIMChannelsCount; ++channel) {
        for (NSUInteger yy = 0; yy < FSPImageSimilaritySSIMWindowSize; ++yy) {
          for (NSUInteger xx = 0; xx < FSPImageSimilaritySSIMWindowSize; ++xx) {
            const NSUInteger byteIndex = FSPImageSimilaritySSIMChannelsCount * ((y + yy) * left.size.width + (x + xx));
            const NSUInteger i = yy * FSPImageSimilaritySSIMWindowSize + xx;
            leftChannels[i] = leftImageData.bytes[byteIndex + channel];
            otherChannels[i] = rightImageData.bytes[byteIndex + channel];
          }
        }

        ssimSum += FSPComputeSSIMForChannels(leftChannels, otherChannels);
        ++ssimCount;
      }
    }
  }

  FSPCleanupImageData(&leftImageData);
  FSPCleanupImageData(&rightImageData);

  return ssimSum / (CGFloat)ssimCount;
}