Mercurial > mplayer.hg
annotate libvo/vo_gif89a.c @ 7703:386e76d9c0cc
argh 100l
author | nexus |
---|---|
date | Thu, 10 Oct 2002 09:14:53 +0000 |
parents | e60109dfc85c |
children | 9fc45fe0d444 |
rev | line source |
---|---|
6053 | 1 /* |
2 * vo_gif89a.c Generate gif89a output in file out.gif | |
3 * | |
4 * Originally based on vo_png.c | |
5 * | |
6 * Stolen (C) 2002 by GifWhore <joey@yunamusic.com> | |
7 * | |
8 */ | |
9 | |
10 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 #include <string.h> | |
13 #include <errno.h> | |
14 | |
15 #include "config.h" | |
16 #include "video_out.h" | |
17 #include "video_out_internal.h" | |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
7124
diff
changeset
|
18 #include "sub.h" |
6053 | 19 |
20 #include "../postproc/rgb2rgb.h" | |
21 | |
22 #include <gif_lib.h> | |
23 | |
24 #define GIFWHORE_version 0.90 | |
25 | |
26 LIBVO_EXTERN (gif89a) | |
27 | |
28 static vo_info_t vo_info = | |
29 { | |
30 "GIF89a (out.gif)", | |
31 "gif89a", | |
32 "GifWhore <joey@yunamusic.com>", | |
33 "" | |
34 }; | |
35 | |
36 extern int verbose; | |
37 extern int vo_config_count; | |
38 | |
39 static int image_width; | |
40 static int image_height; | |
41 static int image_format; | |
42 static uint8_t *image_data=NULL; | |
43 | |
44 static int reverse_map = 0; | |
45 static unsigned char framenum = 0; | |
46 static int gif_frameskip; | |
47 static int gif_framedelay; | |
48 static int target_fps = 0; | |
49 | |
50 GifFileType *newgif=NULL; | |
51 | |
52 static uint32_t config | |
53 (uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, | |
7124
eca7dbad0166
finally removed query_vaa, bes_da and vo_tune_info - the obsoleted libvo api
alex
parents:
6211
diff
changeset
|
54 uint32_t fullscreen, char *title, uint32_t format) { |
6053 | 55 char filename[] = "out.gif"; |
56 ColorMapObject *Cmap; | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
57 #ifdef HAVE_GIF_4 |
6053 | 58 char LB[] = { |
59 'N','E','T','S', | |
60 'C','A','P','E', | |
61 '2','.','0' }; | |
62 char LB2[] = { 1, 0x00, 0x00 }; | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
63 #endif |
6053 | 64 |
65 if (target_fps == 0) target_fps = 5; | |
66 gif_frameskip = (vo_fps + 0.25) / target_fps; | |
67 gif_framedelay = 100 / target_fps; | |
68 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
69 image_width = width; |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
70 image_height = height; |
6053 | 71 image_format = format; |
72 | |
73 Cmap = MakeMapObject(256, NULL); | |
74 | |
75 switch(format) { | |
76 case IMGFMT_BGR24: | |
77 reverse_map = 1; | |
78 break; | |
79 case IMGFMT_RGB24: | |
80 break; | |
81 case IMGFMT_YV12: | |
7487
e60109dfc85c
U-V swapping fixed, patch by Joey Parrish <joey@yunamusic.com>
arpi
parents:
7472
diff
changeset
|
82 yuv2rgb_init(24, MODE_BGR); |
6053 | 83 image_data = malloc(image_width*image_height*3); |
84 break; | |
85 default: | |
86 return 1; | |
87 } | |
88 | |
89 if (vo_config_count > 0) | |
90 return 0; | |
91 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
92 // this line causes crashes in certain earlier versions of libungif. |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
93 // i don't know exactly which, but certainly all those before v4. |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
94 // if you have problems, you need to upgrade your gif library. |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
95 #ifdef HAVE_GIF_4 |
6053 | 96 EGifSetGifVersion("89a"); |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
97 #else |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
98 fprintf(stderr, "vo_gif89a: Your version of libgif/libungif needs to be upgraded.\n"); |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
99 fprintf(stderr, "vo_gif89a: Some functionality has been disabled.\n"); |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
100 #endif |
6053 | 101 newgif = EGifOpenFileName(filename, 0); |
102 if (newgif == NULL) | |
103 { | |
104 fprintf(stderr, "error opening file for output.\n"); | |
105 return(1); | |
106 } | |
107 EGifPutScreenDesc(newgif, image_width, image_height, 256, 0, Cmap); | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
108 #ifdef HAVE_GIF_4 |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
109 // version 3 of libgif/libungif does not support multiple control blocks. |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
110 // for this version, looping will be disabled. |
6053 | 111 EGifPutExtensionFirst(newgif, 0xFF, 11, LB); |
112 EGifPutExtensionLast(newgif, 0, 3, LB2); | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
113 #endif |
6053 | 114 |
115 return 0; | |
116 } | |
117 | |
118 static const vo_info_t* get_info(void) | |
119 { | |
120 return &vo_info; | |
121 } | |
122 | |
123 static uint32_t draw_frame(uint8_t * src[]) | |
124 { | |
125 uint8_t *use_data; | |
126 ColorMapObject *Cmap; | |
127 uint8_t Colors[256 * 3]; | |
128 int z; | |
129 char CB[] = { (char)(gif_framedelay >> 8), (char)(gif_framedelay & 0xff), 0, 0}; | |
130 | |
131 if ((framenum++ % gif_frameskip)) return(0); | |
132 | |
133 Cmap = MakeMapObject(256, NULL); | |
134 use_data = (uint8_t *)malloc(image_width * image_height); | |
135 if (gif_reduce(image_width, image_height, src[0], use_data, Colors)) return(0); | |
136 | |
137 if (reverse_map) | |
138 { | |
139 for (z = 0; z < 256; z++) { | |
140 Cmap->Colors[z].Blue = Colors[(z * 3) + 0]; | |
141 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
142 Cmap->Colors[z].Red = Colors[(z * 3) + 2]; | |
143 } | |
144 } | |
145 else | |
146 { | |
147 for (z = 0; z < 256; z++) { | |
148 Cmap->Colors[z].Red = Colors[(z * 3) + 0]; | |
149 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
150 Cmap->Colors[z].Blue = Colors[(z * 3) + 2]; | |
151 } | |
152 } | |
153 | |
154 EGifPutExtension(newgif, 0xF9, 0x04, CB); | |
155 EGifPutImageDesc(newgif, 0, 0, image_width, image_height, 0, Cmap); | |
156 EGifPutLine(newgif, use_data, image_width * image_height); | |
157 FreeMapObject(Cmap); | |
158 free(use_data); | |
159 | |
160 return (0); | |
161 } | |
162 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
163 #ifdef USE_OSD |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
164 static void draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride) |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
165 { |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
166 vo_draw_alpha_rgb24(w, h, src, srca, stride, image_data + 3 * (y0 * image_width + x0), 3 * image_width); |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
167 } |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
168 #endif |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
169 |
6053 | 170 static void draw_osd(void) |
171 { | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
172 #ifdef USE_OSD |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
173 vo_draw_text(image_width, image_height, draw_alpha); |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
174 #endif |
6053 | 175 } |
176 | |
177 static void flip_page (void) | |
178 { | |
179 uint8_t *use_data; | |
180 ColorMapObject *Cmap; | |
181 uint8_t Colors[256 * 3]; | |
182 int z; | |
183 char CB[] = { (char)(gif_framedelay >> 8), (char)(gif_framedelay & 0xff), 0, 0}; | |
184 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
185 if (image_format == IMGFMT_YV12) { |
6053 | 186 |
187 if ((framenum++ % gif_frameskip)) return; | |
188 | |
189 Cmap = MakeMapObject(256, NULL); | |
190 use_data = (uint8_t *)malloc(image_width * image_height); | |
191 if (gif_reduce(image_width, image_height, image_data, use_data, Colors)) return; | |
192 | |
193 if (reverse_map) | |
194 { | |
195 for (z = 0; z < 256; z++) { | |
196 Cmap->Colors[z].Blue = Colors[(z * 3) + 0]; | |
197 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
198 Cmap->Colors[z].Red = Colors[(z * 3) + 2]; | |
199 } | |
200 } | |
201 else | |
202 { | |
203 for (z = 0; z < 256; z++) { | |
204 Cmap->Colors[z].Red = Colors[(z * 3) + 0]; | |
205 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
206 Cmap->Colors[z].Blue = Colors[(z * 3) + 2]; | |
207 } | |
208 } | |
209 | |
210 EGifPutExtension(newgif, 0xF9, 0x04, CB); | |
211 EGifPutImageDesc(newgif, 0, 0, image_width, image_height, 0, Cmap); | |
212 EGifPutLine(newgif, use_data, image_width * image_height); | |
213 FreeMapObject(Cmap); | |
214 free(use_data); | |
215 } | |
216 } | |
217 | |
218 static uint32_t draw_slice( uint8_t *src[],int stride[],int w,int h,int x,int y ) | |
219 { | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
220 uint8_t *dst = image_data + (image_width * y + x) * 3; |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
221 yuv2rgb(dst,src[0],src[1],src[2],w,h,image_width*3,stride[0],stride[1]); |
6053 | 222 return 0; |
223 } | |
224 | |
225 static uint32_t | |
226 query_format(uint32_t format) | |
227 { | |
228 switch(format){ | |
229 case IMGFMT_YV12: | |
6211 | 230 return VFCAP_CSP_SUPPORTED | VFCAP_TIMER | VFCAP_ACCEPT_STRIDE; |
6053 | 231 case IMGFMT_RGB|24: |
232 case IMGFMT_BGR|24: | |
6211 | 233 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_TIMER; |
6053 | 234 } |
235 return 0; | |
236 } | |
237 | |
238 static void | |
239 uninit(void) | |
240 { | |
241 char temp[256]; | |
242 | |
243 if (image_data) { free(image_data); image_data=NULL; } | |
244 | |
245 if (vo_config_count > 0) { | |
246 sprintf(temp, "gifwhore v%2.2f (c) %s\r\n", | |
247 GIFWHORE_version, "joey@yunamusic.com"); | |
248 EGifPutComment(newgif, temp); | |
249 EGifCloseFile(newgif); | |
250 } | |
251 } | |
252 | |
253 | |
254 static void check_events(void) | |
255 { | |
256 } | |
257 | |
258 int gif_reduce(int width, int height, | |
259 unsigned char *source, | |
260 unsigned char *destination, | |
261 unsigned char *palette) | |
262 { | |
263 GifColorType cmap[256]; | |
264 unsigned char Ra[width * height]; | |
265 unsigned char Ga[width * height]; | |
266 unsigned char Ba[width * height]; | |
267 unsigned char *R, *G, *B; | |
268 int Size = 256; | |
269 int i; | |
270 | |
271 R = Ra; G = Ga; B = Ba; | |
272 for (i = 0; i < width * height; i++) | |
273 { | |
274 *R++ = *source++; | |
275 *G++ = *source++; | |
276 *B++ = *source++; | |
277 } | |
278 | |
279 R = Ra; G = Ga; B = Ba; | |
280 if (QuantizeBuffer(width, height, &Size, | |
281 R, G, B, | |
282 destination, cmap) == GIF_ERROR) | |
283 { | |
284 fprintf(stderr, "vo_gif89a: Quantize failed!\n"); | |
285 return(-1); | |
286 } | |
287 | |
288 for (i = 0; i < Size; i++) | |
289 { | |
290 *palette++ = cmap[i].Red; | |
291 *palette++ = cmap[i].Green; | |
292 *palette++ = cmap[i].Blue; | |
293 } | |
294 | |
295 return(0); | |
296 } | |
297 | |
298 static uint32_t preinit(const char *arg) | |
299 { | |
300 int i = 0; | |
301 if (arg) i = atoi(arg); | |
302 if (i > vo_fps) i = vo_fps; | |
303 if (i < 1) i = 5; | |
304 target_fps = i; | |
305 return 0; | |
306 } | |
307 | |
308 static uint32_t control(uint32_t request, void *data, ...) | |
309 { | |
310 switch (request) { | |
311 case VOCTRL_QUERY_FORMAT: | |
312 return query_format(*((uint32_t*)data)); | |
313 } | |
314 return VO_NOTIMPL; | |
315 } | |
316 |