PR #21353 opened by Ramiro Polla (ramiro)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21353
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21353.patch

JPEG is mostly byte-aligned. We only really need GetBitContext while
decoding the image data.

Suggested-by: Andreas Rheinhardt <[email protected]>


>From 0adcbb1d92e84576f7fba34575569a926a228ff9 Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Mon, 6 Oct 2025 12:33:34 +0200
Subject: [PATCH 1/5] avcodec/mjpegdec: improve check for length in
 ff_mjpeg_decode_dqt()

---
 libavcodec/mjpegdec.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index c347825c37..2485591aab 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -208,6 +208,8 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s)
             av_log(s->avctx, AV_LOG_ERROR, "dqt: invalid precision\n");
             return AVERROR_INVALIDDATA;
         }
+        if (len < (1 + 64 * (1+pr)))
+            return AVERROR_INVALIDDATA;
         index = get_bits(&s->gb, 4);
         if (index >= 4)
             return AVERROR_INVALIDDATA;
-- 
2.49.1


>From bb14b33a719592dd150b483b4bfc9e28d5d285b6 Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Fri, 12 Sep 2025 17:15:41 +0200
Subject: [PATCH 2/5] avcodec/mjpegdec: add mjpeg_parse_len() helper

And check for length field in a consistent manner.
---
 libavcodec/mjpegdec.c | 79 +++++++++++++++++++++++++------------------
 1 file changed, 46 insertions(+), 33 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 2485591aab..903a139f49 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -101,12 +101,12 @@ static int init_default_huffman_tables(MJpegDecodeContext 
*s)
 static void parse_avid(MJpegDecodeContext *s, uint8_t *buf, int len)
 {
     s->buggy_avid = 1;
-    if (len > 14 && buf[12] == 1) /* 1 - NTSC */
+    if (len > 12 && buf[12] == 1) /* 1 - NTSC */
         s->interlace_polarity = 1;
-    if (len > 14 && buf[12] == 2) /* 2 - PAL */
+    if (len > 12 && buf[12] == 2) /* 2 - PAL */
         s->interlace_polarity = 0;
     if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(s->avctx, AV_LOG_INFO, "AVID: len:%d %d\n", len, len > 14 ? 
buf[12] : -1);
+        av_log(s->avctx, AV_LOG_INFO, "AVID: len:%d %d\n", len, len > 12 ? 
buf[12] : -1);
 }
 
 static void init_idct(AVCodecContext *avctx)
@@ -190,17 +190,25 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
 }
 
 
