test/testyuv.c
changeset 11702 cf166abbde4a
child 11811 5d94cb6b24d3
equal deleted inserted replaced
11701:d131f3193794 11702:cf166abbde4a
       
     1 /*
       
     2   Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
       
     3 
       
     4   This software is provided 'as-is', without any express or implied
       
     5   warranty.  In no event will the authors be held liable for any damages
       
     6   arising from the use of this software.
       
     7 
       
     8   Permission is granted to anyone to use this software for any purpose,
       
     9   including commercial applications, and to alter it and redistribute it
       
    10   freely.
       
    11 */
       
    12 #include <stdlib.h>
       
    13 #include <stdio.h>
       
    14 #include <string.h>
       
    15 
       
    16 #include "SDL.h"
       
    17 #include "SDL_test_font.h"
       
    18 #include "testyuv_cvt.h"
       
    19 
       
    20 
       
    21 /* 422 (YUY2, etc) formats are the largest */
       
    22 #define MAX_YUV_SURFACE_SIZE(W, H, P)  (H*4*(W+P+1)/2)
       
    23 
       
    24 
       
    25 /* Return true if the YUV format is packed pixels */
       
    26 static SDL_bool is_packed_yuv_format(Uint32 format)
       
    27 {
       
    28     return (format == SDL_PIXELFORMAT_YUY2 ||
       
    29             format == SDL_PIXELFORMAT_UYVY ||
       
    30             format == SDL_PIXELFORMAT_YVYU);
       
    31 }
       
    32 
       
    33 /* Create a surface with a good pattern for verifying YUV conversion */
       
    34 static SDL_Surface *generate_test_pattern(int pattern_size)
       
    35 {
       
    36     SDL_Surface *pattern = SDL_CreateRGBSurfaceWithFormat(0, pattern_size, pattern_size, 0, SDL_PIXELFORMAT_RGB24);
       
    37 
       
    38     if (pattern) {
       
    39         int i, x, y;
       
    40         Uint8 *p, c;
       
    41         const int thickness = 2;    /* Important so 2x2 blocks of color are the same, to avoid Cr/Cb interpolation over pixels */
       
    42 
       
    43         /* R, G, B in alternating horizontal bands */
       
    44         for (y = 0; y < pattern->h; y += thickness) {
       
    45             for (i = 0; i < thickness; ++i) {
       
    46                 p = (Uint8 *)pattern->pixels + (y + i) * pattern->pitch + ((y/thickness) % 3);
       
    47                 for (x = 0; x < pattern->w; ++x) {
       
    48                     *p = 0xFF;
       
    49                     p += 3;
       
    50                 }
       
    51             }
       
    52         }
       
    53 
       
    54         /* Black and white in alternating vertical bands */
       
    55         c = 0xFF;
       
    56         for (x = 1*thickness; x < pattern->w; x += 2*thickness) {
       
    57             for (i = 0; i < thickness; ++i) {
       
    58                 p = (Uint8 *)pattern->pixels + (x + i)*3;
       
    59                 for (y = 0; y < pattern->h; ++y) {
       
    60                     SDL_memset(p, c, 3);
       
    61                     p += pattern->pitch;
       
    62                 }
       
    63             }
       
    64             if (c) {
       
    65                 c = 0x00;
       
    66             } else {
       
    67                 c = 0xFF;
       
    68             }
       
    69         }
       
    70     }
       
    71     return pattern;
       
    72 }
       
    73 
       
    74 static SDL_bool verify_yuv_data(Uint32 format, const Uint8 *yuv, int yuv_pitch, SDL_Surface *surface)
       
    75 {
       
    76     const int tolerance = 20;
       
    77     const int size = (surface->h * surface->pitch);
       
    78     Uint8 *rgb;
       
    79     SDL_bool result = SDL_FALSE;
       
    80 
       
    81     rgb = (Uint8 *)SDL_malloc(size);
       
    82     if (!rgb) {
       
    83         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory");
       
    84         return SDL_FALSE;
       
    85     }
       
    86 
       
    87     if (SDL_ConvertPixels(surface->w, surface->h, format, yuv, yuv_pitch, surface->format->format, rgb, surface->pitch) == 0) {
       
    88         int x, y;
       
    89         result = SDL_TRUE;
       
    90         for (y = 0; y < surface->h; ++y) {
       
    91             const Uint8 *actual = rgb + y * surface->pitch;
       
    92             const Uint8 *expected = (const Uint8 *)surface->pixels + y * surface->pitch;
       
    93             for (x = 0; x < surface->w; ++x) {
       
    94                 int deltaR = (int)actual[0] - expected[0];
       
    95                 int deltaG = (int)actual[1] - expected[1];
       
    96                 int deltaB = (int)actual[2] - expected[2];
       
    97                 int distance = (deltaR * deltaR + deltaG * deltaG + deltaB * deltaB);
       
    98                 if (distance > tolerance) {
       
    99                     SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Pixel at %d,%d was 0x%.2x,0x%.2x,0x%.2x, expected 0x%.2x,0x%.2x,0x%.2x, distance = %d\n", x, y, actual[0], actual[1], actual[2], expected[0], expected[1], expected[2], distance);
       
   100                     result = SDL_FALSE;
       
   101                 }
       
   102                 actual += 3;
       
   103                 expected += 3;
       
   104             }
       
   105         }
       
   106     } else {
       
   107         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(format), SDL_GetPixelFormatName(surface->format->format), SDL_GetError());
       
   108     }
       
   109     SDL_free(rgb);
       
   110 
       
   111     return result;
       
   112 }
       
   113 
       
   114 static int run_automated_tests(int pattern_size, int extra_pitch)
       
   115 {
       
   116     const Uint32 formats[] = {
       
   117         SDL_PIXELFORMAT_YV12,
       
   118         SDL_PIXELFORMAT_IYUV,
       
   119         SDL_PIXELFORMAT_NV12,
       
   120         SDL_PIXELFORMAT_NV21,
       
   121         SDL_PIXELFORMAT_YUY2,
       
   122         SDL_PIXELFORMAT_UYVY,
       
   123         SDL_PIXELFORMAT_YVYU
       
   124     };
       
   125     int i, j;
       
   126     SDL_Surface *pattern = generate_test_pattern(pattern_size);
       
   127     const int yuv_len = MAX_YUV_SURFACE_SIZE(pattern->w, pattern->h, extra_pitch);
       
   128     Uint8 *yuv1 = (Uint8 *)SDL_malloc(yuv_len);
       
   129     Uint8 *yuv2 = (Uint8 *)SDL_malloc(yuv_len);
       
   130     int yuv1_pitch, yuv2_pitch;
       
   131     int result = -1;
       
   132     
       
   133     if (!pattern || !yuv1 || !yuv2) {
       
   134         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't allocate test surfaces");
       
   135         goto done;
       
   136     }
       
   137 
       
   138     /* Verify conversion from YUV formats */
       
   139     for (i = 0; i < SDL_arraysize(formats); ++i) {
       
   140         if (!ConvertRGBtoYUV(formats[i], pattern->pixels, pattern->pitch, yuv1, pattern->w, pattern->h, SDL_GetYUVConversionModeForResolution(pattern->w, pattern->h), 0, 100)) {
       
   141             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "ConvertRGBtoYUV() doesn't support converting to %s\n", SDL_GetPixelFormatName(formats[i]));
       
   142             goto done;
       
   143         }
       
   144         yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w);
       
   145         if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) {
       
   146             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to RGB\n", SDL_GetPixelFormatName(formats[i]));
       
   147             goto done;
       
   148         }
       
   149     }
       
   150 
       
   151     /* Verify conversion to YUV formats */
       
   152     for (i = 0; i < SDL_arraysize(formats); ++i) {
       
   153         yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch;
       
   154         if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) {
       
   155             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError());
       
   156             goto done;
       
   157         }
       
   158         if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) {
       
   159             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from RGB to %s\n", SDL_GetPixelFormatName(formats[i]));
       
   160             goto done;
       
   161         }
       
   162     }
       
   163 
       
   164     /* Verify conversion between YUV formats */
       
   165     for (i = 0; i < SDL_arraysize(formats); ++i) {
       
   166         for (j = 0; j < SDL_arraysize(formats); ++j) {
       
   167             yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch;
       
   168             yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch;
       
   169             if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) {
       
   170                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError());
       
   171                 goto done;
       
   172             }
       
   173             if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv2, yuv2_pitch) < 0) {
       
   174                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError());
       
   175                 goto done;
       
   176             }
       
   177             if (!verify_yuv_data(formats[j], yuv2, yuv2_pitch, pattern)) {
       
   178                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]));
       
   179                 goto done;
       
   180             }
       
   181         }
       
   182     }
       
   183 
       
   184     /* Verify conversion between YUV formats in-place */
       
   185     for (i = 0; i < SDL_arraysize(formats); ++i) {
       
   186         for (j = 0; j < SDL_arraysize(formats); ++j) {
       
   187             if (is_packed_yuv_format(formats[i]) != is_packed_yuv_format(formats[j])) {
       
   188                 /* Can't change plane vs packed pixel layout in-place */
       
   189                 continue;
       
   190             }
       
   191 
       
   192             yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch;
       
   193             yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch;
       
   194             if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) {
       
   195                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError());
       
   196                 goto done;
       
   197             }
       
   198             if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv1, yuv2_pitch) < 0) {
       
   199                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError());
       
   200                 goto done;
       
   201             }
       
   202             if (!verify_yuv_data(formats[j], yuv1, yuv2_pitch, pattern)) {
       
   203                 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]));
       
   204                 goto done;
       
   205             }
       
   206         }
       
   207     }
       
   208 
       
   209 
       
   210     result = 0;
       
   211 
       
   212 done:
       
   213     SDL_free(yuv1);
       
   214     SDL_free(yuv2);
       
   215     SDL_FreeSurface(pattern);
       
   216     return result;
       
   217 }
       
   218 
       
   219 int
       
   220 main(int argc, char **argv)
       
   221 {
       
   222     struct {
       
   223         SDL_bool enable_intrinsics;
       
   224         int pattern_size;
       
   225         int extra_pitch;
       
   226     } automated_test_params[] = {
       
   227         /* Test: even width and height */
       
   228         { SDL_FALSE, 2, 0 },
       
   229         { SDL_FALSE, 4, 0 },
       
   230         /* Test: odd width and height */
       
   231         { SDL_FALSE, 1, 0 },
       
   232         { SDL_FALSE, 3, 0 },
       
   233         /* Test: even width and height, extra pitch */
       
   234         { SDL_FALSE, 2, 3 },
       
   235         { SDL_FALSE, 4, 3 },
       
   236         /* Test: odd width and height, extra pitch */
       
   237         { SDL_FALSE, 1, 3 },
       
   238         { SDL_FALSE, 3, 3 },
       
   239         /* Test: even width and height with intrinsics */
       
   240         { SDL_TRUE, 32, 0 },
       
   241         /* Test: odd width and height with intrinsics */
       
   242         { SDL_TRUE, 33, 0 },
       
   243         { SDL_TRUE, 37, 0 },
       
   244         /* Test: even width and height with intrinsics, extra pitch */
       
   245         { SDL_TRUE, 32, 3 },
       
   246         /* Test: odd width and height with intrinsics, extra pitch */
       
   247         { SDL_TRUE, 33, 3 },
       
   248         { SDL_TRUE, 37, 3 },
       
   249     };
       
   250     int arg = 1;
       
   251     const char *filename;
       
   252     SDL_Surface *original;
       
   253     SDL_Surface *converted;
       
   254     SDL_Window *window;
       
   255     SDL_Renderer *renderer;
       
   256     SDL_Texture *output[3];
       
   257     const char *titles[3] = { "ORIGINAL", "SOFTWARE", "HARDWARE" };
       
   258     char title[128];
       
   259     const char *yuv_name;
       
   260     const char *yuv_mode;
       
   261     Uint32 rgb_format = SDL_PIXELFORMAT_RGBX8888;
       
   262     Uint32 yuv_format = SDL_PIXELFORMAT_YV12;
       
   263     int current = 0;
       
   264     int pitch;
       
   265     Uint8 *raw_yuv;
       
   266     Uint32 then, now, i, iterations = 100;
       
   267     SDL_bool should_run_automated_tests = SDL_FALSE;
       
   268 
       
   269     while (argv[arg] && *argv[arg] == '-') {
       
   270         if (SDL_strcmp(argv[arg], "--jpeg") == 0) {
       
   271             SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_JPEG);
       
   272         } else if (SDL_strcmp(argv[arg], "--bt601") == 0) {
       
   273             SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT601);
       
   274         } else if (SDL_strcmp(argv[arg], "--bt709") == 0) {
       
   275             SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT709);
       
   276         } else if (SDL_strcmp(argv[arg], "--auto") == 0) {
       
   277             SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_AUTOMATIC);
       
   278         } else if (SDL_strcmp(argv[arg], "--yv12") == 0) {
       
   279             yuv_format = SDL_PIXELFORMAT_YV12;
       
   280         } else if (SDL_strcmp(argv[arg], "--iyuv") == 0) {
       
   281             yuv_format = SDL_PIXELFORMAT_IYUV;
       
   282         } else if (SDL_strcmp(argv[arg], "--yuy2") == 0) {
       
   283             yuv_format = SDL_PIXELFORMAT_YUY2;
       
   284         } else if (SDL_strcmp(argv[arg], "--uyvy") == 0) {
       
   285             yuv_format = SDL_PIXELFORMAT_UYVY;
       
   286         } else if (SDL_strcmp(argv[arg], "--yvyu") == 0) {
       
   287             yuv_format = SDL_PIXELFORMAT_YVYU;
       
   288         } else if (SDL_strcmp(argv[arg], "--nv12") == 0) {
       
   289             yuv_format = SDL_PIXELFORMAT_NV12;
       
   290         } else if (SDL_strcmp(argv[arg], "--nv21") == 0) {
       
   291             yuv_format = SDL_PIXELFORMAT_NV21;
       
   292         } else if (SDL_strcmp(argv[arg], "--rgb555") == 0) {
       
   293             rgb_format = SDL_PIXELFORMAT_RGB555;
       
   294         } else if (SDL_strcmp(argv[arg], "--rgb565") == 0) {
       
   295             rgb_format = SDL_PIXELFORMAT_RGB565;
       
   296         } else if (SDL_strcmp(argv[arg], "--rgb24") == 0) {
       
   297             rgb_format = SDL_PIXELFORMAT_RGB24;
       
   298         } else if (SDL_strcmp(argv[arg], "--argb") == 0) {
       
   299             rgb_format = SDL_PIXELFORMAT_ARGB8888;
       
   300         } else if (SDL_strcmp(argv[arg], "--abgr") == 0) {
       
   301             rgb_format = SDL_PIXELFORMAT_ABGR8888;
       
   302         } else if (SDL_strcmp(argv[arg], "--rgba") == 0) {
       
   303             rgb_format = SDL_PIXELFORMAT_RGBA8888;
       
   304         } else if (SDL_strcmp(argv[arg], "--bgra") == 0) {
       
   305             rgb_format = SDL_PIXELFORMAT_BGRA8888;
       
   306         } else if (SDL_strcmp(argv[arg], "--automated") == 0) {
       
   307             should_run_automated_tests = SDL_TRUE;
       
   308         } else {
       
   309             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Usage: %s [--jpeg|--bt601|-bt709|--auto] [--yv12|--iyuv|--yuy2|--uyvy|--yvyu|--nv12|--nv21] [--rgb555|--rgb565|--rgb24|--argb|--abgr|--rgba|--bgra] [image_filename]\n", argv[0]);
       
   310             return 1;
       
   311         }
       
   312         ++arg;
       
   313     }
       
   314 
       
   315     /* Run automated tests */
       
   316     if (should_run_automated_tests) {
       
   317         for (i = 0; i < SDL_arraysize(automated_test_params); ++i) {
       
   318             SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Running automated test, pattern size %d, extra pitch %d, intrinsics %s\n", 
       
   319                 automated_test_params[i].pattern_size,
       
   320                 automated_test_params[i].extra_pitch,
       
   321                 automated_test_params[i].enable_intrinsics ? "enabled" : "disabled");
       
   322             if (run_automated_tests(automated_test_params[i].pattern_size, automated_test_params[i].extra_pitch) < 0) {
       
   323                 return 2;
       
   324             }
       
   325         }
       
   326         return 0;
       
   327     }
       
   328 
       
   329     if (argv[arg]) {
       
   330         filename = argv[arg];
       
   331     } else {
       
   332         filename = "testyuv.bmp";
       
   333     }
       
   334     original = SDL_ConvertSurfaceFormat(SDL_LoadBMP(filename), SDL_PIXELFORMAT_RGB24, 0);
       
   335     if (!original) {
       
   336         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
       
   337         return 3;
       
   338     }
       
   339 
       
   340     raw_yuv = SDL_calloc(1, MAX_YUV_SURFACE_SIZE(original->w, original->h, 0));
       
   341     ConvertRGBtoYUV(yuv_format, original->pixels, original->pitch, raw_yuv, original->w, original->h,
       
   342         SDL_GetYUVConversionModeForResolution(original->w, original->h),
       
   343         0, 100);
       
   344     pitch = CalculateYUVPitch(yuv_format, original->w);
       
   345 
       
   346     converted = SDL_CreateRGBSurfaceWithFormat(0, original->w, original->h, 0, rgb_format);
       
   347     if (!converted) {
       
   348         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create converted surface: %s\n", SDL_GetError());
       
   349         return 3;
       
   350     }
       
   351 
       
   352     then = SDL_GetTicks();
       
   353     for ( i = 0; i < iterations; ++i ) {
       
   354         SDL_ConvertPixels(original->w, original->h, yuv_format, raw_yuv, pitch, rgb_format, converted->pixels, converted->pitch);
       
   355     }
       
   356     now = SDL_GetTicks();
       
   357     SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "%d iterations in %d ms, %.2fms each\n", iterations, (now - then), (float)(now - then)/iterations);
       
   358 
       
   359     window = SDL_CreateWindow("YUV test",
       
   360                               SDL_WINDOWPOS_UNDEFINED,
       
   361                               SDL_WINDOWPOS_UNDEFINED,
       
   362                               original->w, original->h,
       
   363                               0);
       
   364     if (!window) {
       
   365         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
       
   366         return 4;
       
   367     }
       
   368 
       
   369     renderer = SDL_CreateRenderer(window, -1, 0);
       
   370     if (!renderer) {
       
   371         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
       
   372         return 4;
       
   373     }
       
   374 
       
   375     output[0] = SDL_CreateTextureFromSurface(renderer, original);
       
   376     output[1] = SDL_CreateTextureFromSurface(renderer, converted);
       
   377     output[2] = SDL_CreateTexture(renderer, yuv_format, SDL_TEXTUREACCESS_STREAMING, original->w, original->h);
       
   378     if (!output[0] || !output[1] || !output[2]) {
       
   379         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError());
       
   380         return 5;
       
   381     }
       
   382     SDL_UpdateTexture(output[2], NULL, raw_yuv, pitch);
       
   383     
       
   384     yuv_name = SDL_GetPixelFormatName(yuv_format);
       
   385     if (SDL_strncmp(yuv_name, "SDL_PIXELFORMAT_", 16) == 0) {
       
   386         yuv_name += 16;
       
   387     }
       
   388 
       
   389     switch (SDL_GetYUVConversionModeForResolution(original->w, original->h)) {
       
   390     case SDL_YUV_CONVERSION_JPEG:
       
   391         yuv_mode = "JPEG";
       
   392         break;
       
   393     case SDL_YUV_CONVERSION_BT601:
       
   394         yuv_mode = "BT.601";
       
   395         break;
       
   396     case SDL_YUV_CONVERSION_BT709:
       
   397         yuv_mode = "BT.709";
       
   398         break;
       
   399     default:
       
   400         yuv_mode = "UNKNOWN";
       
   401         break;
       
   402     }
       
   403 
       
   404     { int done = 0;
       
   405         while ( !done )
       
   406         {
       
   407             SDL_Event event;
       
   408             while (SDL_PollEvent(&event) > 0) {
       
   409                 if (event.type == SDL_QUIT) {
       
   410                     done = 1;
       
   411                 }
       
   412                 if (event.type == SDL_KEYDOWN) {
       
   413                     if (event.key.keysym.sym == SDLK_ESCAPE) {
       
   414                         done = 1;
       
   415                     } else if (event.key.keysym.sym == SDLK_LEFT) {
       
   416                         --current;
       
   417                     } else if (event.key.keysym.sym == SDLK_RIGHT) {
       
   418                         ++current;
       
   419                     }
       
   420                 }
       
   421                 if (event.type == SDL_MOUSEBUTTONDOWN) {
       
   422                     if (event.button.x < (original->w/2)) {
       
   423                         --current;
       
   424                     } else {
       
   425                         ++current;
       
   426                     }
       
   427                 }
       
   428             }
       
   429 
       
   430             /* Handle wrapping */
       
   431             if (current < 0) {
       
   432                 current += SDL_arraysize(output);
       
   433             }
       
   434             if (current >= SDL_arraysize(output)) {
       
   435                 current -= SDL_arraysize(output);
       
   436             }
       
   437 
       
   438             SDL_RenderClear(renderer);
       
   439             SDL_RenderCopy(renderer, output[current], NULL, NULL);
       
   440             SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
       
   441             if (current == 0) {
       
   442                 SDLTest_DrawString(renderer, 4, 4, titles[current]);
       
   443             } else {
       
   444                 SDL_snprintf(title, sizeof(title), "%s %s %s", titles[current], yuv_name, yuv_mode);
       
   445                 SDLTest_DrawString(renderer, 4, 4, title);
       
   446             }
       
   447             SDL_RenderPresent(renderer);
       
   448             SDL_Delay(10);
       
   449         }
       
   450     }
       
   451     SDL_Quit();
       
   452     return 0;
       
   453 }
       
   454 
       
   455 /* vi: set ts=4 sw=4 expandtab: */