forked from AOMediaCodec/libavif
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathavif.h
1645 lines (1413 loc) · 81.6 KB
/
avif.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Copyright 2019 Joe Drago. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause
#ifndef AVIF_AVIF_H
#define AVIF_AVIF_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// ---------------------------------------------------------------------------
// Export macros
// AVIF_BUILDING_SHARED_LIBS should only be defined when libavif is being built
// as a shared library.
// AVIF_DLL should be defined if libavif is a shared library. If you are using
// libavif as a CMake dependency, through a CMake package config file or through
// pkg-config, this is defined automatically.
//
// Here's what AVIF_API will be defined as in shared build:
// | | Windows | Unix |
// | Build | __declspec(dllexport) | __attribute__((visibility("default"))) |
// | Use | __declspec(dllimport) | |
//
// For static build, AVIF_API is always defined as nothing.
#if defined(_WIN32)
#define AVIF_HELPER_EXPORT __declspec(dllexport)
#define AVIF_HELPER_IMPORT __declspec(dllimport)
#elif defined(__GNUC__) && __GNUC__ >= 4
#define AVIF_HELPER_EXPORT __attribute__((visibility("default")))
#define AVIF_HELPER_IMPORT
#else
#define AVIF_HELPER_EXPORT
#define AVIF_HELPER_IMPORT
#endif
#if defined(AVIF_DLL)
#if defined(AVIF_BUILDING_SHARED_LIBS)
#define AVIF_API AVIF_HELPER_EXPORT
#else
#define AVIF_API AVIF_HELPER_IMPORT
#endif // defined(AVIF_BUILDING_SHARED_LIBS)
#else
#define AVIF_API
#endif // defined(AVIF_DLL)
// [[nodiscard]] requires C++17 and C23.
//
// If the -std=c2x or -std=gnu2x option is specified, __STDC_VERSION__ is
// * 202000L in GCC 13.2.0, Clang 16.0.6, and Apple Clang 15.0.0; or
// * 202311L in Clang 19.0.0git.
// If the /std:clatest option is specified, __STDC_VERSION__ is
// * 202312L in Microsoft Visual Studio 17.10.5.
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L)
#define AVIF_NODISCARD [[nodiscard]]
#else
// Starting with 3.9, clang allows defining the warn_unused_result attribute for enums.
#if defined(__clang__) && defined(__has_attribute) && ((__clang_major__ << 8) | __clang_minor__) >= ((3 << 8) | 9)
#if __has_attribute(warn_unused_result)
#define AVIF_NODISCARD __attribute__((warn_unused_result))
#else
#define AVIF_NODISCARD
#endif
#else
#define AVIF_NODISCARD
#endif
#endif
// ---------------------------------------------------------------------------
// Constants
// AVIF_VERSION_DEVEL should always be 0 for official releases / version tags,
// and non-zero during development of the next release. This should allow for
// downstream projects to do greater-than preprocessor checks on AVIF_VERSION
// to leverage in-development code without breaking their stable builds.
#define AVIF_VERSION_MAJOR 1
#define AVIF_VERSION_MINOR 1
#define AVIF_VERSION_PATCH 1
#define AVIF_VERSION_DEVEL 1
#define AVIF_VERSION \
((AVIF_VERSION_MAJOR * 1000000) + (AVIF_VERSION_MINOR * 10000) + (AVIF_VERSION_PATCH * 100) + AVIF_VERSION_DEVEL)
typedef int avifBool;
#define AVIF_TRUE 1
#define AVIF_FALSE 0
#define AVIF_DIAGNOSTICS_ERROR_BUFFER_SIZE 256
// A reasonable default for maximum image size (in pixel count) to avoid out-of-memory errors or
// integer overflow in (32-bit) int or unsigned int arithmetic operations.
#define AVIF_DEFAULT_IMAGE_SIZE_LIMIT (16384 * 16384)
// A reasonable default for maximum image dimension (width or height).
#define AVIF_DEFAULT_IMAGE_DIMENSION_LIMIT 32768
// a 12 hour AVIF image sequence, running at 60 fps (a basic sanity check as this is quite ridiculous)
#define AVIF_DEFAULT_IMAGE_COUNT_LIMIT (12 * 3600 * 60)
#define AVIF_QUALITY_DEFAULT -1
#define AVIF_QUALITY_LOSSLESS 100
#define AVIF_QUALITY_WORST 0
#define AVIF_QUALITY_BEST 100
#define AVIF_QUANTIZER_LOSSLESS 0
#define AVIF_QUANTIZER_BEST_QUALITY 0
#define AVIF_QUANTIZER_WORST_QUALITY 63
#define AVIF_PLANE_COUNT_YUV 3
#define AVIF_SPEED_DEFAULT -1
#define AVIF_SPEED_SLOWEST 0
#define AVIF_SPEED_FASTEST 10
// This value is used to indicate that an animated AVIF file has to be repeated infinitely.
#define AVIF_REPETITION_COUNT_INFINITE -1
// This value is used if an animated AVIF file does not have repetitions specified using an EditList box. Applications can choose
// to handle this case however they want.
#define AVIF_REPETITION_COUNT_UNKNOWN -2
// The number of spatial layers in AV1, with spatial_id = 0..3.
#define AVIF_MAX_AV1_LAYER_COUNT 4
typedef enum avifPlanesFlag
{
AVIF_PLANES_YUV = (1 << 0),
AVIF_PLANES_A = (1 << 1),
AVIF_PLANES_ALL = 0xff
} avifPlanesFlag;
typedef uint32_t avifPlanesFlags;
typedef enum avifChannelIndex
{
// These can be used as the index for the yuvPlanes and yuvRowBytes arrays in avifImage.
AVIF_CHAN_Y = 0,
AVIF_CHAN_U = 1,
AVIF_CHAN_V = 2,
// This may not be used in yuvPlanes and yuvRowBytes, but is available for use with avifImagePlane().
AVIF_CHAN_A = 3
} avifChannelIndex;
// ---------------------------------------------------------------------------
// Version
AVIF_API const char * avifVersion(void);
AVIF_API void avifCodecVersions(char outBuffer[256]);
AVIF_API unsigned int avifLibYUVVersion(void); // returns 0 if libavif wasn't compiled with libyuv support
// ---------------------------------------------------------------------------
// Memory management
// Returns NULL on memory allocation failure.
AVIF_API void * avifAlloc(size_t size);
AVIF_API void avifFree(void * p);
// ---------------------------------------------------------------------------
// avifResult
typedef enum AVIF_NODISCARD avifResult
{
AVIF_RESULT_OK = 0,
AVIF_RESULT_UNKNOWN_ERROR = 1,
AVIF_RESULT_INVALID_FTYP = 2,
AVIF_RESULT_NO_CONTENT = 3,
AVIF_RESULT_NO_YUV_FORMAT_SELECTED = 4,
AVIF_RESULT_REFORMAT_FAILED = 5,
AVIF_RESULT_UNSUPPORTED_DEPTH = 6,
AVIF_RESULT_ENCODE_COLOR_FAILED = 7,
AVIF_RESULT_ENCODE_ALPHA_FAILED = 8,
AVIF_RESULT_BMFF_PARSE_FAILED = 9,
AVIF_RESULT_MISSING_IMAGE_ITEM = 10,
AVIF_RESULT_DECODE_COLOR_FAILED = 11,
AVIF_RESULT_DECODE_ALPHA_FAILED = 12,
AVIF_RESULT_COLOR_ALPHA_SIZE_MISMATCH = 13,
AVIF_RESULT_ISPE_SIZE_MISMATCH = 14,
AVIF_RESULT_NO_CODEC_AVAILABLE = 15,
AVIF_RESULT_NO_IMAGES_REMAINING = 16,
AVIF_RESULT_INVALID_EXIF_PAYLOAD = 17,
AVIF_RESULT_INVALID_IMAGE_GRID = 18,
AVIF_RESULT_INVALID_CODEC_SPECIFIC_OPTION = 19,
AVIF_RESULT_TRUNCATED_DATA = 20,
AVIF_RESULT_IO_NOT_SET = 21, // the avifIO field of avifDecoder is not set
AVIF_RESULT_IO_ERROR = 22,
AVIF_RESULT_WAITING_ON_IO = 23, // similar to EAGAIN/EWOULDBLOCK, this means the avifIO doesn't have necessary data available yet
AVIF_RESULT_INVALID_ARGUMENT = 24, // an argument passed into this function is invalid
AVIF_RESULT_NOT_IMPLEMENTED = 25, // a requested code path is not (yet) implemented
AVIF_RESULT_OUT_OF_MEMORY = 26,
AVIF_RESULT_CANNOT_CHANGE_SETTING = 27, // a setting that can't change is changed during encoding
AVIF_RESULT_INCOMPATIBLE_IMAGE = 28, // the image is incompatible with already encoded images
AVIF_RESULT_INTERNAL_ERROR = 29, // some invariants have not been satisfied (likely a bug in libavif)
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
AVIF_RESULT_ENCODE_GAIN_MAP_FAILED = 30,
AVIF_RESULT_DECODE_GAIN_MAP_FAILED = 31,
AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE = 32,
#endif
#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
AVIF_RESULT_ENCODE_SAMPLE_TRANSFORM_FAILED = 33,
AVIF_RESULT_DECODE_SAMPLE_TRANSFORM_FAILED = 34,
#endif
// Kept for backward compatibility; please use the symbols above instead.
AVIF_RESULT_NO_AV1_ITEMS_FOUND = AVIF_RESULT_MISSING_IMAGE_ITEM
} avifResult;
AVIF_API const char * avifResultToString(avifResult result);
// ---------------------------------------------------------------------------
// avifHeaderFormat
typedef enum avifHeaderFormat
{
// AVIF file with an "avif" brand, a MetaBox and all its required boxes for maximum compatibility.
AVIF_HEADER_FULL,
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
// AVIF file with a "mif3" brand and a MinimizedImageBox to reduce the encoded file size.
// This is based on the w24144 "Low-overhead image file format" MPEG proposal for HEIF.
// WARNING: Experimental feature. Produces files that are incompatible with older decoders.
AVIF_HEADER_REDUCED,
#endif
} avifHeaderFormat;
// ---------------------------------------------------------------------------
// avifROData/avifRWData: Generic raw memory storage
typedef struct avifROData
{
const uint8_t * data;
size_t size;
} avifROData;
// Note: Use avifRWDataFree() if any avif*() function populates one of these.
typedef struct avifRWData
{
uint8_t * data;
size_t size;
} avifRWData;
// clang-format off
// Initialize avifROData/avifRWData on the stack with this
#define AVIF_DATA_EMPTY { NULL, 0 }
// clang-format on
// The avifRWData input must be zero-initialized before being manipulated with these functions.
// If AVIF_RESULT_OUT_OF_MEMORY is returned, raw is left unchanged.
AVIF_API avifResult avifRWDataRealloc(avifRWData * raw, size_t newSize);
AVIF_API avifResult avifRWDataSet(avifRWData * raw, const uint8_t * data, size_t len);
AVIF_API void avifRWDataFree(avifRWData * raw);
// ---------------------------------------------------------------------------
// Metadata
// Validates the first bytes of the Exif payload and finds the TIFF header offset (up to UINT32_MAX).
AVIF_API avifResult avifGetExifTiffHeaderOffset(const uint8_t * exif, size_t exifSize, size_t * offset);
// Returns the offset to the Exif 8-bit orientation value and AVIF_RESULT_OK, or an error.
// If the offset is set to exifSize, there was no parsing error but no orientation tag was found.
AVIF_API avifResult avifGetExifOrientationOffset(const uint8_t * exif, size_t exifSize, size_t * offset);
// ---------------------------------------------------------------------------
// avifPixelFormat
//
// Note to libavif maintainers: The lookup tables in avifImageYUVToRGBLibYUV
// rely on the ordering of this enum values for their correctness. So changing
// the values in this enum will require auditing avifImageYUVToRGBLibYUV for
// correctness.
typedef enum avifPixelFormat
{
// No YUV pixels are present. Alpha plane can still be present.
AVIF_PIXEL_FORMAT_NONE = 0,
AVIF_PIXEL_FORMAT_YUV444,
AVIF_PIXEL_FORMAT_YUV422,
AVIF_PIXEL_FORMAT_YUV420,
AVIF_PIXEL_FORMAT_YUV400,
AVIF_PIXEL_FORMAT_COUNT
} avifPixelFormat;
AVIF_API const char * avifPixelFormatToString(avifPixelFormat format);
typedef struct avifPixelFormatInfo
{
avifBool monochrome;
int chromaShiftX;
int chromaShiftY;
} avifPixelFormatInfo;
// Returns the avifPixelFormatInfo depending on the avifPixelFormat.
// When monochrome is AVIF_TRUE, chromaShiftX and chromaShiftY are set to 1 according to the AV1 specification but they should be ignored.
//
// Note: This function implements the second table on page 119 of the AV1 specification version 1.0.0 with Errata 1.
// For monochrome 4:0:0, subsampling_x and subsampling are specified as 1 to allow
// an AV1 implementation that only supports profile 0 to hardcode subsampling_x and subsampling_y to 1.
AVIF_API void avifGetPixelFormatInfo(avifPixelFormat format, avifPixelFormatInfo * info);
// ---------------------------------------------------------------------------
// avifChromaSamplePosition
typedef enum avifChromaSamplePosition
{
AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN = 0,
AVIF_CHROMA_SAMPLE_POSITION_VERTICAL = 1,
AVIF_CHROMA_SAMPLE_POSITION_COLOCATED = 2,
AVIF_CHROMA_SAMPLE_POSITION_RESERVED = 3
} avifChromaSamplePosition;
// ---------------------------------------------------------------------------
// avifRange
typedef enum avifRange
{
// avifRange is only applicable to YUV planes. RGB and alpha planes are always full range.
AVIF_RANGE_LIMITED = 0, /**<- Y [16..235], UV [16..240] (bit depth 8) */
/**<- Y [64..940], UV [64..960] (bit depth 10) */
/**<- Y [256..3760], UV [256..3840] (bit depth 12) */
AVIF_RANGE_FULL = 1 /**<- [0..255] (bit depth 8) */
/**<- [0..1023] (bit depth 10) */
/**<- [0..4095] (bit depth 12) */
} avifRange;
// ---------------------------------------------------------------------------
// CICP enums - https://www.itu.int/rec/T-REC-H.273-201612-S/en
enum
{
// This is actually reserved, but libavif uses it as a sentinel value.
AVIF_COLOR_PRIMARIES_UNKNOWN = 0,
AVIF_COLOR_PRIMARIES_BT709 = 1,
AVIF_COLOR_PRIMARIES_SRGB = 1,
AVIF_COLOR_PRIMARIES_IEC61966_2_4 = 1,
AVIF_COLOR_PRIMARIES_UNSPECIFIED = 2,
AVIF_COLOR_PRIMARIES_BT470M = 4,
AVIF_COLOR_PRIMARIES_BT470BG = 5,
AVIF_COLOR_PRIMARIES_BT601 = 6,
AVIF_COLOR_PRIMARIES_SMPTE240 = 7,
AVIF_COLOR_PRIMARIES_GENERIC_FILM = 8,
AVIF_COLOR_PRIMARIES_BT2020 = 9,
AVIF_COLOR_PRIMARIES_BT2100 = 9,
AVIF_COLOR_PRIMARIES_XYZ = 10,
AVIF_COLOR_PRIMARIES_SMPTE431 = 11,
AVIF_COLOR_PRIMARIES_SMPTE432 = 12,
AVIF_COLOR_PRIMARIES_DCI_P3 = 12,
AVIF_COLOR_PRIMARIES_EBU3213 = 22
};
typedef uint16_t avifColorPrimaries; // AVIF_COLOR_PRIMARIES_*
// outPrimaries: rX, rY, gX, gY, bX, bY, wX, wY
AVIF_API void avifColorPrimariesGetValues(avifColorPrimaries acp, float outPrimaries[8]);
AVIF_API avifColorPrimaries avifColorPrimariesFind(const float inPrimaries[8], const char ** outName);
enum
{
// This is actually reserved, but libavif uses it as a sentinel value.
AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN = 0,
AVIF_TRANSFER_CHARACTERISTICS_BT709 = 1,
AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED = 2,
AVIF_TRANSFER_CHARACTERISTICS_BT470M = 4, // 2.2 gamma
AVIF_TRANSFER_CHARACTERISTICS_BT470BG = 5, // 2.8 gamma
AVIF_TRANSFER_CHARACTERISTICS_BT601 = 6,
AVIF_TRANSFER_CHARACTERISTICS_SMPTE240 = 7,
AVIF_TRANSFER_CHARACTERISTICS_LINEAR = 8,
AVIF_TRANSFER_CHARACTERISTICS_LOG100 = 9,
AVIF_TRANSFER_CHARACTERISTICS_LOG100_SQRT10 = 10,
AVIF_TRANSFER_CHARACTERISTICS_IEC61966 = 11,
AVIF_TRANSFER_CHARACTERISTICS_BT1361 = 12,
AVIF_TRANSFER_CHARACTERISTICS_SRGB = 13,
AVIF_TRANSFER_CHARACTERISTICS_BT2020_10BIT = 14,
AVIF_TRANSFER_CHARACTERISTICS_BT2020_12BIT = 15,
AVIF_TRANSFER_CHARACTERISTICS_PQ = 16, // Perceptual Quantizer (HDR); BT.2100 PQ
AVIF_TRANSFER_CHARACTERISTICS_SMPTE2084 = 16,
AVIF_TRANSFER_CHARACTERISTICS_SMPTE428 = 17,
AVIF_TRANSFER_CHARACTERISTICS_HLG = 18 // Hybrid Log-Gamma (HDR); ARIB STD-B67; BT.2100 HLG
};
typedef uint16_t avifTransferCharacteristics; // AVIF_TRANSFER_CHARACTERISTICS_*
// If the given transfer characteristics can be expressed with a simple gamma value, sets 'gamma'
// to that value and returns AVIF_RESULT_OK. Returns an error otherwise.
AVIF_API avifResult avifTransferCharacteristicsGetGamma(avifTransferCharacteristics atc, float * gamma);
AVIF_API avifTransferCharacteristics avifTransferCharacteristicsFindByGamma(float gamma);
enum
{
AVIF_MATRIX_COEFFICIENTS_IDENTITY = 0,
AVIF_MATRIX_COEFFICIENTS_BT709 = 1,
AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED = 2,
AVIF_MATRIX_COEFFICIENTS_FCC = 4,
AVIF_MATRIX_COEFFICIENTS_BT470BG = 5,
AVIF_MATRIX_COEFFICIENTS_BT601 = 6,
AVIF_MATRIX_COEFFICIENTS_SMPTE240 = 7,
AVIF_MATRIX_COEFFICIENTS_YCGCO = 8,
AVIF_MATRIX_COEFFICIENTS_BT2020_NCL = 9,
AVIF_MATRIX_COEFFICIENTS_BT2020_CL = 10,
AVIF_MATRIX_COEFFICIENTS_SMPTE2085 = 11,
AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_NCL = 12,
AVIF_MATRIX_COEFFICIENTS_CHROMA_DERIVED_CL = 13,
AVIF_MATRIX_COEFFICIENTS_ICTCP = 14,
#if defined(AVIF_ENABLE_EXPERIMENTAL_YCGCO_R)
AVIF_MATRIX_COEFFICIENTS_YCGCO_RE = 16,
AVIF_MATRIX_COEFFICIENTS_YCGCO_RO = 17,
#endif
AVIF_MATRIX_COEFFICIENTS_LAST
};
typedef uint16_t avifMatrixCoefficients; // AVIF_MATRIX_COEFFICIENTS_*
// ---------------------------------------------------------------------------
// avifDiagnostics
typedef struct avifDiagnostics
{
// Upon receiving an error from any non-const libavif API call, if the toplevel structure used
// in the API call (avifDecoder, avifEncoder) contains a diag member, this buffer may be
// populated with a NULL-terminated, freeform error string explaining the first encountered error in
// more detail. It will be cleared at the beginning of every non-const API call.
//
// Note: If an error string contains the "[Strict]" prefix, it means that you encountered an
// error that only occurs during strict decoding. If you disable strict mode, you will no
// longer encounter this error.
char error[AVIF_DIAGNOSTICS_ERROR_BUFFER_SIZE];
} avifDiagnostics;
AVIF_API void avifDiagnosticsClearError(avifDiagnostics * diag);
// ---------------------------------------------------------------------------
// Fraction utilities
typedef struct avifFraction
{
int32_t n;
int32_t d;
} avifFraction;
typedef struct avifSignedFraction
{
int32_t n;
uint32_t d;
} avifSignedFraction;
typedef struct avifUnsignedFraction
{
uint32_t n;
uint32_t d;
} avifUnsignedFraction;
// Creates an int32/uint32 fraction that is approximately equal to 'v'.
// Returns AVIF_FALSE if 'v' is NaN or abs(v) is > INT32_MAX.
AVIF_NODISCARD AVIF_API avifBool avifDoubleToSignedFraction(double v, avifSignedFraction * fraction);
// Creates a uint32/uint32 fraction that is approximately equal to 'v'.
// Returns AVIF_FALSE if 'v' is < 0 or > UINT32_MAX or NaN.
AVIF_NODISCARD AVIF_API avifBool avifDoubleToUnsignedFraction(double v, avifUnsignedFraction * fraction);
// ---------------------------------------------------------------------------
// Optional transformation structs
typedef enum avifTransformFlag
{
AVIF_TRANSFORM_NONE = 0,
AVIF_TRANSFORM_PASP = (1 << 0),
AVIF_TRANSFORM_CLAP = (1 << 1),
AVIF_TRANSFORM_IROT = (1 << 2),
AVIF_TRANSFORM_IMIR = (1 << 3)
} avifTransformFlag;
typedef uint32_t avifTransformFlags;
typedef struct avifPixelAspectRatioBox
{
// 'pasp' from ISO/IEC 14496-12:2022 12.1.4.3
// define the relative width and height of a pixel
uint32_t hSpacing;
uint32_t vSpacing;
} avifPixelAspectRatioBox;
// NOTE: The members of the avifCleanApertureBox struct are declared as uint32_t to match the
// unsigned int(32) type used in ISO/IEC 14496-12:2022 faithfully. However, ISO/IEC 14496-12:2022
// 12.1.4.1 clearly interprets these values as signed int(32) and talks about them being strictly
// positive, positive, or negative. Cast these struct members to int32_t before use. See also the
// clean aperture extension in the QuickTime File Format:
// https://developer.apple.com/documentation/quicktime-file-format/clean_aperture
typedef struct avifCleanApertureBox
{
// 'clap' from ISO/IEC 14496-12:2022 12.1.4.3
// a fractional number which defines the width of the clean aperture image
uint32_t widthN;
uint32_t widthD;
// a fractional number which defines the height of the clean aperture image
uint32_t heightN;
uint32_t heightD;
// a fractional number which defines the horizontal offset between the clean aperture image
// centre and the full aperture image centre. Typically 0.
uint32_t horizOffN;
uint32_t horizOffD;
// a fractional number which defines the vertical offset between clean aperture image centre
// and the full aperture image centre. Typically 0.
uint32_t vertOffN;
uint32_t vertOffD;
} avifCleanApertureBox;
typedef struct avifImageRotation
{
// 'irot' from ISO/IEC 23008-12:2017 6.5.10
// angle * 90 specifies the angle (in anti-clockwise direction) in units of degrees.
uint8_t angle; // legal values: [0-3]
} avifImageRotation;
typedef struct avifImageMirror
{
// 'imir' from ISO/IEC 23008-12:2022 6.5.12:
//
// 'axis' specifies how the mirroring is performed:
//
// 0 indicates that the top and bottom parts of the image are exchanged;
// 1 specifies that the left and right parts are exchanged.
//
// NOTE In Exif, orientation tag can be used to signal mirroring operations. Exif
// orientation tag 4 corresponds to axis = 0 of ImageMirror, and Exif orientation tag 2
// corresponds to axis = 1 accordingly.
//
// Legal values: [0, 1]
uint8_t axis;
} avifImageMirror;
// ---------------------------------------------------------------------------
// avifCropRect - Helper struct/functions to work with avifCleanApertureBox
typedef struct avifCropRect
{
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
} avifCropRect;
// These will return AVIF_FALSE if the resultant values violate any standards, and if so, the output
// values are not guaranteed to be complete or correct and should not be used.
AVIF_NODISCARD AVIF_API avifBool avifCropRectConvertCleanApertureBox(avifCropRect * cropRect,
const avifCleanApertureBox * clap,
uint32_t imageW,
uint32_t imageH,
avifPixelFormat yuvFormat,
avifDiagnostics * diag);
AVIF_NODISCARD AVIF_API avifBool avifCleanApertureBoxConvertCropRect(avifCleanApertureBox * clap,
const avifCropRect * cropRect,
uint32_t imageW,
uint32_t imageH,
avifPixelFormat yuvFormat,
avifDiagnostics * diag);
// ---------------------------------------------------------------------------
// avifContentLightLevelInformationBox
typedef struct avifContentLightLevelInformationBox
{
// 'clli' from ISO/IEC 23000-22:2019 (MIAF) 7.4.4.2.2. The SEI message semantics written above
// each entry were originally described in ISO/IEC 23008-2:2020 (HEVC) section D.3.35,
// available at https://standards.iso.org/ittf/PubliclyAvailableStandards/
// Given the red, green, and blue colour primary intensities in the linear light domain for the
// location of a luma sample in a corresponding 4:4:4 representation, denoted as E_R, E_G, and E_B,
// the maximum component intensity is defined as E_Max = Max(E_R, Max(E_G, E_B)).
// The light level corresponding to the stimulus is then defined as the CIE 1931 luminance
// corresponding to equal amplitudes of E_Max for all three colour primary intensities for red,
// green, and blue (with appropriate scaling to reflect the nominal luminance level associated
// with peak white, e.g. ordinarily scaling to associate peak white with 10 000 candelas per
// square metre when transfer_characteristics is equal to 16).
// max_content_light_level, when not equal to 0, indicates an upper bound on the maximum light
// level among all individual samples in a 4:4:4 representation of red, green, and blue colour
// primary intensities (in the linear light domain) for the pictures of the CLVS, in units of
// candelas per square metre. When equal to 0, no such upper bound is indicated by
// max_content_light_level.
uint16_t maxCLL;
// max_pic_average_light_level, when not equal to 0, indicates an upper bound on the maximum
// average light level among the samples in a 4:4:4 representation of red, green, and blue
// colour primary intensities (in the linear light domain) for any individual picture of the
// CLVS, in units of candelas per square metre. When equal to 0, no such upper bound is
// indicated by max_pic_average_light_level.
uint16_t maxPALL;
} avifContentLightLevelInformationBox;
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
// ---------------------------------------------------------------------------
// avifGainMap
// Gain Maps are a solution for a consistent and adaptive display of HDR images.
// Gain Maps are a HIGHLY EXPERIMENTAL FEATURE. The format might still change and
// images containing a gain map encoded with the current version of libavif might
// not decode with a future version of libavif. The API is not guaranteed
// to be stable, and might even be removed in the future. Use at your own risk.
// This is based on ISO/IEC JTC 1/SC 29/WG 3 m64379
// This product includes Gain Map technology under license by Adobe.
//
// Terms:
// base image: main image stored in the file, shown by viewers that do not support
// gain maps
// alternate image: image obtained by combining the base image and the gain map
// gain map: data structure that contains pixels and metadata used for conversion
// between the base image and the alternate image
struct avifImage;
// Gain map image and associated metadata.
// Must be allocated by calling avifGainMapCreate().
typedef struct avifGainMap
{
// Gain map pixels.
// Owned by the avifGainMap and gets freed when calling avifGainMapDestroy().
// Used fields: width, height, depth, yuvFormat, yuvRange,
// yuvChromaSamplePosition, yuvPlanes, yuvRowBytes, imageOwnsYUVPlanes,
// matrixCoefficients. The colorPrimaries and transferCharacteristics fields
// shall be 2. Other fields are ignored.
struct avifImage * image;
// Gain map metadata used to interpret and apply the gain map pixel data.
// When encoding an image grid, all metadata below shall be identical for all
// cells.
// Parameters for converting the gain map from its image encoding to log2 space.
// gainMapLog2 = lerp(gainMapMin, gainMapMax, pow(gainMapEncoded, gainMapGamma));
// where 'lerp' is a linear interpolation function.
// Minimum value in the gain map, log2-encoded, per RGB channel.
avifSignedFraction gainMapMin[3];
// Maximum value in the gain map, log2-encoded, per RGB channel.
avifSignedFraction gainMapMax[3];
// Gain map gamma value with which the gain map was encoded, per RGB channel.
// For decoding, the inverse value (1/gamma) should be used.
avifUnsignedFraction gainMapGamma[3];
// Parameters used in gain map computation/tone mapping to avoid numerical
// instability.
// toneMappedLinear = ((baseImageLinear + baseOffset) * exp(gainMapLog * w)) - alternateOffset;
// Where 'w' is a weight parameter based on the display's HDR capacity
// (see below).
// Offset constants for the base image, per RGB channel.
avifSignedFraction baseOffset[3];
// Offset constants for the alternate image, per RGB channel.
avifSignedFraction alternateOffset[3];
// Log2-encoded HDR headroom of the base and alternate images respectively.
// If baseHdrHeadroom is < alternateHdrHeadroom, the result of tone mapping
// for a display with an HDR headroom that is <= baseHdrHeadroom is the base
// image, and the result of tone mapping for a display with an HDR headroom >=
// alternateHdrHeadroom is the alternate image.
// Conversely, if baseHdrHeadroom is > alternateHdrHeadroom, the result of
// tone mapping for a display with an HDR headroom that is >= baseHdrHeadroom
// is the base image, and the result of tone mapping for a display with an HDR
// headroom <= alternateHdrHeadroom is the alternate image.
// For a display with a capacity between baseHdrHeadroom and alternateHdrHeadroom,
// tone mapping results in an interpolation between the base and alternate
// versions. baseHdrHeadroom and alternateHdrHeadroom can be tuned to change how
// the gain map should be applied.
//
// If 'H' is the display's current log2-encoded HDR capacity (HDR to SDR ratio),
// then the weight 'w' to apply the gain map is computed as follows:
// f = clamp((H - baseHdrHeadroom) /
// (alternateHdrHeadroom - baseHdrHeadroom), 0, 1);
// w = sign(alternateHdrHeadroom - baseHdrHeadroom) * f
avifUnsignedFraction baseHdrHeadroom;
avifUnsignedFraction alternateHdrHeadroom;
// True if tone mapping should be performed in the color space of the
// base image. If false, the color space of the alternate image should
// be used.
avifBool useBaseColorSpace;
// Colorimetry of the alternate image (ICC profile and/or CICP information
// of the alternate image that the gain map was created from).
avifRWData altICC;
avifColorPrimaries altColorPrimaries;
avifTransferCharacteristics altTransferCharacteristics;
avifMatrixCoefficients altMatrixCoefficients;
avifRange altYUVRange;
// Hint on the approximate amount of colour resolution available after fully
// applying the gain map ('pixi' box content of the alternate image that the
// gain map was created from).
uint32_t altDepth;
uint32_t altPlaneCount;
// Optimal viewing conditions of the alternate image ('clli' box content
// of the alternate image that the gain map was created from).
avifContentLightLevelInformationBox altCLLI;
} avifGainMap;
// Allocates a gain map. Returns NULL if a memory allocation failed.
// The 'image' field is NULL by default and must be allocated separately.
AVIF_API avifGainMap * avifGainMapCreate(void);
// Frees a gain map, including the 'image' field if non NULL.
AVIF_API void avifGainMapDestroy(avifGainMap * gainMap);
#endif // AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP
// ---------------------------------------------------------------------------
#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
// Sample Transforms are a HIGHLY EXPERIMENTAL FEATURE. The format might still
// change and images containing a sample transform item encoded with the current
// version of libavif might not decode with a future version of libavif.
// Use at your own risk.
// This is based on a proposal from the Alliance for Open Media.
typedef enum avifSampleTransformRecipe
{
AVIF_SAMPLE_TRANSFORM_NONE,
// Encode the 8 most significant bits of each input image sample losslessly
// into a base image. The remaining 8 least significant bits are encoded in
// a separate hidden image item. The two are combined at decoding into one
// image with the same bit depth as the original image. It is backward
// compatible in the sense that it is possible to decode only the base image
// (ignoring the hidden image item), leading to a valid image but with
// precision loss (16-bit samples truncated to the 8 most significant bits).
AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_8B_8B,
// Encode the 12 most significant bits of each input image sample losslessly
// into a base image. The remaining 4 least significant bits are encoded in
// a separate hidden image item. The two are combined at decoding into one
// image with the same bit depth as the original image. It is backward
// compatible in the sense that it is possible to decode only the base image
// (ignoring the hidden image item), leading to a valid image but with
// precision loss (16-bit samples truncated to the 12 most significant
// bits).
AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_4B,
// Encode the 12 most significant bits of each input image sample lossily or
// losslessly into a base image. The difference between the original and
// decoded values of these samples is encoded as a separate 8-bit hidden
// image item. The two are combined at decoding into one image with the same
// bit depth as the original image. It is backward compatible in the sense
// that it is possible to decode only the base image (ignoring the hidden
// image item), leading to a valid image but with loss due to precision
// truncation and/or compression.
AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_8B_OVERLAP_4B
} avifSampleTransformRecipe;
#endif // AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM
// ---------------------------------------------------------------------------
// avifImage
// NOTE: The avifImage struct may be extended in a future release. Code outside the libavif library
// must allocate avifImage by calling the avifImageCreate() or avifImageCreateEmpty() function.
typedef struct avifImage
{
// Image information
uint32_t width;
uint32_t height;
uint32_t depth; // all planes must share this depth; if depth>8, all planes are uint16_t internally
avifPixelFormat yuvFormat;
avifRange yuvRange;
avifChromaSamplePosition yuvChromaSamplePosition;
uint8_t * yuvPlanes[AVIF_PLANE_COUNT_YUV];
uint32_t yuvRowBytes[AVIF_PLANE_COUNT_YUV];
avifBool imageOwnsYUVPlanes;
uint8_t * alphaPlane;
uint32_t alphaRowBytes;
avifBool imageOwnsAlphaPlane;
avifBool alphaPremultiplied;
// ICC Profile
avifRWData icc;
// CICP information:
// These are stored in the AV1 payload and used to signal YUV conversion. Additionally, if an
// ICC profile is not specified, these will be stored in the AVIF container's `colr` box with
// a type of `nclx`. If your system supports ICC profiles, be sure to check for the existence
// of one (avifImage.icc) before relying on the values listed here!
avifColorPrimaries colorPrimaries;
avifTransferCharacteristics transferCharacteristics;
avifMatrixCoefficients matrixCoefficients;
// CLLI information:
// Content Light Level Information. Used to represent maximum and average light level of an
// image. Useful for tone mapping HDR images, especially when using transfer characteristics
// SMPTE2084 (PQ). The default value of (0, 0) means the content light level information is
// unknown or unavailable, and will cause libavif to avoid writing a clli box for it.
avifContentLightLevelInformationBox clli;
// Transformations - These metadata values are encoded/decoded when transformFlags are set
// appropriately, but do not impact/adjust the actual pixel buffers used (images won't be
// pre-cropped or mirrored upon decode). Basic explanations from the standards are offered in
// comments above, but for detailed explanations, please refer to the HEIF standard (ISO/IEC
// 23008-12:2017) and the BMFF standard (ISO/IEC 14496-12:2022).
//
// To encode any of these boxes, set the values in the associated box, then enable the flag in
// transformFlags. On decode, only honor the values in boxes with the associated transform flag set.
// These also apply to gainMap->image, if any.
avifTransformFlags transformFlags;
avifPixelAspectRatioBox pasp;
avifCleanApertureBox clap;
avifImageRotation irot;
avifImageMirror imir;
// Metadata - set with avifImageSetMetadata*() before write, check .size>0 for existence after read
avifRWData exif; // exif_payload chunk from the ExifDataBlock specified in ISO/IEC 23008-12:2022 Section A.2.1.
// The value of the 4-byte exif_tiff_header_offset field, which is not part of this avifRWData
// byte sequence, can be retrieved by calling avifGetExifTiffHeaderOffset(avifImage.exif).
avifRWData xmp;
// Version 1.0.0 ends here. Add any new members after this line.
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
// Gain map image and metadata. NULL if no gain map is present.
// Owned by the avifImage and gets freed when calling avifImageDestroy().
// gainMap->image->transformFlags is always AVIF_TRANSFORM_NONE.
avifGainMap * gainMap;
#endif
} avifImage;
// avifImageCreate() and avifImageCreateEmpty() return NULL if arguments are invalid or if a memory allocation failed.
AVIF_NODISCARD AVIF_API avifImage * avifImageCreate(uint32_t width, uint32_t height, uint32_t depth, avifPixelFormat yuvFormat);
AVIF_NODISCARD AVIF_API avifImage * avifImageCreateEmpty(void); // helper for making an image to decode into
// Performs a deep copy of an image, including all metadata and planes, and the gain map metadata/planes if present
// and if AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP is defined.
AVIF_API avifResult avifImageCopy(avifImage * dstImage, const avifImage * srcImage, avifPlanesFlags planes);
// Performs a shallow copy of a rectangular area of an image. 'dstImage' does not own the planes.
// Ignores the gainMap field (which exists only if AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP is defined).
AVIF_API avifResult avifImageSetViewRect(avifImage * dstImage, const avifImage * srcImage, const avifCropRect * rect);
AVIF_API void avifImageDestroy(avifImage * image);
AVIF_API avifResult avifImageSetProfileICC(avifImage * image, const uint8_t * icc, size_t iccSize);
// Sets Exif metadata. Attempts to parse the Exif metadata for Exif orientation. Sets
// image->transformFlags, image->irot and image->imir if the Exif metadata is parsed successfully,
// otherwise leaves image->transformFlags, image->irot and image->imir unchanged.
// Warning: If the Exif payload is set and invalid, avifEncoderWrite() may return AVIF_RESULT_INVALID_EXIF_PAYLOAD.
AVIF_API avifResult avifImageSetMetadataExif(avifImage * image, const uint8_t * exif, size_t exifSize);
// Sets XMP metadata.
AVIF_API avifResult avifImageSetMetadataXMP(avifImage * image, const uint8_t * xmp, size_t xmpSize);
// Allocate/free/steal planes. These functions ignore the gainMap field (which exists only if
// AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP is defined).
AVIF_API avifResult avifImageAllocatePlanes(avifImage * image, avifPlanesFlags planes); // Ignores any pre-existing planes
AVIF_API void avifImageFreePlanes(avifImage * image, avifPlanesFlags planes); // Ignores already-freed planes
AVIF_API void avifImageStealPlanes(avifImage * dstImage, avifImage * srcImage, avifPlanesFlags planes);
// ---------------------------------------------------------------------------
// Understanding maxThreads
//
// libavif's structures and API use the setting 'maxThreads' in a few places. The intent of this
// setting is to limit concurrent thread activity/usage, not necessarily to put a hard ceiling on
// how many sleeping threads happen to exist behind the scenes. The goal of this setting is to
// ensure that at any given point during libavif's encoding or decoding, no more than *maxThreads*
// threads are simultaneously **active and taking CPU time**.
//
// As an important example, when encoding an image sequence that has an alpha channel, two
// long-lived underlying AV1 encoders must simultaneously exist (one for color, one for alpha). For
// each additional frame fed into libavif, its YUV planes are fed into one instance of the AV1
// encoder, and its alpha plane is fed into another. These operations happen serially, so only one
// of these AV1 encoders is ever active at a time. However, the AV1 encoders might pre-create a
// pool of worker threads upon initialization, so during this process, twice the amount of worker
// threads actually simultaneously exist on the machine, but half of them are guaranteed to be
// sleeping.
//
// This design ensures that AV1 implementations are given as many threads as possible to ensure a
// speedy encode or decode, despite the complexities of occasionally needing two AV1 codec instances
// (due to alpha payloads being separate from color payloads). If your system has a hard ceiling on
// the number of threads that can ever be in flight at a given time, please account for this
// accordingly.
// ---------------------------------------------------------------------------
// Scaling
// Scales the YUV/A planes in-place. dstWidth and dstHeight must both be <= AVIF_DEFAULT_IMAGE_DIMENSION_LIMIT and
// dstWidth*dstHeight should be <= AVIF_DEFAULT_IMAGE_SIZE_LIMIT.
AVIF_API avifResult avifImageScale(avifImage * image, uint32_t dstWidth, uint32_t dstHeight, avifDiagnostics * diag);
// ---------------------------------------------------------------------------
// Optional YUV<->RGB support
// To convert to/from RGB, create an avifRGBImage on the stack, call avifRGBImageSetDefaults() on
// it, and then tweak the values inside of it accordingly. At a minimum, you should populate
// ->pixels and ->rowBytes with an appropriately sized pixel buffer, which should be at least
// (->rowBytes * ->height) bytes, where ->rowBytes is at least (->width * avifRGBImagePixelSize()).
// If you don't want to supply your own pixel buffer, you can use the
// avifRGBImageAllocatePixels()/avifRGBImageFreePixels() convenience functions.
// avifImageRGBToYUV() and avifImageYUVToRGB() will perform depth rescaling and limited<->full range
// conversion, if necessary. Pixels in an avifRGBImage buffer are always full range, and conversion
// routines will fail if the width and height don't match the associated avifImage.
// If libavif is built with a version of libyuv offering a fast conversion between RGB and YUV for
// the given inputs, libavif will use it. See reformat_libyuv.c for the details.
// libyuv is faster but may have slightly less precision than built-in conversion, so avoidLibYUV
// can be set to AVIF_TRUE when AVIF_CHROMA_UPSAMPLING_BEST_QUALITY or
// AVIF_CHROMA_DOWNSAMPLING_BEST_QUALITY is used, to get the most precise but slowest results.
// Note to libavif maintainers: The lookup tables in avifImageYUVToRGBLibYUV
// rely on the ordering of this enum values for their correctness. So changing
// the values in this enum will require auditing avifImageYUVToRGBLibYUV for
// correctness.
typedef enum avifRGBFormat
{
AVIF_RGB_FORMAT_RGB = 0,
AVIF_RGB_FORMAT_RGBA, // This is the default format set in avifRGBImageSetDefaults().
AVIF_RGB_FORMAT_ARGB,
AVIF_RGB_FORMAT_BGR,
AVIF_RGB_FORMAT_BGRA,
AVIF_RGB_FORMAT_ABGR,
// RGB_565 format uses five bits for the red and blue components and six
// bits for the green component. Each RGB pixel is 16 bits (2 bytes), which
// is packed as follows:
// uint16_t: [r4 r3 r2 r1 r0 g5 g4 g3 g2 g1 g0 b4 b3 b2 b1 b0]
// r4 and r0 are the MSB and LSB of the red component respectively.
// g5 and g0 are the MSB and LSB of the green component respectively.
// b4 and b0 are the MSB and LSB of the blue component respectively.
// This format is only supported for YUV -> RGB conversion and when
// avifRGBImage.depth is set to 8.
AVIF_RGB_FORMAT_RGB_565,
AVIF_RGB_FORMAT_COUNT
} avifRGBFormat;
AVIF_API uint32_t avifRGBFormatChannelCount(avifRGBFormat format);
AVIF_API avifBool avifRGBFormatHasAlpha(avifRGBFormat format);
typedef enum avifChromaUpsampling
{
AVIF_CHROMA_UPSAMPLING_AUTOMATIC = 0, // Chooses best trade off of speed/quality (uses BILINEAR libyuv if available,
// or falls back to NEAREST libyuv if available, or falls back to BILINEAR built-in)
AVIF_CHROMA_UPSAMPLING_FASTEST = 1, // Chooses speed over quality (same as NEAREST)
AVIF_CHROMA_UPSAMPLING_BEST_QUALITY = 2, // Chooses the best quality upsampling, given settings (same as BILINEAR)
AVIF_CHROMA_UPSAMPLING_NEAREST = 3, // Uses nearest-neighbor filter
AVIF_CHROMA_UPSAMPLING_BILINEAR = 4 // Uses bilinear filter
} avifChromaUpsampling;
typedef enum avifChromaDownsampling
{
AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC = 0, // Chooses best trade off of speed/quality (same as AVERAGE)
AVIF_CHROMA_DOWNSAMPLING_FASTEST = 1, // Chooses speed over quality (same as AVERAGE)
AVIF_CHROMA_DOWNSAMPLING_BEST_QUALITY = 2, // Chooses the best quality upsampling (same as AVERAGE)
AVIF_CHROMA_DOWNSAMPLING_AVERAGE = 3, // Uses averaging filter
AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV = 4 // Uses sharp yuv filter (libsharpyuv), available for 4:2:0 only, ignored for 4:2:2
} avifChromaDownsampling;
// NOTE: avifRGBImage must be initialized with avifRGBImageSetDefaults() (preferred) or memset()
// before use.
typedef struct avifRGBImage
{
uint32_t width; // must match associated avifImage
uint32_t height; // must match associated avifImage
uint32_t depth; // legal depths [8, 10, 12, 16]. if depth>8, pixels must be uint16_t internally
avifRGBFormat format; // all channels are always full range
avifChromaUpsampling chromaUpsampling; // How to upsample from 4:2:0 or 4:2:2 UV when converting to RGB (ignored for 4:4:4 and 4:0:0).
// Ignored when converting to YUV. Defaults to AVIF_CHROMA_UPSAMPLING_AUTOMATIC.
avifChromaDownsampling chromaDownsampling; // How to downsample to 4:2:0 or 4:2:2 UV when converting from RGB (ignored for 4:4:4 and 4:0:0).
// Ignored when converting to RGB. Defaults to AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC.
avifBool avoidLibYUV; // If AVIF_FALSE and libyuv conversion between RGB and YUV (including upsampling or downsampling if any)
// is available for the avifImage/avifRGBImage combination, then libyuv is used. Default is AVIF_FALSE.
avifBool ignoreAlpha; // Used for XRGB formats, treats formats containing alpha (such as ARGB) as if they were RGB, treating
// the alpha bits as if they were all 1.
avifBool alphaPremultiplied; // indicates if RGB value is pre-multiplied by alpha. Default: false
avifBool isFloat; // indicates if RGBA values are in half float (f16) format. Valid only when depth == 16. Default: false
int maxThreads; // Number of threads to be used for the YUV to RGB conversion. Note that this value is ignored for RGB to YUV
// conversion. Setting this to zero has the same effect as setting it to one. Negative values are invalid.
// Default: 1.
uint8_t * pixels;
uint32_t rowBytes;
} avifRGBImage;
// Sets rgb->width, rgb->height, and rgb->depth to image->width, image->height, and image->depth.
// Sets rgb->pixels to NULL and rgb->rowBytes to 0. Sets the other fields of 'rgb' to default
// values.
AVIF_API void avifRGBImageSetDefaults(avifRGBImage * rgb, const avifImage * image);
AVIF_API uint32_t avifRGBImagePixelSize(const avifRGBImage * rgb);
// Convenience functions. If you supply your own pixels/rowBytes, you do not need to use these.
AVIF_API avifResult avifRGBImageAllocatePixels(avifRGBImage * rgb);
AVIF_API void avifRGBImageFreePixels(avifRGBImage * rgb);
// The main conversion functions
AVIF_API avifResult avifImageRGBToYUV(avifImage * image, const avifRGBImage * rgb);
AVIF_API avifResult avifImageYUVToRGB(const avifImage * image, avifRGBImage * rgb);
// Premultiply handling functions.
// (Un)premultiply is automatically done by the main conversion functions above,
// so usually you don't need to call these. They are there for convenience.
AVIF_API avifResult avifRGBImagePremultiplyAlpha(avifRGBImage * rgb);
AVIF_API avifResult avifRGBImageUnpremultiplyAlpha(avifRGBImage * rgb);
// ---------------------------------------------------------------------------
// YUV Utils
AVIF_API int avifFullToLimitedY(uint32_t depth, int v);
AVIF_API int avifFullToLimitedUV(uint32_t depth, int v);
AVIF_API int avifLimitedToFullY(uint32_t depth, int v);
AVIF_API int avifLimitedToFullUV(uint32_t depth, int v);
// ---------------------------------------------------------------------------
// Codec selection
typedef enum avifCodecChoice