Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/libogg/bitwise.c
21079 views
1
/********************************************************************
2
* *
3
* THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. *
4
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7
* *
8
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2014 *
9
* by the Xiph.Org Foundation http://www.xiph.org/ *
10
* *
11
********************************************************************
12
13
function: packing variable sized words into an octet stream
14
15
********************************************************************/
16
17
/* We're 'LSb' endian; if we write a word but read individual bits,
18
then we'll read the lsb first */
19
20
#include <string.h>
21
#include <stdlib.h>
22
#include <limits.h>
23
#include <ogg/ogg.h>
24
25
#define BUFFER_INCREMENT 256
26
27
static const unsigned long mask[]=
28
{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
29
0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
30
0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
31
0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
32
0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
33
0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
34
0x3fffffff,0x7fffffff,0xffffffff };
35
36
static const unsigned int mask8B[]=
37
{0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
38
39
void oggpack_writeinit(oggpack_buffer *b){
40
memset(b,0,sizeof(*b));
41
b->ptr=b->buffer=_ogg_malloc(BUFFER_INCREMENT);
42
if (!b->buffer)
43
return;
44
b->buffer[0]='\0';
45
b->storage=BUFFER_INCREMENT;
46
}
47
48
void oggpackB_writeinit(oggpack_buffer *b){
49
oggpack_writeinit(b);
50
}
51
52
int oggpack_writecheck(oggpack_buffer *b){
53
if(!b->ptr || !b->storage)return -1;
54
return 0;
55
}
56
57
int oggpackB_writecheck(oggpack_buffer *b){
58
return oggpack_writecheck(b);
59
}
60
61
void oggpack_writetrunc(oggpack_buffer *b,long bits){
62
long bytes=bits>>3;
63
if(b->ptr){
64
bits-=bytes*8;
65
b->ptr=b->buffer+bytes;
66
b->endbit=bits;
67
b->endbyte=bytes;
68
*b->ptr&=mask[bits];
69
}
70
}
71
72
void oggpackB_writetrunc(oggpack_buffer *b,long bits){
73
long bytes=bits>>3;
74
if(b->ptr){
75
bits-=bytes*8;
76
b->ptr=b->buffer+bytes;
77
b->endbit=bits;
78
b->endbyte=bytes;
79
*b->ptr&=mask8B[bits];
80
}
81
}
82
83
/* Takes only up to 32 bits. */
84
void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
85
if(bits<0 || bits>32) goto err;
86
if(b->endbyte>=b->storage-4){
87
void *ret;
88
if(!b->ptr)return;
89
if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
90
ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
91
if(!ret) goto err;
92
b->buffer=ret;
93
b->storage+=BUFFER_INCREMENT;
94
b->ptr=b->buffer+b->endbyte;
95
}
96
97
value&=mask[bits];
98
bits+=b->endbit;
99
100
b->ptr[0]|=value<<b->endbit;
101
102
if(bits>=8){
103
b->ptr[1]=(unsigned char)(value>>(8-b->endbit));
104
if(bits>=16){
105
b->ptr[2]=(unsigned char)(value>>(16-b->endbit));
106
if(bits>=24){
107
b->ptr[3]=(unsigned char)(value>>(24-b->endbit));
108
if(bits>=32){
109
if(b->endbit)
110
b->ptr[4]=(unsigned char)(value>>(32-b->endbit));
111
else
112
b->ptr[4]=0;
113
}
114
}
115
}
116
}
117
118
b->endbyte+=bits/8;
119
b->ptr+=bits/8;
120
b->endbit=bits&7;
121
return;
122
err:
123
oggpack_writeclear(b);
124
}
125
126
/* Takes only up to 32 bits. */
127
void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
128
if(bits<0 || bits>32) goto err;
129
if(b->endbyte>=b->storage-4){
130
void *ret;
131
if(!b->ptr)return;
132
if(b->storage>LONG_MAX-BUFFER_INCREMENT) goto err;
133
ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
134
if(!ret) goto err;
135
b->buffer=ret;
136
b->storage+=BUFFER_INCREMENT;
137
b->ptr=b->buffer+b->endbyte;
138
}
139
140
value=(value&mask[bits])<<(32-bits);
141
bits+=b->endbit;
142
143
b->ptr[0]|=value>>(24+b->endbit);
144
145
if(bits>=8){
146
b->ptr[1]=(unsigned char)(value>>(16+b->endbit));
147
if(bits>=16){
148
b->ptr[2]=(unsigned char)(value>>(8+b->endbit));
149
if(bits>=24){
150
b->ptr[3]=(unsigned char)(value>>(b->endbit));
151
if(bits>=32){
152
if(b->endbit)
153
b->ptr[4]=(unsigned char)(value<<(8-b->endbit));
154
else
155
b->ptr[4]=0;
156
}
157
}
158
}
159
}
160
161
b->endbyte+=bits/8;
162
b->ptr+=bits/8;
163
b->endbit=bits&7;
164
return;
165
err:
166
oggpack_writeclear(b);
167
}
168
169
void oggpack_writealign(oggpack_buffer *b){
170
int bits=8-b->endbit;
171
if(bits<8)
172
oggpack_write(b,0,bits);
173
}
174
175
void oggpackB_writealign(oggpack_buffer *b){
176
int bits=8-b->endbit;
177
if(bits<8)
178
oggpackB_write(b,0,bits);
179
}
180
181
static void oggpack_writecopy_helper(oggpack_buffer *b,
182
void *source,
183
long bits,
184
void (*w)(oggpack_buffer *,
185
unsigned long,
186
int),
187
int msb){
188
unsigned char *ptr=(unsigned char *)source;
189
190
long bytes=bits/8;
191
long pbytes=(b->endbit+bits)/8;
192
bits-=bytes*8;
193
194
/* expand storage up-front */
195
if(b->endbyte+pbytes>=b->storage){
196
void *ret;
197
if(!b->ptr) goto err;
198
if(b->storage>b->endbyte+pbytes+BUFFER_INCREMENT) goto err;
199
b->storage=b->endbyte+pbytes+BUFFER_INCREMENT;
200
ret=_ogg_realloc(b->buffer,b->storage);
201
if(!ret) goto err;
202
b->buffer=ret;
203
b->ptr=b->buffer+b->endbyte;
204
}
205
206
/* copy whole octets */
207
if(b->endbit){
208
int i;
209
/* unaligned copy. Do it the hard way. */
210
for(i=0;i<bytes;i++)
211
w(b,(unsigned long)(ptr[i]),8);
212
}else{
213
/* aligned block copy */
214
memmove(b->ptr,source,bytes);
215
b->ptr+=bytes;
216
b->endbyte+=bytes;
217
*b->ptr=0;
218
}
219
220
/* copy trailing bits */
221
if(bits){
222
if(msb)
223
w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits);
224
else
225
w(b,(unsigned long)(ptr[bytes]),bits);
226
}
227
return;
228
err:
229
oggpack_writeclear(b);
230
}
231
232
void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){
233
oggpack_writecopy_helper(b,source,bits,oggpack_write,0);
234
}
235
236
void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){
237
oggpack_writecopy_helper(b,source,bits,oggpackB_write,1);
238
}
239
240
void oggpack_reset(oggpack_buffer *b){
241
if(!b->ptr)return;
242
b->ptr=b->buffer;
243
b->buffer[0]=0;
244
b->endbit=b->endbyte=0;
245
}
246
247
void oggpackB_reset(oggpack_buffer *b){
248
oggpack_reset(b);
249
}
250
251
void oggpack_writeclear(oggpack_buffer *b){
252
if(b->buffer)_ogg_free(b->buffer);
253
memset(b,0,sizeof(*b));
254
}
255
256
void oggpackB_writeclear(oggpack_buffer *b){
257
oggpack_writeclear(b);
258
}
259
260
void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
261
memset(b,0,sizeof(*b));
262
b->buffer=b->ptr=buf;
263
b->storage=bytes;
264
}
265
266
void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
267
oggpack_readinit(b,buf,bytes);
268
}
269
270
/* Read in bits without advancing the bitptr; bits <= 32 */
271
long oggpack_look(oggpack_buffer *b,int bits){
272
unsigned long ret;
273
unsigned long m;
274
275
if(bits<0 || bits>32) return -1;
276
m=mask[bits];
277
bits+=b->endbit;
278
279
if(b->endbyte >= b->storage-4){
280
/* not the main path */
281
if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
282
/* special case to avoid reading b->ptr[0], which might be past the end of
283
the buffer; also skips some useless accounting */
284
else if(!bits)return(0L);
285
}
286
287
ret=b->ptr[0]>>b->endbit;
288
if(bits>8){
289
ret|=(unsigned long)b->ptr[1]<<(8-b->endbit);
290
if(bits>16){
291
ret|=(unsigned long)b->ptr[2]<<(16-b->endbit);
292
if(bits>24){
293
ret|=(unsigned long)b->ptr[3]<<(24-b->endbit);
294
if(bits>32 && b->endbit)
295
ret|=(unsigned long)b->ptr[4]<<(32-b->endbit);
296
}
297
}
298
}
299
return(m&ret);
300
}
301
302
/* Read in bits without advancing the bitptr; bits <= 32 */
303
long oggpackB_look(oggpack_buffer *b,int bits){
304
unsigned long ret;
305
int m=32-bits;
306
307
if(m<0 || m>32) return -1;
308
bits+=b->endbit;
309
310
if(b->endbyte >= b->storage-4){
311
/* not the main path */
312
if(b->endbyte > b->storage-((bits+7)>>3)) return -1;
313
/* special case to avoid reading b->ptr[0], which might be past the end of
314
the buffer; also skips some useless accounting */
315
else if(!bits)return(0L);
316
}
317
318
ret=(unsigned long)b->ptr[0]<<(24+b->endbit);
319
if(bits>8){
320
ret|=(unsigned long)b->ptr[1]<<(16+b->endbit);
321
if(bits>16){
322
ret|=(unsigned long)b->ptr[2]<<(8+b->endbit);
323
if(bits>24){
324
ret|=(unsigned long)b->ptr[3]<<(b->endbit);
325
if(bits>32 && b->endbit)
326
ret|=b->ptr[4]>>(8-b->endbit);
327
}
328
}
329
}
330
return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1);
331
}
332
333
long oggpack_look1(oggpack_buffer *b){
334
if(b->endbyte>=b->storage)return(-1);
335
return((b->ptr[0]>>b->endbit)&1);
336
}
337
338
long oggpackB_look1(oggpack_buffer *b){
339
if(b->endbyte>=b->storage)return(-1);
340
return((b->ptr[0]>>(7-b->endbit))&1);
341
}
342
343
void oggpack_adv(oggpack_buffer *b,int bits){
344
bits+=b->endbit;
345
346
if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
347
348
b->ptr+=bits/8;
349
b->endbyte+=bits/8;
350
b->endbit=bits&7;
351
return;
352
353
overflow:
354
b->ptr=NULL;
355
b->endbyte=b->storage;
356
b->endbit=1;
357
}
358
359
void oggpackB_adv(oggpack_buffer *b,int bits){
360
oggpack_adv(b,bits);
361
}
362
363
void oggpack_adv1(oggpack_buffer *b){
364
if(++(b->endbit)>7){
365
b->endbit=0;
366
b->ptr++;
367
b->endbyte++;
368
}
369
}
370
371
void oggpackB_adv1(oggpack_buffer *b){
372
oggpack_adv1(b);
373
}
374
375
/* bits <= 32 */
376
long oggpack_read(oggpack_buffer *b,int bits){
377
long ret;
378
unsigned long m;
379
380
if(bits<0 || bits>32) goto err;
381
m=mask[bits];
382
bits+=b->endbit;
383
384
if(b->endbyte >= b->storage-4){
385
/* not the main path */
386
if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
387
/* special case to avoid reading b->ptr[0], which might be past the end of
388
the buffer; also skips some useless accounting */
389
else if(!bits)return(0L);
390
}
391
392
ret=b->ptr[0]>>b->endbit;
393
if(bits>8){
394
ret|=(unsigned long)b->ptr[1]<<(8-b->endbit);
395
if(bits>16){
396
ret|=(unsigned long)b->ptr[2]<<(16-b->endbit);
397
if(bits>24){
398
ret|=(unsigned long)b->ptr[3]<<(24-b->endbit);
399
if(bits>32 && b->endbit){
400
ret|=(unsigned long)b->ptr[4]<<(32-b->endbit);
401
}
402
}
403
}
404
}
405
ret&=m;
406
b->ptr+=bits/8;
407
b->endbyte+=bits/8;
408
b->endbit=bits&7;
409
return ret;
410
411
overflow:
412
err:
413
b->ptr=NULL;
414
b->endbyte=b->storage;
415
b->endbit=1;
416
return -1L;
417
}
418
419
/* bits <= 32 */
420
long oggpackB_read(oggpack_buffer *b,int bits){
421
long ret;
422
long m=32-bits;
423
424
if(m<0 || m>32) goto err;
425
bits+=b->endbit;
426
427
if(b->endbyte+4>=b->storage){
428
/* not the main path */
429
if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow;
430
/* special case to avoid reading b->ptr[0], which might be past the end of
431
the buffer; also skips some useless accounting */
432
else if(!bits)return(0L);
433
}
434
435
ret=(unsigned long)b->ptr[0]<<(24+b->endbit);
436
if(bits>8){
437
ret|=(unsigned long)b->ptr[1]<<(16+b->endbit);
438
if(bits>16){
439
ret|=(unsigned long)b->ptr[2]<<(8+b->endbit);
440
if(bits>24){
441
ret|=(unsigned long)b->ptr[3]<<(b->endbit);
442
if(bits>32 && b->endbit)
443
ret|=b->ptr[4]>>(8-b->endbit);
444
}
445
}
446
}
447
ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1);
448
449
b->ptr+=bits/8;
450
b->endbyte+=bits/8;
451
b->endbit=bits&7;
452
return ret;
453
454
overflow:
455
err:
456
b->ptr=NULL;
457
b->endbyte=b->storage;
458
b->endbit=1;
459
return -1L;
460
}
461
462
long oggpack_read1(oggpack_buffer *b){
463
long ret;
464
465
if(b->endbyte >= b->storage) goto overflow;
466
ret=(b->ptr[0]>>b->endbit)&1;
467
468
b->endbit++;
469
if(b->endbit>7){
470
b->endbit=0;
471
b->ptr++;
472
b->endbyte++;
473
}
474
return ret;
475
476
overflow:
477
b->ptr=NULL;
478
b->endbyte=b->storage;
479
b->endbit=1;
480
return -1L;
481
}
482
483
long oggpackB_read1(oggpack_buffer *b){
484
long ret;
485
486
if(b->endbyte >= b->storage) goto overflow;
487
ret=(b->ptr[0]>>(7-b->endbit))&1;
488
489
b->endbit++;
490
if(b->endbit>7){
491
b->endbit=0;
492
b->ptr++;
493
b->endbyte++;
494
}
495
return ret;
496
497
overflow:
498
b->ptr=NULL;
499
b->endbyte=b->storage;
500
b->endbit=1;
501
return -1L;
502
}
503
504
long oggpack_bytes(oggpack_buffer *b){
505
return(b->endbyte+(b->endbit+7)/8);
506
}
507
508
long oggpack_bits(oggpack_buffer *b){
509
return(b->endbyte*8+b->endbit);
510
}
511
512
long oggpackB_bytes(oggpack_buffer *b){
513
return oggpack_bytes(b);
514
}
515
516
long oggpackB_bits(oggpack_buffer *b){
517
return oggpack_bits(b);
518
}
519
520
unsigned char *oggpack_get_buffer(oggpack_buffer *b){
521
return(b->buffer);
522
}
523
524
unsigned char *oggpackB_get_buffer(oggpack_buffer *b){
525
return oggpack_get_buffer(b);
526
}
527
528
/* Self test of the bitwise routines; everything else is based on
529
them, so they damned well better be solid. */
530
531
#ifdef _V_SELFTEST
532
#include <stdio.h>
533
534
static int ilog(unsigned int v){
535
int ret=0;
536
while(v){
537
ret++;
538
v>>=1;
539
}
540
return(ret);
541
}
542
543
oggpack_buffer o;
544
oggpack_buffer r;
545
546
void report(char *in){
547
fprintf(stderr,"%s",in);
548
exit(1);
549
}
550
551
void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
552
long bytes,i;
553
unsigned char *buffer;
554
555
oggpack_reset(&o);
556
for(i=0;i<vals;i++)
557
oggpack_write(&o,b[i],bits?bits:ilog(b[i]));
558
buffer=oggpack_get_buffer(&o);
559
bytes=oggpack_bytes(&o);
560
if(bytes!=compsize)report("wrong number of bytes!\n");
561
for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
562
for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
563
report("wrote incorrect value!\n");
564
}
565
oggpack_readinit(&r,buffer,bytes);
566
for(i=0;i<vals;i++){
567
int tbit=bits?bits:ilog(b[i]);
568
if(oggpack_look(&r,tbit)==-1)
569
report("out of data!\n");
570
if((unsigned long)oggpack_look(&r,tbit)!=(b[i]&mask[tbit]))
571
report("looked at incorrect value!\n");
572
if(tbit==1)
573
if((unsigned long)oggpack_look1(&r)!=(b[i]&mask[tbit]))
574
report("looked at single bit incorrect value!\n");
575
if(tbit==1){
576
if((unsigned long)oggpack_read1(&r)!=(b[i]&mask[tbit]))
577
report("read incorrect single bit value!\n");
578
}else{
579
if((unsigned long)oggpack_read(&r,tbit)!=(b[i]&mask[tbit]))
580
report("read incorrect value!\n");
581
}
582
}
583
if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
584
}
585
586
void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){
587
long bytes,i;
588
unsigned char *buffer;
589
590
oggpackB_reset(&o);
591
for(i=0;i<vals;i++)
592
oggpackB_write(&o,b[i],bits?bits:ilog(b[i]));
593
buffer=oggpackB_get_buffer(&o);
594
bytes=oggpackB_bytes(&o);
595
if(bytes!=compsize)report("wrong number of bytes!\n");
596
for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){
597
for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]);
598
report("wrote incorrect value!\n");
599
}
600
oggpackB_readinit(&r,buffer,bytes);
601
for(i=0;i<vals;i++){
602
int tbit=bits?bits:ilog(b[i]);
603
if(oggpackB_look(&r,tbit)==-1)
604
report("out of data!\n");
605
if((unsigned long)oggpackB_look(&r,tbit)!=(b[i]&mask[tbit]))
606
report("looked at incorrect value!\n");
607
if(tbit==1)
608
if((unsigned long)oggpackB_look1(&r)!=(b[i]&mask[tbit]))
609
report("looked at single bit incorrect value!\n");
610
if(tbit==1){
611
if((unsigned long)oggpackB_read1(&r)!=(b[i]&mask[tbit]))
612
report("read incorrect single bit value!\n");
613
}else{
614
if((unsigned long)oggpackB_read(&r,tbit)!=(b[i]&mask[tbit]))
615
report("read incorrect value!\n");
616
}
617
}
618
if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
619
}
620
621
void copytest(int prefill, int copy){
622
oggpack_buffer source_write;
623
oggpack_buffer dest_write;
624
oggpack_buffer source_read;
625
oggpack_buffer dest_read;
626
unsigned char *source;
627
unsigned char *dest;
628
long source_bytes,dest_bytes;
629
int i;
630
631
oggpack_writeinit(&source_write);
632
oggpack_writeinit(&dest_write);
633
634
for(i=0;i<(prefill+copy+7)/8;i++)
635
oggpack_write(&source_write,(i^0x5a)&0xff,8);
636
source=oggpack_get_buffer(&source_write);
637
source_bytes=oggpack_bytes(&source_write);
638
639
/* prefill */
640
oggpack_writecopy(&dest_write,source,prefill);
641
642
/* check buffers; verify end byte masking */
643
dest=oggpack_get_buffer(&dest_write);
644
dest_bytes=oggpack_bytes(&dest_write);
645
if(dest_bytes!=(prefill+7)/8){
646
fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
647
exit(1);
648
}
649
oggpack_readinit(&source_read,source,source_bytes);
650
oggpack_readinit(&dest_read,dest,dest_bytes);
651
652
for(i=0;i<prefill;i+=8){
653
int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
654
int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
655
if(s!=d){
656
fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
657
exit(1);
658
}
659
}
660
if(prefill<dest_bytes){
661
if(oggpack_read(&dest_read,dest_bytes-prefill)!=0){
662
fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
663
exit(1);
664
}
665
}
666
667
/* second copy */
668
oggpack_writecopy(&dest_write,source,copy);
669
670
/* check buffers; verify end byte masking */
671
dest=oggpack_get_buffer(&dest_write);
672
dest_bytes=oggpack_bytes(&dest_write);
673
if(dest_bytes!=(copy+prefill+7)/8){
674
fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
675
exit(1);
676
}
677
oggpack_readinit(&source_read,source,source_bytes);
678
oggpack_readinit(&dest_read,dest,dest_bytes);
679
680
for(i=0;i<prefill;i+=8){
681
int s=oggpack_read(&source_read,prefill-i<8?prefill-i:8);
682
int d=oggpack_read(&dest_read,prefill-i<8?prefill-i:8);
683
if(s!=d){
684
fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
685
exit(1);
686
}
687
}
688
689
oggpack_readinit(&source_read,source,source_bytes);
690
for(i=0;i<copy;i+=8){
691
int s=oggpack_read(&source_read,copy-i<8?copy-i:8);
692
int d=oggpack_read(&dest_read,copy-i<8?copy-i:8);
693
if(s!=d){
694
fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
695
exit(1);
696
}
697
}
698
699
if(copy+prefill<dest_bytes){
700
if(oggpack_read(&dest_read,dest_bytes-copy-prefill)!=0){
701
fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
702
exit(1);
703
}
704
}
705
706
oggpack_writeclear(&source_write);
707
oggpack_writeclear(&dest_write);
708
709
710
}
711
712
void copytestB(int prefill, int copy){
713
oggpack_buffer source_write;
714
oggpack_buffer dest_write;
715
oggpack_buffer source_read;
716
oggpack_buffer dest_read;
717
unsigned char *source;
718
unsigned char *dest;
719
long source_bytes,dest_bytes;
720
int i;
721
722
oggpackB_writeinit(&source_write);
723
oggpackB_writeinit(&dest_write);
724
725
for(i=0;i<(prefill+copy+7)/8;i++)
726
oggpackB_write(&source_write,(i^0x5a)&0xff,8);
727
source=oggpackB_get_buffer(&source_write);
728
source_bytes=oggpackB_bytes(&source_write);
729
730
/* prefill */
731
oggpackB_writecopy(&dest_write,source,prefill);
732
733
/* check buffers; verify end byte masking */
734
dest=oggpackB_get_buffer(&dest_write);
735
dest_bytes=oggpackB_bytes(&dest_write);
736
if(dest_bytes!=(prefill+7)/8){
737
fprintf(stderr,"wrong number of bytes after prefill! %ld!=%d\n",dest_bytes,(prefill+7)/8);
738
exit(1);
739
}
740
oggpackB_readinit(&source_read,source,source_bytes);
741
oggpackB_readinit(&dest_read,dest,dest_bytes);
742
743
for(i=0;i<prefill;i+=8){
744
int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
745
int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
746
if(s!=d){
747
fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
748
exit(1);
749
}
750
}
751
if(prefill<dest_bytes){
752
if(oggpackB_read(&dest_read,dest_bytes-prefill)!=0){
753
fprintf(stderr,"prefill=%d mismatch! trailing bits not zero\n",prefill);
754
exit(1);
755
}
756
}
757
758
/* second copy */
759
oggpackB_writecopy(&dest_write,source,copy);
760
761
/* check buffers; verify end byte masking */
762
dest=oggpackB_get_buffer(&dest_write);
763
dest_bytes=oggpackB_bytes(&dest_write);
764
if(dest_bytes!=(copy+prefill+7)/8){
765
fprintf(stderr,"wrong number of bytes after prefill+copy! %ld!=%d\n",dest_bytes,(copy+prefill+7)/8);
766
exit(1);
767
}
768
oggpackB_readinit(&source_read,source,source_bytes);
769
oggpackB_readinit(&dest_read,dest,dest_bytes);
770
771
for(i=0;i<prefill;i+=8){
772
int s=oggpackB_read(&source_read,prefill-i<8?prefill-i:8);
773
int d=oggpackB_read(&dest_read,prefill-i<8?prefill-i:8);
774
if(s!=d){
775
fprintf(stderr,"prefill=%d mismatch! byte %d, %x!=%x\n",prefill,i/8,s,d);
776
exit(1);
777
}
778
}
779
780
oggpackB_readinit(&source_read,source,source_bytes);
781
for(i=0;i<copy;i+=8){
782
int s=oggpackB_read(&source_read,copy-i<8?copy-i:8);
783
int d=oggpackB_read(&dest_read,copy-i<8?copy-i:8);
784
if(s!=d){
785
fprintf(stderr,"prefill=%d copy=%d mismatch! byte %d, %x!=%x\n",prefill,copy,i/8,s,d);
786
exit(1);
787
}
788
}
789
790
if(copy+prefill<dest_bytes){
791
if(oggpackB_read(&dest_read,dest_bytes-copy-prefill)!=0){
792
fprintf(stderr,"prefill=%d copy=%d mismatch! trailing bits not zero\n",prefill,copy);
793
exit(1);
794
}
795
}
796
797
oggpackB_writeclear(&source_write);
798
oggpackB_writeclear(&dest_write);
799
800
}
801
802
int main(void){
803
unsigned char *buffer;
804
long bytes,i,j;
805
static unsigned long testbuffer1[]=
806
{18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
807
567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
808
int test1size=43;
809
810
static unsigned long testbuffer2[]=
811
{216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
812
1233432,534,5,346435231,14436467,7869299,76326614,167548585,
813
85525151,0,12321,1,349528352};
814
int test2size=21;
815
816
static unsigned long testbuffer3[]=
817
{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,
818
0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
819
int test3size=56;
820
821
static unsigned long large[]=
822
{2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
823
1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
824
85525151,0,12321,1,2146528352};
825
826
int onesize=33;
827
static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
828
34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
829
223,4};
830
static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
831
8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
832
245,251,128};
833
834
int twosize=6;
835
static int two[6]={61,255,255,251,231,29};
836
static int twoB[6]={247,63,255,253,249,120};
837
838
int threesize=54;
839
static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
840
142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
841
58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
842
100,52,4,14,18,86,77,1};
843
static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
844
130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
845
233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
846
200,20,254,4,58,106,176,144,0};
847
848
int foursize=38;
849
static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
850
132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
851
28,2,133,0,1};
852
static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
853
1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
854
129,10,4,32};
855
856
int fivesize=45;
857
static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
858
241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
859
84,75,159,2,1,0,132,192,8,0,0,18,22};
860
static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
861
124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
862
172,150,169,129,79,128,0,6,4,32,0,27,9,0};
863
864
int sixsize=7;
865
static int six[7]={17,177,170,242,169,19,148};
866
static int sixB[7]={136,141,85,79,149,200,41};
867
868
/* Test read/write together */
869
/* Later we test against pregenerated bitstreams */
870
oggpack_writeinit(&o);
871
872
fprintf(stderr,"\nSmall preclipped packing (LSb): ");
873
cliptest(testbuffer1,test1size,0,one,onesize);
874
fprintf(stderr,"ok.");
875
876
fprintf(stderr,"\nNull bit call (LSb): ");
877
cliptest(testbuffer3,test3size,0,two,twosize);
878
fprintf(stderr,"ok.");
879
880
fprintf(stderr,"\nLarge preclipped packing (LSb): ");
881
cliptest(testbuffer2,test2size,0,three,threesize);
882
fprintf(stderr,"ok.");
883
884
fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
885
oggpack_reset(&o);
886
for(i=0;i<test2size;i++)
887
oggpack_write(&o,large[i],32);
888
buffer=oggpack_get_buffer(&o);
889
bytes=oggpack_bytes(&o);
890
oggpack_readinit(&r,buffer,bytes);
891
for(i=0;i<test2size;i++){
892
if(oggpack_look(&r,32)==-1)report("out of data. failed!");
893
if((unsigned long)oggpack_look(&r,32)!=large[i]){
894
fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpack_look(&r,32),large[i],
895
oggpack_look(&r,32),large[i]);
896
report("read incorrect value!\n");
897
}
898
oggpack_adv(&r,32);
899
}
900
if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n");
901
fprintf(stderr,"ok.");
902
903
fprintf(stderr,"\nSmall unclipped packing (LSb): ");
904
cliptest(testbuffer1,test1size,7,four,foursize);
905
fprintf(stderr,"ok.");
906
907
fprintf(stderr,"\nLarge unclipped packing (LSb): ");
908
cliptest(testbuffer2,test2size,17,five,fivesize);
909
fprintf(stderr,"ok.");
910
911
fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
912
cliptest(testbuffer3,test3size,1,six,sixsize);
913
fprintf(stderr,"ok.");
914
915
fprintf(stderr,"\nTesting read past end (LSb): ");
916
oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
917
for(i=0;i<64;i++){
918
if(oggpack_read(&r,1)!=0){
919
fprintf(stderr,"failed; got -1 prematurely.\n");
920
exit(1);
921
}
922
}
923
if(oggpack_look(&r,1)!=-1 ||
924
oggpack_read(&r,1)!=-1){
925
fprintf(stderr,"failed; read past end without -1.\n");
926
exit(1);
927
}
928
oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
929
if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){
930
fprintf(stderr,"failed 2; got -1 prematurely.\n");
931
exit(1);
932
}
933
934
if(oggpack_look(&r,18)!=0 ||
935
oggpack_look(&r,18)!=0){
936
fprintf(stderr,"failed 3; got -1 prematurely.\n");
937
exit(1);
938
}
939
if(oggpack_look(&r,19)!=-1 ||
940
oggpack_look(&r,19)!=-1){
941
fprintf(stderr,"failed; read past end without -1.\n");
942
exit(1);
943
}
944
if(oggpack_look(&r,32)!=-1 ||
945
oggpack_look(&r,32)!=-1){
946
fprintf(stderr,"failed; read past end without -1.\n");
947
exit(1);
948
}
949
oggpack_writeclear(&o);
950
fprintf(stderr,"ok.");
951
952
/* this is partly glassbox; we're mostly concerned about the allocation boundaries */
953
954
fprintf(stderr,"\nTesting aligned writecopies (LSb): ");
955
for(i=0;i<71;i++)
956
for(j=0;j<5;j++)
957
copytest(j*8,i);
958
for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
959
for(j=0;j<5;j++)
960
copytest(j*8,i);
961
fprintf(stderr,"ok. ");
962
963
fprintf(stderr,"\nTesting unaligned writecopies (LSb): ");
964
for(i=0;i<71;i++)
965
for(j=1;j<40;j++)
966
if(j&0x7)
967
copytest(j,i);
968
for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
969
for(j=1;j<40;j++)
970
if(j&0x7)
971
copytest(j,i);
972
973
fprintf(stderr,"ok. \n");
974
975
976
/********** lazy, cut-n-paste retest with MSb packing ***********/
977
978
/* Test read/write together */
979
/* Later we test against pregenerated bitstreams */
980
oggpackB_writeinit(&o);
981
982
fprintf(stderr,"\nSmall preclipped packing (MSb): ");
983
cliptestB(testbuffer1,test1size,0,oneB,onesize);
984
fprintf(stderr,"ok.");
985
986
fprintf(stderr,"\nNull bit call (MSb): ");
987
cliptestB(testbuffer3,test3size,0,twoB,twosize);
988
fprintf(stderr,"ok.");
989
990
fprintf(stderr,"\nLarge preclipped packing (MSb): ");
991
cliptestB(testbuffer2,test2size,0,threeB,threesize);
992
fprintf(stderr,"ok.");
993
994
fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
995
oggpackB_reset(&o);
996
for(i=0;i<test2size;i++)
997
oggpackB_write(&o,large[i],32);
998
buffer=oggpackB_get_buffer(&o);
999
bytes=oggpackB_bytes(&o);
1000
oggpackB_readinit(&r,buffer,bytes);
1001
for(i=0;i<test2size;i++){
1002
if(oggpackB_look(&r,32)==-1)report("out of data. failed!");
1003
if((unsigned long)oggpackB_look(&r,32)!=large[i]){
1004
fprintf(stderr,"%ld != %lu (%lx!=%lx):",oggpackB_look(&r,32),large[i],
1005
oggpackB_look(&r,32),large[i]);
1006
report("read incorrect value!\n");
1007
}
1008
oggpackB_adv(&r,32);
1009
}
1010
if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n");
1011
fprintf(stderr,"ok.");
1012
1013
fprintf(stderr,"\nSmall unclipped packing (MSb): ");
1014
cliptestB(testbuffer1,test1size,7,fourB,foursize);
1015
fprintf(stderr,"ok.");
1016
1017
fprintf(stderr,"\nLarge unclipped packing (MSb): ");
1018
cliptestB(testbuffer2,test2size,17,fiveB,fivesize);
1019
fprintf(stderr,"ok.");
1020
1021
fprintf(stderr,"\nSingle bit unclipped packing (MSb): ");
1022
cliptestB(testbuffer3,test3size,1,sixB,sixsize);
1023
fprintf(stderr,"ok.");
1024
1025
fprintf(stderr,"\nTesting read past end (MSb): ");
1026
oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
1027
for(i=0;i<64;i++){
1028
if(oggpackB_read(&r,1)!=0){
1029
fprintf(stderr,"failed; got -1 prematurely.\n");
1030
exit(1);
1031
}
1032
}
1033
if(oggpackB_look(&r,1)!=-1 ||
1034
oggpackB_read(&r,1)!=-1){
1035
fprintf(stderr,"failed; read past end without -1.\n");
1036
exit(1);
1037
}
1038
oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8);
1039
if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){
1040
fprintf(stderr,"failed 2; got -1 prematurely.\n");
1041
exit(1);
1042
}
1043
1044
if(oggpackB_look(&r,18)!=0 ||
1045
oggpackB_look(&r,18)!=0){
1046
fprintf(stderr,"failed 3; got -1 prematurely.\n");
1047
exit(1);
1048
}
1049
if(oggpackB_look(&r,19)!=-1 ||
1050
oggpackB_look(&r,19)!=-1){
1051
fprintf(stderr,"failed; read past end without -1.\n");
1052
exit(1);
1053
}
1054
if(oggpackB_look(&r,32)!=-1 ||
1055
oggpackB_look(&r,32)!=-1){
1056
fprintf(stderr,"failed; read past end without -1.\n");
1057
exit(1);
1058
}
1059
fprintf(stderr,"ok.");
1060
oggpackB_writeclear(&o);
1061
1062
/* this is partly glassbox; we're mostly concerned about the allocation boundaries */
1063
1064
fprintf(stderr,"\nTesting aligned writecopies (MSb): ");
1065
for(i=0;i<71;i++)
1066
for(j=0;j<5;j++)
1067
copytestB(j*8,i);
1068
for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
1069
for(j=0;j<5;j++)
1070
copytestB(j*8,i);
1071
fprintf(stderr,"ok. ");
1072
1073
fprintf(stderr,"\nTesting unaligned writecopies (MSb): ");
1074
for(i=0;i<71;i++)
1075
for(j=1;j<40;j++)
1076
if(j&0x7)
1077
copytestB(j,i);
1078
for(i=BUFFER_INCREMENT*8-71;i<BUFFER_INCREMENT*8+71;i++)
1079
for(j=1;j<40;j++)
1080
if(j&0x7)
1081
copytestB(j,i);
1082
1083
fprintf(stderr,"ok. \n\n");
1084
1085
return(0);
1086
}
1087
#endif /* _V_SELFTEST */
1088
1089
#undef BUFFER_INCREMENT
1090
1091