Coverage Report

Created: 2025-11-16 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libswscale/format.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2024 Niklas Haas
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#include "libavutil/avassert.h"
22
#include "libavutil/hdr_dynamic_metadata.h"
23
#include "libavutil/mastering_display_metadata.h"
24
#include "libavutil/refstruct.h"
25
26
#include "format.h"
27
#include "csputils.h"
28
#include "ops_internal.h"
29
30
0
#define Q(N) ((AVRational) { N, 1 })
31
0
#define Q0   Q(0)
32
0
#define Q1   Q(1)
33
34
#define RET(x)                                                                 \
35
0
    do {                                                                       \
36
0
        int _ret = (x);                                                        \
37
0
        if (_ret  < 0)                                                         \
38
0
            return _ret;                                                       \
39
0
    } while (0)
40
41
typedef struct LegacyFormatEntry {
42
    uint8_t is_supported_in         :1;
43
    uint8_t is_supported_out        :1;
44
    uint8_t is_supported_endianness :1;
45
} LegacyFormatEntry;
46
47
/* Format support table for legacy swscale */
48
static const LegacyFormatEntry legacy_format_entries[] = {
49
    [AV_PIX_FMT_YUV420P]        = { 1, 1 },
50
    [AV_PIX_FMT_YUYV422]        = { 1, 1 },
51
    [AV_PIX_FMT_RGB24]          = { 1, 1 },
52
    [AV_PIX_FMT_BGR24]          = { 1, 1 },
53
    [AV_PIX_FMT_YUV422P]        = { 1, 1 },
54
    [AV_PIX_FMT_YUV444P]        = { 1, 1 },
55
    [AV_PIX_FMT_YUV410P]        = { 1, 1 },
56
    [AV_PIX_FMT_YUV411P]        = { 1, 1 },
57
    [AV_PIX_FMT_GRAY8]          = { 1, 1 },
58
    [AV_PIX_FMT_MONOWHITE]      = { 1, 1 },
59
    [AV_PIX_FMT_MONOBLACK]      = { 1, 1 },
60
    [AV_PIX_FMT_PAL8]           = { 1, 0 },
61
    [AV_PIX_FMT_YUVJ420P]       = { 1, 1 },
62
    [AV_PIX_FMT_YUVJ411P]       = { 1, 1 },
63
    [AV_PIX_FMT_YUVJ422P]       = { 1, 1 },
64
    [AV_PIX_FMT_YUVJ444P]       = { 1, 1 },
65
    [AV_PIX_FMT_YVYU422]        = { 1, 1 },
66
    [AV_PIX_FMT_UYVY422]        = { 1, 1 },
67
    [AV_PIX_FMT_UYYVYY411]      = { 1, 0 },
68
    [AV_PIX_FMT_BGR8]           = { 1, 1 },
69
    [AV_PIX_FMT_BGR4]           = { 0, 1 },
70
    [AV_PIX_FMT_BGR4_BYTE]      = { 1, 1 },
71
    [AV_PIX_FMT_RGB8]           = { 1, 1 },
72
    [AV_PIX_FMT_RGB4]           = { 0, 1 },
73
    [AV_PIX_FMT_RGB4_BYTE]      = { 1, 1 },
74
    [AV_PIX_FMT_NV12]           = { 1, 1 },
75
    [AV_PIX_FMT_NV21]           = { 1, 1 },
76
    [AV_PIX_FMT_ARGB]           = { 1, 1 },
77
    [AV_PIX_FMT_RGBA]           = { 1, 1 },
78
    [AV_PIX_FMT_ABGR]           = { 1, 1 },
79
    [AV_PIX_FMT_BGRA]           = { 1, 1 },
80
    [AV_PIX_FMT_0RGB]           = { 1, 1 },
81
    [AV_PIX_FMT_RGB0]           = { 1, 1 },
82
    [AV_PIX_FMT_0BGR]           = { 1, 1 },
83
    [AV_PIX_FMT_BGR0]           = { 1, 1 },
84
    [AV_PIX_FMT_GRAY9BE]        = { 1, 1 },
85
    [AV_PIX_FMT_GRAY9LE]        = { 1, 1 },
86
    [AV_PIX_FMT_GRAY10BE]       = { 1, 1 },
87
    [AV_PIX_FMT_GRAY10LE]       = { 1, 1 },
88
    [AV_PIX_FMT_GRAY12BE]       = { 1, 1 },
89
    [AV_PIX_FMT_GRAY12LE]       = { 1, 1 },
90
    [AV_PIX_FMT_GRAY14BE]       = { 1, 1 },
91
    [AV_PIX_FMT_GRAY14LE]       = { 1, 1 },
92
    [AV_PIX_FMT_GRAY16BE]       = { 1, 1 },
93
    [AV_PIX_FMT_GRAY16LE]       = { 1, 1 },
94
    [AV_PIX_FMT_YUV440P]        = { 1, 1 },
95
    [AV_PIX_FMT_YUVJ440P]       = { 1, 1 },
96
    [AV_PIX_FMT_YUV440P10LE]    = { 1, 1 },
97
    [AV_PIX_FMT_YUV440P10BE]    = { 1, 1 },
98
    [AV_PIX_FMT_YUV440P12LE]    = { 1, 1 },
99
    [AV_PIX_FMT_YUV440P12BE]    = { 1, 1 },
100
    [AV_PIX_FMT_YUVA420P]       = { 1, 1 },
101
    [AV_PIX_FMT_YUVA422P]       = { 1, 1 },
102
    [AV_PIX_FMT_YUVA444P]       = { 1, 1 },
103
    [AV_PIX_FMT_YUVA420P9BE]    = { 1, 1 },
104
    [AV_PIX_FMT_YUVA420P9LE]    = { 1, 1 },
105
    [AV_PIX_FMT_YUVA422P9BE]    = { 1, 1 },
106
    [AV_PIX_FMT_YUVA422P9LE]    = { 1, 1 },
107
    [AV_PIX_FMT_YUVA444P9BE]    = { 1, 1 },
108
    [AV_PIX_FMT_YUVA444P9LE]    = { 1, 1 },
109
    [AV_PIX_FMT_YUVA420P10BE]   = { 1, 1 },
110
    [AV_PIX_FMT_YUVA420P10LE]   = { 1, 1 },
111
    [AV_PIX_FMT_YUVA422P10BE]   = { 1, 1 },
112
    [AV_PIX_FMT_YUVA422P10LE]   = { 1, 1 },
113
    [AV_PIX_FMT_YUVA444P10BE]   = { 1, 1 },
114
    [AV_PIX_FMT_YUVA444P10LE]   = { 1, 1 },
115
    [AV_PIX_FMT_YUVA420P16BE]   = { 1, 1 },
116
    [AV_PIX_FMT_YUVA420P16LE]   = { 1, 1 },
117
    [AV_PIX_FMT_YUVA422P16BE]   = { 1, 1 },
118
    [AV_PIX_FMT_YUVA422P16LE]   = { 1, 1 },
119
    [AV_PIX_FMT_YUVA444P16BE]   = { 1, 1 },
120
    [AV_PIX_FMT_YUVA444P16LE]   = { 1, 1 },
121
    [AV_PIX_FMT_RGB48BE]        = { 1, 1 },
122
    [AV_PIX_FMT_RGB48LE]        = { 1, 1 },
123
    [AV_PIX_FMT_RGBA64BE]       = { 1, 1, 1 },
124
    [AV_PIX_FMT_RGBA64LE]       = { 1, 1, 1 },
125
    [AV_PIX_FMT_RGB565BE]       = { 1, 1 },
126
    [AV_PIX_FMT_RGB565LE]       = { 1, 1 },
127
    [AV_PIX_FMT_RGB555BE]       = { 1, 1 },
128
    [AV_PIX_FMT_RGB555LE]       = { 1, 1 },
129
    [AV_PIX_FMT_BGR565BE]       = { 1, 1 },
130
    [AV_PIX_FMT_BGR565LE]       = { 1, 1 },
131
    [AV_PIX_FMT_BGR555BE]       = { 1, 1 },
132
    [AV_PIX_FMT_BGR555LE]       = { 1, 1 },
133
    [AV_PIX_FMT_YUV420P16LE]    = { 1, 1 },
134
    [AV_PIX_FMT_YUV420P16BE]    = { 1, 1 },
135
    [AV_PIX_FMT_YUV422P16LE]    = { 1, 1 },
136
    [AV_PIX_FMT_YUV422P16BE]    = { 1, 1 },
137
    [AV_PIX_FMT_YUV444P16LE]    = { 1, 1 },
138
    [AV_PIX_FMT_YUV444P16BE]    = { 1, 1 },
139
    [AV_PIX_FMT_RGB444LE]       = { 1, 1 },
140
    [AV_PIX_FMT_RGB444BE]       = { 1, 1 },
141
    [AV_PIX_FMT_BGR444LE]       = { 1, 1 },
142
    [AV_PIX_FMT_BGR444BE]       = { 1, 1 },
143
    [AV_PIX_FMT_YA8]            = { 1, 1 },
144
    [AV_PIX_FMT_YA16BE]         = { 1, 1 },
145
    [AV_PIX_FMT_YA16LE]         = { 1, 1 },
146
    [AV_PIX_FMT_BGR48BE]        = { 1, 1 },
147
    [AV_PIX_FMT_BGR48LE]        = { 1, 1 },
148
    [AV_PIX_FMT_BGRA64BE]       = { 1, 1, 1 },
149
    [AV_PIX_FMT_BGRA64LE]       = { 1, 1, 1 },
150
    [AV_PIX_FMT_YUV420P9BE]     = { 1, 1 },
151
    [AV_PIX_FMT_YUV420P9LE]     = { 1, 1 },
152
    [AV_PIX_FMT_YUV420P10BE]    = { 1, 1 },
153
    [AV_PIX_FMT_YUV420P10LE]    = { 1, 1 },
154
    [AV_PIX_FMT_YUV420P12BE]    = { 1, 1 },
155
    [AV_PIX_FMT_YUV420P12LE]    = { 1, 1 },
156
    [AV_PIX_FMT_YUV420P14BE]    = { 1, 1 },
157
    [AV_PIX_FMT_YUV420P14LE]    = { 1, 1 },
158
    [AV_PIX_FMT_YUV422P9BE]     = { 1, 1 },
159
    [AV_PIX_FMT_YUV422P9LE]     = { 1, 1 },
160
    [AV_PIX_FMT_YUV422P10BE]    = { 1, 1 },
161
    [AV_PIX_FMT_YUV422P10LE]    = { 1, 1 },
162
    [AV_PIX_FMT_YUV422P12BE]    = { 1, 1 },
163
    [AV_PIX_FMT_YUV422P12LE]    = { 1, 1 },
164
    [AV_PIX_FMT_YUV422P14BE]    = { 1, 1 },
165
    [AV_PIX_FMT_YUV422P14LE]    = { 1, 1 },
166
    [AV_PIX_FMT_YUV444P9BE]     = { 1, 1 },
167
    [AV_PIX_FMT_YUV444P9LE]     = { 1, 1 },
168
    [AV_PIX_FMT_YUV444P10BE]    = { 1, 1 },
169
    [AV_PIX_FMT_YUV444P10LE]    = { 1, 1 },
170
    [AV_PIX_FMT_YUV444P12BE]    = { 1, 1 },
171
    [AV_PIX_FMT_YUV444P12LE]    = { 1, 1 },
172
    [AV_PIX_FMT_YUV444P14BE]    = { 1, 1 },
173
    [AV_PIX_FMT_YUV444P14LE]    = { 1, 1 },
174
    [AV_PIX_FMT_YUV444P10MSBBE] = { 1, 1 },
175
    [AV_PIX_FMT_YUV444P10MSBLE] = { 1, 1 },
176
    [AV_PIX_FMT_YUV444P12MSBBE] = { 1, 1 },
177
    [AV_PIX_FMT_YUV444P12MSBLE] = { 1, 1 },
178
    [AV_PIX_FMT_GBRP]           = { 1, 1 },
179
    [AV_PIX_FMT_GBRP9LE]        = { 1, 1 },
180
    [AV_PIX_FMT_GBRP9BE]        = { 1, 1 },
181
    [AV_PIX_FMT_GBRP10LE]       = { 1, 1 },
182
    [AV_PIX_FMT_GBRP10BE]       = { 1, 1 },
183
    [AV_PIX_FMT_GBRAP10LE]      = { 1, 1 },
184
    [AV_PIX_FMT_GBRAP10BE]      = { 1, 1 },
185
    [AV_PIX_FMT_GBRP10MSBLE]    = { 1, 1 },
186
    [AV_PIX_FMT_GBRP10MSBBE]    = { 1, 1 },
187
    [AV_PIX_FMT_GBRP12LE]       = { 1, 1 },
188
    [AV_PIX_FMT_GBRP12BE]       = { 1, 1 },
189
    [AV_PIX_FMT_GBRP12MSBLE]    = { 1, 1 },
190
    [AV_PIX_FMT_GBRP12MSBBE]    = { 1, 1 },
191
    [AV_PIX_FMT_GBRAP12LE]      = { 1, 1 },
192
    [AV_PIX_FMT_GBRAP12BE]      = { 1, 1 },
193
    [AV_PIX_FMT_GBRP14LE]       = { 1, 1 },
194
    [AV_PIX_FMT_GBRP14BE]       = { 1, 1 },
195
    [AV_PIX_FMT_GBRAP14LE]      = { 1, 1 },
196
    [AV_PIX_FMT_GBRAP14BE]      = { 1, 1 },
197
    [AV_PIX_FMT_GBRP16LE]       = { 1, 1 },
198
    [AV_PIX_FMT_GBRP16BE]       = { 1, 1 },
199
    [AV_PIX_FMT_GBRPF32LE]      = { 1, 1 },
200
    [AV_PIX_FMT_GBRPF32BE]      = { 1, 1 },
201
    [AV_PIX_FMT_GBRAPF32LE]     = { 1, 1 },
202
    [AV_PIX_FMT_GBRAPF32BE]     = { 1, 1 },
203
    [AV_PIX_FMT_GBRPF16LE]      = { 1, 0 },
204
    [AV_PIX_FMT_GBRPF16BE]      = { 1, 0 },
205
    [AV_PIX_FMT_GBRAPF16LE]     = { 1, 0 },
206
    [AV_PIX_FMT_GBRAPF16BE]     = { 1, 0 },
207
    [AV_PIX_FMT_GBRAP]          = { 1, 1 },
208
    [AV_PIX_FMT_GBRAP16LE]      = { 1, 1 },
209
    [AV_PIX_FMT_GBRAP16BE]      = { 1, 1 },
210
    [AV_PIX_FMT_BAYER_BGGR8]    = { 1, 0 },
211
    [AV_PIX_FMT_BAYER_RGGB8]    = { 1, 0 },
212
    [AV_PIX_FMT_BAYER_GBRG8]    = { 1, 0 },
213
    [AV_PIX_FMT_BAYER_GRBG8]    = { 1, 0 },
214
    [AV_PIX_FMT_BAYER_BGGR16LE] = { 1, 0 },
215
    [AV_PIX_FMT_BAYER_BGGR16BE] = { 1, 0 },
216
    [AV_PIX_FMT_BAYER_RGGB16LE] = { 1, 0 },
217
    [AV_PIX_FMT_BAYER_RGGB16BE] = { 1, 0 },
218
    [AV_PIX_FMT_BAYER_GBRG16LE] = { 1, 0 },
219
    [AV_PIX_FMT_BAYER_GBRG16BE] = { 1, 0 },
220
    [AV_PIX_FMT_BAYER_GRBG16LE] = { 1, 0 },
221
    [AV_PIX_FMT_BAYER_GRBG16BE] = { 1, 0 },
222
    [AV_PIX_FMT_XYZ12BE]        = { 1, 1, 1 },
223
    [AV_PIX_FMT_XYZ12LE]        = { 1, 1, 1 },
224
    [AV_PIX_FMT_AYUV64LE]       = { 1, 1},
225
    [AV_PIX_FMT_AYUV64BE]       = { 1, 1 },
226
    [AV_PIX_FMT_P010LE]         = { 1, 1 },
227
    [AV_PIX_FMT_P010BE]         = { 1, 1 },
228
    [AV_PIX_FMT_P012LE]         = { 1, 1 },
229
    [AV_PIX_FMT_P012BE]         = { 1, 1 },
230
    [AV_PIX_FMT_P016LE]         = { 1, 1 },
231
    [AV_PIX_FMT_P016BE]         = { 1, 1 },
232
    [AV_PIX_FMT_GRAYF32LE]      = { 1, 1 },
233
    [AV_PIX_FMT_GRAYF32BE]      = { 1, 1 },
234
    [AV_PIX_FMT_GRAYF16LE]      = { 1, 0 },
235
    [AV_PIX_FMT_GRAYF16BE]      = { 1, 0 },
236
    [AV_PIX_FMT_YAF32LE]        = { 1, 0 },
237
    [AV_PIX_FMT_YAF32BE]        = { 1, 0 },
238
    [AV_PIX_FMT_YAF16LE]        = { 1, 0 },
239
    [AV_PIX_FMT_YAF16BE]        = { 1, 0 },
240
    [AV_PIX_FMT_YUVA422P12BE]   = { 1, 1 },
241
    [AV_PIX_FMT_YUVA422P12LE]   = { 1, 1 },
242
    [AV_PIX_FMT_YUVA444P12BE]   = { 1, 1 },
243
    [AV_PIX_FMT_YUVA444P12LE]   = { 1, 1 },
244
    [AV_PIX_FMT_NV24]           = { 1, 1 },
245
    [AV_PIX_FMT_NV42]           = { 1, 1 },
246
    [AV_PIX_FMT_Y210LE]         = { 1, 1 },
247
    [AV_PIX_FMT_Y212LE]         = { 1, 1 },
248
    [AV_PIX_FMT_Y216LE]         = { 1, 1 },
249
    [AV_PIX_FMT_X2RGB10LE]      = { 1, 1 },
250
    [AV_PIX_FMT_X2BGR10LE]      = { 1, 1 },
251
    [AV_PIX_FMT_NV20BE]         = { 1, 1 },
252
    [AV_PIX_FMT_NV20LE]         = { 1, 1 },
253
    [AV_PIX_FMT_P210BE]         = { 1, 1 },
254
    [AV_PIX_FMT_P210LE]         = { 1, 1 },
255
    [AV_PIX_FMT_P212BE]         = { 1, 1 },
256
    [AV_PIX_FMT_P212LE]         = { 1, 1 },
257
    [AV_PIX_FMT_P410BE]         = { 1, 1 },
258
    [AV_PIX_FMT_P410LE]         = { 1, 1 },
259
    [AV_PIX_FMT_P412BE]         = { 1, 1 },
260
    [AV_PIX_FMT_P412LE]         = { 1, 1 },
261
    [AV_PIX_FMT_P216BE]         = { 1, 1 },
262
    [AV_PIX_FMT_P216LE]         = { 1, 1 },
263
    [AV_PIX_FMT_P416BE]         = { 1, 1 },
264
    [AV_PIX_FMT_P416LE]         = { 1, 1 },
265
    [AV_PIX_FMT_NV16]           = { 1, 1 },
266
    [AV_PIX_FMT_VUYA]           = { 1, 1 },
267
    [AV_PIX_FMT_VUYX]           = { 1, 1 },
268
    [AV_PIX_FMT_RGBAF16BE]      = { 1, 0 },
269
    [AV_PIX_FMT_RGBAF16LE]      = { 1, 0 },
270
    [AV_PIX_FMT_RGBF16BE]       = { 1, 0 },
271
    [AV_PIX_FMT_RGBF16LE]       = { 1, 0 },
272
    [AV_PIX_FMT_RGBF32BE]       = { 1, 0 },
273
    [AV_PIX_FMT_RGBF32LE]       = { 1, 0 },
274
    [AV_PIX_FMT_XV30LE]         = { 1, 1 },
275
    [AV_PIX_FMT_XV36LE]         = { 1, 1 },
276
    [AV_PIX_FMT_XV36BE]         = { 1, 1 },
277
    [AV_PIX_FMT_XV48LE]         = { 1, 1 },
278
    [AV_PIX_FMT_XV48BE]         = { 1, 1 },
279
    [AV_PIX_FMT_AYUV]           = { 1, 1 },
280
    [AV_PIX_FMT_UYVA]           = { 1, 1 },
281
    [AV_PIX_FMT_VYU444]         = { 1, 1 },
282
    [AV_PIX_FMT_V30XLE]         = { 1, 1 },
283
};
284
285
int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
286
15.3k
{
287
15.3k
    return (unsigned)pix_fmt < FF_ARRAY_ELEMS(legacy_format_entries) ?
288
15.3k
    legacy_format_entries[pix_fmt].is_supported_in : 0;
289
15.3k
}
290
291
int sws_isSupportedOutput(enum AVPixelFormat pix_fmt)
292
15.3k
{
293
15.3k
    return (unsigned)pix_fmt < FF_ARRAY_ELEMS(legacy_format_entries) ?
294
15.3k
    legacy_format_entries[pix_fmt].is_supported_out : 0;
295
15.3k
}
296
297
int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
298
3.57k
{
299
3.57k
    return (unsigned)pix_fmt < FF_ARRAY_ELEMS(legacy_format_entries) ?
300
3.57k
    legacy_format_entries[pix_fmt].is_supported_endianness : 0;
301
3.57k
}
302
303
/**
304
 * This function also sanitizes and strips the input data, removing irrelevant
305
 * fields for certain formats.
306
 */
