]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/loco.c
avcodec: Constify AVCodecs
[ffmpeg] / libavcodec / loco.c
index 9d0f144451f3c9bbfae68e059bdb6c5b27f84fcb..ebd81f43f27970b1c0ffeccd9d3c3f01de902ec9 100644 (file)
@@ -82,12 +82,14 @@ static inline void loco_update_rice_param(RICEContext *r, int val)
 
 static inline int loco_get_rice(RICEContext *r)
 {
-    int v;
+    unsigned v;
     if (r->run > 0) { /* we have zero run */
         r->run--;
         loco_update_rice_param(r, 0);
         return 0;
     }
+    if (get_bits_left(&r->gb) < 1)
+        return INT_MIN;
     v = get_ur_golomb_jpegls(&r->gb, loco_get_rice_param(r), INT_MAX, 0);
     loco_update_rice_param(r, (v + 1) >> 1);
     if (!v) {
@@ -114,22 +116,22 @@ 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;
+    unsigned val;
     int ret;
     int i, j;
 
@@ -153,17 +155,23 @@ 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;
+        if (val == INT_MIN)
+           return AVERROR_INVALIDDATA;
+        data[i] = data[i - 1] + val;
     }
     data += stride;
     for (j = 1; j < height; j++) {
         /* restore left column */
         val = loco_get_rice(&rc);
+        if (val == INT_MIN)
+           return AVERROR_INVALIDDATA;
         data[0] = data[-stride] + val;
         /* 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;
+            if (val == INT_MIN)
+                return -1;
+            data[i] = loco_predict(&data[i], stride) + val;
         }
         data += stride;
     }
@@ -171,19 +179,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 +216,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);
@@ -293,6 +303,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
         avpriv_request_sample(avctx, "LOCO codec version %i", version);
     }
 
+    if (l->lossy > 65536U) {
+        av_log(avctx, AV_LOG_ERROR, "lossy %i is too large\n", l->lossy);
+        return AVERROR_INVALIDDATA;
+    }
+
     l->mode = AV_RL32(avctx->extradata + 4);
     switch (l->mode) {
     case LOCO_CYUY2:
@@ -302,7 +317,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 +325,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);
@@ -322,7 +337,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-AVCodec ff_loco_decoder = {
+const AVCodec ff_loco_decoder = {
     .name           = "loco",
     .long_name      = NULL_IF_CONFIG_SMALL("LOCO"),
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -331,4 +346,5 @@ AVCodec ff_loco_decoder = {
     .init           = decode_init,
     .decode         = decode_frame,
     .capabilities   = AV_CODEC_CAP_DR1,
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };