... | ... |
@@ -2346,6 +2346,8 @@ Set the key points for all components (not including master). |
2346 | 2346 |
Can be used in addition to the other key points component |
2347 | 2347 |
options. In this case, the unset component(s) will fallback on this |
2348 | 2348 |
@option{all} setting. |
2349 |
+@item psfile |
|
2350 |
+Specify a Photoshop curves file (@code{.asv}) to import the settings from. |
|
2349 | 2351 |
@end table |
2350 | 2352 |
|
2351 | 2353 |
To avoid some filtergraph syntax conflicts, each key points list need to be |
... | ... |
@@ -30,7 +30,7 @@ |
30 | 30 |
|
31 | 31 |
#define LIBAVFILTER_VERSION_MAJOR 3 |
32 | 32 |
#define LIBAVFILTER_VERSION_MINOR 56 |
33 |
-#define LIBAVFILTER_VERSION_MICRO 100 |
|
33 |
+#define LIBAVFILTER_VERSION_MICRO 101 |
|
34 | 34 |
|
35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
36 | 36 |
LIBAVFILTER_VERSION_MINOR, \ |
... | ... |
@@ -19,7 +19,10 @@ |
19 | 19 |
*/ |
20 | 20 |
|
21 | 21 |
#include "libavutil/opt.h" |
22 |
+#include "libavutil/bprint.h" |
|
22 | 23 |
#include "libavutil/eval.h" |
24 |
+#include "libavutil/file.h" |
|
25 |
+#include "libavutil/intreadwrite.h" |
|
23 | 26 |
#include "libavutil/avassert.h" |
24 | 27 |
#include "avfilter.h" |
25 | 28 |
#include "formats.h" |
... | ... |
@@ -54,6 +57,7 @@ typedef struct { |
54 | 54 |
char *comp_points_str[NB_COMP + 1]; |
55 | 55 |
char *comp_points_str_all; |
56 | 56 |
uint8_t graph[NB_COMP + 1][256]; |
57 |
+ char *psfile; |
|
57 | 58 |
} CurvesContext; |
58 | 59 |
|
59 | 60 |
#define OFFSET(x) offsetof(CurvesContext, x) |
... | ... |
@@ -80,6 +84,7 @@ static const AVOption curves_options[] = { |
80 | 80 |
{ "blue", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, |
81 | 81 |
{ "b", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, |
82 | 82 |
{ "all", "set points coordinates for all components", OFFSET(comp_points_str_all), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, |
83 |
+ { "psfile", "set Photoshop curves file name", OFFSET(psfile), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, |
|
83 | 84 |
{ NULL } |
84 | 85 |
}; |
85 | 86 |
|
... | ... |
@@ -297,6 +302,60 @@ end: |
297 | 297 |
return ret; |
298 | 298 |
} |
299 | 299 |
|
300 |
+static int parse_psfile(AVFilterContext *ctx, const char *fname) |
|
301 |
+{ |
|
302 |
+ CurvesContext *curves = ctx->priv; |
|
303 |
+ uint8_t *buf; |
|
304 |
+ size_t size; |
|
305 |
+ int i, ret, av_unused(version), nb_curves; |
|
306 |
+ AVBPrint ptstr; |
|
307 |
+ static const int comp_ids[] = {3, 0, 1, 2}; |
|
308 |
+ |
|
309 |
+ av_bprint_init(&ptstr, 0, AV_BPRINT_SIZE_AUTOMATIC); |
|
310 |
+ |
|
311 |
+ ret = av_file_map(fname, &buf, &size, 0, NULL); |
|
312 |
+ if (ret < 0) |
|
313 |
+ return ret; |
|
314 |
+ |
|
315 |
+#define READ16(dst) do { \ |
|
316 |
+ if (size < 2) \ |
|
317 |
+ return AVERROR_INVALIDDATA; \ |
|
318 |
+ dst = AV_RB16(buf); \ |
|
319 |
+ buf += 2; \ |
|
320 |
+ size -= 2; \ |
|
321 |
+} while (0) |
|
322 |
+ |
|
323 |
+ READ16(version); |
|
324 |
+ READ16(nb_curves); |
|
325 |
+ for (i = 0; i < FFMIN(nb_curves, FF_ARRAY_ELEMS(comp_ids)); i++) { |
|
326 |
+ int nb_points, n; |
|
327 |
+ av_bprint_clear(&ptstr); |
|
328 |
+ READ16(nb_points); |
|
329 |
+ for (n = 0; n < nb_points; n++) { |
|
330 |
+ int y, x; |
|
331 |
+ READ16(y); |
|
332 |
+ READ16(x); |
|
333 |
+ av_bprintf(&ptstr, "%f/%f ", x / 255., y / 255.); |
|
334 |
+ } |
|
335 |
+ if (*ptstr.str) { |
|
336 |
+ char **pts = &curves->comp_points_str[comp_ids[i]]; |
|
337 |
+ if (!*pts) { |
|
338 |
+ *pts = av_strdup(ptstr.str); |
|
339 |
+ av_log(ctx, AV_LOG_DEBUG, "curves %d (intid=%d) [%d points]: [%s]\n", |
|
340 |
+ i, comp_ids[i], nb_points, *pts); |
|
341 |
+ if (!*pts) { |
|
342 |
+ ret = AVERROR(ENOMEM); |
|
343 |
+ goto end; |
|
344 |
+ } |
|
345 |
+ } |
|
346 |
+ } |
|
347 |
+ } |
|
348 |
+end: |
|
349 |
+ av_bprint_finalize(&ptstr, NULL); |
|
350 |
+ av_file_unmap(buf, size); |
|
351 |
+ return ret; |
|
352 |
+} |
|
353 |
+ |
|
300 | 354 |
static av_cold int init(AVFilterContext *ctx) |
301 | 355 |
{ |
302 | 356 |
int i, j, ret; |
... | ... |
@@ -317,6 +376,12 @@ static av_cold int init(AVFilterContext *ctx) |
317 | 317 |
} |
318 | 318 |
} |
319 | 319 |
|
320 |
+ if (curves->psfile) { |
|
321 |
+ ret = parse_psfile(ctx, curves->psfile); |
|
322 |
+ if (ret < 0) |
|
323 |
+ return ret; |
|
324 |
+ } |
|
325 |
+ |
|
320 | 326 |
if (curves->preset != PRESET_NONE) { |
321 | 327 |
#define SET_COMP_IF_NOT_SET(n, name) do { \ |
322 | 328 |
if (!pts[n] && curves_presets[curves->preset].name) { \ |