Skip to content

Commit

Permalink
Remove decoder param of avifCodecGetNextImageFunc
Browse files Browse the repository at this point in the history
Remove the decoder parameter of avifCodecGetNextImageFunc so that the
avifCodec struct is independent of the avifDecoder struct.

Add the maxThreads and imageSizeLimit fields to the avifCodec struct so
that they remain available to avifCodecGetNextImageFunc.

This allows us to remove the avifDecoder local variable in
avifEncoderDecodeSatoBaseImage().
  • Loading branch information
wantehchang committed Aug 6, 2024
1 parent 47f154a commit d77a33f
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 22 deletions.
10 changes: 6 additions & 4 deletions include/avif/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,6 @@ typedef enum avifEncoderChange
typedef int avifEncoderChanges;

typedef avifBool (*avifCodecGetNextImageFunc)(struct avifCodec * codec,
struct avifDecoder * decoder,
const avifDecodeSample * sample,
avifBool alpha,
avifBool * isLimitedRangeAlpha,
Expand Down Expand Up @@ -618,9 +617,12 @@ typedef struct 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

// Decoder options (for getNextImage):
int maxThreads; // See avifDecoder::maxThreads.
uint32_t imageSizeLimit; // See avifDecoder::imageSizeLimit.
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;
Expand Down
3 changes: 1 addition & 2 deletions src/codec_aom.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ static void aomCodecDestroyInternal(avifCodec * codec)
#if defined(AVIF_CODEC_AOM_DECODE)

static avifBool aomCodecGetNextImage(struct avifCodec * codec,
struct avifDecoder * decoder,
const avifDecodeSample * sample,
avifBool alpha,
avifBool * isLimitedRangeAlpha,
Expand All @@ -100,7 +99,7 @@ static avifBool aomCodecGetNextImage(struct avifCodec * codec,
if (!codec->internal->decoderInitialized) {
aom_codec_dec_cfg_t cfg;
memset(&cfg, 0, sizeof(aom_codec_dec_cfg_t));
cfg.threads = decoder->maxThreads;
cfg.threads = codec->maxThreads;
cfg.allow_lowbitdepth = 1;

aom_codec_iface_t * decoder_interface = aom_codec_av1_dx();
Expand Down
3 changes: 1 addition & 2 deletions src/codec_avm.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ static avifResult avifCheckCodecVersionAVM()
}

static avifBool avmCodecGetNextImage(struct avifCodec * codec,
struct avifDecoder * decoder,
const avifDecodeSample * sample,
avifBool alpha,
avifBool * isLimitedRangeAlpha,
Expand All @@ -64,7 +63,7 @@ static avifBool avmCodecGetNextImage(struct avifCodec * codec,

aom_codec_dec_cfg_t cfg;
memset(&cfg, 0, sizeof(aom_codec_dec_cfg_t));
cfg.threads = decoder->maxThreads;
cfg.threads = codec->maxThreads;

aom_codec_iface_t * decoder_interface = aom_codec_av1_dx();
if (aom_codec_dec_init(&codec->internal->decoder, decoder_interface, &cfg, 0)) {
Expand Down
7 changes: 3 additions & 4 deletions src/codec_dav1d.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ static void dav1dCodecDestroyInternal(avifCodec * codec)
}

static avifBool dav1dCodecGetNextImage(struct avifCodec * codec,
struct avifDecoder * decoder,
const avifDecodeSample * sample,
avifBool alpha,
avifBool * isLimitedRangeAlpha,
Expand All @@ -61,16 +60,16 @@ static avifBool dav1dCodecGetNextImage(struct avifCodec * codec,
// Give all available threads to decode a single frame as fast as possible
#if DAV1D_API_VERSION_MAJOR >= 6
dav1dSettings.max_frame_delay = 1;
dav1dSettings.n_threads = AVIF_CLAMP(decoder->maxThreads, 1, DAV1D_MAX_THREADS);
dav1dSettings.n_threads = AVIF_CLAMP(codec->maxThreads, 1, DAV1D_MAX_THREADS);
#else
dav1dSettings.n_frame_threads = 1;
dav1dSettings.n_tile_threads = AVIF_CLAMP(decoder->maxThreads, 1, DAV1D_MAX_TILE_THREADS);
dav1dSettings.n_tile_threads = AVIF_CLAMP(codec->maxThreads, 1, DAV1D_MAX_TILE_THREADS);
#endif // DAV1D_API_VERSION_MAJOR >= 6
// Set a maximum frame size limit to avoid OOM'ing fuzzers. In 32-bit builds, if
// frame_size_limit > 8192 * 8192, dav1d reduces frame_size_limit to 8192 * 8192 and logs
// a message, so we set frame_size_limit to at most 8192 * 8192 to avoid the dav1d_log
// message.
dav1dSettings.frame_size_limit = (sizeof(size_t) < 8) ? AVIF_MIN(decoder->imageSizeLimit, 8192 * 8192) : decoder->imageSizeLimit;
dav1dSettings.frame_size_limit = (sizeof(size_t) < 8) ? AVIF_MIN(codec->imageSizeLimit, 8192 * 8192) : codec->imageSizeLimit;
dav1dSettings.operating_point = codec->operatingPoint;
dav1dSettings.all_layers = codec->allLayers;

Expand Down
3 changes: 1 addition & 2 deletions src/codec_libgav1.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@ static void gav1CodecDestroyInternal(avifCodec * codec)
}

static avifBool gav1CodecGetNextImage(struct avifCodec * codec,
struct avifDecoder * decoder,
const avifDecodeSample * sample,
avifBool alpha,
avifBool * isLimitedRangeAlpha,
avifImage * image)
{
if (codec->internal->gav1Decoder == NULL) {
codec->internal->gav1Settings.threads = decoder->maxThreads;
codec->internal->gav1Settings.threads = codec->maxThreads;
codec->internal->gav1Settings.operating_point = codec->operatingPoint;
codec->internal->gav1Settings.output_all_layers = codec->allLayers;

Expand Down
4 changes: 3 additions & 1 deletion src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -5711,7 +5711,9 @@ static avifResult avifDecoderDecodeTiles(avifDecoder * decoder, uint32_t nextIma
}

avifBool isLimitedRangeAlpha = AVIF_FALSE;
if (!tile->codec->getNextImage(tile->codec, decoder, sample, avifIsAlpha(tile->input->itemCategory), &isLimitedRangeAlpha, tile->image)) {
tile->codec->maxThreads = decoder->maxThreads;
tile->codec->imageSizeLimit = decoder->imageSizeLimit;
if (!tile->codec->getNextImage(tile->codec, sample, avifIsAlpha(tile->input->itemCategory), &isLimitedRangeAlpha, tile->image)) {
avifDiagnosticsPrintf(&decoder->diag, "tile->codec->getNextImage() failed");
return avifGetErrorForItemCategory(tile->input->itemCategory);
}
Expand Down
10 changes: 3 additions & 7 deletions src/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -1331,17 +1331,13 @@ static avifResult avifEncoderDecodeSatoBaseImage(avifEncoder * encoder,
}
AVIF_ASSERT_OR_RETURN(sample.data.size != 0); // There should be at least one base item.

// avifCodecGetNextImageFunc() uses only a few fields of its decoder argument.
avifDecoder decoder;
memset(&decoder, 0, sizeof(decoder));
decoder.maxThreads = encoder->maxThreads;
decoder.imageSizeLimit = AVIF_DEFAULT_IMAGE_SIZE_LIMIT;

AVIF_CHECKRES(avifCodecCreate(AVIF_CODEC_CHOICE_AUTO, AVIF_CODEC_FLAG_CAN_DECODE, codec));
(*codec)->diag = &encoder->diag;
(*codec)->maxThreads = encoder->maxThreads;
(*codec)->imageSizeLimit = AVIF_DEFAULT_IMAGE_SIZE_LIMIT;
AVIF_CHECKRES(avifImageCreateAllocate(decodedBaseImage, original, numBits, planes));
avifBool isLimitedRangeAlpha = AVIF_FALSE; // Ignored.
AVIF_CHECKERR((*codec)->getNextImage(*codec, &decoder, &sample, planes == AVIF_PLANES_A, &isLimitedRangeAlpha, *decodedBaseImage),
AVIF_CHECKERR((*codec)->getNextImage(*codec, &sample, planes == AVIF_PLANES_A, &isLimitedRangeAlpha, *decodedBaseImage),
AVIF_RESULT_ENCODE_SAMPLE_TRANSFORM_FAILED);
return AVIF_RESULT_OK;
}
Expand Down

0 comments on commit d77a33f

Please sign in to comment.