1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-21 10:55:51 +02:00

avfilter/paletteuse: add sierra3 dithering

Sierra3 according to
https://bisqwit.iki.fi/jutut/kuvat/ordered_dither/error_diffusion.txt:

          *  5  3
    2  4  5  4  2
       2  3  2      / 32
This commit is contained in:
Clément Bœsch 2022-12-30 11:37:20 +01:00
parent 11926c4bd4
commit 9973343bf9
2 changed files with 32 additions and 0 deletions

View File

@ -18524,6 +18524,8 @@ Floyd and Steingberg dithering (error diffusion)
Frankie Sierra dithering v2 (error diffusion)
@item sierra2_4a
Frankie Sierra dithering v2 "Lite" (error diffusion)
@item sierra3
Frankie Sierra dithering v3 (error diffusion)
@end table
Default is @var{sierra2_4a}.

View File

@ -42,6 +42,7 @@ enum dithering_mode {
DITHERING_FLOYD_STEINBERG,
DITHERING_SIERRA2,
DITHERING_SIERRA2_4A,
DITHERING_SIERRA3,
NB_DITHERING
};
@ -113,6 +114,7 @@ static const AVOption paletteuse_options[] = {
{ "floyd_steinberg", "Floyd and Steingberg dithering (error diffusion)", 0, AV_OPT_TYPE_CONST, {.i64=DITHERING_FLOYD_STEINBERG}, INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
{ "sierra2", "Frankie Sierra dithering v2 (error diffusion)", 0, AV_OPT_TYPE_CONST, {.i64=DITHERING_SIERRA2}, INT_MIN, INT_MAX, FLAGS, "dithering_mode" },
{ "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" },
{ "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" },
@ -368,6 +370,32 @@ static av_always_inline int set_frame(PaletteUseContext *s, AVFrame *out, AVFram
if (left && down) src[src_linesize + x - 1] = dither_color(src[src_linesize + x - 1], er, eg, eb, 1, 2);
if ( down) src[src_linesize + x ] = dither_color(src[src_linesize + x ], er, eg, eb, 1, 2);
} else if (dither == DITHERING_SIERRA3) {
const int right = x < w - 1, down = y < h - 1, left = x > x_start;
const int right2 = x < w - 2, down2 = y < h - 2, left2 = x > x_start + 1;
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, 5, 5);
if (right2) src[ x + 2] = dither_color(src[ x + 2], er, eg, eb, 3, 5);
if (down) {
if (left2) src[src_linesize + x - 2] = dither_color(src[src_linesize + x - 2], er, eg, eb, 2, 5);
if (left) src[src_linesize + x - 1] = dither_color(src[src_linesize + x - 1], er, eg, eb, 4, 5);
if (1) src[src_linesize + x ] = dither_color(src[src_linesize + x ], er, eg, eb, 5, 5);
if (right) src[src_linesize + x + 1] = dither_color(src[src_linesize + x + 1], er, eg, eb, 4, 5);
if (right2) src[src_linesize + x + 2] = dither_color(src[src_linesize + x + 2], er, eg, eb, 2, 5);
if (down2) {
if (left) src[src_linesize*2 + x - 1] = dither_color(src[src_linesize*2 + x - 1], er, eg, eb, 2, 5);
if (1) src[src_linesize*2 + x ] = dither_color(src[src_linesize*2 + x ], er, eg, eb, 3, 5);
if (right) src[src_linesize*2 + x + 1] = dither_color(src[src_linesize*2 + x + 1], er, eg, eb, 2, 5);
}
}
} else {
const int color = color_get(s, src[x]);
@ -842,6 +870,7 @@ DEFINE_SET_FRAME(heckbert, DITHERING_HECKBERT)
DEFINE_SET_FRAME(floyd_steinberg, DITHERING_FLOYD_STEINBERG)
DEFINE_SET_FRAME(sierra2, DITHERING_SIERRA2)
DEFINE_SET_FRAME(sierra2_4a, DITHERING_SIERRA2_4A)
DEFINE_SET_FRAME(sierra3, DITHERING_SIERRA3)
static const set_frame_func set_frame_lut[NB_DITHERING] = {
set_frame_none,
@ -850,6 +879,7 @@ static const set_frame_func set_frame_lut[NB_DITHERING] = {
set_frame_floyd_steinberg,
set_frame_sierra2,
set_frame_sierra2_4a,
set_frame_sierra3,
};
static int dither_value(int p)