Skip to content

Commit e4ee643

Browse files
authored
Added IMG_GetAnimationDecoderStatus() (#611)
1 parent 74c7bb5 commit e4ee643

File tree

6 files changed

+54
-6
lines changed

6 files changed

+54
-6
lines changed

include/SDL3_image/SDL_image.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,6 +2403,18 @@ extern SDL_DECLSPEC IMG_Animation * SDLCALL IMG_LoadGIFAnimation_IO(SDL_IOStream
24032403
*/
24042404
extern SDL_DECLSPEC IMG_Animation * SDLCALL IMG_LoadWEBPAnimation_IO(SDL_IOStream *src);
24052405

2406+
/**
2407+
* An enum representing the status of the encoder and decoder.
2408+
*/
2409+
typedef enum IMG_AnimationDecoderStatus
2410+
{
2411+
IMG_DECODER_STATUS_OK, /**< Decoded the frame successfully. */
2412+
IMG_DECODER_STATUS_FAILED, /**< Decoding the frame failed. Call SDL_GetError for more information. */
2413+
IMG_DECODER_STATUS_COMPLETE, /**< No more frames available. */
2414+
2415+
IMG_DECODER_STATUS_INVALID, /**< Invalid decoder status that does not represent any valid status. */
2416+
} IMG_AnimationDecoderStatus;
2417+
24062418
/**
24072419
* An object representing the encoder context.
24082420
*/
@@ -2688,6 +2700,19 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL IMG_GetAnimationDecoderProperties(I
26882700
*/
26892701
extern SDL_DECLSPEC bool SDLCALL IMG_GetAnimationDecoderFrame(IMG_AnimationDecoder *decoder, SDL_Surface **frame, Uint64 *duration);
26902702

2703+
/**
2704+
* Get the decoder status indicating the current state of the decoder.
2705+
*
2706+
* \param decoder the decoder to get the status of.
2707+
* \returns the status of the underlying decoder, or IMG_DECODER_STATUS_INVALID if the given
2708+
* decoder is invalid.
2709+
*
2710+
* \since This function is available since SDL_image 3.4.0.
2711+
*
2712+
* \sa IMG_GetAnimationDecoderFrame
2713+
*/
2714+
extern SDL_DECLSPEC IMG_AnimationDecoderStatus SDLCALL IMG_GetAnimationDecoderStatus(IMG_AnimationDecoder *decoder);
2715+
26912716
/**
26922717
* Reset an animation decoder.
26932718
*

src/IMG_anim_decoder.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,23 @@ bool IMG_GetAnimationDecoderFrame(IMG_AnimationDecoder *decoder, SDL_Surface **f
193193
if (!duration) {
194194
duration = &temp_duration;
195195
}
196-
197196
SDL_ClearError();
197+
// Reset the status before trying to get the next frame.
198+
decoder->status = IMG_DECODER_STATUS_OK;
198199

199200
bool result = decoder->GetNextFrame(decoder, frame, duration);
200201
if (temp_frame) {
201202
SDL_DestroySurface(temp_frame);
202203
}
203204

205+
if (!result) {
206+
if (SDL_GetError()[0] == '\0') {
207+
decoder->status = IMG_DECODER_STATUS_COMPLETE;
208+
} else {
209+
decoder->status = IMG_DECODER_STATUS_FAILED;
210+
}
211+
}
212+
204213
if (result) {
205214
decoder->accumulated_pts += *duration;
206215
} else {
@@ -242,12 +251,22 @@ bool IMG_ResetAnimationDecoder(IMG_AnimationDecoder *decoder)
242251

243252
Uint64 IMG_CalculateDuration(IMG_AnimationDecoder* decoder, int delay_num, int delay_den)
244253
{
245-
if (delay_den < 1)
254+
if (delay_den < 1) {
246255
delay_den = 100;
256+
}
247257

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

261+
IMG_AnimationDecoderStatus IMG_GetAnimationDecoderStatus(IMG_AnimationDecoder* decoder)
262+
{
263+
if (!decoder) {
264+
return IMG_DECODER_STATUS_INVALID;
265+
}
266+
267+
return decoder->status;
268+
}
269+
251270
IMG_Animation *IMG_DecodeAsAnimation(SDL_IOStream *src, const char *format, int maxFrames)
252271
{
253272
IMG_AnimationDecoder *decoder = IMG_CreateAnimationDecoder_IO(src, false, format);

src/IMG_anim_decoder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ typedef struct IMG_AnimationDecoderContext IMG_AnimationDecoderContext;
2323

2424
struct IMG_AnimationDecoder
2525
{
26+
IMG_AnimationDecoderStatus status;
2627
SDL_PropertiesID props;
2728
SDL_IOStream *src;
2829
Sint64 start;

src/IMG_anim_encoder.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,12 @@ bool IMG_AddAnimationEncoderFrame(IMG_AnimationEncoder *encoder, SDL_Surface *su
171171
if (!surface || surface->w <= 0 || surface->h <= 0) {
172172
return SDL_InvalidParamError("surface");
173173
}
174-
175174
bool result = encoder->AddFrame(encoder, surface, duration);
176175

177-
encoder->accumulated_pts += duration;
178-
encoder->last_delay = duration;
176+
if (result) {
177+
encoder->accumulated_pts += duration;
178+
encoder->last_delay = duration;
179+
}
179180

180181
return result;
181182
}

src/IMG_webp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,9 @@ static bool IMG_AnimationDecoderGetNextFrame_Internal(IMG_AnimationDecoder *deco
448448
int totalFrames = decoder->ctx->iter.num_frames;
449449
int availableFrames = totalFrames - (decoder->ctx->iter.frame_num - 1);
450450

451-
if (availableFrames < 1)
451+
if (availableFrames < 1) {
452452
return false;
453+
}
453454

454455
SDL_Surface *canvas = decoder->ctx->canvas;
455456
uint32_t bgcolor = decoder->ctx->bgcolor;

src/SDL_image.sym

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,6 @@ SDL3_image_0.0.0 {
8383
IMG_ResetAnimationDecoder;
8484
IMG_CloseAnimationDecoder;
8585
IMG_GetAnimationDecoderProperties;
86+
IMG_GetAnimationDecoderStatus;
8687
local: *;
8788
};

0 commit comments

Comments
 (0)