1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.uirendering.cts.bitmapcomparers; 17 18 import android.graphics.Color; 19 import android.util.Log; 20 21 /** 22 * This class contains methods to add the error amongst all pixels in two images while taking into 23 * account the number of pixels that are non-white. Note only use this if the content background is 24 * white. 25 */ 26 public class WeightedPixelDifference extends BitmapComparer { 27 private static final String TAG = "WeightedPixel"; 28 private static final int NUM_OF_COLUMNS = 10; 29 private static final float TOTAL_ERROR_DIVISOR = 1024.0f; 30 31 private float mThreshold; 32 33 public WeightedPixelDifference(float threshold) { 34 mThreshold = threshold; 35 } 36 37 /** 38 * Calculates if pixels in a specific line are the same color 39 * @return true if the pixels are the same color 40 */ 41 private static boolean inspectRegions(int[] ideal, int start, int stride, int regionSize) { 42 int regionColor = ideal[start]; 43 for (int y = 0 ; y < regionSize ; y++) { 44 for (int x = 0 ; x < regionSize ; x++) { 45 int index = indexFromXAndY(x, y, stride, start); 46 if (ideal[index] != regionColor) { 47 return true; 48 } 49 } 50 } 51 return false; 52 } 53 54 /** 55 * Finds the error between each individual channel in the color. 56 */ 57 private static float errorBetweenPixels(int color1, int color2) { 58 float error = 0f; 59 error += Math.abs(Color.red(color1) - Color.red(color2)); 60 error += Math.abs(Color.green(color1) - Color.green(color2)); 61 error += Math.abs(Color.blue(color1) - Color.blue(color2)); 62 error += Math.abs(Color.alpha(color1) - Color.alpha(color2)); 63 return error; 64 } 65 66 /** 67 * Calculates the error between the pixels in the ideal and given 68 * @return true if the accumulated error is smaller than the threshold 69 */ 70 @Override 71 public boolean verifySame(int[] ideal, int[] given, int offset, int stride, int width, 72 int height) { 73 int interestingRegions = 0; 74 int regionSize = width / NUM_OF_COLUMNS; 75 76 for (int y = 0 ; y < height ; y += regionSize) { 77 for (int x = 0 ; x < width ; x += regionSize) { 78 int index = indexFromXAndY(x, y,stride, offset); 79 if (inspectRegions(ideal, index, stride, regionSize)) { 80 interestingRegions++; 81 } 82 } 83 } 84 85 int interestingPixels = Math.max(1, interestingRegions) * regionSize * regionSize; 86 87 float totalError = 0; 88 89 for (int y = 0 ; y < height ; y++) { 90 for (int x = 0 ; x < width ; x++) { 91 int index = indexFromXAndY(x, y, stride, offset); 92 int idealColor = ideal[index]; 93 int givenColor = given[index]; 94 if (idealColor == givenColor) { 95 continue; 96 } 97 totalError += errorBetweenPixels(idealColor, givenColor); 98 } 99 } 100 101 totalError /= TOTAL_ERROR_DIVISOR; 102 totalError /= interestingPixels; 103 104 Log.d(TAG, "Total error : " + totalError); 105 106 return totalError < mThreshold; 107 } 108 } 109