Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Side by Side Diff: experimental/skpdiff/SkPMetric.cpp

Issue 19787006: ports for mac, ios, android, linux, windows (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 SkASSERT(z < slices); 83 SkASSERT(z < slices);
84 return image[z]; 84 return image[z];
85 } 85 }
86 }; 86 };
87 87
88 typedef ImageArray<float> ImageL3D; 88 typedef ImageArray<float> ImageL3D;
89 89
90 90
91 #define MAT_ROW_MULT(rc,gc,bc) r*rc + g*gc + b*bc 91 #define MAT_ROW_MULT(rc,gc,bc) r*rc + g*gc + b*bc
92 92
93 93 static void adobergb_to_cielab(float r, float g, float b, LAB* lab) {
94 void adobergb_to_cielab(float r, float g, float b, LAB* lab) {
95 // Conversion of Adobe RGB to XYZ taken from from "Adobe RGB (1998) ColorIma ge Encoding" 94 // Conversion of Adobe RGB to XYZ taken from from "Adobe RGB (1998) ColorIma ge Encoding"
96 // URL:http://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf 95 // URL:http://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
97 // Section: 4.3.5.3 96 // Section: 4.3.5.3
98 // See Also: http://en.wikipedia.org/wiki/Adobe_rgb 97 // See Also: http://en.wikipedia.org/wiki/Adobe_rgb
99 float x = MAT_ROW_MULT(0.57667f, 0.18556f, 0.18823f); 98 float x = MAT_ROW_MULT(0.57667f, 0.18556f, 0.18823f);
100 float y = MAT_ROW_MULT(0.29734f, 0.62736f, 0.07529f); 99 float y = MAT_ROW_MULT(0.29734f, 0.62736f, 0.07529f);
101 float z = MAT_ROW_MULT(0.02703f, 0.07069f, 0.99134f); 100 float z = MAT_ROW_MULT(0.02703f, 0.07069f, 0.99134f);
102 101
103 // The following is the white point in XYZ, so it's simply the row wise addi tion of the above 102 // The following is the white point in XYZ, so it's simply the row wise addi tion of the above
104 // matrix. 103 // matrix.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 adobergb_to_cielab(rgb.r, rgb.g, rgb.b, &lab); 144 adobergb_to_cielab(rgb.r, rgb.g, rgb.b, &lab);
146 outImageLAB->writePixel(x, y, lab); 145 outImageLAB->writePixel(x, y, lab);
147 } 146 }
148 } 147 }
149 bitmap->unlockPixels(); 148 bitmap->unlockPixels();
150 } 149 }
151 150
152 // From Barten SPIE 1989 151 // From Barten SPIE 1989
153 static float contrast_sensitivity(float cyclesPerDegree, float luminance) { 152 static float contrast_sensitivity(float cyclesPerDegree, float luminance) {
154 float a = 440.0f * powf(1.0f + 0.7f / luminance, -0.2f); 153 float a = 440.0f * powf(1.0f + 0.7f / luminance, -0.2f);
155 float b = 0.3f * powf(1 + 100.0 / luminance, 0.15f); 154 float b = 0.3f * powf(1.0f + 100.0f / luminance, 0.15f);
156 return a * 155 return a *
157 cyclesPerDegree * 156 cyclesPerDegree *
158 expf(-b * cyclesPerDegree) * 157 expf(-b * cyclesPerDegree) *
159 sqrtf(1.0f + 0.06f * expf(b * cyclesPerDegree)); 158 sqrtf(1.0f + 0.06f * expf(b * cyclesPerDegree));
160 } 159 }
161 160
162 #if 0 161 #if 0
163 // We're keeping these around for reference and in case the lookup tables are no longer desired. 162 // We're keeping these around for reference and in case the lookup tables are no longer desired.
164 // They are no longer called by any code in this file. 163 // They are no longer called by any code in this file.
165 164
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 // As we move down, scroll the row pointers down with us 251 // As we move down, scroll the row pointers down with us
253 for (int y = 0; y < matrixCount - 1; y++) 252 for (int y = 0; y < matrixCount - 1; y++)
254 { 253 {
255 rowPtrs[y] = rowPtrs[y + 1]; 254 rowPtrs[y] = rowPtrs[y + 1];
256 } 255 }
257 rowPtrs[matrixCount - 1] += imageL->width; 256 rowPtrs[matrixCount - 1] += imageL->width;
258 writeRow += imageL->width; 257 writeRow += imageL->width;
259 } 258 }
260 } 259 }
261 260
262 float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk IPoint>* poi) { 261 static double pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTD Array<SkIPoint>* poi) {
263 int width = baselineLAB->width; 262 int width = baselineLAB->width;
264 int height = baselineLAB->height; 263 int height = baselineLAB->height;
265 int maxLevels = (int)log2(width < height ? width : height); 264 int maxLevels = 0;
266 265
267 const float fov = M_PI / 180.0f * 45.0f; 266 // 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;
268 for ( ; smallerDimension > 1; smallerDimension /= 2) {
269 maxLevels++;
270 }
271
272 const float fov = SK_ScalarPI / 180.0f * 45.0f;
268 float contrastSensitivityMax = contrast_sensitivity(3.248f, 100.0f); 273 float contrastSensitivityMax = contrast_sensitivity(3.248f, 100.0f);
269 float pixelsPerDegree = width / (2.0f * tanf(fov * 0.5f) * 180.0f / M_PI); 274 float pixelsPerDegree = width / (2.0f * tanf(fov * 0.5f) * 180.0f / SK_Scala rPI);
270 275
271 ImageL3D baselineL(width, height, maxLevels); 276 ImageL3D baselineL(width, height, maxLevels);
272 ImageL3D testL(width, height, maxLevels); 277 ImageL3D testL(width, height, maxLevels);
273 ImageL scratchImageL(width, height); 278 ImageL scratchImageL(width, height);
274 float* cyclesPerDegree = SkNEW_ARRAY(float, maxLevels); 279 float* cyclesPerDegree = SkNEW_ARRAY(float, maxLevels);
275 float* thresholdFactorFrequency = SkNEW_ARRAY(float, maxLevels - 2); 280 float* thresholdFactorFrequency = SkNEW_ARRAY(float, maxLevels - 2);
276 float* contrast = SkNEW_ARRAY(float, maxLevels - 2); 281 float* contrast = SkNEW_ARRAY(float, maxLevels - 2);
277 282
278 lab_to_l(baselineLAB, baselineL.getLayer(0)); 283 lab_to_l(baselineLAB, baselineL.getLayer(0));
279 lab_to_l(testLAB, testL.getLayer(0)); 284 lab_to_l(testLAB, testL.getLayer(0));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 float lTest; 324 float lTest;
320 baselineL.getLayer(0)->readPixel(x, y, &lBaseline); 325 baselineL.getLayer(0)->readPixel(x, y, &lBaseline);
321 testL.getLayer(0)->readPixel(x, y, &lTest); 326 testL.getLayer(0)->readPixel(x, y, &lTest);
322 327
323 float avgLBaseline; 328 float avgLBaseline;
324 float avgLTest; 329 float avgLTest;
325 baselineL.getLayer(maxLevels - 1)->readPixel(x, y, &avgLBaseline); 330 baselineL.getLayer(maxLevels - 1)->readPixel(x, y, &avgLBaseline);
326 testL.getLayer(maxLevels - 1)->readPixel(x, y, &avgLTest); 331 testL.getLayer(maxLevels - 1)->readPixel(x, y, &avgLTest);
327 332
328 float lAdapt = 0.5f * (avgLBaseline + avgLTest); 333 float lAdapt = 0.5f * (avgLBaseline + avgLTest);
329 if (lAdapt < 1e-5) { 334 if (lAdapt < 1e-5f) {
330 lAdapt = 1e-5; 335 lAdapt = 1e-5f;
331 } 336 }
332 337
333 float contrastSum = 0.0f; 338 float contrastSum = 0.0f;
334 for (int levelIndex = 0; levelIndex < maxLevels - 2; levelIndex++) { 339 for (int levelIndex = 0; levelIndex < maxLevels - 2; levelIndex++) {
335 float baselineL0, baselineL1, baselineL2; 340 float baselineL0, baselineL1, baselineL2;
336 float testL0, testL1, testL2; 341 float testL0, testL1, testL2;
337 baselineL.getLayer(levelIndex + 0)->readPixel(x, y, &baselineL0) ; 342 baselineL.getLayer(levelIndex + 0)->readPixel(x, y, &baselineL0) ;
338 testL. getLayer(levelIndex + 0)->readPixel(x, y, &testL0); 343 testL. getLayer(levelIndex + 0)->readPixel(x, y, &testL0);
339 baselineL.getLayer(levelIndex + 1)->readPixel(x, y, &baselineL1) ; 344 baselineL.getLayer(levelIndex + 1)->readPixel(x, y, &baselineL1) ;
340 testL. getLayer(levelIndex + 1)->readPixel(x, y, &testL1); 345 testL. getLayer(levelIndex + 1)->readPixel(x, y, &testL1);
341 baselineL.getLayer(levelIndex + 2)->readPixel(x, y, &baselineL2) ; 346 baselineL.getLayer(levelIndex + 2)->readPixel(x, y, &baselineL2) ;
342 testL. getLayer(levelIndex + 2)->readPixel(x, y, &testL2); 347 testL. getLayer(levelIndex + 2)->readPixel(x, y, &testL2);
343 348
344 float baselineContrast1 = fabsf(baselineL0 - baselineL1); 349 float baselineContrast1 = fabsf(baselineL0 - baselineL1);
345 float testContrast1 = fabsf(testL0 - testL1); 350 float testContrast1 = fabsf(testL0 - testL1);
346 float numerator = (baselineContrast1 > testContrast1) ? 351 float numerator = (baselineContrast1 > testContrast1) ?
347 baselineContrast1 : testContrast1; 352 baselineContrast1 : testContrast1;
348 353
349 float baselineContrast2 = fabsf(baselineL2); 354 float baselineContrast2 = fabsf(baselineL2);
350 float testContrast2 = fabsf(testL2); 355 float testContrast2 = fabsf(testL2);
351 float denominator = (baselineContrast2 > testContrast2) ? 356 float denominator = (baselineContrast2 > testContrast2) ?
352 baselineContrast2 : testContrast2; 357 baselineContrast2 : testContrast2;
353 358
354 // Avoid divides by close to zero 359 // Avoid divides by close to zero
355 if (denominator < 1e-5) { 360 if (denominator < 1e-5f) {
356 denominator = 1e-5; 361 denominator = 1e-5f;
357 } 362 }
358 contrast[levelIndex] = numerator / denominator; 363 contrast[levelIndex] = numerator / denominator;
359 contrastSum += contrast[levelIndex]; 364 contrastSum += contrast[levelIndex];
360 } 365 }
361 366
362 if (contrastSum < 1e-5) { 367 if (contrastSum < 1e-5f) {
363 contrastSum = 1e-5; 368 contrastSum = 1e-5f;
364 } 369 }
365 370
366 float F = 0.0f; 371 float F = 0.0f;
367 for (int levelIndex = 0; levelIndex < maxLevels - 2; levelIndex++) { 372 for (int levelIndex = 0; levelIndex < maxLevels - 2; levelIndex++) {
368 float contrastSensitivity = contrastSensitivityTable[levelIndex * 1000 + 373 float contrastSensitivity = contrastSensitivityTable[levelIndex * 1000 +
369 (int)(lAdap t * 10.0)]; 374 (int)(lAdap t * 10.0)];
370 float mask = SkPMetricUtil::get_visual_mask(contrast[levelIndex] * 375 float mask = SkPMetricUtil::get_visual_mask(contrast[levelIndex] *
371 contrastSensitivity) ; 376 contrastSensitivity) ;
372 377
373 F += contrast[levelIndex] + 378 F += contrast[levelIndex] +
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 return fQueuedDiffs[id].result; 467 return fQueuedDiffs[id].result;
463 } 468 }
464 469
465 int SkPMetric::getPointsOfInterestCount(int id) { 470 int SkPMetric::getPointsOfInterestCount(int id) {
466 return fQueuedDiffs[id].poi.count(); 471 return fQueuedDiffs[id].poi.count();
467 } 472 }
468 473
469 SkIPoint* SkPMetric::getPointsOfInterest(int id) { 474 SkIPoint* SkPMetric::getPointsOfInterest(int id) {
470 return fQueuedDiffs[id].poi.begin(); 475 return fQueuedDiffs[id].poi.begin();
471 } 476 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698