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 }