| // 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 |