framing.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:39k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <ogg/ogg.h>
  4. int ogg_page_version(ogg_page *og){
  5.   return((int)(og->header[4]));
  6. }
  7. int ogg_page_continued(ogg_page *og){
  8.   return((int)(og->header[5]&0x01));
  9. }
  10. int ogg_page_bos(ogg_page *og){
  11.   return((int)(og->header[5]&0x02));
  12. }
  13. int ogg_page_eos(ogg_page *og){
  14.   return((int)(og->header[5]&0x04));
  15. }
  16. ogg_int64_t ogg_page_granulepos(ogg_page *og){
  17.   unsigned char *page=og->header;
  18.   ogg_int64_t granulepos=page[13]&(0xff);
  19.   granulepos= (granulepos<<8)|(page[12]&0xff);
  20.   granulepos= (granulepos<<8)|(page[11]&0xff);
  21.   granulepos= (granulepos<<8)|(page[10]&0xff);
  22.   granulepos= (granulepos<<8)|(page[9]&0xff);
  23.   granulepos= (granulepos<<8)|(page[8]&0xff);
  24.   granulepos= (granulepos<<8)|(page[7]&0xff);
  25.   granulepos= (granulepos<<8)|(page[6]&0xff);
  26.   return(granulepos);
  27. }
  28. int ogg_page_serialno(ogg_page *og){
  29.   return(og->header[14] |
  30.  (og->header[15]<<8) |
  31.  (og->header[16]<<16) |
  32.  (og->header[17]<<24));
  33. }
  34.  
  35. long ogg_page_pageno(ogg_page *og){
  36.   return(og->header[18] |
  37.  (og->header[19]<<8) |
  38.  (og->header[20]<<16) |
  39.  (og->header[21]<<24));
  40. }
  41. int ogg_page_packets(ogg_page *og){
  42.   int i,n=og->header[26],count=0;
  43.   for(i=0;i<n;i++)
  44.     if(og->header[27+i]<255)count++;
  45.   return(count);
  46. }
  47. #if 0
  48. static ogg_uint32_t _ogg_crc_entry(unsigned long index){
  49.   int           i;
  50.   unsigned long r;
  51.   r = index << 24;
  52.   for (i=0; i<8; i++)
  53.     if (r & 0x80000000UL)
  54.       r = (r << 1) ^ 0x04c11db7; 
  55.     else
  56.        r<<=1;
  57.  return (r & 0xffffffffUL);
  58. }
  59. #endif
  60. const ogg_uint32_t crc_lookup[256]={
  61.   0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
  62.   0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
  63.   0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
  64.   0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
  65.   0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
  66.   0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
  67.   0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
  68.   0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
  69.   0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
  70.   0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
  71.   0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
  72.   0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
  73.   0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
  74.   0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
  75.   0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
  76.   0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
  77.   0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
  78.   0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
  79.   0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
  80.   0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
  81.   0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
  82.   0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
  83.   0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
  84.   0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
  85.   0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
  86.   0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
  87.   0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
  88.   0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
  89.   0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
  90.   0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
  91.   0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
  92.   0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
  93.   0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
  94.   0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
  95.   0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
  96.   0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
  97.   0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
  98.   0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
  99.   0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
  100.   0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
  101.   0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
  102.   0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
  103.   0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
  104.   0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
  105.   0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
  106.   0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
  107.   0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
  108.   0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
  109.   0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
  110.   0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
  111.   0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
  112.   0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
  113.   0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
  114.   0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
  115.   0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
  116.   0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
  117.   0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
  118.   0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
  119.   0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
  120.   0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
  121.   0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
  122.   0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
  123.   0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
  124.   0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
  125. int ogg_stream_init(ogg_stream_state *os,int serialno){
  126.   if(os){
  127.     memset(os,0,sizeof(*os));
  128.     os->body_storage=16*1024;
  129.     os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data));
  130.     os->lacing_storage=1024;
  131.     os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
  132.     os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
  133.     os->serialno=serialno;
  134.     return(0);
  135.   }
  136.   return(-1);
  137. int ogg_stream_clear(ogg_stream_state *os){
  138.   if(os){
  139.     if(os->body_data)_ogg_free(os->body_data);
  140.     if(os->lacing_vals)_ogg_free(os->lacing_vals);
  141.     if(os->granule_vals)_ogg_free(os->granule_vals);
  142.     memset(os,0,sizeof(*os));    
  143.   }
  144.   return(0);
  145. int ogg_stream_destroy(ogg_stream_state *os){
  146.   if(os){
  147.     ogg_stream_clear(os);
  148.     _ogg_free(os);
  149.   }
  150.   return(0);
  151. static void _os_body_expand(ogg_stream_state *os,int needed){
  152.   if(os->body_storage<=os->body_fill+needed){
  153.     os->body_storage+=(needed+1024);
  154.     os->body_data=_ogg_realloc(os->body_data,os->body_storage*sizeof(*os->body_data));
  155.   }
  156. }
  157. static void _os_lacing_expand(ogg_stream_state *os,int needed){
  158.   if(os->lacing_storage<=os->lacing_fill+needed){
  159.     os->lacing_storage+=(needed+32);
  160.     os->lacing_vals=_ogg_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals));
  161.     os->granule_vals=_ogg_realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals));
  162.   }
  163. }
  164. void ogg_page_checksum_set(ogg_page *og){
  165.   if(og){
  166.     ogg_uint32_t crc_reg=0;
  167.     int i;
  168.     og->header[22]=0;
  169.     og->header[23]=0;
  170.     og->header[24]=0;
  171.     og->header[25]=0;
  172.     
  173.     for(i=0;i<og->header_len;i++)
  174.       crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
  175.     for(i=0;i<og->body_len;i++)
  176.       crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
  177.     
  178.     og->header[22]=crc_reg&0xff;
  179.     og->header[23]=(crc_reg>>8)&0xff;
  180.     og->header[24]=(crc_reg>>16)&0xff;
  181.     og->header[25]=(crc_reg>>24)&0xff;
  182.   }
  183. }
  184. int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
  185.   int lacing_vals=op->bytes/255+1,i;
  186.   if(os->body_returned){
  187.    
  188.     
  189.     os->body_fill-=os->body_returned;
  190.     if(os->body_fill)
  191.       memmove(os->body_data,os->body_data+os->body_returned,
  192.       os->body_fill);
  193.     os->body_returned=0;
  194.   }
  195.  
  196.   _os_body_expand(os,op->bytes);
  197.   _os_lacing_expand(os,lacing_vals);
  198.   memcpy(os->body_data+os->body_fill,op->packet,op->bytes);
  199.   os->body_fill+=op->bytes;
  200.   for(i=0;i<lacing_vals-1;i++){
  201.     os->lacing_vals[os->lacing_fill+i]=255;
  202.     os->granule_vals[os->lacing_fill+i]=os->granulepos;
  203.   }
  204.   os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255;
  205.   os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos;
  206.   os->lacing_vals[os->lacing_fill]|= 0x100;
  207.   os->lacing_fill+=lacing_vals;
  208.   os->packetno++;
  209.   if(op->e_o_s)os->e_o_s=1;
  210.   return(0);
  211. }
  212. int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
  213.   int i;
  214.   int vals=0;
  215.   int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
  216.   int bytes=0;
  217.   long acc=0;
  218.   ogg_int64_t granule_pos=os->granule_vals[0];
  219.   if(maxvals==0)return(0);
  220.   
  221.   
  222.   if(os->b_o_s==0){  
  223.     granule_pos=0;
  224.     for(vals=0;vals<maxvals;vals++){
  225.       if((os->lacing_vals[vals]&0x0ff)<255){
  226. vals++;
  227. break;
  228.       }
  229.     }
  230.   }else{
  231.     for(vals=0;vals<maxvals;vals++){
  232.       if(acc>4096)break;
  233.       acc+=os->lacing_vals[vals]&0x0ff;
  234.       granule_pos=os->granule_vals[vals];
  235.     }
  236.   }
  237.   
  238.   memcpy(os->header,"OggS",4);
  239.   
  240.   os->header[4]=0x00;
  241.   
  242.   os->header[5]=0x00;
  243.   if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
  244.   if(os->b_o_s==0)os->header[5]|=0x02;
  245.   if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
  246.   os->b_o_s=1;
  247.   for(i=6;i<14;i++){
  248.     os->header[i]=(granule_pos&0xff);
  249.     granule_pos>>=8;
  250.   }
  251.   {
  252.     long serialno=os->serialno;
  253.     for(i=14;i<18;i++){
  254.       os->header[i]=(serialno&0xff);
  255.       serialno>>=8;
  256.     }
  257.   }
  258.  
  259.   if(os->pageno==-1)os->pageno=0; 
  260.   {
  261.     long pageno=os->pageno++;
  262.     for(i=18;i<22;i++){
  263.       os->header[i]=(pageno&0xff);
  264.       pageno>>=8;
  265.     }
  266.   }
  267.   
  268.   os->header[22]=0;
  269.   os->header[23]=0;
  270.   os->header[24]=0;
  271.   os->header[25]=0;
  272.   
  273.   os->header[26]=vals&0xff;
  274.   for(i=0;i<vals;i++)
  275.     bytes+=os->header[i+27]=(os->lacing_vals[i]&0xff);
  276.   
  277.   og->header=os->header;
  278.   og->header_len=os->header_fill=vals+27;
  279.   og->body=os->body_data+os->body_returned;
  280.   og->body_len=bytes;
  281.   
  282.   
  283.   os->lacing_fill-=vals;
  284.   memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
  285.   memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
  286.   os->body_returned+=bytes;
  287.   
  288.   
  289.   ogg_page_checksum_set(og);
  290.   /* done */
  291.   return(1);
  292. }
  293. int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
  294.   if((os->e_o_s&&os->lacing_fill) ||        
  295.      os->body_fill-os->body_returned > 4096 ||
  296.      os->lacing_fill>=255 ||                  
  297.      (os->lacing_fill&&!os->b_o_s)){          
  298.         
  299.     return(ogg_stream_flush(os,og));
  300.   }
  301.   
  302.   return(0);
  303. }
  304. int ogg_stream_eos(ogg_stream_state *os){
  305.   return os->e_o_s;
  306. }
  307. int ogg_sync_init(ogg_sync_state *oy){
  308.   if(oy){
  309.     memset(oy,0,sizeof(*oy));
  310.   }
  311.   return(0);
  312. }
  313. int ogg_sync_clear(ogg_sync_state *oy){
  314.   if(oy){
  315.     if(oy->data)_ogg_free(oy->data);
  316.     ogg_sync_init(oy);
  317.   }
  318.   return(0);
  319. }
  320. int ogg_sync_destroy(ogg_sync_state *oy){
  321.   if(oy){
  322.     ogg_sync_clear(oy);
  323.     _ogg_free(oy);
  324.   }
  325.   return(0);
  326. }
  327. char *ogg_sync_buffer(ogg_sync_state *oy, long size){
  328.   if(oy->returned){
  329.     oy->fill-=oy->returned;
  330.     if(oy->fill>0)
  331.       memmove(oy->data,oy->data+oy->returned,oy->fill);
  332.     oy->returned=0;
  333.   }
  334.   if(size>oy->storage-oy->fill){
  335.     long newsize=size+oy->fill+4096; 
  336.     if(oy->data)
  337.       oy->data=_ogg_realloc(oy->data,newsize);
  338.     else
  339.       oy->data=_ogg_malloc(newsize);
  340.     oy->storage=newsize;
  341.   }
  342.   return((char *)oy->data+oy->fill);
  343. }
  344. int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
  345.   if(oy->fill+bytes>oy->storage)return(-1);
  346.   oy->fill+=bytes;
  347.   return(0);
  348. }
  349. long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
  350.   unsigned char *page=oy->data+oy->returned;
  351.   unsigned char *next;
  352.   long bytes=oy->fill-oy->returned;
  353.   
  354.   if(oy->headerbytes==0){
  355.     int headerbytes,i;
  356.     if(bytes<27)return(0); 
  357.     
  358.     if(memcmp(page,"OggS",4))goto sync_fail;
  359.     
  360.     headerbytes=page[26]+27;
  361.     if(bytes<headerbytes)return(0); 
  362.     
  363.     
  364.     for(i=0;i<page[26];i++)
  365.       oy->bodybytes+=page[27+i];
  366.     oy->headerbytes=headerbytes;
  367.   }
  368.   
  369.   if(oy->bodybytes+oy->headerbytes>bytes)return(0);
  370.   
  371.   {
  372.     char chksum[4];
  373.     ogg_page log;
  374.     
  375.     memcpy(chksum,page+22,4);
  376.     memset(page+22,0,4);
  377.     
  378.     log.header=page;
  379.     log.header_len=oy->headerbytes;
  380.     log.body=page+oy->headerbytes;
  381.     log.body_len=oy->bodybytes;
  382.     ogg_page_checksum_set(&log);
  383.     
  384.     if(memcmp(chksum,page+22,4)){
  385.   
  386.       memcpy(page+22,chksum,4);
  387.       
  388.       goto sync_fail;
  389.     }
  390.   }
  391.   
  392.   {
  393.     unsigned char *page=oy->data+oy->returned;
  394.     long bytes;
  395.     if(og){
  396.       og->header=page;
  397.       og->header_len=oy->headerbytes;
  398.       og->body=page+oy->headerbytes;
  399.       og->body_len=oy->bodybytes;
  400.     }
  401.     oy->unsynced=0;
  402.     oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
  403.     oy->headerbytes=0;
  404.     oy->bodybytes=0;
  405.     return(bytes);
  406.   }
  407.   
  408.  sync_fail:
  409.   
  410.   oy->headerbytes=0;
  411.   oy->bodybytes=0;
  412.   
  413.   next=memchr(page+1,'O',bytes-1);
  414.   if(!next)
  415.     next=oy->data+oy->fill;
  416.   oy->returned=next-oy->data;
  417.   return(-(next-page));
  418. }
  419. int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
  420.   
  421.   while(1){
  422.     long ret=ogg_sync_pageseek(oy,og);
  423.     if(ret>0){
  424.       return(1);
  425.     }
  426.     if(ret==0){
  427.       return(0);
  428.     }
  429.     
  430.     if(!oy->unsynced){
  431.       oy->unsynced=1;
  432.       return(-1);
  433.     }
  434.   }
  435. }
  436. int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
  437.   unsigned char *header=og->header;
  438.   unsigned char *body=og->body;
  439.   long           bodysize=og->body_len;
  440.   int            segptr=0;
  441.   int version=ogg_page_version(og);
  442.   int continued=ogg_page_continued(og);
  443.   int bos=ogg_page_bos(og);
  444.   int eos=ogg_page_eos(og);
  445.   ogg_int64_t granulepos=ogg_page_granulepos(og);
  446.   int serialno=ogg_page_serialno(og);
  447.   long pageno=ogg_page_pageno(og);
  448.   int segments=header[26];
  449.   
  450.   {
  451.     long lr=os->lacing_returned;
  452.     long br=os->body_returned;
  453.     if(br){
  454.       os->body_fill-=br;
  455.       if(os->body_fill)
  456. memmove(os->body_data,os->body_data+br,os->body_fill);
  457.       os->body_returned=0;
  458.     }
  459.     if(lr){
  460.       if(os->lacing_fill-lr){
  461. memmove(os->lacing_vals,os->lacing_vals+lr,
  462. (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
  463. memmove(os->granule_vals,os->granule_vals+lr,
  464. (os->lacing_fill-lr)*sizeof(*os->granule_vals));
  465.       }
  466.       os->lacing_fill-=lr;
  467.       os->lacing_packet-=lr;
  468.       os->lacing_returned=0;
  469.     }
  470.   }
  471.   if(serialno!=os->serialno)return(-1);
  472.   if(version>0)return(-1);
  473.   _os_lacing_expand(os,segments+1);
  474.   if(pageno!=os->pageno){
  475.     int i;
  476.     for(i=os->lacing_packet;i<os->lacing_fill;i++)
  477.       os->body_fill-=os->lacing_vals[i]&0xff;
  478.     os->lacing_fill=os->lacing_packet;
  479.     if(os->pageno!=-1){
  480.       os->lacing_vals[os->lacing_fill++]=0x400;
  481.       os->lacing_packet++;
  482.     }
  483.    
  484.     if(continued){
  485.       bos=0;
  486.       for(;segptr<segments;segptr++){
  487. int val=header[27+segptr];
  488. body+=val;
  489. bodysize-=val;
  490. if(val<255){
  491.   segptr++;
  492.   break;
  493. }
  494.       }
  495.     }
  496.   }
  497.   
  498.   if(bodysize){
  499.     _os_body_expand(os,bodysize);
  500.     memcpy(os->body_data+os->body_fill,body,bodysize);
  501.     os->body_fill+=bodysize;
  502.   }
  503.   {
  504.     int saved=-1;
  505.     while(segptr<segments){
  506.       int val=header[27+segptr];
  507.       os->lacing_vals[os->lacing_fill]=val;
  508.       os->granule_vals[os->lacing_fill]=-1;
  509.       
  510.       if(bos){
  511. os->lacing_vals[os->lacing_fill]|=0x100;
  512. bos=0;
  513.       }
  514.       
  515.       if(val<255)saved=os->lacing_fill;
  516.       
  517.       os->lacing_fill++;
  518.       segptr++;
  519.       
  520.       if(val<255)os->lacing_packet=os->lacing_fill;
  521.     }
  522.   
  523.     if(saved!=-1){
  524.       os->granule_vals[saved]=granulepos;
  525.     }
  526.   }
  527.   if(eos){
  528.     os->e_o_s=1;
  529.     if(os->lacing_fill>0)
  530.       os->lacing_vals[os->lacing_fill-1]|=0x200;
  531.   }
  532.   os->pageno=pageno+1;
  533.   return(0);
  534. }
  535. int ogg_sync_reset(ogg_sync_state *oy){
  536.   oy->fill=0;
  537.   oy->returned=0;
  538.   oy->unsynced=0;
  539.   oy->headerbytes=0;
  540.   oy->bodybytes=0;
  541.   return(0);
  542. }
  543. int ogg_stream_reset(ogg_stream_state *os){
  544.   os->body_fill=0;
  545.   os->body_returned=0;
  546.   os->lacing_fill=0;
  547.   os->lacing_packet=0;
  548.   os->lacing_returned=0;
  549.   os->header_fill=0;
  550.   os->e_o_s=0;
  551.   os->b_o_s=0;
  552.   os->pageno=-1;
  553.   os->packetno=0;
  554.   os->granulepos=0;
  555.   return(0);
  556. }
  557. int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){
  558.   ogg_stream_reset(os);
  559.   os->serialno=serialno;
  560.   return(0);
  561. }
  562. static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){
  563.   
  564.   int ptr=os->lacing_returned;
  565.   if(os->lacing_packet<=ptr)return(0);
  566.   if(os->lacing_vals[ptr]&0x400){
  567.     
  568.     os->lacing_returned++;
  569.     os->packetno++;
  570.     return(-1);
  571.   }
  572.   if(!op && !adv)return(1); 
  573.   {
  574.     int size=os->lacing_vals[ptr]&0xff;
  575.     int bytes=size;
  576.     int eos=os->lacing_vals[ptr]&0x200; 
  577.     int bos=os->lacing_vals[ptr]&0x100; 
  578.     while(size==255){
  579.       int val=os->lacing_vals[++ptr];
  580.       size=val&0xff;
  581.       if(val&0x200)eos=0x200;
  582.       bytes+=size;
  583.     }
  584.     if(op){
  585.       op->e_o_s=eos;
  586.       op->b_o_s=bos;
  587.       op->packet=os->body_data+os->body_returned;
  588.       op->packetno=os->packetno;
  589.       op->granulepos=os->granule_vals[ptr];
  590.       op->bytes=bytes;
  591.     }
  592.     if(adv){
  593.       os->body_returned+=bytes;
  594.       os->lacing_returned=ptr+1;
  595.       os->packetno++;
  596.     }
  597.   }
  598.   return(1);
  599. }
  600. int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
  601.   return _packetout(os,op,1);
  602. }
  603. int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){
  604.   return _packetout(os,op,0);
  605. }
  606. void ogg_packet_clear(ogg_packet *op) {
  607.   _ogg_free(op->packet);
  608.   memset(op, 0, sizeof(*op));
  609. }
  610. #ifdef _V_SELFTEST
  611. #include <stdio.h>
  612. ogg_stream_state os_en, os_de;
  613. ogg_sync_state oy;
  614. void checkpacket(ogg_packet *op,int len, int no, int pos){
  615.   long j;
  616.   static int sequence=0;
  617.   static int lastno=0;
  618.   if(op->bytes!=len){
  619.     fprintf(stderr,"incorrect packet length!n");
  620.     exit(1);
  621.   }
  622.   if(op->granulepos!=pos){
  623.     fprintf(stderr,"incorrect packet position!n");
  624.     exit(1);
  625.   }
  626.   
  627.   if(no==0){
  628.     sequence=0;
  629.   }else{
  630.     sequence++;
  631.     if(no>lastno+1)
  632.       sequence++;
  633.   }
  634.   lastno=no;
  635.   if(op->packetno!=sequence){
  636.     fprintf(stderr,"incorrect packet sequence %ld != %dn",
  637.     (long)(op->packetno),sequence);
  638.     exit(1);
  639.   }
  640.   for(j=0;j<op->bytes;j++)
  641.     if(op->packet[j]!=((j+no)&0xff)){
  642.       fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!nn",
  643.       j,op->packet[j],(j+no)&0xff);
  644.       exit(1);
  645.     }
  646. }
  647. void check_page(unsigned char *data,const int *header,ogg_page *og){
  648.   long j;
  649.   for(j=0;j<og->body_len;j++)
  650.     if(og->body[j]!=data[j]){
  651.       fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!nn",
  652.       j,data[j],og->body[j]);
  653.       exit(1);
  654.     }
  655.   for(j=0;j<og->header_len;j++){
  656.     if(og->header[j]!=header[j]){
  657.       fprintf(stderr,"header content mismatch at pos %ld:n",j);
  658.       for(j=0;j<header[26]+27;j++)
  659. fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
  660.       fprintf(stderr,"n");
  661.       exit(1);
  662.     }
  663.   }
  664.   if(og->header_len!=header[26]+27){
  665.     fprintf(stderr,"header length incorrect! (%ld!=%d)n",
  666.     og->header_len,header[26]+27);
  667.     exit(1);
  668.   }
  669. }
  670. void print_header(ogg_page *og){
  671.   int j;
  672.   fprintf(stderr,"nHEADER:n");
  673.   fprintf(stderr,"  capture: %c %c %c %c  version: %d  flags: %xn",
  674.   og->header[0],og->header[1],og->header[2],og->header[3],
  675.   (int)og->header[4],(int)og->header[5]);
  676.   fprintf(stderr,"  granulepos: %d  serialno: %d  pageno: %ldn",
  677.   (og->header[9]<<24)|(og->header[8]<<16)|
  678.   (og->header[7]<<8)|og->header[6],
  679.   (og->header[17]<<24)|(og->header[16]<<16)|
  680.   (og->header[15]<<8)|og->header[14],
  681.   ((long)(og->header[21])<<24)|(og->header[20]<<16)|
  682.   (og->header[19]<<8)|og->header[18]);
  683.   fprintf(stderr,"  checksum: %02x:%02x:%02x:%02xn  segments: %d (",
  684.   (int)og->header[22],(int)og->header[23],
  685.   (int)og->header[24],(int)og->header[25],
  686.   (int)og->header[26]);
  687.   for(j=27;j<og->header_len;j++)
  688.     fprintf(stderr,"%d ",(int)og->header[j]);
  689.   fprintf(stderr,")nn");
  690. }
  691. void copy_page(ogg_page *og){
  692.   unsigned char *temp=_ogg_malloc(og->header_len);
  693.   memcpy(temp,og->header,og->header_len);
  694.   og->header=temp;
  695.   temp=_ogg_malloc(og->body_len);
  696.   memcpy(temp,og->body,og->body_len);
  697.   og->body=temp;
  698. }
  699. void error(void){
  700.   fprintf(stderr,"error!n");
  701.   exit(1);
  702. }
  703. /* 17 only */
  704. const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06,
  705.        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  706.        0x01,0x02,0x03,0x04,0,0,0,0,
  707.        0x15,0xed,0xec,0x91,
  708.        1,
  709.        17};
  710. /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
  711. const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02,
  712.        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  713.        0x01,0x02,0x03,0x04,0,0,0,0,
  714.        0x59,0x10,0x6c,0x2c,
  715.        1,
  716.        17};
  717. const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04,
  718.        0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
  719.        0x01,0x02,0x03,0x04,1,0,0,0,
  720.        0x89,0x33,0x85,0xce,
  721.        13,
  722.        254,255,0,255,1,255,245,255,255,0,
  723.        255,255,90};
  724. const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02,
  725.        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  726.        0x01,0x02,0x03,0x04,0,0,0,0,
  727.        0xff,0x7b,0x23,0x17,
  728.        1,
  729.        0};
  730. const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04,
  731.        0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
  732.        0x01,0x02,0x03,0x04,1,0,0,0,
  733.        0x5c,0x3f,0x66,0xcb,
  734.        17,
  735.        17,254,255,0,0,255,1,0,255,245,255,255,0,
  736.        255,255,90,0};
  737. const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02,
  738.        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  739.        0x01,0x02,0x03,0x04,0,0,0,0,
  740.        0x01,0x27,0x31,0xaa,
  741.        18,
  742.        255,255,255,255,255,255,255,255,
  743.        255,255,255,255,255,255,255,255,255,10};
  744. const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04,
  745.        0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
  746.        0x01,0x02,0x03,0x04,1,0,0,0,
  747.        0x7f,0x4e,0x8a,0xd2,
  748.        4,
  749.        255,4,255,0};
  750. const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02,
  751.        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  752.        0x01,0x02,0x03,0x04,0,0,0,0,
  753.        0xff,0x7b,0x23,0x17,
  754.        1,
  755.        0};
  756. const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00,
  757.        0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  758.        0x01,0x02,0x03,0x04,1,0,0,0,
  759.        0x34,0x24,0xd5,0x29,
  760.        17,
  761.        255,255,255,255,255,255,255,255,
  762.        255,255,255,255,255,255,255,255,255};
  763. const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05,
  764.        0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
  765.        0x01,0x02,0x03,0x04,2,0,0,0,
  766.        0xc8,0xc3,0xcb,0xed,
  767.        5,
  768.        10,255,4,255,0};
  769. const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02,
  770.        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  771.        0x01,0x02,0x03,0x04,0,0,0,0,
  772.        0xff,0x7b,0x23,0x17,
  773.        1,
  774.        0};
  775. const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00,
  776.        0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
  777.        0x01,0x02,0x03,0x04,1,0,0,0,
  778.        0xed,0x2a,0x2e,0xa7,
  779.        255,
  780.        10,10,10,10,10,10,10,10,
  781.        10,10,10,10,10,10,10,10,
  782.        10,10,10,10,10,10,10,10,
  783.        10,10,10,10,10,10,10,10,
  784.        10,10,10,10,10,10,10,10,
  785.        10,10,10,10,10,10,10,10,
  786.        10,10,10,10,10,10,10,10,
  787.        10,10,10,10,10,10,10,10,
  788.        10,10,10,10,10,10,10,10,
  789.        10,10,10,10,10,10,10,10,
  790.        10,10,10,10,10,10,10,10,
  791.        10,10,10,10,10,10,10,10,
  792.        10,10,10,10,10,10,10,10,
  793.        10,10,10,10,10,10,10,10,
  794.        10,10,10,10,10,10,10,10,
  795.        10,10,10,10,10,10,10,10,
  796.        10,10,10,10,10,10,10,10,
  797.        10,10,10,10,10,10,10,10,
  798.        10,10,10,10,10,10,10,10,
  799.        10,10,10,10,10,10,10,10,
  800.        10,10,10,10,10,10,10,10,
  801.        10,10,10,10,10,10,10,10,
  802.        10,10,10,10,10,10,10,10,
  803.        10,10,10,10,10,10,10,10,
  804.        10,10,10,10,10,10,10,10,
  805.        10,10,10,10,10,10,10,10,
  806.        10,10,10,10,10,10,10,10,
  807.        10,10,10,10,10,10,10,10,
  808.        10,10,10,10,10,10,10,10,
  809.        10,10,10,10,10,10,10,10,
  810.        10,10,10,10,10,10,10,10,
  811.        10,10,10,10,10,10,10};
  812. const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04,
  813.        0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
  814.        0x01,0x02,0x03,0x04,2,0,0,0,
  815.        0x6c,0x3b,0x82,0x3d,
  816.        1,
  817.        50};
  818. const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02,
  819.        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  820.        0x01,0x02,0x03,0x04,0,0,0,0,
  821.        0xff,0x7b,0x23,0x17,
  822.        1,
  823.        0};
  824. const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00,
  825.        0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
  826.        0x01,0x02,0x03,0x04,1,0,0,0,
  827.        0x3c,0xd9,0x4d,0x3f,
  828.        17,
  829.        100,255,255,255,255,255,255,255,255,
  830.        255,255,255,255,255,255,255,255};
  831. const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01,
  832.        0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
  833.        0x01,0x02,0x03,0x04,2,0,0,0,
  834.        0xbd,0xd5,0xb5,0x8b,
  835.        17,
  836.        255,255,255,255,255,255,255,255,
  837.        255,255,255,255,255,255,255,255,255};
  838. const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05,
  839.        0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
  840.        0x01,0x02,0x03,0x04,3,0,0,0,
  841.        0xef,0xdd,0x88,0xde,
  842.        7,
  843.        255,255,75,255,4,255,0};
  844. const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02,
  845.        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  846.        0x01,0x02,0x03,0x04,0,0,0,0,
  847.        0xff,0x7b,0x23,0x17,
  848.        1,
  849.        0};
  850. const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00,
  851.        0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
  852.        0x01,0x02,0x03,0x04,1,0,0,0,
  853.        0x3c,0xd9,0x4d,0x3f,
  854.        17,
  855.        100,255,255,255,255,255,255,255,255,
  856.        255,255,255,255,255,255,255,255};
  857. const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
  858.        0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
  859.        0x01,0x02,0x03,0x04,2,0,0,0,
  860.        0xd4,0xe0,0x60,0xe5,
  861.        1,0};
  862. void test_pack(const int *pl, const int **headers){
  863.   unsigned char *data=_ogg_malloc(1024*1024); 
  864.   long inptr=0;
  865.   long outptr=0;
  866.   long deptr=0;
  867.   long depacket=0;
  868.   long granule_pos=7,pageno=0;
  869.   int i,j,packets,pageout=0;
  870.   int eosflag=0;
  871.   int bosflag=0;
  872.   ogg_stream_reset(&os_en);
  873.   ogg_stream_reset(&os_de);
  874.   ogg_sync_reset(&oy);
  875.   for(packets=0;;packets++)if(pl[packets]==-1)break;
  876.   for(i=0;i<packets;i++){
  877.     ogg_packet op;
  878.     int len=pl[i];
  879.     
  880.     op.packet=data+inptr;
  881.     op.bytes=len;
  882.     op.e_o_s=(pl[i+1]<0?1:0);
  883.     op.granulepos=granule_pos;
  884.     granule_pos+=1024;
  885.     for(j=0;j<len;j++)data[inptr++]=i+j;
  886.     ogg_stream_packetin(&os_en,&op);
  887.     {
  888.       ogg_page og;
  889.       
  890.       while(ogg_stream_pageout(&os_en,&og)){
  891. fprintf(stderr,"%ld, ",pageno);
  892. if(headers[pageno]==NULL){
  893.   fprintf(stderr,"coded too many pages!n");
  894.   exit(1);
  895. }
  896. check_page(data+outptr,headers[pageno],&og);
  897. outptr+=og.body_len;
  898. pageno++;
  899. {
  900.   ogg_page og_de;
  901.   ogg_packet op_de,op_de2;
  902.   char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
  903.   memcpy(buf,og.header,og.header_len);
  904.   memcpy(buf+og.header_len,og.body,og.body_len);
  905.   ogg_sync_wrote(&oy,og.header_len+og.body_len);
  906.   while(ogg_sync_pageout(&oy,&og_de)>0){
  907.     
  908.     check_page(data+deptr,headers[pageout],&og_de);
  909.     deptr+=og_de.body_len;
  910.     pageout++;
  911.     ogg_stream_pagein(&os_de,&og_de);
  912.     while(ogg_stream_packetpeek(&os_de,&op_de2)>0){
  913.       ogg_stream_packetpeek(&os_de,NULL);
  914.       ogg_stream_packetout(&os_de,&op_de); 
  915.       
  916.       if(memcmp(&op_de,&op_de2,sizeof(op_de))){
  917. fprintf(stderr,"packetout != packetpeek! pos=%ldn",
  918. depacket);
  919. exit(1);
  920.       }
  921.      
  922.       if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
  923. fprintf(stderr,"packet data mismatch in decode! pos=%ldn",
  924. depacket);
  925. exit(1);
  926.       }
  927.       if(bosflag==0 && op_de.b_o_s==0){
  928. fprintf(stderr,"b_o_s flag not set on packet!n");
  929. exit(1);
  930.       }
  931.       if(bosflag && op_de.b_o_s){
  932. fprintf(stderr,"b_o_s flag incorrectly set on packet!n");
  933. exit(1);
  934.       }
  935.       bosflag=1;
  936.       depacket+=op_de.bytes;
  937.       
  938.       if(eosflag){
  939. fprintf(stderr,"Multiple decoded packets with eos flag!n");
  940. exit(1);
  941.       }
  942.       if(op_de.e_o_s)eosflag=1;
  943.       if(op_de.granulepos!=-1){
  944. fprintf(stderr," granule:%ld ",(long)op_de.granulepos);
  945.       }
  946.     }
  947.   }
  948. }
  949.       }
  950.     }
  951.   }
  952.   _ogg_free(data);
  953.   if(headers[pageno]!=NULL){
  954.     fprintf(stderr,"did not write last page!n");
  955.     exit(1);
  956.   }
  957.   if(headers[pageout]!=NULL){
  958.     fprintf(stderr,"did not decode last page!n");
  959.     exit(1);
  960.   }
  961.   if(inptr!=outptr){
  962.     fprintf(stderr,"encoded page data incomplete!n");
  963.     exit(1);
  964.   }
  965.   if(inptr!=deptr){
  966.     fprintf(stderr,"decoded page data incomplete!n");
  967.     exit(1);
  968.   }
  969.   if(inptr!=depacket){
  970.     fprintf(stderr,"decoded packet data incomplete!n");
  971.     exit(1);
  972.   }
  973.   if(!eosflag){
  974.     fprintf(stderr,"Never got a packet with EOS set!n");
  975.     exit(1);
  976.   }
  977.   fprintf(stderr,"ok.n");
  978. }
  979. int main(void){
  980.   ogg_stream_init(&os_en,0x04030201);
  981.   ogg_stream_init(&os_de,0x04030201);
  982.   ogg_sync_init(&oy);
  983.   
  984.   {
  985.     /* 17 only */
  986.     const int packets[]={17, -1};
  987.     const int *headret[]={head1_0,NULL};
  988.     
  989.     fprintf(stderr,"testing single page encoding... ");
  990.     test_pack(packets,headret);
  991.   }
  992.   {
  993.     /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
  994.     const int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
  995.     const int *headret[]={head1_1,head2_1,NULL};
  996.     
  997.     fprintf(stderr,"testing basic page encoding... ");
  998.     test_pack(packets,headret);
  999.   }
  1000.   {
  1001.     const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
  1002.     const int *headret[]={head1_2,head2_2,NULL};
  1003.     
  1004.     fprintf(stderr,"testing basic nil packets... ");
  1005.     test_pack(packets,headret);
  1006.   }
  1007.   {
  1008.     const int packets[]={4345,259,255,-1};
  1009.     const int *headret[]={head1_3,head2_3,NULL};
  1010.     
  1011.     fprintf(stderr,"testing initial-packet lacing > 4k... ");
  1012.     test_pack(packets,headret);
  1013.   }
  1014.   {
  1015.     const int packets[]={0,4345,259,255,-1};
  1016.     const int *headret[]={head1_4,head2_4,head3_4,NULL};
  1017.     
  1018.     fprintf(stderr,"testing single packet page span... ");
  1019.     test_pack(packets,headret);
  1020.   }
  1021.   {
  1022.     const int packets[]={0,10,10,10,10,10,10,10,10,
  1023.    10,10,10,10,10,10,10,10,
  1024.    10,10,10,10,10,10,10,10,
  1025.    10,10,10,10,10,10,10,10,
  1026.    10,10,10,10,10,10,10,10,
  1027.    10,10,10,10,10,10,10,10,
  1028.    10,10,10,10,10,10,10,10,
  1029.    10,10,10,10,10,10,10,10,
  1030.    10,10,10,10,10,10,10,10,
  1031.    10,10,10,10,10,10,10,10,
  1032.    10,10,10,10,10,10,10,10,
  1033.    10,10,10,10,10,10,10,10,
  1034.    10,10,10,10,10,10,10,10,
  1035.    10,10,10,10,10,10,10,10,
  1036.    10,10,10,10,10,10,10,10,
  1037.    10,10,10,10,10,10,10,10,
  1038.    10,10,10,10,10,10,10,10,
  1039.    10,10,10,10,10,10,10,10,
  1040.    10,10,10,10,10,10,10,10,
  1041.    10,10,10,10,10,10,10,10,
  1042.    10,10,10,10,10,10,10,10,
  1043.    10,10,10,10,10,10,10,10,
  1044.    10,10,10,10,10,10,10,10,
  1045.    10,10,10,10,10,10,10,10,
  1046.    10,10,10,10,10,10,10,10,
  1047.    10,10,10,10,10,10,10,10,
  1048.    10,10,10,10,10,10,10,10,
  1049.    10,10,10,10,10,10,10,10,
  1050.    10,10,10,10,10,10,10,10,
  1051.    10,10,10,10,10,10,10,10,
  1052.    10,10,10,10,10,10,10,10,
  1053.    10,10,10,10,10,10,10,50,-1};
  1054.     const int *headret[]={head1_5,head2_5,head3_5,NULL};
  1055.     
  1056.     fprintf(stderr,"testing max packet segments... ");
  1057.     test_pack(packets,headret);
  1058.   }
  1059.   {
  1060.     const int packets[]={0,100,9000,259,255,-1};
  1061.     const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
  1062.     
  1063.     fprintf(stderr,"testing very large packets... ");
  1064.     test_pack(packets,headret);
  1065.   }
  1066.   {
  1067.     const int packets[]={0,100,4080,-1};
  1068.     const int *headret[]={head1_7,head2_7,head3_7,NULL};
  1069.     
  1070.     fprintf(stderr,"testing zero data page (1 nil packet)... ");
  1071.     test_pack(packets,headret);
  1072.   }
  1073.   {
  1074.     unsigned char *data=_ogg_malloc(1024*1024);
  1075.     int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1};
  1076.     int inptr=0,i,j;
  1077.     ogg_page og[5];
  1078.     
  1079.     ogg_stream_reset(&os_en);
  1080.     for(i=0;pl[i]!=-1;i++){
  1081.       ogg_packet op;
  1082.       int len=pl[i];
  1083.       
  1084.       op.packet=data+inptr;
  1085.       op.bytes=len;
  1086.       op.e_o_s=(pl[i+1]<0?1:0);
  1087.       op.granulepos=(i+1)*1000;
  1088.       for(j=0;j<len;j++)data[inptr++]=i+j;
  1089.       ogg_stream_packetin(&os_en,&op);
  1090.     }
  1091.     _ogg_free(data);
  1092.     for(i=0;i<5;i++){
  1093.       if(ogg_stream_pageout(&os_en,&og[i])==0){
  1094. fprintf(stderr,"Too few pages output building sync tests!n");
  1095. exit(1);
  1096.       }
  1097.       copy_page(&og[i]);
  1098.     }
  1099.     {
  1100.       ogg_page temp;
  1101.       ogg_packet test;
  1102.       fprintf(stderr,"Testing loss of pages... ");
  1103.       ogg_sync_reset(&oy);
  1104.       ogg_stream_reset(&os_de);
  1105.       for(i=0;i<5;i++){
  1106. memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
  1107.        og[i].header_len);
  1108. ogg_sync_wrote(&oy,og[i].header_len);
  1109. memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
  1110. ogg_sync_wrote(&oy,og[i].body_len);
  1111.       }
  1112.       ogg_sync_pageout(&oy,&temp);
  1113.       ogg_stream_pagein(&os_de,&temp);
  1114.       ogg_sync_pageout(&oy,&temp);
  1115.       ogg_stream_pagein(&os_de,&temp);
  1116.       ogg_sync_pageout(&oy,&temp);
  1117.       /* skip */
  1118.       ogg_sync_pageout(&oy,&temp);
  1119.       ogg_stream_pagein(&os_de,&temp);
  1120.       
  1121.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1122.       checkpacket(&test,0,0,0);
  1123.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1124.       checkpacket(&test,100,1,-1);
  1125.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1126.       checkpacket(&test,4079,2,3000);
  1127.       if(ogg_stream_packetout(&os_de,&test)!=-1){
  1128. fprintf(stderr,"Error: loss of page did not return errorn");
  1129. exit(1);
  1130.       }
  1131.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1132.       checkpacket(&test,76,5,-1);
  1133.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1134.       checkpacket(&test,34,6,-1);
  1135.       fprintf(stderr,"ok.n");
  1136.     }
  1137.     /* Test lost pages on pagein/packetout: rollback with continuation */
  1138.     {
  1139.       ogg_page temp;
  1140.       ogg_packet test;
  1141.       fprintf(stderr,"Testing loss of pages (rollback required)... ");
  1142.       ogg_sync_reset(&oy);
  1143.       ogg_stream_reset(&os_de);
  1144.       for(i=0;i<5;i++){
  1145. memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
  1146.        og[i].header_len);
  1147. ogg_sync_wrote(&oy,og[i].header_len);
  1148. memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
  1149. ogg_sync_wrote(&oy,og[i].body_len);
  1150.       }
  1151.       ogg_sync_pageout(&oy,&temp);
  1152.       ogg_stream_pagein(&os_de,&temp);
  1153.       ogg_sync_pageout(&oy,&temp);
  1154.       ogg_stream_pagein(&os_de,&temp);
  1155.       ogg_sync_pageout(&oy,&temp);
  1156.       ogg_stream_pagein(&os_de,&temp);
  1157.       ogg_sync_pageout(&oy,&temp);
  1158.       /* skip */
  1159.       ogg_sync_pageout(&oy,&temp);
  1160.       ogg_stream_pagein(&os_de,&temp);
  1161.       
  1162.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1163.       checkpacket(&test,0,0,0);
  1164.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1165.       checkpacket(&test,100,1,-1);
  1166.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1167.       checkpacket(&test,4079,2,3000);
  1168.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1169.       checkpacket(&test,2956,3,4000);
  1170.       if(ogg_stream_packetout(&os_de,&test)!=-1){
  1171. fprintf(stderr,"Error: loss of page did not return errorn");
  1172. exit(1);
  1173.       }
  1174.       if(ogg_stream_packetout(&os_de,&test)!=1)error();
  1175.       checkpacket(&test,300,13,14000);
  1176.       fprintf(stderr,"ok.n");
  1177.     }
  1178.     
  1179.     {
  1180.       ogg_page og_de;
  1181.       fprintf(stderr,"Testing sync on partial inputs... ");
  1182.       ogg_sync_reset(&oy);
  1183.       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
  1184.      3);
  1185.       ogg_sync_wrote(&oy,3);
  1186.       if(ogg_sync_pageout(&oy,&og_de)>0)error();
  1187.       
  1188.       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3,
  1189.      20);
  1190.       ogg_sync_wrote(&oy,20);
  1191.       if(ogg_sync_pageout(&oy,&og_de)>0)error();
  1192.       
  1193.       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23,
  1194.      5);
  1195.       ogg_sync_wrote(&oy,5);
  1196.       if(ogg_sync_pageout(&oy,&og_de)>0)error();
  1197.       
  1198.       
  1199.       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28,
  1200.      og[1].header_len-28);
  1201.       ogg_sync_wrote(&oy,og[1].header_len-28);
  1202.       if(ogg_sync_pageout(&oy,&og_de)>0)error();
  1203.       
  1204.       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000);
  1205.       ogg_sync_wrote(&oy,1000);
  1206.       if(ogg_sync_pageout(&oy,&og_de)>0)error();
  1207.       
  1208.       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000,
  1209.      og[1].body_len-1000);
  1210.       ogg_sync_wrote(&oy,og[1].body_len-1000);
  1211.       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
  1212.       
  1213.       fprintf(stderr,"ok.n");
  1214.     }
  1215.     {
  1216.       ogg_page og_de;
  1217.       fprintf(stderr,"Testing sync on 1+partial inputs... ");
  1218.       ogg_sync_reset(&oy); 
  1219.       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
  1220.      og[1].header_len);
  1221.       ogg_sync_wrote(&oy,og[1].header_len);
  1222.       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
  1223.      og[1].body_len);
  1224.       ogg_sync_wrote(&oy,og[1].body_len);
  1225.       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
  1226.      20);
  1227.       ogg_sync_wrote(&oy,20);
  1228.       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
  1229.       if(ogg_sync_pageout(&oy,&og_de)>0)error();
  1230.       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20,
  1231.      og[1].header_len-20);
  1232.       ogg_sync_wrote(&oy,og[1].header_len-20);
  1233.       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
  1234.      og[1].body_len);
  1235.       ogg_sync_wrote(&oy,og[1].body_len);
  1236.       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
  1237.       fprintf(stderr,"ok.n");
  1238.     }
  1239.     
  1240.     {
  1241.       ogg_page og_de;
  1242.       fprintf(stderr,"Testing search for capture... ");
  1243.       ogg_sync_reset(&oy); 
  1244.       
  1245.       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
  1246.      og[1].body_len);
  1247.       ogg_sync_wrote(&oy,og[1].body_len);
  1248.       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
  1249.      og[1].header_len);
  1250.       ogg_sync_wrote(&oy,og[1].header_len);
  1251.       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
  1252.      og[1].body_len);
  1253.       ogg_sync_wrote(&oy,og[1].body_len);
  1254.       memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
  1255.      20);
  1256.       ogg_sync_wrote(&oy,20);
  1257.       if(ogg_sync_pageout(&oy,&og_de)>0)error();
  1258.       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
  1259.       if(ogg_sync_pageout(&oy,&og_de)>0)error();
  1260.       memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20,
  1261.      og[2].header_len-20);
  1262.       ogg_sync_wrote(&oy,og[2].header_len-20);
  1263.       memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
  1264.      og[2].body_len);
  1265.       ogg_sync_wrote(&oy,og[2].body_len);
  1266.       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
  1267.       fprintf(stderr,"ok.n");
  1268.     }
  1269.     {
  1270.       ogg_page og_de;
  1271.       fprintf(stderr,"Testing recapture... ");
  1272.       ogg_sync_reset(&oy); 
  1273.       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
  1274.      og[1].header_len);
  1275.       ogg_sync_wrote(&oy,og[1].header_len);
  1276.       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
  1277.      og[1].body_len);
  1278.       ogg_sync_wrote(&oy,og[1].body_len);
  1279.       memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
  1280.      og[2].header_len);
  1281.       ogg_sync_wrote(&oy,og[2].header_len);
  1282.       memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
  1283.      og[2].header_len);
  1284.       ogg_sync_wrote(&oy,og[2].header_len);
  1285.       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
  1286.       memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
  1287.      og[2].body_len-5);
  1288.       ogg_sync_wrote(&oy,og[2].body_len-5);
  1289.       memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header,
  1290.      og[3].header_len);
  1291.       ogg_sync_wrote(&oy,og[3].header_len);
  1292.       memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body,
  1293.      og[3].body_len);
  1294.       ogg_sync_wrote(&oy,og[3].body_len);
  1295.       if(ogg_sync_pageout(&oy,&og_de)>0)error();
  1296.       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
  1297.       fprintf(stderr,"ok.n");
  1298.     }
  1299.   }    
  1300.   return(0);
  1301. }
  1302. #endif