blob: 60f0d80d97447dd458583a67c3bd3502d23138cd [file] [log] [blame]
// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause
#include <vector>
#include "avif/avif.h"
#include "gtest/gtest.h"
#include "testutil.h"
namespace avif {
namespace {
constexpr uint8_t kWidth = 4;
constexpr uint8_t kHeight = 4;
constexpr uint8_t kPlaneSize = 16;
constexpr uint8_t kUOffset = 16;
constexpr uint8_t kVOffset = 32;
constexpr uint8_t kYuv[][kPlaneSize * 4] = {
// White
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
// Red
{0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,
0x4c, 0x4c, 0x4c, 0x4c, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
// Mixed
{0x88, 0x88, 0x88, 0x88, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c,
0x88, 0x88, 0x88, 0x88, 0xa4, 0xa4, 0xa4, 0xa4, 0x72, 0x72, 0x72, 0x72,
0x72, 0x72, 0x72, 0x72, 0xa4, 0xa4, 0xa4, 0xa4, 0x7a, 0x7a, 0x7a, 0x7a,
0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0x7a, 0x7a, 0x7a, 0x7a}};
constexpr uint8_t kRgb[][kWidth * kHeight * 4] = {
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff},
{0x80, 0x80, 0xc8, 0xff, 0x80, 0x80, 0xc8, 0xff, 0x80, 0x80, 0xc8,
0xff, 0x80, 0x80, 0xc8, 0xff, 0xe5, 0x4b, 0x63, 0xff, 0xe5, 0x4b,
0x63, 0xff, 0xe5, 0x4b, 0x63, 0xff, 0xe5, 0x4b, 0x63, 0xff, 0xe5,
0x4b, 0x63, 0xff, 0xe5, 0x4b, 0x63, 0xff, 0xe5, 0x4b, 0x63, 0xff,
0xe5, 0x4b, 0x63, 0xff, 0x80, 0x80, 0xc8, 0xff, 0x80, 0x80, 0xc8,
0xff, 0x80, 0x80, 0xc8, 0xff, 0x80, 0x80, 0xc8, 0xff}};
TEST(ReformatTest, YUVToRGBConversion) {
for (int p = 0; p < 3; ++p) {
ImagePtr image(
avifImageCreate(kWidth, kHeight, 8, AVIF_PIXEL_FORMAT_YUV444));
ASSERT_NE(image, nullptr);
ASSERT_EQ(avifImageAllocatePlanes(image.get(), AVIF_PLANES_YUV),
AVIF_RESULT_OK);
memcpy(image->yuvPlanes[0], kYuv[p], kPlaneSize);
memcpy(image->yuvPlanes[1], kYuv[p] + kUOffset, kPlaneSize);
memcpy(image->yuvPlanes[2], kYuv[p] + kVOffset, kPlaneSize);
avifRGBImage rgb;
avifRGBImageSetDefaults(&rgb, image.get());
std::vector<uint8_t> rgb_pixels(kWidth * kHeight * 4);
rgb.pixels = rgb_pixels.data();
rgb.rowBytes = kWidth * 4;
ASSERT_EQ(avifImageYUVToRGB(image.get(), &rgb), AVIF_RESULT_OK);
for (int i = 0; i < rgb_pixels.size(); ++i) {
EXPECT_EQ(rgb.pixels[i], kRgb[p][i]);
}
avifImageFreePlanes(image.get(), AVIF_PLANES_YUV);
}
}
} // namespace
} // namespace avif
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}