]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/jpeg2000dec.c
Use av_packet_rescale_ts() to simplify code.
[ffmpeg] / libavcodec / jpeg2000dec.c
index 589cbc12b1e2030b0672f65591e7fb9be6e717f0..7d081eadd1fe07c4d90131e808c62a388c87fc2a 100644 (file)
@@ -25,6 +25,9 @@
  * JPEG 2000 image decoder
  */
 
+#include <inttypes.h>
+
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
@@ -345,7 +348,7 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
 
     if (tmp.mct && s->ncomponents < 3) {
         av_log(s->avctx, AV_LOG_ERROR,
-               "MCT %d with too few components (%d)\n",
+               "MCT %"PRIu8" with too few components (%d)\n",
                tmp.mct, s->ncomponents);
         return AVERROR_INVALIDDATA;
     }
@@ -497,12 +500,12 @@ static int get_sot(Jpeg2000DecoderContext *s, int n)
     bytestream2_get_byteu(&s->g);               // TNsot
 
     if (Psot > bytestream2_get_bytes_left(&s->g) + n + 2) {
-        av_log(s->avctx, AV_LOG_ERROR, "Psot %d too big\n", Psot);
+        av_log(s->avctx, AV_LOG_ERROR, "Psot %"PRIu32" too big\n", Psot);
         return AVERROR_INVALIDDATA;
     }
 
     if (TPsot >= FF_ARRAY_ELEMS(s->tile[Isot].tile_part)) {
-        avpriv_request_sample(s->avctx, "Support for %d components", TPsot);
+        avpriv_request_sample(s->avctx, "Support for %"PRIu8" components", TPsot);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -715,6 +718,13 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s,
             }
             cblk->length   += cblk->lengthinc;
             cblk->lengthinc = 0;
+
+            if (cblk->length > sizeof(cblk->data)) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "Block length %"PRIu16" > data size %zd\n",
+                       cblk->length, sizeof(cblk->data));
+                return AVERROR_INVALIDDATA;
+            }
         }
     }
     return 0;
