xref: /aosp_15_r20/external/tremolo/Tremolo/bitwise.c (revision bda690e46497e1f65c5077173b9c548e6e0cd5a1)
1*bda690e4SXin Li /************************************************************************
2*bda690e4SXin Li  * Copyright (C) 2002-2009, Xiph.org Foundation
3*bda690e4SXin Li  * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
4*bda690e4SXin Li  * All rights reserved.
5*bda690e4SXin Li  *
6*bda690e4SXin Li  * Redistribution and use in source and binary forms, with or without
7*bda690e4SXin Li  * modification, are permitted provided that the following conditions
8*bda690e4SXin Li  * are met:
9*bda690e4SXin Li  *
10*bda690e4SXin Li  *     * Redistributions of source code must retain the above copyright
11*bda690e4SXin Li  * notice, this list of conditions and the following disclaimer.
12*bda690e4SXin Li  *     * Redistributions in binary form must reproduce the above
13*bda690e4SXin Li  * copyright notice, this list of conditions and the following disclaimer
14*bda690e4SXin Li  * in the documentation and/or other materials provided with the
15*bda690e4SXin Li  * distribution.
16*bda690e4SXin Li  *     * Neither the names of the Xiph.org Foundation nor Pinknoise
17*bda690e4SXin Li  * Productions Ltd nor the names of its contributors may be used to
18*bda690e4SXin Li  * endorse or promote products derived from this software without
19*bda690e4SXin Li  * specific prior written permission.
20*bda690e4SXin Li  *
21*bda690e4SXin Li  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*bda690e4SXin Li  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*bda690e4SXin Li  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24*bda690e4SXin Li  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25*bda690e4SXin Li  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26*bda690e4SXin Li  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27*bda690e4SXin Li  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28*bda690e4SXin Li  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29*bda690e4SXin Li  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30*bda690e4SXin Li  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*bda690e4SXin Li  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*bda690e4SXin Li  ************************************************************************
33*bda690e4SXin Li 
34*bda690e4SXin Li   function: packing variable sized words into an octet stream
35*bda690e4SXin Li 
36*bda690e4SXin Li  ************************************************************************/
37*bda690e4SXin Li 
38*bda690e4SXin Li /* We're 'LSb' endian; if we write a word but read individual bits,
39*bda690e4SXin Li    then we'll read the lsb first */
40*bda690e4SXin Li 
41*bda690e4SXin Li #include <string.h>
42*bda690e4SXin Li #include <stdlib.h>
43*bda690e4SXin Li #include "misc.h"
44*bda690e4SXin Li #include "ogg.h"
45*bda690e4SXin Li 
46*bda690e4SXin Li #include <stdio.h>
47*bda690e4SXin Li 
48*bda690e4SXin Li 
49*bda690e4SXin Li #if !defined(ARM_LITTLE_ENDIAN) || defined(_V_BIT_TEST)
50*bda690e4SXin Li static unsigned long mask[]=
51*bda690e4SXin Li {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
52*bda690e4SXin Li  0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
53*bda690e4SXin Li  0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
54*bda690e4SXin Li  0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
55*bda690e4SXin Li  0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
56*bda690e4SXin Li  0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
57*bda690e4SXin Li  0x3fffffff,0x7fffffff,0xffffffff };
58*bda690e4SXin Li #endif
59*bda690e4SXin Li 
60*bda690e4SXin Li #ifdef ARM_LITTLE_ENDIAN
61*bda690e4SXin Li 
62*bda690e4SXin Li #ifdef DEBUGGING_BITWISE
63*bda690e4SXin Li extern void oggpack_readinitARM(oggpack_buffer *b,ogg_reference *r);
64*bda690e4SXin Li 
oggpack_readinit(oggpack_buffer * b,ogg_reference * r)65*bda690e4SXin Li void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
66*bda690e4SXin Li     oggpack_readinitARM(b,r);
67*bda690e4SXin Li     //fprintf(stderr, "Init: buffer=(%d,%x,%d,%d) %08x%08x\n",
68*bda690e4SXin Li     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
69*bda690e4SXin Li     //        b->ptr[1], b->ptr[0]);
70*bda690e4SXin Li     //fflush(stderr);
71*bda690e4SXin Li }
72*bda690e4SXin Li 
73*bda690e4SXin Li extern long oggpack_lookARM(oggpack_buffer *b,int bits);
74*bda690e4SXin Li 
oggpack_look(oggpack_buffer * b,int bits)75*bda690e4SXin Li long oggpack_look(oggpack_buffer *b,int bits){
76*bda690e4SXin Li     long l;
77*bda690e4SXin Li 
78*bda690e4SXin Li     //fprintf(stderr, "PreLook: buffer=(%x,%x,%x) %08x%08x (%d bits)\n",
79*bda690e4SXin Li     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord,
80*bda690e4SXin Li     //        b->ptr[1], b->ptr[0], bits);
81*bda690e4SXin Li     //fflush(stderr);
82*bda690e4SXin Li     l = oggpack_lookARM(b,bits);
83*bda690e4SXin Li     //fprintf(stderr, "Look: buffer=(%d,%x,%d,%d) %08x%08x (%d bits) (result=%x)\n",
84*bda690e4SXin Li     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
85*bda690e4SXin Li     //        b->ptr[1], b->ptr[0], bits, l);
86*bda690e4SXin Li     //fflush(stderr);
87*bda690e4SXin Li 
88*bda690e4SXin Li     return l;
89*bda690e4SXin Li }
90*bda690e4SXin Li 
91*bda690e4SXin Li extern void oggpack_advARM(oggpack_buffer *b,int bits);
92*bda690e4SXin Li 
oggpack_adv(oggpack_buffer * b,int bits)93*bda690e4SXin Li void oggpack_adv(oggpack_buffer *b,int bits){
94*bda690e4SXin Li     //fprintf(stderr, "Adv before: buffer=(%x,%x,%x) %08x%08x (%d bits)\n",
95*bda690e4SXin Li     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord,
96*bda690e4SXin Li     //        b->ptr[1], b->ptr[0],bits);
97*bda690e4SXin Li     //fflush(stderr);
98*bda690e4SXin Li     oggpack_advARM(b,bits);
99*bda690e4SXin Li     //fprintf(stderr, "Adv: buffer=(%d,%x,%d,%d) %08x%08x\n",
100*bda690e4SXin Li     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
101*bda690e4SXin Li     //        b->ptr[1], b->ptr[0]);
102*bda690e4SXin Li     //fflush(stderr);
103*bda690e4SXin Li }
104*bda690e4SXin Li 
105*bda690e4SXin Li extern long oggpack_readARM(oggpack_buffer *b,int bits);
106*bda690e4SXin Li 
107*bda690e4SXin Li /* bits <= 32 */
oggpack_read(oggpack_buffer * b,int bits)108*bda690e4SXin Li long oggpack_read(oggpack_buffer *b,int bits){
109*bda690e4SXin Li     long l;
110*bda690e4SXin Li 
111*bda690e4SXin Li     //fprintf(stderr, "PreRead: buffer=(%d,%x,%d,%d) %08x%08x (%d bits)\n",
112*bda690e4SXin Li     //        b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
113*bda690e4SXin Li     //        b->ptr[1], b->ptr[0], bits);
114*bda690e4SXin Li     //fflush(stderr);
115*bda690e4SXin Li     l = oggpack_readARM(b,bits);
116*bda690e4SXin Li     //fprintf(stderr, "Read: buffer=(%d,%x,%d,%d) %08x%08x (%d bits) (result=%x)\n",
117*bda690e4SXin Li     //       b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
118*bda690e4SXin Li     //       b->ptr[1], b->ptr[0], bits, l);
119*bda690e4SXin Li     //fflush(stderr);
120*bda690e4SXin Li 
121*bda690e4SXin Li     return l;
122*bda690e4SXin Li }
123*bda690e4SXin Li #endif
124*bda690e4SXin Li 
oggpack_eop(oggpack_buffer * b)125*bda690e4SXin Li int oggpack_eop(oggpack_buffer *b){
126*bda690e4SXin Li   int ret;
127*bda690e4SXin Li   if(b->bitsLeftInSegment<0)ret= -1;
128*bda690e4SXin Li   else ret = 0;
129*bda690e4SXin Li   //fprintf(stderr, "EOP %d\n", ret);
130*bda690e4SXin Li   //fflush(stderr);
131*bda690e4SXin Li   return ret;
132*bda690e4SXin Li }
133*bda690e4SXin Li 
oggpack_bytes(oggpack_buffer * b)134*bda690e4SXin Li long oggpack_bytes(oggpack_buffer *b){
135*bda690e4SXin Li   long ret;
136*bda690e4SXin Li   if(b->bitsLeftInSegment<0) ret = b->count+b->head->length;
137*bda690e4SXin Li   else ret = b->count + b->head->length - (b->bitsLeftInSegment)/8;
138*bda690e4SXin Li   //fprintf(stderr, "count=%d length=%d bitsLeftInSegment=%d\n",
139*bda690e4SXin Li   //        b->count, b->head->length, b->bitsLeftInSegment);
140*bda690e4SXin Li   //fflush(stderr);
141*bda690e4SXin Li   return ret;
142*bda690e4SXin Li }
143*bda690e4SXin Li 
oggpack_bits(oggpack_buffer * b)144*bda690e4SXin Li long oggpack_bits(oggpack_buffer *b){
145*bda690e4SXin Li   long ret;
146*bda690e4SXin Li   if(b->bitsLeftInSegment<0) ret=(b->count+b->head->length)*8;
147*bda690e4SXin Li   else ret = b->count*8 + b->head->length*8 - b->bitsLeftInSegment;
148*bda690e4SXin Li   //fprintf(stderr, "count=%d length=%d bitsLeftInSegment=%d\n",
149*bda690e4SXin Li   //        b->count, b->head->length, b->bitsLeftInSegment);
150*bda690e4SXin Li   //fflush(stderr);
151*bda690e4SXin Li   return ret;
152*bda690e4SXin Li }
153*bda690e4SXin Li 
154*bda690e4SXin Li #else
155*bda690e4SXin Li 
156*bda690e4SXin Li /* spans forward, skipping as many bytes as headend is negative; if
157*bda690e4SXin Li    headend is zero, simply finds next byte.  If we're up to the end
158*bda690e4SXin Li    of the buffer, leaves headend at zero.  If we've read past the end,
159*bda690e4SXin Li    halt the decode process. */
160*bda690e4SXin Li 
_span(oggpack_buffer * b)161*bda690e4SXin Li static void _span(oggpack_buffer *b){
162*bda690e4SXin Li   while(b->headend-(b->headbit>>3)<1){
163*bda690e4SXin Li     b->headend-=b->headbit>>3;
164*bda690e4SXin Li     b->headbit&=0x7;
165*bda690e4SXin Li 
166*bda690e4SXin Li     if(b->head && b->head->next){
167*bda690e4SXin Li       b->count+=b->head->length;
168*bda690e4SXin Li       b->head=b->head->next;
169*bda690e4SXin Li 
170*bda690e4SXin Li       if(b->headend+b->head->length>0)
171*bda690e4SXin Li 	b->headptr=b->head->buffer->data+b->head->begin-b->headend;
172*bda690e4SXin Li 
173*bda690e4SXin Li       b->headend+=b->head->length;
174*bda690e4SXin Li     }else{
175*bda690e4SXin Li       /* we've either met the end of decode, or gone past it. halt
176*bda690e4SXin Li 	 only if we're past */
177*bda690e4SXin Li       if(b->headend*8<b->headbit) {
178*bda690e4SXin Li 	/* read has fallen off the end */
179*bda690e4SXin Li 	b->headend=-1;
180*bda690e4SXin Li       }
181*bda690e4SXin Li       break;
182*bda690e4SXin Li     }
183*bda690e4SXin Li   }
184*bda690e4SXin Li }
185*bda690e4SXin Li 
oggpack_readinit(oggpack_buffer * b,ogg_reference * r)186*bda690e4SXin Li void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
187*bda690e4SXin Li   memset(b,0,sizeof(*b));
188*bda690e4SXin Li 
189*bda690e4SXin Li   b->tail=b->head=r;
190*bda690e4SXin Li   b->count=0;
191*bda690e4SXin Li   if (b->head && r->length) {
192*bda690e4SXin Li     b->headptr=b->head->buffer->data+b->head->begin;
193*bda690e4SXin Li     b->headend=b->head->length;
194*bda690e4SXin Li   } else {
195*bda690e4SXin Li     b->headptr=0;
196*bda690e4SXin Li     b->headend=0;
197*bda690e4SXin Li   }
198*bda690e4SXin Li   _span(b);
199*bda690e4SXin Li 
200*bda690e4SXin Li   //fprintf(stderr,
201*bda690e4SXin Li   //        "Init: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x\n",
202*bda690e4SXin Li   //        b->headbit, b->headptr, b->headend, b->count,
203*bda690e4SXin Li   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
204*bda690e4SXin Li   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0]);
205*bda690e4SXin Li   //fflush(stderr);
206*bda690e4SXin Li }
207*bda690e4SXin Li 
208*bda690e4SXin Li #define _lookspan()   while(!end){\
209*bda690e4SXin Li                         head=head->next;\
210*bda690e4SXin Li                         if(!head) return -1;\
211*bda690e4SXin Li                         ptr=head->buffer->data + head->begin;\
212*bda690e4SXin Li                         end=head->length;\
213*bda690e4SXin Li                       }
214*bda690e4SXin Li 
215*bda690e4SXin Li /* Read in bits without advancing the bitptr; bits <= 32 */
oggpack_look(oggpack_buffer * b,int bits)216*bda690e4SXin Li long oggpack_look(oggpack_buffer *b,int bits){
217*bda690e4SXin Li   unsigned long m=mask[bits];
218*bda690e4SXin Li   unsigned long ret = 0;
219*bda690e4SXin Li   int BITS = bits;
220*bda690e4SXin Li 
221*bda690e4SXin Li   if (!b->headptr || b->headend < 0) return 0;
222*bda690e4SXin Li 
223*bda690e4SXin Li   bits+=b->headbit;
224*bda690e4SXin Li 
225*bda690e4SXin Li   if(bits >= b->headend<<3){
226*bda690e4SXin Li     int            end=b->headend;
227*bda690e4SXin Li     unsigned char *ptr=b->headptr;
228*bda690e4SXin Li     ogg_reference *head=b->head;
229*bda690e4SXin Li 
230*bda690e4SXin Li     if(end<0)return 0;
231*bda690e4SXin Li     if (!head || !end)return 0;
232*bda690e4SXin Li 
233*bda690e4SXin Li     if(bits){
234*bda690e4SXin Li       _lookspan();
235*bda690e4SXin Li       ret=*ptr++>>b->headbit;
236*bda690e4SXin Li       if(bits>8){
237*bda690e4SXin Li         --end;
238*bda690e4SXin Li         _lookspan();
239*bda690e4SXin Li         ret|=*ptr++<<(8-b->headbit);
240*bda690e4SXin Li         if(bits>16){
241*bda690e4SXin Li           --end;
242*bda690e4SXin Li           _lookspan();
243*bda690e4SXin Li           ret|=*ptr++<<(16-b->headbit);
244*bda690e4SXin Li           if(bits>24){
245*bda690e4SXin Li             --end;
246*bda690e4SXin Li             _lookspan();
247*bda690e4SXin Li             ret|=*ptr++<<(24-b->headbit);
248*bda690e4SXin Li             if(bits>32 && b->headbit){
249*bda690e4SXin Li               --end;
250*bda690e4SXin Li               _lookspan();
251*bda690e4SXin Li               ret|=*ptr<<(32-b->headbit);
252*bda690e4SXin Li             }
253*bda690e4SXin Li           }
254*bda690e4SXin Li         }
255*bda690e4SXin Li       }
256*bda690e4SXin Li     }
257*bda690e4SXin Li 
258*bda690e4SXin Li   }else{
259*bda690e4SXin Li 
260*bda690e4SXin Li     /* make this a switch jump-table */
261*bda690e4SXin Li     ret=b->headptr[0]>>b->headbit;
262*bda690e4SXin Li     if(bits>8){
263*bda690e4SXin Li       ret|=b->headptr[1]<<(8-b->headbit);
264*bda690e4SXin Li       if(bits>16){
265*bda690e4SXin Li         ret|=b->headptr[2]<<(16-b->headbit);
266*bda690e4SXin Li         if(bits>24){
267*bda690e4SXin Li           ret|=b->headptr[3]<<(24-b->headbit);
268*bda690e4SXin Li           if(bits>32 && b->headbit)
269*bda690e4SXin Li             ret|=b->headptr[4]<<(32-b->headbit);
270*bda690e4SXin Li         }
271*bda690e4SXin Li       }
272*bda690e4SXin Li     }
273*bda690e4SXin Li   }
274*bda690e4SXin Li 
275*bda690e4SXin Li   ret&=m;
276*bda690e4SXin Li   //fprintf(stderr,
277*bda690e4SXin Li   //        "Look: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits) return=%x\n",
278*bda690e4SXin Li   //        b->headbit, b->headptr, b->headend, b->count,
279*bda690e4SXin Li   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
280*bda690e4SXin Li   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
281*bda690e4SXin Li   //        BITS, ret);
282*bda690e4SXin Li   //fflush(stderr);
283*bda690e4SXin Li   return ret;
284*bda690e4SXin Li }
285*bda690e4SXin Li 
286*bda690e4SXin Li /* limited to 32 at a time */
oggpack_adv(oggpack_buffer * b,int bits)287*bda690e4SXin Li void oggpack_adv(oggpack_buffer *b,int bits){
288*bda690e4SXin Li     int BITS=bits;
289*bda690e4SXin Li   bits+=b->headbit;
290*bda690e4SXin Li   b->headbit=bits&7;
291*bda690e4SXin Li   b->headend-=(bits>>3);
292*bda690e4SXin Li   b->headptr+=(bits>>3);
293*bda690e4SXin Li   if(b->headend<1)_span(b);
294*bda690e4SXin Li   //fprintf(stderr, "Adv: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits)\n",
295*bda690e4SXin Li   //        b->headbit, b->headptr, b->headend,b->count,
296*bda690e4SXin Li   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
297*bda690e4SXin Li   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
298*bda690e4SXin Li   //        BITS);
299*bda690e4SXin Li   //fflush(stderr);
300*bda690e4SXin Li }
301*bda690e4SXin Li 
oggpack_eop(oggpack_buffer * b)302*bda690e4SXin Li int oggpack_eop(oggpack_buffer *b){
303*bda690e4SXin Li   int ret;
304*bda690e4SXin Li   if(b->headend<0)ret= -1;
305*bda690e4SXin Li   else ret = 0;
306*bda690e4SXin Li   //fprintf(stderr, "EOP %d\n", ret);
307*bda690e4SXin Li   //fflush(stderr);
308*bda690e4SXin Li   return ret;
309*bda690e4SXin Li }
310*bda690e4SXin Li 
oggpack_bytes(oggpack_buffer * b)311*bda690e4SXin Li long oggpack_bytes(oggpack_buffer *b){
312*bda690e4SXin Li   long ret;
313*bda690e4SXin Li   if(b->headend<0) ret = b->count+b->head->length;
314*bda690e4SXin Li   ret = b->count + b->head->length-b->headend + (b->headbit+7)/8;
315*bda690e4SXin Li   //fprintf(stderr, "Bytes: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bytes)\n",
316*bda690e4SXin Li   //        b->headbit, b->headptr, b->headend, b->count,
317*bda690e4SXin Li   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
318*bda690e4SXin Li   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
319*bda690e4SXin Li   //        ret);
320*bda690e4SXin Li   //fflush(stderr);
321*bda690e4SXin Li   return ret;
322*bda690e4SXin Li }
323*bda690e4SXin Li 
oggpack_bits(oggpack_buffer * b)324*bda690e4SXin Li long oggpack_bits(oggpack_buffer *b){
325*bda690e4SXin Li   long ret;
326*bda690e4SXin Li   if(b->headend<0) ret = (b->count+b->head->length)*8;
327*bda690e4SXin Li   else ret = (b->count + b->head->length-b->headend)*8 + b->headbit;
328*bda690e4SXin Li   //fprintf(stderr, "Bits: buffer=(%x,%x,%x) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits)\n",
329*bda690e4SXin Li   //        b->headbit, b->headptr, b->headend,
330*bda690e4SXin Li   //        b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
331*bda690e4SXin Li   //        b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
332*bda690e4SXin Li   //        ret);
333*bda690e4SXin Li   //fflush(stderr);
334*bda690e4SXin Li   return ret;
335*bda690e4SXin Li }
336*bda690e4SXin Li 
337*bda690e4SXin Li /* bits <= 32 */
oggpack_read(oggpack_buffer * b,int bits)338*bda690e4SXin Li long oggpack_read(oggpack_buffer *b,int bits){
339*bda690e4SXin Li   long ret=oggpack_look(b,bits);
340*bda690e4SXin Li   oggpack_adv(b,bits);
341*bda690e4SXin Li   return(ret);
342*bda690e4SXin Li }
343*bda690e4SXin Li 
344*bda690e4SXin Li #endif
345*bda690e4SXin Li 
346*bda690e4SXin Li /* Self test of the bitwise routines; everything else is based on
347*bda690e4SXin Li    them, so they damned well better be solid. */
348*bda690e4SXin Li 
349*bda690e4SXin Li #ifdef _V_BIT_TEST
350*bda690e4SXin Li #include <string.h>
351*bda690e4SXin Li #include <stdlib.h>
352*bda690e4SXin Li #include <stdio.h>
353*bda690e4SXin Li #include "framing.c"
354*bda690e4SXin Li 
ilog(unsigned long v)355*bda690e4SXin Li static int ilog(unsigned long v){
356*bda690e4SXin Li   int ret=0;
357*bda690e4SXin Li   while(v){
358*bda690e4SXin Li     ret++;
359*bda690e4SXin Li     v>>=1;
360*bda690e4SXin Li   }
361*bda690e4SXin Li   return(ret);
362*bda690e4SXin Li }
363*bda690e4SXin Li 
364*bda690e4SXin Li oggpack_buffer r;
365*bda690e4SXin Li oggpack_buffer o;
366*bda690e4SXin Li ogg_buffer_state *bs;
367*bda690e4SXin Li ogg_reference *or;
368*bda690e4SXin Li #define TESTWORDS 256
369*bda690e4SXin Li 
report(char * in)370*bda690e4SXin Li void report(char *in){
371*bda690e4SXin Li   fprintf(stderr,"%s",in);
372*bda690e4SXin Li   exit(1);
373*bda690e4SXin Li }
374*bda690e4SXin Li 
getbyte(ogg_reference * or,int position)375*bda690e4SXin Li int getbyte(ogg_reference *or,int position){
376*bda690e4SXin Li   while(or && position>=or->length){
377*bda690e4SXin Li     position-=or->length;
378*bda690e4SXin Li     or=or->next;
379*bda690e4SXin Li     if(or==NULL){
380*bda690e4SXin Li       fprintf(stderr,"\n\tERROR: getbyte ran off end of buffer.\n");
381*bda690e4SXin Li       exit(1);
382*bda690e4SXin Li     }
383*bda690e4SXin Li   }
384*bda690e4SXin Li 
385*bda690e4SXin Li   if((position+or->begin)&1)
386*bda690e4SXin Li     return (or->buffer->data[(position+or->begin)>>1])&0xff;
387*bda690e4SXin Li   else
388*bda690e4SXin Li     return (or->buffer->data[(position+or->begin)>>1]>>8)&0xff;
389*bda690e4SXin Li }
390*bda690e4SXin Li 
cliptest(unsigned long * b,int vals,int bits,int * comp,int compsize)391*bda690e4SXin Li void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
392*bda690e4SXin Li   long i,bitcount=0;
393*bda690e4SXin Li   ogg_reference *or=ogg_buffer_alloc(bs,64);
394*bda690e4SXin Li   for(i=0;i<compsize;i++)
395*bda690e4SXin Li     or->buffer->data[i]= comp[i];
396*bda690e4SXin Li   or->length=i;
397*bda690e4SXin Li 
398*bda690e4SXin Li   oggpack_readinit(&r,or);
399*bda690e4SXin Li   for(i=0;i<vals;i++){
400*bda690e4SXin Li     unsigned long test;
401*bda690e4SXin Li     int tbit=bits?bits:ilog(b[i]);
402*bda690e4SXin Li     if((test=oggpack_look(&r,tbit))==0xffffffff)
403*bda690e4SXin Li       report("out of data!\n");
404*bda690e4SXin Li     if(test!=(b[i]&mask[tbit])){
405*bda690e4SXin Li       fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
406*bda690e4SXin Li       report("looked at incorrect value!\n");
407*bda690e4SXin Li     }
408*bda690e4SXin Li     if((test=oggpack_read(&r,tbit))==0xffffffff){
409*bda690e4SXin Li       report("premature end of data when reading!\n");
410*bda690e4SXin Li     }
411*bda690e4SXin Li     if(test!=(b[i]&mask[tbit])){
412*bda690e4SXin Li       fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
413*bda690e4SXin Li       report("read incorrect value!\n");
414*bda690e4SXin Li     }
415*bda690e4SXin Li     bitcount+=tbit;
416*bda690e4SXin Li 
417*bda690e4SXin Li     if(bitcount!=oggpack_bits(&r))
418*bda690e4SXin Li       report("wrong number of bits while reading!\n");
419*bda690e4SXin Li     if((bitcount+7)/8!=oggpack_bytes(&r))
420*bda690e4SXin Li       report("wrong number of bytes while reading!\n");
421*bda690e4SXin Li 
422*bda690e4SXin Li   }
423*bda690e4SXin Li   if(oggpack_bytes(&r)!=(bitcount+7)/8){
424*bda690e4SXin Li       fprintf(stderr, "%d vs %d\n", oggpack_bytes(&r), (bitcount+7)/8);
425*bda690e4SXin Li       report("leftover bytes after read!\n");
426*bda690e4SXin Li   }
427*bda690e4SXin Li   ogg_buffer_release(or);
428*bda690e4SXin Li }
429*bda690e4SXin Li 
_end_verify(int count)430*bda690e4SXin Li void _end_verify(int count){
431*bda690e4SXin Li   int i;
432*bda690e4SXin Li 
433*bda690e4SXin Li   /* are the proper number of bits left over? */
434*bda690e4SXin Li   int leftover=count*8-oggpack_bits(&o);
435*bda690e4SXin Li   if(leftover>7)
436*bda690e4SXin Li     report("\nERROR: too many bits reported left over.\n");
437*bda690e4SXin Li 
438*bda690e4SXin Li   /* does reading to exactly byte alignment *not* trip EOF? */
439*bda690e4SXin Li   if(oggpack_read(&o,leftover)==-1)
440*bda690e4SXin Li     report("\nERROR: read to but not past exact end tripped EOF.\n");
441*bda690e4SXin Li   if(oggpack_bits(&o)!=count*8)
442*bda690e4SXin Li     report("\nERROR: read to but not past exact end reported bad bitcount.\n");
443*bda690e4SXin Li 
444*bda690e4SXin Li   /* does EOF trip properly after a single additional bit? */
445*bda690e4SXin Li   if(oggpack_read(&o,1)!=-1)
446*bda690e4SXin Li     report("\nERROR: read past exact end did not trip EOF.\n");
447*bda690e4SXin Li   if(oggpack_bits(&o)!=count*8)
448*bda690e4SXin Li     report("\nERROR: read past exact end reported bad bitcount.\n");
449*bda690e4SXin Li 
450*bda690e4SXin Li   /* does EOF stay set over additional bit reads? */
451*bda690e4SXin Li   for(i=0;i<=32;i++){
452*bda690e4SXin Li     if(oggpack_read(&o,i)!=-1)
453*bda690e4SXin Li       report("\nERROR: EOF did not stay set on stream.\n");
454*bda690e4SXin Li     if(oggpack_bits(&o)!=count*8)
455*bda690e4SXin Li       report("\nERROR: read past exact end reported bad bitcount.\n");
456*bda690e4SXin Li   }
457*bda690e4SXin Li }
458*bda690e4SXin Li 
_end_verify2(int count)459*bda690e4SXin Li void _end_verify2(int count){
460*bda690e4SXin Li   int i;
461*bda690e4SXin Li 
462*bda690e4SXin Li   /* are the proper number of bits left over? */
463*bda690e4SXin Li   int leftover=count*8-oggpack_bits(&o);
464*bda690e4SXin Li   if(leftover>7)
465*bda690e4SXin Li     report("\nERROR: too many bits reported left over.\n");
466*bda690e4SXin Li 
467*bda690e4SXin Li   /* does reading to exactly byte alignment *not* trip EOF? */
468*bda690e4SXin Li   oggpack_adv(&o,leftover);
469*bda690e4SXin Li #ifdef ARM_LITTLE_ENDIAN
470*bda690e4SXin Li     if(o.bitsLeftInSegment!=0)
471*bda690e4SXin Li #else
472*bda690e4SXin Li   if(o.headend!=0)
473*bda690e4SXin Li #endif
474*bda690e4SXin Li     report("\nERROR: read to but not past exact end tripped EOF.\n");
475*bda690e4SXin Li   if(oggpack_bits(&o)!=count*8)
476*bda690e4SXin Li     report("\nERROR: read to but not past exact end reported bad bitcount.\n");
477*bda690e4SXin Li 
478*bda690e4SXin Li   /* does EOF trip properly after a single additional bit? */
479*bda690e4SXin Li   oggpack_adv(&o,1);
480*bda690e4SXin Li #ifdef ARM_LITTLE_ENDIAN
481*bda690e4SXin Li     if(o.bitsLeftInSegment>=0)
482*bda690e4SXin Li #else
483*bda690e4SXin Li   if(o.headend>=0)
484*bda690e4SXin Li #endif
485*bda690e4SXin Li     report("\nERROR: read past exact end did not trip EOF.\n");
486*bda690e4SXin Li   if(oggpack_bits(&o)!=count*8)
487*bda690e4SXin Li     report("\nERROR: read past exact end reported bad bitcount.\n");
488*bda690e4SXin Li 
489*bda690e4SXin Li   /* does EOF stay set over additional bit reads? */
490*bda690e4SXin Li   for(i=0;i<=32;i++){
491*bda690e4SXin Li     oggpack_adv(&o,i);
492*bda690e4SXin Li #ifdef ARM_LITTLE_ENDIAN
493*bda690e4SXin Li     if(o.bitsLeftInSegment>=0)
494*bda690e4SXin Li #else
495*bda690e4SXin Li     if(o.headend>=0)
496*bda690e4SXin Li #endif
497*bda690e4SXin Li       report("\nERROR: EOF did not stay set on stream.\n");
498*bda690e4SXin Li     if(oggpack_bits(&o)!=count*8)
499*bda690e4SXin Li       report("\nERROR: read past exact end reported bad bitcount.\n");
500*bda690e4SXin Li   }
501*bda690e4SXin Li }
502*bda690e4SXin Li 
ogg_buffer_length(ogg_reference * or)503*bda690e4SXin Li long ogg_buffer_length(ogg_reference *or){
504*bda690e4SXin Li   int count=0;
505*bda690e4SXin Li   while(or){
506*bda690e4SXin Li     count+=or->length;
507*bda690e4SXin Li     or=or->next;
508*bda690e4SXin Li   }
509*bda690e4SXin Li   return count;
510*bda690e4SXin Li }
511*bda690e4SXin Li 
ogg_buffer_extend(ogg_reference * or,long bytes)512*bda690e4SXin Li ogg_reference *ogg_buffer_extend(ogg_reference *or,long bytes){
513*bda690e4SXin Li   if(or){
514*bda690e4SXin Li     while(or->next){
515*bda690e4SXin Li       or=or->next;
516*bda690e4SXin Li     }
517*bda690e4SXin Li     or->next=ogg_buffer_alloc(or->buffer->ptr.owner,bytes);
518*bda690e4SXin Li     return(or->next);
519*bda690e4SXin Li   }
520*bda690e4SXin Li   return 0;
521*bda690e4SXin Li }
522*bda690e4SXin Li 
ogg_buffer_posttruncate(ogg_reference * or,long pos)523*bda690e4SXin Li void ogg_buffer_posttruncate(ogg_reference *or,long pos){
524*bda690e4SXin Li   /* walk to the point where we want to begin truncate */
525*bda690e4SXin Li   while(or && pos>or->length){
526*bda690e4SXin Li     pos-=or->length;
527*bda690e4SXin Li     or=or->next;
528*bda690e4SXin Li   }
529*bda690e4SXin Li   if(or){
530*bda690e4SXin Li     ogg_buffer_release(or->next);
531*bda690e4SXin Li     or->next=0;
532*bda690e4SXin Li     or->length=pos;
533*bda690e4SXin Li   }
534*bda690e4SXin Li }
535*bda690e4SXin Li 
main(void)536*bda690e4SXin Li int main(void){
537*bda690e4SXin Li   long i;
538*bda690e4SXin Li   static unsigned long testbuffer1[]=
539*bda690e4SXin Li     {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
540*bda690e4SXin Li        567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
541*bda690e4SXin Li   int test1size=43;
542*bda690e4SXin Li 
543*bda690e4SXin Li   static unsigned long testbuffer2[]=
544*bda690e4SXin Li     {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
545*bda690e4SXin Li        1233432,534,5,346435231,14436467,7869299,76326614,167548585,
546*bda690e4SXin Li        85525151,0,12321,1,349528352};
547*bda690e4SXin Li   int test2size=21;
548*bda690e4SXin Li 
549*bda690e4SXin Li   static unsigned long testbuffer3[]=
550*bda690e4SXin Li     {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,
551*bda690e4SXin Li        0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
552*bda690e4SXin Li   int test3size=56;
553*bda690e4SXin Li 
554*bda690e4SXin Li   static unsigned long large[]=
555*bda690e4SXin Li     {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
556*bda690e4SXin Li        1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
557*bda690e4SXin Li        85525151,0,12321,1,2146528352};
558*bda690e4SXin Li 
559*bda690e4SXin Li   int onesize=33;
560*bda690e4SXin Li   static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
561*bda690e4SXin Li                     34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
562*bda690e4SXin Li                     223,4};
563*bda690e4SXin Li 
564*bda690e4SXin Li   int twosize=6;
565*bda690e4SXin Li   static int two[6]={61,255,255,251,231,29};
566*bda690e4SXin Li 
567*bda690e4SXin Li   int threesize=54;
568*bda690e4SXin Li   static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
569*bda690e4SXin Li                       142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
570*bda690e4SXin Li                       58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
571*bda690e4SXin Li                       100,52,4,14,18,86,77,1};
572*bda690e4SXin Li 
573*bda690e4SXin Li   int foursize=38;
574*bda690e4SXin Li   static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
575*bda690e4SXin Li                      132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
576*bda690e4SXin Li                      28,2,133,0,1};
577*bda690e4SXin Li 
578*bda690e4SXin Li   int fivesize=45;
579*bda690e4SXin Li   static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
580*bda690e4SXin Li                      241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
581*bda690e4SXin Li                      84,75,159,2,1,0,132,192,8,0,0,18,22};
582*bda690e4SXin Li 
583*bda690e4SXin Li   int sixsize=7;
584*bda690e4SXin Li   static int six[7]={17,177,170,242,169,19,148};
585*bda690e4SXin Li 
586*bda690e4SXin Li   /* Test read/write together */
587*bda690e4SXin Li   /* Later we test against pregenerated bitstreams */
588*bda690e4SXin Li   bs=ogg_buffer_create();
589*bda690e4SXin Li 
590*bda690e4SXin Li   fprintf(stderr,"\nSmall preclipped packing (LSb): ");
591*bda690e4SXin Li   cliptest(testbuffer1,test1size,0,one,onesize);
592*bda690e4SXin Li   fprintf(stderr,"ok.");
593*bda690e4SXin Li 
594*bda690e4SXin Li   fprintf(stderr,"\nNull bit call (LSb): ");
595*bda690e4SXin Li   cliptest(testbuffer3,test3size,0,two,twosize);
596*bda690e4SXin Li   fprintf(stderr,"ok.");
597*bda690e4SXin Li 
598*bda690e4SXin Li   fprintf(stderr,"\nLarge preclipped packing (LSb): ");
599*bda690e4SXin Li   cliptest(testbuffer2,test2size,0,three,threesize);
600*bda690e4SXin Li   fprintf(stderr,"ok.");
601*bda690e4SXin Li 
602*bda690e4SXin Li   fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
603*bda690e4SXin Li 
604*bda690e4SXin Li   or=ogg_buffer_alloc(bs,128);
605*bda690e4SXin Li   for(i=0;i<test2size;i++){
606*bda690e4SXin Li     or->buffer->data[i*4]  = large[i]&0xff;
607*bda690e4SXin Li     or->buffer->data[i*4+1]  = (large[i]>>8)&0xff;
608*bda690e4SXin Li     or->buffer->data[i*4+2]  = (large[i]>>16)&0xff;
609*bda690e4SXin Li     or->buffer->data[i*4+3]  = (large[i]>>24)&0xff;
610*bda690e4SXin Li   }
611*bda690e4SXin Li   or->length=test2size*4;
612*bda690e4SXin Li   oggpack_readinit(&r,or);
613*bda690e4SXin Li   for(i=0;i<test2size;i++){
614*bda690e4SXin Li     unsigned long test;
615*bda690e4SXin Li     if((test=oggpack_look(&r,32))==0xffffffffUL)report("out of data. failed!");
616*bda690e4SXin Li     if(test!=large[i]){
617*bda690e4SXin Li       fprintf(stderr,"%ld != %ld (%lx!=%lx):",test,large[i],
618*bda690e4SXin Li               test,large[i]);
619*bda690e4SXin Li       report("read incorrect value!\n");
620*bda690e4SXin Li     }
621*bda690e4SXin Li     oggpack_adv(&r,32);
622*bda690e4SXin Li   }
623*bda690e4SXin Li   ogg_buffer_release(or);
624*bda690e4SXin Li   if(oggpack_bytes(&r)!=test2size*4){
625*bda690e4SXin Li     fprintf(stderr, "%d vs %d\n", oggpack_bytes(&r), test2size*4);
626*bda690e4SXin Li     report("leftover bytes after read!\n");
627*bda690e4SXin Li   }
628*bda690e4SXin Li   fprintf(stderr,"ok.");
629*bda690e4SXin Li 
630*bda690e4SXin Li   fprintf(stderr,"\nSmall unclipped packing (LSb): ");
631*bda690e4SXin Li   cliptest(testbuffer1,test1size,7,four,foursize);
632*bda690e4SXin Li   fprintf(stderr,"ok.");
633*bda690e4SXin Li 
634*bda690e4SXin Li   fprintf(stderr,"\nLarge unclipped packing (LSb): ");
635*bda690e4SXin Li   cliptest(testbuffer2,test2size,17,five,fivesize);
636*bda690e4SXin Li   fprintf(stderr,"ok.");
637*bda690e4SXin Li 
638*bda690e4SXin Li   fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
639*bda690e4SXin Li   cliptest(testbuffer3,test3size,1,six,sixsize);
640*bda690e4SXin Li   fprintf(stderr,"ok.");
641*bda690e4SXin Li 
642*bda690e4SXin Li   fprintf(stderr,"\nTesting read past end (LSb): ");
643*bda690e4SXin Li   {
644*bda690e4SXin Li     unsigned char dda[]={0,0,0,0};
645*bda690e4SXin Li     ogg_buffer lob={dda,8,0,{0}};
646*bda690e4SXin Li     ogg_reference lor={&lob,0,8,0};
647*bda690e4SXin Li 
648*bda690e4SXin Li     oggpack_readinit(&r,&lor);
649*bda690e4SXin Li     for(i=0;i<64;i++){
650*bda690e4SXin Li       if(oggpack_read(&r,1)<0){
651*bda690e4SXin Li         fprintf(stderr,"failed; got -1 prematurely.\n");
652*bda690e4SXin Li         exit(1);
653*bda690e4SXin Li       }
654*bda690e4SXin Li     }
655*bda690e4SXin Li     if(oggpack_look(&r,1)!=-1 ||
656*bda690e4SXin Li        oggpack_read(&r,1)!=-1){
657*bda690e4SXin Li       fprintf(stderr,"failed; read past end without -1.\n");
658*bda690e4SXin Li       exit(1);
659*bda690e4SXin Li     }
660*bda690e4SXin Li   }
661*bda690e4SXin Li   {
662*bda690e4SXin Li     unsigned char dda[]={0,0,0,0};
663*bda690e4SXin Li     ogg_buffer lob={dda,8,0,{0}};
664*bda690e4SXin Li     ogg_reference lor={&lob,0,8,0};
665*bda690e4SXin Li     unsigned long test;
666*bda690e4SXin Li 
667*bda690e4SXin Li     oggpack_readinit(&r,&lor);
668*bda690e4SXin Li     if((test=oggpack_read(&r,30))==0xffffffffUL ||
669*bda690e4SXin Li        (test=oggpack_read(&r,16))==0xffffffffUL){
670*bda690e4SXin Li       fprintf(stderr,"failed 2; got -1 prematurely.\n");
671*bda690e4SXin Li       exit(1);
672*bda690e4SXin Li     }
673*bda690e4SXin Li 
674*bda690e4SXin Li     if((test=oggpack_look(&r,18))==0xffffffffUL){
675*bda690e4SXin Li       fprintf(stderr,"failed 3; got -1 prematurely.\n");
676*bda690e4SXin Li       exit(1);
677*bda690e4SXin Li     }
678*bda690e4SXin Li     if((test=oggpack_look(&r,19))!=0xffffffffUL){
679*bda690e4SXin Li       fprintf(stderr,"failed; read past end without -1.\n");
680*bda690e4SXin Li       exit(1);
681*bda690e4SXin Li     }
682*bda690e4SXin Li     if((test=oggpack_look(&r,32))!=0xffffffffUL){
683*bda690e4SXin Li       fprintf(stderr,"failed; read past end without -1.\n");
684*bda690e4SXin Li       exit(1);
685*bda690e4SXin Li     }
686*bda690e4SXin Li   }
687*bda690e4SXin Li   fprintf(stderr,"ok.\n");
688*bda690e4SXin Li 
689*bda690e4SXin Li   /* now the scary shit: randomized testing */
690*bda690e4SXin Li 
691*bda690e4SXin Li   for(i=0;i<10000;i++){
692*bda690e4SXin Li     long j,count=0,count2=0,bitcount=0;
693*bda690e4SXin Li     unsigned long values[TESTWORDS];
694*bda690e4SXin Li     int len[TESTWORDS];
695*bda690e4SXin Li     unsigned char flat[4*TESTWORDS]; /* max possible needed size */
696*bda690e4SXin Li 
697*bda690e4SXin Li     memset(flat,0,sizeof(flat));
698*bda690e4SXin Li     fprintf(stderr,"\rRandomized testing (LSb)... (%ld)   ",10000-i);
699*bda690e4SXin Li 
700*bda690e4SXin Li     /* generate a list of words and lengths */
701*bda690e4SXin Li     /* write the required number of bits out to packbuffer */
702*bda690e4SXin Li     {
703*bda690e4SXin Li       long word=0;
704*bda690e4SXin Li       long bit=0;
705*bda690e4SXin Li       int k;
706*bda690e4SXin Li 
707*bda690e4SXin Li       for(j=0;j<TESTWORDS;j++){
708*bda690e4SXin Li 	values[j]=rand();
709*bda690e4SXin Li 	len[j]=(rand()%33);
710*bda690e4SXin Li 
711*bda690e4SXin Li 	for(k=0;k<len[j];k++){
712*bda690e4SXin Li 	  flat[word] |= ((values[j]>>k)&0x1)<<bit;
713*bda690e4SXin Li 	  bit++;
714*bda690e4SXin Li 	  bitcount++;
715*bda690e4SXin Li 	  if(bit>7){
716*bda690e4SXin Li 	    bit=0;
717*bda690e4SXin Li 	    word++;
718*bda690e4SXin Li 	  }
719*bda690e4SXin Li 	}
720*bda690e4SXin Li       }
721*bda690e4SXin Li     }
722*bda690e4SXin Li     count2=(bitcount+7)>>3;
723*bda690e4SXin Li 
724*bda690e4SXin Li     /* construct random-length buffer chain from flat vector; random
725*bda690e4SXin Li        byte starting offset within the length of the vector */
726*bda690e4SXin Li     {
727*bda690e4SXin Li       ogg_reference *or=NULL,*orl=NULL;
728*bda690e4SXin Li       long pos=0;
729*bda690e4SXin Li 
730*bda690e4SXin Li       /* build buffer chain */
731*bda690e4SXin Li       while(count2){
732*bda690e4SXin Li         int ilen=(rand()%32),k;
733*bda690e4SXin Li         int ibegin=(rand()%32);
734*bda690e4SXin Li 
735*bda690e4SXin Li 
736*bda690e4SXin Li         if(ilen>count2)ilen=count2;
737*bda690e4SXin Li 
738*bda690e4SXin Li         if(or)
739*bda690e4SXin Li           orl=ogg_buffer_extend(orl,64);
740*bda690e4SXin Li         else
741*bda690e4SXin Li           or=orl=ogg_buffer_alloc(bs,64);
742*bda690e4SXin Li 
743*bda690e4SXin Li         orl->length=ilen;
744*bda690e4SXin Li         orl->begin=ibegin;
745*bda690e4SXin Li 
746*bda690e4SXin Li 	for(k=0;k<ilen;k++)
747*bda690e4SXin Li 	  orl->buffer->data[ibegin++]= flat[pos++];
748*bda690e4SXin Li 
749*bda690e4SXin Li         count2-=ilen;
750*bda690e4SXin Li       }
751*bda690e4SXin Li 
752*bda690e4SXin Li       if(ogg_buffer_length(or)!=(bitcount+7)/8){
753*bda690e4SXin Li         fprintf(stderr,"\nERROR: buffer length incorrect after build.\n");
754*bda690e4SXin Li         exit(1);
755*bda690e4SXin Li       }
756*bda690e4SXin Li 
757*bda690e4SXin Li 
758*bda690e4SXin Li       {
759*bda690e4SXin Li         int begin=0; //=(rand()%TESTWORDS);
760*bda690e4SXin Li         int ilen=(rand()%(TESTWORDS-begin));
761*bda690e4SXin Li         int bitoffset,bitcount=0;
762*bda690e4SXin Li         unsigned long temp;
763*bda690e4SXin Li 
764*bda690e4SXin Li         for(j=0;j<begin;j++)
765*bda690e4SXin Li           bitcount+=len[j];
766*bda690e4SXin Li         or=ogg_buffer_pretruncate(or,bitcount/8);
767*bda690e4SXin Li         bitoffset=bitcount%=8;
768*bda690e4SXin Li         for(;j<begin+ilen;j++)
769*bda690e4SXin Li           bitcount+=len[j];
770*bda690e4SXin Li         ogg_buffer_posttruncate(or,((bitcount+7)/8));
771*bda690e4SXin Li 
772*bda690e4SXin Li         if((count=ogg_buffer_length(or))!=(bitcount+7)/8){
773*bda690e4SXin Li           fprintf(stderr,"\nERROR: buffer length incorrect after truncate.\n");
774*bda690e4SXin Li           exit(1);
775*bda690e4SXin Li         }
776*bda690e4SXin Li 
777*bda690e4SXin Li         oggpack_readinit(&o,or);
778*bda690e4SXin Li 
779*bda690e4SXin Li         /* verify bit count */
780*bda690e4SXin Li         if(oggpack_bits(&o)!=0){
781*bda690e4SXin Li           fprintf(stderr,"\nERROR: Read bitcounter not zero!\n");
782*bda690e4SXin Li           exit(1);
783*bda690e4SXin Li         }
784*bda690e4SXin Li         if(oggpack_bytes(&o)!=0){
785*bda690e4SXin Li           fprintf(stderr,"\nERROR: Read bytecounter not zero!\n");
786*bda690e4SXin Li           exit(1);
787*bda690e4SXin Li         }
788*bda690e4SXin Li 
789*bda690e4SXin Li         bitcount=bitoffset;
790*bda690e4SXin Li         oggpack_read(&o,bitoffset);
791*bda690e4SXin Li 
792*bda690e4SXin Li         /* read and compare to original list */
793*bda690e4SXin Li         for(j=begin;j<begin+ilen;j++){
794*bda690e4SXin Li 	  temp=oggpack_read(&o,len[j]);
795*bda690e4SXin Li           if(temp==0xffffffffUL){
796*bda690e4SXin Li             fprintf(stderr,"\nERROR: End of stream too soon! word: %ld,%d\n",
797*bda690e4SXin Li                     j-begin,ilen);
798*bda690e4SXin Li             exit(1);
799*bda690e4SXin Li           }
800*bda690e4SXin Li           if(temp!=(values[j]&mask[len[j]])){
801*bda690e4SXin Li             fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %ld, len %d\n"
802*bda690e4SXin Li ,
803*bda690e4SXin Li                     values[j]&mask[len[j]],temp,j-begin,len[j]);
804*bda690e4SXin Li             exit(1);
805*bda690e4SXin Li           }
806*bda690e4SXin Li           bitcount+=len[j];
807*bda690e4SXin Li           if(oggpack_bits(&o)!=bitcount){
808*bda690e4SXin Li             fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
809*bda690e4SXin Li                     bitcount,oggpack_bits(&o));
810*bda690e4SXin Li             exit(1);
811*bda690e4SXin Li           }
812*bda690e4SXin Li           if(oggpack_bytes(&o)!=(bitcount+7)/8){
813*bda690e4SXin Li             fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
814*bda690e4SXin Li                     (bitcount+7)/8,oggpack_bytes(&o));
815*bda690e4SXin Li             exit(1);
816*bda690e4SXin Li           }
817*bda690e4SXin Li 
818*bda690e4SXin Li         }
819*bda690e4SXin Li         _end_verify(count);
820*bda690e4SXin Li 
821*bda690e4SXin Li         /* look/adv version */
822*bda690e4SXin Li         oggpack_readinit(&o,or);
823*bda690e4SXin Li         bitcount=bitoffset;
824*bda690e4SXin Li         oggpack_adv(&o,bitoffset);
825*bda690e4SXin Li 
826*bda690e4SXin Li         /* read and compare to original list */
827*bda690e4SXin Li         for(j=begin;j<begin+ilen;j++){
828*bda690e4SXin Li 	  temp=oggpack_look(&o,len[j]);
829*bda690e4SXin Li 
830*bda690e4SXin Li           if(temp==0xffffffffUL){
831*bda690e4SXin Li             fprintf(stderr,"\nERROR: End of stream too soon! word: %ld\n",
832*bda690e4SXin Li                     j-begin);
833*bda690e4SXin Li             exit(1);
834*bda690e4SXin Li           }
835*bda690e4SXin Li           if(temp!=(values[j]&mask[len[j]])){
836*bda690e4SXin Li             fprintf(stderr,"\nERROR: Incorrect look %lx != %lx, word %ld, len %d\n"
837*bda690e4SXin Li ,
838*bda690e4SXin Li                     values[j]&mask[len[j]],temp,j-begin,len[j]);
839*bda690e4SXin Li             exit(1);
840*bda690e4SXin Li           }
841*bda690e4SXin Li 	  oggpack_adv(&o,len[j]);
842*bda690e4SXin Li           bitcount+=len[j];
843*bda690e4SXin Li           if(oggpack_bits(&o)!=bitcount){
844*bda690e4SXin Li             fprintf(stderr,"\nERROR: Look/Adv bitcounter %d != %ld!\n",
845*bda690e4SXin Li                     bitcount,oggpack_bits(&o));
846*bda690e4SXin Li             exit(1);
847*bda690e4SXin Li           }
848*bda690e4SXin Li           if(oggpack_bytes(&o)!=(bitcount+7)/8){
849*bda690e4SXin Li             fprintf(stderr,"\nERROR: Look/Adv bytecounter %d != %ld!\n",
850*bda690e4SXin Li                     (bitcount+7)/8,oggpack_bytes(&o));
851*bda690e4SXin Li             exit(1);
852*bda690e4SXin Li           }
853*bda690e4SXin Li 
854*bda690e4SXin Li         }
855*bda690e4SXin Li         _end_verify2(count);
856*bda690e4SXin Li 
857*bda690e4SXin Li       }
858*bda690e4SXin Li       ogg_buffer_release(or);
859*bda690e4SXin Li     }
860*bda690e4SXin Li   }
861*bda690e4SXin Li   fprintf(stderr,"\rRandomized testing (LSb)... ok.   \n");
862*bda690e4SXin Li 
863*bda690e4SXin Li   return(0);
864*bda690e4SXin Li }
865*bda690e4SXin Li 
866*bda690e4SXin Li #ifdef _WIN32_WCE
WinMain(void)867*bda690e4SXin Li int WinMain(void){
868*bda690e4SXin Li     return main();
869*bda690e4SXin Li }
870*bda690e4SXin Li #endif
871*bda690e4SXin Li 
872*bda690e4SXin Li #endif
873