Skip to content

Commit

Permalink
Fix gif decoder for some animated gif files
Browse files Browse the repository at this point in the history
  • Loading branch information
brendan-duncan committed Apr 28, 2023
1 parent f97f10f commit df0fd90
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
32 changes: 24 additions & 8 deletions lib/src/formats/gif_decoder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ class GifDecoder extends Decoder {
if (gifImage == null) {
return info;
}
gifImage
..duration = _duration
..clearFrame = _disposalMethod == 2;
if (_transparentFlag != 0) {
if (gifImage.colorMap == null && info!.globalColorMap != null) {
gifImage.colorMap = GifColorMap.from(info!.globalColorMap!);
}
if (gifImage.colorMap != null) {
gifImage.colorMap!.transparent = _transparent;
}
}
info!.frames.add(gifImage);
break;
case extensionRecordType:
Expand Down Expand Up @@ -95,15 +106,20 @@ class GifDecoder extends Decoder {
}
}

var _transparentFlag = 0;
var _disposalMethod = 0;
var _transparent = 0;
var _duration = 0;

void _readGraphicsControlExt(InputBuffer input) {
/*int blockSize =*/ input.readByte();
final b = input.readByte();
final duration = input.readUint16();
final transparent = input.readByte();
_duration = input.readUint16();
_transparent = input.readByte();
/*int endBlock =*/ input.readByte();
final disposalMethod = (b >> 2) & 0x7;
_disposalMethod = (b >> 2) & 0x7;
//int userInput = (b >> 1) & 0x1;
final transparentFlag = b & 0x1;
_transparentFlag = b & 0x1;

final recordType = input.peekBytes(1)[0];
if (recordType == imageDescRecordType) {
Expand All @@ -114,15 +130,15 @@ class GifDecoder extends Decoder {
}

gifImage
..duration = duration
..clearFrame = disposalMethod == 2;
..duration = _duration
..clearFrame = _disposalMethod == 2;

if (transparentFlag != 0) {
if (_transparentFlag != 0) {
if (gifImage.colorMap == null && info!.globalColorMap != null) {
gifImage.colorMap = GifColorMap.from(info!.globalColorMap!);
}
if (gifImage.colorMap != null) {
gifImage.colorMap!.transparent = transparent;
gifImage.colorMap!.transparent = _transparent;
}
}

Expand Down
Binary file added test/_data/gif/hand_anim.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions test/formats/gif_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import '../_test_util.dart';
void main() {
group('Format', () {
group('gif', () {
test('hand_anim', () async {
final g1 = await decodeGifFile('test/_data/gif/hand_anim.gif');
await encodeGifFile('$testOutputPath/gif/hand_anim.gif', g1!);
});

test('transparencyAnim', () async {
final g1 = await decodePngFile('test/_data/png/g1.png');
final g2 = await decodePngFile('test/_data/png/g2.png');
Expand Down

0 comments on commit df0fd90

Please sign in to comment.