xref: /aosp_15_r20/external/libultrahdr/tests/jpegencoderhelper_test.cpp (revision 89a0ef05262152531a00a15832a2d3b1e3990773)
1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 
19 #include <fstream>
20 #include <iostream>
21 
22 #include "ultrahdr/ultrahdrcommon.h"
23 #include "ultrahdr/jpegencoderhelper.h"
24 
25 namespace ultrahdr {
26 
27 #ifdef __ANDROID__
28 #define ALIGNED_IMAGE "/data/local/tmp/minnie-320x240.yu12"
29 #define SINGLE_CHANNEL_IMAGE "/data/local/tmp/minnie-320x240.y"
30 #define UNALIGNED_IMAGE "/data/local/tmp/minnie-318x240.yu12"
31 #define RGB_IMAGE "/data/local/tmp/minnie-320x240.rgb"
32 #else
33 #define ALIGNED_IMAGE "./data/minnie-320x240.yu12"
34 #define SINGLE_CHANNEL_IMAGE "./data/minnie-320x240.y"
35 #define UNALIGNED_IMAGE "./data/minnie-318x240.yu12"
36 #define RGB_IMAGE "./data/minnie-320x240.rgb"
37 #endif
38 #define ALIGNED_IMAGE_WIDTH 320
39 #define ALIGNED_IMAGE_HEIGHT 240
40 #define SINGLE_CHANNEL_IMAGE_WIDTH ALIGNED_IMAGE_WIDTH
41 #define SINGLE_CHANNEL_IMAGE_HEIGHT ALIGNED_IMAGE_HEIGHT
42 #define UNALIGNED_IMAGE_WIDTH 318
43 #define UNALIGNED_IMAGE_HEIGHT 240
44 #define JPEG_QUALITY 90
45 
46 class JpegEncoderHelperTest : public testing::Test {
47  public:
48   struct Image {
49     std::unique_ptr<uint8_t[]> buffer;
50     unsigned int width;
51     unsigned int height;
52   };
53   JpegEncoderHelperTest();
54   ~JpegEncoderHelperTest();
55 
56  protected:
57   virtual void SetUp();
58   virtual void TearDown();
59 
60   Image mAlignedImage, mUnalignedImage, mSingleChannelImage, mRgbImage;
61 };
62 
JpegEncoderHelperTest()63 JpegEncoderHelperTest::JpegEncoderHelperTest() {}
64 
~JpegEncoderHelperTest()65 JpegEncoderHelperTest::~JpegEncoderHelperTest() {}
66 
loadFile(const char filename[],JpegEncoderHelperTest::Image * result)67 static bool loadFile(const char filename[], JpegEncoderHelperTest::Image* result) {
68   std::ifstream ifd(filename, std::ios::binary | std::ios::ate);
69   if (ifd.good()) {
70     int size = ifd.tellg();
71     ifd.seekg(0, std::ios::beg);
72     result->buffer.reset(new uint8_t[size]);
73     ifd.read(reinterpret_cast<char*>(result->buffer.get()), size);
74     ifd.close();
75     return true;
76   }
77   return false;
78 }
79 
SetUp()80 void JpegEncoderHelperTest::SetUp() {
81   if (!loadFile(ALIGNED_IMAGE, &mAlignedImage)) {
82     FAIL() << "Load file " << ALIGNED_IMAGE << " failed";
83   }
84   mAlignedImage.width = ALIGNED_IMAGE_WIDTH;
85   mAlignedImage.height = ALIGNED_IMAGE_HEIGHT;
86   if (!loadFile(UNALIGNED_IMAGE, &mUnalignedImage)) {
87     FAIL() << "Load file " << UNALIGNED_IMAGE << " failed";
88   }
89   mUnalignedImage.width = UNALIGNED_IMAGE_WIDTH;
90   mUnalignedImage.height = UNALIGNED_IMAGE_HEIGHT;
91   if (!loadFile(SINGLE_CHANNEL_IMAGE, &mSingleChannelImage)) {
92     FAIL() << "Load file " << SINGLE_CHANNEL_IMAGE << " failed";
93   }
94   mSingleChannelImage.width = SINGLE_CHANNEL_IMAGE_WIDTH;
95   mSingleChannelImage.height = SINGLE_CHANNEL_IMAGE_HEIGHT;
96   if (!loadFile(RGB_IMAGE, &mRgbImage)) {
97     FAIL() << "Load file " << RGB_IMAGE << " failed";
98   }
99   mRgbImage.width = ALIGNED_IMAGE_WIDTH;
100   mRgbImage.height = ALIGNED_IMAGE_HEIGHT;
101 }
102 
TearDown()103 void JpegEncoderHelperTest::TearDown() {}
104 
TEST_F(JpegEncoderHelperTest,encodeAlignedImage)105 TEST_F(JpegEncoderHelperTest, encodeAlignedImage) {
106   JpegEncoderHelper encoder;
107   const uint8_t* yPlane = mAlignedImage.buffer.get();
108   const uint8_t* uPlane = yPlane + mAlignedImage.width * mAlignedImage.height;
109   const uint8_t* vPlane = uPlane + mAlignedImage.width * mAlignedImage.height / 4;
110   const uint8_t* planes[3]{yPlane, uPlane, vPlane};
111   const unsigned int strides[3]{mAlignedImage.width, mAlignedImage.width / 2,
112                                 mAlignedImage.width / 2};
113   EXPECT_EQ(encoder
114                 .compressImage(planes, strides, mAlignedImage.width, mAlignedImage.height,
115                                UHDR_IMG_FMT_12bppYCbCr420, JPEG_QUALITY, NULL, 0)
116                 .error_code,
117             UHDR_CODEC_OK);
118   ASSERT_GT(encoder.getCompressedImageSize(), static_cast<uint32_t>(0));
119 }
120 
TEST_F(JpegEncoderHelperTest,encodeUnalignedImage)121 TEST_F(JpegEncoderHelperTest, encodeUnalignedImage) {
122   JpegEncoderHelper encoder;
123   const uint8_t* yPlane = mUnalignedImage.buffer.get();
124   const uint8_t* uPlane = yPlane + mUnalignedImage.width * mUnalignedImage.height;
125   const uint8_t* vPlane = uPlane + mUnalignedImage.width * mUnalignedImage.height / 4;
126   const uint8_t* planes[3]{yPlane, uPlane, vPlane};
127   const unsigned int strides[3]{mUnalignedImage.width, mUnalignedImage.width / 2,
128                                 mUnalignedImage.width / 2};
129   EXPECT_EQ(encoder
130                 .compressImage(planes, strides, mUnalignedImage.width, mUnalignedImage.height,
131                                UHDR_IMG_FMT_12bppYCbCr420, JPEG_QUALITY, NULL, 0)
132                 .error_code,
133             UHDR_CODEC_OK);
134   ASSERT_GT(encoder.getCompressedImageSize(), static_cast<uint32_t>(0));
135 }
136 
TEST_F(JpegEncoderHelperTest,encodeSingleChannelImage)137 TEST_F(JpegEncoderHelperTest, encodeSingleChannelImage) {
138   JpegEncoderHelper encoder;
139   const uint8_t* yPlane = mSingleChannelImage.buffer.get();
140   const uint8_t* planes[1]{yPlane};
141   const unsigned int strides[1]{mSingleChannelImage.width};
142   EXPECT_EQ(
143       encoder
144           .compressImage(planes, strides, mSingleChannelImage.width, mSingleChannelImage.height,
145                          UHDR_IMG_FMT_8bppYCbCr400, JPEG_QUALITY, NULL, 0)
146           .error_code,
147       UHDR_CODEC_OK);
148   ASSERT_GT(encoder.getCompressedImageSize(), static_cast<uint32_t>(0));
149 }
150 
TEST_F(JpegEncoderHelperTest,encodeRGBImage)151 TEST_F(JpegEncoderHelperTest, encodeRGBImage) {
152   JpegEncoderHelper encoder;
153   const uint8_t* rgbPlane = mRgbImage.buffer.get();
154   const uint8_t* planes[1]{rgbPlane};
155   const unsigned int strides[1]{mRgbImage.width};
156   EXPECT_EQ(encoder
157                 .compressImage(planes, strides, mRgbImage.width, mRgbImage.height,
158                                UHDR_IMG_FMT_24bppRGB888, JPEG_QUALITY, NULL, 0)
159                 .error_code,
160             UHDR_CODEC_OK);
161   ASSERT_GT(encoder.getCompressedImageSize(), static_cast<uint32_t>(0));
162 }
163 
164 }  // namespace ultrahdr
165