| OLD | NEW |
| 1 #include <cmath> | 1 #include <cmath> |
| 2 | 2 |
| 3 #include "SkBitmap.h" | 3 #include "SkBitmap.h" |
| 4 #include "skpdiff_util.h" | 4 #include "skpdiff_util.h" |
| 5 #include "SkPMetric.h" | 5 #include "SkPMetric.h" |
| 6 #include "SkPMetricUtil_generated.h" | 6 #include "SkPMetricUtil_generated.h" |
| 7 | 7 |
| 8 struct RGB { | 8 struct RGB { |
| 9 float r, g, b; | 9 float r, g, b; |
| 10 }; | 10 }; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 } else { | 116 } else { |
| 117 f[i] = 7.787f * f[i] + 4.0f / 29.0f; | 117 f[i] = 7.787f * f[i] + 4.0f / 29.0f; |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 lab->l = 116.0f * f[1] - 16.0f; | 120 lab->l = 116.0f * f[1] - 16.0f; |
| 121 lab->a = 500.0f * (f[0] - f[1]); | 121 lab->a = 500.0f * (f[0] - f[1]); |
| 122 lab->b = 200.0f * (f[1] - f[2]); | 122 lab->b = 200.0f * (f[1] - f[2]); |
| 123 } | 123 } |
| 124 | 124 |
| 125 /// Converts a 8888 bitmap to LAB color space and puts it into the output | 125 /// Converts a 8888 bitmap to LAB color space and puts it into the output |
| 126 static void bitmap_to_cielab(const SkBitmap* bitmap, ImageLAB* outImageLAB) { | 126 static bool bitmap_to_cielab(const SkBitmap* bitmap, ImageLAB* outImageLAB) { |
| 127 SkASSERT(bitmap->config() == SkBitmap::kARGB_8888_Config); | 127 SkBitmap bm8888; |
| 128 if (bitmap->config() != SkBitmap::kARGB_8888_Config) { |
| 129 if (!bitmap->copyTo(&bm8888, SkBitmap::kARGB_8888_Config)) { |
| 130 return false; |
| 131 } |
| 132 bitmap = &bm8888; |
| 133 } |
| 128 | 134 |
| 129 int width = bitmap->width(); | 135 int width = bitmap->width(); |
| 130 int height = bitmap->height(); | 136 int height = bitmap->height(); |
| 131 SkASSERT(outImageLAB->width == width); | 137 SkASSERT(outImageLAB->width == width); |
| 132 SkASSERT(outImageLAB->height == height); | 138 SkASSERT(outImageLAB->height == height); |
| 133 | 139 |
| 134 bitmap->lockPixels(); | 140 bitmap->lockPixels(); |
| 135 RGB rgb; | 141 RGB rgb; |
| 136 LAB lab; | 142 LAB lab; |
| 137 for (int y = 0; y < height; y++) { | 143 for (int y = 0; y < height; y++) { |
| 138 unsigned char* row = (unsigned char*)bitmap->getAddr(0, y); | 144 unsigned char* row = (unsigned char*)bitmap->getAddr(0, y); |
| 139 for (int x = 0; x < width; x++) { | 145 for (int x = 0; x < width; x++) { |
| 140 // Perform gamma correction which is assumed to be 2.2 | 146 // Perform gamma correction which is assumed to be 2.2 |
| 141 rgb.r = SkPMetricUtil::get_gamma(row[x * 4 + 2]); | 147 rgb.r = SkPMetricUtil::get_gamma(row[x * 4 + 2]); |
| 142 rgb.g = SkPMetricUtil::get_gamma(row[x * 4 + 1]); | 148 rgb.g = SkPMetricUtil::get_gamma(row[x * 4 + 1]); |
| 143 rgb.b = SkPMetricUtil::get_gamma(row[x * 4 + 0]); | 149 rgb.b = SkPMetricUtil::get_gamma(row[x * 4 + 0]); |
| 144 adobergb_to_cielab(rgb.r, rgb.g, rgb.b, &lab); | 150 adobergb_to_cielab(rgb.r, rgb.g, rgb.b, &lab); |
| 145 outImageLAB->writePixel(x, y, lab); | 151 outImageLAB->writePixel(x, y, lab); |
| 146 } | 152 } |
| 147 } | 153 } |
| 148 bitmap->unlockPixels(); | 154 bitmap->unlockPixels(); |
| 155 return true; |
| 149 } | 156 } |
| 150 | 157 |
| 151 // From Barten SPIE 1989 | 158 // From Barten SPIE 1989 |
| 152 static float contrast_sensitivity(float cyclesPerDegree, float luminance) { | 159 static float contrast_sensitivity(float cyclesPerDegree, float luminance) { |
| 153 float a = 440.0f * powf(1.0f + 0.7f / luminance, -0.2f); | 160 float a = 440.0f * powf(1.0f + 0.7f / luminance, -0.2f); |
| 154 float b = 0.3f * powf(1.0f + 100.0f / luminance, 0.15f); | 161 float b = 0.3f * powf(1.0f + 100.0f / luminance, 0.15f); |
| 155 return a * | 162 return a * |
| 156 cyclesPerDegree * | 163 cyclesPerDegree * |
| 157 expf(-b * cyclesPerDegree) * | 164 expf(-b * cyclesPerDegree) * |
| 158 sqrtf(1.0f + 0.06f * expf(b * cyclesPerDegree)); | 165 sqrtf(1.0f + 0.06f * expf(b * cyclesPerDegree)); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 int width = baselineLAB->width; | 269 int width = baselineLAB->width; |
| 263 int height = baselineLAB->height; | 270 int height = baselineLAB->height; |
| 264 int maxLevels = 0; | 271 int maxLevels = 0; |
| 265 | 272 |
| 266 // Calculates how many levels to make by how many times the image can be div
ided in two | 273 // Calculates how many levels to make by how many times the image can be div
ided in two |
| 267 int smallerDimension = width < height ? width : height; | 274 int smallerDimension = width < height ? width : height; |
| 268 for ( ; smallerDimension > 1; smallerDimension /= 2) { | 275 for ( ; smallerDimension > 1; smallerDimension /= 2) { |
| 269 maxLevels++; | 276 maxLevels++; |
| 270 } | 277 } |
| 271 | 278 |
| 279 // We'll be creating new arrays with maxLevels - 2, and ImageL3D requires ma
xLevels > 0, |
| 280 // so just return failure if we're less than 3. |
| 281 if (maxLevels <= 2) { |
| 282 return 0.0; |
| 283 } |
| 284 |
| 272 const float fov = SK_ScalarPI / 180.0f * 45.0f; | 285 const float fov = SK_ScalarPI / 180.0f * 45.0f; |
| 273 float contrastSensitivityMax = contrast_sensitivity(3.248f, 100.0f); | 286 float contrastSensitivityMax = contrast_sensitivity(3.248f, 100.0f); |
| 274 float pixelsPerDegree = width / (2.0f * tanf(fov * 0.5f) * 180.0f / SK_Scala
rPI); | 287 float pixelsPerDegree = width / (2.0f * tanf(fov * 0.5f) * 180.0f / SK_Scala
rPI); |
| 275 | 288 |
| 276 ImageL3D baselineL(width, height, maxLevels); | 289 ImageL3D baselineL(width, height, maxLevels); |
| 277 ImageL3D testL(width, height, maxLevels); | 290 ImageL3D testL(width, height, maxLevels); |
| 278 ImageL scratchImageL(width, height); | 291 ImageL scratchImageL(width, height); |
| 279 float* cyclesPerDegree = SkNEW_ARRAY(float, maxLevels); | 292 float* cyclesPerDegree = SkNEW_ARRAY(float, maxLevels); |
| 280 float* thresholdFactorFrequency = SkNEW_ARRAY(float, maxLevels - 2); | 293 float* thresholdFactorFrequency = SkNEW_ARRAY(float, maxLevels - 2); |
| 281 float* contrast = SkNEW_ARRAY(float, maxLevels - 2); | 294 float* contrast = SkNEW_ARRAY(float, maxLevels - 2); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 // Ensure the images are comparable | 456 // Ensure the images are comparable |
| 444 if (baseline->width() != test->width() || baseline->height() != test->height
() || | 457 if (baseline->width() != test->width() || baseline->height() != test->height
() || |
| 445 baseline->width() <= 0 || baseline->height() <= 0) { | 458 baseline->width() <= 0 || baseline->height() <= 0) { |
| 446 diff.finished = true; | 459 diff.finished = true; |
| 447 return diffID; | 460 return diffID; |
| 448 } | 461 } |
| 449 | 462 |
| 450 ImageLAB baselineLAB(baseline->width(), baseline->height()); | 463 ImageLAB baselineLAB(baseline->width(), baseline->height()); |
| 451 ImageLAB testLAB(baseline->width(), baseline->height()); | 464 ImageLAB testLAB(baseline->width(), baseline->height()); |
| 452 | 465 |
| 453 bitmap_to_cielab(baseline, &baselineLAB); | 466 if (!bitmap_to_cielab(baseline, &baselineLAB) || !bitmap_to_cielab(test, &te
stLAB)) { |
| 454 bitmap_to_cielab(test, &testLAB); | 467 return diffID; |
| 468 } |
| 455 | 469 |
| 456 diff.result = pmetric(&baselineLAB, &testLAB, &diff.poi); | 470 diff.result = pmetric(&baselineLAB, &testLAB, &diff.poi); |
| 457 | 471 |
| 458 SkDebugf("Time: %f\n", (get_seconds() - startTime)); | 472 SkDebugf("Time: %f\n", (get_seconds() - startTime)); |
| 459 | 473 |
| 460 return diffID; | 474 return diffID; |
| 461 } | 475 } |
| 462 | 476 |
| 463 | 477 |
| 464 void SkPMetric::deleteDiff(int id) { | 478 void SkPMetric::deleteDiff(int id) { |
| 465 // clean up the POI array to save space | 479 // clean up the POI array to save space |
| 466 return fQueuedDiffs[id].poi.reset(); | 480 return fQueuedDiffs[id].poi.reset(); |
| 467 } | 481 } |
| 468 | 482 |
| 469 bool SkPMetric::isFinished(int id) { | 483 bool SkPMetric::isFinished(int id) { |
| 470 return fQueuedDiffs[id].finished; | 484 return fQueuedDiffs[id].finished; |
| 471 } | 485 } |
| 472 | 486 |
| 473 double SkPMetric::getResult(int id) { | 487 double SkPMetric::getResult(int id) { |
| 474 return fQueuedDiffs[id].result; | 488 return fQueuedDiffs[id].result; |
| 475 } | 489 } |
| 476 | 490 |
| 477 int SkPMetric::getPointsOfInterestCount(int id) { | 491 int SkPMetric::getPointsOfInterestCount(int id) { |
| 478 return fQueuedDiffs[id].poi.count(); | 492 return fQueuedDiffs[id].poi.count(); |
| 479 } | 493 } |
| 480 | 494 |
| 481 SkIPoint* SkPMetric::getPointsOfInterest(int id) { | 495 SkIPoint* SkPMetric::getPointsOfInterest(int id) { |
| 482 return fQueuedDiffs[id].poi.begin(); | 496 return fQueuedDiffs[id].poi.begin(); |
| 483 } | 497 } |
| OLD | NEW |