@@ -1160,8 +1170,12 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
     if (s->precision <= 8) {
         for (compno = 0; compno < s->ncomponents; compno++) {
             Jpeg2000Component *comp = tile->comp + compno;
+            Jpeg2000CodingStyle *codsty = tile->codsty + compno;
             float *datap = comp->f_data;
             int32_t *i_datap = comp->i_data;
+            int cbps = s->cbps[compno];
+            int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
+
             y    = tile->comp[compno].coord[1][0] - s->image_offset_y;
             line = picture->data[0] + y * picture->linesize[0];
             for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {
@@ -1170,18 +1184,24 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
                 x   = tile->comp[compno].coord[0][0] - s->image_offset_x;
                 dst = line + x * s->ncomponents + compno;
 
-                for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s->cdx[compno]) {
-                     int val;
-                    /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
-                    if (tile->codsty->transform == FF_DWT97)
-                        val = lrintf(*datap) + (1 << (s->cbps[compno] - 1));
-                    else
-                        val = *i_datap + (1 << (s->cbps[compno] - 1));
-                    val = av_clip(val, 0, (1 << s->cbps[compno]) - 1);
-                    *dst = val << (8 - s->cbps[compno]);
-                    datap++;
-                    i_datap++;
-                    dst += s->ncomponents;
+                if (codsty->transform == FF_DWT97) {
+                    for (; x < w; x += s->cdx[compno]) {
+                        int val = lrintf(*datap) + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        *dst = val << (8 - cbps);
+                        datap++;
+                        dst += s->ncomponents;
+                    }
+                } else {
+                    for (; x < w; x += s->cdx[compno]) {
+                        int val = *i_datap + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        *dst = val << (8 - cbps);
+                        i_datap++;
+                        dst += s->ncomponents;
+                    }
                 }
                 line += picture->linesize[0];
             }
@@ -1189,9 +1209,12 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
     } else {
         for (compno = 0; compno < s->ncomponents; compno++) {
             Jpeg2000Component *comp = tile->comp + compno;
+            Jpeg2000CodingStyle *codsty = tile->codsty + compno;
             float *datap = comp->f_data;
             int32_t *i_datap = comp->i_data;
             uint16_t *linel;
+            int cbps = s->cbps[compno];
+            int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
 
             y     = tile->comp[compno].coord[1][0] - s->image_offset_y;
             linel = (uint16_t *)picture->data[0] + y * (picture->linesize[0] >> 1);
@@ -1199,24 +1222,32 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
                 uint16_t *dst;
                 x   = tile->comp[compno].coord[0][0] - s->image_offset_x;
                 dst = linel + (x * s->ncomponents + compno);
-                for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s-> cdx[compno]) {
-                    int val;
-                    /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
-                    if (tile->codsty->transform == FF_DWT97)
-                        val = lrintf(*datap) + (1 << (s->cbps[compno] - 1));
-                    else
-                        val = *i_datap + (1 << (s->cbps[compno] - 1));
-                    val = av_clip(val, 0, (1 << s->cbps[compno]) - 1);
-                    /* align 12 bit values in little-endian mode */
-                    *dst = val << (16 - s->cbps[compno]);
-                    datap++;
-                    i_datap++;
-                    dst += s->ncomponents;
+                if (codsty->transform == FF_DWT97) {
+                    for (; x < w; x += s-> cdx[compno]) {
+                        int  val = lrintf(*datap) + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        /* align 12 bit values in little-endian mode */
+                        *dst = val << (16 - cbps);
+                        datap++;
+                        dst += s->ncomponents;
+                    }
+                } else {
+                    for (; x < w; x += s-> cdx[compno]) {
+                        int val = *i_datap + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        /* align 12 bit values in little-endian mode */
+                        *dst = val << (16 - cbps);
+                        i_datap++;
+                        dst += s->ncomponents;
+                    }
                 }
                 linel += picture->linesize[0] >> 1;
             }
         }
     }
+
     return 0;
 }
 
@@ -1233,6 +1264,7 @@ static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s)
         av_freep(&s->tile[tileno].comp);
     }
     av_freep(&s->tile);
+    s->numXtiles = s->numYtiles = 0;
 }
 
 static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
@@ -1262,6 +1294,10 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
                 av_log(s->avctx, AV_LOG_ERROR, "Missing SOT\n");
                 return AVERROR_INVALIDDATA;
             }
+            if (!s->tile) {
+                av_log(s->avctx, AV_LOG_ERROR, "Missing SIZ\n");
+                return AVERROR_INVALIDDATA;
+            }
 
             tile = s->tile + s->curtileno;
             tp = tile->tile_part + tile->tp_idx;
@@ -1310,14 +1346,15 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
             break;
         default:
             av_log(s->avctx, AV_LOG_ERROR,
-                   "unsupported marker 0x%.4X at pos 0x%X\n",
+                   "unsupported marker 0x%.4"PRIX16" at pos 0x%X\n",
                    marker, bytestream2_tell(&s->g) - 4);
             bytestream2_skip(&s->g, len - 2);
             break;
         }
         if (bytestream2_tell(&s->g) - oldpos != len || ret) {
             av_log(s->avctx, AV_LOG_ERROR,
-                   "error during processing marker segment %.4x\n", marker);
+                   "error during processing marker segment %.4"PRIx16"\n",
+                   marker);
             return ret ? ret : -1;
         }
     }
@@ -1434,9 +1471,10 @@ end:
     return ret;
 }
 
-static void jpeg2000_init_static_data(AVCodec *codec)
+static av_cold void jpeg2000_init_static_data(AVCodec *codec)
 {
     ff_jpeg2000_init_tier1_luts();
+    ff_mqc_init_context_tables();
 }
 
 #define OFFSET(x) offsetof(Jpeg2000DecoderContext, x)