/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cobalt/loader/image/image_decoder.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/render_tree/resource_provider_stub.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace loader {
namespace image {

namespace {

struct MockImageDecoderCallback {
  void SuccessCallback(const scoped_refptr<render_tree::Image>& value) {
    image = value;
  }

  MOCK_METHOD1(FailureCallback, void(const std::string& message));
  MOCK_METHOD1(ErrorCallback, void(const std::string& message));

  scoped_refptr<render_tree::Image> image;
};

class MockImageDecoder : public Decoder {
 public:
  MockImageDecoder();
  ~MockImageDecoder() OVERRIDE {}

  LoadResponseType OnResponseStarted(
      Fetcher* fetcher,
      const scoped_refptr<net::HttpResponseHeaders>& headers) OVERRIDE;

  void DecodeChunk(const char* data, size_t size) OVERRIDE;

  void Finish() OVERRIDE;

  scoped_refptr<render_tree::Image> Image();

  void ExpectCallWithFailure(const std::string& message);
  void ExpectCallWithError(const std::string& message);

 protected:
  ::testing::StrictMock<MockImageDecoderCallback> image_decoder_callback_;
  render_tree::ResourceProviderStub resource_provider_;
  scoped_ptr<Decoder> image_decoder_;
};

MockImageDecoder::MockImageDecoder() {
  image_decoder_.reset(
      new ImageDecoder(&resource_provider_,
                       base::Bind(&MockImageDecoderCallback::SuccessCallback,
                                  base::Unretained(&image_decoder_callback_)),
                       base::Bind(&MockImageDecoderCallback::FailureCallback,
                                  base::Unretained(&image_decoder_callback_)),
                       base::Bind(&MockImageDecoderCallback::ErrorCallback,
                                  base::Unretained(&image_decoder_callback_))));
}

LoadResponseType MockImageDecoder::OnResponseStarted(
    Fetcher* fetcher, const scoped_refptr<net::HttpResponseHeaders>& headers) {
  return image_decoder_->OnResponseStarted(fetcher, headers);
}

void MockImageDecoder::DecodeChunk(const char* data, size_t size) {
  image_decoder_->DecodeChunk(data, size);
}

void MockImageDecoder::Finish() { image_decoder_->Finish(); }

scoped_refptr<render_tree::Image> MockImageDecoder::Image() {
  return image_decoder_callback_.image;
}

void MockImageDecoder::ExpectCallWithFailure(const std::string& message) {
  EXPECT_CALL(image_decoder_callback_, FailureCallback(message));
}

void MockImageDecoder::ExpectCallWithError(const std::string& message) {
  EXPECT_CALL(image_decoder_callback_, ErrorCallback(message));
}

FilePath GetTestImagePath(const char* file_name) {
  FilePath data_directory;
  CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &data_directory));
  return data_directory.Append(FILE_PATH_LITERAL("cobalt"))
      .Append(FILE_PATH_LITERAL("loader"))
      .Append(FILE_PATH_LITERAL("testdata"))
      .Append(FILE_PATH_LITERAL(file_name));
}

std::vector<uint8> GetImageData(const FilePath& file_path) {
  int64 size;
  std::vector<uint8> image_data;

  bool success = file_util::GetFileSize(file_path, &size);

  CHECK(success) << "Could not get file size.";
  CHECK_GT(size, 0);

  image_data.resize(static_cast<size_t>(size));

  int num_of_bytes =
      file_util::ReadFile(file_path, reinterpret_cast<char*>(&image_data[0]),
                          static_cast<int>(size));

  CHECK_EQ(num_of_bytes, image_data.size()) << "Could not read '"
                                            << file_path.value() << "'.";
  return image_data;
}

// Check if pixels are the same as |test_color|.
bool CheckSameColor(const uint8* pixels, int width, int height,
                    uint32 test_color) {
  // Iterate through each pixel testing that the value is the expected value.
  for (int index = 0; index < width * height; ++index) {
    uint32 current_color = static_cast<uint32>(
        (pixels[0] << 24) | (pixels[1] << 16) | (pixels[2] << 8) | pixels[3]);
    pixels += 4;
    if (current_color != test_color) {
      return false;
    }
  }
  return true;
}

}  // namespace

