-
-/* XXX: random value that shouldn't be taken into effect if there is no
- * transparent color in the palette (the transparency bit will be set to 0) */
-#define DEFAULT_TRANSPARENCY_INDEX 0x1f
-
-static int get_palette_transparency_index(const uint32_t *palette)
-{
- int transparent_color_index = -1;
- unsigned i, smallest_alpha = 0xff;
-
- if (!palette)
- return -1;
-
- 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;
- }
- }
- return smallest_alpha < 128 ? transparent_color_index : -1;
-}
-
-static int gif_image_write_header(AVIOContext *pb, AVStream *st,
- int loop_count, uint32_t *palette)
-{
- int i;
- int64_t aspect = 0;
- const AVRational sar = st->sample_aspect_ratio;
-
- if (sar.num > 0 && sar.den > 0) {
- aspect = sar.num * 64LL / sar.den - 15;
- if (aspect < 0 || aspect > 255)
- aspect = 0;
- }
-
- avio_write(pb, "GIF", 3);
- avio_write(pb, "89a", 3);
- avio_wl16(pb, st->codecpar->width);
- avio_wl16(pb, st->codecpar->height);
-
- if (palette) {
- const int bcid = get_palette_transparency_index(palette);
-
- avio_w8(pb, 0xf7); /* flags: global clut, 256 entries */
- avio_w8(pb, bcid < 0 ? DEFAULT_TRANSPARENCY_INDEX : bcid); /* background color index */
- avio_w8(pb, aspect);
- for (i = 0; i < 256; i++) {
- const uint32_t v = palette[i] & 0xffffff;
- avio_wb24(pb, v);
- }
- } else {
- avio_w8(pb, 0); /* flags */
- avio_w8(pb, 0); /* background color index */
- avio_w8(pb, aspect);
- }
-
-
- if (loop_count >= 0 ) {
- /* "NETSCAPE EXTENSION" for looped animation GIF */
- avio_w8(pb, 0x21); /* GIF Extension code */
- avio_w8(pb, 0xff); /* Application Extension Label */
- avio_w8(pb, 0x0b); /* Length of Application Block */
- avio_write(pb, "NETSCAPE2.0", sizeof("NETSCAPE2.0") - 1);
- avio_w8(pb, 0x03); /* Length of Data Sub-Block */
- avio_w8(pb, 0x01);
- avio_wl16(pb, (uint16_t)loop_count);
- avio_w8(pb, 0x00); /* Data Sub-block Terminator */
- }
-
- avio_flush(pb);
- return 0;
-}