Skip to content

Commit f652c3f

Browse files
committed
Convert RGB values to linear if the frame TRC is linear
1 parent 4c9c093 commit f652c3f

15 files changed

Lines changed: 160 additions & 47 deletions

src/framework/mlt.vers

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,4 +679,5 @@ MLT_7.34.0 {
679679
mlt_image_color_pri_id;
680680
mlt_image_default_trc;
681681
mlt_image_default_primaries;
682+
mlt_color_convert_trc;
682683
} MLT_7.32.0;

src/framework/mlt_types.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* \file mlt_types.c
33
* \brief Mlt types helper functions
44
*
5-
* Copyright (C) 2023 Meltytech, LLC
5+
* Copyright (C) 2023-2025 Meltytech, LLC
66
*
77
* This library is free software; you can redistribute it and/or
88
* modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,9 @@
2121

2222
#include "mlt_types.h"
2323

24+
#include "mlt_image.h"
25+
26+
#include <math.h>
2427
#include <stdlib.h>
2528
#include <string.h>
2629

@@ -63,3 +66,36 @@ mlt_deinterlacer mlt_deinterlacer_id(const char *name)
6366
}
6467
return mlt_deinterlacer_invalid;
6568
}
69+
70+
uint8_t srgb_to_linear(uint8_t value)
71+
{
72+
// Normalize the 8-bit value to the [0.0, 1.0] range
73+
double factor = (double) value / 255.0;
74+
if (factor < 0.04045) {
75+
factor *= 0.0773993808;
76+
} else {
77+
factor = pow(factor * 0.9478672986 + 0.0521327014, 2.4);
78+
}
79+
// Map back to 0-255 range
80+
double linear_value = round((double) 255 * factor);
81+
return (uint8_t) CLAMP(linear_value, 0.0, 255.0);
82+
}
83+
84+
/** Convert a standard sRGB color value to the specified colorspace.
85+
*
86+
* \param color a standard sRGB color value
87+
* \param trc_name a string representing the TRC to convert to
88+
* \return the converted color
89+
*/
90+
91+
mlt_color mlt_color_convert_trc(mlt_color color, const char *trc_name)
92+
{
93+
mlt_color_trc trc = mlt_image_color_trc_id(trc_name);
94+
// Only linear is supported for now.
95+
if (trc == mlt_color_trc_linear) {
96+
color.r = srgb_to_linear(color.r);
97+
color.g = srgb_to_linear(color.g);
98+
color.b = srgb_to_linear(color.b);
99+
}
100+
return color;
101+
}

src/framework/mlt_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ MLT_EXPORT char *strptime(const char *buf, const char *fmt, struct tm *tm);
358358

359359
MLT_EXPORT const char *mlt_deinterlacer_name(mlt_deinterlacer method);
360360
MLT_EXPORT mlt_deinterlacer mlt_deinterlacer_id(const char *name);
361+
MLT_EXPORT mlt_color mlt_color_convert_trc(mlt_color color, const char *trc_name);
361362

362363
#ifdef __cplusplus
363364
}

src/modules/plus/filter_chroma.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* filter_chroma.c -- Maps a chroma key to the alpha channel
3-
* Copyright (C) 2007-2022 Meltytech, LLC
3+
* Copyright (C) 2007-2025 Meltytech, LLC
44
* Author: Charles Yates <charles.yates@gmail.com>
55
*
66
* This program is free software; you can redistribute it and/or modify
@@ -62,6 +62,8 @@ static int filter_get_image(mlt_frame frame,
6262
length);
6363
mlt_color key_val
6464
= mlt_properties_anim_get_color(MLT_FILTER_PROPERTIES(this), "key", position, length);
65+
key_val = mlt_color_convert_trc(key_val,
66+
mlt_properties_get(MLT_FRAME_PROPERTIES(frame), "color_trc"));
6567
uint8_t u, v;
6668

6769
RGB2UV_601_SCALED(key_val.r, key_val.g, key_val.b, u, v);

src/modules/plus/filter_chroma_hold.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* filter_chroma.c -- Maps a chroma key to the alpha channel
3-
* Copyright (C) 2008-2022 Meltytech, LLC
3+
* Copyright (C) 2008-2025 Meltytech, LLC
44
*
55
* This program is free software; you can redistribute it and/or modify
66
* it under the terms of the GNU Lesser General Public License as published by
@@ -59,6 +59,8 @@ static int filter_get_image(mlt_frame frame,
5959
length);
6060
mlt_color key_val
6161
= mlt_properties_anim_get_color(MLT_FILTER_PROPERTIES(this), "key", position, length);
62+
key_val = mlt_color_convert_trc(key_val,
63+
mlt_properties_get(MLT_FRAME_PROPERTIES(frame), "color_trc"));
6264
uint8_t r = key_val.r;
6365
uint8_t g = key_val.g;
6466
uint8_t b = key_val.b;

