Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d113517
Add IMG_CoderStatus to the header
LordOfXen Aug 14, 2025
73020a5
Bring back comment spacing applied by SDLWikiBot
LordOfXen Aug 14, 2025
d9054c1
Add IMG_CoderStatus to IMG_AnimationDecoder
LordOfXen Aug 14, 2025
ae1dfa7
Add IMG_CoderStatus to IMG_AnimationEncoder
LordOfXen Aug 14, 2025
352a83c
Add IMG_GetAnimationEncoderStatus
LordOfXen Aug 14, 2025
b869614
Add IMG_GetAnimationDecoderStatus
LordOfXen Aug 14, 2025
3ce6266
Update IMG_GetAnimationDecoderFrame to include IMG_CoderStatus
LordOfXen Aug 14, 2025
9c90198
Update IMG_AddAnimationEncoderFrame to use IMG_CoderStatus
LordOfXen Aug 14, 2025
f8c04b2
Set GIF Decoder status when we reach EOF
LordOfXen Aug 14, 2025
fcc79ce
Set PNG coder status when we reach EOF
LordOfXen Aug 14, 2025
6b90f2b
Set AVIF coder status when we reach EOF
LordOfXen Aug 14, 2025
37bbd60
Add IMG_CODER_STATUS_MAX for AVIF_RESULT_NO_IMAGES_REMAINING as well
LordOfXen Aug 14, 2025
9e5e04c
Update WEBP to use coder status when we reach EOF
LordOfXen Aug 14, 2025
a2dbf24
Remove status assignments from AVIF
LordOfXen Aug 14, 2025
818a74e
Remove status assignments from GIF
LordOfXen Aug 14, 2025
dc8af3f
Remove status assignments from PNG
LordOfXen Aug 14, 2025
fe6b63b
Remove status assignments from WEBP
LordOfXen Aug 14, 2025
285d5a4
Remove CoderStatus from Encoder
LordOfXen Aug 14, 2025
71a8408
Remove Encoder Status and Update Coder Status to IMG_AnimationDecoder…
LordOfXen Aug 14, 2025
4e54d77
Remove status from encoder
LordOfXen Aug 14, 2025
c2747e9
Update IMG_CoderStatus to IMG_AnimationDecoderStatus
LordOfXen Aug 14, 2025
fa963f5
Update the check in IMG_GetAnimationDecoderFrame and update IMG_Coder…
LordOfXen Aug 14, 2025
b7d1fa6
BUG FIX: Increase accumulated_pts and last_delay only if AddFrame suc…
LordOfXen Aug 14, 2025
792cc8b
Update IMG_CODER_STATUS_OK to IMG_DECODER_STATUS_OK
LordOfXen Aug 14, 2025
d2f7f02
Remove padding
LordOfXen Aug 14, 2025
5baee55
Remove padding
LordOfXen Aug 14, 2025
2f22906
Remove padding
LordOfXen Aug 14, 2025
147b775
Revert changes to parameters of IMG_AddAnimationEncoderFrame
LordOfXen Aug 14, 2025
7a6a25d
Add IMG_GetAnimationDecoderStatus to SYM
LordOfXen Aug 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions include/SDL3_image/SDL_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -2403,6 +2403,18 @@ extern SDL_DECLSPEC IMG_Animation * SDLCALL IMG_LoadGIFAnimation_IO(SDL_IOStream
*/
extern SDL_DECLSPEC IMG_Animation * SDLCALL IMG_LoadWEBPAnimation_IO(SDL_IOStream *src);

/**
* An enum representing the status of the encoder and decoder.
*/
typedef enum IMG_AnimationDecoderStatus
{
IMG_DECODER_STATUS_OK, /**< Decoded the frame successfully. */
IMG_DECODER_STATUS_FAILED, /**< Decoding the frame failed. Call SDL_GetError for more information. */
IMG_DECODER_STATUS_COMPLETE, /**< No more frames available. */

IMG_DECODER_STATUS_INVALID, /**< Invalid decoder status that does not represent any valid status. */
} IMG_AnimationDecoderStatus;

/**
* An object representing the encoder context.
*/
Expand Down Expand Up @@ -2688,6 +2700,19 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL IMG_GetAnimationDecoderProperties(I
*/
extern SDL_DECLSPEC bool SDLCALL IMG_GetAnimationDecoderFrame(IMG_AnimationDecoder *decoder, SDL_Surface **frame, Uint64 *duration);

/**
* Get the decoder status indicating the current state of the decoder.
*
* \param decoder the decoder to get the status of.
* \returns the status of the underlying decoder, or IMG_DECODER_STATUS_INVALID if the given
* decoder is invalid.
*
* \since This function is available since SDL_image 3.4.0.
*
* \sa IMG_GetAnimationDecoderFrame
*/
extern SDL_DECLSPEC IMG_AnimationDecoderStatus SDLCALL IMG_GetAnimationDecoderStatus(IMG_AnimationDecoder *decoder);

/**
* Reset an animation decoder.
*
Expand Down
23 changes: 21 additions & 2 deletions src/IMG_anim_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,23 @@ bool IMG_GetAnimationDecoderFrame(IMG_AnimationDecoder *decoder, SDL_Surface **f
if (!duration) {
duration = &temp_duration;
}

SDL_ClearError();
// Reset the status before trying to get the next frame.
decoder->status = IMG_DECODER_STATUS_OK;

bool result = decoder->GetNextFrame(decoder, frame, duration);
if (temp_frame) {
SDL_DestroySurface(temp_frame);
}

if (!result) {
if (SDL_GetError()[0] == '\0') {
decoder->status = IMG_DECODER_STATUS_COMPLETE;
} else {
decoder->status = IMG_DECODER_STATUS_FAILED;
}
}

if (result) {
decoder->accumulated_pts += *duration;
} else {
Expand Down Expand Up @@ -242,12 +251,22 @@ bool IMG_ResetAnimationDecoder(IMG_AnimationDecoder *decoder)

Uint64 IMG_CalculateDuration(IMG_AnimationDecoder* decoder, int delay_num, int delay_den)
{
if (delay_den < 1)
if (delay_den < 1) {
delay_den = 100;
}

return (Uint64)SDL_round(((double)delay_num / delay_den) * ((double)decoder->timebase_denominator / (double)decoder->timebase_numerator));
}

IMG_AnimationDecoderStatus IMG_GetAnimationDecoderStatus(IMG_AnimationDecoder* decoder)
{
if (!decoder) {
return IMG_DECODER_STATUS_INVALID;
}

return decoder->status;
}

IMG_Animation *IMG_DecodeAsAnimation(SDL_IOStream *src, const char *format, int maxFrames)
{
IMG_AnimationDecoder *decoder = IMG_CreateAnimationDecoder_IO(src, false, format);
Expand Down
1 change: 1 addition & 0 deletions src/IMG_anim_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ typedef struct IMG_AnimationDecoderContext IMG_AnimationDecoderContext;

struct IMG_AnimationDecoder
{
IMG_AnimationDecoderStatus status;
SDL_PropertiesID props;
SDL_IOStream *src;
Sint64 start;
Expand Down
7 changes: 4 additions & 3 deletions src/IMG_anim_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,12 @@ bool IMG_AddAnimationEncoderFrame(IMG_AnimationEncoder *encoder, SDL_Surface *su
if (!surface || surface->w <= 0 || surface->h <= 0) {
return SDL_InvalidParamError("surface");
}

bool result = encoder->AddFrame(encoder, surface, duration);

encoder->accumulated_pts += duration;
encoder->last_delay = duration;
if (result) {
encoder->accumulated_pts += duration;
encoder->last_delay = duration;
}

return result;
}
Expand Down
3 changes: 2 additions & 1 deletion src/IMG_webp.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,9 @@ static bool IMG_AnimationDecoderGetNextFrame_Internal(IMG_AnimationDecoder *deco
int totalFrames = decoder->ctx->iter.num_frames;
int availableFrames = totalFrames - (decoder->ctx->iter.frame_num - 1);

if (availableFrames < 1)
if (availableFrames < 1) {
return false;
}

SDL_Surface *canvas = decoder->ctx->canvas;
uint32_t bgcolor = decoder->ctx->bgcolor;
Expand Down
1 change: 1 addition & 0 deletions src/SDL_image.sym
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,6 @@ SDL3_image_0.0.0 {
IMG_ResetAnimationDecoder;
IMG_CloseAnimationDecoder;
IMG_GetAnimationDecoderProperties;
IMG_GetAnimationDecoderStatus;
local: *;
};
Loading