UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
src
color.h
Go to the documentation of this file.
1
5
/*
6
* Copyright (c) 2022 CESNET, z. s. p. o.
7
* All rights reserved.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, is permitted provided that the following conditions
11
* are met:
12
*
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
*
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
*
20
* 3. Neither the name of CESNET nor the names of its contributors may be
21
* used to endorse or promote products derived from this software without
22
* specific prior written permission.
23
*
24
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
25
* "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
26
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
28
* EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
*/
37
38
#ifndef COLOR_H_CD26B745_C30E_4DA3_8280_C9492B6BFF25
39
#define COLOR_H_CD26B745_C30E_4DA3_8280_C9492B6BFF25
40
41
#ifdef __cplusplus
42
#include <cstdint>
43
#else
44
#include <assert.h>
45
#include <stdint.h>
46
#endif
47
48
#include "
utils/macros.h
"
// CLAMP
49
50
/* @brief Color space coedfficients - RGB full range to YCbCr bt. 709 limited range
51
*
52
* RGB should use SDI full range [1<<(depth-8)..255<<(depth-8)-1], see [limits]
53
*
54
* Scaled by 1<<COMP_BASE, footroom 16/255, headroom 235/255 (luma), 240/255 (chroma); limits [2^(depth-8)..255*2^(depth-8)-1]
55
* matrix Y = [ 0.182586, 0.614231, 0.062007; -0.100643, -0.338572, 0.4392157; 0.4392157, -0.398942, -0.040274 ]
56
* * [coefficients]: https://gist.github.com/yohhoy/dafa5a47dade85d8b40625261af3776a "Rec. 709 coefficients"
57
* * [limits]: https://tech.ebu.ch/docs/r/r103.pdf "SDI limits"
58
*
59
* @ingroup lavc_video_conversions
60
*
61
* @todo
62
* Use this transformations in all conversions.
63
* @{
64
*/
65
typedef
int32_t
comp_type_t
;
// int32_t provides much better performance than int_fast32_t
66
#define COMP_BASE (sizeof(comp_type_t) == 4 ? 14 : 18)
// computation will be less precise when comp_type_t is 32 bit
67
static_assert
(
sizeof
(
comp_type_t
) * 8 >=
COMP_BASE
+ 18,
"comp_type_t not wide enough (we are computing in up to 16 bits!)"
);
68
69
#define KG(kr,kb) (1.-kr-kb)
70
#ifdef YCBCR_FULL
71
#define C_EPS 0
// prevent under/overflows when there is no clip
72
#define Y_LIMIT(out_depth) 1.0
73
#define CBCR_LIMIT(out_depth) 1.0
74
#else
75
#define C_EPS 0.5
76
#define Y_LIMIT(out_depth) \
77
(219. * (1 << ((out_depth) - 8)) / ((1 << (out_depth)) - 1))
78
#define CBCR_LIMIT(out_depth) \
79
(224. * (1 << ((out_depth) - 8)) / ((1 << (out_depth)) - 1))
80
#endif
// !defined YCBCR_FULL
81
82
#define KR_709 .212639
83
#define KB_709 .072192
84
#define KR_2020 .262700
85
#define KB_2020 .059302
86
#define KR_P3 .228975
87
#define KB_P3 .079287
88
89
#define KG_709 KG(KR_709,KB_709)
90
#define D (2.*(KR_709+KG_709))
91
#define E (2.*(1.-KR_709))
92
93
#define Y_R(out_depth) \
94
((comp_type_t) (((KR_709 * Y_LIMIT(out_depth)) * (1 << COMP_BASE)) + \
95
C_EPS))
96
#define Y_G(out_depth) \
97
((comp_type_t) (((KG_709 * Y_LIMIT(out_depth)) * (1 << COMP_BASE)) + \
98
C_EPS))
99
#define Y_B(out_depth) \
100
((comp_type_t) (((KB_709 * Y_LIMIT(out_depth)) * (1 << COMP_BASE)) + \
101
C_EPS))
102
#define CB_R(out_depth) \
103
((comp_type_t) (((-KR_709 / D * CBCR_LIMIT(out_depth)) * \
104
(1 << COMP_BASE)) - C_EPS))
105
#define CB_G(out_depth) \
106
((comp_type_t) (((-KG_709 / D * CBCR_LIMIT(out_depth)) * \
107
(1 << COMP_BASE)) - C_EPS))
108
#define CB_B(out_depth) \
109
((comp_type_t) ((((1 - KB_709) / D * CBCR_LIMIT(out_depth)) * \
110
(1 << COMP_BASE)) + C_EPS))
111
#define CR_R(out_depth) \
112
((comp_type_t) ((((1 - KR_709) / E * CBCR_LIMIT(out_depth)) * \
113
(1 << COMP_BASE)) - C_EPS))
114
#define CR_G(out_depth) \
115
((comp_type_t) (((-KG_709 / E * CBCR_LIMIT(out_depth)) * \
116
(1 << COMP_BASE)) - C_EPS))
117
#define CR_B(out_depth) \
118
((comp_type_t) (((-KB_709 / E * CBCR_LIMIT(out_depth)) * \
119
(1 << COMP_BASE)) + C_EPS))
120
#define RGB_TO_Y_709_SCALED(out_depth, r, g, b) \
121
((r) * Y_R(out_depth) + (g) * Y_G(out_depth) + (b) * Y_B(out_depth))
122
#define RGB_TO_CB_709_SCALED(out_depth, r, g, b) \
123
((r) * CB_R(out_depth) + (g) * CB_G(out_depth) + (b) * CB_B(out_depth))
124
#define RGB_TO_CR_709_SCALED(out_depth, r, g, b) \
125
((r) * CR_R(out_depth) + (g) * CR_G(out_depth) + (b) * CR_B(out_depth))
126
#ifdef YCBCR_FULL
127
#define LIMIT_LO(depth) 0
128
#define LIMIT_HI_Y(depth) ((1<<(depth))-1)
129
#define LIMIT_HI_CBCR(depth) ((1<<(depth))-1)
130
#else
131
#define LIMIT_LO(depth) (1<<((depth)-4))
132
#define LIMIT_HI_Y(depth) (235 * (1<<((depth)-8)))
133
#define LIMIT_HI_CBCR(depth) (240 * (1<<((depth)-8)))
134
#endif
135
// TODO: remove
136
#define CLAMP_LIMITED_Y(val, depth) (val)
137
#define CLAMP_LIMITED_CBCR(val, depth) (val)
138
139
#define C_SIGN(x) ((x) > 0 ? 1. : -1.)
140
#define SCALED(x) ((comp_type_t) (((x) * (1<<COMP_BASE)) + C_SIGN(x) * C_EPS))
141
#define R_CR(in_depth, kr, kb) ((2. * (1. - (kr))) / CBCR_LIMIT(in_depth))
142
#define G_CB(in_depth, kr, kb) \
143
((-(kb) * (2. * ((kr) + KG(kr, kb))) / KG(kr, kb)) / \
144
CBCR_LIMIT(in_depth))
145
#define G_CR(in_depth, kr, kb) \
146
((-(kr) * (2. * (1. - (kr))) / KG(kr, kb)) / CBCR_LIMIT(in_depth))
147
#define B_CB(in_depth, kr, kb) \
148
((2. * ((kr) + KG(kr, kb))) / CBCR_LIMIT(in_depth))
149
150
#define Y_LIMIT_INV(in_depth) (1./Y_LIMIT(in_depth))
151
#define Y_SCALE(in_depth) \
152
SCALED(Y_LIMIT_INV(in_depth))
// precomputed value, Y multiplier is same
153
// for all channels
154
#define YCBCR_TO_R_709_SCALED(in_depth, y, cb, cr) \
155
((y)
/* * r_y */
+ (cr) * SCALED(R_CR(in_depth, KR_709, KB_709)))
156
#define YCBCR_TO_G_709_SCALED(in_depth, y, cb, cr) \
157
((y)
/* * g_y */
+ (cb) * SCALED(G_CB(in_depth, KR_709, KB_709)) + \
158
(cr) * SCALED(G_CR(in_depth, KR_709, KB_709)))
159
#define YCBCR_TO_B_709_SCALED(in_depth, y, cb, cr) \
160
((y)
/* * b_y */
+ (cb) * SCALED(B_CB(in_depth, KR_709, KB_709)))
161
#define FULL_FOOT(depth) (1 << ((depth) - 8))
162
#define FULL_HEAD(depth) ((255<<((depth)-8))-1)
163
#define CLAMP_FULL(val, depth) CLAMP((val), FULL_FOOT(depth), FULL_HEAD(depth))
164
165
// new API
166
struct
color_coeffs
{
167
short
y_r
,
y_g
,
y_b
;
168
short
cb_r
,
cb_g
,
cb_b
;
169
short
cr_r
,
cr_g
,
cr_b
;
170
171
short
r_cr
,
g_cb
,
g_cr
;
172
int
b_cb
;
// b_cb is 34712 so doesn't fit to 16-bit short
173
};
174
const
struct
color_coeffs
*
get_color_coeffs
(
int
ycbcr_bit_depth);
175
#define RGB_TO_Y(t, r, g, b) ((r) * (t)->y_r + (g) * (t)->y_g + (b) * (t)->y_b)
176
#define RGB_TO_CB(t, r, g, b) \
177
((r) * (t)->cb_r + (g) * (t)->cb_g + (b) * (t)->cb_b)
178
#define RGB_TO_CR(t, r, g, b) \
179
((r) * (t)->cr_r + (g) * (t)->cr_g + (b) * (t)->cr_b)
181
#define YCBCR_TO_R(t, y_scaled, cb, cr) ((y) + (cr) * (t)->r_cr)
182
#define YCBCR_TO_G(t, y_scaled, cb, cr) \
183
((y) + (cb) * (t)->g_cb + (cr) * (t)->g_cr)
184
#define YCBCR_TO_B(t, y_scaled, cb, cr) ((y) + (cb) * (t)->b_cb)
185
189
#define FORMAT_RGBA(r, g, b, rshift, gshift, bshift, alpha_mask, depth) \
190
((alpha_mask) | (CLAMP_FULL((r), (depth)) << (rshift) | \
191
CLAMP_FULL((g), (depth)) << (gshift) | \
192
CLAMP_FULL((b), (depth)) << (bshift)))
194
195
#define MK_MONOCHROME(val) \
196
FORMAT_RGBA((val), (val), (val), 0, 8, 16, 0xFF000000, 8)
197
#define RGBA_BLACK MK_MONOCHROME(0x00)
198
#define RGBA_GRAY MK_MONOCHROME(0x80)
199
#define RGBA_WHITE MK_MONOCHROME(0xFF)
200
201
#endif
// !defined COLOR_H_CD26B745_C30E_4DA3_8280_C9492B6BFF25
comp_type_t
int32_t comp_type_t
Definition
color.h:65
COMP_BASE
#define COMP_BASE
Definition
color.h:66
get_color_coeffs
const struct color_coeffs * get_color_coeffs(int ycbcr_bit_depth)
Definition
color.c:58
macros.h
color_coeffs
Definition
color.h:166
color_coeffs::y_g
short y_g
Definition
color.h:167
color_coeffs::y_b
short y_b
Definition
color.h:167
color_coeffs::cr_b
short cr_b
Definition
color.h:169
color_coeffs::cr_r
short cr_r
Definition
color.h:169
color_coeffs::g_cr
short g_cr
Definition
color.h:171
color_coeffs::r_cr
short r_cr
Definition
color.h:171
color_coeffs::y_r
short y_r
Definition
color.h:167
color_coeffs::b_cb
int b_cb
Definition
color.h:172
color_coeffs::cr_g
short cr_g
Definition
color.h:169
color_coeffs::g_cb
short g_cb
Definition
color.h:171
color_coeffs::cb_b
short cb_b
Definition
color.h:168
color_coeffs::cb_g
short cb_g
Definition
color.h:168
color_coeffs::cb_r
short cb_r
Definition
color.h:168
Generated on Wed Sep 25 2024 14:27:15 for UltraGrid by
1.12.0