1/************************************************************************
2 * Copyright (C) 2002-2009, Xiph.org Foundation
3 * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 *     * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *     * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 *     * Neither the names of the Xiph.org Foundation nor Pinknoise
17 * Productions Ltd nor the names of its contributors may be used to
18 * endorse or promote products derived from this software without
19 * specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 ************************************************************************
33
34 function: stdio-based convenience library for opening/seeking/decoding
35 last mod: $Id: vorbisfile.c,v 1.6.2.5 2003/11/20 06:16:17 xiphmont Exp $
36
37 ************************************************************************/
38
39#include <stdlib.h>
40#include <stdio.h>
41//#include <gerrno.h>
42#include <string.h>
43#include <math.h>
44
45#include "codec_internal.h"
46#include "ivorbisfile.h"
47
48#include "os.h"
49#include "misc.h"
50
51int gerrno;
52
53#define  NOTOPEN   0
54#define  PARTOPEN  1
55#define  OPENED    2
56#define  STREAMSET 3 /* serialno and link set, but not to current link */
57#define  LINKSET   4 /* serialno and link set to current link */
58#define  INITSET   5
59
60/* A 'chained bitstream' is a Vorbis bitstream that contains more than
61   one logical bitstream arranged end to end (the only form of Ogg
62   multiplexing allowed in a Vorbis bitstream; grouping [parallel
63   multiplexing] is not allowed in Vorbis) */
64
65/* A Vorbis file can be played beginning to end (streamed) without
66   worrying ahead of time about chaining (see decoder_example.c).  If
67   we have the whole file, however, and want random access
68   (seeking/scrubbing) or desire to know the total length/time of a
69   file, we need to account for the possibility of chaining. */
70
71/* We can handle things a number of ways; we can determine the entire
72   bitstream structure right off the bat, or find pieces on demand.
73   This example determines and caches structure for the entire
74   bitstream, but builds a virtual decoder on the fly when moving
75   between links in the chain. */
76
77/* There are also different ways to implement seeking.  Enough
78   information exists in an Ogg bitstream to seek to
79   sample-granularity positions in the output.  Or, one can seek by
80   picking some portion of the stream roughly in the desired area if
81   we only want coarse navigation through the stream. */
82
83/*************************************************************************
84 * Many, many internal helpers.  The intention is not to be confusing;
85 * rampant duplication and monolithic function implementation would be
86 * harder to understand anyway.  The high level functions are last.  Begin
87 * grokking near the end of the file */
88
89
90/* read a little more data from the file/pipe into the ogg_sync framer */
91static long _get_data(OggVorbis_File *vf){
92  gerrno=0;
93  if(vf->datasource){
94    unsigned char *buffer=ogg_sync_bufferin(vf->oy,CHUNKSIZE);
95    long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
96    if(bytes>0)ogg_sync_wrote(vf->oy,bytes);
97    if(bytes==0 && gerrno)return -1;
98    return bytes;
99  }else
100    return 0;
101}
102
103/* save a tiny smidge of verbosity to make the code more readable */
104static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
105  if(vf->datasource){
106    (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
107    vf->offset=offset;
108    ogg_sync_reset(vf->oy);
109  }else{
110    /* shouldn't happen unless someone writes a broken callback */
111    return;
112  }
113}
114
115/* The read/seek functions track absolute position within the stream */
116
117/* from the head of the stream, get the next page.  boundary specifies
118   if the function is allowed to fetch more data from the stream (and
119   how much) or only use internally buffered data.
120
121   boundary: -1) unbounded search
122              0) read no additional data; use cached only
123	      n) search for a new page beginning for n bytes
124
125   return:   <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
126              n) found a page at absolute offset n
127
128              produces a refcounted page */
129
130static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
131				  ogg_int64_t boundary){
132  if(boundary>0)boundary+=vf->offset;
133  while(1){
134    long more;
135
136    if(boundary>0 && vf->offset>=boundary)return OV_FALSE;
137    more=ogg_sync_pageseek(vf->oy,og);
138
139    if(more<0){
140      /* skipped n bytes */
141      vf->offset-=more;
142    }else{
143      if(more==0){
144	/* send more paramedics */
145	if(!boundary)return OV_FALSE;
146	{
147	  long ret=_get_data(vf);
148	  if(ret==0)return OV_EOF;
149	  if(ret<0)return OV_EREAD;
150	}
151      }else{
152	/* got a page.  Return the offset at the page beginning,
153           advance the internal offset past the page end */
154	ogg_int64_t ret=vf->offset;
155	vf->offset+=more;
156	return ret;
157
158      }
159    }
160  }
161}
162
163/* find the latest page beginning before the current stream cursor
164   position. Much dirtier than the above as Ogg doesn't have any
165   backward search linkage.  no 'readp' as it will certainly have to
166   read. */
167/* returns offset or OV_EREAD, OV_FAULT and produces a refcounted page */
168
169static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
170  ogg_int64_t begin=vf->offset;
171  ogg_int64_t end=begin;
172  ogg_int64_t ret;
173  ogg_int64_t offset=-1;
174
175  while(offset==-1){
176    begin-=CHUNKSIZE;
177    if(begin<0)
178      begin=0;
179    _seek_helper(vf,begin);
180    while(vf->offset<end){
181      ret=_get_next_page(vf,og,end-vf->offset);
182      if(ret==OV_EREAD)return OV_EREAD;
183      if(ret<0){
184	break;
185      }else{
186	offset=ret;
187      }
188    }
189  }
190
191  /* we have the offset.  Actually snork and hold the page now */
192  _seek_helper(vf,offset);
193  ret=_get_next_page(vf,og,CHUNKSIZE);
194  if(ret<0)
195    /* this shouldn't be possible */
196    return OV_EFAULT;
197
198  return offset;
199}
200
201/* finds each bitstream link one at a time using a bisection search
202   (has to begin by knowing the offset of the lb's initial page).
203   Recurses for each link so it can alloc the link storage after
204   finding them all, then unroll and fill the cache at the same time */
205static int _bisect_forward_serialno(OggVorbis_File *vf,
206				    ogg_int64_t begin,
207				    ogg_int64_t searched,
208				    ogg_int64_t end,
209				    ogg_uint32_t currentno,
210				    long m){
211  ogg_int64_t endsearched=end;
212  ogg_int64_t next=end;
213  ogg_page og={0,0,0,0};
214  ogg_int64_t ret;
215
216  /* the below guards against garbage seperating the last and
217     first pages of two links. */
218  while(searched<endsearched){
219    ogg_int64_t bisect;
220
221    if(endsearched-searched<CHUNKSIZE){
222      bisect=searched;
223    }else{
224      bisect=(searched+endsearched)/2;
225    }
226
227    _seek_helper(vf,bisect);
228    ret=_get_next_page(vf,&og,-1);
229    if(ret==OV_EREAD)return OV_EREAD;
230    if(ret<0 || ogg_page_serialno(&og)!=currentno){
231      endsearched=bisect;
232      if(ret>=0)next=ret;
233    }else{
234      searched=ret+og.header_len+og.body_len;
235    }
236    ogg_page_release(&og);
237  }
238
239  _seek_helper(vf,next);
240  ret=_get_next_page(vf,&og,-1);
241  if(ret==OV_EREAD)return OV_EREAD;
242
243  if(searched>=end || ret<0){
244    ogg_page_release(&og);
245    vf->links=m+1;
246    vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
247    vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
248    vf->offsets[m+1]=searched;
249  }else{
250    ret=_bisect_forward_serialno(vf,next,vf->offset,
251				 end,ogg_page_serialno(&og),m+1);
252    ogg_page_release(&og);
253    if(ret==OV_EREAD)return OV_EREAD;
254  }
255
256  vf->offsets[m]=begin;
257  vf->serialnos[m]=currentno;
258  return 0;
259}
260
261static int _decode_clear(OggVorbis_File *vf){
262  if(vf->ready_state==INITSET){
263    vorbis_dsp_destroy(vf->vd);
264    vf->vd=0;
265    vf->ready_state=STREAMSET;
266  }
267
268  if(vf->ready_state>=STREAMSET){
269    vorbis_info_clear(&vf->vi);
270    vorbis_comment_clear(&vf->vc);
271    vf->ready_state=OPENED;
272  }
273  return 0;
274}
275
276/* uses the local ogg_stream storage in vf; this is important for
277   non-streaming input sources */
278/* consumes the page that's passed in (if any) */
279/* state is LINKSET upon successful return */
280
281static int _fetch_headers(OggVorbis_File *vf,
282			  vorbis_info *vi,
283			  vorbis_comment *vc,
284			  ogg_uint32_t *serialno,
285			  ogg_page *og_ptr){
286  ogg_page og={0,0,0,0};
287  ogg_packet op={0,0,0,0,0,0};
288  int i,ret;
289
290  if(vf->ready_state>OPENED)_decode_clear(vf);
291
292  if(!og_ptr){
293    ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
294    if(llret==OV_EREAD)return OV_EREAD;
295    if(llret<0)return OV_ENOTVORBIS;
296    og_ptr=&og;
297  }
298
299  ogg_stream_reset_serialno(vf->os,ogg_page_serialno(og_ptr));
300  if(serialno)*serialno=vf->os->serialno;
301
302  /* extract the initial header from the first page and verify that the
303     Ogg bitstream is in fact Vorbis data */
304
305  vorbis_info_init(vi);
306  vorbis_comment_init(vc);
307
308  i=0;
309  while(i<3){
310    ogg_stream_pagein(vf->os,og_ptr);
311    while(i<3){
312      int result=ogg_stream_packetout(vf->os,&op);
313      if(result==0)break;
314      if(result==-1){
315	ret=OV_EBADHEADER;
316	goto bail_header;
317      }
318      if((ret=vorbis_dsp_headerin(vi,vc,&op))){
319	goto bail_header;
320      }
321      i++;
322    }
323    if(i<3)
324      if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
325	ret=OV_EBADHEADER;
326	goto bail_header;
327      }
328  }
329
330  ogg_packet_release(&op);
331  ogg_page_release(&og);
332  vf->ready_state=LINKSET;
333  return 0;
334
335 bail_header:
336  ogg_packet_release(&op);
337  ogg_page_release(&og);
338  vorbis_info_clear(vi);
339  vorbis_comment_clear(vc);
340  vf->ready_state=OPENED;
341
342  return ret;
343}
344
345/* we no longer preload all vorbis_info (and the associated
346   codec_setup) structs.  Call this to seek and fetch the info from
347   the bitstream, if needed */
348static int _set_link_number(OggVorbis_File *vf,int link){
349  if(link != vf->current_link) _decode_clear(vf);
350  if(vf->ready_state<STREAMSET){
351    _seek_helper(vf,vf->offsets[link]);
352    ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
353    vf->current_serialno=vf->serialnos[link];
354    vf->current_link=link;
355    return _fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL);
356  }
357  return 0;
358}
359
360static int _set_link_number_preserve_pos(OggVorbis_File *vf,int link){
361  ogg_int64_t pos=vf->offset;
362  int ret=_set_link_number(vf,link);
363  if(ret)return ret;
364  _seek_helper(vf,pos);
365  if(pos<vf->offsets[link] || pos>=vf->offsets[link+1])
366    vf->ready_state=STREAMSET;
367  return 0;
368}
369
370/* last step of the OggVorbis_File initialization; get all the offset
371   positions.  Only called by the seekable initialization (local
372   stream storage is hacked slightly; pay attention to how that's
373   done) */
374
375/* this is void and does not propogate errors up because we want to be
376   able to open and use damaged bitstreams as well as we can.  Just
377   watch out for missing information for links in the OggVorbis_File
378   struct */
379static void _prefetch_all_offsets(OggVorbis_File *vf, ogg_int64_t dataoffset){
380  ogg_page og={0,0,0,0};
381  int i;
382  ogg_int64_t ret;
383
384  vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
385  vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
386
387  for(i=0;i<vf->links;i++){
388    if(i==0){
389      /* we already grabbed the initial header earlier.  Just set the offset */
390      vf->dataoffsets[i]=dataoffset;
391      _seek_helper(vf,dataoffset);
392
393    }else{
394
395      /* seek to the location of the initial header */
396
397      _seek_helper(vf,vf->offsets[i]);
398      if(_fetch_headers(vf,&vf->vi,&vf->vc,NULL,NULL)<0){
399    	vf->dataoffsets[i]=-1;
400      }else{
401	vf->dataoffsets[i]=vf->offset;
402      }
403    }
404
405    /* fetch beginning PCM offset */
406
407    if(vf->dataoffsets[i]!=-1){
408      ogg_int64_t accumulated=0,pos;
409      long        lastblock=-1;
410      int         result;
411
412      ogg_stream_reset_serialno(vf->os,vf->serialnos[i]);
413
414      while(1){
415	ogg_packet op={0,0,0,0,0,0};
416
417	ret=_get_next_page(vf,&og,-1);
418	if(ret<0)
419	  /* this should not be possible unless the file is
420             truncated/mangled */
421	  break;
422
423	if(ogg_page_serialno(&og)!=vf->serialnos[i])
424	  break;
425
426	pos=ogg_page_granulepos(&og);
427
428	/* count blocksizes of all frames in the page */
429	ogg_stream_pagein(vf->os,&og);
430	while((result=ogg_stream_packetout(vf->os,&op))){
431	  if(result>0){ /* ignore holes */
432	    long thisblock=vorbis_packet_blocksize(&vf->vi,&op);
433	    if(lastblock!=-1)
434	      accumulated+=(lastblock+thisblock)>>2;
435	    lastblock=thisblock;
436	  }
437	}
438	ogg_packet_release(&op);
439
440	if(pos!=-1){
441	  /* pcm offset of last packet on the first audio page */
442	  accumulated= pos-accumulated;
443	  break;
444	}
445      }
446
447      /* less than zero?  This is a stream with samples trimmed off
448         the beginning, a normal occurrence; set the offset to zero */
449      if(accumulated<0)accumulated=0;
450
451      vf->pcmlengths[i*2]=accumulated;
452    }
453
454    /* get the PCM length of this link. To do this,
455       get the last page of the stream */
456    {
457      ogg_int64_t end=vf->offsets[i+1];
458      _seek_helper(vf,end);
459
460      while(1){
461	ret=_get_prev_page(vf,&og);
462	if(ret<0){
463	  /* this should not be possible */
464	  vorbis_info_clear(&vf->vi);
465	  vorbis_comment_clear(&vf->vc);
466	  break;
467	}
468	if(ogg_page_granulepos(&og)!=-1){
469	  vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
470	  break;
471	}
472	vf->offset=ret;
473      }
474    }
475  }
476  ogg_page_release(&og);
477}
478
479static int _make_decode_ready(OggVorbis_File *vf){
480  int i;
481  switch(vf->ready_state){
482  case OPENED:
483  case STREAMSET:
484    for(i=0;i<vf->links;i++)
485      if(vf->offsets[i+1]>=vf->offset)break;
486    if(i==vf->links)return -1;
487    i=_set_link_number_preserve_pos(vf,i);
488    if(i)return i;
489    /* fall through */
490  case LINKSET:
491    vf->vd=vorbis_dsp_create(&vf->vi);
492    vf->ready_state=INITSET;
493    vf->bittrack=0;
494    vf->samptrack=0;
495  case INITSET:
496    return 0;
497  default:
498    return -1;
499  }
500
501}
502
503static int _open_seekable2(OggVorbis_File *vf){
504  ogg_uint32_t serialno=vf->current_serialno;
505  ogg_uint32_t tempserialno;
506  ogg_int64_t dataoffset=vf->offset, end;
507  ogg_page og={0,0,0,0};
508
509  /* we're partially open and have a first link header state in
510     storage in vf */
511  /* we can seek, so set out learning all about this file */
512  (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
513  vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
514
515  /* We get the offset for the last page of the physical bitstream.
516     Most OggVorbis files will contain a single logical bitstream */
517  end=_get_prev_page(vf,&og);
518  if(end<0)return (int)end;
519
520  /* more than one logical bitstream? */
521  tempserialno=ogg_page_serialno(&og);
522  ogg_page_release(&og);
523
524  if(tempserialno!=serialno){
525
526    /* Chained bitstream. Bisect-search each logical bitstream
527       section.  Do so based on serial number only */
528    if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return OV_EREAD;
529
530  }else{
531
532    /* Only one logical bitstream */
533    if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return OV_EREAD;
534
535  }
536
537  /* the initial header memory is referenced by vf after; don't free it */
538  _prefetch_all_offsets(vf,dataoffset);
539  return ov_raw_seek(vf,0);
540}
541
542/* fetch and process a packet.  Handles the case where we're at a
543   bitstream boundary and dumps the decoding machine.  If the decoding
544   machine is unloaded, it loads it.  It also keeps pcm_offset up to
545   date (seek and read both use this.  seek uses a special hack with
546   readp).
547
548   return: <0) error, OV_HOLE (lost packet) or OV_EOF
549            0) need more data (only if readp==0)
550	    1) got a packet
551*/
552
553static int _fetch_and_process_packet(OggVorbis_File *vf,
554				     int readp,
555				     int spanp){
556  ogg_page og={0,0,0,0};
557  ogg_packet op={0,0,0,0,0,0};
558  int ret=0;
559
560  /* handle one packet.  Try to fetch it from current stream state */
561  /* extract packets from page */
562  while(1){
563
564    /* process a packet if we can.  If the machine isn't loaded,
565       neither is a page */
566    if(vf->ready_state==INITSET){
567      while(1) {
568	int result=ogg_stream_packetout(vf->os,&op);
569	ogg_int64_t granulepos;
570
571	if(result<0){
572	  ret=OV_HOLE; /* hole in the data. */
573	  goto cleanup;
574	}
575	if(result>0){
576	  /* got a packet.  process it */
577	  granulepos=op.granulepos;
578	  if(!vorbis_dsp_synthesis(vf->vd,&op,1)){ /* lazy check for lazy
579						      header handling.  The
580						      header packets aren't
581						      audio, so if/when we
582						      submit them,
583						      vorbis_synthesis will
584						      reject them */
585
586	    vf->samptrack+=vorbis_dsp_pcmout(vf->vd,NULL,0);
587	    vf->bittrack+=op.bytes*8;
588
589	    /* update the pcm offset. */
590	    if(granulepos!=-1 && !op.e_o_s){
591	      int link=(vf->seekable?vf->current_link:0);
592	      int i,samples;
593
594	      /* this packet has a pcm_offset on it (the last packet
595	         completed on a page carries the offset) After processing
596	         (above), we know the pcm position of the *last* sample
597	         ready to be returned. Find the offset of the *first*
598
599	         As an aside, this trick is inaccurate if we begin
600	         reading anew right at the last page; the end-of-stream
601	         granulepos declares the last frame in the stream, and the
602	         last packet of the last page may be a partial frame.
603	         So, we need a previous granulepos from an in-sequence page
604	         to have a reference point.  Thus the !op.e_o_s clause
605	         above */
606
607	      if(vf->seekable && link>0)
608		granulepos-=vf->pcmlengths[link*2];
609	      if(granulepos<0)granulepos=0; /* actually, this
610					       shouldn't be possible
611					       here unless the stream
612					       is very broken */
613
614	      samples=vorbis_dsp_pcmout(vf->vd,NULL,0);
615
616	      granulepos-=samples;
617	      for(i=0;i<link;i++)
618	        granulepos+=vf->pcmlengths[i*2+1];
619	      vf->pcm_offset=granulepos;
620	    }
621	    ret=1;
622	    goto cleanup;
623	  }
624	}
625	else
626	  break;
627      }
628    }
629
630    if(vf->ready_state>=OPENED){
631      int ret;
632      if(!readp){
633	ret=0;
634	goto cleanup;
635      }
636      ret=(int)_get_next_page(vf,&og,-1);
637      if(ret<0){
638	ret=OV_EOF; /* eof. leave unitialized */
639	goto cleanup;
640      }
641
642	/* bitrate tracking; add the header's bytes here, the body bytes
643	   are done by packet above */
644      vf->bittrack+=og.header_len*8;
645
646      /* has our decoding just traversed a bitstream boundary? */
647      if(vf->ready_state==INITSET){
648	if(vf->current_serialno!=ogg_page_serialno(&og)){
649	  if(!spanp){
650	    ret=OV_EOF;
651	    goto cleanup;
652	  }
653
654	  _decode_clear(vf);
655	}
656      }
657    }
658
659    /* Do we need to load a new machine before submitting the page? */
660    /* This is different in the seekable and non-seekable cases.
661
662       In the seekable case, we already have all the header
663       information loaded and cached; we just initialize the machine
664       with it and continue on our merry way.
665
666       In the non-seekable (streaming) case, we'll only be at a
667       boundary if we just left the previous logical bitstream and
668       we're now nominally at the header of the next bitstream
669    */
670
671    if(vf->ready_state!=INITSET){
672      int link,ret;
673
674      if(vf->ready_state<STREAMSET){
675	if(vf->seekable){
676	  vf->current_serialno=ogg_page_serialno(&og);
677
678	  /* match the serialno to bitstream section.  We use this rather than
679	     offset positions to avoid problems near logical bitstream
680	     boundaries */
681	  for(link=0;link<vf->links;link++)
682	    if(vf->serialnos[link]==vf->current_serialno)break;
683	  if(link==vf->links){
684	    ret=OV_EBADLINK; /* sign of a bogus stream.  error out,
685				leave machine uninitialized */
686	    goto cleanup;
687	  }
688
689	  vf->current_link=link;
690	  ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
691	  if(ret) goto cleanup;
692
693	}else{
694	  /* we're streaming */
695	  /* fetch the three header packets, build the info struct */
696
697	  int ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
698	  if(ret) goto cleanup;
699	  vf->current_link++;
700	}
701      }
702
703      if(_make_decode_ready(vf)) return OV_EBADLINK;
704    }
705    ogg_stream_pagein(vf->os,&og);
706  }
707 cleanup:
708  ogg_packet_release(&op);
709  ogg_page_release(&og);
710  return ret;
711}
712
713/* if, eg, 64 bit stdio is configured by default, this will build with
714   fseek64 */
715static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
716  if(f==NULL)return -1;
717  return fseek(f,(long)off,whence);
718}
719
720static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
721		     long ibytes, ov_callbacks callbacks){
722  int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
723  int ret;
724
725  memset(vf,0,sizeof(*vf));
726
727  /* Tremor assumes in multiple places that right shift of a signed
728     integer is an arithmetic shift */
729  if( (-1>>1) != -1) return OV_EIMPL;
730
731  vf->datasource=f;
732  vf->callbacks = callbacks;
733
734  /* init the framing state */
735  vf->oy=ogg_sync_create();
736
737  /* perhaps some data was previously read into a buffer for testing
738     against other stream types.  Allow initialization from this
739     previously read data (as we may be reading from a non-seekable
740     stream) */
741  if(initial){
742    unsigned char *buffer=ogg_sync_bufferin(vf->oy,ibytes);
743    memcpy(buffer,initial,ibytes);
744    ogg_sync_wrote(vf->oy,ibytes);
745  }
746
747  /* can we seek? Stevens suggests the seek test was portable */
748  if(offsettest!=-1)vf->seekable=1;
749
750  /* No seeking yet; Set up a 'single' (current) logical bitstream
751     entry for partial open */
752  vf->links=1;
753  vf->os=ogg_stream_create(-1); /* fill in the serialno later */
754
755  /* Try to fetch the headers, maintaining all the storage */
756  if((ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL))<0){
757    vf->datasource=NULL;
758    ov_clear(vf);
759  }else if(vf->ready_state < PARTOPEN)
760    vf->ready_state=PARTOPEN;
761  return ret;
762}
763
764static int _ov_open2(OggVorbis_File *vf){
765  if(vf->ready_state < OPENED)
766    vf->ready_state=OPENED;
767  if(vf->seekable){
768    int ret=_open_seekable2(vf);
769    if(ret){
770      vf->datasource=NULL;
771      ov_clear(vf);
772    }
773    return ret;
774  }
775  return 0;
776}
777
778
779/* clear out the OggVorbis_File struct */
780int ov_clear(OggVorbis_File *vf){
781  if(vf){
782    vorbis_dsp_destroy(vf->vd);
783    vf->vd=0;
784    ogg_stream_destroy(vf->os);
785    vorbis_info_clear(&vf->vi);
786    vorbis_comment_clear(&vf->vc);
787    if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
788    if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
789    if(vf->serialnos)_ogg_free(vf->serialnos);
790    if(vf->offsets)_ogg_free(vf->offsets);
791    ogg_sync_destroy(vf->oy);
792
793    if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
794    memset(vf,0,sizeof(*vf));
795  }
796#ifdef DEBUG_LEAKS
797  _VDBG_dump();
798#endif
799  return 0;
800}
801
802/* inspects the OggVorbis file and finds/documents all the logical
803   bitstreams contained in it.  Tries to be tolerant of logical
804   bitstream sections that are truncated/woogie.
805
806   return: -1) error
807            0) OK
808*/
809
810int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
811    ov_callbacks callbacks){
812  int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
813  if(ret)return ret;
814  return _ov_open2(vf);
815}
816
817int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
818  ov_callbacks callbacks = {
819    (size_t (*)(void *, size_t, size_t, void *))  fread,
820    (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
821    (int (*)(void *))                             fclose,
822    (long (*)(void *))                            ftell
823  };
824
825  return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
826}
827
828/* Only partially open the vorbis file; test for Vorbisness, and load
829   the headers for the first chain.  Do not seek (although test for
830   seekability).  Use ov_test_open to finish opening the file, else
831   ov_clear to close/free it. Same return codes as open. */
832
833int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
834    ov_callbacks callbacks)
835{
836  return _ov_open1(f,vf,initial,ibytes,callbacks);
837}
838
839int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
840  ov_callbacks callbacks = {
841    (size_t (*)(void *, size_t, size_t, void *))  fread,
842    (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
843    (int (*)(void *))                             fclose,
844    (long (*)(void *))                            ftell
845  };
846
847  return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
848}
849
850int ov_test_open(OggVorbis_File *vf){
851  if(vf->ready_state!=PARTOPEN)return OV_EINVAL;
852  return _ov_open2(vf);
853}
854
855/* How many logical bitstreams in this physical bitstream? */
856long ov_streams(OggVorbis_File *vf){
857  return vf->links;
858}
859
860/* Is the FILE * associated with vf seekable? */
861long ov_seekable(OggVorbis_File *vf){
862  return vf->seekable;
863}
864
865/* returns the bitrate for a given logical bitstream or the entire
866   physical bitstream.  If the file is open for random access, it will
867   find the *actual* average bitrate.  If the file is streaming, it
868   returns the nominal bitrate (if set) else the average of the
869   upper/lower bounds (if set) else -1 (unset).
870
871   If you want the actual bitrate field settings, get them from the
872   vorbis_info structs */
873
874long ov_bitrate(OggVorbis_File *vf,int i){
875  if(vf->ready_state<OPENED)return OV_EINVAL;
876  if(i>=vf->links)return OV_EINVAL;
877  if(!vf->seekable && i!=0)return ov_bitrate(vf,0);
878  if(i<0){
879    ogg_int64_t bits=0;
880    int i;
881    for(i=0;i<vf->links;i++)
882      bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
883    /* This once read: return(rint(bits/ov_time_total(vf,-1)));
884     * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
885     * so this is slightly transformed to make it work.
886     */
887    return (long)(bits*1000/ov_time_total(vf,-1));
888  }else{
889    if(vf->seekable){
890      /* return the actual bitrate */
891      return (long)((vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i));
892    }else{
893      /* return nominal if set */
894      if(vf->vi.bitrate_nominal>0){
895	return vf->vi.bitrate_nominal;
896      }else{
897	if(vf->vi.bitrate_upper>0){
898	  if(vf->vi.bitrate_lower>0){
899	    return (vf->vi.bitrate_upper+vf->vi.bitrate_lower)/2;
900	  }else{
901	    return vf->vi.bitrate_upper;
902	  }
903	}
904	return OV_FALSE;
905      }
906    }
907  }
908}
909
910/* returns the actual bitrate since last call.  returns -1 if no
911   additional data to offer since last call (or at beginning of stream),
912   EINVAL if stream is only partially open
913*/
914long ov_bitrate_instant(OggVorbis_File *vf){
915  long ret;
916  if(vf->ready_state<OPENED)return OV_EINVAL;
917  if(vf->samptrack==0)return OV_FALSE;
918  ret=(long)(vf->bittrack/vf->samptrack*vf->vi.rate);
919  vf->bittrack=0;
920  vf->samptrack=0;
921  return ret;
922}
923
924/* Guess */
925long ov_serialnumber(OggVorbis_File *vf,int i){
926  if(i>=vf->links)return ov_serialnumber(vf,vf->links-1);
927  if(!vf->seekable && i>=0)return ov_serialnumber(vf,-1);
928  if(i<0){
929    return vf->current_serialno;
930  }else{
931    return vf->serialnos[i];
932  }
933}
934
935/* returns: total raw (compressed) length of content if i==-1
936            raw (compressed) length of that logical bitstream for i==0 to n
937	    OV_EINVAL if the stream is not seekable (we can't know the length)
938	    or if stream is only partially open
939*/
940ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
941  if(vf->ready_state<OPENED)return OV_EINVAL;
942  if(!vf->seekable || i>=vf->links)return OV_EINVAL;
943  if(i<0){
944    ogg_int64_t acc=0;
945    int i;
946    for(i=0;i<vf->links;i++)
947      acc+=ov_raw_total(vf,i);
948    return acc;
949  }else{
950    return vf->offsets[i+1]-vf->offsets[i];
951  }
952}
953
954/* returns: total PCM length (samples) of content if i==-1 PCM length
955	    (samples) of that logical bitstream for i==0 to n
956	    OV_EINVAL if the stream is not seekable (we can't know the
957	    length) or only partially open
958*/
959ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
960  if(vf->ready_state<OPENED)return OV_EINVAL;
961  if(!vf->seekable || i>=vf->links)return OV_EINVAL;
962  if(i<0){
963    ogg_int64_t acc=0;
964    int i;
965    for(i=0;i<vf->links;i++)
966      acc+=ov_pcm_total(vf,i);
967    return acc;
968  }else{
969    return vf->pcmlengths[i*2+1];
970  }
971}
972
973/* returns: total milliseconds of content if i==-1
974            milliseconds in that logical bitstream for i==0 to n
975	    OV_EINVAL if the stream is not seekable (we can't know the
976	    length) or only partially open
977*/
978ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){
979  if(vf->ready_state<OPENED)return OV_EINVAL;
980  if(!vf->seekable || i>=vf->links)return OV_EINVAL;
981  if(i<0){
982    ogg_int64_t acc=0;
983    int i;
984    for(i=0;i<vf->links;i++)
985      acc+=ov_time_total(vf,i);
986    return acc;
987  }else{
988    return ((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi.rate;
989  }
990}
991
992/* seek to an offset relative to the *compressed* data. This also
993   scans packets to update the PCM cursor. It will cross a logical
994   bitstream boundary, but only if it can't get any packets out of the
995   tail of the bitstream we seek to (so no surprises).
996
997   returns zero on success, nonzero on failure */
998
999int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1000  ogg_stream_state *work_os=NULL;
1001  ogg_page og={0,0,0,0};
1002  ogg_packet op={0,0,0,0,0,0};
1003
1004  if(vf->ready_state<OPENED)return OV_EINVAL;
1005  if(!vf->seekable)
1006    return OV_ENOSEEK; /* don't dump machine if we can't seek */
1007
1008  if(pos<0 || pos>vf->end)return OV_EINVAL;
1009
1010  /* don't yet clear out decoding machine (if it's initialized), in
1011     the case we're in the same link.  Restart the decode lapping, and
1012     let _fetch_and_process_packet deal with a potential bitstream
1013     boundary */
1014  vf->pcm_offset=-1;
1015  ogg_stream_reset_serialno(vf->os,
1016			    vf->current_serialno); /* must set serialno */
1017  vorbis_dsp_restart(vf->vd);
1018
1019  _seek_helper(vf,pos);
1020
1021  /* we need to make sure the pcm_offset is set, but we don't want to
1022     advance the raw cursor past good packets just to get to the first
1023     with a granulepos.  That's not equivalent behavior to beginning
1024     decoding as immediately after the seek position as possible.
1025
1026     So, a hack.  We use two stream states; a local scratch state and
1027     the shared vf->os stream state.  We use the local state to
1028     scan, and the shared state as a buffer for later decode.
1029
1030     Unfortuantely, on the last page we still advance to last packet
1031     because the granulepos on the last page is not necessarily on a
1032     packet boundary, and we need to make sure the granpos is
1033     correct.
1034  */
1035
1036  {
1037    int lastblock=0;
1038    int accblock=0;
1039    int thisblock;
1040    int eosflag;
1041
1042    work_os=ogg_stream_create(vf->current_serialno); /* get the memory ready */
1043    while(1){
1044      if(vf->ready_state>=STREAMSET){
1045	/* snarf/scan a packet if we can */
1046	int result=ogg_stream_packetout(work_os,&op);
1047
1048	if(result>0){
1049
1050	  if(vf->vi.codec_setup){
1051	    thisblock=vorbis_packet_blocksize(&vf->vi,&op);
1052	    if(thisblock<0){
1053	      ogg_stream_packetout(vf->os,NULL);
1054	      thisblock=0;
1055	    }else{
1056
1057	      if(eosflag)
1058		ogg_stream_packetout(vf->os,NULL);
1059	      else
1060		if(lastblock)accblock+=(lastblock+thisblock)>>2;
1061	    }
1062
1063	    if(op.granulepos!=-1){
1064	      int i,link=vf->current_link;
1065	      ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1066	      if(granulepos<0)granulepos=0;
1067
1068	      for(i=0;i<link;i++)
1069		granulepos+=vf->pcmlengths[i*2+1];
1070	      vf->pcm_offset=granulepos-accblock;
1071	      break;
1072	    }
1073	    lastblock=thisblock;
1074	    continue;
1075	  }else
1076	    ogg_stream_packetout(vf->os,NULL);
1077	}
1078      }
1079
1080      if(!lastblock){
1081	if(_get_next_page(vf,&og,-1)<0){
1082	  vf->pcm_offset=ov_pcm_total(vf,-1);
1083	  break;
1084	}
1085      }else{
1086	/* huh?  Bogus stream with packets but no granulepos */
1087	vf->pcm_offset=-1;
1088	break;
1089      }
1090
1091      /* did we just grab a page from other than current link? */
1092      if(vf->ready_state>=STREAMSET)
1093	if(vf->current_serialno!=ogg_page_serialno(&og)){
1094	  _decode_clear(vf); /* clear out stream state */
1095	  ogg_stream_destroy(work_os);
1096	}
1097
1098      if(vf->ready_state<STREAMSET){
1099	int link;
1100
1101	vf->current_serialno=ogg_page_serialno(&og);
1102	for(link=0;link<vf->links;link++)
1103	  if(vf->serialnos[link]==vf->current_serialno)break;
1104	if(link==vf->links)
1105	  goto seek_error; /* sign of a bogus stream.  error out,
1106			      leave machine uninitialized */
1107
1108	/* need to initialize machine to this link */
1109	{
1110	  int ret=_set_link_number_preserve_pos(vf,link);
1111	  if(ret) goto seek_error;
1112	}
1113	ogg_stream_reset_serialno(vf->os,vf->current_serialno);
1114	ogg_stream_reset_serialno(work_os,vf->current_serialno);
1115
1116
1117      }
1118
1119      {
1120	ogg_page dup;
1121	ogg_page_dup(&dup,&og);
1122	eosflag=ogg_page_eos(&og);
1123	ogg_stream_pagein(vf->os,&og);
1124	ogg_stream_pagein(work_os,&dup);
1125      }
1126    }
1127  }
1128
1129  ogg_packet_release(&op);
1130  ogg_page_release(&og);
1131  ogg_stream_destroy(work_os);
1132  vf->bittrack=0;
1133  vf->samptrack=0;
1134  return 0;
1135
1136 seek_error:
1137  ogg_packet_release(&op);
1138  ogg_page_release(&og);
1139
1140  /* dump the machine so we're in a known state */
1141  vf->pcm_offset=-1;
1142  ogg_stream_destroy(work_os);
1143  _decode_clear(vf);
1144  return OV_EBADLINK;
1145}
1146
1147/* Page granularity seek (faster than sample granularity because we
1148   don't do the last bit of decode to find a specific sample).
1149
1150   Seek to the last [granule marked] page preceeding the specified pos
1151   location, such that decoding past the returned point will quickly
1152   arrive at the requested position. */
1153int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1154  int link=-1;
1155  ogg_int64_t result=0;
1156  ogg_int64_t total=ov_pcm_total(vf,-1);
1157  ogg_page og={0,0,0,0};
1158  ogg_packet op={0,0,0,0,0,0};
1159
1160  if(vf->ready_state<OPENED)return OV_EINVAL;
1161  if(!vf->seekable)return OV_ENOSEEK;
1162  if(pos<0 || pos>total)return OV_EINVAL;
1163
1164  /* which bitstream section does this pcm offset occur in? */
1165  for(link=vf->links-1;link>=0;link--){
1166    total-=vf->pcmlengths[link*2+1];
1167    if(pos>=total)break;
1168  }
1169
1170
1171  if(link!=vf->current_link){
1172    int ret=_set_link_number(vf,link);
1173    if(ret) goto seek_error;
1174  }else{
1175    vorbis_dsp_restart(vf->vd);
1176  }
1177
1178  ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
1179
1180  /* search within the logical bitstream for the page with the highest
1181     pcm_pos preceeding (or equal to) pos.  There is a danger here;
1182     missing pages or incorrect frame number information in the
1183     bitstream could make our task impossible.  Account for that (it
1184     would be an error condition) */
1185
1186  /* new search algorithm by HB (Nicholas Vinen) */
1187  {
1188    ogg_int64_t end=vf->offsets[link+1];
1189    ogg_int64_t begin=vf->offsets[link];
1190    ogg_int64_t begintime = vf->pcmlengths[link*2];
1191    ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1192    ogg_int64_t target=pos-total+begintime;
1193    ogg_int64_t best=begin;
1194
1195    while(begin<end){
1196      ogg_int64_t bisect;
1197
1198      if(end-begin<CHUNKSIZE){
1199	bisect=begin;
1200      }else{
1201	/* take a (pretty decent) guess. */
1202	bisect=begin +
1203	  (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1204	if(bisect<=begin)
1205	  bisect=begin+1;
1206      }
1207
1208      _seek_helper(vf,bisect);
1209
1210      while(begin<end){
1211	result=_get_next_page(vf,&og,end-vf->offset);
1212	if(result==OV_EREAD) goto seek_error;
1213	if(result<0){
1214	  if(bisect<=begin+1)
1215	    end=begin; /* found it */
1216	  else{
1217	    if(bisect==0) goto seek_error;
1218	    bisect-=CHUNKSIZE;
1219	    if(bisect<=begin)bisect=begin+1;
1220	    _seek_helper(vf,bisect);
1221	  }
1222	}else{
1223	  ogg_int64_t granulepos=ogg_page_granulepos(&og);
1224	  if(granulepos==-1)continue;
1225	  if(granulepos<target){
1226	    best=result;  /* raw offset of packet with granulepos */
1227	    begin=vf->offset; /* raw offset of next page */
1228	    begintime=granulepos;
1229
1230	    if(target-begintime>44100)break;
1231	    bisect=begin; /* *not* begin + 1 */
1232	  }else{
1233	    if(bisect<=begin+1)
1234	      end=begin;  /* found it */
1235	    else{
1236	      if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1237		end=result;
1238		bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1239		if(bisect<=begin)bisect=begin+1;
1240		_seek_helper(vf,bisect);
1241	      }else{
1242		end=result;
1243		endtime=granulepos;
1244		break;
1245	      }
1246	    }
1247	  }
1248	}
1249      }
1250    }
1251
1252    /* found our page. seek to it, update pcm offset. Easier case than
1253       raw_seek, don't keep packets preceeding granulepos. */
1254    {
1255
1256      /* seek */
1257      _seek_helper(vf,best);
1258      vf->pcm_offset=-1;
1259
1260      if(_get_next_page(vf,&og,-1)<0){
1261	ogg_page_release(&og);
1262	return OV_EOF; /* shouldn't happen */
1263      }
1264
1265      ogg_stream_pagein(vf->os,&og);
1266
1267      /* pull out all but last packet; the one with granulepos */
1268      while(1){
1269	result=ogg_stream_packetpeek(vf->os,&op);
1270	if(result==0){
1271	  /* !!! the packet finishing this page originated on a
1272             preceeding page. Keep fetching previous pages until we
1273             get one with a granulepos or without the 'continued' flag
1274             set.  Then just use raw_seek for simplicity. */
1275
1276	  _seek_helper(vf,best);
1277
1278	  while(1){
1279	    result=_get_prev_page(vf,&og);
1280	    if(result<0) goto seek_error;
1281	    if(ogg_page_granulepos(&og)>-1 ||
1282	       !ogg_page_continued(&og)){
1283	      return ov_raw_seek(vf,result);
1284	    }
1285	    vf->offset=result;
1286	  }
1287	}
1288	if(result<0){
1289	  result = OV_EBADPACKET;
1290	  goto seek_error;
1291	}
1292	if(op.granulepos!=-1){
1293	  vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1294	  if(vf->pcm_offset<0)vf->pcm_offset=0;
1295	  vf->pcm_offset+=total;
1296	  break;
1297	}else
1298	  result=ogg_stream_packetout(vf->os,NULL);
1299      }
1300    }
1301  }
1302
1303  /* verify result */
1304  if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1305    result=OV_EFAULT;
1306    goto seek_error;
1307  }
1308  vf->bittrack=0;
1309  vf->samptrack=0;
1310
1311  ogg_page_release(&og);
1312  ogg_packet_release(&op);
1313  return 0;
1314
1315 seek_error:
1316
1317  ogg_page_release(&og);
1318  ogg_packet_release(&op);
1319
1320  /* dump machine so we're in a known state */
1321  vf->pcm_offset=-1;
1322  _decode_clear(vf);
1323  return (int)result;
1324}
1325
1326/* seek to a sample offset relative to the decompressed pcm stream
1327   returns zero on success, nonzero on failure */
1328
1329int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1330  ogg_packet op={0,0,0,0,0,0};
1331  ogg_page og={0,0,0,0};
1332  int thisblock,lastblock=0;
1333  int ret=ov_pcm_seek_page(vf,pos);
1334  if(ret<0)return ret;
1335  if(_make_decode_ready(vf))return OV_EBADLINK;
1336
1337  /* discard leading packets we don't need for the lapping of the
1338     position we want; don't decode them */
1339
1340  while(1){
1341
1342    int ret=ogg_stream_packetpeek(vf->os,&op);
1343    if(ret>0){
1344      thisblock=vorbis_packet_blocksize(&vf->vi,&op);
1345      if(thisblock<0){
1346	ogg_stream_packetout(vf->os,NULL);
1347	continue; /* non audio packet */
1348      }
1349      if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1350
1351      if(vf->pcm_offset+((thisblock+
1352			  vorbis_info_blocksize(&vf->vi,1))>>2)>=pos)break;
1353
1354      /* remove the packet from packet queue and track its granulepos */
1355      ogg_stream_packetout(vf->os,NULL);
1356      vorbis_dsp_synthesis(vf->vd,&op,0);  /* set up a vb with
1357					      only tracking, no
1358					      pcm_decode */
1359
1360      /* end of logical stream case is hard, especially with exact
1361	 length positioning. */
1362
1363      if(op.granulepos>-1){
1364	int i;
1365	/* always believe the stream markers */
1366	vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1367	if(vf->pcm_offset<0)vf->pcm_offset=0;
1368	for(i=0;i<vf->current_link;i++)
1369	  vf->pcm_offset+=vf->pcmlengths[i*2+1];
1370      }
1371
1372      lastblock=thisblock;
1373
1374    }else{
1375      if(ret<0 && ret!=OV_HOLE)break;
1376
1377      /* suck in a new page */
1378      if(_get_next_page(vf,&og,-1)<0)break;
1379      if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1380
1381      if(vf->ready_state<STREAMSET){
1382	int link,ret;
1383
1384	vf->current_serialno=ogg_page_serialno(&og);
1385	for(link=0;link<vf->links;link++)
1386	  if(vf->serialnos[link]==vf->current_serialno)break;
1387	if(link==vf->links){
1388	  ogg_page_release(&og);
1389	  ogg_packet_release(&op);
1390	  return OV_EBADLINK;
1391	}
1392
1393
1394	vf->current_link=link;
1395	ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
1396	if(ret) return ret;
1397	if(_make_decode_ready(vf))return OV_EBADLINK;
1398	lastblock=0;
1399      }
1400
1401      ogg_stream_pagein(vf->os,&og);
1402    }
1403  }
1404
1405  vf->bittrack=0;
1406  vf->samptrack=0;
1407  /* discard samples until we reach the desired position. Crossing a
1408     logical bitstream boundary with abandon is OK. */
1409  while(vf->pcm_offset<pos){
1410    ogg_int64_t target=pos-vf->pcm_offset;
1411    long samples=vorbis_dsp_pcmout(vf->vd,NULL,0);
1412
1413    if(samples>target)samples=(long)target;
1414    vorbis_dsp_read(vf->vd,samples);
1415    vf->pcm_offset+=samples;
1416
1417    if(samples<target)
1418      if(_fetch_and_process_packet(vf,1,1)<=0)
1419	vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1420  }
1421
1422  ogg_page_release(&og);
1423  ogg_packet_release(&op);
1424  return 0;
1425}
1426
1427/* seek to a playback time relative to the decompressed pcm stream
1428   returns zero on success, nonzero on failure */
1429int ov_time_seek(OggVorbis_File *vf,ogg_int64_t milliseconds){
1430  /* translate time to PCM position and call ov_pcm_seek */
1431
1432  int link=-1;
1433  ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1434  ogg_int64_t time_total=ov_time_total(vf,-1);
1435
1436  if(vf->ready_state<OPENED)return OV_EINVAL;
1437  if(!vf->seekable)return OV_ENOSEEK;
1438  if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
1439
1440  /* which bitstream section does this time offset occur in? */
1441  for(link=vf->links-1;link>=0;link--){
1442    pcm_total-=vf->pcmlengths[link*2+1];
1443    time_total-=ov_time_total(vf,link);
1444    if(milliseconds>=time_total)break;
1445  }
1446
1447  /* enough information to convert time offset to pcm offset */
1448  {
1449    int ret=_set_link_number(vf,link);
1450    if(ret)return ret;
1451    return
1452      ov_pcm_seek(vf,pcm_total+(milliseconds-time_total)*
1453		  vf->vi.rate/1000);
1454  }
1455}
1456
1457/* page-granularity version of ov_time_seek
1458   returns zero on success, nonzero on failure */
1459int ov_time_seek_page(OggVorbis_File *vf,ogg_int64_t milliseconds){
1460  /* translate time to PCM position and call ov_pcm_seek */
1461
1462  int link=-1;
1463  ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1464  ogg_int64_t time_total=ov_time_total(vf,-1);
1465
1466  if(vf->ready_state<OPENED)return OV_EINVAL;
1467  if(!vf->seekable)return OV_ENOSEEK;
1468  if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
1469
1470  /* which bitstream section does this time offset occur in? */
1471  for(link=vf->links-1;link>=0;link--){
1472    pcm_total-=vf->pcmlengths[link*2+1];
1473    time_total-=ov_time_total(vf,link);
1474    if(milliseconds>=time_total)break;
1475  }
1476
1477  /* enough information to convert time offset to pcm offset */
1478  {
1479    int ret=_set_link_number(vf,link);
1480    if(ret)return ret;
1481    return
1482      ov_pcm_seek_page(vf,pcm_total+(milliseconds-time_total)*
1483		       vf->vi.rate/1000);
1484  }
1485}
1486
1487/* tell the current stream offset cursor.  Note that seek followed by
1488   tell will likely not give the set offset due to caching */
1489ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1490  if(vf->ready_state<OPENED)return OV_EINVAL;
1491  return vf->offset;
1492}
1493
1494/* return PCM offset (sample) of next PCM sample to be read */
1495ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1496  if(vf->ready_state<OPENED)return OV_EINVAL;
1497  return vf->pcm_offset;
1498}
1499
1500/* return time offset (milliseconds) of next PCM sample to be read */
1501ogg_int64_t ov_time_tell(OggVorbis_File *vf){
1502  int link=0;
1503  ogg_int64_t pcm_total=0;
1504  ogg_int64_t time_total=0;
1505
1506  if(vf->ready_state<OPENED)return OV_EINVAL;
1507  if(vf->seekable){
1508    pcm_total=ov_pcm_total(vf,-1);
1509    time_total=ov_time_total(vf,-1);
1510
1511    /* which bitstream section does this time offset occur in? */
1512    for(link=vf->links-1;link>=0;link--){
1513      pcm_total-=vf->pcmlengths[link*2+1];
1514      time_total-=ov_time_total(vf,link);
1515      if(vf->pcm_offset>=pcm_total)break;
1516    }
1517  }
1518
1519  return time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi.rate;
1520}
1521
1522/*  link:   -1) return the vorbis_info struct for the bitstream section
1523                currently being decoded
1524           0-n) to request information for a specific bitstream section
1525
1526    In the case of a non-seekable bitstream, any call returns the
1527    current bitstream.  NULL in the case that the machine is not
1528    initialized */
1529
1530vorbis_info *ov_info(OggVorbis_File *vf,int link){
1531  if(vf->seekable){
1532    if(link>=vf->links)return NULL;
1533    if(link>=0){
1534      int ret=_set_link_number_preserve_pos(vf,link);
1535      if(ret)return NULL;
1536    }
1537  }
1538  return &vf->vi;
1539}
1540
1541/* grr, strong typing, grr, no templates/inheritence, grr */
1542vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1543  if(vf->seekable){
1544    if(link>=vf->links)return NULL;
1545    if(link>=0){
1546      int ret=_set_link_number_preserve_pos(vf,link);
1547      if(ret)return NULL;
1548    }
1549  }
1550  return &vf->vc;
1551}
1552
1553/* up to this point, everything could more or less hide the multiple
1554   logical bitstream nature of chaining from the toplevel application
1555   if the toplevel application didn't particularly care.  However, at
1556   the point that we actually read audio back, the multiple-section
1557   nature must surface: Multiple bitstream sections do not necessarily
1558   have to have the same number of channels or sampling rate.
1559
1560   ov_read returns the sequential logical bitstream number currently
1561   being decoded along with the PCM data in order that the toplevel
1562   application can take action on channel/sample rate changes.  This
1563   number will be incremented even for streamed (non-seekable) streams
1564   (for seekable streams, it represents the actual logical bitstream
1565   index within the physical bitstream.  Note that the accessor
1566   functions above are aware of this dichotomy).
1567
1568   input values: buffer) a buffer to hold packed PCM data for return
1569		 length) the byte length requested to be placed into buffer
1570
1571   return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1572                   0) EOF
1573		   n) number of bytes of PCM actually returned.  The
1574		   below works on a packet-by-packet basis, so the
1575		   return length is not related to the 'length' passed
1576		   in, just guaranteed to fit.
1577
1578	    *section) set to the logical bitstream number */
1579
1580long ov_read(OggVorbis_File *vf,void *buffer,int bytes_req,int *bitstream){
1581
1582  long samples;
1583  long channels;
1584
1585  if(vf->ready_state<OPENED)return OV_EINVAL;
1586
1587  while(1){
1588    if(vf->ready_state==INITSET){
1589      channels=vf->vi.channels;
1590      samples=vorbis_dsp_pcmout(vf->vd,buffer,(bytes_req>>1)/channels);
1591      if(samples){
1592	if(samples>0){
1593	  vorbis_dsp_read(vf->vd,samples);
1594	  vf->pcm_offset+=samples;
1595	  if(bitstream)*bitstream=vf->current_link;
1596	  return samples*2*channels;
1597	}
1598	return samples;
1599      }
1600    }
1601
1602    /* suck in another packet */
1603    {
1604      int ret=_fetch_and_process_packet(vf,1,1);
1605      if(ret==OV_EOF)
1606	return 0;
1607      if(ret<=0)
1608	return ret;
1609    }
1610
1611  }
1612}
1613