--- libavcodec/dirac_dwt.c | 571 ++++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/dirac_dwt.h | 74 +++++++ libavcodec/dwt.h | 7 +- 3 files changed, 650 insertions(+), 2 deletions(-) create mode 100644 libavcodec/dirac_dwt.c create mode 100644 libavcodec/dirac_dwt.h
diff --git a/libavcodec/dirac_dwt.c b/libavcodec/dirac_dwt.c new file mode 100644 index 0000000..4b3908a --- /dev/null +++ b/libavcodec/dirac_dwt.c @@ -0,0 +1,571 @@ +#include "dirac_dwt.h" + +static av_always_inline void interleave(IDWTELEM *dst, IDWTELEM *src0, + IDWTELEM *src1, int w2, int add, + int shift) +{ + int i; + for (i = 0; i < w2; i++) { + dst[2 * i] = src0[i] + add >> shift; + dst[2 * i + 1] = src1[i] + add >> shift; + } +} + +static void horizontal_compose_dirac53i(IDWTELEM *b, IDWTELEM *temp, int w) +{ + const int w2 = w >> 1; + int x; + + temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]); + for (x = 1; x < w2; x++) { + temp[x] = COMPOSE_53iL0(b[x + w2 - 1], b[x], b[x + w2]); + temp[x + w2 - 1] = COMPOSE_DIRAC53iH0(temp[x - 1], b[x + w2 - 1], + temp[x]); + } + temp[w - 1] = COMPOSE_DIRAC53iH0(temp[w2 - 1], b[w - 1], temp[w2 - 1]); + + interleave(b, temp, temp + w2, w2, 1, 1); +} + +static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w) +{ + const int w2 = w >> 1; + int x; + + tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]); + for (x = 1; x < w2; x++) + tmp[x] = COMPOSE_53iL0(b[x + w2 - 1], b[x], b[x + w2]); + + // extend the edges + tmp[-1] = tmp[0]; + tmp[w2 + 1] = tmp[w2] = tmp[w2 - 1]; + + for (x = 0; x < w2; x++) { + b[2 * x] = tmp[x] + 1 >> 1; + b[2 * x + 1] = COMPOSE_DD97iH0(tmp[x - 1], tmp[x], b[x + w2], + tmp[x + 1], tmp[x + 2]) + 1 >> 1; + } +} + +static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w) +{ + const int w2 = w >> 1; + int x; + + tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2], b[w2 + 1]); + tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2 + 1], b[w2 + 2]); + for (x = 2; x < w2 - 1; x++) + tmp[x] = COMPOSE_DD137iL0(b[x + w2 - 2], b[x + w2 - 1], b[x], b[x + w2], + b[x + w2 + 1]); + tmp[w2 - 1] = COMPOSE_DD137iL0(b[w - 3], b[w - 2], b[w2 - 1], b[w - 1], + b[w - 1]); + + // extend the edges + tmp[-1] = tmp[0]; + tmp[w2 + 1] = tmp[w2] = tmp[w2 - 1]; + + for (x = 0; x < w2; x++) { + b[2 * x] = tmp[x] + 1 >> 1; + b[2 * x + 1] = COMPOSE_DD97iH0(tmp[x - 1], tmp[x], b[x + w2], + tmp[x + 1], tmp[x + 2]) + 1 >> 1; + } +} + +static av_always_inline void horizontal_compose_haari(IDWTELEM *b, + IDWTELEM *temp, int w, + int shift) +{ + const int w2 = w >> 1; + int x; + + for (x = 0; x < w2; x++) { + temp[x] = COMPOSE_HAARiL0(b[x], b[x + w2]); + temp[x + w2] = COMPOSE_HAARiH0(b[x + w2], temp[x]); + } + + interleave(b, temp, temp + w2, w2, shift, shift); +} + +static void horizontal_compose_haar0i(IDWTELEM *b, IDWTELEM *temp, int w) +{ + horizontal_compose_haari(b, temp, w, 0); +} + +static void horizontal_compose_haar1i(IDWTELEM *b, IDWTELEM *temp, int w) +{ + horizontal_compose_haari(b, temp, w, 1); +} + +static void horizontal_compose_fidelityi(IDWTELEM *b, IDWTELEM *tmp, int w) +{ + const int w2 = w >> 1; + int i, x; + IDWTELEM v[8]; + + for (x = 0; x < w2; x++) { + for (i = 0; i < 8; i++) + v[i] = b[av_clip(x - 3 + i, 0, w2 - 1)]; + tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x + w2], v[4], + v[5], v[6], v[7]); + } + + for (x = 0; x < w2; x++) { + for (i = 0; i < 8; i++) + v[i] = tmp[av_clip(x - 4 + i, 0, w2 - 1)]; + tmp[x + w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], + v[5], v[6], v[7]); + } + + interleave(b, tmp + w2, tmp, w2, 0, 0); +} + +static void horizontal_compose_daub97i(IDWTELEM *b, IDWTELEM *temp, int w) +{ + const int w2 = w >> 1; + int x, b0, b1, b2; + + temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]); + for (x = 1; x < w2; x++) { + temp[x] = COMPOSE_DAUB97iL1(b[x + w2 - 1], b[x], b[x + w2]); + temp[x + w2 - 1] = COMPOSE_DAUB97iH1(temp[x - 1], b[x + w2 - 1], + temp[x]); + } + temp[w - 1] = COMPOSE_DAUB97iH1(temp[w2 - 1], b[w - 1], temp[w2 - 1]); + + // second stage combined with interleave and shift + b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]); + b[0] = b0 + 1 >> 1; + for (x = 1; x < w2; x++) { + b2 = COMPOSE_DAUB97iL0(temp[x + w2 - 1], temp[x], temp[x + w2]); + b1 = COMPOSE_DAUB97iH0(b0, temp[x + w2 - 1], b2); + b[2 * x - 1] = b1 + 1 >> 1; + b[2 * x] = b2 + 1 >> 1; + b0 = b2; + } + b[w - 1] = (COMPOSE_DAUB97iH0(b2, temp[w - 1], b2) + 1) >> 1; +} + +static void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, + IDWTELEM *b2, int width) +{ + int i; + + for (i = 0; i < width; i++) + b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]); +} + +static void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + IDWTELEM *b3, IDWTELEM *b4, int width) +{ + int i; + + for (i = 0; i < width; i++) + b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]); +} + +static void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + IDWTELEM *b3, IDWTELEM *b4, int width) +{ + int i; + + for (i = 0; i < width; i++) + b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]); +} + +static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width) +{ + int i; + + for (i = 0; i < width; i++) { + b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]); + b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]); + } +} + +static void vertical_compose_fidelityiH0(IDWTELEM *dst, IDWTELEM *b[8], + int width) +{ + int i; + + for (i = 0; i < width; i++) + dst[i] = COMPOSE_FIDELITYiH0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], + b[4][i], b[5][i], b[6][i], b[7][i]); +} + +static void vertical_compose_fidelityiL0(IDWTELEM *dst, IDWTELEM *b[8], + int width) +{ + int i; + + for (i = 0; i < width; i++) + dst[i] = COMPOSE_FIDELITYiL0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], + b[4][i], b[5][i], b[6][i], b[7][i]); +} + +static void vertical_compose_daub97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + int width) +{ + int i; + + for (i = 0; i < width; i++) + b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]); +} + +static void vertical_compose_daub97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + int width) +{ + int i; + + for (i = 0; i < width; i++) + b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]); +} + +static void vertical_compose_daub97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + int width) +{ + int i; + + for (i = 0; i < width; i++) + b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]); +} + +static void vertical_compose_daub97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + int width) +{ + int i; + + for (i = 0; i < width; i++) + b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]); +} + +static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, + int height, int stride) +{ + vertical_compose_3tap vertical_compose_l0 = d->vertical_compose_l0; + vertical_compose_5tap vertical_compose_h0 = d->vertical_compose_h0; + DWTCompose *cs = d->cs + level; + + int i, y = cs->y; + IDWTELEM *b[8]; + for (i = 0; i < 6; i++) + b[i] = cs->b[i]; + b[6] = d->buffer + av_clip(y + 5, 0, height - 2) * stride; + b[7] = d->buffer + av_clip(y + 6, 1, height - 1) * stride; + + if (y + 5 < (unsigned)height) + vertical_compose_l0(b[5], b[6], b[7], width); + if (y + 1 < (unsigned)height) + vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width); + if (y - 1 < (unsigned)height) + d->horizontal_compose(b[0], d->temp, width); + if (y + 0 < (unsigned)height) + d->horizontal_compose(b[1], d->temp, width); + + for (i = 0; i < 6; i++) + cs->b[i] = b[i + 2]; + cs->y += 2; +} + +static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, + int height, int stride) +{ + vertical_compose_3tap vertical_compose_l0 = d->vertical_compose_l0; + vertical_compose_3tap vertical_compose_h0 = d->vertical_compose_h0; + DWTCompose *cs = d->cs + level; + + int y = cs->y; + IDWTELEM *b[4] = { cs->b[0], cs->b[1] }; + b[2] = d->buffer + mirror(y + 1, height - 1) * stride; + b[3] = d->buffer + mirror(y + 2, height - 1) * stride; + + if (y + 1 < (unsigned)height) + vertical_compose_l0(b[1], b[2], b[3], width); + if (y + 0 < (unsigned)height) + vertical_compose_h0(b[0], b[1], b[2], width); + if (y - 1 < (unsigned)height) + d->horizontal_compose(b[0], d->temp, width); + if (y + 0 < (unsigned)height) + d->horizontal_compose(b[1], d->temp, width); + + cs->b[0] = b[2]; + cs->b[1] = b[3]; + cs->y += 2; +} + +static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, + int height, int stride) +{ + vertical_compose_5tap vertical_compose_l0 = d->vertical_compose_l0; + vertical_compose_5tap vertical_compose_h0 = d->vertical_compose_h0; + DWTCompose *cs = d->cs + level; + + int i, y = cs->y; + IDWTELEM *b[10]; + for (i = 0; i < 8; i++) + b[i] = cs->b[i]; + b[8] = d->buffer + av_clip(y + 7, 0, height - 2) * stride; + b[9] = d->buffer + av_clip(y + 8, 1, height - 1) * stride; + + if (y + 5 < (unsigned)height) + vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width); + if (y + 1 < (unsigned)height) + vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width); + if (y - 1 < (unsigned)height) + d->horizontal_compose(b[0], d->temp, width); + if (y + 0 < (unsigned)height) + d->horizontal_compose(b[1], d->temp, width); + + for (i = 0; i < 8; i++) + cs->b[i] = b[i + 2]; + cs->y += 2; +} + +// haar makes the assumption that height is even (always true for dirac) +static void spatial_compose_haari_dy(DWTContext *d, int level, int width, + int height, int stride) +{ + vertical_compose_2tap vertical_compose = d->vertical_compose; + int y = d->cs[level].y; + IDWTELEM *b0 = d->buffer + (y - 1) * stride; + IDWTELEM *b1 = d->buffer + y * stride; + + vertical_compose(b0, b1, width); + d->horizontal_compose(b0, d->temp, width); + d->horizontal_compose(b1, d->temp, width); + + d->cs[level].y += 2; +} + +// Don't do sliced idwt for fidelity; the 9 tap filter makes it a bit annoying +// Fortunately, this filter isn't used in practice. +static void spatial_compose_fidelity(DWTContext *d, int level, int width, + int height, int stride) +{ + vertical_compose_9tap vertical_compose_l0 = d->vertical_compose_l0; + vertical_compose_9tap vertical_compose_h0 = d->vertical_compose_h0; + int i, y; + IDWTELEM *b[8]; + + for (y = 1; y < height; y += 2) { + for (i = 0; i < 8; i++) + b[i] = d->buffer + av_clip((y - 7 + 2 * i), 0, height - 2) * stride; + vertical_compose_h0(d->buffer + y * stride, b, width); + } + + for (y = 0; y < height; y += 2) { + for (i = 0; i < 8; i++) + b[i] = d->buffer + av_clip((y - 7 + 2 * i), 1, height - 1) * stride; + vertical_compose_l0(d->buffer + y * stride, b, width); + } + + for (y = 0; y < height; y++) + d->horizontal_compose(d->buffer + y * stride, d->temp, width); + + d->cs[level].y = height + 1; +} + +static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, + int height, int stride) +{ + vertical_compose_3tap vertical_compose_l0 = d->vertical_compose_l0; + vertical_compose_3tap vertical_compose_h0 = d->vertical_compose_h0; + vertical_compose_3tap vertical_compose_l1 = d->vertical_compose_l1; + vertical_compose_3tap vertical_compose_h1 = d->vertical_compose_h1; + DWTCompose *cs = d->cs + level; + + int i, y = cs->y; + IDWTELEM *b[6]; + for (i = 0; i < 4; i++) + b[i] = cs->b[i]; + b[4] = d->buffer + mirror(y + 3, height - 1) * stride; + b[5] = d->buffer + mirror(y + 4, height - 1) * stride; + + if (y + 3 < (unsigned)height) + vertical_compose_l1(b[3], b[4], b[5], width); + if (y + 2 < (unsigned)height) + vertical_compose_h1(b[2], b[3], b[4], width); + if (y + 1 < (unsigned)height) + vertical_compose_l0(b[1], b[2], b[3], width); + if (y + 0 < (unsigned)height) + vertical_compose_h0(b[0], b[1], b[2], width); + + if (y - 1 < (unsigned)height) + d->horizontal_compose(b[0], d->temp, width); + if (y + 0 < (unsigned)height) + d->horizontal_compose(b[1], d->temp, width); + + for (i = 0; i < 4; i++) + cs->b[i] = b[i + 2]; + cs->y += 2; +} + +static void spatial_compose97i_init2(DWTCompose *cs, IDWTELEM *buffer, + int height, int stride) +{ + cs->b[0] = buffer + mirror(-3 - 1, height - 1) * stride; + cs->b[1] = buffer + mirror(-3, height - 1) * stride; + cs->b[2] = buffer + mirror(-3 + 1, height - 1) * stride; + cs->b[3] = buffer + mirror(-3 + 2, height - 1) * stride; + cs->y = -3; +} + +static void spatial_compose53i_init2(DWTCompose *cs, IDWTELEM *buffer, + int height, int stride) +{ + cs->b[0] = buffer + mirror(-1 - 1, height - 1) * stride; + cs->b[1] = buffer + mirror(-1, height - 1) * stride; + cs->y = -1; +} + +static void spatial_compose_dd97i_init(DWTCompose *cs, IDWTELEM *buffer, + int height, int stride) +{ + cs->b[0] = buffer + av_clip(-5 - 1, 0, height - 2) * stride; + cs->b[1] = buffer + av_clip(-5, 1, height - 1) * stride; + cs->b[2] = buffer + av_clip(-5 + 1, 0, height - 2) * stride; + cs->b[3] = buffer + av_clip(-5 + 2, 1, height - 1) * stride; + cs->b[4] = buffer + av_clip(-5 + 3, 0, height - 2) * stride; + cs->b[5] = buffer + av_clip(-5 + 4, 1, height - 1) * stride; + cs->y = -5; +} + +static void spatial_compose_dd137i_init(DWTCompose *cs, IDWTELEM *buffer, + int height, int stride) +{ + cs->b[0] = buffer + av_clip(-5 - 1, 0, height - 2) * stride; + cs->b[1] = buffer + av_clip(-5, 1, height - 1) * stride; + cs->b[2] = buffer + av_clip(-5 + 1, 0, height - 2) * stride; + cs->b[3] = buffer + av_clip(-5 + 2, 1, height - 1) * stride; + cs->b[4] = buffer + av_clip(-5 + 3, 0, height - 2) * stride; + cs->b[5] = buffer + av_clip(-5 + 4, 1, height - 1) * stride; + cs->b[6] = buffer + av_clip(-5 + 5, 0, height - 2) * stride; + cs->b[7] = buffer + av_clip(-5 + 6, 1, height - 1) * stride; + cs->y = -5; +} + +int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, + int height, int stride, enum dwt_type type, + int decomposition_count, IDWTELEM *temp) +{ + int level; + + d->buffer = buffer; + d->width = width; + d->height = height; + d->stride = stride; + d->decomposition_count = decomposition_count; + d->temp = temp + 8; + + for (level = decomposition_count - 1; level >= 0; level--) { + int hl = height >> level; + int stride_l = stride << level; + + switch (type) { + case DWT_DIRAC_DD9_7: + spatial_compose_dd97i_init(d->cs + level, buffer, hl, stride_l); + break; + case DWT_DIRAC_LEGALL5_3: + spatial_compose53i_init2(d->cs + level, buffer, hl, stride_l); + break; + case DWT_DIRAC_DD13_7: + spatial_compose_dd137i_init(d->cs + level, buffer, hl, stride_l); + break; + case DWT_DIRAC_HAAR0: + case DWT_DIRAC_HAAR1: + d->cs[level].y = 1; + break; + case DWT_DIRAC_DAUB9_7: + spatial_compose97i_init2(d->cs + level, buffer, hl, stride_l); + break; + default: + d->cs[level].y = 0; + break; + } + } + + switch (type) { + case DWT_DIRAC_DD9_7: + d->spatial_compose = spatial_compose_dd97i_dy; + d->vertical_compose_l0 = vertical_compose53iL0; + d->vertical_compose_h0 = vertical_compose_dd97iH0; + d->horizontal_compose = horizontal_compose_dd97i; + d->support = 7; + break; + case DWT_DIRAC_LEGALL5_3: + d->spatial_compose = spatial_compose_dirac53i_dy; + d->vertical_compose_l0 = vertical_compose53iL0; + d->vertical_compose_h0 = vertical_compose_dirac53iH0; + d->horizontal_compose = horizontal_compose_dirac53i; + d->support = 3; + break; + case DWT_DIRAC_DD13_7: + d->spatial_compose = spatial_compose_dd137i_dy; + d->vertical_compose_l0 = vertical_compose_dd137iL0; + d->vertical_compose_h0 = vertical_compose_dd97iH0; + d->horizontal_compose = horizontal_compose_dd137i; + d->support = 7; + break; + case DWT_DIRAC_HAAR0: + case DWT_DIRAC_HAAR1: + d->spatial_compose = spatial_compose_haari_dy; + d->vertical_compose = vertical_compose_haar; + if (type == DWT_DIRAC_HAAR0) + d->horizontal_compose = horizontal_compose_haar0i; + else + d->horizontal_compose = horizontal_compose_haar1i; + d->support = 1; + break; + case DWT_DIRAC_FIDELITY: + d->spatial_compose = spatial_compose_fidelity; + d->vertical_compose_l0 = vertical_compose_fidelityiL0; + d->vertical_compose_h0 = vertical_compose_fidelityiH0; + d->horizontal_compose = horizontal_compose_fidelityi; + break; + case DWT_DIRAC_DAUB9_7: + d->spatial_compose = spatial_compose_daub97i_dy; + d->vertical_compose_l0 = vertical_compose_daub97iL0; + d->vertical_compose_h0 = vertical_compose_daub97iH0; + d->vertical_compose_l1 = vertical_compose_daub97iL1; + d->vertical_compose_h1 = vertical_compose_daub97iH1; + d->horizontal_compose = horizontal_compose_daub97i; + d->support = 5; + break; + default: + av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type); + return AVERROR_OPTION_NOT_FOUND; + } + + return 0; +} + +void ff_spatial_idwt_slice2(DWTContext *d, int y) +{ + int level, support = d->support; + + for (level = d->decomposition_count - 1; level >= 0; level--) { + int wl = d->width >> level; + int hl = d->height >> level; + int stride_l = d->stride << level; + + while (d->cs[level].y <= FFMIN((y >> level) + support, hl)) + d->spatial_compose(d, level, wl, hl, stride_l); + } +} + +int ff_spatial_idwt2(IDWTELEM *buffer, int width, int height, int stride, + enum dwt_type type, int decomposition_count, + IDWTELEM *temp) +{ + DWTContext d; + int y; + int ret; + + if (ret = ff_spatial_idwt_init2(&d, buffer, width, height, stride, type, + decomposition_count, temp)) + return ret; + + for (y = 0; y < d.height; y += 4) + ff_spatial_idwt_slice2(&d, y); + + return 0; +} diff --git a/libavcodec/dirac_dwt.h b/libavcodec/dirac_dwt.h new file mode 100644 index 0000000..ff0e4ba --- /dev/null +++ b/libavcodec/dirac_dwt.h @@ -0,0 +1,74 @@ +#include "dwt.h" + +enum dwt_type { + DWT_SNOW_DAUB9_7, + DWT_SNOW_LEGALL5_3, + DWT_DIRAC_DD9_7, + DWT_DIRAC_LEGALL5_3, + DWT_DIRAC_DD13_7, + DWT_DIRAC_HAAR0, + DWT_DIRAC_HAAR1, + DWT_DIRAC_FIDELITY, + DWT_DIRAC_DAUB9_7, + DWT_NUM_TYPES +}; + + +// Possible prototypes for vertical_compose functions +typedef void (*vertical_compose_2tap)(IDWTELEM *b0, IDWTELEM *b1, int width); +typedef void (*vertical_compose_3tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + int width); +typedef void (*vertical_compose_5tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + IDWTELEM *b3, IDWTELEM *b4, int width); +typedef void (*vertical_compose_9tap)(IDWTELEM *dst, IDWTELEM *b[8], + int width); + +// -1 if an error occurred, e.g. the dwt_type isn't recognized +int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, + int height, int stride, enum dwt_type type, + int decomposition_count, IDWTELEM *temp); + +int ff_spatial_idwt2(IDWTELEM *buffer, int width, int height, int stride, + enum dwt_type type, int decomposition_count, + IDWTELEM *temp); + +void ff_spatial_idwt_slice2(DWTContext *d, int y); + +// shared stuff for simd optimiztions +#define COMPOSE_53iL0(b0, b1, b2) \ + (b1 - ((b0 + b2 + 2) >> 2)) + +#define COMPOSE_DIRAC53iH0(b0, b1, b2) \ + (b1 + ((b0 + b2 + 1) >> 1)) + +#define COMPOSE_DD97iH0(b0, b1, b2, b3, b4) \ + (b2 + ((-b0 + 9 * b1 + 9 * b3 - b4 + 8) >> 4)) + +#define COMPOSE_DD137iL0(b0, b1, b2, b3, b4) \ + (b2 - ((-b0 + 9 * b1 + 9 * b3 - b4 + 16) >> 5)) + +#define COMPOSE_HAARiL0(b0, b1) \ + (b0 - ((b1 + 1) >> 1)) + +#define COMPOSE_HAARiH0(b0, b1) \ + (b0 + b1) + +#define COMPOSE_FIDELITYiL0(b0, b1, b2, b3, b4, b5, b6, b7, b8) \ + (b4 - ((-8 * (b0 + b8) + 21 * (b1 + b7) - 46 * (b2 + b6) + \ + 161 * (b3 + b5) + 128) >> 8)) + +#define COMPOSE_FIDELITYiH0(b0, b1, b2, b3, b4, b5, b6, b7, b8) \ + (b4 + ((-2 * (b0 + b8) + 10 * (b1 + b7) - 25 * (b2 + b6) + \ + 81 * (b3 + b5) + 128) >> 8)) + +#define COMPOSE_DAUB97iL1(b0, b1, b2) \ + (b1 - ((1817 * (b0 + b2) + 2048) >> 12)) + +#define COMPOSE_DAUB97iH1(b0, b1, b2) \ + (b1 - ((113 * (b0 + b2) + 64) >> 7)) + +#define COMPOSE_DAUB97iL0(b0, b1, b2) \ + (b1 + ((217 * (b0 + b2) + 2048) >> 12)) + +#define COMPOSE_DAUB97iH0(b0, b1, b2) \ + (b1 + ((6497 * (b0 + b2) + 2048) >> 12)) diff --git a/libavcodec/dwt.h b/libavcodec/dwt.h index b41e128..8cf51f0 100644 --- a/libavcodec/dwt.h +++ b/libavcodec/dwt.h @@ -26,7 +26,12 @@ typedef int DWTELEM; typedef short IDWTELEM; +#define MAX_DWT_SUPPORT 8 +#define MAX_DECOMPOSITIONS 8 + typedef struct { + IDWTELEM *b[MAX_DWT_SUPPORT]; + IDWTELEM *b0; IDWTELEM *b1; IDWTELEM *b2; @@ -57,8 +62,6 @@ typedef struct DWTContext { int add, uint8_t *dst8); } DWTContext; -#define MAX_DECOMPOSITIONS 8 - #define DWT_97 0 #define DWT_53 1 -- 1.7.10.4 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel