Skip to content

Commit bc8aeee

Browse files
committed
avcodec/jpeg2000dec: Fix FF_DWT97_INT to pass the conformance testing defined in ISO/IEC 15444-4
This commit fixes the problem described below on the integer version of the inverse 9-7 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. - These failure comes from the insufficient fraction bits of the fixed-point implementation of the 9-7 DWT.
1 parent 3f9b78b commit bc8aeee

File tree

4 files changed

+38
-20
lines changed

4 files changed

+38
-20
lines changed

libavcodec/j2kenc.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,7 +1384,9 @@ static void truncpasses(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile)
13841384
Jpeg2000Band *band = reslevel->band + bandno;
13851385
Jpeg2000Prec *prec = band->prec + precno;
13861386

1387-
int64_t dwt_norm = dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 15;
1387+
// Shifting down to 1 bit above from the binary point.
1388+
// This is mandatory for FF_DWT97_INT to maintain its precision.
1389+
int64_t dwt_norm = dwt_norms[codsty->transform == FF_DWT53][bandpos][lev] * (int64_t)band->i_stepsize >> 14;
13881390
int64_t lambda_prime = av_rescale(s->lambda, 1 << WMSEDEC_SHIFT, dwt_norm * dwt_norm);
13891391
for (cblkno = 0; cblkno < prec->nb_codeblocks_height * prec->nb_codeblocks_width; cblkno++){
13901392
Jpeg2000Cblk *cblk = prec->cblk + cblkno;
@@ -1457,7 +1459,10 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno
14571459
int *ptr = t1.data + (y-yy0)*t1.stride;
14581460
for (x = xx0; x < xx1; x++){
14591461
*ptr = (comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]);
1460-
*ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 15 - NMSEDEC_FRACBITS;
1462+
1463+
// Shifting down to 1 bit above from the binary point.
1464+
// This is mandatory for FF_DWT97_INT to maintain its precision.
1465+
*ptr = (int64_t)*ptr * (int64_t)(16384 * 65536 / band->i_stepsize) >> 14 - NMSEDEC_FRACBITS;
14611466
ptr++;
14621467
}
14631468
}

libavcodec/jpeg2000.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,17 +260,16 @@ static void init_band_stepsize(AVCodecContext *avctx,
260260
band->f_stepsize *= F_LFTG_X * F_LFTG_X * 4;
261261
break;
262262
}
263-
if (codsty->transform == FF_DWT97) {
264-
band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2);
265-
}
263+
// scaling
264+
band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2);
266265
}
267266

268267
if (band->f_stepsize > (INT_MAX >> 15)) {
269268
band->f_stepsize = 0;
270269
av_log(avctx, AV_LOG_ERROR, "stepsize out of range\n");
271270
}
272271

273-
band->i_stepsize = band->f_stepsize * (1 << 15);
272+
band->i_stepsize = lrint(band->f_stepsize * (1 << 15) + 0.5f);
274273

275274
/* FIXME: In OpenJPEG code stepsize = stepsize * 0.5. Why?
276275
* If not set output of entropic decoder is not correct. */

libavcodec/jpeg2000dec.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2136,7 +2136,9 @@ static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk,
21362136
int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
21372137
int *src = t1->data + j*t1->stride;
21382138
for (i = 0; i < w; ++i)
2139-
datap[i] = (src[i] * (int64_t)band->i_stepsize + (1<<15)) >> 16;
2139+
// Shifting down to 1 bit above from the binary point.
2140+
// This is mandatory for FF_DWT97_INT to pass the conformance testing.
2141+
datap[i] = (int32_t)(src[i] * (int64_t)band->i_stepsize + (1 << 14)) >> 15;
21402142
}
21412143
}
21422144

libavcodec/jpeg2000dwt.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
/* Lifting parameters in integer format.
4141
* Computed as param = (float param) * (1 << 16) */
42-
#define I_LFTG_ALPHA 103949ll
42+
#define I_LFTG_ALPHA 38413ll // = 103949 - 65536, (= 1.586 - 1.0)
4343
#define I_LFTG_BETA 3472ll
4444
#define I_LFTG_GAMMA 57862ll
4545
#define I_LFTG_DELTA 29066ll
@@ -234,8 +234,11 @@ static void sd_1d97_int(int *p, int i0, int i1)
234234
extend97_int(p, i0, i1);
235235
i0++; i1++;
236236

