From f4c4905d9eda05332f970eeadc7a2a5b2ddb31a2 Mon Sep 17 00:00:00 2001 From: flashk Date: Thu, 1 Nov 2018 10:49:40 -0700 Subject: [PATCH 1/2] Fix handling of alpha values in animated gifs The gif loader was incorrectly setting pixels as transparent in certain animated gifs. It was ignoring the disposal method value in the extension block and always overwriting the alpha value in each frame. It is common for some animated gifs to set the disposal method so that the previous alpha value is retained. This patch modifies the loader to respect the disposal method flag. --- src/osgPlugins/gif/ReaderWriterGIF.cpp | 28 +++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/osgPlugins/gif/ReaderWriterGIF.cpp b/src/osgPlugins/gif/ReaderWriterGIF.cpp index d9369902c..668735281 100644 --- a/src/osgPlugins/gif/ReaderWriterGIF.cpp +++ b/src/osgPlugins/gif/ReaderWriterGIF.cpp @@ -295,7 +295,8 @@ decode_row(GifFileType * giffile, unsigned char * buffer, unsigned char * rowdata, int x, int y, int len, -int transparent) +int transparent, +int overwrite) { GifColorType * cmentry; ColorMapObject * colormap; @@ -321,6 +322,8 @@ int transparent) // keep pixels of last image if transparent mode is on // this is necessary for GIF animating ptr += 3; + if(overwrite) *ptr = 0x00; + ++ptr; } else { @@ -337,8 +340,8 @@ int transparent) *ptr++ = col; *ptr++ = col; } + *ptr++ = 0xff; } - *ptr++ = (col == transparent ? 0x00 : 0xff); } } @@ -360,7 +363,7 @@ GifImageStream** obj) unsigned char * rowdata; unsigned char * buffer, * ptr; unsigned char bg; - int transparent, delaytime; + int transparent, delaytime, overwrite; GifRecordType recordtype; GifByteType * extension; GifFileType * giffile; @@ -383,6 +386,7 @@ GifImageStream** obj) transparent = -1; /* no transparent color by default */ delaytime = 8; /* delay time of a frame */ + overwrite = 1; /* overwrite previous alpha values in animated gifs */ n = giffile->SHeight * giffile->SWidth; buffer = new unsigned char [n * 4]; @@ -485,7 +489,7 @@ GifImageStream** obj) delete [] rowdata; return NULL; } - else decode_row(giffile, buffer, rowdata, col, j, width, transparent); + else decode_row(giffile, buffer, rowdata, col, j, width, transparent, gif_num > 1 ? overwrite : true); } } } @@ -500,7 +504,7 @@ GifImageStream** obj) delete [] rowdata; return NULL; } - else decode_row(giffile, buffer, rowdata, col, row, width, transparent); + else decode_row(giffile, buffer, rowdata, col, row, width, transparent, gif_num > 1 ? overwrite : true); } } @@ -529,6 +533,20 @@ GifImageStream** obj) if (extension[0] >= 4 && extension[1] & 0x1) transparent = extension[4]; else transparent = -1; + // Set alpha overwrite flag based on disposal method + unsigned char disposal_method = (extension[1]>>2) & 0x7; + switch (disposal_method) + { + case 0: + case 2: + overwrite = 1; + break; + case 1: + case 3: + overwrite = 0; + break; + } + delaytime = (extension[3]<<8)+extension[2]; // minimum unit 1/100s, so 8 here means 8/100s } while (extension != NULL) From ba7147dd951ef396d1a363bc237f6636b76c0b46 Mon Sep 17 00:00:00 2001 From: OpenSceneGraph git repository Date: Fri, 2 Nov 2018 08:34:43 +0000 Subject: [PATCH 2/2] Replaced tabs with spaces to fix indentation --- src/osgPlugins/gif/ReaderWriterGIF.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgPlugins/gif/ReaderWriterGIF.cpp b/src/osgPlugins/gif/ReaderWriterGIF.cpp index 668735281..70baf48b8 100644 --- a/src/osgPlugins/gif/ReaderWriterGIF.cpp +++ b/src/osgPlugins/gif/ReaderWriterGIF.cpp @@ -322,7 +322,7 @@ int overwrite) // keep pixels of last image if transparent mode is on // this is necessary for GIF animating ptr += 3; - if(overwrite) *ptr = 0x00; + if(overwrite) *ptr = 0x00; ++ptr; } else @@ -340,7 +340,7 @@ int overwrite) *ptr++ = col; *ptr++ = col; } - *ptr++ = 0xff; + *ptr++ = 0xff; } } }