[FFmpeg-cvslog] j2k/jpeg2000: log2_prec size cleanup

Michael Niedermayer git at videolan.org
Sun May 26 22:34:38 CEST 2013


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Sun May 26 21:50:17 2013 +0200| [bd89b2b22ac71aae4ec5c6a27adb88d877b7b76e] | committer: Michael Niedermayer

j2k/jpeg2000: log2_prec size cleanup

This also changes the cblk size storage method to what jpeg2000 uses

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

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

 libavcodec/j2k.c         |   63 +++++++++++++++++++++++++++++++++-------------
 libavcodec/j2k.h         |    4 +--
 libavcodec/j2kdec.c      |   30 ++++++++++++++--------
 libavcodec/j2kenc.c      |   12 ++++-----
 libavcodec/jpeg2000.h    |    2 --
 libavcodec/jpeg2000dec.c |   10 +++++---
 6 files changed, 78 insertions(+), 43 deletions(-)

diff --git a/libavcodec/j2k.c b/libavcodec/j2k.c
index d575b84..c779480 100644
--- a/libavcodec/j2k.c
+++ b/libavcodec/j2k.c
@@ -174,6 +174,7 @@ void ff_j2k_set_significant(Jpeg2000T1Context *t1, int x, int y,
 
 int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, Jpeg2000QuantStyle *qntsty, int cbps, int dx, int dy)
 {
+    uint8_t log2_band_prec_width, log2_band_prec_height;
     int reslevelno, bandno, gbandno = 0, ret, i, j, csize = 1;
 
     if (ret=ff_j2k_dwt_init(&comp->dwt, comp->coord, codsty->nreslevels-1, codsty->transform))
@@ -195,6 +196,9 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty,
             for (j = 0; j < 2; j++)
                 reslevel->coord[i][j] =
                     ff_jpeg2000_ceildivpow2(comp->coord[i][j], declvl - 1);
+        // update precincts size: 2^n value
+        reslevel->log2_prec_width  = codsty->log2_prec_widths[reslevelno];
+        reslevel->log2_prec_height = codsty->log2_prec_heights[reslevelno];
 
         if (reslevelno == 0)
             reslevel->nbands = 1;
@@ -204,14 +208,14 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty,
         if (reslevel->coord[0][1] == reslevel->coord[0][0])
             reslevel->num_precincts_x = 0;
         else
-            reslevel->num_precincts_x = ff_jpeg2000_ceildivpow2(reslevel->coord[0][1], codsty->log2_prec_width)
-                                        - (reslevel->coord[0][0] >> codsty->log2_prec_width);
+            reslevel->num_precincts_x = ff_jpeg2000_ceildivpow2(reslevel->coord[0][1], reslevel->log2_prec_width)
+                                        - (reslevel->coord[0][0] >> reslevel->log2_prec_width);
 
         if (reslevel->coord[1][1] == reslevel->coord[1][0])
             reslevel->num_precincts_y = 0;
         else
-            reslevel->num_precincts_y = ff_jpeg2000_ceildivpow2(reslevel->coord[1][1], codsty->log2_prec_height)
-                                        - (reslevel->coord[1][0] >> codsty->log2_prec_height);
+            reslevel->num_precincts_y = ff_jpeg2000_ceildivpow2(reslevel->coord[1][1], reslevel->log2_prec_height)
+                                        - (reslevel->coord[1][0] >> reslevel->log2_prec_height);
 
         reslevel->band = av_malloc_array(reslevel->nbands, sizeof(*reslevel->band));
         if (!reslevel->band)
@@ -233,22 +237,45 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty,
             } else
                 band->stepsize = 1 << 13;
 