237-
for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++)
238-
p[2 * i + 1] -= (I_LFTG_ALPHA * (p[2 * i] + p[2 * i + 2]) + (1 << 15)) >> 16;
237+
for (i = (i0>>1) - 2; i < (i1>>1) + 1; i++) {
238+
int64_t sum = p[2 * i] + p[2 * i + 2];
239+
p[2 * i + 1] -= sum;
240+
p[2 * i + 1] -= (I_LFTG_ALPHA * sum + (1 << 15)) >> 16;
241+
}
239242
for (i = (i0>>1) - 1; i < (i1>>1) + 1; i++)
240243
p[2 * i] -= (I_LFTG_BETA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
241244
for (i = (i0>>1) - 1; i < (i1>>1); i++)
@@ -276,7 +279,7 @@ static void dwt_encode97_int(DWTContext *s, int *t)
276279

277280
// copy back and deinterleave
278281
for (i = mv; i < lv; i+=2, j++)
279-
t[w*j + lp] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16;
282+
t[w*j + lp] = l[i];
280283
for (i = 1-mv; i < lv; i+=2, j++)
281284
t[w*j + lp] = l[i];
282285
}
@@ -293,15 +296,18 @@ static void dwt_encode97_int(DWTContext *s, int *t)
293296

294297
// copy back and deinterleave
295298
for (i = mh; i < lh; i+=2, j++)
296-
t[w*lp + j] = ((l[i] * I_LFTG_X) + (1 << 15)) >> 16;
299+
t[w*lp + j] = l[i];
297300
for (i = 1-mh; i < lh; i+=2, j++)
298301
t[w*lp + j] = l[i];
299302
}
300303

301304
}
302305

303306
for (i = 0; i < w * h; i++)
304-
t[i] = (t[i] + ((1<<I_PRESHIFT)>>1)) >> I_PRESHIFT;
307+
// Shifting down to the binary point.
308+
// In FF_DWT97_INT, the binary point of the input coefficients is 1 bit above from the LSB.
309+
// So, we need `>> (I_PRESHIFT + 1)` here.
310+
t[i] = (t[i] + ((1<<(I_PRESHIFT + 1))>>1)) >> (I_PRESHIFT + 1);
305311
}
306312

307313
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)
471477
for (i = (i0 >> 1); i < (i1 >> 1) + 1; i++)
472478
p[2 * i] += (I_LFTG_BETA * (p[2 * i - 1] + (int64_t)p[2 * i + 1]) + (1 << 15)) >> 16;
473479
/* step 6 */
474-
for (i = (i0 >> 1); i < (i1 >> 1); i++)
475-
p[2 * i + 1] += (I_LFTG_ALPHA * (p[2 * i] + (int64_t)p[2 * i + 2]) + (1 << 15)) >> 16;
480+
for (i = (i0 >> 1); i < (i1 >> 1); i++) {
481+
int64_t sum = p[2 * i] + (int64_t) p[2 * i + 2];
482+
p[2 * i + 1] += sum;
483+
p[2 * i + 1] += (I_LFTG_ALPHA * sum + (1 << 15)) >> 16;
484+
}
476485
}
477486

478487
static void dwt_decode97_int(DWTContext *s, int32_t *t)
@@ -500,9 +509,9 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t)
500509
l = line + mh;
501510
for (lp = 0; lp < lv; lp++) {
502511
int i, j = 0;
503-
// rescale with interleaving
512+
// interleaving
504513
for (i = mh; i < lh; i += 2, j++)
505-
l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16;
514+
l[i] = data[w * lp + j];
506515
for (i = 1 - mh; i < lh; i += 2, j++)
507516
l[i] = data[w * lp + j];
508517

@@ -516,9 +525,9 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t)
516525
l = line + mv;
517526
for (lp = 0; lp < lh; lp++) {
518527
int i, j = 0;
519-
// rescale with interleaving
528+
// interleaving
520529
for (i = mv; i < lv; i += 2, j++)
521-
l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16;
530+
l[i] = data[w * j + lp];
522531
for (i = 1 - mv; i < lv; i += 2, j++)
523532
l[i] = data[w * j + lp];
524533

@@ -530,7 +539,10 @@ static void dwt_decode97_int(DWTContext *s, int32_t *t)
530539
}
531540

532541
for (i = 0; i < w * h; i++)
533-
data[i] = (data[i] + ((1LL<<I_PRESHIFT)>>1)) >> I_PRESHIFT;
542+
// Shifting down to the binary point.
543+
// In FF_DWT97_INT, the binary point of the input coefficients is 1 bit above from the LSB.
544+
// So, we need `>> (I_PRESHIFT + 1)` here.
545+
data[i] = (int32_t)(data[i] + ((1LL<<(I_PRESHIFT + 1))>>1)) >> (I_PRESHIFT + 1);
534546
}
535547

536548
int ff_jpeg2000_dwt_init(DWTContext *s, int border[2][2],

0 commit comments

Comments
 (0)