]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/jpeglsdec.c
mpeg12dec: avoid signed overflow in bitrate calculation
[ffmpeg] / libavcodec / jpeglsdec.c
index cec561226a29d70ac5adc8d4bf9da12f79a32532..9f8ccecec6c2720e7c51da7b630a93bc5a77aed8 100644 (file)
@@ -28,6 +28,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "golomb.h"
+#include "internal.h"
 #include "mathops.h"
 #include "mjpeg.h"
 #include "mjpegdec.h"
@@ -76,7 +77,7 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s)
         av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id);
         return AVERROR_INVALIDDATA;
     }
-    av_dlog(s->avctx, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3);
+    ff_dlog(s->avctx, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3);
 
     return 0;
 }
@@ -274,13 +275,19 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
     int i, t = 0;
     uint8_t *zero, *last, *cur;
     JLSState *state;
-    int off = 0, stride = 1, width, shift;
+    int off = 0, stride = 1, width, shift, ret = 0;
 
     zero = av_mallocz(s->picture_ptr->linesize[0]);
+    if (!zero)
+        return AVERROR(ENOMEM);
     last = zero;
     cur  = s->picture_ptr->data[0];
 
     state = av_mallocz(sizeof(JLSState));
+    if (!state) {
+        av_free(zero);
+        return AVERROR(ENOMEM);
+    }
     /* initialize JPEG-LS state from JPEG parameters */
     state->near   = near;
     state->bpp    = (s->bits < 2) ? 2 : s->bits;
@@ -297,15 +304,19 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
     else
         shift = point_transform + (16 - s->bits);
 
-    av_dlog(s->avctx,
+    ff_dlog(s->avctx,
             "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) "
             "RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",
             s->width, s->height, state->near, state->maxval,
             state->T1, state->T2, state->T3,
             state->reset, state->limit, state->qbpp, state->range);
-    av_dlog(s->avctx, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n",
+    ff_dlog(s->avctx, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n",
             ilv, point_transform, s->bits, s->cur_scan);
     if (ilv == 0) { /* separate planes */
+        if (s->cur_scan > s->nb_components) {
+            ret = AVERROR_INVALIDDATA;
+            goto end;
+        }
         off    = s->cur_scan - 1;
         stride = (s->nb_components > 1) ? 3 : 1;
         width  = s->width * stride;
@@ -347,9 +358,8 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
         }
     } else if (ilv == 2) { /* sample interleaving */
         avpriv_report_missing_feature(s->avctx, "Sample interleaved images");
-        av_free(state);
-        av_free(zero);
-        return AVERROR_PATCHWELCOME;
+        ret = AVERROR_PATCHWELCOME;
+        goto end;
     }
 
     if (shift) { /* we need to do point transform or normalize samples */
@@ -375,10 +385,12 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
             }
         }
     }
+
+end:
     av_free(state);
     av_free(zero);
 
-    return 0;
+    return ret;
 }
 
 AVCodec ff_jpegls_decoder = {
@@ -390,5 +402,6 @@ AVCodec ff_jpegls_decoder = {
     .init           = ff_mjpeg_decode_init,
     .close          = ff_mjpeg_decode_end,
     .decode         = ff_mjpeg_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .capabilities   = AV_CODEC_CAP_DR1,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };