72 #define OFFSET(x) offsetof(CurvesContext, x)
73 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
102 static const struct {
109 "0/1 0.129/1 0.466/0.498 0.725/0 1/0",
110 "0/1 0.109/1 0.301/0.498 0.517/0 1/0",
111 "0/1 0.098/1 0.235/0.498 0.423/0 1/0",
114 "0.25/0.156 0.501/0.501 0.686/0.745",
115 "0.25/0.188 0.38/0.501 0.745/0.815 1/0.815",
116 "0.231/0.094 0.709/0.874",
126 "0/0.11 0.42/0.51 1/0.95",
128 "0/0.22 0.49/0.44 1/0.8",
154 point->
x =
av_strtod(p, &p);
if (p && *p) p++;
155 point->
y =
av_strtod(p, &p);
if (p && *p) p++;
156 if (point->
x < 0 || point->
x > 1 || point->
y < 0 || point->
y > 1) {
158 "x and y must be in the [0;1] range.\n", point->
x, point->
y);
164 if ((
int)(last->
x * 255) >= (
int)(point->
x * 255)) {
166 "and (%f;%f) are too close from each other or not "
167 "strictly increasing on the x-axis\n",
168 last->
x, last->
y, point->
x, point->
y);
181 last->
x = last->
y = 0;
183 }
else if ((*points)->x != 0.) {
226 double (*matrix)[3] =
av_calloc(n,
sizeof(*matrix));
227 double *h =
av_malloc((n - 1) *
sizeof(*h));
230 if (!matrix || !h || !r) {
237 for (point = points; point; point = point->
next) {
239 h[i] = point->
x - xprev;
246 for (i = 1; i < n - 1; i++) {
247 double yp = point->
y,
250 r[i] = 6 * ((yn-yc)/h[i] - (yc-yp)/h[i-1]);
259 matrix[0][
MD] = matrix[n - 1][
MD] = 1;
260 for (i = 1; i < n - 1; i++) {
261 matrix[i][
BD] = h[i-1];
262 matrix[i][
MD] = 2 * (h[i-1] + h[i]);
263 matrix[i][
AD] = h[i];
267 for (i = 1; i <
n; i++) {
268 double den = matrix[i][
MD] - matrix[i][
BD] * matrix[i-1][
AD];
269 double k = den ? 1./den : 1.;
271 r[i] = (r[i] - matrix[i][
BD] * r[i - 1]) * k;
273 for (i = n - 2; i >= 0; i--)
274 r[i] = r[i] - matrix[i][
AD] * r[i + 1];
280 while (point->
next) {
281 double yc = point->
y;
282 double yn = point->
next->
y;
285 double b = (yn-yc)/h[i] - h[i]*r[i]/2. - h[i]*(r[i+1]-r[i])/6.;
286 double c = r[i] / 2.;
287 double d = (r[i+1] - r[i]) / (6.*h[i]);
290 int x_start = point->
x * 255;
291 int x_end = point->
next->
x * 255;
294 x_end >= 0 && x_end <= 255);
296 for (x = x_start; x <= x_end; x++) {
297 double xx = (x - x_start) * 1/255.;
298 double yy = a + b*xx + c*xx*xx + d*xx*xx*xx;
299 y[
x] = av_clipf(yy, 0, 1) * 255;
321 static const int comp_ids[] = {3, 0, 1, 2};
329 #define READ16(dst) do { \
331 return AVERROR_INVALIDDATA; \
332 dst = AV_RB16(buf); \
343 for (n = 0; n < nb_points; n++) {
347 av_bprintf(&ptstr,
"%f/%f ", x / 255., y / 255.);
354 i, comp_ids[i], nb_points, *pts);
380 for (i = 0; i <
NB_COMP; i++) {
395 #define SET_COMP_IF_NOT_SET(n, name) do { \
396 if (!pts[n] && curves_presets[curves->preset].name) { \
397 pts[n] = av_strdup(curves_presets[curves->preset].name); \
399 return AVERROR(ENOMEM); \
408 for (i = 0; i <
NB_COMP + 1; i++) {
419 for (j = 0; j < 256; j++)
424 for (i = 0; i <
NB_COMP; i++) {
425 struct keypoint *point = comp_points[i];
433 for (j = 0; j < 256; j++)
439 for (i = 0; i < NB_COMP + 1; i++) {
440 struct keypoint *point = comp_points[i];
478 int x,
y, direct = 0;
485 const int step = curves->
step;
506 for (y = 0; y < inlink->
h; y++) {
507 for (x = 0; x < inlink->
w * step; x += step) {
508 dst[x +
r] = curves->
graph[
R][src[x +
r]];
509 dst[x +
g] = curves->
graph[
G][src[x +
g]];
510 dst[x +
b] = curves->
graph[
B][src[x +
b]];
511 if (!direct && step == 4)
512 dst[x +
a] = src[x +
a];
550 .priv_class = &curves_class,