[FFmpeg-cvslog] lavfi/curves: add support for Photoshop curves files (.acv).

Clément Bœsch git at videolan.org
Mon Apr 15 11:37:32 CEST 2013


ffmpeg | branch: master | Clément Bœsch <ubitux at gmail.com> | Mon Apr 15 03:49:36 2013 +0200| [1cb02d4fbc290c6e485fd301b902d8258d5c4994] | committer: Clément Bœsch

lavfi/curves: add support for Photoshop curves files (.acv).

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1cb02d4fbc290c6e485fd301b902d8258d5c4994
---

 doc/filters.texi        |    2 ++
 libavfilter/version.h   |    2 +-
 libavfilter/vf_curves.c |   65 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 8df1a88..23d777d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -2346,6 +2346,8 @@ Set the key points for all components (not including master).
 Can be used in addition to the other key points component
 options. In this case, the unset component(s) will fallback on this
 @option{all} setting.
+ at item psfile
+Specify a Photoshop curves file (@code{.asv}) to import the settings from.
 @end table
 
 To avoid some filtergraph syntax conflicts, each key points list need to be
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 6cf3b05..56f8c0d 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -30,7 +30,7 @@
 
 #define LIBAVFILTER_VERSION_MAJOR  3
 #define LIBAVFILTER_VERSION_MINOR  56
-#define LIBAVFILTER_VERSION_MICRO 100
+#define LIBAVFILTER_VERSION_MICRO 101
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
                                                LIBAVFILTER_VERSION_MINOR, \
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index 35a5af3..dc012fa 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) {           \



More information about the ffmpeg-cvslog mailing list