+static int mjpeg_parse_len(MJpegDecodeContext *s, int *plen, const char *name)
+{
+    int len = get_bits(&s->gb, 16);
+    if (len < 2 || get_bits_left(&s->gb) < (8 * len - 16)) {
+        av_log(s->avctx, AV_LOG_ERROR, "%s: invalid len %d\n", name, len);
+        return AVERROR_INVALIDDATA;
+    }
+    *plen = len - 2;
+    return 0;
+}
+
 /* quantize tables */
 int ff_mjpeg_decode_dqt(MJpegDecodeContext *s)
 {
     int len, index, i;
 
-    len = get_bits(&s->gb, 16) - 2;
-
-    if (8*len > get_bits_left(&s->gb)) {
-        av_log(s->avctx, AV_LOG_ERROR, "dqt: len %d is too large\n", len);
-        return AVERROR_INVALIDDATA;
-    }
+    int ret = mjpeg_parse_len(s, &len, "dqt");
+    if (ret < 0)
+        return ret;
 
     while (len >= 65) {
         int pr = get_bits(&s->gb, 4);
@@ -243,12 +251,9 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
     uint8_t val_table[256];
     int ret = 0;
 
-    len = get_bits(&s->gb, 16) - 2;
-
-    if (8*len > get_bits_left(&s->gb)) {
-        av_log(s->avctx, AV_LOG_ERROR, "dht: len %d is too large\n", len);
-        return AVERROR_INVALIDDATA;
-    }
+    ret = mjpeg_parse_len(s, &len, "dht");
+    if (ret < 0)
+        return ret;
 
     while (len > 0) {
         if (len < 17)
@@ -308,7 +313,11 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
     memset(s->upscale_h, 0, sizeof(s->upscale_h));
     memset(s->upscale_v, 0, sizeof(s->upscale_v));
 
-    len     = get_bits(&s->gb, 16);
+    ret = mjpeg_parse_len(s, &len, "sof");
+    if (ret < 0)
+        return ret;
+    if (len < 6)
+        return AVERROR_INVALIDDATA;
     bits    = get_bits(&s->gb, 8);
 
     if (bits > 16 || bits < 1) {
@@ -365,7 +374,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
                                       "bits/component or 16-bit gray");
         return AVERROR_PATCHWELCOME;
     }
-    if (len != 8 + 3 * nb_components) {
+    len -= 6;
+    if (len != 3 * nb_components) {
         av_log(s->avctx, AV_LOG_ERROR, "decode_sof0: error, len(%d) mismatch 
%d components\n", len, nb_components);
         return AVERROR_INVALIDDATA;
     }
@@ -1683,8 +1693,11 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const 
uint8_t *mb_bitmask,
         return AVERROR_INVALIDDATA;
     }
 
-    /* XXX: verify len field validity */
-    len = get_bits(&s->gb, 16);
+    ret = mjpeg_parse_len(s, &len, "sos");
+    if (ret < 0)
+        return ret;
+    if (len < 1)
+        return AVERROR_INVALIDDATA;
     nb_components = get_bits(&s->gb, 8);
     if (nb_components == 0 || nb_components > MAX_COMPONENTS) {
         avpriv_report_missing_feature(s->avctx,
@@ -1692,8 +1705,8 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const 
uint8_t *mb_bitmask,
                                       nb_components);
         return AVERROR_PATCHWELCOME;
     }
-    if (len != 6 + 2 * nb_components) {
-        av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len);
+    if (len != 4 + 2 * nb_components) {
+        av_log(s->avctx, AV_LOG_ERROR, "decode_sos: len(%d) mismatch %d 
components\n", len, nb_components);
         return AVERROR_INVALIDDATA;
     }
     for (i = 0; i < nb_components; i++) {
@@ -1850,10 +1863,9 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
 {
     int len, id, i;
 
-    len = get_bits(&s->gb, 16);
-    if (len < 2)
+    int ret = mjpeg_parse_len(s, &len, "app");
+    if (ret < 0)
         return AVERROR_INVALIDDATA;
-    len -= 2;
 
     if (len < 4) {
         if (s->avctx->err_recognition & AV_EF_EXPLODE)
@@ -1862,9 +1874,6 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
         goto out;
     }
 
-    if (8 * len > get_bits_left(&s->gb))
-        return AVERROR_INVALIDDATA;
-
     id   = get_bits_long(&s->gb, 32);
     len -= 4;
 
@@ -2155,16 +2164,21 @@ out:
 
 static int mjpeg_decode_com(MJpegDecodeContext *s)
 {
-    int len = get_bits(&s->gb, 16);
-    if (len >= 2 && 8 * len - 16 <= get_bits_left(&s->gb)) {
+    int len;
+    int ret = mjpeg_parse_len(s, &len, "com");
+    if (ret < 0)
+        return ret;
+    if (!len)
+        return 0;
+
         int i;
-        char *cbuf = av_malloc(len - 1);
+        char *cbuf = av_malloc(len + 1);
         if (!cbuf)
             return AVERROR(ENOMEM);
 
-        for (i = 0; i < len - 2; i++)
+        for (i = 0; i < len; i++)
             cbuf[i] = get_bits(&s->gb, 8);
-        if (i > 0 && cbuf[i - 1] == '\n')
+        if (cbuf[i - 1] == '\n')
             cbuf[i - 1] = 0;
         else
             cbuf[i] = 0;
@@ -2186,7 +2200,6 @@ static int mjpeg_decode_com(MJpegDecodeContext *s)
         }
 
         av_free(cbuf);
-    }
 
     return 0;
 }
-- 
2.49.1


>From b4c7d15dc0c9a2d54498be8a39157a621ac76382 Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Mon, 29 Dec 2025 17:25:40 +0100
Subject: [PATCH 3/5] avcodec/mjpegdec: fix indentation for previous commit

---
 libavcodec/mjpegdec.c | 50 +++++++++++++++++++++----------------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 903a139f49..958b18b444 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -2171,35 +2171,35 @@ static int mjpeg_decode_com(MJpegDecodeContext *s)
     if (!len)
         return 0;
 
-        int i;
-        char *cbuf = av_malloc(len + 1);
-        if (!cbuf)
-            return AVERROR(ENOMEM);
+    int i;
+    char *cbuf = av_malloc(len + 1);
+    if (!cbuf)
+        return AVERROR(ENOMEM);
 
-        for (i = 0; i < len; i++)
-            cbuf[i] = get_bits(&s->gb, 8);
-        if (cbuf[i - 1] == '\n')
-            cbuf[i - 1] = 0;
-        else
-            cbuf[i] = 0;
+    for (i = 0; i < len; i++)
+        cbuf[i] = get_bits(&s->gb, 8);
+    if (cbuf[i - 1] == '\n')
+        cbuf[i - 1] = 0;
+    else
+        cbuf[i] = 0;
 
-        if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-            av_log(s->avctx, AV_LOG_INFO, "comment: '%s'\n", cbuf);
+    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(s->avctx, AV_LOG_INFO, "comment: '%s'\n", cbuf);
 
-        /* buggy avid, it puts EOI only at every 10th frame */
-        if (!strncmp(cbuf, "AVID", 4)) {
-            parse_avid(s, cbuf, len);
-        } else if (!strcmp(cbuf, "CS=ITU601"))
-            s->cs_itu601 = 1;
-        else if ((!strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32) && 
s->avctx->codec_tag) ||
-                 (!strncmp(cbuf, "Metasoft MJPEG Codec", 20)))
-            s->flipped = 1;
-        else if (!strcmp(cbuf, "MULTISCOPE II")) {
-            s->avctx->sample_aspect_ratio = (AVRational) { 1, 2 };
-            s->multiscope = 2;
-        }
+    /* buggy avid, it puts EOI only at every 10th frame */
+    if (!strncmp(cbuf, "AVID", 4)) {
+        parse_avid(s, cbuf, len);
+    } else if (!strcmp(cbuf, "CS=ITU601"))
+        s->cs_itu601 = 1;
+    else if ((!strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32) && 
s->avctx->codec_tag) ||
+             (!strncmp(cbuf, "Metasoft MJPEG Codec", 20)))
+        s->flipped = 1;
+    else if (!strcmp(cbuf, "MULTISCOPE II")) {
+        s->avctx->sample_aspect_ratio = (AVRational) { 1, 2 };
+        s->multiscope = 2;
+    }
 
-        av_free(cbuf);
+    av_free(cbuf);
 
     return 0;
 }
-- 
2.49.1


>From a784eb00c8f6b4d9954b903e873b84ce193e78d5 Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Wed, 10 Sep 2025 16:01:43 +0200
Subject: [PATCH 4/5] avcodec/mxpegdec: remove unnecessary scope and
 indentation

---
 libavcodec/mxpegdec.c | 216 +++++++++++++++++++++---------------------
 1 file changed, 107 insertions(+), 109 deletions(-)

diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index 8861a3969d..9526189f66 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -216,119 +216,117 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, 
AVFrame *rframe,
                                           &unescaped_buf_ptr, 
&unescaped_buf_size);
         if (start_code < 0)
             goto the_end;
-        {
-            init_get_bits(&jpg->gb, unescaped_buf_ptr, unescaped_buf_size*8);
 
-            if (start_code >= APP0 && start_code <= APP15) {
-                mxpeg_decode_app(s, unescaped_buf_ptr, unescaped_buf_size);
-            }
+        init_get_bits(&jpg->gb, unescaped_buf_ptr, unescaped_buf_size*8);
 
-            switch (start_code) {
-            case SOI:
-                if (jpg->got_picture) //emulating EOI
-                    goto the_end;
-                break;
-            case EOI:
-                goto the_end;
-            case DQT:
-                ret = ff_mjpeg_decode_dqt(jpg);
-                if (ret < 0) {
-                    av_log(avctx, AV_LOG_ERROR,
-                           "quantization table decode error\n");
-                    return ret;
-                }
-                break;
-            case DHT:
-                ret = ff_mjpeg_decode_dht(jpg);
-                if (ret < 0) {
-                    av_log(avctx, AV_LOG_ERROR,
-                           "huffman table decode error\n");
-                    return ret;
-                }
-                break;
-            case COM:
-                ret = mxpeg_decode_com(s, unescaped_buf_ptr,
-                                       unescaped_buf_size);
-                if (ret < 0)
-                    return ret;
-                break;
-            case SOF0:
-                if (s->got_sof_data > 1) {
-                    av_log(avctx, AV_LOG_ERROR,
-                           "Multiple SOF in a frame\n");
-                    return AVERROR_INVALIDDATA;
-                }
-                ret = ff_mjpeg_decode_sof(jpg);
-                if (ret < 0) {
-                    av_log(avctx, AV_LOG_ERROR,
-                           "SOF data decode error\n");
-                    s->got_sof_data = 0;
-                    return ret;
-                }
-                if (jpg->interlaced) {
-                    av_log(avctx, AV_LOG_ERROR,
-                           "Interlaced mode not supported in MxPEG\n");
-                    s->got_sof_data = 0;
-                    return AVERROR(EINVAL);
-                }
-                s->got_sof_data ++;
-                break;
-            case SOS:
-                if (!s->got_sof_data) {
-                    av_log(avctx, AV_LOG_WARNING,
-                           "Can not process SOS without SOF data, skipping\n");
-                    break;
-                }
-                if (!jpg->got_picture) {
-                    if (jpg->first_picture) {
-                        av_log(avctx, AV_LOG_WARNING,
-                               "First picture has no SOF, skipping\n");
-                        break;
-                    }
-                    if (!s->got_mxm_bitmask){
-                        av_log(avctx, AV_LOG_WARNING,
-                               "Non-key frame has no MXM, skipping\n");
-                        break;
-                    }
-                    /* use stored SOF data to allocate current picture */
-                    av_frame_unref(jpg->picture_ptr);
-                    if ((ret = ff_get_buffer(avctx, jpg->picture_ptr,
-                                             AV_GET_BUFFER_FLAG_REF)) < 0)
-                        return ret;
-                    jpg->picture_ptr->pict_type = AV_PICTURE_TYPE_P;
-                    jpg->picture_ptr->flags &= ~AV_FRAME_FLAG_KEY;
-                    jpg->got_picture = 1;
-                } else {
-                    jpg->picture_ptr->pict_type = AV_PICTURE_TYPE_I;
-                    jpg->picture_ptr->flags |= AV_FRAME_FLAG_KEY;
-                }
-
-                if (s->got_mxm_bitmask) {
-                    AVFrame *reference_ptr = s->picture[s->picture_index ^ 1];
-                    if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0)
-                        break;
-
-                    /* allocate dummy reference picture if needed */
-                    if (!reference_ptr->data[0] &&
-                        (ret = ff_get_buffer(avctx, reference_ptr,
-                                             AV_GET_BUFFER_FLAG_REF)) < 0)
-                        return ret;
-
-                    ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, 
s->bitmask_size, reference_ptr);
-                    if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
-                        return ret;
-                } else {
-                    ret = ff_mjpeg_decode_sos(jpg, NULL, 0, NULL);
-                    if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
-                        return ret;
-                }
-
-                break;
-            }
-
-            buf_ptr += (get_bits_count(&jpg->gb)+7) >> 3;
+        if (start_code >= APP0 && start_code <= APP15) {
+            mxpeg_decode_app(s, unescaped_buf_ptr, unescaped_buf_size);
         }
 