src/modules/qt/filter_audiolevelgraph.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ static void convert_levels(mlt_filter filter, mlt_frame frame, int channels, flo
110110
static void draw_levels(mlt_filter filter, mlt_frame frame, QImage *qimg, int width, int height)
111111
{
112112
mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter);
113+
mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame);
113114
mlt_position position = mlt_filter_get_position(filter, frame);
114115
mlt_position length = mlt_filter_get_length2(filter, frame);
115116
mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter));
@@ -133,7 +134,7 @@ static void draw_levels(mlt_filter filter, mlt_frame frame, QImage *qimg, int wi
133134
* scale;
134135
int segment_width = mlt_properties_anim_get_int(filter_properties, "thickness", position, length)
135136
* scale;
136-
QVector<QColor> colors = get_graph_colors(filter_properties, position, length);
137+
QVector<QColor> colors = get_graph_colors(filter_properties, frame_properties, position, length);
137138

138139
QRectF r(rect.x, rect.y, rect.w, rect.h);
139140
QPainter p(qimg);
@@ -143,13 +144,13 @@ static void draw_levels(mlt_filter filter, mlt_frame frame, QImage *qimg, int wi
143144
r.setHeight(r.height() / 2.0);
144145
}
145146

146-
setup_graph_painter(p, r, filter_properties, position, length);
147-
setup_graph_pen(p, r, filter_properties, scale, position, length);
147+
setup_graph_painter(p, r, filter_properties, frame_properties, position, length);
148+
setup_graph_pen(p, r, filter_properties, frame_properties, scale, position, length);
148149

149150
int channels = mlt_properties_anim_get_int(filter_properties, "channels", position, length);
150151
if (channels == 0) {
151152
// "0" means use number of channels in the frame
152-
channels = mlt_properties_get_int(MLT_FRAME_PROPERTIES(frame), "audio_channels");
153+
channels = mlt_properties_get_int(frame_properties, "audio_channels");
153154
}
154155
if (channels == 0)
155156
channels = 1;

src/modules/qt/filter_audiospectrum.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ static void convert_fft_to_spectrum(mlt_filter filter,
181181
static void draw_spectrum(mlt_filter filter, mlt_frame frame, QImage *qimg, int width, int height)
182182
{
183183
mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter);
184+
mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame);
184185
mlt_position position = mlt_filter_get_position(filter, frame);
185186
mlt_position length = mlt_filter_get_length2(filter, frame);
186187
mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter));
@@ -206,7 +207,7 @@ static void draw_spectrum(mlt_filter filter, mlt_frame frame, QImage *qimg, int
206207
* scale;
207208
int segment_width = mlt_properties_anim_get_int(filter_properties, "thickness", position, length)
208209
* scale;
209-
QVector<QColor> colors = get_graph_colors(filter_properties, position, length);
210+
QVector<QColor> colors = get_graph_colors(filter_properties, frame_properties, position, length);
210211

211212
QRectF r(rect.x, rect.y, rect.w, rect.h);
212213
QPainter p(qimg);
@@ -216,8 +217,8 @@ static void draw_spectrum(mlt_filter filter, mlt_frame frame, QImage *qimg, int
216217
r.setHeight(r.height() / 2.0);
217218
}
218219

219-
setup_graph_painter(p, r, filter_properties, position, length);
220-
setup_graph_pen(p, r, filter_properties, scale, position, length);
220+
setup_graph_painter(p, r, filter_properties, frame_properties, position, length);
221+
setup_graph_pen(p, r, filter_properties, frame_properties, scale, position, length);
221222

222223
int bands = mlt_properties_anim_get_int(filter_properties, "bands", position, length);
223224
if (bands == 0) {

src/modules/qt/filter_audiowaveform.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ static void draw_waveforms(mlt_filter filter,
275275
int height)
276276
{
277277
mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter);
278+
mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame);
278279
mlt_position position = mlt_filter_get_position(filter, frame);
279280
mlt_position length = mlt_filter_get_length2(filter, frame);
280281
mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter));
@@ -299,7 +300,7 @@ static void draw_waveforms(mlt_filter filter,
299300

300301
QPainter p(qimg);
301302

302-
setup_graph_painter(p, r, filter_properties, position, length);
303+
setup_graph_painter(p, r, filter_properties, frame_properties, position, length);
303304

304305
if (show_channel == -1) // Combine all channels
305306
{
@@ -326,15 +327,15 @@ static void draw_waveforms(mlt_filter filter,
326327
// Divide the rectangle into smaller rectangles for each channel.
327328
c_rect.setY(r.y() + c_height * c);
328329
c_rect.setHeight(c_height);
329-
setup_graph_pen(p, c_rect, filter_properties, scale, position, length);
330+
setup_graph_pen(p, c_rect, filter_properties, frame_properties, scale, position, length);
330331
paint_waveform(p, c_rect, audio + c, samples, channels, fill);
331332
}
332333
} else if (show_channel > 0) { // Show one specific channel
333334
if (show_channel > channels) {
334335
// Sanity
335336
show_channel = 1;
336337
}
337-
setup_graph_pen(p, r, filter_properties, scale, position, length);
338+
setup_graph_pen(p, r, filter_properties, frame_properties, scale, position, length);
338339
paint_waveform(p, r, audio + show_channel - 1, samples, channels, fill);
339340
}
340341

src/modules/qt/filter_lightshow.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ static int filter_get_audio(mlt_frame frame,
122122
return 0;
123123
}
124124

125-
static void setup_pen(QPainter &p, QRect &rect, mlt_properties filter_properties)
125+
static void setup_pen(QPainter &p,
126+
QRect &rect,
127+
mlt_properties filter_properties,
128+
mlt_properties frame_properties)
126129
{
127130
QVector<QColor> colors;
128131
bool color_found = true;
@@ -133,6 +136,8 @@ static void setup_pen(QPainter &p, QRect &rect, mlt_properties filter_properties
133136
if (mlt_properties_exists(filter_properties, prop_name.toUtf8().constData())) {
134137
mlt_color mcolor = mlt_properties_get_color(filter_properties,
135138
prop_name.toUtf8().constData());
139+
mcolor = mlt_color_convert_trc(mcolor,
140+
mlt_properties_get(frame_properties, "color_trc"));
136141
colors.append(QColor(mcolor.r, mcolor.g, mcolor.b, mcolor.a));
137142
} else {
138143
color_found = false;
@@ -177,14 +182,18 @@ static void setup_pen(QPainter &p, QRect &rect, mlt_properties filter_properties
177182
p.setPen(QColor(0, 0, 0, 0)); // Clear pen
178183
}
179184

180-
static void draw_light(mlt_properties filter_properties, QImage *qimg, mlt_rect *rect, double mag)
185+
static void draw_light(mlt_properties filter_properties,
186+
mlt_properties frame_properties,
187+
QImage *qimg,
188+
mlt_rect *rect,
189+
double mag)
181190
{
182191
QPainter p(qimg);
183192
QRect r(rect->x, rect->y, rect->w, rect->h);
184193
p.setRenderHint(QPainter::Antialiasing);
185194
// Output transparency = input transparency
186195
p.setCompositionMode(QPainter::CompositionMode_SourceAtop);
187-
setup_pen(p, r, filter_properties);
196+
setup_pen(p, r, filter_properties, frame_properties);
188197
p.setOpacity(mag);
189198
p.drawRect(r);
190199
p.end();
@@ -235,7 +244,7 @@ static int filter_get_image(mlt_frame frame,
235244
if (!error) {
236245
QImage qimg(*width, *height, QImage::Format_ARGB32);
237246
convert_mlt_to_qimage(*image, &qimg, *width, *height, *format);
238-
draw_light(filter_properties, &qimg, &rect, mag);
247+
draw_light(filter_properties, frame_properties, &qimg, &rect, mag);
239248
convert_qimage_to_mlt(&qimg, *image, *width, *height);
240249
}
241250
} else {

src/modules/qt/filter_qtcrop.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ static int get_image(mlt_frame frame,
5454
QPainter painter(&bgImage);
5555
QPainterPath path;
5656
mlt_color color = mlt_properties_anim_get_color(properties, "color", position, length);
57+
color = mlt_color_convert_trc(color,
58+
mlt_properties_get(MLT_FRAME_PROPERTIES(frame), "color_trc"));
5759
double radius = mlt_properties_anim_get_double(properties, "radius", position, length);
5860

5961
painter.setRenderHints(QPainter::Antialiasing

0 commit comments

Comments
 (0)