Chromium Code Reviews| 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 | 6 |
| 7 struct RGB { | 7 struct RGB { |
| 8 float r, g, b; | 8 float r, g, b; |
| 9 }; | 9 }; |
| 10 | 10 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 } | 31 } |
| 32 | 32 |
| 33 void readPixel(int x, int y, T* pixel) const { | 33 void readPixel(int x, int y, T* pixel) const { |
| 34 SkASSERT(x >= 0); | 34 SkASSERT(x >= 0); |
| 35 SkASSERT(y >= 0); | 35 SkASSERT(y >= 0); |
| 36 SkASSERT(x < width); | 36 SkASSERT(x < width); |
| 37 SkASSERT(y < height); | 37 SkASSERT(y < height); |
| 38 *pixel = image[y * width + x]; | 38 *pixel = image[y * width + x]; |
| 39 } | 39 } |
| 40 | 40 |
| 41 T* getRow(int y) const { | |
| 42 return &image[y * width]; | |
| 43 } | |
| 44 | |
| 41 void writePixel(int x, int y, const T& pixel) { | 45 void writePixel(int x, int y, const T& pixel) { |
| 42 SkASSERT(x >= 0); | 46 SkASSERT(x >= 0); |
| 43 SkASSERT(y >= 0); | 47 SkASSERT(y >= 0); |
| 44 SkASSERT(x < width); | 48 SkASSERT(x < width); |
| 45 SkASSERT(y < height); | 49 SkASSERT(y < height); |
| 46 image[y * width + x] = pixel; | 50 image[y * width + x] = pixel; |
| 47 } | 51 } |
| 48 }; | 52 }; |
| 49 | 53 |
| 50 typedef Image2D<float> ImageL; | 54 typedef Image2D<float> ImageL; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 for (int y = 0; y < imageLAB->height; y++) { | 188 for (int y = 0; y < imageLAB->height; y++) { |
| 185 for (int x = 0; x < imageLAB->width; x++) { | 189 for (int x = 0; x < imageLAB->width; x++) { |
| 186 LAB lab; | 190 LAB lab; |
| 187 imageLAB->readPixel(x, y, &lab); | 191 imageLAB->readPixel(x, y, &lab); |
| 188 outImageL->writePixel(x, y, lab.l); | 192 outImageL->writePixel(x, y, lab.l); |
| 189 } | 193 } |
| 190 } | 194 } |
| 191 } | 195 } |
| 192 | 196 |
| 193 /// Convolves an image with the given filter in one direction and saves it to th e output image | 197 /// Convolves an image with the given filter in one direction and saves it to th e output image |
| 194 static void convolve(const ImageL* imageL, | 198 static void convolve(const ImageL* imageL, bool vertical, ImageL* outImageL) { |
| 195 bool vertical, const float* matrix, int radius, | |
| 196 ImageL* outImageL) { | |
| 197 SkASSERT(imageL->width == outImageL->width); | 199 SkASSERT(imageL->width == outImageL->width); |
| 198 SkASSERT(imageL->height == outImageL->height); | 200 SkASSERT(imageL->height == outImageL->height); |
| 201 | |
| 202 const float matrix[] = { 0.05f, 0.25f, 0.4f, 0.25f, 0.05f }; | |
| 203 const int matrixCount = sizeof(matrix) / sizeof(float); | |
|
tfarina
2013/07/16 13:07:26
SK_ARRAY_COUNT?
| |
| 204 const int radius = matrixCount / 2; | |
| 205 | |
| 206 // Keep track of what rows are being operated on for quick access. | |
| 207 float* rowPtrs[matrixCount]; // Because matrixCount is constant, this won't create a VLA | |
| 208 for (int y = radius; y < matrixCount; y++) { | |
| 209 rowPtrs[y] = imageL->getRow(y - radius); | |
| 210 } | |
| 211 float* writeRow = outImageL->getRow(0); | |
| 212 | |
| 213 | |
| 199 for (int y = 0; y < imageL->height; y++) { | 214 for (int y = 0; y < imageL->height; y++) { |
| 200 for (int x = 0; x < imageL->width; x++) { | 215 for (int x = 0; x < imageL->width; x++) { |
| 201 float lSum = 0.0f; | 216 float lSum = 0.0f; |
| 202 float l; | |
| 203 for (int xx = -radius; xx <= radius; xx++) { | 217 for (int xx = -radius; xx <= radius; xx++) { |
| 204 int nx = x; | 218 int nx = x; |
| 205 int ny = y; | 219 int ny = y; |
| 206 | 220 |
| 207 // We mirror at edges so that edge pixels that the filter weight ing still makes | 221 // We mirror at edges so that edge pixels that the filter weight ing still makes |
| 208 // sense. | 222 // sense. |
| 209 if (vertical) { | 223 if (vertical) { |
| 210 ny += xx; | 224 ny += xx; |
| 211 if (ny < 0) { | 225 if (ny < 0) { |
| 212 ny = -ny; | 226 ny = -ny; |
| 213 } | 227 } |
| 214 if (ny >= imageL->height) { | 228 if (ny >= imageL->height) { |
| 215 ny = imageL->height + (imageL->height - ny - 1); | 229 ny = imageL->height + (imageL->height - ny - 1); |
| 216 } | 230 } |
| 217 } else { | 231 } else { |
| 218 nx += xx; | 232 nx += xx; |
| 219 if (nx < 0) { | 233 if (nx < 0) { |
| 220 nx = -nx; | 234 nx = -nx; |
| 221 } | 235 } |
| 222 if (nx >= imageL->width) { | 236 if (nx >= imageL->width) { |
| 223 nx = imageL->width + (imageL->width - nx - 1); | 237 nx = imageL->width + (imageL->width - nx - 1); |
| 224 } | 238 } |
| 225 } | 239 } |
| 226 | 240 |
| 227 imageL->readPixel(nx, ny, &l); | |
| 228 float weight = matrix[xx + radius]; | 241 float weight = matrix[xx + radius]; |
| 229 lSum += l * weight; | 242 lSum += rowPtrs[ny - y + radius][nx] * weight; |
| 230 } | 243 } |
| 231 outImageL->writePixel(x, y, lSum); | 244 writeRow[x] = lSum; |
| 232 } | 245 } |
| 246 // As we move down, scroll the row pointers down with us | |
| 247 for (int y = 0; y < matrixCount - 1; y++) | |
| 248 { | |
| 249 rowPtrs[y] = rowPtrs[y + 1]; | |
| 250 } | |
| 251 rowPtrs[matrixCount - 1] += imageL->width; | |
| 252 writeRow += imageL->width; | |
| 233 } | 253 } |
| 234 } | 254 } |
| 235 | 255 |
| 236 float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk IPoint>* poi) { | 256 float pmetric(const ImageLAB* baselineLAB, const ImageLAB* testLAB, SkTDArray<Sk IPoint>* poi) { |
| 237 int width = baselineLAB->width; | 257 int width = baselineLAB->width; |
| 238 int height = baselineLAB->height; | 258 int height = baselineLAB->height; |
| 239 int maxLevels = (int)log2(width < height ? width : height); | 259 int maxLevels = (int)log2(width < height ? width : height); |
| 240 | 260 |
| 241 const float fov = M_PI / 180.0f * 45.0f; | 261 const float fov = M_PI / 180.0f * 45.0f; |
| 242 float contrastSensitivityMax = contrast_sensitivity(3.248f, 100.0f); | 262 float contrastSensitivityMax = contrast_sensitivity(3.248f, 100.0f); |
| 243 float pixelsPerDegree = width / (2.0f * tanf(fov * 0.5f) * 180.0f / M_PI); | 263 float pixelsPerDegree = width / (2.0f * tanf(fov * 0.5f) * 180.0f / M_PI); |
| 244 | 264 |
| 245 ImageL3D baselineL(width, height, maxLevels); | 265 ImageL3D baselineL(width, height, maxLevels); |
| 246 ImageL3D testL(width, height, maxLevels); | 266 ImageL3D testL(width, height, maxLevels); |
| 247 ImageL scratchImageL(width, height); | 267 ImageL scratchImageL(width, height); |
| 248 float* cyclesPerDegree = SkNEW_ARRAY(float, maxLevels); | 268 float* cyclesPerDegree = SkNEW_ARRAY(float, maxLevels); |
| 249 float* thresholdFactorFrequency = SkNEW_ARRAY(float, maxLevels - 2); | 269 float* thresholdFactorFrequency = SkNEW_ARRAY(float, maxLevels - 2); |
| 250 float* contrast = SkNEW_ARRAY(float, maxLevels - 2); | 270 float* contrast = SkNEW_ARRAY(float, maxLevels - 2); |
| 251 | 271 |
| 252 lab_to_l(baselineLAB, baselineL.getLayer(0)); | 272 lab_to_l(baselineLAB, baselineL.getLayer(0)); |
| 253 lab_to_l(testLAB, testL.getLayer(0)); | 273 lab_to_l(testLAB, testL.getLayer(0)); |
| 254 | 274 |
| 255 // Compute cpd - Cycles per degree on the pyramid | 275 // Compute cpd - Cycles per degree on the pyramid |
| 256 cyclesPerDegree[0] = 0.5f * pixelsPerDegree; | 276 cyclesPerDegree[0] = 0.5f * pixelsPerDegree; |
| 257 for (int levelIndex = 1; levelIndex < maxLevels; levelIndex++) { | 277 for (int levelIndex = 1; levelIndex < maxLevels; levelIndex++) { |
| 258 cyclesPerDegree[levelIndex] = cyclesPerDegree[levelIndex - 1] * 0.5f; | 278 cyclesPerDegree[levelIndex] = cyclesPerDegree[levelIndex - 1] * 0.5f; |
| 259 } | 279 } |
| 260 | 280 |
| 261 const float filterMatrix[] = { 0.05f, 0.25f, 0.4f, 0.25f, 0.05f }; | |
| 262 // Compute G - The convolved lum for the baseline | 281 // Compute G - The convolved lum for the baseline |
| 263 for (int levelIndex = 1; levelIndex < maxLevels; levelIndex++) { | 282 for (int levelIndex = 1; levelIndex < maxLevels; levelIndex++) { |
| 264 convolve(baselineL.getLayer(levelIndex - 1), false, filterMatrix, 2, &sc ratchImageL); | 283 convolve(baselineL.getLayer(levelIndex - 1), false, &scratchImageL); |
| 265 convolve(&scratchImageL, true, filterMatrix, 2, baselineL.getLayer(level Index)); | 284 convolve(&scratchImageL, true, baselineL.getLayer(levelIndex)); |
| 266 } | 285 } |
| 267 for (int levelIndex = 1; levelIndex < maxLevels; levelIndex++) { | 286 for (int levelIndex = 1; levelIndex < maxLevels; levelIndex++) { |
| 268 convolve(testL.getLayer(levelIndex - 1), false, filterMatrix, 2, &scratc hImageL); | 287 convolve(testL.getLayer(levelIndex - 1), false, &scratchImageL); |
| 269 convolve(&scratchImageL, true, filterMatrix, 2, testL.getLayer(levelInde x)); | 288 convolve(&scratchImageL, true, testL.getLayer(levelIndex)); |
| 270 } | 289 } |
| 271 | 290 |
| 272 // Compute F_freq - The elevation f | 291 // Compute F_freq - The elevation f |
| 273 for (int levelIndex = 0; levelIndex < maxLevels - 2; levelIndex++) { | 292 for (int levelIndex = 0; levelIndex < maxLevels - 2; levelIndex++) { |
| 274 float cpd = cyclesPerDegree[levelIndex]; | 293 float cpd = cyclesPerDegree[levelIndex]; |
| 275 thresholdFactorFrequency[levelIndex] = contrastSensitivityMax / | 294 thresholdFactorFrequency[levelIndex] = contrastSensitivityMax / |
| 276 contrast_sensitivity(cpd, 100.0f) ; | 295 contrast_sensitivity(cpd, 100.0f) ; |
| 277 } | 296 } |
| 278 | 297 |
| 279 int failures = 0; | 298 int failures = 0; |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 return fQueuedDiffs[id].result; | 444 return fQueuedDiffs[id].result; |
| 426 } | 445 } |
| 427 | 446 |
| 428 int SkPMetric::getPointsOfInterestCount(int id) { | 447 int SkPMetric::getPointsOfInterestCount(int id) { |
| 429 return fQueuedDiffs[id].poi.count(); | 448 return fQueuedDiffs[id].poi.count(); |
| 430 } | 449 } |
| 431 | 450 |
| 432 SkIPoint* SkPMetric::getPointsOfInterest(int id) { | 451 SkIPoint* SkPMetric::getPointsOfInterest(int id) { |
| 433 return fQueuedDiffs[id].poi.begin(); | 452 return fQueuedDiffs[id].poi.begin(); |
| 434 } | 453 } |
| OLD | NEW |