Message ID | 20240905015436.78024-1-owatanab@es.takushoku-u.ac.jp |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,v3,1/2] avcodec/jpeg2000dec: Fix FF_DWT97_INT to pass the conformance testing defined in ISO/IEC 15444-4. | expand |
Context | Check | Description |
---|---|---|
yinshiyou/make_loongarch64 | success | Make finished |
yinshiyou/make_fate_loongarch64 | fail | Make fate failed |
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | fail | Make fate failed |
Some typos and trailing white spaces are found. Those will be corrected in the upcoming v4. > On Sep 5, 2024, at 10:54, WATANABE Osamu <owatanab@es.takushoku-u.ac.jp> wrote: > > This commit fixes the problem described below on the integer version of the inverse DWT processing (FF_DWT97_INT, https://trac.ffmpeg.org/ticket/10123), which is activated with `-flags +bitexact`. > > - Problem > - The tests for the following codestreams were failed with `-flags +bitexact`. > - p0_04.j2k, p0_05.j2k, p0_09.j2k, p1_02.j2k, p1_03.j2k, p1_06.j2k. > - ds0_ht_04_b11.j2k, ds0_ht_04_b12.j2k, ds0_ht_05_b11.j2k, ds0_ht_05_b12.j2k, ds0_ht_09_b11.j2k, ds1_ht_02_b11.j2k, ds1_ht_02_b12.j2k, ds1_ht_03_b11.j2k, ds1_ht_03_b12.j2k, ds1_ht_06_b11.j2k. > > Signed-off-by: Osamu Watanabe <owatanab@es.takushoku-u.ac.jp> > --- > libavcodec/j2kenc.c | 9 +++++++-- > libavcodec/jpeg2000.c | 7 +++---- > libavcodec/jpeg2000dec.c | 4 +++- > libavcodec/jpeg2000dwt.c | 38 +++++++++++++++++++++++++------------- > 4 files changed, 38 insertions(+), 20 deletions(-) > > diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c > index 91e66d8104..ecd9f42401 100644 > --- a/libavcodec/j2kenc.c > +++ b/libavcodec/j2kenc.c > @@ -1384,7 +1384,9 @@ static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) > Jpeg2000Band *band = reslevel->band + bandno; > Jpeg2000Prec *prec = band->prec + precno; > > - int64_t dwt_norm = dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 15; > + // Shifting down to 1 bit above from the bi/nary point. > + // This is mandatory for FF_DWT97_INT to maintain its precision. > + int64_t dwt_norm = dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 14; > int64_t lambda_prime = av_rescale(s->lambda, 1 << WMSEDEC_SHIFT, dwt_norm * dwt_norm); > for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ > Jpeg2000Cblk *cblk = prec->cblk + cblkno; > @@ -1457,7 +1459,10 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno > int *ptr = t1.data + (y-yy0)*t1.stride; > for (x = xx0; x < xx1; x++){ > *ptr = (comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]); > - *ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 15 - NMSEDEC_FRACBITS; > + > + // Shifting down to 1 bit above from the bi/nary point. > + // This is mandatory for FF_DWT97_INT to maintain its precision. > + *ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 14 - NMSEDEC_FRACBITS; > ptr++; > } > } > diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c > index d6ffb02319..2d093e4705 100644 > --- a/libavcodec/jpeg2000.c > +++ b/libavcodec/jpeg2000.c > @@ -260,9 +260,8 @@ static void init_band_stepsize(AVCodecContext *avctx, > band->f_stepsize *= F_LFTG_X * F_LFTG_X * 4; > break; > } > - if (codsty->transform == FF_DWT97) { > - band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2); > - } > + // scaling > + band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2); > } > > if (band->f_stepsize > (INT_MAX >> 15)) { > @@ -270,7 +269,7 @@ static void init_band_stepsize(AVCodecContext *avctx, > av_log(avctx, AV_LOG_ERROR, "stepsize out of range\n"); > } > > - band->i_stepsize = band->f_stepsize * (1 << 15); > + band->i_stepsize = lrint(band->f_stepsize * (1 << 15) + 0.5f); > > /* FIXME: In OpenJPEG code stepsize = stepsize * 0.5. Why? > * If not set output of entropic decoder is not correct. */ > diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c > index 2e09b279dc..6af8c764d0 100644 > --- a/libavcodec/jpeg2000dec.c > +++ b/libavcodec/jpeg2000dec.c > @@ -2136,7 +2136,9 @@ static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk, > int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x]; > int *src = t1->data + j*t1->stride; > for (i = 0; i < w; ++i) > - datap[i] = (src[i] * (int64_t)band->i_stepsize + (1<<15)) >> 16; > + // Shifting down to 1 bit above from the binary point. > + // This is mandatory for FF_DWT97_INT to pass the conformance testing. > + datap[i] = (int32_t)(src[i] * (int64_t)band->i_stepsize + (1 << 14)) >> 15; > } > } > > diff --git a/libavcodec/jpeg2000dwt.c b/libavcodec/jpeg2000dwt.c > index 34e33553f7..6994809ac0 100644 > --- a/libavcodec/jpeg2000dwt.c > +++ b/libavcodec/jpeg2000dwt.c > @@ -39,7 +39,7 @@ > > /* Lifting parameters in integer format. > * Computed as param = (float param) * (1 << 16) */ > -#define I_LFTG_ALPHA 103949ll > +#define I_LFTG_ALPHA 38413ll // = 103949 - 65536, (= 1.586 - 1.0) > #define I_LFTG_BETA 3472ll > #define I_LFTG_GAMMA 57862ll > #define I_LFTG_DELTA 29066ll > @@ -234,8 +234,11 @@ static void sd_1d97_int(int *p, int i0, int i1) > extend97_int(p, i0, i1); > i0++; i1++; > > - for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++) > - p[2 * i + 1] -= (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16; > + for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++) { > + int64_t sum = p[2 * i] + p[2 * i + 2]; > + p[2 * i + 1] -= sum; > + p[2 * i + 1] -= (I_LFTG_ALPHA * sum + (1 << 15)) >> 16; > + } > for (i = (i0>>1) - 1; i < (i1>>1) + 1; i++) > p[2 * i] -= (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16; > for (i = (i0>>1) - 1; i < (i1>>1); i++) > @@ -276,7 +279,7 @@ static void dwt_encode97_int(DWTContext *s, int *t) > > // copy back and deinterleave > for (i = mv; i < lv; i+=2, j++) > - t[w*j + lp] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; > + t[w*j + lp] = l[i]; // ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; > for (i = 1-mv; i < lv; i+=2, j++) > t[w*j + lp] = l[i]; > } > @@ -293,7 +296,7 @@ static void dwt_encode97_int(DWTContext *s, int *t) > > // copy back and deinterleave > for (i = mh; i < lh; i+=2, j++) > - t[w*lp + j] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; > + t[w*lp + j] = l[i]; // ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; > for (i = 1-mh; i < lh; i+=2, j++) > t[w*lp + j] = l[i]; > } > @@ -301,7 +304,10 @@ static void dwt_encode97_int(DWTContext *s, int *t) > } > > for (i = 0; i < w * h; i++) > - t[i] = (t[i] + ((1<<I_PRESHIFT)>>1)) >> I_PRESHIFT; > + // Shifting down to the binary point. > + // In FF_DWT97_INT, the binary point of the input coefficients is 1 bit above from the LSB. > + // So, we need `>> (I_PRESHIFT + 1)` here. > + t[i] = (t[i] + ((1<<(I_PRESHIFT + 1))>>1)) >> (I_PRESHIFT + 1); > } > > static void sr_1d53(unsigned *p, int i0, int i1) > @@ -471,8 +477,11 @@ static void sr_1d97_int(int32_t *p, int i0, int i1) > for (i = (i0 >> 1); i < (i1 >> 1) + 1; i++) > p[2 * i] += (I_LFTG_BETA * (p[2 * i - 1] + (int64_t)p[2 * i + 1]) + (1 << 15)) >> 16; > /* step 6 */ > - for (i = (i0 >> 1); i < (i1 >> 1); i++) > - p[2 * i + 1] += (I_LFTG_ALPHA * (p[2 * i] + (int64_t)p[2 * i + 2]) + (1 << 15)) >> 16; > + for (i = (i0 >> 1); i < (i1 >> 1); i++) { > + int64_t sum = p[2 * i] + (int64_t) p[2 * i + 2]; > + p[2 * i + 1] += sum; > + p[2 * i + 1] += (I_LFTG_ALPHA * sum + (1 << 15)) >> 16; > + } > } > > static void dwt_decode97_int(DWTContext *s, int32_t *t) > @@ -500,9 +509,9 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t) > l = line + mh; > for (lp = 0; lp < lv; lp++) { > int i, j = 0; > - // rescale with interleaving > + // interleaving > for (i = mh; i < lh; i += 2, j++) > - l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16; > + l[i] = data[w * lp + j]; > for (i = 1 - mh; i < lh; i += 2, j++) > l[i] = data[w * lp + j]; > > @@ -516,9 +525,9 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t) > l = line + mv; > for (lp = 0; lp < lh; lp++) { > int i, j = 0; > - // rescale with interleaving > + // interleaving > for (i = mv; i < lv; i += 2, j++) > - l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16; > + l[i] = data[w * j + lp]; > for (i = 1 - mv; i < lv; i += 2, j++) > l[i] = data[w * j + lp]; > > @@ -530,7 +539,10 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t) > } > > for (i = 0; i < w * h; i++) > - data[i] = (data[i] + ((1LL<<I_PRESHIFT)>>1)) >> I_PRESHIFT; > + // Shifting down to the binary point. > + // In FF_DWT97_INT, the binary point of the input coefficients is 1 bit above from the LSB. > + // So, we need `>> (I_PRESHIFT + 1)` here. > + data[i] = (int32_t)(data[i] + ((1LL<<(I_PRESHIFT + 1))>>1)) >> (I_PRESHIFT + 1); > } > > int ff_jpeg2000_dwt_init(DWTContext *s, int border[2][2], > -- > 2.43.0 >
diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index 91e66d8104..ecd9f42401 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -1384,7 +1384,9 @@ static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile) Jpeg2000Band *band = reslevel->band + bandno; Jpeg2000Prec *prec = band->prec + precno; - int64_t dwt_norm = dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 15; + // Shifting down to 1 bit above from the bi/nary point. + // This is mandatory for FF_DWT97_INT to maintain its precision. + int64_t dwt_norm = dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 14; int64_t lambda_prime = av_rescale(s->lambda, 1 << WMSEDEC_SHIFT, dwt_norm * dwt_norm); for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){ Jpeg2000Cblk *cblk = prec->cblk + cblkno; @@ -1457,7 +1459,10 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno int *ptr = t1.data + (y-yy0)*t1.stride; for (x = xx0; x < xx1; x++){ *ptr = (comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]); - *ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 15 - NMSEDEC_FRACBITS; + + // Shifting down to 1 bit above from the bi/nary point. + // This is mandatory for FF_DWT97_INT to maintain its precision. + *ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 14 - NMSEDEC_FRACBITS; ptr++; } } diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index d6ffb02319..2d093e4705 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -260,9 +260,8 @@ static void init_band_stepsize(AVCodecContext *avctx, band->f_stepsize *= F_LFTG_X * F_LFTG_X * 4; break; } - if (codsty->transform == FF_DWT97) { - band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2); - } + // scaling + band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2); } if (band->f_stepsize > (INT_MAX >> 15)) { @@ -270,7 +269,7 @@ static void init_band_stepsize(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "stepsize out of range\n"); } - band->i_stepsize = band->f_stepsize * (1 << 15); + band->i_stepsize = lrint(band->f_stepsize * (1 << 15) + 0.5f); /* FIXME: In OpenJPEG code stepsize = stepsize * 0.5. Why? * If not set output of entropic decoder is not correct. */ diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 2e09b279dc..6af8c764d0 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -2136,7 +2136,9 @@ static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk, int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x]; int *src = t1->data + j*t1->stride; for (i = 0; i < w; ++i) - datap[i] = (src[i] * (int64_t)band->i_stepsize + (1<<15)) >> 16; + // Shifting down to 1 bit above from the binary point. + // This is mandatory for FF_DWT97_INT to pass the conformance testing. + datap[i] = (int32_t)(src[i] * (int64_t)band->i_stepsize + (1 << 14)) >> 15; } } diff --git a/libavcodec/jpeg2000dwt.c b/libavcodec/jpeg2000dwt.c index 34e33553f7..6994809ac0 100644 --- a/libavcodec/jpeg2000dwt.c +++ b/libavcodec/jpeg2000dwt.c @@ -39,7 +39,7 @@ /* Lifting parameters in integer format. * Computed as param = (float param) * (1 << 16) */ -#define I_LFTG_ALPHA 103949ll +#define I_LFTG_ALPHA 38413ll // = 103949 - 65536, (= 1.586 - 1.0) #define I_LFTG_BETA 3472ll #define I_LFTG_GAMMA 57862ll #define I_LFTG_DELTA 29066ll @@ -234,8 +234,11 @@ static void sd_1d97_int(int *p, int i0, int i1) extend97_int(p, i0, i1); i0++; i1++; - for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++) - p[2 * i + 1] -= (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16; + for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++) { + int64_t sum = p[2 * i] + p[2 * i + 2]; + p[2 * i + 1] -= sum; + p[2 * i + 1] -= (I_LFTG_ALPHA * sum + (1 << 15)) >> 16; + } for (i = (i0>>1) - 1; i < (i1>>1) + 1; i++) p[2 * i] -= (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16; for (i = (i0>>1) - 1; i < (i1>>1); i++) @@ -276,7 +279,7 @@ static void dwt_encode97_int(DWTContext *s, int *t) // copy back and deinterleave for (i = mv; i < lv; i+=2, j++) - t[w*j + lp] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; + t[w*j + lp] = l[i]; // ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; for (i = 1-mv; i < lv; i+=2, j++) t[w*j + lp] = l[i]; } @@ -293,7 +296,7 @@ static void dwt_encode97_int(DWTContext *s, int *t) // copy back and deinterleave for (i = mh; i < lh; i+=2, j++) - t[w*lp + j] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; + t[w*lp + j] = l[i]; // ((l[i] * I_LFTG_X) + (1 << 15)) >> 16; for (i = 1-mh; i < lh; i+=2, j++) t[w*lp + j] = l[i]; } @@ -301,7 +304,10 @@ static void dwt_encode97_int(DWTContext *s, int *t) } for (i = 0; i < w * h; i++) - t[i] = (t[i] + ((1<<I_PRESHIFT)>>1)) >> I_PRESHIFT; + // Shifting down to the binary point. + // In FF_DWT97_INT, the binary point of the input coefficients is 1 bit above from the LSB. + // So, we need `>> (I_PRESHIFT + 1)` here. + t[i] = (t[i] + ((1<<(I_PRESHIFT + 1))>>1)) >> (I_PRESHIFT + 1); } static void sr_1d53(unsigned *p, int i0, int i1) @@ -471,8 +477,11 @@ static void sr_1d97_int(int32_t *p, int i0, int i1) for (i = (i0 >> 1); i < (i1 >> 1) + 1; i++) p[2 * i] += (I_LFTG_BETA * (p[2 * i - 1] + (int64_t)p[2 * i + 1]) + (1 << 15)) >> 16; /* step 6 */ - for (i = (i0 >> 1); i < (i1 >> 1); i++) - p[2 * i + 1] += (I_LFTG_ALPHA * (p[2 * i] + (int64_t)p[2 * i + 2]) + (1 << 15)) >> 16; + for (i = (i0 >> 1); i < (i1 >> 1); i++) { + int64_t sum = p[2 * i] + (int64_t) p[2 * i + 2]; + p[2 * i + 1] += sum; + p[2 * i + 1] += (I_LFTG_ALPHA * sum + (1 << 15)) >> 16; + } } static void dwt_decode97_int(DWTContext *s, int32_t *t) @@ -500,9 +509,9 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t) l = line + mh; for (lp = 0; lp < lv; lp++) { int i, j = 0; - // rescale with interleaving + // interleaving for (i = mh; i < lh; i += 2, j++) - l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16; + l[i] = data[w * lp + j]; for (i = 1 - mh; i < lh; i += 2, j++) l[i] = data[w * lp + j]; @@ -516,9 +525,9 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t) l = line + mv; for (lp = 0; lp < lh; lp++) { int i, j = 0; - // rescale with interleaving + // interleaving for (i = mv; i < lv; i += 2, j++) - l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16; + l[i] = data[w * j + lp]; for (i = 1 - mv; i < lv; i += 2, j++) l[i] = data[w * j + lp]; @@ -530,7 +539,10 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t) } for (i = 0; i < w * h; i++) - data[i] = (data[i] + ((1LL<<I_PRESHIFT)>>1)) >> I_PRESHIFT; + // Shifting down to the binary point. + // In FF_DWT97_INT, the binary point of the input coefficients is 1 bit above from the LSB. + // So, we need `>> (I_PRESHIFT + 1)` here. + data[i] = (int32_t)(data[i] + ((1LL<<(I_PRESHIFT + 1))>>1)) >> (I_PRESHIFT + 1); } int ff_jpeg2000_dwt_init(DWTContext *s, int border[2][2],
This commit fixes the problem described below on the integer version of the inverse DWT processing (FF_DWT97_INT, https://trac.ffmpeg.org/ticket/10123), which is activated with `-flags +bitexact`. - Problem - The tests for the following codestreams were failed with `-flags +bitexact`. - p0_04.j2k, p0_05.j2k, p0_09.j2k, p1_02.j2k, p1_03.j2k, p1_06.j2k. - ds0_ht_04_b11.j2k, ds0_ht_04_b12.j2k, ds0_ht_05_b11.j2k, ds0_ht_05_b12.j2k, ds0_ht_09_b11.j2k, ds1_ht_02_b11.j2k, ds1_ht_02_b12.j2k, ds1_ht_03_b11.j2k, ds1_ht_03_b12.j2k, ds1_ht_06_b11.j2k. Signed-off-by: Osamu Watanabe <owatanab@es.takushoku-u.ac.jp> --- libavcodec/j2kenc.c | 9 +++++++-- libavcodec/jpeg2000.c | 7 +++---- libavcodec/jpeg2000dec.c | 4 +++- libavcodec/jpeg2000dwt.c | 38 +++++++++++++++++++++++++------------- 4 files changed, 38 insertions(+), 20 deletions(-)