On Tue, Apr 26, 2016 at 12:41:02PM -0400, Ronald S. Bultje wrote: > --- > doc/filters.texi | 13 ++++ > libavfilter/colorspacedsp.c | 9 +++ > libavfilter/colorspacedsp.h | 6 ++ > libavfilter/colorspacedsp_template.c | 128 > +++++++++++++++++++++++++++++++++++ > libavfilter/vf_colorspace.c | 53 ++++++++++++++- > 5 files changed, 207 insertions(+), 2 deletions(-) [...] > diff --git a/libavfilter/colorspacedsp_template.c > b/libavfilter/colorspacedsp_template.c > index f225391..db4a8d2 100644 > --- a/libavfilter/colorspacedsp_template.c > +++ b/libavfilter/colorspacedsp_template.c > @@ -199,6 +199,134 @@ static void fn(rgb2yuv)(uint8_t *_yuv[3], ptrdiff_t > yuv_stride[3], > } > } > > +/* floyd-steinberg dithering - for any mid-top pixel A in a 3x2 block of > pixels: > + * 1 A 2 > + * 3 4 5 > + * the rounding error is distributed over the neighbouring pixels: > + * 2: 7/16th, 3: 3/16th, 4: 5/16th and 5: 1/16th > + */ > +static void fn(rgb2yuv_fsb)(uint8_t *_yuv[3], ptrdiff_t yuv_stride[3], > + int16_t *rgb[3], ptrdiff_t s, > + int w, int h, const int16_t > rgb2yuv_coeffs[3][3][8], > + const int16_t yuv_offset[8], > + int *rnd_scratch[3][2]) > +{ > + pixel **yuv = (pixel **) _yuv; > + pixel *yuv0 = yuv[0], *yuv1 = yuv[1], *yuv2 = yuv[2]; > + const int16_t *rgb0 = rgb[0], *rgb1 = rgb[1], *rgb2 = rgb[2]; > + int y, x; > + const int sh = 29 - BIT_DEPTH; > + const int rnd = 1 << (sh - 1); > + int cry = rgb2yuv_coeffs[0][0][0]; > + int cgy = rgb2yuv_coeffs[0][1][0]; > + int cby = rgb2yuv_coeffs[0][2][0]; > + int cru = rgb2yuv_coeffs[1][0][0]; > + int cgu = rgb2yuv_coeffs[1][1][0]; > + int cburv = rgb2yuv_coeffs[1][2][0]; > + int cgv = rgb2yuv_coeffs[2][1][0]; > + int cbv = rgb2yuv_coeffs[2][2][0]; > + ptrdiff_t s0 = yuv_stride[0] / sizeof(pixel); > + const int uv_offset = 128 << (BIT_DEPTH - 8); > + unsigned mask = (1 << sh) - 1; > + > + for (x = 0; x < w; x++) { > + rnd_scratch[0][0][x] = > + rnd_scratch[0][1][x] = rnd; > + } > + av_assert2(rgb2yuv_coeffs[1][2][0] == rgb2yuv_coeffs[2][0][0]); > + w = AV_CEIL_RSHIFT(w, SS_W); > + h = AV_CEIL_RSHIFT(h, SS_H); > + for (x = 0; x < w; x++) { > + rnd_scratch[1][0][x] = > + rnd_scratch[1][1][x] = > + rnd_scratch[2][0][x] = > + rnd_scratch[2][1][x] = rnd; > + } > + for (y = 0; y < h; y++) { > + for (x = 0; x < w; x++) { > + int r00 = rgb0[x << SS_W], g00 = rgb1[x << SS_W], b00 = rgb2[x > << SS_W]; > + int y00; > +#if SS_W == 1 > + int r01 = rgb0[x * 2 + 1], g01 = rgb1[x * 2 + 1], b01 = rgb2[x * > 2 + 1]; > + int y01; > +#if SS_H == 1
SS_W/SS_H should be documented or named so they are self explanatory [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I have often repented speaking, but never of holding my tongue. -- Xenocrates
signature.asc
Description: Digital signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel