[FFmpeg-cvslog] jpeg2000: Factor out band initialization

Luca Barbato git at videolan.org
Wed Sep 16 13:59:12 CEST 2015


ffmpeg | branch: master | Luca Barbato <lu_zero at gentoo.org> | Fri Sep 11 05:26:35 2015 +0200| [7fb93eae43cc89bd7c1c275344e1cdbadab7155b] | committer: Luca Barbato

jpeg2000: Factor out band initialization

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7fb93eae43cc89bd7c1c275344e1cdbadab7155b
---

 libavcodec/jpeg2000.c |  406 ++++++++++++++++++++++++++-----------------------
 1 file changed, 213 insertions(+), 193 deletions(-)

diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c
index 2ccd078..a5ce802 100644
--- a/libavcodec/jpeg2000.c
+++ b/libavcodec/jpeg2000.c
@@ -195,13 +195,219 @@ void ff_jpeg2000_set_significance(Jpeg2000T1Context *t1, int x, int y,
 
 static const uint8_t lut_gain[2][4] = { { 0, 0, 0, 0 }, { 0, 1, 1, 2 } };
 
+static int init_band(AVCodecContext *avctx,
+                     Jpeg2000ResLevel *reslevel,
+                     Jpeg2000Component *comp,
+                     Jpeg2000CodingStyle *codsty,
+                     Jpeg2000QuantStyle *qntsty,
+                     int bandno, int gbandno, int reslevelno,
+                     int cbps, int dx, int dy)
+{
+    Jpeg2000Band *band = reslevel->band + bandno;
+    uint8_t log2_band_prec_width, log2_band_prec_height;
+    int declvl = codsty->nreslevels - reslevelno;    // N_L -r see  ISO/IEC 15444-1:2002 B.5
+    int cblkno, precno;
+    int nb_precincts;
+    int i, j;
+
+    /* TODO: Implementation of quantization step not finished,
+     * see ISO/IEC 15444-1:2002 E.1 and A.6.4. */
+    switch (qntsty->quantsty) {
+        uint8_t gain;
+        int numbps;
+    case JPEG2000_QSTY_NONE:
+        /* TODO: to verify. No quantization in this case */
+        band->f_stepsize = 1;
+        break;
+    case JPEG2000_QSTY_SI:
+        /*TODO: Compute formula to implement. */
+        numbps = cbps +
+                 lut_gain[codsty->transform == FF_DWT53][bandno + (reslevelno > 0)];
+        band->f_stepsize = SHL(2048 + qntsty->mant[gbandno],
+                               2 + numbps - qntsty->expn[gbandno]);
+        break;
+    case JPEG2000_QSTY_SE:
+        /* Exponent quantization step.
+         * Formula:
+         * delta_b = 2 ^ (R_b - expn_b) * (1 + (mant_b / 2 ^ 11))
+         * R_b = R_I + log2 (gain_b )
+         * see ISO/IEC 15444-1:2002 E.1.1 eqn. E-3 and E-4 */
+        /* TODO/WARN: value of log2 (gain_b ) not taken into account
+         * but it works (compared to OpenJPEG). Why?
+         * Further investigation needed. */
+        gain            = cbps;
+        band->f_stepsize  = pow(2.0, gain - qntsty->expn[gbandno]);
+        band->f_stepsize *= qntsty->mant[gbandno] / 2048.0 + 1.0;
+        break;
+    default:
+        band->f_stepsize = 0;
+        av_log(avctx, AV_LOG_ERROR, "Unknown quantization format\n");
+        break;
+    }
+    /* FIXME: In openjepg code stespize = stepsize * 0.5. Why?
+     * If not set output of entropic decoder is not correct. */
+    if (!av_codec_is_encoder(avctx->codec))
+        band->f_stepsize *= 0.5;
+
+    band->i_stepsize = band->f_stepsize * (1 << 16);
+
+    /* computation of tbx_0, tbx_1, tby_0, tby_1
+     * see ISO/IEC 15444-1:2002 B.5 eq. B-15 and tbl B.1
+     * codeblock width and height is computed for
+     * DCI JPEG 2000 codeblock_width = codeblock_width = 32 = 2 ^ 5 */
+    if (reslevelno == 0) {
+        /* for reslevelno = 0, only one band, x0_b = y0_b = 0 */
+        for (i = 0; i < 2; i++)
+            for (j = 0; j < 2; j++)
+                band->coord[i][j] =
+                    ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] - comp->coord_o[i][0],
+                                            declvl - 1);
+        log2_band_prec_width  = reslevel->log2_prec_width;
+        log2_band_prec_height = reslevel->log2_prec_height;
+        /* see ISO/IEC 15444-1:2002 eq. B-17 and eq. B-15 */
+        band->log2_cblk_width  = FFMIN(codsty->log2_cblk_width,
+                                       reslevel->log2_prec_width);
+        band->log2_cblk_height = FFMIN(codsty->log2_cblk_height,
+                                       reslevel->log2_prec_height);
+    } else {
+        /* 3 bands x0_b = 1 y0_b = 0; x0_b = 0 y0_b = 1; x0_b = y0_b = 1 */
+        /* x0_b and y0_b are computed with ((bandno + 1 >> i) & 1) */
+        for (i = 0; i < 2; i++)
+            for (j = 0; j < 2; j++)
+                /* Formula example for tbx_0 = ceildiv((tcx_0 - 2 ^ (declvl - 1) * x0_b) / declvl) */
+                band->coord[i][j] =
+                    ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] - comp->coord_o[i][0] -
+                                            (((bandno + 1 >> i) & 1) << declvl - 1),
+                                            declvl);
+        /* TODO: Manage case of 3 band offsets here or
+         * in coding/decoding function? */
+
+        /* see ISO/IEC 15444-1:2002 eq. B-17 and eq. B-15 */
+        band->log2_cblk_width  = FFMIN(codsty->log2_cblk_width,
+                                       reslevel->log2_prec_width - 1);
+        band->log2_cblk_height = FFMIN(codsty->log2_cblk_height,
+                                       reslevel->log2_prec_height - 1);
+
+        log2_band_prec_width  = reslevel->log2_prec_width  - 1;
+        log2_band_prec_height = reslevel->log2_prec_height - 1;
+    }
+
+    for (j = 0; j < 2; j++)
+        band->coord[0][j] = ff_jpeg2000_ceildiv(band->coord[0][j], dx);
+    for (j = 0; j < 2; j++)
+        band->coord[1][j] = ff_jpeg2000_ceildiv(band->coord[1][j], dy);
+
+    nb_precincts = reslevel->num_precincts_x * reslevel->num_precincts_y;
+    band->prec = av_mallocz_array(nb_precincts, sizeof(*band->prec));
+    if (!band->prec)
+        return AVERROR(ENOMEM);
+
+    for (precno = 0; precno < nb_precincts; precno++) {
+        Jpeg2000Prec *prec = band->prec + precno;
+        int nb_codeblocks;
+
+        /* TODO: Explain formula for JPEG200 DCINEMA. */
+        /* TODO: Verify with previous count of codeblocks per band */
+
+        /* Compute P_x0 */
+        prec->coord[0][0] = (precno % reslevel->num_precincts_x) *
+                            (1 << log2_band_prec_width);
+        prec->coord[0][0] = FFMAX(prec->coord[0][0], band->coord[0][0]);
+
+        /* Compute P_y0 */
+        prec->coord[1][0] = (precno / reslevel->num_precincts_x) *
+                            (1 << log2_band_prec_height);
+        prec->coord[1][0] = FFMAX(prec->coord[1][0], band->coord[1][0]);
+
+        /* Compute P_x1 */
+        prec->coord[0][1] = prec->coord[0][0] +
+                            (1 << log2_band_prec_width);
+        prec->coord[0][1] = FFMIN(prec->coord[0][1], band->coord[0][1]);
+
+        /* Compute P_y1 */
+        prec->coord[1][1] = prec->coord[1][0] +
+                            (1 << log2_band_prec_height);
+        prec->coord[1][1] = FFMIN(prec->coord[1][1], band->coord[1][1]);
+
+        prec->nb_codeblocks_width =
+            ff_jpeg2000_ceildivpow2(prec->coord[0][1] -
+                                    prec->coord[0][0],
+                                    band->log2_cblk_width);
+        prec->nb_codeblocks_height =
+            ff_jpeg2000_ceildivpow2(prec->coord[1][1] -
+                                    prec->coord[1][0],
+                                    band->log2_cblk_height);
+
+        /* Tag trees initialization */
+        prec->cblkincl =
+            ff_jpeg2000_tag_tree_init(prec->nb_codeblocks_width,
+                                      prec->nb_codeblocks_height);
+        if (!prec->cblkincl)
+            return AVERROR(ENOMEM);
+
+        prec->zerobits =
+            ff_jpeg2000_tag_tree_init(prec->nb_codeblocks_width,
+                                      prec->nb_codeblocks_height);
+        if (!prec->zerobits)
+            return AVERROR(ENOMEM);
+
+        nb_codeblocks = prec->nb_codeblocks_width * prec->nb_codeblocks_height;
+        prec->cblk = av_mallocz_array(nb_codeblocks, sizeof(*prec->cblk));
+        if (!prec->cblk)
+            return AVERROR(ENOMEM);
+        for (cblkno = 0; cblkno < nb_codeblocks; cblkno++) {
+            Jpeg2000Cblk *cblk = prec->cblk + cblkno;
+            uint16_t Cx0, Cy0;
+
+            /* Compute coordinates of codeblocks */
+            /* Compute Cx0*/
+            Cx0 = (prec->coord[0][0] >> band->log2_cblk_width) << band->log2_cblk_width;
+            Cx0 = Cx0 + ((cblkno % prec->nb_codeblocks_width)  << band->log2_cblk_width);
+            cblk->coord[0][0] = FFMAX(Cx0, prec->coord[0][0]);
+
+            /* Compute Cy0*/
+            Cy0 = (prec->coord[1][0] >> band->log2_cblk_height) << band->log2_cblk_height;
+            Cy0 = Cy0 + ((cblkno / prec->nb_codeblocks_width)   << band->log2_cblk_height);
+            cblk->coord[1][0] = FFMAX(Cy0, prec->coord[1][0]);
+
+            /* Compute Cx1 */
+            cblk->coord[0][1] = FFMIN(Cx0 + (1 << band->log2_cblk_width),
+                                      prec->coord[0][1]);
+
+            /* Compute Cy1 */
+            cblk->coord[1][1] = FFMIN(Cy0 + (1 << band->log2_cblk_height),
+                                      prec->coord[1][1]);
+            /* Update code-blocks coordinates according sub-band position */
+            if ((bandno + !!reslevelno) & 1) {
+                cblk->coord[0][0] += comp->reslevel[reslevelno-1].coord[0][1] -
+                                     comp->reslevel[reslevelno-1].coord[0][0];
+                cblk->coord[0][1] += comp->reslevel[reslevelno-1].coord[0][1] -
+                                     comp->reslevel[reslevelno-1].coord[0][0];
+            }
+            if ((bandno + !!reslevelno) & 2) {
+                cblk->coord[1][0] += comp->reslevel[reslevelno-1].coord[1][1] -
+                                     comp->reslevel[reslevelno-1].coord[1][0];
+                cblk->coord[1][1] += comp->reslevel[reslevelno-1].coord[1][1] -
+                                     comp->reslevel[reslevelno-1].coord[1][0];
+            }
+
+            cblk->zero      = 0;
+            cblk->lblock    = 3;
+            cblk->length    = 0;
+            cblk->lengthinc = 0;
+            cblk->npasses   = 0;
+        }
+    }
+
+    return 0;
+}
+
 int ff_jpeg2000_init_component(Jpeg2000Component *comp,
                                Jpeg2000CodingStyle *codsty,
                                Jpeg2000QuantStyle *qntsty,
                                int cbps, int dx, int dy,
                                AVCodecContext *avctx)
 {
-    uint8_t log2_band_prec_width, log2_band_prec_height;
     int reslevelno, bandno, gbandno = 0, ret, i, j;
     uint32_t csize;
 
@@ -282,198 +488,12 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp,
             return AVERROR(ENOMEM);
 
         for (bandno = 0; bandno < reslevel->nbands; bandno++, gbandno++) {
-            Jpeg2000Band *band = reslevel->band + bandno;
-            int cblkno, precno;
-            int nb_precincts;
-
-            /* TODO: Implementation of quantization step not finished,
-             * see ISO/IEC 15444-1:2002 E.1 and A.6.4. */
-            switch (qntsty->quantsty) {
-                uint8_t gain;
-                int numbps;
-            case JPEG2000_QSTY_NONE:
-                /* TODO: to verify. No quantization in this case */
-                band->f_stepsize = 1;
-                break;
-            case JPEG2000_QSTY_SI:
-                /*TODO: Compute formula to implement. */
-                numbps = cbps +
-                         lut_gain[codsty->transform == FF_DWT53][bandno + (reslevelno > 0)];
-                band->f_stepsize = SHL(2048 + qntsty->mant[gbandno],
-                                       2 + numbps - qntsty->expn[gbandno]);
-                break;
-            case JPEG2000_QSTY_SE:
-                /* Exponent quantization step.
-                 * Formula:
-                 * delta_b = 2 ^ (R_b - expn_b) * (1 + (mant_b / 2 ^ 11))
-                 * R_b = R_I + log2 (gain_b )
-                 * see ISO/IEC 15444-1:2002 E.1.1 eqn. E-3 and E-4 */
-                /* TODO/WARN: value of log2 (gain_b ) not taken into account
-                 * but it works (compared to OpenJPEG). Why?
-                 * Further investigation needed. */
-                gain            = cbps;
-                band->f_stepsize  = pow(2.0, gain - qntsty->expn[gbandno]);
-                band->f_stepsize *= qntsty->mant[gbandno] / 2048.0 + 1.0;
-                break;
-            default:
-                band->f_stepsize = 0;
-                av_log(avctx, AV_LOG_ERROR, "Unknown quantization format\n");
-                break;
-            }
-            /* FIXME: In openjepg code stespize = stepsize * 0.5. Why?
-             * If not set output of entropic decoder is not correct. */
-            if (!av_codec_is_encoder(avctx->codec))
-                band->f_stepsize *= 0.5;
-
-            band->i_stepsize = band->f_stepsize * (1 << 16);
-
-            /* computation of tbx_0, tbx_1, tby_0, tby_1
-             * see ISO/IEC 15444-1:2002 B.5 eq. B-15 and tbl B.1
-             * codeblock width and height is computed for
-             * DCI JPEG 2000 codeblock_width = codeblock_width = 32 = 2 ^ 5 */
-            if (reslevelno == 0) {
-                /* for reslevelno = 0, only one band, x0_b = y0_b = 0 */
-                for (i = 0; i < 2; i++)
-                    for (j = 0; j < 2; j++)
-                        band->coord[i][j] =
-                            ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] - comp->coord_o[i][0],
-                                                    declvl - 1);
-                log2_band_prec_width  = reslevel->log2_prec_width;
-                log2_band_prec_height = reslevel->log2_prec_height;
-                /* see ISO/IEC 15444-1:2002 eq. B-17 and eq. B-15 */
-                band->log2_cblk_width  = FFMIN(codsty->log2_cblk_width,
-                                               reslevel->log2_prec_width);
-                band->log2_cblk_height = FFMIN(codsty->log2_cblk_height,
-                                               reslevel->log2_prec_height);
-            } else {
-                /* 3 bands x0_b = 1 y0_b = 0; x0_b = 0 y0_b = 1; x0_b = y0_b = 1 */
-                /* x0_b and y0_b are computed with ((bandno + 1 >> i) & 1) */
-                for (i = 0; i < 2; i++)
-                    for (j = 0; j < 2; j++)
-                        /* Formula example for tbx_0 = ceildiv((tcx_0 - 2 ^ (declvl - 1) * x0_b) / declvl) */
-                        band->coord[i][j] =
-                            ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] - comp->coord_o[i][0] -
-                                                    (((bandno + 1 >> i) & 1) << declvl - 1),
-                                                    declvl);
-                /* TODO: Manage case of 3 band offsets here or
-                 * in coding/decoding function? */
-
-                /* see ISO/IEC 15444-1:2002 eq. B-17 and eq. B-15 */
-                band->log2_cblk_width  = FFMIN(codsty->log2_cblk_width,
-                                               reslevel->log2_prec_width - 1);
-                band->log2_cblk_height = FFMIN(codsty->log2_cblk_height,
-                                               reslevel->log2_prec_height - 1);
-
-                log2_band_prec_width  = reslevel->log2_prec_width  - 1;
-                log2_band_prec_height = reslevel->log2_prec_height - 1;
-            }
-
-            for (j = 0; j < 2; j++)
-                band->coord[0][j] = ff_jpeg2000_ceildiv(band->coord[0][j], dx);
-            for (j = 0; j < 2; j++)
-                band->coord[1][j] = ff_jpeg2000_ceildiv(band->coord[1][j], dy);
-
-            nb_precincts = reslevel->num_precincts_x * reslevel->num_precincts_y;
-            band->prec = av_mallocz_array(nb_precincts, sizeof(*band->prec));
-            if (!band->prec)
-                return AVERROR(ENOMEM);
-
-            for (precno = 0; precno < nb_precincts; precno++) {
-                Jpeg2000Prec *prec = band->prec + precno;
-                int nb_codeblocks;
-
-                /* TODO: Explain formula for JPEG200 DCINEMA. */
-                /* TODO: Verify with previous count of codeblocks per band */
-
-                /* Compute P_x0 */
-                prec->coord[0][0] = (precno % reslevel->num_precincts_x) *
-                                    (1 << log2_band_prec_width);
-                prec->coord[0][0] = FFMAX(prec->coord[0][0], band->coord[0][0]);
-
-                /* Compute P_y0 */
-                prec->coord[1][0] = (precno / reslevel->num_precincts_x) *
-                                    (1 << log2_band_prec_height);
-                prec->coord[1][0] = FFMAX(prec->coord[1][0], band->coord[1][0]);
-
-                /* Compute P_x1 */
-                prec->coord[0][1] = prec->coord[0][0] +
-                                    (1 << log2_band_prec_width);
-                prec->coord[0][1] = FFMIN(prec->coord[0][1], band->coord[0][1]);
-
-                /* Compute P_y1 */
-                prec->coord[1][1] = prec->coord[1][0] +
-                                    (1 << log2_band_prec_height);
-                prec->coord[1][1] = FFMIN(prec->coord[1][1], band->coord[1][1]);
-
-                prec->nb_codeblocks_width =
-                    ff_jpeg2000_ceildivpow2(prec->coord[0][1] -
-                                            prec->coord[0][0],
-                                            band->log2_cblk_width);
-                prec->nb_codeblocks_height =
-                    ff_jpeg2000_ceildivpow2(prec->coord[1][1] -
-                                            prec->coord[1][0],
-                                            band->log2_cblk_height);
-
-                /* Tag trees initialization */
-                prec->cblkincl =
-                    ff_jpeg2000_tag_tree_init(prec->nb_codeblocks_width,
-                                              prec->nb_codeblocks_height);
-                if (!prec->cblkincl)
-                    return AVERROR(ENOMEM);
-
-                prec->zerobits =
-                    ff_jpeg2000_tag_tree_init(prec->nb_codeblocks_width,
-                                              prec->nb_codeblocks_height);
-                if (!prec->zerobits)
-                    return AVERROR(ENOMEM);
-
-                nb_codeblocks = prec->nb_codeblocks_width * prec->nb_codeblocks_height;
-                prec->cblk = av_mallocz_array(nb_codeblocks, sizeof(*prec->cblk));
-                if (!prec->cblk)
-                    return AVERROR(ENOMEM);
-                for (cblkno = 0; cblkno < nb_codeblocks; cblkno++) {
-                    Jpeg2000Cblk *cblk = prec->cblk + cblkno;
-                    uint16_t Cx0, Cy0;
-
-                    /* Compute coordinates of codeblocks */
-                    /* Compute Cx0*/
-                    Cx0 = (prec->coord[0][0] >> band->log2_cblk_width) << band->log2_cblk_width;
-                    Cx0 = Cx0 + ((cblkno % prec->nb_codeblocks_width)  << band->log2_cblk_width);
-                    cblk->coord[0][0] = FFMAX(Cx0, prec->coord[0][0]);
-
-                    /* Compute Cy0*/
-                    Cy0 = (prec->coord[1][0] >> band->log2_cblk_height) << band->log2_cblk_height;
-                    Cy0 = Cy0 + ((cblkno / prec->nb_codeblocks_width)   << band->log2_cblk_height);
-                    cblk->coord[1][0] = FFMAX(Cy0, prec->coord[1][0]);
-
-                    /* Compute Cx1 */
-                    cblk->coord[0][1] = FFMIN(Cx0 + (1 << band->log2_cblk_width),
-                                              prec->coord[0][1]);
-
-                    /* Compute Cy1 */
-                    cblk->coord[1][1] = FFMIN(Cy0 + (1 << band->log2_cblk_height),
-                                              prec->coord[1][1]);
-                    /* Update code-blocks coordinates according sub-band position */
-                    if ((bandno + !!reslevelno) & 1) {
-                        cblk->coord[0][0] += comp->reslevel[reslevelno-1].coord[0][1] -
-                                             comp->reslevel[reslevelno-1].coord[0][0];
-                        cblk->coord[0][1] += comp->reslevel[reslevelno-1].coord[0][1] -
-                                             comp->reslevel[reslevelno-1].coord[0][0];
-                    }
-                    if ((bandno + !!reslevelno) & 2) {
-                        cblk->coord[1][0] += comp->reslevel[reslevelno-1].coord[1][1] -
-                                             comp->reslevel[reslevelno-1].coord[1][0];
-                        cblk->coord[1][1] += comp->reslevel[reslevelno-1].coord[1][1] -
-                                             comp->reslevel[reslevelno-1].coord[1][0];
-                    }
-
-                    cblk->zero      = 0;
-                    cblk->lblock    = 3;
-                    cblk->length    = 0;
-                    cblk->lengthinc = 0;
-                    cblk->npasses   = 0;
-                }
-            }
+            ret = init_band(avctx, reslevel,
+                            comp, codsty, qntsty,
+                            bandno, gbandno, reslevelno,
+                            cbps, dx, dy);
+            if (ret < 0)
+                return ret;
         }
     }
     return 0;



More information about the ffmpeg-cvslog mailing list