From 3d9ee7aebaa3a2f81bdaeeda5bfa36b331c53e21 Mon Sep 17 00:00:00 2001 From: Aaron Boxer Date: Wed, 16 Mar 2016 19:50:45 -0400 Subject: [PATCH] fixed valgrind error where MQ coder was accessing uninitialized memory in RESTART mode. Unfortunately, there is still a problem with RESTART: lossless encoding with RESTART produces a lossy image. --- src/lib/openjp2/mqc.cpp | 2 +- src/lib/openjp2/t1.cpp | 38 ++++++++++++++++---------------------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/lib/openjp2/mqc.cpp b/src/lib/openjp2/mqc.cpp index 5db95a382..e27f48b59 100644 --- a/src/lib/openjp2/mqc.cpp +++ b/src/lib/openjp2/mqc.cpp @@ -222,7 +222,7 @@ static opj_mqc_state_t mqc_states[47 * 2] = { static void opj_mqc_byteout(opj_mqc_t *mqc) { - if (mqc->bp == mqc->start - 1) { + if (mqc->bp < mqc->start) { mqc->bp++; *mqc->bp = (uint8_t)(mqc->c >> 19); mqc->c &= 0x7ffff; diff --git a/src/lib/openjp2/t1.cpp b/src/lib/openjp2/t1.cpp index b182af90f..7927cf83e 100644 --- a/src/lib/openjp2/t1.cpp +++ b/src/lib/openjp2/t1.cpp @@ -1572,6 +1572,9 @@ double opj_t1_encode_cblk(opj_t1_t *t1, opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); opj_mqc_init_enc(mqc, cblk->data); + bool TERMALL = (cblksty & J2K_CCP_CBLKSTY_TERMALL); + bool LAZY = (cblksty & J2K_CCP_CBLKSTY_LAZY); + for (passno = 0; bpno >= 0; ++passno) { opj_tcd_pass_t *pass = &cblk->passes[passno]; uint32_t correction = 3; @@ -1592,36 +1595,25 @@ double opj_t1_encode_cblk(opj_t1_t *t1, break; } + /* fixed_quality */ tempwmsedec = opj_t1_getwmsedec(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps,mct_norms, mct_numcomps) ; cumwmsedec += tempwmsedec; - /* Code switch "RESTART" (i.e. TERMALL) */ - if ((cblksty & J2K_CCP_CBLKSTY_TERMALL) && !((passtype == 2) && (bpno - 1 < 0))) { + if ( TERMALL || + (LAZY && ((bpno < ((int32_t)(cblk->numbps) - 4) && (passtype > 0)) + || ((bpno == ((int32_t)cblk->numbps - 4)) && (passtype == 2)))) + ) { if (type == T1_TYPE_RAW) { opj_mqc_flush(mqc); correction = 1; - /* correction = mqc_bypass_flush_enc(); */ - } else { /* correction = mqc_restart_enc(); */ + } else { opj_mqc_flush(mqc); correction = 1; } pass->term = 1; } else { - if (((bpno < ((int32_t) (cblk->numbps) - 4) && (passtype > 0)) - || ((bpno == ((int32_t)cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) { - if (type == T1_TYPE_RAW) { - opj_mqc_flush(mqc); - correction = 1; - /* correction = mqc_bypass_flush_enc(); */ - } else { /* correction = mqc_restart_enc(); */ - opj_mqc_flush(mqc); - correction = 1; - } - pass->term = 1; - } else { - pass->term = 0; - } + pass->term = 0; } if (++passtype == 3) { @@ -1629,8 +1621,8 @@ double opj_t1_encode_cblk(opj_t1_t *t1, bpno--; } - if (pass->term && bpno > 0) { - type = ((bpno < ((int32_t) (cblk->numbps) - 4)) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + if (pass->term) { + type = ((bpno < ((int32_t) (cblk->numbps) - 4)) && (passtype < 2) && LAZY) ? T1_TYPE_RAW : T1_TYPE_MQ; if (type == T1_TYPE_RAW) opj_mqc_bypass_init_enc(mqc); else @@ -1638,7 +1630,9 @@ double opj_t1_encode_cblk(opj_t1_t *t1, } pass->distortiondec = cumwmsedec; - pass->rate = opj_mqc_numbytes(mqc) + correction; /* FIXME */ + pass->rate = opj_mqc_numbytes(mqc); + if (pass->rate > 0) + pass->rate += correction; /* Code-switch "RESET" */ if (cblksty & J2K_CCP_CBLKSTY_RESET) @@ -1648,7 +1642,7 @@ double opj_t1_encode_cblk(opj_t1_t *t1, /* Code switch "ERTERM" (i.e. PTERM) */ if (cblksty & J2K_CCP_CBLKSTY_PTERM) opj_mqc_erterm_enc(mqc); - else /* Default coding */ if (!(cblksty & J2K_CCP_CBLKSTY_LAZY)) + else if (!LAZY && !TERMALL) opj_mqc_flush(mqc); cblk->totalpasses = passno;