michael@0: /******************************************************************** michael@0: * * michael@0: * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * michael@0: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * michael@0: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * michael@0: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * michael@0: * * michael@0: * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * michael@0: * by the Xiph.Org Foundation http://www.xiph.org/ * michael@0: * * michael@0: ******************************************************************** michael@0: michael@0: function: michael@0: last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $ michael@0: michael@0: ********************************************************************/ michael@0: michael@0: /**\mainpage michael@0: * michael@0: * \section intro Introduction michael@0: * michael@0: * This is the documentation for libtheora C API. michael@0: * The current reference michael@0: * implementation for Theora, a free, michael@0: * patent-unencumbered video codec. michael@0: * Theora is derived from On2's VP3 codec with additional features and michael@0: * integration with Ogg multimedia formats by michael@0: * the Xiph.Org Foundation. michael@0: * Complete documentation of the format itself is available in michael@0: * the Theora michael@0: * specification. michael@0: * michael@0: * \subsection Organization michael@0: * michael@0: * The functions documented here are actually subdivided into three michael@0: * separate libraries: michael@0: * - libtheoraenc contains the encoder interface, michael@0: * described in \ref encfuncs. michael@0: * - libtheoradec contains the decoder interface and michael@0: * routines shared with the encoder. michael@0: * You must also link to this if you link to libtheoraenc. michael@0: * The routines in this library are described in \ref decfuncs and michael@0: * \ref basefuncs. michael@0: * - libtheora contains the \ref oldfuncs. michael@0: * michael@0: * New code should link to libtheoradec and, if using encoder michael@0: * features, libtheoraenc. Together these two export both michael@0: * the standard and the legacy API, so this is all that is needed by michael@0: * any code. The older libtheora library is provided just for michael@0: * compatibility with older build configurations. michael@0: * michael@0: * In general the recommended 1.x API symbols can be distinguished michael@0: * by their th_ or TH_ namespace prefix. michael@0: * The older, legacy API uses theora_ or OC_ michael@0: * prefixes instead. michael@0: */ michael@0: michael@0: /**\file michael@0: * The shared libtheoradec and libtheoraenc C API. michael@0: * You don't need to include this directly.*/ michael@0: michael@0: #if !defined(_O_THEORA_CODEC_H_) michael@0: # define _O_THEORA_CODEC_H_ (1) michael@0: # include michael@0: michael@0: #if defined(__cplusplus) michael@0: extern "C" { michael@0: #endif michael@0: michael@0: michael@0: michael@0: /**\name Return codes*/ michael@0: /*@{*/ michael@0: /**An invalid pointer was provided.*/ michael@0: #define TH_EFAULT (-1) michael@0: /**An invalid argument was provided.*/ michael@0: #define TH_EINVAL (-10) michael@0: /**The contents of the header were incomplete, invalid, or unexpected.*/ michael@0: #define TH_EBADHEADER (-20) michael@0: /**The header does not belong to a Theora stream.*/ michael@0: #define TH_ENOTFORMAT (-21) michael@0: /**The bitstream version is too high.*/ michael@0: #define TH_EVERSION (-22) michael@0: /**The specified function is not implemented.*/ michael@0: #define TH_EIMPL (-23) michael@0: /**There were errors in the video data packet.*/ michael@0: #define TH_EBADPACKET (-24) michael@0: /**The decoded packet represented a dropped frame. michael@0: The player can continue to display the current frame, as the contents of the michael@0: decoded frame buffer have not changed.*/ michael@0: #define TH_DUPFRAME (1) michael@0: /*@}*/ michael@0: michael@0: /**The currently defined color space tags. michael@0: * See the Theora michael@0: * specification, Chapter 4, for exact details on the meaning michael@0: * of each of these color spaces.*/ michael@0: typedef enum{ michael@0: /**The color space was not specified at the encoder. michael@0: It may be conveyed by an external means.*/ michael@0: TH_CS_UNSPECIFIED, michael@0: /**A color space designed for NTSC content.*/ michael@0: TH_CS_ITU_REC_470M, michael@0: /**A color space designed for PAL/SECAM content.*/ michael@0: TH_CS_ITU_REC_470BG, michael@0: /**The total number of currently defined color spaces.*/ michael@0: TH_CS_NSPACES michael@0: }th_colorspace; michael@0: michael@0: /**The currently defined pixel format tags. michael@0: * See the Theora michael@0: * specification, Section 4.4, for details on the precise sample michael@0: * locations.*/ michael@0: typedef enum{ michael@0: /**Chroma decimation by 2 in both the X and Y directions (4:2:0). michael@0: The Cb and Cr chroma planes are half the width and half the michael@0: height of the luma plane.*/ michael@0: TH_PF_420, michael@0: /**Currently reserved.*/ michael@0: TH_PF_RSVD, michael@0: /**Chroma decimation by 2 in the X direction (4:2:2). michael@0: The Cb and Cr chroma planes are half the width of the luma plane, but full michael@0: height.*/ michael@0: TH_PF_422, michael@0: /**No chroma decimation (4:4:4). michael@0: The Cb and Cr chroma planes are full width and full height.*/ michael@0: TH_PF_444, michael@0: /**The total number of currently defined pixel formats.*/ michael@0: TH_PF_NFORMATS michael@0: }th_pixel_fmt; michael@0: michael@0: michael@0: michael@0: /**A buffer for a single color plane in an uncompressed image. michael@0: * This contains the image data in a left-to-right, top-down format. michael@0: * Each row of pixels is stored contiguously in memory, but successive michael@0: * rows need not be. michael@0: * Use \a stride to compute the offset of the next row. michael@0: * The encoder accepts both positive \a stride values (top-down in memory) michael@0: * and negative (bottom-up in memory). michael@0: * The decoder currently always generates images with positive strides.*/ michael@0: typedef struct{ michael@0: /**The width of this plane.*/ michael@0: int width; michael@0: /**The height of this plane.*/ michael@0: int height; michael@0: /**The offset in bytes between successive rows.*/ michael@0: int stride; michael@0: /**A pointer to the beginning of the first row.*/ michael@0: unsigned char *data; michael@0: }th_img_plane; michael@0: michael@0: /**A complete image buffer for an uncompressed frame. michael@0: * The chroma planes may be decimated by a factor of two in either michael@0: * direction, as indicated by th_info#pixel_fmt. michael@0: * The width and height of the Y' plane must be multiples of 16. michael@0: * They may need to be cropped for display, using the rectangle michael@0: * specified by th_info#pic_x, th_info#pic_y, th_info#pic_width, michael@0: * and th_info#pic_height. michael@0: * All samples are 8 bits. michael@0: * \note The term YUV often used to describe a colorspace is ambiguous. michael@0: * The exact parameters of the RGB to YUV conversion process aside, in michael@0: * many contexts the U and V channels actually have opposite meanings. michael@0: * To avoid this confusion, we are explicit: the name of the color michael@0: * channels are Y'CbCr, and they appear in that order, always. michael@0: * The prime symbol denotes that the Y channel is non-linear. michael@0: * Cb and Cr stand for "Chroma blue" and "Chroma red", respectively.*/ michael@0: typedef th_img_plane th_ycbcr_buffer[3]; michael@0: michael@0: /**Theora bitstream information. michael@0: * This contains the basic playback parameters for a stream, and corresponds to michael@0: * the initial 'info' header packet. michael@0: * To initialize an encoder, the application fills in this structure and michael@0: * passes it to th_encode_alloc(). michael@0: * A default encoding mode is chosen based on the values of the #quality and michael@0: * #target_bitrate fields. michael@0: * On decode, it is filled in by th_decode_headerin(), and then passed to michael@0: * th_decode_alloc(). michael@0: * michael@0: * Encoded Theora frames must be a multiple of 16 in size; michael@0: * this is what the #frame_width and #frame_height members represent. michael@0: * To handle arbitrary picture sizes, a crop rectangle is specified in the michael@0: * #pic_x, #pic_y, #pic_width and #pic_height members. michael@0: * michael@0: * All frame buffers contain pointers to the full, padded frame. michael@0: * However, the current encoder will not reference pixels outside of michael@0: * the cropped picture region, and the application does not need to fill them michael@0: * in. michael@0: * The decoder will allocate storage for a full frame, but the michael@0: * application should not rely on the padding containing sensible michael@0: * data. michael@0: * michael@0: * It is also generally recommended that the offsets and sizes should still be michael@0: * multiples of 2 to avoid chroma sampling shifts when chroma is sub-sampled. michael@0: * See the Theora michael@0: * specification, Section 4.4, for more details. michael@0: * michael@0: * Frame rate, in frames per second, is stored as a rational fraction, as is michael@0: * the pixel aspect ratio. michael@0: * Note that this refers to the aspect ratio of the individual pixels, not of michael@0: * the overall frame itself. michael@0: * The frame aspect ratio can be computed from pixel aspect ratio using the michael@0: * image dimensions.*/ michael@0: typedef struct{ michael@0: /**\name Theora version michael@0: * Bitstream version information.*/ michael@0: /*@{*/ michael@0: unsigned char version_major; michael@0: unsigned char version_minor; michael@0: unsigned char version_subminor; michael@0: /*@}*/ michael@0: /**The encoded frame width. michael@0: * This must be a multiple of 16, and less than 1048576.*/ michael@0: ogg_uint32_t frame_width; michael@0: /**The encoded frame height. michael@0: * This must be a multiple of 16, and less than 1048576.*/ michael@0: ogg_uint32_t frame_height; michael@0: /**The displayed picture width. michael@0: * This must be no larger than width.*/ michael@0: ogg_uint32_t pic_width; michael@0: /**The displayed picture height. michael@0: * This must be no larger than height.*/ michael@0: ogg_uint32_t pic_height; michael@0: /**The X offset of the displayed picture. michael@0: * This must be no larger than #frame_width-#pic_width or 255, whichever is michael@0: * smaller.*/ michael@0: ogg_uint32_t pic_x; michael@0: /**The Y offset of the displayed picture. michael@0: * This must be no larger than #frame_height-#pic_height, and michael@0: * #frame_height-#pic_height-#pic_y must be no larger than 255. michael@0: * This slightly funny restriction is due to the fact that the offset is michael@0: * specified from the top of the image for consistency with the standard michael@0: * graphics left-handed coordinate system used throughout this API, while michael@0: * it is stored in the encoded stream as an offset from the bottom.*/ michael@0: ogg_uint32_t pic_y; michael@0: /**\name Frame rate michael@0: * The frame rate, as a fraction. michael@0: * If either is 0, the frame rate is undefined.*/ michael@0: /*@{*/ michael@0: ogg_uint32_t fps_numerator; michael@0: ogg_uint32_t fps_denominator; michael@0: /*@}*/ michael@0: /**\name Aspect ratio michael@0: * The aspect ratio of the pixels. michael@0: * If either value is zero, the aspect ratio is undefined. michael@0: * If not specified by any external means, 1:1 should be assumed. michael@0: * The aspect ratio of the full picture can be computed as michael@0: * \code michael@0: * aspect_numerator*pic_width/(aspect_denominator*pic_height). michael@0: * \endcode */ michael@0: /*@{*/ michael@0: ogg_uint32_t aspect_numerator; michael@0: ogg_uint32_t aspect_denominator; michael@0: /*@}*/ michael@0: /**The color space.*/ michael@0: th_colorspace colorspace; michael@0: /**The pixel format.*/ michael@0: th_pixel_fmt pixel_fmt; michael@0: /**The target bit-rate in bits per second. michael@0: If initializing an encoder with this struct, set this field to a non-zero michael@0: value to activate CBR encoding by default.*/ michael@0: int target_bitrate; michael@0: /**The target quality level. michael@0: Valid values range from 0 to 63, inclusive, with higher values giving michael@0: higher quality. michael@0: If initializing an encoder with this struct, and #target_bitrate is set michael@0: to zero, VBR encoding at this quality will be activated by default.*/ michael@0: /*Currently this is set so that a qi of 0 corresponds to distortions of 24 michael@0: times the JND, and each increase by 16 halves that value. michael@0: This gives us fine discrimination at low qualities, yet effective rate michael@0: control at high qualities. michael@0: The qi value 63 is special, however. michael@0: For this, the highest quality, we use one half of a JND for our threshold. michael@0: Due to the lower bounds placed on allowable quantizers in Theora, we will michael@0: not actually be able to achieve quality this good, but this should michael@0: provide as close to visually lossless quality as Theora is capable of. michael@0: We could lift the quantizer restrictions without breaking VP3.1 michael@0: compatibility, but this would result in quantized coefficients that are michael@0: too large for the current bitstream to be able to store. michael@0: We'd have to redesign the token syntax to store these large coefficients, michael@0: which would make transcoding complex.*/ michael@0: int quality; michael@0: /**The amount to shift to extract the last keyframe number from the granule michael@0: * position. michael@0: * This can be at most 31. michael@0: * th_info_init() will set this to a default value (currently 6, michael@0: * which is good for streaming applications), but you can set it to 0 to michael@0: * make every frame a keyframe. michael@0: * The maximum distance between key frames is michael@0: * 1<<#keyframe_granule_shift. michael@0: * The keyframe frequency can be more finely controlled with michael@0: * #TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, which can also be adjusted michael@0: * during encoding (for example, to force the next frame to be a keyframe), michael@0: * but it cannot be set larger than the amount permitted by this field after michael@0: * the headers have been output.*/ michael@0: int keyframe_granule_shift; michael@0: }th_info; michael@0: michael@0: /**The comment information. michael@0: * michael@0: * This structure holds the in-stream metadata corresponding to michael@0: * the 'comment' header packet. michael@0: * The comment header is meant to be used much like someone jotting a quick michael@0: * note on the label of a video. michael@0: * It should be a short, to the point text note that can be more than a couple michael@0: * words, but not more than a short paragraph. michael@0: * michael@0: * The metadata is stored as a series of (tag, value) pairs, in michael@0: * length-encoded string vectors. michael@0: * The first occurrence of the '=' character delimits the tag and value. michael@0: * A particular tag may occur more than once, and order is significant. michael@0: * The character set encoding for the strings is always UTF-8, but the tag michael@0: * names are limited to ASCII, and treated as case-insensitive. michael@0: * See the Theora michael@0: * specification, Section 6.3.3 for details. michael@0: * michael@0: * In filling in this structure, th_decode_headerin() will null-terminate michael@0: * the user_comment strings for safety. michael@0: * However, the bitstream format itself treats them as 8-bit clean vectors, michael@0: * possibly containing null characters, and so the length array should be michael@0: * treated as their authoritative length. michael@0: */ michael@0: typedef struct th_comment{ michael@0: /**The array of comment string vectors.*/ michael@0: char **user_comments; michael@0: /**An array of the corresponding length of each vector, in bytes.*/ michael@0: int *comment_lengths; michael@0: /**The total number of comment strings.*/ michael@0: int comments; michael@0: /**The null-terminated vendor string. michael@0: This identifies the software used to encode the stream.*/ michael@0: char *vendor; michael@0: }th_comment; michael@0: michael@0: michael@0: michael@0: /**A single base matrix.*/ michael@0: typedef unsigned char th_quant_base[64]; michael@0: michael@0: /**A set of \a qi ranges.*/ michael@0: typedef struct{ michael@0: /**The number of ranges in the set.*/ michael@0: int nranges; michael@0: /**The size of each of the #nranges ranges. michael@0: These must sum to 63.*/ michael@0: const int *sizes; michael@0: /**#nranges +1 base matrices. michael@0: Matrices \a i and i+1 form the endpoints of range \a i.*/ michael@0: const th_quant_base *base_matrices; michael@0: }th_quant_ranges; michael@0: michael@0: /**A complete set of quantization parameters. michael@0: The quantizer for each coefficient is calculated as: michael@0: \code michael@0: Q=MAX(MIN(qmin[qti][ci!=0],scale[ci!=0][qi]*base[qti][pli][qi][ci]/100), michael@0: 1024). michael@0: \endcode michael@0: michael@0: \a qti is the quantization type index: 0 for intra, 1 for inter. michael@0: ci!=0 is 0 for the DC coefficient and 1 for AC coefficients. michael@0: \a qi is the quality index, ranging between 0 (low quality) and 63 (high michael@0: quality). michael@0: \a pli is the color plane index: 0 for Y', 1 for Cb, 2 for Cr. michael@0: \a ci is the DCT coefficient index. michael@0: Coefficient indices correspond to the normal 2D DCT block michael@0: ordering--row-major with low frequencies first--\em not zig-zag order. michael@0: michael@0: Minimum quantizers are constant, and are given by: michael@0: \code michael@0: qmin[2][2]={{4,2},{8,4}}. michael@0: \endcode michael@0: michael@0: Parameters that can be stored in the bitstream are as follows: michael@0: - The two scale matrices ac_scale and dc_scale. michael@0: \code michael@0: scale[2][64]={dc_scale,ac_scale}. michael@0: \endcode michael@0: - The base matrices for each \a qi, \a qti and \a pli (up to 384 in all). michael@0: In order to avoid storing a full 384 base matrices, only a sparse set of michael@0: matrices are stored, and the rest are linearly interpolated. michael@0: This is done as follows. michael@0: For each \a qti and \a pli, a series of \a n \a qi ranges is defined. michael@0: The size of each \a qi range can vary arbitrarily, but they must sum to michael@0: 63. michael@0: Then, n+1 matrices are specified, one for each endpoint of the michael@0: ranges. michael@0: For interpolation purposes, each range's endpoints are the first \a qi michael@0: value it contains and one past the last \a qi value it contains. michael@0: Fractional values are rounded to the nearest integer, with ties rounded michael@0: away from zero. michael@0: michael@0: Base matrices are stored by reference, so if the same matrices are used michael@0: multiple times, they will only appear once in the bitstream. michael@0: The bitstream is also capable of omitting an entire set of ranges and michael@0: its associated matrices if they are the same as either the previous michael@0: set (indexed in row-major order) or if the inter set is the same as the michael@0: intra set. michael@0: michael@0: - Loop filter limit values. michael@0: The same limits are used for the loop filter in all color planes, despite michael@0: potentially differing levels of quantization in each. michael@0: michael@0: For the current encoder, scale[ci!=0][qi] must be no greater michael@0: than scale[ci!=0][qi-1] and base[qti][pli][qi][ci] must michael@0: be no greater than base[qti][pli][qi-1][ci]. michael@0: These two conditions ensure that the actual quantizer for a given \a qti, michael@0: \a pli, and \a ci does not increase as \a qi increases. michael@0: This is not required by the decoder.*/ michael@0: typedef struct{ michael@0: /**The DC scaling factors.*/ michael@0: ogg_uint16_t dc_scale[64]; michael@0: /**The AC scaling factors.*/ michael@0: ogg_uint16_t ac_scale[64]; michael@0: /**The loop filter limit values.*/ michael@0: unsigned char loop_filter_limits[64]; michael@0: /**The \a qi ranges for each \a ci and \a pli.*/ michael@0: th_quant_ranges qi_ranges[2][3]; michael@0: }th_quant_info; michael@0: michael@0: michael@0: michael@0: /**The number of Huffman tables used by Theora.*/ michael@0: #define TH_NHUFFMAN_TABLES (80) michael@0: /**The number of DCT token values in each table.*/ michael@0: #define TH_NDCT_TOKENS (32) michael@0: michael@0: /**A Huffman code for a Theora DCT token. michael@0: * Each set of Huffman codes in a given table must form a complete, prefix-free michael@0: * code. michael@0: * There is no requirement that all the tokens in a table have a valid code, michael@0: * but the current encoder is not optimized to take advantage of this. michael@0: * If each of the five grouops of 16 tables does not contain at least one table michael@0: * with a code for every token, then the encoder may fail to encode certain michael@0: * frames. michael@0: * The complete table in the first group of 16 does not have to be in the same michael@0: * place as the complete table in the other groups, but the complete tables in michael@0: * the remaining four groups must all be in the same place.*/ michael@0: typedef struct{ michael@0: /**The bit pattern for the code, with the LSbit of the pattern aligned in michael@0: * the LSbit of the word.*/ michael@0: ogg_uint32_t pattern; michael@0: /**The number of bits in the code. michael@0: * This must be between 0 and 32, inclusive.*/ michael@0: int nbits; michael@0: }th_huff_code; michael@0: michael@0: michael@0: michael@0: /**\defgroup basefuncs Functions Shared by Encode and Decode*/ michael@0: /*@{*/ michael@0: /**\name Basic shared functions*/ michael@0: /*@{*/ michael@0: /**Retrieves a human-readable string to identify the library vendor and michael@0: * version. michael@0: * \return the version string.*/ michael@0: extern const char *th_version_string(void); michael@0: /**Retrieves the library version number. michael@0: * This is the highest bitstream version that the encoder library will produce, michael@0: * or that the decoder library can decode. michael@0: * This number is composed of a 16-bit major version, 8-bit minor version michael@0: * and 8 bit sub-version, composed as follows: michael@0: * \code michael@0: * (VERSION_MAJOR<<16)+(VERSION_MINOR<<8)+(VERSION_SUBMINOR) michael@0: * \endcode michael@0: * \return the version number.*/ michael@0: extern ogg_uint32_t th_version_number(void); michael@0: /**Converts a granule position to an absolute frame index, starting at michael@0: * 0. michael@0: * The granule position is interpreted in the context of a given michael@0: * #th_enc_ctx or #th_dec_ctx handle (either will suffice). michael@0: * \param _encdec A previously allocated #th_enc_ctx or #th_dec_ctx michael@0: * handle. michael@0: * \param _granpos The granule position to convert. michael@0: * \returns The absolute frame index corresponding to \a _granpos. michael@0: * \retval -1 The given granule position was invalid (i.e. negative).*/ michael@0: extern ogg_int64_t th_granule_frame(void *_encdec,ogg_int64_t _granpos); michael@0: /**Converts a granule position to an absolute time in seconds. michael@0: * The granule position is interpreted in the context of a given michael@0: * #th_enc_ctx or #th_dec_ctx handle (either will suffice). michael@0: * \param _encdec A previously allocated #th_enc_ctx or #th_dec_ctx michael@0: * handle. michael@0: * \param _granpos The granule position to convert. michael@0: * \return The absolute time in seconds corresponding to \a _granpos. michael@0: * This is the "end time" for the frame, or the latest time it should michael@0: * be displayed. michael@0: * It is not the presentation time. michael@0: * \retval -1 The given granule position was invalid (i.e. negative).*/ michael@0: extern double th_granule_time(void *_encdec,ogg_int64_t _granpos); michael@0: /**Determines whether a Theora packet is a header or not. michael@0: * This function does no verification beyond checking the packet type bit, so michael@0: * it should not be used for bitstream identification; use michael@0: * th_decode_headerin() for that. michael@0: * As per the Theora specification, an empty (0-byte) packet is treated as a michael@0: * data packet (a delta frame with no coded blocks). michael@0: * \param _op An ogg_packet containing encoded Theora data. michael@0: * \retval 1 The packet is a header packet michael@0: * \retval 0 The packet is a video data packet.*/ michael@0: extern int th_packet_isheader(ogg_packet *_op); michael@0: /**Determines whether a theora packet is a key frame or not. michael@0: * This function does no verification beyond checking the packet type and michael@0: * key frame bits, so it should not be used for bitstream identification; use michael@0: * th_decode_headerin() for that. michael@0: * As per the Theora specification, an empty (0-byte) packet is treated as a michael@0: * delta frame (with no coded blocks). michael@0: * \param _op An ogg_packet containing encoded Theora data. michael@0: * \retval 1 The packet contains a key frame. michael@0: * \retval 0 The packet contains a delta frame. michael@0: * \retval -1 The packet is not a video data packet.*/ michael@0: extern int th_packet_iskeyframe(ogg_packet *_op); michael@0: /*@}*/ michael@0: michael@0: michael@0: /**\name Functions for manipulating header data*/ michael@0: /*@{*/ michael@0: /**Initializes a th_info structure. michael@0: * This should be called on a freshly allocated #th_info structure before michael@0: * attempting to use it. michael@0: * \param _info The #th_info struct to initialize.*/ michael@0: extern void th_info_init(th_info *_info); michael@0: /**Clears a #th_info structure. michael@0: * This should be called on a #th_info structure after it is no longer michael@0: * needed. michael@0: * \param _info The #th_info struct to clear.*/ michael@0: extern void th_info_clear(th_info *_info); michael@0: michael@0: /**Initialize a #th_comment structure. michael@0: * This should be called on a freshly allocated #th_comment structure michael@0: * before attempting to use it. michael@0: * \param _tc The #th_comment struct to initialize.*/ michael@0: extern void th_comment_init(th_comment *_tc); michael@0: /**Add a comment to an initialized #th_comment structure. michael@0: * \note Neither th_comment_add() nor th_comment_add_tag() support michael@0: * comments containing null values, although the bitstream format does michael@0: * support them. michael@0: * To add such comments you will need to manipulate the #th_comment michael@0: * structure directly. michael@0: * \param _tc The #th_comment struct to add the comment to. michael@0: * \param _comment Must be a null-terminated UTF-8 string containing the michael@0: * comment in "TAG=the value" form.*/ michael@0: extern void th_comment_add(th_comment *_tc, char *_comment); michael@0: /**Add a comment to an initialized #th_comment structure. michael@0: * \note Neither th_comment_add() nor th_comment_add_tag() support michael@0: * comments containing null values, although the bitstream format does michael@0: * support them. michael@0: * To add such comments you will need to manipulate the #th_comment michael@0: * structure directly. michael@0: * \param _tc The #th_comment struct to add the comment to. michael@0: * \param _tag A null-terminated string containing the tag associated with michael@0: * the comment. michael@0: * \param _val The corresponding value as a null-terminated string.*/ michael@0: extern void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val); michael@0: /**Look up a comment value by its tag. michael@0: * \param _tc An initialized #th_comment structure. michael@0: * \param _tag The tag to look up. michael@0: * \param _count The instance of the tag. michael@0: * The same tag can appear multiple times, each with a distinct michael@0: * value, so an index is required to retrieve them all. michael@0: * The order in which these values appear is significant and michael@0: * should be preserved. michael@0: * Use th_comment_query_count() to get the legal range for michael@0: * the \a _count parameter. michael@0: * \return A pointer to the queried tag's value. michael@0: * This points directly to data in the #th_comment structure. michael@0: * It should not be modified or freed by the application, and michael@0: * modifications to the structure may invalidate the pointer. michael@0: * \retval NULL If no matching tag is found.*/ michael@0: extern char *th_comment_query(th_comment *_tc,char *_tag,int _count); michael@0: /**Look up the number of instances of a tag. michael@0: * Call this first when querying for a specific tag and then iterate over the michael@0: * number of instances with separate calls to th_comment_query() to michael@0: * retrieve all the values for that tag in order. michael@0: * \param _tc An initialized #th_comment structure. michael@0: * \param _tag The tag to look up. michael@0: * \return The number on instances of this particular tag.*/ michael@0: extern int th_comment_query_count(th_comment *_tc,char *_tag); michael@0: /**Clears a #th_comment structure. michael@0: * This should be called on a #th_comment structure after it is no longer michael@0: * needed. michael@0: * It will free all memory used by the structure members. michael@0: * \param _tc The #th_comment struct to clear.*/ michael@0: extern void th_comment_clear(th_comment *_tc); michael@0: /*@}*/ michael@0: /*@}*/ michael@0: michael@0: michael@0: michael@0: #if defined(__cplusplus) michael@0: } michael@0: #endif michael@0: michael@0: #endif