-            if (reslevelno == 0) {  // the same everywhere
-                band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width-1);
-                band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height-1);
+            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[i][j], declvl-1);
+                        band->coord[i][j] =
+                            ff_jpeg2000_ceildivpow2(comp->coord[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{
-                band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width);
-                band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height);
-
+                /* 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++)
-                        band->coord[i][j] = ff_jpeg2000_ceildivpow2(comp->coord[i][j] - (((bandno+1>>i)&1) << declvl-1), declvl);
+                        /* Formula example for tbx_0 = ceildiv((tcx_0 - 2 ^ (declvl - 1) * x0_b) / declvl) */
+                        band->coord[i][j] =
+                            ff_jpeg2000_ceildivpow2(comp->coord[i][j] -
+                                                    (((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;
             }
-            band->cblknx = ff_jpeg2000_ceildiv(band->coord[0][1], band->codeblock_width)  - band->coord[0][0] / band->codeblock_width;
-            band->cblkny = ff_jpeg2000_ceildiv(band->coord[1][1], band->codeblock_height) - band->coord[1][0] / band->codeblock_height;
+            band->cblknx = ff_jpeg2000_ceildivpow2(band->coord[0][1], band->log2_cblk_width)  - (band->coord[0][0] >> band->log2_cblk_width);
+            band->cblkny = ff_jpeg2000_ceildivpow2(band->coord[1][1], band->log2_cblk_height) - (band->coord[1][0] >> band->log2_cblk_height);
 
             for (j = 0; j < 2; j++)
                 band->coord[0][j] = ff_jpeg2000_ceildiv(band->coord[0][j], dx);
@@ -279,11 +306,11 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty,
             }
 
             y0 = band->coord[1][0];
-            y1 = ((band->coord[1][0] + (1<<codsty->log2_prec_height)) & ~((1<<codsty->log2_prec_height)-1)) - y0;
+            y1 = ((band->coord[1][0] + (1<<reslevel->log2_prec_height)) & ~((1<<reslevel->log2_prec_height)-1)) - y0;
             yi0 = 0;
             yi1 = ff_jpeg2000_ceildivpow2(y1 - y0, codsty->log2_cblk_height) << codsty->log2_cblk_height;
             yi1 = FFMIN(yi1, band->cblkny);
-            cblkperprech = 1<<(codsty->log2_prec_height - codsty->log2_cblk_height);
+            cblkperprech = 1<<(reslevel->log2_prec_height - codsty->log2_cblk_height);
             for (precy = 0, precno = 0; precy < reslevel->num_precincts_y; precy++) {
                 for (precx = 0; precx < reslevel->num_precincts_x; precx++, precno++) {
                     band->prec[precno].yi0 = yi0;
@@ -294,12 +321,12 @@ int ff_j2k_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty,
                 yi1 = FFMIN(yi1, band->cblkny);
             }
             x0 = band->coord[0][0];
-            x1 = ((band->coord[0][0] + (1<<codsty->log2_prec_width)) & ~((1<<codsty->log2_prec_width)-1)) - x0;
+            x1 = ((band->coord[0][0] + (1<<reslevel->log2_prec_width)) & ~((1<<reslevel->log2_prec_width)-1)) - x0;
             xi0 = 0;
             xi1 = ff_jpeg2000_ceildivpow2(x1 - x0, codsty->log2_cblk_width) << codsty->log2_cblk_width;
             xi1 = FFMIN(xi1, band->cblknx);
 
-            cblkperprecw = 1<<(codsty->log2_prec_width - codsty->log2_cblk_width);
+            cblkperprecw = 1<<(reslevel->log2_prec_width - codsty->log2_cblk_width);
             for (precx = 0, precno = 0; precx < reslevel->num_precincts_x; precx++) {
                 for (precy = 0; precy < reslevel->num_precincts_y; precy++, precno = 0) {
                     Jpeg2000Prec *prec = band->prec + precno;
diff --git a/libavcodec/j2k.h b/libavcodec/j2k.h
index 1c077f9..c395945 100644
--- a/libavcodec/j2k.h
+++ b/libavcodec/j2k.h
@@ -130,8 +130,6 @@ typedef struct Jpeg2000CodingStyle {
             log2_cblk_height; // exponent of codeblock size
     uint8_t transform;        // DWT type
     uint8_t csty;             // coding style
-    uint8_t log2_prec_width,
-            log2_prec_height; // precinct size
     uint8_t nlayers;          // number of layers
     uint8_t mct;              // multiple component transformation
     uint8_t cblk_style;       // codeblock coding style
@@ -172,7 +170,7 @@ typedef struct Jpeg2000Prec {
 
 typedef struct Jpeg2000Band {
     uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
-    uint16_t codeblock_width, codeblock_height;
+    uint16_t log2_cblk_width, log2_cblk_height;
     uint16_t cblknx, cblkny;
     uint32_t stepsize; // quantization stepsize (* 2^13)
     Jpeg2000Prec *prec;
diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c
index f3b9ad1..a368a64 100644
--- a/libavcodec/j2kdec.c
+++ b/libavcodec/j2kdec.c
@@ -230,9 +230,15 @@ static int get_siz(Jpeg2000DecoderContext *s)
 /** get common part for COD and COC segments */
 static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
 {
+    uint8_t byte;
+
     if (bytestream2_get_bytes_left(&s->g) < 5)
         return AVERROR(EINVAL);
-          c->nreslevels = bytestream2_get_byteu(&s->g) + 1; // num of resolution levels - 1
+    c->nreslevels = bytestream2_get_byteu(&s->g) + 1; // num of resolution levels - 1
+    if (c->nreslevels >= JPEG2000_MAX_RESLEVELS) {
+        av_log(s->avctx, AV_LOG_ERROR, "nreslevels %d is invalid\n", c->nreslevels);
+        return AVERROR_INVALIDDATA;
+    }
 
     c->log2_cblk_width  = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk width
     c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height
@@ -250,9 +256,14 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
     c->transform = bytestream2_get_byteu(&s->g); // transformation
     if (c->csty & JPEG2000_CSTY_PREC) {
         int i;
-
-        for (i = 0; i < c->nreslevels; i++)
-            bytestream2_get_byte(&s->g);
+        for (i = 0; i < c->nreslevels; i++) {
+            byte = bytestream2_get_byte(&s->g);
+            c->log2_prec_widths[i]  =  byte       & 0x0F;    // precinct PPx
+            c->log2_prec_heights[i] = (byte >> 4) & 0x0F;    // precinct PPy
+        }
+    } else {
+        memset(c->log2_prec_widths , 15, sizeof(c->log2_prec_widths ));
+        memset(c->log2_prec_heights, 15, sizeof(c->log2_prec_heights));
     }
     return 0;
 }
@@ -266,9 +277,6 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, uint8_t *p
     if (bytestream2_get_bytes_left(&s->g) < 5)
         return AVERROR(EINVAL);
 
-    tmp.log2_prec_width  =
-    tmp.log2_prec_height = 15;
-
     tmp.csty = bytestream2_get_byteu(&s->g);
 
     // get progression order
@@ -756,7 +764,7 @@ static int decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
 
                 yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0];
                 y0 = yy0;
-                yy1 = FFMIN(ff_jpeg2000_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height,
+                yy1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[1][0] + 1,  band->log2_cblk_height) << band->log2_cblk_height,
                             band->coord[1][1]) - band->coord[1][0] + yy0;
 
                 if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1])
@@ -768,7 +776,7 @@ static int decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
                     else
                         xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0];
                     x0 = xx0;
-                    xx1 = FFMIN(ff_jpeg2000_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width,
+                    xx1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[0][0] + 1, band->log2_cblk_width) << band->log2_cblk_width,
                                 band->coord[0][1]) - band->coord[0][0] + xx0;
 
                     for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++) {
@@ -792,10 +800,10 @@ static int decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
                             }
                         }
                         xx0 = xx1;
-                        xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0);
+                        xx1 = FFMIN(xx1 + (1 << band->log2_cblk_width), band->coord[0][1] - band->coord[0][0] + x0);
                     }
                     yy0 = yy1;
