summaryrefslogtreecommitdiff
path: root/songdbj/com/jcraft/jogg
diff options
context:
space:
mode:
Diffstat (limited to 'songdbj/com/jcraft/jogg')
-rw-r--r--songdbj/com/jcraft/jogg/Buffer.java541
-rw-r--r--songdbj/com/jcraft/jogg/Packet.java82
-rw-r--r--songdbj/com/jcraft/jogg/Page.java973
-rw-r--r--songdbj/com/jcraft/jogg/StreamState.java657
-rw-r--r--songdbj/com/jcraft/jogg/SyncState.java275
5 files changed, 2528 insertions, 0 deletions
diff --git a/songdbj/com/jcraft/jogg/Buffer.java b/songdbj/com/jcraft/jogg/Buffer.java
new file mode 100644
index 0000000000..a40a9def9c
--- /dev/null
+++ b/songdbj/com/jcraft/jogg/Buffer.java
@@ -0,0 +1,541 @@
1/* -*-mode:java; c-basic-offset:2; -*- */
2/* JOrbis
3 * Copyright (C) 2000 ymnk, JCraft,Inc.
4 *
5 * Written by: 2000 ymnk<ymnk@jcraft.com>
6 *
7 * Many thanks to
8 * Monty <monty@xiph.org> and
9 * The XIPHOPHORUS Company http://www.xiph.org/ .
10 * JOrbis has been based on their awesome works, Vorbis codec.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public License
14 * as published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27package com.jcraft.jogg;
28
29public class Buffer{
30 private static final int BUFFER_INCREMENT=256;
31
32 private static final int[] mask={
33 0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
34 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
35 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
36 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
37 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
38 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
39 0x3fffffff,0x7fffffff,0xffffffff
40 };
41
42 int ptr=0;
43 byte[] buffer=null;
44 int endbit=0;
45 int endbyte=0;
46 int storage=0;
47
48 public void writeinit(){
49 buffer=new byte[BUFFER_INCREMENT];
50 ptr=0;
51 buffer[0]=(byte)'\0';
52 storage=BUFFER_INCREMENT;
53 }
54
55 public void write(byte[] s){
56 for(int i=0; i<s.length; i++){
57 if(s[i]==0)break;
58 write(s[i],8);
59 }
60 }
61
62 public void read(byte[] s, int bytes){
63 int i=0;
64 while(bytes--!=0){
65 s[i++]=(byte)(read(8));
66 }
67 }
68
69 void reset(){
70 ptr=0;
71 buffer[0]=(byte)'\0';
72 endbit=endbyte=0;
73 }
74
75 public void writeclear(){
76 buffer=null;
77 }
78
79 public void readinit(byte[] buf, int bytes){
80 readinit(buf, 0, bytes);
81 }
82
83 public void readinit(byte[] buf, int start, int bytes){
84//System.err.println("readinit: start="+start+", bytes="+bytes);
85//for(int i=0;i<bytes; i++){
86//System.err.println(i+": "+Integer.toHexString(buf[i+start]));
87//}
88 ptr=start;
89 buffer=buf;
90 endbit=endbyte=0;
91 storage=bytes;
92 }
93
94 public void write(int value, int bits){
95//System.err.println("write: "+Integer.toHexString(value)+", bits="+bits+" ptr="+ptr+", storage="+storage+", endbyte="+endbyte);
96 if(endbyte+4>=storage){
97 byte[] foo=new byte[storage+BUFFER_INCREMENT];
98 System.arraycopy(buffer, 0, foo, 0, storage);
99 buffer=foo;
100 storage+=BUFFER_INCREMENT;
101 }
102
103 value&=mask[bits];
104 bits+=endbit;
105 buffer[ptr]|=(byte)(value<<endbit);
106
107 if(bits>=8){
108 buffer[ptr+1]=(byte)(value>>>(8-endbit));
109 if(bits>=16){
110 buffer[ptr+2]=(byte)(value>>>(16-endbit));
111 if(bits>=24){
112 buffer[ptr+3]=(byte)(value>>>(24-endbit));
113 if(bits>=32){
114 if(endbit>0)
115 buffer[ptr+4]=(byte)(value>>>(32-endbit));
116 else
117 buffer[ptr+4]=0;
118 }
119 }
120 }
121 }
122
123 endbyte+=bits/8;
124 ptr+=bits/8;
125 endbit=bits&7;
126 }
127
128 public int look(int bits){
129 int ret;
130 int m=mask[bits];
131
132 bits+=endbit;
133
134//System.err.println("look ptr:"+ptr+", bits="+bits+", endbit="+endbit+", storage="+storage);
135
136 if(endbyte+4>=storage){
137 if(endbyte+(bits-1)/8>=storage)return(-1);
138 }
139
140 ret=((buffer[ptr])&0xff)>>>endbit;
141// ret=((byte)(buffer[ptr]))>>>endbit;
142 if(bits>8){
143 ret|=((buffer[ptr+1])&0xff)<<(8-endbit);
144// ret|=((byte)(buffer[ptr+1]))<<(8-endbit);
145 if(bits>16){
146 ret|=((buffer[ptr+2])&0xff)<<(16-endbit);
147// ret|=((byte)(buffer[ptr+2]))<<(16-endbit);
148 if(bits>24){
149 ret|=((buffer[ptr+3])&0xff)<<(24-endbit);
150//System.err.print("ret="+Integer.toHexString(ret)+", ((byte)(buffer[ptr+3]))="+Integer.toHexString(((buffer[ptr+3])&0xff)));
151// ret|=((byte)(buffer[ptr+3]))<<(24-endbit);
152//System.err.println(" ->ret="+Integer.toHexString(ret));
153 if(bits>32 && endbit!=0){
154 ret|=((buffer[ptr+4])&0xff)<<(32-endbit);
155// ret|=((byte)(buffer[ptr+4]))<<(32-endbit);
156 }
157 }
158 }
159 }
160 return(m&ret);
161 }
162
163 public int look1(){
164 if(endbyte>=storage)return(-1);
165 return((buffer[ptr]>>endbit)&1);
166 }
167
168 public void adv(int bits){
169 bits+=endbit;
170 ptr+=bits/8;
171 endbyte+=bits/8;
172 endbit=bits&7;
173 }
174
175 public void adv1(){
176 ++endbit;
177 if(endbit>7){
178 endbit=0;
179 ptr++;
180 endbyte++;
181 }
182 }
183
184 public int read(int bits){
185//System.err.println(this+" read: bits="+bits+", storage="+storage+", endbyte="+endbyte);
186//System.err.println(this+" read: bits="+bits+", storage="+storage+", endbyte="+endbyte+
187// ", ptr="+ptr+", endbit="+endbit+", buf[ptr]="+buffer[ptr]);
188
189 int ret;
190 int m=mask[bits];
191
192 bits+=endbit;
193
194 if(endbyte+4>=storage){
195 ret=-1;
196 if(endbyte+(bits-1)/8>=storage){
197 ptr+=bits/8;
198 endbyte+=bits/8;
199 endbit=bits&7;
200 return(ret);
201 }
202 }
203
204/*
205 ret=(byte)(buffer[ptr]>>>endbit);
206 if(bits>8){
207 ret|=(buffer[ptr+1]<<(8-endbit));
208 if(bits>16){
209 ret|=(buffer[ptr+2]<<(16-endbit));
210 if(bits>24){
211 ret|=(buffer[ptr+3]<<(24-endbit));
212 if(bits>32 && endbit>0){
213 ret|=(buffer[ptr+4]<<(32-endbit));
214 }
215 }
216 }
217 }
218*/
219 ret=((buffer[ptr])&0xff)>>>endbit;
220 if(bits>8){
221 ret|=((buffer[ptr+1])&0xff)<<(8-endbit);
222// ret|=((byte)(buffer[ptr+1]))<<(8-endbit);
223 if(bits>16){
224 ret|=((buffer[ptr+2])&0xff)<<(16-endbit);
225// ret|=((byte)(buffer[ptr+2]))<<(16-endbit);
226 if(bits>24){
227 ret|=((buffer[ptr+3])&0xff)<<(24-endbit);
228// ret|=((byte)(buffer[ptr+3]))<<(24-endbit);
229 if(bits>32 && endbit!=0){
230 ret|=((buffer[ptr+4])&0xff)<<(32-endbit);
231// ret|=((byte)(buffer[ptr+4]))<<(32-endbit);
232 }
233 }
234 }
235 }
236
237 ret&=m;
238
239 ptr+=bits/8;
240// ptr=bits/8;
241 endbyte+=bits/8;
242// endbyte=bits/8;
243 endbit=bits&7;
244 return(ret);
245 }
246
247 public int readB(int bits){
248 //System.err.println(this+" read: bits="+bits+", storage="+storage+", endbyte="+endbyte+
249 // ", ptr="+ptr+", endbit="+endbit+", buf[ptr]="+buffer[ptr]);
250 int ret;
251 int m=32-bits;
252
253 bits+=endbit;
254
255 if(endbyte+4>=storage){
256 /* not the main path */
257 ret=-1;
258 if(endbyte*8+bits>storage*8) {
259 ptr+=bits/8;
260 endbyte+=bits/8;
261 endbit=bits&7;
262 return(ret);
263 }
264 }
265
266 ret=(buffer[ptr]&0xff)<<(24+endbit);
267 if(bits>8){
268 ret|=(buffer[ptr+1]&0xff)<<(16+endbit);
269 if(bits>16){
270 ret|=(buffer[ptr+2]&0xff)<<(8+endbit);
271 if(bits>24){
272 ret|=(buffer[ptr+3]&0xff)<<(endbit);
273 if(bits>32 && (endbit != 0))
274 ret|=(buffer[ptr+4]&0xff)>>(8-endbit);
275 }
276 }
277 }
278 ret=(ret>>>(m>>1))>>>((m+1)>>1);
279
280 ptr+=bits/8;
281 endbyte+=bits/8;
282 endbit=bits&7;
283 return(ret);
284 }
285
286 public int read1(){
287 int ret;
288 if(endbyte>=storage){
289 ret=-1;
290 endbit++;
291 if(endbit>7){
292 endbit=0;
293 ptr++;
294 endbyte++;
295 }
296 return(ret);
297 }
298
299 ret=(buffer[ptr]>>endbit)&1;
300
301 endbit++;
302 if(endbit>7){
303 endbit=0;
304 ptr++;
305 endbyte++;
306 }
307 return(ret);
308 }
309
310 public int bytes(){
311 return(endbyte+(endbit+7)/8);
312 }
313
314 public int bits(){
315 return(endbyte*8+endbit);
316 }
317
318 public byte[] buffer(){
319 return(buffer);
320 }
321
322 public static int ilog(int v){
323 int ret=0;
324 while(v>0){
325 ret++;
326 v>>>=1;
327 }
328 return(ret);
329 }
330
331 public static void report(String in){
332 System.err.println(in);
333 System.exit(1);
334 }
335
336 /*
337 static void cliptest(int[] b, int vals, int bits, int[] comp, int compsize){
338 int bytes;
339 byte[] buffer;
340
341 o.reset();
342 for(int i=0;i<vals;i++){
343 o.write(b[i],((bits!=0)?bits:ilog(b[i])));
344 }
345 buffer=o.buffer();
346 bytes=o.bytes();
347System.err.println("cliptest: bytes="+bytes);
348 if(bytes!=compsize)report("wrong number of bytes!\n");
349 for(int i=0;i<bytes;i++){
350 if(buffer[i]!=(byte)comp[i]){
351 for(int j=0;j<bytes;j++){
352 System.err.println(j+": "+Integer.toHexString(buffer[j])+" "+
353 Integer.toHexString(comp[j]));
354 }
355 report("wrote incorrect value!\n");
356 }
357 }
358System.err.println("bits: "+bits);
359 r.readinit(buffer,bytes);
360 for(int i=0;i<vals;i++){
361 int tbit=(bits!=0)?bits:ilog(b[i]);
362System.err.println(Integer.toHexString(b[i])+" tbit: "+tbit);
363 if(r.look(tbit)==-1){
364 report("out of data!\n");
365 }
366 if(r.look(tbit)!=(b[i]&mask[tbit])){
367 report(i+" looked at incorrect value! "+Integer.toHexString(r.look(tbit))+", "+Integer.toHexString(b[i]&mask[tbit])+":"+b[i]+" bit="+tbit);
368 }
369 if(tbit==1){
370 if(r.look1()!=(b[i]&mask[tbit])){
371 report("looked at single bit incorrect value!\n");
372 }
373 }
374 if(tbit==1){
375 if(r.read1()!=(b[i]&mask[tbit])){
376 report("read incorrect single bit value!\n");
377 }
378 }
379 else{
380 if(r.read(tbit)!=(b[i]&mask[tbit])){
381 report("read incorrect value!\n");
382 }
383 }
384 }
385 if(r.bytes()!=bytes){
386 report("leftover bytes after read!\n");
387 }
388 }
389
390 static int[] testbuffer1=
391 {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
392 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
393 static int test1size=43;
394
395 static int[] testbuffer2=
396 {216531625,1237861823,56732452,131,3212421,12325343,34547562,12313212,
397 1233432,534,5,346435231,14436467,7869299,76326614,167548585,
398 85525151,0,12321,1,349528352};
399 static int test2size=21;
400
401 static int[] large=
402 {2136531625,2137861823,56732452,131,3212421,12325343,34547562,12313212,
403 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
404 85525151,0,12321,1,2146528352};
405
406 static int[] testbuffer3=
407 {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,
408 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
409 static int test3size=56;
410
411 static int onesize=33;
412 static int[] one={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
413 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
414 223,4};
415
416 static int twosize=6;
417 static int[] two={61,255,255,251,231,29};
418
419 static int threesize=54;
420 static int[] three={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
421 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
422 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
423 100,52,4,14,18,86,77,1};
424
425 static int foursize=38;
426 static int[] four={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
427 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
428 28,2,133,0,1};
429
430 static int fivesize=45;
431 static int[] five={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
432 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
433 84,75,159,2,1,0,132,192,8,0,0,18,22};
434
435 static int sixsize=7;
436 static int[] six={17,177,170,242,169,19,148};
437
438 static Buffer o=new Buffer();
439 static Buffer r=new Buffer();
440
441 public static void main(String[] arg){
442 byte[] buffer;
443 int bytes;
444// o=new Buffer();
445// r=new Buffer();
446
447 o.writeinit();
448
449 System.err.print("\nSmall preclipped packing: ");
450 cliptest(testbuffer1,test1size,0,one,onesize);
451 System.err.print("ok.");
452
453 System.err.print("\nNull bit call: ");
454 cliptest(testbuffer3,test3size,0,two,twosize);
455 System.err.print("ok.");
456
457 System.err.print("\nLarge preclipped packing: ");
458 cliptest(testbuffer2,test2size,0,three,threesize);
459 System.err.print("ok.");
460
461 System.err.print("\n32 bit preclipped packing: ");
462 o.reset();
463 for(int i=0;i<test2size;i++)
464 o.write(large[i],32);
465 buffer=o.buffer();
466 bytes=o.bytes();
467
468
469 r.readinit(buffer,bytes);
470 for(int i=0;i<test2size;i++){
471 if(r.look(32)==-1){
472 report("out of data. failed!");
473 }
474 if(r.look(32)!=large[i]){
475 System.err.print(r.look(32)+" != "+large[i]+" ("+
476 Integer.toHexString(r.look(32))+"!="+
477 Integer.toHexString(large[i])+")");
478 report("read incorrect value!\n");
479 }
480 r.adv(32);
481 }
482 if(r.bytes()!=bytes)report("leftover bytes after read!\n");
483 System.err.print("ok.");
484
485 System.err.print("\nSmall unclipped packing: ");
486 cliptest(testbuffer1,test1size,7,four,foursize);
487 System.err.print("ok.");
488
489 System.err.print("\nLarge unclipped packing: ");
490 cliptest(testbuffer2,test2size,17,five,fivesize);
491 System.err.print("ok.");
492
493 System.err.print("\nSingle bit unclicpped packing: ");
494 cliptest(testbuffer3,test3size,1,six,sixsize);
495 System.err.print("ok.");
496
497 System.err.print("\nTesting read past end: ");
498 r.readinit("\0\0\0\0\0\0\0\0".getBytes(),8);
499 for(int i=0;i<64;i++){
500 if(r.read(1)!=0){
501 System.err.print("failed; got -1 prematurely.\n");
502 System.exit(1);
503 }
504 }
505
506 if(r.look(1)!=-1 ||
507 r.read(1)!=-1){
508 System.err.print("failed; read past end without -1.\n");
509 System.exit(1);
510 }
511
512 r.readinit("\0\0\0\0\0\0\0\0".getBytes(),8);
513 if(r.read(30)!=0 || r.read(16)!=0){
514 System.err.print("failed 2; got -1 prematurely.\n");
515 System.exit(1);
516 }
517
518 if(r.look(18)!=0 ||
519 r.look(18)!=0){
520 System.err.print("failed 3; got -1 prematurely.\n");
521 System.exit(1);
522 }
523 if(r.look(19)!=-1 ||
524 r.look(19)!=-1){
525 System.err.print("failed; read past end without -1.\n");
526 System.exit(1);
527 }
528 if(r.look(32)!=-1 ||
529 r.look(32)!=-1){
530 System.err.print("failed; read past end without -1.\n");
531 System.exit(1);
532 }
533 System.err.print("ok.\n\n");
534 }
535 */
536}
537
538
539
540
541
diff --git a/songdbj/com/jcraft/jogg/Packet.java b/songdbj/com/jcraft/jogg/Packet.java
new file mode 100644
index 0000000000..22a8a5439b
--- /dev/null
+++ b/songdbj/com/jcraft/jogg/Packet.java
@@ -0,0 +1,82 @@
1/* JOrbis
2 * Copyright (C) 2000 ymnk, JCraft,Inc.
3 *
4 * Written by: 2000 ymnk<ymnk@jcraft.com>
5 *
6 * Many thanks to
7 * Monty <monty@xiph.org> and
8 * The XIPHOPHORUS Company http://www.xiph.org/ .
9 * JOrbis has been based on their awesome works, Vorbis codec.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public License
13 * as published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * You should have received a copy of the GNU Library General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26package com.jcraft.jogg;
27
28public class Packet{
29 public byte[] packet_base;
30 public int packet;
31 public int bytes;
32 public int b_o_s;
33 public int e_o_s;
34
35 public long granulepos;
36
37 public long packetno; // sequence number for decode; the framing
38 // knows where there's a hole in the data,
39 // but we need coupling so that the codec
40 // (which is in a seperate abstraction
41 // layer) also knows about the gap
42
43 /*
44 // TEST
45 static int sequence=0;
46 static int lastno=0;
47 void checkpacket(int len, int no, int pos){
48 if(bytes!=len){
49 System.err.println("incorrect packet length!");
50 System.exit(1);
51 }
52 if(granulepos!=pos){
53 System.err.println("incorrect packet position!");
54 System.exit(1);
55 }
56
57 // packet number just follows sequence/gap; adjust the input number
58 // for that
59 if(no==0){
60 sequence=0;
61 }
62 else{
63 sequence++;
64 if(no>lastno+1)
65 sequence++;
66 }
67 lastno=no;
68 if(packetno!=sequence){
69 System.err.println("incorrect packet sequence "+packetno+" != "+sequence);
70 System.exit(1);
71 }
72
73 // Test data
74 for(int j=0;j<bytes;j++){
75 if((packet_base[packet+j]&0xff)!=((j+no)&0xff)){
76 System.err.println("body data mismatch at pos "+ j+": "+(packet_base[packet+j]&0xff)+"!="+((j+no)&0xff)+"!\n");
77 System.exit(1);
78 }
79 }
80 }
81 */
82}
diff --git a/songdbj/com/jcraft/jogg/Page.java b/songdbj/com/jcraft/jogg/Page.java
new file mode 100644
index 0000000000..fc1add010e
--- /dev/null
+++ b/songdbj/com/jcraft/jogg/Page.java
@@ -0,0 +1,973 @@
1/* -*-mode:java; c-basic-offset:2; -*- */
2/* JOrbis
3 * Copyright (C) 2000 ymnk, JCraft,Inc.
4 *
5 * Written by: 2000 ymnk<ymnk@jcraft.com>
6 *
7 * Many thanks to
8 * Monty <monty@xiph.org> and
9 * The XIPHOPHORUS Company http://www.xiph.org/ .
10 * JOrbis has been based on their awesome works, Vorbis codec.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public License
14 * as published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27package com.jcraft.jogg;
28
29public class Page{
30 private static int[] crc_lookup=new int[256];
31 static {
32 for(int i=0; i<crc_lookup.length; i++){
33 crc_lookup[i]=crc_entry(i);
34 }
35 }
36
37 private static int crc_entry(int index){
38 int r=index<<24;
39 for(int i=0; i<8; i++){
40 if((r& 0x80000000)!=0){
41 r=(r << 1)^0x04c11db7; /* The same as the ethernet generator
42 polynomial, although we use an
43 unreflected alg and an init/final
44 of 0, not 0xffffffff */
45 }
46 else{
47 r<<=1;
48 }
49 }
50 return(r&0xffffffff);
51 }
52
53 public byte[] header_base;
54 public int header;
55 public int header_len;
56 public byte[] body_base;
57 public int body;
58 public int body_len;
59
60 int version(){
61 return header_base[header+4]&0xff;
62 }
63 int continued(){
64 return (header_base[header+5]&0x01);
65 }
66 public int bos(){
67 return (header_base[header+5]&0x02);
68 }
69 public int eos(){
70 return (header_base[header+5]&0x04);
71 }
72 public long granulepos(){
73 long foo=header_base[header+13]&0xff;
74 foo=(foo<<8)|(header_base[header+12]&0xff);
75 foo=(foo<<8)|(header_base[header+11]&0xff);
76 foo=(foo<<8)|(header_base[header+10]&0xff);
77 foo=(foo<<8)|(header_base[header+9]&0xff);
78 foo=(foo<<8)|(header_base[header+8]&0xff);
79 foo=(foo<<8)|(header_base[header+7]&0xff);
80 foo=(foo<<8)|(header_base[header+6]&0xff);
81 return(foo);
82 }
83 public int serialno(){
84 return (header_base[header+14]&0xff)|
85 ((header_base[header+15]&0xff)<<8)|
86 ((header_base[header+16]&0xff)<<16)|
87 ((header_base[header+17]&0xff)<<24);
88 }
89 int pageno(){
90 return (header_base[header+18]&0xff)|
91 ((header_base[header+19]&0xff)<<8)|
92 ((header_base[header+20]&0xff)<<16)|
93 ((header_base[header+21]&0xff)<<24);
94 }
95
96 void checksum(){
97 int crc_reg=0;
98
99// for(int i=0;i<header_len;i++){
100// System.err.println("chksum: "+Integer.toHexString(header_base[header+i]&0xff));
101// }
102
103 for(int i=0;i<header_len;i++){
104 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg>>>24)&0xff)^(header_base[header+i]&0xff)];
105 }
106 for(int i=0;i<body_len;i++){
107 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg>>>24)&0xff)^(body_base[body+i]&0xff)];
108 }
109 header_base[header+22]=(byte)crc_reg/*&0xff*/;
110 header_base[header+23]=(byte)(crc_reg>>>8)/*&0xff*/;
111 header_base[header+24]=(byte)(crc_reg>>>16)/*&0xff*/;
112 header_base[header+25]=(byte)(crc_reg>>>24)/*&0xff*/;
113 }
114 public Page copy(){
115 return copy(new Page());
116 }
117 public Page copy(Page p){
118 byte[] tmp=new byte[header_len];
119 System.arraycopy(header_base, header, tmp, 0, header_len);
120 p.header_len=header_len;
121 p.header_base=tmp;
122 p.header=0;
123 tmp=new byte[body_len];
124 System.arraycopy(body_base, body, tmp, 0, body_len);
125 p.body_len=body_len;
126 p.body_base=tmp;
127 p.body=0;
128 return p;
129 }
130 /*
131 // TEST
132 static StreamState os_en, os_de;
133 static SyncState oy;
134 void check_page(byte[] data_base, int data, int[] _header){
135 // Test data
136 for(int j=0;j<body_len;j++)
137 if(body_base[body+j]!=data_base[data+j]){
138 System.err.println("body data mismatch at pos "+j+": "+data_base[data+j]+"!="+body_base[body+j]+"!\n");
139 System.exit(1);
140 }
141
142 // Test header
143 for(int j=0;j<header_len;j++){
144 if((header_base[header+j]&0xff)!=_header[j]){
145 System.err.println("header content mismatch at pos "+j);
146 for(int jj=0;jj<_header[26]+27;jj++)
147 System.err.print(" ("+jj+")"+Integer.toHexString(_header[jj])+":"+Integer.toHexString(header_base[header+jj]));
148 System.err.println("");
149 System.exit(1);
150 }
151 }
152 if(header_len!=_header[26]+27){
153 System.err.print("header length incorrect! ("+header_len+"!="+(_header[26]+27)+")");
154 System.exit(1);
155 }
156 }
157
158 void print_header(){
159 System.err.println("\nHEADER:");
160 System.err.println(" capture: "+
161 (header_base[header+0]&0xff)+" "+
162 (header_base[header+1]&0xff)+" "+
163 (header_base[header+2]&0xff)+" "+
164 (header_base[header+3]&0xff)+" "+
165 " version: "+(header_base[header+4]&0xff)+" flags: "+
166 (header_base[header+5]&0xff));
167 System.err.println(" pcmpos: "+
168 (((header_base[header+9]&0xff)<<24)|
169 ((header_base[header+8]&0xff)<<16)|
170 ((header_base[header+7]&0xff)<<8)|
171 ((header_base[header+6]&0xff)))+
172 " serialno: "+
173 (((header_base[header+17]&0xff)<<24)|
174 ((header_base[header+16]&0xff)<<16)|
175 ((header_base[header+15]&0xff)<<8)|
176 ((header_base[header+14]&0xff)))+
177 " pageno: "+
178 (((header_base[header+21]&0xff)<<24)|
179 ((header_base[header+20]&0xff)<<16)|
180 ((header_base[header+19]&0xff)<<8)|
181 ((header_base[header+18]&0xff))));
182
183 System.err.println(" checksum: "+
184 (header_base[header+22]&0xff)+":"+
185 (header_base[header+23]&0xff)+":"+
186 (header_base[header+24]&0xff)+":"+
187 (header_base[header+25]&0xff)+"\n segments: "+
188 (header_base[header+26]&0xff)+" (");
189 for(int j=27;j<header_len;j++){
190 System.err.println((header_base[header+j]&0xff)+" ");
191 }
192 System.err.println(")\n");
193 }
194
195 void copy_page(){
196 byte[] tmp=new byte[header_len];
197 System.arraycopy(header_base, header, tmp, 0, header_len);
198 header_base=tmp;
199 header=0;
200 tmp=new byte[body_len];
201 System.arraycopy(body_base, body, tmp, 0, body_len);
202 body_base=tmp;
203 body=0;
204 }
205
206 static void test_pack(int[] pl, int[][] headers){
207 byte[] data=new byte[1024*1024]; // for scripted test cases only
208 int inptr=0;
209 int outptr=0;
210 int deptr=0;
211 int depacket=0;
212 int pcm_pos=7;
213 int packets,pageno=0,pageout=0;
214 int eosflag=0;
215 int bosflag=0;
216
217 os_en.reset();
218 os_de.reset();
219 oy.reset();
220
221 for(packets=0;;packets++){
222 if(pl[packets]==-1)break;
223 }
224
225 for(int i=0;i<packets;i++){
226 // construct a test packet
227 Packet op=new Packet();
228 int len=pl[i];
229 op.packet_base=data;
230 op.packet=inptr;
231 op.bytes=len;
232 op.e_o_s=(pl[i+1]<0?1:0);
233 op.granulepos=pcm_pos;
234
235 pcm_pos+=1024;
236
237 for(int j=0;j<len;j++){
238 data[inptr++]=(byte)(i+j);
239 }
240
241 // submit the test packet
242 os_en.packetin(op);
243
244 // retrieve any finished pages
245 {
246 Page og=new Page();
247
248 while(os_en.pageout(og)!=0){
249 // We have a page. Check it carefully
250 //System.err.print(pageno+", ");
251 if(headers[pageno]==null){
252 System.err.println("coded too many pages!");
253 System.exit(1);
254 }
255 og.check_page(data, outptr, headers[pageno]);
256
257 outptr+=og.body_len;
258 pageno++;
259
260//System.err.println("1# pageno="+pageno+", pageout="+pageout);
261
262 // have a complete page; submit it to sync/decode
263
264 {
265 Page og_de=new Page();
266 Packet op_de=new Packet();
267 int index=oy.buffer(og.header_len+og.body_len);
268 byte[] buf=oy.data;
269 System.arraycopy(og.header_base, og.header, buf, index, og.header_len);
270 System.arraycopy(og.body_base, og.body, buf, index+og.header_len, og.body_len);
271 oy.wrote(og.header_len+og.body_len);
272
273//System.err.println("2# pageno="+pageno+", pageout="+pageout);
274
275 while(oy.pageout(og_de)>0){
276 // got a page. Happy happy. Verify that it's good.
277
278 og_de.check_page(data, deptr, headers[pageout]);
279 deptr+=og_de.body_len;
280 pageout++;
281
282 // submit it to deconstitution
283 os_de.pagein(og_de);
284
285 // packets out?
286 while(os_de.packetout(op_de)>0){
287
288 // verify the packet!
289 // check data
290 boolean check=false;
291 for(int ii=0; ii<op_de.bytes; ii++){
292 if(data[depacket+ii]!=op_de.packet_base[op_de.packet+ii]){
293 check=true;
294 break;
295 }
296 }
297 if(check){
298 System.err.println("packet data mismatch in decode! pos="+
299 depacket);
300 System.exit(1);
301 }
302
303 // check bos flag
304 if(bosflag==0 && op_de.b_o_s==0){
305 System.err.println("b_o_s flag not set on packet!");
306 System.exit(1);
307 }
308 if(bosflag!=0 && op_de.b_o_s!=0){
309 System.err.println("b_o_s flag incorrectly set on packet!");
310 System.exit(1);
311 }
312
313 bosflag=1;
314 depacket+=op_de.bytes;
315
316 // check eos flag
317 if(eosflag!=0){
318 System.err.println("Multiple decoded packets with eos flag!");
319 System.exit(1);
320 }
321
322 if(op_de.e_o_s!=0)eosflag=1;
323
324 // check pcmpos flag
325 if(op_de.granulepos!=-1){
326 System.err.print(" pcm:"+op_de.granulepos+" ");
327 }
328 }
329 }
330 }
331 }
332 }
333 }
334 //free(data);
335 if(headers[pageno]!=null){
336 System.err.println("did not write last page!");
337 System.exit(1);
338 }
339 if(headers[pageout]!=null){
340 System.err.println("did not decode last page!");
341 System.exit(1);
342 }
343 if(inptr!=outptr){
344 System.err.println("encoded page data incomplete!");
345 System.exit(1);
346 }
347 if(inptr!=deptr){
348 System.err.println("decoded page data incomplete!");
349 System.exit(1);
350 }
351 if(inptr!=depacket){
352 System.err.println("decoded packet data incomplete!");
353 System.exit(1);
354 }
355 if(eosflag==0){
356 System.err.println("Never got a packet with EOS set!");
357 }
358 System.err.println("ok.");
359 }
360
361 static void error(){
362 System.err.println("error!");
363 System.exit(1);
364 }
365 public static void main(String[] arg){
366
367 os_en=new StreamState(0x04030201);
368 os_de=new StreamState(0x04030201);
369
370 oy=new SyncState();
371
372 // Exercise each code path in the framing code. Also verify that
373 // the checksums are working.
374
375 {
376 // 17 only
377 int[] packets={17, -1};
378 int[] head1={0x4f,0x67,0x67,0x53,0,0x06,
379 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
380 0x01,0x02,0x03,0x04,0,0,0,0,
381 0x15,0xed,0xec,0x91,
382 1,
383 17};
384 int[][] headret={head1, null};
385
386 System.err.print("testing single page encoding... ");
387 test_pack(packets,headret);
388 }
389
390 {
391 // 17, 254, 255, 256, 500, 510, 600 byte, pad
392 int[] packets={17, 254, 255, 256, 500, 510, 600, -1};
393 int[] head1={0x4f,0x67,0x67,0x53,0,0x02,
394 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
395 0x01,0x02,0x03,0x04,0,0,0,0,
396 0x59,0x10,0x6c,0x2c,
397 1,
398 17};
399 int[] head2={0x4f,0x67,0x67,0x53,0,0x04,
400 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
401 0x01,0x02,0x03,0x04,1,0,0,0,
402 0x89,0x33,0x85,0xce,
403 13,
404 254,255,0,255,1,255,245,255,255,0,
405 255,255,90};
406 int[][] headret={head1,head2,null};
407
408 System.err.print("testing basic page encoding... ");
409 test_pack(packets,headret);
410 }
411
412 {
413 // nil packets; beginning,middle,end
414 int[] packets={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
415
416 int[] head1={0x4f,0x67,0x67,0x53,0,0x02,
417 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
418 0x01,0x02,0x03,0x04,0,0,0,0,
419 0xff,0x7b,0x23,0x17,
420 1,
421 0};
422 int[] head2={0x4f,0x67,0x67,0x53,0,0x04,
423 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
424 0x01,0x02,0x03,0x04,1,0,0,0,
425 0x5c,0x3f,0x66,0xcb,
426 17,
427 17,254,255,0,0,255,1,0,255,245,255,255,0,
428 255,255,90,0};
429 int[][] headret={head1,head2,null};
430
431 System.err.print("testing basic nil packets... ");
432 test_pack(packets,headret);
433 }
434
435 {
436 // large initial packet
437 int[] packets={4345,259,255,-1};
438
439 int[] head1={0x4f,0x67,0x67,0x53,0,0x02,
440 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
441 0x01,0x02,0x03,0x04,0,0,0,0,
442 0x01,0x27,0x31,0xaa,
443 18,
444 255,255,255,255,255,255,255,255,
445 255,255,255,255,255,255,255,255,255,10};
446
447 int[] head2={0x4f,0x67,0x67,0x53,0,0x04,
448 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
449 0x01,0x02,0x03,0x04,1,0,0,0,
450 0x7f,0x4e,0x8a,0xd2,
451 4,
452 255,4,255,0};
453 int[][] headret={head1,head2,null};
454
455 System.err.print("testing initial-packet lacing > 4k... ");
456 test_pack(packets,headret);
457 }
458
459 {
460 // continuing packet test
461 int[] packets={0,4345,259,255,-1};
462
463 int[] head1={0x4f,0x67,0x67,0x53,0,0x02,
464 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
465 0x01,0x02,0x03,0x04,0,0,0,0,
466 0xff,0x7b,0x23,0x17,
467 1,
468 0};
469
470 int[] head2={0x4f,0x67,0x67,0x53,0,0x00,
471 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
472 0x01,0x02,0x03,0x04,1,0,0,0,
473 0x34,0x24,0xd5,0x29,
474 17,
475 255,255,255,255,255,255,255,255,
476 255,255,255,255,255,255,255,255,255};
477
478 int[] head3={0x4f,0x67,0x67,0x53,0,0x05,
479 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
480 0x01,0x02,0x03,0x04,2,0,0,0,
481 0xc8,0xc3,0xcb,0xed,
482 5,
483 10,255,4,255,0};
484 int[][] headret={head1,head2,head3,null};
485
486 System.err.print("testing single packet page span... ");
487 test_pack(packets,headret);
488 }
489
490 // page with the 255 segment limit
491 {
492
493 int[] packets={0,10,10,10,10,10,10,10,10,
494 10,10,10,10,10,10,10,10,
495 10,10,10,10,10,10,10,10,
496 10,10,10,10,10,10,10,10,
497 10,10,10,10,10,10,10,10,
498 10,10,10,10,10,10,10,10,
499 10,10,10,10,10,10,10,10,
500 10,10,10,10,10,10,10,10,
501 10,10,10,10,10,10,10,10,
502 10,10,10,10,10,10,10,10,
503 10,10,10,10,10,10,10,10,
504 10,10,10,10,10,10,10,10,
505 10,10,10,10,10,10,10,10,
506 10,10,10,10,10,10,10,10,
507 10,10,10,10,10,10,10,10,
508 10,10,10,10,10,10,10,10,
509 10,10,10,10,10,10,10,10,
510 10,10,10,10,10,10,10,10,
511 10,10,10,10,10,10,10,10,
512 10,10,10,10,10,10,10,10,
513 10,10,10,10,10,10,10,10,
514 10,10,10,10,10,10,10,10,
515 10,10,10,10,10,10,10,10,
516 10,10,10,10,10,10,10,10,
517 10,10,10,10,10,10,10,10,
518 10,10,10,10,10,10,10,10,
519 10,10,10,10,10,10,10,10,
520 10,10,10,10,10,10,10,10,
521 10,10,10,10,10,10,10,10,
522 10,10,10,10,10,10,10,10,
523 10,10,10,10,10,10,10,10,
524 10,10,10,10,10,10,10,50,-1};
525
526 int[] head1={0x4f,0x67,0x67,0x53,0,0x02,
527 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
528 0x01,0x02,0x03,0x04,0,0,0,0,
529 0xff,0x7b,0x23,0x17,
530 1,
531 0};
532
533 int[] head2={0x4f,0x67,0x67,0x53,0,0x00,
534 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
535 0x01,0x02,0x03,0x04,1,0,0,0,
536 0xed,0x2a,0x2e,0xa7,
537 255,
538 10,10,10,10,10,10,10,10,
539 10,10,10,10,10,10,10,10,
540 10,10,10,10,10,10,10,10,
541 10,10,10,10,10,10,10,10,
542 10,10,10,10,10,10,10,10,
543 10,10,10,10,10,10,10,10,
544 10,10,10,10,10,10,10,10,
545 10,10,10,10,10,10,10,10,
546 10,10,10,10,10,10,10,10,
547 10,10,10,10,10,10,10,10,
548 10,10,10,10,10,10,10,10,
549 10,10,10,10,10,10,10,10,
550 10,10,10,10,10,10,10,10,
551 10,10,10,10,10,10,10,10,
552 10,10,10,10,10,10,10,10,
553 10,10,10,10,10,10,10,10,
554 10,10,10,10,10,10,10,10,
555 10,10,10,10,10,10,10,10,
556 10,10,10,10,10,10,10,10,
557 10,10,10,10,10,10,10,10,
558 10,10,10,10,10,10,10,10,
559 10,10,10,10,10,10,10,10,
560 10,10,10,10,10,10,10,10,
561 10,10,10,10,10,10,10,10,
562 10,10,10,10,10,10,10,10,
563 10,10,10,10,10,10,10,10,
564 10,10,10,10,10,10,10,10,
565 10,10,10,10,10,10,10,10,
566 10,10,10,10,10,10,10,10,
567 10,10,10,10,10,10,10,10,
568 10,10,10,10,10,10,10,10,
569 10,10,10,10,10,10,10};
570
571 int[] head3={0x4f,0x67,0x67,0x53,0,0x04,
572 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
573 0x01,0x02,0x03,0x04,2,0,0,0,
574 0x6c,0x3b,0x82,0x3d,
575 1,
576 50};
577 int[][] headret={head1,head2,head3,null};
578
579 System.err.print("testing max packet segments... ");
580 test_pack(packets,headret);
581 }
582
583 {
584 // packet that overspans over an entire page
585
586 int[] packets={0,100,9000,259,255,-1};
587
588 int[] head1={0x4f,0x67,0x67,0x53,0,0x02,
589 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
590 0x01,0x02,0x03,0x04,0,0,0,0,
591 0xff,0x7b,0x23,0x17,
592 1,
593 0};
594
595 int[] head2={0x4f,0x67,0x67,0x53,0,0x00,
596 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
597 0x01,0x02,0x03,0x04,1,0,0,0,
598 0x3c,0xd9,0x4d,0x3f,
599 17,
600 100,255,255,255,255,255,255,255,255,
601 255,255,255,255,255,255,255,255};
602
603 int[] head3={0x4f,0x67,0x67,0x53,0,0x01,
604 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
605 0x01,0x02,0x03,0x04,2,0,0,0,
606 0xbd,0xd5,0xb5,0x8b,
607 17,
608 255,255,255,255,255,255,255,255,
609 255,255,255,255,255,255,255,255,255};
610
611 int[] head4={0x4f,0x67,0x67,0x53,0,0x05,
612 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
613 0x01,0x02,0x03,0x04,3,0,0,0,
614 0xef,0xdd,0x88,0xde,
615 7,
616 255,255,75,255,4,255,0};
617 int[][] headret={head1,head2,head3,head4,null};
618
619 System.err.print("testing very large packets... ");
620 test_pack(packets,headret);
621 }
622
623 {
624 // term only page. why not?
625
626 int[] packets={0,100,4080,-1};
627
628 int[] head1={0x4f,0x67,0x67,0x53,0,0x02,
629 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
630 0x01,0x02,0x03,0x04,0,0,0,0,
631 0xff,0x7b,0x23,0x17,
632 1,
633 0};
634
635 int[] head2={0x4f,0x67,0x67,0x53,0,0x00,
636 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
637 0x01,0x02,0x03,0x04,1,0,0,0,
638 0x3c,0xd9,0x4d,0x3f,
639 17,
640 100,255,255,255,255,255,255,255,255,
641 255,255,255,255,255,255,255,255};
642
643 int[] head3={0x4f,0x67,0x67,0x53,0,0x05,
644 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
645 0x01,0x02,0x03,0x04,2,0,0,0,
646 0xd4,0xe0,0x60,0xe5,
647 1,0};
648
649 int[][] headret={head1,head2,head3,null};
650
651 System.err.print("testing zero data page (1 nil packet)... ");
652 test_pack(packets,headret);
653 }
654
655 {
656 // build a bunch of pages for testing
657 byte[] data=new byte[1024*1024];
658 int[] pl={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1};
659 int inptr=0;
660 Page[] og=new Page[5];
661 for(int i=0; i<5; i++){
662 og[i]=new Page();
663 }
664
665 os_en.reset();
666
667 for(int i=0;pl[i]!=-1;i++){
668 Packet op=new Packet();
669 int len=pl[i];
670
671 op.packet_base=data;
672 op.packet=inptr;
673 op.bytes=len;
674 op.e_o_s=(pl[i+1]<0?1:0);
675 op.granulepos=(i+1)*1000;
676
677 for(int j=0;j<len;j++)data[inptr++]=(byte)(i+j);
678 os_en.packetin(op);
679 }
680
681// free(data);
682
683 // retrieve finished pages
684 for(int i=0;i<5;i++){
685 if(os_en.pageout(og[i])==0){
686 System.err.print("Too few pages output building sync tests!\n");
687 System.exit(1);
688 }
689 og[i].copy_page();
690 }
691
692 // Test lost pages on pagein/packetout: no rollback
693 {
694 Page temp=new Page();
695 Packet test=new Packet();
696
697 System.err.print("Testing loss of pages... ");
698
699 oy.reset();
700 os_de.reset();
701 for(int i=0;i<5;i++){
702 int index=oy.buffer(og[i].header_len);
703 System.arraycopy(og[i].header_base, og[i].header,
704 oy.data, index, og[i].header_len);
705 oy.wrote(og[i].header_len);
706 index=oy.buffer(og[i].body_len);
707 System.arraycopy(og[i].body_base, og[i].body,
708 oy.data, index, og[i].body_len);
709 oy.wrote(og[i].body_len);
710 }
711
712 oy.pageout(temp);
713 os_de.pagein(temp);
714 oy.pageout(temp);
715 os_de.pagein(temp);
716 oy.pageout(temp);
717
718 // skip
719 oy.pageout(temp);
720 os_de.pagein(temp);
721
722 // do we get the expected results/packets?
723
724 if(os_de.packetout(test)!=1)error();
725 test.checkpacket(0,0,0);
726 if(os_de.packetout(test)!=1)error();
727 test.checkpacket(100,1,-1);
728 if(os_de.packetout(test)!=1)error();
729 test.checkpacket(4079,2,3000);
730 if(os_de.packetout(test)!=-1){
731 System.err.println("Error: loss of page did not return error");
732 System.exit(1);
733 }
734 if(os_de.packetout(test)!=1)error();
735 test.checkpacket(76,5,-1);
736 if(os_de.packetout(test)!=1)error();
737 test.checkpacket(34,6,-1);
738 System.err.println("ok.");
739 }
740
741 // Test lost pages on pagein/packetout: rollback with continuation
742 {
743 Page temp=new Page();
744 Packet test=new Packet();
745
746 System.err.print("Testing loss of pages (rollback required)... ");
747
748 oy.reset();
749 os_de.reset();
750 for(int i=0;i<5;i++){
751 int index=oy.buffer(og[i].header_len);
752 System.arraycopy(og[i].header_base, og[i].header,
753 oy.data, index, og[i].header_len);
754 oy.wrote(og[i].header_len);
755 index=oy.buffer(og[i].body_len);
756 System.arraycopy(og[i].body_base, og[i].body,
757 oy.data, index, og[i].body_len);
758 oy.wrote(og[i].body_len);
759 }
760
761 oy.pageout(temp);
762 os_de.pagein(temp);
763 oy.pageout(temp);
764 os_de.pagein(temp);
765 oy.pageout(temp);
766 os_de.pagein(temp);
767 oy.pageout(temp);
768 // skip
769 oy.pageout(temp);
770 os_de.pagein(temp);
771
772 // do we get the expected results/packets?
773
774 if(os_de.packetout(test)!=1)error();
775 test.checkpacket(0,0,0);
776 if(os_de.packetout(test)!=1)error();
777 test.checkpacket(100,1,-1);
778 if(os_de.packetout(test)!=1)error();
779 test.checkpacket(4079,2,3000);
780 if(os_de.packetout(test)!=1)error();
781 test.checkpacket(2956,3,4000);
782 if(os_de.packetout(test)!=-1){
783 System.err.println("Error: loss of page did not return error");
784 System.exit(1);
785 }
786 if(os_de.packetout(test)!=1)error();
787 test.checkpacket(300,13,14000);
788 System.err.println("ok.");
789 }
790
791 // the rest only test sync
792 {
793 Page og_de=new Page();
794 // Test fractional page inputs: incomplete capture
795 System.err.print("Testing sync on partial inputs... ");
796 oy.reset();
797 int index=oy.buffer(og[1].header_len);
798 System.arraycopy(og[1].header_base, og[1].header,
799 oy.data, index, 3);
800 oy.wrote(3);
801 if(oy.pageout(og_de)>0)error();
802
803 // Test fractional page inputs: incomplete fixed header
804 index=oy.buffer(og[1].header_len);
805 System.arraycopy(og[1].header_base, og[1].header+3,
806 oy.data, index, 20);
807
808 oy.wrote(20);
809 if(oy.pageout(og_de)>0)error();
810
811 // Test fractional page inputs: incomplete header
812 index=oy.buffer(og[1].header_len);
813 System.arraycopy(og[1].header_base, og[1].header+23,
814 oy.data, index, 5);
815 oy.wrote(5);
816 if(oy.pageout(og_de)>0)error();
817
818 // Test fractional page inputs: incomplete body
819 index=oy.buffer(og[1].header_len);
820 System.arraycopy(og[1].header_base, og[1].header+28,
821 oy.data, index, og[1].header_len-28);
822 oy.wrote(og[1].header_len-28);
823 if(oy.pageout(og_de)>0)error();
824
825 index=oy.buffer(og[1].body_len);
826 System.arraycopy(og[1].body_base, og[1].body,
827 oy.data, index, 1000);
828 oy.wrote(1000);
829 if(oy.pageout(og_de)>0)error();
830
831 index=oy.buffer(og[1].body_len);
832 System.arraycopy(og[1].body_base, og[1].body+1000,
833 oy.data, index, og[1].body_len-1000);
834 oy.wrote(og[1].body_len-1000);
835 if(oy.pageout(og_de)<=0)error();
836 System.err.println("ok.");
837 }
838
839 // Test fractional page inputs: page + incomplete capture
840 {
841 Page og_de=new Page();
842 System.err.print("Testing sync on 1+partial inputs... ");
843 oy.reset();
844
845 int index=oy.buffer(og[1].header_len);
846 System.arraycopy(og[1].header_base, og[1].header,
847 oy.data, index, og[1].header_len);
848 oy.wrote(og[1].header_len);
849
850 index=oy.buffer(og[1].body_len);
851 System.arraycopy(og[1].body_base, og[1].body,
852 oy.data, index, og[1].body_len);
853 oy.wrote(og[1].body_len);
854
855 index=oy.buffer(og[1].header_len);
856 System.arraycopy(og[1].header_base, og[1].header,
857 oy.data, index, 20);
858 oy.wrote(20);
859 if(oy.pageout(og_de)<=0)error();
860 if(oy.pageout(og_de)>0)error();
861
862 index=oy.buffer(og[1].header_len);
863 System.arraycopy(og[1].header_base, og[1].header+20,
864 oy.data, index, og[1].header_len-20);
865 oy.wrote(og[1].header_len-20);
866 index=oy.buffer(og[1].body_len);
867 System.arraycopy(og[1].body_base, og[1].body,
868 oy.data, index, og[1].body_len);
869
870 oy.wrote(og[1].body_len);
871 if(oy.pageout(og_de)<=0)error();
872
873 System.err.println("ok.");
874 }
875
876// // // // // // // // //
877 // Test recapture: garbage + page
878 {
879 Page og_de=new Page();
880 System.err.print("Testing search for capture... ");
881 oy.reset();
882
883 // 'garbage'
884 int index=oy.buffer(og[1].body_len);
885 System.arraycopy(og[1].body_base, og[1].body,
886 oy.data, index, og[1].body_len);
887 oy.wrote(og[1].body_len);
888
889 index=oy.buffer(og[1].header_len);
890 System.arraycopy(og[1].header_base, og[1].header,
891 oy.data, index, og[1].header_len);
892 oy.wrote(og[1].header_len);
893
894 index=oy.buffer(og[1].body_len);
895 System.arraycopy(og[1].body_base, og[1].body,
896 oy.data, index, og[1].body_len);
897 oy.wrote(og[1].body_len);
898
899 index=oy.buffer(og[2].header_len);
900 System.arraycopy(og[2].header_base, og[2].header,
901 oy.data, index, 20);
902
903 oy.wrote(20);
904 if(oy.pageout(og_de)>0)error();
905 if(oy.pageout(og_de)<=0)error();
906 if(oy.pageout(og_de)>0)error();
907
908 index=oy.buffer(og[2].header_len);
909 System.arraycopy(og[2].header_base, og[2].header+20,
910 oy.data, index, og[2].header_len-20);
911 oy.wrote(og[2].header_len-20);
912 index=oy.buffer(og[2].body_len);
913 System.arraycopy(og[2].body_base, og[2].body,
914 oy.data, index, og[2].body_len);
915 oy.wrote(og[2].body_len);
916 if(oy.pageout(og_de)<=0)error();
917
918 System.err.println("ok.");
919 }
920
921 // Test recapture: page + garbage + page
922 {
923 Page og_de=new Page();
924 System.err.print("Testing recapture... ");
925 oy.reset();
926
927 int index=oy.buffer(og[1].header_len);
928 System.arraycopy(og[1].header_base, og[1].header,
929 oy.data, index, og[1].header_len);
930 oy.wrote(og[1].header_len);
931
932 index=oy.buffer(og[1].body_len);
933 System.arraycopy(og[1].body_base, og[1].body,
934 oy.data, index, og[1].body_len);
935 oy.wrote(og[1].body_len);
936
937 index=oy.buffer(og[2].header_len);
938 System.arraycopy(og[2].header_base, og[2].header,
939 oy.data, index, og[2].header_len);
940 oy.wrote(og[2].header_len);
941
942 index=oy.buffer(og[2].header_len);
943 System.arraycopy(og[2].header_base, og[2].header,
944 oy.data, index, og[2].header_len);
945 oy.wrote(og[2].header_len);
946
947 if(oy.pageout(og_de)<=0)error();
948
949 index=oy.buffer(og[2].body_len);
950 System.arraycopy(og[2].body_base, og[2].body,
951 oy.data, index, og[2].body_len-5);
952 oy.wrote(og[2].body_len-5);
953
954 index=oy.buffer(og[3].header_len);
955 System.arraycopy(og[3].header_base, og[3].header,
956 oy.data, index, og[3].header_len);
957 oy.wrote(og[3].header_len);
958
959 index=oy.buffer(og[3].body_len);
960 System.arraycopy(og[3].body_base, og[3].body,
961 oy.data, index, og[3].body_len);
962 oy.wrote(og[3].body_len);
963
964 if(oy.pageout(og_de)>0)error();
965 if(oy.pageout(og_de)<=0)error();
966
967 System.err.println("ok.");
968 }
969 }
970 //return(0);
971 }
972 */
973}
diff --git a/songdbj/com/jcraft/jogg/StreamState.java b/songdbj/com/jcraft/jogg/StreamState.java
new file mode 100644
index 0000000000..2f34b374f8
--- /dev/null
+++ b/songdbj/com/jcraft/jogg/StreamState.java
@@ -0,0 +1,657 @@
1/* JOrbis
2 * Copyright (C) 2000 ymnk, JCraft,Inc.
3 *
4 * Written by: 2000 ymnk<ymnk@jcraft.com>
5 *
6 * Many thanks to
7 * Monty <monty@xiph.org> and
8 * The XIPHOPHORUS Company http://www.xiph.org/ .
9 * JOrbis has been based on their awesome works, Vorbis codec.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public License
13 * as published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * You should have received a copy of the GNU Library General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26package com.jcraft.jogg;
27
28public class StreamState{
29 byte[] body_data; /* bytes from packet bodies */
30 int body_storage; /* storage elements allocated */
31 int body_fill; /* elements stored; fill mark */
32private int body_returned; /* elements of fill returned */
33
34
35 int[] lacing_vals; /* The values that will go to the segment table */
36 long[] granule_vals; /* pcm_pos values for headers. Not compact
37 this way, but it is simple coupled to the
38 lacing fifo */
39 int lacing_storage;
40 int lacing_fill;
41 int lacing_packet;
42 int lacing_returned;
43
44 byte[] header=new byte[282]; /* working space for header encode */
45 int header_fill;
46
47 public int e_o_s; /* set when we have buffered the last packet in the
48 logical bitstream */
49 int b_o_s; /* set after we've written the initial page
50 of a logical bitstream */
51 int serialno;
52 int pageno;
53 long packetno; /* sequence number for decode; the framing
54 knows where there's a hole in the data,
55 but we need coupling so that the codec
56 (which is in a seperate abstraction
57 layer) also knows about the gap */
58 long granulepos;
59
60 public StreamState(){
61 init();
62 }
63
64 StreamState(int serialno){
65 this();
66 init(serialno);
67 }
68 void init(){
69 body_storage=16*1024;
70 body_data=new byte[body_storage];
71 lacing_storage=1024;
72 lacing_vals=new int[lacing_storage];
73 granule_vals=new long[lacing_storage];
74 }
75 public void init(int serialno){
76 if(body_data==null){ init(); }
77 else{
78 for(int i=0; i<body_data.length; i++) body_data[i]=0;
79 for(int i=0; i<lacing_vals.length; i++) lacing_vals[i]=0;
80 for(int i=0; i<granule_vals.length; i++) granule_vals[i]=0;
81 }
82 this.serialno=serialno;
83 }
84 public void clear(){
85 body_data=null;
86 lacing_vals=null;
87 granule_vals=null;
88 //memset(os,0,sizeof(ogg_stream_state));
89 }
90 void destroy(){
91 clear();
92 }
93 void body_expand(int needed){
94 if(body_storage<=body_fill+needed){
95 body_storage+=(needed+1024);
96 byte[] foo=new byte[body_storage];
97 System.arraycopy(body_data, 0, foo, 0, body_data.length);
98 body_data=foo;
99//System.out.println("expand: body_fill="+body_fill+", body_storage="+body_data.length);
100 }
101 }
102 void lacing_expand(int needed){
103 if(lacing_storage<=lacing_fill+needed){
104 lacing_storage+=(needed+32);
105 int[] foo=new int[lacing_storage];
106 System.arraycopy(lacing_vals, 0, foo, 0, lacing_vals.length);
107 lacing_vals=foo;
108
109 long[] bar=new long[lacing_storage];
110 System.arraycopy(granule_vals, 0, bar, 0, granule_vals.length);
111 granule_vals=bar;
112 }
113 }
114
115 /* submit data to the internal buffer of the framing engine */
116 public int packetin(Packet op){
117 int lacing_val=op.bytes/255+1;
118
119 if(body_returned!=0){
120 /* advance packet data according to the body_returned pointer. We
121 had to keep it around to return a pointer into the buffer last
122 call */
123
124 body_fill-=body_returned;
125 if(body_fill!=0){
126// memmove(os->body_data,os->body_data+os->body_returned,
127// os->body_fill*sizeof(char));
128 System.arraycopy(body_data, body_returned, body_data, 0, body_fill);
129 }
130 body_returned=0;
131 }
132
133 /* make sure we have the buffer storage */
134 body_expand(op.bytes);
135 lacing_expand(lacing_val);
136
137 /* Copy in the submitted packet. Yes, the copy is a waste; this is
138 the liability of overly clean abstraction for the time being. It
139 will actually be fairly easy to eliminate the extra copy in the
140 future */
141
142 System.arraycopy(op.packet_base, op.packet, body_data, body_fill, op.bytes);
143 body_fill+=op.bytes;
144//System.out.println("add: "+body_fill);
145
146 /* Store lacing vals for this packet */
147 int j;
148 for(j=0;j<lacing_val-1;j++){
149 lacing_vals[lacing_fill+j]=255;
150 granule_vals[lacing_fill+j]=granulepos;
151 }
152 lacing_vals[lacing_fill+j]=(op.bytes)%255;
153 granulepos=granule_vals[lacing_fill+j]=op.granulepos;
154
155 /* flag the first segment as the beginning of the packet */
156 lacing_vals[lacing_fill]|= 0x100;
157
158 lacing_fill+=lacing_val;
159
160 /* for the sake of completeness */
161 packetno++;
162
163 if(op.e_o_s!=0)e_o_s=1;
164 return(0);
165 }
166
167 public int packetout(Packet op){
168
169 /* The last part of decode. We have the stream broken into packet
170 segments. Now we need to group them into packets (or return the
171 out of sync markers) */
172
173 int ptr=lacing_returned;
174
175 if(lacing_packet<=ptr){
176 return(0);
177 }
178
179 if((lacing_vals[ptr]&0x400)!=0){
180 /* We lost sync here; let the app know */
181 lacing_returned++;
182
183 /* we need to tell the codec there's a gap; it might need to
184 handle previous packet dependencies. */
185 packetno++;
186 return(-1);
187 }
188
189 /* Gather the whole packet. We'll have no holes or a partial packet */
190 {
191 int size=lacing_vals[ptr]&0xff;
192 int bytes=0;
193
194 op.packet_base=body_data;
195 op.packet=body_returned;
196 op.e_o_s=lacing_vals[ptr]&0x200; /* last packet of the stream? */
197 op.b_o_s=lacing_vals[ptr]&0x100; /* first packet of the stream? */
198 bytes+=size;
199
200 while(size==255){
201 int val=lacing_vals[++ptr];
202 size=val&0xff;
203 if((val&0x200)!=0)op.e_o_s=0x200;
204 bytes+=size;
205 }
206
207 op.packetno=packetno;
208 op.granulepos=granule_vals[ptr];
209 op.bytes=bytes;
210
211//System.out.println(this+" # body_returned="+body_returned);
212 body_returned+=bytes;
213//System.out.println(this+"## body_returned="+body_returned);
214
215 lacing_returned=ptr+1;
216 }
217 packetno++;
218 return(1);
219 }
220
221
222 // add the incoming page to the stream state; we decompose the page
223 // into packet segments here as well.
224
225 public int pagein(Page og){
226 byte[] header_base=og.header_base;
227 int header=og.header;
228 byte[] body_base=og.body_base;
229 int body=og.body;
230 int bodysize=og.body_len;
231 int segptr=0;
232
233 int version=og.version();
234 int continued=og.continued();
235 int bos=og.bos();
236 int eos=og.eos();
237 long granulepos=og.granulepos();
238 int _serialno=og.serialno();
239 int _pageno=og.pageno();
240 int segments=header_base[header+26]&0xff;
241
242 // clean up 'returned data'
243 {
244 int lr=lacing_returned;
245 int br=body_returned;
246
247 // body data
248
249//System.out.println("br="+br+", body_fill="+body_fill);
250
251 if(br!=0){
252 body_fill-=br;
253 if(body_fill!=0){
254 System.arraycopy(body_data, br, body_data, 0, body_fill);
255 }
256 body_returned=0;
257 }
258
259//System.out.println("?? br="+br+", body_fill="+body_fill+" body_returned="+body_returned);
260
261 if(lr!=0){
262 // segment table
263 if((lacing_fill-lr)!=0){
264 System.arraycopy(lacing_vals, lr, lacing_vals, 0, lacing_fill-lr);
265 System.arraycopy(granule_vals, lr, granule_vals, 0, lacing_fill-lr);
266 }
267 lacing_fill-=lr;
268 lacing_packet-=lr;
269 lacing_returned=0;
270 }
271 }
272
273 // check the serial number
274 if(_serialno!=serialno)return(-1);
275 if(version>0)return(-1);
276
277 lacing_expand(segments+1);
278
279 // are we in sequence?
280 if(_pageno!=pageno){
281 int i;
282
283 // unroll previous partial packet (if any)
284 for(i=lacing_packet;i<lacing_fill;i++){
285 body_fill-=lacing_vals[i]&0xff;
286//System.out.println("??");
287 }
288 lacing_fill=lacing_packet;
289
290 // make a note of dropped data in segment table
291 if(pageno!=-1){
292 lacing_vals[lacing_fill++]=0x400;
293 lacing_packet++;
294 }
295
296 // are we a 'continued packet' page? If so, we'll need to skip
297 // some segments
298 if(continued!=0){
299 bos=0;
300 for(;segptr<segments;segptr++){
301 int val=(header_base[header+27+segptr]&0xff);
302 body+=val;
303 bodysize-=val;
304 if(val<255){
305 segptr++;
306 break;
307 }
308 }
309 }
310 }
311
312//System.out.println("bodysize="+bodysize);
313
314 if(bodysize!=0){
315 body_expand(bodysize);
316 System.arraycopy(body_base, body, body_data, body_fill, bodysize);
317 body_fill+=bodysize;
318 }
319
320//System.out.println("bodyfill="+body_fill);
321
322 {
323 int saved=-1;
324 while(segptr<segments){
325 int val=(header_base[header+27+segptr]&0xff);
326 lacing_vals[lacing_fill]=val;
327 granule_vals[lacing_fill]=-1;
328
329 if(bos!=0){
330 lacing_vals[lacing_fill]|=0x100;
331 bos=0;
332 }
333
334 if(val<255)saved=lacing_fill;
335
336 lacing_fill++;
337 segptr++;
338
339 if(val<255)lacing_packet=lacing_fill;
340 }
341
342 /* set the granulepos on the last pcmval of the last full packet */
343 if(saved!=-1){
344 granule_vals[saved]=granulepos;
345 }
346 }
347
348 if(eos!=0){
349 e_o_s=1;
350 if(lacing_fill>0)
351 lacing_vals[lacing_fill-1]|=0x200;
352 }
353
354 pageno=_pageno+1;
355 return(0);
356 }
357
358
359/* This will flush remaining packets into a page (returning nonzero),
360 even if there is not enough data to trigger a flush normally
361 (undersized page). If there are no packets or partial packets to
362 flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will
363 try to flush a normal sized page like ogg_stream_pageout; a call to
364 ogg_stream_flush does not gurantee that all packets have flushed.
365 Only a return value of 0 from ogg_stream_flush indicates all packet
366 data is flushed into pages.
367
368 ogg_stream_page will flush the last page in a stream even if it's
369 undersized; you almost certainly want to use ogg_stream_pageout
370 (and *not* ogg_stream_flush) unless you need to flush an undersized
371 page in the middle of a stream for some reason. */
372
373 public int flush(Page og){
374
375//System.out.println(this+" ---body_returned: "+body_returned);
376
377 int i;
378 int vals=0;
379 int maxvals=(lacing_fill>255?255:lacing_fill);
380 int bytes=0;
381 int acc=0;
382 long granule_pos=granule_vals[0];
383
384 if(maxvals==0)return(0);
385
386 /* construct a page */
387 /* decide how many segments to include */
388
389 /* If this is the initial header case, the first page must only include
390 the initial header packet */
391 if(b_o_s==0){ /* 'initial header page' case */
392 granule_pos=0;
393 for(vals=0;vals<maxvals;vals++){
394 if((lacing_vals[vals]&0x0ff)<255){
395 vals++;
396 break;
397 }
398 }
399 }
400 else{
401 for(vals=0;vals<maxvals;vals++){
402 if(acc>4096)break;
403 acc+=(lacing_vals[vals]&0x0ff);
404 granule_pos=granule_vals[vals];
405 }
406 }
407
408 /* construct the header in temp storage */
409 System.arraycopy("OggS".getBytes(), 0, header, 0, 4);
410
411 /* stream structure version */
412 header[4]=0x00;
413
414 /* continued packet flag? */
415 header[5]=0x00;
416 if((lacing_vals[0]&0x100)==0)header[5]|=0x01;
417 /* first page flag? */
418 if(b_o_s==0) header[5]|=0x02;
419 /* last page flag? */
420 if(e_o_s!=0 && lacing_fill==vals) header[5]|=0x04;
421 b_o_s=1;
422
423 /* 64 bits of PCM position */
424 for(i=6;i<14;i++){
425 header[i]=(byte)granule_pos;
426 granule_pos>>>=8;
427 }
428
429 /* 32 bits of stream serial number */
430 {
431 int _serialno=serialno;
432 for(i=14;i<18;i++){
433 header[i]=(byte)_serialno;
434 _serialno>>>=8;
435 }
436 }
437
438 /* 32 bits of page counter (we have both counter and page header
439 because this val can roll over) */
440 if(pageno==-1)pageno=0; /* because someone called
441 stream_reset; this would be a
442 strange thing to do in an
443 encode stream, but it has
444 plausible uses */
445 {
446 int _pageno=pageno++;
447 for(i=18;i<22;i++){
448 header[i]=(byte)_pageno;
449 _pageno>>>=8;
450 }
451 }
452
453 /* zero for computation; filled in later */
454 header[22]=0;
455 header[23]=0;
456 header[24]=0;
457 header[25]=0;
458
459 /* segment table */
460 header[26]=(byte)vals;
461 for(i=0;i<vals;i++){
462 header[i+27]=(byte)lacing_vals[i];
463 bytes+=(header[i+27]&0xff);
464 }
465
466 /* set pointers in the ogg_page struct */
467 og.header_base=header;
468 og.header=0;
469 og.header_len=header_fill=vals+27;
470 og.body_base=body_data;
471 og.body=body_returned;
472 og.body_len=bytes;
473
474 /* advance the lacing data and set the body_returned pointer */
475
476//System.out.println("###body_returned: "+body_returned);
477
478 lacing_fill-=vals;
479 System.arraycopy(lacing_vals, vals, lacing_vals, 0, lacing_fill*4);
480 System.arraycopy(granule_vals, vals, granule_vals, 0, lacing_fill*8);
481 body_returned+=bytes;
482
483//System.out.println("####body_returned: "+body_returned);
484
485 /* calculate the checksum */
486
487 og.checksum();
488
489 /* done */
490 return(1);
491 }
492
493
494/* This constructs pages from buffered packet segments. The pointers
495returned are to static buffers; do not free. The returned buffers are
496good only until the next call (using the same ogg_stream_state) */
497 public int pageout(Page og){
498// if(body_returned!=0){
499// /* advance packet data according to the body_returned pointer. We
500// had to keep it around to return a pointer into the buffer last
501// call */
502//
503// body_fill-=body_returned;
504// if(body_fill!=0){ // overlap?
505// System.arraycopy(body_data, body_returned, body_data, 0, body_fill);
506// }
507// body_returned=0;
508// }
509//
510//System.out.println("pageout: e_o_s="+e_o_s+" lacing_fill="+lacing_fill+" body_fill="+body_fill+", lacing_fill="+lacing_fill+" b_o_s="+b_o_s);
511//
512// if((e_o_s!=0&&lacing_fill!=0) || /* 'were done, now flush' case */
513// body_fill > 4096 || /* 'page nominal size' case */
514// lacing_fill>=255 || /* 'segment table full' case */
515// (lacing_fill!=0&&b_o_s==0)){ /* 'initial header page' case */
516// int vals=0,bytes=0;
517// int maxvals=(lacing_fill>255?255:lacing_fill);
518// long acc=0;
519// long pcm_pos=granule_vals[0];
520//
521// /* construct a page */
522// /* decide how many segments to include */
523//
524// /* If this is the initial header case, the first page must only include
525// the initial header packet */
526// if(b_o_s==0){ /* 'initial header page' case */
527// pcm_pos=0;
528// for(vals=0;vals<maxvals;vals++){
529// if((lacing_vals[vals]&0x0ff)<255){
530// vals++;
531// break;
532// }
533// }
534// }
535// else{
536// for(vals=0;vals<maxvals;vals++){
537// if(acc>4096)break;
538// acc+=lacing_vals[vals]&0x0ff;
539// pcm_pos=granule_vals[vals];
540// }
541// }
542//
543// /* construct the header in temp storage */
544// System.arraycopy("OggS".getBytes(), 0, header, 0, 4);
545//
546// /* stream structure version */
547// header[4]=0x00;
548//
549// /* continued packet flag? */
550// header[5]=0x00;
551// if((lacing_vals[0]&0x100)==0)header[5]|=0x01;
552// /* first page flag? */
553// if(b_o_s==0)header[5]|=0x02;
554// /* last page flag? */
555// if(e_o_s!=0 && lacing_fill==vals)header[5]|=0x04;
556// b_o_s=1;
557//
558// /* 64 bits of PCM position */
559// for(int i=6;i<14;i++){
560// header[i]=(byte)pcm_pos;
561// pcm_pos>>>=8;
562// }
563//
564// /* 32 bits of stream serial number */
565// {
566// int serialn=serialno;
567// for(int i=14;i<18;i++){
568// header[i]=(byte)serialn;
569// serialn>>>=8;
570// }
571// }
572//
573//
574///* 32 bits of page counter (we have both counter and page header
575// because this val can roll over) */
576// if(pageno==-1)pageno=0; /* because someone called
577// stream_reset; this would be a
578// strange thing to do in an
579// encode stream, but it has
580// plausible uses */
581// {
582// int pagen=pageno++;
583// for(int i=18;i<22;i++){
584// header[i]=(byte)pagen;
585// pagen>>>=8;
586// }
587// }
588//
589// /* zero for computation; filled in later */
590// header[22]=0;
591// header[23]=0;
592// header[24]=0;
593// header[25]=0;
594//
595// /* segment table */
596// header[26]=(byte)vals;
597// for(int i=0;i<vals;i++){
598// header[i+27]=(byte)lacing_vals[i];
599// bytes+=header[i+27]&0xff;
600//// bytes+=header[i+27]=(lacing_vals[i]&0xff);
601// }
602//
603// /* advance the lacing data and set the body_returned pointer */
604//
605// lacing_fill-=vals;
606// System.arraycopy(lacing_vals, vals, lacing_vals, 0, lacing_fill);
607// System.arraycopy(granule_vals, vals, granule_vals, 0, lacing_fill);
608// body_returned=bytes;
609//
610// /* set pointers in the ogg_page struct */
611// og.header_base=header;
612// og.header=0;
613// og.header_len=header_fill=vals+27;
614//
615// og.body_base=body_data;
616// og.body=0;
617// og.body_len=bytes;
618//
619// /* calculate the checksum */
620//
621// og.checksum();
622// return(1);
623// }
624// /* not enough data to construct a page and not end of stream */
625// return(0);
626//System.out.println("pageout: "+body_returned);
627 if((e_o_s!=0&&lacing_fill!=0) || /* 'were done, now flush' case */
628 body_fill-body_returned> 4096 || /* 'page nominal size' case */
629 lacing_fill>=255 || /* 'segment table full' case */
630 (lacing_fill!=0&&b_o_s==0)){ /* 'initial header page' case */
631 return flush(og);
632 }
633 return 0;
634 }
635
636 public int eof(){
637 return e_o_s;
638 }
639
640 public int reset(){
641 body_fill=0;
642 body_returned=0;
643
644 lacing_fill=0;
645 lacing_packet=0;
646 lacing_returned=0;
647
648 header_fill=0;
649
650 e_o_s=0;
651 b_o_s=0;
652 pageno=-1;
653 packetno=0;
654 granulepos=0;
655 return(0);
656 }
657}
diff --git a/songdbj/com/jcraft/jogg/SyncState.java b/songdbj/com/jcraft/jogg/SyncState.java
new file mode 100644
index 0000000000..b3705e54dd
--- /dev/null
+++ b/songdbj/com/jcraft/jogg/SyncState.java
@@ -0,0 +1,275 @@
1/* JOrbis
2 * Copyright (C) 2000 ymnk, JCraft,Inc.
3 *
4 * Written by: 2000 ymnk<ymnk@jcraft.com>
5 *
6 * Many thanks to
7 * Monty <monty@xiph.org> and
8 * The XIPHOPHORUS Company http://www.xiph.org/ .
9 * JOrbis has been based on their awesome works, Vorbis codec.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public License
13 * as published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * You should have received a copy of the GNU Library General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26package com.jcraft.jogg;
27
28// DECODING PRIMITIVES: packet streaming layer
29
30// This has two layers to place more of the multi-serialno and paging
31// control in the application's hands. First, we expose a data buffer
32// using ogg_decode_buffer(). The app either copies into the
33// buffer, or passes it directly to read(), etc. We then call
34// ogg_decode_wrote() to tell how many bytes we just added.
35//
36// Pages are returned (pointers into the buffer in ogg_sync_state)
37// by ogg_decode_stream(). The page is then submitted to
38// ogg_decode_page() along with the appropriate
39// ogg_stream_state* (ie, matching serialno). We then get raw
40// packets out calling ogg_stream_packet() with a
41// ogg_stream_state. See the 'frame-prog.txt' docs for details and
42// example code.
43
44public class SyncState{
45
46 public byte[] data;
47 int storage;
48 int fill;
49 int returned;
50
51 int unsynced;
52 int headerbytes;
53 int bodybytes;
54
55 public int clear(){
56 data=null;
57 return(0);
58 }
59
60// !!!!!!!!!!!!
61// byte[] buffer(int size){
62 public int buffer(int size){
63 // first, clear out any space that has been previously returned
64 if(returned!=0){
65 fill-=returned;
66 if(fill>0){
67 System.arraycopy(data, returned, data, 0, fill);
68 }
69 returned=0;
70 }
71
72 if(size>storage-fill){
73 // We need to extend the internal buffer
74 int newsize=size+fill+4096; // an extra page to be nice
75 if(data!=null){
76 byte[] foo=new byte[newsize];
77 System.arraycopy(data, 0, foo, 0, data.length);
78 data=foo;
79 }
80 else{
81 data=new byte[newsize];
82 }
83 storage=newsize;
84 }
85
86 // expose a segment at least as large as requested at the fill mark
87// return((char *)oy->data+oy->fill);
88// return(data);
89 return(fill);
90 }
91
92 public int wrote(int bytes){
93 if(fill+bytes>storage)return(-1);
94 fill+=bytes;
95 return(0);
96 }
97
98// sync the stream. This is meant to be useful for finding page
99// boundaries.
100//
101// return values for this:
102// -n) skipped n bytes
103// 0) page not ready; more data (no bytes skipped)
104// n) page synced at current location; page length n bytes
105 private Page pageseek=new Page();
106 private byte[] chksum=new byte[4];
107 public int pageseek(Page og){
108 int page=returned;
109 int next;
110 int bytes=fill-returned;
111
112 if(headerbytes==0){
113 int _headerbytes,i;
114 if(bytes<27)return(0); // not enough for a header
115
116 /* verify capture pattern */
117//!!!!!!!!!!!
118 if(data[page]!='O' ||
119 data[page+1]!='g' ||
120 data[page+2]!='g' ||
121 data[page+3]!='S'){
122 headerbytes=0;
123 bodybytes=0;
124
125 // search for possible capture
126 next=0;
127 for(int ii=0; ii<bytes-1; ii++){
128 if(data[page+1+ii]=='O'){next=page+1+ii; break;}
129 }
130 //next=memchr(page+1,'O',bytes-1);
131 if(next==0) next=fill;
132
133 returned=next;
134 return(-(next-page));
135 }
136 _headerbytes=(data[page+26]&0xff)+27;
137 if(bytes<_headerbytes)return(0); // not enough for header + seg table
138
139 // count up body length in the segment table
140
141 for(i=0;i<(data[page+26]&0xff);i++){
142 bodybytes+=(data[page+27+i]&0xff);
143 }
144 headerbytes=_headerbytes;
145 }
146
147 if(bodybytes+headerbytes>bytes)return(0);
148
149 // The whole test page is buffered. Verify the checksum
150 synchronized(chksum){
151 // Grab the checksum bytes, set the header field to zero
152
153 System.arraycopy(data, page+22, chksum, 0, 4);
154 data[page+22]=0;
155 data[page+23]=0;
156 data[page+24]=0;
157 data[page+25]=0;
158
159 // set up a temp page struct and recompute the checksum
160 Page log=pageseek;
161 log.header_base=data;
162 log.header=page;
163 log.header_len=headerbytes;
164
165 log.body_base=data;
166 log.body=page+headerbytes;
167 log.body_len=bodybytes;
168 log.checksum();
169
170 // Compare
171 if(chksum[0]!=data[page+22] ||
172 chksum[1]!=data[page+23] ||
173 chksum[2]!=data[page+24] ||
174 chksum[3]!=data[page+25]){
175 // D'oh. Mismatch! Corrupt page (or miscapture and not a page at all)
176 // replace the computed checksum with the one actually read in
177 System.arraycopy(chksum, 0, data, page+22, 4);
178 // Bad checksum. Lose sync */
179
180 headerbytes=0;
181 bodybytes=0;
182 // search for possible capture
183 next=0;
184 for(int ii=0; ii<bytes-1; ii++){
185 if(data[page+1+ii]=='O'){next=page+1+ii; break;}
186 }
187 //next=memchr(page+1,'O',bytes-1);
188 if(next==0) next=fill;
189 returned=next;
190 return(-(next-page));
191 }
192 }
193
194 // yes, have a whole page all ready to go
195 {
196 page=returned;
197
198 if(og!=null){
199 og.header_base=data;
200 og.header=page;
201 og.header_len=headerbytes;
202 og.body_base=data;
203 og.body=page+headerbytes;
204 og.body_len=bodybytes;
205 }
206
207 unsynced=0;
208 returned+=(bytes=headerbytes+bodybytes);
209 headerbytes=0;
210 bodybytes=0;
211 return(bytes);
212 }
213// headerbytes=0;
214// bodybytes=0;
215// next=0;
216// for(int ii=0; ii<bytes-1; ii++){
217// if(data[page+1+ii]=='O'){next=page+1+ii;}
218// }
219// //next=memchr(page+1,'O',bytes-1);
220// if(next==0) next=fill;
221// returned=next;
222// return(-(next-page));
223 }
224
225
226// sync the stream and get a page. Keep trying until we find a page.
227// Supress 'sync errors' after reporting the first.
228//
229// return values:
230// -1) recapture (hole in data)
231// 0) need more data
232// 1) page returned
233//
234// Returns pointers into buffered data; invalidated by next call to
235// _stream, _clear, _init, or _buffer
236
237 public int pageout(Page og){
238 // all we need to do is verify a page at the head of the stream
239 // buffer. If it doesn't verify, we look for the next potential
240 // frame
241
242 while(true){
243 int ret=pageseek(og);
244 if(ret>0){
245 // have a page
246 return(1);
247 }
248 if(ret==0){
249 // need more data
250 return(0);
251 }
252
253 // head did not start a synced page... skipped some bytes
254 if(unsynced==0){
255 unsynced=1;
256 return(-1);
257 }
258 // loop. keep looking
259 }
260 }
261
262// clear things to an initial state. Good to call, eg, before seeking
263 public int reset(){
264 fill=0;
265 returned=0;
266 unsynced=0;
267 headerbytes=0;
268 bodybytes=0;
269 return(0);
270 }
271 public void init(){}
272
273 public int getDataOffset(){ return returned; }
274 public int getBufferOffset(){ return fill; }
275}