]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/jpeg2000.c
Merge commit 'cf7d2f2d2134c0854edf2db91e7436ac2bc9874f'
[ffmpeg] / libavcodec / jpeg2000.c
index d7ab4e1d6b1669ff91ceae441dd711d25d99a0b2..d9869fd277f1d8f664d8d8a325c66096182597dc 100644 (file)
@@ -253,6 +253,118 @@ static void init_band_stepsize(AVCodecContext *avctx,
         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,
@@ -264,9 +376,9 @@ static int init_band(AVCodecContext *avctx,
     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 precno;
     int nb_precincts;
-    int i, j;
+    int i, j, ret;
 
     init_band_stepsize(avctx, band, codsty, qntsty, bandno, gbandno, reslevelno, cbps);
 
@@ -321,107 +433,11 @@ static int init_band(AVCodecContext *avctx,
         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_prec(band, reslevel, comp,
+                        precno, bandno, reslevelno,
+                        log2_band_prec_width, log2_band_prec_height);
+        if (ret < 0)
+            return ret;
     }
 
     return 0;