- Main Page
- Related Pages
- Data Structures
- Files
- Examples

- File List

# /home/v/Kate/WORK_TREES/kate-sorceress-backup/v/src/kate/src/kate_bitwise.c

    00001 /********************************************************************
    00002  * This file was modified from the libogg distribution for          *
    00003  * inclusion into libkate                                           *
    00004  ********************************************************************/
    00005
    00006 /********************************************************************
    00007  *                                                                  *
    00008  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
    00009  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
    00010  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
    00011  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
    00012  *                                                                  *
    00013  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
    00014  * by the Xiph.Org Foundation http://www.xiph.org/                  *
    00015  *                                                                  *
    00016  ********************************************************************
    00017
    00018   function: packing variable sized words into an octet stream
    00019   last mod: $Id: kate_bitwise.c,v 1.3 2008/08/05 20:14:21 lyrian Exp $
    00020
    00021  ********************************************************************/
    00022
    00023 /* We're 'LSb' endian; if we write a word but read individual bits,
    00024    then we'll read the lsb first */
    00025
    00026 #define KATE_INTERNAL
    00027 #include "kate_internal.h"
    00028
    00029 #ifdef HAVE_STRING_H
    00030 #include <string.h>
    00031 #endif
    00032 #ifdef HAVE_STDLIB_H
    00033 #include <stdlib.h>
    00034 #endif
    00035 #include "kate_bitwise.h"
    00036
    00037 #define BUFFER_INCREMENT 256
    00038
    00039 static const unsigned long mask[]=
    00040 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
    00041  0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
    00042  0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
    00043  0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
    00044  0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
    00045  0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
    00046  0x3fffffff,0x7fffffff,0xffffffff };
    00047
    00048 void kate_pack_writeinit(kate_pack_buffer *b){
    00049   memset(b,0,sizeof(*b));
    00050   b->ptr=b->buffer=kate_malloc(BUFFER_INCREMENT);
    00051   b->buffer[0]='\0';
    00052   b->storage=BUFFER_INCREMENT;
    00053 }
    00054
    00055 void kate_pack_writetrunc(kate_pack_buffer *b,long bits){
    00056   long bytes=bits>>3;
    00057   bits-=bytes*8;
    00058   b->ptr=b->buffer+bytes;
    00059   b->endbit=bits;
    00060   b->endbyte=bytes;
    00061   *b->ptr&=mask[bits];
    00062 }
    00063
    00064 /* Takes only up to 32 bits. */
    00065 void kate_pack_write(kate_pack_buffer *b,unsigned long value,int bits){
    00066   if(b->endbyte+4>=b->storage){
    00067     b->buffer=kate_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
    00068     b->storage+=BUFFER_INCREMENT;
    00069     b->ptr=b->buffer+b->endbyte;
    00070   }
    00071
    00072   value&=mask[bits];
    00073   bits+=b->endbit;
    00074
    00075   b->ptr[0]|=value<<b->endbit;
    00076
    00077   if(bits>=8){
    00078     b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
    00079     if(bits>=16){
    00080       b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
    00081       if(bits>=24){
    00082         b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
    00083         if(bits>=32){
    00084           if(b->endbit)
    00085             b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
    00086           else
    00087             b->ptr[4]=0;
    00088         }
    00089       }
    00090     }
    00091   }
    00092
    00093   b->endbyte+=bits/8;
    00094   b->ptr+=bits/8;
    00095   b->endbit=bits&7;
    00096 }
    00097
    00098 void kate_pack_writealign(kate_pack_buffer *b){
    00099   int bits=8-b->endbit;
    00100   if(bits<8)
    00101     kate_pack_write(b,0,bits);
    00102 }
    00103
    00104 static void kate_pack_writecopy_helper(kate_pack_buffer *b,
    00105                                      void *source,
    00106                                      long bits,
    00107                                      void (*w)(kate_pack_buffer *,
    00108                                                unsigned long,
    00109                                                int),
    00110                                      int msb){
    00111   unsigned char *ptr=(unsigned char *)source;
    00112
    00113   long bytes=bits/8;
    00114   bits-=bytes*8;
    00115
    00116   if(b->endbit){
    00117     int i;
    00118     /* unaligned copy.  Do it the hard way. */
    00119     for(i=0;i<bytes;i++)
    00120       w(b,(unsigned long)(ptr[i]),8);
    00121   }else{
    00122     /* aligned block copy */
    00123     if(b->endbyte+bytes+1>=b->storage){
    00124       b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
    00125       b->buffer=kate_realloc(b->buffer,b->storage);
    00126       b->ptr=b->buffer+b->endbyte;
    00127     }
    00128
    00129     memmove(b->ptr,source,bytes);
    00130     b->ptr+=bytes;
    00131     b->endbyte+=bytes;
    00132     *b->ptr=0;
    00133
    00134   }
    00135   if(bits){
    00136     if(msb)
    00137       w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
    00138     else
    00139       w(b,(unsigned long)(ptr[bytes]),bits);
    00140   }
    00141 }
    00142
    00143 void kate_pack_writecopy(kate_pack_buffer *b,void *source,long bits){
    00144   kate_pack_writecopy_helper(b,source,bits,kate_pack_write,0);
    00145 }
    00146
    00147 void kate_pack_reset(kate_pack_buffer *b){
    00148   b->ptr=b->buffer;
    00149   b->buffer[0]=0;
    00150   b->endbit=b->endbyte=0;
    00151 }
    00152
    00153 void kate_pack_writeclear(kate_pack_buffer *b){
    00154   kate_free(b->buffer);
    00155   memset(b,0,sizeof(*b));
    00156 }
    00157
    00158 void kate_pack_readinit(kate_pack_buffer *b,unsigned char *buf,int bytes){
    00159   memset(b,0,sizeof(*b));
    00160   b->buffer=b->ptr=buf;
    00161   b->storage=bytes;
    00162 }
    00163
    00164 /* Read in bits without advancing the bitptr; bits <= 32 */
    00165 long kate_pack_look(kate_pack_buffer *b,int bits){
    00166   unsigned long ret;
    00167   unsigned long m=mask[bits];
    00168
    00169   bits+=b->endbit;
    00170
    00171   if(b->endbyte+4>=b->storage){
    00172     /* not the main path */
    00173     if(b->endbyte*8+bits>b->storage*8)return(-1);
    00174   }
    00175
    00176   ret=b->ptr[0]>>b->endbit;
    00177   if(bits>8){
    00178     ret|=b->ptr[1]<<(8-b->endbit);
    00179     if(bits>16){
    00180       ret|=b->ptr[2]<<(16-b->endbit);
    00181       if(bits>24){
    00182         ret|=b->ptr[3]<<(24-b->endbit);
    00183         if(bits>32 && b->endbit)
    00184           ret|=b->ptr[4]<<(32-b->endbit);
    00185       }
    00186     }
    00187   }
    00188   return(m&ret);
    00189 }
    00190
    00191 long kate_pack_look1(kate_pack_buffer *b){
    00192   if(b->endbyte>=b->storage)return(-1);
    00193   return((b->ptr[0]>>b->endbit)&1);
    00194 }
    00195
    00196 void kate_pack_adv(kate_pack_buffer *b,int bits){
    00197   bits+=b->endbit;
    00198   b->ptr+=bits/8;
    00199   b->endbyte+=bits/8;
    00200   b->endbit=bits&7;
    00201 }
    00202
    00203 void kate_pack_adv1(kate_pack_buffer *b){
    00204   if(++(b->endbit)>7){
    00205     b->endbit=0;
    00206     b->ptr++;
    00207     b->endbyte++;
    00208   }
    00209 }
    00210
    00211 /* bits <= 32 */
    00212 long kate_pack_read(kate_pack_buffer *b,int bits){
    00213   long ret;
    00214   unsigned long m=mask[bits];
    00215
    00216   bits+=b->endbit;
    00217
    00218   if(b->endbyte+4>=b->storage){
    00219     /* not the main path */
    00220     ret=-1L;
    00221     if(b->endbyte*8+bits>b->storage*8)goto overflow;
    00222   }
    00223
    00224   ret=b->ptr[0]>>b->endbit;
    00225   if(bits>8){
    00226     ret|=b->ptr[1]<<(8-b->endbit);
    00227     if(bits>16){
    00228       ret|=b->ptr[2]<<(16-b->endbit);
    00229       if(bits>24){
    00230         ret|=b->ptr[3]<<(24-b->endbit);
    00231         if(bits>32 && b->endbit){
    00232           ret|=b->ptr[4]<<(32-b->endbit);
    00233         }
    00234       }
    00235     }
    00236   }
    00237   ret&=m;
    00238
    00239  overflow:
    00240
    00241   b->ptr+=bits/8;
    00242   b->endbyte+=bits/8;
    00243   b->endbit=bits&7;
    00244   return(ret);
    00245 }
    00246
    00247 long kate_pack_read1(kate_pack_buffer *b){
    00248   long ret;
    00249
    00250   if(b->endbyte>=b->storage){
    00251     /* not the main path */
    00252     ret=-1L;
    00253     goto overflow;
    00254   }
    00255
    00256   ret=(b->ptr[0]>>b->endbit)&1;
    00257
    00258  overflow:
    00259
    00260   b->endbit++;
    00261   if(b->endbit>7){
    00262     b->endbit=0;
    00263     b->ptr++;
    00264     b->endbyte++;
    00265   }
    00266   return(ret);
    00267 }
    00268
    00269 long kate_pack_bytes(kate_pack_buffer *b){
    00270   return(b->endbyte+(b->endbit+7)/8);
    00271 }
    00272
    00273 long kate_pack_bits(kate_pack_buffer *b){
    00274   return(b->endbyte*8+b->endbit);
    00275 }
    00276
    00277 unsigned char *kate_pack_get_buffer(kate_pack_buffer *b){
    00278   return(b->buffer);
    00279 }
    00280
    00281 long kate_pack_readable_bits(kate_pack_buffer *b){
    00282   return b->storage*8-kate_pack_bits(b);
    00283 }
    00284
    00285 #undef BUFFER_INCREMENT