// TODO: Test special images like the image has gAMA chunk information,
// pngs with 16 bit depth, and large pngs.

TEST(ImageDecoderTest, DecodeImageWithContentLength0) {
  MockImageDecoder image_decoder;
  image_decoder.ExpectCallWithFailure(
      "No content returned, but expected some.");

  const char kImageWithContentLength0Headers[] = {
      "HTTP/1.1 200 OK\0"
      "Content-Length: 0\0"
      "Content-Type: image/jpeg\0"
      "Expires: Wed, 20 Apr 2016 19:33:44 GMT\0"
      "Date: Wed, 20 Apr 2016 18:33:44 GMT\0"
      "Server: UploadServer\0"
      "Accept-Ranges: bytes\0"
      "Cache-Control: public, max-age=3600\0"};
  scoped_refptr<net::HttpResponseHeaders> headers(new net::HttpResponseHeaders(
      std::string(kImageWithContentLength0Headers,
                  kImageWithContentLength0Headers +
                      sizeof(kImageWithContentLength0Headers))));
  image_decoder.OnResponseStarted(NULL, headers);
  image_decoder.Finish();

  EXPECT_FALSE(image_decoder.Image());
}

TEST(ImageDecoderTest, DecodeNonImageTypeWithContentLength0) {
  MockImageDecoder image_decoder;
  image_decoder.ExpectCallWithFailure(
      "No content returned, but expected some. Not an image mime type.");

  const char kHTMLWithContentLength0Headers[] = {
      "HTTP/1.1 200 OK\0"
      "Content-Length: 0\0"
      "Content-Type: text/html\0"
      "Expires: Wed, 20 Apr 2016 19:33:44 GMT\0"
      "Date: Wed, 20 Apr 2016 18:33:44 GMT\0"
      "Server: UploadServer\0"
      "Accept-Ranges: bytes\0"
      "Cache-Control: public, max-age=3600\0"};
  scoped_refptr<net::HttpResponseHeaders> headers(new net::HttpResponseHeaders(
      std::string(kHTMLWithContentLength0Headers,
                  kHTMLWithContentLength0Headers +
                      sizeof(kHTMLWithContentLength0Headers))));
  image_decoder.OnResponseStarted(NULL, headers);
  image_decoder.Finish();

  EXPECT_FALSE(image_decoder.Image());
}

TEST(ImageDecoderTest, DecodeNonImageType) {
  MockImageDecoder image_decoder;
  image_decoder.ExpectCallWithFailure("Not an image mime type.");

  const char kHTMLHeaders[] = {
      "HTTP/1.1 200 OK\0"
      "Content-Type: text/html; charset=UTF-8\0"
      "Expires: Wed, 20 Apr 2016 19:33:44 GMT\0"
      "Date: Wed, 20 Apr 2016 18:33:44 GMT\0"
      "Server: gws\0"
      "Accept-Ranges: none\0"
      "Cache-Control: private, max-age=0\0"};
  scoped_refptr<net::HttpResponseHeaders> headers(new net::HttpResponseHeaders(
      std::string(kHTMLHeaders, kHTMLHeaders + sizeof(kHTMLHeaders))));

  const char kContent[] = {
      "<!DOCTYPE html><html><head></head><body></body></html>"};

  image_decoder.OnResponseStarted(NULL, headers);
  image_decoder.DecodeChunk(kContent, sizeof(kContent));
  image_decoder.Finish();

  EXPECT_FALSE(image_decoder.Image());
}

TEST(ImageDecoderTest, DecodeNoContentType) {
  MockImageDecoder image_decoder;
  image_decoder.ExpectCallWithFailure("Not an image mime type.");

  const char kHTMLHeaders[] = {
      "HTTP/1.1 200 OK\0"
      "Expires: Wed, 20 Apr 2016 19:33:44 GMT\0"
      "Date: Wed, 20 Apr 2016 18:33:44 GMT\0"
      "Server: gws\0"
      "Accept-Ranges: none\0"
      "Cache-Control: private, max-age=0\0"};
  scoped_refptr<net::HttpResponseHeaders> headers(new net::HttpResponseHeaders(
      std::string(kHTMLHeaders, kHTMLHeaders + sizeof(kHTMLHeaders))));

  const char kContent[] = {
      "<!DOCTYPE html><html><head></head><body></body></html>"};

  image_decoder.OnResponseStarted(NULL, headers);
  image_decoder.DecodeChunk(kContent, sizeof(kContent));
  image_decoder.Finish();

  EXPECT_FALSE(image_decoder.Image());
}

