1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Reference Library 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. *
8 * THE Ogg Reference Library SOURCE CODE IS (C) COPYRIGHT 1994-2004 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: pack variable sized words into an octet stream
16 ********************************************************************/
18 /* the 'ogg2pack_xxx functions are 'LSb' endian; if we write a word but
19 read individual bits, then we'll read the lsb first */
20 /* the 'ogg2packB_xxx functions are 'MSb' endian; if we write a word but
21 read individual bits, then we'll read the msb first */
25 #include "ogginternal.h"
27 static 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 };
36 int ogg2pack_buffersize(void){
37 return sizeof(ogg2pack_buffer
);
40 void ogg2pack_writeinit(ogg2pack_buffer
*b
,ogg2_buffer_state
*bs
){
41 memset(b
,0,sizeof(*b
));
45 void ogg2packB_writeinit(ogg2pack_buffer
*b
,ogg2_buffer_state
*bs
){
46 ogg2pack_writeinit(b
,bs
);
50 static void _ogg2pack_extend(ogg2pack_buffer
*b
){
52 b
->head
->length
=b
->head
->buffer
->size
; /* only because ->begin is always
53 zero in a write buffer */
54 b
->count
+=b
->head
->length
;
55 b
->head
=ogg2_buffer_extend(b
->head
,OGG2PACK_CHUNKSIZE
);
57 b
->head
=b
->tail
=ogg2_buffer_alloc(b
->owner
,OGG2PACK_CHUNKSIZE
);
60 b
->headptr
=b
->head
->buffer
->data
;
61 b
->headend
=b
->head
->buffer
->size
;
64 /* Takes only up to 32 bits. */
65 void ogg2pack_write(ogg2pack_buffer
*b
,unsigned long value
,int bits
){
74 *b
->headptr
|=value
<<b
->headbit
;
78 if(!--b
->headend
)_ogg2pack_extend(b
);
79 *b
->headptr
=value
>>(8-b
->headbit
);
83 if(!--b
->headend
)_ogg2pack_extend(b
);
84 *b
->headptr
=value
>>(16-b
->headbit
);
88 if(!--b
->headend
)_ogg2pack_extend(b
);
89 *b
->headptr
=value
>>(24-b
->headbit
);
93 if(!--b
->headend
)_ogg2pack_extend(b
);
95 *b
->headptr
=value
>>(32-b
->headbit
);
107 /* Takes only up to 32 bits. */
108 void ogg2packB_write(ogg2pack_buffer
*b
,unsigned long value
,int bits
){
110 value
=(value
&mask
[bits
])<<(32-bits
);
115 *b
->headptr
=value
>>24;
117 *b
->headptr
|=value
>>(24+b
->headbit
);
121 if(!--b
->headend
)_ogg2pack_extend(b
);
122 *b
->headptr
=value
>>(16+b
->headbit
);
126 if(!--b
->headend
)_ogg2pack_extend(b
);
127 *b
->headptr
=value
>>(8+b
->headbit
);
131 if(!--b
->headend
)_ogg2pack_extend(b
);
132 *b
->headptr
=value
>>(b
->headbit
);
136 if(!--b
->headend
)_ogg2pack_extend(b
);
138 *b
->headptr
=value
<<(8-b
->headbit
);
149 void ogg2pack_writealign(ogg2pack_buffer
*b
){
150 int bits
=8-b
->headbit
;
152 ogg2pack_write(b
,0,bits
);
155 void ogg2packB_writealign(ogg2pack_buffer
*b
){
156 int bits
=8-b
->headbit
;
158 ogg2packB_write(b
,0,bits
);
161 ogg2_reference
*ogg2pack_writebuffer(ogg2pack_buffer
*b
){
162 /* unlike generic ogg2_buffer_references, the oggpack write buffers
163 will never have any potential prefixed/unused ogg2_buffer data */
165 b
->head
->length
=b
->headptr
-b
->head
->buffer
->data
+(b
->headbit
+7)/8;
169 ogg2_reference
*ogg2packB_writebuffer(ogg2pack_buffer
*b
){
170 return ogg2pack_writebuffer(b
);
173 /* frees and deallocates the ogg2pack_buffer ogg2_buffer usage */
174 void ogg2pack_writeclear(ogg2pack_buffer
*b
){
175 ogg2_buffer_release(b
->tail
);
176 memset(b
,0,sizeof(*b
));
179 void ogg2packB_writeclear(ogg2pack_buffer
*b
){
180 ogg2pack_writeclear(b
);
183 /* mark read process as having run off the end */
184 static void _adv_halt(ogg2pack_buffer
*b
){
185 b
->headptr
=b
->head
->buffer
->data
+b
->head
->begin
+b
->head
->length
;
190 /* spans forward, skipping as many bytes as headend is negative; if
191 headend is zero, simply finds next byte. If we're up to the end
192 of the buffer, leaves headend at zero. If we've read past the end,
193 halt the decode process. */
194 static void _span(ogg2pack_buffer
*b
){
197 b
->count
+=b
->head
->length
;
198 b
->head
=b
->head
->next
;
199 b
->headptr
=b
->head
->buffer
->data
+b
->head
->begin
-b
->headend
;
200 b
->headend
+=b
->head
->length
;
202 /* we've either met the end of decode, or gone past it. halt
203 only if we're past */
204 if(b
->headend
<0 || b
->headbit
)
205 /* read has fallen off the end */
213 void ogg2pack_readinit(ogg2pack_buffer
*b
,ogg2_reference
*r
){
214 memset(b
,0,sizeof(*b
));
218 b
->headptr
=b
->head
->buffer
->data
+b
->head
->begin
;
219 b
->headend
=b
->head
->length
;
223 void ogg2packB_readinit(ogg2pack_buffer
*b
,ogg2_reference
*r
){
224 ogg2pack_readinit(b
,r
);
227 #define _lookspan() while(!end){\
229 if(!head) return -1;\
230 ptr=head->buffer->data + head->begin;\
234 /* Read in bits without advancing the bitptr; bits <= 32 */
235 int ogg2pack_look(ogg2pack_buffer
*b
,int bits
,unsigned long *ret
){
236 unsigned long m
=mask
[bits
];
240 if(bits
>= b
->headend
*8){
242 unsigned char *ptr
=b
->headptr
;
243 ogg2_reference
*head
=b
->head
;
249 *ret
=*ptr
++>>b
->headbit
;
253 *ret
|=*ptr
++<<(8-b
->headbit
);
257 *ret
|=*ptr
++<<(16-b
->headbit
);
261 *ret
|=*ptr
++<<(24-b
->headbit
);
262 if(bits
>32 && b
->headbit
){
265 *ret
|=*ptr
<<(32-b
->headbit
);
274 /* make this a switch jump-table */
275 *ret
=b
->headptr
[0]>>b
->headbit
;
277 *ret
|=b
->headptr
[1]<<(8-b
->headbit
);
279 *ret
|=b
->headptr
[2]<<(16-b
->headbit
);
281 *ret
|=b
->headptr
[3]<<(24-b
->headbit
);
282 if(bits
>32 && b
->headbit
)
283 *ret
|=b
->headptr
[4]<<(32-b
->headbit
);
293 /* Read in bits without advancing the bitptr; bits <= 32 */
294 int ogg2packB_look(ogg2pack_buffer
*b
,int bits
,unsigned long *ret
){
299 if(bits
>= b
->headend
<<3){
301 unsigned char *ptr
=b
->headptr
;
302 ogg2_reference
*head
=b
->head
;
308 *ret
=*ptr
++<<(24+b
->headbit
);
312 *ret
|=*ptr
++<<(16+b
->headbit
);
316 *ret
|=*ptr
++<<(8+b
->headbit
);
320 *ret
|=*ptr
++<<(b
->headbit
);
321 if(bits
>32 && b
->headbit
){
324 *ret
|=*ptr
>>(8-b
->headbit
);
333 *ret
=b
->headptr
[0]<<(24+b
->headbit
);
335 *ret
|=b
->headptr
[1]<<(16+b
->headbit
);
337 *ret
|=b
->headptr
[2]<<(8+b
->headbit
);
339 *ret
|=b
->headptr
[3]<<(b
->headbit
);
340 if(bits
>32 && b
->headbit
)
341 *ret
|=b
->headptr
[4]>>(8-b
->headbit
);
351 long ogg2pack_look1(ogg2pack_buffer
*b
){
352 if(b
->headend
<1)return -1;
353 return (b
->headptr
[0]>>b
->headbit
)&1;
356 long ogg2packB_look1(ogg2pack_buffer
*b
){
357 if(b
->headend
<1)return -1;
358 return (b
->headptr
[0]>>(7-b
->headbit
))&1;
361 /* limited to 32 at a time */
362 void ogg2pack_adv(ogg2pack_buffer
*b
,int bits
){
370 void ogg2packB_adv(ogg2pack_buffer
*b
,int bits
){
371 ogg2pack_adv(b
,bits
);
374 /* spans forward and finds next byte. Never halts */
375 static void _span_one(ogg2pack_buffer
*b
){
378 b
->count
+=b
->head
->length
;
379 b
->head
=b
->head
->next
;
380 b
->headptr
=b
->head
->buffer
->data
+b
->head
->begin
;
381 b
->headend
=b
->head
->length
;
387 void ogg2pack_adv1(ogg2pack_buffer
*b
){
409 void ogg2packB_adv1(ogg2pack_buffer
*b
){
413 static int _halt_one(ogg2pack_buffer
*b
){
422 int ogg2pack_read(ogg2pack_buffer
*b
,int bits
,unsigned long *ret
){
423 unsigned long m
=mask
[bits
];
427 if(bits
>= b
->headend
<<3){
429 if(b
->headend
<0)return(-1);
432 if (_halt_one(b
)) return -1;
433 *ret
=*b
->headptr
>>b
->headbit
;
440 if (_halt_one(b
)) return -1;
441 *ret
|=*b
->headptr
<<(8-b
->headbit
);
448 if (_halt_one(b
)) return -1;
449 *ret
|=*b
->headptr
<<(16-b
->headbit
);
456 if (_halt_one(b
)) return -1;
457 *ret
|=*b
->headptr
<<(24-b
->headbit
);
464 if (_halt_one(b
)) return -1;
465 if(b
->headbit
)*ret
|=*b
->headptr
<<(32-b
->headbit
);
478 *ret
=b
->headptr
[0]>>b
->headbit
;
480 *ret
|=b
->headptr
[1]<<(8-b
->headbit
);
482 *ret
|=b
->headptr
[2]<<(16-b
->headbit
);
484 *ret
|=b
->headptr
[3]<<(24-b
->headbit
);
485 if(bits
>32 && b
->headbit
){
486 *ret
|=b
->headptr
[4]<<(32-b
->headbit
);
502 int ogg2packB_read(ogg2pack_buffer
*b
,int bits
,unsigned long *ret
){
507 if(bits
>= b
->headend
<<3){
509 if(b
->headend
<0)return(-1);
512 if (_halt_one(b
)) return -1;
513 *ret
=*b
->headptr
<<(24+b
->headbit
);
520 if (_halt_one(b
)) return -1;
521 *ret
|=*b
->headptr
<<(16+b
->headbit
);
528 if (_halt_one(b
)) return -1;
529 *ret
|=*b
->headptr
<<(8+b
->headbit
);
536 if (_halt_one(b
)) return -1;
537 *ret
|=*b
->headptr
<<(b
->headbit
);
544 if (_halt_one(b
)) return -1;
545 if(b
->headbit
)*ret
|=*b
->headptr
>>(8-b
->headbit
);
558 *ret
=b
->headptr
[0]<<(24+b
->headbit
);
560 *ret
|=b
->headptr
[1]<<(16+b
->headbit
);
562 *ret
|=b
->headptr
[2]<<(8+b
->headbit
);
564 *ret
|=b
->headptr
[3]<<(b
->headbit
);
565 if(bits
>32 && b
->headbit
)
566 *ret
|=b
->headptr
[4]>>(8-b
->headbit
);
580 long ogg2pack_read1(ogg2pack_buffer
*b
){
584 if (_halt_one(b
)) return -1;
586 ret
=b
->headptr
[0]>>b
->headbit
++;
587 b
->headptr
+=b
->headbit
/8;
588 b
->headend
-=b
->headbit
/8;
593 ret
=b
->headptr
[0]>>b
->headbit
++;
594 b
->headptr
+=b
->headbit
/8;
595 b
->headend
-=b
->headbit
/8;
603 long ogg2packB_read1(ogg2pack_buffer
*b
){
607 if (_halt_one(b
)) return -1;
609 ret
=b
->headptr
[0]>>(7-b
->headbit
++);
610 b
->headptr
+=b
->headbit
/8;
611 b
->headend
-=b
->headbit
/8;
616 ret
=b
->headptr
[0]>>(7-b
->headbit
++);
617 b
->headptr
+=b
->headbit
/8;
618 b
->headend
-=b
->headbit
/8;
626 long ogg2pack_bytes(ogg2pack_buffer
*b
){
627 return(b
->count
+b
->headptr
-b
->head
->buffer
->data
-b
->head
->begin
+
631 long ogg2pack_bits(ogg2pack_buffer
*b
){
632 return((b
->count
+b
->headptr
-b
->head
->buffer
->data
-b
->head
->begin
)*8+
636 long ogg2packB_bytes(ogg2pack_buffer
*b
){
637 return ogg2pack_bytes(b
);
640 long ogg2packB_bits(ogg2pack_buffer
*b
){
641 return ogg2pack_bits(b
);
644 int ogg2pack_eop(ogg2pack_buffer
*b
){
645 return(b
->headend
<0?-1:0);
648 int ogg2packB_eop(ogg2pack_buffer
*b
){
649 return ogg2pack_eop(b
);
652 /* Self test of the bitwise routines; everything else is based on
653 them, so they damned well better be solid. */
658 static int ilog(unsigned int v
){
669 ogg2_buffer_state
*bs
;
671 #define TESTWORDS 4096
673 void report(char *in
){
674 fprintf(stderr
,"%s",in
);
678 int getbyte(ogg2_reference
*or,int position
){
679 while(or && position
>=or->length
){
680 position
-=or->length
;
683 fprintf(stderr
,"\n\tERROR: getbyte ran off end of buffer.\n");
688 return(or->buffer
->data
[position
+or->begin
]);
691 void cliptest(unsigned long *b
,int vals
,int bits
,int *comp
,int compsize
){
692 long bytes
,i
,bitcount
=0;
695 ogg2pack_writeinit(&o
,bs
);
697 ogg2pack_write(&o
,b
[i
],bits
?bits
:ilog(b
[i
]));
698 bitcount
+=bits
?bits
:ilog(b
[i
]);
699 if(bitcount
!=ogg2pack_bits(&o
)){
700 report("wrong number of bits while writing!\n");
702 if((bitcount
+7)/8!=ogg2pack_bytes(&o
)){
703 report("wrong number of bytes while writing!\n");
707 or=ogg2pack_writebuffer(&o
);
708 bytes
=ogg2pack_bytes(&o
);
710 if(bytes
!=compsize
)report("wrong number of bytes!\n");
711 for(i
=0;i
<bytes
;i
++)if(getbyte(or,i
)!=comp
[i
]){
712 for(i
=0;i
<bytes
;i
++)fprintf(stderr
,"%x %x\n",getbyte(or,i
),(int)comp
[i
]);
713 report("wrote incorrect value!\n");
717 ogg2pack_readinit(&r
,or);
720 int tbit
=bits
?bits
:ilog(b
[i
]);
721 if(ogg2pack_look(&r
,tbit
,&test
))
722 report("out of data!\n");
723 if(test
!=(b
[i
]&mask
[tbit
])){
724 fprintf(stderr
,"%ld) %lx %lx\n",i
,(b
[i
]&mask
[tbit
]),test
);
725 report("looked at incorrect value!\n");
728 if(ogg2pack_look1(&r
)!=(int)(b
[i
]&mask
[tbit
]))
729 report("looked at single bit incorrect value!\n");
731 if(ogg2pack_read1(&r
)!=(int)(b
[i
]&mask
[tbit
]))
732 report("read incorrect single bit value!\n");
734 if(ogg2pack_read(&r
,tbit
,&test
)){
735 report("premature end of data when reading!\n");
737 if(test
!=(b
[i
]&mask
[tbit
])){
738 fprintf(stderr
,"%ld) %lx %lx\n",i
,(b
[i
]&mask
[tbit
]),test
);
739 report("read incorrect value!\n");
744 if(bitcount
!=ogg2pack_bits(&r
))
745 report("wrong number of bits while reading!\n");
746 if((bitcount
+7)/8!=ogg2pack_bytes(&r
))
747 report("wrong number of bytes while reading!\n");
750 if(ogg2pack_bytes(&r
)!=bytes
)report("leftover bytes after read!\n");
751 ogg2pack_writeclear(&o
);
755 void cliptestB(unsigned long *b
,int vals
,int bits
,int *comp
,int compsize
){
759 ogg2packB_writeinit(&o
,bs
);
761 ogg2packB_write(&o
,b
[i
],bits
?bits
:ilog(b
[i
]));
762 or=ogg2packB_writebuffer(&o
);
763 bytes
=ogg2packB_bytes(&o
);
764 if(bytes
!=compsize
)report("wrong number of bytes!\n");
765 for(i
=0;i
<bytes
;i
++)if(getbyte(or,i
)!=comp
[i
]){
766 for(i
=0;i
<bytes
;i
++)fprintf(stderr
,"%x %x\n",getbyte(or,i
),(int)comp
[i
]);
767 report("wrote incorrect value!\n");
769 ogg2packB_readinit(&r
,or);
772 int tbit
=bits
?bits
:ilog(b
[i
]);
773 if(ogg2packB_look(&r
,tbit
,&test
))
774 report("out of data!\n");
775 if(test
!=(b
[i
]&mask
[tbit
]))
776 report("looked at incorrect value!\n");
778 if(ogg2packB_look1(&r
)!=(int)(b
[i
]&mask
[tbit
]))
779 report("looked at single bit incorrect value!\n");
781 if(ogg2packB_read1(&r
)!=(int)(b
[i
]&mask
[tbit
]))
782 report("read incorrect single bit value!\n");
784 if(ogg2packB_read(&r
,tbit
,&test
))
785 report("premature end of data when reading!\n");
786 if(test
!=(b
[i
]&mask
[tbit
]))
787 report("read incorrect value!\n");
790 if(ogg2packB_bytes(&r
)!=bytes
)report("leftover bytes after read!\n");
791 ogg2packB_writeclear(&o
);
794 int flatten (unsigned char *flat
){
795 unsigned char *ptr
=flat
;
796 ogg2_reference
*head
=ogg2pack_writebuffer(&o
);
798 memcpy(ptr
,head
->buffer
->data
+head
->begin
,head
->length
);
805 void lsbverify(unsigned long *values
,int *len
,unsigned char *flat
) {
810 /* verify written buffer is correct bit-by-bit */
811 for(j
=0;j
<TESTWORDS
;j
++){
812 for(k
=0;k
<len
[j
];k
++){
813 int origbit
=(values
[j
]>>k
)&1;
814 int bit
=(flat
[flatbyte
]>>flatbit
)&1;
822 fprintf(stderr
,"\n\tERROR: bit mismatch! "
823 "word %d, bit %d, value %lx, len %d\n",
824 j
,k
,values
[j
],len
[j
]);
831 /* verify that trailing packing is zeroed */
832 while(flatbit
&& flatbit
<8){
833 int bit
=(flat
[flatbyte
]>>flatbit
++)&1;
836 fprintf(stderr
,"\n\tERROR: trailing byte padding not zero!\n");
844 void msbverify(unsigned long *values
,int *len
,unsigned char *flat
) {
849 /* verify written buffer is correct bit-by-bit */
850 for(j
=0;j
<TESTWORDS
;j
++){
851 for(k
=0;k
<len
[j
];k
++){
852 int origbit
=(values
[j
]>>(len
[j
]-k
-1))&1;
853 int bit
=(flat
[flatbyte
]>>(7-flatbit
))&1;
861 fprintf(stderr
,"\n\tERROR: bit mismatch! "
862 "word %d, bit %d, value %lx, len %d\n",
863 j
,k
,values
[j
],len
[j
]);
870 /* verify that trailing packing is zeroed */
871 while(flatbit
&& flatbit
<8){
872 int bit
=(flat
[flatbyte
]>>(7-flatbit
++))&1;
875 fprintf(stderr
,"\n\tERROR: trailing byte padding not zero!\n");
882 void _end_verify(int count
){
886 /* are the proper number of bits left over? */
887 int leftover
=count
*8-ogg2pack_bits(&o
);
889 report("\nERROR: too many bits reported left over.\n");
891 /* does reading to exactly byte alignment *not* trip EOF? */
892 if(ogg2pack_read(&o
,leftover
,&temp
))
893 report("\nERROR: read to but not past exact end tripped EOF.\n");
894 if(ogg2pack_bits(&o
)!=count
*8)
895 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
897 /* does EOF trip properly after a single additional bit? */
898 if(!ogg2pack_read(&o
,1,&temp
))
899 report("\nERROR: read past exact end did not trip EOF.\n");
900 if(ogg2pack_bits(&o
)!=count
*8)
901 report("\nERROR: read past exact end reported bad bitcount.\n");
903 /* does EOF stay set over additional bit reads? */
905 if(!ogg2pack_read(&o
,i
,&temp
))
906 report("\nERROR: EOF did not stay set on stream.\n");
907 if(ogg2pack_bits(&o
)!=count
*8)
908 report("\nERROR: read past exact end reported bad bitcount.\n");
912 void _end_verify2(int count
){
915 /* are the proper number of bits left over? */
916 int leftover
=count
*8-ogg2pack_bits(&o
);
918 report("\nERROR: too many bits reported left over.\n");
920 /* does reading to exactly byte alignment *not* trip EOF? */
921 ogg2pack_adv(&o
,leftover
);
923 report("\nERROR: read to but not past exact end tripped EOF.\n");
924 if(ogg2pack_bits(&o
)!=count
*8)
925 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
927 /* does EOF trip properly after a single additional bit? */
930 report("\nERROR: read past exact end did not trip EOF.\n");
931 if(ogg2pack_bits(&o
)!=count
*8)
932 report("\nERROR: read past exact end reported bad bitcount.\n");
934 /* does EOF stay set over additional bit reads? */
938 report("\nERROR: EOF did not stay set on stream.\n");
939 if(ogg2pack_bits(&o
)!=count
*8)
940 report("\nERROR: read past exact end reported bad bitcount.\n");
944 void _end_verify3(int count
){
948 /* are the proper number of bits left over? */
949 int leftover
=count
*8-ogg2packB_bits(&o
);
951 report("\nERROR: too many bits reported left over.\n");
953 /* does reading to exactly byte alignment *not* trip EOF? */
954 if(ogg2packB_read(&o
,leftover
,&temp
))
955 report("\nERROR: read to but not past exact end tripped EOF.\n");
956 if(ogg2packB_bits(&o
)!=count
*8)
957 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
959 /* does EOF trip properly after a single additional bit? */
960 if(!ogg2packB_read(&o
,1,&temp
))
961 report("\nERROR: read past exact end did not trip EOF.\n");
962 if(ogg2packB_bits(&o
)!=count
*8)
963 report("\nERROR: read past exact end reported bad bitcount.\n");
965 /* does EOF stay set over additional bit reads? */
967 if(!ogg2packB_read(&o
,i
,&temp
))
968 report("\nERROR: EOF did not stay set on stream.\n");
969 if(ogg2packB_bits(&o
)!=count
*8)
970 report("\nERROR: read past exact end reported bad bitcount.\n");
974 void _end_verify4(int count
){
977 /* are the proper number of bits left over? */
978 int leftover
=count
*8-ogg2packB_bits(&o
);
980 report("\nERROR: too many bits reported left over.\n");
982 /* does reading to exactly byte alignment *not* trip EOF? */
983 for(i
=0;i
<leftover
;i
++){
986 report("\nERROR: read to but not past exact end tripped EOF.\n");
988 if(ogg2packB_bits(&o
)!=count
*8)
989 report("\nERROR: read to but not past exact end reported bad bitcount.\n");
991 /* does EOF trip properly after a single additional bit? */
994 report("\nERROR: read past exact end did not trip EOF.\n");
995 if(ogg2packB_bits(&o
)!=count
*8)
996 report("\nERROR: read past exact end reported bad bitcount.\n");
998 /* does EOF stay set over additional bit reads? */
1002 report("\nERROR: EOF did not stay set on stream.\n");
1003 if(ogg2packB_bits(&o
)!=count
*8)
1004 report("\nERROR: read past exact end reported bad bitcount.\n");
1010 static unsigned long testbuffer1
[]=
1011 {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
1012 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
1015 static unsigned long testbuffer2
[]=
1016 {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
1017 1233432,534,5,346435231,14436467,7869299,76326614,167548585,
1018 85525151,0,12321,1,349528352};
1021 static unsigned long testbuffer3
[]=
1022 {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,
1023 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
1026 static unsigned long large
[]=
1027 {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
1028 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
1029 85525151,0,12321,1,2146528352};
1032 static int one
[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
1033 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
1035 static int oneB
[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
1036 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
1040 static int two
[6]={61,255,255,251,231,29};
1041 static int twoB
[6]={247,63,255,253,249,120};
1044 static int three
[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
1045 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
1046 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
1047 100,52,4,14,18,86,77,1};
1048 static int threeB
[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
1049 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
1050 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
1051 200,20,254,4,58,106,176,144,0};
1054 static int four
[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
1055 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
1057 static int fourB
[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
1058 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
1062 static int five
[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
1063 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
1064 84,75,159,2,1,0,132,192,8,0,0,18,22};
1065 static int fiveB
[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
1066 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
1067 172,150,169,129,79,128,0,6,4,32,0,27,9,0};
1070 static int six
[7]={17,177,170,242,169,19,148};
1071 static int sixB
[7]={136,141,85,79,149,200,41};
1073 /* Test read/write together */
1074 /* Later we test against pregenerated bitstreams */
1075 bs
=ogg2_buffer_create();
1077 fprintf(stderr
,"\nSmall preclipped packing (LSb): ");
1078 cliptest(testbuffer1
,test1size
,0,one
,onesize
);
1079 fprintf(stderr
,"ok.");
1081 fprintf(stderr
,"\nNull bit call (LSb): ");
1082 cliptest(testbuffer3
,test3size
,0,two
,twosize
);
1083 fprintf(stderr
,"ok.");
1085 fprintf(stderr
,"\nLarge preclipped packing (LSb): ");
1086 cliptest(testbuffer2
,test2size
,0,three
,threesize
);
1087 fprintf(stderr
,"ok.");
1089 fprintf(stderr
,"\n32 bit preclipped packing (LSb): ");
1091 ogg2pack_writeclear(&o
);
1092 ogg2pack_writeinit(&o
,bs
);
1093 for(i
=0;i
<test2size
;i
++)
1094 ogg2pack_write(&o
,large
[i
],32);
1095 or=ogg2pack_writebuffer(&o
);
1096 bytes
=ogg2pack_bytes(&o
);
1097 ogg2pack_readinit(&r
,or);
1098 for(i
=0;i
<test2size
;i
++){
1100 if(ogg2pack_look(&r
,32,&test
)==-1)report("out of data. failed!");
1102 fprintf(stderr
,"%ld != %ld (%lx!=%lx):",test
,large
[i
],
1104 report("read incorrect value!\n");
1106 ogg2pack_adv(&r
,32);
1108 if(ogg2pack_bytes(&r
)!=bytes
)report("leftover bytes after read!\n");
1109 fprintf(stderr
,"ok.");
1111 fprintf(stderr
,"\nSmall unclipped packing (LSb): ");
1112 cliptest(testbuffer1
,test1size
,7,four
,foursize
);
1113 fprintf(stderr
,"ok.");
1115 fprintf(stderr
,"\nLarge unclipped packing (LSb): ");
1116 cliptest(testbuffer2
,test2size
,17,five
,fivesize
);
1117 fprintf(stderr
,"ok.");
1119 fprintf(stderr
,"\nSingle bit unclipped packing (LSb): ");
1120 cliptest(testbuffer3
,test3size
,1,six
,sixsize
);
1121 fprintf(stderr
,"ok.");
1123 fprintf(stderr
,"\nTesting read past end (LSb): ");
1125 ogg2_buffer lob
={"\0\0\0\0\0\0\0\0",8,0,{0}};
1126 ogg2_reference lor
={&lob
,0,8,0,1};
1128 ogg2pack_readinit(&r
,&lor
);
1130 if(ogg2pack_read1(&r
)!=0){
1131 fprintf(stderr
,"failed; got -1 prematurely.\n");
1135 if(ogg2pack_look1(&r
)!=-1 ||
1136 ogg2pack_read1(&r
)!=-1){
1137 fprintf(stderr
,"failed; read past end without -1.\n");
1142 ogg2_buffer lob
={"\0\0\0\0\0\0\0\0",8,0,{0}};
1143 ogg2_reference lor
={&lob
,0,8,0,1};
1146 ogg2pack_readinit(&r
,&lor
);
1147 if(ogg2pack_read(&r
,30,&test
)!=0 || ogg2pack_read(&r
,16,&test
)!=0){
1148 fprintf(stderr
,"failed 2; got -1 prematurely.\n");
1152 if(ogg2pack_look(&r
,18,&test
)!=0){
1153 fprintf(stderr
,"failed 3; got -1 prematurely.\n");
1156 if(ogg2pack_look(&r
,19,&test
)!=-1){
1157 fprintf(stderr
,"failed; read past end without -1.\n");
1160 if(ogg2pack_look(&r
,32,&test
)!=-1){
1161 fprintf(stderr
,"failed; read past end without -1.\n");
1165 fprintf(stderr
,"ok.\n");
1166 ogg2pack_writeclear(&o
);
1168 /********** lazy, cut-n-paste retest with MSb packing ***********/
1170 /* Test read/write together */
1171 /* Later we test against pregenerated bitstreams */
1173 fprintf(stderr
,"\nSmall preclipped packing (MSb): ");
1174 cliptestB(testbuffer1
,test1size
,0,oneB
,onesize
);
1175 fprintf(stderr
,"ok.");
1177 fprintf(stderr
,"\nNull bit call (MSb): ");
1178 cliptestB(testbuffer3
,test3size
,0,twoB
,twosize
);
1179 fprintf(stderr
,"ok.");
1181 fprintf(stderr
,"\nLarge preclipped packing (MSb): ");
1182 cliptestB(testbuffer2
,test2size
,0,threeB
,threesize
);
1183 fprintf(stderr
,"ok.");
1185 fprintf(stderr
,"\n32 bit preclipped packing (MSb): ");
1187 ogg2packB_writeinit(&o
,bs
);
1188 for(i
=0;i
<test2size
;i
++)
1189 ogg2packB_write(&o
,large
[i
],32);
1190 or=ogg2packB_writebuffer(&o
);
1191 bytes
=ogg2packB_bytes(&o
);
1192 ogg2packB_readinit(&r
,or);
1193 for(i
=0;i
<test2size
;i
++){
1195 if(ogg2packB_look(&r
,32,&test
)==-1)report("out of data. failed!");
1197 fprintf(stderr
,"%ld != %ld (%lx!=%lx):",test
,large
[i
],
1199 report("read incorrect value!\n");
1201 ogg2packB_adv(&r
,32);
1203 if(ogg2packB_bytes(&r
)!=bytes
)report("leftover bytes after read!\n");
1204 fprintf(stderr
,"ok.");
1206 fprintf(stderr
,"\nSmall unclipped packing (MSb): ");
1207 cliptestB(testbuffer1
,test1size
,7,fourB
,foursize
);
1208 fprintf(stderr
,"ok.");
1210 fprintf(stderr
,"\nLarge unclipped packing (MSb): ");
1211 cliptestB(testbuffer2
,test2size
,17,fiveB
,fivesize
);
1212 fprintf(stderr
,"ok.");
1214 fprintf(stderr
,"\nSingle bit unclipped packing (MSb): ");
1215 cliptestB(testbuffer3
,test3size
,1,sixB
,sixsize
);
1216 fprintf(stderr
,"ok.");
1218 fprintf(stderr
,"\nTesting read past end (MSb): ");
1220 ogg2_buffer lob
={"\0\0\0\0\0\0\0\0",8,0,{0}};
1221 ogg2_reference lor
={&lob
,0,8,0,1};
1224 ogg2packB_readinit(&r
,&lor
);
1226 if(ogg2packB_read(&r
,1,&test
)){
1227 fprintf(stderr
,"failed; got -1 prematurely.\n");
1231 if(ogg2packB_look(&r
,1,&test
)!=-1 ||
1232 ogg2packB_read(&r
,1,&test
)!=-1){
1233 fprintf(stderr
,"failed; read past end without -1.\n");
1238 ogg2_buffer lob
={"\0\0\0\0\0\0\0\0",8,0,{0}};
1239 ogg2_reference lor
={&lob
,0,8,0,1};
1241 ogg2packB_readinit(&r
,&lor
);
1243 if(ogg2packB_read(&r
,30,&test
)!=0 || ogg2packB_read(&r
,16,&test
)!=0){
1244 fprintf(stderr
,"failed 2; got -1 prematurely.\n");
1248 if(ogg2packB_look(&r
,18,&test
)!=0){
1249 fprintf(stderr
,"failed 3; got -1 prematurely.\n");
1252 if(ogg2packB_look(&r
,19,&test
)!=-1){
1253 fprintf(stderr
,"failed 4; read past end without -1.\n");
1256 if(ogg2packB_look(&r
,32,&test
)!=-1){
1257 fprintf(stderr
,"failed 5; read past end without -1.\n");
1260 fprintf(stderr
,"ok.\n\n");
1262 ogg2packB_writeclear(&o
);
1264 /* now the scary shit: randomized testing */
1266 for(i
=0;i
<10000;i
++){
1267 int j
,count
=0,count2
=0,bitcount
=0;
1268 unsigned long values
[TESTWORDS
];
1270 unsigned char flat
[4*TESTWORDS
]; /* max possible needed size */
1272 fprintf(stderr
,"\rRandomized testing (LSb)... (%ld) ",10000-i
);
1273 ogg2pack_writeinit(&o
,bs
);
1275 /* generate a list of words and lengths */
1276 /* write the required number of bits out to packbuffer */
1277 for(j
=0;j
<TESTWORDS
;j
++){
1281 ogg2pack_write(&o
,values
[j
],len
[j
]);
1284 if(ogg2pack_bits(&o
)!=bitcount
){
1285 fprintf(stderr
,"\nERROR: Write bitcounter %d != %ld!\n",
1286 bitcount
,ogg2pack_bits(&o
));
1289 if(ogg2pack_bytes(&o
)!=(bitcount
+7)/8){
1290 fprintf(stderr
,"\nERROR: Write bytecounter %d != %ld!\n",
1291 (bitcount
+7)/8,ogg2pack_bytes(&o
));
1297 /* flatten the packbuffer out to a vector */
1298 count2
=flatten(flat
);
1299 if(count2
<(bitcount
+7)/8){
1300 fprintf(stderr
,"\nERROR: flattened write buffer incorrect length\n");
1303 ogg2pack_writeclear(&o
);
1305 /* verify against original list */
1306 lsbverify(values
,len
,flat
);
1308 /* construct random-length buffer chain from flat vector; random
1309 byte starting offset within the length of the vector */
1311 ogg2_reference
*or=NULL
,*orl
=NULL
;
1312 unsigned char *ptr
=flat
;
1314 /* build buffer chain */
1316 int ilen
=(rand()%32);
1317 int ibegin
=(rand()%32);
1319 if(ilen
>count2
)ilen
=count2
;
1322 orl
=ogg2_buffer_extend(orl
,ilen
+ibegin
);
1324 or=orl
=ogg2_buffer_alloc(bs
,ilen
+ibegin
);
1326 memcpy(orl
->buffer
->data
+ibegin
,ptr
,ilen
);
1335 if(ogg2_buffer_length(or)!=(bitcount
+7)/8){
1336 fprintf(stderr
,"\nERROR: buffer length incorrect after build.\n");
1342 int begin
=(rand()%TESTWORDS
);
1343 int ilen
=(rand()%(TESTWORDS
-begin
));
1344 int bitoffset
,bitcount
=0;
1347 for(j
=0;j
<begin
;j
++)
1349 or=ogg2_buffer_pretruncate(or,bitcount
/8);
1350 bitoffset
=bitcount
%=8;
1351 for(;j
<begin
+ilen
;j
++)
1353 ogg2_buffer_posttruncate(or,((bitcount
+7)/8));
1355 if((count
=ogg2_buffer_length(or))!=(bitcount
+7)/8){
1356 fprintf(stderr
,"\nERROR: buffer length incorrect after truncate.\n");
1360 ogg2pack_readinit(&o
,or);
1362 /* verify bit count */
1363 if(ogg2pack_bits(&o
)!=0){
1364 fprintf(stderr
,"\nERROR: Read bitcounter not zero!\n");
1367 if(ogg2pack_bytes(&o
)!=0){
1368 fprintf(stderr
,"\nERROR: Read bytecounter not zero!\n");
1373 ogg2pack_read(&o
,bitoffset
,&temp
);
1375 /* read and compare to original list */
1376 for(j
=begin
;j
<begin
+ilen
;j
++){
1378 if(len
[j
]==1 && rand()%1)
1379 temp
=ret
=ogg2pack_read1(&o
);
1381 ret
=ogg2pack_read(&o
,len
[j
],&temp
);
1383 fprintf(stderr
,"\nERROR: End of stream too soon! word: %d,%d\n",
1387 if(temp
!=(values
[j
]&mask
[len
[j
]])){
1388 fprintf(stderr
,"\nERROR: Incorrect read %lx != %lx, word %d, len %d\n",
1389 values
[j
]&mask
[len
[j
]],temp
,j
-begin
,len
[j
]);
1393 if(ogg2pack_bits(&o
)!=bitcount
){
1394 fprintf(stderr
,"\nERROR: Read bitcounter %d != %ld!\n",
1395 bitcount
,ogg2pack_bits(&o
));
1398 if(ogg2pack_bytes(&o
)!=(bitcount
+7)/8){
1399 fprintf(stderr
,"\nERROR: Read bytecounter %d != %ld!\n",
1400 (bitcount
+7)/8,ogg2pack_bytes(&o
));
1407 /* look/adv version */
1408 ogg2pack_readinit(&o
,or);
1410 ogg2pack_adv(&o
,bitoffset
);
1412 /* read and compare to original list */
1413 for(j
=begin
;j
<begin
+ilen
;j
++){
1415 if(len
[j
]==1 && rand()%1)
1416 temp
=ret
=ogg2pack_look1(&o
);
1418 ret
=ogg2pack_look(&o
,len
[j
],&temp
);
1421 fprintf(stderr
,"\nERROR: End of stream too soon! word: %d\n",
1425 if(temp
!=(values
[j
]&mask
[len
[j
]])){
1426 fprintf(stderr
,"\nERROR: Incorrect look %lx != %lx, word %d, len %d\n",
1427 values
[j
]&mask
[len
[j
]],temp
,j
-begin
,len
[j
]);
1430 if(len
[j
]==1 && rand()%1)
1433 ogg2pack_adv(&o
,len
[j
]);
1435 if(ogg2pack_bits(&o
)!=bitcount
){
1436 fprintf(stderr
,"\nERROR: Look/Adv bitcounter %d != %ld!\n",
1437 bitcount
,ogg2pack_bits(&o
));
1440 if(ogg2pack_bytes(&o
)!=(bitcount
+7)/8){
1441 fprintf(stderr
,"\nERROR: Look/Adv bytecounter %d != %ld!\n",
1442 (bitcount
+7)/8,ogg2pack_bytes(&o
));
1447 _end_verify2(count
);
1450 ogg2_buffer_release(or);
1453 fprintf(stderr
,"\rRandomized testing (LSb)... ok. \n");
1455 /* cut & paste: lazy bastahd alert */
1457 for(i
=0;i
<10000;i
++){
1458 int j
,count
,count2
=0,bitcount
=0;
1459 unsigned long values
[TESTWORDS
];
1461 unsigned char flat
[4*TESTWORDS
]; /* max possible needed size */
1463 fprintf(stderr
,"\rRandomized testing (MSb)... (%ld) ",10000-i
);
1464 ogg2packB_writeinit(&o
,bs
);
1466 /* generate a list of words and lengths */
1467 /* write the required number of bits out to packbuffer */
1468 for(j
=0;j
<TESTWORDS
;j
++){
1472 ogg2packB_write(&o
,values
[j
],len
[j
]);
1475 if(ogg2packB_bits(&o
)!=bitcount
){
1476 fprintf(stderr
,"\nERROR: Write bitcounter %d != %ld!\n",
1477 bitcount
,ogg2packB_bits(&o
));
1480 if(ogg2packB_bytes(&o
)!=(bitcount
+7)/8){
1481 fprintf(stderr
,"\nERROR: Write bytecounter %d != %ld!\n",
1482 (bitcount
+7)/8,ogg2packB_bytes(&o
));
1488 /* flatten the packbuffer out to a vector */
1489 count2
=flatten(flat
);
1490 if(count2
<(bitcount
+7)/8){
1491 fprintf(stderr
,"\nERROR: flattened write buffer incorrect length\n");
1494 ogg2packB_writeclear(&o
);
1496 /* verify against original list */
1497 msbverify(values
,len
,flat
);
1499 /* construct random-length buffer chain from flat vector; random
1500 byte starting offset within the length of the vector */
1502 ogg2_reference
*or=NULL
,*orl
=NULL
;
1503 unsigned char *ptr
=flat
;
1505 /* build buffer chain */
1507 int ilen
=(rand()%32);
1508 int ibegin
=(rand()%32);
1510 if(ilen
>count2
)ilen
=count2
;
1513 orl
=ogg2_buffer_extend(orl
,ilen
+ibegin
);
1515 or=orl
=ogg2_buffer_alloc(bs
,ilen
+ibegin
);
1517 memcpy(orl
->buffer
->data
+ibegin
,ptr
,ilen
);
1526 if(ogg2_buffer_length(or)!=(bitcount
+7)/8){
1527 fprintf(stderr
,"\nERROR: buffer length incorrect after build.\n");
1533 int begin
=(rand()%TESTWORDS
);
1534 int ilen
=(rand()%(TESTWORDS
-begin
));
1535 int bitoffset
,bitcount
=0;
1538 for(j
=0;j
<begin
;j
++)
1540 /* also exercise the split code */
1542 ogg2_reference
*temp
=ogg2_buffer_split(&or,0,bitcount
/8);
1543 ogg2_buffer_release(temp
);
1546 bitoffset
=bitcount
%=8;
1547 for(;j
<begin
+ilen
;j
++)
1549 ogg2_buffer_posttruncate(or,((bitcount
+7)/8));
1551 if((count
=ogg2_buffer_length(or))!=(bitcount
+7)/8){
1552 fprintf(stderr
,"\nERROR: buffer length incorrect after truncate.\n");
1556 ogg2packB_readinit(&o
,or);
1558 /* verify bit count */
1559 if(ogg2packB_bits(&o
)!=0){
1560 fprintf(stderr
,"\nERROR: Read bitcounter not zero!\n");
1563 if(ogg2packB_bytes(&o
)!=0){
1564 fprintf(stderr
,"\nERROR: Read bytecounter not zero!\n");
1569 ogg2packB_read(&o
,bitoffset
,&temp
);
1571 /* read and compare to original list */
1572 for(j
=begin
;j
<begin
+ilen
;j
++){
1574 if(len
[j
]==1 && rand()%1)
1575 temp
=ret
=ogg2packB_read1(&o
);
1577 ret
=ogg2packB_read(&o
,len
[j
],&temp
);
1579 fprintf(stderr
,"\nERROR: End of stream too soon! word: %d,%d\n",
1583 if(temp
!=(values
[j
]&mask
[len
[j
]])){
1584 fprintf(stderr
,"\nERROR: Incorrect read %lx != %lx, word %d, len %d\n",
1585 values
[j
]&mask
[len
[j
]],temp
,j
-begin
,len
[j
]);
1589 if(ogg2packB_bits(&o
)!=bitcount
){
1590 fprintf(stderr
,"\nERROR: Read bitcounter %d != %ld!\n",
1591 bitcount
,ogg2packB_bits(&o
));
1594 if(ogg2packB_bytes(&o
)!=(bitcount
+7)/8){
1595 fprintf(stderr
,"\nERROR: Read bytecounter %d != %ld!\n",
1596 (bitcount
+7)/8,ogg2packB_bytes(&o
));
1601 _end_verify3(count
);
1603 /* look/adv version */
1604 ogg2packB_readinit(&o
,or);
1606 ogg2packB_adv(&o
,bitoffset
);
1608 /* read and compare to original list */
1609 for(j
=begin
;j
<begin
+ilen
;j
++){
1611 if(len
[j
]==1 && rand()%1)
1612 temp
=ret
=ogg2packB_look1(&o
);
1614 ret
=ogg2packB_look(&o
,len
[j
],&temp
);
1617 fprintf(stderr
,"\nERROR: End of stream too soon! word: %d\n",
1621 if(temp
!=(values
[j
]&mask
[len
[j
]])){
1622 fprintf(stderr
,"\nERROR: Incorrect look %lx != %lx, word %d, len %d\n",
1623 values
[j
]&mask
[len
[j
]],temp
,j
-begin
,len
[j
]);
1626 if(len
[j
]==1 && rand()%1)
1629 ogg2packB_adv(&o
,len
[j
]);
1631 if(ogg2packB_bits(&o
)!=bitcount
){
1632 fprintf(stderr
,"\nERROR: Look/Adv bitcounter %d != %ld!\n",
1633 bitcount
,ogg2packB_bits(&o
));
1636 if(ogg2packB_bytes(&o
)!=(bitcount
+7)/8){
1637 fprintf(stderr
,"\nERROR: Look/Adv bytecounter %d != %ld!\n",
1638 (bitcount
+7)/8,ogg2packB_bytes(&o
));
1643 _end_verify4(count
);
1646 ogg2_buffer_release(or);
1649 fprintf(stderr
,"\rRandomized testing (MSb)... ok. \n");
1651 ogg2_buffer_destroy(bs
);
1654 #endif /* _V_SELFTEST */