]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/j2kdec.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / j2kdec.c
index 01a1e2e39989d76f44fb7d26d69ad1e385ee4e75..2cbd7cc529aea902170de922087bb6fee82a9ba7 100644 (file)
@@ -64,9 +64,9 @@ typedef struct {
     J2kCodingStyle codsty[4];
     J2kQuantStyle  qntsty[4];
 
-    uint8_t *buf_start;
-    uint8_t *buf;
-    uint8_t *buf_end;
+    const uint8_t *buf_start;
+    const uint8_t *buf;
+    const uint8_t *buf_end;
     int bit_index;
 
     int16_t curtileno;
@@ -220,6 +220,9 @@ static int get_siz(J2kDecoderContext *s)
      s->tile_offset_y = bytestream_get_be32(&s->buf); // YT0Siz
        s->ncomponents = bytestream_get_be16(&s->buf); // CSiz
 
+    if(s->tile_width<=0 || s->tile_height<=0)
+        return AVERROR(EINVAL);
+
     if (s->buf_end - s->buf < 2 * s->ncomponents)
         return AVERROR(EINVAL);
 
@@ -227,7 +230,7 @@ static int get_siz(J2kDecoderContext *s)
         uint8_t x = bytestream_get_byte(&s->buf);
         s->cbps[i] = (x & 0x7f) + 1;
         s->precision = FFMAX(s->cbps[i], s->precision);
-        s->sgnd[i] = (x & 0x80) == 1;
+        s->sgnd[i] = !!(x & 0x80);
         s->cdx[i] = bytestream_get_byte(&s->buf);
         s->cdy[i] = bytestream_get_byte(&s->buf);
     }
@@ -235,6 +238,9 @@ static int get_siz(J2kDecoderContext *s)
     s->numXtiles = ff_j2k_ceildiv(s->width - s->tile_offset_x, s->tile_width);
     s->numYtiles = ff_j2k_ceildiv(s->height - s->tile_offset_y, s->tile_height);
 
+    if(s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(J2kTile))
+        return AVERROR(EINVAL);
+
     s->tile = av_mallocz(s->numXtiles * s->numYtiles * sizeof(J2kTile));
     if (!s->tile)
         return AVERROR(ENOMEM);
@@ -268,7 +274,7 @@ static int get_siz(J2kDecoderContext *s)
     if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0)
         return ret;
 
-    s->picture.pict_type = FF_I_TYPE;
+    s->picture.pict_type = AV_PICTURE_TYPE_I;
     s->picture.key_frame = 1;
 
     return 0;
@@ -359,7 +365,7 @@ static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q)
 
     if (q->quantsty == J2K_QSTY_NONE){
         n -= 3;
-        if (s->buf_end - s->buf < n)
+        if (s->buf_end - s->buf < n || 32*3 < n)
             return AVERROR(EINVAL);
         for (i = 0; i < n; i++)
             q->expn[i] = bytestream_get_byte(&s->buf) >> 3;
@@ -376,7 +382,7 @@ static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q)
         }
     } else{
         n = (n - 3) >> 1;
-        if (s->buf_end - s->buf < n)
+        if (s->buf_end - s->buf < n || 32*3 < n)
             return AVERROR(EINVAL);
         for (i = 0; i < n; i++){
             x = bytestream_get_be16(&s->buf);
@@ -421,6 +427,10 @@ static uint8_t get_sot(J2kDecoderContext *s)
         return AVERROR(EINVAL);
 
     s->curtileno = bytestream_get_be16(&s->buf); ///< Isot
+    if((unsigned)s->curtileno >= s->numXtiles * s->numYtiles){
+        s->curtileno=0;
+        return AVERROR(EINVAL);
+    }
 
     s->buf += 4; ///< Psot (ignored)
 
@@ -903,13 +913,15 @@ static int decode_codestream(J2kDecoderContext *s)
 
     for (;;){
         int marker, len, ret = 0;
-        uint8_t *oldbuf;
+        const uint8_t *oldbuf;
         if (s->buf_end - s->buf < 2){
             av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n");
             break;
         }
 
         marker = bytestream_get_be16(&s->buf);
+        if(s->avctx->debug & FF_DEBUG_STARTCODE)
+            av_log(s->avctx, AV_LOG_DEBUG, "marker 0x%.4X at pos 0x%tx\n", marker, s->buf - s->buf_start - 4);
         oldbuf = s->buf;
 
         if (marker == J2K_SOD){
@@ -1056,16 +1068,15 @@ static av_cold int decode_end(AVCodecContext *avctx)
 }
 
 AVCodec ff_jpeg2000_decoder = {
-    "j2k",
-    AVMEDIA_TYPE_VIDEO,
-    CODEC_ID_JPEG2000,
-    sizeof(J2kDecoderContext),
-    j2kdec_init,
-    NULL,
-    decode_end,
-    decode_frame,
+    .name           = "j2k",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = CODEC_ID_JPEG2000,
+    .priv_data_size = sizeof(J2kDecoderContext),
+    .init           = j2kdec_init,
+    .close          = decode_end,
+    .decode         = decode_frame,
     .capabilities = CODEC_CAP_EXPERIMENTAL,
     .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"),
     .pix_fmts =
-        (enum PixelFormat[]) {PIX_FMT_GRAY8, PIX_FMT_RGB24, -1}
+        (enum PixelFormat[]) {PIX_FMT_GRAY8, PIX_FMT_RGB24, PIX_FMT_NONE}
 };