1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <fcntl.h>
17 #include <fstream>
18 #include <gtest/gtest.h>
19 #include <string>
20
21 #include "abs_image_decoder.h"
22 #include "jpeg_decoder_yuv.h"
23 #include "media_errors.h"
24
25 using namespace testing::ext;
26 using namespace OHOS::ImagePlugin;
27 using namespace OHOS::Media;
28 namespace OHOS {
29 namespace Multimedia {
30 static const std::string IMAGE_INPUT_JPG_PATH = "/data/local/tmp/image/";
31 #define TREE_ORIGINAL_WIDTH 480
32 #define TREE_ORIGINAL_HEIGHT 360
33 #define ODDTREE_ORIGINAL_WIDTH 481
34 #define ODDTREE_ORIGINAL_HEIGHT 361
35 class JpgYuvDecoderTest : public testing::Test {
36 public:
JpgYuvDecoderTest()37 JpgYuvDecoderTest() {}
~JpgYuvDecoderTest()38 ~JpgYuvDecoderTest() {}
39
40 bool ReadImageData(std::string jpgpath, uint8_t*& jpegBuffer, uint32_t& jpegBufferSize);
41 void DecodeToYUV(std::string srcjpg, int width, int height, JpegYuvFmt outfmt);
42 };
43
ReadImageData(std::string jpgpath,uint8_t * & jpegBuffer,uint32_t & jpegBufferSize)44 bool JpgYuvDecoderTest::ReadImageData(std::string jpgpath, uint8_t*& jpegBuffer, uint32_t& jpegBufferSize)
45 {
46 FILE* jpgFile = fopen(jpgpath.c_str(), "rb");
47 if (jpgFile == nullptr) {
48 return false;
49 }
50 int ret = fseek(jpgFile, 0, SEEK_END);
51 if (ret != 0) {
52 return false;
53 }
54 jpegBufferSize = static_cast<int>(ftell(jpgFile));
55 ret = fseek(jpgFile, 0, SEEK_SET);
56 if (ret != 0) {
57 return false;
58 }
59 if (jpegBufferSize == 0 || jpegBufferSize > PIXEL_MAP_MAX_RAM_SIZE) {
60 return false;
61 } else {
62 jpegBuffer = new uint8_t[jpegBufferSize];
63 }
64 if (jpegBuffer == nullptr) {
65 return false;
66 }
67 jpegBufferSize = fread(jpegBuffer, 1, jpegBufferSize, jpgFile);
68 if (jpegBufferSize == 0) {
69 return false;
70 }
71 ret = fclose(jpgFile);
72 if (ret != 0) {
73 return false;
74 }
75 return true;
76 }
77
DecodeToYUV(std::string srcjpg,int width,int height,JpegYuvFmt outfmt)78 void JpgYuvDecoderTest::DecodeToYUV(std::string srcjpg, int width, int height, JpegYuvFmt outfmt)
79 {
80 std::string jpgpath = IMAGE_INPUT_JPG_PATH;
81 jpgpath.append(srcjpg);
82 uint32_t jpegBufferSize = 0;
83 uint8_t* jpegBuffer = nullptr;
84 bool readret = ReadImageData(jpgpath, jpegBuffer, jpegBufferSize);
85 ASSERT_TRUE(readret);
86 ASSERT_NE(jpegBufferSize, 0);
87 ASSERT_NE(jpegBuffer, nullptr);
88
89 uint32_t yuvBufferSize = JpegDecoderYuv::GetYuvOutSize(width, height);
90 ASSERT_NE(yuvBufferSize, 0);
91 if (yuvBufferSize == 0 || yuvBufferSize > PIXEL_MAP_MAX_RAM_SIZE) {
92 ASSERT_TRUE(false);
93 return;
94 }
95 uint8_t* yuvBuffer = new uint8_t[yuvBufferSize];
96 if (yuvBuffer == nullptr) {
97 ASSERT_TRUE(false);
98 return;
99 }
100 std::unique_ptr<JpegDecoderYuv> decoderPtr = std::make_unique<JpegDecoderYuv>();
101 JpegDecoderYuvParameter para = { 0, 0, jpegBuffer, jpegBufferSize, yuvBuffer, yuvBufferSize,
102 outfmt, width, height };
103 DecodeContext context;
104 int ret = decoderPtr->DoDecode(context, para);
105 ASSERT_EQ(ret, SUCCESS);
106 ASSERT_NE(context.yuvInfo.imageSize.width, 0);
107 ASSERT_NE(context.yuvInfo.imageSize.height, 0);
108 ASSERT_NE(context.yuvInfo.yWidth, 0);
109 ASSERT_NE(context.yuvInfo.yHeight, 0);
110 ASSERT_NE(context.yuvInfo.uvWidth, 0);
111 ASSERT_NE(context.yuvInfo.uvHeight, 0);
112 if (outfmt == JpegYuvFmt::OutFmt_YU12 || outfmt == JpegYuvFmt::OutFmt_YV12) {
113 ASSERT_NE(context.yuvInfo.yStride, 0);
114 ASSERT_NE(context.yuvInfo.uStride, 0);
115 ASSERT_NE(context.yuvInfo.vStride, 0);
116 } else {
117 ASSERT_NE(context.yuvInfo.yStride, 0);
118 ASSERT_NE(context.yuvInfo.uvStride, 0);
119 }
120 delete[] yuvBuffer;
121 delete[] jpegBuffer;
122 }
123
124 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest001, TestSize.Level3)
125 {
126 int32_t jpegwidth = 480;
127 int32_t jpegheight = 360;
128 int32_t width = jpegwidth;
129 int32_t height = jpegheight;
130 bool ret = JpegDecoderYuv::GetScaledSize(jpegwidth, jpegheight, width, height);
131 ASSERT_EQ(ret, true);
132
133 ret = JpegDecoderYuv::GetScaledSize(0, jpegheight, width, height);
134 ASSERT_EQ(ret, false);
135 ret = JpegDecoderYuv::GetScaledSize(jpegwidth, 0, width, height);
136 ASSERT_EQ(ret, false);
137
138 width = 0;
139 height = jpegheight;
140 ret = JpegDecoderYuv::GetScaledSize(jpegwidth, jpegheight, width, height);
141 ASSERT_EQ(ret, true);
142 width = jpegwidth;
143 height = 0;
144 ret = JpegDecoderYuv::GetScaledSize(jpegwidth, jpegheight, width, height);
145 ASSERT_EQ(ret, true);
146
147 int testScale = 4;
148 width = jpegwidth * testScale;
149 height = jpegheight * testScale;
150 ret = JpegDecoderYuv::GetScaledSize(jpegwidth, jpegheight, width, height);
151 ASSERT_EQ(ret, true);
152 width = jpegwidth / testScale;
153 height = jpegheight / testScale;
154 ret = JpegDecoderYuv::GetScaledSize(jpegwidth, jpegheight, width, height);
155 ASSERT_EQ(ret, true);
156
157 int offset = 11;
158 width = jpegwidth + offset;
159 height = jpegheight + offset;
160 ret = JpegDecoderYuv::GetScaledSize(jpegwidth, jpegheight, width, height);
161 ASSERT_EQ(ret, true);
162 width = jpegwidth - offset;
163 height = jpegheight - offset;
164 ret = JpegDecoderYuv::GetScaledSize(jpegwidth, jpegheight, width, height);
165 ASSERT_EQ(ret, true);
166 }
167
168 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest002, TestSize.Level3)
169 {
170 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
171 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
172 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
173 DecodeToYUV("test-tree-444.jpg", TREE_ORIGINAL_WIDTH, TREE_ORIGINAL_HEIGHT, outfmtList[j]);
174 }
175 }
176
177 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest003, TestSize.Level3)
178 {
179 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
180 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
181 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
182 DecodeToYUV("test-tree-422.jpg", TREE_ORIGINAL_WIDTH, TREE_ORIGINAL_HEIGHT, outfmtList[j]);
183 }
184 }
185
186 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest004, TestSize.Level3)
187 {
188 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
189 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
190 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
191 DecodeToYUV("test-tree-420.jpg", TREE_ORIGINAL_WIDTH, TREE_ORIGINAL_HEIGHT, outfmtList[j]);
192 }
193 }
194
195 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest005, TestSize.Level3)
196 {
197 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
198 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
199 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
200 DecodeToYUV("test-tree-400.jpg", TREE_ORIGINAL_WIDTH, TREE_ORIGINAL_HEIGHT, outfmtList[j]);
201 }
202 }
203
204 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest006, TestSize.Level3)
205 {
206 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
207 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
208 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
209 DecodeToYUV("test-tree-440.jpg", TREE_ORIGINAL_WIDTH, TREE_ORIGINAL_HEIGHT, outfmtList[j]);
210 }
211 }
212
213 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest007, TestSize.Level3)
214 {
215 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
216 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
217 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
218 DecodeToYUV("test-tree-411.jpg", TREE_ORIGINAL_WIDTH, TREE_ORIGINAL_HEIGHT, outfmtList[j]);
219 }
220 }
221
222 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest008, TestSize.Level3)
223 {
224 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
225 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
226 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
227 DecodeToYUV("test-treeodd-444.jpg", ODDTREE_ORIGINAL_WIDTH, ODDTREE_ORIGINAL_HEIGHT, outfmtList[j]);
228 }
229 }
230
231 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest009, TestSize.Level3)
232 {
233 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
234 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
235 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
236 DecodeToYUV("test-treeodd-422.jpg", ODDTREE_ORIGINAL_WIDTH, ODDTREE_ORIGINAL_HEIGHT, outfmtList[j]);
237 }
238 }
239
240 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest010, TestSize.Level3)
241 {
242 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
243 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
244 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
245 DecodeToYUV("test-treeodd-420.jpg", ODDTREE_ORIGINAL_WIDTH, ODDTREE_ORIGINAL_HEIGHT, outfmtList[j]);
246 }
247 }
248
249 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest011, TestSize.Level3)
250 {
251 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
252 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
253 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
254 DecodeToYUV("test-treeodd-400.jpg", ODDTREE_ORIGINAL_WIDTH, ODDTREE_ORIGINAL_HEIGHT, outfmtList[j]);
255 }
256 }
257
258 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest012, TestSize.Level3)
259 {
260 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
261 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
262 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
263 DecodeToYUV("test-treeodd-440.jpg", ODDTREE_ORIGINAL_WIDTH, ODDTREE_ORIGINAL_HEIGHT, outfmtList[j]);
264 }
265 }
266
267 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest013, TestSize.Level3)
268 {
269 JpegYuvFmt outfmtList[] = { JpegYuvFmt::OutFmt_YU12, JpegYuvFmt::OutFmt_YV12,
270 JpegYuvFmt::OutFmt_NV12, JpegYuvFmt::OutFmt_NV21};
271 for (uint32_t j = 0; j < sizeof(outfmtList) / sizeof(JpegYuvFmt); j++) {
272 DecodeToYUV("test-treeodd-411.jpg", ODDTREE_ORIGINAL_WIDTH, ODDTREE_ORIGINAL_HEIGHT, outfmtList[j]);
273 }
274 }
275
276 HWTEST_F(JpgYuvDecoderTest, JpgYuvDecoderTest014, TestSize.Level3)
277 {
278 int32_t jpegwidth = 480;
279 int32_t jpegheight = 360;
280 float maxScale = 2.5;
281 float minScale = 0.05;
282 float step = 0.01;
283 for (float scaleFactor = maxScale; scaleFactor > minScale; scaleFactor -= step) {
284 int32_t width = jpegwidth * scaleFactor;
285 int32_t height = jpegheight * scaleFactor;
286 bool ret = JpegDecoderYuv::GetScaledSize(jpegwidth, jpegheight, width, height);
287 ASSERT_EQ(ret, true);
288 DecodeToYUV("test-tree-444.jpg", width, height, JpegYuvFmt::OutFmt_NV21);
289 }
290 }
291
292 }
293 }