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 #ifndef PLUGINS_COMMON_LIBS_IMAGE_LIBEXTPLUGIN_INCLUDE_JPEG_DECODER_YUV_H
17 #define PLUGINS_COMMON_LIBS_IMAGE_LIBEXTPLUGIN_INCLUDE_JPEG_DECODER_YUV_H
18 
19 #include <string>
20 
21 #include "abs_image_decoder.h"
22 #include "jpeg_yuvdata_converter.h"
23 #include "jpeglib.h"
24 #include "turbojpeg.h"
25 
26 namespace OHOS {
27 namespace ImagePlugin {
28 
29 typedef int (*FUNC_I4xxToI420)(const YuvPlaneInfo& src, const YuvPlaneInfo& dest);
30 typedef int (*FUNC_I4xxToNV21)(const YuvPlaneInfo& src, const YuvPlaneInfo& dest);
31 
32 struct ConverterPair {
33     FUNC_I4xxToI420 to420Func = nullptr;
34     FUNC_I4xxToNV21 toNV21Func = nullptr;
35 };
36 
37 enum class JpegYuvFmt {
38     OutFmt_YU12 = 1,
39     OutFmt_YV12,
40     OutFmt_NV12,
41     OutFmt_NV21,
42 };
43 
44 enum JpegYuvDecodeError {
45     JpegYuvDecodeError_Unknown = -1,
46     JpegYuvDecodeError_Success = 0,
47     JpegYuvDecodeError_InvalidParameter,
48     JpegYuvDecodeError_DecodeFailed,
49     JpegYuvDecodeError_BadImage,
50     JpegYuvDecodeError_SubSampleNotSupport,
51     JpegYuvDecodeError_MemoryMallocFailed,
52     JpegYuvDecodeError_MemoryNotEnoughToSaveResult,
53     JpegYuvDecodeError_ConvertError,
54 };
55 
56 struct JpegDecoderYuvParameter {
57     uint32_t jpgwidth_ = 0;
58     uint32_t jpgheight_ = 0;
59     const uint8_t *jpegBuffer_ = nullptr;
60     uint32_t jpegBufferSize_ = 0;
61     uint8_t *yuvBuffer_ = nullptr;
62     uint32_t yuvBufferSize_ = 0;
63     JpegYuvFmt outfmt_ = JpegYuvFmt::OutFmt_YU12;
64     uint32_t outwidth_ = 0;
65     uint32_t outheight_ = 0;
66 };
67 
68 struct JpegScaleFactor {
69     uint32_t num;
70     uint32_t denom;
71 };
72 
73 typedef int (*FUNC_I444ToI420)(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u,
74     const uint8_t* src_v, int src_stride_v, uint8_t* dst_y, int dst_stride_y, uint8_t* dst_u,
75     int dst_stride_u, uint8_t* dst_v, int dst_stride_v, int width, int height);
76 typedef int (*FUNC_I444ToNV21)(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u,
77     const uint8_t* src_v, int src_stride_v, uint8_t* dst_y, int dst_stride_y, uint8_t* dst_vu,
78     int dst_stride_vu, int width, int height);
79 typedef int (*FUNC_I422ToI420)(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u,
80     const uint8_t* src_v, int src_stride_v, uint8_t* dst_y, int dst_stride_y, uint8_t* dst_u,
81     int dst_stride_u, uint8_t* dst_v, int dst_stride_v, int width, int height);
82 typedef int (*FUNC_I422ToNV21)(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u,
83     const uint8_t* src_v, int src_stride_v, uint8_t* dst_y, int dst_stride_y, uint8_t* dst_vu,
84     int dst_stride_vu, int width, int height);
85 typedef int (*FUNC_I420ToNV21)(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u,
86     const uint8_t* src_v, int src_stride_v, uint8_t* dst_y, int dst_stride_y, uint8_t* dst_vu,
87     int dst_stride_vu, int width, int height);
88 typedef int (*FUNC_I400ToI420)(const uint8_t* src_y, int src_stride_y, uint8_t* dst_y, int dst_stride_y,
89     uint8_t* dst_u, int dst_stride_u, uint8_t* dst_v, int dst_stride_v, int width, int height);
90 
91 struct LibYuvConvertFuncs {
92     FUNC_I444ToI420 I444ToI420 = nullptr;
93     FUNC_I444ToNV21 I444ToNV21 = nullptr;
94     FUNC_I422ToI420 I422ToI420 = nullptr;
95     FUNC_I422ToNV21 I422ToNV21 = nullptr;
96     FUNC_I420ToNV21 I420ToNV21 = nullptr;
97     FUNC_I400ToI420 I400ToI420 = nullptr;
98 };
99 
100 class JpegDecoderYuv {
101 public:
102     JpegDecoderYuv();
103     static bool LoadLibYuv();
104     static void UnloadLibYuv();
GetLibyuvConverter()105     static LibYuvConvertFuncs& GetLibyuvConverter() { return libyuvFuncs_; }
106     int DoDecode(DecodeContext &context, JpegDecoderYuvParameter &decodeParameter);
107     static bool GetScaledSize(uint32_t jpgwidth, uint32_t jpgheight, int32_t &width, int32_t &height);
108     static uint32_t GetYuvOutSize(uint32_t width, uint32_t height);
109 
110 protected:
111     static void InitPlaneOutInfoTo420(uint32_t width, uint32_t height, YuvPlaneInfo &info);
112     static void InitPlaneOutInfoTo420NV(uint32_t width, uint32_t height, YuvPlaneInfo &info);
113     static void FillJpgOutYuvInfo(YuvPlaneInfo& info, uint32_t width, uint32_t height, uint8_t* data, int samp);
114     static uint32_t Get420OutPlaneWidth(YuvComponentIndex com, int imageWidth);
115     static uint32_t Get420OutPlaneHeight(YuvComponentIndex com, int imageHeight);
116     static uint32_t Get420OutPlaneSize(YuvComponentIndex com, int imageWidth, int imageHeight);
117     static uint32_t GetJpegDecompressedYuvSize(uint32_t width, uint32_t height, int subsample);
118     static void InitYuvDataOutInfoTo420(uint32_t width, uint32_t height, OHOS::Media::YUVDataInfo &info,
119                                         JpegYuvFmt fmt);
120     static void InitYuvDataOutInfoTo420NV(uint32_t width, uint32_t height, OHOS::Media::YUVDataInfo &info);
121     static void InitYuvDataOutInfo(uint32_t width, uint32_t height, OHOS::Media::YUVDataInfo &info);
122     static bool IsYU12YV12Format(JpegYuvFmt fmt);
123     static tjscalingfactor GetScaledFactor(uint32_t jpgwidth, uint32_t jpgheight, uint32_t width, uint32_t height);
124     static void JpegCalculateOutputSize(uint32_t jpgwidth, uint32_t jpgheight, uint32_t& width, uint32_t& height);
125     bool IsSupportedSubSample(int jpegSubsamp);
126     bool IsOutSizeValid(uint32_t outwidth, uint32_t outheight);
127     bool CanFastDecodeFrom420to420(uint32_t width, uint32_t height, uint32_t jpgYuvSizeOut, int subsamp);
128     int DecodeHeader(tjhandle dehandle, int& retSubsamp);
129     int DoDecodeToYuvPlane(DecodeContext &context, tjhandle dehandle, uint32_t outw, uint32_t outh);
130     int DecodeFrom420To420(DecodeContext &context, tjhandle dehandle, uint32_t width, uint32_t height);
131     bool ValidateParameter(YuvPlaneInfo &srcPlaneInfo, ConverterPair &converter);
132     int ConvertFrom4xx(YuvPlaneInfo &srcPlaneInfo, ConverterPair &converter);
133     int ConvertFromGray(YuvPlaneInfo &srcPlaneInfo);
134 
135 protected:
136     JpegDecoderYuvParameter decodeParameter_;
137     static void* dlHandler_;
138     static LibYuvConvertFuncs libyuvFuncs_;
139 };
140 
141 }
142 }
143 #endif