LCOV - code coverage report
Current view: directory - media/libogg/src - ogg_framing.c (source / functions) Found Hit Coverage
Test: app.info Lines: 451 0 0.0 %
Date: 2012-06-02 Functions: 39 0 0.0 %

       1                 : /********************************************************************
       2                 :  *                                                                  *
       3                 :  * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE.              *
       4                 :  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
       5                 :  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
       6                 :  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
       7                 :  *                                                                  *
       8                 :  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
       9                 :  * by the Xiph.Org Foundation http://www.xiph.org/                  *
      10                 :  *                                                                  *
      11                 :  ********************************************************************
      12                 : 
      13                 :  function: code raw packets into framed OggSquish stream and
      14                 :            decode Ogg streams back into raw packets
      15                 :  last mod: $Id: framing.c 18052 2011-08-04 17:57:02Z giles $
      16                 : 
      17                 :  note: The CRC code is directly derived from public domain code by
      18                 :  Ross Williams (ross@guest.adelaide.edu.au).  See docs/framing.html
      19                 :  for details.
      20                 : 
      21                 :  ********************************************************************/
      22                 : 
      23                 : #include <stdlib.h>
      24                 : #include <string.h>
      25                 : #include <ogg/ogg.h>
      26                 : 
      27                 : /* A complete description of Ogg framing exists in docs/framing.html */
      28                 : 
      29               0 : int ogg_page_version(const ogg_page *og){
      30               0 :   return((int)(og->header[4]));
      31                 : }
      32                 : 
      33               0 : int ogg_page_continued(const ogg_page *og){
      34               0 :   return((int)(og->header[5]&0x01));
      35                 : }
      36                 : 
      37               0 : int ogg_page_bos(const ogg_page *og){
      38               0 :   return((int)(og->header[5]&0x02));
      39                 : }
      40                 : 
      41               0 : int ogg_page_eos(const ogg_page *og){
      42               0 :   return((int)(og->header[5]&0x04));
      43                 : }
      44                 : 
      45               0 : ogg_int64_t ogg_page_granulepos(const ogg_page *og){
      46               0 :   unsigned char *page=og->header;
      47               0 :   ogg_int64_t granulepos=page[13]&(0xff);
      48               0 :   granulepos= (granulepos<<8)|(page[12]&0xff);
      49               0 :   granulepos= (granulepos<<8)|(page[11]&0xff);
      50               0 :   granulepos= (granulepos<<8)|(page[10]&0xff);
      51               0 :   granulepos= (granulepos<<8)|(page[9]&0xff);
      52               0 :   granulepos= (granulepos<<8)|(page[8]&0xff);
      53               0 :   granulepos= (granulepos<<8)|(page[7]&0xff);
      54               0 :   granulepos= (granulepos<<8)|(page[6]&0xff);
      55               0 :   return(granulepos);
      56                 : }
      57                 : 
      58               0 : int ogg_page_serialno(const ogg_page *og){
      59               0 :   return(og->header[14] |
      60               0 :          (og->header[15]<<8) |
      61               0 :          (og->header[16]<<16) |
      62               0 :          (og->header[17]<<24));
      63                 : }
      64                 : 
      65               0 : long ogg_page_pageno(const ogg_page *og){
      66               0 :   return(og->header[18] |
      67               0 :          (og->header[19]<<8) |
      68               0 :          (og->header[20]<<16) |
      69               0 :          (og->header[21]<<24));
      70                 : }
      71                 : 
      72                 : 
      73                 : 
      74                 : /* returns the number of packets that are completed on this page (if
      75                 :    the leading packet is begun on a previous page, but ends on this
      76                 :    page, it's counted */
      77                 : 
      78                 : /* NOTE:
      79                 :    If a page consists of a packet begun on a previous page, and a new
      80                 :    packet begun (but not completed) on this page, the return will be:
      81                 :      ogg_page_packets(page)   ==1,
      82                 :      ogg_page_continued(page) !=0
      83                 : 
      84                 :    If a page happens to be a single packet that was begun on a
      85                 :    previous page, and spans to the next page (in the case of a three or
      86                 :    more page packet), the return will be:
      87                 :      ogg_page_packets(page)   ==0,
      88                 :      ogg_page_continued(page) !=0
      89                 : */
      90                 : 
      91               0 : int ogg_page_packets(const ogg_page *og){
      92               0 :   int i,n=og->header[26],count=0;
      93               0 :   for(i=0;i<n;i++)
      94               0 :     if(og->header[27+i]<255)count++;
      95               0 :   return(count);
      96                 : }
      97                 : 
      98                 : 
      99                 : #if 0
     100                 : /* helper to initialize lookup for direct-table CRC (illustrative; we
     101                 :    use the static init below) */
     102                 : 
     103                 : static ogg_uint32_t _ogg_crc_entry(unsigned long index){
     104                 :   int           i;
     105                 :   unsigned long r;
     106                 : 
     107                 :   r = index << 24;
     108                 :   for (i=0; i<8; i++)
     109                 :     if (r & 0x80000000UL)
     110                 :       r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator
     111                 :                                     polynomial, although we use an
     112                 :                                     unreflected alg and an init/final
     113                 :                                     of 0, not 0xffffffff */
     114                 :     else
     115                 :        r<<=1;
     116                 :  return (r & 0xffffffffUL);
     117                 : }
     118                 : #endif
     119                 : 
     120                 : static const ogg_uint32_t crc_lookup[256]={
     121                 :   0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
     122                 :   0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
     123                 :   0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
     124                 :   0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
     125                 :   0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
     126                 :   0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
     127                 :   0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
     128                 :   0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
     129                 :   0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
     130                 :   0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
     131                 :   0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
     132                 :   0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
     133                 :   0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
     134                 :   0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
     135                 :   0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
     136                 :   0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
     137                 :   0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
     138                 :   0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
     139                 :   0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
     140                 :   0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
     141                 :   0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
     142                 :   0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
     143                 :   0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
     144                 :   0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
     145                 :   0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
     146                 :   0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
     147                 :   0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
     148                 :   0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
     149                 :   0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
     150                 :   0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
     151                 :   0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
     152                 :   0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
     153                 :   0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
     154                 :   0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
     155                 :   0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
     156                 :   0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
     157                 :   0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
     158                 :   0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
     159                 :   0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
     160                 :   0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
     161                 :   0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
     162                 :   0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
     163                 :   0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
     164                 :   0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
     165                 :   0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
     166                 :   0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
     167                 :   0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
     168                 :   0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
     169                 :   0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
     170                 :   0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
     171                 :   0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
     172                 :   0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
     173                 :   0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
     174                 :   0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
     175                 :   0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
     176                 :   0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
     177                 :   0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
     178                 :   0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
     179                 :   0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
     180                 :   0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
     181                 :   0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
     182                 :   0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
     183                 :   0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
     184                 :   0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
     185                 : 
     186                 : /* init the encode/decode logical stream state */
     187                 : 
     188               0 : int ogg_stream_init(ogg_stream_state *os,int serialno){
     189               0 :   if(os){
     190               0 :     memset(os,0,sizeof(*os));
     191               0 :     os->body_storage=16*1024;
     192               0 :     os->lacing_storage=1024;
     193                 : 
     194               0 :     os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data));
     195               0 :     os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
     196               0 :     os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
     197                 : 
     198               0 :     if(!os->body_data || !os->lacing_vals || !os->granule_vals){
     199               0 :       ogg_stream_clear(os);
     200               0 :       return -1;
     201                 :     }
     202                 : 
     203               0 :     os->serialno=serialno;
     204                 : 
     205               0 :     return(0);
     206                 :   }
     207               0 :   return(-1);
     208                 : }
     209                 : 
     210                 : /* async/delayed error detection for the ogg_stream_state */
     211               0 : int ogg_stream_check(ogg_stream_state *os){
     212               0 :   if(!os || !os->body_data) return -1;
     213               0 :   return 0;
     214                 : }
     215                 : 
     216                 : /* _clear does not free os, only the non-flat storage within */
     217               0 : int ogg_stream_clear(ogg_stream_state *os){
     218               0 :   if(os){
     219               0 :     if(os->body_data)_ogg_free(os->body_data);
     220               0 :     if(os->lacing_vals)_ogg_free(os->lacing_vals);
     221               0 :     if(os->granule_vals)_ogg_free(os->granule_vals);
     222                 : 
     223               0 :     memset(os,0,sizeof(*os));
     224                 :   }
     225               0 :   return(0);
     226                 : }
     227                 : 
     228               0 : int ogg_stream_destroy(ogg_stream_state *os){
     229               0 :   if(os){
     230               0 :     ogg_stream_clear(os);
     231               0 :     _ogg_free(os);
     232                 :   }
     233               0 :   return(0);
     234                 : }
     235                 : 
     236                 : /* Helpers for ogg_stream_encode; this keeps the structure and
     237                 :    what's happening fairly clear */
     238                 : 
     239               0 : static int _os_body_expand(ogg_stream_state *os,int needed){
     240               0 :   if(os->body_storage<=os->body_fill+needed){
     241                 :     void *ret;
     242               0 :     ret=_ogg_realloc(os->body_data,(os->body_storage+needed+1024)*
     243                 :                      sizeof(*os->body_data));
     244               0 :     if(!ret){
     245               0 :       ogg_stream_clear(os);
     246               0 :       return -1;
     247                 :     }
     248               0 :     os->body_storage+=(needed+1024);
     249               0 :     os->body_data=ret;
     250                 :   }
     251               0 :   return 0;
     252                 : }
     253                 : 
     254               0 : static int _os_lacing_expand(ogg_stream_state *os,int needed){
     255               0 :   if(os->lacing_storage<=os->lacing_fill+needed){
     256                 :     void *ret;
     257               0 :     ret=_ogg_realloc(os->lacing_vals,(os->lacing_storage+needed+32)*
     258                 :                      sizeof(*os->lacing_vals));
     259               0 :     if(!ret){
     260               0 :       ogg_stream_clear(os);
     261               0 :       return -1;
     262                 :     }
     263               0 :     os->lacing_vals=ret;
     264               0 :     ret=_ogg_realloc(os->granule_vals,(os->lacing_storage+needed+32)*
     265                 :                      sizeof(*os->granule_vals));
     266               0 :     if(!ret){
     267               0 :       ogg_stream_clear(os);
     268               0 :       return -1;
     269                 :     }
     270               0 :     os->granule_vals=ret;
     271               0 :     os->lacing_storage+=(needed+32);
     272                 :   }
     273               0 :   return 0;
     274                 : }
     275                 : 
     276                 : /* checksum the page */
     277                 : /* Direct table CRC; note that this will be faster in the future if we
     278                 :    perform the checksum simultaneously with other copies */
     279                 : 
     280               0 : void ogg_page_checksum_set(ogg_page *og){
     281               0 :   if(og){
     282               0 :     ogg_uint32_t crc_reg=0;
     283                 :     int i;
     284                 : 
     285                 :     /* safety; needed for API behavior, but not framing code */
     286               0 :     og->header[22]=0;
     287               0 :     og->header[23]=0;
     288               0 :     og->header[24]=0;
     289               0 :     og->header[25]=0;
     290                 : 
     291               0 :     for(i=0;i<og->header_len;i++)
     292               0 :       crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
     293               0 :     for(i=0;i<og->body_len;i++)
     294               0 :       crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
     295                 : 
     296               0 :     og->header[22]=(unsigned char)(crc_reg&0xff);
     297               0 :     og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
     298               0 :     og->header[24]=(unsigned char)((crc_reg>>16)&0xff);
     299               0 :     og->header[25]=(unsigned char)((crc_reg>>24)&0xff);
     300                 :   }
     301               0 : }
     302                 : 
     303                 : /* submit data to the internal buffer of the framing engine */
     304               0 : int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
     305                 :                        long e_o_s, ogg_int64_t granulepos){
     306                 : 
     307               0 :   int bytes = 0, lacing_vals, i;
     308                 : 
     309               0 :   if(ogg_stream_check(os)) return -1;
     310               0 :   if(!iov) return 0;
     311                 : 
     312               0 :   for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len;
     313               0 :   lacing_vals=bytes/255+1;
     314                 : 
     315               0 :   if(os->body_returned){
     316                 :     /* advance packet data according to the body_returned pointer. We
     317                 :        had to keep it around to return a pointer into the buffer last
     318                 :        call */
     319                 : 
     320               0 :     os->body_fill-=os->body_returned;
     321               0 :     if(os->body_fill)
     322               0 :       memmove(os->body_data,os->body_data+os->body_returned,
     323               0 :               os->body_fill);
     324               0 :     os->body_returned=0;
     325                 :   }
     326                 : 
     327                 :   /* make sure we have the buffer storage */
     328               0 :   if(_os_body_expand(os,bytes) || _os_lacing_expand(os,lacing_vals))
     329               0 :     return -1;
     330                 : 
     331                 :   /* Copy in the submitted packet.  Yes, the copy is a waste; this is
     332                 :      the liability of overly clean abstraction for the time being.  It
     333                 :      will actually be fairly easy to eliminate the extra copy in the
     334                 :      future */
     335                 : 
     336               0 :   for (i = 0; i < count; ++i) {
     337               0 :     memcpy(os->body_data+os->body_fill, iov[i].iov_base, iov[i].iov_len);
     338               0 :     os->body_fill += (int)iov[i].iov_len;
     339                 :   }
     340                 : 
     341                 :   /* Store lacing vals for this packet */
     342               0 :   for(i=0;i<lacing_vals-1;i++){
     343               0 :     os->lacing_vals[os->lacing_fill+i]=255;
     344               0 :     os->granule_vals[os->lacing_fill+i]=os->granulepos;
     345                 :   }
     346               0 :   os->lacing_vals[os->lacing_fill+i]=bytes%255;
     347               0 :   os->granulepos=os->granule_vals[os->lacing_fill+i]=granulepos;
     348                 : 
     349                 :   /* flag the first segment as the beginning of the packet */
     350               0 :   os->lacing_vals[os->lacing_fill]|= 0x100;
     351                 : 
     352               0 :   os->lacing_fill+=lacing_vals;
     353                 : 
     354                 :   /* for the sake of completeness */
     355               0 :   os->packetno++;
     356                 : 
     357               0 :   if(e_o_s)os->e_o_s=1;
     358                 : 
     359               0 :   return(0);
     360                 : }
     361                 : 
     362               0 : int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
     363                 :   ogg_iovec_t iov;
     364               0 :   iov.iov_base = op->packet;
     365               0 :   iov.iov_len = op->bytes;
     366               0 :   return ogg_stream_iovecin(os, &iov, 1, op->e_o_s, op->granulepos);
     367                 : }
     368                 : 
     369                 : /* Conditionally flush a page; force==0 will only flush nominal-size
     370                 :    pages, force==1 forces us to flush a page regardless of page size
     371                 :    so long as there's any data available at all. */
     372               0 : static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int nfill){
     373                 :   int i;
     374               0 :   int vals=0;
     375               0 :   int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
     376               0 :   int bytes=0;
     377               0 :   long acc=0;
     378               0 :   ogg_int64_t granule_pos=-1;
     379                 : 
     380               0 :   if(ogg_stream_check(os)) return(0);
     381               0 :   if(maxvals==0) return(0);
     382                 : 
     383                 :   /* construct a page */
     384                 :   /* decide how many segments to include */
     385                 : 
     386                 :   /* If this is the initial header case, the first page must only include
     387                 :      the initial header packet */
     388               0 :   if(os->b_o_s==0){  /* 'initial header page' case */
     389               0 :     granule_pos=0;
     390               0 :     for(vals=0;vals<maxvals;vals++){
     391               0 :       if((os->lacing_vals[vals]&0x0ff)<255){
     392               0 :         vals++;
     393               0 :         break;
     394                 :       }
     395                 :     }
     396                 :   }else{
     397                 : 
     398                 :     /* The extra packets_done, packet_just_done logic here attempts to do two things:
     399                 :        1) Don't unneccessarily span pages.
     400                 :        2) Unless necessary, don't flush pages if there are less than four packets on
     401                 :           them; this expands page size to reduce unneccessary overhead if incoming packets
     402                 :           are large.
     403                 :        These are not necessary behaviors, just 'always better than naive flushing'
     404                 :        without requiring an application to explicitly request a specific optimized
     405                 :        behavior. We'll want an explicit behavior setup pathway eventually as well. */
     406                 : 
     407               0 :     int packets_done=0;
     408               0 :     int packet_just_done=0;
     409               0 :     for(vals=0;vals<maxvals;vals++){
     410               0 :       if(acc>nfill && packet_just_done>=4){
     411               0 :         force=1;
     412               0 :         break;
     413                 :       }
     414               0 :       acc+=os->lacing_vals[vals]&0x0ff;
     415               0 :       if((os->lacing_vals[vals]&0xff)<255){
     416               0 :         granule_pos=os->granule_vals[vals];
     417               0 :         packet_just_done=++packets_done;
     418                 :       }else
     419               0 :         packet_just_done=0;
     420                 :     }
     421               0 :     if(vals==255)force=1;
     422                 :   }
     423                 : 
     424               0 :   if(!force) return(0);
     425                 : 
     426                 :   /* construct the header in temp storage */
     427               0 :   memcpy(os->header,"OggS",4);
     428                 : 
     429                 :   /* stream structure version */
     430               0 :   os->header[4]=0x00;
     431                 : 
     432                 :   /* continued packet flag? */
     433               0 :   os->header[5]=0x00;
     434               0 :   if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
     435                 :   /* first page flag? */
     436               0 :   if(os->b_o_s==0)os->header[5]|=0x02;
     437                 :   /* last page flag? */
     438               0 :   if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
     439               0 :   os->b_o_s=1;
     440                 : 
     441                 :   /* 64 bits of PCM position */
     442               0 :   for(i=6;i<14;i++){
     443               0 :     os->header[i]=(unsigned char)(granule_pos&0xff);
     444               0 :     granule_pos>>=8;
     445                 :   }
     446                 : 
     447                 :   /* 32 bits of stream serial number */
     448                 :   {
     449               0 :     long serialno=os->serialno;
     450               0 :     for(i=14;i<18;i++){
     451               0 :       os->header[i]=(unsigned char)(serialno&0xff);
     452               0 :       serialno>>=8;
     453                 :     }
     454                 :   }
     455                 : 
     456                 :   /* 32 bits of page counter (we have both counter and page header
     457                 :      because this val can roll over) */
     458               0 :   if(os->pageno==-1)os->pageno=0; /* because someone called
     459                 :                                      stream_reset; this would be a
     460                 :                                      strange thing to do in an
     461                 :                                      encode stream, but it has
     462                 :                                      plausible uses */
     463                 :   {
     464               0 :     long pageno=os->pageno++;
     465               0 :     for(i=18;i<22;i++){
     466               0 :       os->header[i]=(unsigned char)(pageno&0xff);
     467               0 :       pageno>>=8;
     468                 :     }
     469                 :   }
     470                 : 
     471                 :   /* zero for computation; filled in later */
     472               0 :   os->header[22]=0;
     473               0 :   os->header[23]=0;
     474               0 :   os->header[24]=0;
     475               0 :   os->header[25]=0;
     476                 : 
     477                 :   /* segment table */
     478               0 :   os->header[26]=(unsigned char)(vals&0xff);
     479               0 :   for(i=0;i<vals;i++)
     480               0 :     bytes+=os->header[i+27]=(unsigned char)(os->lacing_vals[i]&0xff);
     481                 : 
     482                 :   /* set pointers in the ogg_page struct */
     483               0 :   og->header=os->header;
     484               0 :   og->header_len=os->header_fill=vals+27;
     485               0 :   og->body=os->body_data+os->body_returned;
     486               0 :   og->body_len=bytes;
     487                 : 
     488                 :   /* advance the lacing data and set the body_returned pointer */
     489                 : 
     490               0 :   os->lacing_fill-=vals;
     491               0 :   memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
     492               0 :   memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
     493               0 :   os->body_returned+=bytes;
     494                 : 
     495                 :   /* calculate the checksum */
     496                 : 
     497               0 :   ogg_page_checksum_set(og);
     498                 : 
     499                 :   /* done */
     500               0 :   return(1);
     501                 : }
     502                 : 
     503                 : /* This will flush remaining packets into a page (returning nonzero),
     504                 :    even if there is not enough data to trigger a flush normally
     505                 :    (undersized page). If there are no packets or partial packets to
     506                 :    flush, ogg_stream_flush returns 0.  Note that ogg_stream_flush will
     507                 :    try to flush a normal sized page like ogg_stream_pageout; a call to
     508                 :    ogg_stream_flush does not guarantee that all packets have flushed.
     509                 :    Only a return value of 0 from ogg_stream_flush indicates all packet
     510                 :    data is flushed into pages.
     511                 : 
     512                 :    since ogg_stream_flush will flush the last page in a stream even if
     513                 :    it's undersized, you almost certainly want to use ogg_stream_pageout
     514                 :    (and *not* ogg_stream_flush) unless you specifically need to flush
     515                 :    a page regardless of size in the middle of a stream. */
     516                 : 
     517               0 : int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
     518               0 :   return ogg_stream_flush_i(os,og,1,4096);
     519                 : }
     520                 : 
     521                 : /* Like the above, but an argument is provided to adjust the nominal
     522                 :    page size for applications which are smart enough to provide their
     523                 :    own delay based flushing */
     524                 : 
     525               0 : int ogg_stream_flush_fill(ogg_stream_state *os,ogg_page *og, int nfill){
     526               0 :   return ogg_stream_flush_i(os,og,1,nfill);
     527                 : }
     528                 : 
     529                 : /* This constructs pages from buffered packet segments.  The pointers
     530                 : returned are to static buffers; do not free. The returned buffers are
     531                 : good only until the next call (using the same ogg_stream_state) */
     532                 : 
     533               0 : int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
     534               0 :   int force=0;
     535               0 :   if(ogg_stream_check(os)) return 0;
     536                 : 
     537               0 :   if((os->e_o_s&&os->lacing_fill) ||          /* 'were done, now flush' case */
     538               0 :      (os->lacing_fill&&!os->b_o_s))           /* 'initial header page' case */
     539               0 :     force=1;
     540                 : 
     541               0 :   return(ogg_stream_flush_i(os,og,force,4096));
     542                 : }
     543                 : 
     544                 : /* Like the above, but an argument is provided to adjust the nominal
     545                 : page size for applications which are smart enough to provide their
     546                 : own delay based flushing */
     547                 : 
     548               0 : int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill){
     549               0 :   int force=0;
     550               0 :   if(ogg_stream_check(os)) return 0;
     551                 : 
     552               0 :   if((os->e_o_s&&os->lacing_fill) ||          /* 'were done, now flush' case */
     553               0 :      (os->lacing_fill&&!os->b_o_s))           /* 'initial header page' case */
     554               0 :     force=1;
     555                 : 
     556               0 :   return(ogg_stream_flush_i(os,og,force,nfill));
     557                 : }
     558                 : 
     559               0 : int ogg_stream_eos(ogg_stream_state *os){
     560               0 :   if(ogg_stream_check(os)) return 1;
     561               0 :   return os->e_o_s;
     562                 : }
     563                 : 
     564                 : /* DECODING PRIMITIVES: packet streaming layer **********************/
     565                 : 
     566                 : /* This has two layers to place more of the multi-serialno and paging
     567                 :    control in the application's hands.  First, we expose a data buffer
     568                 :    using ogg_sync_buffer().  The app either copies into the
     569                 :    buffer, or passes it directly to read(), etc.  We then call
     570                 :    ogg_sync_wrote() to tell how many bytes we just added.
     571                 : 
     572                 :    Pages are returned (pointers into the buffer in ogg_sync_state)
     573                 :    by ogg_sync_pageout().  The page is then submitted to
     574                 :    ogg_stream_pagein() along with the appropriate
     575                 :    ogg_stream_state* (ie, matching serialno).  We then get raw
     576                 :    packets out calling ogg_stream_packetout() with a
     577                 :    ogg_stream_state. */
     578                 : 
     579                 : /* initialize the struct to a known state */
     580               0 : int ogg_sync_init(ogg_sync_state *oy){
     581               0 :   if(oy){
     582               0 :     oy->storage = -1; /* used as a readiness flag */
     583               0 :     memset(oy,0,sizeof(*oy));
     584                 :   }
     585               0 :   return(0);
     586                 : }
     587                 : 
     588                 : /* clear non-flat storage within */
     589               0 : int ogg_sync_clear(ogg_sync_state *oy){
     590               0 :   if(oy){
     591               0 :     if(oy->data)_ogg_free(oy->data);
     592               0 :     memset(oy,0,sizeof(*oy));
     593                 :   }
     594               0 :   return(0);
     595                 : }
     596                 : 
     597               0 : int ogg_sync_destroy(ogg_sync_state *oy){
     598               0 :   if(oy){
     599               0 :     ogg_sync_clear(oy);
     600               0 :     _ogg_free(oy);
     601                 :   }
     602               0 :   return(0);
     603                 : }
     604                 : 
     605               0 : int ogg_sync_check(ogg_sync_state *oy){
     606               0 :   if(oy->storage<0) return -1;
     607               0 :   return 0;
     608                 : }
     609                 : 
     610               0 : char *ogg_sync_buffer(ogg_sync_state *oy, long size){
     611               0 :   if(ogg_sync_check(oy)) return NULL;
     612                 : 
     613                 :   /* first, clear out any space that has been previously returned */
     614               0 :   if(oy->returned){
     615               0 :     oy->fill-=oy->returned;
     616               0 :     if(oy->fill>0)
     617               0 :       memmove(oy->data,oy->data+oy->returned,oy->fill);
     618               0 :     oy->returned=0;
     619                 :   }
     620                 : 
     621               0 :   if(size>oy->storage-oy->fill){
     622                 :     /* We need to extend the internal buffer */
     623               0 :     long newsize=size+oy->fill+4096; /* an extra page to be nice */
     624                 :     void *ret;
     625                 : 
     626               0 :     if(oy->data)
     627               0 :       ret=_ogg_realloc(oy->data,newsize);
     628                 :     else
     629               0 :       ret=_ogg_malloc(newsize);
     630               0 :     if(!ret){
     631               0 :       ogg_sync_clear(oy);
     632               0 :       return NULL;
     633                 :     }
     634               0 :     oy->data=ret;
     635               0 :     oy->storage=newsize;
     636                 :   }
     637                 : 
     638                 :   /* expose a segment at least as large as requested at the fill mark */
     639               0 :   return((char *)oy->data+oy->fill);
     640                 : }
     641                 : 
     642               0 : int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
     643               0 :   if(ogg_sync_check(oy))return -1;
     644               0 :   if(oy->fill+bytes>oy->storage)return -1;
     645               0 :   oy->fill+=bytes;
     646               0 :   return(0);
     647                 : }
     648                 : 
     649                 : /* sync the stream.  This is meant to be useful for finding page
     650                 :    boundaries.
     651                 : 
     652                 :    return values for this:
     653                 :   -n) skipped n bytes
     654                 :    0) page not ready; more data (no bytes skipped)
     655                 :    n) page synced at current location; page length n bytes
     656                 : 
     657                 : */
     658                 : 
     659               0 : long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
     660               0 :   unsigned char *page=oy->data+oy->returned;
     661                 :   unsigned char *next;
     662               0 :   long bytes=oy->fill-oy->returned;
     663                 : 
     664               0 :   if(ogg_sync_check(oy))return 0;
     665                 : 
     666               0 :   if(oy->headerbytes==0){
     667                 :     int headerbytes,i;
     668               0 :     if(bytes<27)return(0); /* not enough for a header */
     669                 : 
     670                 :     /* verify capture pattern */
     671               0 :     if(memcmp(page,"OggS",4))goto sync_fail;
     672                 : 
     673               0 :     headerbytes=page[26]+27;
     674               0 :     if(bytes<headerbytes)return(0); /* not enough for header + seg table */
     675                 : 
     676                 :     /* count up body length in the segment table */
     677                 : 
     678               0 :     for(i=0;i<page[26];i++)
     679               0 :       oy->bodybytes+=page[27+i];
     680               0 :     oy->headerbytes=headerbytes;
     681                 :   }
     682                 : 
     683               0 :   if(oy->bodybytes+oy->headerbytes>bytes)return(0);
     684                 : 
     685                 :   /* The whole test page is buffered.  Verify the checksum */
     686                 :   {
     687                 :     /* Grab the checksum bytes, set the header field to zero */
     688                 :     char chksum[4];
     689                 :     ogg_page log;
     690                 : 
     691               0 :     memcpy(chksum,page+22,4);
     692               0 :     memset(page+22,0,4);
     693                 : 
     694                 :     /* set up a temp page struct and recompute the checksum */
     695               0 :     log.header=page;
     696               0 :     log.header_len=oy->headerbytes;
     697               0 :     log.body=page+oy->headerbytes;
     698               0 :     log.body_len=oy->bodybytes;
     699               0 :     ogg_page_checksum_set(&log);
     700                 : 
     701                 :     /* Compare */
     702               0 :     if(memcmp(chksum,page+22,4)){
     703                 :       /* D'oh.  Mismatch! Corrupt page (or miscapture and not a page
     704                 :          at all) */
     705                 :       /* replace the computed checksum with the one actually read in */
     706               0 :       memcpy(page+22,chksum,4);
     707                 : 
     708                 :       /* Bad checksum. Lose sync */
     709               0 :       goto sync_fail;
     710                 :     }
     711                 :   }
     712                 : 
     713                 :   /* yes, have a whole page all ready to go */
     714                 :   {
     715               0 :     unsigned char *page=oy->data+oy->returned;
     716                 :     long bytes;
     717                 : 
     718               0 :     if(og){
     719               0 :       og->header=page;
     720               0 :       og->header_len=oy->headerbytes;
     721               0 :       og->body=page+oy->headerbytes;
     722               0 :       og->body_len=oy->bodybytes;
     723                 :     }
     724                 : 
     725               0 :     oy->unsynced=0;
     726               0 :     oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
     727               0 :     oy->headerbytes=0;
     728               0 :     oy->bodybytes=0;
     729               0 :     return(bytes);
     730                 :   }
     731                 : 
     732                 :  sync_fail:
     733                 : 
     734               0 :   oy->headerbytes=0;
     735               0 :   oy->bodybytes=0;
     736                 : 
     737                 :   /* search for possible capture */
     738               0 :   next=memchr(page+1,'O',bytes-1);
     739               0 :   if(!next)
     740               0 :     next=oy->data+oy->fill;
     741                 : 
     742               0 :   oy->returned=(int)(next-oy->data);
     743               0 :   return((long)-(next-page));
     744                 : }
     745                 : 
     746                 : /* sync the stream and get a page.  Keep trying until we find a page.
     747                 :    Suppress 'sync errors' after reporting the first.
     748                 : 
     749                 :    return values:
     750                 :    -1) recapture (hole in data)
     751                 :     0) need more data
     752                 :     1) page returned
     753                 : 
     754                 :    Returns pointers into buffered data; invalidated by next call to
     755                 :    _stream, _clear, _init, or _buffer */
     756                 : 
     757               0 : int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
     758                 : 
     759               0 :   if(ogg_sync_check(oy))return 0;
     760                 : 
     761                 :   /* all we need to do is verify a page at the head of the stream
     762                 :      buffer.  If it doesn't verify, we look for the next potential
     763                 :      frame */
     764                 : 
     765                 :   for(;;){
     766               0 :     long ret=ogg_sync_pageseek(oy,og);
     767               0 :     if(ret>0){
     768                 :       /* have a page */
     769               0 :       return(1);
     770                 :     }
     771               0 :     if(ret==0){
     772                 :       /* need more data */
     773               0 :       return(0);
     774                 :     }
     775                 : 
     776                 :     /* head did not start a synced page... skipped some bytes */
     777               0 :     if(!oy->unsynced){
     778               0 :       oy->unsynced=1;
     779               0 :       return(-1);
     780                 :     }
     781                 : 
     782                 :     /* loop. keep looking */
     783                 : 
     784               0 :   }
     785                 : }
     786                 : 
     787                 : /* add the incoming page to the stream state; we decompose the page
     788                 :    into packet segments here as well. */
     789                 : 
     790               0 : int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
     791               0 :   unsigned char *header=og->header;
     792               0 :   unsigned char *body=og->body;
     793               0 :   long           bodysize=og->body_len;
     794               0 :   int            segptr=0;
     795                 : 
     796               0 :   int version=ogg_page_version(og);
     797               0 :   int continued=ogg_page_continued(og);
     798               0 :   int bos=ogg_page_bos(og);
     799               0 :   int eos=ogg_page_eos(og);
     800               0 :   ogg_int64_t granulepos=ogg_page_granulepos(og);
     801               0 :   int serialno=ogg_page_serialno(og);
     802               0 :   long pageno=ogg_page_pageno(og);
     803               0 :   int segments=header[26];
     804                 : 
     805               0 :   if(ogg_stream_check(os)) return -1;
     806                 : 
     807                 :   /* clean up 'returned data' */
     808                 :   {
     809               0 :     long lr=os->lacing_returned;
     810               0 :     long br=os->body_returned;
     811                 : 
     812                 :     /* body data */
     813               0 :     if(br){
     814               0 :       os->body_fill-=br;
     815               0 :       if(os->body_fill)
     816               0 :         memmove(os->body_data,os->body_data+br,os->body_fill);
     817               0 :       os->body_returned=0;
     818                 :     }
     819                 : 
     820               0 :     if(lr){
     821                 :       /* segment table */
     822               0 :       if(os->lacing_fill-lr){
     823               0 :         memmove(os->lacing_vals,os->lacing_vals+lr,
     824               0 :                 (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
     825               0 :         memmove(os->granule_vals,os->granule_vals+lr,
     826               0 :                 (os->lacing_fill-lr)*sizeof(*os->granule_vals));
     827                 :       }
     828               0 :       os->lacing_fill-=lr;
     829               0 :       os->lacing_packet-=lr;
     830               0 :       os->lacing_returned=0;
     831                 :     }
     832                 :   }
     833                 : 
     834                 :   /* check the serial number */
     835               0 :   if(serialno!=os->serialno)return(-1);
     836               0 :   if(version>0)return(-1);
     837                 : 
     838               0 :   if(_os_lacing_expand(os,segments+1)) return -1;
     839                 : 
     840                 :   /* are we in sequence? */
     841               0 :   if(pageno!=os->pageno){
     842                 :     int i;
     843                 : 
     844                 :     /* unroll previous partial packet (if any) */
     845               0 :     for(i=os->lacing_packet;i<os->lacing_fill;i++)
     846               0 :       os->body_fill-=os->lacing_vals[i]&0xff;
     847               0 :     os->lacing_fill=os->lacing_packet;
     848                 : 
     849                 :     /* make a note of dropped data in segment table */
     850               0 :     if(os->pageno!=-1){
     851               0 :       os->lacing_vals[os->lacing_fill++]=0x400;
     852               0 :       os->lacing_packet++;
     853                 :     }
     854                 :   }
     855                 : 
     856                 :   /* are we a 'continued packet' page?  If so, we may need to skip
     857                 :      some segments */
     858               0 :   if(continued){
     859               0 :     if(os->lacing_fill<1 ||
     860               0 :        os->lacing_vals[os->lacing_fill-1]==0x400){
     861               0 :       bos=0;
     862               0 :       for(;segptr<segments;segptr++){
     863               0 :         int val=header[27+segptr];
     864               0 :         body+=val;
     865               0 :         bodysize-=val;
     866               0 :         if(val<255){
     867               0 :           segptr++;
     868               0 :           break;
     869                 :         }
     870                 :       }
     871                 :     }
     872                 :   }
     873                 : 
     874               0 :   if(bodysize){
     875               0 :     if(_os_body_expand(os,bodysize)) return -1;
     876               0 :     memcpy(os->body_data+os->body_fill,body,bodysize);
     877               0 :     os->body_fill+=bodysize;
     878                 :   }
     879                 : 
     880                 :   {
     881               0 :     int saved=-1;
     882               0 :     while(segptr<segments){
     883               0 :       int val=header[27+segptr];
     884               0 :       os->lacing_vals[os->lacing_fill]=val;
     885               0 :       os->granule_vals[os->lacing_fill]=-1;
     886                 : 
     887               0 :       if(bos){
     888               0 :         os->lacing_vals[os->lacing_fill]|=0x100;
     889               0 :         bos=0;
     890                 :       }
     891                 : 
     892               0 :       if(val<255)saved=os->lacing_fill;
     893                 : 
     894               0 :       os->lacing_fill++;
     895               0 :       segptr++;
     896                 : 
     897               0 :       if(val<255)os->lacing_packet=os->lacing_fill;
     898                 :     }
     899                 : 
     900                 :     /* set the granulepos on the last granuleval of the last full packet */
     901               0 :     if(saved!=-1){
     902               0 :       os->granule_vals[saved]=granulepos;
     903                 :     }
     904                 : 
     905                 :   }
     906                 : 
     907               0 :   if(eos){
     908               0 :     os->e_o_s=1;
     909               0 :     if(os->lacing_fill>0)
     910               0 :       os->lacing_vals[os->lacing_fill-1]|=0x200;
     911                 :   }
     912                 : 
     913               0 :   os->pageno=pageno+1;
     914                 : 
     915               0 :   return(0);
     916                 : }
     917                 : 
     918                 : /* clear things to an initial state.  Good to call, eg, before seeking */
     919               0 : int ogg_sync_reset(ogg_sync_state *oy){
     920               0 :   if(ogg_sync_check(oy))return -1;
     921                 : 
     922               0 :   oy->fill=0;
     923               0 :   oy->returned=0;
     924               0 :   oy->unsynced=0;
     925               0 :   oy->headerbytes=0;
     926               0 :   oy->bodybytes=0;
     927               0 :   return(0);
     928                 : }
     929                 : 
     930               0 : int ogg_stream_reset(ogg_stream_state *os){
     931               0 :   if(ogg_stream_check(os)) return -1;
     932                 : 
     933               0 :   os->body_fill=0;
     934               0 :   os->body_returned=0;
     935                 : 
     936               0 :   os->lacing_fill=0;
     937               0 :   os->lacing_packet=0;
     938               0 :   os->lacing_returned=0;
     939                 : 
     940               0 :   os->header_fill=0;
     941                 : 
     942               0 :   os->e_o_s=0;
     943               0 :   os->b_o_s=0;
     944               0 :   os->pageno=-1;
     945               0 :   os->packetno=0;
     946               0 :   os->granulepos=0;
     947                 : 
     948               0 :   return(0);
     949                 : }
     950                 : 
     951               0 : int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){
     952               0 :   if(ogg_stream_check(os)) return -1;
     953               0 :   ogg_stream_reset(os);
     954               0 :   os->serialno=serialno;
     955               0 :   return(0);
     956                 : }
     957                 : 
     958               0 : static int _packetout(ogg_stream_state *os,ogg_packet *op,int adv){
     959                 : 
     960                 :   /* The last part of decode. We have the stream broken into packet
     961                 :      segments.  Now we need to group them into packets (or return the
     962                 :      out of sync markers) */
     963                 : 
     964               0 :   int ptr=os->lacing_returned;
     965                 : 
     966               0 :   if(os->lacing_packet<=ptr)return(0);
     967                 : 
     968               0 :   if(os->lacing_vals[ptr]&0x400){
     969                 :     /* we need to tell the codec there's a gap; it might need to
     970                 :        handle previous packet dependencies. */
     971               0 :     os->lacing_returned++;
     972               0 :     os->packetno++;
     973               0 :     return(-1);
     974                 :   }
     975                 : 
     976               0 :   if(!op && !adv)return(1); /* just using peek as an inexpensive way
     977                 :                                to ask if there's a whole packet
     978                 :                                waiting */
     979                 : 
     980                 :   /* Gather the whole packet. We'll have no holes or a partial packet */
     981                 :   {
     982               0 :     int size=os->lacing_vals[ptr]&0xff;
     983               0 :     long bytes=size;
     984               0 :     int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */
     985               0 :     int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */
     986                 : 
     987               0 :     while(size==255){
     988               0 :       int val=os->lacing_vals[++ptr];
     989               0 :       size=val&0xff;
     990               0 :       if(val&0x200)eos=0x200;
     991               0 :       bytes+=size;
     992                 :     }
     993                 : 
     994               0 :     if(op){
     995               0 :       op->e_o_s=eos;
     996               0 :       op->b_o_s=bos;
     997               0 :       op->packet=os->body_data+os->body_returned;
     998               0 :       op->packetno=os->packetno;
     999               0 :       op->granulepos=os->granule_vals[ptr];
    1000               0 :       op->bytes=bytes;
    1001                 :     }
    1002                 : 
    1003               0 :     if(adv){
    1004               0 :       os->body_returned+=bytes;
    1005               0 :       os->lacing_returned=ptr+1;
    1006               0 :       os->packetno++;
    1007                 :     }
    1008                 :   }
    1009               0 :   return(1);
    1010                 : }
    1011                 : 
    1012               0 : int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
    1013               0 :   if(ogg_stream_check(os)) return 0;
    1014               0 :   return _packetout(os,op,1);
    1015                 : }
    1016                 : 
    1017               0 : int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){
    1018               0 :   if(ogg_stream_check(os)) return 0;
    1019               0 :   return _packetout(os,op,0);
    1020                 : }
    1021                 : 
    1022               0 : void ogg_packet_clear(ogg_packet *op) {
    1023               0 :   _ogg_free(op->packet);
    1024               0 :   memset(op, 0, sizeof(*op));
    1025               0 : }
    1026                 : 
    1027                 : #ifdef _V_SELFTEST
    1028                 : #include <stdio.h>
    1029                 : 
    1030                 : ogg_stream_state os_en, os_de;
    1031                 : ogg_sync_state oy;
    1032                 : 
    1033                 : void checkpacket(ogg_packet *op,long len, int no, long pos){
    1034                 :   long j;
    1035                 :   static int sequence=0;
    1036                 :   static int lastno=0;
    1037                 : 
    1038                 :   if(op->bytes!=len){
    1039                 :     fprintf(stderr,"incorrect packet length (%ld != %ld)!\n",op->bytes,len);
    1040                 :     exit(1);
    1041                 :   }
    1042                 :   if(op->granulepos!=pos){
    1043                 :     fprintf(stderr,"incorrect packet granpos (%ld != %ld)!\n",(long)op->granulepos,pos);
    1044                 :     exit(1);
    1045                 :   }
    1046                 : 
    1047                 :   /* packet number just follows sequence/gap; adjust the input number
    1048                 :      for that */
    1049                 :   if(no==0){
    1050                 :     sequence=0;
    1051                 :   }else{
    1052                 :     sequence++;
    1053                 :     if(no>lastno+1)
    1054                 :       sequence++;
    1055                 :   }
    1056                 :   lastno=no;
    1057                 :   if(op->packetno!=sequence){
    1058                 :     fprintf(stderr,"incorrect packet sequence %ld != %d\n",
    1059                 :             (long)(op->packetno),sequence);
    1060                 :     exit(1);
    1061                 :   }
    1062                 : 
    1063                 :   /* Test data */
    1064                 :   for(j=0;j<op->bytes;j++)
    1065                 :     if(op->packet[j]!=((j+no)&0xff)){
    1066                 :       fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n",
    1067                 :               j,op->packet[j],(j+no)&0xff);
    1068                 :       exit(1);
    1069                 :     }
    1070                 : }
    1071                 : 
    1072                 : void check_page(unsigned char *data,const int *header,ogg_page *og){
    1073                 :   long j;
    1074                 :   /* Test data */
    1075                 :   for(j=0;j<og->body_len;j++)
    1076                 :     if(og->body[j]!=data[j]){
    1077                 :       fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n",
    1078                 :               j,data[j],og->body[j]);
    1079                 :       exit(1);
    1080                 :     }
    1081                 : 
    1082                 :   /* Test header */
    1083                 :   for(j=0;j<og->header_len;j++){
    1084                 :     if(og->header[j]!=header[j]){
    1085                 :       fprintf(stderr,"header content mismatch at pos %ld:\n",j);
    1086                 :       for(j=0;j<header[26]+27;j++)
    1087                 :         fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
    1088                 :       fprintf(stderr,"\n");
    1089                 :       exit(1);
    1090                 :     }
    1091                 :   }
    1092                 :   if(og->header_len!=header[26]+27){
    1093                 :     fprintf(stderr,"header length incorrect! (%ld!=%d)\n",
    1094                 :             og->header_len,header[26]+27);
    1095                 :     exit(1);
    1096                 :   }
    1097                 : }
    1098                 : 
    1099                 : void print_header(ogg_page *og){
    1100                 :   int j;
    1101                 :   fprintf(stderr,"\nHEADER:\n");
    1102                 :   fprintf(stderr,"  capture: %c %c %c %c  version: %d  flags: %x\n",
    1103                 :           og->header[0],og->header[1],og->header[2],og->header[3],
    1104                 :           (int)og->header[4],(int)og->header[5]);
    1105                 : 
    1106                 :   fprintf(stderr,"  granulepos: %d  serialno: %d  pageno: %ld\n",
    1107                 :           (og->header[9]<<24)|(og->header[8]<<16)|
    1108                 :           (og->header[7]<<8)|og->header[6],
    1109                 :           (og->header[17]<<24)|(og->header[16]<<16)|
    1110                 :           (og->header[15]<<8)|og->header[14],
    1111                 :           ((long)(og->header[21])<<24)|(og->header[20]<<16)|
    1112                 :           (og->header[19]<<8)|og->header[18]);
    1113                 : 
    1114                 :   fprintf(stderr,"  checksum: %02x:%02x:%02x:%02x\n  segments: %d (",
    1115                 :           (int)og->header[22],(int)og->header[23],
    1116                 :           (int)og->header[24],(int)og->header[25],
    1117                 :           (int)og->header[26]);
    1118                 : 
    1119                 :   for(j=27;j<og->header_len;j++)
    1120                 :     fprintf(stderr,"%d ",(int)og->header[j]);
    1121                 :   fprintf(stderr,")\n\n");
    1122                 : }
    1123                 : 
    1124                 : void copy_page(ogg_page *og){
    1125                 :   unsigned char *temp=_ogg_malloc(og->header_len);
    1126                 :   memcpy(temp,og->header,og->header_len);
    1127                 :   og->header=temp;
    1128                 : 
    1129                 :   temp=_ogg_malloc(og->body_len);
    1130                 :   memcpy(temp,og->body,og->body_len);
    1131                 :   og->body=temp;
    1132                 : }
    1133                 : 
    1134                 : void free_page(ogg_page *og){
    1135                 :   _ogg_free (og->header);
    1136                 :   _ogg_free (og->body);
    1137                 : }
    1138                 : 
    1139                 : void error(void){
    1140                 :   fprintf(stderr,"error!\n");
    1141                 :   exit(1);
    1142                 : }
    1143                 : 
    1144                 : /* 17 only */
    1145                 : const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06,
    1146                 :                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    1147                 :                        0x01,0x02,0x03,0x04,0,0,0,0,
    1148                 :                        0x15,0xed,0xec,0x91,
    1149                 :                        1,
    1150                 :                        17};
    1151                 : 
    1152                 : /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
    1153                 : const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02,
    1154                 :                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    1155                 :                        0x01,0x02,0x03,0x04,0,0,0,0,
    1156                 :                        0x59,0x10,0x6c,0x2c,
    1157                 :                        1,
    1158                 :                        17};
    1159                 : const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04,
    1160                 :                        0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
    1161                 :                        0x01,0x02,0x03,0x04,1,0,0,0,
    1162                 :                        0x89,0x33,0x85,0xce,
    1163                 :                        13,
    1164                 :                        254,255,0,255,1,255,245,255,255,0,
    1165                 :                        255,255,90};
    1166                 : 
    1167                 : /* nil packets; beginning,middle,end */
    1168                 : const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02,
    1169                 :                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    1170                 :                        0x01,0x02,0x03,0x04,0,0,0,0,
    1171                 :                        0xff,0x7b,0x23,0x17,
    1172                 :                        1,
    1173                 :                        0};
    1174                 : const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04,
    1175                 :                        0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
    1176                 :                        0x01,0x02,0x03,0x04,1,0,0,0,
    1177                 :                        0x5c,0x3f,0x66,0xcb,
    1178                 :                        17,
    1179                 :                        17,254,255,0,0,255,1,0,255,245,255,255,0,
    1180                 :                        255,255,90,0};
    1181                 : 
    1182                 : /* large initial packet */
    1183                 : const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02,
    1184                 :                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    1185                 :                        0x01,0x02,0x03,0x04,0,0,0,0,
    1186                 :                        0x01,0x27,0x31,0xaa,
    1187                 :                        18,
    1188                 :                        255,255,255,255,255,255,255,255,
    1189                 :                        255,255,255,255,255,255,255,255,255,10};
    1190                 : 
    1191                 : const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04,
    1192                 :                        0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
    1193                 :                        0x01,0x02,0x03,0x04,1,0,0,0,
    1194                 :                        0x7f,0x4e,0x8a,0xd2,
    1195                 :                        4,
    1196                 :                        255,4,255,0};
    1197                 : 
    1198                 : 
    1199                 : /* continuing packet test */
    1200                 : const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02,
    1201                 :                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    1202                 :                        0x01,0x02,0x03,0x04,0,0,0,0,
    1203                 :                        0xff,0x7b,0x23,0x17,
    1204                 :                        1,
    1205                 :                        0};
    1206                 : 
    1207                 : const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00,
    1208                 :                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
    1209                 :                        0x01,0x02,0x03,0x04,1,0,0,0,
    1210                 :                        0xf8,0x3c,0x19,0x79,
    1211                 :                        255,
    1212                 :                        255,255,255,255,255,255,255,255,
    1213                 :                        255,255,255,255,255,255,255,255,
    1214                 :                        255,255,255,255,255,255,255,255,
    1215                 :                        255,255,255,255,255,255,255,255,
    1216                 :                        255,255,255,255,255,255,255,255,
    1217                 :                        255,255,255,255,255,255,255,255,
    1218                 :                        255,255,255,255,255,255,255,255,
    1219                 :                        255,255,255,255,255,255,255,255,
    1220                 :                        255,255,255,255,255,255,255,255,
    1221                 :                        255,255,255,255,255,255,255,255,
    1222                 :                        255,255,255,255,255,255,255,255,
    1223                 :                        255,255,255,255,255,255,255,255,
    1224                 :                        255,255,255,255,255,255,255,255,
    1225                 :                        255,255,255,255,255,255,255,255,
    1226                 :                        255,255,255,255,255,255,255,255,
    1227                 :                        255,255,255,255,255,255,255,255,
    1228                 :                        255,255,255,255,255,255,255,255,
    1229                 :                        255,255,255,255,255,255,255,255,
    1230                 :                        255,255,255,255,255,255,255,255,
    1231                 :                        255,255,255,255,255,255,255,255,
    1232                 :                        255,255,255,255,255,255,255,255,
    1233                 :                        255,255,255,255,255,255,255,255,
    1234                 :                        255,255,255,255,255,255,255,255,
    1235                 :                        255,255,255,255,255,255,255,255,
    1236                 :                        255,255,255,255,255,255,255,255,
    1237                 :                        255,255,255,255,255,255,255,255,
    1238                 :                        255,255,255,255,255,255,255,255,
    1239                 :                        255,255,255,255,255,255,255,255,
    1240                 :                        255,255,255,255,255,255,255,255,
    1241                 :                        255,255,255,255,255,255,255,255,
    1242                 :                        255,255,255,255,255,255,255,255,
    1243                 :                        255,255,255,255,255,255,255};
    1244                 : 
    1245                 : const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05,
    1246                 :                        0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
    1247                 :                        0x01,0x02,0x03,0x04,2,0,0,0,
    1248                 :                        0x38,0xe6,0xb6,0x28,
    1249                 :                        6,
    1250                 :                        255,220,255,4,255,0};
    1251                 : 
    1252                 : 
    1253                 : /* spill expansion test */
    1254                 : const int head1_4b[] = {0x4f,0x67,0x67,0x53,0,0x02,
    1255                 :                         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    1256                 :                         0x01,0x02,0x03,0x04,0,0,0,0,
    1257                 :                         0xff,0x7b,0x23,0x17,
    1258                 :                         1,
    1259                 :                         0};
    1260                 : 
    1261                 : const int head2_4b[] = {0x4f,0x67,0x67,0x53,0,0x00,
    1262                 :                         0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
    1263                 :                         0x01,0x02,0x03,0x04,1,0,0,0,
    1264                 :                         0xce,0x8f,0x17,0x1a,
    1265                 :                         23,
    1266                 :                         255,255,255,255,255,255,255,255,
    1267                 :                         255,255,255,255,255,255,255,255,255,10,255,4,255,0,0};
    1268                 : 
    1269                 : 
    1270                 : const int head3_4b[] = {0x4f,0x67,0x67,0x53,0,0x04,
    1271                 :                         0x07,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
    1272                 :                         0x01,0x02,0x03,0x04,2,0,0,0,
    1273                 :                         0x9b,0xb2,0x50,0xa1,
    1274                 :                         1,
    1275                 :                         0};
    1276                 : 
    1277                 : /* page with the 255 segment limit */
    1278                 : const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02,
    1279                 :                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    1280                 :                        0x01,0x02,0x03,0x04,0,0,0,0,
    1281                 :                        0xff,0x7b,0x23,0x17,
    1282                 :                        1,
    1283                 :                        0};
    1284                 : 
    1285                 : const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00,
    1286                 :                        0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
    1287                 :                        0x01,0x02,0x03,0x04,1,0,0,0,
    1288                 :                        0xed,0x2a,0x2e,0xa7,
    1289                 :                        255,
    1290                 :                        10,10,10,10,10,10,10,10,
    1291                 :                        10,10,10,10,10,10,10,10,
    1292                 :                        10,10,10,10,10,10,10,10,
    1293                 :                        10,10,10,10,10,10,10,10,
    1294                 :                        10,10,10,10,10,10,10,10,
    1295                 :                        10,10,10,10,10,10,10,10,
    1296                 :                        10,10,10,10,10,10,10,10,
    1297                 :                        10,10,10,10,10,10,10,10,
    1298                 :                        10,10,10,10,10,10,10,10,
    1299                 :                        10,10,10,10,10,10,10,10,
    1300                 :                        10,10,10,10,10,10,10,10,
    1301                 :                        10,10,10,10,10,10,10,10,
    1302                 :                        10,10,10,10,10,10,10,10,
    1303                 :                        10,10,10,10,10,10,10,10,
    1304                 :                        10,10,10,10,10,10,10,10,
    1305                 :                        10,10,10,10,10,10,10,10,
    1306                 :                        10,10,10,10,10,10,10,10,
    1307                 :                        10,10,10,10,10,10,10,10,
    1308                 :                        10,10,10,10,10,10,10,10,
    1309                 :                        10,10,10,10,10,10,10,10,
    1310                 :                        10,10,10,10,10,10,10,10,
    1311                 :                        10,10,10,10,10,10,10,10,
    1312                 :                        10,10,10,10,10,10,10,10,
    1313                 :                        10,10,10,10,10,10,10,10,
    1314                 :                        10,10,10,10,10,10,10,10,
    1315                 :                        10,10,10,10,10,10,10,10,
    1316                 :                        10,10,10,10,10,10,10,10,
    1317                 :                        10,10,10,10,10,10,10,10,
    1318                 :                        10,10,10,10,10,10,10,10,
    1319                 :                        10,10,10,10,10,10,10,10,
    1320                 :                        10,10,10,10,10,10,10,10,
    1321                 :                        10,10,10,10,10,10,10};
    1322                 : 
    1323                 : const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04,
    1324                 :                        0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
    1325                 :                        0x01,0x02,0x03,0x04,2,0,0,0,
    1326                 :                        0x6c,0x3b,0x82,0x3d,
    1327                 :                        1,
    1328                 :                        50};
    1329                 : 
    1330                 : 
    1331                 : /* packet that overspans over an entire page */
    1332                 : const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02,
    1333                 :                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    1334                 :                        0x01,0x02,0x03,0x04,0,0,0,0,
    1335                 :                        0xff,0x7b,0x23,0x17,
    1336                 :                        1,
    1337                 :                        0};
    1338                 : 
    1339                 : const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00,
    1340                 :                        0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
    1341                 :                        0x01,0x02,0x03,0x04,1,0,0,0,
    1342                 :                        0x68,0x22,0x7c,0x3d,
    1343                 :                        255,
    1344                 :                        100,
    1345                 :                        255,255,255,255,255,255,255,255,
    1346                 :                        255,255,255,255,255,255,255,255,
    1347                 :                        255,255,255,255,255,255,255,255,
    1348                 :                        255,255,255,255,255,255,255,255,
    1349                 :                        255,255,255,255,255,255,255,255,
    1350                 :                        255,255,255,255,255,255,255,255,
    1351                 :                        255,255,255,255,255,255,255,255,
    1352                 :                        255,255,255,255,255,255,255,255,
    1353                 :                        255,255,255,255,255,255,255,255,
    1354                 :                        255,255,255,255,255,255,255,255,
    1355                 :                        255,255,255,255,255,255,255,255,
    1356                 :                        255,255,255,255,255,255,255,255,
    1357                 :                        255,255,255,255,255,255,255,255,
    1358                 :                        255,255,255,255,255,255,255,255,
    1359                 :                        255,255,255,255,255,255,255,255,
    1360                 :                        255,255,255,255,255,255,255,255,
    1361                 :                        255,255,255,255,255,255,255,255,
    1362                 :                        255,255,255,255,255,255,255,255,
    1363                 :                        255,255,255,255,255,255,255,255,
    1364                 :                        255,255,255,255,255,255,255,255,
    1365                 :                        255,255,255,255,255,255,255,255,
    1366                 :                        255,255,255,255,255,255,255,255,
    1367                 :                        255,255,255,255,255,255,255,255,
    1368                 :                        255,255,255,255,255,255,255,255,
    1369                 :                        255,255,255,255,255,255,255,255,
    1370                 :                        255,255,255,255,255,255,255,255,
    1371                 :                        255,255,255,255,255,255,255,255,
    1372                 :                        255,255,255,255,255,255,255,255,
    1373                 :                        255,255,255,255,255,255,255,255,
    1374                 :                        255,255,255,255,255,255,255,255,
    1375                 :                        255,255,255,255,255,255,255,255,
    1376                 :                        255,255,255,255,255,255};
    1377                 : 
    1378                 : const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01,
    1379                 :                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
    1380                 :                        0x01,0x02,0x03,0x04,2,0,0,0,
    1381                 :                        0xf4,0x87,0xba,0xf3,
    1382                 :                        255,
    1383                 :                        255,255,255,255,255,255,255,255,
    1384                 :                        255,255,255,255,255,255,255,255,
    1385                 :                        255,255,255,255,255,255,255,255,
    1386                 :                        255,255,255,255,255,255,255,255,
    1387                 :                        255,255,255,255,255,255,255,255,
    1388                 :                        255,255,255,255,255,255,255,255,
    1389                 :                        255,255,255,255,255,255,255,255,
    1390                 :                        255,255,255,255,255,255,255,255,
    1391                 :                        255,255,255,255,255,255,255,255,
    1392                 :                        255,255,255,255,255,255,255,255,
    1393                 :                        255,255,255,255,255,255,255,255,
    1394                 :                        255,255,255,255,255,255,255,255,
    1395                 :                        255,255,255,255,255,255,255,255,
    1396                 :                        255,255,255,255,255,255,255,255,
    1397                 :                        255,255,255,255,255,255,255,255,
    1398                 :                        255,255,255,255,255,255,255,255,
    1399                 :                        255,255,255,255,255,255,255,255,
    1400                 :                        255,255,255,255,255,255,255,255,
    1401                 :                        255,255,255,255,255,255,255,255,
    1402                 :                        255,255,255,255,255,255,255,255,
    1403                 :                        255,255,255,255,255,255,255,255,
    1404                 :                        255,255,255,255,255,255,255,255,
    1405                 :                        255,255,255,255,255,255,255,255,
    1406                 :                        255,255,255,255,255,255,255,255,
    1407                 :                        255,255,255,255,255,255,255,255,
    1408                 :                        255,255,255,255,255,255,255,255,
    1409                 :                        255,255,255,255,255,255,255,255,
    1410                 :                        255,255,255,255,255,255,255,255,
    1411                 :                        255,255,255,255,255,255,255,255,
    1412                 :                        255,255,255,255,255,255,255,255,
    1413                 :                        255,255,255,255,255,255,255,255,
    1414                 :                        255,255,255,255,255,255,255};
    1415                 : 
    1416                 : const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05,
    1417                 :                        0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
    1418                 :                        0x01,0x02,0x03,0x04,3,0,0,0,
    1419                 :                        0xf7,0x2f,0x6c,0x60,
    1420                 :                        5,
    1421                 :                        254,255,4,255,0};
    1422                 : 
    1423                 : /* packet that overspans over an entire page */
    1424                 : const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02,
    1425                 :                        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    1426                 :                        0x01,0x02,0x03,0x04,0,0,0,0,
    1427                 :                        0xff,0x7b,0x23,0x17,
    1428                 :                        1,
    1429                 :                        0};
    1430                 : 
    1431                 : const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00,
    1432                 :                        0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
    1433                 :                        0x01,0x02,0x03,0x04,1,0,0,0,
    1434                 :                        0x68,0x22,0x7c,0x3d,
    1435                 :                        255,
    1436                 :                        100,
    1437                 :                        255,255,255,255,255,255,255,255,
    1438                 :                        255,255,255,255,255,255,255,255,
    1439                 :                        255,255,255,255,255,255,255,255,
    1440                 :                        255,255,255,255,255,255,255,255,
    1441                 :                        255,255,255,255,255,255,255,255,
    1442                 :                        255,255,255,255,255,255,255,255,
    1443                 :                        255,255,255,255,255,255,255,255,
    1444                 :                        255,255,255,255,255,255,255,255,
    1445                 :                        255,255,255,255,255,255,255,255,
    1446                 :                        255,255,255,255,255,255,255,255,
    1447                 :                        255,255,255,255,255,255,255,255,
    1448                 :                        255,255,255,255,255,255,255,255,
    1449                 :                        255,255,255,255,255,255,255,255,
    1450                 :                        255,255,255,255,255,255,255,255,
    1451                 :                        255,255,255,255,255,255,255,255,
    1452                 :                        255,255,255,255,255,255,255,255,
    1453                 :                        255,255,255,255,255,255,255,255,
    1454                 :                        255,255,255,255,255,255,255,255,
    1455                 :                        255,255,255,255,255,255,255,255,
    1456                 :                        255,255,255,255,255,255,255,255,
    1457                 :                        255,255,255,255,255,255,255,255,
    1458                 :                        255,255,255,255,255,255,255,255,
    1459                 :                        255,255,255,255,255,255,255,255,
    1460                 :                        255,255,255,255,255,255,255,255,
    1461                 :                        255,255,255,255,255,255,255,255,
    1462                 :                        255,255,255,255,255,255,255,255,
    1463                 :                        255,255,255,255,255,255,255,255,
    1464                 :                        255,255,255,255,255,255,255,255,
    1465                 :                        255,255,255,255,255,255,255,255,
    1466                 :                        255,255,255,255,255,255,255,255,
    1467                 :                        255,255,255,255,255,255,255,255,
    1468                 :                        255,255,255,255,255,255};
    1469                 : 
    1470                 : const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
    1471                 :                        0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
    1472                 :                        0x01,0x02,0x03,0x04,2,0,0,0,
    1473                 :                        0xd4,0xe0,0x60,0xe5,
    1474                 :                        1,
    1475                 :                        0};
    1476                 : 
    1477                 : void test_pack(const int *pl, const int **headers, int byteskip,
    1478                 :                int pageskip, int packetskip){
    1479                 :   unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */
    1480                 :   long inptr=0;
    1481                 :   long outptr=0;
    1482                 :   long deptr=0;
    1483                 :   long depacket=0;
    1484                 :   long granule_pos=7,pageno=0;
    1485                 :   int i,j,packets,pageout=pageskip;
    1486                 :   int eosflag=0;
    1487                 :   int bosflag=0;
    1488                 : 
    1489                 :   int byteskipcount=0;
    1490                 : 
    1491                 :   ogg_stream_reset(&os_en);
    1492                 :   ogg_stream_reset(&os_de);
    1493                 :   ogg_sync_reset(&oy);
    1494                 : 
    1495                 :   for(packets=0;packets<packetskip;packets++)
    1496                 :     depacket+=pl[packets];
    1497                 : 
    1498                 :   for(packets=0;;packets++)if(pl[packets]==-1)break;
    1499                 : 
    1500                 :   for(i=0;i<packets;i++){
    1501                 :     /* construct a test packet */
    1502                 :     ogg_packet op;
    1503                 :     int len=pl[i];
    1504                 : 
    1505                 :     op.packet=data+inptr;
    1506                 :     op.bytes=len;
    1507                 :     op.e_o_s=(pl[i+1]<0?1:0);
    1508                 :     op.granulepos=granule_pos;
    1509                 : 
    1510                 :     granule_pos+=1024;
    1511                 : 
    1512                 :     for(j=0;j<len;j++)data[inptr++]=i+j;
    1513                 : 
    1514                 :     /* submit the test packet */
    1515                 :     ogg_stream_packetin(&os_en,&op);
    1516                 : 
    1517                 :     /* retrieve any finished pages */
    1518                 :     {
    1519                 :       ogg_page og;
    1520                 : 
    1521                 :       while(ogg_stream_pageout(&os_en,&og)){
    1522                 :         /* We have a page.  Check it carefully */
    1523                 : 
    1524                 :         fprintf(stderr,"%ld, ",pageno);
    1525                 : 
    1526                 :         if(headers[pageno]==NULL){
    1527                 :           fprintf(stderr,"coded too many pages!\n");
    1528                 :           exit(1);
    1529                 :         }
    1530                 : 
    1531                 :         check_page(data+outptr,headers[pageno],&og);
    1532                 : 
    1533                 :         outptr+=og.body_len;
    1534                 :         pageno++;
    1535                 :         if(pageskip){
    1536                 :           bosflag=1;
    1537                 :           pageskip--;
    1538                 :           deptr+=og.body_len;
    1539                 :         }
    1540                 : 
    1541                 :         /* have a complete page; submit it to sync/decode */
    1542                 : 
    1543                 :         {
    1544                 :           ogg_page og_de;
    1545                 :           ogg_packet op_de,op_de2;
    1546                 :           char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
    1547                 :           char *next=buf;
    1548                 :           byteskipcount+=og.header_len;
    1549                 :           if(byteskipcount>byteskip){
    1550                 :             memcpy(next,og.header,byteskipcount-byteskip);
    1551                 :             next+=byteskipcount-byteskip;
    1552                 :             byteskipcount=byteskip;
    1553                 :           }
    1554                 : 
    1555                 :           byteskipcount+=og.body_len;
    1556                 :           if(byteskipcount>byteskip){
    1557                 :             memcpy(next,og.body,byteskipcount-byteskip);
    1558                 :             next+=byteskipcount-byteskip;
    1559                 :             byteskipcount=byteskip;
    1560                 :           }
    1561                 : 
    1562                 :           ogg_sync_wrote(&oy,next-buf);
    1563                 : 
    1564                 :           while(1){
    1565                 :             int ret=ogg_sync_pageout(&oy,&og_de);
    1566                 :             if(ret==0)break;
    1567                 :             if(ret<0)continue;
    1568                 :             /* got a page.  Happy happy.  Verify that it's good. */
    1569                 : 
    1570                 :             fprintf(stderr,"(%d), ",pageout);
    1571                 : 
    1572                 :             check_page(data+deptr,headers[pageout],&og_de);
    1573                 :             deptr+=og_de.body_len;
    1574                 :             pageout++;
    1575                 : 
    1576                 :             /* submit it to deconstitution */
    1577                 :             ogg_stream_pagein(&os_de,&og_de);
    1578                 : 
    1579                 :             /* packets out? */
    1580                 :             while(ogg_stream_packetpeek(&os_de,&op_de2)>0){
    1581                 :               ogg_stream_packetpeek(&os_de,NULL);
    1582                 :               ogg_stream_packetout(&os_de,&op_de); /* just catching them all */
    1583                 : 
    1584                 :               /* verify peek and out match */
    1585                 :               if(memcmp(&op_de,&op_de2,sizeof(op_de))){
    1586                 :                 fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
    1587                 :                         depacket);
    1588                 :                 exit(1);
    1589                 :               }
    1590                 : 
    1591                 :               /* verify the packet! */
    1592                 :               /* check data */
    1593                 :               if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
    1594                 :                 fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
    1595                 :                         depacket);
    1596                 :                 exit(1);
    1597                 :               }
    1598                 :               /* check bos flag */
    1599                 :               if(bosflag==0 && op_de.b_o_s==0){
    1600                 :                 fprintf(stderr,"b_o_s flag not set on packet!\n");
    1601                 :                 exit(1);
    1602                 :               }
    1603                 :               if(bosflag && op_de.b_o_s){
    1604                 :                 fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
    1605                 :                 exit(1);
    1606                 :               }
    1607                 :               bosflag=1;
    1608                 :               depacket+=op_de.bytes;
    1609                 : 
    1610                 :               /* check eos flag */
    1611                 :               if(eosflag){
    1612                 :                 fprintf(stderr,"Multiple decoded packets with eos flag!\n");
    1613                 :                 exit(1);
    1614                 :               }
    1615                 : 
    1616                 :               if(op_de.e_o_s)eosflag=1;
    1617                 : 
    1618                 :               /* check granulepos flag */
    1619                 :               if(op_de.granulepos!=-1){
    1620                 :                 fprintf(stderr," granule:%ld ",(long)op_de.granulepos);
    1621                 :               }
    1622                 :             }
    1623                 :           }
    1624                 :         }
    1625                 :       }
    1626                 :     }
    1627                 :   }
    1628                 :   _ogg_free(data);
    1629                 :   if(headers[pageno]!=NULL){
    1630                 :     fprintf(stderr,"did not write last page!\n");
    1631                 :     exit(1);
    1632                 :   }
    1633                 :   if(headers[pageout]!=NULL){
    1634                 :     fprintf(stderr,"did not decode last page!\n");
    1635                 :     exit(1);
    1636                 :   }
    1637                 :   if(inptr!=outptr){
    1638                 :     fprintf(stderr,"encoded page data incomplete!\n");
    1639                 :     exit(1);
    1640                 :   }
    1641                 :   if(inptr!=deptr){
    1642                 :     fprintf(stderr,"decoded page data incomplete!\n");
    1643                 :     exit(1);
    1644                 :   }
    1645                 :   if(inptr!=depacket){
    1646                 :     fprintf(stderr,"decoded packet data incomplete!\n");
    1647                 :     exit(1);
    1648                 :   }
    1649                 :   if(!eosflag){
    1650                 :     fprintf(stderr,"Never got a packet with EOS set!\n");
    1651                 :     exit(1);
    1652                 :   }
    1653                 :   fprintf(stderr,"ok.\n");
    1654                 : }
    1655                 : 
    1656                 : int main(void){
    1657                 : 
    1658                 :   ogg_stream_init(&os_en,0x04030201);
    1659                 :   ogg_stream_init(&os_de,0x04030201);
    1660                 :   ogg_sync_init(&oy);
    1661                 : 
    1662                 :   /* Exercise each code path in the framing code.  Also verify that
    1663                 :      the checksums are working.  */
    1664                 : 
    1665                 :   {
    1666                 :     /* 17 only */
    1667                 :     const int packets[]={17, -1};
    1668                 :     const int *headret[]={head1_0,NULL};
    1669                 : 
    1670                 :     fprintf(stderr,"testing single page encoding... ");
    1671                 :     test_pack(packets,headret,0,0,0);
    1672                 :   }
    1673                 : 
    1674                 :   {
    1675                 :     /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
    1676                 :     const int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
    1677                 :     const int *headret[]={head1_1,head2_1,NULL};
    1678                 : 
    1679                 :     fprintf(stderr,"testing basic page encoding... ");
    1680                 :     test_pack(packets,headret,0,0,0);
    1681                 :   }
    1682                 : 
    1683                 :   {
    1684                 :     /* nil packets; beginning,middle,end */
    1685                 :     const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
    1686                 :     const int *headret[]={head1_2,head2_2,NULL};
    1687                 : 
    1688                 :     fprintf(stderr,"testing basic nil packets... ");
    1689                 :     test_pack(packets,headret,0,0,0);
    1690                 :   }
    1691                 : 
    1692                 :   {
    1693                 :     /* large initial packet */
    1694                 :     const int packets[]={4345,259,255,-1};
    1695                 :     const int *headret[]={head1_3,head2_3,NULL};
    1696                 : 
    1697                 :     fprintf(stderr,"testing initial-packet lacing > 4k... ");
    1698                 :     test_pack(packets,headret,0,0,0);
    1699                 :   }
    1700                 : 
    1701                 :   {
    1702                 :     /* continuing packet test; with page spill expansion, we have to
    1703                 :        overflow the lacing table. */
    1704                 :     const int packets[]={0,65500,259,255,-1};
    1705                 :     const int *headret[]={head1_4,head2_4,head3_4,NULL};
    1706                 : 
    1707                 :     fprintf(stderr,"testing single packet page span... ");
    1708                 :     test_pack(packets,headret,0,0,0);
    1709                 :   }
    1710                 : 
    1711                 :   {
    1712                 :     /* spill expand packet test */
    1713                 :     const int packets[]={0,4345,259,255,0,0,-1};
    1714                 :     const int *headret[]={head1_4b,head2_4b,head3_4b,NULL};
    1715                 : 
    1716                 :     fprintf(stderr,"testing page spill expansion... ");
    1717                 :     test_pack(packets,headret,0,0,0);
    1718                 :   }
    1719                 : 
    1720                 :   /* page with the 255 segment limit */
    1721                 :   {
    1722                 : 
    1723                 :     const int packets[]={0,10,10,10,10,10,10,10,10,
    1724                 :                    10,10,10,10,10,10,10,10,
    1725                 :                    10,10,10,10,10,10,10,10,
    1726                 :                    10,10,10,10,10,10,10,10,
    1727                 :                    10,10,10,10,10,10,10,10,
    1728                 :                    10,10,10,10,10,10,10,10,
    1729                 :                    10,10,10,10,10,10,10,10,
    1730                 :                    10,10,10,10,10,10,10,10,
    1731                 :                    10,10,10,10,10,10,10,10,
    1732                 :                    10,10,10,10,10,10,10,10,
    1733                 :                    10,10,10,10,10,10,10,10,
    1734                 :                    10,10,10,10,10,10,10,10,
    1735                 :                    10,10,10,10,10,10,10,10,
    1736                 :                    10,10,10,10,10,10,10,10,
    1737                 :                    10,10,10,10,10,10,10,10,
    1738                 :                    10,10,10,10,10,10,10,10,
    1739                 :                    10,10,10,10,10,10,10,10,
    1740                 :                    10,10,10,10,10,10,10,10,
    1741                 :                    10,10,10,10,10,10,10,10,
    1742                 :                    10,10,10,10,10,10,10,10,
    1743                 :                    10,10,10,10,10,10,10,10,
    1744                 :                    10,10,10,10,10,10,10,10,
    1745                 :                    10,10,10,10,10,10,10,10,
    1746                 :                    10,10,10,10,10,10,10,10,
    1747                 :                    10,10,10,10,10,10,10,10,
    1748                 :                    10,10,10,10,10,10,10,10,
    1749                 :                    10,10,10,10,10,10,10,10,
    1750                 :                    10,10,10,10,10,10,10,10,
    1751                 :                    10,10,10,10,10,10,10,10,
    1752                 :                    10,10,10,10,10,10,10,10,
    1753                 :                    10,10,10,10,10,10,10,10,
    1754                 :                    10,10,10,10,10,10,10,50,-1};
    1755                 :     const int *headret[]={head1_5,head2_5,head3_5,NULL};
    1756                 : 
    1757                 :     fprintf(stderr,"testing max packet segments... ");
    1758                 :     test_pack(packets,headret,0,0,0);
    1759                 :   }
    1760                 : 
    1761                 :   {
    1762                 :     /* packet that overspans over an entire page */
    1763                 :     const int packets[]={0,100,130049,259,255,-1};
    1764                 :     const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
    1765                 : 
    1766                 :     fprintf(stderr,"testing very large packets... ");
    1767                 :     test_pack(packets,headret,0,0,0);
    1768                 :   }
    1769                 : 
    1770                 :   {
    1771                 :     /* test for the libogg 1.1.1 resync in large continuation bug
    1772                 :        found by Josh Coalson)  */
    1773                 :     const int packets[]={0,100,130049,259,255,-1};
    1774                 :     const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
    1775                 : 
    1776                 :     fprintf(stderr,"testing continuation resync in very large packets... ");
    1777                 :     test_pack(packets,headret,100,2,3);
    1778                 :   }
    1779                 : 
    1780                 :   {
    1781                 :     /* term only page.  why not? */
    1782                 :     const int packets[]={0,100,64770,-1};
    1783                 :     const int *headret[]={head1_7,head2_7,head3_7,NULL};
    1784                 : 
    1785                 :     fprintf(stderr,"testing zero data page (1 nil packet)... ");
    1786                 :     test_pack(packets,headret,0,0,0);
    1787                 :   }
    1788                 : 
    1789                 : 
    1790                 : 
    1791                 :   {
    1792                 :     /* build a bunch of pages for testing */
    1793                 :     unsigned char *data=_ogg_malloc(1024*1024);
    1794                 :     int pl[]={0, 1,1,98,4079, 1,1,2954,2057, 76,34,912,0,234,1000,1000, 1000,300,-1};
    1795                 :     int inptr=0,i,j;
    1796                 :     ogg_page og[5];
    1797                 : 
    1798                 :     ogg_stream_reset(&os_en);
    1799                 : 
    1800                 :     for(i=0;pl[i]!=-1;i++){
    1801                 :       ogg_packet op;
    1802                 :       int len=pl[i];
    1803                 : 
    1804                 :       op.packet=data+inptr;
    1805                 :       op.bytes=len;
    1806                 :       op.e_o_s=(pl[i+1]<0?1:0);
    1807                 :       op.granulepos=(i+1)*1000;
    1808                 : 
    1809                 :       for(j=0;j<len;j++)data[inptr++]=i+j;
    1810                 :       ogg_stream_packetin(&os_en,&op);
    1811                 :     }
    1812                 : 
    1813                 :     _ogg_free(data);
    1814                 : 
    1815                 :     /* retrieve finished pages */
    1816                 :     for(i=0;i<5;i++){
    1817                 :       if(ogg_stream_pageout(&os_en,&og[i])==0){
    1818                 :         fprintf(stderr,"Too few pages output building sync tests!\n");
    1819                 :         exit(1);
    1820                 :       }
    1821                 :       copy_page(&og[i]);
    1822                 :     }
    1823                 : 
    1824                 :     /* Test lost pages on pagein/packetout: no rollback */
    1825                 :     {
    1826                 :       ogg_page temp;
    1827                 :       ogg_packet test;
    1828                 : 
    1829                 :       fprintf(stderr,"Testing loss of pages... ");
    1830                 : 
    1831                 :       ogg_sync_reset(&oy);
    1832                 :       ogg_stream_reset(&os_de);
    1833                 :       for(i=0;i<5;i++){
    1834                 :         memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
    1835                 :                og[i].header_len);
    1836                 :         ogg_sync_wrote(&oy,og[i].header_len);
    1837                 :         memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
    1838                 :         ogg_sync_wrote(&oy,og[i].body_len);
    1839                 :       }
    1840                 : 
    1841                 :       ogg_sync_pageout(&oy,&temp);
    1842                 :       ogg_stream_pagein(&os_de,&temp);
    1843                 :       ogg_sync_pageout(&oy,&temp);
    1844                 :       ogg_stream_pagein(&os_de,&temp);
    1845                 :       ogg_sync_pageout(&oy,&temp);
    1846                 :       /* skip */
    1847                 :       ogg_sync_pageout(&oy,&temp);
    1848                 :       ogg_stream_pagein(&os_de,&temp);
    1849                 : 
    1850                 :       /* do we get the expected results/packets? */
    1851                 : 
    1852                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1853                 :       checkpacket(&test,0,0,0);
    1854                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1855                 :       checkpacket(&test,1,1,-1);
    1856                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1857                 :       checkpacket(&test,1,2,-1);
    1858                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1859                 :       checkpacket(&test,98,3,-1);
    1860                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1861                 :       checkpacket(&test,4079,4,5000);
    1862                 :       if(ogg_stream_packetout(&os_de,&test)!=-1){
    1863                 :         fprintf(stderr,"Error: loss of page did not return error\n");
    1864                 :         exit(1);
    1865                 :       }
    1866                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1867                 :       checkpacket(&test,76,9,-1);
    1868                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1869                 :       checkpacket(&test,34,10,-1);
    1870                 :       fprintf(stderr,"ok.\n");
    1871                 :     }
    1872                 : 
    1873                 :     /* Test lost pages on pagein/packetout: rollback with continuation */
    1874                 :     {
    1875                 :       ogg_page temp;
    1876                 :       ogg_packet test;
    1877                 : 
    1878                 :       fprintf(stderr,"Testing loss of pages (rollback required)... ");
    1879                 : 
    1880                 :       ogg_sync_reset(&oy);
    1881                 :       ogg_stream_reset(&os_de);
    1882                 :       for(i=0;i<5;i++){
    1883                 :         memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
    1884                 :                og[i].header_len);
    1885                 :         ogg_sync_wrote(&oy,og[i].header_len);
    1886                 :         memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
    1887                 :         ogg_sync_wrote(&oy,og[i].body_len);
    1888                 :       }
    1889                 : 
    1890                 :       ogg_sync_pageout(&oy,&temp);
    1891                 :       ogg_stream_pagein(&os_de,&temp);
    1892                 :       ogg_sync_pageout(&oy,&temp);
    1893                 :       ogg_stream_pagein(&os_de,&temp);
    1894                 :       ogg_sync_pageout(&oy,&temp);
    1895                 :       ogg_stream_pagein(&os_de,&temp);
    1896                 :       ogg_sync_pageout(&oy,&temp);
    1897                 :       /* skip */
    1898                 :       ogg_sync_pageout(&oy,&temp);
    1899                 :       ogg_stream_pagein(&os_de,&temp);
    1900                 : 
    1901                 :       /* do we get the expected results/packets? */
    1902                 : 
    1903                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1904                 :       checkpacket(&test,0,0,0);
    1905                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1906                 :       checkpacket(&test,1,1,-1);
    1907                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1908                 :       checkpacket(&test,1,2,-1);
    1909                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1910                 :       checkpacket(&test,98,3,-1);
    1911                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1912                 :       checkpacket(&test,4079,4,5000);
    1913                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1914                 :       checkpacket(&test,1,5,-1);
    1915                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1916                 :       checkpacket(&test,1,6,-1);
    1917                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1918                 :       checkpacket(&test,2954,7,-1);
    1919                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1920                 :       checkpacket(&test,2057,8,9000);
    1921                 :       if(ogg_stream_packetout(&os_de,&test)!=-1){
    1922                 :         fprintf(stderr,"Error: loss of page did not return error\n");
    1923                 :         exit(1);
    1924                 :       }
    1925                 :       if(ogg_stream_packetout(&os_de,&test)!=1)error();
    1926                 :       checkpacket(&test,300,17,18000);
    1927                 :       fprintf(stderr,"ok.\n");
    1928                 :     }
    1929                 : 
    1930                 :     /* the rest only test sync */
    1931                 :     {
    1932                 :       ogg_page og_de;
    1933                 :       /* Test fractional page inputs: incomplete capture */
    1934                 :       fprintf(stderr,"Testing sync on partial inputs... ");
    1935                 :       ogg_sync_reset(&oy);
    1936                 :       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
    1937                 :              3);
    1938                 :       ogg_sync_wrote(&oy,3);
    1939                 :       if(ogg_sync_pageout(&oy,&og_de)>0)error();
    1940                 : 
    1941                 :       /* Test fractional page inputs: incomplete fixed header */
    1942                 :       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3,
    1943                 :              20);
    1944                 :       ogg_sync_wrote(&oy,20);
    1945                 :       if(ogg_sync_pageout(&oy,&og_de)>0)error();
    1946                 : 
    1947                 :       /* Test fractional page inputs: incomplete header */
    1948                 :       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23,
    1949                 :              5);
    1950                 :       ogg_sync_wrote(&oy,5);
    1951                 :       if(ogg_sync_pageout(&oy,&og_de)>0)error();
    1952                 : 
    1953                 :       /* Test fractional page inputs: incomplete body */
    1954                 : 
    1955                 :       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28,
    1956                 :              og[1].header_len-28);
    1957                 :       ogg_sync_wrote(&oy,og[1].header_len-28);
    1958                 :       if(ogg_sync_pageout(&oy,&og_de)>0)error();
    1959                 : 
    1960                 :       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000);
    1961                 :       ogg_sync_wrote(&oy,1000);
    1962                 :       if(ogg_sync_pageout(&oy,&og_de)>0)error();
    1963                 : 
    1964                 :       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000,
    1965                 :              og[1].body_len-1000);
    1966                 :       ogg_sync_wrote(&oy,og[1].body_len-1000);
    1967                 :       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
    1968                 : 
    1969                 :       fprintf(stderr,"ok.\n");
    1970                 :     }
    1971                 : 
    1972                 :     /* Test fractional page inputs: page + incomplete capture */
    1973                 :     {
    1974                 :       ogg_page og_de;
    1975                 :       fprintf(stderr,"Testing sync on 1+partial inputs... ");
    1976                 :       ogg_sync_reset(&oy);
    1977                 : 
    1978                 :       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
    1979                 :              og[1].header_len);
    1980                 :       ogg_sync_wrote(&oy,og[1].header_len);
    1981                 : 
    1982                 :       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
    1983                 :              og[1].body_len);
    1984                 :       ogg_sync_wrote(&oy,og[1].body_len);
    1985                 : 
    1986                 :       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
    1987                 :              20);
    1988                 :       ogg_sync_wrote(&oy,20);
    1989                 :       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
    1990                 :       if(ogg_sync_pageout(&oy,&og_de)>0)error();
    1991                 : 
    1992                 :       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20,
    1993                 :              og[1].header_len-20);
    1994                 :       ogg_sync_wrote(&oy,og[1].header_len-20);
    1995                 :       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
    1996                 :              og[1].body_len);
    1997                 :       ogg_sync_wrote(&oy,og[1].body_len);
    1998                 :       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
    1999                 : 
    2000                 :       fprintf(stderr,"ok.\n");
    2001                 :     }
    2002                 : 
    2003                 :     /* Test recapture: garbage + page */
    2004                 :     {
    2005                 :       ogg_page og_de;
    2006                 :       fprintf(stderr,"Testing search for capture... ");
    2007                 :       ogg_sync_reset(&oy);
    2008                 : 
    2009                 :       /* 'garbage' */
    2010                 :       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
    2011                 :              og[1].body_len);
    2012                 :       ogg_sync_wrote(&oy,og[1].body_len);
    2013                 : 
    2014                 :       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
    2015                 :              og[1].header_len);
    2016                 :       ogg_sync_wrote(&oy,og[1].header_len);
    2017                 : 
    2018                 :       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
    2019                 :              og[1].body_len);
    2020                 :       ogg_sync_wrote(&oy,og[1].body_len);
    2021                 : 
    2022                 :       memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
    2023                 :              20);
    2024                 :       ogg_sync_wrote(&oy,20);
    2025                 :       if(ogg_sync_pageout(&oy,&og_de)>0)error();
    2026                 :       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
    2027                 :       if(ogg_sync_pageout(&oy,&og_de)>0)error();
    2028                 : 
    2029                 :       memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20,
    2030                 :              og[2].header_len-20);
    2031                 :       ogg_sync_wrote(&oy,og[2].header_len-20);
    2032                 :       memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
    2033                 :              og[2].body_len);
    2034                 :       ogg_sync_wrote(&oy,og[2].body_len);
    2035                 :       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
    2036                 : 
    2037                 :       fprintf(stderr,"ok.\n");
    2038                 :     }
    2039                 : 
    2040                 :     /* Test recapture: page + garbage + page */
    2041                 :     {
    2042                 :       ogg_page og_de;
    2043                 :       fprintf(stderr,"Testing recapture... ");
    2044                 :       ogg_sync_reset(&oy);
    2045                 : 
    2046                 :       memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
    2047                 :              og[1].header_len);
    2048                 :       ogg_sync_wrote(&oy,og[1].header_len);
    2049                 : 
    2050                 :       memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
    2051                 :              og[1].body_len);
    2052                 :       ogg_sync_wrote(&oy,og[1].body_len);
    2053                 : 
    2054                 :       memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
    2055                 :              og[2].header_len);
    2056                 :       ogg_sync_wrote(&oy,og[2].header_len);
    2057                 : 
    2058                 :       memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
    2059                 :              og[2].header_len);
    2060                 :       ogg_sync_wrote(&oy,og[2].header_len);
    2061                 : 
    2062                 :       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
    2063                 : 
    2064                 :       memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
    2065                 :              og[2].body_len-5);
    2066                 :       ogg_sync_wrote(&oy,og[2].body_len-5);
    2067                 : 
    2068                 :       memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header,
    2069                 :              og[3].header_len);
    2070                 :       ogg_sync_wrote(&oy,og[3].header_len);
    2071                 : 
    2072                 :       memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body,
    2073                 :              og[3].body_len);
    2074                 :       ogg_sync_wrote(&oy,og[3].body_len);
    2075                 : 
    2076                 :       if(ogg_sync_pageout(&oy,&og_de)>0)error();
    2077                 :       if(ogg_sync_pageout(&oy,&og_de)<=0)error();
    2078                 : 
    2079                 :       fprintf(stderr,"ok.\n");
    2080                 :     }
    2081                 : 
    2082                 :     /* Free page data that was previously copied */
    2083                 :     {
    2084                 :       for(i=0;i<5;i++){
    2085                 :         free_page(&og[i]);
    2086                 :       }
    2087                 :     }
    2088                 :   }
    2089                 : 
    2090                 :   return(0);
    2091                 : }
    2092                 : 
    2093                 : #endif

Generated by: LCOV version 1.7