| // 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(); |
| } |