307
SwsFormat ff_fmt_from_frame(const AVFrame *frame, int field)
308
0
{
309
0
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
310
0
    const AVColorPrimariesDesc *primaries;
311
0
    AVFrameSideData *sd;
312
313
0
    SwsFormat fmt = {
314
0
        .width  = frame->width,
315
0
        .height = frame->height,
316
0
        .format = frame->format,
317
0
        .range  = frame->color_range,
318
0
        .csp    = frame->colorspace,
319
0
        .loc    = frame->chroma_location,
320
0
        .desc   = desc,
321
0
        .color = {
322
0
            .prim = frame->color_primaries,
323
0
            .trc  = frame->color_trc,
324
0
        },
325
0
    };
326
327
0
    av_assert1(fmt.width > 0);
328
0
    av_assert1(fmt.height > 0);
329
0
    av_assert1(fmt.format != AV_PIX_FMT_NONE);
330
0
    av_assert0(desc);
331
0
    if (desc->flags & (AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_BAYER)) {
332
        /* RGB-like family */
333
0
        fmt.csp   = AVCOL_SPC_RGB;
334
0
        fmt.range = AVCOL_RANGE_JPEG;
335
0
    } else if (desc->flags & AV_PIX_FMT_FLAG_XYZ) {
336
0
        fmt.csp   = AVCOL_SPC_UNSPECIFIED;
337
0
        fmt.color = (SwsColor) {
338
0
            .prim = AVCOL_PRI_BT709, /* swscale currently hard-codes this XYZ matrix */
339
0
            .trc  = AVCOL_TRC_SMPTE428,
340
0
        };
341
0
    } else if (desc->nb_components < 3) {
342
        /* Grayscale formats */
343
0
        fmt.color.prim = AVCOL_PRI_UNSPECIFIED;
344
0
        fmt.csp        = AVCOL_SPC_UNSPECIFIED;
345
0
        if (desc->flags & AV_PIX_FMT_FLAG_FLOAT)
346
0
            fmt.range = AVCOL_RANGE_UNSPECIFIED;
347
0
        else
348
0
            fmt.range = AVCOL_RANGE_JPEG; // FIXME: this restriction should be lifted
349
0
    }
350
351
0
    switch (frame->format) {
352
0
    case AV_PIX_FMT_YUVJ420P:
353
0
    case AV_PIX_FMT_YUVJ411P:
354
0
    case AV_PIX_FMT_YUVJ422P:
355
0
    case AV_PIX_FMT_YUVJ444P:
356
0
    case AV_PIX_FMT_YUVJ440P:
357
0
        fmt.range = AVCOL_RANGE_JPEG;
358
0
        break;
359
0
    }
360
361
0
    if (!desc->log2_chroma_w && !desc->log2_chroma_h)
362
0
        fmt.loc = AVCHROMA_LOC_UNSPECIFIED;
363
364
0
    if (frame->flags & AV_FRAME_FLAG_INTERLACED) {
365
0
        fmt.height = (fmt.height + (field == FIELD_TOP)) >> 1;
366
0
        fmt.interlaced = 1;
367
0
    }
368
369
    /* Set luminance and gamut information */
370
0
    fmt.color.min_luma = av_make_q(0, 1);
371
0
    switch (fmt.color.trc) {
372
0
    case AVCOL_TRC_SMPTE2084:
373
0
        fmt.color.max_luma = av_make_q(10000, 1); break;
374
0
    case AVCOL_TRC_ARIB_STD_B67:
375
0
        fmt.color.max_luma = av_make_q( 1000, 1); break; /* HLG reference display */
376
0
    default:
377
0
        fmt.color.max_luma = av_make_q(  203, 1); break; /* SDR reference brightness */
378
0
    }
379
380
0
    primaries = av_csp_primaries_desc_from_id(fmt.color.prim);
381
0
    if (primaries)
382
0
        fmt.color.gamut = primaries->prim;
383
384
0
    if ((sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA))) {
385
0
        const AVMasteringDisplayMetadata *mdm = (const AVMasteringDisplayMetadata *) sd->data;
386
0
        if (mdm->has_luminance) {
387
0
            fmt.color.min_luma = mdm->min_luminance;
388
0
            fmt.color.max_luma = mdm->max_luminance;
389
0
        }
390
391
0
        if (mdm->has_primaries) {
392
            /* Ignore mastering display white point as it has no bearance on
393
             * the underlying content */
394
0
            fmt.color.gamut.r.x = mdm->display_primaries[0][0];
395
0
            fmt.color.gamut.r.y = mdm->display_primaries[0][1];
396
0
            fmt.color.gamut.g.x = mdm->display_primaries[1][0];
397
0
            fmt.color.gamut.g.y = mdm->display_primaries[1][1];
398
0
            fmt.color.gamut.b.x = mdm->display_primaries[2][0];
399
0
            fmt.color.gamut.b.y = mdm->display_primaries[2][1];
400
0
        }
401
0
    }
