]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/scpr.c
avcodec/movtextdec: Call mov_text_cleanup() on close
[ffmpeg] / libavcodec / scpr.c
index d5ce8c785db2fbcd1938e0f97e493576187b0607..1fc0593dbb6e50340ffe0ac9d163caadc41f7f8e 100644 (file)
@@ -63,7 +63,7 @@ typedef struct SCPRContext {
     int             cxshift;
 
     int           (*get_freq)(RangeCoder *rc, unsigned total_freq, unsigned *freq);
-    void          (*decode)(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq);
+    int           (*decode)(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq);
 } SCPRContext;
 
 static void init_rangecoder(RangeCoder *rc, GetByteContext *gb)
@@ -130,7 +130,7 @@ static void reinit_tables(SCPRContext *s)
     s->mv_model[1][512] = 512;
 }
 
-static void decode(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq)
+static int decode(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq)
 {
     rc->code -= cumFreq * rc->range;
     rc->range *= freq;
@@ -140,6 +140,8 @@ static void decode(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigne
         rc->code = (rc->code << 8) | byte;
         rc->range <<= 8;
     }
+
+    return 0;
 }
 
 static int get_freq(RangeCoder *rc, unsigned total_freq, unsigned *freq)
@@ -157,9 +159,14 @@ static int get_freq(RangeCoder *rc, unsigned total_freq, unsigned *freq)
     return 0;
 }
 
-static void decode0(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq)
+static int decode0(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq)
 {
-    int t = rc->range * (uint64_t)cumFreq / total_freq;
+    int t;
+
+    if (total_freq == 0)
+        return AVERROR_INVALIDDATA;
+
+    t = rc->range * (uint64_t)cumFreq / total_freq;
 
     rc->code1 += t + 1;
     rc->range = rc->range * (uint64_t)(freq + cumFreq) / total_freq - (t + 1);
@@ -170,6 +177,8 @@ static void decode0(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsign
         rc->code1 <<= 8;
         rc->range <<= 8;
     }
+
+    return 0;
 }
 
 static int get_freq0(RangeCoder *rc, unsigned total_freq, unsigned *freq)
@@ -202,7 +211,8 @@ static int decode_value(SCPRContext *s, unsigned *cnt, unsigned maxc, unsigned s
             break;
         c++;
     }
-    s->decode(gb, rc, cumfr, cnt_c, totfr);
+    if ((ret = s->decode(gb, rc, cumfr, cnt_c, totfr)) < 0)
+        return ret;
 
     cnt[c] = cnt_c + step;
     totfr += step;
@@ -251,7 +261,10 @@ static int decode_unit(SCPRContext *s, PixelModel *pixel, unsigned step, unsigne
             break;
         c++;
     }
-    s->decode(gb, rc, cumfr, cnt_c, totfr);
+
+    if ((ret = s->decode(gb, rc, cumfr, cnt_c, totfr)) < 0)
+        return ret;
+
     pixel->freq[c] = cnt_c + step;
     pixel->lookup[x] = cnt_x + step;
     totfr += step;
@@ -282,7 +295,8 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
     SCPRContext *s = avctx->priv_data;
     GetByteContext *gb = &s->gb;
     int cx = 0, cx1 = 0, k = 0, clr = 0;
-    int run, r, g, b, off, y = 0, x = 0, ret;
+    int run, r, g, b, off, y = 0, x = 0, z, ret;
+    unsigned backstep = linesize - avctx->width;
     const int cxshift = s->cxshift;
     unsigned lx, ly, ptype;
 
@@ -411,18 +425,25 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
             while (run-- > 0) {
                 uint8_t *odst = (uint8_t *)dst;
 
-                if (y < 1 || y >= avctx->height)
+                if (y < 1 || y >= avctx->height ||
+                    (y == 1 && x == 0))
                     return AVERROR_INVALIDDATA;
 
+                if (x == 0) {
+                    z = backstep;
+                } else {
+                    z = 0;
+                }
+
                 r = odst[(ly * linesize + lx) * 4] +
-                    odst[((y * linesize + x) + off) * 4 + 4] -
-                    odst[((y * linesize + x) + off) * 4];
+                    odst[((y * linesize + x) + off - z) * 4 + 4] -
+                    odst[((y * linesize + x) + off - z) * 4];
                 g = odst[(ly * linesize + lx) * 4 + 1] +
-                    odst[((y * linesize + x) + off) * 4 + 5] -
-                    odst[((y * linesize + x) + off) * 4 + 1];
+                    odst[((y * linesize + x) + off - z) * 4 + 5] -
+                    odst[((y * linesize + x) + off - z) * 4 + 1];
                 b = odst[(ly * linesize + lx) * 4 + 2] +
-                    odst[((y * linesize + x) + off) * 4 + 6] -
-                    odst[((y * linesize + x) + off) * 4 + 2];
+                    odst[((y * linesize + x) + off - z) * 4 + 6] -
+                    odst[((y * linesize + x) + off - z) * 4 + 2];
                 clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);
                 dst[y * linesize + x] = clr;
                 lx = x;
@@ -436,10 +457,17 @@ static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)
             break;
         case 5:
             while (run-- > 0) {
-                if (y < 1 || y >= avctx->height)
+                if (y < 1 || y >= avctx->height ||
+                    (y == 1 && x == 0))
                     return AVERROR_INVALIDDATA;
 
-                clr = dst[y * linesize + x + off];
+                if (x == 0) {
+                    z = backstep;
+                } else {
+                    z = 0;
+                }
+
+                clr = dst[y * linesize + x + off - z];
                 dst[y * linesize + x] = clr;
                 lx = x;
                 ly = y;