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