Skip to content

Commit e1509ee

Browse files
authored
Removed memset and ignoreAlpha (#20)
1 parent 7de1212 commit e1509ee

File tree

2 files changed

+30
-46
lines changed

2 files changed

+30
-46
lines changed

src/PIL/AvifImagePlugin.py

+12-16
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# Decoder options as module globals, until there is a way to pass parameters
1717
# to Image.open (see https://github.com/python-pillow/Pillow/issues/569)
1818
DECODE_CODEC_CHOICE = "auto"
19+
# Decoding is only affected by this for libavif **0.8.4** or greater.
1920
DEFAULT_MAX_THREADS = 0
2021

2122

@@ -61,10 +62,7 @@ class AvifImageFile(ImageFile.ImageFile):
6162

6263
def _open(self) -> None:
6364
if not SUPPORTED:
64-
msg = (
65-
"image file could not be identified because AVIF "
66-
"support not installed"
67-
)
65+
msg = "image file could not be opened because AVIF support not installed"
6866
raise SyntaxError(msg)
6967

7068
if DECODE_CODEC_CHOICE != "auto" and not _avif.decoder_codec_available(
@@ -116,11 +114,11 @@ def seek(self, frame: int) -> None:
116114
def load(self) -> Image.core.PixelAccess | None:
117115
if self.tile:
118116
# We need to load the image data for this frame
119-
data, timescale, tsp_in_ts, dur_in_ts = self._decoder.get_frame(
120-
self.__frame
117+
data, timescale, pts_in_timescales, dur_in_timescales = (
118+
self._decoder.get_frame(self.__frame)
121119
)
122-
self.info["timestamp"] = round(1000 * (tsp_in_ts / timescale))
123-
self.info["duration"] = round(1000 * (dur_in_ts / timescale))
120+
self.info["timestamp"] = round(1000 * (pts_in_timescales / timescale))
121+
self.info["duration"] = round(1000 * (dur_in_timescales / timescale))
124122

125123
# Set tile
126124
if self.fp and self._exclusive_fp:
@@ -212,8 +210,7 @@ def _save(
212210

213211
# Setup the AVIF encoder
214212
enc = _avif.AvifEncoder(
215-
im.size[0],
216-
im.size[1],
213+
im.size,
217214
subsampling,
218215
quality,
219216
speed,
@@ -233,7 +230,7 @@ def _save(
233230

234231
# Add each frame
235232
frame_idx = 0
236-
frame_dur = 0
233+
frame_duration = 0
237234
cur_idx = im.tell()
238235
try:
239236
for ims in [im] + append_images:
@@ -252,16 +249,15 @@ def _save(
252249

253250
# Update frame duration
254251
if isinstance(duration, (list, tuple)):
255-
frame_dur = duration[frame_idx]
252+
frame_duration = duration[frame_idx]
256253
else:
257-
frame_dur = duration
254+
frame_duration = duration
258255

259256
# Append the frame to the animation encoder
260257
enc.add(
261258
frame.tobytes("raw", rawmode),
262-
frame_dur,
263-
frame.size[0],
264-
frame.size[1],
259+
frame_duration,
260+
frame.size,
265261
rawmode,
266262
is_single_frame,
267263
)

src/_avif.c

+18-30
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
typedef struct {
88
PyObject_HEAD avifEncoder *encoder;
99
avifImage *image;
10-
int frame_index;
10+
int first_frame;
1111
} AvifEncoderObject;
1212

1313
static PyTypeObject AvifEncoder_Type;
@@ -16,7 +16,6 @@ static PyTypeObject AvifEncoder_Type;
1616
typedef struct {
1717
PyObject_HEAD avifDecoder *decoder;
1818
Py_buffer buffer;
19-
char *mode;
2019
} AvifDecoderObject;
2120

2221
static PyTypeObject AvifDecoder_Type;
@@ -154,7 +153,7 @@ exif_orientation_to_irot_imir(avifImage *image, int orientation) {
154153
}
155154

156155
static int
157-
_codec_available(const char *name, uint32_t flags) {
156+
_codec_available(const char *name, avifCodecFlags flags) {
158157
avifCodecChoice codec = avifCodecChoiceFromName(name);
159158
if (codec == AVIF_CODEC_CHOICE_AUTO) {
160159
return 0;
@@ -252,7 +251,7 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
252251

253252
if (!PyArg_ParseTuple(
254253
args,
255-
"IIsiiissiiOOy*y*iy*O",
254+
"(II)siiissiiOOy*y*iy*O",
256255
&width,
257256
&height,
258257
&subsampling,
@@ -372,7 +371,7 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
372371
avifEncoderDestroy(encoder);
373372
return NULL;
374373
}
375-
self->frame_index = -1;
374+
self->first_frame = 1;
376375

377376
avifResult result;
378377
if (icc_buffer.len) {
@@ -466,10 +465,9 @@ _encoder_add(AvifEncoderObject *self, PyObject *args) {
466465
unsigned int width;
467466
unsigned int height;
468467
char *mode;
469-
PyObject *is_single_frame = NULL;
468+
unsigned int is_single_frame;
470469
PyObject *ret = Py_None;
471470

472-
int is_first_frame;
473471
avifRGBImage rgb;
474472
avifResult result;
475473

@@ -479,7 +477,7 @@ _encoder_add(AvifEncoderObject *self, PyObject *args) {
479477

480478
if (!PyArg_ParseTuple(
481479
args,
482-
"z#IIIsO",
480+
"y#I(II)sp",
483481
(char **)&rgb_bytes,
484482
&size,
485483
&duration,
@@ -491,8 +489,6 @@ _encoder_add(AvifEncoderObject *self, PyObject *args) {
491489
return NULL;
492490
}
493491

494-
is_first_frame = self->frame_index == -1;
495-
496492
if (image->width != width || image->height != height) {
497493
PyErr_Format(
498494
PyExc_ValueError,
@@ -505,7 +501,7 @@ _encoder_add(AvifEncoderObject *self, PyObject *args) {
505501
return NULL;
506502
}
507503

508-
if (is_first_frame) {
504+
if (self->first_frame) {
509505
// If we don't have an image populated with yuv planes, this is the first frame
510506
frame = image;
511507
} else {
@@ -577,7 +573,7 @@ _encoder_add(AvifEncoderObject *self, PyObject *args) {
577573
}
578574

579575
uint32_t addImageFlags = AVIF_ADD_IMAGE_FLAG_NONE;
580-
if (PyObject_IsTrue(is_single_frame)) {
576+
if (is_single_frame) {
581577
addImageFlags |= AVIF_ADD_IMAGE_FLAG_SINGLE;
582578
}
583579

@@ -597,12 +593,12 @@ _encoder_add(AvifEncoderObject *self, PyObject *args) {
597593

598594
end:
599595
avifRGBImageFreePixels(&rgb);
600-
if (!is_first_frame) {
596+
if (!self->first_frame) {
601597
avifImageDestroy(frame);
602598
}
603599

604600
if (ret == Py_None) {
605-
self->frame_index++;
601+
self->first_frame = 0;
606602
Py_RETURN_NONE;
607603
} else {
608604
return ret;
@@ -708,12 +704,6 @@ AvifDecoderNew(PyObject *self_, PyObject *args) {
708704
return NULL;
709705
}
710706

711-
if (decoder->alphaPresent) {
712-
self->mode = "RGBA";
713-
} else {
714-
self->mode = "RGB";
715-
}
716-
717707
self->decoder = decoder;
718708
self->buffer = buffer;
719709

@@ -757,7 +747,7 @@ _decoder_get_info(AvifDecoderObject *self) {
757747
image->width,
758748
image->height,
759749
decoder->imageCount,
760-
self->mode,
750+
decoder->alphaPresent == AVIF_TRUE ? "RGBA" : "RGB",
761751
NULL == icc ? Py_None : icc,
762752
NULL == exif ? Py_None : exif,
763753
irot_imir_to_exif_orientation(image),
@@ -793,25 +783,19 @@ _decoder_get_frame(AvifDecoderObject *self, PyObject *args) {
793783
PyErr_Format(
794784
exc_type_for_avif_result(result),
795785
"Failed to decode frame %u: %s",
796-
decoder->imageIndex + 1,
786+
frame_index,
797787
avifResultToString(result)
798788
);
799789
return NULL;
800790
}
801791

802792
image = decoder->image;
803793

804-
memset(&rgb, 0, sizeof(rgb));
805794
avifRGBImageSetDefaults(&rgb, image);
806795

807796
rgb.depth = 8;
808-
809-
if (decoder->alphaPresent) {
810-
rgb.format = AVIF_RGB_FORMAT_RGBA;
811-
} else {
812-
rgb.format = AVIF_RGB_FORMAT_RGB;
813-
rgb.ignoreAlpha = AVIF_TRUE;
814-
}
797+
rgb.format =
798+
decoder->alphaPresent == AVIF_TRUE ? AVIF_RGB_FORMAT_RGBA : AVIF_RGB_FORMAT_RGB;
815799

816800
result = avifRGBImageAllocatePixels(&rgb);
817801
if (result != AVIF_RESULT_OK) {
@@ -940,5 +924,9 @@ PyInit__avif(void) {
940924
return NULL;
941925
}
942926

927+
#ifdef Py_GIL_DISABLED
928+
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
929+
#endif
930+
943931
return m;
944932
}

0 commit comments

Comments
 (0)