1559 lines · 68.8 KB · C
RawDownload
/* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009  Josh Coalson * Copyright (C) 2011-2016  Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Xiph.org Foundation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FLAC__STREAM_DECODER_H#define FLAC__STREAM_DECODER_H #include <stdio.h> /* for FILE */#include "export.h"#include "format.h" #ifdef __cplusplusextern "C" {#endif  /** \file include/FLAC/stream_decoder.h * *  \brief *  This module contains the functions which implement the stream *  decoder. * *  See the detailed documentation in the *  \link flac_stream_decoder stream decoder \endlink module. */ /** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces *  \ingroup flac * *  \brief *  This module describes the decoder layers provided by libFLAC. * * The stream decoder can be used to decode complete streams either from * the client via callbacks, or directly from a file, depending on how * it is initialized.  When decoding via callbacks, the client provides * callbacks for reading FLAC data and writing decoded samples, and * handling metadata and errors.  If the client also supplies seek-related * callback, the decoder function for sample-accurate seeking within the * FLAC input is also available.  When decoding from a file, the client * needs only supply a filename or open \c FILE* and write/metadata/error * callbacks; the rest of the callbacks are supplied internally.  For more * info see the \link flac_stream_decoder stream decoder \endlink module. */ /** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface *  \ingroup flac_decoder * *  \brief *  This module contains the functions which implement the stream *  decoder. * * The stream decoder can decode native FLAC, and optionally Ogg FLAC * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. * * The basic usage of this decoder is as follows: * - The program creates an instance of a decoder using *   FLAC__stream_decoder_new(). * - The program overrides the default settings using *   FLAC__stream_decoder_set_*() functions. * - The program initializes the instance to validate the settings and *   prepare for decoding using *   - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() *     or FLAC__stream_decoder_init_file() for native FLAC, *   - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() *     or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC * - The program calls the FLAC__stream_decoder_process_*() functions *   to decode data, which subsequently calls the callbacks. * - The program finishes the decoding with FLAC__stream_decoder_finish(), *   which flushes the input and output and resets the decoder to the *   uninitialized state. * - The instance may be used again or deleted with *   FLAC__stream_decoder_delete(). * * In more detail, the program will create a new instance by calling * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() * functions to override the default decoder options, and call * one of the FLAC__stream_decoder_init_*() functions. * * There are three initialization functions for native FLAC, one for * setting up the decoder to decode FLAC data from the client via * callbacks, and two for decoding directly from a FLAC file. * * For decoding via callbacks, use FLAC__stream_decoder_init_stream(). * You must also supply several callbacks for handling I/O.  Some (like * seeking) are optional, depending on the capabilities of the input. * * For decoding directly from a file, use FLAC__stream_decoder_init_FILE() * or FLAC__stream_decoder_init_file().  Then you must only supply an open * \c FILE* or filename and fewer callbacks; the decoder will handle * the other callbacks internally. * * There are three similarly-named init functions for decoding from Ogg * FLAC streams.  Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the * library has been built with Ogg support. * * Once the decoder is initialized, your program will call one of several * functions to start the decoding process: * * - FLAC__stream_decoder_process_single() - Tells the decoder to process at *   most one metadata block or audio frame and return, calling either the *   metadata callback or write callback, respectively, once.  If the decoder *   loses sync it will return with only the error callback being called. * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder *   to process the stream from the current location and stop upon reaching *   the first audio frame.  The client will get one metadata, write, or error *   callback per metadata block, audio frame, or sync error, respectively. * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder *   to process the stream from the current location until the read callback *   returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or *   FLAC__STREAM_DECODER_READ_STATUS_ABORT.  The client will get one metadata, *   write, or error callback per metadata block, audio frame, or sync error, *   respectively. * * When the decoder has finished decoding (normally or through an abort), * the instance is finished by calling FLAC__stream_decoder_finish(), which * ensures the decoder is in the correct state and frees memory.  Then the * instance may be deleted with FLAC__stream_decoder_delete() or initialized * again to decode another stream. * * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method. * At any point after the stream decoder has been initialized, the client can * call this function to seek to an exact sample within the stream. * Subsequently, the first time the write callback is called it will be * passed a (possibly partial) block starting at that sample. * * If the client cannot seek via the callback interface provided, but still * has another way of seeking, it can flush the decoder using * FLAC__stream_decoder_flush() and start feeding data from the new position * through the read callback. * * The stream decoder also provides MD5 signature checking.  If this is * turned on before initialization, FLAC__stream_decoder_finish() will * report when the decoded MD5 signature does not match the one stored * in the STREAMINFO block.  MD5 checking is automatically turned off * (until the next FLAC__stream_decoder_reset()) if there is no signature * in the STREAMINFO block or when a seek is attempted. * * The FLAC__stream_decoder_set_metadata_*() functions deserve special * attention.  By default, the decoder only calls the metadata_callback for * the STREAMINFO block.  These functions allow you to tell the decoder * explicitly which blocks to parse and return via the metadata_callback * and/or which to skip.  Use a FLAC__stream_decoder_set_metadata_respond_all(), * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify * which blocks to return.  Remember that metadata blocks can potentially * be big (for example, cover art) so filtering out the ones you don't * use can reduce the memory requirements of the decoder.  Also note the * special forms FLAC__stream_decoder_set_metadata_respond_application(id) * and FLAC__stream_decoder_set_metadata_ignore_application(id) for * filtering APPLICATION blocks based on the application ID. * * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but * they still can legally be filtered from the metadata_callback. * * \note * The "set" functions may only be called when the decoder is in the * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but * before FLAC__stream_decoder_init_*().  If this is the case they will * return \c true, otherwise \c false. * * \note * FLAC__stream_decoder_finish() resets all settings to the constructor * defaults, including the callbacks. * * \{ */  /** State values for a FLAC__StreamDecoder * * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). */typedef enum { 	FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0,	/**< The decoder is ready to search for metadata. */ 	FLAC__STREAM_DECODER_READ_METADATA,	/**< The decoder is ready to or is in the process of reading metadata. */ 	FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC,	/**< The decoder is ready to or is in the process of searching for the	 * frame sync code.	 */ 	FLAC__STREAM_DECODER_READ_FRAME,	/**< The decoder is ready to or is in the process of reading a frame. */ 	FLAC__STREAM_DECODER_END_OF_STREAM,	/**< The decoder has reached the end of the stream. */ 	FLAC__STREAM_DECODER_OGG_ERROR,	/**< An error occurred in the underlying Ogg layer.  */ 	FLAC__STREAM_DECODER_SEEK_ERROR,	/**< An error occurred while seeking.  The decoder must be flushed	 * with FLAC__stream_decoder_flush() or reset with	 * FLAC__stream_decoder_reset() before decoding can continue.	 */ 	FLAC__STREAM_DECODER_ABORTED,	/**< The decoder was aborted by the read or write callback. */ 	FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR,	/**< An error occurred allocating memory.  The decoder is in an invalid	 * state and can no longer be used.	 */ 	FLAC__STREAM_DECODER_UNINITIALIZED	/**< The decoder is in the uninitialized state; one of the	 * FLAC__stream_decoder_init_*() functions must be called before samples	 * can be processed.	 */ } FLAC__StreamDecoderState; /** Maps a FLAC__StreamDecoderState to a C string. * *  Using a FLAC__StreamDecoderState as the index to this array *  will give the string equivalent.  The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderStateString[];  /** Possible return values for the FLAC__stream_decoder_init_*() functions. */typedef enum { 	FLAC__STREAM_DECODER_INIT_STATUS_OK = 0,	/**< Initialization was successful. */ 	FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER,	/**< The library was not compiled with support for the given container	 * format.	 */ 	FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS,	/**< A required callback was not supplied. */ 	FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR,	/**< An error occurred allocating memory. */ 	FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE,	/**< fopen() failed in FLAC__stream_decoder_init_file() or	 * FLAC__stream_decoder_init_ogg_file(). */ 	FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED	/**< FLAC__stream_decoder_init_*() was called when the decoder was	 * already initialized, usually because	 * FLAC__stream_decoder_finish() was not called.	 */ } FLAC__StreamDecoderInitStatus; /** Maps a FLAC__StreamDecoderInitStatus to a C string. * *  Using a FLAC__StreamDecoderInitStatus as the index to this array *  will give the string equivalent.  The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[];  /** Return values for the FLAC__StreamDecoder read callback. */typedef enum { 	FLAC__STREAM_DECODER_READ_STATUS_CONTINUE,	/**< The read was OK and decoding can continue. */ 	FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM,	/**< The read was attempted while at the end of the stream.  Note that	 * the client must only return this value when the read callback was	 * called when already at the end of the stream.  Otherwise, if the read	 * itself moves to the end of the stream, the client should still return	 * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on	 * the next read callback it should return	 * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count	 * of \c 0.	 */ 	FLAC__STREAM_DECODER_READ_STATUS_ABORT	/**< An unrecoverable error occurred.  The decoder will return from the process call. */ } FLAC__StreamDecoderReadStatus; /** Maps a FLAC__StreamDecoderReadStatus to a C string. * *  Using a FLAC__StreamDecoderReadStatus as the index to this array *  will give the string equivalent.  The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[];  /** Return values for the FLAC__StreamDecoder seek callback. */typedef enum { 	FLAC__STREAM_DECODER_SEEK_STATUS_OK,	/**< The seek was OK and decoding can continue. */ 	FLAC__STREAM_DECODER_SEEK_STATUS_ERROR,	/**< An unrecoverable error occurred.  The decoder will return from the process call. */ 	FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED	/**< Client does not support seeking. */ } FLAC__StreamDecoderSeekStatus; /** Maps a FLAC__StreamDecoderSeekStatus to a C string. * *  Using a FLAC__StreamDecoderSeekStatus as the index to this array *  will give the string equivalent.  The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[];  /** Return values for the FLAC__StreamDecoder tell callback. */typedef enum { 	FLAC__STREAM_DECODER_TELL_STATUS_OK,	/**< The tell was OK and decoding can continue. */ 	FLAC__STREAM_DECODER_TELL_STATUS_ERROR,	/**< An unrecoverable error occurred.  The decoder will return from the process call. */ 	FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED	/**< Client does not support telling the position. */ } FLAC__StreamDecoderTellStatus; /** Maps a FLAC__StreamDecoderTellStatus to a C string. * *  Using a FLAC__StreamDecoderTellStatus as the index to this array *  will give the string equivalent.  The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[];  /** Return values for the FLAC__StreamDecoder length callback. */typedef enum { 	FLAC__STREAM_DECODER_LENGTH_STATUS_OK,	/**< The length call was OK and decoding can continue. */ 	FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR,	/**< An unrecoverable error occurred.  The decoder will return from the process call. */ 	FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED	/**< Client does not support reporting the length. */ } FLAC__StreamDecoderLengthStatus; /** Maps a FLAC__StreamDecoderLengthStatus to a C string. * *  Using a FLAC__StreamDecoderLengthStatus as the index to this array *  will give the string equivalent.  The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[];  /** Return values for the FLAC__StreamDecoder write callback. */typedef enum { 	FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE,	/**< The write was OK and decoding can continue. */ 	FLAC__STREAM_DECODER_WRITE_STATUS_ABORT	/**< An unrecoverable error occurred.  The decoder will return from the process call. */ } FLAC__StreamDecoderWriteStatus; /** Maps a FLAC__StreamDecoderWriteStatus to a C string. * *  Using a FLAC__StreamDecoderWriteStatus as the index to this array *  will give the string equivalent.  The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[];  /** Possible values passed back to the FLAC__StreamDecoder error callback. *  \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- *  all.  The rest could be caused by bad sync (false synchronization on *  data that is not the start of a frame) or corrupted data.  The error *  itself is the decoder's best guess at what happened assuming a correct *  sync.  For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER *  could be caused by a correct sync on the start of a frame, but some *  data in the frame header was corrupted.  Or it could be the result of *  syncing on a point the stream that looked like the starting of a frame *  but was not.  \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM *  could be because the decoder encountered a valid frame made by a future *  version of the encoder which it cannot parse, or because of a false *  sync making it appear as though an encountered frame was generated by *  a future encoder. */typedef enum { 	FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC,	/**< An error in the stream caused the decoder to lose synchronization. */ 	FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER,	/**< The decoder encountered a corrupted frame header. */ 	FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH,	/**< The frame's data did not match the CRC in the footer. */ 	FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM	/**< The decoder encountered reserved fields in use in the stream. */ } FLAC__StreamDecoderErrorStatus; /** Maps a FLAC__StreamDecoderErrorStatus to a C string. * *  Using a FLAC__StreamDecoderErrorStatus as the index to this array *  will give the string equivalent.  The contents should not be modified. */extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[];  /*********************************************************************** * * class FLAC__StreamDecoder * ***********************************************************************/ struct FLAC__StreamDecoderProtected;struct FLAC__StreamDecoderPrivate;/** The opaque structure definition for the stream decoder type. *  See the \link flac_stream_decoder stream decoder module \endlink *  for a detailed description. */typedef struct {	struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */	struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */} FLAC__StreamDecoder; /** Signature for the read callback. * *  A function pointer matching this signature must be passed to *  FLAC__stream_decoder_init*_stream(). The supplied function will be *  called when the decoder needs more input data.  The address of the *  buffer to be filled is supplied, along with the number of bytes the *  buffer can hold.  The callback may choose to supply less data and *  modify the byte count but must be careful not to overflow the buffer. *  The callback then returns a status code chosen from *  FLAC__StreamDecoderReadStatus. * * Here is an example of a read callback for stdio streams: * \code * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) * { *   FILE *file = ((MyClientData*)client_data)->file; *   if(*bytes > 0) { *     *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); *     if(ferror(file)) *       return FLAC__STREAM_DECODER_READ_STATUS_ABORT; *     else if(*bytes == 0) *       return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; *     else *       return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; *   } *   else *     return FLAC__STREAM_DECODER_READ_STATUS_ABORT; * } * \endcode * * \note In general, FLAC__StreamDecoder functions which change the * state should not be called on the \a decoder while in the callback. *

Lines 1–500 of 1559.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t