| @@ -42,6 +42,7 @@ typedef struct { | |||
| float *plane[16+1][4]; | |||
| int linesize; | |||
| int hsub, vsub; | |||
| int pixel_depth; | |||
| } OWDenoiseContext; | |||
| #define OFFSET(x) offsetof(OWDenoiseContext, x) | |||
| @@ -188,9 +189,18 @@ static void filter(OWDenoiseContext *s, | |||
| while (1<<depth > width || 1<<depth > height) | |||
| depth--; | |||
| for (y = 0; y < height; y++) | |||
| for(x = 0; x < width; x++) | |||
| s->plane[0][0][y*s->linesize + x] = src[y*src_linesize + x]; | |||
| if (s->pixel_depth <= 8) { | |||
| for (y = 0; y < height; y++) | |||
| for(x = 0; x < width; x++) | |||
| s->plane[0][0][y*s->linesize + x] = src[y*src_linesize + x]; | |||
| } else { | |||
| const uint16_t *src16 = (const uint16_t *)src; | |||
| src_linesize /= 2; | |||
| for (y = 0; y < height; y++) | |||
| for(x = 0; x < width; x++) | |||
| s->plane[0][0][y*s->linesize + x] = src16[y*src_linesize + x]; | |||
| } | |||
| for (i = 0; i < depth; i++) | |||
| decompose2D2(s->plane[i + 1], s->plane[i][0], s->plane[0] + 1, s->linesize, 1<<i, width, height); | |||
| @@ -211,11 +221,23 @@ static void filter(OWDenoiseContext *s, | |||
| for (i = depth-1; i >= 0; i--) | |||
| compose2D2(s->plane[i][0], s->plane[i + 1], s->plane[0] + 1, s->linesize, 1<<i, width, height); | |||
| for (y = 0; y < height; y++) { | |||
| for (x = 0; x < width; x++) { | |||
| i = s->plane[0][0][y*s->linesize + x] + dither[x&7][y&7]*(1.0/64) + 1.0/128; // yes the rounding is insane but optimal :) | |||
| if ((unsigned)i > 255U) i = ~(i >> 31); | |||
| dst[y*dst_linesize + x] = i; | |||
| if (s->pixel_depth <= 8) { | |||
| for (y = 0; y < height; y++) { | |||
| for (x = 0; x < width; x++) { | |||
| i = s->plane[0][0][y*s->linesize + x] + dither[x&7][y&7]*(1.0/64) + 1.0/128; // yes the rounding is insane but optimal :) | |||
| if ((unsigned)i > 255U) i = ~(i >> 31); | |||
| dst[y*dst_linesize + x] = i; | |||
| } | |||
| } | |||
| } else { | |||
| uint16_t *dst16 = (uint16_t *)dst; | |||
| dst_linesize /= 2; | |||
| for (y = 0; y < height; y++) { | |||
| for (x = 0; x < width; x++) { | |||
| i = s->plane[0][0][y*s->linesize + x]; | |||
| dst16[y*dst_linesize + x] = i; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -277,6 +299,13 @@ static int query_formats(AVFilterContext *ctx) | |||
| AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, | |||
| AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, | |||
| AV_PIX_FMT_YUVA420P, | |||
| AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, | |||
| AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, | |||
| AV_PIX_FMT_YUV440P10, | |||
| AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12, | |||
| AV_PIX_FMT_YUV440P12, | |||
| AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, | |||
| AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, | |||
| AV_PIX_FMT_NONE | |||
| }; | |||
| AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); | |||
| @@ -294,6 +323,7 @@ static int config_input(AVFilterLink *inlink) | |||
| s->hsub = desc->log2_chroma_w; | |||
| s->vsub = desc->log2_chroma_h; | |||
| s->pixel_depth = desc->comp[0].depth; | |||
| s->linesize = FFALIGN(inlink->w, 16); | |||
| for (j = 0; j < 4; j++) { | |||