TEST(ImageDecoderTest, DecodeImageWithNoContent) {
  MockImageDecoder image_decoder;
  image_decoder.ExpectCallWithFailure(
      "No content returned. Not an image mime type.");

  const char kHTMLWithNoContentHeaders[] = {
      "HTTP/1.1 204 No Content\0"
      "Expires: Tue, 27 Apr 1971 19:44:06 EST\0"
      "Content-Length: 0\0"
      "Content-Type: text/html; charset=utf-8\0"
      "Date: Wed, 20 Apr 2016 18:33:44 GMT\0"
      "Server: Ytfe_Worker\0"
      "Accept-Ranges: bytes\0"
      "Cache-Control: no-cache\0"};
  scoped_refptr<net::HttpResponseHeaders> headers(
      new net::HttpResponseHeaders(std::string(
          kHTMLWithNoContentHeaders,
          kHTMLWithNoContentHeaders + sizeof(kHTMLWithNoContentHeaders))));
  image_decoder.OnResponseStarted(NULL, headers);
  image_decoder.Finish();

  EXPECT_FALSE(image_decoder.Image());
}

TEST(ImageDecoderTest, DecodeImageWithLessThanHeaderBytes) {
  MockImageDecoder image_decoder;
  image_decoder.ExpectCallWithError("No enough image data for header.");

  const char kPartialWebPHeader[] = {"RIFF"};
  image_decoder.DecodeChunk(kPartialWebPHeader, sizeof(kPartialWebPHeader));
  image_decoder.Finish();

  EXPECT_FALSE(image_decoder.Image());
}

TEST(ImageDecoderTest, FailedToDecodeImage) {
  MockImageDecoder image_decoder;
  image_decoder.ExpectCallWithError("PNGImageDecoder failed to decode image.");

  const char kPartialPNGImage[] = {
      "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52\x00\x00"
      "\x02\x6C\x00\x00\x01\x2C"};
  image_decoder.DecodeChunk(kPartialPNGImage, sizeof(kPartialPNGImage));
  image_decoder.Finish();

  EXPECT_FALSE(image_decoder.Image());
}

TEST(ImageDecoderTest, UnsupportedImageFormat) {
  MockImageDecoder image_decoder;
  image_decoder.ExpectCallWithError("Unsupported image format.");

  const char kPartialICOImage[] = {
      "\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00"};
  image_decoder.DecodeChunk(kPartialICOImage, sizeof(kPartialICOImage));
  image_decoder.Finish();

  EXPECT_FALSE(image_decoder.Image());
}

// Test that we can properly decode the PNG image.
TEST(ImageDecoderTest, DecodePNGImage) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("non_interlaced_png.png"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]),
                            image_data.size());
  image_decoder.Finish();

  // All pixels in the PNG image should have premultiplied alpha RGBA
  // values of (127, 0, 0, 127).
  uint8 r = 127;
  uint8 g = 0;
  uint8 b = 0;
  uint8 a = 127;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

// Test that we can properly decode the PNG image with multiple chunks.
TEST(ImageDecoderTest, DecodePNGImageWithMultipleChunks) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("non_interlaced_png.png"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]), 4);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[4]), 2);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[6]), 94);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[100]), 100);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[200]),
                            image_data.size() - 200);
  image_decoder.Finish();

  // All pixels in the PNG image should have premultiplied alpha RGBA
  // values of (127, 0, 0, 127).
  uint8 r = 127;
  uint8 g = 0;
  uint8 b = 0;
  uint8 a = 127;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

// Test that we can properly decode the the interlaced PNG.
TEST(ImageDecoderTest, DecodeInterlacedPNGImage) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("interlaced_png.png"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]),
                            image_data.size());
  image_decoder.Finish();

  // All pixels in the PNG image should have premultiplied alpha RGBA
  // values of (128, 88, 0, 255).
  uint8 r = 128;
  uint8 g = 88;
  uint8 b = 0;
  uint8 a = 255;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