402
403
0
    if ((sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS))) {
404
0
        const AVDynamicHDRPlus *dhp = (const AVDynamicHDRPlus *) sd->data;
405
0
        const AVHDRPlusColorTransformParams *pars = &dhp->params[0];
406
0
        const AVRational nits = av_make_q(10000, 1);
407
0
        AVRational maxrgb = pars->maxscl[0];
408
409
0
        if (!dhp->num_windows || dhp->application_version > 1)
410
0
            goto skip_hdr10;
411
412
        /* Maximum of MaxSCL components */
413
0
        if (av_cmp_q(pars->maxscl[1], maxrgb) > 0)
414
0
            maxrgb = pars->maxscl[1];
415
0
        if (av_cmp_q(pars->maxscl[2], maxrgb) > 0)
416
0
            maxrgb = pars->maxscl[2];
417
418
0
        if (maxrgb.num > 0) {
419
            /* Estimate true luminance from MaxSCL */
420
0
            const AVLumaCoefficients *luma = av_csp_luma_coeffs_from_avcsp(fmt.csp);
421
0
            if (!luma)
422
0
                goto skip_hdr10;
423
0
            fmt.color.frame_peak = av_add_q(av_mul_q(luma->cr, pars->maxscl[0]),
424
0
                                   av_add_q(av_mul_q(luma->cg, pars->maxscl[1]),
425
0
                                            av_mul_q(luma->cb, pars->maxscl[2])));
426
            /* Scale the scene average brightness by the ratio between the
427
             * maximum luminance and the MaxRGB values */
428
0
            fmt.color.frame_avg = av_mul_q(pars->average_maxrgb,
429
0
                                           av_div_q(fmt.color.frame_peak, maxrgb));
430
0
        } else {
431
            /**
432
             * Calculate largest value from histogram to use as fallback for
433
             * clips with missing MaxSCL information. Note that this may end
434
             * up picking the "reserved" value at the 5% percentile, which in
435
             * practice appears to track the brightest pixel in the scene.
436
             */
437
0
            for (int i = 0; i < pars->num_distribution_maxrgb_percentiles; i++) {
438
0
                const AVRational pct = pars->distribution_maxrgb[i].percentile;
439
0
                if (av_cmp_q(pct, maxrgb) > 0)
440
0
                    maxrgb = pct;
441
0
                fmt.color.frame_peak = maxrgb;
442
0
                fmt.color.frame_avg  = pars->average_maxrgb;
443
0
            }
444
0
        }
445
446
        /* Rescale to nits */
447
0
        fmt.color.frame_peak = av_mul_q(nits, fmt.color.frame_peak);
448
0
        fmt.color.frame_avg  = av_mul_q(nits, fmt.color.frame_avg);
449
0
    }
450
0
skip_hdr10:
451
452
    /* PQ is always scaled down to absolute zero, so ignore mastering metadata */
453
0
    if (fmt.color.trc == AVCOL_TRC_SMPTE2084)
454
0
        fmt.color.min_luma = av_make_q(0, 1);
455
456
0
    return fmt;
