]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/huffyuvdec.c
flac/x86: add ff_flac_lpc_32_sse4()
[ffmpeg] / libavcodec / huffyuvdec.c
index ced22f620a11c548b5e528f4503a65a692146175..7a1579f681932e50ce56a407039d819d45fdc23c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * huffyuv decoder
  *
- * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2002-2014 Michael Niedermayer <michaelni@gmx.at>
  *
  * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
  * the algorithm used
@@ -120,19 +120,23 @@ static int generate_joint_tables(HYuvContext *s)
         int p, i, y, u;
         for (p = 0; p < 4; p++) {
             int p0 = s->version > 2 ? p : 0;
-            for (i = y = 0; y < s->n; y++) {
+            for (i = y = 0; y < s->vlc_n; y++) {
                 int len0 = s->len[p0][y];
                 int limit = VLC_BITS - len0;
                 if(limit <= 0 || !len0)
                     continue;
-                for (u = 0; u < s->n; u++) {
+                if((sign_extend(y, 8) & (s->vlc_n-1)) != y)
+                    continue;
+                for (u = 0; u < s->vlc_n; u++) {
                     int len1 = s->len[p][u];
                     if (len1 > limit || !len1)
                         continue;
+                    if((sign_extend(u, 8) & (s->vlc_n-1)) != u)
+                        continue;
                     av_assert0(i < (1 << VLC_BITS));
                     len[i] = len0 + len1;
                     bits[i] = (s->bits[p0][y] << len1) + s->bits[p][u];
-                    symbols[i] = (y << 8) + u; //FIXME
+                    symbols[i] = (y << 8) + (u & 0xFF);
                     if(symbols[i] != 0xffff) // reserved to mean "invalid"
                         i++;
                 }
@@ -201,13 +205,13 @@ static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length)
         count = 1 + s->alpha + 2*s->chroma;
 
     for (i = 0; i < count; i++) {
-        if (read_len_table(s->len[i], &gb, s->n) < 0)
+        if (read_len_table(s->len[i], &gb, s->vlc_n) < 0)
             return -1;
-        if (ff_huffyuv_generate_bits_table(s->bits[i], s->len[i], s->n) < 0) {
+        if (ff_huffyuv_generate_bits_table(s->bits[i], s->len[i], s->vlc_n) < 0) {
             return -1;
         }
         ff_free_vlc(&s->vlc[i]);
-        if ((ret = init_vlc(&s->vlc[i], VLC_BITS, s->n, s->len[i], 1, 1,
+        if ((ret = init_vlc(&s->vlc[i], VLC_BITS, s->vlc_n, s->len[i], 1, 1,
                            s->bits[i], 4, 4, 0)) < 0)
             return ret;
     }
@@ -261,7 +265,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 {
     HYuvContext *s = avctx->priv_data;
 
-    ff_huffyuv_common_init(avctx);
     memset(s->vlc, 0, 4 * sizeof(VLC));
 
     s->interlaced = s->height > 288;
@@ -281,6 +284,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     s->bps = 8;
     s->n = 1<<s->bps;
+    s->vlc_n = FFMIN(s->n, MAX_VLC_N);
     s->chroma = 1;
     if (s->version >= 2) {
         int method, interlace;
@@ -298,6 +302,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
         } else {
             s->bps = (avctx->extradata[1] >> 4) + 1;
             s->n = 1<<s->bps;
+            s->vlc_n = FFMIN(s->n, MAX_VLC_N);
             s->chroma_h_shift = avctx->extradata[1] & 3;
             s->chroma_v_shift = (avctx->extradata[1] >> 2) & 3;
             s->yuv   = !!(((uint8_t*)avctx->extradata)[2] & 1);
@@ -375,12 +380,30 @@ static av_cold int decode_init(AVCodecContext *avctx)
         case 0x070:
             avctx->pix_fmt = AV_PIX_FMT_GRAY8;
             break;
+        case 0x0F0:
+            avctx->pix_fmt = AV_PIX_FMT_GRAY16;
+            break;
         case 0x170:
             avctx->pix_fmt = AV_PIX_FMT_GRAY8A;
             break;
         case 0x470:
             avctx->pix_fmt = AV_PIX_FMT_GBRP;
             break;
+        case 0x480:
+            avctx->pix_fmt = AV_PIX_FMT_GBRP9;
+            break;
+        case 0x490:
+            avctx->pix_fmt = AV_PIX_FMT_GBRP10;
+            break;
+        case 0x4B0:
+            avctx->pix_fmt = AV_PIX_FMT_GBRP12;
+            break;
+        case 0x4D0:
+            avctx->pix_fmt = AV_PIX_FMT_GBRP14;
+            break;
+        case 0x4F0:
+            avctx->pix_fmt = AV_PIX_FMT_GBRP16;
+            break;
         case 0x570:
             avctx->pix_fmt = AV_PIX_FMT_GBRAP;
             break;
@@ -399,6 +422,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
         case 0x6D0:
             avctx->pix_fmt = AV_PIX_FMT_YUV444P14;
             break;
+        case 0x6F0:
+            avctx->pix_fmt = AV_PIX_FMT_YUV444P16;
+            break;
         case 0x671:
             avctx->pix_fmt = AV_PIX_FMT_YUV422P;
             break;
@@ -414,6 +440,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
         case 0x6D1:
             avctx->pix_fmt = AV_PIX_FMT_YUV422P14;
             break;
+        case 0x6F1:
+            avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
+            break;
         case 0x672:
             avctx->pix_fmt = AV_PIX_FMT_YUV411P;
             break;
@@ -435,6 +464,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
         case 0x6D5:
             avctx->pix_fmt = AV_PIX_FMT_YUV420P14;
             break;
+        case 0x6F5:
+            avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
+            break;
         case 0x67A:
             avctx->pix_fmt = AV_PIX_FMT_YUV410P;
             break;
@@ -447,6 +479,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
         case 0x790:
             avctx->pix_fmt = AV_PIX_FMT_YUVA444P10;
             break;
+        case 0x7F0:
+            avctx->pix_fmt = AV_PIX_FMT_YUVA444P16;
+            break;
         case 0x771:
             avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
             break;
@@ -456,6 +491,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
         case 0x791:
             avctx->pix_fmt = AV_PIX_FMT_YUVA422P10;
             break;
+        case 0x7F1:
+            avctx->pix_fmt = AV_PIX_FMT_YUVA422P16;
+            break;
         case 0x775:
             avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
             break;
@@ -465,11 +503,15 @@ static av_cold int decode_init(AVCodecContext *avctx)
         case 0x795:
             avctx->pix_fmt = AV_PIX_FMT_YUVA420P10;
             break;
+        case 0x7F5:
+            avctx->pix_fmt = AV_PIX_FMT_YUVA420P16;
+            break;
         default:
             return AVERROR_INVALIDDATA;
         }
     }
 
+    ff_huffyuv_common_init(avctx);
 
     if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P || avctx->pix_fmt == AV_PIX_FMT_YUV420P) && avctx->width & 1) {
         av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n");
@@ -557,9 +599,22 @@ static void decode_422_bitstream(HYuvContext *s, int count)
         dst1 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3);\
     }\
 }
+#define READ_2PIX_PLANE14(dst0, dst1, plane){\
+    int16_t code = get_vlc2(&s->gb, s->vlc[4+plane].table, VLC_BITS, 1);\
+    if(code != (int16_t)0xffff){\
+        dst0 = code>>8;\
+        dst1 = sign_extend(code, 8);\
+    }else{\
+        dst0 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3);\
+        dst1 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3);\
+    }\
+}
+
 #define READ_2PIX_PLANE16(dst0, dst1, plane){\
