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