457
0
}
458
459
static int infer_prim_ref(SwsColor *csp, const SwsColor *ref)
460
0
{
461
0
    if (csp->prim != AVCOL_PRI_UNSPECIFIED)
462
0
        return 0;
463
464
    /* Reuse the reference gamut only for "safe", similar primaries */
465
0
    switch (ref->prim) {
466
0
    case AVCOL_PRI_BT709:
467
0
    case AVCOL_PRI_BT470M:
468
0
    case AVCOL_PRI_BT470BG:
469
0
    case AVCOL_PRI_SMPTE170M:
470
0
    case AVCOL_PRI_SMPTE240M:
471
0
        csp->prim  = ref->prim;
472
0
        csp->gamut = ref->gamut;
473
0
        break;
474
0
    default:
475
0
        csp->prim  = AVCOL_PRI_BT709;
476
0
        csp->gamut = av_csp_primaries_desc_from_id(csp->prim)->prim;
477
0
        break;
478
0
    }
479
480
0
    return 1;
481
0
}
482
483
static int infer_trc_ref(SwsColor *csp, const SwsColor *ref)
484
0
{
485
0
    if (csp->trc != AVCOL_TRC_UNSPECIFIED)
486
0
        return 0;
487
488
    /* Pick a suitable SDR transfer function, to try and minimize conversions */
489
0
    switch (ref->trc) {
490
0
    case AVCOL_TRC_UNSPECIFIED:
491
    /* HDR curves, never default to these */
492
0
    case AVCOL_TRC_SMPTE2084:
493
0
    case AVCOL_TRC_ARIB_STD_B67:
494
0
        csp->trc = AVCOL_TRC_BT709;
495
0
        csp->min_luma = av_make_q(0, 1);
496
0
        csp->max_luma = av_make_q(203, 1);
497
0
        break;
498
0
    default:
499
0
        csp->trc = ref->trc;
500
0
        csp->min_luma = ref->min_luma;
501
0
        csp->max_luma = ref->max_luma;
502
0
        break;
503
0
    }
504
505
0
    return 1;
506
0
}
507
508
bool ff_infer_colors(SwsColor *src, SwsColor *dst)
509
0
{
510
0
    int incomplete = 0;
511
512
0
    incomplete |= infer_prim_ref(dst, src);
513
0
    incomplete |= infer_prim_ref(src, dst);
514
0
    av_assert0(src->prim != AVCOL_PRI_UNSPECIFIED);
515
0
    av_assert0(dst->prim != AVCOL_PRI_UNSPECIFIED);
516
517
0
    incomplete |= infer_trc_ref(dst, src);
518
0
    incomplete |= infer_trc_ref(src, dst);
519
0
    av_assert0(src->trc != AVCOL_TRC_UNSPECIFIED);
520
0
    av_assert0(dst->trc != AVCOL_TRC_UNSPECIFIED);
521
522
0
    return incomplete;
523
0
}
524
525
int sws_test_format(enum AVPixelFormat format, int output)
526
0
{
527
0
    return output ? sws_isSupportedOutput(format) : sws_isSupportedInput(format);
528
0
}
529
530
int sws_test_colorspace(enum AVColorSpace csp, int output)
531
0
{
532
0
    switch (csp) {
533
0
    case AVCOL_SPC_UNSPECIFIED:
534
0
    case AVCOL_SPC_RGB:
535
0
    case AVCOL_SPC_BT709:
536
0
    case AVCOL_SPC_BT470BG:
537
0
    case AVCOL_SPC_SMPTE170M:
538
0
    case AVCOL_SPC_FCC:
539
0
    case AVCOL_SPC_SMPTE240M:
540
0
    case AVCOL_SPC_BT2020_NCL:
541
0
        return 1;
542
0
    default:
543
0
        return 0;
544
0
    }
545
0
}
546
547
int sws_test_primaries(enum AVColorPrimaries prim, int output)
548
0
{
549
0
    return ((prim > AVCOL_PRI_RESERVED0 && prim < AVCOL_PRI_NB) ||
550
0
            (prim >= AVCOL_PRI_EXT_BASE && prim < AVCOL_PRI_EXT_NB)) &&
551
0
           prim != AVCOL_PRI_RESERVED;
552
0
}
553
554
int sws_test_transfer(enum AVColorTransferCharacteristic trc, int output)
555
0
{
556
0
    av_csp_eotf_function eotf = output ? av_csp_itu_eotf_inv(trc)
557
0
                                       : av_csp_itu_eotf(trc);
558
0
    return trc == AVCOL_TRC_UNSPECIFIED || eotf != NULL;
559
0
}
560
561
static int test_range(enum AVColorRange range)
562
0
{
563
0
    return (unsigned)range < AVCOL_RANGE_NB;
564
0
}
565
566
static int test_loc(enum AVChromaLocation loc)
567
0
{
568
0
    return (unsigned)loc < AVCHROMA_LOC_NB;
569
0
}
570
571
int ff_test_fmt(const SwsFormat *fmt, int output)
572
0
{
573
0
    return fmt->width > 0 && fmt->height > 0            &&
574
0
           sws_test_format    (fmt->format,     output) &&
575
0
           sws_test_colorspace(fmt->csp,        output) &&
576
0
           sws_test_primaries (fmt->color.prim, output) &&
577
0
           sws_test_transfer  (fmt->color.trc,  output) &&
578
0
           test_range         (fmt->range)              &&
579
0
           test_loc           (fmt->loc);
580
0
}
581
582
int sws_test_frame(const AVFrame *frame, int output)
583
0
{
584
0
    for (int field = 0; field < 2; field++) {
585
0
        const SwsFormat fmt = ff_fmt_from_frame(frame, field);
586
0
        if (!ff_test_fmt(&fmt, output))
587
0
            return 0;
588
0
        if (!fmt.interlaced)
589
0
            break;
590
0
    }
591
592
0
    return 1;
593
0
}
594
595
int sws_is_noop(const AVFrame *dst, const AVFrame *src)
596
0
{
597
0
    for (int field = 0; field < 2; field++) {
598
0
        SwsFormat dst_fmt = ff_fmt_from_frame(dst, field);
599
0
        SwsFormat src_fmt = ff_fmt_from_frame(src, field);
600
0
        if (!ff_fmt_equal(&dst_fmt, &src_fmt))
601
0
            return 0;
602
0
        if (!dst_fmt.interlaced)
603
0
            break;
604
0
    }
605
606
0
    return 1;
607
0
}
608
609
#if CONFIG_UNSTABLE
610
611
/* Returns the type suitable for a pixel after fully decoding/unpacking it */
612
static SwsPixelType fmt_pixel_type(enum AVPixelFormat fmt)
613
0
{
614
0
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
615
0
    const int bits = FFALIGN(desc->comp[0].depth, 8);
616
0
    if (desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
617
0
        switch (bits) {
618
0
        case 32: return SWS_PIXEL_F32;
619
0
        }
620
0
    } else {
621
0
        switch (bits) {
622
0
        case  8: return SWS_PIXEL_U8;
623
0
        case 16: return SWS_PIXEL_U16;
624
0
        case 32: return SWS_PIXEL_U32;
625
0
        }
626
0
    }
627
628
0
    return SWS_PIXEL_NONE;
629
0
}
630
631
static SwsSwizzleOp fmt_swizzle(enum AVPixelFormat fmt)
632
0
{
633
0
    switch (fmt) {
634
0
    case AV_PIX_FMT_ARGB:
635
0
    case AV_PIX_FMT_0RGB:
636
0
    case AV_PIX_FMT_AYUV64LE:
637
0
    case AV_PIX_FMT_AYUV64BE:
638
0
    case AV_PIX_FMT_AYUV:
639
0
    case AV_PIX_FMT_X2RGB10LE:
640
0
    case AV_PIX_FMT_X2RGB10BE:
641
0
        return (SwsSwizzleOp) {{ .x = 3, 0, 1, 2 }};
642
0
    case AV_PIX_FMT_BGR24:
643
0
    case AV_PIX_FMT_BGR8:
644
0
    case AV_PIX_FMT_BGR4:
645
0
    case AV_PIX_FMT_BGR4_BYTE:
646
0
    case AV_PIX_FMT_BGRA:
647
0
    case AV_PIX_FMT_BGR565BE:
648
0
    case AV_PIX_FMT_BGR565LE:
649
0
    case AV_PIX_FMT_BGR555BE:
650
0
    case AV_PIX_FMT_BGR555LE:
651
0
    case AV_PIX_FMT_BGR444BE:
652
0
    case AV_PIX_FMT_BGR444LE:
653
0
    case AV_PIX_FMT_BGR48BE:
654
0
    case AV_PIX_FMT_BGR48LE:
655
0
    case AV_PIX_FMT_BGRA64BE:
656
0
    case AV_PIX_FMT_BGRA64LE:
657
0
    case AV_PIX_FMT_BGR0:
658
0
    case AV_PIX_FMT_VUYA:
659
0
    case AV_PIX_FMT_VUYX:
660
0
        return (SwsSwizzleOp) {{ .x = 2, 1, 0, 3 }};
661
0
    case AV_PIX_FMT_ABGR:
662
0
    case AV_PIX_FMT_0BGR:
663
0
    case AV_PIX_FMT_X2BGR10LE:
664
0
    case AV_PIX_FMT_X2BGR10BE:
665
0
        return (SwsSwizzleOp) {{ .x = 3, 2, 1, 0 }};
666
0
    case AV_PIX_FMT_YA8:
667
0
    case AV_PIX_FMT_YA16BE:
668
0
    case AV_PIX_FMT_YA16LE:
669
0
        return (SwsSwizzleOp) {{ .x = 0, 3, 1, 2 }};
670
0
    case AV_PIX_FMT_XV30BE:
671
0
    case AV_PIX_FMT_XV30LE:
672
0
        return (SwsSwizzleOp) {{ .x = 3, 2, 0, 1 }};
673
0
    case AV_PIX_FMT_VYU444:
674
0
    case AV_PIX_FMT_V30XBE:
675
0
    case AV_PIX_FMT_V30XLE:
676
0
        return (SwsSwizzleOp) {{ .x = 2, 0, 1, 3 }};
677
0
    case AV_PIX_FMT_XV36BE:
678
0
    case AV_PIX_FMT_XV36LE:
679
0
    case AV_PIX_FMT_XV48BE:
680
0
    case AV_PIX_FMT_XV48LE:
681
0
    case AV_PIX_FMT_UYVA:
682
0
        return (SwsSwizzleOp) {{ .x = 1, 0, 2, 3 }};
683
0
    case AV_PIX_FMT_GBRP:
684
0
    case AV_PIX_FMT_GBRP9BE:
685
0
    case AV_PIX_FMT_GBRP9LE:
686
0
    case AV_PIX_FMT_GBRP10BE:
687
0
    case AV_PIX_FMT_GBRP10LE:
688
0
    case AV_PIX_FMT_GBRP12BE:
689
0
    case AV_PIX_FMT_GBRP12LE:
690
0
    case AV_PIX_FMT_GBRP14BE:
691
0
    case AV_PIX_FMT_GBRP14LE:
692
0
    case AV_PIX_FMT_GBRP16BE:
693
0
    case AV_PIX_FMT_GBRP16LE:
694
0
    case AV_PIX_FMT_GBRPF16BE:
695
0
    case AV_PIX_FMT_GBRPF16LE:
696
0
    case AV_PIX_FMT_GBRAP:
697
0
    case AV_PIX_FMT_GBRAP10LE:
698
0
    case AV_PIX_FMT_GBRAP10BE:
699
0
    case AV_PIX_FMT_GBRAP12LE:
700
0
    case AV_PIX_FMT_GBRAP12BE:
701
0
    case AV_PIX_FMT_GBRAP14LE:
702
0
    case AV_PIX_FMT_GBRAP14BE:
703
0
    case AV_PIX_FMT_GBRAP16LE:
704
0
    case AV_PIX_FMT_GBRAP16BE:
705
0
    case AV_PIX_FMT_GBRPF32BE:
706
0
    case AV_PIX_FMT_GBRPF32LE:
707
0
    case AV_PIX_FMT_GBRAPF16BE:
708
0
    case AV_PIX_FMT_GBRAPF16LE:
709
0
    case AV_PIX_FMT_GBRAPF32BE:
710
0
    case AV_PIX_FMT_GBRAPF32LE:
711
0
    case AV_PIX_FMT_GBRP10MSBBE:
712
0
    case AV_PIX_FMT_GBRP10MSBLE:
713
0
    case AV_PIX_FMT_GBRP12MSBBE:
714
0
    case AV_PIX_FMT_GBRP12MSBLE:
715
0
        return (SwsSwizzleOp) {{ .x = 1, 2, 0, 3 }};
716
0
    default:
717
0
        return (SwsSwizzleOp) {{ .x = 0, 1, 2, 3 }};
718
0
    }
719
0
}
720
721
0
static SwsSwizzleOp swizzle_inv(SwsSwizzleOp swiz) {
722
    /* Input[x] =: Output[swizzle.x] */
723
0
    unsigned out[4];
724
0
    out[swiz.x] = 0;
725
0
    out[swiz.y] = 1;
726
0
    out[swiz.z] = 2;
727
0
    out[swiz.w] = 3;
728
0
    return (SwsSwizzleOp) {{ .x = out[0], out[1], out[2], out[3] }};
729
0
}
730
731
/* Shift factor for MSB aligned formats */
732
static int fmt_shift(enum AVPixelFormat fmt)
733
0
{
734
0
    switch (fmt) {
735
0
    case AV_PIX_FMT_P010BE:
736
0
    case AV_PIX_FMT_P010LE:
737
0
    case AV_PIX_FMT_P210BE:
738
0
    case AV_PIX_FMT_P210LE:
739
0
    case AV_PIX_FMT_Y210BE:
740
0
    case AV_PIX_FMT_Y210LE:
741
0
    case AV_PIX_FMT_YUV444P10MSBBE:
742
0
    case AV_PIX_FMT_YUV444P10MSBLE:
743
0
    case AV_PIX_FMT_GBRP10MSBBE:
744
0
    case AV_PIX_FMT_GBRP10MSBLE:
745
0
        return 6;
746
0
    case AV_PIX_FMT_P012BE:
747
0
    case AV_PIX_FMT_P012LE:
748
0
    case AV_PIX_FMT_P212BE:
749
0
    case AV_PIX_FMT_P212LE:
750
0
    case AV_PIX_FMT_P412BE:
751
0
    case AV_PIX_FMT_P412LE:
752
0
    case AV_PIX_FMT_XV36BE:
753
0
    case AV_PIX_FMT_XV36LE:
754
0
    case AV_PIX_FMT_XYZ12BE:
755
0
    case AV_PIX_FMT_XYZ12LE:
756
0
    case AV_PIX_FMT_YUV444P12MSBBE:
757
0
    case AV_PIX_FMT_YUV444P12MSBLE:
758
0
    case AV_PIX_FMT_GBRP12MSBBE:
759
0
    case AV_PIX_FMT_GBRP12MSBLE:
760
0
        return 4;
761
0
    }
762
763
0
    return 0;
764
0
}
765
766
/**
767
 * This initializes all absent components explicitly to zero. There is no
768
 * need to worry about the correct neutral value as fmt_decode() will
769
 * implicitly ignore and overwrite absent components in any case. This function
770
 * is just to ensure that we don't operate on undefined memory. In most cases,
771
 * it will end up getting pushed towards the output or optimized away entirely
772
 * by the optimization pass.
773
 */
