| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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 } | 
| OLD | NEW | 
|---|