@@ -18,7 +18,6 @@ struct giflib_decoder_struct {
18
18
uint8_t bg_red;
19
19
uint8_t bg_blue;
20
20
uint8_t bg_alpha;
21
- uint32_t background_color;
22
21
bool have_read_first_frame;
23
22
bool seek_clear_extensions;
24
23
};
@@ -134,11 +133,6 @@ int giflib_decoder_get_prev_frame_disposal(const giflib_decoder d)
134
133
}
135
134
}
136
135
137
- uint32_t giflib_decoder_get_background_color (const giflib_decoder d)
138
- {
139
- return d->background_color ;
140
- }
141
-
142
136
void giflib_decoder_release (giflib_decoder d)
143
137
{
144
138
if (d->pixels ) {
@@ -490,6 +484,23 @@ giflib_decoder_frame_state giflib_decoder_skip_frame(giflib_decoder d)
490
484
static int interlace_offset[] = {0 , 4 , 2 , 1 };
491
485
static int interlace_jumps[] = {8 , 8 , 4 , 2 };
492
486
487
+ static void extract_background_color (GifFileType* gif, GraphicsControlBlock* gcb,
488
+ uint8_t * r, uint8_t * g, uint8_t * b, uint8_t * a) {
489
+ bool have_transparency = (gcb->TransparentColor != NO_TRANSPARENT_COLOR);
490
+ if (have_transparency) {
491
+ *r = *g = *b = *a = 0 ;
492
+ }
493
+ else if (gif->SColorMap && gif->SColorMap ->Colors ) {
494
+ *r = gif->SColorMap ->Colors [gif->SBackGroundColor ].Red ;
495
+ *g = gif->SColorMap ->Colors [gif->SBackGroundColor ].Green ;
496
+ *b = gif->SColorMap ->Colors [gif->SBackGroundColor ].Blue ;
497
+ *a = 255 ;
498
+ }
499
+ else {
500
+ *r = *g = *b = *a = 255 ;
501
+ }
502
+ }
503
+
493
504
// decode the full frame and write it into mat
494
505
// decode_frame_header *must* be called before this function
495
506
bool giflib_decoder_decode_frame (giflib_decoder d, opencv_mat mat)
@@ -557,21 +568,9 @@ bool giflib_decoder_decode_frame(giflib_decoder d, opencv_mat mat)
557
568
giflib_get_frame_gcb (d->gif , &gcb);
558
569
559
570
if (!d->have_read_first_frame ) {
560
- bool have_transparency = (gcb.TransparentColor != NO_TRANSPARENT_COLOR);
561
- if (have_transparency) {
562
- d->bg_red = d->bg_green = d->bg_blue = d->bg_alpha = 0 ;
563
- }
564
- else if (d->gif ->SColorMap && d->gif ->SColorMap ->Colors ) {
565
- d->bg_red = d->gif ->SColorMap ->Colors [d->gif ->SBackGroundColor ].Red ;
566
- d->bg_green = d->gif ->SColorMap ->Colors [d->gif ->SBackGroundColor ].Green ;
567
- d->bg_blue = d->gif ->SColorMap ->Colors [d->gif ->SBackGroundColor ].Blue ;
568
- d->bg_alpha = 255 ;
569
- }
570
- else {
571
- d->bg_red = d->bg_green = d->bg_blue = d->bg_alpha = 255 ;
572
- }
573
- d->background_color = (uint32_t )d->bg_alpha << 24 | ((uint32_t )d->bg_red << 16 ) |
574
- ((uint32_t )d->bg_green << 8 ) | (uint32_t )d->bg_blue ;
571
+ GraphicsControlBlock gcb;
572
+ giflib_get_frame_gcb (d->gif , &gcb);
573
+ extract_background_color (d->gif , &gcb, &d->bg_red , &d->bg_green , &d->bg_blue , &d->bg_alpha );
575
574
}
576
575
577
576
if (!giflib_decoder_render_frame (d, &gcb, mat)) {
@@ -1133,10 +1132,9 @@ int giflib_encoder_get_output_length(giflib_encoder e)
1133
1132
1134
1133
struct GifAnimationInfo giflib_decoder_get_animation_info (const giflib_decoder d) {
1135
1134
// Default to 1 loop (play once) if no NETSCAPE2.0 extension is found
1136
- GifAnimationInfo info = {1 , 0 }; // Initialize with defaults
1135
+ GifAnimationInfo info = {1 , 0 , 255 , 255 , 255 , 0 }; // loop_count, frame_count, bg_r, bg_g, bg_b, bg_a
1137
1136
1138
1137
// Create a temporary decoder to read extension blocks
1139
- // We need a separate decoder because reading extension blocks modifies decoder state
1140
1138
giflib_decoder loopReader = new struct giflib_decoder_struct ();
1141
1139
if (!loopReader) {
1142
1140
return info; // Return default on allocation failure
@@ -1153,21 +1151,31 @@ struct GifAnimationInfo giflib_decoder_get_animation_info(const giflib_decoder d
1153
1151
}
1154
1152
1155
1153
bool found_loop_count = false ;
1156
- // Read all blocks until we hit end
1154
+ bool found_gcb = false ;
1155
+ GraphicsControlBlock gcb = {};
1157
1156
GifRecordType recordType;
1157
+
1158
+ // Read all blocks until we hit end
1158
1159
while (DGifGetRecordType (gif, &recordType) == GIF_OK) {
1159
1160
switch (recordType) {
1160
1161
case EXTENSION_RECORD_TYPE: {
1161
1162
GifByteType* ExtData;
1162
1163
int ExtFunction;
1163
1164
1164
1165
if (DGifGetExtension (gif, &ExtFunction, &ExtData) == GIF_OK && ExtData != NULL ) {
1166
+ // Look for GraphicsControlBlock if we haven't found it yet
1167
+ if (!found_gcb && ExtFunction == GRAPHICS_EXT_FUNC_CODE) {
1168
+ found_gcb = true ;
1169
+ DGifExtensionToGCB (ExtData[0 ], &ExtData[1 ], &gcb);
1170
+ // Get background color as soon as we have the GCB
1171
+ extract_background_color (gif, &gcb, &info.bg_red , &info.bg_green ,
1172
+ &info.bg_blue , &info.bg_alpha );
1173
+ }
1165
1174
// Look for NETSCAPE2.0 extension
1166
- if (!found_loop_count &&
1175
+ else if (!found_loop_count &&
1167
1176
ExtFunction == APPLICATION_EXT_FUNC_CODE &&
1168
1177
ExtData[0 ] >= 11 &&
1169
1178
memcmp (ExtData + 1 , " NETSCAPE2.0" , 11 ) == 0 ) {
1170
- // Get the next block with loop count
1171
1179
if (DGifGetExtensionNext (gif, &ExtData) == GIF_OK &&
1172
1180
ExtData != NULL &&
1173
1181
ExtData[0 ] >= 3 &&
@@ -1215,6 +1223,12 @@ struct GifAnimationInfo giflib_decoder_get_animation_info(const giflib_decoder d
1215
1223
}
1216
1224
}
1217
1225
1226
+ // If we never found a GCB, still need to set background color
1227
+ if (!found_gcb) {
1228
+ extract_background_color (gif, &gcb, &info.bg_red , &info.bg_green ,
1229
+ &info.bg_blue , &info.bg_alpha );
1230
+ }
1231
+
1218
1232
cleanup:
1219
1233
DGifCloseFile (gif, &error);
1220
1234
delete loopReader;
0 commit comments