774
static SwsConst fmt_clear(enum AVPixelFormat fmt)
775
0
{
776
0
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
777
0
    const bool has_chroma = desc->nb_components >= 3;
778
0
    const bool has_alpha  = desc->flags & AV_PIX_FMT_FLAG_ALPHA;
779
780
0
    SwsConst c = {0};
781
0
    if (!has_chroma)
782
0
        c.q4[1] = c.q4[2] = Q0;
783
0
    if (!has_alpha)
784
0
        c.q4[3] = Q0;
785
786
0
    return c;
787
0
}
788
789
static int fmt_read_write(enum AVPixelFormat fmt, SwsReadWriteOp *rw_op,
790
                          SwsPackOp *pack_op)
791
0
{
792
0
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
793
0
    if (!desc)
794
0
        return AVERROR(EINVAL);
795
796
0
    switch (fmt) {
797
0
    case AV_PIX_FMT_NONE:
798
0
    case AV_PIX_FMT_NB:
799
0
        break;
800
801
    /* Packed bitstream formats */
802
0
    case AV_PIX_FMT_MONOWHITE:
803
0
    case AV_PIX_FMT_MONOBLACK:
804
0
        *pack_op = (SwsPackOp) {0};
805
0
        *rw_op = (SwsReadWriteOp) {
806
0
            .elems = 1,
807
0
            .frac  = 3,
808
0
        };
809
0
        return 0;
810
0
    case AV_PIX_FMT_RGB4:
811
0
    case AV_PIX_FMT_BGR4:
812
0
        *pack_op = (SwsPackOp) {{ 1, 2, 1 }};
813
0
        *rw_op = (SwsReadWriteOp) {
814
0
            .elems = 1,
815
0
            .packed = true,
816
0
            .frac  = 1,
817
0
        };
818
0
        return 0;
819
    /* Packed 8-bit aligned formats */
820
0
    case AV_PIX_FMT_RGB4_BYTE:
821
0
    case AV_PIX_FMT_BGR4_BYTE:
822
0
        *pack_op = (SwsPackOp) {{ 1, 2, 1 }};
823
0
        *rw_op = (SwsReadWriteOp) { .elems = 1, .packed = true };
824
0
        return 0;
825
0
    case AV_PIX_FMT_BGR8:
826
0
        *pack_op = (SwsPackOp) {{ 2, 3, 3 }};
827
0
        *rw_op = (SwsReadWriteOp) { .elems = 1, .packed = true };
828
0
        return 0;
829
0
    case AV_PIX_FMT_RGB8:
830
0
        *pack_op = (SwsPackOp) {{ 3, 3, 2 }};
831
0
        *rw_op = (SwsReadWriteOp) { .elems = 1, .packed = true };
832
0
        return 0;
833
834
    /* Packed 16-bit aligned formats */
835
0
    case AV_PIX_FMT_RGB565BE:
836
0
    case AV_PIX_FMT_RGB565LE:
837
0
    case AV_PIX_FMT_BGR565BE:
838
0
    case AV_PIX_FMT_BGR565LE:
839
0
        *pack_op = (SwsPackOp) {{ 5, 6, 5 }};
840
0
        *rw_op = (SwsReadWriteOp) { .elems = 1, .packed = true };
841
0
        return 0;
842
0
    case AV_PIX_FMT_RGB555BE:
843
0
    case AV_PIX_FMT_RGB555LE:
844
0
    case AV_PIX_FMT_BGR555BE:
845
0
    case AV_PIX_FMT_BGR555LE:
846
0
        *pack_op = (SwsPackOp) {{ 5, 5, 5 }};
847
0
        *rw_op = (SwsReadWriteOp) { .elems = 1, .packed = true };
848
0
        return 0;
849
0
    case AV_PIX_FMT_RGB444BE:
850
0
    case AV_PIX_FMT_RGB444LE:
851
0
    case AV_PIX_FMT_BGR444BE:
852
0
    case AV_PIX_FMT_BGR444LE:
853
0
        *pack_op = (SwsPackOp) {{ 4, 4, 4 }};
854
0
        *rw_op = (SwsReadWriteOp) { .elems = 1, .packed = true };
855
0
        return 0;
856
    /* Packed 32-bit aligned 4:4:4 formats */
857
0
    case AV_PIX_FMT_X2RGB10BE:
858
0
    case AV_PIX_FMT_X2RGB10LE:
859
0
    case AV_PIX_FMT_X2BGR10BE:
860
0
    case AV_PIX_FMT_X2BGR10LE:
861
0
    case AV_PIX_FMT_XV30BE:
862
0
    case AV_PIX_FMT_XV30LE:
863
0
        *pack_op = (SwsPackOp) {{ 2, 10, 10, 10 }};
864
0
        *rw_op = (SwsReadWriteOp) { .elems = 1, .packed = true };
865
0
        return 0;
866
0
    case AV_PIX_FMT_V30XBE:
867
0
    case AV_PIX_FMT_V30XLE:
868
0
        *pack_op = (SwsPackOp) {{ 10, 10, 10, 2 }};
869
0
        *rw_op = (SwsReadWriteOp) { .elems = 1, .packed = true };
870
0
        return 0;
871
    /* 3 component formats with one channel ignored */
872
0
    case AV_PIX_FMT_RGB0:
873
0
    case AV_PIX_FMT_BGR0:
874
0
    case AV_PIX_FMT_0RGB:
875
0
    case AV_PIX_FMT_0BGR:
876
0
    case AV_PIX_FMT_XV36BE:
877
0
    case AV_PIX_FMT_XV36LE:
878
0
    case AV_PIX_FMT_XV48BE:
879
0
    case AV_PIX_FMT_XV48LE:
880
0
    case AV_PIX_FMT_VUYX:
881
0
        *pack_op = (SwsPackOp) {0};
882
0
        *rw_op = (SwsReadWriteOp) { .elems = 4, .packed = true };
883
0
        return 0;
884
    /* Unpacked byte-aligned 4:4:4 formats */
885
0
    case AV_PIX_FMT_YUV444P:
886
0
    case AV_PIX_FMT_YUVJ444P:
887
0
    case AV_PIX_FMT_YUV444P9BE:
888
0
    case AV_PIX_FMT_YUV444P9LE:
889
0
    case AV_PIX_FMT_YUV444P10BE:
890
0
    case AV_PIX_FMT_YUV444P10LE:
891
0
    case AV_PIX_FMT_YUV444P12BE:
892
0
    case AV_PIX_FMT_YUV444P12LE:
893
0
    case AV_PIX_FMT_YUV444P14BE:
894
0
    case AV_PIX_FMT_YUV444P14LE:
895
0
    case AV_PIX_FMT_YUV444P16BE:
896
0
    case AV_PIX_FMT_YUV444P16LE:
897
0
    case AV_PIX_FMT_YUV444P10MSBBE:
898
0
    case AV_PIX_FMT_YUV444P10MSBLE:
899
0
    case AV_PIX_FMT_YUV444P12MSBBE:
900
0
    case AV_PIX_FMT_YUV444P12MSBLE:
901
0
    case AV_PIX_FMT_YUVA444P:
902
0
    case AV_PIX_FMT_YUVA444P9BE:
903
0
    case AV_PIX_FMT_YUVA444P9LE:
904
0
    case AV_PIX_FMT_YUVA444P10BE:
905
0
    case AV_PIX_FMT_YUVA444P10LE:
906
0
    case AV_PIX_FMT_YUVA444P12BE:
907
0
    case AV_PIX_FMT_YUVA444P12LE:
908
0
    case AV_PIX_FMT_YUVA444P16BE:
909
0
    case AV_PIX_FMT_YUVA444P16LE:
910
0
    case AV_PIX_FMT_AYUV:
911
0
    case AV_PIX_FMT_UYVA:
912
0
    case AV_PIX_FMT_VYU444:
913
0
    case AV_PIX_FMT_AYUV64BE:
914
0
    case AV_PIX_FMT_AYUV64LE:
915
0
    case AV_PIX_FMT_VUYA:
916
0
    case AV_PIX_FMT_RGB24:
917
0
    case AV_PIX_FMT_BGR24:
918
0
    case AV_PIX_FMT_RGB48BE:
919
0
    case AV_PIX_FMT_RGB48LE:
920
0
    case AV_PIX_FMT_BGR48BE:
921
0
    case AV_PIX_FMT_BGR48LE:
922
    //case AV_PIX_FMT_RGB96BE: TODO: AVRational can't fit 2^32-1
923
    //case AV_PIX_FMT_RGB96LE:
924
    //case AV_PIX_FMT_RGBF16BE: TODO: no support for float16 currently
925
    //case AV_PIX_FMT_RGBF16LE:
926
0
    case AV_PIX_FMT_RGBF32BE:
927
0
    case AV_PIX_FMT_RGBF32LE:
928
0
    case AV_PIX_FMT_ARGB:
929
0
    case AV_PIX_FMT_RGBA:
930
0
    case AV_PIX_FMT_ABGR:
931
0
    case AV_PIX_FMT_BGRA:
932
0
    case AV_PIX_FMT_RGBA64BE:
933
0
    case AV_PIX_FMT_RGBA64LE:
934
0
    case AV_PIX_FMT_BGRA64BE:
935
0
    case AV_PIX_FMT_BGRA64LE:
936
    //case AV_PIX_FMT_RGBA128BE: TODO: AVRational can't fit 2^32-1
937
    //case AV_PIX_FMT_RGBA128LE:
938
0
    case AV_PIX_FMT_RGBAF32BE:
939
0
    case AV_PIX_FMT_RGBAF32LE:
940
0
    case AV_PIX_FMT_GBRP:
941
0
    case AV_PIX_FMT_GBRP9BE:
942
0
    case AV_PIX_FMT_GBRP9LE:
943
0
    case AV_PIX_FMT_GBRP10BE:
944
0
    case AV_PIX_FMT_GBRP10LE:
945
0
    case AV_PIX_FMT_GBRP12BE:
946
0
    case AV_PIX_FMT_GBRP12LE:
947
0
    case AV_PIX_FMT_GBRP14BE:
948
0
    case AV_PIX_FMT_GBRP14LE:
949
0
    case AV_PIX_FMT_GBRP16BE:
950
0
    case AV_PIX_FMT_GBRP16LE:
951
    //case AV_PIX_FMT_GBRPF16BE: TODO
952
    //case AV_PIX_FMT_GBRPF16LE:
953
0
    case AV_PIX_FMT_GBRP10MSBBE:
954
0
    case AV_PIX_FMT_GBRP10MSBLE:
955
0
    case AV_PIX_FMT_GBRP12MSBBE:
956
0
    case AV_PIX_FMT_GBRP12MSBLE:
957
0
    case AV_PIX_FMT_GBRPF32BE:
958
0
    case AV_PIX_FMT_GBRPF32LE:
959
0
    case AV_PIX_FMT_GBRAP:
960
0
    case AV_PIX_FMT_GBRAP10BE:
961
0
    case AV_PIX_FMT_GBRAP10LE:
962
0
    case AV_PIX_FMT_GBRAP12BE:
963
0
    case AV_PIX_FMT_GBRAP12LE:
964
0
    case AV_PIX_FMT_GBRAP14BE:
965
0
    case AV_PIX_FMT_GBRAP14LE:
966
0
    case AV_PIX_FMT_GBRAP16BE:
967
0
    case AV_PIX_FMT_GBRAP16LE:
968
    //case AV_PIX_FMT_GBRAPF16BE: TODO
969
    //case AV_PIX_FMT_GBRAPF16LE:
970
0
    case AV_PIX_FMT_GBRAPF32BE:
971
0
    case AV_PIX_FMT_GBRAPF32LE:
972
0
    case AV_PIX_FMT_GRAY8:
973
0
    case AV_PIX_FMT_GRAY9BE:
974
0
    case AV_PIX_FMT_GRAY9LE:
975
0
    case AV_PIX_FMT_GRAY10BE:
976
0
    case AV_PIX_FMT_GRAY10LE:
977
0
    case AV_PIX_FMT_GRAY12BE:
978
0
    case AV_PIX_FMT_GRAY12LE:
979
0
    case AV_PIX_FMT_GRAY14BE:
980
0
    case AV_PIX_FMT_GRAY14LE:
981
0
    case AV_PIX_FMT_GRAY16BE:
982
0
    case AV_PIX_FMT_GRAY16LE:
983
    //case AV_PIX_FMT_GRAYF16BE: TODO
984
    //case AV_PIX_FMT_GRAYF16LE:
985
    //case AV_PIX_FMT_YAF16BE:
986
    //case AV_PIX_FMT_YAF16LE:
987
0
    case AV_PIX_FMT_GRAYF32BE:
988
0
    case AV_PIX_FMT_GRAYF32LE:
989
0
    case AV_PIX_FMT_YAF32BE:
990
0
    case AV_PIX_FMT_YAF32LE:
991
0
    case AV_PIX_FMT_YA8:
992
0
    case AV_PIX_FMT_YA16LE:
993
0
    case AV_PIX_FMT_YA16BE:
994
0
        *pack_op = (SwsPackOp) {0};
995
0
        *rw_op = (SwsReadWriteOp) {
996
0
            .elems  = desc->nb_components,
997
0
            .packed = desc->nb_components > 1 && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR),
998
0
        };
999
0
        return 0;
1000
0
    }
