comparison gif.c @ 4207:122c1576f705 libavformat

cleanup gif, use BISTREAM_WRITER_LE
author bcoudurier
date Wed, 14 Jan 2009 00:27:43 +0000
parents 7a0230981402
children 77e0c7511d41
comparison
equal deleted inserted replaced
4206:c3102b189cb6 4207:122c1576f705
38 * could help reduce the size of the files _a lot_... 38 * could help reduce the size of the files _a lot_...
39 * some sites mentions an RLE type compression also. 39 * some sites mentions an RLE type compression also.
40 */ 40 */
41 41
42 #include "avformat.h" 42 #include "avformat.h"
43
44 /* The GIF format uses reversed order for bitstreams... */
45 /* at least they don't use PDP_ENDIAN :) */
46 #define BITSTREAM_WRITER_LE
47
43 #include "libavcodec/bitstream.h" 48 #include "libavcodec/bitstream.h"
44 49
45 /* bitstream minipacket size */ 50 /* bitstream minipacket size */
46 #define GIF_CHUNKS 100 51 #define GIF_CHUNKS 100
47 52
99 { 0xff, 0x99, 0x00 }, { 0xff, 0x99, 0x33 }, { 0xff, 0x99, 0x66 }, { 0xff, 0x99, 0x99 }, { 0xff, 0x99, 0xcc }, { 0xff, 0x99, 0xff }, 104 { 0xff, 0x99, 0x00 }, { 0xff, 0x99, 0x33 }, { 0xff, 0x99, 0x66 }, { 0xff, 0x99, 0x99 }, { 0xff, 0x99, 0xcc }, { 0xff, 0x99, 0xff },
100 { 0xff, 0xcc, 0x00 }, { 0xff, 0xcc, 0x33 }, { 0xff, 0xcc, 0x66 }, { 0xff, 0xcc, 0x99 }, { 0xff, 0xcc, 0xcc }, { 0xff, 0xcc, 0xff }, 105 { 0xff, 0xcc, 0x00 }, { 0xff, 0xcc, 0x33 }, { 0xff, 0xcc, 0x66 }, { 0xff, 0xcc, 0x99 }, { 0xff, 0xcc, 0xcc }, { 0xff, 0xcc, 0xff },
101 { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0x33 }, { 0xff, 0xff, 0x66 }, { 0xff, 0xff, 0x99 }, { 0xff, 0xff, 0xcc }, { 0xff, 0xff, 0xff }, 106 { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0x33 }, { 0xff, 0xff, 0x66 }, { 0xff, 0xff, 0x99 }, { 0xff, 0xff, 0xcc }, { 0xff, 0xff, 0xff },
102 }; 107 };
103 108
104 /* The GIF format uses reversed order for bitstreams... */
105 /* at least they don't use PDP_ENDIAN :) */
106 /* so we 'extend' PutBitContext. hmmm, OOP :) */
107 /* seems this thing changed slightly since I wrote it... */
108
109 #ifdef ALT_BITSTREAM_WRITER
110 # error no ALT_BITSTREAM_WRITER support for now
111 #endif
112
113 static void gif_put_bits_rev(PutBitContext *s, int n, unsigned int value)
114 {
115 unsigned int bit_buf;
116 int bit_cnt;
117
118 // printf("put_bits=%d %x\n", n, value);
119 assert(n == 32 || value < (1U << n));
120
121 bit_buf = s->bit_buf;
122 bit_cnt = 32 - s->bit_left; /* XXX:lazyness... was = s->bit_cnt; */
123
124 // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);
125 /* XXX: optimize */
126 if (n < (32-bit_cnt)) {
127 bit_buf |= value << (bit_cnt);
128 bit_cnt+=n;
129 } else {
130 bit_buf |= value << (bit_cnt);
131
132 *s->buf_ptr = bit_buf & 0xff;
133 s->buf_ptr[1] = (bit_buf >> 8) & 0xff;
134 s->buf_ptr[2] = (bit_buf >> 16) & 0xff;
135 s->buf_ptr[3] = (bit_buf >> 24) & 0xff;
136
137 //printf("bitbuf = %08x\n", bit_buf);
138 s->buf_ptr+=4;
139 if (s->buf_ptr >= s->buf_end)
140 abort();
141 // flush_buffer_rev(s);
142 bit_cnt=bit_cnt + n - 32;
143 if (bit_cnt == 0) {
144 bit_buf = 0;
145 } else {
146 bit_buf = value >> (n - bit_cnt);
147 }
148 }
149
150 s->bit_buf = bit_buf;
151 s->bit_left = 32 - bit_cnt;
152 }
153
154 /* pad the end of the output stream with zeros */
155 static void gif_flush_put_bits_rev(PutBitContext *s)
156 {
157 while (s->bit_left < 32) {
158 /* XXX: should test end of buffer */
159 *s->buf_ptr++=s->bit_buf & 0xff;
160 s->bit_buf>>=8;
161 s->bit_left+=8;
162 }
163 // flush_buffer_rev(s);
164 s->bit_left=32;
165 s->bit_buf=0;
166 }
167
168 /* !RevPutBitContext */
169
170 /* GIF header */ 109 /* GIF header */
171 static int gif_image_write_header(ByteIOContext *pb, 110 static int gif_image_write_header(ByteIOContext *pb,
172 int width, int height, int loop_count, 111 int width, int height, int loop_count,
173 uint32_t *palette) 112 uint32_t *palette)
174 { 113 {
270 */ 209 */
271 ptr = buf; 210 ptr = buf;
272 w = width; 211 w = width;
273 while(left>0) { 212 while(left>0) {
274 213
275 gif_put_bits_rev(&p, 9, 0x0100); /* clear code */ 214 put_bits(&p, 9, 0x0100); /* clear code */
276 215
277 for(i=(left<GIF_CHUNKS)?left:GIF_CHUNKS;i;i--) { 216 for(i=(left<GIF_CHUNKS)?left:GIF_CHUNKS;i;i--) {
278 if (pix_fmt == PIX_FMT_RGB24) { 217 if (pix_fmt == PIX_FMT_RGB24) {
279 v = gif_clut_index(ptr[0], ptr[1], ptr[2]); 218 v = gif_clut_index(ptr[0], ptr[1], ptr[2]);
280 ptr+=3; 219 ptr+=3;
281 } else { 220 } else {
282 v = *ptr++; 221 v = *ptr++;
283 } 222 }
284 gif_put_bits_rev(&p, 9, v); 223 put_bits(&p, 9, v);
285 if (--w == 0) { 224 if (--w == 0) {
286 w = width; 225 w = width;
287 buf += linesize; 226 buf += linesize;
288 ptr = buf; 227 ptr = buf;
289 } 228 }
290 } 229 }
291 230
292 if(left<=GIF_CHUNKS) { 231 if(left<=GIF_CHUNKS) {
293 gif_put_bits_rev(&p, 9, 0x101); /* end of stream */ 232 put_bits(&p, 9, 0x101); /* end of stream */
294 gif_flush_put_bits_rev(&p); 233 flush_put_bits(&p);
295 } 234 }
296 if(pbBufPtr(&p) - p.buf > 0) { 235 if(pbBufPtr(&p) - p.buf > 0) {
297 put_byte(pb, pbBufPtr(&p) - p.buf); /* byte count of the packet */ 236 put_byte(pb, pbBufPtr(&p) - p.buf); /* byte count of the packet */
298 put_buffer(pb, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */ 237 put_buffer(pb, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */
299 p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */ 238 p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */