[xiph-commits] r16274 - branches/theora-thusnelda/lib/dec

gumboot at svn.xiph.org gumboot at svn.xiph.org
Tue Jul 14 02:04:32 PDT 2009


Author: gumboot
Date: 2009-07-14 02:04:32 -0700 (Tue, 14 Jul 2009)
New Revision: 16274

Modified:
   branches/theora-thusnelda/lib/dec/bitpack.c
   branches/theora-thusnelda/lib/dec/bitpack.h
   branches/theora-thusnelda/lib/dec/decinfo.c
   branches/theora-thusnelda/lib/dec/decint.h
   branches/theora-thusnelda/lib/dec/decode.c
   branches/theora-thusnelda/lib/dec/dequant.c
   branches/theora-thusnelda/lib/dec/dequant.h
   branches/theora-thusnelda/lib/dec/huffdec.c
   branches/theora-thusnelda/lib/dec/huffdec.h
Log:
Rewrite the bit-packing to use a sliding window/cache mechanism and abstract its error checking into separate calls to minimise overheads.


Modified: branches/theora-thusnelda/lib/dec/bitpack.c
===================================================================
--- branches/theora-thusnelda/lib/dec/bitpack.c	2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/bitpack.c	2009-07-14 09:04:32 UTC (rev 16274)
@@ -14,108 +14,98 @@
   last mod: $Id$
 
  ********************************************************************/
-
-/*We're 'MSb' endian; if we write a word but read individual bits,
-   then we'll read the MSb first.*/
-
 #include <string.h>
 #include <stdlib.h>
 #include "bitpack.h"
 
-void theorapackB_readinit(oggpack_buffer *_b,unsigned char *_buf,int _bytes){
+/*We're 'MSb' endian; if we write a word but read individual bits,
+   then we'll read the MSb first.*/
+
+void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes){
   memset(_b,0,sizeof(*_b));
-  _b->buffer=_b->ptr=_buf;
-  _b->storage=_bytes;
+  _b->ptr=_buf;
+  _b->stop=_buf+_bytes;
 }
 
