zenilib: zenilib/jni/external/libogg/src/framing.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
framing.c
Go to the documentation of this file.
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 int ogg_page_version(const ogg_page *og){
30 return((int)(og->header[4]));
31 }
32
33 int ogg_page_continued(const ogg_page *og){
34 return((int)(og->header[5]&0x01));
35 }
36
37 int ogg_page_bos(const ogg_page *og){
38 return((int)(og->header[5]&0x02));
39 }
40
41 int ogg_page_eos(const ogg_page *og){
42 return((int)(og->header[5]&0x04));
43 }
44
45 ogg_int64_t ogg_page_granulepos(const ogg_page *og){
46 unsigned char *page=og->header;
47 ogg_int64_t granulepos=page[13]&(0xff);
48 granulepos= (granulepos<<8)|(page[12]&0xff);
49 granulepos= (granulepos<<8)|(page[11]&0xff);
50 granulepos= (granulepos<<8)|(page[10]&0xff);
51 granulepos= (granulepos<<8)|(page[9]&0xff);
52 granulepos= (granulepos<<8)|(page[8]&0xff);
53 granulepos= (granulepos<<8)|(page[7]&0xff);
54 granulepos= (granulepos<<8)|(page[6]&0xff);
55 return(granulepos);
56 }
57
58 int ogg_page_serialno(const ogg_page *og){
59 return(og->header[14] |
60 (og->header[15]<<8) |
61 (og->header[16]<<16) |
62 (og->header[17]<<24));
63 }
64
65 long ogg_page_pageno(const ogg_page *og){
66 return(og->header[18] |
67 (og->header[19]<<8) |
68 (og->header[20]<<16) |
69 (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 int ogg_page_packets(const ogg_page *og){
92 int i,n=og->header[26],count=0;
93 for(i=0;i<n;i++)
94 if(og->header[27+i]<255)count++;
95 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 int ogg_stream_init(ogg_stream_state *os,int serialno){
189 if(os){
190 memset(os,0,sizeof(*os));
191 os->body_storage=16*1024;
192 os->lacing_storage=1024;
193
194 os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data));
195 os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
196 os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
197
198 if(!os->body_data || !os->lacing_vals || !os->granule_vals){
199 ogg_stream_clear(os);
200 return -1;
201 }
202
203 os->serialno=serialno;
204
205 return(0);
206 }
207 return(-1);
208 }
209
210 /* async/delayed error detection for the ogg_stream_state */
211 int ogg_stream_check(ogg_stream_state *os){
212 if(!os || !os->body_data) return -1;
213 return 0;
214 }
215
216 /* _clear does not free os, only the non-flat storage within */
217 int ogg_stream_clear(ogg_stream_state *os){
218 if(os){
219 if(os->body_data)_ogg_free(os->body_data);
220 if(os->lacing_vals)_ogg_free(os->lacing_vals);
221 if(os->granule_vals)_ogg_free(os->granule_vals);
222
223 memset(os,0,sizeof(*os));
224 }
225 return(0);
226 }
227
228 int ogg_stream_destroy(ogg_stream_state *os){
229 if(os){
230 ogg_stream_clear(os);
231 _ogg_free(os);
232 }
233 return(0);
234 }
235
236 /* Helpers for ogg_stream_encode; this keeps the structure and
237 what's happening fairly clear */
238
239 static int _os_body_expand(ogg_stream_state *os,int needed){
240 if(os->body_storage<=os->body_fill+needed){
241 void *ret;
242 ret=_ogg_realloc(os->body_data,(os->body_storage+needed+1024)*
243 sizeof(*os->body_data));
244 if(!ret){
245 ogg_stream_clear(os);
246 return -1;
247 }
248 os->body_storage+=(needed+1024);
249 os->body_data=ret;
250 }
251 return 0;
252 }
253
254 static int _os_lacing_expand(ogg_stream_state *os,int needed){
255 if(os->lacing_storage<=os->lacing_fill+needed){
256 void *ret;
257 ret=_ogg_realloc(os->lacing_vals,(os->lacing_storage+needed+32)*
258 sizeof(*os->lacing_vals));
259 if(!ret){
260 ogg_stream_clear(os);
261 return -1;
262 }
263 os->lacing_vals=ret;
264 ret=_ogg_realloc(os->granule_vals,(os->lacing_storage+needed+32)*
265 sizeof(*os->granule_vals));
266 if(!ret){
267 ogg_stream_clear(os);
268 return -1;
269 }
270 os->granule_vals=ret;
271 os->lacing_storage+=(needed+32);
272 }
273 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 void ogg_page_checksum_set(ogg_page *og){
281 if(og){
282 ogg_uint32_t crc_reg=0;
283 int i;
284
285 /* safety; needed for API behavior, but not framing code */
286 og->header[22]=0;
287 og->header[23]=0;
288 og->header[24]=0;
289 og->header[25]=0;
290
291 for(i=0;i<og->header_len;i++)
292 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]];
293 for(i=0;i<og->body_len;i++)
294 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
295
296 og->header[22]=(unsigned char)(crc_reg&0xff);
297 og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
298 og->header[24]=(unsigned char)((crc_reg>>16)&0xff);
299 og->header[25]=(unsigned char)((crc_reg>>24)&0xff);
300 }
301 }
302
303 /* submit data to the internal buffer of the framing engine */
304 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 int bytes = 0, lacing_vals, i;
308
309 if(ogg_stream_check(os)) return -1;
310 if(!iov) return 0;
311
312 for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len;
313 lacing_vals=bytes/255+1;
314
315 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 os->body_fill-=os->body_returned;
321 if(os->body_fill)
322 memmove(os->body_data,os->body_data+os->body_returned,
323 os->body_fill);
324 os->body_returned=0;
325 }
326
327 /* make sure we have the buffer storage */
328 if(_os_body_expand(os,bytes) || _os_lacing_expand(os,lacing_vals))
329 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 for (i = 0; i < count; ++i) {
337 memcpy(os->body_data+os->body_fill, iov[i].iov_base, iov[i].iov_len);
338 os->body_fill += (int)iov[i].iov_len;
339 }
340
341 /* Store lacing vals for this packet */
342 for(i=0;i<lacing_vals-1;i++){
343 os->lacing_vals[os->lacing_fill+i]=255;
344 os->granule_vals[os->lacing_fill+i]=os->granulepos;
345 }
346 os->lacing_vals[os->lacing_fill+i]=bytes%255;
347 os->granulepos=os->granule_vals[os->lacing_fill+i]=granulepos;
348
349 /* flag the first segment as the beginning of the packet */
350 os->lacing_vals[os->lacing_fill]|= 0x100;
351
352 os->lacing_fill+=lacing_vals;
353
354 /* for the sake of completeness */
355 os->packetno++;
356
357 if(e_o_s)os->e_o_s=1;
358
359 return(0);
360 }
361
362 int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
363 ogg_iovec_t iov;
364 iov.iov_base = op->packet;
365 iov.iov_len = op->bytes;
366 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 static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int nfill){
373 int i;
374 int vals=0;
375 int maxvals=(os->lacing_fill>255?255:os->lacing_fill);
376 int bytes=0;
377 long acc=0;
378 ogg_int64_t granule_pos=-1;
379
380 if(ogg_stream_check(os)) return(0);
381 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 if(os->b_o_s==0){ /* 'initial header page' case */
389 granule_pos=0;
390 for(vals=0;vals<maxvals;vals++){
391 if((os->lacing_vals[vals]&0x0ff)<255){
392 vals++;
393 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 int packets_done=0;
408 int packet_just_done=0;
409 for(vals=0;vals<maxvals;vals++){
410 if(acc>nfill && packet_just_done>=4){
411 force=1;
412 break;
413 }
414 acc+=os->lacing_vals[vals]&0x0ff;
415 if((os->lacing_vals[vals]&0xff)<255){
416 granule_pos=os->granule_vals[vals];
417 packet_just_done=++packets_done;
418 }else
419 packet_just_done=0;
420 }
421 if(vals==255)force=1;
422 }
423
424 if(!force) return(0);
425
426 /* construct the header in temp storage */
427 memcpy(os->header,"OggS",4);
428
429 /* stream structure version */
430 os->header[4]=0x00;
431
432 /* continued packet flag? */
433 os->header[5]=0x00;
434 if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01;
435 /* first page flag? */
436 if(os->b_o_s==0)os->header[5]|=0x02;
437 /* last page flag? */
438 if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04;
439 os->b_o_s=1;
440
441 /* 64 bits of PCM position */
442 for(i=6;i<14;i++){
443 os->header[i]=(unsigned char)(granule_pos&0xff);
444 granule_pos>>=8;
445 }
446
447 /* 32 bits of stream serial number */
448 {
449 long serialno=os->serialno;
450 for(i=14;i<18;i++){
451 os->header[i]=(unsigned char)(serialno&0xff);
452 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 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 long pageno=os->pageno++;
465 for(i=18;i<22;i++){
466 os->header[i]=(unsigned char)(pageno&0xff);
467 pageno>>=8;
468 }
469 }
470
471 /* zero for computation; filled in later */
472 os->header[22]=0;
473 os->header[23]=0;
474 os->header[24]=0;
475 os->header[25]=0;
476
477 /* segment table */
478 os->header[26]=(unsigned char)(vals&0xff);
479 for(i=0;i<vals;i++)
480 bytes+=os->header[i+27]=(unsigned char)(os->lacing_vals[i]&0xff);
481
482 /* set pointers in the ogg_page struct */
483 og->header=os->header;
484 og->header_len=os->header_fill=vals+27;
485 og->body=os->body_data+os->body_returned;
486 og->body_len=bytes;
487
488 /* advance the lacing data and set the body_returned pointer */
489
490 os->lacing_fill-=vals;
491 memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
492 memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
493 os->body_returned+=bytes;
494
495 /* calculate the checksum */
496
497 ogg_page_checksum_set(og);
498
499 /* done */
500 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 int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){
518 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 int ogg_stream_flush_fill(ogg_stream_state *os,ogg_page *og, int nfill){
526 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 int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){
534 int force=0;
535 if(ogg_stream_check(os)) return 0;
536
537 if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */
538 (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */
539 force=1;
540
541 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 int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill){
549 int force=0;
550 if(ogg_stream_check(os)) return 0;
551
552 if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */
553 (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */
554 force=1;
555
556 return(ogg_stream_flush_i(os,og,force,nfill));
557 }
558
559 int ogg_stream_eos(ogg_stream_state *os){
560 if(ogg_stream_check(os)) return 1;
561 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 int ogg_sync_init(ogg_sync_state *oy){
581 if(oy){
582 oy->storage = -1; /* used as a readiness flag */
583 memset(oy,0,sizeof(*oy));
584 }
585 return(0);
586 }
587
588 /* clear non-flat storage within */
589 int ogg_sync_clear(ogg_sync_state *oy){
590 if(oy){
591 if(oy->data)_ogg_free(oy->data);
592 memset(oy,0,sizeof(*oy));
593 }
594 return(0);
595 }
596
597 int ogg_sync_destroy(ogg_sync_state *oy){
598 if(oy){
599 ogg_sync_clear(oy);
600 _ogg_free(oy);
601 }
602 return(0);
603 }
604
605 int ogg_sync_check(ogg_sync_state *oy){
606 if(oy->storage<0) return -1;
607 return 0;
608 }
609
610 char *ogg_sync_buffer(ogg_sync_state *oy, long size){
611 if(ogg_sync_check(oy)) return NULL;
612
613 /* first, clear out any space that has been previously returned */
614 if(oy->returned){
615 oy->fill-=oy->returned;
616 if(oy->fill>0)
617 memmove(oy->data,oy->data+oy->returned,oy->fill);
618 oy->returned=0;
619 }
620
621 if(size>oy->storage-oy->fill){
622 /* We need to extend the internal buffer */
623 long newsize=size+oy->fill+4096; /* an extra page to be nice */
624 void *ret;
625
626 if(oy->data)
627 ret=_ogg_realloc(oy->data,newsize);
628 else
629 ret=_ogg_malloc(newsize);
630 if(!ret){
631 ogg_sync_clear(oy);
632 return NULL;
633 }
634 oy->data=ret;
635 oy->storage=newsize;
636 }
637
638 /* expose a segment at least as large as requested at the fill mark */
639 return((char *)oy->data+oy->fill);
640 }
641
642 int ogg_sync_wrote(ogg_sync_state *oy, long bytes){
643 if(ogg_sync_check(oy))return -1;
644 if(oy->fill+bytes>oy->storage)return -1;
645 oy->fill+=bytes;
646 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 long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
660 unsigned char *page=oy->data+oy->returned;
661 unsigned char *next;
662 long bytes=oy->fill-oy->returned;
663
664 if(ogg_sync_check(oy))return 0;
665
666 if(oy->headerbytes==0){
667 int headerbytes,i;
668 if(bytes<27)return(0); /* not enough for a header */
669
670 /* verify capture pattern */
671 if(memcmp(page,"OggS",4))goto sync_fail;
672
673 headerbytes=page[26]+27;
674 if(bytes<headerbytes)return(0); /* not enough for header + seg table */
675
676 /* count up body length in the segment table */
677
678 for(i=0;i<page[26];i++)
679 oy->bodybytes+=page[27+i];
680 oy->headerbytes=headerbytes;
681 }
682
683 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 memcpy(chksum,page+22,4);
692 memset(page+22,0,4);
693
694 /* set up a temp page struct and recompute the checksum */
695 log.header=page;
696 log.header_len=oy->headerbytes;
697 log.body=page+oy->headerbytes;
698 log.body_len=oy->bodybytes;
699 ogg_page_checksum_set(&log);
700
701 /* Compare */
702 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 memcpy(page+22,chksum,4);
707
708 /* Bad checksum. Lose sync */
709 goto sync_fail;
710 }
711 }
712
713 /* yes, have a whole page all ready to go */
714 {
715 unsigned char *page=oy->data+oy->returned;
716 long bytes;
717
718 if(og){
719 og->header=page;
720 og->header_len=oy->headerbytes;
721 og->body=page+oy->headerbytes;
722 og->body_len=oy->bodybytes;
723 }
724
725 oy->unsynced=0;
726 oy->returned+=(bytes=oy->headerbytes+oy->bodybytes);
727 oy->headerbytes=0;
728 oy->bodybytes=0;
729 return(bytes);
730 }
731
732 sync_fail:
733
734 oy->headerbytes=0;
735 oy->bodybytes=0;
736
737 /* search for possible capture */
738 next=memchr(page+1,'O',bytes-1);
739 if(!next)
740 next=oy->data+oy->fill;
741
742 oy->returned=(int)(next-oy->data);
743 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 int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
758
759 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 long ret=ogg_sync_pageseek(oy,og);
767 if(ret>0){
768 /* have a page */
769 return(1);
770 }
771 if(ret==0){
772 /* need more data */
773 return(0);
774 }
775
776 /* head did not start a synced page... skipped some bytes */
777 if(!oy->unsynced){
778 oy->unsynced=1;
779 return(-1);
780 }
781
782 /* loop. keep looking */
783
784 }
785 }
786
787 /* add the incoming page to the stream state; we decompose the page
788 into packet segments here as well. */
789
790 int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
791 unsigned char *header=og->header;
792 unsigned char *body=og->body;
793 long bodysize=og->body_len;
794 int segptr=0;
795
796 int version=ogg_page_version(og);
797 int continued=ogg_page_continued(og);
798 int bos=ogg_page_bos(og);
799 int eos=ogg_page_eos(og);
800 ogg_int64_t granulepos=ogg_page_granulepos(og);
801 int serialno=ogg_page_serialno(og);
802 long pageno=ogg_page_pageno(og);
803 int segments=header[26];
804
805 if(ogg_stream_check(os)) return -1;
806
807 /* clean up 'returned data' */
808 {
809 long lr=os->lacing_returned;
810 long br=os->body_returned;
811
812 /* body data */
813 if(br){
814 os->body_fill-=br;
815 if(os->body_fill)
816 memmove(os->body_data,os->body_data+br,os->body_fill);
817 os->body_returned=0;
818 }
819
820 if(lr){
821 /* segment table */
822 if(os->lacing_fill-lr){
823 memmove(os->lacing_vals,os->lacing_vals+lr,
824 (os->lacing_fill-lr)*sizeof(*os->lacing_vals));
825 memmove(os->granule_vals,os->granule_vals+lr,
826 (os->lacing_fill-lr)*sizeof(*os->granule_vals));
827 }
828 os->lacing_fill-=lr;
829 os->lacing_packet-=lr;
830 os->lacing_returned=0;
831 }
832 }
833
834 /* check the serial number */
835 if(serialno!=os->serialno)return(-1);
836 if(version>0)return(-1);
837
838 if(_os_lacing_expand(os,segments+1)) return -1;
839
840 /* are we in sequence? */
841 if(pageno!=os->pageno){
842 int i;
843
844 /* unroll previous partial packet (if any) */
845 for(i=os->lacing_packet;i<os->lacing_fill;i++)
846 os->body_fill-=os->lacing_vals[i]&0xff;
847 os->lacing_fill=os->lacing_packet;
848
849 /* make a note of dropped data in segment table */
850 if(os->pageno!=-1){
851 os->lacing_vals[os->lacing_fill++]=0x400;
852 os->lacing_packet++;
853 }
854 }
855
856 /* are we a 'continued packet' page? If so, we may need to skip
857 some segments */
858 if(continued){
859 if(os->lacing_fill<1 ||
860 os->lacing_vals[os->lacing_fill-1]==0x400){
861 bos=0;
862 for(;segptr<segments;segptr++){
863 int val=header[27+segptr];
864 body+=val;
865 bodysize-=val;
866 if(val<255){
867 segptr++;
868 break;
869 }
870 }
871 }
872 }
873
874 if(bodysize){
875 if(_os_body_expand(os,bodysize)) return -1;
876 memcpy(os->body_data+os->body_fill,body,bodysize);
877 os->body_fill+=bodysize;
878 }
879
880 {
881 int saved=-1;
882 while(segptr<segments){
883 int val=header[27+segptr];
884 os->lacing_vals[os->lacing_fill]=val;
885 os->granule_vals[os->lacing_fill]=-1;
886
887 if(bos){
888 os->lacing_vals[os->lacing_fill]|=0x100;
889 bos=0;
890 }
891
892 if(val<255)saved=os->lacing_fill;
893
894 os->lacing_fill++;
895 segptr++;
896
897 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 if(saved!=-1){
902 os->granule_vals[saved]=granulepos;
903 }
904
905 }
906
907 if(eos){
908 os->e_o_s=1;
909 if(os->lacing_fill>0)
910 os->lacing_vals[os->lacing_fill-1]|=0x200;
911 }
912
913 os->pageno=pageno+1;
914
915 return(0);
916 }
917
918 /* clear things to an initial state. Good to call, eg, before seeking */
919 int ogg_sync_reset(ogg_sync_state *oy){
920 if(ogg_sync_check(oy))return -1;
921
922 oy->fill=0;
923 oy->returned=0;
924 oy->unsynced=0;
925 oy->headerbytes=0;
926 oy->bodybytes=0;
927 return(0);
928 }
929
930 int ogg_stream_reset(ogg_stream_state *os){
931 if(ogg_stream_check(os)) return -1;
932
933 os->body_fill=0;
934 os->body_returned=0;
935
936 os->lacing_fill=0;
937 os->lacing_packet=0;
938 os->lacing_returned=0;
939
940 os->header_fill=0;
941
942 os->e_o_s=0;
943 os->b_o_s=0;
944 os->pageno=-1;
945 os->packetno=0;
946 os->granulepos=0;
947
948 return(0);
949 }
950
951 int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno){
952 if(ogg_stream_check(os)) return -1;
953 ogg_stream_reset(os);
954 os->serialno=serialno;
955 return(0);
956 }
957
958 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 int ptr=os->lacing_returned;
965
966 if(os->lacing_packet<=ptr)return(0);
967
968 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 os->lacing_returned++;
972 os->packetno++;
973 return(-1);
974 }
975
976 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 int size=os->lacing_vals[ptr]&0xff;
983 long bytes=size;
984 int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */
985 int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */
986
987 while(size==255){
988 int val=os->lacing_vals[++ptr];
989 size=val&0xff;
990 if(val&0x200)eos=0x200;
991 bytes+=size;
992 }
993
994 if(op){
995 op->e_o_s=eos;
996 op->b_o_s=bos;
997 op->packet=os->body_data+os->body_returned;
998 op->packetno=os->packetno;
999 op->granulepos=os->granule_vals[ptr];
1000 op->bytes=bytes;
1001 }
1002
1003 if(adv){
1004 os->body_returned+=bytes;
1005 os->lacing_returned=ptr+1;
1006 os->packetno++;
1007 }
1008 }
1009 return(1);
1010 }
1011
1012 int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op){
1013 if(ogg_stream_check(os)) return 0;
1014 return _packetout(os,op,1);
1015 }
1016
1017 int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){
1018 if(ogg_stream_check(os)) return 0;
1019 return _packetout(os,op,0);
1020 }
1021
1022 void ogg_packet_clear(ogg_packet *op) {
1023 _ogg_free(op->packet);
1024 memset(op, 0, sizeof(*op));
1025 }
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
ogg_iovec_t::iov_len
size_t iov_len
Definition: ogg.h:29
ogg_page_eos
int ogg_page_eos(const ogg_page *og)
Definition: framing.c:41
ogg_stream_state::lacing_storage
long lacing_storage
Definition: ogg.h:64
ogg_stream_state::b_o_s
int b_o_s
Definition: ogg.h:74
ogg_sync_state::fill
int fill
Definition: ogg.h:108
val
GLuint const GLfloat * val
Definition: glew.h:2715
_os_body_expand
static int _os_body_expand(ogg_stream_state *os, int needed)
Definition: framing.c:239
header
cannot open resource broken file module version is too low unimplemented feature broken offset within table missing module invalid character code cannot render this glyph format invalid composite glyph invalid pixel size invalid library handle invalid face handle invalid glyph slot handle invalid cache manager handle too many modules out of memory cannot open stream invalid stream skip invalid stream operation nested frame access raster uninitialized raster overflow too many registered caches too few arguments code overflow division by zero found debug opcode nested DEFS execution context too long too many instruction definitions horizontal header(hhea) table missing" ) FT_ERRORDEF_( Locations_Missing
ogg_page
Definition: ogg.h:43
ogg_stream_flush
int ogg_stream_flush(ogg_stream_state *os, ogg_page *og)
Definition: framing.c:517
ogg_stream_check
int ogg_stream_check(ogg_stream_state *os)
Definition: framing.c:211
ogg_page::body
unsigned char * body
Definition: ogg.h:46
main
int main(int argc, char **argv)
Definition: bootstrap.cpp:102
NULL
#define NULL
Definition: ftobjs.h:61
ogg_stream_state::body_fill
long body_fill
Definition: ogg.h:56
ogg_stream_state::lacing_fill
long lacing_fill
Definition: ogg.h:65
n
GLclampd n
Definition: glew.h:7287
ogg_packet
Definition: ogg.h:90
ogg_sync_state::data
unsigned char * data
Definition: ogg.h:106
ogg_stream_state::body_data
unsigned char * body_data
Definition: ogg.h:54
memmove
#define memmove
Definition: SDL_qsort.c:81
ogg_stream_flush_fill
int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill)
Definition: framing.c:525
ogg_page::header_len
long header_len
Definition: ogg.h:45
ogg_stream_state::body_returned
long body_returned
Definition: ogg.h:57
j
int32_t j
Definition: e_log.c:102
memset
#define memset
Definition: SDL_malloc.c:633
version
int const char * version
Definition: zlib.h:813
_ogg_free
#define _ogg_free
Definition: os_types.h:25
ogg_sync_wrote
int ogg_sync_wrote(ogg_sync_state *oy, long bytes)
Definition: framing.c:642
ogg_sync_state::bodybytes
int bodybytes
Definition: ogg.h:113
len
GLenum GLsizei len
Definition: glew.h:7035
ogg_stream_pageout_fill
int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill)
Definition: framing.c:548
ogg_sync_state::unsynced
int unsynced
Definition: ogg.h:111
ogg_stream_eos
int ogg_stream_eos(ogg_stream_state *os)
Definition: framing.c:559
ogg_stream_state::granule_vals
ogg_int64_t * granule_vals
Definition: ogg.h:61
ogg.h
ret
ret
Definition: glew_str_glx.c:2
ogg_sync_pageout
int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og)
Definition: framing.c:757
ogg_stream_state::serialno
long serialno
Definition: ogg.h:76
ogg_stream_state::header
unsigned char header[282]
Definition: ogg.h:69
packets
static UDPpacket ** packets
Definition: chat.cpp:46
_packetout
static int _packetout(ogg_stream_state *os, ogg_packet *op, int adv)
Definition: framing.c:958
_os_lacing_expand
static int _os_lacing_expand(ogg_stream_state *os, int needed)
Definition: framing.c:254
ogg_sync_buffer
char * ogg_sync_buffer(ogg_sync_state *oy, long size)
Definition: framing.c:610
ogg_sync_reset
int ogg_sync_reset(ogg_sync_state *oy)
Definition: framing.c:919
ogg_page_continued
int ogg_page_continued(const ogg_page *og)
Definition: framing.c:33
ogg_stream_state::pageno
long pageno
Definition: ogg.h:77
ogg_sync_state::storage
int storage
Definition: ogg.h:107
int
int
Definition: SDL_systhread.c:37
ogg_packet::bytes
long bytes
Definition: ogg.h:92
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
error
FT_Error error
Definition: cffdrivr.c:407
ogg_stream_state::lacing_vals
int * lacing_vals
Definition: ogg.h:60
ogg_stream_packetpeek
int ogg_stream_packetpeek(ogg_stream_state *os, ogg_packet *op)
Definition: framing.c:1017
ogg_stream_packetin
int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op)
Definition: framing.c:362
count
GLint GLsizei count
Definition: gl2ext.h:1011
ogg_stream_pagein
int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og)
Definition: framing.c:790
ogg_iovec_t
Definition: ogg.h:27
ogg_packet::packet
unsigned char * packet
Definition: ogg.h:91
ogg_page_bos
int ogg_page_bos(const ogg_page *og)
Definition: framing.c:37
ogg_packet_clear
void ogg_packet_clear(ogg_packet *op)
Definition: framing.c:1022
ogg_page_checksum_set
void ogg_page_checksum_set(ogg_page *og)
Definition: framing.c:280
index
GLuint index
Definition: glew.h:1800
ogg_sync_check
int ogg_sync_check(ogg_sync_state *oy)
Definition: framing.c:605
ogg_stream_pageout
int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og)
Definition: framing.c:533
ogg_sync_clear
int ogg_sync_clear(ogg_sync_state *oy)
Definition: framing.c:589
ogg_sync_destroy
int ogg_sync_destroy(ogg_sync_state *oy)
Definition: framing.c:597
crc_lookup
static const ogg_uint32_t crc_lookup[256]
Definition: framing.c:120
ogg_page::header
unsigned char * header
Definition: ogg.h:44
ogg_packet::b_o_s
long b_o_s
Definition: ogg.h:93
_ogg_realloc
#define _ogg_realloc
Definition: os_types.h:24
ogg_uint32_t
unsigned int ogg_uint32_t
Definition: config_types.h:22
ogg_page_pageno
long ogg_page_pageno(const ogg_page *og)
Definition: framing.c:65
ogg_stream_clear
int ogg_stream_clear(ogg_stream_state *os)
Definition: framing.c:217
ogg_stream_flush_i
static int ogg_stream_flush_i(ogg_stream_state *os, ogg_page *og, int force, int nfill)
Definition: framing.c:372
ogg_stream_iovecin
int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count, long e_o_s, ogg_int64_t granulepos)
Definition: framing.c:304
ogg_stream_state::lacing_returned
long lacing_returned
Definition: ogg.h:67
ogg_page_packets
int ogg_page_packets(const ogg_page *og)
Definition: framing.c:91
ogg_sync_pageseek
long ogg_sync_pageseek(ogg_sync_state *oy, ogg_page *og)
Definition: framing.c:659
ogg_sync_state
Definition: ogg.h:105
ogg_stream_state::packetno
ogg_int64_t packetno
Definition: ogg.h:78
buf
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2539
memcpy
#define memcpy
Definition: SDL_malloc.c:634
ogg_stream_destroy
int ogg_stream_destroy(ogg_stream_state *os)
Definition: framing.c:228
ogg_packet::granulepos
ogg_int64_t granulepos
Definition: ogg.h:96
ogg_stream_packetout
int ogg_stream_packetout(ogg_stream_state *os, ogg_packet *op)
Definition: framing.c:1012
String.h
r
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
ogg_stream_state
Definition: ogg.h:53
ogg_stream_reset
int ogg_stream_reset(ogg_stream_state *os)
Definition: framing.c:930
ogg_sync_init
int ogg_sync_init(ogg_sync_state *oy)
Definition: framing.c:580
ogg_stream_state::e_o_s
int e_o_s
Definition: ogg.h:72
ogg_sync_state::returned
int returned
Definition: ogg.h:109
ogg_stream_state::header_fill
int header_fill
Definition: ogg.h:70
i
int i
Definition: pngrutil.c:1377
ogg_stream_reset_serialno
int ogg_stream_reset_serialno(ogg_stream_state *os, int serialno)
Definition: framing.c:951
ogg_page_serialno
int ogg_page_serialno(const ogg_page *og)
Definition: framing.c:58
ogg_page::body_len
long body_len
Definition: ogg.h:47
ogg_iovec_t::iov_base
void * iov_base
Definition: ogg.h:28
ogg_stream_state::lacing_packet
long lacing_packet
Definition: ogg.h:66
ogg_packet::e_o_s
long e_o_s
Definition: ogg.h:94
ogg_sync_state::headerbytes
int headerbytes
Definition: ogg.h:112
ogg_stream_state::granulepos
ogg_int64_t granulepos
Definition: ogg.h:83
ogg_int64_t
long ogg_int64_t
Definition: config_types.h:23
ogg_page_granulepos
ogg_int64_t ogg_page_granulepos(const ogg_page *og)
Definition: framing.c:45
ogg_stream_init
int ogg_stream_init(ogg_stream_state *os, int serialno)
Definition: framing.c:188
ogg_packet::packetno
ogg_int64_t packetno
Definition: ogg.h:98
ogg_stream_state::body_storage
long body_storage
Definition: ogg.h:55
ogg_page_version
int ogg_page_version(const ogg_page *og)
Definition: framing.c:29
_ogg_malloc
#define _ogg_malloc
Definition: os_types.h:22
size
GLsizei size
Definition: gl2ext.h:1467