Mercurial > mplayer.hg
annotate libvo/vo_gif89a.c @ 8151:76b693c15c47
updating
author | pontscho |
---|---|
date | Mon, 11 Nov 2002 17:13:37 +0000 |
parents | 5b39e79af5fe |
children | a1ff87c254ff |
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 | |
8148
5b39e79af5fe
removed get_info, using the same sheme as in libmpcodecs instead
alex
parents:
8123
diff
changeset
|
26 static vo_info_t info = |
6053 | 27 { |
28 "GIF89a (out.gif)", | |
29 "gif89a", | |
30 "GifWhore <joey@yunamusic.com>", | |
31 "" | |
32 }; | |
33 | |
8148
5b39e79af5fe
removed get_info, using the same sheme as in libmpcodecs instead
alex
parents:
8123
diff
changeset
|
34 LIBVO_EXTERN (gif89a) |
5b39e79af5fe
removed get_info, using the same sheme as in libmpcodecs instead
alex
parents:
8123
diff
changeset
|
35 |
6053 | 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 | |
8123
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7487
diff
changeset
|
118 /* forward declaration */ |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7487
diff
changeset
|
119 int gif_reduce(int width, int height, unsigned char *source, unsigned char *destination, unsigned char *palette); |
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
7487
diff
changeset
|
120 |
6053 | 121 static uint32_t draw_frame(uint8_t * src[]) |
122 { | |
123 uint8_t *use_data; | |
124 ColorMapObject *Cmap; | |
125 uint8_t Colors[256 * 3]; | |
126 int z; | |
127 char CB[] = { (char)(gif_framedelay >> 8), (char)(gif_framedelay & 0xff), 0, 0}; | |
128 | |
129 if ((framenum++ % gif_frameskip)) return(0); | |
130 | |
131 Cmap = MakeMapObject(256, NULL); | |
132 use_data = (uint8_t *)malloc(image_width * image_height); | |
133 if (gif_reduce(image_width, image_height, src[0], use_data, Colors)) return(0); | |
134 | |
135 if (reverse_map) | |
136 { | |
137 for (z = 0; z < 256; z++) { | |
138 Cmap->Colors[z].Blue = Colors[(z * 3) + 0]; | |
139 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
140 Cmap->Colors[z].Red = Colors[(z * 3) + 2]; | |
141 } | |
142 } | |
143 else | |
144 { | |
145 for (z = 0; z < 256; z++) { | |
146 Cmap->Colors[z].Red = Colors[(z * 3) + 0]; | |
147 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
148 Cmap->Colors[z].Blue = Colors[(z * 3) + 2]; | |
149 } | |
150 } | |
151 | |
152 EGifPutExtension(newgif, 0xF9, 0x04, CB); | |
153 EGifPutImageDesc(newgif, 0, 0, image_width, image_height, 0, Cmap); | |
154 EGifPutLine(newgif, use_data, image_width * image_height); | |
155 FreeMapObject(Cmap); | |
156 free(use_data); | |
157 | |
158 return (0); | |
159 } | |
160 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
161 #ifdef USE_OSD |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
162 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
|
163 { |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
164 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
|
165 } |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
166 #endif |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
167 |
6053 | 168 static void draw_osd(void) |
169 { | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
170 #ifdef USE_OSD |
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
171 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
|
172 #endif |
6053 | 173 } |
174 | |
175 static void flip_page (void) | |
176 { | |
177 uint8_t *use_data; | |
178 ColorMapObject *Cmap; | |
179 uint8_t Colors[256 * 3]; | |
180 int z; | |
181 char CB[] = { (char)(gif_framedelay >> 8), (char)(gif_framedelay & 0xff), 0, 0}; | |
182 | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
183 if (image_format == IMGFMT_YV12) { |
6053 | 184 |
185 if ((framenum++ % gif_frameskip)) return; | |
186 | |
187 Cmap = MakeMapObject(256, NULL); | |
188 use_data = (uint8_t *)malloc(image_width * image_height); | |
189 if (gif_reduce(image_width, image_height, image_data, use_data, Colors)) return; | |
190 | |
191 if (reverse_map) | |
192 { | |
193 for (z = 0; z < 256; z++) { | |
194 Cmap->Colors[z].Blue = Colors[(z * 3) + 0]; | |
195 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
196 Cmap->Colors[z].Red = Colors[(z * 3) + 2]; | |
197 } | |
198 } | |
199 else | |
200 { | |
201 for (z = 0; z < 256; z++) { | |
202 Cmap->Colors[z].Red = Colors[(z * 3) + 0]; | |
203 Cmap->Colors[z].Green = Colors[(z * 3) + 1]; | |
204 Cmap->Colors[z].Blue = Colors[(z * 3) + 2]; | |
205 } | |
206 } | |
207 | |
208 EGifPutExtension(newgif, 0xF9, 0x04, CB); | |
209 EGifPutImageDesc(newgif, 0, 0, image_width, image_height, 0, Cmap); | |
210 EGifPutLine(newgif, use_data, image_width * image_height); | |
211 FreeMapObject(Cmap); | |
212 free(use_data); | |
213 } | |
214 } | |
215 | |
216 static uint32_t draw_slice( uint8_t *src[],int stride[],int w,int h,int x,int y ) | |
217 { | |
6078
4a9c7041141d
cleanups, removed swscaler, osd support - by Joey Parrish <joey@yunamusic.com>
arpi
parents:
6053
diff
changeset
|
218 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
|
219 yuv2rgb(dst,src[0],src[1],src[2],w,h,image_width*3,stride[0],stride[1]); |
6053 | 220 return 0; |
221 } | |
222 | |
223 static uint32_t | |
224 query_format(uint32_t format) | |
225 { | |
226 switch(format){ | |
227 case IMGFMT_YV12: | |
6211 | 228 return VFCAP_CSP_SUPPORTED | VFCAP_TIMER | VFCAP_ACCEPT_STRIDE; |
6053 | 229 case IMGFMT_RGB|24: |
230 case IMGFMT_BGR|24: | |
6211 | 231 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_TIMER; |
6053 | 232 } |
233 return 0; | |
234 } | |
235 | |
236 static void | |
237 uninit(void) | |
238 { | |
239 char temp[256]; | |
240 | |
241 if (image_data) { free(image_data); image_data=NULL; } | |
242 | |
243 if (vo_config_count > 0) { | |
244 sprintf(temp, "gifwhore v%2.2f (c) %s\r\n", | |
245 GIFWHORE_version, "joey@yunamusic.com"); | |
246 EGifPutComment(newgif, temp); | |
247 EGifCloseFile(newgif); | |
248 } | |
249 } | |
250 | |
251 | |
252 static void check_events(void) | |
253 { | |
254 } | |
255 | |
256 int gif_reduce(int width, int height, | |
257 unsigned char *source, | |
258 unsigned char *destination, | |
259 unsigned char *palette) | |
260 { | |
261 GifColorType cmap[256]; | |
262 unsigned char Ra[width * height]; | |
263 unsigned char Ga[width * height]; | |
264 unsigned char Ba[width * height]; | |
265 unsigned char *R, *G, *B; | |
266 int Size = 256; | |
267 int i; | |
268 | |
269 R = Ra; G = Ga; B = Ba; | |
270 for (i = 0; i < width * height; i++) | |
271 { | |
272 *R++ = *source++; | |
273 *G++ = *source++; | |
274 *B++ = *source++; | |
275 } | |
276 | |
277 R = Ra; G = Ga; B = Ba; | |
278 if (QuantizeBuffer(width, height, &Size, | |
279 R, G, B, | |
280 destination, cmap) == GIF_ERROR) | |
281 { | |
282 fprintf(stderr, "vo_gif89a: Quantize failed!\n"); | |
283 return(-1); | |
284 } | |
285 | |
286 for (i = 0; i < Size; i++) | |
287 { | |
288 *palette++ = cmap[i].Red; | |
289 *palette++ = cmap[i].Green; | |
290 *palette++ = cmap[i].Blue; | |
291 } | |
292 | |
293 return(0); | |
294 } | |
295 | |
296 static uint32_t preinit(const char *arg) | |
297 { | |
298 int i = 0; | |
299 if (arg) i = atoi(arg); | |
300 if (i > vo_fps) i = vo_fps; | |
301 if (i < 1) i = 5; | |
302 target_fps = i; | |
303 return 0; | |
304 } | |
305 | |
306 static uint32_t control(uint32_t request, void *data, ...) | |
307 { | |
308 switch (request) { | |
309 case VOCTRL_QUERY_FORMAT: | |
310 return query_format(*((uint32_t*)data)); | |
311 } | |
312 return VO_NOTIMPL; | |
313 } | |
314 |