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 const static 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=(unsigned char*)_ogg_malloc(os->body_storage*sizeof(*os->body_data));
00193
00194 os->lacing_storage=1024;
00195 os->lacing_vals=(int*)_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
00196 os->granule_vals=(ogg_int64_t*)_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=(unsigned char*)_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=(int*)_ogg_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals));
00239 os->granule_vals=(ogg_int64_t*)_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]=crc_reg&0xff;
00264 og->header[23]=(crc_reg>>8)&0xff;
00265 og->header[24]=(crc_reg>>16)&0xff;
00266 og->header[25]=(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=os->granule_vals[0];
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 granule_pos=os->granule_vals[vals];
00361 }
00362 }
00363
00364
00365 memcpy(os->header,"OggS",4);
00366
00367
00368 os->header[4]=0x00;
00369
00370
00371 os->header[5]=0x00;
00372 if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
00373
00374 if(os->b_o_s==0)os->header[5]|=0x02;
00375
00376 if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
00377 os->b_o_s=1;
00378
00379
00380 for(i=6;i<14;i++){
00381 os->header[i]=(granule_pos&0xff);
00382 granule_pos>>=8;
00383 }
00384
00385
00386 {
00387 long serialno=os->serialno;
00388 for(i=14;i<18;i++){
00389 os->header[i]=(serialno&0xff);
00390 serialno>>=8;
00391 }
00392 }
00393
00394
00395
00396 if(os->pageno==-1)os->pageno=0;
00397
00398
00399
00400
00401 {
00402 long pageno=os->pageno++;
00403 for(i=18;i<22;i++){
00404 os->header[i]=(pageno&0xff);
00405 pageno>>=8;
00406 }
00407 }
00408
00409
00410 os->header[22]=0;
00411 os->header[23]=0;
00412 os->header[24]=0;
00413 os->header[25]=0;
00414
00415
00416 os->header[26]=vals&0xff;
00417 for(i=0;i<vals;i++)
00418 bytes+=os->header[i+27]=(os->lacing_vals[i]&0xff);
00419
00420
00421 og->header=os->header;
00422 og->header_len=os->header_fill=vals+27;
00423 og->body=os->body_data+os->body_returned;
00424 og->body_len=bytes;
00425
00426
00427
00428 os->lacing_fill-=vals;
00429 memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
00430 memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
00431 os->body_returned+=bytes;
00432
00433
00434
00435 ogg_page_checksum_set(og);
00436
00437
00438 return(1);
00439 }
00440
00441
00442
00443
00444
00445
00446 int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
00447
00448 if((os->e_o_s&&os->lacing_fill) ||
00449 os->body_fill-os->body_returned > 4096 ||
00450 os->lacing_fill>=255 ||
00451 (os->lacing_fill&&!os->b_o_s)){
00452
00453 return(ogg_stream_flush(os,og));
00454 }
00455
00456
00457 return(0);
00458 }
00459
00460 int ogg_stream_eos(ogg_stream_state *os){
00461 return os->e_o_s;
00462 }
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
00490 int ogg_sync_clear(ogg_sync_state *oy){
00491 if(oy){
00492 if(oy->data)_ogg_free(oy->data);
00493 ogg_sync_init(oy);
00494 }
00495 return(0);
00496 }
00497
00498 int ogg_sync_destroy(ogg_sync_state *oy){
00499 if(oy){
00500 ogg_sync_clear(oy);
00501 _ogg_free(oy);
00502 }
00503 return(0);
00504 }
00505
00506 char *ogg_sync_buffer(ogg_sync_state *oy, long size){
00507
00508
00509 if(oy->returned){
00510 oy->fill-=oy->returned;
00511 if(oy->fill>0)
00512 memmove(oy->data,oy->data+oy->returned,oy->fill);
00513 oy->returned=0;
00514 }
00515
00516 if(size>oy->storage-oy->fill){
00517
00518 long newsize=size+oy->fill+4096;
00519
00520 if(oy->data)
00521 oy->data=(unsigned char*)_ogg_realloc(oy->data,newsize);
00522 else
00523 oy->data=(unsigned char*)_ogg_malloc(newsize);
00524 oy->storage=newsize;
00525 }
00526
00527
00528 return((char *)oy->data+oy->fill);
00529 }
00530
00531 int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
00532 if(oy->fill+bytes>oy->storage)return(-1);
00533 oy->fill+=bytes;
00534 return(0);
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
00548 unsigned char *page=oy->data+oy->returned;
00549 unsigned char *next;
00550 long bytes=oy->fill-oy->returned;
00551
00552 if(oy->headerbytes==0){
00553 int headerbytes,i;
00554 if(bytes<27)return(0);
00555
00556
00557 if(memcmp(page,"OggS",4))goto sync_fail;
00558
00559 headerbytes=page[26]+27;
00560 if(bytes<headerbytes)return(0);
00561
00562
00563
00564 for(i=0;i<page[26];i++)
00565 oy->bodybytes+=page[27+i];
00566 oy->headerbytes=headerbytes;
00567 }
00568
00569 if(oy->bodybytes+oy->headerbytes>bytes)return(0);
00570
00571
00572 {
00573
00574 char chksum[4];
00575 ogg_page log;
00576
00577 memcpy(chksum,page+22,4);
00578 memset(page+22,0,4);
00579
00580
00581 log.header=page;
00582 log.header_len=oy->headerbytes;
00583 log.body=page+oy->headerbytes;
00584 log.body_len=oy->bodybytes;
00585 ogg_page_checksum_set(&log);
00586
00587
00588 if(memcmp(chksum,page+22,4)){
00589
00590
00591
00592 memcpy(page+22,chksum,4);
00593
00594
00595 goto sync_fail;
00596 }
00597 }
00598
00599
00600 {
00601 unsigned char *page=oy->data+oy->returned;
00602 long bytes;
00603
00604 if(og){
00605 og->header=page;
00606 og->header_len=oy->headerbytes;
00607 og->body=page+oy->headerbytes;
00608 og->body_len=oy->bodybytes;
00609 }
00610
00611 oy->unsynced=0;
00612 oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
00613 oy->headerbytes=0;
00614 oy->bodybytes=0;
00615 return(bytes);
00616 }
00617
00618 sync_fail:
00619
00620 oy->headerbytes=0;
00621 oy->bodybytes=0;
00622
00623
00624 next=(unsigned char*)memchr(page+1,'O',bytes-1);
00625 if(!next)
00626 next=oy->data+oy->fill;
00627
00628 oy->returned=next-oy->data;
00629 return(-(next-page));
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
00644
00645
00646
00647
00648
00649 while(1){
00650 long ret=ogg_sync_pageseek(oy,og);
00651 if(ret>0){
00652
00653 return(1);
00654 }
00655 if(ret==0){
00656
00657 return(0);
00658 }
00659
00660
00661 if(!oy->unsynced){
00662 oy->unsynced=1;
00663 return(-1);
00664 }
00665
00666
00667
00668 }
00669 }
00670
00671
00672
00673
00674 int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
00675 unsigned char *header=og->header;
00676 unsigned char *body=og->body;
00677 long bodysize=og->body_len;
00678 int segptr=0;
00679
00680 int version=ogg_page_version(og);
00681 int continued=ogg_page_continued(og);
00682 int bos=ogg_page_bos(og);
00683 int eos=ogg_page_eos(og);
00684 ogg_int64_t granulepos=ogg_page_granulepos(og);
00685 int serialno=ogg_page_serialno(og);
00686 long pageno=ogg_page_pageno(og);
00687 int segments=header[26];
00688
00689
00690 {
00691 long lr=os->lacing_returned;
00692 long br=os->body_returned;
00693
00694
00695 if(br){
00696 os->body_fill-=br;
00697 if(os->body_fill)
00698 memmove(os->body_data,os->body_data+br,os->body_fill);
00699 os->body_returned=0;
00700 }
00701
00702 if(lr){
00703
00704 if(os->lacing_fill-lr){
00705 memmove(os->lacing_vals,os->lacing_vals+lr,
00706 (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
00707 memmove(os->granule_vals,os->granule_vals+lr,
00708 (os->lacing_fill-lr)*sizeof(*os->granule_vals));
00709 }
00710 os->lacing_fill-=lr;
00711 os->lacing_packet-=lr;
00712 os->lacing_returned=0;
00713 }
00714 }
00715
00716
00717 if(serialno!=os->serialno)return(-1);
00718 if(version>0)return(-1);
00719
00720 _os_lacing_expand(os,segments+1);
00721
00722
00723 if(pageno!=os->pageno){
00724 int i;
00725
00726
00727 for(i=os->lacing_packet;i<os->lacing_fill;i++)
00728 os->body_fill-=os->lacing_vals[i]&0xff;
00729 os->lacing_fill=os->lacing_packet;
00730
00731
00732 if(os->pageno!=-1){
00733 os->lacing_vals[os->lacing_fill++]=0x400;
00734 os->lacing_packet++;
00735 }
00736
00737
00738
00739 if(continued){
00740 bos=0;
00741 for(;segptr<segments;segptr++){
00742 int val=header[27+segptr];
00743 body+=val;
00744 bodysize-=val;
00745 if(val<255){
00746 segptr++;
00747 break;
00748 }
00749 }
00750 }
00751 }
00752
00753 if(bodysize){
00754 _os_body_expand(os,bodysize);
00755 memcpy(os->body_data+os->body_fill,body,bodysize);
00756 os->body_fill+=bodysize;
00757 }
00758
00759 {
00760 int saved=-1;
00761 while(segptr<segments){
00762 int val=header[27+segptr];
00763 os->lacing_vals[os->lacing_fill]=val;
00764 os->granule_vals[os->lacing_fill]=-1;
00765
00766 if(bos){
00767 os->lacing_vals[os->lacing_fill]|=0x100;
00768 bos=0;
00769 }
00770
00771 if(val<255)saved=os->lacing_fill;
00772
00773 os->lacing_fill++;
00774 segptr++;
00775
00776 if(val<255)os->lacing_packet=os->lacing_fill;
00777 }
00778
00779
00780 if(saved!=-1){
00781 os->granule_vals[saved]=granulepos;
00782 }
00783
00784 }
00785
00786 if(eos){
00787 os->e_o_s=1;
00788 if(os->lacing_fill>0)
00789 os->lacing_vals[os->lacing_fill-1]|=0x200;
00790 }
00791
00792 os->pageno=pageno+1;
00793
00794 return(0);
00795 }
00796
00797
00798 int ogg_sync_reset(ogg_sync_state *oy){
00799 oy->fill=0;
00800 oy->returned=0;
00801 oy->unsynced=0;
00802 oy->headerbytes=0;
00803 oy->bodybytes=0;
00804 return(0);
00805 }
00806
00807 int ogg_stream_reset(ogg_stream_state *os){
00808 os->body_fill=0;
00809 os->body_returned=0;
00810
00811 os->lacing_fill=0;
00812 os->lacing_packet=0;
00813 os->lacing_returned=0;
00814
00815 os->header_fill=0;
00816
00817 os->e_o_s=0;
00818 os->b_o_s=0;
00819 os->pageno=-1;
00820 os->packetno=0;
00821 os->granulepos=0;
00822
00823 return(0);
00824 }
00825
00826 int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){
00827 ogg_stream_reset(os);
00828 os->serialno=serialno;
00829 return(0);
00830 }
00831
00832 static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){
00833
00834
00835
00836
00837
00838 int ptr=os->lacing_returned;
00839
00840 if(os->lacing_packet<=ptr)return(0);
00841
00842 if(os->lacing_vals[ptr]&0x400){
00843
00844
00845 os->lacing_returned++;
00846 os->packetno++;
00847 return(-1);
00848 }
00849
00850 if(!op && !adv)return(1);
00851
00852
00853
00854
00855 {
00856 int size=os->lacing_vals[ptr]&0xff;
00857 int bytes=size;
00858 int eos=os->lacing_vals[ptr]&0x200;
00859 int bos=os->lacing_vals[ptr]&0x100;
00860
00861 while(size==255){
00862 int val=os->lacing_vals[++ptr];
00863 size=val&0xff;
00864 if(val&0x200)eos=0x200;
00865 bytes+=size;
00866 }
00867
00868 if(op){
00869 op->e_o_s=eos;
00870 op->b_o_s=bos;
00871 op->packet=os->body_data+os->body_returned;
00872 op->packetno=os->packetno;
00873 op->granulepos=os->granule_vals[ptr];
00874 op->bytes=bytes;
00875 }
00876
00877 if(adv){
00878 os->body_returned+=bytes;
00879 os->lacing_returned=ptr+1;
00880 os->packetno++;
00881 }
00882 }
00883 return(1);
00884 }
00885
00886 int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
00887 return _packetout(os,op,1);
00888 }
00889
00890 int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){
00891 return _packetout(os,op,0);
00892 }
00893
00894 void ogg_packet_clear(ogg_packet *op) {
00895 _ogg_free(op->packet);
00896 memset(op, 0, sizeof(*op));
00897 }
00898
00899 #ifdef _V_SELFTEST
00900 #include <stdio.h>
00901
00902 ogg_stream_state os_en, os_de;
00903 ogg_sync_state oy;
00904
00905 void checkpacket(ogg_packet *op,int len, int no, int pos){
00906 long j;
00907 int sequence=0;
00908 int lastno=0;
00909
00910 if(op->bytes!=len){
00911 fprintf(stderr,"incorrect packet length!\n");
00912 exit(1);
00913 }
00914 if(op->granulepos!=pos){
00915 fprintf(stderr,"incorrect packet position!\n");
00916 exit(1);
00917 }
00918
00919
00920
00921 if(no==0){
00922 sequence=0;
00923 }else{
00924 sequence++;
00925 if(no>lastno+1)
00926 sequence++;
00927 }
00928 lastno=no;
00929 if(op->packetno!=sequence){
00930 fprintf(stderr,"incorrect packet sequence %ld != %d\n",
00931 (long)(op->packetno),sequence);
00932 exit(1);
00933 }
00934
00935
00936 for(j=0;j<op->bytes;j++)
00937 if(op->packet[j]!=((j+no)&0xff)){
00938 fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n",
00939 j,op->packet[j],(j+no)&0xff);
00940 exit(1);
00941 }
00942 }
00943
00944 void check_page(unsigned char *data,const int *header,ogg_page *og){
00945 long j;
00946
00947 for(j=0;j<og->body_len;j++)
00948 if(og->body[j]!=data[j]){
00949 fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n",
00950 j,data[j],og->body[j]);
00951 exit(1);
00952 }
00953
00954
00955 for(j=0;j<og->header_len;j++){
00956 if(og->header[j]!=header[j]){
00957 fprintf(stderr,"header content mismatch at pos %ld:\n",j);
00958 for(j=0;j<header[26]+27;j++)
00959 fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
00960 fprintf(stderr,"\n");
00961 exit(1);
00962 }
00963 }
00964 if(og->header_len!=header[26]+27){
00965 fprintf(stderr,"header length incorrect! (%ld!=%d)\n",
00966 og->header_len,header[26]+27);
00967 exit(1);
00968 }
00969 }
00970
00971 void print_header(ogg_page *og){
00972 int j;
00973 fprintf(stderr,"\nHEADER:\n");
00974 fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n",
00975 og->header[0],og->header[1],og->header[2],og->header[3],
00976 (int)og->header[4],(int)og->header[5]);
00977
00978 fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n",
00979 (og->header[9]<<24)|(og->header[8]<<16)|
00980 (og->header[7]<<8)|og->header[6],
00981 (og->header[17]<<24)|(og->header[16]<<16)|
00982 (og->header[15]<<8)|og->header[14],
00983 ((long)(og->header[21])<<24)|(og->header[20]<<16)|
00984 (og->header[19]<<8)|og->header[18]);
00985
00986 fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (",
00987 (int)og->header[22],(int)og->header[23],
00988 (int)og->header[24],(int)og->header[25],
00989 (int)og->header[26]);
00990
00991 for(j=27;j<og->header_len;j++)
00992 fprintf(stderr,"%d ",(int)og->header[j]);
00993 fprintf(stderr,")\n\n");
00994 }
00995
00996 void copy_page(ogg_page *og){
00997 unsigned char *temp=_ogg_malloc(og->header_len);
00998 memcpy(temp,og->header,og->header_len);
00999 og->header=temp;
01000
01001 temp=_ogg_malloc(og->body_len);
01002 memcpy(temp,og->body,og->body_len);
01003 og->body=temp;
01004 }
01005
01006 void error(void){
01007 fprintf(stderr,"error!\n");
01008 exit(1);
01009 }
01010
01011
01012 const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06,
01013 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01014 0x01,0x02,0x03,0x04,0,0,0,0,
01015 0x15,0xed,0xec,0x91,
01016 1,
01017 17};
01018
01019
01020 const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02,
01021 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01022 0x01,0x02,0x03,0x04,0,0,0,0,
01023 0x59,0x10,0x6c,0x2c,
01024 1,
01025 17};
01026 const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04,
01027 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
01028 0x01,0x02,0x03,0x04,1,0,0,0,
01029 0x89,0x33,0x85,0xce,
01030 13,
01031 254,255,0,255,1,255,245,255,255,0,
01032 255,255,90};
01033
01034
01035 const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02,
01036 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01037 0x01,0x02,0x03,0x04,0,0,0,0,
01038 0xff,0x7b,0x23,0x17,
01039 1,
01040 0};
01041 const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04,
01042 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
01043 0x01,0x02,0x03,0x04,1,0,0,0,
01044 0x5c,0x3f,0x66,0xcb,
01045 17,
01046 17,254,255,0,0,255,1,0,255,245,255,255,0,
01047 255,255,90,0};
01048
01049
01050 const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02,
01051 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01052 0x01,0x02,0x03,0x04,0,0,0,0,
01053 0x01,0x27,0x31,0xaa,
01054 18,
01055 255,255,255,255,255,255,255,255,
01056 255,255,255,255,255,255,255,255,255,10};
01057
01058 const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04,
01059 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
01060 0x01,0x02,0x03,0x04,1,0,0,0,
01061 0x7f,0x4e,0x8a,0xd2,
01062 4,
01063 255,4,255,0};
01064
01065
01066
01067 const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02,
01068 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01069 0x01,0x02,0x03,0x04,0,0,0,0,
01070 0xff,0x7b,0x23,0x17,
01071 1,
01072 0};
01073
01074 const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00,
01075 0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01076 0x01,0x02,0x03,0x04,1,0,0,0,
01077 0x34,0x24,0xd5,0x29,
01078 17,
01079 255,255,255,255,255,255,255,255,
01080 255,255,255,255,255,255,255,255,255};
01081
01082 const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05,
01083 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
01084 0x01,0x02,0x03,0x04,2,0,0,0,
01085 0xc8,0xc3,0xcb,0xed,
01086 5,
01087 10,255,4,255,0};
01088
01089
01090
01091 const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02,
01092 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01093 0x01,0x02,0x03,0x04,0,0,0,0,
01094 0xff,0x7b,0x23,0x17,
01095 1,
01096 0};
01097
01098 const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00,
01099 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
01100 0x01,0x02,0x03,0x04,1,0,0,0,
01101 0xed,0x2a,0x2e,0xa7,
01102 255,
01103 10,10,10,10,10,10,10,10,
01104 10,10,10,10,10,10,10,10,
01105 10,10,10,10,10,10,10,10,
01106 10,10,10,10,10,10,10,10,
01107 10,10,10,10,10,10,10,10,
01108 10,10,10,10,10,10,10,10,
01109 10,10,10,10,10,10,10,10,
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};
01135
01136 const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04,
01137 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
01138 0x01,0x02,0x03,0x04,2,0,0,0,
01139 0x6c,0x3b,0x82,0x3d,
01140 1,
01141 50};
01142
01143
01144
01145 const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02,
01146 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01147 0x01,0x02,0x03,0x04,0,0,0,0,
01148 0xff,0x7b,0x23,0x17,
01149 1,
01150 0};
01151
01152 const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00,
01153 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
01154 0x01,0x02,0x03,0x04,1,0,0,0,
01155 0x3c,0xd9,0x4d,0x3f,
01156 17,
01157 100,255,255,255,255,255,255,255,255,
01158 255,255,255,255,255,255,255,255};
01159
01160 const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01,
01161 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
01162 0x01,0x02,0x03,0x04,2,0,0,0,
01163 0xbd,0xd5,0xb5,0x8b,
01164 17,
01165 255,255,255,255,255,255,255,255,
01166 255,255,255,255,255,255,255,255,255};
01167
01168 const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05,
01169 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
01170 0x01,0x02,0x03,0x04,3,0,0,0,
01171 0xef,0xdd,0x88,0xde,
01172 7,
01173 255,255,75,255,4,255,0};
01174
01175
01176 const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02,
01177 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
01178 0x01,0x02,0x03,0x04,0,0,0,0,
01179 0xff,0x7b,0x23,0x17,
01180 1,
01181 0};
01182
01183 const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00,
01184 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
01185 0x01,0x02,0x03,0x04,1,0,0,0,
01186 0x3c,0xd9,0x4d,0x3f,
01187 17,
01188 100,255,255,255,255,255,255,255,255,
01189 255,255,255,255,255,255,255,255};
01190
01191 const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
01192 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
01193 0x01,0x02,0x03,0x04,2,0,0,0,
01194 0xd4,0xe0,0x60,0xe5,
01195 1,0};
01196
01197 void test_pack(const int *pl, const int **headers){
01198 unsigned char *data=_ogg_malloc(1024*1024);
01199 long inptr=0;
01200 long outptr=0;
01201 long deptr=0;
01202 long depacket=0;
01203 long granule_pos=7,pageno=0;
01204 int i,j,packets,pageout=0;
01205 int eosflag=0;
01206 int bosflag=0;
01207
01208 ogg_stream_reset(&os_en);
01209 ogg_stream_reset(&os_de);
01210 ogg_sync_reset(&oy);
01211
01212 for(packets=0;;packets++)if(pl[packets]==-1)break;
01213
01214 for(i=0;i<packets;i++){
01215
01216 ogg_packet op;
01217 int len=pl[i];
01218
01219 op.packet=data+inptr;
01220 op.bytes=len;
01221 op.e_o_s=(pl[i+1]<0?1:0);
01222 op.granulepos=granule_pos;
01223
01224 granule_pos+=1024;
01225
01226 for(j=0;j<len;j++)data[inptr++]=i+j;
01227
01228
01229 ogg_stream_packetin(&os_en,&op);
01230
01231
01232 {
01233 ogg_page og;
01234
01235 while(ogg_stream_pageout(&os_en,&og)){
01236
01237
01238 fprintf(stderr,"%ld, ",pageno);
01239
01240 if(headers[pageno]==NULL){
01241 fprintf(stderr,"coded too many pages!\n");
01242 exit(1);
01243 }
01244
01245 check_page(data+outptr,headers[pageno],&og);
01246
01247 outptr+=og.body_len;
01248 pageno++;
01249
01250
01251
01252 {
01253 ogg_page og_de;
01254 ogg_packet op_de,op_de2;
01255 char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
01256 memcpy(buf,og.header,og.header_len);
01257 memcpy(buf+og.header_len,og.body,og.body_len);
01258 ogg_sync_wrote(&oy,og.header_len+og.body_len);
01259
01260 while(ogg_sync_pageout(&oy,&og_de)>0){
01261
01262
01263 check_page(data+deptr,headers[pageout],&og_de);
01264 deptr+=og_de.body_len;
01265 pageout++;
01266
01267
01268 ogg_stream_pagein(&os_de,&og_de);
01269
01270
01271 while(ogg_stream_packetpeek(&os_de,&op_de2)>0){
01272 ogg_stream_packetpeek(&os_de,NULL);
01273 ogg_stream_packetout(&os_de,&op_de);
01274
01275
01276 if(memcmp(&op_de,&op_de2,sizeof(op_de))){
01277 fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
01278 depacket);
01279 exit(1);
01280 }
01281
01282
01283
01284 if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
01285 fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
01286 depacket);
01287 exit(1);
01288 }
01289
01290 if(bosflag==0 && op_de.b_o_s==0){
01291 fprintf(stderr,"b_o_s flag not set on packet!\n");
01292 exit(1);
01293 }
01294 if(bosflag && op_de.b_o_s){
01295 fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
01296 exit(1);
01297 }
01298 bosflag=1;
01299 depacket+=op_de.bytes;
01300
01301
01302 if(eosflag){
01303 fprintf(stderr,"Multiple decoded packets with eos flag!\n");
01304 exit(1);
01305 }
01306
01307 if(op_de.e_o_s)eosflag=1;
01308
01309
01310 if(op_de.granulepos!=-1){
01311 fprintf(stderr," granule:%ld ",(long)op_de.granulepos);
01312 }
01313 }
01314 }
01315 }
01316 }
01317 }
01318 }
01319 _ogg_free(data);
01320 if(headers[pageno]!=NULL){
01321 fprintf(stderr,"did not write last page!\n");
01322 exit(1);
01323 }
01324 if(headers[pageout]!=NULL){
01325 fprintf(stderr,"did not decode last page!\n");
01326 exit(1);
01327 }
01328 if(inptr!=outptr){
01329 fprintf(stderr,"encoded page data incomplete!\n");
01330 exit(1);
01331 }
01332 if(inptr!=deptr){
01333 fprintf(stderr,"decoded page data incomplete!\n");
01334 exit(1);
01335 }
01336 if(inptr!=depacket){
01337 fprintf(stderr,"decoded packet data incomplete!\n");
01338 exit(1);
01339 }
01340 if(!eosflag){
01341 fprintf(stderr,"Never got a packet with EOS set!\n");
01342 exit(1);
01343 }
01344 fprintf(stderr,"ok.\n");
01345 }
01346
01347 int main(void){
01348
01349 ogg_stream_init(&os_en,0x04030201);
01350 ogg_stream_init(&os_de,0x04030201);
01351 ogg_sync_init(&oy);
01352
01353
01354
01355
01356 {
01357
01358 const int packets[]={17, -1};
01359 const int *headret[]={head1_0,NULL};
01360
01361 fprintf(stderr,"testing single page encoding... ");
01362 test_pack(packets,headret);
01363 }
01364
01365 {
01366
01367 const int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
01368 const int *headret[]={head1_1,head2_1,NULL};
01369
01370 fprintf(stderr,"testing basic page encoding... ");
01371 test_pack(packets,headret);
01372 }
01373
01374 {
01375
01376 const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
01377 const int *headret[]={head1_2,head2_2,NULL};
01378
01379 fprintf(stderr,"testing basic nil packets... ");
01380 test_pack(packets,headret);
01381 }
01382
01383 {
01384
01385 const int packets[]={4345,259,255,-1};
01386 const int *headret[]={head1_3,head2_3,NULL};
01387
01388 fprintf(stderr,"testing initial-packet lacing > 4k... ");
01389 test_pack(packets,headret);
01390 }
01391
01392 {
01393
01394 const int packets[]={0,4345,259,255,-1};
01395 const int *headret[]={head1_4,head2_4,head3_4,NULL};
01396
01397 fprintf(stderr,"testing single packet page span... ");
01398 test_pack(packets,headret);
01399 }
01400
01401
01402 {
01403
01404 const int packets[]={0,10,10,10,10,10,10,10,10,
01405 10,10,10,10,10,10,10,10,
01406 10,10,10,10,10,10,10,10,
01407 10,10,10,10,10,10,10,10,
01408 10,10,10,10,10,10,10,10,
01409 10,10,10,10,10,10,10,10,
01410 10,10,10,10,10,10,10,10,
01411 10,10,10,10,10,10,10,10,
01412 10,10,10,10,10,10,10,10,
01413 10,10,10,10,10,10,10,10,
01414 10,10,10,10,10,10,10,10,
01415 10,10,10,10,10,10,10,10,
01416 10,10,10,10,10,10,10,10,
01417 10,10,10,10,10,10,10,10,
01418 10,10,10,10,10,10,10,10,
01419 10,10,10,10,10,10,10,10,
01420 10,10,10,10,10,10,10,10,
01421 10,10,10,10,10,10,10,10,
01422 10,10,10,10,10,10,10,10,
01423 10,10,10,10,10,10,10,10,
01424 10,10,10,10,10,10,10,10,
01425 10,10,10,10,10,10,10,10,
01426 10,10,10,10,10,10,10,10,
01427 10,10,10,10,10,10,10,10,
01428 10,10,10,10,10,10,10,10,
01429 10,10,10,10,10,10,10,10,
01430 10,10,10,10,10,10,10,10,
01431 10,10,10,10,10,10,10,10,
01432 10,10,10,10,10,10,10,10,
01433 10,10,10,10,10,10,10,10,
01434 10,10,10,10,10,10,10,10,
01435 10,10,10,10,10,10,10,50,-1};
01436 const int *headret[]={head1_5,head2_5,head3_5,NULL};
01437
01438 fprintf(stderr,"testing max packet segments... ");
01439 test_pack(packets,headret);
01440 }
01441
01442 {
01443
01444 const int packets[]={0,100,9000,259,255,-1};
01445 const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
01446
01447 fprintf(stderr,"testing very large packets... ");
01448 test_pack(packets,headret);
01449 }
01450
01451 {
01452
01453 const int packets[]={0,100,4080,-1};
01454 const int *headret[]={head1_7,head2_7,head3_7,NULL};
01455
01456 fprintf(stderr,"testing zero data page (1 nil packet)... ");
01457 test_pack(packets,headret);
01458 }
01459
01460
01461
01462 {
01463
01464 unsigned char *data=_ogg_malloc(1024*1024);
01465 int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1};
01466 int inptr=0,i,j;
01467 ogg_page og[5];
01468
01469 ogg_stream_reset(&os_en);
01470
01471 for(i=0;pl[i]!=-1;i++){
01472 ogg_packet op;
01473 int len=pl[i];
01474
01475 op.packet=data+inptr;
01476 op.bytes=len;
01477 op.e_o_s=(pl[i+1]<0?1:0);
01478 op.granulepos=(i+1)*1000;
01479
01480 for(j=0;j<len;j++)data[inptr++]=i+j;
01481 ogg_stream_packetin(&os_en,&op);
01482 }
01483
01484 _ogg_free(data);
01485
01486
01487 for(i=0;i<5;i++){
01488 if(ogg_stream_pageout(&os_en,&og[i])==0){
01489 fprintf(stderr,"Too few pages output building sync tests!\n");
01490 exit(1);
01491 }
01492 copy_page(&og[i]);
01493 }
01494
01495
01496 {
01497 ogg_page temp;
01498 ogg_packet test;
01499
01500 fprintf(stderr,"Testing loss of pages... ");
01501
01502 ogg_sync_reset(&oy);
01503 ogg_stream_reset(&os_de);
01504 for(i=0;i<5;i++){
01505 memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
01506 og[i].header_len);
01507 ogg_sync_wrote(&oy,og[i].header_len);
01508 memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
01509 ogg_sync_wrote(&oy,og[i].body_len);
01510 }
01511
01512 ogg_sync_pageout(&oy,&temp);
01513 ogg_stream_pagein(&os_de,&temp);
01514 ogg_sync_pageout(&oy,&temp);
01515 ogg_stream_pagein(&os_de,&temp);
01516 ogg_sync_pageout(&oy,&temp);
01517
01518 ogg_sync_pageout(&oy,&temp);
01519 ogg_stream_pagein(&os_de,&temp);
01520
01521
01522
01523 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01524 checkpacket(&test,0,0,0);
01525 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01526 checkpacket(&test,100,1,-1);
01527 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01528 checkpacket(&test,4079,2,3000);
01529 if(ogg_stream_packetout(&os_de,&test)!=-1){
01530 fprintf(stderr,"Error: loss of page did not return error\n");
01531 exit(1);
01532 }
01533 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01534 checkpacket(&test,76,5,-1);
01535 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01536 checkpacket(&test,34,6,-1);
01537 fprintf(stderr,"ok.\n");
01538 }
01539
01540
01541 {
01542 ogg_page temp;
01543 ogg_packet test;
01544
01545 fprintf(stderr,"Testing loss of pages (rollback required)... ");
01546
01547 ogg_sync_reset(&oy);
01548 ogg_stream_reset(&os_de);
01549 for(i=0;i<5;i++){
01550 memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
01551 og[i].header_len);
01552 ogg_sync_wrote(&oy,og[i].header_len);
01553 memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
01554 ogg_sync_wrote(&oy,og[i].body_len);
01555 }
01556
01557 ogg_sync_pageout(&oy,&temp);
01558 ogg_stream_pagein(&os_de,&temp);
01559 ogg_sync_pageout(&oy,&temp);
01560 ogg_stream_pagein(&os_de,&temp);
01561 ogg_sync_pageout(&oy,&temp);
01562 ogg_stream_pagein(&os_de,&temp);
01563 ogg_sync_pageout(&oy,&temp);
01564
01565 ogg_sync_pageout(&oy,&temp);
01566 ogg_stream_pagein(&os_de,&temp);
01567
01568
01569
01570 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01571 checkpacket(&test,0,0,0);
01572 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01573 checkpacket(&test,100,1,-1);
01574 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01575 checkpacket(&test,4079,2,3000);
01576 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01577 checkpacket(&test,2956,3,4000);
01578 if(ogg_stream_packetout(&os_de,&test)!=-1){
01579 fprintf(stderr,"Error: loss of page did not return error\n");
01580 exit(1);
01581 }
01582 if(ogg_stream_packetout(&os_de,&test)!=1)error();
01583 checkpacket(&test,300,13,14000);
01584 fprintf(stderr,"ok.\n");
01585 }
01586
01587
01588 {
01589 ogg_page og_de;
01590
01591 fprintf(stderr,"Testing sync on partial inputs... ");
01592 ogg_sync_reset(&oy);
01593 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
01594 3);
01595 ogg_sync_wrote(&oy,3);
01596 if(ogg_sync_pageout(&oy,&og_de)>0)error();
01597
01598
01599 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3,
01600 20);
01601 ogg_sync_wrote(&oy,20);
01602 if(ogg_sync_pageout(&oy,&og_de)>0)error();
01603
01604
01605 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23,
01606 5);
01607 ogg_sync_wrote(&oy,5);
01608 if(ogg_sync_pageout(&oy,&og_de)>0)error();
01609
01610
01611
01612 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28,
01613 og[1].header_len-28);
01614 ogg_sync_wrote(&oy,og[1].header_len-28);
01615 if(ogg_sync_pageout(&oy,&og_de)>0)error();
01616
01617 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000);
01618 ogg_sync_wrote(&oy,1000);
01619 if(ogg_sync_pageout(&oy,&og_de)>0)error();
01620
01621 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000,
01622 og[1].body_len-1000);
01623 ogg_sync_wrote(&oy,og[1].body_len-1000);
01624 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
01625
01626 fprintf(stderr,"ok.\n");
01627 }
01628
01629
01630 {
01631 ogg_page og_de;
01632 fprintf(stderr,"Testing sync on 1+partial inputs... ");
01633 ogg_sync_reset(&oy);
01634
01635 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
01636 og[1].header_len);
01637 ogg_sync_wrote(&oy,og[1].header_len);
01638
01639 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
01640 og[1].body_len);
01641 ogg_sync_wrote(&oy,og[1].body_len);
01642
01643 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
01644 20);
01645 ogg_sync_wrote(&oy,20);
01646 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
01647 if(ogg_sync_pageout(&oy,&og_de)>0)error();
01648
01649 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20,
01650 og[1].header_len-20);
01651 ogg_sync_wrote(&oy,og[1].header_len-20);
01652 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
01653 og[1].body_len);
01654 ogg_sync_wrote(&oy,og[1].body_len);
01655 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
01656
01657 fprintf(stderr,"ok.\n");
01658 }
01659
01660
01661 {
01662 ogg_page og_de;
01663 fprintf(stderr,"Testing search for capture... ");
01664 ogg_sync_reset(&oy);
01665
01666
01667 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
01668 og[1].body_len);
01669 ogg_sync_wrote(&oy,og[1].body_len);
01670
01671 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
01672 og[1].header_len);
01673 ogg_sync_wrote(&oy,og[1].header_len);
01674
01675 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
01676 og[1].body_len);
01677 ogg_sync_wrote(&oy,og[1].body_len);
01678
01679 memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
01680 20);
01681 ogg_sync_wrote(&oy,20);
01682 if(ogg_sync_pageout(&oy,&og_de)>0)error();
01683 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
01684 if(ogg_sync_pageout(&oy,&og_de)>0)error();
01685
01686 memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20,
01687 og[2].header_len-20);
01688 ogg_sync_wrote(&oy,og[2].header_len-20);
01689 memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
01690 og[2].body_len);
01691 ogg_sync_wrote(&oy,og[2].body_len);
01692 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
01693
01694 fprintf(stderr,"ok.\n");
01695 }
01696
01697
01698 {
01699 ogg_page og_de;
01700 fprintf(stderr,"Testing recapture... ");
01701 ogg_sync_reset(&oy);
01702
01703 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
01704 og[1].header_len);
01705 ogg_sync_wrote(&oy,og[1].header_len);
01706
01707 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
01708 og[1].body_len);
01709 ogg_sync_wrote(&oy,og[1].body_len);
01710
01711 memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
01712 og[2].header_len);
01713 ogg_sync_wrote(&oy,og[2].header_len);
01714
01715 memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
01716 og[2].header_len);
01717 ogg_sync_wrote(&oy,og[2].header_len);
01718
01719 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
01720
01721 memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
01722 og[2].body_len-5);
01723 ogg_sync_wrote(&oy,og[2].body_len-5);
01724
01725 memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header,
01726 og[3].header_len);
01727 ogg_sync_wrote(&oy,og[3].header_len);
01728
01729 memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body,
01730 og[3].body_len);
01731 ogg_sync_wrote(&oy,og[3].body_len);
01732
01733 if(ogg_sync_pageout(&oy,&og_de)>0)error();
01734 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
01735
01736 fprintf(stderr,"ok.\n");
01737 }
01738 }
01739
01740 return(0);
01741 }
01742
01743 #endif
01744
01745
01746
01747