Home | History | Annotate | Download | only in decoder
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef VP8_DECODER_DBOOLHUFF_H_
     12 #define VP8_DECODER_DBOOLHUFF_H_
     13 
     14 #include <stddef.h>
     15 #include <limits.h>
     16 
     17 #include "./vpx_config.h"
     18 #include "vpx_ports/mem.h"
     19 #include "vpx/vp8dx.h"
     20 #include "vpx/vpx_integer.h"
     21 
     22 #ifdef __cplusplus
     23 extern "C" {
     24 #endif
     25 
     26 typedef size_t VP8_BD_VALUE;
     27 
     28 #define VP8_BD_VALUE_SIZE ((int)sizeof(VP8_BD_VALUE) * CHAR_BIT)
     29 
     30 /*This is meant to be a large, positive constant that can still be efficiently
     31    loaded as an immediate (on platforms like ARM, for example).
     32   Even relatively modest values like 100 would work fine.*/
     33 #define VP8_LOTS_OF_BITS (0x40000000)
     34 
     35 typedef struct {
     36   const unsigned char *user_buffer_end;
     37   const unsigned char *user_buffer;
     38   VP8_BD_VALUE value;
     39   int count;
     40   unsigned int range;
     41   vpx_decrypt_cb decrypt_cb;
     42   void *decrypt_state;
     43 } BOOL_DECODER;
     44 
     45 DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]);
     46 
     47 int vp8dx_start_decode(BOOL_DECODER *br, const unsigned char *source,
     48                        unsigned int source_sz, vpx_decrypt_cb decrypt_cb,
     49                        void *decrypt_state);
     50 
     51 void vp8dx_bool_decoder_fill(BOOL_DECODER *br);
     52 
     53 static int vp8dx_decode_bool(BOOL_DECODER *br, int probability) {
     54   unsigned int bit = 0;
     55   VP8_BD_VALUE value;
     56   unsigned int split;
     57   VP8_BD_VALUE bigsplit;
     58   int count;
     59   unsigned int range;
     60 
     61   split = 1 + (((br->range - 1) * probability) >> 8);
     62 
     63   if (br->count < 0) vp8dx_bool_decoder_fill(br);
     64 
     65   value = br->value;
     66   count = br->count;
     67 
     68   bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8);
     69 
     70   range = split;
     71 
     72   if (value >= bigsplit) {
     73     range = br->range - split;
     74     value = value - bigsplit;
     75     bit = 1;
     76   }
     77 
     78   {
     79     register int shift = vp8_norm[range];
     80     range <<= shift;
     81     value <<= shift;
     82     count -= shift;
     83   }
     84   br->value = value;
     85   br->count = count;
     86   br->range = range;
     87 
     88   return bit;
     89 }
     90 
     91 static INLINE int vp8_decode_value(BOOL_DECODER *br, int bits) {
     92   int z = 0;
     93   int bit;
     94 
     95   for (bit = bits - 1; bit >= 0; bit--) {
     96     z |= (vp8dx_decode_bool(br, 0x80) << bit);
     97   }
     98 
     99   return z;
    100 }
    101 
    102 static INLINE int vp8dx_bool_error(BOOL_DECODER *br) {
    103   /* Check if we have reached the end of the buffer.
    104    *
    105    * Variable 'count' stores the number of bits in the 'value' buffer, minus
    106    * 8. The top byte is part of the algorithm, and the remainder is buffered
    107    * to be shifted into it. So if count == 8, the top 16 bits of 'value' are
    108    * occupied, 8 for the algorithm and 8 in the buffer.
    109    *
    110    * When reading a byte from the user's buffer, count is filled with 8 and
    111    * one byte is filled into the value buffer. When we reach the end of the
    112    * data, count is additionally filled with VP8_LOTS_OF_BITS. So when
    113    * count == VP8_LOTS_OF_BITS - 1, the user's data has been exhausted.
    114    */
    115   if ((br->count > VP8_BD_VALUE_SIZE) && (br->count < VP8_LOTS_OF_BITS)) {
    116     /* We have tried to decode bits after the end of
    117      * stream was encountered.
    118      */
    119     return 1;
    120   }
    121 
    122   /* No error. */
    123   return 0;
    124 }
    125 
    126 #ifdef __cplusplus
    127 }  // extern "C"
    128 #endif
    129 
    130 #endif  // VP8_DECODER_DBOOLHUFF_H_
    131