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