Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /******************************************************************** |
michael@0 | 2 | * * |
michael@0 | 3 | * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * |
michael@0 | 4 | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
michael@0 | 5 | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
michael@0 | 6 | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
michael@0 | 7 | * * |
michael@0 | 8 | * THE OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2009 * |
michael@0 | 9 | * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * |
michael@0 | 10 | * * |
michael@0 | 11 | ******************************************************************** |
michael@0 | 12 | |
michael@0 | 13 | function: packing variable sized words into an octet stream |
michael@0 | 14 | last mod: $Id: bitpack.c 17410 2010-09-21 21:53:48Z tterribe $ |
michael@0 | 15 | |
michael@0 | 16 | ********************************************************************/ |
michael@0 | 17 | #include <string.h> |
michael@0 | 18 | #include <stdlib.h> |
michael@0 | 19 | #include "bitpack.h" |
michael@0 | 20 | |
michael@0 | 21 | /*We're 'MSb' endian; if we write a word but read individual bits, |
michael@0 | 22 | then we'll read the MSb first.*/ |
michael@0 | 23 | |
michael@0 | 24 | void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes){ |
michael@0 | 25 | memset(_b,0,sizeof(*_b)); |
michael@0 | 26 | _b->ptr=_buf; |
michael@0 | 27 | _b->stop=_buf+_bytes; |
michael@0 | 28 | } |
michael@0 | 29 | |
michael@0 | 30 | static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){ |
michael@0 | 31 | const unsigned char *ptr; |
michael@0 | 32 | const unsigned char *stop; |
michael@0 | 33 | oc_pb_window window; |
michael@0 | 34 | int available; |
michael@0 | 35 | unsigned shift; |
michael@0 | 36 | stop=_b->stop; |
michael@0 | 37 | ptr=_b->ptr; |
michael@0 | 38 | window=_b->window; |
michael@0 | 39 | available=_b->bits; |
michael@0 | 40 | shift=OC_PB_WINDOW_SIZE-available; |
michael@0 | 41 | while(7<shift&&ptr<stop){ |
michael@0 | 42 | shift-=8; |
michael@0 | 43 | window|=(oc_pb_window)*ptr++<<shift; |
michael@0 | 44 | } |
michael@0 | 45 | _b->ptr=ptr; |
michael@0 | 46 | available=OC_PB_WINDOW_SIZE-shift; |
michael@0 | 47 | if(_bits>available){ |
michael@0 | 48 | if(ptr>=stop){ |
michael@0 | 49 | _b->eof=1; |
michael@0 | 50 | available=OC_LOTS_OF_BITS; |
michael@0 | 51 | } |
michael@0 | 52 | else window|=*ptr>>(available&7); |
michael@0 | 53 | } |
michael@0 | 54 | _b->bits=available; |
michael@0 | 55 | return window; |
michael@0 | 56 | } |
michael@0 | 57 | |
michael@0 | 58 | int oc_pack_look1(oc_pack_buf *_b){ |
michael@0 | 59 | oc_pb_window window; |
michael@0 | 60 | int available; |
michael@0 | 61 | window=_b->window; |
michael@0 | 62 | available=_b->bits; |
michael@0 | 63 | if(available<1)_b->window=window=oc_pack_refill(_b,1); |
michael@0 | 64 | return window>>OC_PB_WINDOW_SIZE-1; |
michael@0 | 65 | } |
michael@0 | 66 | |
michael@0 | 67 | void oc_pack_adv1(oc_pack_buf *_b){ |
michael@0 | 68 | _b->window<<=1; |
michael@0 | 69 | _b->bits--; |
michael@0 | 70 | } |
michael@0 | 71 | |
michael@0 | 72 | /*Here we assume that 0<=_bits&&_bits<=32.*/ |
michael@0 | 73 | long oc_pack_read_c(oc_pack_buf *_b,int _bits){ |
michael@0 | 74 | oc_pb_window window; |
michael@0 | 75 | int available; |
michael@0 | 76 | long result; |
michael@0 | 77 | window=_b->window; |
michael@0 | 78 | available=_b->bits; |
michael@0 | 79 | if(_bits==0)return 0; |
michael@0 | 80 | if(available<_bits){ |
michael@0 | 81 | window=oc_pack_refill(_b,_bits); |
michael@0 | 82 | available=_b->bits; |
michael@0 | 83 | } |
michael@0 | 84 | result=window>>OC_PB_WINDOW_SIZE-_bits; |
michael@0 | 85 | available-=_bits; |
michael@0 | 86 | window<<=1; |
michael@0 | 87 | window<<=_bits-1; |
michael@0 | 88 | _b->window=window; |
michael@0 | 89 | _b->bits=available; |
michael@0 | 90 | return result; |
michael@0 | 91 | } |
michael@0 | 92 | |
michael@0 | 93 | int oc_pack_read1_c(oc_pack_buf *_b){ |
michael@0 | 94 | oc_pb_window window; |
michael@0 | 95 | int available; |
michael@0 | 96 | int result; |
michael@0 | 97 | window=_b->window; |
michael@0 | 98 | available=_b->bits; |
michael@0 | 99 | if(available<1){ |
michael@0 | 100 | window=oc_pack_refill(_b,1); |
michael@0 | 101 | available=_b->bits; |
michael@0 | 102 | } |
michael@0 | 103 | result=window>>OC_PB_WINDOW_SIZE-1; |
michael@0 | 104 | available--; |
michael@0 | 105 | window<<=1; |
michael@0 | 106 | _b->window=window; |
michael@0 | 107 | _b->bits=available; |
michael@0 | 108 | return result; |
michael@0 | 109 | } |
michael@0 | 110 | |
michael@0 | 111 | long oc_pack_bytes_left(oc_pack_buf *_b){ |
michael@0 | 112 | if(_b->eof)return -1; |
michael@0 | 113 | return _b->stop-_b->ptr+(_b->bits>>3); |
michael@0 | 114 | } |