-                    yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0);
+                    yy1 = FFMIN(yy1 + (1 << band->log2_cblk_height), band->coord[1][1] - band->coord[1][0] + y0);
                 }
             }
         }
diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c
index c8ff66e..4c047c3 100644
--- a/libavcodec/j2kenc.c
+++ b/libavcodec/j2kenc.c
@@ -821,7 +821,7 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno
                 int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos;
                 yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0];
                 y0 = yy0;
-                yy1 = FFMIN(ff_jpeg2000_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height,
+                yy1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[1][0] + 1, band->log2_cblk_height) << band->log2_cblk_height,
                             band->coord[1][1]) - band->coord[1][0] + yy0;
 
                 if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1])
@@ -835,7 +835,7 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno
                     else
                         xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0];
                     x0 = xx0;
-                    xx1 = FFMIN(ff_jpeg2000_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width,
+                    xx1 = FFMIN(ff_jpeg2000_ceildivpow2(band->coord[0][0] + 1, band->log2_cblk_width) << band->log2_cblk_width,
                                 band->coord[0][1]) - band->coord[0][0] + xx0;
 
                     for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){
@@ -860,10 +860,10 @@ static int encode_tile(Jpeg2000EncoderContext *s, Jpeg2000Tile *tile, int tileno
                         encode_cblk(s, &t1, band->cblk + cblkno, tile, xx1 - xx0, yy1 - yy0,
                                     bandpos, codsty->nreslevels - reslevelno - 1);
                         xx0 = xx1;
-                        xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0);
+                        xx1 = FFMIN(xx1 + (1 << band->log2_cblk_width), band->coord[0][1] - band->coord[0][0] + x0);
                     }
                     yy0 = yy1;