+        switch (start_code) {
+        case SOI:
+            if (jpg->got_picture) //emulating EOI
+                goto the_end;
+            break;
+        case EOI:
+            goto the_end;
+        case DQT:
+            ret = ff_mjpeg_decode_dqt(jpg);
+            if (ret < 0) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "quantization table decode error\n");
+                return ret;
+            }
+            break;
+        case DHT:
+            ret = ff_mjpeg_decode_dht(jpg);
+            if (ret < 0) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "huffman table decode error\n");
+                return ret;
+            }
+            break;
+        case COM:
+            ret = mxpeg_decode_com(s, unescaped_buf_ptr,
+                                   unescaped_buf_size);
+            if (ret < 0)
+                return ret;
+            break;
+        case SOF0:
+            if (s->got_sof_data > 1) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Multiple SOF in a frame\n");
+                return AVERROR_INVALIDDATA;
+            }
+            ret = ff_mjpeg_decode_sof(jpg);
+            if (ret < 0) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "SOF data decode error\n");
+                s->got_sof_data = 0;
+                return ret;
+            }
+            if (jpg->interlaced) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Interlaced mode not supported in MxPEG\n");
+                s->got_sof_data = 0;
+                return AVERROR(EINVAL);
+            }
+            s->got_sof_data ++;
+            break;
+        case SOS:
+            if (!s->got_sof_data) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "Can not process SOS without SOF data, skipping\n");
+                break;
+            }
+            if (!jpg->got_picture) {
+                if (jpg->first_picture) {
+                    av_log(avctx, AV_LOG_WARNING,
+                           "First picture has no SOF, skipping\n");
+                    break;
+                }
+                if (!s->got_mxm_bitmask){
+                    av_log(avctx, AV_LOG_WARNING,
+                           "Non-key frame has no MXM, skipping\n");
+                    break;
+                }
+                /* use stored SOF data to allocate current picture */
+                av_frame_unref(jpg->picture_ptr);
+                if ((ret = ff_get_buffer(avctx, jpg->picture_ptr,
+                                         AV_GET_BUFFER_FLAG_REF)) < 0)
+                    return ret;
+                jpg->picture_ptr->pict_type = AV_PICTURE_TYPE_P;
+                jpg->picture_ptr->flags &= ~AV_FRAME_FLAG_KEY;
+                jpg->got_picture = 1;
+            } else {
+                jpg->picture_ptr->pict_type = AV_PICTURE_TYPE_I;
+                jpg->picture_ptr->flags |= AV_FRAME_FLAG_KEY;
+            }
+
+            if (s->got_mxm_bitmask) {
+                AVFrame *reference_ptr = s->picture[s->picture_index ^ 1];
+                if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0)
+                    break;
+
+                /* allocate dummy reference picture if needed */
+                if (!reference_ptr->data[0] &&
+                    (ret = ff_get_buffer(avctx, reference_ptr,
+                                         AV_GET_BUFFER_FLAG_REF)) < 0)
+                    return ret;
+
+                ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, 
s->bitmask_size, reference_ptr);
+                if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
+                    return ret;
+            } else {
+                ret = ff_mjpeg_decode_sos(jpg, NULL, 0, NULL);
+                if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
+                    return ret;
+            }
+
+            break;
+        }
+
+        buf_ptr += (get_bits_count(&jpg->gb)+7) >> 3;
     }
 
 the_end:
-- 
2.49.1


>From 3a7db51f20b662cfe6e58c120aad8e71490fe7df Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Fri, 12 Sep 2025 19:01:42 +0200
Subject: [PATCH 5/5] avcodec/mjpegdec: use GetByteContext instead of
 GetBitContext where possible

JPEG is mostly byte-aligned. We only really need GetBitContext while
decoding the image data.

Suggested-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/jpeglsdec.c |  20 ++---
 libavcodec/mjpegbdec.c |  14 ++--
 libavcodec/mjpegdec.c  | 180 +++++++++++++++++++++--------------------
 libavcodec/mjpegdec.h  |   2 +
 libavcodec/mxpegdec.c  |   8 +-
 5 files changed, 114 insertions(+), 110 deletions(-)

diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index 6c4c6ad33c..154f1ed074 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -53,19 +53,19 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s)
     int id;
     int tid, wt, maxtab, i, j;
 
-    int len = get_bits(&s->gb, 16);
-    id = get_bits(&s->gb, 8);
+    int len = bytestream2_get_be16(&s->gB);
+    id = bytestream2_get_byte(&s->gB);
 
     switch (id) {
     case 1:
         if (len < 13)
             return AVERROR_INVALIDDATA;
 
-        s->maxval = get_bits(&s->gb, 16);
-        s->t1     = get_bits(&s->gb, 16);
-        s->t2     = get_bits(&s->gb, 16);
-        s->t3     = get_bits(&s->gb, 16);
-        s->reset  = get_bits(&s->gb, 16);
+        s->maxval = bytestream2_get_be16u(&s->gB);
+        s->t1     = bytestream2_get_be16u(&s->gB);
+        s->t2     = bytestream2_get_be16u(&s->gB);
+        s->t3     = bytestream2_get_be16u(&s->gB);
+        s->reset  = bytestream2_get_be16u(&s->gB);
 
         if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
             av_log(s->avctx, AV_LOG_DEBUG, "Coding parameters maxval:%d T1:%d 
T2:%d T3:%d reset:%d\n",
@@ -78,8 +78,8 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s)
     case 2:
         s->palette_index = 0;
     case 3:
-        tid= get_bits(&s->gb, 8);
-        wt = get_bits(&s->gb, 8);
+        tid= bytestream2_get_byte(&s->gB);
+        wt = bytestream2_get_byte(&s->gB);
 
         if (len < 5)
             return AVERROR_INVALIDDATA;
@@ -129,7 +129,7 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s)
                 uint8_t k = i << shift;
                 pal[k] = wt < 4 ? 0xFF000000 : 0;
                 for (j=0; j<wt; j++) {
-                    pal[k] |= get_bits(&s->gb, 8) << (8*(wt-j-1));
+                    pal[k] |= bytestream2_get_byte(&s->gB) << (8*(wt-j-1));
                 }
             }
             s->palette_index = i;
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c
index 4db1d9a89d..79eed6eaa6 100644
--- a/libavcodec/mjpegbdec.c
+++ b/libavcodec/mjpegbdec.c
@@ -84,7 +84,7 @@ read_header:
     dqt_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dqt is %d and size 