1001
1002
0
    return AVERROR(ENOTSUP);
1003
0
}
1004
1005
static SwsPixelType get_packed_type(SwsPackOp pack)
1006
0
{
1007
0
    const int sum = pack.pattern[0] + pack.pattern[1] +
1008
0
                    pack.pattern[2] + pack.pattern[3];
1009
0
    if (sum > 16)
1010
0
        return SWS_PIXEL_U32;
1011
0
    else if (sum > 8)
1012
0
        return SWS_PIXEL_U16;
1013
0
    else
1014
0
        return SWS_PIXEL_U8;
1015
0
}
1016
1017
#if HAVE_BIGENDIAN
1018
#  define NATIVE_ENDIAN_FLAG AV_PIX_FMT_FLAG_BE
1019
#else
1020
0
#  define NATIVE_ENDIAN_FLAG 0
1021
#endif
1022
1023
int ff_sws_decode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt)
1024
0
{
1025
0
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
1026
0
    SwsPixelType pixel_type = fmt_pixel_type(fmt);
1027
0
    SwsPixelType raw_type = pixel_type;
1028
0
    SwsReadWriteOp rw_op;
1029
0
    SwsPackOp unpack;
1030
1031
0
    RET(fmt_read_write(fmt, &rw_op, &unpack));
1032
0
    if (unpack.pattern[0])
1033
0
        raw_type = get_packed_type(unpack);
1034
1035
    /* TODO: handle subsampled or semipacked input formats */
1036
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1037
0
        .op   = SWS_OP_READ,
1038
0
        .type = raw_type,
1039
0
        .rw   = rw_op,
1040
0
    }));
1041
1042
0
    if ((desc->flags & AV_PIX_FMT_FLAG_BE) != NATIVE_ENDIAN_FLAG) {
1043
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1044
0
            .op   = SWS_OP_SWAP_BYTES,
1045
0
            .type = raw_type,
1046
0
        }));
1047
0
    }
1048
1049
0
    if (unpack.pattern[0]) {
1050
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1051
0
            .op   = SWS_OP_UNPACK,
1052
0
            .type = raw_type,
1053
0
            .pack = unpack,
1054
0
        }));
1055
1056
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1057
0
            .op   = SWS_OP_CONVERT,
1058
0
            .type = raw_type,
1059
0
            .convert.to = pixel_type,
1060
0
        }));
1061
0
    }
1062
1063
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1064
0
        .op      = SWS_OP_SWIZZLE,
1065
0
        .type    = pixel_type,
1066
0
        .swizzle = swizzle_inv(fmt_swizzle(fmt)),
1067
0
    }));
1068
1069
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1070
0
        .op   = SWS_OP_RSHIFT,
1071
0
        .type = pixel_type,
1072
0
        .c.u  = fmt_shift(fmt),
1073
0
    }));
1074
1075
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1076
0
        .op   = SWS_OP_CLEAR,
1077
0
        .type = pixel_type,
1078
0
        .c    = fmt_clear(fmt),
1079
0
    }));
1080
1081
0
    return 0;
1082
0
}
1083
1084
int ff_sws_encode_pixfmt(SwsOpList *ops, enum AVPixelFormat fmt)
1085
0
{
1086
0
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
1087
0
    SwsPixelType pixel_type = fmt_pixel_type(fmt);
1088
0
    SwsPixelType raw_type = pixel_type;
1089
0
    SwsReadWriteOp rw_op;
1090
0
    SwsPackOp pack;
1091
1092
0
    RET(fmt_read_write(fmt, &rw_op, &pack));
1093
0
    if (pack.pattern[0])
1094
0
        raw_type = get_packed_type(pack);
1095
1096
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1097
0
        .op   = SWS_OP_LSHIFT,
1098
0
        .type = pixel_type,
1099
0
        .c.u  = fmt_shift(fmt),
1100
0
    }));
1101
1102
0
    if (rw_op.elems > desc->nb_components) {
1103
        /* Format writes unused alpha channel, clear it explicitly for sanity */
1104
0
        av_assert1(!(desc->flags & AV_PIX_FMT_FLAG_ALPHA));
1105
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1106
0
            .op   = SWS_OP_CLEAR,
1107
0
            .type = pixel_type,
1108
0
            .c.q4[3] = Q0,
1109
0
        }));
1110
0
    }
1111
1112
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1113
0
        .op      = SWS_OP_SWIZZLE,
1114
0
        .type    = pixel_type,
1115
0
        .swizzle = fmt_swizzle(fmt),
