gcc 3.x was miscompiling this function at -O2 and above. Rearrange things
[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.64 2002/10/26 13:37:03 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;
404   ogg_int64_t dataoffset=vf->offset, end;
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     float br;
786     for(i=0;i<vf->links;i++)
787       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
788     /* This once read: return(rint(bits/ov_time_total(vf,-1)));
789      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
790      * so this is slightly transformed to make it work.
791      */
792     br = bits/ov_time_total(vf,-1);
793     return(rint(br));
794   }else{
795     if(vf->seekable){
796       /* return the actual bitrate */
797       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
798     }else{
799       /* return nominal if set */
800       if(vf->vi[i].bitrate_nominal>0){
801         return vf->vi[i].bitrate_nominal;
802       }else{
803         if(vf->vi[i].bitrate_upper>0){
804           if(vf->vi[i].bitrate_lower>0){
805             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
806           }else{
807             return vf->vi[i].bitrate_upper;
808           }
809         }
810         return(OV_FALSE);
811       }
812     }
813   }
814 }
815
816 /* returns the actual bitrate since last call.  returns -1 if no
817    additional data to offer since last call (or at beginning of stream),
818    EINVAL if stream is only partially open 
819 */
820 long ov_bitrate_instant(OggVorbis_File *vf){
821   int link=(vf->seekable?vf->current_link:0);
822   long ret;
823   if(vf->ready_state<OPENED)return(OV_EINVAL);
824   if(vf->samptrack==0)return(OV_FALSE);
825   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
826   vf->bittrack=0.f;
827   vf->samptrack=0.f;
828   return(ret);
829 }
830
831 /* Guess */
832 long ov_serialnumber(OggVorbis_File *vf,int i){
833   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
834   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
835   if(i<0){
836     return(vf->current_serialno);
837   }else{
838     return(vf->serialnos[i]);
839   }
840 }
841
842 /* returns: total raw (compressed) length of content if i==-1
843             raw (compressed) length of that logical bitstream for i==0 to n
844             OV_EINVAL if the stream is not seekable (we can't know the length)
845             or if stream is only partially open
846 */
847 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
848   if(vf->ready_state<OPENED)return(OV_EINVAL);
849   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
850   if(i<0){
851     ogg_int64_t acc=0;
852     int i;
853     for(i=0;i<vf->links;i++)
854       acc+=ov_raw_total(vf,i);
855     return(acc);
856   }else{
857     return(vf->offsets[i+1]-vf->offsets[i]);
858   }
859 }
860
861 /* returns: total PCM length (samples) of content if i==-1 PCM length
862             (samples) of that logical bitstream for i==0 to n
863             OV_EINVAL if the stream is not seekable (we can't know the
864             length) or only partially open 
865 */
866 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
867   if(vf->ready_state<OPENED)return(OV_EINVAL);
868   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
869   if(i<0){
870     ogg_int64_t acc=0;
871     int i;
872     for(i=0;i<vf->links;i++)
873       acc+=ov_pcm_total(vf,i);
874     return(acc);
875   }else{
876     return(vf->pcmlengths[i*2+1]);
877   }
878 }
879
880 /* returns: total seconds of content if i==-1
881             seconds in that logical bitstream for i==0 to n
882             OV_EINVAL if the stream is not seekable (we can't know the
883             length) or only partially open 
884 */
885 double ov_time_total(OggVorbis_File *vf,int i){
886   if(vf->ready_state<OPENED)return(OV_EINVAL);
887   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
888   if(i<0){
889     double acc=0;
890     int i;
891     for(i=0;i<vf->links;i++)
892       acc+=ov_time_total(vf,i);
893     return(acc);
894   }else{
895     return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
896   }
897 }
898
899 /* seek to an offset relative to the *compressed* data. This also
900    scans packets to update the PCM cursor. It will cross a logical
901    bitstream boundary, but only if it can't get any packets out of the
902    tail of the bitstream we seek to (so no surprises).
903
904    returns zero on success, nonzero on failure */
905
906 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
907   ogg_stream_state work_os;
908
909   if(vf->ready_state<OPENED)return(OV_EINVAL);
910   if(!vf->seekable)
911     return(OV_ENOSEEK); /* don't dump machine if we can't seek */
912
913   if(pos<0 || pos>vf->end)return(OV_EINVAL);
914
915   /* clear out decoding machine state */
916   vf->pcm_offset=-1;
917   _decode_clear(vf);
918   
919   _seek_helper(vf,pos);
920
921   /* we need to make sure the pcm_offset is set, but we don't want to
922      advance the raw cursor past good packets just to get to the first
923      with a granulepos.  That's not equivalent behavior to beginning
924      decoding as immediately after the seek position as possible.
925
926      So, a hack.  We use two stream states; a local scratch state and
927      a the shared vf->os stream state.  We use the local state to
928      scan, and the shared state as a buffer for later decode. 
929
930      Unfortuantely, on the last page we still advance to last packet
931      because the granulepos on the last page is not necessarily on a
932      packet boundary, and we need to make sure the granpos is
933      correct. 
934   */
935
936   {
937     ogg_page og;
938     ogg_packet op;
939     int lastblock=0;
940     int accblock=0;
941     int thisblock;
942     int eosflag;
943
944     ogg_stream_init(&work_os,-1); /* get the memory ready */
945
946     while(1){
947       if(vf->ready_state==STREAMSET){
948         /* snarf/scan a packet if we can */
949         int result=ogg_stream_packetout(&work_os,&op);
950       
951         if(result>0){
952
953           if(vf->vi[vf->current_link].codec_setup)
954             thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
955           if(eosflag)
956             ogg_stream_packetout(&vf->os,NULL);
957           else
958             if(lastblock)accblock+=(lastblock+thisblock)>>2;
959
960           if(op.granulepos!=-1){
961             int i,link=vf->current_link;
962             ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
963             if(granulepos<0)granulepos=0;
964             
965             for(i=0;i<link;i++)
966               granulepos+=vf->pcmlengths[i*2+1];
967             vf->pcm_offset=granulepos-accblock;
968             break;
969           }
970           lastblock=thisblock;
971           continue;
972         }
973       }
974       
975       if(!lastblock){
976         if(_get_next_page(vf,&og,-1)<0){
977           vf->pcm_offset=ov_pcm_total(vf,-1);
978           break;
979         }
980       }else{
981         /* huh?  Bogus stream with packets but no granulepos */
982         vf->pcm_offset=-1;
983         break;
984       }
985       
986       /* has our decoding just traversed a bitstream boundary? */
987       if(vf->ready_state==STREAMSET)
988         if(vf->current_serialno!=ogg_page_serialno(&og)){
989         _decode_clear(vf); /* clear out stream state */
990         ogg_stream_clear(&work_os);
991       }
992
993       if(vf->ready_state<STREAMSET){
994         int link;
995         
996         vf->current_serialno=ogg_page_serialno(&og);
997         for(link=0;link<vf->links;link++)
998           if(vf->serialnos[link]==vf->current_serialno)break;
999         if(link==vf->links)goto seek_error; /* sign of a bogus stream.
1000                                                error out, leave
1001                                                machine uninitialized */
1002         vf->current_link=link;
1003         
1004         ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1005         ogg_stream_reset_serialno(&work_os,vf->current_serialno); 
1006         vf->ready_state=STREAMSET;
1007         
1008       }
1009     
1010       ogg_stream_pagein(&vf->os,&og);
1011       ogg_stream_pagein(&work_os,&og);
1012       eosflag=ogg_page_eos(&og);
1013     }
1014   }
1015
1016   ogg_stream_clear(&work_os);
1017   return(0);
1018
1019  seek_error:
1020   /* dump the machine so we're in a known state */
1021   vf->pcm_offset=-1;
1022   ogg_stream_clear(&work_os);
1023   _decode_clear(vf);
1024   return OV_EBADLINK;
1025 }
1026
1027 /* Page granularity seek (faster than sample granularity because we
1028    don't do the last bit of decode to find a specific sample).
1029
1030    Seek to the last [granule marked] page preceeding the specified pos
1031    location, such that decoding past the returned point will quickly
1032    arrive at the requested position. */
1033 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1034   int link=-1;
1035   ogg_int64_t result=0;
1036   ogg_int64_t total=ov_pcm_total(vf,-1);
1037
1038   if(vf->ready_state<OPENED)return(OV_EINVAL);
1039   if(!vf->seekable)return(OV_ENOSEEK);
1040
1041   if(pos<0 || pos>total)return(OV_EINVAL);
1042  
1043   /* which bitstream section does this pcm offset occur in? */
1044   for(link=vf->links-1;link>=0;link--){
1045     total-=vf->pcmlengths[link*2+1];
1046     if(pos>=total)break;
1047   }
1048
1049   /* search within the logical bitstream for the page with the highest
1050      pcm_pos preceeding (or equal to) pos.  There is a danger here;
1051      missing pages or incorrect frame number information in the
1052      bitstream could make our task impossible.  Account for that (it
1053      would be an error condition) */
1054
1055   /* new search algorithm by HB (Nicholas Vinen) */
1056   {
1057     ogg_int64_t end=vf->offsets[link+1];
1058     ogg_int64_t begin=vf->offsets[link];
1059     ogg_int64_t begintime = vf->pcmlengths[link*2];
1060     ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1061     ogg_int64_t target=pos-total+begintime;
1062     ogg_int64_t best=begin;
1063     
1064     ogg_page og;
1065     while(begin<end){
1066       ogg_int64_t bisect;
1067       
1068       if(end-begin<CHUNKSIZE){
1069         bisect=begin;
1070       }else{
1071         /* take a (pretty decent) guess. */
1072         bisect=begin + 
1073           (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1074         if(bisect<=begin)
1075           bisect=begin+1;
1076       }
1077       
1078       _seek_helper(vf,bisect);
1079     
1080       while(begin<end){
1081         result=_get_next_page(vf,&og,end-vf->offset);
1082         if(result==OV_EREAD) goto seek_error;
1083         if(result<0){
1084           if(bisect<=begin+1)
1085             end=begin; /* found it */
1086           else{
1087             if(bisect==0) goto seek_error;
1088             bisect-=CHUNKSIZE;
1089             if(bisect<=begin)bisect=begin+1;
1090             _seek_helper(vf,bisect);
1091           }
1092         }else{
1093           ogg_int64_t granulepos=ogg_page_granulepos(&og);
1094           if(granulepos==-1)continue;
1095           if(granulepos<target){
1096             best=result;  /* raw offset of packet with granulepos */ 
1097             begin=vf->offset; /* raw offset of next page */
1098             begintime=granulepos;
1099             
1100             if(target-begintime>44100)break;
1101             bisect=begin; /* *not* begin + 1 */
1102           }else{
1103             if(bisect<=begin+1)
1104               end=begin;  /* found it */
1105             else{
1106               if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1107                 end=result;
1108                 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1109                 if(bisect<=begin)bisect=begin+1;
1110                 _seek_helper(vf,bisect);
1111               }else{
1112                 end=result;
1113                 endtime=granulepos;
1114                 break;
1115               }
1116             }
1117           }
1118         }
1119       }
1120     }
1121
1122     /* found our page. seek to it, update pcm offset. Easier case than
1123        raw_seek, don't keep packets preceeding granulepos. */
1124     {
1125       ogg_page og;
1126       ogg_packet op;
1127       /* clear out decoding machine state */
1128       _decode_clear(vf);  
1129       /* seek */
1130       _seek_helper(vf,best);
1131       
1132       if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1133       vf->current_serialno=ogg_page_serialno(&og);
1134       vf->current_link=link;
1135       
1136       ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1137       vf->ready_state=STREAMSET;
1138       ogg_stream_pagein(&vf->os,&og);
1139
1140       /* pull out all but last packet; the one with granulepos */
1141       while(1){
1142         result=ogg_stream_packetpeek(&vf->os,&op);
1143         if(result==0){
1144           /* !!! the packet finishing this page originated on a
1145              preceeding page. Keep fetching previous pages until we
1146              get one with a granulepos or without the 'continued' flag
1147              set.  Then just use raw_seek for simplicity. */
1148
1149           _decode_clear(vf);  
1150           _seek_helper(vf,best);
1151
1152           while(1){
1153             result=_get_prev_page(vf,&og);
1154             if(result<0) goto seek_error;
1155             if(ogg_page_granulepos(&og)>-1 ||
1156                !ogg_page_continued(&og)){
1157               return ov_raw_seek(vf,result);
1158             }
1159             vf->offset=result;
1160           }
1161         }
1162         if(result<0){
1163       result = OV_EBADPACKET; 
1164       goto seek_error;
1165     }
1166         if(op.granulepos!=-1){
1167           vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1168           if(vf->pcm_offset<0)vf->pcm_offset=0;
1169           vf->pcm_offset+=total;
1170           break;
1171         }else
1172           result=ogg_stream_packetout(&vf->os,NULL);
1173       }
1174     }
1175   }
1176   
1177   /* verify result */
1178   if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1179     result=OV_EFAULT;
1180     goto seek_error;
1181   }
1182   return(0);
1183   
1184  seek_error:
1185   /* dump machine so we're in a known state */
1186   vf->pcm_offset=-1;
1187   _decode_clear(vf);
1188   return (int)result;
1189 }
1190
1191 /* seek to a sample offset relative to the decompressed pcm stream 
1192    returns zero on success, nonzero on failure */
1193
1194 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1195   int thisblock,lastblock=0;
1196   int ret=ov_pcm_seek_page(vf,pos);
1197   if(ret<0)return(ret);
1198   _make_decode_ready(vf);
1199
1200   /* discard leading packets we don't need for the lapping of the
1201      position we want; don't decode them */
1202
1203   while(1){
1204     ogg_packet op;
1205     ogg_page og;
1206
1207     int ret=ogg_stream_packetpeek(&vf->os,&op);
1208     if(ret>0){
1209       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1210       if(thisblock<0)thisblock=0; /* non audio packet */
1211       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1212       
1213       if(vf->pcm_offset+((thisblock+
1214                           vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1215       
1216       /* remove the packet from packet queue and track its granulepos */
1217       ogg_stream_packetout(&vf->os,NULL);
1218       vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
1219                                                    only tracking, no
1220                                                    pcm_decode */
1221       vorbis_synthesis_blockin(&vf->vd,&vf->vb); 
1222       
1223       /* end of logical stream case is hard, especially with exact
1224          length positioning. */
1225       
1226       if(op.granulepos>-1){
1227         int i;
1228         /* always believe the stream markers */
1229         vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1230         if(vf->pcm_offset<0)vf->pcm_offset=0;
1231         for(i=0;i<vf->current_link;i++)
1232           vf->pcm_offset+=vf->pcmlengths[i*2+1];
1233       }
1234         
1235       lastblock=thisblock;
1236       
1237     }else{
1238       if(ret<0 && ret!=OV_HOLE)break;
1239       
1240       /* suck in a new page */
1241       if(_get_next_page(vf,&og,-1)<0)break;
1242       if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1243       
1244       if(vf->ready_state<STREAMSET){
1245         int link;
1246         
1247         vf->current_serialno=ogg_page_serialno(&og);
1248         for(link=0;link<vf->links;link++)
1249           if(vf->serialnos[link]==vf->current_serialno)break;
1250         if(link==vf->links)return(OV_EBADLINK);
1251         vf->current_link=link;
1252         
1253         ogg_stream_reset_serialno(&vf->os,vf->current_serialno); 
1254         vf->ready_state=STREAMSET;      
1255         _make_decode_ready(vf);
1256         lastblock=0;
1257       }
1258
1259       ogg_stream_pagein(&vf->os,&og);
1260     }
1261   }
1262
1263   /* discard samples until we reach the desired position. Crossing a
1264      logical bitstream boundary with abandon is OK. */
1265   while(vf->pcm_offset<pos){
1266     float **pcm;
1267     ogg_int64_t target=pos-vf->pcm_offset;
1268     long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1269
1270     if(samples>target)samples=target;
1271     vorbis_synthesis_read(&vf->vd,samples);
1272     vf->pcm_offset+=samples;
1273     
1274     if(samples<target)
1275       if(_fetch_and_process_packet(vf,NULL,1)<=0)
1276         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1277   }
1278   return 0;
1279 }
1280
1281 /* seek to a playback time relative to the decompressed pcm stream 
1282    returns zero on success, nonzero on failure */
1283 int ov_time_seek(OggVorbis_File *vf,double seconds){
1284   /* translate time to PCM position and call ov_pcm_seek */
1285
1286   int link=-1;
1287   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1288   double time_total=ov_time_total(vf,-1);
1289
1290   if(vf->ready_state<OPENED)return(OV_EINVAL);
1291   if(!vf->seekable)return(OV_ENOSEEK);
1292   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1293   
1294   /* which bitstream section does this time offset occur in? */
1295   for(link=vf->links-1;link>=0;link--){
1296     pcm_total-=vf->pcmlengths[link*2+1];
1297     time_total-=ov_time_total(vf,link);
1298     if(seconds>=time_total)break;
1299   }
1300
1301   /* enough information to convert time offset to pcm offset */
1302   {
1303     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1304     return(ov_pcm_seek(vf,target));
1305   }
1306 }
1307
1308 /* page-granularity version of ov_time_seek 
1309    returns zero on success, nonzero on failure */
1310 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1311   /* translate time to PCM position and call ov_pcm_seek */
1312
1313   int link=-1;
1314   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1315   double time_total=ov_time_total(vf,-1);
1316
1317   if(vf->ready_state<OPENED)return(OV_EINVAL);
1318   if(!vf->seekable)return(OV_ENOSEEK);
1319   if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1320   
1321   /* which bitstream section does this time offset occur in? */
1322   for(link=vf->links-1;link>=0;link--){
1323     pcm_total-=vf->pcmlengths[link*2+1];
1324     time_total-=ov_time_total(vf,link);
1325     if(seconds>=time_total)break;
1326   }
1327
1328   /* enough information to convert time offset to pcm offset */
1329   {
1330     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1331     return(ov_pcm_seek_page(vf,target));
1332   }
1333 }
1334
1335 /* tell the current stream offset cursor.  Note that seek followed by
1336    tell will likely not give the set offset due to caching */
1337 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1338   if(vf->ready_state<OPENED)return(OV_EINVAL);
1339   return(vf->offset);
1340 }
1341
1342 /* return PCM offset (sample) of next PCM sample to be read */
1343 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1344   if(vf->ready_state<OPENED)return(OV_EINVAL);
1345   return(vf->pcm_offset);
1346 }
1347
1348 /* return time offset (seconds) of next PCM sample to be read */
1349 double ov_time_tell(OggVorbis_File *vf){
1350   int link=0;
1351   ogg_int64_t pcm_total=0;
1352   double time_total=0.f;
1353   
1354   if(vf->ready_state<OPENED)return(OV_EINVAL);
1355   if(vf->seekable){
1356     pcm_total=ov_pcm_total(vf,-1);
1357     time_total=ov_time_total(vf,-1);
1358   
1359     /* which bitstream section does this time offset occur in? */
1360     for(link=vf->links-1;link>=0;link--){
1361       pcm_total-=vf->pcmlengths[link*2+1];
1362       time_total-=ov_time_total(vf,link);
1363       if(vf->pcm_offset>=pcm_total)break;
1364     }
1365   }
1366
1367   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1368 }
1369
1370 /*  link:   -1) return the vorbis_info struct for the bitstream section
1371                 currently being decoded
1372            0-n) to request information for a specific bitstream section
1373     
1374     In the case of a non-seekable bitstream, any call returns the
1375     current bitstream.  NULL in the case that the machine is not
1376     initialized */
1377
1378 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1379   if(vf->seekable){
1380     if(link<0)
1381       if(vf->ready_state>=STREAMSET)
1382         return vf->vi+vf->current_link;
1383       else
1384       return vf->vi;
1385     else
1386       if(link>=vf->links)
1387         return NULL;
1388       else
1389         return vf->vi+link;
1390   }else{
1391     return vf->vi;
1392   }
1393 }
1394
1395 /* grr, strong typing, grr, no templates/inheritence, grr */
1396 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1397   if(vf->seekable){
1398     if(link<0)
1399       if(vf->ready_state>=STREAMSET)
1400         return vf->vc+vf->current_link;
1401       else
1402         return vf->vc;
1403     else
1404       if(link>=vf->links)
1405         return NULL;
1406       else
1407         return vf->vc+link;
1408   }else{
1409     return vf->vc;
1410   }
1411 }
1412
1413 static int host_is_big_endian() {
1414   ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1415   unsigned char *bytewise = (unsigned char *)&pattern;
1416   if (bytewise[0] == 0xfe) return 1;
1417   return 0;
1418 }
1419
1420 /* up to this point, everything could more or less hide the multiple
1421    logical bitstream nature of chaining from the toplevel application
1422    if the toplevel application didn't particularly care.  However, at
1423    the point that we actually read audio back, the multiple-section
1424    nature must surface: Multiple bitstream sections do not necessarily
1425    have to have the same number of channels or sampling rate.
1426
1427    ov_read returns the sequential logical bitstream number currently
1428    being decoded along with the PCM data in order that the toplevel
1429    application can take action on channel/sample rate changes.  This
1430    number will be incremented even for streamed (non-seekable) streams
1431    (for seekable streams, it represents the actual logical bitstream
1432    index within the physical bitstream.  Note that the accessor
1433    functions above are aware of this dichotomy).
1434
1435    input values: buffer) a buffer to hold packed PCM data for return
1436                  length) the byte length requested to be placed into buffer
1437                  bigendianp) should the data be packed LSB first (0) or
1438                              MSB first (1)
1439                  word) word size for output.  currently 1 (byte) or 
1440                        2 (16 bit short)
1441
1442    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1443                    0) EOF
1444                    n) number of bytes of PCM actually returned.  The
1445                    below works on a packet-by-packet basis, so the
1446                    return length is not related to the 'length' passed
1447                    in, just guaranteed to fit.
1448
1449             *section) set to the logical bitstream number */
1450
1451 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1452                     int bigendianp,int word,int sgned,int *bitstream){
1453   int i,j;
1454   int host_endian = host_is_big_endian();
1455
1456   float **pcm;
1457   long samples;
1458
1459   if(vf->ready_state<OPENED)return(OV_EINVAL);
1460
1461   while(1){
1462     if(vf->ready_state>=STREAMSET){
1463       samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1464       if(samples)break;
1465     }
1466
1467     /* suck in another packet */
1468     {
1469       int ret=_fetch_and_process_packet(vf,NULL,1);
1470       if(ret==OV_EOF)return(0);
1471       if(ret<=0)return(ret);
1472     }
1473
1474   }
1475
1476   if(samples>0){
1477   
1478     /* yay! proceed to pack data into the byte buffer */
1479     
1480     long channels=ov_info(vf,-1)->channels;
1481     long bytespersample=word * channels;
1482     vorbis_fpu_control fpu;
1483     if(samples>length/bytespersample)samples=length/bytespersample;
1484
1485     if(samples <= 0)
1486       return OV_EINVAL;
1487     
1488     /* a tight loop to pack each size */
1489     {
1490       int val;
1491       if(word==1){
1492         int off=(sgned?0:128);
1493         vorbis_fpu_setround(&fpu);
1494         for(j=0;j<samples;j++)
1495           for(i=0;i<channels;i++){
1496             val=vorbis_ftoi(pcm[i][j]*128.f);
1497             if(val>127)val=127;
1498             else if(val<-128)val=-128;
1499             *buffer++=val+off;
1500           }
1501         vorbis_fpu_restore(fpu);
1502       }else{
1503         int off=(sgned?0:32768);
1504         
1505         if(host_endian==bigendianp){
1506           if(sgned){
1507             
1508             vorbis_fpu_setround(&fpu);
1509             for(i=0;i<channels;i++) { /* It's faster in this order */
1510               float *src=pcm[i];
1511               short *dest=((short *)buffer)+i;
1512               for(j=0;j<samples;j++) {
1513                 val=vorbis_ftoi(src[j]*32768.f);
1514                 if(val>32767)val=32767;
1515                 else if(val<-32768)val=-32768;
1516                 *dest=val;
1517                 dest+=channels;
1518               }
1519             }
1520             vorbis_fpu_restore(fpu);
1521             
1522           }else{
1523             
1524             vorbis_fpu_setround(&fpu);
1525             for(i=0;i<channels;i++) {
1526               float *src=pcm[i];
1527               short *dest=((short *)buffer)+i;
1528               for(j=0;j<samples;j++) {
1529                 val=vorbis_ftoi(src[j]*32768.f);
1530                 if(val>32767)val=32767;
1531                 else if(val<-32768)val=-32768;
1532                 *dest=val+off;
1533                 dest+=channels;
1534               }
1535             }
1536             vorbis_fpu_restore(fpu);
1537             
1538           }
1539         }else if(bigendianp){
1540           
1541           vorbis_fpu_setround(&fpu);
1542           for(j=0;j<samples;j++)
1543             for(i=0;i<channels;i++){
1544               val=vorbis_ftoi(pcm[i][j]*32768.f);
1545               if(val>32767)val=32767;
1546               else if(val<-32768)val=-32768;
1547               val+=off;
1548               *buffer++=(val>>8);
1549               *buffer++=(val&0xff);
1550             }
1551           vorbis_fpu_restore(fpu);
1552           
1553         }else{
1554           int val;
1555           vorbis_fpu_setround(&fpu);
1556           for(j=0;j<samples;j++)
1557             for(i=0;i<channels;i++){
1558               val=vorbis_ftoi(pcm[i][j]*32768.f);
1559               if(val>32767)val=32767;
1560               else if(val<-32768)val=-32768;
1561               val+=off;
1562               *buffer++=(val&0xff);
1563               *buffer++=(val>>8);
1564                 }
1565           vorbis_fpu_restore(fpu);  
1566           
1567         }
1568       }
1569     }
1570     
1571     vorbis_synthesis_read(&vf->vd,samples);
1572     vf->pcm_offset+=samples;
1573     if(bitstream)*bitstream=vf->current_link;
1574     return(samples*bytespersample);
1575   }else{
1576     return(samples);
1577   }
1578 }
1579
1580 /* input values: pcm_channels) a float vector per channel of output
1581                  length) the sample length being read by the app
1582
1583    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1584                    0) EOF
1585                    n) number of samples of PCM actually returned.  The
1586                    below works on a packet-by-packet basis, so the
1587                    return length is not related to the 'length' passed
1588                    in, just guaranteed to fit.
1589
1590             *section) set to the logical bitstream number */
1591
1592
1593
1594 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
1595                    int *bitstream){
1596
1597   if(vf->ready_state<OPENED)return(OV_EINVAL);
1598
1599   while(1){
1600     if(vf->ready_state>=STREAMSET){
1601       float **pcm;
1602       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1603       if(samples){
1604         if(pcm_channels)*pcm_channels=pcm;
1605         if(samples>length)samples=length;
1606         vorbis_synthesis_read(&vf->vd,samples);
1607         vf->pcm_offset+=samples;
1608         if(bitstream)*bitstream=vf->current_link;
1609         return samples;
1610
1611       }
1612     }
1613
1614     /* suck in another packet */
1615     {
1616       int ret=_fetch_and_process_packet(vf,NULL,1);
1617       if(ret==OV_EOF)return(0);
1618       if(ret<=0)return(ret);
1619     }
1620
1621   }
1622 }
1623