-    dst0 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3);\
-    dst1 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3);\
+    dst0 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3)<<2;\
+    dst0 += get_bits(&s->gb, 2);\
+    dst1 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3)<<2;\
+    dst1 += get_bits(&s->gb, 2);\
 }
 static void decode_plane_bitstream(HYuvContext *s, int count, int plane)
 {
@@ -577,6 +632,16 @@ static void decode_plane_bitstream(HYuvContext *s, int count, int plane)
                 READ_2PIX_PLANE(s->temp[0][2 * i], s->temp[0][2 * i + 1], plane);
             }
         }
+    } else if (s->bps <= 14) {
+        if (count >= (get_bits_left(&s->gb)) / (31 * 2)) {
+            for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {
+                READ_2PIX_PLANE14(s->temp16[0][2 * i], s->temp16[0][2 * i + 1], plane);
+            }
+        } else {
+            for(i=0; i<count; i++){
+                READ_2PIX_PLANE14(s->temp16[0][2 * i], s->temp16[0][2 * i + 1], plane);
+            }
+        }
     } else {
         if (count >= (get_bits_left(&s->gb)) / (31 * 2)) {
             for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {
@@ -680,26 +745,7 @@ static int left_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, int
     if (s->bps <= 8) {
         return s->dsp.add_hfyu_left_prediction(dst, src, w, acc);
     } else {
-        //FIXME optimize
-        unsigned mask = s->n-1;
-        int i;
-        const uint16_t *src16 = (const uint16_t *)src;
-        uint16_t       *dst16 = (      uint16_t *)dst;
-
-        for(i=0; i<w-1; i++){
-            acc+= src16[i];
-            dst16[i]= acc & mask;
-            i++;
-            acc+= src16[i];
-            dst16[i]= acc & mask;
-        }
-
-        for(; i<w; i++){
-            acc+= src16[i];
-            dst16[i]= acc & mask;
-        }
-
-        return acc;
+        return s->llviddsp.add_hfyu_left_prediction_int16((      uint16_t *)dst, (const uint16_t *)src, s->n-1, w, acc);
     }
 }
 
@@ -708,20 +754,7 @@ static void add_bytes(HYuvContext *s, uint8_t *dst, uint8_t *src, int w)
     if (s->bps <= 8) {
         s->dsp.add_bytes(dst, src, w);
     } else {
-        //FIXME optimize
-        const uint16_t *src16 = (const uint16_t *)src;
-        uint16_t       *dst16 = (      uint16_t *)dst;
-        long i;
-        unsigned long msb = 0x1000100010001ULL << (s->bps-1);
-        unsigned long lsb = msb - 0x1000100010001ULL;
-        unsigned long mask = lsb + msb;
-        for (i = 0; i <= w - (int)sizeof(long)/2; i += sizeof(long)/2) {
-            long a = *(long*)(src16+i);
-            long b = *(long*)(dst16+i);
-            *(long*)(dst16+i) = ((a&lsb) + (b&lsb)) ^ ((a^b)&msb);
-        }
-        for(; i<w; i++)
-            dst16[i] = (dst16[i] + src16[i]) & mask;
+        s->llviddsp.add_int16((uint16_t*)dst, (const uint16_t*)src, s->n - 1, w);
     }
 }
 
@@ -730,25 +763,7 @@ static void add_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *s
     if (s->bps <= 8) {
         s->dsp.add_hfyu_median_prediction(dst, src, diff, w, left, left_top);
     } else {
-        //FIXME optimize
-        unsigned mask = s->n-1;
-        int i;
-        uint16_t l, lt;
-        const uint16_t *src16  = (const uint16_t *)src;
-        const uint16_t *diff16 = (const uint16_t *)diff;
-        uint16_t       *dst16  = (      uint16_t *)dst;
-
-        l  = *left;
-        lt = *left_top;
-
-        for(i=0; i<w; i++){
-            l  = (mid_pred(l, src16[i], (l + src16[i] - lt) & mask) + diff16[i]) & mask;
-            lt = src16[i];
-            dst16[i] = l;
-        }
-
-        *left     = l;
-        *left_top = lt;
+        s->llviddsp.add_hfyu_median_prediction_int16((uint16_t *)dst, (const uint16_t *)src, (const uint16_t *)diff, s->n-1, w, left, left_top);
     }
 }
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,