-                    yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0);
+                    yy1 = FFMIN(yy1 + (1 << band->log2_cblk_height), band->coord[1][1] - band->coord[1][0] + y0);
                 }
             }
         }
@@ -969,8 +969,8 @@ static av_cold int j2kenc_init(AVCodecContext *avctx)
 
     // defaults:
     // TODO: implement setting non-standard precinct size
-    codsty->log2_prec_width  = 15;
-    codsty->log2_prec_height = 15;
+    memset(codsty->log2_prec_widths , 15, sizeof(codsty->log2_prec_widths ));
+    memset(codsty->log2_prec_heights, 15, sizeof(codsty->log2_prec_heights));
     codsty->nreslevels       = 7;
     codsty->log2_cblk_width  = 4;
     codsty->log2_cblk_height = 4;
diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h
index c2d6d90..e15fa78 100644
--- a/libavcodec/jpeg2000.h
+++ b/libavcodec/jpeg2000.h
@@ -134,8 +134,6 @@ typedef struct Jpeg2000CodingStyle {
             log2_cblk_height; // exponent of codeblock size
     uint8_t transform;        // DWT type
     uint8_t csty;             // coding style
-    uint8_t log2_prec_width,
-            log2_prec_height; // precinct size
     uint8_t nlayers;          // number of layers
     uint8_t mct;              // multiple component transformation
     uint8_t cblk_style;       // codeblock coding style
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
index 6bd9eb0..99b6643 100644
--- a/libavcodec/jpeg2000dec.c
+++ b/libavcodec/jpeg2000dec.c
@@ -256,6 +256,10 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
     if (bytestream2_get_bytes_left(&s->g) < 5)
         return AVERROR(EINVAL);
     c->nreslevels = bytestream2_get_byteu(&s->g) + 1; // num of resolution levels - 1
+    if (c->nreslevels >= JPEG2000_MAX_RESLEVELS) {
+        av_log(s->avctx, AV_LOG_ERROR, "nreslevels %d is invalid\n", c->nreslevels);
+        return AVERROR_INVALIDDATA;
+    }
 
     /* compute number of resolution levels to decode */
     if (c->nreslevels < s->reduction_factor)
@@ -289,6 +293,9 @@ static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
             c->log2_prec_widths[i]  =  byte       & 0x0F;    // precinct PPx
             c->log2_prec_heights[i] = (byte >> 4) & 0x0F;    // precinct PPy
         }
+    } else {
+        memset(c->log2_prec_widths , 15, sizeof(c->log2_prec_widths ));
+        memset(c->log2_prec_heights, 15, sizeof(c->log2_prec_heights));
     }
     return 0;
 }
@@ -303,9 +310,6 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
     if (bytestream2_get_bytes_left(&s->g) < 5)
         return AVERROR(EINVAL);
 
-    tmp.log2_prec_width  =
-    tmp.log2_prec_height = 15;
-
     tmp.csty = bytestream2_get_byteu(&s->g);
 
     // get progression order



More information about the ffmpeg-cvslog mailing list