@@ -243,6 +243,8 @@ typedef struct avifEncoderData
243243 // Fields specific to AV1/AV2
244244 const char * imageItemType ; // "av01" for AV1 ("av02" for AV2 if AVIF_CODEC_AVM)
245245 const char * configPropName ; // "av1C" for AV1 ("av2C" for AV2 if AVIF_CODEC_AVM)
246+ // Custom AV1 encoding function
247+ avifBool customEncodeImageFuncUsed ;
246248} avifEncoderData ;
247249
248250static void avifEncoderDataDestroy (avifEncoderData * data );
@@ -2104,17 +2106,38 @@ static avifResult avifEncoderAddImageInternal(avifEncoder * encoder,
21042106 // If alpha channel is present, set disableLaggedOutput to AVIF_TRUE. If the encoder supports it, this enables
21052107 // avifEncoderDataShouldForceKeyframeForAlpha to force a keyframe in the alpha channel whenever a keyframe has been
21062108 // encoded in the color channel for animated images.
2107- avifResult encodeResult = item -> codec -> encodeImage (item -> codec ,
2108- encoder ,
2109- cellImage ,
2110- isAlpha ,
2111- encoder -> data -> tileRowsLog2 ,
2112- encoder -> data -> tileColsLog2 ,
2113- quantizer ,
2114- encoderChanges ,
2115- /*disableLaggedOutput=*/ encoder -> data -> alphaPresent ,
2116- addImageFlags ,
2117- item -> encodeOutput );
2109+ const avifBool disableLaggedOutput = encoder -> data -> alphaPresent ;
2110+
2111+ avifResult encodeResult = AVIF_RESULT_NO_CONTENT ;
2112+ if (encoder -> customEncodeImageFunc != NULL && encoder -> customEncodeFinishFunc != NULL ) {
2113+ const avifEncoderCustomEncodeImageArgs args = {
2114+ addImageFlags ,
2115+ quantizer ,
2116+ encoder -> data -> tileRowsLog2 ,
2117+ encoder -> data -> tileColsLog2 ,
2118+ isAlpha ,
2119+ #if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP )
2120+ item -> itemCategory == AVIF_ITEM_GAIN_MAP
2121+ #endif
2122+ };
2123+ encodeResult = encoder -> customEncodeImageFunc (encoder , cellImage , & args );
2124+ encoder -> data -> customEncodeImageFuncUsed = encodeResult != AVIF_RESULT_NO_CONTENT ;
2125+ }
2126+
2127+ if (encodeResult == AVIF_RESULT_NO_CONTENT ) {
2128+ encodeResult = item -> codec -> encodeImage (item -> codec ,
2129+ encoder ,
2130+ cellImage ,
2131+ isAlpha ,
2132+ encoder -> data -> tileRowsLog2 ,
2133+ encoder -> data -> tileColsLog2 ,
2134+ quantizer ,
2135+ encoderChanges ,
2136+ disableLaggedOutput ,
2137+ addImageFlags ,
2138+ item -> encodeOutput );
2139+ }
2140+
21182141#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM )
21192142 // Revert quality settings if they changed.
21202143 if (* encoderMinQuantizer != originalMinQuantizer || * encoderMaxQuantizer != originalMaxQuantizer ) {
@@ -3094,7 +3117,14 @@ avifResult avifEncoderFinish(avifEncoder * encoder, avifRWData * output)
30943117 for (uint32_t itemIndex = 0 ; itemIndex < encoder -> data -> items .count ; ++ itemIndex ) {
30953118 avifEncoderItem * item = & encoder -> data -> items .item [itemIndex ];
30963119 if (item -> codec ) {
3097- if (!item -> codec -> encodeFinish (item -> codec , item -> encodeOutput )) {
3120+ if (encoder -> data -> customEncodeImageFuncUsed ) {
3121+ avifROData sample = AVIF_DATA_EMPTY ;
3122+ avifResult encodeResult ;
3123+ while ((encodeResult = encoder -> customEncodeFinishFunc (encoder , & sample )) != AVIF_RESULT_NO_IMAGES_REMAINING ) {
3124+ AVIF_CHECKRES (encodeResult );
3125+ AVIF_CHECKRES (avifCodecEncodeOutputAddSample (item -> encodeOutput , sample .data , sample .size , /*sync=*/ AVIF_TRUE ));
3126+ }
3127+ } else if (!item -> codec -> encodeFinish (item -> codec , item -> encodeOutput )) {
30983128 return avifGetErrorForItemCategory (item -> itemCategory );
30993129 }
31003130
0 commit comments