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