@@ -123,6 +123,16 @@ int giflib_decoder_get_prev_frame_delay(const giflib_decoder d)
123
123
return d->prev_frame_delay_time ;
124
124
}
125
125
126
+ int giflib_decoder_get_prev_frame_disposal (const giflib_decoder d)
127
+ {
128
+ switch (d->prev_frame_disposal ) {
129
+ case DISPOSE_DO_NOT:
130
+ return GIF_DISPOSE_NONE;
131
+ default :
132
+ return GIF_DISPOSE_BACKGROUND;
133
+ }
134
+ }
135
+
126
136
void giflib_decoder_release (giflib_decoder d)
127
137
{
128
138
if (d->pixels ) {
@@ -1113,15 +1123,15 @@ int giflib_encoder_get_output_length(giflib_encoder e)
1113
1123
return e->dst_offset ;
1114
1124
}
1115
1125
1116
- int giflib_decoder_get_loop_count (const giflib_decoder d) {
1126
+ struct GifAnimationInfo giflib_decoder_get_animation_info (const giflib_decoder d) {
1117
1127
// Default to 1 loop (play once) if no NETSCAPE2.0 extension is found
1118
- int loop_count = 1 ;
1128
+ GifAnimationInfo info = { 1 , 0 }; // Initialize with defaults
1119
1129
1120
1130
// Create a temporary decoder to read extension blocks
1121
1131
// We need a separate decoder because reading extension blocks modifies decoder state
1122
1132
giflib_decoder loopReader = new struct giflib_decoder_struct ();
1123
1133
if (!loopReader) {
1124
- return loop_count ; // Return default on allocation failure
1134
+ return info ; // Return default on allocation failure
1125
1135
}
1126
1136
1127
1137
memset (loopReader, 0 , sizeof (struct giflib_decoder_struct ));
@@ -1131,10 +1141,11 @@ int giflib_decoder_get_loop_count(const giflib_decoder d) {
1131
1141
GifFileType* gif = DGifOpen (loopReader, decode_func, &error);
1132
1142
if (error) {
1133
1143
delete loopReader;
1134
- return loop_count ;
1144
+ return info ;
1135
1145
}
1136
1146
1137
- // Read all blocks until we find NETSCAPE2.0 or hit end
1147
+ bool found_loop_count = false ;
1148
+ // Read all blocks until we hit end
1138
1149
GifRecordType recordType;
1139
1150
while (DGifGetRecordType (gif, &recordType) == GIF_OK) {
1140
1151
switch (recordType) {
@@ -1144,15 +1155,17 @@ int giflib_decoder_get_loop_count(const giflib_decoder d) {
1144
1155
1145
1156
if (DGifGetExtension (gif, &ExtFunction, &ExtData) == GIF_OK && ExtData != NULL ) {
1146
1157
// Look for NETSCAPE2.0 extension
1147
- if (ExtFunction == APPLICATION_EXT_FUNC_CODE && ExtData[0 ] >= 11 &&
1158
+ if (!found_loop_count &&
1159
+ ExtFunction == APPLICATION_EXT_FUNC_CODE &&
1160
+ ExtData[0 ] >= 11 &&
1148
1161
memcmp (ExtData + 1 , " NETSCAPE2.0" , 11 ) == 0 ) {
1149
1162
// Get the next block with loop count
1150
1163
if (DGifGetExtensionNext (gif, &ExtData) == GIF_OK &&
1151
1164
ExtData != NULL &&
1152
1165
ExtData[0 ] >= 3 &&
1153
1166
ExtData[1 ] == 1 ) {
1154
- loop_count = ExtData[2 ] | (ExtData[3 ] << 8 );
1155
- goto cleanup; // Found what we need
1167
+ info. loop_count = ExtData[2 ] | (ExtData[3 ] << 8 );
1168
+ found_loop_count = true ;
1156
1169
}
1157
1170
}
1158
1171
@@ -1167,10 +1180,23 @@ int giflib_decoder_get_loop_count(const giflib_decoder d) {
1167
1180
}
1168
1181
1169
1182
case IMAGE_DESC_RECORD_TYPE:
1170
- // Skip image data
1183
+ // Count frame and skip image data
1184
+ info.frame_count ++;
1171
1185
if (DGifGetImageDesc (gif) != GIF_OK) {
1172
1186
goto cleanup;
1173
1187
}
1188
+ // Skip the image data
1189
+ {
1190
+ GifByteType* CodeBlock;
1191
+ if (DGifGetCode (gif, &error, &CodeBlock) == GIF_ERROR) {
1192
+ goto cleanup;
1193
+ }
1194
+ while (CodeBlock != NULL ) {
1195
+ if (DGifGetCodeNext (gif, &CodeBlock) == GIF_ERROR) {
1196
+ goto cleanup;
1197
+ }
1198
+ }
1199
+ }
1174
1200
break ;
1175
1201
1176
1202
case TERMINATE_RECORD_TYPE:
@@ -1184,5 +1210,5 @@ int giflib_decoder_get_loop_count(const giflib_decoder d) {
1184
1210
cleanup:
1185
1211
DGifCloseFile (gif, &error);
1186
1212
delete loopReader;
1187
- return loop_count ;
1213
+ return info ;
1188
1214
}
0 commit comments