Remove CBitmapSurface.
[SDL.s60v3.git] / test / testoverlay.c
blobda53f9ea0956ddf4b054d17ad4114251ce249edc
2 /* Bring up a window and play with it */
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
8 #define BENCHMARK_SDL
10 #define NOTICE(X) printf("%s", X);
12 #define WINDOW_WIDTH 640
13 #define WINDOW_HEIGHT 480
15 #include "SDL.h"
17 SDL_Surface *screen, *pic;
18 SDL_Overlay *overlay;
19 int scale;
20 int monochrome;
21 int luminance;
22 int w, h;
24 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
25 static void quit(int rc)
27 SDL_Quit();
28 exit(rc);
31 /* NOTE: These RGB conversion functions are not intended for speed,
32 only as examples.
35 void RGBtoYUV(Uint8 *rgb, int *yuv, int monochrome, int luminance)
37 if (monochrome)
39 #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[1] = 128;
42 yuv[2] = 128;
43 #else
44 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
45 yuv[1] = 128;
46 yuv[2] = 128;
47 #endif
49 else
51 #if 1 /* these are the two formulas that I found on the FourCC site... */
52 yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
53 yuv[1] = (rgb[2]-yuv[0])*0.565 + 128;
54 yuv[2] = (rgb[0]-yuv[0])*0.713 + 128;
55 #else
56 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]);
58 yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
59 #endif
62 if (luminance!=100)
64 yuv[0]=yuv[0]*luminance/100;
65 if (yuv[0]>255)
66 yuv[0]=255;
69 /* clamp values...if you need to, we don't seem to have a need */
71 for(i=0;i<3;i++)
73 if(yuv[i]<0)
74 yuv[i]=0;
75 if(yuv[i]>255)
76 yuv[i]=255;
81 void ConvertRGBtoYV12(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
83 int x,y;
84 int yuv[3];
85 Uint8 *p,*op[3];
87 SDL_LockSurface(s);
88 SDL_LockYUVOverlay(o);
90 /* Black initialization */
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));
97 /* Convert */
98 for(y=0; y<s->h && y<o->h; y++)
100 p=((Uint8 *) s->pixels)+s->pitch*y;
101 op[0]=o->pixels[0]+o->pitches[0]*y;
102 op[1]=o->pixels[1]+o->pitches[1]*(y/2);
103 op[2]=o->pixels[2]+o->pitches[2]*(y/2);
104 for(x=0; x<s->w && x<o->w; x++)
106 RGBtoYUV(p, yuv, monochrome, luminance);
107 *(op[0]++)=yuv[0];
108 if(x%2==0 && y%2==0)
110 *(op[1]++)=yuv[2];
111 *(op[2]++)=yuv[1];
113 p+=s->format->BytesPerPixel;
117 SDL_UnlockYUVOverlay(o);
118 SDL_UnlockSurface(s);
121 void ConvertRGBtoIYUV(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
123 int x,y;
124 int yuv[3];
125 Uint8 *p,*op[3];
127 SDL_LockSurface(s);
128 SDL_LockYUVOverlay(o);
130 /* Black initialization */
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));
137 /* Convert */
138 for(y=0; y<s->h && y<o->h; y++)
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++)
146 RGBtoYUV(p,yuv, monochrome, luminance);
147 *(op[0]++)=yuv[0];
148 if(x%2==0 && y%2==0)
150 *(op[1]++)=yuv[1];
151 *(op[2]++)=yuv[2];
153 p+=s->format->BytesPerPixel;
157 SDL_UnlockYUVOverlay(o);
158 SDL_UnlockSurface(s);
161 void ConvertRGBtoUYVY(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
163 int x,y;
164 int yuv[3];
165 Uint8 *p,*op;
167 SDL_LockSurface(s);
168 SDL_LockYUVOverlay(o);
170 for(y=0; y<s->h && y<o->h; y++)
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++)
176 RGBtoYUV(p, yuv, monochrome, luminance);
177 if(x%2==0)
179 *(op++)=yuv[1];
180 *(op++)=yuv[0];
181 *(op++)=yuv[2];
183 else
184 *(op++)=yuv[0];
186 p+=s->format->BytesPerPixel;
190 SDL_UnlockYUVOverlay(o);
191 SDL_UnlockSurface(s);
194 void ConvertRGBtoYVYU(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
196 int x,y;
197 int yuv[3];
198 Uint8 *p,*op;
200 SDL_LockSurface(s);
201 SDL_LockYUVOverlay(o);
203 for(y=0; y<s->h && y<o->h; y++)
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++)
209 RGBtoYUV(p,yuv, monochrome, luminance);
210 if(x%2==0)
212 *(op++)=yuv[0];
213 *(op++)=yuv[2];
214 op[1]=yuv[1];
216 else
218 *op=yuv[0];
219 op+=2;
222 p+=s->format->BytesPerPixel;
226 SDL_UnlockYUVOverlay(o);
227 SDL_UnlockSurface(s);
230 void ConvertRGBtoYUY2(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
232 int x,y;
233 int yuv[3];
234 Uint8 *p,*op;
236 SDL_LockSurface(s);
237 SDL_LockYUVOverlay(o);
239 for(y=0; y<s->h && y<o->h; y++)
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++)
245 RGBtoYUV(p,yuv, monochrome, luminance);
246 if(x%2==0)
248 *(op++)=yuv[0];
249 *(op++)=yuv[1];
250 op[1]=yuv[2];
252 else
254 *op=yuv[0];
255 op+=2;
258 p+=s->format->BytesPerPixel;
262 SDL_UnlockYUVOverlay(o);
263 SDL_UnlockSurface(s);
266 void Draw()
268 SDL_Rect rect;
269 int i;
270 int disp;
272 if(!scale)
274 rect.w=overlay->w;
275 rect.h=overlay->h;
276 for(i=0; i<h-rect.h && i<w-rect.w; i++)
278 rect.x=i;
279 rect.y=i;
280 SDL_DisplayYUVOverlay(overlay,&rect);
283 else
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++)
292 rect.w+=2;
293 rect.h+=2;
294 rect.x--;
295 rect.y--;
296 SDL_DisplayYUVOverlay(overlay,&rect);
299 printf("Displayed %d times.\n",i);
302 static void PrintUsage(char *argv0)
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");
321 int main(int argc, char **argv)
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
330 Uint32 then, now;
331 #endif
332 int i;
334 /* Set default options and check command-line */
335 flip = 0;
336 scale=0;
337 monochrome=0;
338 luminance=100;
339 delay = 1;
340 w = WINDOW_WIDTH;
341 h = WINDOW_HEIGHT;
342 desired_bpp = 0;
343 video_flags = 0;
344 overlay_format = SDL_YV12_OVERLAY;
346 while ( argc > 1 ) {
347 if ( strcmp(argv[1], "-delay") == 0 ) {
348 if ( argv[2] ) {
349 delay = atoi(argv[2]);
350 argv += 2;
351 argc -= 2;
352 } else {
353 fprintf(stderr,
354 "The -delay option requires an argument\n");
355 return(1);
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);
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);
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);
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);
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
414 fprintf(stderr, "The -format option %s is not recognized\n",argv[2]);
415 return(1);
417 argv += 2;
418 argc -= 2;
419 } else {
420 fprintf(stderr,
421 "The -format option requires an argument\n");
422 return(1);
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;
456 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
457 fprintf(stderr,
458 "Couldn't initialize SDL: %s\n", SDL_GetError());
459 return(1);
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);
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;
479 /* Set the window manager title bar */
480 SDL_WM_SetCaption("SDL test overlay", "testoverlay");
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);
491 /* Convert the picture to 32bits, for easy conversion */
493 SDL_Surface *newsurf;
494 SDL_PixelFormat format;
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;
520 newsurf=SDL_ConvertSurface(pic, &format, SDL_SWSURFACE);
521 if(!newsurf)
523 fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n",
524 SDL_GetError());
525 quit(1);
527 SDL_FreeSurface(pic);
528 pic=newsurf;
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);
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++)
547 printf(" plane %d: pitch=%d\n", i, overlay->pitches[i]);
550 /* Convert to YUV, and draw to the overlay */
551 #ifdef BENCHMARK_SDL
552 then = SDL_GetTicks();
553 #endif
554 switch(overlay->format)
556 case SDL_YV12_OVERLAY:
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;
576 #ifdef BENCHMARK_SDL
577 now = SDL_GetTicks();
578 printf("Conversion Time: %d milliseconds\n", now-then);
579 #endif
581 /* Do all the drawing work */
582 #ifdef BENCHMARK_SDL
583 then = SDL_GetTicks();
584 #endif
585 Draw();
586 #ifdef BENCHMARK_SDL
587 now = SDL_GetTicks();
588 printf("Time: %d milliseconds\n", now-then);
589 #endif
590 SDL_Delay(delay*1000);
591 SDL_Quit();
592 return(0);