| // Copyright 2019 Joe Drago. All rights reserved. | 
 | // SPDX-License-Identifier: BSD-2-Clause | 
 |  | 
 | #ifndef AVIF_INTERNAL_H | 
 | #define AVIF_INTERNAL_H | 
 |  | 
 | #include "avif/avif.h" // IWYU pragma: export | 
 |  | 
 | #ifdef __cplusplus | 
 | extern "C" { | 
 | #endif | 
 |  | 
 | // Yes, clamp macros are nasty. Do not use them. | 
 | #define AVIF_CLAMP(x, low, high) (((x) < (low)) ? (low) : (((high) < (x)) ? (high) : (x))) | 
 | #define AVIF_MIN(a, b) (((a) < (b)) ? (a) : (b)) | 
 | #define AVIF_MAX(a, b) (((a) > (b)) ? (a) : (b)) | 
 |  | 
 | // Used by stream related things. | 
 | #define AVIF_CHECK(A)          \ | 
 |     do {                       \ | 
 |         if (!(A))              \ | 
 |             return AVIF_FALSE; \ | 
 |     } while (0) | 
 |  | 
 | // Used instead of CHECK if needing to return a specific error on failure, instead of AVIF_FALSE | 
 | #define AVIF_CHECKERR(A, ERR) \ | 
 |     do {                      \ | 
 |         if (!(A))             \ | 
 |             return ERR;       \ | 
 |     } while (0) | 
 |  | 
 | // Forward any error to the caller now or continue execution. | 
 | #define AVIF_CHECKRES(A)                 \ | 
 |     do {                                 \ | 
 |         const avifResult result__ = (A); \ | 
 |         if (result__ != AVIF_RESULT_OK)  \ | 
 |             return result__;             \ | 
 |     } while (0) | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // URNs and Content-Types | 
 |  | 
 | #define AVIF_URN_ALPHA0 "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha" | 
 | #define AVIF_URN_ALPHA1 "urn:mpeg:hevc:2015:auxid:1" | 
 |  | 
 | #define AVIF_CONTENT_TYPE_XMP "application/rdf+xml" | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // Utils | 
 |  | 
 | float avifRoundf(float v); | 
 |  | 
 | // H (host) is platform-dependent. Could be little- or big-endian. | 
 | // N (network) is big-endian: most- to least-significant bytes. | 
 | // C (custom) is little-endian: least- to most-significant bytes. | 
 | // Never read N or C values; only access after casting to uint8_t*. | 
 | uint16_t avifHTONS(uint16_t s); | 
 | uint16_t avifNTOHS(uint16_t s); | 
 | uint16_t avifCTOHS(uint16_t s); | 
 | uint32_t avifHTONL(uint32_t l); | 
 | uint32_t avifNTOHL(uint32_t l); | 
 | uint32_t avifCTOHL(uint32_t l); | 
 | uint64_t avifHTON64(uint64_t l); | 
 | uint64_t avifNTOH64(uint64_t l); | 
 |  | 
 | void avifCalcYUVCoefficients(const avifImage * image, float * outR, float * outG, float * outB); | 
 |  | 
 | #define AVIF_ARRAY_DECLARE(TYPENAME, ITEMSTYPE, ITEMSNAME) \ | 
 |     typedef struct TYPENAME                                \ | 
 |     {                                                      \ | 
 |         ITEMSTYPE * ITEMSNAME;                             \ | 
 |         uint32_t elementSize;                              \ | 
 |         uint32_t count;                                    \ | 
 |         uint32_t capacity;                                 \ | 
 |     } TYPENAME | 
 | avifBool avifArrayCreate(void * arrayStruct, uint32_t elementSize, uint32_t initialCapacity); | 
 | uint32_t avifArrayPushIndex(void * arrayStruct); | 
 | void * avifArrayPushPtr(void * arrayStruct); | 
 | void avifArrayPush(void * arrayStruct, void * element); | 
 | void avifArrayPop(void * arrayStruct); | 
 | void avifArrayDestroy(void * arrayStruct); | 
 |  | 
 | void avifFractionSimplify(avifFraction * f); | 
 | avifBool avifFractionCD(avifFraction * a, avifFraction * b); | 
 | avifBool avifFractionAdd(avifFraction a, avifFraction b, avifFraction * result); | 
 | avifBool avifFractionSub(avifFraction a, avifFraction b, avifFraction * result); | 
 |  | 
 | void avifImageSetDefaults(avifImage * image); | 
 | // Copies all fields that do not need to be freed/allocated from srcImage to dstImage. | 
 | void avifImageCopyNoAlloc(avifImage * dstImage, const avifImage * srcImage); | 
 |  | 
 | // Copies the samples from srcImage to dstImage. dstImage must be allocated. | 
 | // srcImage and dstImage must have the same width, height, and depth. | 
 | // If the AVIF_PLANES_YUV bit is set in planes, then srcImage and dstImage must have the same yuvFormat and yuvRange. | 
 | void avifImageCopySamples(avifImage * dstImage, const avifImage * srcImage, avifPlanesFlags planes); | 
 |  | 
 | typedef struct avifAlphaParams | 
 | { | 
 |     uint32_t width; | 
 |     uint32_t height; | 
 |  | 
 |     uint32_t srcDepth; | 
 |     const uint8_t * srcPlane; | 
 |     uint32_t srcRowBytes; | 
 |     uint32_t srcOffsetBytes; | 
 |     uint32_t srcPixelBytes; | 
 |  | 
 |     uint32_t dstDepth; | 
 |     uint8_t * dstPlane; | 
 |     uint32_t dstRowBytes; | 
 |     uint32_t dstOffsetBytes; | 
 |     uint32_t dstPixelBytes; | 
 |  | 
 | } avifAlphaParams; | 
 |  | 
 | avifBool avifFillAlpha(const avifAlphaParams * params); | 
 | avifBool avifReformatAlpha(const avifAlphaParams * params); | 
 |  | 
 | typedef enum avifReformatMode | 
 | { | 
 |     AVIF_REFORMAT_MODE_YUV_COEFFICIENTS = 0, // Normal YUV conversion using coefficients | 
 |     AVIF_REFORMAT_MODE_IDENTITY,             // Pack GBR directly into YUV planes (AVIF_MATRIX_COEFFICIENTS_IDENTITY) | 
 |     AVIF_REFORMAT_MODE_YCGCO,                // YUV conversion using AVIF_MATRIX_COEFFICIENTS_YCGCO | 
 | #if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R) | 
 |     AVIF_REFORMAT_MODE_YCGCO_RE, // YUV conversion using AVIF_MATRIX_COEFFICIENTS_YCGCO_RE | 
 |     AVIF_REFORMAT_MODE_YCGCO_RO, // YUV conversion using AVIF_MATRIX_COEFFICIENTS_YCGCO_RO | 
 | #endif | 
 | } avifReformatMode; | 
 |  | 
 | typedef enum avifAlphaMultiplyMode | 
 | { | 
 |     AVIF_ALPHA_MULTIPLY_MODE_NO_OP = 0, | 
 |     AVIF_ALPHA_MULTIPLY_MODE_MULTIPLY, | 
 |     AVIF_ALPHA_MULTIPLY_MODE_UNMULTIPLY | 
 | } avifAlphaMultiplyMode; | 
 |  | 
 | typedef struct avifReformatState | 
 | { | 
 |     // YUV coefficients | 
 |     float kr; | 
 |     float kg; | 
 |     float kb; | 
 |  | 
 |     uint32_t yuvChannelBytes; | 
 |     uint32_t rgbChannelBytes; | 
 |     uint32_t rgbPixelBytes; | 
 |     uint32_t rgbOffsetBytesR; | 
 |     uint32_t rgbOffsetBytesG; | 
 |     uint32_t rgbOffsetBytesB; | 
 |     uint32_t rgbOffsetBytesA; | 
 |  | 
 |     uint32_t yuvDepth; | 
 |     avifRange yuvRange; | 
 |     int yuvMaxChannel; | 
 |     int rgbMaxChannel; | 
 |     float rgbMaxChannelF; | 
 |     float biasY;   // minimum Y value | 
 |     float biasUV;  // the value of 0.5 for the appropriate bit depth [128, 512, 2048] | 
 |     float rangeY;  // difference between max and min Y | 
 |     float rangeUV; // difference between max and min UV | 
 |  | 
 |     avifPixelFormatInfo formatInfo; | 
 |  | 
 |     avifReformatMode mode; | 
 | } avifReformatState; | 
 |  | 
 | // Returns: | 
 | // * AVIF_RESULT_OK              - Converted successfully with libyuv | 
 | // * AVIF_RESULT_NOT_IMPLEMENTED - The fast path for this combination is not implemented with libyuv, use built-in RGB conversion | 
 | // * [any other error]           - Return error to caller | 
 | avifResult avifImageRGBToYUVLibYUV(avifImage * image, const avifRGBImage * rgb); | 
 |  | 
 | // Parameters: | 
 | // * image - input YUV image | 
 | // * rgb - output RGB image | 
 | // * reformatAlpha - if set to AVIF_TRUE, the function will attempt to copy the alpha channel to the output RGB image using | 
 | // libyuv. | 
 | // * alphaReformattedWithLibYUV - Output parameter. If reformatAlpha is set to true and libyuv was able to copy over the alpha | 
 | // channel, then this will be set to AVIF_TRUE. Otherwise, this will be set to AVIF_FALSE. The value in this parameter is valid | 
 | // only if the return value of the function is AVIF_RESULT_OK or AVIF_RESULT_NOT_IMPLEMENTED. | 
 | // Returns: | 
 | // * AVIF_RESULT_OK              - Converted successfully with libyuv | 
 | // * AVIF_RESULT_NOT_IMPLEMENTED - The fast path for this combination is not implemented with libyuv, use built-in YUV conversion | 
 | // * [any other error]           - Return error to caller | 
 | avifResult avifImageYUVToRGBLibYUV(const avifImage * image, avifRGBImage * rgb, avifBool reformatAlpha, avifBool * alphaReformattedWithLibYUV); | 
 |  | 
 | // Returns: | 
 | // * AVIF_RESULT_OK              - Converted successfully with libsharpyuv | 
 | // * AVIF_RESULT_NOT_IMPLEMENTED - libsharpyuv is not compiled in, or doesn't support this type of input | 
 | // * [any other error]           - Return error to caller | 
 | avifResult avifImageRGBToYUVLibSharpYUV(avifImage * image, const avifRGBImage * rgb, const avifReformatState * state); | 
 |  | 
 | // Returns: | 
 | // * AVIF_RESULT_OK               - Converted successfully with libyuv. | 
 | // * AVIF_RESULT_NOT_IMPLEMENTED  - The fast path for this conversion is not implemented with libyuv, use built-in conversion. | 
 | // * AVIF_RESULT_INVALID_ARGUMENT - Return error to caller. | 
 | avifResult avifRGBImageToF16LibYUV(avifRGBImage * rgb); | 
 |  | 
 | // Returns: | 
 | // * AVIF_RESULT_OK              - (Un)Premultiply successfully with libyuv | 
 | // * AVIF_RESULT_NOT_IMPLEMENTED - The fast path for this combination is not implemented with libyuv, use built-in (Un)Premultiply | 
 | // * [any other error]           - Return error to caller | 
 | avifResult avifRGBImagePremultiplyAlphaLibYUV(avifRGBImage * rgb); | 
 | avifResult avifRGBImageUnpremultiplyAlphaLibYUV(avifRGBImage * rgb); | 
 |  | 
 | avifBool avifDimensionsTooLarge(uint32_t width, uint32_t height, uint32_t imageSizeLimit, uint32_t imageDimensionLimit); | 
 |  | 
 | // Given the number of encoding threads or decoding threads available and the image dimensions, | 
 | // chooses suitable values of *tileRowsLog2 and *tileColsLog2. | 
 | // | 
 | // Note: Although avifSetTileConfiguration() is only used in src/write.c and could be a static | 
 | // function in that file, it is defined as an internal global function so that it can be tested by | 
 | // unit tests. | 
 | void avifSetTileConfiguration(int threads, uint32_t width, uint32_t height, int * tileRowsLog2, int * tileColsLog2); | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // Scaling | 
 |  | 
 | // This scales the YUV/A planes in-place. | 
 | avifBool avifImageScale(avifImage * image, | 
 |                         uint32_t dstWidth, | 
 |                         uint32_t dstHeight, | 
 |                         uint32_t imageSizeLimit, | 
 |                         uint32_t imageDimensionLimit, | 
 |                         avifDiagnostics * diag); | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // AVIF item type | 
 |  | 
 | typedef enum avifItemCategory | 
 | { | 
 |     AVIF_ITEM_COLOR = 0, | 
 |     AVIF_ITEM_ALPHA = 1 | 
 | } avifItemCategory; | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // Grid AVIF images | 
 |  | 
 | // Returns false if the tiles in a grid image violate any standards. | 
 | // The image contains imageW*imageH pixels. The tiles are of tileW*tileH pixels each. | 
 | avifBool avifAreGridDimensionsValid(avifPixelFormat yuvFormat, uint32_t imageW, uint32_t imageH, uint32_t tileW, uint32_t tileH, avifDiagnostics * diag); | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // Metadata | 
 |  | 
 | // Attempts to parse the image->exif payload for Exif orientation and sets image->transformFlags, image->irot and | 
 | // image->imir on success. Returns AVIF_RESULT_INVALID_EXIF_PAYLOAD on failure. | 
 | avifResult avifImageExtractExifOrientationToIrotImir(avifImage * image); | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // avifCodecDecodeInput | 
 |  | 
 | // Legal spatial_id values are [0,1,2,3], so this serves as a sentinel value for "do not filter by spatial_id" | 
 | #define AVIF_SPATIAL_ID_UNSET 0xff | 
 |  | 
 | typedef struct avifDecodeSample | 
 | { | 
 |     avifROData data; | 
 |     avifBool ownsData; | 
 |     avifBool partialData; // if true, data exists but doesn't have all of the sample in it | 
 |  | 
 |     uint32_t itemID;   // if non-zero, data comes from a mergedExtents buffer in an avifDecoderItem, not a file offset | 
 |     uint64_t offset;   // additional offset into data. Can be used to offset into an itemID's payload as well. | 
 |     size_t size;       // | 
 |     uint8_t spatialID; // If set to a value other than AVIF_SPATIAL_ID_UNSET, output frames from this sample should be | 
 |                        // skipped until the output frame's spatial_id matches this ID. | 
 |     avifBool sync;     // is sync sample (keyframe) | 
 | } avifDecodeSample; | 
 | AVIF_ARRAY_DECLARE(avifDecodeSampleArray, avifDecodeSample, sample); | 
 |  | 
 | typedef struct avifCodecDecodeInput | 
 | { | 
 |     avifDecodeSampleArray samples; | 
 |     avifBool allLayers;            // if true, the underlying codec must decode all layers, not just the best layer | 
 |     avifItemCategory itemCategory; // category of item being decoded | 
 | } avifCodecDecodeInput; | 
 |  | 
 | avifCodecDecodeInput * avifCodecDecodeInputCreate(void); | 
 | void avifCodecDecodeInputDestroy(avifCodecDecodeInput * decodeInput); | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // avifCodecEncodeOutput | 
 |  | 
 | typedef struct avifEncodeSample | 
 | { | 
 |     avifRWData data; | 
 |     avifBool sync; // is sync sample (keyframe) | 
 | } avifEncodeSample; | 
 | AVIF_ARRAY_DECLARE(avifEncodeSampleArray, avifEncodeSample, sample); | 
 |  | 
 | typedef struct avifCodecEncodeOutput | 
 | { | 
 |     avifEncodeSampleArray samples; | 
 | } avifCodecEncodeOutput; | 
 |  | 
 | avifCodecEncodeOutput * avifCodecEncodeOutputCreate(void); | 
 | avifResult avifCodecEncodeOutputAddSample(avifCodecEncodeOutput * encodeOutput, const uint8_t * data, size_t len, avifBool sync); | 
 | void avifCodecEncodeOutputDestroy(avifCodecEncodeOutput * encodeOutput); | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // avifCodecSpecificOptions (key/value string pairs for advanced tuning) | 
 |  | 
 | typedef struct avifCodecSpecificOption | 
 | { | 
 |     char * key;   // Must be a simple lowercase alphanumeric string | 
 |     char * value; // Free-form string to be interpreted by the codec | 
 | } avifCodecSpecificOption; | 
 | AVIF_ARRAY_DECLARE(avifCodecSpecificOptions, avifCodecSpecificOption, entries); | 
 |  | 
 | // Returns NULL if a memory allocation failed. | 
 | avifCodecSpecificOptions * avifCodecSpecificOptionsCreate(void); | 
 | void avifCodecSpecificOptionsClear(avifCodecSpecificOptions * csOptions); | 
 | void avifCodecSpecificOptionsDestroy(avifCodecSpecificOptions * csOptions); | 
 | avifResult avifCodecSpecificOptionsSet(avifCodecSpecificOptions * csOptions, const char * key, const char * value); // if(value==NULL), key is deleted | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // avifCodecType (underlying video format) | 
 |  | 
 | // Alliance for Open Media video formats that can be used in the AVIF image format. | 
 | typedef enum avifCodecType | 
 | { | 
 |     AVIF_CODEC_TYPE_UNKNOWN, | 
 |     AVIF_CODEC_TYPE_AV1, | 
 | #if defined(AVIF_CODEC_AVM) | 
 |     AVIF_CODEC_TYPE_AV2, // Experimental. | 
 | #endif | 
 | } avifCodecType; | 
 |  | 
 | // Returns AVIF_CODEC_TYPE_UNKNOWN unless the chosen codec is available with the requiredFlags. | 
 | avifCodecType avifCodecTypeFromChoice(avifCodecChoice choice, avifCodecFlags requiredFlags); | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // avifCodec (abstraction layer to use different codec implementations) | 
 |  | 
 | struct avifCodec; | 
 | struct avifCodecInternal; | 
 |  | 
 | typedef enum avifEncoderChange | 
 | { | 
 |     AVIF_ENCODER_CHANGE_MIN_QUANTIZER = (1u << 0), | 
 |     AVIF_ENCODER_CHANGE_MAX_QUANTIZER = (1u << 1), | 
 |     AVIF_ENCODER_CHANGE_MIN_QUANTIZER_ALPHA = (1u << 2), | 
 |     AVIF_ENCODER_CHANGE_MAX_QUANTIZER_ALPHA = (1u << 3), | 
 |     AVIF_ENCODER_CHANGE_TILE_ROWS_LOG2 = (1u << 4), | 
 |     AVIF_ENCODER_CHANGE_TILE_COLS_LOG2 = (1u << 5), | 
 |     AVIF_ENCODER_CHANGE_QUANTIZER = (1u << 6), | 
 |     AVIF_ENCODER_CHANGE_QUANTIZER_ALPHA = (1u << 7), | 
 |     AVIF_ENCODER_CHANGE_SCALING_MODE = (1u << 8), | 
 |  | 
 |     AVIF_ENCODER_CHANGE_CODEC_SPECIFIC = (1u << 31) | 
 | } avifEncoderChange; | 
 | typedef uint32_t avifEncoderChanges; | 
 |  | 
 | typedef avifBool (*avifCodecGetNextImageFunc)(struct avifCodec * codec, | 
 |                                               struct avifDecoder * decoder, | 
 |                                               const avifDecodeSample * sample, | 
 |                                               avifBool alpha, | 
 |                                               avifBool * isLimitedRangeAlpha, | 
 |                                               avifImage * image); | 
 | // EncodeImage and EncodeFinish are not required to always emit a sample, but when all images are | 
 | // encoded and EncodeFinish is called, the number of samples emitted must match the number of submitted frames. | 
 | // avifCodecEncodeImageFunc may return AVIF_RESULT_UNKNOWN_ERROR to automatically emit the appropriate | 
 | // AVIF_RESULT_ENCODE_COLOR_FAILED or AVIF_RESULT_ENCODE_ALPHA_FAILED depending on the alpha argument. | 
 | // avifCodecEncodeImageFunc should use tileRowsLog2 and tileColsLog2 instead of | 
 | // encoder->tileRowsLog2, encoder->tileColsLog2, and encoder->autoTiling. The caller of | 
 | // avifCodecEncodeImageFunc is responsible for automatic tiling if encoder->autoTiling is set to | 
 | // AVIF_TRUE. The actual tiling values are passed to avifCodecEncodeImageFunc as parameters. | 
 | // Similarly, avifCodecEncodeImageFunc should use the quantizer parameter instead of | 
 | // encoder->quality and encoder->qualityAlpha. If disableLaggedOutput is AVIF_TRUE, then the encoder will emit the output frame | 
 | // without any lag (if supported). Note that disableLaggedOutput is only used by the first call to this function (which | 
 | // initializes the encoder) and is ignored by the subsequent calls. | 
 | // | 
 | // Note: The caller of avifCodecEncodeImageFunc always passes encoder->data->tileRowsLog2 and | 
 | // encoder->data->tileColsLog2 as the tileRowsLog2 and tileColsLog2 arguments. Because | 
 | // encoder->data is of a struct type defined in src/write.c, avifCodecEncodeImageFunc cannot | 
 | // dereference encoder->data and has to receive encoder->data->tileRowsLog2 and | 
 | // encoder->data->tileColsLog2 via function parameters. | 
 | typedef avifResult (*avifCodecEncodeImageFunc)(struct avifCodec * codec, | 
 |                                                avifEncoder * encoder, | 
 |                                                const avifImage * image, | 
 |                                                avifBool alpha, | 
 |                                                int tileRowsLog2, | 
 |                                                int tileColsLog2, | 
 |                                                int quantizer, | 
 |                                                avifEncoderChanges encoderChanges, | 
 |                                                avifBool disableLaggedOutput, | 
 |                                                avifAddImageFlags addImageFlags, | 
 |                                                avifCodecEncodeOutput * output); | 
 | typedef avifBool (*avifCodecEncodeFinishFunc)(struct avifCodec * codec, avifCodecEncodeOutput * output); | 
 | typedef void (*avifCodecDestroyInternalFunc)(struct avifCodec * codec); | 
 |  | 
 | typedef struct avifCodec | 
 | { | 
 |     avifCodecSpecificOptions * csOptions; // Contains codec-specific key/value pairs for advanced tuning. | 
 |                                           // If a codec uses a value, it must mark it as used. | 
 |                                           // This array is NOT owned by avifCodec. | 
 |     struct avifCodecInternal * internal;  // up to each codec to use how it wants | 
 |                                           // | 
 |     avifDiagnostics * diag;               // Shallow copy; owned by avifEncoder or avifDecoder | 
 |                                           // | 
 |     uint8_t operatingPoint;               // Operating point, defaults to 0. | 
 |     avifBool allLayers;                   // if true, the underlying codec must decode all layers, not just the best layer | 
 |  | 
 |     avifCodecGetNextImageFunc getNextImage; | 
 |     avifCodecEncodeImageFunc encodeImage; | 
 |     avifCodecEncodeFinishFunc encodeFinish; | 
 |     avifCodecDestroyInternalFunc destroyInternal; | 
 | } avifCodec; | 
 |  | 
 | avifCodec * avifCodecCreate(avifCodecChoice choice, avifCodecFlags requiredFlags); | 
 | void avifCodecDestroy(avifCodec * codec); | 
 |  | 
 | avifCodec * avifCodecCreateAOM(void);     // requires AVIF_CODEC_AOM (codec_aom.c) | 
 | const char * avifCodecVersionAOM(void);   // requires AVIF_CODEC_AOM (codec_aom.c) | 
 | avifCodec * avifCodecCreateDav1d(void);   // requires AVIF_CODEC_DAV1D (codec_dav1d.c) | 
 | const char * avifCodecVersionDav1d(void); // requires AVIF_CODEC_DAV1D (codec_dav1d.c) | 
 | avifCodec * avifCodecCreateGav1(void);    // requires AVIF_CODEC_LIBGAV1 (codec_libgav1.c) | 
 | const char * avifCodecVersionGav1(void);  // requires AVIF_CODEC_LIBGAV1 (codec_libgav1.c) | 
 | avifCodec * avifCodecCreateRav1e(void);   // requires AVIF_CODEC_RAV1E (codec_rav1e.c) | 
 | const char * avifCodecVersionRav1e(void); // requires AVIF_CODEC_RAV1E (codec_rav1e.c) | 
 | avifCodec * avifCodecCreateSvt(void);     // requires AVIF_CODEC_SVT (codec_svt.c) | 
 | const char * avifCodecVersionSvt(void);   // requires AVIF_CODEC_SVT (codec_svt.c) | 
 | avifCodec * avifCodecCreateAVM(void);     // requires AVIF_CODEC_AVM (codec_avm.c) | 
 | const char * avifCodecVersionAVM(void);   // requires AVIF_CODEC_AVM (codec_avm.c) | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // avifDiagnostics | 
 |  | 
 | #ifdef __clang__ | 
 | __attribute__((__format__(__printf__, 2, 3))) | 
 | #endif | 
 | void avifDiagnosticsPrintf(avifDiagnostics * diag, const char * format, ...); | 
 |  | 
 | // --------------------------------------------------------------------------- | 
 | // avifStream | 
 | // | 
 | // In network byte order (big-endian) unless otherwise specified. | 
 |  | 
 | typedef size_t avifBoxMarker; | 
 |  | 
 | typedef struct avifBoxHeader | 
 | { | 
 |     // Size of the box in bytes, excluding the box header. | 
 |     size_t size; | 
 |  | 
 |     uint8_t type[4]; | 
 | } avifBoxHeader; | 
 |  | 
 | typedef struct avifROStream | 
 | { | 
 |     avifROData * raw; | 
 |  | 
 |     // Index of the next byte in the raw stream. | 
 |     size_t offset; | 
 |  | 
 |     // If 0, byte-aligned functions can be used (avifROStreamRead() etc.). | 
 |     // Otherwise, it represents the number of bits already used in the last byte | 
 |     // (located at offset-1). | 
 |     size_t numUsedBitsInPartialByte; | 
 |  | 
 |     // Error information, if any. | 
 |     avifDiagnostics * diag; | 
 |     const char * diagContext; | 
 | } avifROStream; | 
 |  | 
 | const uint8_t * avifROStreamCurrent(avifROStream * stream); | 
 | void avifROStreamStart(avifROStream * stream, avifROData * raw, avifDiagnostics * diag, const char * diagContext); | 
 | size_t avifROStreamOffset(const avifROStream * stream); | 
 | void avifROStreamSetOffset(avifROStream * stream, size_t offset); | 
 |  | 
 | avifBool avifROStreamHasBytesLeft(const avifROStream * stream, size_t byteCount); | 
 | size_t avifROStreamRemainingBytes(const avifROStream * stream); | 
 | // The following functions require byte alignment. | 
 | avifBool avifROStreamSkip(avifROStream * stream, size_t byteCount); | 
 | avifBool avifROStreamRead(avifROStream * stream, uint8_t * data, size_t size); | 
 | avifBool avifROStreamReadU16(avifROStream * stream, uint16_t * v); | 
 | avifBool avifROStreamReadU16Endianness(avifROStream * stream, uint16_t * v, avifBool littleEndian); | 
 | avifBool avifROStreamReadU32(avifROStream * stream, uint32_t * v); | 
 | avifBool avifROStreamReadU32Endianness(avifROStream * stream, uint32_t * v, avifBool littleEndian); | 
 | avifBool avifROStreamReadUX8(avifROStream * stream, uint64_t * v, uint64_t factor); // Reads a factor*8 sized uint, saves in v | 
 | avifBool avifROStreamReadU64(avifROStream * stream, uint64_t * v); | 
 | avifBool avifROStreamReadString(avifROStream * stream, char * output, size_t outputSize); | 
 | avifBool avifROStreamReadBoxHeader(avifROStream * stream, avifBoxHeader * header); // This fails if the size reported by the header cannot fit in the stream | 
 | avifBool avifROStreamReadBoxHeaderPartial(avifROStream * stream, avifBoxHeader * header); // This doesn't require that the full box can fit in the stream | 
 | avifBool avifROStreamReadVersionAndFlags(avifROStream * stream, uint8_t * version, uint32_t * flags); // version and flags ptrs are both optional | 
 | avifBool avifROStreamReadAndEnforceVersion(avifROStream * stream, uint8_t enforcedVersion); // currently discards flags | 
 | // The following functions can write non-aligned bits. | 
 | avifBool avifROStreamReadBits8(avifROStream * stream, uint8_t * v, size_t bitCount); | 
 | avifBool avifROStreamReadBits(avifROStream * stream, uint32_t * v, size_t bitCount); | 
 | avifBool avifROStreamReadVarInt(avifROStream * stream, uint32_t * v); | 
 |  | 
 | typedef struct avifRWStream | 
 | { | 
 |     avifRWData * raw; | 
 |  | 
 |     // Index of the next byte in the raw stream. | 
 |     size_t offset; | 
 |  | 
 |     // If 0, byte-aligned functions can be used (avifRWStreamWrite() etc.). | 
 |     // Otherwise, it represents the number of bits already used in the last byte | 
 |     // (located at offset-1). | 
 |     size_t numUsedBitsInPartialByte; | 
 | } avifRWStream; | 
 |  | 
 | void avifRWStreamStart(avifRWStream * stream, avifRWData * raw); | 
 | size_t avifRWStreamOffset(const avifRWStream * stream); | 
 | void avifRWStreamSetOffset(avifRWStream * stream, size_t offset); | 
 |  | 
 | void avifRWStreamFinishWrite(avifRWStream * stream); | 
 | // The following functions require byte alignment. | 
 | avifResult avifRWStreamWrite(avifRWStream * stream, const void * data, size_t size); | 
 | avifResult avifRWStreamWriteChars(avifRWStream * stream, const char * chars, size_t size); | 
 | avifResult avifRWStreamWriteBox(avifRWStream * stream, const char * type, size_t contentSize, avifBoxMarker * marker); | 
 | avifResult avifRWStreamWriteFullBox(avifRWStream * stream, const char * type, size_t contentSize, int version, uint32_t flags, avifBoxMarker * marker); | 
 | void avifRWStreamFinishBox(avifRWStream * stream, avifBoxMarker marker); | 
 | avifResult avifRWStreamWriteU8(avifRWStream * stream, uint8_t v); | 
 | avifResult avifRWStreamWriteU16(avifRWStream * stream, uint16_t v); | 
 | avifResult avifRWStreamWriteU32(avifRWStream * stream, uint32_t v); | 
 | avifResult avifRWStreamWriteU64(avifRWStream * stream, uint64_t v); | 
 | avifResult avifRWStreamWriteZeros(avifRWStream * stream, size_t byteCount); | 
 | // The following functions can write non-aligned bits. | 
 | avifResult avifRWStreamWriteBits(avifRWStream * stream, uint32_t v, size_t bitCount); | 
 | avifResult avifRWStreamWriteVarInt(avifRWStream * stream, uint32_t v); | 
 |  | 
 | // This is to make it clear that the box size is currently unknown, and will be determined later (with a call to avifRWStreamFinishBox) | 
 | #define AVIF_BOX_SIZE_TBD 0 | 
 |  | 
 | // Used for both av1C and av2C. | 
 | typedef struct avifCodecConfigurationBox | 
 | { | 
 |     // [skipped; is constant] unsigned int (1)marker = 1; | 
 |     // [skipped; is constant] unsigned int (7)version = 1; | 
 |  | 
 |     uint8_t seqProfile;           // unsigned int (3) seq_profile; | 
 |     uint8_t seqLevelIdx0;         // unsigned int (5) seq_level_idx_0; | 
 |     uint8_t seqTier0;             // unsigned int (1) seq_tier_0; | 
 |     uint8_t highBitdepth;         // unsigned int (1) high_bitdepth; | 
 |     uint8_t twelveBit;            // unsigned int (1) twelve_bit; | 
 |     uint8_t monochrome;           // unsigned int (1) monochrome; | 
 |     uint8_t chromaSubsamplingX;   // unsigned int (1) chroma_subsampling_x; | 
 |     uint8_t chromaSubsamplingY;   // unsigned int (1) chroma_subsampling_y; | 
 |     uint8_t chromaSamplePosition; // unsigned int (2) chroma_sample_position; | 
 |  | 
 |     // unsigned int (3)reserved = 0; | 
 |     // unsigned int (1)initial_presentation_delay_present; | 
 |     // if (initial_presentation_delay_present) { | 
 |     //     unsigned int (4)initial_presentation_delay_minus_one; | 
 |     // } else { | 
 |     //     unsigned int (4)reserved = 0; | 
 |     // } | 
 | } avifCodecConfigurationBox; | 
 |  | 
 | typedef struct avifSequenceHeader | 
 | { | 
 |     uint8_t reduced_still_picture_header; | 
 |     uint32_t maxWidth; | 
 |     uint32_t maxHeight; | 
 |     uint32_t bitDepth; | 
 |     avifPixelFormat yuvFormat; | 
 |     avifChromaSamplePosition chromaSamplePosition; | 
 |     avifColorPrimaries colorPrimaries; | 
 |     avifTransferCharacteristics transferCharacteristics; | 
 |     avifMatrixCoefficients matrixCoefficients; | 
 |     avifRange range; | 
 |     avifCodecConfigurationBox av1C; // TODO(yguyon): Rename or add av2C | 
 | } avifSequenceHeader; | 
 |  | 
 | avifBool avifSequenceHeaderParse(avifSequenceHeader * header, const avifROData * sample, avifCodecType codecType); | 
 |  | 
 | #define AVIF_INDEFINITE_DURATION64 UINT64_MAX | 
 | #define AVIF_INDEFINITE_DURATION32 UINT32_MAX | 
 |  | 
 | #ifdef __cplusplus | 
 | } // extern "C" | 
 | #endif | 
 |  | 
 | #endif // ifndef AVIF_INTERNAL_H |