@@ -18,7 +18,6 @@ struct giflib_decoder_struct {
1818 uint8_t bg_red;
1919 uint8_t bg_blue;
2020 uint8_t bg_alpha;
21- uint32_t background_color;
2221 bool have_read_first_frame;
2322 bool seek_clear_extensions;
2423};
@@ -134,11 +133,6 @@ int giflib_decoder_get_prev_frame_disposal(const giflib_decoder d)
134133 }
135134}
136135
137- uint32_t giflib_decoder_get_background_color (const giflib_decoder d)
138- {
139- return d->background_color ;
140- }
141-
142136void giflib_decoder_release (giflib_decoder d)
143137{
144138 if (d->pixels ) {
@@ -490,6 +484,23 @@ giflib_decoder_frame_state giflib_decoder_skip_frame(giflib_decoder d)
490484static int interlace_offset[] = {0 , 4 , 2 , 1 };
491485static int interlace_jumps[] = {8 , 8 , 4 , 2 };
492486
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+
493504// decode the full frame and write it into mat
494505// decode_frame_header *must* be called before this function
495506bool 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)
557568 giflib_get_frame_gcb (d->gif , &gcb);
558569
559570 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 );
575574 }
576575
577576 if (!giflib_decoder_render_frame (d, &gcb, mat)) {
@@ -1133,10 +1132,9 @@ int giflib_encoder_get_output_length(giflib_encoder e)
11331132
11341133struct GifAnimationInfo giflib_decoder_get_animation_info (const giflib_decoder d) {
11351134 // 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
11371136
11381137 // Create a temporary decoder to read extension blocks
1139- // We need a separate decoder because reading extension blocks modifies decoder state
11401138 giflib_decoder loopReader = new struct giflib_decoder_struct ();
11411139 if (!loopReader) {
11421140 return info; // Return default on allocation failure
@@ -1153,21 +1151,31 @@ struct GifAnimationInfo giflib_decoder_get_animation_info(const giflib_decoder d
11531151 }
11541152
11551153 bool found_loop_count = false ;
1156- // Read all blocks until we hit end
1154+ bool found_gcb = false ;
1155+ GraphicsControlBlock gcb = {};
11571156 GifRecordType recordType;
1157+
1158+ // Read all blocks until we hit end
11581159 while (DGifGetRecordType (gif, &recordType) == GIF_OK) {
11591160 switch (recordType) {
11601161 case EXTENSION_RECORD_TYPE: {
11611162 GifByteType* ExtData;
11621163 int ExtFunction;
11631164
11641165 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+ }
11651174 // Look for NETSCAPE2.0 extension
1166- if (!found_loop_count &&
1175+ else if (!found_loop_count &&
11671176 ExtFunction == APPLICATION_EXT_FUNC_CODE &&
11681177 ExtData[0 ] >= 11 &&
11691178 memcmp (ExtData + 1 , " NETSCAPE2.0" , 11 ) == 0 ) {
1170- // Get the next block with loop count
11711179 if (DGifGetExtensionNext (gif, &ExtData) == GIF_OK &&
11721180 ExtData != NULL &&
11731181 ExtData[0 ] >= 3 &&
@@ -1215,6 +1223,12 @@ struct GifAnimationInfo giflib_decoder_get_animation_info(const giflib_decoder d
12151223 }
12161224 }
12171225
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+
12181232cleanup:
12191233 DGifCloseFile (gif, &error);
12201234 delete loopReader;
0 commit comments