Index: experimental/skpdiff/SkPMetric.cpp |
diff --git a/experimental/skpdiff/SkPMetric.cpp b/experimental/skpdiff/SkPMetric.cpp |
index c68646c93c2d21d6ad4ce28953526ad564aa3e10..e6210bfa3673daeff910e31c3eaa85cd60fa6fad 100644 |
--- a/experimental/skpdiff/SkPMetric.cpp |
+++ b/experimental/skpdiff/SkPMetric.cpp |
@@ -3,6 +3,7 @@ |
#include "SkBitmap.h" |
#include "skpdiff_util.h" |
#include "SkPMetric.h" |
+#include "SkPMetricUtil_generated.h" |
struct RGB { |
float r, g, b; |
@@ -112,7 +113,7 @@ void adobergb_to_cielab(float r, float g, float b, LAB* lab) { |
// http://en.wikipedia.org/wiki/CIELAB#Forward_transformation |
for (int i = 0; i < 3; i++) { |
if (f[i] >= 0.008856f) { |
- f[i] = powf(f[i], 1.0f / 3.0f); |
+ f[i] = SkPMetricUtil::get_cube_root(f[i]); |
} else { |
f[i] = 7.787f * f[i] + 4.0f / 29.0f; |
} |
@@ -138,9 +139,9 @@ static void bitmap_to_cielab(const SkBitmap* bitmap, ImageLAB* outImageLAB) { |
unsigned char* row = (unsigned char*)bitmap->getAddr(0, y); |
for (int x = 0; x < width; x++) { |
// Perform gamma correction which is assumed to be 2.2 |
- rgb.r = powf(row[x * 4 + 2] / 255.0f, 2.2f); |
- rgb.g = powf(row[x * 4 + 1] / 255.0f, 2.2f); |
- rgb.b = powf(row[x * 4 + 0] / 255.0f, 2.2f); |
+ rgb.r = SkPMetricUtil::get_gamma(row[x * 4 + 2]); |
+ rgb.g = SkPMetricUtil::get_gamma(row[x * 4 + 1]); |
+ rgb.b = SkPMetricUtil::get_gamma(row[x * 4 + 0]); |
adobergb_to_cielab(rgb.r, rgb.g, rgb.b, &lab); |
outImageLAB->writePixel(x, y, lab); |
} |
@@ -158,8 +159,12 @@ static float contrast_sensitivity(float cyclesPerDegree, float luminance) { |
sqrtf(1.0f + 0.06f * expf(b * cyclesPerDegree)); |
} |
+#if 0 |
+// We're keeping these around for reference and in case the lookup tables are no longer desired. |
+// They are no longer called by any code in this file. |
+ |
// From Daly 1993 |
-static float visual_mask(float contrast) { |
+ static float visual_mask(float contrast) { |
float x = powf(392.498f * contrast, 0.7f); |
x = powf(0.0153f * x, 4.0f); |
return powf(1.0f + x, 0.25f); |
@@ -183,6 +188,8 @@ static float threshold_vs_intensity(float adaptationLuminance) { |
return powf(10.0f, x); |
} |
+#endif |
+ |
/// Simply takes the L channel from the input and puts it into the output |
static void lab_to_l(const ImageLAB* imageLAB, ImageL* outImageL) { |
for (int y = 0; y < imageLAB->height; y++) { |
@@ -210,7 +217,6 @@ static void convolve(const ImageL* imageL, bool vertical, ImageL* outImageL) { |
} |
float* writeRow = outImageL->getRow(0); |
- |
for (int y = 0; y < imageL->height; y++) { |
for (int x = 0; x < imageL->width; x++) { |
float lSum = 0.0f; |
@@ -278,6 +284,16 @@ float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk |
cyclesPerDegree[levelIndex] = cyclesPerDegree[levelIndex - 1] * 0.5f; |
} |
+ // Contrast sensitivity is based on image dimensions. Therefore it cannot be statically |
+ // generated. |
+ float* contrastSensitivityTable = SkNEW_ARRAY(float, maxLevels * 1000); |
+ for (int levelIndex = 0; levelIndex < maxLevels; levelIndex++) { |
+ for (int csLum = 0; csLum < 1000; csLum++) { |
+ contrastSensitivityTable[levelIndex * 1000 + csLum] = |
+ contrast_sensitivity(cyclesPerDegree[levelIndex], (float)csLum / 10.0f + 1e-5f); |
+ } |
+ } |
+ |
// Compute G - The convolved lum for the baseline |
for (int levelIndex = 1; levelIndex < maxLevels; levelIndex++) { |
convolve(baselineL.getLayer(levelIndex - 1), false, &scratchImageL); |
@@ -339,7 +355,6 @@ float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk |
if (denominator < 1e-5) { |
denominator = 1e-5; |
} |
- |
contrast[levelIndex] = numerator / denominator; |
contrastSum += contrast[levelIndex]; |
} |
@@ -350,8 +365,10 @@ float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk |
float F = 0.0f; |
for (int levelIndex = 0; levelIndex < maxLevels - 2; levelIndex++) { |
- float mask = visual_mask(contrast[levelIndex] * |
- contrast_sensitivity(cyclesPerDegree[levelIndex], lAdapt)); |
+ float contrastSensitivity = contrastSensitivityTable[levelIndex * 1000 + |
+ (int)(lAdapt * 10.0)]; |
+ float mask = SkPMetricUtil::get_visual_mask(contrast[levelIndex] * |
+ contrastSensitivity); |
F += contrast[levelIndex] + |
thresholdFactorFrequency[levelIndex] * mask / contrastSum; |
@@ -367,7 +384,7 @@ float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk |
bool isFailure = false; |
- if (fabsf(lBaseline - lTest) > F * threshold_vs_intensity(lAdapt)) { |
+ if (fabsf(lBaseline - lTest) > F * SkPMetricUtil::get_threshold_vs_intensity(lAdapt)) { |
isFailure = true; |
} else { |
LAB baselineColor; |
@@ -398,6 +415,7 @@ float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk |
SkDELETE_ARRAY(cyclesPerDegree); |
SkDELETE_ARRAY(contrast); |
SkDELETE_ARRAY(thresholdFactorFrequency); |
+ SkDELETE_ARRAY(contrastSensitivityTable); |
return 1.0 - (double)failures / (width * height); |
} |
@@ -406,8 +424,8 @@ const char* SkPMetric::getName() { |
} |
int SkPMetric::queueDiff(SkBitmap* baseline, SkBitmap* test) { |
- int diffID = fQueuedDiffs.count(); |
double startTime = get_seconds(); |
+ int diffID = fQueuedDiffs.count(); |
QueuedDiff& diff = fQueuedDiffs.push_back(); |
diff.result = 0.0; |
@@ -433,7 +451,7 @@ int SkPMetric::queueDiff(SkBitmap* baseline, SkBitmap* test) { |
void SkPMetric::deleteDiff(int id) { |
- fQueuedDiffs[id].poi.reset(); |
+ |
} |
bool SkPMetric::isFinished(int id) { |