Mercurial > sdl-ios-xcode
comparison test/testoverlay.c @ 1895:c121d94672cb
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 10 Jul 2006 21:04:37 +0000 |
parents | 4d3bb026cd16 |
children | c785543d1843 |
comparison
equal
deleted
inserted
replaced
1894:c69cee13dd76 | 1895:c121d94672cb |
---|---|
20 int monochrome; | 20 int monochrome; |
21 int luminance; | 21 int luminance; |
22 int w, h; | 22 int w, h; |
23 | 23 |
24 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ | 24 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ |
25 static void quit(int rc) | 25 static void |
26 { | 26 quit(int rc) |
27 SDL_Quit(); | 27 { |
28 exit(rc); | 28 SDL_Quit(); |
29 exit(rc); | |
29 } | 30 } |
30 | 31 |
31 /* NOTE: These RGB conversion functions are not intended for speed, | 32 /* NOTE: These RGB conversion functions are not intended for speed, |
32 only as examples. | 33 only as examples. |
33 */ | 34 */ |
34 | 35 |
35 void RGBtoYUV(Uint8 *rgb, int *yuv, int monochrome, int luminance) | 36 void |
36 { | 37 RGBtoYUV(Uint8 * rgb, int *yuv, int monochrome, int luminance) |
37 if (monochrome) | 38 { |
38 { | 39 if (monochrome) { |
39 #if 1 /* these are the two formulas that I found on the FourCC site... */ | 40 #if 1 /* these are the two formulas that I found on the FourCC site... */ |
40 yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2]; | 41 yuv[0] = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]; |
41 yuv[1] = 128; | 42 yuv[1] = 128; |
42 yuv[2] = 128; | 43 yuv[2] = 128; |
43 #else | 44 #else |
44 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16; | 45 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16; |
45 yuv[1] = 128; | 46 yuv[1] = 128; |
46 yuv[2] = 128; | 47 yuv[2] = 128; |
47 #endif | 48 #endif |
48 } | 49 } else { |
49 else | 50 #if 1 /* these are the two formulas that I found on the FourCC site... */ |
50 { | 51 yuv[0] = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]; |
51 #if 1 /* these are the two formulas that I found on the FourCC site... */ | 52 yuv[1] = (rgb[2] - yuv[0]) * 0.565 + 128; |
52 yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2]; | 53 yuv[2] = (rgb[0] - yuv[0]) * 0.713 + 128; |
53 yuv[1] = (rgb[2]-yuv[0])*0.565 + 128; | |
54 yuv[2] = (rgb[0]-yuv[0])*0.713 + 128; | |
55 #else | 54 #else |
56 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16; | 55 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16; |
57 yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]); | 56 yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]); |
58 yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]); | 57 yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]); |
59 #endif | 58 #endif |
60 } | 59 } |
61 | 60 |
62 if (luminance!=100) | 61 if (luminance != 100) { |
63 { | 62 yuv[0] = yuv[0] * luminance / 100; |
64 yuv[0]=yuv[0]*luminance/100; | 63 if (yuv[0] > 255) |
65 if (yuv[0]>255) | 64 yuv[0] = 255; |
66 yuv[0]=255; | |
67 } | 65 } |
68 | 66 |
69 /* clamp values...if you need to, we don't seem to have a need */ | 67 /* clamp values...if you need to, we don't seem to have a need */ |
70 /* | 68 /* |
71 for(i=0;i<3;i++) | 69 for(i=0;i<3;i++) |
70 { | |
71 if(yuv[i]<0) | |
72 yuv[i]=0; | |
73 if(yuv[i]>255) | |
74 yuv[i]=255; | |
75 } | |
76 */ | |
77 } | |
78 | |
79 void | |
80 ConvertRGBtoYV12(SDL_Surface * s, SDL_Overlay * o, int monochrome, | |
81 int luminance) | |
82 { | |
83 int x, y; | |
84 int yuv[3]; | |
85 Uint8 *p, *op[3]; | |
86 | |
87 SDL_LockSurface(s); | |
88 SDL_LockYUVOverlay(o); | |
89 | |
90 /* Black initialization */ | |
91 /* | |
92 memset(o->pixels[0],0,o->pitches[0]*o->h); | |
93 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); | |
94 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); | |
95 */ | |
96 | |
97 /* Convert */ | |
98 for (y = 0; y < s->h && y < o->h; y++) { | |
99 p = ((Uint8 *) s->pixels) + s->pitch * y; | |
100 op[0] = o->pixels[0] + o->pitches[0] * y; | |
101 op[1] = o->pixels[1] + o->pitches[1] * (y / 2); | |
102 op[2] = o->pixels[2] + o->pitches[2] * (y / 2); | |
103 for (x = 0; x < s->w && x < o->w; x++) { | |
104 RGBtoYUV(p, yuv, monochrome, luminance); | |
105 *(op[0]++) = yuv[0]; | |
106 if (x % 2 == 0 && y % 2 == 0) { | |
107 *(op[1]++) = yuv[2]; | |
108 *(op[2]++) = yuv[1]; | |
109 } | |
110 p += s->format->BytesPerPixel; | |
111 } | |
112 } | |
113 | |
114 SDL_UnlockYUVOverlay(o); | |
115 SDL_UnlockSurface(s); | |
116 } | |
117 | |
118 void | |
119 ConvertRGBtoIYUV(SDL_Surface * s, SDL_Overlay * o, int monochrome, | |
120 int luminance) | |
121 { | |
122 int x, y; | |
123 int yuv[3]; | |
124 Uint8 *p, *op[3]; | |
125 | |
126 SDL_LockSurface(s); | |
127 SDL_LockYUVOverlay(o); | |
128 | |
129 /* Black initialization */ | |
130 /* | |
131 memset(o->pixels[0],0,o->pitches[0]*o->h); | |
132 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); | |
133 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); | |
134 */ | |
135 | |
136 /* Convert */ | |
137 for (y = 0; y < s->h && y < o->h; y++) { | |
138 p = ((Uint8 *) s->pixels) + s->pitch * y; | |
139 op[0] = o->pixels[0] + o->pitches[0] * y; | |
140 op[1] = o->pixels[1] + o->pitches[1] * (y / 2); | |
141 op[2] = o->pixels[2] + o->pitches[2] * (y / 2); | |
142 for (x = 0; x < s->w && x < o->w; x++) { | |
143 RGBtoYUV(p, yuv, monochrome, luminance); | |
144 *(op[0]++) = yuv[0]; | |
145 if (x % 2 == 0 && y % 2 == 0) { | |
146 *(op[1]++) = yuv[1]; | |
147 *(op[2]++) = yuv[2]; | |
148 } | |
149 p += s->format->BytesPerPixel; | |
150 } | |
151 } | |
152 | |
153 SDL_UnlockYUVOverlay(o); | |
154 SDL_UnlockSurface(s); | |
155 } | |
156 | |
157 void | |
158 ConvertRGBtoUYVY(SDL_Surface * s, SDL_Overlay * o, int monochrome, | |
159 int luminance) | |
160 { | |
161 int x, y; | |
162 int yuv[3]; | |
163 Uint8 *p, *op; | |
164 | |
165 SDL_LockSurface(s); | |
166 SDL_LockYUVOverlay(o); | |
167 | |
168 for (y = 0; y < s->h && y < o->h; y++) { | |
169 p = ((Uint8 *) s->pixels) + s->pitch * y; | |
170 op = o->pixels[0] + o->pitches[0] * y; | |
171 for (x = 0; x < s->w && x < o->w; x++) { | |
172 RGBtoYUV(p, yuv, monochrome, luminance); | |
173 if (x % 2 == 0) { | |
174 *(op++) = yuv[1]; | |
175 *(op++) = yuv[0]; | |
176 *(op++) = yuv[2]; | |
177 } else | |
178 *(op++) = yuv[0]; | |
179 | |
180 p += s->format->BytesPerPixel; | |
181 } | |
182 } | |
183 | |
184 SDL_UnlockYUVOverlay(o); | |
185 SDL_UnlockSurface(s); | |
186 } | |
187 | |
188 void | |
189 ConvertRGBtoYVYU(SDL_Surface * s, SDL_Overlay * o, int monochrome, | |
190 int luminance) | |
191 { | |
192 int x, y; | |
193 int yuv[3]; | |
194 Uint8 *p, *op; | |
195 | |
196 SDL_LockSurface(s); | |
197 SDL_LockYUVOverlay(o); | |
198 | |
199 for (y = 0; y < s->h && y < o->h; y++) { | |
200 p = ((Uint8 *) s->pixels) + s->pitch * y; | |
201 op = o->pixels[0] + o->pitches[0] * y; | |
202 for (x = 0; x < s->w && x < o->w; x++) { | |
203 RGBtoYUV(p, yuv, monochrome, luminance); | |
204 if (x % 2 == 0) { | |
205 *(op++) = yuv[0]; | |
206 *(op++) = yuv[2]; | |
207 op[1] = yuv[1]; | |
208 } else { | |
209 *op = yuv[0]; | |
210 op += 2; | |
211 } | |
212 | |
213 p += s->format->BytesPerPixel; | |
214 } | |
215 } | |
216 | |
217 SDL_UnlockYUVOverlay(o); | |
218 SDL_UnlockSurface(s); | |
219 } | |
220 | |
221 void | |
222 ConvertRGBtoYUY2(SDL_Surface * s, SDL_Overlay * o, int monochrome, | |
223 int luminance) | |
224 { | |
225 int x, y; | |
226 int yuv[3]; | |
227 Uint8 *p, *op; | |
228 | |
229 SDL_LockSurface(s); | |
230 SDL_LockYUVOverlay(o); | |
231 | |
232 for (y = 0; y < s->h && y < o->h; y++) { | |
233 p = ((Uint8 *) s->pixels) + s->pitch * y; | |
234 op = o->pixels[0] + o->pitches[0] * y; | |
235 for (x = 0; x < s->w && x < o->w; x++) { | |
236 RGBtoYUV(p, yuv, monochrome, luminance); | |
237 if (x % 2 == 0) { | |
238 *(op++) = yuv[0]; | |
239 *(op++) = yuv[1]; | |
240 op[1] = yuv[2]; | |
241 } else { | |
242 *op = yuv[0]; | |
243 op += 2; | |
244 } | |
245 | |
246 p += s->format->BytesPerPixel; | |
247 } | |
248 } | |
249 | |
250 SDL_UnlockYUVOverlay(o); | |
251 SDL_UnlockSurface(s); | |
252 } | |
253 | |
254 void | |
255 Draw() | |
256 { | |
257 SDL_Rect rect; | |
258 int i; | |
259 int disp; | |
260 | |
261 if (!scale) { | |
262 rect.w = overlay->w; | |
263 rect.h = overlay->h; | |
264 for (i = 0; i < h - rect.h && i < w - rect.w; i++) { | |
265 rect.x = i; | |
266 rect.y = i; | |
267 SDL_DisplayYUVOverlay(overlay, &rect); | |
268 } | |
269 } else { | |
270 rect.w = overlay->w / 2; | |
271 rect.h = overlay->h / 2; | |
272 rect.x = (w - rect.w) / 2; | |
273 rect.y = (h - rect.h) / 2; | |
274 disp = rect.y - 1; | |
275 for (i = 0; i < disp; i++) { | |
276 rect.w += 2; | |
277 rect.h += 2; | |
278 rect.x--; | |
279 rect.y--; | |
280 SDL_DisplayYUVOverlay(overlay, &rect); | |
281 } | |
282 } | |
283 printf("Displayed %d times.\n", i); | |
284 } | |
285 | |
286 static void | |
287 PrintUsage(char *argv0) | |
288 { | |
289 fprintf(stderr, "Usage: %s [arg] [arg] [arg] ...\n", argv0); | |
290 fprintf(stderr, "Where 'arg' is one of:\n"); | |
291 fprintf(stderr, " -delay <seconds>\n"); | |
292 fprintf(stderr, " -width <pixels>\n"); | |
293 fprintf(stderr, " -height <pixels>\n"); | |
294 fprintf(stderr, " -bpp <bits>\n"); | |
295 fprintf(stderr, | |
296 " -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n"); | |
297 fprintf(stderr, " -hw\n"); | |
298 fprintf(stderr, " -flip\n"); | |
299 fprintf(stderr, | |
300 " -scale (test scaling features, from 50%% upto window size)\n"); | |
301 fprintf(stderr, " -mono (use monochromatic RGB2YUV conversion)\n"); | |
302 fprintf(stderr, | |
303 " -lum <perc> (use luminance correction during RGB2YUV conversion,\n"); | |
304 fprintf(stderr, | |
305 " from 0%% to unlimited, normal is 100%%)\n"); | |
306 fprintf(stderr, " -help (shows this help)\n"); | |
307 fprintf(stderr, " -fullscreen (test overlay in fullscreen mode)\n"); | |
308 } | |
309 | |
310 int | |
311 main(int argc, char **argv) | |
312 { | |
313 char *argv0 = argv[0]; | |
314 int flip; | |
315 int delay; | |
316 int desired_bpp; | |
317 Uint32 video_flags, overlay_format; | |
318 char *bmpfile; | |
319 #ifdef BENCHMARK_SDL | |
320 Uint32 then, now; | |
321 #endif | |
322 int i; | |
323 | |
324 /* Set default options and check command-line */ | |
325 flip = 0; | |
326 scale = 0; | |
327 monochrome = 0; | |
328 luminance = 100; | |
329 delay = 1; | |
330 w = WINDOW_WIDTH; | |
331 h = WINDOW_HEIGHT; | |
332 desired_bpp = 0; | |
333 video_flags = 0; | |
334 overlay_format = SDL_YV12_OVERLAY; | |
335 | |
336 while (argc > 1) { | |
337 if (strcmp(argv[1], "-delay") == 0) { | |
338 if (argv[2]) { | |
339 delay = atoi(argv[2]); | |
340 argv += 2; | |
341 argc -= 2; | |
342 } else { | |
343 fprintf(stderr, "The -delay option requires an argument\n"); | |
344 return (1); | |
345 } | |
346 } else if (strcmp(argv[1], "-width") == 0) { | |
347 if (argv[2] && ((w = atoi(argv[2])) > 0)) { | |
348 argv += 2; | |
349 argc -= 2; | |
350 } else { | |
351 fprintf(stderr, "The -width option requires an argument\n"); | |
352 return (1); | |
353 } | |
354 } else if (strcmp(argv[1], "-height") == 0) { | |
355 if (argv[2] && ((h = atoi(argv[2])) > 0)) { | |
356 argv += 2; | |
357 argc -= 2; | |
358 } else { | |
359 fprintf(stderr, "The -height option requires an argument\n"); | |
360 return (1); | |
361 } | |
362 } else if (strcmp(argv[1], "-bpp") == 0) { | |
363 if (argv[2]) { | |
364 desired_bpp = atoi(argv[2]); | |
365 argv += 2; | |
366 argc -= 2; | |
367 } else { | |
368 fprintf(stderr, "The -bpp option requires an argument\n"); | |
369 return (1); | |
370 } | |
371 } else if (strcmp(argv[1], "-lum") == 0) { | |
372 if (argv[2]) { | |
373 luminance = atoi(argv[2]); | |
374 argv += 2; | |
375 argc -= 2; | |
376 } else { | |
377 fprintf(stderr, "The -lum option requires an argument\n"); | |
378 return (1); | |
379 } | |
380 } else if (strcmp(argv[1], "-format") == 0) { | |
381 if (argv[2]) { | |
382 if (!strcmp(argv[2], "YV12")) | |
383 overlay_format = SDL_YV12_OVERLAY; | |
384 else if (!strcmp(argv[2], "IYUV")) | |
385 overlay_format = SDL_IYUV_OVERLAY; | |
386 else if (!strcmp(argv[2], "YUY2")) | |
387 overlay_format = SDL_YUY2_OVERLAY; | |
388 else if (!strcmp(argv[2], "UYVY")) | |
389 overlay_format = SDL_UYVY_OVERLAY; | |
390 else if (!strcmp(argv[2], "YVYU")) | |
391 overlay_format = SDL_YVYU_OVERLAY; | |
392 else { | |
393 fprintf(stderr, | |
394 "The -format option %s is not recognized\n", | |
395 argv[2]); | |
396 return (1); | |
397 } | |
398 argv += 2; | |
399 argc -= 2; | |
400 } else { | |
401 fprintf(stderr, "The -format option requires an argument\n"); | |
402 return (1); | |
403 } | |
404 } else if (strcmp(argv[1], "-hw") == 0) { | |
405 video_flags |= SDL_HWSURFACE; | |
406 argv += 1; | |
407 argc -= 1; | |
408 } else if (strcmp(argv[1], "-flip") == 0) { | |
409 video_flags |= SDL_DOUBLEBUF; | |
410 argv += 1; | |
411 argc -= 1; | |
412 } else if (strcmp(argv[1], "-scale") == 0) { | |
413 scale = 1; | |
414 argv += 1; | |
415 argc -= 1; | |
416 } else if (strcmp(argv[1], "-mono") == 0) { | |
417 monochrome = 1; | |
418 argv += 1; | |
419 argc -= 1; | |
420 } else if ((strcmp(argv[1], "-help") == 0) | |
421 || (strcmp(argv[1], "-h") == 0)) { | |
422 PrintUsage(argv0); | |
423 return (1); | |
424 } else if (strcmp(argv[1], "-fullscreen") == 0) { | |
425 video_flags |= SDL_FULLSCREEN; | |
426 argv += 1; | |
427 argc -= 1; | |
428 } else | |
429 break; | |
430 } | |
431 if (SDL_Init(SDL_INIT_VIDEO) < 0) { | |
432 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); | |
433 return (1); | |
434 } | |
435 | |
436 /* Initialize the display */ | |
437 screen = SDL_SetVideoMode(w, h, desired_bpp, video_flags); | |
438 if (screen == NULL) { | |
439 fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n", | |
440 w, h, desired_bpp, SDL_GetError()); | |
441 quit(1); | |
442 } | |
443 printf("Set%s %dx%dx%d mode\n", | |
444 screen->flags & SDL_FULLSCREEN ? " fullscreen" : "", | |
445 screen->w, screen->h, screen->format->BitsPerPixel); | |
446 printf("(video surface located in %s memory)\n", | |
447 (screen->flags & SDL_HWSURFACE) ? "video" : "system"); | |
448 if (screen->flags & SDL_DOUBLEBUF) { | |
449 printf("Double-buffering enabled\n"); | |
450 flip = 1; | |
451 } | |
452 | |
453 /* Set the window manager title bar */ | |
454 SDL_WM_SetCaption("SDL test overlay", "testoverlay"); | |
455 | |
456 /* Load picture */ | |
457 bmpfile = (argv[1] ? argv[1] : "sample.bmp"); | |
458 pic = SDL_LoadBMP(bmpfile); | |
459 if (pic == NULL) { | |
460 fprintf(stderr, "Couldn't load %s: %s\n", bmpfile, SDL_GetError()); | |
461 quit(1); | |
462 } | |
463 | |
464 /* Convert the picture to 32bits, for easy conversion */ | |
72 { | 465 { |
73 if(yuv[i]<0) | 466 SDL_Surface *newsurf; |
74 yuv[i]=0; | 467 SDL_PixelFormat format; |
75 if(yuv[i]>255) | 468 |
76 yuv[i]=255; | 469 format.palette = NULL; |
77 } | 470 format.BitsPerPixel = 32; |
78 */ | 471 format.BytesPerPixel = 4; |
79 } | 472 #if SDL_BYTEORDER == SDL_LIL_ENDIAN |
80 | 473 format.Rshift = 0; |
81 void ConvertRGBtoYV12(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance) | 474 format.Gshift = 8; |
82 { | 475 format.Bshift = 16; |
83 int x,y; | 476 #else |
84 int yuv[3]; | 477 format.Rshift = 24; |
85 Uint8 *p,*op[3]; | 478 format.Gshift = 16; |
86 | 479 format.Bshift = 8; |
87 SDL_LockSurface(s); | 480 #endif |
88 SDL_LockYUVOverlay(o); | 481 format.Ashift = 0; |
89 | 482 format.Rmask = 0xff << format.Rshift; |
90 /* Black initialization */ | 483 format.Gmask = 0xff << format.Gshift; |
91 /* | 484 format.Bmask = 0xff << format.Bshift; |
92 memset(o->pixels[0],0,o->pitches[0]*o->h); | 485 format.Amask = 0; |
93 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); | 486 format.Rloss = 0; |
94 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); | 487 format.Gloss = 0; |
95 */ | 488 format.Bloss = 0; |
96 | 489 format.Aloss = 8; |
97 /* Convert */ | 490 format.colorkey = 0; |
98 for(y=0; y<s->h && y<o->h; y++) | 491 format.alpha = 0; |
99 { | 492 |
100 p=((Uint8 *) s->pixels)+s->pitch*y; | 493 newsurf = SDL_ConvertSurface(pic, &format, SDL_SWSURFACE); |
101 op[0]=o->pixels[0]+o->pitches[0]*y; | 494 if (!newsurf) { |
102 op[1]=o->pixels[1]+o->pitches[1]*(y/2); | 495 fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n", |
103 op[2]=o->pixels[2]+o->pitches[2]*(y/2); | 496 SDL_GetError()); |
104 for(x=0; x<s->w && x<o->w; x++) | 497 quit(1); |
105 { | 498 } |
106 RGBtoYUV(p, yuv, monochrome, luminance); | 499 SDL_FreeSurface(pic); |
107 *(op[0]++)=yuv[0]; | 500 pic = newsurf; |
108 if(x%2==0 && y%2==0) | 501 } |
109 { | 502 |
110 *(op[1]++)=yuv[2]; | 503 /* Create the overlay */ |
111 *(op[2]++)=yuv[1]; | 504 overlay = SDL_CreateYUVOverlay(pic->w, pic->h, overlay_format, screen); |
112 } | 505 if (overlay == NULL) { |
113 p+=s->format->BytesPerPixel; | 506 fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError()); |
114 } | 507 quit(1); |
115 } | 508 } |
116 | 509 printf("Created %dx%dx%d %s %s overlay\n", overlay->w, overlay->h, |
117 SDL_UnlockYUVOverlay(o); | 510 overlay->planes, overlay->hw_overlay ? "hardware" : "software", |
118 SDL_UnlockSurface(s); | 511 overlay->format == SDL_YV12_OVERLAY ? "YV12" : overlay->format == |
119 } | 512 SDL_IYUV_OVERLAY ? "IYUV" : overlay->format == |
120 | 513 SDL_YUY2_OVERLAY ? "YUY2" : overlay->format == |
121 void ConvertRGBtoIYUV(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance) | 514 SDL_UYVY_OVERLAY ? "UYVY" : overlay->format == |
122 { | 515 SDL_YVYU_OVERLAY ? "YVYU" : "Unknown"); |
123 int x,y; | 516 for (i = 0; i < overlay->planes; i++) { |
124 int yuv[3]; | 517 printf(" plane %d: pitch=%d\n", i, overlay->pitches[i]); |
125 Uint8 *p,*op[3]; | 518 } |
126 | 519 |
127 SDL_LockSurface(s); | 520 /* Convert to YUV, and draw to the overlay */ |
128 SDL_LockYUVOverlay(o); | |
129 | |
130 /* Black initialization */ | |
131 /* | |
132 memset(o->pixels[0],0,o->pitches[0]*o->h); | |
133 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); | |
134 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); | |
135 */ | |
136 | |
137 /* Convert */ | |
138 for(y=0; y<s->h && y<o->h; y++) | |
139 { | |
140 p=((Uint8 *) s->pixels)+s->pitch*y; | |
141 op[0]=o->pixels[0]+o->pitches[0]*y; | |
142 op[1]=o->pixels[1]+o->pitches[1]*(y/2); | |
143 op[2]=o->pixels[2]+o->pitches[2]*(y/2); | |
144 for(x=0; x<s->w && x<o->w; x++) | |
145 { | |
146 RGBtoYUV(p,yuv, monochrome, luminance); | |
147 *(op[0]++)=yuv[0]; | |
148 if(x%2==0 && y%2==0) | |
149 { | |
150 *(op[1]++)=yuv[1]; | |
151 *(op[2]++)=yuv[2]; | |
152 } | |
153 p+=s->format->BytesPerPixel; | |
154 } | |
155 } | |
156 | |
157 SDL_UnlockYUVOverlay(o); | |
158 SDL_UnlockSurface(s); | |
159 } | |
160 | |
161 void ConvertRGBtoUYVY(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance) | |
162 { | |
163 int x,y; | |
164 int yuv[3]; | |
165 Uint8 *p,*op; | |
166 | |
167 SDL_LockSurface(s); | |
168 SDL_LockYUVOverlay(o); | |
169 | |
170 for(y=0; y<s->h && y<o->h; y++) | |
171 { | |
172 p=((Uint8 *) s->pixels)+s->pitch*y; | |
173 op=o->pixels[0]+o->pitches[0]*y; | |
174 for(x=0; x<s->w && x<o->w; x++) | |
175 { | |
176 RGBtoYUV(p, yuv, monochrome, luminance); | |
177 if(x%2==0) | |
178 { | |
179 *(op++)=yuv[1]; | |
180 *(op++)=yuv[0]; | |
181 *(op++)=yuv[2]; | |
182 } | |
183 else | |
184 *(op++)=yuv[0]; | |
185 | |
186 p+=s->format->BytesPerPixel; | |
187 } | |
188 } | |
189 | |
190 SDL_UnlockYUVOverlay(o); | |
191 SDL_UnlockSurface(s); | |
192 } | |
193 | |
194 void ConvertRGBtoYVYU(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance) | |
195 { | |
196 int x,y; | |
197 int yuv[3]; | |
198 Uint8 *p,*op; | |
199 | |
200 SDL_LockSurface(s); | |
201 SDL_LockYUVOverlay(o); | |
202 | |
203 for(y=0; y<s->h && y<o->h; y++) | |
204 { | |
205 p=((Uint8 *) s->pixels)+s->pitch*y; | |
206 op=o->pixels[0]+o->pitches[0]*y; | |
207 for(x=0; x<s->w && x<o->w; x++) | |
208 { | |
209 RGBtoYUV(p,yuv, monochrome, luminance); | |
210 if(x%2==0) | |
211 { | |
212 *(op++)=yuv[0]; | |
213 *(op++)=yuv[2]; | |
214 op[1]=yuv[1]; | |
215 } | |
216 else | |
217 { | |
218 *op=yuv[0]; | |
219 op+=2; | |
220 } | |
221 | |
222 p+=s->format->BytesPerPixel; | |
223 } | |
224 } | |
225 | |
226 SDL_UnlockYUVOverlay(o); | |
227 SDL_UnlockSurface(s); | |
228 } | |
229 | |
230 void ConvertRGBtoYUY2(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance) | |
231 { | |
232 int x,y; | |
233 int yuv[3]; | |
234 Uint8 *p,*op; | |
235 | |
236 SDL_LockSurface(s); | |
237 SDL_LockYUVOverlay(o); | |
238 | |
239 for(y=0; y<s->h && y<o->h; y++) | |
240 { | |
241 p=((Uint8 *) s->pixels)+s->pitch*y; | |
242 op=o->pixels[0]+o->pitches[0]*y; | |
243 for(x=0; x<s->w && x<o->w; x++) | |
244 { | |
245 RGBtoYUV(p,yuv, monochrome, luminance); | |
246 if(x%2==0) | |
247 { | |
248 *(op++)=yuv[0]; | |
249 *(op++)=yuv[1]; | |
250 op[1]=yuv[2]; | |
251 } | |
252 else | |
253 { | |
254 *op=yuv[0]; | |
255 op+=2; | |
256 } | |
257 | |
258 p+=s->format->BytesPerPixel; | |
259 } | |
260 } | |
261 | |
262 SDL_UnlockYUVOverlay(o); | |
263 SDL_UnlockSurface(s); | |
264 } | |
265 | |
266 void Draw() | |
267 { | |
268 SDL_Rect rect; | |
269 int i; | |
270 int disp; | |
271 | |
272 if(!scale) | |
273 { | |
274 rect.w=overlay->w; | |
275 rect.h=overlay->h; | |
276 for(i=0; i<h-rect.h && i<w-rect.w; i++) | |
277 { | |
278 rect.x=i; | |
279 rect.y=i; | |
280 SDL_DisplayYUVOverlay(overlay,&rect); | |
281 } | |
282 } | |
283 else | |
284 { | |
285 rect.w=overlay->w/2; | |
286 rect.h=overlay->h/2; | |
287 rect.x=(w-rect.w)/2; | |
288 rect.y=(h-rect.h)/2; | |
289 disp=rect.y-1; | |
290 for(i=0; i<disp; i++) | |
291 { | |
292 rect.w+=2; | |
293 rect.h+=2; | |
294 rect.x--; | |
295 rect.y--; | |
296 SDL_DisplayYUVOverlay(overlay,&rect); | |
297 } | |
298 } | |
299 printf("Displayed %d times.\n",i); | |
300 } | |
301 | |
302 static void PrintUsage(char *argv0) | |
303 { | |
304 fprintf(stderr, "Usage: %s [arg] [arg] [arg] ...\n", argv0); | |
305 fprintf(stderr, "Where 'arg' is one of:\n"); | |
306 fprintf(stderr, " -delay <seconds>\n"); | |
307 fprintf(stderr, " -width <pixels>\n"); | |
308 fprintf(stderr, " -height <pixels>\n"); | |
309 fprintf(stderr, " -bpp <bits>\n"); | |
310 fprintf(stderr, " -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n"); | |
311 fprintf(stderr, " -hw\n"); | |
312 fprintf(stderr, " -flip\n"); | |
313 fprintf(stderr, " -scale (test scaling features, from 50%% upto window size)\n"); | |
314 fprintf(stderr, " -mono (use monochromatic RGB2YUV conversion)\n"); | |
315 fprintf(stderr, " -lum <perc> (use luminance correction during RGB2YUV conversion,\n"); | |
316 fprintf(stderr, " from 0%% to unlimited, normal is 100%%)\n"); | |
317 fprintf(stderr, " -help (shows this help)\n"); | |
318 fprintf(stderr, " -fullscreen (test overlay in fullscreen mode)\n"); | |
319 } | |
320 | |
321 int main(int argc, char **argv) | |
322 { | |
323 char *argv0 = argv[0]; | |
324 int flip; | |
325 int delay; | |
326 int desired_bpp; | |
327 Uint32 video_flags, overlay_format; | |
328 char *bmpfile; | |
329 #ifdef BENCHMARK_SDL | 521 #ifdef BENCHMARK_SDL |
330 Uint32 then, now; | 522 then = SDL_GetTicks(); |
331 #endif | 523 #endif |
332 int i; | 524 switch (overlay->format) { |
333 | 525 case SDL_YV12_OVERLAY: |
334 /* Set default options and check command-line */ | 526 ConvertRGBtoYV12(pic, overlay, monochrome, luminance); |
335 flip = 0; | 527 break; |
336 scale=0; | 528 case SDL_UYVY_OVERLAY: |
337 monochrome=0; | 529 ConvertRGBtoUYVY(pic, overlay, monochrome, luminance); |
338 luminance=100; | 530 break; |
339 delay = 1; | 531 case SDL_YVYU_OVERLAY: |
340 w = WINDOW_WIDTH; | 532 ConvertRGBtoYVYU(pic, overlay, monochrome, luminance); |
341 h = WINDOW_HEIGHT; | 533 break; |
342 desired_bpp = 0; | 534 case SDL_YUY2_OVERLAY: |
343 video_flags = 0; | 535 ConvertRGBtoYUY2(pic, overlay, monochrome, luminance); |
344 overlay_format = SDL_YV12_OVERLAY; | 536 break; |
345 | 537 case SDL_IYUV_OVERLAY: |
346 while ( argc > 1 ) { | 538 ConvertRGBtoIYUV(pic, overlay, monochrome, luminance); |
347 if ( strcmp(argv[1], "-delay") == 0 ) { | 539 break; |
348 if ( argv[2] ) { | 540 default: |
349 delay = atoi(argv[2]); | 541 printf("cannot convert RGB picture to obtained YUV format!\n"); |
350 argv += 2; | 542 quit(1); |
351 argc -= 2; | 543 break; |
352 } else { | 544 } |
353 fprintf(stderr, | |
354 "The -delay option requires an argument\n"); | |
355 return(1); | |
356 } | |
357 } else | |
358 if ( strcmp(argv[1], "-width") == 0 ) { | |
359 if ( argv[2] && ((w = atoi(argv[2])) > 0) ) { | |
360 argv += 2; | |
361 argc -= 2; | |
362 } else { | |
363 fprintf(stderr, | |
364 "The -width option requires an argument\n"); | |
365 return(1); | |
366 } | |
367 } else | |
368 if ( strcmp(argv[1], "-height") == 0 ) { | |
369 if ( argv[2] && ((h = atoi(argv[2])) > 0) ) { | |
370 argv += 2; | |
371 argc -= 2; | |
372 } else { | |
373 fprintf(stderr, | |
374 "The -height option requires an argument\n"); | |
375 return(1); | |
376 } | |
377 } else | |
378 if ( strcmp(argv[1], "-bpp") == 0 ) { | |
379 if ( argv[2] ) { | |
380 desired_bpp = atoi(argv[2]); | |
381 argv += 2; | |
382 argc -= 2; | |
383 } else { | |
384 fprintf(stderr, | |
385 "The -bpp option requires an argument\n"); | |
386 return(1); | |
387 } | |
388 } else | |
389 if ( strcmp(argv[1], "-lum") == 0 ) { | |
390 if ( argv[2] ) { | |
391 luminance = atoi(argv[2]); | |
392 argv += 2; | |
393 argc -= 2; | |
394 } else { | |
395 fprintf(stderr, | |
396 "The -lum option requires an argument\n"); | |
397 return(1); | |
398 } | |
399 } else | |
400 if ( strcmp(argv[1], "-format") == 0 ) { | |
401 if ( argv[2] ) { | |
402 if(!strcmp(argv[2],"YV12")) | |
403 overlay_format = SDL_YV12_OVERLAY; | |
404 else if(!strcmp(argv[2],"IYUV")) | |
405 overlay_format = SDL_IYUV_OVERLAY; | |
406 else if(!strcmp(argv[2],"YUY2")) | |
407 overlay_format = SDL_YUY2_OVERLAY; | |
408 else if(!strcmp(argv[2],"UYVY")) | |
409 overlay_format = SDL_UYVY_OVERLAY; | |
410 else if(!strcmp(argv[2],"YVYU")) | |
411 overlay_format = SDL_YVYU_OVERLAY; | |
412 else | |
413 { | |
414 fprintf(stderr, "The -format option %s is not recognized\n",argv[2]); | |
415 return(1); | |
416 } | |
417 argv += 2; | |
418 argc -= 2; | |
419 } else { | |
420 fprintf(stderr, | |
421 "The -format option requires an argument\n"); | |
422 return(1); | |
423 } | |
424 } else | |
425 if ( strcmp(argv[1], "-hw") == 0 ) { | |
426 video_flags |= SDL_HWSURFACE; | |
427 argv += 1; | |
428 argc -= 1; | |
429 } else | |
430 if ( strcmp(argv[1], "-flip") == 0 ) { | |
431 video_flags |= SDL_DOUBLEBUF; | |
432 argv += 1; | |
433 argc -= 1; | |
434 } else | |
435 if ( strcmp(argv[1], "-scale") == 0 ) { | |
436 scale = 1; | |
437 argv += 1; | |
438 argc -= 1; | |
439 } else | |
440 if ( strcmp(argv[1], "-mono") == 0 ) { | |
441 monochrome = 1; | |
442 argv += 1; | |
443 argc -= 1; | |
444 } else | |
445 if (( strcmp(argv[1], "-help") == 0 ) || (strcmp(argv[1], "-h") == 0)) { | |
446 PrintUsage(argv0); | |
447 return(1); | |
448 } else | |
449 if ( strcmp(argv[1], "-fullscreen") == 0 ) { | |
450 video_flags |= SDL_FULLSCREEN; | |
451 argv += 1; | |
452 argc -= 1; | |
453 } else | |
454 break; | |
455 } | |
456 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { | |
457 fprintf(stderr, | |
458 "Couldn't initialize SDL: %s\n", SDL_GetError()); | |
459 return(1); | |
460 } | |
461 | |
462 /* Initialize the display */ | |
463 screen = SDL_SetVideoMode(w, h, desired_bpp, video_flags); | |
464 if ( screen == NULL ) { | |
465 fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n", | |
466 w, h, desired_bpp, SDL_GetError()); | |
467 quit(1); | |
468 } | |
469 printf("Set%s %dx%dx%d mode\n", | |
470 screen->flags & SDL_FULLSCREEN ? " fullscreen" : "", | |
471 screen->w, screen->h, screen->format->BitsPerPixel); | |
472 printf("(video surface located in %s memory)\n", | |
473 (screen->flags&SDL_HWSURFACE) ? "video" : "system"); | |
474 if ( screen->flags & SDL_DOUBLEBUF ) { | |
475 printf("Double-buffering enabled\n"); | |
476 flip = 1; | |
477 } | |
478 | |
479 /* Set the window manager title bar */ | |
480 SDL_WM_SetCaption("SDL test overlay", "testoverlay"); | |
481 | |
482 /* Load picture */ | |
483 bmpfile=(argv[1]?argv[1]:"sample.bmp"); | |
484 pic = SDL_LoadBMP(bmpfile); | |
485 if ( pic == NULL ) { | |
486 fprintf(stderr, "Couldn't load %s: %s\n", bmpfile, | |
487 SDL_GetError()); | |
488 quit(1); | |
489 } | |
490 | |
491 /* Convert the picture to 32bits, for easy conversion */ | |
492 { | |
493 SDL_Surface *newsurf; | |
494 SDL_PixelFormat format; | |
495 | |
496 format.palette=NULL; | |
497 format.BitsPerPixel=32; | |
498 format.BytesPerPixel=4; | |
499 #if SDL_BYTEORDER == SDL_LIL_ENDIAN | |
500 format.Rshift=0; | |
501 format.Gshift=8; | |
502 format.Bshift=16; | |
503 #else | |
504 format.Rshift=24; | |
505 format.Gshift=16; | |
506 format.Bshift=8; | |
507 #endif | |
508 format.Ashift=0; | |
509 format.Rmask=0xff<<format.Rshift; | |
510 format.Gmask=0xff<<format.Gshift; | |
511 format.Bmask=0xff<<format.Bshift; | |
512 format.Amask=0; | |
513 format.Rloss=0; | |
514 format.Gloss=0; | |
515 format.Bloss=0; | |
516 format.Aloss=8; | |
517 format.colorkey=0; | |
518 format.alpha=0; | |
519 | |
520 newsurf=SDL_ConvertSurface(pic, &format, SDL_SWSURFACE); | |
521 if(!newsurf) | |
522 { | |
523 fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n", | |
524 SDL_GetError()); | |
525 quit(1); | |
526 } | |
527 SDL_FreeSurface(pic); | |
528 pic=newsurf; | |
529 } | |
530 | |
531 /* Create the overlay */ | |
532 overlay = SDL_CreateYUVOverlay(pic->w, pic->h, overlay_format, screen); | |
533 if ( overlay == NULL ) { | |
534 fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError()); | |
535 quit(1); | |
536 } | |
537 printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes, | |
538 overlay->hw_overlay?"hardware":"software", | |
539 overlay->format==SDL_YV12_OVERLAY?"YV12": | |
540 overlay->format==SDL_IYUV_OVERLAY?"IYUV": | |
541 overlay->format==SDL_YUY2_OVERLAY?"YUY2": | |
542 overlay->format==SDL_UYVY_OVERLAY?"UYVY": | |
543 overlay->format==SDL_YVYU_OVERLAY?"YVYU": | |
544 "Unknown"); | |
545 for(i=0; i<overlay->planes; i++) | |
546 { | |
547 printf(" plane %d: pitch=%d\n", i, overlay->pitches[i]); | |
548 } | |
549 | |
550 /* Convert to YUV, and draw to the overlay */ | |
551 #ifdef BENCHMARK_SDL | 545 #ifdef BENCHMARK_SDL |
552 then = SDL_GetTicks(); | 546 now = SDL_GetTicks(); |
553 #endif | 547 printf("Conversion Time: %d milliseconds\n", now - then); |
554 switch(overlay->format) | 548 #endif |
555 { | 549 |
556 case SDL_YV12_OVERLAY: | 550 /* Do all the drawing work */ |
557 ConvertRGBtoYV12(pic,overlay,monochrome,luminance); | |
558 break; | |
559 case SDL_UYVY_OVERLAY: | |
560 ConvertRGBtoUYVY(pic,overlay,monochrome,luminance); | |
561 break; | |
562 case SDL_YVYU_OVERLAY: | |
563 ConvertRGBtoYVYU(pic,overlay,monochrome,luminance); | |
564 break; | |
565 case SDL_YUY2_OVERLAY: | |
566 ConvertRGBtoYUY2(pic,overlay,monochrome,luminance); | |
567 break; | |
568 case SDL_IYUV_OVERLAY: | |
569 ConvertRGBtoIYUV(pic,overlay,monochrome,luminance); | |
570 break; | |
571 default: | |
572 printf("cannot convert RGB picture to obtained YUV format!\n"); | |
573 quit(1); | |
574 break; | |
575 } | |
576 #ifdef BENCHMARK_SDL | 551 #ifdef BENCHMARK_SDL |
577 now = SDL_GetTicks(); | 552 then = SDL_GetTicks(); |
578 printf("Conversion Time: %d milliseconds\n", now-then); | 553 #endif |
579 #endif | 554 Draw(); |
580 | |
581 /* Do all the drawing work */ | |
582 #ifdef BENCHMARK_SDL | 555 #ifdef BENCHMARK_SDL |
583 then = SDL_GetTicks(); | 556 now = SDL_GetTicks(); |
584 #endif | 557 printf("Time: %d milliseconds\n", now - then); |
585 Draw(); | 558 #endif |
586 #ifdef BENCHMARK_SDL | 559 SDL_Delay(delay * 1000); |
587 now = SDL_GetTicks(); | 560 SDL_Quit(); |
588 printf("Time: %d milliseconds\n", now-then); | 561 return (0); |
589 #endif | 562 } |
590 SDL_Delay(delay*1000); | |
591 SDL_Quit(); | |
592 return(0); | |
593 } | |
594 |