test/testoverlay.c
changeset 1895 c121d94672cb
parent 1439 4d3bb026cd16
child 2267 c785543d1843
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