summaryrefslogtreecommitdiff
path: root/libavfilter/vf_curves.c
diff options
context:
space:
mode:
authorClément Bœsch <u@pkh.me>2016-07-22 01:17:44 +0200
committerClément Bœsch <u@pkh.me>2016-07-24 12:18:30 +0200
commit4a8f5f1fd83dfa92e02901e543d79124c4e551dc (patch)
tree0ac7c79830f307d0be98e0709a04d0d47db7932b /libavfilter/vf_curves.c
parent5c14018fc4f6ae9fcce7eaf8dd2d66cb6fbfc7bc (diff)
lavfi/curves: add plot option
Diffstat (limited to 'libavfilter/vf_curves.c')
-rw-r--r--libavfilter/vf_curves.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index 7128fbef2c..84df448123 100644
--- a/libavfilter/vf_curves.c
+++ b/libavfilter/vf_curves.c
@@ -67,6 +67,7 @@ typedef struct {
char *psfile;
uint8_t rgba_map[4];
int step;
+ char *plot_filename;
} CurvesContext;
typedef struct ThreadData {
@@ -98,6 +99,7 @@ static const AVOption curves_options[] = {
{ "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 },
+ { "plot", "save Gnuplot script of the curves in specified file", OFFSET(plot_filename), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
{ NULL }
};
@@ -377,6 +379,65 @@ end:
return ret;
}
+static int dump_curves(const char *fname, uint8_t graph[NB_COMP + 1][256],
+ struct keypoint *comp_points[NB_COMP + 1])
+{
+ int i;
+ AVBPrint buf;
+ static const char * const colors[] = { "red", "green", "blue", "#404040", };
+ FILE *f = av_fopen_utf8(fname, "w");
+
+ av_assert0(FF_ARRAY_ELEMS(colors) == NB_COMP + 1);
+
+ if (!f) {
+ int ret = AVERROR(errno);
+ av_log(NULL, AV_LOG_ERROR, "Cannot open file '%s' for writing: %s\n",
+ fname, av_err2str(ret));
+ return ret;
+ }
+
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+ av_bprintf(&buf, "set xtics 0.1\n");
+ av_bprintf(&buf, "set ytics 0.1\n");
+ av_bprintf(&buf, "set size square\n");
+ av_bprintf(&buf, "set grid\n");
+
+ for (i = 0; i < FF_ARRAY_ELEMS(colors); i++) {
+ av_bprintf(&buf, "%s'-' using 1:2 with lines lc '%s' title ''",
+ i ? ", " : "plot ", colors[i]);
+ if (comp_points[i])
+ av_bprintf(&buf, ", '-' using 1:2 with points pointtype 3 lc '%s' title ''",
+ colors[i]);
+ }
+ av_bprintf(&buf, "\n");
+
+ for (i = 0; i < FF_ARRAY_ELEMS(colors); i++) {
+ int x;
+
+ /* plot generated values */
+ for (x = 0; x < 256; x++)
+ av_bprintf(&buf, "%f %f\n", x/255., graph[i][x]/255.);
+ av_bprintf(&buf, "e\n");
+
+ /* plot user knots */
+ if (comp_points[i]) {
+ const struct keypoint *point = comp_points[i];
+
+ while (point) {
+ av_bprintf(&buf, "%f %f\n", point->x, point->y);
+ point = point->next;
+ }
+ av_bprintf(&buf, "e\n");
+ }
+ }
+
+ fwrite(buf.str, 1, buf.len, f);
+ fclose(f);
+ av_bprint_finalize(&buf, NULL);
+ return 0;
+}
+
static av_cold int init(AVFilterContext *ctx)
{
int i, j, ret;
@@ -448,6 +509,9 @@ static av_cold int init(AVFilterContext *ctx)
}
}
+ if (curves->plot_filename)
+ dump_curves(curves->plot_filename, curves->graph, comp_points);
+
for (i = 0; i < NB_COMP + 1; i++) {
struct keypoint *point = comp_points[i];
while (point) {