@@ -106,30 +106,43 @@ _encoder_codec_available(PyObject *self, PyObject *args) {
106106 return PyBool_FromLong (is_available );
107107}
108108
109- static void
109+ static int
110110_add_codec_specific_options (avifEncoder * encoder , PyObject * opts ) {
111111 Py_ssize_t i , size ;
112112 PyObject * keyval , * py_key , * py_val ;
113113 char * key , * val ;
114114 if (!PyTuple_Check (opts )) {
115- return ;
115+ PyErr_SetString (PyExc_ValueError , "Invalid advanced codec options" );
116+ return 1 ;
116117 }
117118 size = PyTuple_GET_SIZE (opts );
118119
119120 for (i = 0 ; i < size ; i ++ ) {
120121 keyval = PyTuple_GetItem (opts , i );
121122 if (!PyTuple_Check (keyval ) || PyTuple_GET_SIZE (keyval ) != 2 ) {
122- return ;
123+ PyErr_SetString (PyExc_ValueError , "Invalid advanced codec options" );
124+ return 1 ;
123125 }
124126 py_key = PyTuple_GetItem (keyval , 0 );
125127 py_val = PyTuple_GetItem (keyval , 1 );
126128 if (!PyBytes_Check (py_key ) || !PyBytes_Check (py_val )) {
127- return ;
129+ PyErr_SetString (PyExc_ValueError , "Invalid advanced codec options" );
130+ return 1 ;
128131 }
129132 key = PyBytes_AsString (py_key );
130133 val = PyBytes_AsString (py_val );
131- avifEncoderSetCodecSpecificOption (encoder , key , val );
134+
135+ avifResult result = avifEncoderSetCodecSpecificOption (encoder , key , val );
136+ if (result != AVIF_RESULT_OK ) {
137+ PyErr_Format (
138+ exc_type_for_avif_result (result ),
139+ "Setting advanced codec options failed: %s" ,
140+ avifResultToString (result )
141+ );
142+ return 1 ;
143+ }
132144 }
145+ return 0 ;
133146}
134147
135148// Encoder functions
@@ -296,9 +309,18 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
296309 encoder -> autoTiling = enc_options .autotiling ;
297310#endif
298311
312+ if (advanced != Py_None ) {
299313#if AVIF_VERSION >= 80200
300- _add_codec_specific_options (encoder , advanced );
314+ if (_add_codec_specific_options (encoder , advanced )) {
315+ return NULL ;
316+ }
317+ #else
318+ PyErr_SetString (
319+ PyExc_ValueError , "Advanced codec options require libavif >= 0.8.2"
320+ );
321+ return NULL ;
301322#endif
323+ }
302324
303325 self -> encoder = encoder ;
304326
@@ -316,14 +338,24 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
316338 image -> alphaPremultiplied = enc_options .alpha_premultiplied ;
317339#endif
318340
341+ avifResult result ;
319342 if (PyBytes_GET_SIZE (icc_bytes )) {
320343 self -> icc_bytes = icc_bytes ;
321344 Py_INCREF (icc_bytes );
322- avifImageSetProfileICC (
345+
346+ result = avifImageSetProfileICC (
323347 image ,
324348 (uint8_t * )PyBytes_AS_STRING (icc_bytes ),
325349 PyBytes_GET_SIZE (icc_bytes )
326350 );
351+ if (result != AVIF_RESULT_OK ) {
352+ PyErr_Format (
353+ exc_type_for_avif_result (result ),
354+ "Setting ICC profile failed: %s" ,
355+ avifResultToString (result )
356+ );
357+ return NULL ;
358+ }
327359 } else {
328360 image -> colorPrimaries = AVIF_COLOR_PRIMARIES_BT709 ;
329361 image -> transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB ;
@@ -332,20 +364,38 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
332364 if (PyBytes_GET_SIZE (exif_bytes )) {
333365 self -> exif_bytes = exif_bytes ;
334366 Py_INCREF (exif_bytes );
335- avifImageSetMetadataExif (
367+
368+ result = avifImageSetMetadataExif (
336369 image ,
337370 (uint8_t * )PyBytes_AS_STRING (exif_bytes ),
338371 PyBytes_GET_SIZE (exif_bytes )
339372 );
373+ if (result != AVIF_RESULT_OK ) {
374+ PyErr_Format (
375+ exc_type_for_avif_result (result ),
376+ "Setting EXIF data failed: %s" ,
377+ avifResultToString (result )
378+ );
379+ return NULL ;
380+ }
340381 }
341382 if (PyBytes_GET_SIZE (xmp_bytes )) {
342383 self -> xmp_bytes = xmp_bytes ;
343384 Py_INCREF (xmp_bytes );
344- avifImageSetMetadataXMP (
385+
386+ result = avifImageSetMetadataXMP (
345387 image ,
346388 (uint8_t * )PyBytes_AS_STRING (xmp_bytes ),
347389 PyBytes_GET_SIZE (xmp_bytes )
348390 );
391+ if (result != AVIF_RESULT_OK ) {
392+ PyErr_Format (
393+ exc_type_for_avif_result (result ),
394+ "Setting XMP data failed: %s" ,
395+ avifResultToString (result )
396+ );
397+ return NULL ;
398+ }
349399 }
350400
351401 self -> image = image ;
@@ -449,7 +499,15 @@ _encoder_add(AvifEncoderObject *self, PyObject *args) {
449499 rgb .format = AVIF_RGB_FORMAT_RGB ;
450500 }
451501
452- avifRGBImageAllocatePixels (& rgb );
502+ result = avifRGBImageAllocatePixels (& rgb );
503+ if (result != AVIF_RESULT_OK ) {
504+ PyErr_Format (
505+ exc_type_for_avif_result (result ),
506+ "Pixel allocation failed: %s" ,
507+ avifResultToString (result )
508+ );
509+ return NULL ;
510+ }
453511
454512 if (rgb .rowBytes * rgb .height != size ) {
455513 PyErr_Format (
@@ -599,14 +657,24 @@ AvifDecoderNew(PyObject *self_, PyObject *args) {
599657#endif
600658 self -> decoder -> codecChoice = codec ;
601659
602- avifDecoderSetIOMemory (
660+ result = avifDecoderSetIOMemory (
603661 self -> decoder ,
604662 (uint8_t * )PyBytes_AS_STRING (self -> data ),
605663 PyBytes_GET_SIZE (self -> data )
606664 );
665+ if (result != AVIF_RESULT_OK ) {
666+ PyErr_Format (
667+ exc_type_for_avif_result (result ),
668+ "Setting IO memory failed: %s" ,
669+ avifResultToString (result )
670+ );
671+ avifDecoderDestroy (self -> decoder );
672+ self -> decoder = NULL ;
673+ Py_DECREF (self );
674+ return NULL ;
675+ }
607676
608677 result = avifDecoderParse (self -> decoder );
609-
610678 if (result != AVIF_RESULT_OK ) {
611679 PyErr_Format (
612680 exc_type_for_avif_result (result ),
@@ -697,7 +765,6 @@ _decoder_get_frame(AvifDecoderObject *self, PyObject *args) {
697765 }
698766
699767 result = avifDecoderNthImage (decoder , frame_index );
700-
701768 if (result != AVIF_RESULT_OK ) {
702769 PyErr_Format (
703770 exc_type_for_avif_result (result ),
@@ -729,7 +796,15 @@ _decoder_get_frame(AvifDecoderObject *self, PyObject *args) {
729796 return NULL ;
730797 }
731798
732- avifRGBImageAllocatePixels (& rgb );
799+ result = avifRGBImageAllocatePixels (& rgb );
800+ if (result != AVIF_RESULT_OK ) {
801+ PyErr_Format (
802+ exc_type_for_avif_result (result ),
803+ "Pixel allocation failed: %s" ,
804+ avifResultToString (result )
805+ );
806+ return NULL ;
807+ }
733808
734809 Py_BEGIN_ALLOW_THREADS result = avifImageYUVToRGB (image , & rgb );
735810 Py_END_ALLOW_THREADS
0 commit comments