Home | History | Annotate | Download | only in bitmapcomparers
      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