Mercurial > libavcodec.hg
comparison gif.c @ 8774:0a8166d20fd3 libavcodec
remove dead rgb24 code, gif encoder now directly takes palette, patch by Daniel Verkamp, daniel at drv dot nu
author | bcoudurier |
---|---|
date | Mon, 09 Feb 2009 08:14:29 +0000 |
parents | 80a01d448b45 |
children | 7c60077e7380 |
comparison
equal
deleted
inserted
replaced
8773:80a01d448b45 | 8774:0a8166d20fd3 |
---|---|
51 #include "bitstream.h" | 51 #include "bitstream.h" |
52 | 52 |
53 /* bitstream minipacket size */ | 53 /* bitstream minipacket size */ |
54 #define GIF_CHUNKS 100 | 54 #define GIF_CHUNKS 100 |
55 | 55 |
56 typedef struct { | |
57 unsigned char r; | |
58 unsigned char g; | |
59 unsigned char b; | |
60 } rgb_triplet; | |
61 | |
62 /* we use the standard 216 color palette */ | |
63 | |
64 /* this script was used to create the palette: | |
65 * for r in 00 33 66 99 cc ff; do for g in 00 33 66 99 cc ff; do echo -n " "; for b in 00 33 66 99 cc ff; do | |
66 * echo -n "{ 0x$r, 0x$g, 0x$b }, "; done; echo ""; done; done | |
67 */ | |
68 | |
69 static const rgb_triplet gif_clut[216] = { | |
70 { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x33 }, { 0x00, 0x00, 0x66 }, { 0x00, 0x00, 0x99 }, { 0x00, 0x00, 0xcc }, { 0x00, 0x00, 0xff }, | |
71 { 0x00, 0x33, 0x00 }, { 0x00, 0x33, 0x33 }, { 0x00, 0x33, 0x66 }, { 0x00, 0x33, 0x99 }, { 0x00, 0x33, 0xcc }, { 0x00, 0x33, 0xff }, | |
72 { 0x00, 0x66, 0x00 }, { 0x00, 0x66, 0x33 }, { 0x00, 0x66, 0x66 }, { 0x00, 0x66, 0x99 }, { 0x00, 0x66, 0xcc }, { 0x00, 0x66, 0xff }, | |
73 { 0x00, 0x99, 0x00 }, { 0x00, 0x99, 0x33 }, { 0x00, 0x99, 0x66 }, { 0x00, 0x99, 0x99 }, { 0x00, 0x99, 0xcc }, { 0x00, 0x99, 0xff }, | |
74 { 0x00, 0xcc, 0x00 }, { 0x00, 0xcc, 0x33 }, { 0x00, 0xcc, 0x66 }, { 0x00, 0xcc, 0x99 }, { 0x00, 0xcc, 0xcc }, { 0x00, 0xcc, 0xff }, | |
75 { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0x33 }, { 0x00, 0xff, 0x66 }, { 0x00, 0xff, 0x99 }, { 0x00, 0xff, 0xcc }, { 0x00, 0xff, 0xff }, | |
76 { 0x33, 0x00, 0x00 }, { 0x33, 0x00, 0x33 }, { 0x33, 0x00, 0x66 }, { 0x33, 0x00, 0x99 }, { 0x33, 0x00, 0xcc }, { 0x33, 0x00, 0xff }, | |
77 { 0x33, 0x33, 0x00 }, { 0x33, 0x33, 0x33 }, { 0x33, 0x33, 0x66 }, { 0x33, 0x33, 0x99 }, { 0x33, 0x33, 0xcc }, { 0x33, 0x33, 0xff }, | |
78 { 0x33, 0x66, 0x00 }, { 0x33, 0x66, 0x33 }, { 0x33, 0x66, 0x66 }, { 0x33, 0x66, 0x99 }, { 0x33, 0x66, 0xcc }, { 0x33, 0x66, 0xff }, | |
79 { 0x33, 0x99, 0x00 }, { 0x33, 0x99, 0x33 }, { 0x33, 0x99, 0x66 }, { 0x33, 0x99, 0x99 }, { 0x33, 0x99, 0xcc }, { 0x33, 0x99, 0xff }, | |
80 { 0x33, 0xcc, 0x00 }, { 0x33, 0xcc, 0x33 }, { 0x33, 0xcc, 0x66 }, { 0x33, 0xcc, 0x99 }, { 0x33, 0xcc, 0xcc }, { 0x33, 0xcc, 0xff }, | |
81 { 0x33, 0xff, 0x00 }, { 0x33, 0xff, 0x33 }, { 0x33, 0xff, 0x66 }, { 0x33, 0xff, 0x99 }, { 0x33, 0xff, 0xcc }, { 0x33, 0xff, 0xff }, | |
82 { 0x66, 0x00, 0x00 }, { 0x66, 0x00, 0x33 }, { 0x66, 0x00, 0x66 }, { 0x66, 0x00, 0x99 }, { 0x66, 0x00, 0xcc }, { 0x66, 0x00, 0xff }, | |
83 { 0x66, 0x33, 0x00 }, { 0x66, 0x33, 0x33 }, { 0x66, 0x33, 0x66 }, { 0x66, 0x33, 0x99 }, { 0x66, 0x33, 0xcc }, { 0x66, 0x33, 0xff }, | |
84 { 0x66, 0x66, 0x00 }, { 0x66, 0x66, 0x33 }, { 0x66, 0x66, 0x66 }, { 0x66, 0x66, 0x99 }, { 0x66, 0x66, 0xcc }, { 0x66, 0x66, 0xff }, | |
85 { 0x66, 0x99, 0x00 }, { 0x66, 0x99, 0x33 }, { 0x66, 0x99, 0x66 }, { 0x66, 0x99, 0x99 }, { 0x66, 0x99, 0xcc }, { 0x66, 0x99, 0xff }, | |
86 { 0x66, 0xcc, 0x00 }, { 0x66, 0xcc, 0x33 }, { 0x66, 0xcc, 0x66 }, { 0x66, 0xcc, 0x99 }, { 0x66, 0xcc, 0xcc }, { 0x66, 0xcc, 0xff }, | |
87 { 0x66, 0xff, 0x00 }, { 0x66, 0xff, 0x33 }, { 0x66, 0xff, 0x66 }, { 0x66, 0xff, 0x99 }, { 0x66, 0xff, 0xcc }, { 0x66, 0xff, 0xff }, | |
88 { 0x99, 0x00, 0x00 }, { 0x99, 0x00, 0x33 }, { 0x99, 0x00, 0x66 }, { 0x99, 0x00, 0x99 }, { 0x99, 0x00, 0xcc }, { 0x99, 0x00, 0xff }, | |
89 { 0x99, 0x33, 0x00 }, { 0x99, 0x33, 0x33 }, { 0x99, 0x33, 0x66 }, { 0x99, 0x33, 0x99 }, { 0x99, 0x33, 0xcc }, { 0x99, 0x33, 0xff }, | |
90 { 0x99, 0x66, 0x00 }, { 0x99, 0x66, 0x33 }, { 0x99, 0x66, 0x66 }, { 0x99, 0x66, 0x99 }, { 0x99, 0x66, 0xcc }, { 0x99, 0x66, 0xff }, | |
91 { 0x99, 0x99, 0x00 }, { 0x99, 0x99, 0x33 }, { 0x99, 0x99, 0x66 }, { 0x99, 0x99, 0x99 }, { 0x99, 0x99, 0xcc }, { 0x99, 0x99, 0xff }, | |
92 { 0x99, 0xcc, 0x00 }, { 0x99, 0xcc, 0x33 }, { 0x99, 0xcc, 0x66 }, { 0x99, 0xcc, 0x99 }, { 0x99, 0xcc, 0xcc }, { 0x99, 0xcc, 0xff }, | |
93 { 0x99, 0xff, 0x00 }, { 0x99, 0xff, 0x33 }, { 0x99, 0xff, 0x66 }, { 0x99, 0xff, 0x99 }, { 0x99, 0xff, 0xcc }, { 0x99, 0xff, 0xff }, | |
94 { 0xcc, 0x00, 0x00 }, { 0xcc, 0x00, 0x33 }, { 0xcc, 0x00, 0x66 }, { 0xcc, 0x00, 0x99 }, { 0xcc, 0x00, 0xcc }, { 0xcc, 0x00, 0xff }, | |
95 { 0xcc, 0x33, 0x00 }, { 0xcc, 0x33, 0x33 }, { 0xcc, 0x33, 0x66 }, { 0xcc, 0x33, 0x99 }, { 0xcc, 0x33, 0xcc }, { 0xcc, 0x33, 0xff }, | |
96 { 0xcc, 0x66, 0x00 }, { 0xcc, 0x66, 0x33 }, { 0xcc, 0x66, 0x66 }, { 0xcc, 0x66, 0x99 }, { 0xcc, 0x66, 0xcc }, { 0xcc, 0x66, 0xff }, | |
97 { 0xcc, 0x99, 0x00 }, { 0xcc, 0x99, 0x33 }, { 0xcc, 0x99, 0x66 }, { 0xcc, 0x99, 0x99 }, { 0xcc, 0x99, 0xcc }, { 0xcc, 0x99, 0xff }, | |
98 { 0xcc, 0xcc, 0x00 }, { 0xcc, 0xcc, 0x33 }, { 0xcc, 0xcc, 0x66 }, { 0xcc, 0xcc, 0x99 }, { 0xcc, 0xcc, 0xcc }, { 0xcc, 0xcc, 0xff }, | |
99 { 0xcc, 0xff, 0x00 }, { 0xcc, 0xff, 0x33 }, { 0xcc, 0xff, 0x66 }, { 0xcc, 0xff, 0x99 }, { 0xcc, 0xff, 0xcc }, { 0xcc, 0xff, 0xff }, | |
100 { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0x33 }, { 0xff, 0x00, 0x66 }, { 0xff, 0x00, 0x99 }, { 0xff, 0x00, 0xcc }, { 0xff, 0x00, 0xff }, | |
101 { 0xff, 0x33, 0x00 }, { 0xff, 0x33, 0x33 }, { 0xff, 0x33, 0x66 }, { 0xff, 0x33, 0x99 }, { 0xff, 0x33, 0xcc }, { 0xff, 0x33, 0xff }, | |
102 { 0xff, 0x66, 0x00 }, { 0xff, 0x66, 0x33 }, { 0xff, 0x66, 0x66 }, { 0xff, 0x66, 0x99 }, { 0xff, 0x66, 0xcc }, { 0xff, 0x66, 0xff }, | |
103 { 0xff, 0x99, 0x00 }, { 0xff, 0x99, 0x33 }, { 0xff, 0x99, 0x66 }, { 0xff, 0x99, 0x99 }, { 0xff, 0x99, 0xcc }, { 0xff, 0x99, 0xff }, | |
104 { 0xff, 0xcc, 0x00 }, { 0xff, 0xcc, 0x33 }, { 0xff, 0xcc, 0x66 }, { 0xff, 0xcc, 0x99 }, { 0xff, 0xcc, 0xcc }, { 0xff, 0xcc, 0xff }, | |
105 { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0x33 }, { 0xff, 0xff, 0x66 }, { 0xff, 0xff, 0x99 }, { 0xff, 0xff, 0xcc }, { 0xff, 0xff, 0xff }, | |
106 }; | |
107 | |
108 /* GIF header */ | 56 /* GIF header */ |
109 static int gif_image_write_header(uint8_t **bytestream, | 57 static int gif_image_write_header(uint8_t **bytestream, |
110 int width, int height, | 58 int width, int height, |
111 uint32_t *palette) | 59 uint32_t *palette) |
112 { | 60 { |
121 bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */ | 69 bytestream_put_byte(bytestream, 0xf7); /* flags: global clut, 256 entries */ |
122 bytestream_put_byte(bytestream, 0x1f); /* background color index */ | 70 bytestream_put_byte(bytestream, 0x1f); /* background color index */ |
123 bytestream_put_byte(bytestream, 0); /* aspect ratio */ | 71 bytestream_put_byte(bytestream, 0); /* aspect ratio */ |
124 | 72 |
125 /* the global palette */ | 73 /* the global palette */ |
126 if (!palette) { | 74 for(i=0;i<256;i++) { |
127 bytestream_put_buffer(bytestream, (const unsigned char *)gif_clut, 216*3); | 75 v = palette[i]; |
128 for(i=0;i<((256-216)*3);i++) | 76 bytestream_put_be24(bytestream, v); |
129 bytestream_put_byte(bytestream, 0); | |
130 } else { | |
131 for(i=0;i<256;i++) { | |
132 v = palette[i]; | |
133 bytestream_put_be24(bytestream, v); | |
134 } | |
135 } | 77 } |
136 | 78 |
137 return 0; | 79 return 0; |
138 } | 80 } |
139 | |
140 /* this is maybe slow, but allows for extensions */ | |
141 static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b) | |
142 { | |
143 return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6)); | |
144 } | |
145 | |
146 | 81 |
147 static int gif_image_write_image(uint8_t **bytestream, | 82 static int gif_image_write_image(uint8_t **bytestream, |
148 int x1, int y1, int width, int height, | 83 int x1, int y1, int width, int height, |
149 const uint8_t *buf, int linesize, int pix_fmt) | 84 const uint8_t *buf, int linesize, int pix_fmt) |
150 { | 85 { |
151 PutBitContext p; | 86 PutBitContext p; |
152 uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */ | 87 uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */ |
153 int i, left, w, v; | 88 int i, left, w; |
154 const uint8_t *ptr; | 89 const uint8_t *ptr; |
155 /* image block */ | 90 /* image block */ |
156 | 91 |
157 bytestream_put_byte(bytestream, 0x2c); | 92 bytestream_put_byte(bytestream, 0x2c); |
158 bytestream_put_le16(bytestream, x1); | 93 bytestream_put_le16(bytestream, x1); |
177 while(left>0) { | 112 while(left>0) { |
178 | 113 |
179 put_bits(&p, 9, 0x0100); /* clear code */ | 114 put_bits(&p, 9, 0x0100); /* clear code */ |
180 | 115 |
181 for(i=(left<GIF_CHUNKS)?left:GIF_CHUNKS;i;i--) { | 116 for(i=(left<GIF_CHUNKS)?left:GIF_CHUNKS;i;i--) { |
182 if (pix_fmt == PIX_FMT_RGB24) { | 117 put_bits(&p, 9, *ptr++); |
183 v = gif_clut_index(ptr[0], ptr[1], ptr[2]); | |
184 ptr+=3; | |
185 } else { | |
186 v = *ptr++; | |
187 } | |
188 put_bits(&p, 9, v); | |
189 if (--w == 0) { | 118 if (--w == 0) { |
190 w = width; | 119 w = width; |
191 buf += linesize; | 120 buf += linesize; |
192 ptr = buf; | 121 ptr = buf; |
193 } | 122 } |