Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 1 | // Copyright 2019 Joe Drago. All rights reserved. |
| 2 | // SPDX-License-Identifier: BSD-2-Clause |
| 3 | |
| 4 | #ifndef AVIF_INTERNAL_H |
| 5 | #define AVIF_INTERNAL_H |
| 6 | |
| 7 | #include "avif/avif.h" |
| 8 | |
Joe Drago | c0d3d66 | 2019-04-12 14:10:16 -0700 | [diff] [blame] | 9 | #ifdef __cplusplus |
| 10 | extern "C" { |
| 11 | #endif |
| 12 | |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 13 | // Yes, clamp macros are nasty. Do not use them. |
Joe Drago | 7a9a661 | 2019-07-17 11:21:24 -0700 | [diff] [blame] | 14 | #define AVIF_CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 15 | |
| 16 | // Used by stream related things. |
Joe Drago | 7a9a661 | 2019-07-17 11:21:24 -0700 | [diff] [blame] | 17 | #define CHECK(A) \ |
Joe Drago | 97b071c | 2019-07-17 14:24:56 -0700 | [diff] [blame] | 18 | if (!(A)) \ |
| 19 | return AVIF_FALSE; |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 20 | |
| 21 | // --------------------------------------------------------------------------- |
Joe Drago | cd1e4c3 | 2019-02-08 11:26:31 -0800 | [diff] [blame] | 22 | // URNs |
| 23 | |
| 24 | #define URN_ALPHA0 "urn:mpeg:mpegB:cicp:systems:auxiliary:alpha" |
| 25 | #define URN_ALPHA1 "urn:mpeg:hevc:2015:auxid:1" |
| 26 | |
| 27 | // --------------------------------------------------------------------------- |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 28 | // Utils |
| 29 | |
| 30 | float avifRoundf(float v); |
| 31 | |
| 32 | uint16_t avifHTONS(uint16_t s); |
| 33 | uint16_t avifNTOHS(uint16_t s); |
| 34 | uint32_t avifHTONL(uint32_t l); |
| 35 | uint32_t avifNTOHL(uint32_t l); |
| 36 | uint64_t avifHTON64(uint64_t l); |
| 37 | uint64_t avifNTOH64(uint64_t l); |
| 38 | |
Joe Drago | cd5b93b | 2019-04-18 11:19:54 -0700 | [diff] [blame] | 39 | int avifFullToLimitedY(int depth, int v); |
| 40 | int avifFullToLimitedUV(int depth, int v); |
| 41 | int avifLimitedToFullY(int depth, int v); |
| 42 | int avifLimitedToFullUV(int depth, int v); |
Joe Drago | 7efd803 | 2019-02-08 14:49:15 -0800 | [diff] [blame] | 43 | |
Joe Drago | 678b938 | 2019-02-09 03:17:47 -0800 | [diff] [blame] | 44 | void avifCalcYUVCoefficients(avifImage * image, float * outR, float * outG, float * outB); |
| 45 | |
Joe Drago | 05559c9 | 2019-07-17 16:33:38 -0700 | [diff] [blame] | 46 | #define AVIF_ARRAY_DECLARE(TYPENAME, ITEMSTYPE, ITEMSNAME) \ |
| 47 | typedef struct TYPENAME \ |
| 48 | { \ |
| 49 | ITEMSTYPE * ITEMSNAME; \ |
| 50 | uint32_t elementSize; \ |
| 51 | uint32_t count; \ |
| 52 | uint32_t capacity; \ |
Joe Drago | 399df4f | 2019-07-23 16:45:14 -0700 | [diff] [blame^] | 53 | } TYPENAME |
Joe Drago | 05559c9 | 2019-07-17 16:33:38 -0700 | [diff] [blame] | 54 | void avifArrayCreate(void * arrayStruct, uint32_t elementSize, uint32_t initialCapacity); |
| 55 | uint32_t avifArrayPushIndex(void * arrayStruct); |
| 56 | void * avifArrayPushPtr(void * arrayStruct); |
| 57 | void avifArrayPush(void * arrayStruct, void * element); |
| 58 | void avifArrayDestroy(void * arrayStruct); |
| 59 | |
Joe Drago | 46ea058 | 2019-07-22 15:55:47 -0700 | [diff] [blame] | 60 | AVIF_ARRAY_DECLARE(avifRawDataArray, avifRawData, raw); |
| 61 | |
| 62 | // Used internally by avifDecoderNextImage() when there is limited range alpha |
| 63 | void avifImageCopyDecoderAlpha(avifImage * image); |
| 64 | |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 65 | // --------------------------------------------------------------------------- |
| 66 | // Memory management |
| 67 | |
| 68 | void * avifAlloc(size_t size); |
| 69 | void avifFree(void * p); |
| 70 | |
| 71 | // --------------------------------------------------------------------------- |
Joe Drago | 46ea058 | 2019-07-22 15:55:47 -0700 | [diff] [blame] | 72 | // avifCodecDecodeInput |
| 73 | |
| 74 | typedef struct avifCodecDecodeInput |
| 75 | { |
| 76 | avifRawDataArray samples; |
| 77 | avifBool alpha; // if true, this is decoding an alpha plane |
| 78 | } avifCodecDecodeInput; |
| 79 | |
Joe Drago | 399df4f | 2019-07-23 16:45:14 -0700 | [diff] [blame^] | 80 | avifCodecDecodeInput * avifCodecDecodeInputCreate(void); |
Joe Drago | 46ea058 | 2019-07-22 15:55:47 -0700 | [diff] [blame] | 81 | void avifCodecDecodeInputDestroy(avifCodecDecodeInput * decodeInput); |
| 82 | |
| 83 | // --------------------------------------------------------------------------- |
Joe Drago | 33f1d36 | 2019-02-13 16:46:22 -0800 | [diff] [blame] | 84 | // avifCodec (abstraction layer to use different AV1 implementations) |
| 85 | |
Joe Drago | 1585797 | 2019-02-13 17:48:28 -0800 | [diff] [blame] | 86 | typedef struct avifCodecConfigurationBox |
| 87 | { |
| 88 | // [skipped; is constant] unsigned int (1)marker = 1; |
| 89 | // [skipped; is constant] unsigned int (7)version = 1; |
| 90 | |
| 91 | uint8_t seqProfile; // unsigned int (3) seq_profile; |
| 92 | uint8_t seqLevelIdx0; // unsigned int (5) seq_level_idx_0; |
| 93 | uint8_t seqTier0; // unsigned int (1) seq_tier_0; |
| 94 | uint8_t highBitdepth; // unsigned int (1) high_bitdepth; |
| 95 | uint8_t twelveBit; // unsigned int (1) twelve_bit; |
| 96 | uint8_t monochrome; // unsigned int (1) monochrome; |
| 97 | uint8_t chromaSubsamplingX; // unsigned int (1) chroma_subsampling_x; |
| 98 | uint8_t chromaSubsamplingY; // unsigned int (1) chroma_subsampling_y; |
| 99 | uint8_t chromaSamplePosition; // unsigned int (2) chroma_sample_position; |
| 100 | |
| 101 | // unsigned int (3)reserved = 0; |
| 102 | // unsigned int (1)initial_presentation_delay_present; |
| 103 | // if (initial_presentation_delay_present) { |
| 104 | // unsigned int (4)initial_presentation_delay_minus_one; |
| 105 | // } else { |
| 106 | // unsigned int (4)reserved = 0; |
| 107 | // } |
| 108 | } avifCodecConfigurationBox; |
| 109 | |
Joe Drago | 33f1d36 | 2019-02-13 16:46:22 -0800 | [diff] [blame] | 110 | typedef enum avifCodecPlanes |
| 111 | { |
| 112 | AVIF_CODEC_PLANES_COLOR = 0, // YUV |
| 113 | AVIF_CODEC_PLANES_ALPHA, |
| 114 | |
| 115 | AVIF_CODEC_PLANES_COUNT |
| 116 | } avifCodecPlanes; |
| 117 | |
Joe Drago | 3533b97 | 2019-07-12 14:32:20 -0700 | [diff] [blame] | 118 | struct avifCodec; |
Joe Drago | 33f1d36 | 2019-02-13 16:46:22 -0800 | [diff] [blame] | 119 | struct avifCodecInternal; |
| 120 | |
Joe Drago | 46ea058 | 2019-07-22 15:55:47 -0700 | [diff] [blame] | 121 | typedef avifBool (*avifCodecDecodeFunc)(struct avifCodec * codec); |
Joe Drago | 97b071c | 2019-07-17 14:24:56 -0700 | [diff] [blame] | 122 | // avifCodecAlphaLimitedRangeFunc: returns AVIF_TRUE if an alpha plane exists and was encoded with limited range |
| 123 | typedef avifBool (*avifCodecAlphaLimitedRangeFunc)(struct avifCodec * codec); |
Joe Drago | 46ea058 | 2019-07-22 15:55:47 -0700 | [diff] [blame] | 124 | typedef avifBool (*avifCodecGetNextImageFunc)(struct avifCodec * codec, avifImage * image); |
Joe Drago | 97b071c | 2019-07-17 14:24:56 -0700 | [diff] [blame] | 125 | // avifCodecEncodeImageFunc: if either OBU* is null, skip its encode. alpha should always be lossless |
Joe Drago | 46ea058 | 2019-07-22 15:55:47 -0700 | [diff] [blame] | 126 | typedef avifBool (*avifCodecEncodeImageFunc)(struct avifCodec * codec, avifImage * image, avifEncoder * encoder, avifRawData * obu, avifBool alpha); |
| 127 | typedef void (*avifCodecGetConfigurationBoxFunc)(struct avifCodec * codec, avifCodecConfigurationBox * outConfig); |
Joe Drago | 7a9a661 | 2019-07-17 11:21:24 -0700 | [diff] [blame] | 128 | typedef void (*avifCodecDestroyInternalFunc)(struct avifCodec * codec); |
Joe Drago | 3533b97 | 2019-07-12 14:32:20 -0700 | [diff] [blame] | 129 | |
Joe Drago | 33f1d36 | 2019-02-13 16:46:22 -0800 | [diff] [blame] | 130 | typedef struct avifCodec |
| 131 | { |
Joe Drago | 46ea058 | 2019-07-22 15:55:47 -0700 | [diff] [blame] | 132 | avifCodecDecodeInput * decodeInput; |
Joe Drago | 33f1d36 | 2019-02-13 16:46:22 -0800 | [diff] [blame] | 133 | struct avifCodecInternal * internal; // up to each codec to use how it wants |
Joe Drago | 3533b97 | 2019-07-12 14:32:20 -0700 | [diff] [blame] | 134 | |
| 135 | avifCodecDecodeFunc decode; |
Joe Drago | 3533b97 | 2019-07-12 14:32:20 -0700 | [diff] [blame] | 136 | avifCodecAlphaLimitedRangeFunc alphaLimitedRange; |
Joe Drago | 46ea058 | 2019-07-22 15:55:47 -0700 | [diff] [blame] | 137 | avifCodecGetNextImageFunc getNextImage; |
Joe Drago | 3533b97 | 2019-07-12 14:32:20 -0700 | [diff] [blame] | 138 | avifCodecEncodeImageFunc encodeImage; |
| 139 | avifCodecGetConfigurationBoxFunc getConfigurationBox; |
| 140 | avifCodecDestroyInternalFunc destroyInternal; |
Joe Drago | 33f1d36 | 2019-02-13 16:46:22 -0800 | [diff] [blame] | 141 | } avifCodec; |
| 142 | |
Joe Drago | 399df4f | 2019-07-23 16:45:14 -0700 | [diff] [blame^] | 143 | avifCodec * avifCodecCreateAOM(void); // requires AVIF_CODEC_AOM |
| 144 | avifCodec * avifCodecCreateDav1d(void); // requires AVIF_CODEC_DAV1D |
Joe Drago | 33f1d36 | 2019-02-13 16:46:22 -0800 | [diff] [blame] | 145 | void avifCodecDestroy(avifCodec * codec); |
| 146 | |
Joe Drago | 33f1d36 | 2019-02-13 16:46:22 -0800 | [diff] [blame] | 147 | // --------------------------------------------------------------------------- |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 148 | // avifStream |
| 149 | |
| 150 | typedef size_t avifBoxMarker; |
| 151 | |
| 152 | typedef struct avifStream |
| 153 | { |
| 154 | avifRawData * raw; |
| 155 | size_t offset; |
| 156 | } avifStream; |
| 157 | |
Joe Drago | 8f7a300 | 2019-02-07 19:35:37 -0800 | [diff] [blame] | 158 | typedef struct avifBoxHeader |
| 159 | { |
| 160 | size_t size; |
| 161 | uint8_t type[4]; |
| 162 | } avifBoxHeader; |
| 163 | |
| 164 | uint8_t * avifStreamCurrent(avifStream * stream); |
| 165 | |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 166 | void avifStreamStart(avifStream * stream, avifRawData * raw); |
| 167 | |
| 168 | // Read |
| 169 | avifBool avifStreamHasBytesLeft(avifStream * stream, size_t byteCount); |
Joe Drago | 8f7a300 | 2019-02-07 19:35:37 -0800 | [diff] [blame] | 170 | size_t avifStreamRemainingBytes(avifStream * stream); |
Joe Drago | eb652d8 | 2019-04-23 16:29:07 -0700 | [diff] [blame] | 171 | size_t avifStreamOffset(avifStream * stream); |
| 172 | void avifStreamSetOffset(avifStream * stream, size_t offset); |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 173 | avifBool avifStreamSkip(avifStream * stream, size_t byteCount); |
| 174 | avifBool avifStreamRead(avifStream * stream, uint8_t * data, size_t size); |
| 175 | avifBool avifStreamReadU16(avifStream * stream, uint16_t * v); |
| 176 | avifBool avifStreamReadU32(avifStream * stream, uint32_t * v); |
| 177 | avifBool avifStreamReadUX8(avifStream * stream, uint64_t * v, uint64_t factor); // Reads a factor*8 sized uint, saves in v |
| 178 | avifBool avifStreamReadU64(avifStream * stream, uint64_t * v); |
Joe Drago | cd1e4c3 | 2019-02-08 11:26:31 -0800 | [diff] [blame] | 179 | avifBool avifStreamReadString(avifStream * stream, char * output, size_t outputSize); |
Joe Drago | 8f7a300 | 2019-02-07 19:35:37 -0800 | [diff] [blame] | 180 | avifBool avifStreamReadBoxHeader(avifStream * stream, avifBoxHeader * header); |
| 181 | avifBool avifStreamReadVersionAndFlags(avifStream * stream, uint8_t * version, uint8_t * flags); // flags is an optional uint8_t[3] |
| 182 | avifBool avifStreamReadAndEnforceVersion(avifStream * stream, uint8_t enforcedVersion); // currently discards flags |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 183 | |
| 184 | // Write |
| 185 | void avifStreamFinishWrite(avifStream * stream); |
| 186 | void avifStreamWrite(avifStream * stream, const uint8_t * data, size_t size); |
Joe Drago | ea252af | 2019-02-12 12:08:38 -0800 | [diff] [blame] | 187 | void avifStreamWriteChars(avifStream * stream, const char * chars, size_t size); |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 188 | avifBoxMarker avifStreamWriteBox(avifStream * stream, const char * type, int version /* -1 for "not a FullBox" */, size_t contentSize); |
| 189 | void avifStreamFinishBox(avifStream * stream, avifBoxMarker marker); |
Joe Drago | c36192a | 2019-01-23 18:50:25 -0800 | [diff] [blame] | 190 | void avifStreamWriteU8(avifStream * stream, uint8_t v); |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 191 | void avifStreamWriteU16(avifStream * stream, uint16_t v); |
| 192 | void avifStreamWriteU32(avifStream * stream, uint32_t v); |
| 193 | void avifStreamWriteZeros(avifStream * stream, size_t byteCount); |
| 194 | |
Joe Drago | c0d3d66 | 2019-04-12 14:10:16 -0700 | [diff] [blame] | 195 | #ifdef __cplusplus |
| 196 | } // extern "C" |
| 197 | #endif |
| 198 | |
Joe Drago | 444f051 | 2019-01-23 17:03:24 -0800 | [diff] [blame] | 199 | #endif // ifndef AVIF_INTERNAL_H |