static double SSIMGetClipped(const uint8_t* src1, int stride1, const uint8_t* src2, int stride2, int xo, int yo, int W, int H) { DistoStats stats = { 0, 0, 0, 0, 0, 0 }; const int ymin = (yo - SSIM_KERNEL < 0) ? 0 : yo - SSIM_KERNEL; const int ymax = (yo + SSIM_KERNEL > H - 1) ? H - 1 : yo + SSIM_KERNEL; const int xmin = (xo - SSIM_KERNEL < 0) ? 0 : xo - SSIM_KERNEL; const int xmax = (xo + SSIM_KERNEL > W - 1) ? W - 1 : xo + SSIM_KERNEL; int x, y; src1 += ymin * stride1; src2 += ymin * stride2; for (y = ymin; y <= ymax; ++y, src1 += stride1, src2 += stride2) { for (x = xmin; x <= xmax; ++x) { const uint32_t w = kWeight[SSIM_KERNEL + x - xo] * kWeight[SSIM_KERNEL + y - yo]; const uint32_t s1 = src1[x]; const uint32_t s2 = src2[x]; stats.w += w; stats.xm += w * s1; stats.ym += w * s2; stats.xxm += w * s1 * s1; stats.xym += w * s1 * s2; stats.yym += w * s2 * s2; } } return SSIMCalculation(&stats); }
double VP8SSIMFromStatsClipped(const VP8DistoStats* const stats) { return SSIMCalculation(stats, stats->w); }
double VP8SSIMFromStats(const VP8DistoStats* const stats) { return SSIMCalculation(stats, kWeightSum); }