]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/loco.c
avcodec/gdv: Check for truncated tags in decompress_5()
[ffmpeg] / libavcodec / loco.c
index 9d0f144451f3c9bbfae68e059bdb6c5b27f84fcb..741db3bdcece517cb6b0216a32f3d7e4b5f1aac0 100644 (file)
@@ -114,19 +114,19 @@ static inline int loco_get_rice(RICEContext *r)
 }
 
 /* LOCO main predictor - LOCO-I/JPEG-LS predictor */
-static inline int loco_predict(uint8_t* data, int stride, int step)
+static inline int loco_predict(uint8_t* data, int stride)
 {
     int a, b, c;
 
     a = data[-stride];
-    b = data[-step];
-    c = data[-stride - step];
+    b = data[-1];
+    c = data[-stride - 1];
 
     return mid_pred(a, a + b - c, b);
 }
 
 static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int height,
-                             int stride, const uint8_t *buf, int buf_size, int step)
+                             int stride, const uint8_t *buf, int buf_size)
 {
     RICEContext rc;
     int val;
@@ -153,7 +153,7 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh
     /* restore top line */
     for (i = 1; i < width; i++) {
         val = loco_get_rice(&rc);
-        data[i * step] = data[i * step - step] + val;
+        data[i] = data[i - 1] + val;
     }
     data += stride;
     for (j = 1; j < height; j++) {
@@ -163,7 +163,7 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh
         /* restore all other pixels */
         for (i = 1; i < width; i++) {
             val = loco_get_rice(&rc);
-            data[i * step] = loco_predict(&data[i * step], stride, step) + val;
+            data[i] = loco_predict(&data[i], stride) + val;
         }
         data += stride;
     }
@@ -171,19 +171,18 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh
     return (get_bits_count(&rc.gb) + 7) >> 3;
 }
 
-static void rotate_faulty_loco(uint8_t *data, int width, int height, int stride, int step)
+static void rotate_faulty_loco(uint8_t *data, int width, int height, int stride)
 {
     int y;
 
     for (y=1; y<height; y++) {
         if (width>=y) {
             memmove(data + y*stride,
-                    data + y*(stride + step),
-                    step*(width-y));
+                    data + y*(stride + 1),
+                    (width-y));
             if (y+1 < height)
-                memmove(data + y*stride + step*(width-y),
-                        data + (y+1)*stride,
-                        step*y);
+                memmove(data + y*stride + (width-y),
+                        data + (y+1)*stride, y);
         }
     }
 }
@@ -209,49 +208,52 @@ static int decode_frame(AVCodecContext *avctx,
     switch(l->mode) {
     case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY:
         decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height,
-                                    p->linesize[0], buf, buf_size, 1);
+                                    p->linesize[0], buf, buf_size);
         ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height,
-                                    p->linesize[1], buf, buf_size, 1);
+                                    p->linesize[1], buf, buf_size);
         ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height,
-                                    p->linesize[2], buf, buf_size, 1);
+                                    p->linesize[2], buf, buf_size);
         break;
     case LOCO_CYV12: case LOCO_YV12:
         decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height,
-                                    p->linesize[0], buf, buf_size, 1);
+                                    p->linesize[0], buf, buf_size);
         ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height / 2,
-                                    p->linesize[2], buf, buf_size, 1);
+                                    p->linesize[2], buf, buf_size);
         ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height / 2,
-                                    p->linesize[1], buf, buf_size, 1);
+                                    p->linesize[1], buf, buf_size);
         break;
     case LOCO_CRGB: case LOCO_RGB:
-        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height,
-                                    -p->linesize[0], buf, buf_size, 3);
+        decoded = loco_decode_plane(l, p->data[1] + p->linesize[1]*(avctx->height-1), avctx->width, avctx->height,
+                                    -p->linesize[1], buf, buf_size);
         ADVANCE_BY_DECODED;
-        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height,
-                                    -p->linesize[0], buf, buf_size, 3);
+        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height,
+                                    -p->linesize[0], buf, buf_size);
         ADVANCE_BY_DECODED;
-        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height,
-                                    -p->linesize[0], buf, buf_size, 3);
-        if (avctx->width & 1)
-            rotate_faulty_loco(p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[0], 3);
+        decoded = loco_decode_plane(l, p->data[2] + p->linesize[2]*(avctx->height-1), avctx->width, avctx->height,
+                                    -p->linesize[2], buf, buf_size);
+        if (avctx->width & 1) {
+            rotate_faulty_loco(p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[0]);
+            rotate_faulty_loco(p->data[1] + p->linesize[1]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[1]);
+            rotate_faulty_loco(p->data[2] + p->linesize[2]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[2]);
+        }
         break;
     case LOCO_CRGBA:
     case LOCO_RGBA:
-        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height,
-                                    -p->linesize[0], buf, buf_size, 4);
+        decoded = loco_decode_plane(l, p->data[1] + p->linesize[1]*(avctx->height-1), avctx->width, avctx->height,
+                                    -p->linesize[1], buf, buf_size);
         ADVANCE_BY_DECODED;
-        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height,
-                                    -p->linesize[0], buf, buf_size, 4);
+        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height,
+                                    -p->linesize[0], buf, buf_size);
         ADVANCE_BY_DECODED;
-        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height,
-                                    -p->linesize[0], buf, buf_size, 4);
+        decoded = loco_decode_plane(l, p->data[2] + p->linesize[2]*(avctx->height-1), avctx->width, avctx->height,
+                                    -p->linesize[2], buf, buf_size);
         ADVANCE_BY_DECODED;
-        decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 3, avctx->width, avctx->height,
-                                    -p->linesize[0], buf, buf_size, 4);
+        decoded = loco_decode_plane(l, p->data[3] + p->linesize[3]*(avctx->height-1), avctx->width, avctx->height,
+                                    -p->linesize[3], buf, buf_size);
         break;
     default:
         av_assert0(0);
@@ -302,7 +304,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
         break;
     case LOCO_CRGB:
     case LOCO_RGB:
-        avctx->pix_fmt = AV_PIX_FMT_BGR24;
+        avctx->pix_fmt = AV_PIX_FMT_GBRP;
         break;
     case LOCO_CYV12:
     case LOCO_YV12:
@@ -310,7 +312,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
         break;
     case LOCO_CRGBA:
     case LOCO_RGBA:
-        avctx->pix_fmt = AV_PIX_FMT_BGRA;
+        avctx->pix_fmt = AV_PIX_FMT_GBRAP;
         break;
     default:
         av_log(avctx, AV_LOG_INFO, "Unknown colorspace, index = %i\n", l->mode);