1 /*
2 ** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** Copyright (C) 2018 Arthur Taylor <art@ified.ca>
4 **
5 ** This program is free software ; you can redistribute it and/or modify
6 ** it under the terms of the GNU Lesser General Public License as published by
7 ** the Free Software Foundation ; either version 2.1 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY ; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
13 ** GNU Lesser General Public License for more details.
14 **
15 ** You should have received a copy of the GNU Lesser General Public License
16 ** along with this program ; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 
20 #ifndef SF_SRC_OGG_H
21 #define SF_SRC_OGG_H
22 
23 enum
24 {	OGG_ANNODEX = 300,
25 	OGG_ANXDATA,
26 	OGG_FLAC,
27 	OGG_FLAC0,
28 	OGG_PCM,
29 	OGG_SPEEX,
30 	OGG_VORBIS,
31 	OGG_OPUS,
32 } ;
33 
34 typedef struct
35 {	/* Sync and verify incoming physical bitstream */
36 	ogg_sync_state osync ;
37 	/* Take physical pages, weld into a logical stream of packets */
38 	ogg_stream_state ostream ;
39 	/* One Ogg bitstream page. Codec packets are inside */
40 	ogg_page opage ;
41 	/* One raw packet of data for decode */
42 	ogg_packet opacket ;
43 
44 	/* Unpacked packets. 255 is max there can ever be in one page. */
45 	ogg_packet pkt [255] ;
46 	/* How many packets */
47 	int pkt_len ;
48 	/* Current packet */
49 	int pkt_indx ;
50 
51 	int eos ;
52 	int codec ;
53 } OGG_PRIVATE ;
54 
55 
56 #define readint(buf, base) (((buf [base + 3] << 24) & 0xff000000) | \
57 								((buf [base + 2] <<16) & 0xff0000) | \
58 								((buf [base + 1] << 8) & 0xff00) | \
59 								(buf [base] & 0xff))
60 
61 int	ogg_read_first_page	(SF_PRIVATE *, OGG_PRIVATE *) ;
62 
63 /*
64 ** Write the whole Ogg page out. Convenience function as the ogg_page struct
65 ** splits header and body data into separate buffers.
66 */
67 int	ogg_write_page	(SF_PRIVATE *, ogg_page *) ;
68 
69 /*
70 ** Wrapper around psf_ftell() that returns the current offset in the file after
71 ** the most recent page that has been returned by ogg_sync_pageout().
72 */
73 sf_count_t ogg_sync_ftell (SF_PRIVATE *) ;
74 
75 /*
76 ** Wrapper around psf_fseek() that on success resets the ogg_sync_state struct
77 ** so that it doesn't get corrupted.
78 */
79 sf_count_t ogg_sync_fseek (SF_PRIVATE *, sf_count_t offset, int whence) ;
80 
81 /*
82 ** Get the next page from the physical bitstream, reading in data as necessary.
83 ** Pays no attention to Ogg BOS/EOS markers or stream serial numbers.
84 ** The page is buffered in the ogg_sync_state struct, (replacing any other
85 ** buffered there) and also returned in *og. readmax sets a boundary for how
86 ** many bytes more may be read from the file, use already buffered only, or
87 ** unlimited reading in the case of a positive, zero or negative argument
88 ** respectively. If a pointer to a sf_count_t is passed in offset, then it will
89 ** be incremented by how many bytes were skipped to find the next page header.
90 ** (Useful for seeking, normally zero.) Returns the page size in bytes on
91 ** success, 0 on out-of-data (be it end of file or readmax reached) and -1 on
92 ** error with psf->error set appropriately.
93 */
94 int	ogg_sync_next_page (SF_PRIVATE * psf, ogg_page *og, sf_count_t readmax, sf_count_t *offset) ;
95 
96 /*
97 ** Load the last page of a stream before the provided file offset. Searches the
98 ** physical bitstream, and selects a page of the passed serialno. The page
99 ** found is loaded in the sync buffer and exposed in odata->opage, and not
100 ** loaded into the ogg_stream_state. If found, the granulepos is returned in
101 ** *gp_out. Returns the file offset *before* the last page on success, or -1 on
102 ** error, setting psf->error as appropriate.
103 */
104 sf_count_t ogg_sync_last_page_before (SF_PRIVATE *psf, OGG_PRIVATE *odata, uint64_t *gp_out, sf_count_t offset, int32_t serialno) ;
105 
106 /*
107 ** Load the next page from the virtual bitstream, reading data as necessary.
108 ** Reads in pages from the physical bitstream, skipping pages until one of the
109 ** virtual bitstream of interest is found, and then feeds it into the
110 ** ogg_stream_state of odata->ostream, where it is buffered. Heeds EOS markers.
111 ** Returns 1 on success, 0 on end of stream, and -1 on fatal error.
112 */
113 int ogg_stream_next_page (SF_PRIVATE * psf, OGG_PRIVATE *odata) ;
114 
115 /*
116 ** Loads the next page using ogg_stream_next_page() and unpacks all packets
117 ** into the array odata->pkt, updating odata->pkt_len and setting
118 ** odata->pkt_indx to 0. Returns 1 if okay, 2 if okay but a hole was found
119 ** in the bitstream, 0 if on end of stream, and -1 on fatal error.
120 */
121 int ogg_stream_unpack_page (SF_PRIVATE *psf, OGG_PRIVATE *odata) ;
122 
123 /*
124 ** Seek within the Ogg virtual bitstream for a page containing target_gp.
125 ** Preforms a bisection search. If not found exactly, the best result is
126 ** returned in *best_gp. Found page is loaded into the virtual bitstream,
127 ** ready for unpacking. Arguments pcm_start and pcm_end are the highest and
128 ** lowest granule positions of the file. begin and end are the file offsets.
129 */
130 int ogg_stream_seek_page_search (SF_PRIVATE *psf, OGG_PRIVATE *odata,
131 								uint64_t target_gp, uint64_t pcm_start, uint64_t pcm_end,
132 								uint64_t *best_gp, sf_count_t begin, sf_count_t end) ;
133 
134 #endif /* SF_SRC_OGG_H */
135