From 3204e675eabf9ac0145a48f26820aeda26924e5a Mon Sep 17 00:00:00 2001 From: Osamu WATANABE Date: Wed, 29 Jul 2020 12:19:07 +0900 Subject: [PATCH 1/5] Fix incorrect calculation of derived stepsizes Why: If the LSB of the Sqcd or Sqcc in the QCD or QCC marker is equal to "1" , this incorrect calculation of derived stepsizes produces wrongly reconstructed sample values. How: The calculation of derived stepsizes in calcstepsizes() has been fixed according to the JPEG 2000 spec defined as the ISO/IEC 15444-1. --- src/libjasper/jpc/jpc_dec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libjasper/jpc/jpc_dec.c b/src/libjasper/jpc/jpc_dec.c index 22275462..a4975f9e 100644 --- a/src/libjasper/jpc/jpc_dec.c +++ b/src/libjasper/jpc/jpc_dec.c @@ -1751,6 +1751,8 @@ static int calcstepsizes(uint_fast16_t refstepsize, int numrlvls, { int bandno; int numbands; + int r; + int nb; uint_fast16_t expn; uint_fast16_t mant; expn = JPC_QCX_GETEXPN(refstepsize); @@ -1758,7 +1760,9 @@ static int calcstepsizes(uint_fast16_t refstepsize, int numrlvls, numbands = 3 * numrlvls - 2; for (bandno = 0; bandno < numbands; ++bandno) { //jas_eprintf("DEBUG %d %d %d %d %d\n", bandno, expn, numrlvls, bandno, ((numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3) : (0))))); - uint_fast16_t e = expn + (bandno + 2) / 3; + r = (bandno + 2) / 3; + nb = (r == 0) ? (numrlvls - 1) - r : (numrlvls - 1) - r + 1; + uint_fast16_t e = expn - (numrlvls - 1) + nb; if (e >= 0x20) return -1; stepsizes[bandno] = JPC_QCX_MANT(mant) | JPC_QCX_EXPN(e); From 1c220a140086d58d33b096bcfd5baec9e45da45e Mon Sep 17 00:00:00 2001 From: Osamu WATANABE Date: Wed, 29 Jul 2020 12:23:08 +0900 Subject: [PATCH 2/5] Fix incorrect propagation of a COC parameter (DWT transform) Why: If the DWT transform differs among components, the information of DWT transform used for each component should be found as the COC marker segment. This information is wrongly used for dequantization and rounding in JasPer. How: Fixed dequantization and rounding in jpc_dec_tiledecode() to use ccp->qmfbid which has the information of DWT transform. --- src/libjasper/jpc/jpc_dec.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libjasper/jpc/jpc_dec.c b/src/libjasper/jpc/jpc_dec.c index a4975f9e..cda2f897 100644 --- a/src/libjasper/jpc/jpc_dec.c +++ b/src/libjasper/jpc/jpc_dec.c @@ -1123,7 +1123,7 @@ static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile) } jpc_undo_roi(band->data, band->roishift, ccp->roishift - band->roishift, band->numbps); - if (tile->realmode) { + if (ccp->qmfbid == JPC_COX_INS) { jas_matrix_asl(band->data, JPC_FIX_FRACBITS); jpc_dequantize(band->data, band->absstepsize); } @@ -1169,9 +1169,10 @@ static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile) } /* Perform rounding and convert to integer values. */ - if (tile->realmode) { - for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps; + for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps; ++compno, ++tcomp) { + ccp = &tile->cp->ccps[compno]; + if (ccp->qmfbid == JPC_COX_INS) { for (jas_matind_t i = 0; i < jas_matrix_numrows(tcomp->data); ++i) { for (jas_matind_t j = 0; j < jas_matrix_numcols(tcomp->data); ++j) { v = jas_matrix_get(tcomp->data, i, j); From cc814c9828c5a6f76ba6c19f1f690c33fae6e3b7 Mon Sep 17 00:00:00 2001 From: Osamu WATANABE Date: Wed, 29 Jul 2020 12:25:00 +0900 Subject: [PATCH 3/5] Fix the problem that a tile with TNsot = 0 for all the tile-parts is never decoded Why: If a tile has multiple tile-parts and all the tile-parts have the TNsot (a parameter in the tile-part header) = 0, such a tile is never decoded. How: Modified the condition whether jpc_dec_tiledecode() shall be invoked or not in jpc_dec_process_eoc() --- src/libjasper/jpc/jpc_dec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libjasper/jpc/jpc_dec.c b/src/libjasper/jpc/jpc_dec.c index cda2f897..06f33e78 100644 --- a/src/libjasper/jpc/jpc_dec.c +++ b/src/libjasper/jpc/jpc_dec.c @@ -1232,7 +1232,8 @@ static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms) for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno, ++tile) { - if (tile->state == JPC_TILE_ACTIVE) { + if (tile->state == JPC_TILE_ACTIVE || + tile->state == JPC_TILE_ACTIVELAST) { if (jpc_dec_tiledecode(dec, tile)) { return -1; } From 2004078036ced28ff167cf439d7a1c648c955201 Mon Sep 17 00:00:00 2001 From: Osamu WATANABE Date: Wed, 29 Jul 2020 12:26:48 +0900 Subject: [PATCH 4/5] Fix incorrect precinct edge detection in RPCL progression order Why: The condition for edge detection of precincts in jpc_pi_nextrpcl is wrong. (For example the p1_07 codestream used for the conformance contains first the packet for component 1, resolution 0, component 0, position (4,0) before the packet for component 0, resolution 0, component 0, position (8,0), but JasPer reads them in the wrong order.) How: Fixed the condition according to the JPEG 2000 spec defined as the ISO/IEC 15444-1. --- src/libjasper/jpc/jpc_t2cod.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libjasper/jpc/jpc_t2cod.c b/src/libjasper/jpc/jpc_t2cod.c index 5b59a06a..f7ef38f9 100644 --- a/src/libjasper/jpc/jpc_t2cod.c +++ b/src/libjasper/jpc/jpc_t2cod.c @@ -292,10 +292,10 @@ static int jpc_pi_nextrpcl(register jpc_pi_t *pi) try0 = JPC_CEILDIV(pi->ystart, pi->picomp->vsamp << r); if (((pi->x == pi->xstart && ((trx0 << r) % (JAS_CAST(uint_fast32_t, 1) << rpx))) - || !(pi->x % (JAS_CAST(uint_fast32_t, 1) << rpx))) && + || !(pi->x % (pi->picomp->hsamp << rpx))) && ((pi->y == pi->ystart && ((try0 << r) % (JAS_CAST(uint_fast32_t, 1) << rpy))) - || !(pi->y % (JAS_CAST(uint_fast32_t, 1) << rpy)))) { + || !(pi->y % (pi->picomp->vsamp << rpy)))) { prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0, pi->pirlvl->prcwidthexpn); From 55562ce1abad526d733be6f49805966d47fa50c8 Mon Sep 17 00:00:00 2001 From: Osamu WATANABE Date: Wed, 29 Jul 2020 12:28:51 +0900 Subject: [PATCH 5/5] Dequantization using the mid-point reconstruction Why: In the JPEG 2000 spec, the reconstruction parameter is introduced in the Annex E (Quantization). This reconstruction parameter can be arbitrarily chosen by the decoder, however, it is important to produce the best visual or objective quality for reconstruction. Generally, values for this parameter fall in the range [0, 1) and a common value is 0.5. How: Added new variable as the reconstruction parameter in jpc_dequantize() and set the value to 0.5. --- src/libjasper/jpc/jpc_dec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libjasper/jpc/jpc_dec.c b/src/libjasper/jpc/jpc_dec.c index 06f33e78..888cc2f9 100644 --- a/src/libjasper/jpc/jpc_dec.c +++ b/src/libjasper/jpc/jpc_dec.c @@ -1946,6 +1946,9 @@ static jpc_fix_t jpc_calcabsstepsize(int stepsize, int numbits) static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize) { + // a reconstruction parameter defined in E 1.1.2 of the ISO/IEC 15444-1 + jpc_fix_t recparam = JPC_FIX_HALF; + assert(absstepsize >= 0); if (absstepsize == jpc_inttofix(1)) { return; @@ -1955,9 +1958,9 @@ static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize) for (jas_matind_t j = 0; j < jas_matrix_numcols(x); ++j) { jas_seqent_t t = jas_matrix_get(x, i, j); if (t) { + // mid-point reconstruction + t = (t > 0) ? jpc_fix_add(t, recparam) : jpc_fix_sub(t, recparam); t = jpc_fix_mul(t, absstepsize); - } else { - t = 0; } jas_matrix_set(x, i, j, t); }