/src/libwebp/sharpyuv/sharpyuv.h
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | // Copyright 2022 Google Inc. All Rights Reserved.  | 
2  |  | //  | 
3  |  | // Use of this source code is governed by a BSD-style license  | 
4  |  | // that can be found in the COPYING file in the root of the source  | 
5  |  | // tree. An additional intellectual property rights grant can be found  | 
6  |  | // in the file PATENTS. All contributing project authors may  | 
7  |  | // be found in the AUTHORS file in the root of the source tree.  | 
8  |  | // -----------------------------------------------------------------------------  | 
9  |  | //  | 
10  |  | // Sharp RGB to YUV conversion.  | 
11  |  |  | 
12  |  | #ifndef WEBP_SHARPYUV_SHARPYUV_H_  | 
13  |  | #define WEBP_SHARPYUV_SHARPYUV_H_  | 
14  |  |  | 
15  |  | #ifdef __cplusplus  | 
16  |  | extern "C" { | 
17  |  | #endif  | 
18  |  |  | 
19  |  | #ifndef SHARPYUV_EXTERN  | 
20  |  | #ifdef WEBP_EXTERN  | 
21  |  | #define SHARPYUV_EXTERN WEBP_EXTERN  | 
22  |  | #else  | 
23  |  | // This explicitly marks library functions and allows for changing the  | 
24  |  | // signature for e.g., Windows DLL builds.  | 
25  |  | #if defined(_WIN32) && defined(WEBP_DLL)  | 
26  |  | #define SHARPYUV_EXTERN __declspec(dllexport)  | 
27  |  | #elif defined(__GNUC__) && __GNUC__ >= 4  | 
28  |  | #define SHARPYUV_EXTERN extern __attribute__((visibility("default"))) | 
29  |  | #else  | 
30  |  | #define SHARPYUV_EXTERN extern  | 
31  |  | #endif /* defined(_WIN32) && defined(WEBP_DLL) */  | 
32  |  | #endif /* WEBP_EXTERN */  | 
33  |  | #endif /* SHARPYUV_EXTERN */  | 
34  |  |  | 
35  |  | #ifndef SHARPYUV_INLINE  | 
36  |  | #ifdef WEBP_INLINE  | 
37  |  | #define SHARPYUV_INLINE WEBP_INLINE  | 
38  |  | #else  | 
39  |  | #ifndef _MSC_VER  | 
40  |  | #if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \  | 
41  |  |     (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)  | 
42  |  | #define SHARPYUV_INLINE inline  | 
43  |  | #else  | 
44  |  | #define SHARPYUV_INLINE  | 
45  |  | #endif  | 
46  |  | #else  | 
47  |  | #define SHARPYUV_INLINE __forceinline  | 
48  |  | #endif /* _MSC_VER */  | 
49  |  | #endif /* WEBP_INLINE */  | 
50  |  | #endif /* SHARPYUV_INLINE */  | 
51  |  |  | 
52  |  | // SharpYUV API version following the convention from semver.org  | 
53  | 0  | #define SHARPYUV_VERSION_MAJOR 0  | 
54  | 0  | #define SHARPYUV_VERSION_MINOR 4  | 
55  |  | #define SHARPYUV_VERSION_PATCH 1  | 
56  |  | // Version as a uint32_t. The major number is the high 8 bits.  | 
57  |  | // The minor number is the middle 8 bits. The patch number is the low 16 bits.  | 
58  |  | #define SHARPYUV_MAKE_VERSION(MAJOR, MINOR, PATCH) \  | 
59  | 0  |   (((MAJOR) << 24) | ((MINOR) << 16) | (PATCH))  | 
60  |  | #define SHARPYUV_VERSION                                                \  | 
61  | 0  |   SHARPYUV_MAKE_VERSION(SHARPYUV_VERSION_MAJOR, SHARPYUV_VERSION_MINOR, \  | 
62  | 0  |                         SHARPYUV_VERSION_PATCH)  | 
63  |  |  | 
64  |  | // Returns the library's version number, packed in hexadecimal. See  | 
65  |  | // SHARPYUV_VERSION.  | 
66  |  | SHARPYUV_EXTERN int SharpYuvGetVersion(void);  | 
67  |  |  | 
68  |  | // RGB to YUV conversion matrix, in 16 bit fixed point.  | 
69  |  | // y_ = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3]  | 
70  |  | // u_ = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3]  | 
71  |  | // v_ = rgb_to_v[0] * r + rgb_to_v[1] * g + rgb_to_v[2] * b + rgb_to_v[3]  | 
72  |  | // Then the values are divided by 1<<16 and rounded.  | 
73  |  | // y = (y_ + (1 << 15)) >> 16  | 
74  |  | // u = (u_ + (1 << 15)) >> 16  | 
75  |  | // v = (v_ + (1 << 15)) >> 16  | 
76  |  | //  | 
77  |  | // Typically, the offset values rgb_to_y[3], rgb_to_u[3] and rgb_to_v[3] depend  | 
78  |  | // on the input's bit depth, e.g., rgb_to_u[3] = 1 << (rgb_bit_depth - 1 + 16).  | 
79  |  | // See also sharpyuv_csp.h to get a predefined matrix or generate a matrix.  | 
80  |  | typedef struct { | 
81  |  |   int rgb_to_y[4];  | 
82  |  |   int rgb_to_u[4];  | 
83  |  |   int rgb_to_v[4];  | 
84  |  | } SharpYuvConversionMatrix;  | 
85  |  |  | 
86  |  | typedef struct SharpYuvOptions SharpYuvOptions;  | 
87  |  |  | 
88  |  | // Enums for transfer functions, as defined in H.273,  | 
89  |  | // https://www.itu.int/rec/T-REC-H.273-202107-I/en  | 
90  |  | typedef enum SharpYuvTransferFunctionType { | 
91  |  |   // 0 is reserved  | 
92  |  |   kSharpYuvTransferFunctionBt709 = 1,  | 
93  |  |   // 2 is unspecified  | 
94  |  |   // 3 is reserved  | 
95  |  |   kSharpYuvTransferFunctionBt470M = 4,  | 
96  |  |   kSharpYuvTransferFunctionBt470Bg = 5,  | 
97  |  |   kSharpYuvTransferFunctionBt601 = 6,  | 
98  |  |   kSharpYuvTransferFunctionSmpte240 = 7,  | 
99  |  |   kSharpYuvTransferFunctionLinear = 8,  | 
100  |  |   kSharpYuvTransferFunctionLog100 = 9,  | 
101  |  |   kSharpYuvTransferFunctionLog100_Sqrt10 = 10,  | 
102  |  |   kSharpYuvTransferFunctionIec61966 = 11,  | 
103  |  |   kSharpYuvTransferFunctionBt1361 = 12,  | 
104  |  |   kSharpYuvTransferFunctionSrgb = 13,  | 
105  |  |   kSharpYuvTransferFunctionBt2020_10Bit = 14,  | 
106  |  |   kSharpYuvTransferFunctionBt2020_12Bit = 15,  | 
107  |  |   kSharpYuvTransferFunctionSmpte2084 = 16,  // PQ  | 
108  |  |   kSharpYuvTransferFunctionSmpte428 = 17,  | 
109  |  |   kSharpYuvTransferFunctionHlg = 18,  | 
110  |  |   kSharpYuvTransferFunctionNum  | 
111  |  | } SharpYuvTransferFunctionType;  | 
112  |  |  | 
113  |  | // Converts RGB to YUV420 using a downsampling algorithm that minimizes  | 
114  |  | // artefacts caused by chroma subsampling.  | 
115  |  | // This is slower than standard downsampling (averaging of 4 UV values).  | 
116  |  | // Assumes that the image will be upsampled using a bilinear filter. If nearest  | 
117  |  | // neighbor is used instead, the upsampled image might look worse than with  | 
118  |  | // standard downsampling.  | 
119  |  | // r_ptr, g_ptr, b_ptr: pointers to the source r, g and b channels. Should point  | 
120  |  | //     to uint8_t buffers if rgb_bit_depth is 8, or uint16_t buffers otherwise.  | 
121  |  | // rgb_step: distance in bytes between two horizontally adjacent pixels on the  | 
122  |  | //     r, g and b channels. If rgb_bit_depth is > 8, it should be a  | 
123  |  | //     multiple of 2.  | 
124  |  | // rgb_stride: distance in bytes between two vertically adjacent pixels on the  | 
125  |  | //     r, g, and b channels. If rgb_bit_depth is > 8, it should be a  | 
126  |  | //     multiple of 2.  | 
127  |  | // rgb_bit_depth: number of bits for each r/g/b value. One of: 8, 10, 12, 16.  | 
128  |  | //     Note: 16 bit input is truncated to 14 bits before conversion to yuv.  | 
129  |  | // yuv_bit_depth: number of bits for each y/u/v value. One of: 8, 10, 12.  | 
130  |  | // y_ptr, u_ptr, v_ptr: pointers to the destination y, u and v channels.  Should  | 
131  |  | //     point to uint8_t buffers if yuv_bit_depth is 8, or uint16_t buffers  | 
132  |  | //     otherwise.  | 
133  |  | // y_stride, u_stride, v_stride: distance in bytes between two vertically  | 
134  |  | //     adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they  | 
135  |  | //     should be multiples of 2.  | 
136  |  | // width, height: width and height of the image in pixels  | 
137  |  | // yuv_matrix: RGB to YUV conversion matrix. The matrix values typically  | 
138  |  | //     depend on the input's rgb_bit_depth.  | 
139  |  | // This function calls SharpYuvConvertWithOptions with a default transfer  | 
140  |  | // function of kSharpYuvTransferFunctionSrgb.  | 
141  |  | SHARPYUV_EXTERN int SharpYuvConvert(const void* r_ptr, const void* g_ptr,  | 
142  |  |                                     const void* b_ptr, int rgb_step,  | 
143  |  |                                     int rgb_stride, int rgb_bit_depth,  | 
144  |  |                                     void* y_ptr, int y_stride, void* u_ptr,  | 
145  |  |                                     int u_stride, void* v_ptr, int v_stride,  | 
146  |  |                                     int yuv_bit_depth, int width, int height,  | 
147  |  |                                     const SharpYuvConversionMatrix* yuv_matrix);  | 
148  |  |  | 
149  |  | struct SharpYuvOptions { | 
150  |  |   // This matrix cannot be NULL and can be initialized by  | 
151  |  |   // SharpYuvComputeConversionMatrix.  | 
152  |  |   const SharpYuvConversionMatrix* yuv_matrix;  | 
153  |  |   SharpYuvTransferFunctionType transfer_type;  | 
154  |  | };  | 
155  |  |  | 
156  |  | // Internal, version-checked, entry point  | 
157  |  | SHARPYUV_EXTERN int SharpYuvOptionsInitInternal(const SharpYuvConversionMatrix*,  | 
158  |  |                                                 SharpYuvOptions*, int);  | 
159  |  |  | 
160  |  | // Should always be called, to initialize a fresh SharpYuvOptions  | 
161  |  | // structure before modification. SharpYuvOptionsInit() must have succeeded  | 
162  |  | // before using the 'options' object.  | 
163  |  | static SHARPYUV_INLINE int SharpYuvOptionsInit(  | 
164  | 0  |     const SharpYuvConversionMatrix* yuv_matrix, SharpYuvOptions* options) { | 
165  | 0  |   return SharpYuvOptionsInitInternal(yuv_matrix, options, SHARPYUV_VERSION);  | 
166  | 0  | } Unexecuted instantiation: picture_csp_enc.c:SharpYuvOptionsInit Unexecuted instantiation: sharpyuv_csp.c:SharpYuvOptionsInit Unexecuted instantiation: sharpyuv.c:SharpYuvOptionsInit Unexecuted instantiation: sharpyuv_cpu.c:SharpYuvOptionsInit Unexecuted instantiation: sharpyuv_dsp.c:SharpYuvOptionsInit Unexecuted instantiation: sharpyuv_gamma.c:SharpYuvOptionsInit Unexecuted instantiation: sharpyuv_sse2.c:SharpYuvOptionsInit  | 
167  |  |  | 
168  |  | SHARPYUV_EXTERN int SharpYuvConvertWithOptions(  | 
169  |  |     const void* r_ptr, const void* g_ptr, const void* b_ptr, int rgb_step,  | 
170  |  |     int rgb_stride, int rgb_bit_depth, void* y_ptr, int y_stride, void* u_ptr,  | 
171  |  |     int u_stride, void* v_ptr, int v_stride, int yuv_bit_depth, int width,  | 
172  |  |     int height, const SharpYuvOptions* options);  | 
173  |  |  | 
174  |  | // TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422  | 
175  |  | // support (it's rarely used in practice, especially for images).  | 
176  |  |  | 
177  |  | #ifdef __cplusplus  | 
178  |  | }  // extern "C"  | 
179  |  | #endif  | 
180  |  |  | 
181  |  | #endif  // WEBP_SHARPYUV_SHARPYUV_H_  |