1116
0
    }));
1117
1118
0
    if (pack.pattern[0]) {
1119
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1120
0
            .op   = SWS_OP_CONVERT,
1121
0
            .type = pixel_type,
1122
0
            .convert.to = raw_type,
1123
0
        }));
1124
1125
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1126
0
            .op   = SWS_OP_PACK,
1127
0
            .type = raw_type,
1128
0
            .pack = pack,
1129
0
        }));
1130
0
    }
1131
1132
0
    if ((desc->flags & AV_PIX_FMT_FLAG_BE) != NATIVE_ENDIAN_FLAG) {
1133
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1134
0
            .op   = SWS_OP_SWAP_BYTES,
1135
0
            .type = raw_type,
1136
0
        }));
1137
0
    }
1138
1139
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1140
0
        .op   = SWS_OP_WRITE,
1141
0
        .type = raw_type,
1142
0
        .rw   = rw_op,
1143
0
    }));
1144
0
    return 0;
1145
0
}
1146
1147
static inline AVRational av_neg_q(AVRational x)
1148
0
{
1149
0
    return (AVRational) { -x.num, x.den };
1150
0
}
1151
1152
static SwsLinearOp fmt_encode_range(const SwsFormat fmt, bool *incomplete)
1153
0
{
1154
0
    SwsLinearOp c = { .m = {
1155
0
        { Q1, Q0, Q0, Q0, Q0 },
1156
0
        { Q0, Q1, Q0, Q0, Q0 },
1157
0
        { Q0, Q0, Q1, Q0, Q0 },
1158
0
        { Q0, Q0, Q0, Q1, Q0 },
1159
0
    }};
1160
1161
0
    const int depth0 = fmt.desc->comp[0].depth;
1162
0
    const int depth1 = fmt.desc->comp[1].depth;
1163
0
    const int depth2 = fmt.desc->comp[2].depth;
1164
0
    const int depth3 = fmt.desc->comp[3].depth;
1165
1166
0
    if (fmt.desc->flags & AV_PIX_FMT_FLAG_FLOAT)
1167
0
        return c; /* floats are directly output as-is */
1168
1169
0
    if (fmt.csp == AVCOL_SPC_RGB || (fmt.desc->flags & AV_PIX_FMT_FLAG_XYZ)) {
1170
0
        c.m[0][0] = Q((1 << depth0) - 1);
1171
0
        c.m[1][1] = Q((1 << depth1) - 1);
1172
0
        c.m[2][2] = Q((1 << depth2) - 1);
1173
0
    } else if (fmt.range == AVCOL_RANGE_JPEG) {
1174
        /* Full range YUV */
1175
0
        c.m[0][0] = Q((1 << depth0) - 1);
1176
0
        if (fmt.desc->nb_components >= 3) {
1177
            /* This follows the ITU-R convention, which is slightly different
1178
             * from the JFIF convention. */
1179
0
            c.m[1][1] = Q((1 << depth1) - 1);
1180
0
            c.m[2][2] = Q((1 << depth2) - 1);
1181
0
            c.m[1][4] = Q(1 << (depth1 - 1));
1182
0
            c.m[2][4] = Q(1 << (depth2 - 1));
1183
0
        }
1184
0
    } else {
1185
        /* Limited range YUV */
1186
0
        if (fmt.range == AVCOL_RANGE_UNSPECIFIED)
1187
0
            *incomplete = true;
1188
0
        c.m[0][0] = Q(219 << (depth0 - 8));
1189
0
        c.m[0][4] = Q( 16 << (depth0 - 8));
1190
0
        if (fmt.desc->nb_components >= 3) {
1191
0
            c.m[1][1] = Q(224 << (depth1 - 8));
1192
0
            c.m[2][2] = Q(224 << (depth2 - 8));
1193
0
            c.m[1][4] = Q(128 << (depth1 - 8));
1194
0
            c.m[2][4] = Q(128 << (depth2 - 8));
1195
0
        }
1196
0
    }
1197
1198
0
    if (fmt.desc->flags & AV_PIX_FMT_FLAG_ALPHA) {
1199
0
        const bool is_ya = fmt.desc->nb_components == 2;
1200
0
        c.m[3][3] = Q((1 << (is_ya ? depth1 : depth3)) - 1);
1201
0
    }
1202
1203
0
    if (fmt.format == AV_PIX_FMT_MONOWHITE) {
1204
        /* This format is inverted, 0 = white, 1 = black */
1205
0
        c.m[0][4] = av_add_q(c.m[0][4], c.m[0][0]);
1206
0
        c.m[0][0] = av_neg_q(c.m[0][0]);
1207
0
    }
1208
1209
0
    c.mask = ff_sws_linear_mask(c);
1210
0
    return c;
1211
0
}
1212
1213
static SwsLinearOp fmt_decode_range(const SwsFormat fmt, bool *incomplete)
1214
0
{
1215
0
    SwsLinearOp c = fmt_encode_range(fmt, incomplete);
1216
1217
    /* Invert main diagonal + offset: x = s * y + k  ==>  y = (x - k) / s */
1218
0
    for (int i = 0; i < 4; i++) {
1219
0
        c.m[i][i] = av_inv_q(c.m[i][i]);
1220
0
        c.m[i][4] = av_mul_q(c.m[i][4], av_neg_q(c.m[i][i]));
1221
0
    }
1222
1223
    /* Explicitly initialize alpha for sanity */
1224
0
    if (!(fmt.desc->flags & AV_PIX_FMT_FLAG_ALPHA))
1225
0
        c.m[3][4] = Q1;
1226
1227
0
    c.mask = ff_sws_linear_mask(c);
1228
0
    return c;
1229
0
}
1230
1231
static AVRational *generate_bayer_matrix(const int size_log2)
1232
0
{
1233
0
    const int size = 1 << size_log2;
1234
0
    const int num_entries = size * size;
1235
0
    AVRational *m = av_refstruct_allocz(sizeof(*m) * num_entries);
1236
0
    av_assert1(size_log2 < 16);
1237
0
    if (!m)
1238
0
        return NULL;
1239
1240
    /* Start with a 1x1 matrix */
1241
0
    m[0] = Q0;
1242
1243
    /* Generate three copies of the current, appropriately scaled and offset */
1244
0
    for (int sz = 1; sz < size; sz <<= 1) {
1245
0
        const int den = 4 * sz * sz;
1246
0
        for (int y = 0; y < sz; y++) {
1247
0
            for (int x = 0; x < sz; x++) {
1248
0
                const AVRational cur = m[y * size + x];
1249
0
                m[(y + sz) * size + x + sz] = av_add_q(cur, av_make_q(1, den));
1250
0
                m[(y     ) * size + x + sz] = av_add_q(cur, av_make_q(2, den));
1251
0
                m[(y + sz) * size + x     ] = av_add_q(cur, av_make_q(3, den));
1252
0
            }
1253
0
        }
1254
0
    }
1255
1256
    /**
1257
     * To correctly round, we need to evenly distribute the result on [0, 1),
1258
     * giving an average value of 1/2.
1259
     *
1260
     * After the above construction, we have a matrix with average value:
1261
     *   [ 0/N + 1/N + 2/N + ... (N-1)/N ] / N = (N-1)/(2N)
1262
     * where N = size * size is the total number of entries.
1263
     *
1264
     * To make the average value equal to 1/2 = N/(2N), add a bias of 1/(2N).
1265
     */
1266
0
    for (int i = 0; i < num_entries; i++)
1267
0
        m[i] = av_add_q(m[i], av_make_q(1, 2 * num_entries));
1268
1269
0
    return m;
1270
0
}
1271
1272
static bool trc_is_hdr(enum AVColorTransferCharacteristic trc)
1273
0
{
1274
0
    static_assert(AVCOL_TRC_NB == 19, "Update this list when adding TRCs");
1275
0
    static_assert(AVCOL_TRC_EXT_NB == 257, "Update this list when adding TRCs");
1276
0
    switch (trc) {
1277
0
    case AVCOL_TRC_LOG:
1278
0
    case AVCOL_TRC_LOG_SQRT:
1279
0
    case AVCOL_TRC_V_LOG:
1280
0
    case AVCOL_TRC_SMPTEST2084:
1281
0
    case AVCOL_TRC_ARIB_STD_B67:
1282
0
        return true;
1283
0
    default:
1284
0
        return false;
1285
0
    }
1286
0
}
1287
1288
static int fmt_dither(SwsContext *ctx, SwsOpList *ops,
1289
                      const SwsPixelType type, const SwsFormat fmt)
1290
0
{
1291
0
    SwsDither mode = ctx->dither;
1292
0
    SwsDitherOp dither;
1293
1294
0
    if (mode == SWS_DITHER_AUTO) {
1295
        /* Visual threshold of perception: 12 bits for SDR, 14 bits for HDR */
1296
0
        const int jnd_bits = trc_is_hdr(fmt.color.trc) ? 14 : 12;
1297
0
        const int bpc = fmt.desc->comp[0].depth;
1298
0
        mode = bpc >= jnd_bits ? SWS_DITHER_NONE : SWS_DITHER_BAYER;
1299
0
    }
1300
1301
0
    switch (mode) {
1302
0
    case SWS_DITHER_NONE:
1303
0
        if (ctx->flags & SWS_ACCURATE_RND) {
1304
            /* Add constant 0.5 for correct rounding */
1305
0
            AVRational *bias = av_refstruct_allocz(sizeof(*bias));
1306
0
            if (!bias)
1307
0
                return AVERROR(ENOMEM);
1308
0
            *bias = (AVRational) {1, 2};
1309
0
            return ff_sws_op_list_append(ops, &(SwsOp) {
1310
0
                .op   = SWS_OP_DITHER,
1311
0
                .type = type,
1312
0
                .dither.matrix = bias,
1313
0
            });
1314
0
        } else {
1315
0
            return 0; /* No-op */
1316
0
        }
1317
0
    case SWS_DITHER_BAYER:
1318
        /* Hardcode 16x16 matrix for now; in theory we could adjust this
1319
         * based on the expected level of precision in the output, since lower
1320
         * bit depth outputs can suffice with smaller dither matrices; however
1321
         * in practice we probably want to use error diffusion for such low bit
1322
         * depths anyway */
1323
0
        dither.size_log2 = 4;
1324
0
        dither.matrix = generate_bayer_matrix(dither.size_log2);
1325
0
        if (!dither.matrix)
1326
0
            return AVERROR(ENOMEM);
1327
0
        return ff_sws_op_list_append(ops, &(SwsOp) {
1328
0
            .op     = SWS_OP_DITHER,
1329
0
            .type   = type,
1330
0
            .dither = dither,
1331
0
        });
1332
0
    case SWS_DITHER_ED:
1333
0
    case SWS_DITHER_A_DITHER:
1334
0
    case SWS_DITHER_X_DITHER:
1335
0
        return AVERROR(ENOTSUP);
1336
1337
0
    case SWS_DITHER_NB:
1338
0
        break;
1339
0
    }
1340
1341
0
    av_unreachable("Invalid dither mode");
1342
0
    return AVERROR(EINVAL);
1343
0
}
1344
1345
static inline SwsLinearOp
1346
linear_mat3(const AVRational m00, const AVRational m01, const AVRational m02,
1347
            const AVRational m10, const AVRational m11, const AVRational m12,
1348
            const AVRational m20, const AVRational m21, const AVRational m22)
