From 13478b270adffcdf6fb2f0daf28b64dfbf71515a Mon Sep 17 00:00:00 2001 From: Clément Bœsch Date: Thu, 18 Apr 2013 03:35:20 +0200 Subject: gif: use only one graphic control extension block per image. The encoder now doesn't produce any extra graphic control extension block anymore. Only the image is encoded, and the muxer writing its own GCE containing notably the timing information now includes the optional palette transmitted through packet side data. This commit avoid setting clashes between the two GCE, and reduce the size of the generated file with pal8 output. --- libavformat/gif.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'libavformat/gif.c') diff --git a/libavformat/gif.c b/libavformat/gif.c index 3d86f23fe6..f26d537b84 100644 --- a/libavformat/gif.c +++ b/libavformat/gif.c @@ -102,15 +102,39 @@ static int gif_write_header(AVFormatContext *s) static int gif_write_packet(AVFormatContext *s, AVPacket *pkt) { + int size; AVCodecContext *enc = s->streams[pkt->stream_index]->codec; AVIOContext *pb = s->pb; int jiffies; + uint8_t flags = 0x4, transparent_color_index = 0x1f; + const uint32_t *palette; + + /* Mark one colour as transparent if the input palette contains at least + * one colour that is more than 50% transparent. */ + palette = (uint32_t*)av_packet_get_side_data(pkt, AV_PKT_DATA_PALETTE, &size); + if (palette && size != AVPALETTE_SIZE) { + av_log(s, AV_LOG_ERROR, "Invalid palette extradata\n"); + return AVERROR_INVALIDDATA; + } + if (palette) { + unsigned i, smallest_alpha = 0xff; + + for (i = 0; i < AVPALETTE_COUNT; i++) { + const uint32_t v = palette[i]; + if (v >> 24 < smallest_alpha) { + smallest_alpha = v >> 24; + transparent_color_index = i; + } + } + if (smallest_alpha < 128) + flags |= 0x1; /* Transparent Color Flag */ + } /* graphic control extension block */ avio_w8(pb, 0x21); avio_w8(pb, 0xf9); avio_w8(pb, 0x04); /* block size */ - avio_w8(pb, 0x04); /* flags */ + avio_w8(pb, flags); /* 1 jiffy is 1/70 s */ /* the delay_time field indicates the number of jiffies - 1 */ @@ -121,7 +145,7 @@ static int gif_write_packet(AVFormatContext *s, AVPacket *pkt) avio_wl16(pb, jiffies); - avio_w8(pb, 0x1f); /* transparent color index */ + avio_w8(pb, transparent_color_index); avio_w8(pb, 0x00); avio_write(pb, pkt->data, pkt->size); -- cgit v1.2.3