-int theorapackB_look1(oggpack_buffer *_b,long *_ret){
-  if(_b->endbyte>=_b->storage){
-    *_ret=0L;
-    return -1;
+static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){
+  const unsigned char *ptr;
+  const unsigned char *stop;
+  oc_pb_window         window;
+  int                  available;
+  window=_b->window;
+  available=_b->bits;
+  ptr=_b->ptr;
+  stop=_b->stop;
+  while(available<=OC_PB_WINDOW_SIZE-8&&ptr<stop){
+    available+=8;
+    window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available;
   }
-  *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
-  return 0;
+  _b->ptr=ptr;
+  if(_bits>available){
+    if(ptr>=stop){
+      _b->eof=1;
+      available=OC_LOTS_OF_BITS;
+    }
+    else window|=*ptr>>(available&7);
+  }
+  _b->bits=available;
+  return window;
 }
 
-void theorapackB_adv1(oggpack_buffer *_b){
-  if(++(_b->endbit)>7){
-    _b->endbit=0;
-    _b->ptr++;
-    _b->endbyte++;
-  }
+int oc_pack_look1(oc_pack_buf *_b){
+  oc_pb_window window;
+  int          available;
+  window=_b->window;
+  available=_b->bits;
+  if(available<1)_b->window=window=oc_pack_refill(_b,1);
+  return window>>OC_PB_WINDOW_SIZE-1;
 }
 
+void oc_pack_adv1(oc_pack_buf *_b){
+  _b->window<<=1;
+  _b->bits--;
+}
+
 /*Here we assume that 0<=_bits&&_bits<=32.*/
-int theorapackB_read(oggpack_buffer *_b,int _bits,long *_ret){
-  long ret;
-  long m;
-  long d;
-  int fail;
-  m=32-_bits;
-  _bits+=_b->endbit;
-  d=_b->storage-_b->endbyte;
-  if(d<=4){
-    /*Not the main path.*/
-    if(d*8<_bits){
-      *_ret=0L;
-      fail=-1;
-      goto overflow;
-    }
-    /*Special case to avoid reading _b->ptr[0], which might be past the end of
-       the buffer; also skips some useless accounting.*/
-    else if(!_bits){
-      *_ret=0L;
-      return 0;
-    }
+long oc_pack_read(oc_pack_buf *_b,int _bits){
+  oc_pb_window window;
+  int          available;
+  long         result;
+  window=_b->window;
+  available=_b->bits;
+  if(_bits==0)return 0;
+  if(_bits>available){
+    window=oc_pack_refill(_b,_bits);
+    available=_b->bits;
   }
-  ret=_b->ptr[0]<<24+_b->endbit;
-  if(_bits>8){
-    ret|=_b->ptr[1]<<16+_b->endbit;
-    if(_bits>16){
-      ret|=_b->ptr[2]<<8+_b->endbit;
-      if(_bits>24){
-        ret|=_b->ptr[3]<<_b->endbit;
-        if(_bits>32)ret|=_b->ptr[4]>>8-_b->endbit;
-      }
-    }
-  }
-  *_ret=((ret&0xFFFFFFFFUL)>>(m>>1))>>(m+1>>1);
-  fail=0;
-overflow:
-  _b->ptr+=_bits>>3;
-  _b->endbyte+=_bits>>3;
-  _b->endbit=_bits&7;
-  return fail;
+  result=window>>OC_PB_WINDOW_SIZE-_bits;
+  available-=_bits;
+  window<<=1;
+  window<<=_bits-1;
+  _b->bits=available;
+  _b->window=window;
+  return result;
 }
 
-int theorapackB_read1(oggpack_buffer *_b,long *_ret){
-  int fail;
-  if(_b->endbyte>=_b->storage){
-    /*Not the main path.*/
-    *_ret=0L;
-    fail=-1;
+int oc_pack_read1(oc_pack_buf *_b){
+  oc_pb_window window;
+  int          available;
+  int          result;
+  window=_b->window;
+  available=_b->bits;
+  if(available<1){
+    window=oc_pack_refill(_b,1);
+    available=_b->bits;
   }
-  else{
-    *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
-    fail=0;
-  }
-  _b->endbit++;
-  if(_b->endbit>7){
-    _b->endbit=0;
-    _b->ptr++;
-    _b->endbyte++;
-  }
-  return fail;
+  result=window>>OC_PB_WINDOW_SIZE-1;
+  available--;
+  window<<=1;
+  _b->bits=available;
+  _b->window=window;
+  return result;
 }
 
-long theorapackB_bytes(oggpack_buffer *_b){
-  return _b->endbyte+(_b->endbit+7>>3);
+long oc_pack_bytes_left(oc_pack_buf *_b){
+  if(_b->eof)return -1;
+  return _b->stop-_b->ptr+(_b->bits>>3);
 }
-
-long theorapackB_bits(oggpack_buffer *_b){
-  return _b->endbyte*8+_b->endbit;
-}
-
-unsigned char *theorapackB_get_buffer(oggpack_buffer *_b){
-  return _b->buffer;
-}

Modified: branches/theora-thusnelda/lib/dec/bitpack.h
===================================================================
--- branches/theora-thusnelda/lib/dec/bitpack.h	2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/bitpack.h	2009-07-14 09:04:32 UTC (rev 16274)
@@ -16,23 +16,44 @@
  ********************************************************************/
 #if !defined(_bitpack_H)
 # define _bitpack_H (1)
-# include <ogg/ogg.h>
+# include <limits.h>
 
-void theorapackB_readinit(oggpack_buffer *_b,unsigned char *_buf,int _bytes);
-int theorapackB_look1(oggpack_buffer *_b,long *_ret);
-void theorapackB_adv1(oggpack_buffer *_b);
+
+
+typedef unsigned long      oc_pb_window;
+typedef struct oc_pack_buf oc_pack_buf;
+
+
+
+# define OC_PB_WINDOW_SIZE ((int)sizeof(oc_pb_window)*CHAR_BIT)
+/*This is meant to be a large, positive constant that can still be efficiently
+   loaded as an immediate (on platforms like ARM, for example).
+  Even relatively modest values like 100 would work fine.*/
+# define OC_LOTS_OF_BITS (0x40000000)
+
+
+
+struct oc_pack_buf{
+  oc_pb_window         window;
+  const unsigned char *ptr;
+  const unsigned char *stop;
+  int                  bits;
+  int                  eof;
+};
+
+void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes);
+int oc_pack_look1(oc_pack_buf *_b);
+void oc_pack_adv1(oc_pack_buf *_b);
 /*Here we assume 0<=_bits&&_bits<=32.*/
-int theorapackB_read(oggpack_buffer *_b,int _bits,long *_ret);
-int theorapackB_read1(oggpack_buffer *_b,long *_ret);
-long theorapackB_bytes(oggpack_buffer *_b);
-long theorapackB_bits(oggpack_buffer *_b);
-unsigned char *theorapackB_get_buffer(oggpack_buffer *_b);
+long oc_pack_read(oc_pack_buf *_b,int _bits);
+int oc_pack_read1(oc_pack_buf *_b);
+/* returns -1 for read beyond EOF, or the number of whole bytes available */
+long oc_pack_bytes_left(oc_pack_buf *_b);
 
 /*These two functions are implemented locally in huffdec.c*/
 /*Read in bits without advancing the bitptr.
   Here we assume 0<=_bits&&_bits<=32.*/
-/*static int theorapackB_look(oggpack_buffer *_b,int _bits,long *_ret);*/
-/*static void theorapackB_adv(oggpack_buffer *_b,int _bits);*/
+/*static int oc_pack_look(oc_pack_buf *_b,int _bits);*/
+/*static void oc_pack_adv(oc_pack_buf *_b,int _bits);*/
 
-
 #endif

Modified: branches/theora-thusnelda/lib/dec/decinfo.c
===================================================================
--- branches/theora-thusnelda/lib/dec/decinfo.c	2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/decinfo.c	2009-07-14 09:04:32 UTC (rev 16274)
@@ -27,30 +27,30 @@
   _opb: The pack buffer to read the octets from.
   _buf: The byte array to store the unpacked bytes in.
   _len: The number of octets to unpack.*/
-static void oc_unpack_octets(oggpack_buffer *_opb,char *_buf,size_t _len){
+static void oc_unpack_octets(oc_pack_buf *_opb,char *_buf,size_t _len){
   while(_len-->0){
     long val;
-    theorapackB_read(_opb,8,&val);
+    val=oc_pack_read(_opb,8);
     *_buf++=(char)val;
   }
 }
 
 /*Unpacks a 32-bit integer encoded by octets in little-endian form.*/
-static long oc_unpack_length(oggpack_buffer *_opb){
+static long oc_unpack_length(oc_pack_buf *_opb){
   long ret[4];
   int  i;
-  for(i=0;i<4;i++)theorapackB_read(_opb,8,ret+i);
+  for(i=0;i<4;i++)ret[i]=oc_pack_read(_opb,8);
   return ret[0]|ret[1]<<8|ret[2]<<16|ret[3]<<24;
 }
 
-static int oc_info_unpack(oggpack_buffer *_opb,th_info *_info){
+static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){
   long val;
   /*Check the codec bitstream version.*/
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->version_major=(unsigned char)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->version_minor=(unsigned char)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->version_subminor=(unsigned char)val;
   /*verify we can parse this bitstream version.
      We accept earlier minors and all subminors, by spec*/
@@ -60,21 +60,21 @@
     return TH_EVERSION;
   }
   /*Read the encoded frame description.*/
-  theorapackB_read(_opb,16,&val);
+  val=oc_pack_read(_opb,16);
   _info->frame_width=(ogg_uint32_t)val<<4;
-  theorapackB_read(_opb,16,&val);
+  val=oc_pack_read(_opb,16);
   _info->frame_height=(ogg_uint32_t)val<<4;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->pic_width=(ogg_uint32_t)val;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->pic_height=(ogg_uint32_t)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->pic_x=(ogg_uint32_t)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->pic_y=(ogg_uint32_t)val;
-  theorapackB_read(_opb,32,&val);
+  val=oc_pack_read(_opb,32);
   _info->fps_numerator=(ogg_uint32_t)val;
-  theorapackB_read(_opb,32,&val);
+  val=oc_pack_read(_opb,32);
   _info->fps_denominator=(ogg_uint32_t)val;
   if(_info->frame_width==0||_info->frame_height==0||
    _info->pic_width+_info->pic_x>_info->frame_width||
@@ -87,38 +87,39 @@
     This is because the bitstream uses a right-handed coordinate system, while
      applications expect a left-handed one.*/
   _info->pic_y=_info->frame_height-_info->pic_height-_info->pic_y;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->aspect_numerator=(ogg_uint32_t)val;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->aspect_denominator=(ogg_uint32_t)val;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   _info->colorspace=(th_colorspace)val;
-  theorapackB_read(_opb,24,&val);
+  val=oc_pack_read(_opb,24);
   _info->target_bitrate=(int)val;
-  theorapackB_read(_opb,6,&val);
+  val=oc_pack_read(_opb,6);
   _info->quality=(int)val;
-  theorapackB_read(_opb,5,&val);
+  val=oc_pack_read(_opb,5);
   _info->keyframe_granule_shift=(int)val;
-  theorapackB_read(_opb,2,&val);
+  val=oc_pack_read(_opb,2);
   _info->pixel_fmt=(th_pixel_fmt)val;
   if(_info->pixel_fmt==TH_PF_RSVD)return TH_EBADHEADER;
-  if(theorapackB_read(_opb,3,&val)<0||val!=0)return TH_EBADHEADER;
+  val=oc_pack_read(_opb,3);
+  if(val!=0||oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
   return 0;
 }
 
-static int oc_comment_unpack(oggpack_buffer *_opb,th_comment *_tc){
+static int oc_comment_unpack(oc_pack_buf *_opb,th_comment *_tc){
   long len;
   int  i;
   /*Read the vendor string.*/
   len=oc_unpack_length(_opb);
-  if(len<0||len>_opb->storage-theorapackB_bytes(_opb))return TH_EBADHEADER;
+  if(len<0||len>oc_pack_bytes_left(_opb))return TH_EBADHEADER;
   _tc->vendor=_ogg_malloc((size_t)len+1);
   oc_unpack_octets(_opb,_tc->vendor,len);
   _tc->vendor[len]='\0';
   /*Read the user comments.*/
   _tc->comments=(int)oc_unpack_length(_opb);
   len=_tc->comments;
-  if(len<0||len>(LONG_MAX>>2)||len<<2>_opb->storage-theorapackB_bytes(_opb)){
+  if(len<0||len>(LONG_MAX>>2)||len<<2>oc_pack_bytes_left(_opb)){
     _tc->comments=0;
     return TH_EBADHEADER;
   }
@@ -128,7 +129,7 @@
    _tc->comments*sizeof(_tc->user_comments[0]));
   for(i=0;i<_tc->comments;i++){
     len=oc_unpack_length(_opb);
-    if(len<0||len>_opb->storage-theorapackB_bytes(_opb)){
+    if(len<0||len>oc_pack_bytes_left(_opb)){
       _tc->comments=i;
       return TH_EBADHEADER;
     }
@@ -137,10 +138,10 @@
     oc_unpack_octets(_opb,_tc->user_comments[i],len);
     _tc->user_comments[i][len]='\0';
   }
-  return theorapackB_read(_opb,0,&len)<0?TH_EBADHEADER:0;
+  return oc_pack_bytes_left(_opb)<0?TH_EBADHEADER:0;
 }
 
-static int oc_setup_unpack(oggpack_buffer *_opb,th_setup_info *_setup){
+static int oc_setup_unpack(oc_pack_buf *_opb,th_setup_info *_setup){
   int ret;
   /*Read the quantizer tables.*/
   ret=oc_quant_params_unpack(_opb,&_setup->qinfo);
@@ -154,13 +155,13 @@
   oc_huff_trees_clear(_setup->huff_tables);
 }
 
-static int oc_dec_headerin(oggpack_buffer *_opb,th_info *_info,
+static int oc_dec_headerin(oc_pack_buf *_opb,th_info *_info,
  th_comment *_tc,th_setup_info **_setup,ogg_packet *_op){
   char buffer[6];
   long val;
   int  packtype;
   int  ret;
-  theorapackB_read(_opb,8,&val);
+  val=oc_pack_read(_opb,8);
   packtype=(int)val;
   /*If we're at a data packet and we have received all three headers, we're
      done.*/
@@ -224,10 +225,10 @@
    stream until it returns 0.*/
 int th_decode_headerin(th_info *_info,th_comment *_tc,
  th_setup_info **_setup,ogg_packet *_op){
-  oggpack_buffer opb;
+  oc_pack_buf opb;
   if(_op==NULL)return TH_EBADHEADER;
   if(_info==NULL)return TH_EFAULT;
-  theorapackB_readinit(&opb,_op->packet,_op->bytes);
+  oc_pack_readinit(&opb,_op->packet,_op->bytes);
   return oc_dec_headerin(&opb,_info,_tc,_setup,_op);
 }
 

Modified: branches/theora-thusnelda/lib/dec/decint.h
===================================================================
--- branches/theora-thusnelda/lib/dec/decint.h	2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/decint.h	2009-07-14 09:04:32 UTC (rev 16274)
@@ -53,7 +53,7 @@
      when a frame has been processed and a data packet is ready.*/
   int                  packet_state;
   /*Buffer in which to assemble packets.*/
-  oggpack_buffer       opb;
+  oc_pack_buf          opb;
   /*Huffman decode trees.*/
   oc_huff_node        *huff_tables[TH_NHUFFMAN_TABLES];
   /*The index of the first token in each plane for each coefficient.*/

Modified: branches/theora-thusnelda/lib/dec/decode.c
===================================================================
--- branches/theora-thusnelda/lib/dec/decode.c	2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/decode.c	2009-07-14 09:04:32 UTC (rev 16274)
@@ -93,7 +93,7 @@
 };
 
 
-static int oc_sb_run_unpack(oggpack_buffer *_opb){
+static int oc_sb_run_unpack(oc_pack_buf *_opb){
   long bits;
   int ret;
   /*Coding scheme:
@@ -105,30 +105,30 @@
      11110xxx                10-17
      111110xxxx              18-33
      111111xxxxxxxxxxxx      34-4129*/
-  theorapackB_read1(_opb,&bits);
+  bits=oc_pack_read1(_opb);
   if(bits==0)return 1;
-  theorapackB_read(_opb,2,&bits);
+  bits=oc_pack_read(_opb,2);
   if((bits&2)==0)return 2+(int)bits;
   else if((bits&1)==0){
-    theorapackB_read1(_opb,&bits);
+    bits=oc_pack_read1(_opb);
     return 4+(int)bits;
   }
-  theorapackB_read(_opb,3,&bits);
+  bits=oc_pack_read(_opb,3);
   if((bits&4)==0)return 6+(int)bits;
   else if((bits&2)==0){
     ret=10+((bits&1)<<2);
-    theorapackB_read(_opb,2,&bits);
+    bits=oc_pack_read(_opb,2);
     return ret+(int)bits;
   }
   else if((bits&1)==0){
-    theorapackB_read(_opb,4,&bits);
+    bits=oc_pack_read(_opb,4);
     return 18+(int)bits;
   }
-  theorapackB_read(_opb,12,&bits);
+  bits=oc_pack_read(_opb,12);
   return 34+(int)bits;
 }
 
-static int oc_block_run_unpack(oggpack_buffer *_opb){
+static int oc_block_run_unpack(oc_pack_buf *_opb){
   long bits;
   long bits2;
   /*Coding scheme:
@@ -139,21 +139,21 @@
      1110xx                  7-10
      11110xx                 11-14
      11111xxxx               15-30*/
-  theorapackB_read(_opb,2,&bits);
+  bits=oc_pack_read(_opb,2);
   if((bits&2)==0)return 1+(int)bits;
   else if((bits&1)==0){
-    theorapackB_read1(_opb,&bits);
+    bits=oc_pack_read1(_opb);
     return 3+(int)bits;
   }
-  theorapackB_read(_opb,2,&bits);
+  bits=oc_pack_read(_opb,2);
   if((bits&2)==0)return 5+(int)bits;
   else if((bits&1)==0){
-    theorapackB_read(_opb,2,&bits);
+    bits=oc_pack_read(_opb,2);
     return 7+(int)bits;
   }
-  theorapackB_read(_opb,3,&bits);
+  bits=oc_pack_read(_opb,3);
   if((bits&4)==0)return 11+bits;
-  theorapackB_read(_opb,2,&bits2);
+  bits2=oc_pack_read(_opb,2);
   return 15+((bits&3)<<2)+bits2;
 }
 
@@ -224,23 +224,23 @@
 static int oc_dec_frame_header_unpack(oc_dec_ctx *_dec){
   long val;
   /*Check to make sure this is a data packet.*/
-  theorapackB_read1(&_dec->opb,&val);
+  val=oc_pack_read1(&_dec->opb);
   if(val!=0)return TH_EBADPACKET;
   /*Read in the frame type (I or P).*/
-  theorapackB_read1(&_dec->opb,&val);
+  val=oc_pack_read1(&_dec->opb);
   _dec->state.frame_type=(int)val;
   /*Read in the qi list.*/
-  theorapackB_read(&_dec->opb,6,&val);
+  val=oc_pack_read(&_dec->opb,6);
   _dec->state.qis[0]=(unsigned char)val;
-  theorapackB_read1(&_dec->opb,&val);
+  val=oc_pack_read1(&_dec->opb);
   if(!val)_dec->state.nqis=1;
   else{
-    theorapackB_read(&_dec->opb,6,&val);
+    val=oc_pack_read(&_dec->opb,6);
     _dec->state.qis[1]=(unsigned char)val;
-    theorapackB_read1(&_dec->opb,&val);
+    val=oc_pack_read1(&_dec->opb);
     if(!val)_dec->state.nqis=2;
     else{
-      theorapackB_read(&_dec->opb,6,&val);
+      val=oc_pack_read(&_dec->opb,6);
       _dec->state.qis[2]=(unsigned char)val;
       _dec->state.nqis=3;
     }
@@ -251,7 +251,7 @@
       I don't know why these remain.*/
     /*I wanted to eliminate wasted bits, but not all config wiggle room
        --Monty.*/
-    theorapackB_read(&_dec->opb,3,&val);
+    val=oc_pack_read(&_dec->opb,3);
     if(val!=0)return TH_EIMPL;
   }
   return 0;
@@ -311,7 +311,7 @@
   unsigned     run_count;
   long         val;
   int          flag;
-  theorapackB_read1(&_dec->opb,&val);
+  val=oc_pack_read1(&_dec->opb);
   flag=(int)val;
   sb_flags=_dec->state.sb_flags;
   nsbs=_dec->state.nsbs;
@@ -328,7 +328,7 @@
     }
     while(--run_count>0&&sbi<nsbs);
     if(full_run&&sbi<nsbs){
-      theorapackB_read1(&_dec->opb,&val);
+      val=oc_pack_read1(&_dec->opb);
       flag=(int)val;
     }
     else flag=!flag;
@@ -354,7 +354,7 @@
   nsbs=_dec->state.nsbs;
   /*Skip partially coded super blocks.*/
   for(sbi=0;sb_flags[sbi].coded_partially;sbi++);
-  theorapackB_read1(&_dec->opb,&val);
+  val=oc_pack_read1(&_dec->opb);
   flag=(int)val;
   do{
     int full_run;
@@ -366,7 +366,7 @@
       sb_flags[sbi].coded_fully=flag;
     }
     if(full_run&&sbi<nsbs){
-      theorapackB_read1(&_dec->opb,&val);
+      val=oc_pack_read1(&_dec->opb);
       flag=(int)val;
     }
     else flag=!flag;
@@ -395,7 +395,7 @@
   npartial=oc_dec_partial_sb_flags_unpack(_dec);
   if(npartial<_dec->state.nsbs)oc_dec_coded_sb_flags_unpack(_dec);
   if(npartial>0){
-    theorapackB_read1(&_dec->opb,&val);
+    val=oc_pack_read1(&_dec->opb);
     flag=!(int)val;
   }
   else flag=0;
@@ -443,21 +443,21 @@
 
 
 
-typedef int (*oc_mode_unpack_func)(oggpack_buffer *_opb);
+typedef int (*oc_mode_unpack_func)(oc_pack_buf *_opb);
 
-static int oc_vlc_mode_unpack(oggpack_buffer *_opb){
+static int oc_vlc_mode_unpack(oc_pack_buf *_opb){
   long val;
   int  i;
   for(i=0;i<7;i++){
-    theorapackB_read1(_opb,&val);
+    val=oc_pack_read1(_opb);
     if(!val)break;
   }
   return i;
 }
 
-static int oc_clc_mode_unpack(oggpack_buffer *_opb){
+static int oc_clc_mode_unpack(oc_pack_buf *_opb){
   long val;
-  theorapackB_read(_opb,3,&val);
+  val=oc_pack_read(_opb,3);
   return (int)val;
 }
 
@@ -473,7 +473,7 @@
   size_t               mbi;
   long                 val;
   int                  mode_scheme;
-  theorapackB_read(&_dec->opb,3,&val);
+  val=oc_pack_read(&_dec->opb,3);
   mode_scheme=(int)val;
   if(mode_scheme==0){
     int mi;
@@ -484,7 +484,7 @@
     /*LOOP VECTORIZES*/
     for(mi=0;mi<OC_NMODES;mi++)scheme0_alphabet[mi]=OC_MODE_INTER_NOMV;
     for(mi=0;mi<OC_NMODES;mi++){
-      theorapackB_read(&_dec->opb,3,&val);
+      val=oc_pack_read(&_dec->opb,3);
       scheme0_alphabet[val]=OC_MODE_ALPHABETS[6][mi];
     }
     alphabet=scheme0_alphabet;
@@ -511,13 +511,13 @@
 
 
 
-typedef int (*oc_mv_comp_unpack_func)(oggpack_buffer *_opb);
+typedef int (*oc_mv_comp_unpack_func)(oc_pack_buf *_opb);
 
-static int oc_vlc_mv_comp_unpack(oggpack_buffer *_opb){
+static int oc_vlc_mv_comp_unpack(oc_pack_buf *_opb){
   long bits;
   int  mask;
   int  mv;
-  theorapackB_read(_opb,3,&bits);
+  bits=oc_pack_read(_opb,3);
   switch(bits){
     case  0:return 0;
     case  1:return 1;
@@ -525,14 +525,14 @@
     case  3:
     case  4:{
       mv=(int)(bits-1);
-      theorapackB_read1(_opb,&bits);
+      bits=oc_pack_read1(_opb);
     }break;
     /*case  5:
     case  6:
     case  7:*/
     default:{
       mv=1<<bits-3;
-      theorapackB_read(_opb,bits-2,&bits);
+      bits=oc_pack_read(_opb,bits-2);
       mv+=(int)(bits>>1);
       bits&=1;
     }break;
@@ -541,11 +541,11 @@
   return mv+mask^mask;
 }
 
-static int oc_clc_mv_comp_unpack(oggpack_buffer *_opb){
+static int oc_clc_mv_comp_unpack(oc_pack_buf *_opb){
   long bits;
   int  mask;
   int  mv;
-  theorapackB_read(_opb,6,&bits);
+  bits=oc_pack_read(_opb,6);
   mv=(int)bits>>1;
   mask=-((int)bits&1);
   return mv+mask^mask;
@@ -568,7 +568,7 @@
   size_t                  mbi;
   long                    val;
   set_chroma_mvs=OC_SET_CHROMA_MVS_TABLE[_dec->state.info.pixel_fmt];
-  theorapackB_read1(&_dec->opb,&val);
+  val=oc_pack_read1(&_dec->opb);
   mv_comp_unpack=val?oc_clc_mv_comp_unpack:oc_vlc_mv_comp_unpack;
   map_idxs=OC_MB_MAP_IDXS[_dec->state.info.pixel_fmt];
   map_nidxs=OC_MB_MAP_NIDXS[_dec->state.info.pixel_fmt];
@@ -691,7 +691,7 @@
      At first we just store the qii in the fragment.
      After all the qii's are decoded, we make a final pass to replace them
       with the corresponding qi's for this frame.*/
-    theorapackB_read1(&_dec->opb,&val);
+    val=oc_pack_read1(&_dec->opb);
     flag=(int)val;
     run_count=nqi1=0;
     fragii=0;
@@ -705,7 +705,7 @@
       }
       while(--run_count>0&&fragii<ncoded_fragis);
       if(full_run&&fragii<ncoded_fragis){
-        theorapackB_read1(&_dec->opb,&val);
+        val=oc_pack_read1(&_dec->opb);
         flag=(int)val;
       }
       else flag=!flag;
@@ -717,7 +717,7 @@
     if(_dec->state.nqis==3&&nqi1>0){
       /*Skip qii==0 fragments.*/
       for(fragii=0;frags[coded_fragis[fragii]].qii==0;fragii++);
-      theorapackB_read1(&_dec->opb,&val);
+      val=oc_pack_read1(&_dec->opb);
       flag=(int)val;
       do{
         int full_run;
@@ -730,7 +730,7 @@
           frags[fragi].qii+=flag;
         }
         if(full_run&&fragii<ncoded_fragis){
-          theorapackB_read1(&_dec->opb,&val);
+          val=oc_pack_read1(&_dec->opb);
           flag=(int)val;
         }
         else flag=!flag;
@@ -897,7 +897,7 @@
       neb=OC_DCT_TOKEN_EXTRA_BITS[token];
       if(neb){
         long val;
-        theorapackB_read(&_dec->opb,neb,&val);
+        val=oc_pack_read(&_dec->opb,neb);
         eb=(int)val;
         extra_bits[ebi++]=(ogg_uint16_t)eb;
       }
@@ -976,7 +976,7 @@
       neb=OC_DCT_TOKEN_EXTRA_BITS[token];
       if(neb){
         long val;
-        theorapackB_read(&_dec->opb,neb,&val);
+        val=oc_pack_read(&_dec->opb,neb);
         eb=(int)val;
         extra_bits[ebi++]=(ogg_uint16_t)eb;
       }
@@ -1041,15 +1041,15 @@
   for(pli=0;pli<3;pli++)for(zzi=0;zzi<64;zzi++){
     ntoks_left[pli][zzi]=_dec->state.ncoded_fragis[pli];
   }
-  theorapackB_read(&_dec->opb,4,&val);
+  val=oc_pack_read(&_dec->opb,4);
   huff_idxs[0]=(int)val;
-  theorapackB_read(&_dec->opb,4,&val);
+  val=oc_pack_read(&_dec->opb,4);
   huff_idxs[1]=(int)val;
   _dec->eob_runs[0][0]=0;
   eobs=oc_dec_dc_coeff_unpack(_dec,huff_idxs,ntoks_left);
-  theorapackB_read(&_dec->opb,4,&val);
+  val=oc_pack_read(&_dec->opb,4);
   huff_idxs[0]=(int)val;
-  theorapackB_read(&_dec->opb,4,&val);
+  val=oc_pack_read(&_dec->opb,4);
   huff_idxs[1]=(int)val;
   zzi=1;
   for(hgi=1;hgi<5;hgi++){
@@ -1954,7 +1954,7 @@
     int                   pli;
     int                   notstart;
     int                   notdone;
-    theorapackB_readinit(&_dec->opb,_op->packet,_op->bytes);
+    oc_pack_readinit(&_dec->opb,_op->packet,_op->bytes);
     ret=oc_dec_frame_header_unpack(_dec);
     if(ret<0)return ret;
     /*Select a free buffer to use for the reconstructed version of this

Modified: branches/theora-thusnelda/lib/dec/dequant.c
===================================================================
--- branches/theora-thusnelda/lib/dec/dequant.c	2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/dequant.c	2009-07-14 09:04:32 UTC (rev 16274)
@@ -21,7 +21,7 @@
 #include "dequant.h"
 #include "decint.h"
 
-int oc_quant_params_unpack(oggpack_buffer *_opb,th_quant_info *_qinfo){
+int oc_quant_params_unpack(oc_pack_buf *_opb,th_quant_info *_qinfo){
   th_quant_base *base_mats;
   long           val;
   int            nbase_mats;
@@ -35,30 +35,30 @@
   int            qri;
   int            qi;
   int            i;
-  theorapackB_read(_opb,3,&val);
+  val=oc_pack_read(_opb,3);
   nbits=(int)val;
   for(qi=0;qi<64;qi++){
-    theorapackB_read(_opb,nbits,&val);
+    val=oc_pack_read(_opb,nbits);
     _qinfo->loop_filter_limits[qi]=(unsigned char)val;
   }
-  theorapackB_read(_opb,4,&val);
+  val=oc_pack_read(_opb,4);
   nbits=(int)val+1;
   for(qi=0;qi<64;qi++){
-    theorapackB_read(_opb,nbits,&val);
+    val=oc_pack_read(_opb,nbits);
     _qinfo->ac_scale[qi]=(ogg_uint16_t)val;
   }
-  theorapackB_read(_opb,4,&val);
+  val=oc_pack_read(_opb,4);
   nbits=(int)val+1;
   for(qi=0;qi<64;qi++){
-    theorapackB_read(_opb,nbits,&val);
+    val=oc_pack_read(_opb,nbits);
     _qinfo->dc_scale[qi]=(ogg_uint16_t)val;
   }
-  theorapackB_read(_opb,9,&val);
+  val=oc_pack_read(_opb,9);
   nbase_mats=(int)val+1;
   base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0]));
   for(bmi=0;bmi<nbase_mats;bmi++){
     for(ci=0;ci<64;ci++){
-      theorapackB_read(_opb,8,&val);
+      val=oc_pack_read(_opb,8);
       base_mats[bmi][ci]=(unsigned char)val;
     }
   }
@@ -71,12 +71,12 @@
     pli=i%3;
     qranges=_qinfo->qi_ranges[qti]+pli;
     if(i>0){
-      theorapackB_read1(_opb,&val);
+      val=oc_pack_read1(_opb);
       if(!val){
         int qtj;
         int plj;
         if(qti>0){
-          theorapackB_read1(_opb,&val);
+          val=oc_pack_read1(_opb);
           if(val){
             qtj=qti-1;
             plj=pli;
@@ -94,13 +94,13 @@
         continue;
       }
     }
-    theorapackB_read(_opb,nbits,&val);
+    val=oc_pack_read(_opb,nbits);
     indices[0]=(int)val;
     for(qi=qri=0;qi<63;){
-      theorapackB_read(_opb,oc_ilog(62-qi),&val);
+      val=oc_pack_read(_opb,oc_ilog(62-qi));
       sizes[qri]=(int)val+1;
       qi+=(int)val+1;
-      theorapackB_read(_opb,nbits,&val);
+      val=oc_pack_read(_opb,nbits);
       indices[++qri]=(int)val;
     }
     /*Note: The caller is responsible for cleaning up any partially

Modified: branches/theora-thusnelda/lib/dec/dequant.h
===================================================================
--- branches/theora-thusnelda/lib/dec/dequant.h	2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/dequant.h	2009-07-14 09:04:32 UTC (rev 16274)
@@ -18,8 +18,9 @@
 #if !defined(_dequant_H)
 # define _dequant_H (1)
 # include "quant.h"
+# include "bitpack.h"
 
-int oc_quant_params_unpack(oggpack_buffer *_opb,
+int oc_quant_params_unpack(oc_pack_buf *_opb,
  th_quant_info *_qinfo);
 void oc_quant_params_clear(th_quant_info *_qinfo);
 

Modified: branches/theora-thusnelda/lib/dec/huffdec.c
===================================================================
--- branches/theora-thusnelda/lib/dec/huffdec.c	2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/huffdec.c	2009-07-14 09:04:32 UTC (rev 16274)
@@ -25,52 +25,64 @@
 #define _ogg_offsetof(_type,_field)\
  ((size_t)((char *)&((_type *)0)->_field-(char *)0))
 
-/*These two functions are really part of the bitpack.c module, but
-  they are only used here. Declaring local static versions so they
-  can be inlined saves considerable function call overhead.*/
+/*These three functions are really part of the bitpack.c module, but
+   they are only used here.
+  Declaring local static versions so they can be inlined saves considerable
+   function call overhead.*/
 
-/*Read in bits without advancing the bitptr.
-  Here we assume 0<=_bits&&_bits<=32.*/
-static int theorapackB_look(oggpack_buffer *_b,int _bits,long *_ret){
-  long ret;
-  long m;
-  long d;
-  m=32-_bits;
-  _bits+=_b->endbit;
-  d=_b->storage-_b->endbyte;
-  if(d<=4){
-    /*Not the main path.*/
-    if(d<=0){
-      *_ret=0L;
-      return -(_bits>d*8);
-    }
-    /*If we have some bits left, but not enough, return the ones we have.*/
-    if(d*8<_bits)_bits=d*8;
+static oc_pb_window inline oc_pack_refill(oc_pack_buf *_b,int _bits){
+  const unsigned char *ptr;
+  const unsigned char *stop;
+  oc_pb_window         window;
+  int                  available;
+  window=_b->window;
+  available=_b->bits;
+  ptr=_b->ptr;
+  stop=_b->stop;
+  /*This version of _refill() doesn't bother setting eof because we won't
+     check for it after we've started decoding DCT tokens.*/
+  if(ptr>=stop)available=OC_LOTS_OF_BITS;
+  while(available<=OC_PB_WINDOW_SIZE-8){
+    available+=8;
+    window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available;
+    if(ptr>=stop)available=OC_LOTS_OF_BITS;
   }
-  ret=_b->ptr[0]<<24+_b->endbit;
-  if(_bits>8){
-    ret|=_b->ptr[1]<<16+_b->endbit;
-    if(_bits>16){
-      ret|=_b->ptr[2]<<8+_b->endbit;
-      if(_bits>24){
-        ret|=_b->ptr[3]<<_b->endbit;
-        if(_bits>32)ret|=_b->ptr[4]>>8-_b->endbit;
-      }
-    }
-  }
-  *_ret=((ret&0xFFFFFFFF)>>(m>>1))>>(m+1>>1);
-  return 0;
+  _b->ptr=ptr;
+  if(_bits>available)window|=*ptr>>(available&7);
+  _b->bits=available;
+  return window;
 }
 
-/*advance the bitptr*/
-static void theorapackB_adv(oggpack_buffer *_b,int _bits){
-  _bits+=_b->endbit;
-  _b->ptr+=_bits>>3;
-  _b->endbyte+=_bits>>3;
-  _b->endbit=_bits&7;
+
+/*Read in bits without advancing the bit pointer.
+  Here we assume 0<=_bits&&_bits<=32.*/
+static long oc_pack_look(oc_pack_buf *_b,int _bits){
+  oc_pb_window window;
+  int          available;
+  long         result;
+  window=_b->window;
+  available=_b->bits;
+  if(_bits==0)return 0;
+  if(_bits>available)_b->window=window=oc_pack_refill(_b,_bits);
+  result=window>>OC_PB_WINDOW_SIZE-_bits;
+  return result;
 }
 
+/*Advance the bit pointer.*/
+static void oc_pack_adv(oc_pack_buf *_b,int _bits){
+  oc_pb_window window;
+  window=_b->window;
+  /*We ignore the special cases for _bits==0 and _bits==32 here, since they are
+     never used actually used.
+    OC_HUFF_SLUSH (defined below) would have to be at least 27 to actually read
+     32 bits in a single go, and would require a 32 GB lookup table (assuming
+     8 byte pointers, since 4 byte pointers couldn't fit such a table).*/
+  window<<=_bits;
+  _b->window=window;
+  _b->bits-=_bits;
+}
 
+
 /*The log_2 of the size of a lookup table is allowed to grow to relative to
    the number of unique nodes it contains.
   E.g., if OC_HUFF_SLUSH is 2, then at most 75% of the space in the tree is
@@ -135,7 +147,7 @@
   _binodes:  The nodes to store the sub-tree in.
   _nbinodes: The number of nodes available for the sub-tree.
   Return: 0 on success, or a negative value on error.*/
-static int oc_huff_tree_unpack(oggpack_buffer *_opb,
+static int oc_huff_tree_unpack(oc_pack_buf *_opb,
  oc_huff_node *_binodes,int _nbinodes){
   oc_huff_node *binode;
   long          bits;
@@ -143,7 +155,8 @@
   if(_nbinodes<1)return TH_EBADHEADER;
   binode=_binodes;
   nused=1;
-  if(theorapackB_read1(_opb,&bits)<0)return TH_EBADHEADER;
+  bits=oc_pack_read1(_opb);
+  if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
   /*Read an internal node:*/
   if(!bits){
     int ret;
@@ -161,7 +174,8 @@
   }
   /*Read a leaf node:*/
   else{
-    if(theorapackB_read(_opb,OC_NDCT_TOKEN_BITS,&bits)<0)return TH_EBADHEADER;
+    bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS);
+    if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
     binode->nbits=0;
     binode->depth=1;
     binode->token=(unsigned char)bits;
@@ -283,7 +297,7 @@
   _opb:   The buffer to unpack the trees from.
   _nodes: The table to fill with the Huffman trees.
   Return: 0 on success, or a negative value on error.*/
-int oc_huff_trees_unpack(oggpack_buffer *_opb,
+int oc_huff_trees_unpack(oc_pack_buf *_opb,
  oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){
   int i;
   for(i=0;i<TH_NHUFFMAN_TABLES;i++){
@@ -317,12 +331,12 @@
   _opb:  The buffer to unpack the token from.
   _node: The tree to unpack the token with.
   Return: The token value.*/
-int oc_huff_token_decode(oggpack_buffer *_opb,const oc_huff_node *_node){
+int oc_huff_token_decode(oc_pack_buf *_opb,const oc_huff_node *_node){
   long bits;
   while(_node->nbits!=0){
-    theorapackB_look(_opb,_node->nbits,&bits);
+    bits=oc_pack_look(_opb,_node->nbits);
     _node=_node->nodes[bits];
-    theorapackB_adv(_opb,_node->depth);
+    oc_pack_adv(_opb,_node->depth);
   }
   return _node->token;
 }

Modified: branches/theora-thusnelda/lib/dec/huffdec.h
===================================================================
--- branches/theora-thusnelda/lib/dec/huffdec.h	2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/huffdec.h	2009-07-14 09:04:32 UTC (rev 16274)
@@ -18,6 +18,7 @@
 #if !defined(_huffdec_H)
 # define _huffdec_H (1)
 # include "huffman.h"
+# include "bitpack.h"
 
 
 
@@ -80,12 +81,12 @@
 
 
 
-int oc_huff_trees_unpack(oggpack_buffer *_opb,
+int oc_huff_trees_unpack(oc_pack_buf *_opb,
  oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]);
 void oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES],
  const oc_huff_node *const _src[TH_NHUFFMAN_TABLES]);
 void oc_huff_trees_clear(oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]);
-int oc_huff_token_decode(oggpack_buffer *_opb,const oc_huff_node *_node);
+int oc_huff_token_decode(oc_pack_buf *_opb,const oc_huff_node *_node);
 
 
 #endif



More information about the commits mailing list