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

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

Issue 19107002: improve convolve speed of skpdiff using direct pointers (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
« no previous file with comments | « no previous file | experimental/skpdiff/skpdiff.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | experimental/skpdiff/skpdiff.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698