]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/bitstream.c
R and B components are stored as a differences to G component in Fraps v5.
[ffmpeg] / libavcodec / bitstream.c
index 35f775437df8e791589a6dd941fa3cc224604dc2..57f139138eb4c3ffdbdeafd288de9b562d522c5e 100644 (file)
@@ -3,6 +3,8 @@
  * Copyright (c) 2000, 2001 Fabrice Bellard.
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
+ * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
+ *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -18,8 +20,6 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
  */
 
 /**
 #include "avcodec.h"
 #include "bitstream.h"
 
+const uint8_t ff_log2_run[32]={
+ 0, 0, 0, 0, 1, 1, 1, 1,
+ 2, 2, 2, 2, 3, 3, 3, 3,
+ 4, 4, 5, 5, 6, 6, 7, 7,
+ 8, 9,10,11,12,13,14,15
+};
+
 /**
  * Same as av_mallocz_static(), but does a realloc.
  *
  * @param[in] ptr The block of memory to reallocate.
  * @param[in] size The requested size.
  * @return Block of memory of requested size.
+ * @deprecated. Code which uses ff_realloc_static is broken/misdesigned
+ * and should correctly use static arrays
  */
-void *ff_realloc_static(void *ptr, unsigned int size);
+attribute_deprecated av_alloc_size(2)
+static void *ff_realloc_static(void *ptr, unsigned int size);
+
+static void *ff_realloc_static(void *ptr, unsigned int size)
+{
+    return av_realloc(ptr, size);
+}
 
 void align_put_bits(PutBitContext *s)
 {
@@ -48,7 +63,7 @@ void align_put_bits(PutBitContext *s)
 #endif
 }
 
