innoHeim/Rsupport Screen Capture Codec decoder
[ffmpeg.git] / libavcodec / jpeg2000.c
index 77cadd8..f5a844f 100644 (file)
@@ -244,6 +244,111 @@ static void init_band_stepsize(AVCodecContext *avctx,
     band->i_stepsize = band->f_stepsize * (1 << 16);
 }
 
+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;
+
+    /* 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;
+}
+
 static int init_band(AVCodecContext *avctx,
                      Jpeg2000ResLevel *reslevel,
                      Jpeg2000Component *comp,
@@ -255,9 +360,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);
 
@@ -314,100 +419,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;
-
-        /* 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_prec(band, reslevel, comp,
+                        precno, bandno, reslevelno,
+                        log2_band_prec_width, log2_band_prec_height);
+        if (ret < 0)
+            return ret;
     }
 
     return 0;