// Test that we can properly decode the interlaced PNG with multiple chunks.
TEST(ImageDecoderTest, DecodeInterlacedPNGImageWithMultipleChunks) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("interlaced_png.png"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]), 4);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[4]), 2);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[6]), 94);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[100]), 100);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[200]),
                            image_data.size() - 200);
  image_decoder.Finish();

  // All pixels in the PNG image should have premultiplied alpha RGBA
  // values of (128, 88, 0, 255).
  uint8 r = 128;
  uint8 g = 88;
  uint8 b = 0;
  uint8 a = 255;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

// Test that we can properly decode the JPEG image.
TEST(ImageDecoderTest, DecodeJPEGImage) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("baseline_jpeg.jpg"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]),
                            image_data.size());
  image_decoder.Finish();

  // All pixels in the JPEG image should have RGBA values of (128, 88, 0, 255).
  uint8 r = 128;
  uint8 g = 88;
  uint8 b = 0;
  uint8 a = 255;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

// Test that we can properly decode the JPEG image with multiple chunks.
TEST(ImageDecoderTest, DecodeJPEGImageWithMultipleChunks) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("baseline_jpeg.jpg"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]), 2);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[2]), 4);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[6]), 94);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[100]), 200);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[300]),
                            image_data.size() - 300);
  image_decoder.Finish();

  // All pixels in the JPEG image should have RGBA values of (128, 88, 0, 255).
  uint8 r = 128;
  uint8 g = 88;
  uint8 b = 0;
  uint8 a = 255;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

// Test that we can properly decode the progressive JPEG image.
TEST(ImageDecoderTest, DecodeProgressiveJPEGImage) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("progressive_jpeg.jpg"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]),
                            image_data.size());
  image_decoder.Finish();

  // All pixels in the JPEG image should have RGBA values of (64, 32, 17, 255).
  uint8 r = 64;
  uint8 g = 32;
  uint8 b = 17;
  uint8 a = 255;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

// Test that we can properly decode the progressive JPEG with multiple chunks.
TEST(ImageDecoderTest, DecodeProgressiveJPEGImageWithMultipleChunks) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("progressive_jpeg.jpg"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]), 2);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[2]), 4);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[6]), 94);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[100]), 200);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[300]),
                            image_data.size() - 300);
  image_decoder.Finish();

  // All pixels in the JPEG image should have RGBA values of (64, 32, 17, 255).
  uint8 r = 64;
  uint8 g = 32;
  uint8 b = 17;
  uint8 a = 255;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

// Test that we can properly decode the WEBP image.
TEST(ImageDecoderTest, DecodeWEBPImage) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("webp_image.webp"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]),
                            image_data.size());
  image_decoder.Finish();

  // All pixels in the WEBP image should have RGBA values of (16, 8, 70, 70).
  uint8 r = 16;
  uint8 g = 8;
  uint8 b = 70;
  uint8 a = 70;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

// Test that we can properly decode the WEBP image with multiple chunks.
TEST(ImageDecoderTest, DecodeWEBPImageWithMultipleChunks) {
  MockImageDecoder image_decoder;

  std::vector<uint8> image_data =
      GetImageData(GetTestImagePath("webp_image.webp"));
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[0]), 2);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[2]), 4);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[6]), 94);
  image_decoder.DecodeChunk(reinterpret_cast<char*>(&image_data[100]),
                            image_data.size() - 100);
  image_decoder.Finish();

  // All pixels in the WEBP image should have RGBA values of (16, 8, 70, 70).
  uint8 r = 16;
  uint8 g = 8;
  uint8 b = 70;
  uint8 a = 70;
  uint32 expected_color =
      static_cast<uint32>((r << 24) | (g << 16) | (b << 8) | a);

  ASSERT_TRUE(image_decoder.Image());
  render_tree::ImageStub* data =
      base::polymorphic_downcast<render_tree::ImageStub*>(
          image_decoder.Image().get());

  math::Size size = data->GetSize();
  uint8* pixels = data->GetImageData()->GetMemory();

  EXPECT_TRUE(
      CheckSameColor(pixels, size.width(), size.height(), expected_color));
}

}  // namespace image
}  // namespace loader
}  // namespace cobalt
