com.github.axet.libogg.Joggpack_buffer Maven / Gradle / Ivy
package com.github.axet.libogg;
import java.util.Arrays;
// XXX what is oggpackB_ functions? may be, it can be removed?
public final class Joggpack_buffer {
int endbyte = 0;
int endbit = 0;
public byte[] buffer = null;
int ptr = 0;
public int storage = 0;
public void clear() {
this.endbyte = 0;
this.endbit = 0;
this.buffer = null;
this.ptr = 0;
this.storage = 0;
}
// bitwise.c
private static final int BUFFER_INCREMENT = 256;
private static final int mask[] = {
0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
0x3fffffff,0x7fffffff,0xffffffff };
private static final int mask8B[] = {
0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
public final void oggpack_writeinit() {
this.endbit = 0;
this.endbyte = 0;
this.ptr = 0;
this.buffer = new byte[ BUFFER_INCREMENT ];
// buffer[0] = '\0';// java: already zeroed
this.storage = BUFFER_INCREMENT;
}
public final int oggpack_writecheck() {
if( this.ptr < 0 || this.storage == 0 ) {
return -1;
}
return 0;
}
public final int oggpackB_writecheck() {
return oggpack_writecheck();
}
public final void oggpack_writetrunc(int bits) {
final int bytes = bits >> 3;
if( this.ptr >= 0 ) {
bits -= bytes << 3;
this.ptr = bytes;
this.endbit = bits;
this.endbyte = bytes;
this.buffer[this.ptr] &= mask[bits];
}
}
public final void oggpackB_writetrunc(int bits) {
final int bytes = bits >> 3;
if( this.ptr >= 0 ) {
bits -= bytes << 3;
this.ptr = bytes;
this.endbit = bits;
this.endbyte = bytes;
this.buffer[this.ptr] &= mask8B[bits];
}
}
public final void oggpackB_writeinit() {
oggpack_writeinit();
}
public final void oggpack_writeclear() {
this.buffer = null;
this.endbit = 0;
this.endbyte = 0;
this.ptr = -1;
this.storage = 0;
}
public final void oggpackB_writeclear() {
oggpack_writeclear();
}
/** Takes only up to 32 bits. */
public final void oggpack_write(int value, int bits) {
if( bits < 0 || bits > 32) {
oggpack_writeclear();
return;
}
if( this.endbyte >= this.storage - 4 ) {
if( this.ptr < 0 ) {
return;
}
if( this.storage > Integer.MAX_VALUE - BUFFER_INCREMENT ) {
oggpack_writeclear();
return;
}
this.storage += BUFFER_INCREMENT;
this.buffer = Arrays.copyOf( this.buffer, this.storage );
this.ptr = this.endbyte;
}
value &= mask[bits];
final int end = this.endbit;// java
bits += end;
final byte[] b = this.buffer;// java
int off = this.ptr;// java
b[off] |= value << end;
if( bits >= 8 ) {
b[++off] = (byte)(value >>> (8 - end));
if( bits >= 16 ) {
b[++off] = (byte)(value >>> (16 - end));
if( bits >= 24 ) {
b[++off] = (byte)(value >>> (24 - end));
if( bits >= 32 ) {
if( end != 0 ) {
b[++off] = (byte)(value >>> (32 - end));
} else {
b[++off] = 0;
}
}
}
}
}
this.endbit = bits & 7;
bits >>>= 3;
this.endbyte += bits;
this.ptr += bits;
return;
}
/** Takes only up to 32 bits. */
private final void oggpackB_write(int value, int bits) {
if( bits < 0 || bits > 32 ) {
oggpack_writeclear();
return;
}
if( this.endbyte >= this.storage - 4 ) {
if( this.ptr < 0 ) {
return;
}
if( this.storage > Integer.MAX_VALUE - BUFFER_INCREMENT ) {
oggpack_writeclear();
return;
}
this.storage += BUFFER_INCREMENT;
this.buffer = Arrays.copyOf( this.buffer, this.storage );
this.ptr = this.endbyte;
}
value = (value & mask[bits]) << (32 - bits);
final int end = this.endbit;// java
bits += end;
final byte[] b = this.buffer;// java
int off = this.ptr;// java
b[off] |= value >>> (24 + end);
if( bits >= 8 ) {
b[++off] = (byte)(value >>> (16 + end));
if( bits >= 16 ) {
b[++off] = (byte)(value >>> (8 + end));
if( bits >= 24 ) {
b[++off] = (byte)(value >>> (end));
if( bits >= 32 ) {
if( end != 0 ) {
b[++off] = (byte)(value << (8 - end));
} else {
b[++off] = 0;
}
}
}
}
}
this.endbit = bits & 7;
bits >>>= 3;
this.endbyte += bits;
this.ptr += bits;
return;
}
public final void oggpack_writealign() {
final int bits = 8 - this.endbit;
if( bits < 8 ) {
oggpack_write( 0, bits );
}
}
public final void oggpackB_writealign() {
final int bits = 8 - this.endbit;
if( bits < 8 ) {
oggpackB_write( 0, bits );
}
}
private final void oggpack_writecopy_helper(
final byte[] source,
int bits,
// void (*w)(oggpack_buffer *, unsigned long, int),// java: use if( msb ) oggpackB_write : oggpack_write;
final boolean msb )
{
final int bytes = bits >>> 3;
final int pbytes = (this.endbit + bits) >>> 3;
bits -= bytes << 3;
/* expand storage up-front */
if( this.endbyte + pbytes >= this.storage ) {
if( this.ptr < 0 ) {
oggpack_writeclear();
return;
}
if( this.storage > this.endbyte + pbytes + BUFFER_INCREMENT ) {
oggpack_writeclear();
return;
}
this.storage = this.endbyte + pbytes + BUFFER_INCREMENT;
this.buffer = Arrays.copyOf( this.buffer, this.storage );
this.ptr = this.endbyte;
}
/* copy whole octets */
if( this.endbit != 0 ) {
/* unaligned copy. Do it the hard way. */
if( msb ) {
for( int i = 0; i < bytes; i++ ) {
oggpackB_write( (int)source[i], 8 );
}
} else {
for( int i = 0; i < bytes; i++ ) {
oggpack_write( (int)source[i], 8 );
}
}
} else {
/* aligned block copy */
System.arraycopy( source, 0, this.buffer, this.ptr, bytes );
this.ptr += bytes;
this.endbyte += bytes;
this.buffer[this.ptr] = 0;
}
/* copy trailing bits */
if( bits != 0 ) {
if( msb ) {
oggpackB_write( (int)(source[bytes] >>> (8 - bits)), bits );
} else {
oggpack_write( (int)source[bytes], bits );
}
}
}
public final void oggpack_writecopy(final byte[] source, final int bits) {
oggpack_writecopy_helper( source, bits, false );
}
public final void oggpackB_writecopy(final byte[] source, final int bits) {
oggpack_writecopy_helper( source, bits, true );
}
public final void oggpack_reset() {
if( this.ptr < 0 ) {
return;
}
this.ptr = 0;
this.buffer[0] = 0;
this.endbit = this.endbyte = 0;
}
public final void oggpackB_reset() {
oggpack_reset();
}
private final void oggpack_readinit(final byte[] buf, final int bytes) {
this.endbit = 0;
this.endbyte = 0;
this.buffer = buf;
this.ptr = 0;
this.storage = bytes;
}
public final void oggpack_readinit(final byte[] buf, final int offset, final int bytes) {// added
this.endbit = 0;
this.endbyte = 0;
this.buffer = buf;
this.ptr = offset;
this.storage = bytes;
}
public final void oggpackB_readinit(final byte[] buf, final int bytes) {
oggpack_readinit( buf, bytes );
}
/** Read in bits without advancing the bitptr; bits <= 32 */
public final int oggpack_look(int bits) {
if( bits < 0 || bits > 32 ) {
return -1;
}
final int m = mask[bits];// unsigned long
final int end = this.endbit;// java
bits += end;
if( this.endbyte >= this.storage - 4 ) {
/* not the main path */
if( this.endbyte > this.storage - ((bits + 7) >> 3) ) {
return -1;
} else if( bits == 0 ) {
return 0;
}
}
final byte[] b = this.buffer;// java
int off = this.ptr;// java
int ret = (((int)b[off]) & 0xff) >>> end;// unsigned long
if( bits > 8 ) {
ret |= (((int)b[++off]) & 0xff) << (8 - end);
if( bits > 16 ) {
ret |= (((int)b[++off]) & 0xff) << (16 - end);
if( bits > 24 ) {
ret |= (((int)b[++off]) & 0xff) << (24 - end);
if( bits > 32 && end != 0 ) {
ret |= (((int)b[++off]) & 0xff) << (32 - end);
}
}
}
}
return (m & ret);
}
/** Read in bits without advancing the bitptr; bits <= 32 */
public final int oggpackB_look(int bits) {
int ret;// unsigned long
final int m = 32 - bits;
if( m < 0 || m > 32 ) {
return -1;
}
final int end = this.endbit;// java
bits += end;
if( this.endbyte >= this.storage - 4 ) {
/* not the main path */
if( this.endbyte > this.storage - ((bits + 7) >> 3)) {
return -1;
} else if( bits == 0 ) {
return 0;
}
}
final byte[] b = this.buffer;// java
int off = this.ptr;// java
ret = (((int)b[off]) & 0xff) << (24 + end);
if( bits > 8 ) {
ret |= (((int)b[++off]) & 0xff) << (16 + end);
if( bits > 16 ) {
ret |= (((int)b[++off]) & 0xff) << (8 + end);
if( bits > 24 ) {
ret |= (((int)b[++off]) & 0xff) << (end);
if( bits > 32 && end != 0 ) {
ret |= (((int)b[++off]) & 0xff) >>> (8 - end);
}
}
}
}
return (ret >>> (m >> 1)) >>> ((m + 1) >> 1);
}
public final int oggpack_look1() {
if( this.endbyte >= this.storage ) {
return (-1);
}
return ((this.buffer[this.ptr] >>> this.endbit) & 1);
}
public final int oggpackB_look1() {
if( this.endbyte >= this.storage ) {
return (-1);
}
return ((this.buffer[this.ptr] >>> (7 - this.endbit)) & 1);
}
public final void oggpack_adv(int bits) {
bits += this.endbit;
if( this.endbyte > this.storage - ((bits + 7) >> 3) ) {// overflow
this.ptr = -1;
this.endbyte = this.storage;
this.endbit = 1;
return;
}
this.endbit = bits & 7;
bits >>>= 3;
this.ptr += bits;
this.endbyte += bits;
return;
}
public final void oggpackB_adv(final int bits) {
oggpack_adv( bits );
}
public final void oggpack_adv1() {
if( ++(this.endbit) > 7) {
this.endbit = 0;
this.ptr++;
this.endbyte++;
}
}
public final void oggpackB_adv1() {
oggpack_adv1();
}
/** bits <= 32 */
public final int oggpack_read(int bits) {
if( bits < 0 || bits > 32 ) {//goto err;
this.ptr = -1;
this.endbyte = this.storage;
this.endbit = 1;
return -1;
}
final int m = mask[bits];
final int end = this.endbit;// java
bits += end;
if( this.endbyte >= this.storage - 4 ) {
/* not the main path */
if( this.endbyte > this.storage - ((bits + 7) >> 3) ) {//goto overflow;
this.ptr = -1;
this.endbyte = this.storage;
this.endbit = 1;
return -1;
}
/* special case to avoid reading b->ptr[0], which might be past the end of
the buffer; also skips some useless accounting */
else if( bits == 0 ) {
return 0;
}
}
final byte[] b = this.buffer;// java
int off = this.ptr;// java
int ret = (((int)b[off]) & 0xff) >>> end;
if( bits > 8 ){
ret |= (((int)b[++off]) & 0xff) << (8 - end);
if( bits > 16 ) {
ret |= (((int)b[++off]) & 0xff) << (16 - end);
if( bits > 24 ){
ret |= (((int)b[++off]) & 0xff) << (24 - end);
if( bits > 32 && end != 0 ) {
ret |= (((int)b[++off]) & 0xff) << (32 - end);
}
}
}
}
ret &= m;
this.endbit = bits & 7;
bits >>>= 3;
this.ptr += bits;
this.endbyte += bits;
return ret;
}
/** bits <= 32 */
public final int oggpackB_read(int bits) {
final int m = 32 - bits;
if( m < 0 || m > 32 ) {//goto err;
this.ptr = -1;
this.endbyte = this.storage;
this.endbit = 1;
return -1;
}
final int end = this.endbit;// java
bits += end;
if( this.endbyte + 4 >= this.storage ) {
/* not the main path */
if( this.endbyte > this.storage - ((bits + 7) >> 3)) {//goto overflow;
this.ptr = -1;
this.endbyte = this.storage;
this.endbit = 1;
return -1;
}
/* special case to avoid reading b->ptr[0], which might be past the end of
the buffer; also skips some useless accounting */
else if( bits == 0 ) {
return 0;
}
}
final byte[] b = this.buffer;// java
int off = this.ptr;// java
int ret = (((int)b[off]) & 0xff) << (24 + end);
if( bits > 8 ) {
ret |= (((int)b[++off]) & 0xff) << (16 + end);
if( bits > 16 ) {
ret |= (((int)b[++off]) & 0xff) << (8 + end);
if( bits > 24 ) {
ret |= (((int)b[++off]) & 0xff) << (end);
if( bits > 32 && end != 0 ) {
ret |= (((int)b[++off]) & 0xff) >>> (8 - end);
}
}
}
}
ret = (ret >>> (m >> 1)) >>> ((m + 1) >> 1);
this.endbit = bits & 7;
bits >>>= 3;
this.ptr += bits;
this.endbyte += bits;
return ret;
}
public final int oggpack_read1() {
if( this.endbyte >= this.storage ) {//goto overflow;
this.ptr = -1;
this.endbyte = this.storage;
this.endbit = 1;
return -1;
}
final int ret = (this.buffer[this.ptr] >>> this.endbit) & 1;
this.endbit++;
if( this.endbit > 7 ) {
this.endbit = 0;
this.ptr++;
this.endbyte++;
}
return ret;
}
public final int oggpackB_read1() {
if( this.endbyte >= this.storage ) {//goto overflow;
this.ptr = -1;
this.endbyte = this.storage;
this.endbit = 1;
return -1;
}
final int ret = (this.buffer[this.ptr] >>> (7 - this.endbit)) & 1;
this.endbit++;
if( this.endbit > 7 ) {
this.endbit = 0;
this.ptr++;
this.endbyte++;
}
return ret;
}
public final int oggpack_bytes() {
return (this.endbyte + ((this.endbit + 7) >>> 3));
}
public final int oggpack_bits() {
return ((this.endbyte << 3) + this.endbit);
}
public final int oggpackB_bytes() {
return oggpack_bytes();
}
public final int oggpackB_bits() {
return oggpack_bits();
}
public final byte[] oggpack_get_buffer() {
return this.buffer;
}
public final byte[] oggpackB_get_buffer() {
return oggpack_get_buffer();
}
/* XXX Self test of the bitwise routines; everything else is based on
//them, so they damned well better be solid.
//#ifdef _V_SELFTEST
private static int ilog(int v) {
int ret = 0;
while( v != 0 ) {
ret++;
v >>>= 1;
}
return ret;
}
private static Joggpack_buffer o = new Joggpack_buffer();
private static Joggpack_buffer r = new Joggpack_buffer();
private static void report(final String in){
System.err.println( in );
System.exit( 1 );
}
@SuppressWarnings("boxing")
private static void cliptest(final int[] b, final int vals, final int bits, final int[] comp, final int compsize) {
int bytes, i;
byte[] buffer;
o.oggpack_reset();
for( i = 0; i < vals; i++ ) {
o.oggpack_write( b[i], (bits != 0) ? bits : ilog( b[i] ) );
}
buffer = o.oggpack_get_buffer();
bytes = o.oggpack_bytes();
if( bytes != compsize ) {
report("wrong number of bytes!\n");
}
for( i = 0; i < bytes; i++ ) {
if( (((int)buffer[i]) & 0xff) != comp[i] ) {
for( i = 0; i < bytes; i++ ) {
System.err.printf("%x %x\n", (int)buffer[i], comp[i] );
}
report("wrote incorrect value!\n");
}
}
r.oggpack_readinit( buffer, bytes );
for( i = 0; i < vals; i++ ) {
final int tbit = (bits != 0) ? bits : ilog( b[i] );
if( r.oggpack_look( tbit ) == -1 ) {
report("out of data!\n");
}
if( r.oggpack_look( tbit ) != (b[i] & mask[tbit]) ) {
report("looked at incorrect value!\n");
}
if( tbit == 1) {
if( r.oggpack_look1() != (b[i] & mask[tbit]) ) {
report("looked at single bit incorrect value!\n");
}
}
if( tbit == 1 ) {
if( r.oggpack_read1() != (b[i] & mask[tbit]) ) {
report("read incorrect single bit value!\n");
}
} else {
if( r.oggpack_read( tbit ) != (b[i] & mask[tbit]) ) {
report("read incorrect value!\n");
}
}
}
if( r.oggpack_bytes() != bytes ) {
report("leftover bytes after read!\n");
}
}
@SuppressWarnings("boxing")
private static void cliptestB(final int[] b, final int vals, final int bits, final int[] comp, final int compsize) {
int bytes,i;
byte[] buffer;
o.oggpackB_reset();
for( i = 0; i < vals; i++ ) {
o.oggpackB_write( b[i], (bits != 0) ? bits : ilog( b[i] ) );
}
buffer = o.oggpackB_get_buffer();
bytes = o.oggpackB_bytes();
if( bytes != compsize ) {
report("wrong number of bytes!\n");
}
for( i = 0; i < bytes; i++ ) {
if( (((int)buffer[i]) & 0xff) != comp[i] ) {
for( i = 0; i < bytes; i++ ) {
System.err.printf("%x %x\n", (int)buffer[i], comp[i] );
}
report("wrote incorrect value!\n");
}
}
r.oggpackB_readinit( buffer, bytes );
for( i = 0; i < vals; i++ ) {
final int tbit = (bits != 0) ? bits : ilog( b[i] );
if( r.oggpackB_look( tbit ) == -1 ) {
report("out of data!\n");
}
if( r.oggpackB_look( tbit ) != (b[i] & mask[tbit]) ) {
report("looked at incorrect value!\n");
}
if( tbit == 1 ) {
if( r.oggpackB_look1() != (b[i] & mask[tbit]) ) {
report("looked at single bit incorrect value!\n");
}
}
if( tbit == 1 ) {
if( r.oggpackB_read1() != (b[i] & mask[tbit]) ) {
report("read incorrect single bit value!\n");
}
} else {
if( r.oggpackB_read( tbit ) != (b[i] & mask[tbit]) ) {
report("read incorrect value!\n");
}
}
}
if( r.oggpackB_bytes() != bytes ) {
report("leftover bytes after read!\n");
}
}
private static final void copytest(final int prefill, final int copy){
final Joggpack_buffer source_write = new Joggpack_buffer();
final Joggpack_buffer dest_write = new Joggpack_buffer();
final Joggpack_buffer source_read = new Joggpack_buffer();
final Joggpack_buffer dest_read = new Joggpack_buffer();
byte[] source;
byte[] dest;
int source_bytes, dest_bytes;
int i;
source_write.oggpack_writeinit();
dest_write.oggpack_writeinit();
for( i = 0; i < (prefill + copy + 7) / 8; i++ ) {
source_write.oggpack_write( (i ^ 0x5a) & 0xff, 8 );
}
source = source_write.oggpack_get_buffer();
source_bytes = source_write.oggpack_bytes();
// prefill
dest_write.oggpack_writecopy( source, prefill );
// check buffers; verify end byte masking
dest = dest_write.oggpack_get_buffer();
dest_bytes = dest_write.oggpack_bytes();
if( dest_bytes != (prefill + 7) / 8 ) {
System.err.printf("wrong number of bytes after prefill! %ld!=%d\n", dest_bytes, (prefill + 7) / 8 );
System.exit( 1 );
}
source_read.oggpack_readinit( source, source_bytes );
dest_read.oggpack_readinit( dest, dest_bytes );
for( i = 0; i < prefill; i += 8 ) {
final int s = source_read.oggpack_read( prefill - i < 8 ? prefill - i : 8 );
final int d = dest_read.oggpack_read( prefill - i < 8 ? prefill - i : 8 );
if( s != d ) {
System.err.printf("prefill=%d mismatch! byte %d, %x!=%x\n", prefill, i / 8, s, d );
System.exit( 1 );
}
}
if( prefill < dest_bytes ) {
if( dest_read.oggpack_read( dest_bytes - prefill ) != 0 ) {
System.err.printf("prefill=%d mismatch! trailing bits not zero\n", prefill );
System.exit( 1 );
}
}
// second copy
dest_write.oggpack_writecopy( source, copy );
// check buffers; verify end byte masking
dest = dest_write.oggpack_get_buffer();
dest_bytes = dest_write.oggpack_bytes();
if( dest_bytes != (copy + prefill + 7) / 8 ) {
System.err.printf("wrong number of bytes after prefill+copy! %ld!=%d\n", dest_bytes, (copy + prefill + 7) / 8 );
System.exit( 1 );
}
source_read.oggpack_readinit( source, source_bytes );
dest_read.oggpack_readinit( dest, dest_bytes );
for( i = 0; i < prefill; i += 8 ) {
final int s = source_read.oggpack_read( prefill - i < 8 ? prefill - i : 8 );
final int d = dest_read.oggpack_read( prefill - i < 8 ? prefill - i : 8 );
if( s != d ) {
System.err.printf("prefill=%d mismatch! byte %d, %x!=%x\n", prefill, i / 8, s, d );
System.exit( 1 );
}
}
source_read.oggpack_readinit( source, source_bytes );
for( i = 0; i < copy; i += 8 ) {
final int s = source_read.oggpack_read( copy - i < 8 ? copy - i : 8 );
final int d = dest_read.oggpack_read( copy - i < 8 ? copy - i : 8 );
if( s != d ) {
System.err.printf("prefill=%d copy=%d mismatch! byte %d, %x!=%x\n", prefill, copy, i / 8, s, d );
System.exit( 1 );
}
}
if( copy + prefill < dest_bytes ) {
if( dest_read.oggpack_read( dest_bytes - copy - prefill ) != 0 ) {
System.err.printf("prefill=%d copy=%d mismatch! trailing bits not zero\n", prefill, copy );
System.exit( 1 );
}
}
source_write.oggpack_writeclear();
dest_write.oggpack_writeclear();
}
private static final void copytestB(final int prefill, final int copy){
final Joggpack_buffer source_write = new Joggpack_buffer();
final Joggpack_buffer dest_write = new Joggpack_buffer();
final Joggpack_buffer source_read = new Joggpack_buffer();
final Joggpack_buffer dest_read = new Joggpack_buffer();
byte[] source;
byte[] dest;
int source_bytes, dest_bytes;
int i;
source_write.oggpackB_writeinit();
dest_write.oggpackB_writeinit();
for( i = 0; i < (prefill + copy + 7) / 8; i++ ) {
source_write.oggpackB_write( (i^0x5a)&0xff, 8 );
}
source = source_write.oggpackB_get_buffer();
source_bytes = source_write.oggpackB_bytes();
// prefill
dest_write.oggpackB_writecopy( source, prefill );
// check buffers; verify end byte masking
dest = dest_write.oggpackB_get_buffer();
dest_bytes = dest_write.oggpackB_bytes();
if( dest_bytes != (prefill + 7) / 8 ) {
System.err.printf("wrong number of bytes after prefill! %ld!=%d\n", dest_bytes, (prefill + 7) / 8 );
System.exit( 1 );
}
source_read.oggpackB_readinit( source, source_bytes );
dest_read.oggpackB_readinit( dest, dest_bytes );
for( i = 0; i < prefill; i += 8 ) {
final int s = source_read.oggpackB_read( prefill - i < 8 ? prefill - i : 8 );
final int d = dest_read.oggpackB_read( prefill - i < 8 ? prefill - i : 8 );
if( s != d ) {
System.err.printf("prefill=%d mismatch! byte %d, %x!=%x\n", prefill, i / 8, s, d );
System.exit( 1 );
}
}
if( prefill < dest_bytes ) {
if( dest_read.oggpackB_read( dest_bytes - prefill ) != 0 ) {
System.err.printf("prefill=%d mismatch! trailing bits not zero\n", prefill );
System.exit( 1 );
}
}
// second copy
dest_write.oggpackB_writecopy( source, copy );
// check buffers; verify end byte masking
dest = dest_write.oggpackB_get_buffer();
dest_bytes = dest_write.oggpackB_bytes();
if( dest_bytes != (copy + prefill + 7) / 8 ) {
System.err.printf("wrong number of bytes after prefill+copy! %ld!=%d\n", dest_bytes, (copy + prefill + 7) / 8 );
System.exit( 1 );
}
source_read.oggpackB_readinit( source, source_bytes );
dest_read.oggpackB_readinit( dest, dest_bytes );
for( i = 0; i < prefill; i += 8 ) {
final int s = source_read.oggpackB_read( prefill - i < 8 ? prefill - i : 8 );
final int d = dest_read.oggpackB_read( prefill - i < 8 ? prefill - i : 8 );
if( s != d ) {
System.err.printf("prefill=%d mismatch! byte %d, %x!=%x\n", prefill, i / 8, s, d );
System.exit( 1 );
}
}
source_read.oggpackB_readinit( source, source_bytes );
for( i = 0; i < copy; i += 8 ) {
final int s = source_read.oggpackB_read( copy - i < 8 ? copy - i : 8 );
final int d = dest_read.oggpackB_read( copy - i < 8 ? copy - i : 8 );
if( s != d ) {
System.err.printf("prefill=%d copy=%d mismatch! byte %d, %x!=%x\n", prefill, copy, i / 8, s, d );
System.exit( 1 );
}
}
if( copy + prefill < dest_bytes ) {
if( dest_read.oggpackB_read( dest_bytes - copy - prefill ) != 0 ) {
System.err.printf("prefill=%d copy=%d mismatch! trailing bits not zero\n", prefill, copy );
System.exit( 1 );
}
}
source_write.oggpackB_writeclear();
dest_write.oggpackB_writeclear();
}
@SuppressWarnings("boxing")
public static void main(final String args[]) {
byte[] buffer;
int bytes, i, j;
final int[] testbuffer1 = {
18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4 };
final int test1size = 43;
final int[] testbuffer2 = {
216531625,1237861823,56732452,131,3212421,12325343,34547562,12313212,
1233432,534,5,346435231,14436467,7869299,76326614,167548585,
85525151,0,12321,1,349528352 };
final int test2size = 21;
final int[] testbuffer3 = {
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,
0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1 };
final int test3size = 56;
final int[] large = {
2136531625,2137861823,56732452,131,3212421,12325343,34547562,12313212,
1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
85525151,0,12321,1,2146528352 };
final int onesize = 33;
final int[] one = { 146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
223,4 };
final int[] oneB = { 150,101,131,33,203,15,204,216,105,193,156,65,84,85,222,
8,139,145,227,126,34,55,244,171,85,100,39,195,173,18,
245,251,128 };
final int twosize = 6;
final int[] two = { 61,255,255,251,231,29 };
final int[] twoB = { 247,63,255,253,249,120 };
final int threesize = 54;
final int[] three = { 169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
100,52,4,14,18,86,77,1 };
final int[] threeB = { 206,128,42,153,57,8,183,251,13,89,36,30,32,144,183,
130,59,240,121,59,85,223,19,228,180,134,33,107,74,98,
233,253,196,135,63,2,110,114,50,155,90,127,37,170,104,
200,20,254,4,58,106,176,144,0 };
final int foursize = 38;
final int[] four = { 18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
28,2,133,0,1 };
final int[] fourB = { 36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41,
1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67,
129,10,4,32 };
final int fivesize = 45;
final int[] five = { 169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
84,75,159,2,1,0,132,192,8,0,0,18,22 };
final int[] fiveB = { 1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226,
124,105,12,0,133,128,0,162,233,242,67,152,77,205,77,
172,150,169,129,79,128,0,6,4,32,0,27,9,0 };
final int sixsize = 7;
final int[] six = { 17,177,170,242,169,19,148 };
final int[] sixB = { 136,141,85,79,149,200,41 };
// Test read/write together
// Later we test against pregenerated bitstreams
o.oggpack_writeinit();
System.err.print("\nSmall preclipped packing (LSb): ");
cliptest( testbuffer1, test1size, 0, one, onesize );
System.err.print("ok.");
System.err.print("\nNull bit call (LSb): ");
cliptest( testbuffer3, test3size, 0, two, twosize );
System.err.print("ok.");
System.err.print("\nLarge preclipped packing (LSb): ");
cliptest( testbuffer2, test2size, 0, three, threesize );
System.err.print("ok.");
System.err.print("\n32 bit preclipped packing (LSb): ");
o.oggpack_reset();
for( i = 0; i < test2size; i++ ) {
o.oggpack_write( large[i], 32 );
}
buffer = o.oggpack_get_buffer();
bytes = o.oggpack_bytes();
r.oggpack_readinit( buffer, bytes );
for( i = 0; i < test2size; i++ ) {
if( r.oggpack_look( 32 ) == -1 ) {
report("out of data. failed!");
}
if( r.oggpack_look( 32 ) != large[i] ) {;
System.err.printf("%d != %d (%x!=%x):", r.oggpack_look( 32 ), large[i],
r.oggpack_look( 32 ), large[i] );
report("read incorrect value!\n");
}
r.oggpack_adv( 32 );
}
if( r.oggpack_bytes() != bytes ) {
report("leftover bytes after read!\n");
}
System.err.print("ok.");
System.err.print("\nSmall unclipped packing (LSb): ");
cliptest(testbuffer1,test1size,7,four,foursize);
System.err.print("ok.");
System.err.print("\nLarge unclipped packing (LSb): ");
cliptest(testbuffer2,test2size,17,five,fivesize);
System.err.print("ok.");
System.err.print("\nSingle bit unclipped packing (LSb): ");
cliptest(testbuffer3,test3size,1,six,sixsize);
System.err.print("ok.");
System.err.print("\nTesting read past end (LSb): ");
r.oggpack_readinit( new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, 8 );
for( i = 0; i < 64; i++ ) {
if( r.oggpack_read( 1 ) != 0 ) {
System.err.print("failed; got -1 prematurely.\n");
System.exit( 1 );
}
}
if( r.oggpack_look( 1 ) != -1 ||
r.oggpack_read( 1) != -1 ) {
System.err.print("failed; read past end without -1.\n");
System.exit( 1 );
}
r.oggpack_readinit( new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }, 8 );
if( r.oggpack_read( 30 ) != 0 || r.oggpack_read( 16 ) != 0 ) {
System.err.print("failed 2; got -1 prematurely.\n");
System.exit( 1 );
}
if( r.oggpack_look( 18 ) != 0 ||
r.oggpack_look( 18 ) != 0) {
System.err.print("failed 3; got -1 prematurely.\n");
System.exit( 1 );
}
if( r.oggpack_look( 19 ) != -1 ||
r.oggpack_look( 19 ) != -1 ) {
System.err.print("failed; read past end without -1.\n");
System.exit( 1 );
}
if( r.oggpack_look( 32 ) != -1 ||
r.oggpack_look( 32 ) != -1 ) {
System.err.print("failed; read past end without -1.\n");
System.exit( 1 );
}
o.oggpack_writeclear();
System.err.print("ok.");
// this is partly glassbox; we're mostly concerned about the allocation boundaries
System.err.print("\nTesting aligned writecopies (LSb): ");
for( i = 0; i < 71; i++ ) {
for( j = 0; j < 5; j++ ) {
copytest( j * 8, i );
}
}
for( i = BUFFER_INCREMENT * 8 - 71; i
© 2015 - 2024 Weber Informatics LLC | Privacy Policy