Skip to content

Commit c2d3328

Browse files
Support for Progressive AVIF encoding
1 parent e82b5af commit c2d3328

File tree

9 files changed

+845
-135
lines changed

9 files changed

+845
-135
lines changed

apps/avifenc.c

Lines changed: 358 additions & 24 deletions
Large diffs are not rendered by default.

include/avif/avif.h

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ typedef int avifBool;
8585
#define AVIF_SPEED_SLOWEST 0
8686
#define AVIF_SPEED_FASTEST 10
8787

88+
#define MAX_AV1_LAYER_COUNT 4
89+
8890
typedef enum avifPlanesFlag
8991
{
9092
AVIF_PLANES_YUV = (1 << 0),
@@ -151,6 +153,7 @@ typedef enum avifResult
151153
AVIF_RESULT_WAITING_ON_IO, // similar to EAGAIN/EWOULDBLOCK, this means the avifIO doesn't have necessary data available yet
152154
AVIF_RESULT_INVALID_ARGUMENT, // an argument passed into this function is invalid
153155
AVIF_RESULT_NOT_IMPLEMENTED, // a requested code path is not (yet) implemented
156+
AVIF_RESULT_INVALID_LAYERS,
154157
AVIF_RESULT_OUT_OF_MEMORY
155158
} avifResult;
156159

@@ -787,9 +790,11 @@ typedef enum avifProgressiveState
787790
// for an image sequence.
788791
AVIF_PROGRESSIVE_STATE_UNAVAILABLE = 0,
789792

790-
// The current AVIF/Source offers a progressive image, but avifDecoder.allowProgressive is not
791-
// enabled, so it will behave as if the image was not progressive and will simply decode the
792-
// best version of this item.
793+
// For decoder, this means the current AVIF/Source offers a progressive image, but
794+
// avifDecoder.allowProgressive is not enabled, so it will behave as if the image was not
795+
// progressive and will simply decode the best version of this item.
796+
// For encoder, this means at least one of color and alpha image has multiple layers and
797+
// indicates this is a progressive image.
793798
AVIF_PROGRESSIVE_STATE_AVAILABLE,
794799

795800
// The current AVIF/Source offers a progressive image, and avifDecoder.allowProgressive is true.
@@ -997,6 +1002,18 @@ AVIF_API avifResult avifDecoderNthImageMaxExtent(const avifDecoder * decoder, ui
9971002
struct avifEncoderData;
9981003
struct avifCodecSpecificOptions;
9991004

1005+
typedef struct avifScalingMode {
1006+
uint64_t numerator;
1007+
uint64_t denominator;
1008+
} avifScalingMode;
1009+
1010+
typedef struct avifLayerConfig {
1011+
int minQuantizer;
1012+
int maxQuantizer;
1013+
avifScalingMode horizontalMode;
1014+
avifScalingMode verticalMode;
1015+
} avifLayerConfig;
1016+
10001017
// Notes:
10011018
// * If avifEncoderWrite() returns AVIF_RESULT_OK, output must be freed with avifRWDataFree()
10021019
// * If (maxThreads < 2), multithreading is disabled
@@ -1025,6 +1042,11 @@ typedef struct avifEncoder
10251042
int keyframeInterval; // How many frames between automatic forced keyframes; 0 to disable (default).
10261043
uint64_t timescale; // timescale of the media (Hz)
10271044

1045+
int extraLayerCount; // Extra layers for color sub image; 0 to disable layer image (default).
1046+
int extraLayerCountAlpha; // Extra layers for alpha sub image; 0 to disable layer image (default).
1047+
avifLayerConfig layers[MAX_AV1_LAYER_COUNT];
1048+
avifLayerConfig layersAlpha[MAX_AV1_LAYER_COUNT];
1049+
10281050
// stats from the most recent write
10291051
avifIOStats ioStats;
10301052

@@ -1073,6 +1095,16 @@ AVIF_API avifResult avifEncoderAddImageGrid(avifEncoder * encoder,
10731095
uint32_t gridRows,
10741096
const avifImage * const * cellImages,
10751097
avifAddImageFlags addImageFlags);
1098+
avifResult avifEncoderAddImageProgressive(avifEncoder * encoder,
1099+
uint32_t layerCount,
1100+
const avifImage * const * layerImages,
1101+
avifAddImageFlags addImageFlags);
1102+
avifResult avifEncoderAddImageProgressiveGrid(avifEncoder * encoder,
1103+
uint32_t gridCols,
1104+
uint32_t gridRows,
1105+
uint32_t layerCount,
1106+
const avifImage * const * layerImages,
1107+
avifAddImageFlags addImageFlags);
10761108
AVIF_API avifResult avifEncoderFinish(avifEncoder * encoder, avifRWData * output);
10771109

10781110
// Codec-specific, optional "advanced" tuning settings, in the form of string key/value pairs. These

include/avif/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ typedef avifResult (*avifCodecEncodeImageFunc)(struct avifCodec * codec,
259259
avifEncoder * encoder,
260260
const avifImage * image,
261261
avifBool alpha,
262+
uint32_t layerIndex,
262263
avifAddImageFlags addImageFlags,
263264
avifCodecEncodeOutput * output);
264265
typedef avifBool (*avifCodecEncodeFinishFunc)(struct avifCodec * codec, avifCodecEncodeOutput * output);

src/avif.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ const char * avifResultToString(avifResult result)
9393
case AVIF_RESULT_WAITING_ON_IO: return "Waiting on IO";
9494
case AVIF_RESULT_INVALID_ARGUMENT: return "Invalid argument";
9595
case AVIF_RESULT_NOT_IMPLEMENTED: return "Not implemented";
96+
case AVIF_RESULT_INVALID_LAYERS: return "Invalid layer image";
9697
case AVIF_RESULT_OUT_OF_MEMORY: return "Out of memory";
9798
case AVIF_RESULT_UNKNOWN_ERROR:
9899
default:

0 commit comments

Comments
 (0)