text: /**
   * @file bitstream.h
   * bitstream api header.
   */
  
  #ifndef BITSTREAM_H
  #define BITSTREAM_H
  
  #include <inttypes.h>
  
  #define BUILD_STANDALONE
  
  #ifndef BUILD_STANDALONE
    #include <config.h>
    #include <system.h>
  #else
    #include <stdio.h>
    #define IBSS_ATTR
    #define ICONST_ATTR
    #define ICODE_ATTR
  #endif
  
  #ifndef ICODE_ATTR_FLAC
  #define ICODE_ATTR_FLAC ICODE_ATTR
  #endif
  
  #ifndef IBSS_ATTR_FLAC_DECODED0
  #define IBSS_ATTR_FLAC_DECODED0 IBSS_ATTR
  #endif
  
  /* Endian conversion routines for standalone compilation */
  #ifdef BUILD_STANDALONE
      #ifdef BUILD_BIGENDIAN
          #define betoh32(x) (x)
          #define letoh32(x) swap32(x)
      #else
          #define letoh32(x) (x)
          #define betoh32(x) swap32(x)
      #endif
  
      /* Taken from rockbox/firmware/export/system.h */
  
      static inline unsigned short swap16(unsigned short value)
          /*
            result[15..8] = value[ 7..0];
            result[ 7..0] = value[15..8];
          */
      {
          return (value >> 8) | (value << 8);
      }
  
      static inline unsigned long swap32(unsigned long value)
          /*
            result[31..24] = value[ 7.. 0];
            result[23..16] = value[15.. 8];
            result[15.. 8] = value[23..16];
            result[ 7.. 0] = value[31..24];
          */
      {
          unsigned long hi = swap16(value >> 16);
          unsigned long lo = swap16(value & 0xffff);
          return (lo << 16) | hi;
      }
  #endif
  
  /* FLAC files are big-endian */
  #define ALT_BITSTREAM_READER_BE
   
  #define NEG_SSR32(a,s) (((int32_t)(a))>>(32-(s)))
  #define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
  
  /* bit input */
  /* buffer, buffer_end and size_in_bits must be present and used by every reader */
  typedef struct GetBitContext {
      const uint8_t *buffer, *buffer_end;
      int index;
      int size_in_bits;
  } GetBitContext;
  
  #define VLC_TYPE int16_t
  
  typedef struct VLC {
      int bits;
      VLC_TYPE (*table)[2]; ///< code, bits
      int table_size, table_allocated;
  } VLC;
  
  typedef struct RL_VLC_ELEM {
      int16_t level;
      int8_t len;
      uint8_t run;
  } RL_VLC_ELEM;
  
  #if defined(ARCH_SPARC) || defined(ARCH_ARMV4L)
  #define UNALIGNED_STORES_ARE_BAD
  #endif
  
  /* used to avoid missaligned exceptions on some archs (alpha, ...) */
  #if defined(ARCH_X86) || defined(ARCH_X86_64)
  #    define unaligned32(a) (*(const uint32_t*)(a))
  #else
  #    ifdef __GNUC__
  static inline uint32_t unaligned32(const void *v) {
      struct Unaligned {
  	uint32_t i;
      } __attribute__((packed));
  
      return ((const struct Unaligned *) v)->i;
  }
  #    elif defined(__DECC)
  static inline uint32_t unaligned32(const void *v) {
      return *(const __unaligned uint32_t *) v;
  }
  #    else
  static inline uint32_t unaligned32(const void *v) {
      return *(const uint32_t *) v;
  }
  #    endif
  #endif //!ARCH_X86
  
  
  /* Bitstream reader API docs:
  name
      abritary name which is used as prefix for the internal variables
  
  gb
      getbitcontext
  
  OPEN_READER(name, gb)
      loads gb into local variables
  
  CLOSE_READER(name, gb)
      stores local vars in gb
  
  UPDATE_CACHE(name, gb)
      refills the internal cache from the bitstream
      after this call at least MIN_CACHE_BITS will be available,
  
  GET_CACHE(name, gb)
      will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit)
  
  SHOW_UBITS(name, gb, num)
      will return the next num bits
  
  SHOW_SBITS(name, gb, num)
      will return the next num bits and do sign extension
  
  SKIP_BITS(name, gb, num)
      will skip over the next num bits
      note, this is equivalent to SKIP_CACHE; SKIP_COUNTER
  
  SKIP_CACHE(name, gb, num)
      will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER)
  
  SKIP_COUNTER(name, gb, num)
      will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
  
  LAST_SKIP_CACHE(name, gb, num)
      will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing
  
  LAST_SKIP_BITS(name, gb, num)
      is equivalent to SKIP_LAST_CACHE; SKIP_COUNTER
  
  for examples see get_bits, show_bits, skip_bits, get_vlc
  */
  
  static inline int unaligned32_be(const void *v)
  {
  #ifdef CONFIG_ALIGN
  	const uint8_t *p=v;
  	return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]);
  #else
  	return betoh32( unaligned32(v)); //original
  #endif
  }
  
  static inline int unaligned32_le(const void *v)
  {
  #ifdef CONFIG_ALIGN
         const uint8_t *p=v;
         return (((p[3]<<8) | p[2])<<16) | (p[1]<<8) | (p[0]);
  #else
         return letoh32( unaligned32(v)); //original
  #endif
  }
  
  #   define MIN_CACHE_BITS 25
  
  #   define OPEN_READER(name, gb)\
          int name##_index= (gb)->index;\
          int name##_cache= 0;\
  
  #   define CLOSE_READER(name, gb)\
          (gb)->index= name##_index;\
  
  # ifdef ALT_BITSTREAM_READER_LE
  #   define UPDATE_CACHE(name, gb)\
          name##_cache= unaligned32_le( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) >> (name##_index&0x07);\
  
  #   define SKIP_CACHE(name, gb, num)\
          name##_cache >>= (num);
  # else
  #   define UPDATE_CACHE(name, gb)\
          name##_cache= unaligned32_be( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\
  
  #   define SKIP_CACHE(name, gb, num)\
          name##_cache <<= (num);
  # endif
  
  // FIXME name?
  #   define SKIP_COUNTER(name, gb, num)\
          name##_index += (num);\
  
  #   define SKIP_BITS(name, gb, num)\
          {\
              SKIP_CACHE(name, gb, num)\
              SKIP_COUNTER(name, gb, num)\
          }\
  
  #   define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
  #   define LAST_SKIP_CACHE(name, gb, num) ;
  
  # ifdef ALT_BITSTREAM_READER_LE
  #   define SHOW_UBITS(name, gb, num)\
          ((name##_cache) & (NEG_USR32(0xffffffff,num)))
  # else
  #   define SHOW_UBITS(name, gb, num)\
          NEG_USR32(name##_cache, num)
  # endif
  
  #   define SHOW_SBITS(name, gb, num)\
          NEG_SSR32(name##_cache, num)
  
  #   define GET_CACHE(name, gb)\
          ((uint32_t)name##_cache)
  
  static inline int get_bits_count(GetBitContext *s){
      return s->index;
  }
  
  static inline int get_sbits(GetBitContext *s, int n){
      register int tmp;
      OPEN_READER(re, s)
      UPDATE_CACHE(re, s)
      tmp= SHOW_SBITS(re, s, n);
      LAST_SKIP_BITS(re, s, n)
      CLOSE_READER(re, s)
      return tmp;
  }
  
  /**
   * reads 0-17 bits.
   * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't
   */
  static inline unsigned int get_bits(GetBitContext *s, int n){
      register int tmp;
      OPEN_READER(re, s)
      UPDATE_CACHE(re, s)
      tmp= SHOW_UBITS(re, s, n);
      LAST_SKIP_BITS(re, s, n)
      CLOSE_READER(re, s)
      return tmp;
  }
  
  unsigned int get_bits_long(GetBitContext *s, int n) ICODE_ATTR_FLAC;
  
  /**
   * shows 0-17 bits.
   * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't
   */
  static inline unsigned int show_bits(GetBitContext *s, int n){
      register int tmp;
      OPEN_READER(re, s)
      UPDATE_CACHE(re, s)
      tmp= SHOW_UBITS(re, s, n);
  //    CLOSE_READER(re, s)
      return tmp;
  }
  
  unsigned int show_bits_long(GetBitContext *s, int n) ICODE_ATTR_FLAC;
  
  static inline void skip_bits(GetBitContext *s, int n){
   //Note gcc seems to optimize this to s->index+=n for the ALT_READER :))
      OPEN_READER(re, s)
      UPDATE_CACHE(re, s)
      LAST_SKIP_BITS(re, s, n)
      CLOSE_READER(re, s)
  }
  
  static inline unsigned int get_bits1(GetBitContext *s){
      int index= s->index;
      uint8_t result= s->buffer[ index>>3 ];
  #ifdef ALT_BITSTREAM_READER_LE
      result>>= (index&0x07);
      result&= 1;
  #else
      result<<= (index&0x07);
      result>>= 8 - 1;
  #endif
      index++;
      s->index= index;
  
      return result;
  }
  
  static inline unsigned int show_bits1(GetBitContext *s){
      return show_bits(s, 1);
  }
  
  static inline void skip_bits1(GetBitContext *s){
      skip_bits(s, 1);
  }
  
  /**
   * init GetBitContext.
   * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits
   * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end
   * @param bit_size the size of the buffer in bits
   */
  static inline void init_get_bits(GetBitContext *s,
                     const uint8_t *buffer, int bit_size)
  {
      int buffer_size= (bit_size+7)>>3;
      if(buffer_size < 0 || bit_size < 0) {
          buffer_size = bit_size = 0;
          buffer = 0;
      }
  
      s->buffer= buffer;
      s->size_in_bits= bit_size;
      s->buffer_end= buffer + buffer_size;
      s->index=0;
      {
          OPEN_READER(re, s)
          UPDATE_CACHE(re, s)
          UPDATE_CACHE(re, s)
          CLOSE_READER(re, s)
      }
  }
  
  void align_get_bits(GetBitContext *s) ICODE_ATTR_FLAC;
  
  #endif /* BITSTREAM_H */
  