00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <ogg/ogg.h>
00026
00027
00028
00029 int ogg_page_version(ogg_page *og){
00030 return((int)(og->header[4]));
00031 }
00032
00033 int ogg_page_continued(ogg_page *og){
00034 return((int)(og->header[5]&0x01));
00035 }
00036
00037 int ogg_page_bos(ogg_page *og){
00038 return((int)(og->header[5]&0x02));
00039 }
00040
00041 int ogg_page_eos(ogg_page *og){
00042 return((int)(og->header[5]&0x04));
00043 }
00044
00045 ogg_int64_t ogg_page_granulepos(ogg_page *og){
00046 unsigned char *page=og->header;
00047 ogg_int64_t granulepos=page[13]&(0xff);
00048 granulepos= (granulepos<<8)|(page[12]&0xff);
00049 granulepos= (granulepos<<8)|(page[11]&0xff);
00050 granulepos= (granulepos<<8)|(page[10]&0xff);
00051 granulepos= (granulepos<<8)|(page[9]&0xff);
00052 granulepos= (granulepos<<8)|(page[8]&0xff);
00053 granulepos= (granulepos<<8)|(page[7]&0xff);
00054 granulepos= (granulepos<<8)|(page[6]&0xff);
00055 return(granulepos);
00056 }
00057
00058 int ogg_page_serialno(ogg_page *og){
00059 return(og->header[14] |
00060 (og->header[15]<<8) |
00061 (og->header[16]<<16) |
00062 (og->header[17]<<24));
00063 }
00064
00065 long ogg_page_pageno(ogg_page *og){
00066 return(og->header[18] |
00067 (og->header[19]<<8) |
00068 (og->header[20]<<16) |
00069 (og->header[21]<<24));
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 int ogg_page_packets(ogg_page *og){
00092 int i,n=og->header[26],count=0;
00093 for(i=0;i<n;i++)
00094 if(og->header[27+i]<255)count++;
00095 return(count);
00096 }
00097
00098
00099 #if 0
00100
00101
00102
00103 static ogg_uint32_t _ogg_crc_entry(unsigned long index){
00104 int i;
00105 unsigned long r;
00106
00107 r = index << 24;
00108 for (i=0; i<8; i++)
00109 if (r & 0x80000000UL)
00110 r = (r << 1) ^ 0x04c11db7;
00111
00112
00113
00114 else
00115 r<<=1;
00116 return (r & 0xffffffffUL);
00117 }
00118 #endif
00119
00120 static const ogg_uint32_t crc_lookup[256]={
00121 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
00122 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
00123 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
00124 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
00125 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
00126 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
00127 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
00128 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
00129 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
00130 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
00131 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
00132 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
00133 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
00134 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
00135 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
00136 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
00137 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
00138 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
00139 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
00140 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
00141 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
00142 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
00143 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
00144 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
00145 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
00146 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
00147 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
00148 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
00149 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
00150 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
00151 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
00152 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
00153 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
00154 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
00155 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
00156 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
00157 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
00158 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
00159 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
00160 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
00161 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
00162 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
00163 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
00164 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
00165 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
00166 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
00167 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
00168 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
00169 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
00170 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
00171 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
00172 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
00173 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
00174 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
00175 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
00176 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
00177 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
00178 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
00179 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
00180 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
00181 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
00182 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
00183 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
00184 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
00185
00186
00187
00188 int ogg_stream_init(ogg_stream_state *os,int serialno){
00189 if(os){
00190 memset(os,0,sizeof(*os));
00191 os->body_storage=16*1024;
00192 os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data));
00193
00194 os->lacing_storage=1024;
00195 os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
00196 os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
00197
00198 os->serialno=serialno;
00199
00200 return(0);
00201 }
00202 return(-1);
00203 }
00204
00205
00206 int ogg_stream_clear(ogg_stream_state *os){
00207 if(os){
00208 if(os->body_data)_ogg_free(os->body_data);
00209 if(os->lacing_vals)_ogg_free(os->lacing_vals);
00210 if(os->granule_vals)_ogg_free(os->granule_vals);
00211
00212 memset(os,0,sizeof(*os));
00213 }
00214 return(0);
00215 }
00216
00217 int ogg_stream_destroy(ogg_stream_state *os){
00218 if(os){
00219 ogg_stream_clear(os);
00220 _ogg_free(os);
00221 }
00222 return(0);
00223 }
00224
00225
00226
00227
00228 static void _os_body_expand(ogg_stream_state *os,int needed){
00229 if(os->body_storage<=os->body_fill+needed){
00230 os->body_storage+=(needed+1024);
00231 os->body_data=_ogg_realloc(os->body_data,os->body_storage*sizeof(*os->body_data));
00232 }
00233 }
00234
00235 static void _os_lacing_expand(ogg_stream_state *os,int needed){
00236 if(os->lacing_storage<=os->lacing_fill+needed){
00237 os->lacing_storage+=(needed+32);
00238 os->lacing_vals=_ogg_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals));
00239 os->granule_vals=_ogg_realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals));
00240 }
00241 }
00242
00243
00244
00245
00246
00247 void ogg_page_checksum_set(ogg_page *og){
00248 if(og){
00249 ogg_uint32_t crc_reg=0;
00250 int i;
00251
00252
00253 og->header[22]=0;
00254 og->header[23]=0;
00255 og->header[24]=0;
00256 og->header[25]=0;
00257
00258 for(i=0;i<og->header_len;i++)
00259 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
00260 for(i=0;i<og->body_len;i++)
00261 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
00262
00263 og->header[22]=(unsigned char)(crc_reg&0xff);
00264 og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
00265 og->header[24]=(unsigned char)((crc_reg>>16)&0xff);
00266 og->header[25]=(unsigned char)((crc_reg>>24)&0xff);
00267 }
00268 }
00269
00270
00271 int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
00272 int lacing_vals=op->bytes/255+1,i;
00273
00274 if(os->body_returned){
00275
00276
00277
00278
00279 os->body_fill-=os->body_returned;
00280 if(os->body_fill)
00281 memmove(os->body_data,os->body_data+os->body_returned,
00282 os->body_fill);
00283 os->body_returned=0;
00284 }
00285
00286
00287 _os_body_expand(os,op->bytes);
00288 _os_lacing_expand(os,lacing_vals);
00289
00290
00291
00292
00293
00294
00295 memcpy(os->body_data+os->body_fill,op->packet,op->bytes);
00296 os->body_fill+=op->bytes;
00297
00298
00299 for(i=0;i<lacing_vals-1;i++){
00300 os->lacing_vals[os->lacing_fill+i]=255;
00301 os->granule_vals[os->lacing_fill+i]=os->granulepos;
00302 }
00303 os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255;
00304 os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos;
00305
00306
00307 os->lacing_vals[os->lacing_fill]|= 0x100;
00308
00309 os->lacing_fill+=lacing_vals;
00310
00311
00312 os->packetno++;
00313
00314 if(op->e_o_s)os->e_o_s=1;
00315
00316 return(0);
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
00334 int i;
00335 int vals=0;
00336 int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
00337 int bytes=0;
00338 long acc=0;
00339 ogg_int64_t granule_pos=-1;
00340
00341 if(maxvals==0)return(0);
00342
00343
00344
00345
00346
00347
00348 if(os->b_o_s==0){
00349 granule_pos=0;
00350 for(vals=0;vals<maxvals;vals++){
00351 if((os->lacing_vals[vals]&0x0ff)<255){
00352 vals++;
00353 break;
00354 }
00355 }
00356 }else{
00357 for(vals=0;vals<maxvals;vals++){
00358 if(acc>4096)break;
00359 acc+=os->lacing_vals[vals]&0x0ff;
00360 if((os->lacing_vals[vals]&0xff)<255)
00361 granule_pos=os->granule_vals[vals];
00362 }
00363 }
00364
00365
00366 memcpy(os->header,"OggS",4);
00367
00368
00369 os->header[4]=0x00;
00370
00371
00372 os->header[5]=0x00;
00373 if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
00374
00375 if(os->b_o_s==0)os->header[5]|=0x02;
00376
00377 if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
00378 os->b_o_s=1;
00379
00380
00381 for(i=6;i<14;i++){
00382 os->header[i]=(unsigned char)(granule_pos&0xff);
00383 granule_pos>>=8;
00384 }
00385
00386
00387 {
00388 long serialno=os->serialno;
00389 for(i=14;i<18;i++){
00390 os->header[i]=(unsigned char)(serialno&0xff);
00391 serialno>>=8;
00392 }
00393 }
00394
00395
00396
00397 if(os->pageno==-1)os->pageno=0;
00398
00399
00400
00401
00402 {
00403 long pageno=os->pageno++;
00404 for(i=18;i<22;i++){
00405 os->header[i]=(unsigned char)(pageno&0xff);
00406 pageno>>=8;
00407 }
00408 }
00409
00410
00411 os->header[22]=0;
00412 os->header[23]=0;
00413 os->header[24]=0;
00414 os->header[25]=0;
00415
00416
00417 os->header[26]=(unsigned char)(vals&0xff);
00418 for(i=0;i<vals;i++)
00419 bytes+=os->header[i+27]=(unsigned char)(os->lacing_vals[i]&0xff);
00420
00421
00422 og->header=os->header;
00423 og->header_len=os->header_fill=vals+27;
00424 og->body=os->body_data+os->body_returned;
00425 og->body_len=bytes;
00426
00427
00428
00429 os->lacing_fill-=vals;
00430 memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
00431 memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
00432 os->body_returned+=bytes;
00433
00434
00435
00436 ogg_page_checksum_set(og);
00437
00438
00439 return(1);
00440 }
00441
00442
00443
00444
00445
00446
00447 int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
00448
00449 if((os->e_o_s&&os->lacing_fill) ||
00450 os->body_fill-os->body_returned > 4096 ||
00451 os->lacing_fill>=255 ||
00452 (os->lacing_fill&&!os->b_o_s)){
00453
00454 return(ogg_stream_flush(os,og));
00455 }
00456
00457
00458 return(0);
00459 }
00460
00461 int ogg_stream_eos(ogg_stream_state *os){
00462 return os->e_o_s;
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 int ogg_sync_init(ogg_sync_state *oy){
00482 if(oy){
00483 memset(oy,0,sizeof(*oy));
00484 }
00485 return(0);
00486 }
00487
00488
00489 int ogg_sync_clear(ogg_sync_state *oy){
00490 if(oy){
00491 if(oy->data)_ogg_free(oy->data);
00492 ogg_sync_init(oy);
00493 }
00494 return(0);
00495 }
00496
00497 int ogg_sync_destroy(ogg_sync_state *oy){
00498 if(oy){
00499 ogg_sync_clear(oy);
00500 _ogg_free(oy);
00501 }
00502 return(0);
00503 }
00504
00505 char *ogg_sync_buffer(ogg_sync_state *oy, long size){
00506
00507
00508 if(oy->returned){
00509 oy->fill-=oy->returned;
00510 if(oy->fill>0)
00511 memmove(oy->data,oy->data+oy->returned,oy->fill);
00512 oy->returned=0;
00513 }
00514
00515 if(size>oy->storage-oy->fill){
00516
00517 long newsize=size+oy->fill+4096;
00518
00519 if(oy->data)
00520 oy->data=_ogg_realloc(oy->data,newsize);
00521 else
00522 oy->data=_ogg_malloc(newsize);
00523 oy->storage=newsize;
00524 }
00525
00526
00527 return((char *)oy->data+oy->fill);
00528 }
00529
00530 int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
00531 if(oy->fill+bytes>oy->storage)return(-1);
00532 oy->fill+=bytes;
00533 return(0);
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
00547 unsigned char *page=oy->data+oy->returned;
00548 unsigned char *next;
00549 long bytes=oy->fill-oy->returned;
00550
00551 if(oy->headerbytes==0){
00552 int headerbytes,i;
00553 if(bytes<27)return(0);
00554
00555
00556 if(memcmp(page,"OggS",4))goto sync_fail;
00557
00558 headerbytes=page[26]+27;
00559 if(bytes<headerbytes)return(0);
00560
00561
00562
00563 for(i=0;i<page[26];i++)
00564 oy->bodybytes+=page[27+i];
00565 oy->headerbytes=headerbytes;
00566 }
00567
00568 if(oy->bodybytes+oy->headerbytes>bytes)return(0);
00569
00570
00571 {
00572
00573 char chksum[4];
00574 ogg_page log;
00575
00576 memcpy(chksum,page+22,4);
00577 memset(page+22,0,4);
00578
00579
00580 log.header=page;
00581 log.header_len=oy->headerbytes;
00582 log.body=page+oy->headerbytes;
00583 log.body_len=oy->bodybytes;
00584 ogg_page_checksum_set(&log);
00585
00586
00587 if(memcmp(chksum,page+22,4)){
00588
00589
00590
00591 memcpy(page+22,chksum,4);
00592
00593
00594 goto sync_fail;
00595 }
00596 }
00597
00598
00599 {
00600 unsigned char *page=oy->data+oy->returned;
00601 long bytes;
00602
00603 if(og){
00604 og->header=page;
00605 og->header_len=oy->headerbytes;
00606 og->body=page+oy->headerbytes;
00607 og->body_len=oy->bodybytes;
00608 }
00609
00610 oy->unsynced=0;
00611 oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
00612 oy->headerbytes=0;
00613 oy->bodybytes=0;
00614 return(bytes);
00615 }
00616
00617 sync_fail:
00618
00619 oy->headerbytes=0;
00620 oy->bodybytes=0;
00621
00622
00623 next=memchr(page+1,'O',bytes-1);
00624 if(!next)
00625 next=oy->data+oy->fill;
00626
00627 oy->returned=next-oy->data;
00628 return(-(next-page));
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
00643
00644
00645
00646
00647
00648 for(;;){
00649 long ret=ogg_sync_pageseek(oy,og);
00650 if(ret>0){
00651
00652 return(1);
00653 }
00654 if(ret==0){
00655
00656 return(0);
00657 }
00658
00659
00660 if(!oy->unsynced){
00661 oy->unsynced=1;
00662 return(-1);
00663 }
00664
00665
00666
00667 }
00668 }
00669
00670
00671
00672
00673 int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
00674 unsigned char *header=og->header;
00675 unsigned char *body=og->body;
00676 long bodysize=og->body_len;
00677 int segptr=0;
00678
00679 int version=ogg_page_version(og);
00680 int continued=ogg_page_continued(og);
00681 int bos=ogg_page_bos(og);
00682 int eos=ogg_page_eos(og);
00683 ogg_int64_t granulepos=ogg_page_granulepos(og);
00684 int serialno=ogg_page_serialno(og);
00685 long pageno=ogg_page_pageno(og);
00686 int segments=header[26];
00687
00688
00689 {
00690 long lr=os->lacing_returned;
00691 long br=os->body_returned;
00692
00693
00694 if(br){
00695 os->body_fill-=br;
00696 if(os->body_fill)
00697 memmove(os->body_data,os->body_data+br,os->body_fill);
00698 os->body_returned=0;
00699 }
00700
00701 if(lr){
00702
00703 if(os->lacing_fill-lr){
00704 memmove(os->lacing_vals,os->lacing_vals+lr,
00705 (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
00706 memmove(os->granule_vals,os->granule_vals+lr,
00707 (os->lacing_fill-lr)*sizeof(*os->granule_vals));
00708 }
00709 os->lacing_fill-=lr;
00710 os->lacing_packet-=lr;
00711 os->lacing_returned=0;
00712 }
00713 }
00714
00715
00716 if(serialno!=os->serialno)return(-1);
00717 if(version>0)return(-1);
00718
00719 _os_lacing_expand(os,segments+1);
00720
00721
00722 if(pageno!=os->pageno){
00723 int i;
00724
00725
00726 for(i=os->lacing_packet;i<os->lacing_fill;i++)
00727 os->body_fill-=os->lacing_vals[i]&0xff;
00728 os->lacing_fill=os->lacing_packet;
00729
00730
00731 if(os->pageno!=-1){
00732 os->lacing_vals[os->lacing_fill++]=0x400;
00733 os->lacing_packet++;
00734 }
00735 }
00736
00737
00738
00739 if(continued){
00740 if(os->lacing_fill<1 ||
00741 os->lacing_vals[os->lacing_fill-1]==0x400){
00742 bos=0;
00743 for(;segptr<segments;segptr++){
00744 int val=header[27+segptr];
00745 body+=val;
00746 bodysize-=val;
00747 if(val<255){
00748 segptr++;
00749 break;
00750 }
00751 }
00752 }
00753 }
00754
00755 if(bodysize){
00756 _os_body_expand(os,bodysize);
00757 memcpy(os->body_data+os->body_fill,body,bodysize);
00758 os->body_fill+=bodysize;
00759 }
00760
00761 {
00762 int saved=-1;
00763 while(segptr<segments){
00764 int val=header[27+segptr];
00765 os->lacing_vals[os->lacing_fill]=val;
00766 os->granule_vals[os->lacing_fill]=-1;
00767
00768 if(bos){
00769 os->lacing_vals[os->lacing_fill]|=0x100;
00770 bos=0;
00771 }
00772
00773 if(val<255)saved=os->lacing_fill;
00774
00775 os->lacing_fill++;
00776 segptr++;
00777
00778 if(val<255)os->lacing_packet=os->lacing_fill;
00779 }
00780
00781
00782 if(saved!=-1){
00783 os->granule_vals[saved]=granulepos;
00784 }
00785
00786 }
00787
00788 if(eos){
00789 os->e_o_s=1;
00790 if(os->lacing_fill>0)
00791 os->lacing_vals[os->lacing_fill-1]|=0x200;
00792 }
00793
00794 os->pageno=pageno+1;
00795
00796 return(0);
00797 }
00798
00799
00800 int ogg_sync_reset(ogg_sync_state *oy){
00801 oy->fill=0;
00802 oy->returned=0;
00803 oy->unsynced=0;
00804 oy->headerbytes=0;
00805 oy->bodybytes=0;
00806 return(0);
00807 }
00808
00809 int ogg_stream_reset(ogg_stream_state *os){
00810 os->body_fill=0;
00811 os->body_returned=0;
00812
00813 os->lacing_fill=0;
00814 os->lacing_packet=0;
00815 os->lacing_returned=0;
00816
00817 os->header_fill=0;
00818
00819 os->e_o_s=0;
00820 os->b_o_s=0;
00821 os->pageno=-1;
00822 os->packetno=0;
00823 os->granulepos=0;
00824
00825 return(0);
00826 }
00827
00828 int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){
00829 ogg_stream_reset(os);
00830 os->serialno=serialno;
00831 return(0);
00832 }
00833
00834 static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){
00835
00836
00837
00838
00839
00840 int ptr=os->lacing_returned;
00841
00842 if(os->lacing_packet<=ptr)return(0);
00843
00844 if(os->lacing_vals[ptr]&0x400){
00845
00846
00847 os->lacing_returned++;
00848 os->packetno++;
00849 return(-1);
00850 }
00851
00852 if(!op && !adv)return(1);
00853
00854
00855
00856
00857 {
00858 int size=os->lacing_vals[ptr]&0xff;
00859 int bytes=size;
00860 int eos=os->lacing_vals[ptr]&0x200;
00861 int bos=os->lacing_vals[ptr]&0x100;
00862
00863 while(size==255){
00864 int val=os->lacing_vals[++ptr];
00865 size=val&0xff;
00866 if(val&0x200)eos=0x200;
00867 bytes+=size;
00868 }
00869
00870 if(op){
00871 op->e_o_s=eos;
00872 op->b_o_s=bos;
00873 op->packet=os->body_data+os->body_returned;
00874 op->packetno=os->packetno;
00875 op->granulepos=os->granule_vals[ptr];
00876 op->bytes=bytes;
00877 }
00878
00879 if(adv){
00880 os->body_returned+=bytes;
00881 os->lacing_returned=ptr+1;
00882 os->packetno++;
00883 }
00884 }
00885 return(1);
00886 }
00887
00888 int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
00889 return _packetout(os,op,1);
00890 }
00891
00892 int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){
00893 return _packetout(os,op,0);
00894 }
00895
00896 void ogg_packet_clear(ogg_packet *op) {
00897 _ogg_free(op->packet);
00898 memset(op, 0, sizeof(*op));
00899 }
00900
00901 #ifdef _V_SELFTEST
00902 #include <stdio.h>
00903
00904 ogg_stream_state os_en, os_de;
00905 ogg_sync_state oy;
00906
00907 void checkpacket(ogg_packet *op,int len, int no, int pos){
00908 long j;
00909 static int sequence=0;
00910 static int lastno=0;
00911
00912 if(op->bytes!=len){
00913 fprintf(stderr,"incorrect packet length!\n");
00914 exit(1);
00915 }
00916 if(op->granulepos!=pos){
00917 fprintf(stderr,"incorrect packet position!\n");
00918 exit(1);
00919 }
00920
00921
00922
00923 if(no==0){
00924 sequence=0;
00925 }else{
00926 sequence++;
00927 if(no>lastno+1)
00928 sequence++;
00929 }
00930 lastno=no;
00931 if(op->packetno!=sequence){
00932 fprintf(stderr,"incorrect packet sequence %ld != %d\n",
00933 (long)(op->packetno),sequence);
00934 exit(1);
00935 }
00936
00937
00938 for(j=0;j<op->bytes;j++)
00939 if(op->packet[j]!=((j+no)&0xff)){
00940 fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n",
00941 j,op->packet[j],(j+no)&0xff);
00942 exit(1);
00943 }
00944 }
00945
00946 void check_page(unsigned char *data,const int *header,ogg_page *og){
00947 long j;
00948
00949 for(j=0;j<og->body_len;j++)
00950 if(og->body[j]!=data[j]){
00951 fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n",
00952 j,data[j],og->body[j]);
00953 exit(1);
00954 }
00955
00956
00957 for(j=0;j<og->header_len;j++){
00958 if(og->header[j]!=header[j]){
00959 fprintf(stderr,"header content mismatch at pos %ld:\n",j);
00960 for(j=0;j<header[26]+27;j++)
00961 fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
00962 fprintf(stderr,"\n");
00963 exit(1);
00964 }
00965 }
00966 if(og->header_len!=header[26]+27){
00967 fprintf(stderr,"header length incorrect! (%ld!=%d)\n",
00968 og->header_len,header[26]+27);
00969 exit(1);
00970 }
00971 }
00972
00973 void print_header(ogg_page *og){
00974 int j;
00975 fprintf(stderr,"\nHEADER:\n");
00976 fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n",
00977 og->header[0],og->header[1],og->header[2],og->header[3],
00978 (int)og->header[4],(int)og->header[5]);
00979
00980 fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n",
00981 (og->header[9]<<24)|(og->header[8]<<16)|
00982 (og->header[7]<<8)|og->header[6],
00983 (og->header[17]<<24)|(og->header[16]<<16)|
00984 (og->header[15]<<8)|og->header[14],
00985 ((long)(og->header[21])<<24)|(og->header[20]<<16)|
00986 (og->header[19]<<8)|og->header[18]);
00987
00988 fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (",
00989 (int)og->header[22],(int)og->header[23],
00990 (int)og->header[24],(int)og->header[25],
00991 (int)og->header[26]);
00992
00993 for(j=27;j<og->header_len;j++)
00994 fprintf(stderr,"%d ",(int)og->header[j]);
00995 fprintf(stderr,")\n\n");
00996 }
00997
00998 void copy_page(ogg_page *og){
00999 unsigned char *temp=_ogg_malloc(og->header_len);
01000 memcpy(temp,og->header,og->header_len);
01001 og->header=temp;
01002
01003 temp=_ogg_malloc(og->body_len);
01004 memcpy(temp,og->body,og->body_len);
01005 og->body=temp;
01006 }
01007
01008 void free_page(ogg_page *og){
01009 _ogg_free (og->header);
01010 _ogg_free (og->body);
01011 }
01012
01013 void error(void){
01014 fprintf(stderr,"error!\n");
01015 exit(1);
01016 }
01017
01018
01019 const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06,
01020 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01021 0x01,0x02,0x03,0x04,0,0,0,0,
01022 0x15,0xed,0xec,0x91,
01023 1,
01024 17};
01025
01026
01027 const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02,
01028 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01029 0x01,0x02,0x03,0x04,0,0,0,0,
01030 0x59,0x10,0x6c,0x2c,
01031 1,
01032 17};
01033 const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04,
01034 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
01035 0x01,0x02,0x03,0x04,1,0,0,0,
01036 0x89,0x33,0x85,0xce,
01037 13,
01038 254,255,0,255,1,255,245,255,255,0,
01039 255,255,90};
01040
01041
01042 const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02,
01043 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01044 0x01,0x02,0x03,0x04,0,0,0,0,
01045 0xff,0x7b,0x23,0x17,
01046 1,
01047 0};
01048 const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04,
01049 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
01050 0x01,0x02,0x03,0x04,1,0,0,0,
01051 0x5c,0x3f,0x66,0xcb,
01052 17,
01053 17,254,255,0,0,255,1,0,255,245,255,255,0,
01054 255,255,90,0};
01055
01056
01057 const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02,
01058 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01059 0x01,0x02,0x03,0x04,0,0,0,0,
01060 0x01,0x27,0x31,0xaa,
01061 18,
01062 255,255,255,255,255,255,255,255,
01063 255,255,255,255,255,255,255,255,255,10};
01064
01065 const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04,
01066 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
01067 0x01,0x02,0x03,0x04,1,0,0,0,
01068 0x7f,0x4e,0x8a,0xd2,
01069 4,
01070 255,4,255,0};
01071
01072
01073
01074 const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02,
01075 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01076 0x01,0x02,0x03,0x04,0,0,0,0,
01077 0xff,0x7b,0x23,0x17,
01078 1,
01079 0};
01080
01081 const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00,
01082 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
01083 0x01,0x02,0x03,0x04,1,0,0,0,
01084 0x54,0x05,0x51,0xc8,
01085 17,
01086 255,255,255,255,255,255,255,255,
01087 255,255,255,255,255,255,255,255,255};
01088
01089 const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05,
01090 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
01091 0x01,0x02,0x03,0x04,2,0,0,0,
01092 0xc8,0xc3,0xcb,0xed,
01093 5,
01094 10,255,4,255,0};
01095
01096
01097
01098 const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02,
01099 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01100 0x01,0x02,0x03,0x04,0,0,0,0,
01101 0xff,0x7b,0x23,0x17,
01102 1,
01103 0};
01104
01105 const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00,
01106 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
01107 0x01,0x02,0x03,0x04,1,0,0,0,
01108 0xed,0x2a,0x2e,0xa7,
01109 255,
01110 10,10,10,10,10,10,10,10,
01111 10,10,10,10,10,10,10,10,
01112 10,10,10,10,10,10,10,10,
01113 10,10,10,10,10,10,10,10,
01114 10,10,10,10,10,10,10,10,
01115 10,10,10,10,10,10,10,10,
01116 10,10,10,10,10,10,10,10,
01117 10,10,10,10,10,10,10,10,
01118 10,10,10,10,10,10,10,10,
01119 10,10,10,10,10,10,10,10,
01120 10,10,10,10,10,10,10,10,
01121 10,10,10,10,10,10,10,10,
01122 10,10,10,10,10,10,10,10,
01123 10,10,10,10,10,10,10,10,
01124 10,10,10,10,10,10,10,10,
01125 10,10,10,10,10,10,10,10,
01126 10,10,10,10,10,10,10,10,
01127 10,10,10,10,10,10,10,10,
01128 10,10,10,10,10,10,10,10,
01129 10,10,10,10,10,10,10,10,
01130 10,10,10,10,10,10,10,10,
01131 10,10,10,10,10,10,10,10,
01132 10,10,10,10,10,10,10,10,
01133 10,10,10,10,10,10,10,10,
01134 10,10,10,10,10,10,10,10,
01135 10,10,10,10,10,10,10,10,
01136 10,10,10,10,10,10,10,10,
01137 10,10,10,10,10,10,10,10,
01138 10,10,10,10,10,10,10,10,
01139 10,10,10,10,10,10,10,10,
01140 10,10,10,10,10,10,10,10,
01141 10,10,10,10,10,10,10};
01142
01143 const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04,
01144 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
01145 0x01,0x02,0x03,0x04,2,0,0,0,
01146 0x6c,0x3b,0x82,0x3d,
01147 1,
01148 50};
01149
01150
01151
01152 const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02,
01153 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01154 0x01,0x02,0x03,0x04,0,0,0,0,
01155 0xff,0x7b,0x23,0x17,
01156 1,
01157 0};
01158
01159 const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00,
01160 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
01161 0x01,0x02,0x03,0x04,1,0,0,0,
01162 0x3c,0xd9,0x4d,0x3f,
01163 17,
01164 100,255,255,255,255,255,255,255,255,
01165 255,255,255,255,255,255,255,255};
01166
01167 const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01,
01168 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
01169 0x01,0x02,0x03,0x04,2,0,0,0,
01170 0x01,0xd2,0xe5,0xe5,
01171 17,
01172 255,255,255,255,255,255,255,255,
01173 255,255,255,255,255,255,255,255,255};
01174
01175 const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05,
01176 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
01177 0x01,0x02,0x03,0x04,3,0,0,0,
01178 0xef,0xdd,0x88,0xde,
01179 7,
01180 255,255,75,255,4,255,0};
01181
01182
01183 const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02,
01184 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01185 0x01,0x02,0x03,0x04,0,0,0,0,
01186 0xff,0x7b,0x23,0x17,
01187 1,
01188 0};
01189
01190 const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00,
01191 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
01192 0x01,0x02,0x03,0x04,1,0,0,0,
01193 0x3c,0xd9,0x4d,0x3f,
01194 17,
01195 100,255,255,255,255,255,255,255,255,
01196 255,255,255,255,255,255,255,255};
01197
01198 const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
01199 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
01200 0x01,0x02,0x03,0x04,2,0,0,0,
01201 0xd4,0xe0,0x60,0xe5,
01202 1,0};
01203
01204 void test_pack(const int *pl, const int **headers, int byteskip,
01205 int pageskip, int packetskip){
01206 unsigned char *data=_ogg_malloc(1024*1024);
01207 long inptr=0;
01208 long outptr=0;
01209 long deptr=0;
01210 long depacket=0;
01211 long granule_pos=7,pageno=0;
01212 int i,j,packets,pageout=pageskip;
01213 int eosflag=0;
01214 int bosflag=0;
01215
01216 int byteskipcount=0;
01217
01218 ogg_stream_reset(&os_en);
01219 ogg_stream_reset(&os_de);
01220 ogg_sync_reset(&oy);
01221
01222 for(packets=0;packets<packetskip;packets++)
01223 depacket+=pl[packets];
01224
01225 for(packets=0;;packets++)if(pl[packets]==-1)break;
01226
01227 for(i=0;i<packets;i++){
01228
01229 ogg_packet op;
01230 int len=pl[i];
01231
01232 op.packet=data+inptr;
01233 op.bytes=len;
01234 op.e_o_s=(pl[i+1]<0?1:0);
01235 op.granulepos=granule_pos;
01236
01237 granule_pos+=1024;
01238
01239 for(j=0;j<len;j++)data[inptr++]=i+j;
01240
01241
01242 ogg_stream_packetin(&os_en,&op);
01243
01244
01245 {
01246 ogg_page og;
01247
01248 while(ogg_stream_pageout(&os_en,&og)){
01249
01250
01251 fprintf(stderr,"%ld, ",pageno);
01252
01253 if(headers[pageno]==NULL){
01254 fprintf(stderr,"coded too many pages!\n");
01255 exit(1);
01256 }
01257
01258 check_page(data+outptr,headers[pageno],&og);
01259
01260 outptr+=og.body_len;
01261 pageno++;
01262 if(pageskip){
01263 bosflag=1;
01264 pageskip--;
01265 deptr+=og.body_len;
01266 }
01267
01268
01269
01270 {
01271 ogg_page og_de;
01272 ogg_packet op_de,op_de2;
01273 char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
01274 char *next=buf;
01275 byteskipcount+=og.header_len;
01276 if(byteskipcount>byteskip){
01277 memcpy(next,og.header,byteskipcount-byteskip);
01278 next+=byteskipcount-byteskip;
01279 byteskipcount=byteskip;
01280 }
01281
01282 byteskipcount+=og.body_len;
01283 if(byteskipcount>byteskip){
01284 memcpy(next,og.body,byteskipcount-byteskip);
01285 next+=byteskipcount-byteskip;
01286 byteskipcount=byteskip;
01287 }
01288
01289 ogg_sync_wrote(&oy,next-buf);
01290
01291 while(1){
01292 int ret=ogg_sync_pageout(&oy,&og_de);
01293 if(ret==0)break;
01294 if(ret<0)continue;
01295
01296
01297 fprintf(stderr,"(%ld), ",pageout);
01298
01299 check_page(data+deptr,headers[pageout],&og_de);
01300 deptr+=og_de.body_len;
01301 pageout++;
01302
01303
01304 ogg_stream_pagein(&os_de,&og_de);
01305
01306
01307 while(ogg_stream_packetpeek(&os_de,&op_de2)>0){
01308 ogg_stream_packetpeek(&os_de,NULL);
01309 ogg_stream_packetout(&os_de,&op_de);
01310
01311
01312 if(memcmp(&op_de,&op_de2,sizeof(op_de))){
01313 fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
01314 depacket);
01315 exit(1);
01316 }
01317
01318
01319
01320 if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
01321 fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
01322 depacket);
01323 exit(1);
01324 }
01325
01326 if(bosflag==0 && op_de.b_o_s==0){
01327 fprintf(stderr,"b_o_s flag not set on packet!\n");
01328 exit(1);
01329 }
01330 if(bosflag && op_de.b_o_s){
01331 fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
01332