blob: 3a8de93e62c23228fd7611f740379351c2af38b3 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/gpu/test/image.h"
#include <memory>
#include "base/files/file_util.h"
#include "base/hash/md5.h"
#include "base/json/json_reader.h"
#include "base/values.h"
#include "media/base/test_data_util.h"
#define VLOGF(level) VLOG(level) << __func__ << "(): "
namespace media {
namespace test {
namespace {
// Resolve the specified test file path to an absolute path. The path can be
// either an absolute path, a path relative to the current directory, or a path
// relative to the test data path.
void ResolveTestFilePath(base::FilePath* file_path) {
if (!file_path->IsAbsolute()) {
if (!PathExists(*file_path))
*file_path = media::GetTestDataPath().Append(*file_path);
*file_path = base::MakeAbsoluteFilePath(*file_path);
}
}
// Converts the |pixel_format| string into a VideoPixelFormat.
VideoPixelFormat ConvertStringtoPixelFormat(const std::string& pixel_format) {
if (pixel_format == "BGRA") {
return PIXEL_FORMAT_ARGB;
} else if (pixel_format == "I420") {
return PIXEL_FORMAT_I420;
} else if (pixel_format == "NV12") {
return PIXEL_FORMAT_NV12;
} else if (pixel_format == "YV12") {
return PIXEL_FORMAT_YV12;
} else if (pixel_format == "RGBA") {
return PIXEL_FORMAT_ABGR;
} else {
VLOG(2) << pixel_format << " is not supported.";
return PIXEL_FORMAT_UNKNOWN;
}
}
} // namespace
// Suffix to append to the image file path to get the metadata file path.
constexpr const base::FilePath::CharType* kMetadataSuffix =
FILE_PATH_LITERAL(".json");
Image::Image(const base::FilePath& file_path) : file_path_(file_path) {}
Image::~Image() {}
bool Image::Load() {
DCHECK(!file_path_.empty());
DCHECK(!IsLoaded());
ResolveTestFilePath(&file_path_);
if (!mapped_file_.Initialize(file_path_)) {
LOG(ERROR) << "Failed to read file: " << file_path_;
return false;
}
if (!LoadMetadata()) {
LOG(ERROR) << "Failed to load metadata";
return false;
}
// Verify that the image's checksum matches the checksum in the metadata.
base::MD5Digest digest;
base::MD5Sum(mapped_file_.data(), mapped_file_.length(), &digest);
if (base::MD5DigestToBase16(digest) != checksum_) {
LOG(ERROR) << "Image checksum not matching metadata";
return false;
}
return true;
}
bool Image::IsLoaded() const {
return mapped_file_.IsValid();
}
bool Image::LoadMetadata() {
if (IsMetadataLoaded()) {
return true;
}
base::FilePath json_path = file_path_.AddExtension(kMetadataSuffix);
ResolveTestFilePath(&json_path);
if (!base::PathExists(json_path)) {
VLOGF(1) << "Image metadata file not found: " << json_path.BaseName();
return false;
}
std::string json_data;
if (!base::ReadFileToString(json_path, &json_data)) {
VLOGF(1) << "Failed to read image metadata file: " << json_path;
return false;
}
base::JSONReader reader;
std::unique_ptr<base::Value> metadata(
reader.ReadToValueDeprecated(json_data));
if (!metadata) {
VLOGF(1) << "Failed to parse image metadata: " << json_path << ": "
<< reader.GetErrorMessage();
return false;
}
// Get the pixel format from the json data.
const base::Value* pixel_format =
metadata->FindKeyOfType("pixel_format", base::Value::Type::STRING);
if (!pixel_format) {
VLOGF(1) << "Key \"pixel_format\" is not found in " << json_path;
return false;
}
pixel_format_ = ConvertStringtoPixelFormat(pixel_format->GetString());
if (pixel_format_ == PIXEL_FORMAT_UNKNOWN) {
VLOGF(1) << pixel_format->GetString() << " is not supported";
return false;
}
// Get the image dimensions from the json data.
const base::Value* width =
metadata->FindKeyOfType("width", base::Value::Type::INTEGER);
if (!width) {
VLOGF(1) << "Key \"width\" is not found in " << json_path;
return false;
}
const base::Value* height =
metadata->FindKeyOfType("height", base::Value::Type::INTEGER);
if (!height) {
VLOGF(1) << "Key \"height\" is not found in " << json_path;
return false;
}
size_ = gfx::Size(width->GetInt(), height->GetInt());
// Get the image checksum from the json data.
const base::Value* checksum =
metadata->FindKeyOfType("checksum", base::Value::Type::STRING);
if (!checksum) {
VLOGF(1) << "Key \"checksum\" is not found in " << json_path;
return false;
}
checksum_ = checksum->GetString();
return true;
}
bool Image::IsMetadataLoaded() const {
return pixel_format_ != PIXEL_FORMAT_UNKNOWN;
}
uint8_t* Image::Data() const {
return mapped_file_.data();
}
size_t Image::DataSize() const {
return mapped_file_.length();
}
VideoPixelFormat Image::PixelFormat() const {
return pixel_format_;
}
const gfx::Size& Image::Size() const {
return size_;
}
const char* Image::Checksum() const {
return checksum_.data();
}
} // namespace test
} // namespace media