blob: 8f18ac0004d1308ae00c089c9be72898d40ddea5 [file] [log] [blame]
Dichen Zhang4a66b3c2022-10-19 18:04:47 +00001/*
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
Dichen Zhangdbceb0e2023-04-14 19:03:18 +000017#include <ultrahdr/jpegencoderhelper.h>
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000018#include <gtest/gtest.h>
19#include <utils/Log.h>
20
21#include <fcntl.h>
22
Dichen Zhangdbceb0e2023-04-14 19:03:18 +000023namespace android::ultrahdr {
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000024
Dichen Zhang56a7d592023-04-14 16:57:34 +000025#define ALIGNED_IMAGE "/sdcard/Documents/minnie-320x240.yu12"
26#define ALIGNED_IMAGE_WIDTH 320
27#define ALIGNED_IMAGE_HEIGHT 240
Dichen Zhanga4819142022-10-21 04:12:30 +000028#define SINGLE_CHANNEL_IMAGE "/sdcard/Documents/minnie-320x240.y"
Dichen Zhang56a7d592023-04-14 16:57:34 +000029#define SINGLE_CHANNEL_IMAGE_WIDTH ALIGNED_IMAGE_WIDTH
30#define SINGLE_CHANNEL_IMAGE_HEIGHT ALIGNED_IMAGE_HEIGHT
31#define UNALIGNED_IMAGE "/sdcard/Documents/minnie-318x240.yu12"
32#define UNALIGNED_IMAGE_WIDTH 318
33#define UNALIGNED_IMAGE_HEIGHT 240
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000034#define JPEG_QUALITY 90
35
Dichen Zhang02dd0592023-02-10 20:16:57 +000036class JpegEncoderHelperTest : public testing::Test {
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000037public:
38 struct Image {
39 std::unique_ptr<uint8_t[]> buffer;
40 size_t width;
41 size_t height;
42 };
Dichen Zhang02dd0592023-02-10 20:16:57 +000043 JpegEncoderHelperTest();
44 ~JpegEncoderHelperTest();
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000045protected:
46 virtual void SetUp();
47 virtual void TearDown();
48
Dichen Zhang56a7d592023-04-14 16:57:34 +000049 Image mAlignedImage, mUnalignedImage, mSingleChannelImage;
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000050};
51
Dichen Zhang02dd0592023-02-10 20:16:57 +000052JpegEncoderHelperTest::JpegEncoderHelperTest() {}
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000053
Dichen Zhang02dd0592023-02-10 20:16:57 +000054JpegEncoderHelperTest::~JpegEncoderHelperTest() {}
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000055
56static size_t getFileSize(int fd) {
57 struct stat st;
58 if (fstat(fd, &st) < 0) {
59 ALOGW("%s : fstat failed", __func__);
60 return 0;
61 }
62 return st.st_size; // bytes
63}
64
Dichen Zhang02dd0592023-02-10 20:16:57 +000065static bool loadFile(const char filename[], JpegEncoderHelperTest::Image* result) {
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000066 int fd = open(filename, O_CLOEXEC);
67 if (fd < 0) {
68 return false;
69 }
70 int length = getFileSize(fd);
71 if (length == 0) {
72 close(fd);
73 return false;
74 }
75 result->buffer.reset(new uint8_t[length]);
76 if (read(fd, result->buffer.get(), length) != static_cast<ssize_t>(length)) {
77 close(fd);
78 return false;
79 }
80 close(fd);
81 return true;
82}
83
Dichen Zhang02dd0592023-02-10 20:16:57 +000084void JpegEncoderHelperTest::SetUp() {
Dichen Zhang56a7d592023-04-14 16:57:34 +000085 if (!loadFile(ALIGNED_IMAGE, &mAlignedImage)) {
86 FAIL() << "Load file " << ALIGNED_IMAGE << " failed";
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000087 }
Dichen Zhang56a7d592023-04-14 16:57:34 +000088 mAlignedImage.width = ALIGNED_IMAGE_WIDTH;
89 mAlignedImage.height = ALIGNED_IMAGE_HEIGHT;
90 if (!loadFile(UNALIGNED_IMAGE, &mUnalignedImage)) {
91 FAIL() << "Load file " << UNALIGNED_IMAGE << " failed";
Dichen Zhang4a66b3c2022-10-19 18:04:47 +000092 }
Dichen Zhang56a7d592023-04-14 16:57:34 +000093 mUnalignedImage.width = UNALIGNED_IMAGE_WIDTH;
94 mUnalignedImage.height = UNALIGNED_IMAGE_HEIGHT;
Dichen Zhanga4819142022-10-21 04:12:30 +000095 if (!loadFile(SINGLE_CHANNEL_IMAGE, &mSingleChannelImage)) {
96 FAIL() << "Load file " << SINGLE_CHANNEL_IMAGE << " failed";
97 }
98 mSingleChannelImage.width = SINGLE_CHANNEL_IMAGE_WIDTH;
99 mSingleChannelImage.height = SINGLE_CHANNEL_IMAGE_HEIGHT;
Dichen Zhang4a66b3c2022-10-19 18:04:47 +0000100}
101
Dichen Zhang02dd0592023-02-10 20:16:57 +0000102void JpegEncoderHelperTest::TearDown() {}
Dichen Zhang4a66b3c2022-10-19 18:04:47 +0000103
Dichen Zhang56a7d592023-04-14 16:57:34 +0000104TEST_F(JpegEncoderHelperTest, encodeAlignedImage) {
Dichen Zhang02dd0592023-02-10 20:16:57 +0000105 JpegEncoderHelper encoder;
Dichen Zhang56a7d592023-04-14 16:57:34 +0000106 EXPECT_TRUE(encoder.compressImage(mAlignedImage.buffer.get(), mAlignedImage.width,
107 mAlignedImage.height, JPEG_QUALITY, NULL, 0));
Dichen Zhang4a66b3c2022-10-19 18:04:47 +0000108 ASSERT_GT(encoder.getCompressedImageSize(), static_cast<uint32_t>(0));
109}
110
Dichen Zhang56a7d592023-04-14 16:57:34 +0000111// The width of the "unaligned" image is not 16-aligned, and will fail if encoded directly.
112// Should pass with the padding zero method.
113TEST_F(JpegEncoderHelperTest, encodeUnalignedImage) {
Dichen Zhang02dd0592023-02-10 20:16:57 +0000114 JpegEncoderHelper encoder;
Dichen Zhang56a7d592023-04-14 16:57:34 +0000115 const size_t paddingZeroLength = JpegEncoderHelper::kCompressBatchSize
116 * JpegEncoderHelper::kCompressBatchSize / 4;
117 std::unique_ptr<uint8_t[]> imageWithPaddingZeros(
118 new uint8_t[UNALIGNED_IMAGE_WIDTH * UNALIGNED_IMAGE_HEIGHT * 3 / 2
119 + paddingZeroLength]);
120 memcpy(imageWithPaddingZeros.get(), mUnalignedImage.buffer.get(),
121 UNALIGNED_IMAGE_WIDTH * UNALIGNED_IMAGE_HEIGHT * 3 / 2);
122 EXPECT_TRUE(encoder.compressImage(imageWithPaddingZeros.get(), mUnalignedImage.width,
123 mUnalignedImage.height, JPEG_QUALITY, NULL, 0));
124 ASSERT_GT(encoder.getCompressedImageSize(), static_cast<uint32_t>(0));
Dichen Zhang4a66b3c2022-10-19 18:04:47 +0000125}
126
Dichen Zhang56a7d592023-04-14 16:57:34 +0000127TEST_F(JpegEncoderHelperTest, encodeSingleChannelImage) {
Dichen Zhang02dd0592023-02-10 20:16:57 +0000128 JpegEncoderHelper encoder;
Dichen Zhanga4819142022-10-21 04:12:30 +0000129 EXPECT_TRUE(encoder.compressImage(mSingleChannelImage.buffer.get(), mSingleChannelImage.width,
130 mSingleChannelImage.height, JPEG_QUALITY, NULL, 0, true));
131 ASSERT_GT(encoder.getCompressedImageSize(), static_cast<uint32_t>(0));
132}
133
Dichen Zhangdbceb0e2023-04-14 19:03:18 +0000134} // namespace android::ultrahdr
Dichen Zhang4a66b3c2022-10-19 18:04:47 +0000135