Mercurial > libavformat.hg
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 */ |