]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/jpeg2000.c
libkvazaar: Replace asserts with proper errors
[ffmpeg] / libavcodec / jpeg2000.c
index 09654e82f6e0ad6333fb1454ddd2c37f02fa69f9..d9869fd277f1d8f664d8d8a325c66096182597dc 100644 (file)
@@ -191,13 +191,264 @@ 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 } }; (unused)
 
+static void init_band_stepsize(AVCodecContext *avctx,
+                               Jpeg2000Band *band,
+                               Jpeg2000CodingStyle *codsty,
+                               Jpeg2000QuantStyle *qntsty,
+                               int bandno, int gbandno, int reslevelno,
+                               int cbps)
+{
+    /* 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;
+    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 */
+        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;
+    }
+    if (codsty->transform != FF_DWT53) {
+        int lband = 0;
+        switch (bandno + (reslevelno > 0)) {
+            case 1:
+            case 2:
+                band->f_stepsize *= F_LFTG_X * 2;
+                lband = 1;
+                break;
+            case 3:
+                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);
+        }
+    }
+
+    band->i_stepsize = band->f_stepsize * (1 << 15);
+
+    /* 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;
+}
+
+static int init_prec(Jpeg2000Band *band,
+                     Jpeg2000ResLevel *reslevel,
+                     Jpeg2000Component *comp,
+                     int precno, int bandno, int reslevelno,
+                     int log2_band_prec_width,
+                     int log2_band_prec_height)
+{
+    Jpeg2000Prec *prec = band->prec + precno;
+    int nb_codeblocks, cblkno;
+
+    prec->decoded_layers = 0;
+
+    /* TODO: Explain formula for JPEG200 DCINEMA. */
+    /* TODO: Verify with previous count of codeblocks per band */
+
+    /* Compute P_x0 */
+    prec->coord[0][0] = ((band->coord[0][0] >> log2_band_prec_width) + precno % reslevel->num_precincts_x) *
+                        (1 << log2_band_prec_width);
+
+    /* Compute P_y0 */
+    prec->coord[1][0] = ((band->coord[1][0] >> log2_band_prec_height) + precno / reslevel->num_precincts_x) *
+                        (1 << log2_band_prec_height);
+
+    /* Compute P_x1 */
+    prec->coord[0][1] = prec->coord[0][0] +
+                        (1 << log2_band_prec_width);
+    prec->coord[0][0] = FFMAX(prec->coord[0][0], band->coord[0][0]);
+    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][0] = FFMAX(prec->coord[1][0], band->coord[1][0]);
+    prec->coord[1][1] = FFMIN(prec->coord[1][1], band->coord[1][1]);
+
+    prec->nb_codeblocks_width =
+        ff_jpeg2000_ceildivpow2(prec->coord[0][1],
+                                band->log2_cblk_width)
+        - (prec->coord[0][0] >> band->log2_cblk_width);
+    prec->nb_codeblocks_height =
+        ff_jpeg2000_ceildivpow2(prec->coord[1][1],
+                                band->log2_cblk_height)
+        - (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);
+
+    if (prec->nb_codeblocks_width * (uint64_t)prec->nb_codeblocks_height > INT_MAX) {
+        prec->cblk = NULL;
+        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;
+        memset(cblk->lengthinc, 0, sizeof(cblk->lengthinc));
+        cblk->npasses   = 0;
+    }
+
+    return 0;
+}
+
+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 precno;
+    int nb_precincts;
+    int i, j, ret;
+
+    init_band_stepsize(avctx, band, codsty, qntsty, bandno, gbandno, reslevelno, cbps);
+
+    /* 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],
+                                            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] -
+                                            (((bandno + 1 >> i) & 1LL) << 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;
+    }
+
+    if (reslevel->num_precincts_x * (uint64_t)reslevel->num_precincts_y > INT_MAX) {
+        band->prec = NULL;
+        return AVERROR(ENOMEM);
+    }
+    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++) {
+        ret = init_prec(band, reslevel, comp,
+                        precno, bandno, reslevelno,
+                        log2_band_prec_width, log2_band_prec_height);
+        if (ret < 0)
+            return ret;
+    }
+
+    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;
 
@@ -280,217 +531,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;
-            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 */
-                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;
-            }
-            if (codsty->transform != FF_DWT53) {
-                int lband = 0;
-                switch (bandno + (reslevelno > 0)) {
-                    case 1:
-                    case 2:
-                        band->f_stepsize *= F_LFTG_X * 2;
-                        lband = 1;
-                        break;
-                    case 3:
-                        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);
-                }
-            }
-
-            band->i_stepsize = band->f_stepsize * (1 << 15);
-
-            /* 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;
-
-            /* 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],
-                                                    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] -
-                                                    (((bandno + 1 >> i) & 1LL) << 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;
-            }
-
-            if (reslevel->num_precincts_x * (uint64_t)reslevel->num_precincts_y > INT_MAX) {
-                band->prec = NULL;
-                return AVERROR(ENOMEM);
-            }
-            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;
-
-                prec->decoded_layers = 0;
-
-                /* TODO: Explain formula for JPEG200 DCINEMA. */
-                /* TODO: Verify with previous count of codeblocks per band */
-
-                /* Compute P_x0 */
-                prec->coord[0][0] = ((band->coord[0][0] >> log2_band_prec_width) + precno % reslevel->num_precincts_x) *
-                                    (1 << log2_band_prec_width);
-
-                /* Compute P_y0 */
-                prec->coord[1][0] = ((band->coord[1][0] >> log2_band_prec_height) + precno / reslevel->num_precincts_x) *
-                                    (1 << log2_band_prec_height);
-
-                /* Compute P_x1 */
-                prec->coord[0][1] = prec->coord[0][0] +
-                                    (1 << log2_band_prec_width);
-                prec->coord[0][0] = FFMAX(prec->coord[0][0], band->coord[0][0]);
-                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][0] = FFMAX(prec->coord[1][0], band->coord[1][0]);
-                prec->coord[1][1] = FFMIN(prec->coord[1][1], band->coord[1][1]);
-
-                prec->nb_codeblocks_width =
-                    ff_jpeg2000_ceildivpow2(prec->coord[0][1],
-                                            band->log2_cblk_width)
-                    - (prec->coord[0][0] >> band->log2_cblk_width);
-                prec->nb_codeblocks_height =
-                    ff_jpeg2000_ceildivpow2(prec->coord[1][1],
-                                            band->log2_cblk_height)
-                    - (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);
-
-                if (prec->nb_codeblocks_width * (uint64_t)prec->nb_codeblocks_height > INT_MAX) {
-                    prec->cblk = NULL;
-                    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;
-                    memset(cblk->lengthinc, 0, sizeof(cblk->lengthinc));
-                    cblk->npasses   = 0;
-                }
-            }
+            ret = init_band(avctx, reslevel,
+                            comp, codsty, qntsty,
+                            bandno, gbandno, reslevelno,
+                            cbps, dx, dy);
+            if (ret < 0)
+                return ret;
         }
     }
     return 0;