diff options
Diffstat (limited to 'libavfilter/vf_curves.c')
-rw-r--r-- | libavfilter/vf_curves.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c index 35a5af3946..dc012fa626 100644 --- a/libavfilter/vf_curves.c +++ b/libavfilter/vf_curves.c @@ -19,7 +19,10 @@ */ #include "libavutil/opt.h" +#include "libavutil/bprint.h" #include "libavutil/eval.h" +#include "libavutil/file.h" +#include "libavutil/intreadwrite.h" #include "libavutil/avassert.h" #include "avfilter.h" #include "formats.h" @@ -54,6 +57,7 @@ typedef struct { char *comp_points_str[NB_COMP + 1]; char *comp_points_str_all; uint8_t graph[NB_COMP + 1][256]; + char *psfile; } CurvesContext; #define OFFSET(x) offsetof(CurvesContext, x) @@ -80,6 +84,7 @@ static const AVOption curves_options[] = { { "blue", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, { "b", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, { "all", "set points coordinates for all components", OFFSET(comp_points_str_all), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, + { "psfile", "set Photoshop curves file name", OFFSET(psfile), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, { NULL } }; @@ -297,6 +302,60 @@ end: return ret; } +static int parse_psfile(AVFilterContext *ctx, const char *fname) +{ + CurvesContext *curves = ctx->priv; + uint8_t *buf; + size_t size; + int i, ret, av_unused(version), nb_curves; + AVBPrint ptstr; + static const int comp_ids[] = {3, 0, 1, 2}; + + av_bprint_init(&ptstr, 0, AV_BPRINT_SIZE_AUTOMATIC); + + ret = av_file_map(fname, &buf, &size, 0, NULL); + if (ret < 0) + return ret; + +#define READ16(dst) do { \ + if (size < 2) \ + return AVERROR_INVALIDDATA; \ + dst = AV_RB16(buf); \ + buf += 2; \ + size -= 2; \ +} while (0) + + READ16(version); + READ16(nb_curves); + for (i = 0; i < FFMIN(nb_curves, FF_ARRAY_ELEMS(comp_ids)); i++) { + int nb_points, n; + av_bprint_clear(&ptstr); + READ16(nb_points); + for (n = 0; n < nb_points; n++) { + int y, x; + READ16(y); + READ16(x); + av_bprintf(&ptstr, "%f/%f ", x / 255., y / 255.); + } + if (*ptstr.str) { + char **pts = &curves->comp_points_str[comp_ids[i]]; + if (!*pts) { + *pts = av_strdup(ptstr.str); + av_log(ctx, AV_LOG_DEBUG, "curves %d (intid=%d) [%d points]: [%s]\n", + i, comp_ids[i], nb_points, *pts); + if (!*pts) { + ret = AVERROR(ENOMEM); + goto end; + } + } + } + } +end: + av_bprint_finalize(&ptstr, NULL); + av_file_unmap(buf, size); + return ret; +} + static av_cold int init(AVFilterContext *ctx) { int i, j, ret; @@ -317,6 +376,12 @@ static av_cold int init(AVFilterContext *ctx) } } + if (curves->psfile) { + ret = parse_psfile(ctx, curves->psfile); + if (ret < 0) + return ret; + } + if (curves->preset != PRESET_NONE) { #define SET_COMP_IF_NOT_SET(n, name) do { \ if (!pts[n] && curves_presets[curves->preset].name) { \ |