-void ff_put_string(PutBitContext * pbc, char *s, int put_zero)
+void ff_put_string(PutBitContext * pbc, const char *s, int put_zero)
 {
     while(*s){
         put_bits(pbc, 8, *s);
@@ -58,6 +73,28 @@ void ff_put_string(PutBitContext * pbc, char *s, int put_zero)
         put_bits(pbc, 8, 0);
 }
 
+void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
+{
+    const uint16_t *srcw= (const uint16_t*)src;
+    int words= length>>4;
+    int bits= length&15;
+    int i;
+
+    if(length==0) return;
+
+    if(ENABLE_SMALL || words < 16 || put_bits_count(pb)&7){
+        for(i=0; i<words; i++) put_bits(pb, 16, be2me_16(srcw[i]));
+    }else{
+        for(i=0; put_bits_count(pb)&31; i++)
+            put_bits(pb, 8, src[i]);
+        flush_put_bits(pb);
+        memcpy(pbBufPtr(pb), src+i, 2*words-i);
+        skip_put_bytes(pb, 2*words-i);
+    }
+
+    put_bits(pb, bits, be2me_16(srcw[words])>>(16-bits));
+}
+
 /* VLC decoding */
 
 //#define DEBUG_VLC
@@ -85,6 +122,8 @@ static int alloc_table(VLC *vlc, int size, int use_static)
     index = vlc->table_size;
     vlc->table_size += size;
     if (vlc->table_size > vlc->table_allocated) {
+        if(use_static>1)
+            abort(); //cant do anything, init_vlc() is used with too little memory
         vlc->table_allocated += (1 << vlc->bits);
         if(use_static)
             vlc->table = ff_realloc_static(vlc->table,
@@ -102,16 +141,17 @@ static int build_table(VLC *vlc, int table_nb_bits,
                        int nb_codes,
                        const void *bits, int bits_wrap, int bits_size,
                        const void *codes, int codes_wrap, int codes_size,
+                       const void *symbols, int symbols_wrap, int symbols_size,
                        uint32_t code_prefix, int n_prefix, int flags)
 {
-    int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2;
+    int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2, symbol;
     uint32_t code;
     VLC_TYPE (*table)[2];
 
     table_size = 1 << table_nb_bits;
-    table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_STATIC);
+    table_index = alloc_table(vlc, table_size, flags & (INIT_VLC_USE_STATIC|INIT_VLC_USE_NEW_STATIC));
 #ifdef DEBUG_VLC
-    printf("new table index=%d size=%d code_prefix=%x n=%d\n",
+    av_log(NULL,AV_LOG_DEBUG,"new table index=%d size=%d code_prefix=%x n=%d\n",
            table_index, table_size, code_prefix, n_prefix);
 #endif
     if (table_index < 0)
@@ -130,8 +170,12 @@ static int build_table(VLC *vlc, int table_nb_bits,
         /* we accept tables with holes */
         if (n <= 0)
             continue;
+        if (!symbols)
+            symbol = i;
+        else
+            GET_DATA(symbol, symbols, i, symbols_wrap, symbols_size);
 #if defined(DEBUG_VLC) && 0
-        printf("i=%d n=%d code=0x%x\n", i, n, code);
+        av_log(NULL,AV_LOG_DEBUG,"i=%d n=%d code=0x%x\n", i, n, code);
 #endif
         /* if code matches the prefix, it is in the table */
         n -= n_prefix;
@@ -156,14 +200,14 @@ static int build_table(VLC *vlc, int table_nb_bits,
                         return -1;
                     }
                     table[j][1] = n; //bits
-                    table[j][0] = i; //code
+                    table[j][0] = symbol;
                     j++;
                 }
             } else {
                 n -= table_nb_bits;
                 j = (code >> ((flags & INIT_VLC_LE) ? n_prefix : n)) & ((1 << table_nb_bits) - 1);
 #ifdef DEBUG_VLC
-                printf("%4x: n=%d (subtable)\n",
+                av_log(NULL,AV_LOG_DEBUG,"%4x: n=%d (subtable)\n",
                        j, n);
 #endif
                 /* compute table size */
@@ -187,6 +231,7 @@ static int build_table(VLC *vlc, int table_nb_bits,
             index = build_table(vlc, n, nb_codes,
                                 bits, bits_wrap, bits_size,
                                 codes, codes_wrap, codes_size,
+                                symbols, symbols_wrap, symbols_size,
                                 (flags & INIT_VLC_LE) ? (code_prefix | (i << n_prefix)) : ((code_prefix << table_nb_bits) | i),
                                 n_prefix + table_nb_bits, flags);
             if (index < 0)
@@ -212,6 +257,8 @@ static int build_table(VLC *vlc, int table_nb_bits,
 
    'codes' : table which gives the bit pattern of of each vlc code.
 
+   'symbols' : table which gives the values to be returned from get_vlc().
+
    'xxx_wrap' : give the number of bytes between each entry of the
    'bits' or 'codes' tables.
 
@@ -219,18 +266,25 @@ static int build_table(VLC *vlc, int table_nb_bits,
    or 'codes' tables.
 
    'wrap' and 'size' allows to use any memory configuration and types
-   (byte/word/long) to store the 'bits' and 'codes' tables.
+   (byte/word/long) to store the 'bits', 'codes', and 'symbols' tables.
 
    'use_static' should be set to 1 for tables, which should be freed
    with av_free_static(), 0 if free_vlc() will be used.
 */
-int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
+int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
              const void *bits, int bits_wrap, int bits_size,
              const void *codes, int codes_wrap, int codes_size,
-             int use_static)
+             const void *symbols, int symbols_wrap, int symbols_size,
+             int flags)
 {
     vlc->bits = nb_bits;
-    if(!use_static) {
+    if(flags & INIT_VLC_USE_NEW_STATIC){
+        if(vlc->table_size && vlc->table_size == vlc->table_allocated){
+            return 0;
+        }else if(vlc->table_size){
+            abort(); // fatal error, we are called on a partially initialized table
+        }
+    }else if(!(flags & INIT_VLC_USE_STATIC)) {
         vlc->table = NULL;
         vlc->table_allocated = 0;
         vlc->table_size = 0;
@@ -242,22 +296,25 @@ int init_vlc(VLC *vlc, int nb_bits, int nb_codes,
     }
 
 #ifdef DEBUG_VLC
-    printf("build table nb_codes=%d\n", nb_codes);
+    av_log(NULL,AV_LOG_DEBUG,"build table nb_codes=%d\n", nb_codes);
 #endif
 
     if (build_table(vlc, nb_bits, nb_codes,
                     bits, bits_wrap, bits_size,
                     codes, codes_wrap, codes_size,
-                    0, 0, use_static) < 0) {
-        av_free(vlc->table);
+                    symbols, symbols_wrap, symbols_size,
+                    0, 0, flags) < 0) {
+        av_freep(&vlc->table);
         return -1;
     }
+    if((flags & INIT_VLC_USE_NEW_STATIC) && vlc->table_size != vlc->table_allocated)
+        av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
     return 0;
 }
 
 
 void free_vlc(VLC *vlc)
 {
-    av_free(vlc->table);
+    av_freep(&vlc->table);
 }