001/* JOrbis 002 * Copyright (C) 2000 ymnk, JCraft,Inc. 003 * 004 * Written by: 2000 ymnk<ymnk@jcaft.com> 005 * 006 * Many thanks to 007 * Monty <monty@xiph.org> and 008 * The XIPHOPHORUS Company http://www.xiph.org/ . 009 * JOrbis has been based on their awesome works, Vorbis codec. 010 * 011 * This program is free software; you can redistribute it and/or 012 * modify it under the terms of the GNU Library General Public License 013 * as published by the Free Software Foundation; either version 2 of 014 * the License, or (at your option) any later version. 015 016 * This program is distributed in the hope that it will be useful, 017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU Library General Public License for more details. 020 * 021 * You should have received a copy of the GNU Library General Public 022 * License along with this program; if not, write to the Free Software 023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 024 */ 025 026package com.jcraft.jogg; 027 028public class Buffer{ 029 private static final int BUFFER_INCREMENT=256; 030 031 private static final int[] mask={ 032 0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, 033 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, 034 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, 035 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, 036 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, 037 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, 038 0x3fffffff,0x7fffffff,0xffffffff 039 }; 040 041 int ptr=0; 042 byte[] buffer=null; 043 int endbit=0; 044 int endbyte=0; 045 int storage=0; 046 047 public void writeinit(){ 048 buffer=new byte[BUFFER_INCREMENT]; 049 ptr=0; 050 buffer[0]=(byte)'\0'; 051 storage=BUFFER_INCREMENT; 052 } 053 054 public void write(byte[] s){ 055 for(int i=0; i<s.length; i++){ 056 if(s[i]==0)break; 057 write(s[i],8); 058 } 059 } 060 061 public void read(byte[] s, int bytes){ 062 int i=0; 063 while(bytes--!=0){ 064 s[i++]=(byte)(read(8)); 065 } 066 } 067 068 void reset(){ 069 ptr=0; 070 buffer[0]=(byte)'\0'; 071 endbit=endbyte=0; 072 } 073 074 public void writeclear(){ 075 buffer=null; 076 } 077 078 public void readinit(byte[] buf, int bytes){ 079 readinit(buf, 0, bytes); 080 } 081 082 public void readinit(byte[] buf, int start, int bytes){ 083//System.err.println("readinit: start="+start+", bytes="+bytes); 084//for(int i=0;i<bytes; i++){ 085//System.err.println(i+": "+Integer.toHexString(buf[i+start])); 086//} 087 ptr=start; 088 buffer=buf; 089 endbit=endbyte=0; 090 storage=bytes; 091 } 092 093 public void write(int value, int bits){ 094//System.err.println("write: "+Integer.toHexString(value)+", bits="+bits+" ptr="+ptr+", storage="+storage+", endbyte="+endbyte); 095 if(endbyte+4>=storage){ 096 byte[] foo=new byte[storage+BUFFER_INCREMENT]; 097 System.arraycopy(buffer, 0, foo, 0, storage); 098 buffer=foo; 099 storage+=BUFFER_INCREMENT; 100 } 101 102 value&=mask[bits]; 103 bits+=endbit; 104 buffer[ptr]|=(byte)(value<<endbit); 105 106 if(bits>=8){ 107 buffer[ptr+1]=(byte)(value>>>(8-endbit)); 108 if(bits>=16){ 109 buffer[ptr+2]=(byte)(value>>>(16-endbit)); 110 if(bits>=24){ 111 buffer[ptr+3]=(byte)(value>>>(24-endbit)); 112 if(bits>=32){ 113 if(endbit>0) 114 buffer[ptr+4]=(byte)(value>>>(32-endbit)); 115 else 116 buffer[ptr+4]=0; 117 } 118 } 119 } 120 } 121 122 endbyte+=bits/8; 123 ptr+=bits/8; 124 endbit=bits&7; 125 } 126 127 public int look(int bits){ 128 int ret; 129 int m=mask[bits]; 130 131 bits+=endbit; 132 133//System.err.println("look ptr:"+ptr+", bits="+bits+", endbit="+endbit+", storage="+storage); 134 135 if(endbyte+4>=storage){ 136 if(endbyte+(bits-1)/8>=storage)return(-1); 137 } 138 139 ret=((buffer[ptr])&0xff)>>>endbit; 140// ret=((byte)(buffer[ptr]))>>>endbit; 141 if(bits>8){ 142 ret|=((buffer[ptr+1])&0xff)<<(8-endbit); 143// ret|=((byte)(buffer[ptr+1]))<<(8-endbit); 144 if(bits>16){ 145 ret|=((buffer[ptr+2])&0xff)<<(16-endbit); 146// ret|=((byte)(buffer[ptr+2]))<<(16-endbit); 147 if(bits>24){ 148 ret|=((buffer[ptr+3])&0xff)<<(24-endbit); 149//System.err.print("ret="+Integer.toHexString(ret)+", ((byte)(buffer[ptr+3]))="+Integer.toHexString(((buffer[ptr+3])&0xff))); 150// ret|=((byte)(buffer[ptr+3]))<<(24-endbit); 151//System.err.println(" ->ret="+Integer.toHexString(ret)); 152 if(bits>32 && endbit!=0){ 153 ret|=((buffer[ptr+4])&0xff)<<(32-endbit); 154// ret|=((byte)(buffer[ptr+4]))<<(32-endbit); 155 } 156 } 157 } 158 } 159 return(m&ret); 160 } 161 162 public int look1(){ 163 if(endbyte>=storage)return(-1); 164 return((buffer[ptr]>>endbit)&1); 165 } 166 167 public void adv(int bits){ 168 bits+=endbit; 169 ptr+=bits/8; 170 endbyte+=bits/8; 171 endbit=bits&7; 172 } 173 174 public void adv1(){ 175 ++endbit; 176 if(endbit>7){ 177 endbit=0; 178 ptr++; 179 endbyte++; 180 } 181 } 182 183 public int read(int bits){ 184//System.err.println(this+" read: bits="+bits+", storage="+storage+", endbyte="+endbyte); 185 int ret; 186 int m=mask[bits]; 187 188 bits+=endbit; 189 190 if(endbyte+4>=storage){ 191 ret=-1; 192 if(endbyte+(bits-1)/8>=storage){ 193 ptr+=bits/8; 194 endbyte+=bits/8; 195 endbit=bits&7; 196 return(ret); 197 } 198 } 199 200/* 201 ret=(byte)(buffer[ptr]>>>endbit); 202 if(bits>8){ 203 ret|=(buffer[ptr+1]<<(8-endbit)); 204 if(bits>16){ 205 ret|=(buffer[ptr+2]<<(16-endbit)); 206 if(bits>24){ 207 ret|=(buffer[ptr+3]<<(24-endbit)); 208 if(bits>32 && endbit>0){ 209 ret|=(buffer[ptr+4]<<(32-endbit)); 210 } 211 } 212 } 213 } 214*/ 215 ret=((buffer[ptr])&0xff)>>>endbit; 216 if(bits>8){ 217 ret|=((buffer[ptr+1])&0xff)<<(8-endbit); 218// ret|=((byte)(buffer[ptr+1]))<<(8-endbit); 219 if(bits>16){ 220 ret|=((buffer[ptr+2])&0xff)<<(16-endbit); 221// ret|=((byte)(buffer[ptr+2]))<<(16-endbit); 222 if(bits>24){ 223 ret|=((buffer[ptr+3])&0xff)<<(24-endbit); 224// ret|=((byte)(buffer[ptr+3]))<<(24-endbit); 225 if(bits>32 && endbit!=0){ 226 ret|=((buffer[ptr+4])&0xff)<<(32-endbit); 227// ret|=((byte)(buffer[ptr+4]))<<(32-endbit); 228 } 229 } 230 } 231 } 232 233 ret&=m; 234 235 ptr+=bits/8; 236// ptr=bits/8; 237 endbyte+=bits/8; 238// endbyte=bits/8; 239 endbit=bits&7; 240 return(ret); 241 } 242 243 public int read1(){ 244 int ret; 245 if(endbyte>=storage){ 246 ret=-1; 247 endbit++; 248 if(endbit>7){ 249 endbit=0; 250 ptr++; 251 endbyte++; 252 } 253 return(ret); 254 } 255 256 ret=(buffer[ptr]>>endbit)&1; 257 258 endbit++; 259 if(endbit>7){ 260 endbit=0; 261 ptr++; 262 endbyte++; 263 } 264 return(ret); 265 } 266 267 public int bytes(){ 268 return(endbyte+(endbit+7)/8); 269 } 270 271 public int bits(){ 272 return(endbyte*8+endbit); 273 } 274 275 public byte[] buffer(){ 276 return(buffer); 277 } 278 279 public static int ilog(int v){ 280 int ret=0; 281 while(v>0){ 282 ret++; 283 v>>>=1; 284 } 285 return(ret); 286 } 287 288 public static void report(String in){ 289 System.err.println(in); 290 System.exit(1); 291 } 292 293 /* 294 static void cliptest(int[] b, int vals, int bits, int[] comp, int compsize){ 295 int bytes; 296 byte[] buffer; 297 298 o.reset(); 299 for(int i=0;i<vals;i++){ 300 o.write(b[i],((bits!=0)?bits:ilog(b[i]))); 301 } 302 buffer=o.buffer(); 303 bytes=o.bytes(); 304System.err.println("cliptest: bytes="+bytes); 305 if(bytes!=compsize)report("wrong number of bytes!\n"); 306 for(int i=0;i<bytes;i++){ 307 if(buffer[i]!=(byte)comp[i]){ 308 for(int j=0;j<bytes;j++){ 309 System.err.println(j+": "+Integer.toHexString(buffer[j])+" "+ 310 Integer.toHexString(comp[j])); 311 } 312 report("wrote incorrect value!\n"); 313 } 314 } 315System.err.println("bits: "+bits); 316 r.readinit(buffer,bytes); 317 for(int i=0;i<vals;i++){ 318 int tbit=(bits!=0)?bits:ilog(b[i]); 319System.err.println(Integer.toHexString(b[i])+" tbit: "+tbit); 320 if(r.look(tbit)==-1){ 321 report("out of data!\n"); 322 } 323 if(r.look(tbit)!=(b[i]&mask[tbit])){ 324 report(i+" looked at incorrect value! "+Integer.toHexString(r.look(tbit))+", "+Integer.toHexString(b[i]&mask[tbit])+":"+b[i]+" bit="+tbit); 325 } 326 if(tbit==1){ 327 if(r.look1()!=(b[i]&mask[tbit])){ 328 report("looked at single bit incorrect value!\n"); 329 } 330 } 331 if(tbit==1){ 332 if(r.read1()!=(b[i]&mask[tbit])){ 333 report("read incorrect single bit value!\n"); 334 } 335 } 336 else{ 337 if(r.read(tbit)!=(b[i]&mask[tbit])){ 338 report("read incorrect value!\n"); 339 } 340 } 341 } 342 if(r.bytes()!=bytes){ 343 report("leftover bytes after read!\n"); 344 } 345 } 346 347 static int[] testbuffer1= 348 {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7, 349 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4}; 350 static int test1size=43; 351 352 static int[] testbuffer2= 353 {216531625,1237861823,56732452,131,3212421,12325343,34547562,12313212, 354 1233432,534,5,346435231,14436467,7869299,76326614,167548585, 355 85525151,0,12321,1,349528352}; 356 static int test2size=21; 357 358 static int[] large= 359 {2136531625,2137861823,56732452,131,3212421,12325343,34547562,12313212, 360 1233432,534,5,2146435231,14436467,7869299,76326614,167548585, 361 85525151,0,12321,1,2146528352}; 362 363 static int[] testbuffer3= 364 {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, 365 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1}; 366 static int test3size=56; 367 368 static int onesize=33; 369 static int[] one={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40, 370 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172, 371 223,4}; 372 373 static int twosize=6; 374 static int[] two={61,255,255,251,231,29}; 375 376 static int threesize=54; 377 static int[] three={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254, 378 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83, 379 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10, 380 100,52,4,14,18,86,77,1}; 381 382 static int foursize=38; 383 static int[] four={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72, 384 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169, 385 28,2,133,0,1}; 386 387 static int fivesize=45; 388 static int[] five={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62, 389 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169, 390 84,75,159,2,1,0,132,192,8,0,0,18,22}; 391 392 static int sixsize=7; 393 static int[] six={17,177,170,242,169,19,148}; 394 395 static Buffer o=new Buffer(); 396 static Buffer r=new Buffer(); 397 398 public static void main(String[] arg){ 399 byte[] buffer; 400 int bytes; 401// o=new Buffer(); 402// r=new Buffer(); 403 404 o.writeinit(); 405 406 System.err.print("\nSmall preclipped packing: "); 407 cliptest(testbuffer1,test1size,0,one,onesize); 408 System.err.print("ok."); 409 410 System.err.print("\nNull bit call: "); 411 cliptest(testbuffer3,test3size,0,two,twosize); 412 System.err.print("ok."); 413 414 System.err.print("\nLarge preclipped packing: "); 415 cliptest(testbuffer2,test2size,0,three,threesize); 416 System.err.print("ok."); 417 418 System.err.print("\n32 bit preclipped packing: "); 419 o.reset(); 420 for(int i=0;i<test2size;i++) 421 o.write(large[i],32); 422 buffer=o.buffer(); 423 bytes=o.bytes(); 424 425 426 r.readinit(buffer,bytes); 427 for(int i=0;i<test2size;i++){ 428 if(r.look(32)==-1){ 429 report("out of data. failed!"); 430 } 431 if(r.look(32)!=large[i]){ 432 System.err.print(r.look(32)+" != "+large[i]+" ("+ 433 Integer.toHexString(r.look(32))+"!="+ 434 Integer.toHexString(large[i])+")"); 435 report("read incorrect value!\n"); 436 } 437 r.adv(32); 438 } 439 if(r.bytes()!=bytes)report("leftover bytes after read!\n"); 440 System.err.print("ok."); 441 442 System.err.print("\nSmall unclipped packing: "); 443 cliptest(testbuffer1,test1size,7,four,foursize); 444 System.err.print("ok."); 445 446 System.err.print("\nLarge unclipped packing: "); 447 cliptest(testbuffer2,test2size,17,five,fivesize); 448 System.err.print("ok."); 449 450 System.err.print("\nSingle bit unclicpped packing: "); 451 cliptest(testbuffer3,test3size,1,six,sixsize); 452 System.err.print("ok."); 453 454 System.err.print("\nTesting read past end: "); 455 r.readinit("\0\0\0\0\0\0\0\0".getBytes(),8); 456 for(int i=0;i<64;i++){ 457 if(r.read(1)!=0){ 458 System.err.print("failed; got -1 prematurely.\n"); 459 System.exit(1); 460 } 461 } 462 463 if(r.look(1)!=-1 || 464 r.read(1)!=-1){ 465 System.err.print("failed; read past end without -1.\n"); 466 System.exit(1); 467 } 468 469 r.readinit("\0\0\0\0\0\0\0\0".getBytes(),8); 470 if(r.read(30)!=0 || r.read(16)!=0){ 471 System.err.print("failed 2; got -1 prematurely.\n"); 472 System.exit(1); 473 } 474 475 if(r.look(18)!=0 || 476 r.look(18)!=0){ 477 System.err.print("failed 3; got -1 prematurely.\n"); 478 System.exit(1); 479 } 480 if(r.look(19)!=-1 || 481 r.look(19)!=-1){ 482 System.err.print("failed; read past end without -1.\n"); 483 System.exit(1); 484 } 485 if(r.look(32)!=-1 || 486 r.look(32)!=-1){ 487 System.err.print("failed; read past end without -1.\n"); 488 System.exit(1); 489 } 490 System.err.print("ok.\n\n"); 491 } 492 */ 493} 494 495 496 497 498