1349
0
{
1350
0
    SwsLinearOp c = {{
1351
0
        { m00, m01, m02, Q0, Q0 },
1352
0
        { m10, m11, m12, Q0, Q0 },
1353
0
        { m20, m21, m22, Q0, Q0 },
1354
0
        {  Q0,  Q0,  Q0, Q1, Q0 },
1355
0
    }};
1356
1357
0
    c.mask = ff_sws_linear_mask(c);
1358
0
    return c;
1359
0
}
1360
1361
int ff_sws_decode_colors(SwsContext *ctx, SwsPixelType type,
1362
                         SwsOpList *ops, const SwsFormat fmt, bool *incomplete)
1363
0
{
1364
0
    const AVLumaCoefficients *c = av_csp_luma_coeffs_from_avcsp(fmt.csp);
1365
1366
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1367
0
        .op         = SWS_OP_CONVERT,
1368
0
        .type       = fmt_pixel_type(fmt.format),
1369
0
        .convert.to = type,
1370
0
    }));
1371
1372
    /* Decode pixel format into standardized range */
1373
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1374
0
        .type = type,
1375
0
        .op   = SWS_OP_LINEAR,
1376
0
        .lin  = fmt_decode_range(fmt, incomplete),
1377
0
    }));
1378
1379
    /* Final step, decode colorspace */
1380
0
    switch (fmt.csp) {
1381
0
    case AVCOL_SPC_RGB:
1382
0
        return 0;
1383
0
    case AVCOL_SPC_UNSPECIFIED:
1384
0
        c = av_csp_luma_coeffs_from_avcsp(AVCOL_SPC_BT470BG);
1385
0
        *incomplete = true;
1386
        /* fall through */
1387
0
    case AVCOL_SPC_FCC:
1388
0
    case AVCOL_SPC_BT470BG:
1389
0
    case AVCOL_SPC_SMPTE170M:
1390
0
    case AVCOL_SPC_BT709:
1391
0
    case AVCOL_SPC_SMPTE240M:
1392
0
    case AVCOL_SPC_BT2020_NCL: {
1393
0
        AVRational crg = av_sub_q(Q0, av_div_q(c->cr, c->cg));
1394
0
        AVRational cbg = av_sub_q(Q0, av_div_q(c->cb, c->cg));
1395
0
        AVRational m02 = av_mul_q(Q(2), av_sub_q(Q1, c->cr));
1396
0
        AVRational m21 = av_mul_q(Q(2), av_sub_q(Q1, c->cb));
1397
0
        AVRational m11 = av_mul_q(cbg, m21);
1398
0
        AVRational m12 = av_mul_q(crg, m02);
1399
1400
0
        return ff_sws_op_list_append(ops, &(SwsOp) {
1401
0
            .type = type,
1402
0
            .op   = SWS_OP_LINEAR,
1403
0
            .lin  = linear_mat3(
1404
0
                Q1,  Q0, m02,
1405
0
                Q1, m11, m12,
1406
0
                Q1, m21,  Q0
1407
0
            ),
1408
0
        });
1409
0
    }
1410
1411
0
    case AVCOL_SPC_YCGCO:
1412
0
        return ff_sws_op_list_append(ops, &(SwsOp) {
1413
0
            .type = type,
1414
0
            .op   = SWS_OP_LINEAR,
1415
0
            .lin  = linear_mat3(
1416
0
                Q1, Q(-1), Q( 1),
1417
0
                Q1, Q( 1), Q( 0),
1418
0
                Q1, Q(-1), Q(-1)
1419
0
            ),
1420
0
        });
1421
1422
0
    case AVCOL_SPC_BT2020_CL:
1423
0
    case AVCOL_SPC_SMPTE2085:
1424
0
    case AVCOL_SPC_CHROMA_DERIVED_NCL:
1425
0
    case AVCOL_SPC_CHROMA_DERIVED_CL:
1426
0
    case AVCOL_SPC_ICTCP:
1427
0
    case AVCOL_SPC_IPT_C2:
1428
0
    case AVCOL_SPC_YCGCO_RE:
1429
0
    case AVCOL_SPC_YCGCO_RO:
1430
0
        return AVERROR(ENOTSUP);
1431
1432
0
    case AVCOL_SPC_RESERVED:
1433
0
        return AVERROR(EINVAL);
1434
1435
0
    case AVCOL_SPC_NB:
1436
0
        break;
1437
0
    }
1438
1439
0
    av_unreachable("Corrupt AVColorSpace value?");
1440
0
    return AVERROR(EINVAL);
1441
0
}
1442
1443
int ff_sws_encode_colors(SwsContext *ctx, SwsPixelType type,
1444
                         SwsOpList *ops, const SwsFormat fmt, bool *incomplete)
1445
0
{
1446
0
    const AVLumaCoefficients *c = av_csp_luma_coeffs_from_avcsp(fmt.csp);
1447
1448
0
    switch (fmt.csp) {
1449
0
    case AVCOL_SPC_RGB:
1450
0
        break;
1451
0
    case AVCOL_SPC_UNSPECIFIED:
1452
0
        c = av_csp_luma_coeffs_from_avcsp(AVCOL_SPC_BT470BG);
1453
0
        *incomplete = true;
1454
        /* fall through */
1455
0
    case AVCOL_SPC_FCC:
1456
0
    case AVCOL_SPC_BT470BG:
1457
0
    case AVCOL_SPC_SMPTE170M:
1458
0
    case AVCOL_SPC_BT709:
1459
0
    case AVCOL_SPC_SMPTE240M:
1460
0
    case AVCOL_SPC_BT2020_NCL: {
1461
0
        AVRational cb1 = av_sub_q(c->cb, Q1);
1462
0
        AVRational cr1 = av_sub_q(c->cr, Q1);
1463
0
        AVRational m20 = av_make_q(1,2);
1464
0
        AVRational m10 = av_mul_q(m20, av_div_q(c->cr, cb1));
1465
0
        AVRational m11 = av_mul_q(m20, av_div_q(c->cg, cb1));
1466
0
        AVRational m21 = av_mul_q(m20, av_div_q(c->cg, cr1));
1467
0
        AVRational m22 = av_mul_q(m20, av_div_q(c->cb, cr1));
1468
1469
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1470
0
            .type = type,
1471
0
            .op   = SWS_OP_LINEAR,
1472
0
            .lin  = linear_mat3(
1473
0
                c->cr, c->cg, c->cb,
1474
0
                m10,     m11,   m20,
1475
0
                m20,     m21,   m22
1476
0
            ),
1477
0
        }));
1478
0
        break;
1479
0
    }
1480
1481
0
    case AVCOL_SPC_YCGCO:
1482
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1483
0
            .type = type,
1484
0
            .op   = SWS_OP_LINEAR,
1485
0
            .lin  = linear_mat3(
1486
0
                av_make_q( 1, 4), av_make_q(1, 2), av_make_q( 1, 4),
1487
0
                av_make_q( 1, 2), av_make_q(0, 1), av_make_q(-1, 2),
1488
0
                av_make_q(-1, 4), av_make_q(1, 2), av_make_q(-1, 4)
1489
0
            ),
1490
0
        }));
1491
0
        break;
1492
1493
0
    case AVCOL_SPC_BT2020_CL:
1494
0
    case AVCOL_SPC_SMPTE2085:
1495
0
    case AVCOL_SPC_CHROMA_DERIVED_NCL:
1496
0
    case AVCOL_SPC_CHROMA_DERIVED_CL:
1497
0
    case AVCOL_SPC_ICTCP:
1498
0
    case AVCOL_SPC_IPT_C2:
1499
0
    case AVCOL_SPC_YCGCO_RE:
1500
0
    case AVCOL_SPC_YCGCO_RO:
1501
0
        return AVERROR(ENOTSUP);
1502
1503
0
    case AVCOL_SPC_RESERVED:
1504
0
    case AVCOL_SPC_NB:
1505
0
        return AVERROR(EINVAL);
1506
0
    }
1507
1508
0
    RET(ff_sws_op_list_append(ops, &(SwsOp) {
1509
0
        .type = type,
1510
0
        .op   = SWS_OP_LINEAR,
1511
0
        .lin  = fmt_encode_range(fmt, incomplete),
1512
0
    }));
1513
1514
0
    if (!(fmt.desc->flags & AV_PIX_FMT_FLAG_FLOAT)) {
1515
0
        SwsConst range = {0};
1516
1517
0
        const bool is_ya = fmt.desc->nb_components == 2;
1518
0
        for (int i = 0; i < fmt.desc->nb_components; i++) {
1519
            /* Clamp to legal pixel range */
1520
0
            const int idx = i * (is_ya ? 3 : 1);
1521
0
            range.q4[idx] = Q((1 << fmt.desc->comp[i].depth) - 1);
1522
0
        }
1523
1524
0
        RET(fmt_dither(ctx, ops, type, fmt));
1525
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1526
0
            .op   = SWS_OP_MAX,
1527
0
            .type = type,
1528
0
            .c.q4 = { Q0, Q0, Q0, Q0 },
1529
0
        }));
1530
1531
0
        RET(ff_sws_op_list_append(ops, &(SwsOp) {
1532
0
            .op   = SWS_OP_MIN,
1533
0
            .type = type,
1534
0
            .c    = range,
1535
0
        }));
1536
0
    }
1537
1538
0
    return ff_sws_op_list_append(ops, &(SwsOp) {
1539
0
        .type       = type,
1540
0
        .op         = SWS_OP_CONVERT,
1541
0
        .convert.to = fmt_pixel_type(fmt.format),
1542
0
    });
1543
0
}
1544
1545
#endif /* CONFIG_UNSTABLE */