76 #define OFFSET(x) offsetof(CurvesContext, x)
77 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
106 static const struct {
113 "0/1 0.129/1 0.466/0.498 0.725/0 1/0",
114 "0/1 0.109/1 0.301/0.498 0.517/0 1/0",
115 "0/1 0.098/1 0.235/0.498 0.423/0 1/0",
118 "0.25/0.156 0.501/0.501 0.686/0.745",
119 "0.25/0.188 0.38/0.501 0.745/0.815 1/0.815",
120 "0.231/0.094 0.709/0.874",
130 "0/0.11 0.42/0.51 1/0.95",
132 "0/0.22 0.49/0.44 1/0.8",
158 point->
x =
av_strtod(p, &p);
if (p && *p) p++;
159 point->
y =
av_strtod(p, &p);
if (p && *p) p++;
160 if (point->
x < 0 || point->
x > 1 || point->
y < 0 || point->
y > 1) {
162 "x and y must be in the [0;1] range.\n", point->
x, point->
y);
168 if ((
int)(last->
x * 255) >= (
int)(point->
x * 255)) {
170 "and (%f;%f) are too close from each other or not "
171 "strictly increasing on the x-axis\n",
172 last->
x, last->
y, point->
x, point->
y);
185 last->
x = last->
y = 0;
187 }
else if ((*points)->x != 0.) {
230 double (*matrix)[3] =
av_calloc(n,
sizeof(*matrix));
231 double *h =
av_malloc((n - 1) *
sizeof(*h));
234 if (!matrix || !h || !r) {
241 for (point = points; point; point = point->
next) {
243 h[i] = point->
x - xprev;
250 for (i = 1; i < n - 1; i++) {
251 double yp = point->
y,
254 r[i] = 6 * ((yn-yc)/h[i] - (yc-yp)/h[i-1]);
263 matrix[0][
MD] = matrix[n - 1][
MD] = 1;
264 for (i = 1; i < n - 1; i++) {
265 matrix[i][
BD] = h[i-1];
266 matrix[i][
MD] = 2 * (h[i-1] + h[i]);
267 matrix[i][
AD] = h[i];
271 for (i = 1; i <
n; i++) {
272 double den = matrix[i][
MD] - matrix[i][
BD] * matrix[i-1][
AD];
273 double k = den ? 1./den : 1.;
275 r[i] = (r[i] - matrix[i][
BD] * r[i - 1]) * k;
277 for (i = n - 2; i >= 0; i--)
278 r[i] = r[i] - matrix[i][
AD] * r[i + 1];
284 while (point->
next) {
285 double yc = point->
y;
286 double yn = point->
next->
y;
289 double b = (yn-yc)/h[i] - h[i]*r[i]/2. - h[i]*(r[i+1]-r[i])/6.;
290 double c = r[i] / 2.;
291 double d = (r[i+1] - r[i]) / (6.*h[i]);
294 int x_start = point->
x * 255;
295 int x_end = point->
next->
x * 255;
298 x_end >= 0 && x_end <= 255);
300 for (x = x_start; x <= x_end; x++) {
301 double xx = (x - x_start) * 1/255.;
302 double yy = a + b*xx + c*xx*xx + d*xx*xx*xx;
303 y[
x] = av_clipf(yy, 0, 1) * 255;
325 static const int comp_ids[] = {3, 0, 1, 2};
333 #define READ16(dst) do { \
335 ret = AVERROR_INVALIDDATA; \
338 dst = AV_RB16(buf); \
349 for (n = 0; n < nb_points; n++) {
353 av_bprintf(&ptstr,
"%f/%f ", x / 255., y / 255.);
360 i, comp_ids[i], nb_points, *pts);
386 for (i = 0; i <
NB_COMP; i++) {
401 #define SET_COMP_IF_NOT_SET(n, name) do { \
402 if (!pts[n] && curves_presets[curves->preset].name) { \
403 pts[n] = av_strdup(curves_presets[curves->preset].name); \
405 return AVERROR(ENOMEM); \
414 for (i = 0; i <
NB_COMP + 1; i++) {
425 for (j = 0; j < 256; j++)
430 for (i = 0; i <
NB_COMP; i++) {
431 struct keypoint *point = comp_points[i];
439 for (j = 0; j < 256; j++)
445 for (i = 0; i < NB_COMP + 1; i++) {
446 struct keypoint *point = comp_points[i];
489 const int direct = out ==
in;
490 const int step = curves->
step;
495 const int slice_start = (in->
height * jobnr ) / nb_jobs;
500 for (y = slice_start; y <
slice_end; y++) {
501 for (x = 0; x < in->
width * step; x += step) {
502 dst[x +
r] = curves->
graph[
R][src[x +
r]];
503 dst[x +
g] = curves->
graph[
G][src[x +
g]];
504 dst[x +
b] = curves->
graph[
B][src[x +
b]];
505 if (!direct && step == 4)
506 dst[x +
a] = src[x +
a];
568 .priv_class = &curves_class,