summaryrefslogtreecommitdiff
path: root/libavformat/gif.c
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2003-02-09 16:25:21 +0000
committerFabrice Bellard <fabrice@bellard.org>2003-02-09 16:25:21 +0000
commit84ab361f3e85e7063b3e0744f5e3aa3a43648030 (patch)
treea49a9aeaf1c6c3ef2d84845d23bec1eeff8afa52 /libavformat/gif.c
parent3ce27f13b9a6a0435cfa5c0b1c50419886e08eb1 (diff)
added 8 bit palette support for non animated GIF
Originally committed as revision 1562 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/gif.c')
-rw-r--r--libavformat/gif.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/libavformat/gif.c b/libavformat/gif.c
index 20ae2a239b..44f3edcc89 100644
--- a/libavformat/gif.c
+++ b/libavformat/gif.c
@@ -167,9 +167,11 @@ static void gif_flush_put_bits_rev(PutBitContext *s)
/* !RevPutBitContext */
/* GIF header */
-static int gif_image_write_header(ByteIOContext *pb, int width, int height)
+static int gif_image_write_header(ByteIOContext *pb,
+ int width, int height, uint32_t *palette)
{
int i;
+ unsigned int v;
put_tag(pb, "GIF");
put_tag(pb, "89a");
@@ -181,10 +183,18 @@ static int gif_image_write_header(ByteIOContext *pb, int width, int height)
put_byte(pb, 0); /* aspect ratio */
/* the global palette */
-
- put_buffer(pb, (unsigned char *)gif_clut, 216*3);
- for(i=0;i<((256-216)*3);i++)
- put_byte(pb, 0);
+ if (!palette) {
+ put_buffer(pb, (unsigned char *)gif_clut, 216*3);
+ for(i=0;i<((256-216)*3);i++)
+ put_byte(pb, 0);
+ } else {
+ for(i=0;i<256;i++) {
+ v = palette[i];
+ put_byte(pb, (v >> 16) & 0xff);
+ put_byte(pb, (v >> 8) & 0xff);
+ put_byte(pb, (v) & 0xff);
+ }
+ }
/* application extension header */
/* XXX: not really sure what to put in here... */
@@ -202,7 +212,7 @@ static int gif_image_write_header(ByteIOContext *pb, int width, int height)
}
/* this is maybe slow, but allows for extensions */
-static inline unsigned char gif_clut_index(rgb_triplet *clut, UINT8 r, UINT8 g, UINT8 b)
+static inline unsigned char gif_clut_index(UINT8 r, UINT8 g, UINT8 b)
{
return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));
}
@@ -210,11 +220,11 @@ static inline unsigned char gif_clut_index(rgb_triplet *clut, UINT8 r, UINT8 g,
static int gif_image_write_image(ByteIOContext *pb,
int x1, int y1, int width, int height,
- uint8_t *buf, int linesize)
+ uint8_t *buf, int linesize, int pix_fmt)
{
PutBitContext p;
UINT8 buffer[200]; /* 100 * 9 / 8 = 113 */
- int i, left, w;
+ int i, left, w, v;
uint8_t *ptr;
/* image block */
@@ -243,8 +253,13 @@ static int gif_image_write_image(ByteIOContext *pb,
gif_put_bits_rev(&p, 9, 0x0100); /* clear code */
for(i=0;i<GIF_CHUNKS;i++) {
- gif_put_bits_rev(&p, 9, gif_clut_index(NULL, ptr[0], ptr[1], ptr[2]));
- ptr+=3;
+ if (pix_fmt == PIX_FMT_RGB24) {
+ v = gif_clut_index(ptr[0], ptr[1], ptr[2]);
+ ptr+=3;
+ } else {
+ v = *ptr++;
+ }
+ gif_put_bits_rev(&p, 9, v);
if (--w == 0) {
w = width;
buf += linesize;
@@ -309,22 +324,12 @@ static int gif_write_header(AVFormatContext *s)
/* XXX: is it allowed ? seems to work so far... */
video_enc->pix_fmt = PIX_FMT_RGB24;
- gif_image_write_header(pb, width, height);
+ gif_image_write_header(pb, width, height, NULL);
put_flush_packet(&s->pb);
return 0;
}
-/* chunk writer callback */
-/* !!! XXX:deprecated
-static void gif_put_chunk(void *pbctx, UINT8 *buffer, int count)
-{
- ByteIOContext *pb = (ByteIOContext *)pbctx;
- put_byte(pb, (UINT8)count);
- put_buffer(pb, buffer, count);
-}
-*/
-
static int gif_write_video(AVFormatContext *s,
AVCodecContext *enc, UINT8 *buf, int size)
{
@@ -354,7 +359,7 @@ static int gif_write_video(AVFormatContext *s,
put_byte(pb, 0x00);
gif_image_write_image(pb, 0, 0, enc->width, enc->height,
- buf, enc->width * 3);
+ buf, enc->width * 3, PIX_FMT_RGB24);
put_flush_packet(&s->pb);
return 0;
@@ -382,9 +387,11 @@ static int gif_write_trailer(AVFormatContext *s)
/* better than nothing gif image writer */
int gif_write(ByteIOContext *pb, AVImageInfo *info)
{
- gif_image_write_header(pb, info->width, info->height);
+ gif_image_write_header(pb, info->width, info->height,
+ (uint32_t *)info->pict.data[1]);
gif_image_write_image(pb, 0, 0, info->width, info->height,
- info->pict.data[0], info->pict.linesize[0]);
+ info->pict.data[0], info->pict.linesize[0],
+ PIX_FMT_PAL8);
put_byte(pb, 0x3b);
put_flush_packet(pb);
return 0;