Merge commit '7fb93eae43cc89bd7c1c275344e1cdbadab7155b'
authorHendrik Leppkes <h.leppkes@gmail.com>
Wed, 16 Sep 2015 11:58:30 +0000 (13:58 +0200)
committerHendrik Leppkes <h.leppkes@gmail.com>
Wed, 16 Sep 2015 11:58:30 +0000 (13:58 +0200)
* commit '7fb93eae43cc89bd7c1c275344e1cdbadab7155b':
  jpeg2000: Factor out band initialization

Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
1  2 
libavcodec/jpeg2000.c

@@@ -171,26 -175,233 +171,252 @@@ void ff_jpeg2000_set_significance(Jpeg2
  {
      x++;
      y++;
 -    t1->flags[y][x] |= JPEG2000_T1_SIG;
 +    t1->flags[(y) * t1->stride + x] |= JPEG2000_T1_SIG;
      if (negative) {
 -        t1->flags[y][x + 1] |= JPEG2000_T1_SIG_W | JPEG2000_T1_SGN_W;
 -        t1->flags[y][x - 1] |= JPEG2000_T1_SIG_E | JPEG2000_T1_SGN_E;
 -        t1->flags[y + 1][x] |= JPEG2000_T1_SIG_N | JPEG2000_T1_SGN_N;
 -        t1->flags[y - 1][x] |= JPEG2000_T1_SIG_S | JPEG2000_T1_SGN_S;
 +        t1->flags[(y) * t1->stride + x + 1] |= JPEG2000_T1_SIG_W | JPEG2000_T1_SGN_W;
 +        t1->flags[(y) * t1->stride + x - 1] |= JPEG2000_T1_SIG_E | JPEG2000_T1_SGN_E;
 +        t1->flags[(y + 1) * t1->stride + x] |= JPEG2000_T1_SIG_N | JPEG2000_T1_SGN_N;
 +        t1->flags[(y - 1) * t1->stride + x] |= JPEG2000_T1_SIG_S | JPEG2000_T1_SGN_S;
      } else {
 -        t1->flags[y][x + 1] |= JPEG2000_T1_SIG_W;
 -        t1->flags[y][x - 1] |= JPEG2000_T1_SIG_E;
 -        t1->flags[y + 1][x] |= JPEG2000_T1_SIG_N;
 -        t1->flags[y - 1][x] |= JPEG2000_T1_SIG_S;
 +        t1->flags[(y) * t1->stride + x + 1] |= JPEG2000_T1_SIG_W;
 +        t1->flags[(y) * t1->stride + x - 1] |= JPEG2000_T1_SIG_E;
 +        t1->flags[(y + 1) * t1->stride + x] |= JPEG2000_T1_SIG_N;
 +        t1->flags[(y - 1) * t1->stride + x] |= JPEG2000_T1_SIG_S;
      }
 -    t1->flags[y + 1][x + 1] |= JPEG2000_T1_SIG_NW;
 -    t1->flags[y + 1][x - 1] |= JPEG2000_T1_SIG_NE;
 -    t1->flags[y - 1][x + 1] |= JPEG2000_T1_SIG_SW;
 -    t1->flags[y - 1][x - 1] |= JPEG2000_T1_SIG_SE;
 +    t1->flags[(y + 1) * t1->stride + x + 1] |= JPEG2000_T1_SIG_NW;
 +    t1->flags[(y + 1) * t1->stride + x - 1] |= JPEG2000_T1_SIG_NE;
 +    t1->flags[(y - 1) * t1->stride + x + 1] |= JPEG2000_T1_SIG_SW;
 +    t1->flags[(y - 1) * t1->stride + x - 1] |= JPEG2000_T1_SIG_SE;
  }
  
 -static const uint8_t lut_gain[2][4] = { { 0, 0, 0, 0 }, { 0, 1, 1, 2 } };
 +// static const uint8_t lut_gain[2][4] = { { 0, 0, 0, 0 }, { 0, 1, 1, 2 } }; (unused)
  
 -        int numbps;
+ 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;
 -        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_NONE:
+         /* TODO: to verify. No quantization in this case */
+         band->f_stepsize = 1;
+         break;
+     case JPEG2000_QSTY_SI:
+         /*TODO: Compute formula to implement. */
 -        /* TODO/WARN: value of log2 (gain_b ) not taken into account
 -         * but it works (compared to OpenJPEG). Why?
 -         * Further investigation needed. */
++//         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 */
 -    band->i_stepsize = band->f_stepsize * (1 << 16);
 -
+         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;
 -                    ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] - comp->coord_o[i][0],
+     /* 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] -
 -                                            (((bandno + 1 >> i) & 1) << declvl - 1),
++                    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] =
 -    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);
 -
++                    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;
+     }
 -        prec->coord[0][0] = (precno % reslevel->num_precincts_x) *
++    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] = FFMAX(prec->coord[0][0], band->coord[0][0]);
++        prec->coord[0][0] = ((band->coord[0][0] >> log2_band_prec_width) + precno % reslevel->num_precincts_x) *
+                             (1 << log2_band_prec_width);
 -        prec->coord[1][0] = (precno / reslevel->num_precincts_x) *
+         /* Compute P_y0 */
 -        prec->coord[1][0] = FFMAX(prec->coord[1][0], band->coord[1][0]);
++        prec->coord[1][0] = ((band->coord[1][0] >> log2_band_prec_height) + precno / reslevel->num_precincts_x) *
+                             (1 << log2_band_prec_height);
 -            ff_jpeg2000_ceildivpow2(prec->coord[0][1] -
 -                                    prec->coord[0][0],
 -                                    band->log2_cblk_width);
+         /* 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[1][1] -
 -                                    prec->coord[1][0],
 -                                    band->log2_cblk_height);
++            ff_jpeg2000_ceildivpow2(prec->coord[0][1],
++                                    band->log2_cblk_width)
++            - (prec->coord[0][0] >> band->log2_cblk_width);
+         prec->nb_codeblocks_height =
 -            Cx0 = (prec->coord[0][0] >> band->log2_cblk_width) << band->log2_cblk_width;
++            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*/
 -            Cy0 = (prec->coord[1][0] >> band->log2_cblk_height) << band->log2_cblk_height;
++            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*/
 -            cblk->lengthinc = 0;
++            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;
+ }
  int ff_jpeg2000_init_component(Jpeg2000Component *comp,
                                 Jpeg2000CodingStyle *codsty,
                                 Jpeg2000QuantStyle *qntsty,