is %d\n");
     av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%"PRIx32"\n", dqt_offs);
     if (dqt_offs) {
-        init_get_bits(&s->gb, buf_ptr+dqt_offs, (buf_end - 
(buf_ptr+dqt_offs))*8);
+        bytestream2_init(&s->gB, buf_ptr+dqt_offs, buf_end - 
(buf_ptr+dqt_offs));
         s->start_code = DQT;
         ret = ff_mjpeg_decode_dqt(s);
         if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
@@ -94,7 +94,7 @@ read_header:
     dht_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dht is %d and size 
is %d\n");
     av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%"PRIx32"\n", dht_offs);
     if (dht_offs) {
-        init_get_bits(&s->gb, buf_ptr+dht_offs, (buf_end - 
(buf_ptr+dht_offs))*8);
+        bytestream2_init(&s->gB, buf_ptr+dht_offs, buf_end - 
(buf_ptr+dht_offs));
         s->start_code = DHT;
         ff_mjpeg_decode_dht(s);
     }
@@ -102,7 +102,7 @@ read_header:
     sof_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size 
is %d\n");
     av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%"PRIx32"\n", sof_offs);
     if (sof_offs) {
-        init_get_bits(&s->gb, buf_ptr+sof_offs, (buf_end - 
(buf_ptr+sof_offs))*8);
+        bytestream2_init(&s->gB, buf_ptr+sof_offs, buf_end - 
(buf_ptr+sof_offs));
         s->start_code = SOF0;
         if ((ret = ff_mjpeg_decode_sof(s)) < 0)
             return ret;
@@ -113,12 +113,12 @@ read_header:
     sod_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size 
is %d\n");
     av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%"PRIx32"\n", sod_offs);
     if (sos_offs) {
-        init_get_bits(&s->gb, buf_ptr + sos_offs,
-                      8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs));
-        s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16));
+        bytestream2_init(&s->gB, buf_ptr+sos_offs,
+                         FFMIN(field_size, buf_end - buf_ptr - sos_offs));
+        s->mjpb_skiptosod = (sod_offs - sos_offs - 
bytestream2_peek_be16(&s->gB));
         s->start_code = SOS;
         if (avctx->skip_frame == AVDISCARD_ALL) {
-            skip_bits(&s->gb, get_bits_left(&s->gb));
+            bytestream2_skipu(&s->gB, bytestream2_get_bytes_left(&s->gB));
         } else {
             ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL);
             if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 958b18b444..417cedae4a 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -148,8 +148,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
 
     if (s->extern_huff) {
         av_log(avctx, AV_LOG_INFO, "using external huffman table\n");
-        if ((ret = init_get_bits(&s->gb, avctx->extradata, 
avctx->extradata_size * 8)) < 0)
-            return ret;
+        bytestream2_init(&s->gB, avctx->extradata, avctx->extradata_size);
         if (ff_mjpeg_decode_dht(s)) {
             av_log(avctx, AV_LOG_ERROR,
                    "error using external huffman table, switching back to 
internal\n");
@@ -192,8 +191,8 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
 
 static int mjpeg_parse_len(MJpegDecodeContext *s, int *plen, const char *name)
 {
-    int len = get_bits(&s->gb, 16);
-    if (len < 2 || get_bits_left(&s->gb) < (8 * len - 16)) {
+    int len = bytestream2_get_be16u(&s->gB);
+    if (len < 2 || bytestream2_get_bytes_left(&s->gB) < (len - 2)) {
         av_log(s->avctx, AV_LOG_ERROR, "%s: invalid len %d\n", name, len);
         return AVERROR_INVALIDDATA;
     }
@@ -211,20 +210,21 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s)
         return ret;
 
     while (len >= 65) {
-        int pr = get_bits(&s->gb, 4);
+        uint8_t b = bytestream2_get_byteu(&s->gB);
+        int pr = b >> 4;
         if (pr > 1) {
             av_log(s->avctx, AV_LOG_ERROR, "dqt: invalid precision\n");
             return AVERROR_INVALIDDATA;
         }
         if (len < (1 + 64 * (1+pr)))
             return AVERROR_INVALIDDATA;
-        index = get_bits(&s->gb, 4);
+        index = b & 0x0F;
         if (index >= 4)
             return AVERROR_INVALIDDATA;
         av_log(s->avctx, AV_LOG_DEBUG, "index=%d\n", index);
         /* read quant table */
         for (i = 0; i < 64; i++) {
-            s->quant_matrixes[index][i] = get_bits(&s->gb, pr ? 16 : 8);
+            s->quant_matrixes[index][i] = pr ? bytestream2_get_be16u(&s->gB) : 
bytestream2_get_byteu(&s->gB);
             if (s->quant_matrixes[index][i] == 0) {
                 int log_level = s->avctx->err_recognition & AV_EF_EXPLODE ? 
AV_LOG_ERROR : AV_LOG_WARNING;
                 av_log(s->avctx, log_level, "dqt: 0 quant value\n");
@@ -258,15 +258,16 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
     while (len > 0) {
         if (len < 17)
             return AVERROR_INVALIDDATA;
-        class = get_bits(&s->gb, 4);
+        uint8_t b = bytestream2_get_byteu(&s->gB);
+        class = b >> 4;
         if (class >= 2)
             return AVERROR_INVALIDDATA;
-        index = get_bits(&s->gb, 4);
+        index = b & 0x0F;
         if (index >= 4)
             return AVERROR_INVALIDDATA;
         n = 0;
         for (i = 1; i <= 16; i++) {
-            bits_table[i] = get_bits(&s->gb, 8);
+            bits_table[i] = bytestream2_get_byteu(&s->gB);
             n += bits_table[i];
         }
         len -= 17;
@@ -274,7 +275,7 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
             return AVERROR_INVALIDDATA;
 
         for (i = 0; i < n; i++) {
-            v = get_bits(&s->gb, 8);
+            v = bytestream2_get_byteu(&s->gB);
             val_table[i] = v;
         }
         len -= n;
@@ -318,7 +319,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
         return ret;
     if (len < 6)
         return AVERROR_INVALIDDATA;
-    bits    = get_bits(&s->gb, 8);
+    bits    = bytestream2_get_byteu(&s->gB);
 
     if (bits > 16 || bits < 1) {
         av_log(s->avctx, AV_LOG_ERROR, "bits %d is invalid\n", bits);
@@ -340,8 +341,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
         return AVERROR(ENOSYS);
     }
 
-    height = get_bits(&s->gb, 16);
-    width  = get_bits(&s->gb, 16);
+    height = bytestream2_get_be16u(&s->gB);
+    width  = bytestream2_get_be16u(&s->gB);
 
     // HACK for odd_height.mov
     if (s->interlaced && s->width == width && s->height == height + 1)
@@ -357,7 +358,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
             return AVERROR_INVALIDDATA;
     }
 
-    nb_components = get_bits(&s->gb, 8);
+    nb_components = bytestream2_get_byteu(&s->gB);
     if (nb_components <= 0 ||
         nb_components > MAX_COMPONENTS)
         return AVERROR_INVALIDDATA;
@@ -385,15 +386,16 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
     s->v_max         = 1;
     for (i = 0; i < nb_components; i++) {
         /* component id */
-        s->component_id[i] = get_bits(&s->gb, 8);
-        h_count[i]         = get_bits(&s->gb, 4);
-        v_count[i]         = get_bits(&s->gb, 4);
+        s->component_id[i] = bytestream2_get_byteu(&s->gB);
+        uint8_t b = bytestream2_get_byteu(&s->gB);
+        h_count[i]         = b >> 4;
+        v_count[i]         = b & 0x0F;
         /* compute hmax and vmax (only used in interleaved case) */
         if (h_count[i] > s->h_max)
             s->h_max = h_count[i];
         if (v_count[i] > s->v_max)
             s->v_max = v_count[i];
-        s->quant_index[i] = get_bits(&s->gb, 8);
+        s->quant_index[i] = bytestream2_get_byteu(&s->gB);
         if (s->quant_index[i] >= 4) {
             av_log(s->avctx, AV_LOG_ERROR, "quant_index is invalid\n");
             return AVERROR_INVALIDDATA;
@@ -1698,7 +1700,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const 
uint8_t *mb_bitmask,
         return ret;
     if (len < 1)
         return AVERROR_INVALIDDATA;
-    nb_components = get_bits(&s->gb, 8);
+    nb_components = bytestream2_get_byteu(&s->gB);
     if (nb_components == 0 || nb_components > MAX_COMPONENTS) {
         avpriv_report_missing_feature(s->avctx,
                                       "decode_sos: nb_components (%d)",
@@ -1710,7 +1712,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const 
uint8_t *mb_bitmask,
         return AVERROR_INVALIDDATA;
     }
     for (i = 0; i < nb_components; i++) {
-        id = get_bits(&s->gb, 8);
+        id = bytestream2_get_byteu(&s->gB);
         av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id);
         /* find component index */
         for (index = 0; index < s->nb_components; index++)
@@ -1733,8 +1735,9 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const 
uint8_t *mb_bitmask,
 
         s->comp_index[i] = index;
 
-        s->dc_index[i] = get_bits(&s->gb, 4);
-        s->ac_index[i] = get_bits(&s->gb, 4);
+        uint8_t b = bytestream2_get_byteu(&s->gB);
+        s->dc_index[i] = b >> 4;
+        s->ac_index[i] = b & 0x0F;
 
         if (s->dc_index[i] <  0 || s->ac_index[i] < 0 ||
             s->dc_index[i] >= 4 || s->ac_index[i] >= 4)
@@ -1743,11 +1746,12 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const 
uint8_t *mb_bitmask,
             goto out_of_range;
     }
 
-    predictor = get_bits(&s->gb, 8);       /* JPEG Ss / lossless JPEG 
predictor /JPEG-LS NEAR */
-    ilv = get_bits(&s->gb, 8);             /* JPEG Se / JPEG-LS ILV */
+    predictor = bytestream2_get_byteu(&s->gB);  /* JPEG Ss / lossless JPEG 
predictor / JPEG-LS NEAR */
+    ilv = bytestream2_get_byteu(&s->gB);        /* JPEG Se / JPEG-LS ILV */
     if(s->avctx->codec_tag != AV_RL32("CJPG")){
-        prev_shift      = get_bits(&s->gb, 4); /* Ah */
-        point_transform = get_bits(&s->gb, 4); /* Al */
+        uint8_t b = bytestream2_get_byteu(&s->gB);
+        prev_shift      = b >> 4;   /* Ah */
+        point_transform = b & 0x0F; /* Al */
     }else
         prev_shift = point_transform = 0;
 
@@ -1773,15 +1777,19 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const 
uint8_t *mb_bitmask,
 
 
     /* mjpeg-b can have padding bytes between sos and image data, skip them */
-    for (i = s->mjpb_skiptosod; i > 0; i--)
-        skip_bits(&s->gb, 8);
+    if (s->mjpb_skiptosod)
+        bytestream2_skip(&s->gB, s->mjpb_skiptosod);
+
+    ret = init_get_bits8(&s->gb, s->gB.buffer, 
bytestream2_get_bytes_left(&s->gB));
+    if (ret < 0)
+        return ret;
 
 next_field:
     for (i = 0; i < nb_components; i++)
         s->last_dc[i] = (4 << s->bits);
 
     if (s->avctx->hwaccel) {
-        int bytes_to_start = get_bits_count(&s->gb) / 8;
+        int bytes_to_start = bytestream2_tell(&s->gB);
         av_assert0(bytes_to_start >= 0 &&
                    s->raw_scan_buffer_size >= bytes_to_start);
 
@@ -1841,6 +1849,10 @@ next_field:
         }
     }
 
+    /* Add the amount of bits read from the unescaped image data buffer
+     * into the GetByteContext. */
+    bytestream2_skipu(&s->gB, (get_bits_count(&s->gb) + 7) / 8);
+
     return 0;
  out_of_range:
     av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n");
@@ -1849,9 +1861,9 @@ next_field:
 
 static int mjpeg_decode_dri(MJpegDecodeContext *s)
 {
-    if (get_bits(&s->gb, 16) != 4)
+    if (bytestream2_get_be16u(&s->gB) != 4)
         return AVERROR_INVALIDDATA;
-    s->restart_interval = get_bits(&s->gb, 16);
+    s->restart_interval = bytestream2_get_be16u(&s->gB);
     s->restart_count    = 0;
     av_log(s->avctx, AV_LOG_DEBUG, "restart interval: %d\n",
            s->restart_interval);
@@ -1874,7 +1886,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
         goto out;
     }
 
-    id   = get_bits_long(&s->gb, 32);
+    id   = bytestream2_get_be32u(&s->gB);
     len -= 4;
 
     if (s->avctx->debug & FF_DEBUG_STARTCODE)
@@ -1893,7 +1905,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
             4bytes      field_size_less_padding
         */
             s->buggy_avid = 1;
-        i = get_bits(&s->gb, 8); len--;
+        i = bytestream2_get_byteu(&s->gB); len--;
         av_log(s->avctx, AV_LOG_DEBUG, "polarity %d\n", i);
         goto out;
     }
@@ -1902,13 +1914,13 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
         int t_w, t_h, v1, v2;
         if (len < 8)
             goto out;
-        skip_bits(&s->gb, 8); /* the trailing zero-byte */
-        v1 = get_bits(&s->gb, 8);
-        v2 = get_bits(&s->gb, 8);
-        skip_bits(&s->gb, 8);
+        bytestream2_skipu(&s->gB, 1); /* the trailing zero-byte */
+        v1 = bytestream2_get_byteu(&s->gB);
+        v2 = bytestream2_get_byteu(&s->gB);
+        bytestream2_skipu(&s->gB, 1);
 
-        s->avctx->sample_aspect_ratio.num = get_bits(&s->gb, 16);
-        s->avctx->sample_aspect_ratio.den = get_bits(&s->gb, 16);
+        s->avctx->sample_aspect_ratio.num = bytestream2_get_be16u(&s->gB);
+        s->avctx->sample_aspect_ratio.den = bytestream2_get_be16u(&s->gB);
         if (   s->avctx->sample_aspect_ratio.num <= 0
             || s->avctx->sample_aspect_ratio.den <= 0) {
             s->avctx->sample_aspect_ratio.num = 0;
@@ -1924,8 +1936,8 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
 
         len -= 8;
         if (len >= 2) {
-            t_w = get_bits(&s->gb, 8);
-            t_h = get_bits(&s->gb, 8);
+            t_w = bytestream2_get_byteu(&s->gB);
+            t_h = bytestream2_get_byteu(&s->gB);
             if (t_w && t_h) {
                 /* skip thumbnail */
                 if (len -10 - (t_w * t_h * 3) > 0)
@@ -1938,13 +1950,13 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
 
     if (   id == AV_RB32("Adob")
         && len >= 8
-        && show_bits(&s->gb, 8) == 'e'
-        && show_bits_long(&s->gb, 32) != AV_RB32("e_CM")) {
-        skip_bits(&s->gb,  8); /* 'e' */
-        skip_bits(&s->gb, 16); /* version */
-        skip_bits(&s->gb, 16); /* flags0 */
-        skip_bits(&s->gb, 16); /* flags1 */
-        s->adobe_transform = get_bits(&s->gb,  8);
+        && bytestream2_peek_byteu(&s->gB) == 'e'
+        && bytestream2_peek_be32u(&s->gB) != AV_RB32("e_CM")) {
+        bytestream2_skipu(&s->gB, 1); /* 'e' */
+        bytestream2_skipu(&s->gB, 2); /* version */
+        bytestream2_skipu(&s->gB, 2); /* flags0 */
+        bytestream2_skipu(&s->gB, 2); /* flags1 */
+        s->adobe_transform = bytestream2_get_byteu(&s->gB);
         if (s->avctx->debug & FF_DEBUG_PICT_INFO)
             av_log(s->avctx, AV_LOG_INFO, "mjpeg: Adobe header found, 
transform=%d\n", s->adobe_transform);
         len -= 8;
@@ -1957,11 +1969,11 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
         if (s->avctx->debug & FF_DEBUG_PICT_INFO)
             av_log(s->avctx, AV_LOG_INFO,
                    "Pegasus lossless jpeg header found\n");
-        skip_bits(&s->gb, 16); /* version ? */
-        skip_bits(&s->gb, 16); /* unknown always 0? */
-        skip_bits(&s->gb, 16); /* unknown always 0? */
-        skip_bits(&s->gb, 16); /* unknown always 0? */
-        switch (i=get_bits(&s->gb, 8)) {
+        bytestream2_skipu(&s->gB, 2); /* version ? */
+        bytestream2_skipu(&s->gB, 2); /* unknown always 0? */
+        bytestream2_skipu(&s->gB, 2); /* unknown always 0? */
+        bytestream2_skipu(&s->gB, 2); /* unknown always 0? */
+        switch (i=bytestream2_get_byteu(&s->gB)) {
         case 1:
             rgb         = 1;
             pegasus_rct = 0;
@@ -1989,14 +2001,14 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
         goto out;
     }
     if (id == AV_RL32("colr") && len > 0) {
-        s->colr = get_bits(&s->gb, 8);
+        s->colr = bytestream2_get_byteu(&s->gB);
         if (s->avctx->debug & FF_DEBUG_PICT_INFO)
             av_log(s->avctx, AV_LOG_INFO, "COLR %d\n", s->colr);
         len --;
         goto out;
     }
     if (id == AV_RL32("xfrm") && len > 0) {
-        s->xfrm = get_bits(&s->gb, 8);
+        s->xfrm = bytestream2_get_byteu(&s->gB);
         if (s->avctx->debug & FF_DEBUG_PICT_INFO)
             av_log(s->avctx, AV_LOG_INFO, "XFRM %d\n", s->xfrm);
         len --;
@@ -2009,12 +2021,12 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
         if (s->avctx->debug & FF_DEBUG_PICT_INFO)
             av_log(s->avctx, AV_LOG_INFO, "_JPSJPS_\n");
 
-        skip_bits(&s->gb, 32); len -= 4;  /* JPS_ */
-        skip_bits(&s->gb, 16); len -= 2;  /* block length */
-        skip_bits(&s->gb, 8);             /* reserved */
-        flags  = get_bits(&s->gb, 8);
-        layout = get_bits(&s->gb, 8);
-        type   = get_bits(&s->gb, 8);
+        bytestream2_skipu(&s->gB, 4); len -= 4;  /* JPS_ */
+        bytestream2_skipu(&s->gB, 2); len -= 2;  /* block length */
+        bytestream2_skipu(&s->gB, 1);            /* reserved */
+        flags  = bytestream2_get_byteu(&s->gB);
+        layout = bytestream2_get_byteu(&s->gB);
+        type   = bytestream2_get_byteu(&s->gB);
         len -= 4;
 
         av_freep(&s->stereo3d);
@@ -2046,21 +2058,17 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
     /* EXIF metadata */
     if (s->start_code == APP1 && id == AV_RB32("Exif") && len >= 2) {
         int ret;
-        const uint8_t *aligned;
 
-        skip_bits(&s->gb, 16); // skip padding
+        bytestream2_skipu(&s->gB, 2); // skip padding
         len -= 2;
 
-        // init byte wise reading
-        aligned = align_get_bits(&s->gb);
-
-        ret = av_exif_parse_buffer(s->avctx, aligned, len, &s->exif_metadata, 
AV_EXIF_TIFF_HEADER);
+        ret = av_exif_parse_buffer(s->avctx, s->gB.buffer, len, 
&s->exif_metadata, AV_EXIF_TIFF_HEADER);
         if (ret < 0) {
             av_log(s->avctx, AV_LOG_WARNING, "unable to parse EXIF buffer\n");
             goto out;
         }
 
-        skip_bits(&s->gb, ret << 3);
+        bytestream2_skipu(&s->gB, ret);
         len -= ret;
 
         goto out;
@@ -2068,7 +2076,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
 
     /* Apple MJPEG-A */
     if ((s->start_code == APP1) && (len > (0x28 - 8))) {
-        id   = get_bits_long(&s->gb, 32);
+        id   = bytestream2_get_be32u(&s->gB);
         len -= 4;
         /* Apple MJPEG-A */
         if (id == AV_RB32("mjpg")) {
@@ -2092,23 +2100,23 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
         unsigned seqno;
         unsigned nummarkers;
 
-        id   = get_bits_long(&s->gb, 32);
-        id2  = get_bits(&s->gb, 24);
+        id   = bytestream2_get_be32u(&s->gB);
+        id2  = bytestream2_get_be24u(&s->gB);
         len -= 7;
         if (id != AV_RB32("PROF") || id2 != AV_RB24("ILE")) {
             av_log(s->avctx, AV_LOG_WARNING, "Invalid ICC_PROFILE header in 
APP2\n");
             goto out;
         }
 
-        skip_bits(&s->gb, 8);
-        seqno  = get_bits(&s->gb, 8);
+        bytestream2_skipu(&s->gB, 1);
+        seqno  = bytestream2_get_byteu(&s->gB);
         len   -= 2;
         if (seqno == 0) {
             av_log(s->avctx, AV_LOG_WARNING, "Invalid sequence number in 
APP2\n");
             goto out;
         }
 
-        nummarkers  = get_bits(&s->gb, 8);
+        nummarkers  = bytestream2_get_byteu(&s->gB);
         len        -= 1;
         if (nummarkers == 0) {
             av_log(s->avctx, AV_LOG_WARNING, "Invalid number of markers coded 
in APP2\n");
@@ -2142,8 +2150,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
             return AVERROR(ENOMEM);
         }
 
-        memcpy(s->iccentries[seqno - 1].data, align_get_bits(&s->gb), len);
-        skip_bits(&s->gb, len << 3);
+        bytestream2_get_bufferu(&s->gB, s->iccentries[seqno - 1].data, len);
         len = 0;
         s->iccread++;
 
@@ -2156,8 +2163,8 @@ out:
     if (len < 0)
         av_log(s->avctx, AV_LOG_ERROR,
                "mjpeg: error, decode_app parser read over the end\n");
-    while (len-- > 0)
-        skip_bits(&s->gb, 8);
+    if (len)
+        bytestream2_skipu(&s->gB, len);
 
     return 0;
 }
@@ -2177,7 +2184,7 @@ static int mjpeg_decode_com(MJpegDecodeContext *s)
         return AVERROR(ENOMEM);
 
     for (i = 0; i < len; i++)
-        cbuf[i] = get_bits(&s->gb, 8);
+        cbuf[i] = bytestream2_get_byteu(&s->gB);
     if (cbuf[i - 1] == '\n')
         cbuf[i - 1] = 0;
     else
@@ -2412,12 +2419,7 @@ redo_for_pal8:
         av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n",
                start_code, buf_end - buf_ptr);
 
-        ret = init_get_bits8(&s->gb, unescaped_buf_ptr, unescaped_buf_size);
-
-        if (ret < 0) {
-            av_log(avctx, AV_LOG_ERROR, "invalid buffer\n");
-            goto fail;
-        }
+        bytestream2_init(&s->gB, unescaped_buf_ptr, unescaped_buf_size);
 
         s->start_code = start_code;
         if (avctx->debug & FF_DEBUG_STARTCODE)
@@ -2614,10 +2616,10 @@ eoi_parser:
 
 skip:
         /* eof process start code */
-        buf_ptr += (get_bits_count(&s->gb) + 7) / 8;
+        buf_ptr += bytestream2_tell(&s->gB);
         av_log(avctx, AV_LOG_DEBUG,
-               "marker parser used %d bytes (%d bits)\n",
-               (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb));
+               "marker parser used %d bytes\n",
+               bytestream2_tell(&s->gB));
     }
     if (s->got_picture && s->cur_scan) {
         av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n");
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index ce688482cf..4f4139dcc4 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -36,6 +36,7 @@
 
 #include "avcodec.h"
 #include "blockdsp.h"
+#include "bytestream.h"
 #include "exif.h"
 #include "get_bits.h"
 #include "hpeldsp.h"
@@ -56,6 +57,7 @@ typedef struct MJpegDecodeContext {
     AVClass *class;
     AVCodecContext *avctx;
     GetBitContext gb;
+    GetByteContext gB;
     int buf_size;
 
     int start_code; /* current start code */
diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index 9526189f66..b66bff56c9 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -86,7 +86,7 @@ static int mxpeg_decode_app(MXpegDecodeContext *s,
     if (buf_size < 2)
         return 0;
     len = AV_RB16(buf_ptr);
-    skip_bits(&s->jpg.gb, 8*FFMIN(len,buf_size));
+    bytestream2_skipu(&s->jpg.gB, FFMIN(len, buf_size));
 
     return 0;
 }
@@ -154,7 +154,7 @@ static int mxpeg_decode_com(MXpegDecodeContext *s,
     if (len > 14 && len <= buf_size && !strncmp(buf_ptr + 2, "MXM", 3)) {
         ret = mxpeg_decode_mxm(s, buf_ptr + 2, len - 2);
     }
-    skip_bits(&s->jpg.gb, 8*FFMIN(len,buf_size));
+    bytestream2_skipu(&s->jpg.gB, FFMIN(len, buf_size));
 
     return ret;
 }
@@ -217,7 +217,7 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, 
AVFrame *rframe,
         if (start_code < 0)
             goto the_end;
 
-        init_get_bits(&jpg->gb, unescaped_buf_ptr, unescaped_buf_size*8);
+        bytestream2_init(&jpg->gB, unescaped_buf_ptr, unescaped_buf_size);
 
         if (start_code >= APP0 && start_code <= APP15) {
             mxpeg_decode_app(s, unescaped_buf_ptr, unescaped_buf_size);
@@ -326,7 +326,7 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, 
AVFrame *rframe,
             break;
         }
 
-        buf_ptr += (get_bits_count(&jpg->gb)+7) >> 3;
+        buf_ptr += bytestream2_tell(&jpg->gB);
     }
 
 the_end:
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to