Atkinson according to https://bisqwit.iki.fi/jutut/kuvat/ordered_dither/error_diffusion.txt:
* 1 1 / 8 1 1 1 1 --- doc/filters.texi | 2 ++ libavfilter/vf_paletteuse.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index 16a8dde4f3..2672ae6ee7 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -18520,6 +18520,8 @@ Frankie Sierra dithering v2 "Lite" (error diffusion) Frankie Sierra dithering v3 (error diffusion) @item burkes Burkes dithering (error diffusion) +@item atkinson +Atkinson dithering by Bill Atkinson at Apple Computer (error diffusion) @end table Default is @var{sierra2_4a}. diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index 3c3b6b3ef8..252ad746f0 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -44,6 +44,7 @@ enum dithering_mode { DITHERING_SIERRA2_4A, DITHERING_SIERRA3, DITHERING_BURKES, + DITHERING_ATKINSON, NB_DITHERING }; @@ -117,6 +118,7 @@ static const AVOption paletteuse_options[] = { { "sierra2_4a", "Frankie Sierra dithering v2 \"Lite\" (error diffusion)", 0, AV_OPT_TYPE_CONST, {.i64=DITHERING_SIERRA2_4A}, INT_MIN, INT_MAX, FLAGS, "dithering_mode" }, { "sierra3", "Frankie Sierra dithering v3 (error diffusion)", 0, AV_OPT_TYPE_CONST, {.i64=DITHERING_SIERRA3}, INT_MIN, INT_MAX, FLAGS, "dithering_mode" }, { "burkes", "Burkes dithering (error diffusion)", 0, AV_OPT_TYPE_CONST, {.i64=DITHERING_BURKES}, INT_MIN, INT_MAX, FLAGS, "dithering_mode" }, + { "atkinson", "Atkinson dithering by Bill Atkinson at Apple Computer (error diffusion)",0, AV_OPT_TYPE_CONST, {.i64=DITHERING_ATKINSON}, INT_MIN, INT_MAX, FLAGS, "dithering_mode" }, { "bayer_scale", "set scale for bayer dithering", OFFSET(bayer_scale), AV_OPT_TYPE_INT, {.i64=2}, 0, 5, FLAGS }, { "diff_mode", "set frame difference mode", OFFSET(diff_mode), AV_OPT_TYPE_INT, {.i64=DIFF_MODE_NONE}, 0, NB_DIFF_MODE-1, FLAGS, "diff_mode" }, { "rectangle", "process smallest different rectangle", 0, AV_OPT_TYPE_CONST, {.i64=DIFF_MODE_RECTANGLE}, INT_MIN, INT_MAX, FLAGS, "diff_mode" }, @@ -418,6 +420,25 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram if (right2) src[src_linesize + x + 2] = dither_color(src[src_linesize + x + 2], er, eg, eb, 2, 5); } + } else if (dither == DITHERING_ATKINSON) { + const int right = x < w - 1, down = y < h - 1, left = x > x_start; + const int right2 = x < w - 2, down2 = y < h - 2; + const int color = get_dst_color_err(s, src[x], &er, &eg, &eb); + + if (color < 0) + return color; + dst[x] = color; + + if (right) src[ x + 1] = dither_color(src[ x + 1], er, eg, eb, 1, 3); + if (right2) src[ x + 2] = dither_color(src[ x + 2], er, eg, eb, 1, 3); + + if (down) { + if (left) src[src_linesize + x - 1] = dither_color(src[src_linesize + x - 1], er, eg, eb, 1, 3); + if (1) src[src_linesize + x ] = dither_color(src[src_linesize + x ], er, eg, eb, 1, 3); + if (right) src[src_linesize + x + 1] = dither_color(src[src_linesize + x + 1], er, eg, eb, 1, 3); + if (down2) src[src_linesize*2 + x ] = dither_color(src[src_linesize*2 + x ], er, eg, eb, 1, 3); + } + } else { const int color = color_get(s, src[x]); @@ -894,6 +915,7 @@ DEFINE_SET_FRAME(sierra2, DITHERING_SIERRA2) DEFINE_SET_FRAME(sierra2_4a, DITHERING_SIERRA2_4A) DEFINE_SET_FRAME(sierra3, DITHERING_SIERRA3) DEFINE_SET_FRAME(burkes, DITHERING_BURKES) +DEFINE_SET_FRAME(atkinson, DITHERING_ATKINSON) static const set_frame_func set_frame_lut[NB_DITHERING] = { set_frame_none, @@ -904,6 +926,7 @@ static const set_frame_func set_frame_lut[NB_DITHERING] = { set_frame_sierra2_4a, set_frame_sierra3, set_frame_burkes, + set_frame_atkinson, }; static int dither_value(int p) -- 2.39.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".