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 }