Home | History | Annotate | Download | only in test
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/test/pixel_test_utils.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/base64.h"
     11 #include "base/files/file_util.h"
     12 #include "base/logging.h"
     13 #include "third_party/skia/include/core/SkBitmap.h"
     14 #include "ui/gfx/codec/png_codec.h"
     15 
     16 namespace cc {
     17 
     18 bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path,
     19     bool discard_transparency) {
     20   std::vector<unsigned char> png_data;
     21   if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap,
     22                                         discard_transparency,
     23                                         &png_data) &&
     24       base::CreateDirectory(file_path.DirName())) {
     25     char* data = reinterpret_cast<char*>(&png_data[0]);
     26     int size = static_cast<int>(png_data.size());
     27     return base::WriteFile(file_path, data, size) == size;
     28   }
     29   return false;
     30 }
     31 
     32 std::string GetPNGDataUrl(const SkBitmap& bitmap) {
     33   std::vector<unsigned char> png_data;
     34   gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data);
     35   std::string data_url;
     36   data_url.insert(data_url.end(), png_data.begin(), png_data.end());
     37   base::Base64Encode(data_url, &data_url);
     38   data_url.insert(0, "data:image/png;base64,");
     39 
     40   return data_url;
     41 }
     42 
     43 bool ReadPNGFile(const base::FilePath& file_path, SkBitmap* bitmap) {
     44   DCHECK(bitmap);
     45   std::string png_data;
     46   return base::ReadFileToString(file_path, &png_data) &&
     47          gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]),
     48                                png_data.length(),
     49                                bitmap);
     50 }
     51 
     52 bool MatchesPNGFile(const SkBitmap& gen_bmp, base::FilePath ref_img_path,
     53                     const PixelComparator& comparator) {
     54   SkBitmap ref_bmp;
     55   if (!ReadPNGFile(ref_img_path, &ref_bmp)) {
     56     LOG(ERROR) << "Cannot read reference image: " << ref_img_path.value();
     57     return false;
     58   }
     59 
     60   // Check if images size matches
     61   if (gen_bmp.width() != ref_bmp.width() ||
     62       gen_bmp.height() != ref_bmp.height()) {
     63     LOG(ERROR)
     64         << "Dimensions do not match! "
     65         << "Actual: " << gen_bmp.width() << "x" << gen_bmp.height()
     66         << "; "
     67         << "Expected: " << ref_bmp.width() << "x" << ref_bmp.height();
     68     return false;
     69   }
     70 
     71   // Shortcut for empty images. They are always equal.
     72   if (gen_bmp.width() == 0 || gen_bmp.height() == 0)
     73     return true;
     74 
     75   bool compare = comparator.Compare(gen_bmp, ref_bmp);
     76   if (!compare) {
     77     std::string gen_bmp_data_url = GetPNGDataUrl(gen_bmp);
     78     std::string ref_bmp_data_url = GetPNGDataUrl(ref_bmp);
     79     LOG(ERROR) << "Pixels do not match!";
     80     LOG(ERROR) << "Actual: " << gen_bmp_data_url;
     81     LOG(ERROR) << "Expected: " << ref_bmp_data_url;
     82   }
     83   return compare;
     84 }
     85 
     86 }  // namespace cc
     87