src/render/SDL_yuv_sw.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 14 Jun 2019 13:56:42 -0700
changeset 12860 0f52dd40abe5
parent 12503 806492103856
permissions -rw-r--r--
Worked around "Undefined symbol: ___isPlatformVersionAtLeast()" link error on Xcode 11 beta
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@12503
     3
  Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
icculus@8093
    21
#include "../SDL_internal.h"
slouken@0
    22
slouken@1895
    23
/* This is the software implementation of the YUV texture support */
slouken@0
    24
slouken@11702
    25
#include "SDL_assert.h"
slouken@0
    26
slouken@11702
    27
#include "SDL_yuv_sw_c.h"
slouken@0
    28
slouken@0
    29
slouken@1895
    30
SDL_SW_YUVTexture *
slouken@2781
    31
SDL_SW_CreateYUVTexture(Uint32 format, int w, int h)
slouken@0
    32
{
slouken@1895
    33
    SDL_SW_YUVTexture *swdata;
slouken@1895
    34
slouken@2781
    35
    switch (format) {
slouken@1965
    36
    case SDL_PIXELFORMAT_YV12:
slouken@1965
    37
    case SDL_PIXELFORMAT_IYUV:
slouken@1965
    38
    case SDL_PIXELFORMAT_YUY2:
slouken@1965
    39
    case SDL_PIXELFORMAT_UYVY:
slouken@1965
    40
    case SDL_PIXELFORMAT_YVYU:
slouken@11574
    41
    case SDL_PIXELFORMAT_NV12:
slouken@11574
    42
    case SDL_PIXELFORMAT_NV21:
slouken@1895
    43
        break;
slouken@1895
    44
    default:
slouken@1895
    45
        SDL_SetError("Unsupported YUV format");
slouken@1895
    46
        return NULL;
slouken@1895
    47
    }
slouken@1895
    48
icculus@7487
    49
    swdata = (SDL_SW_YUVTexture *) SDL_calloc(1, sizeof(*swdata));
icculus@7487
    50
    if (!swdata) {
icculus@7487
    51
        SDL_OutOfMemory();
icculus@7487
    52
        return NULL;
icculus@7487
    53
    }
icculus@7487
    54
slouken@2781
    55
    swdata->format = format;
slouken@1965
    56
    swdata->target_format = SDL_PIXELFORMAT_UNKNOWN;
slouken@2786
    57
    swdata->w = w;
slouken@2786
    58
    swdata->h = h;
slouken@11574
    59
    {
slouken@11574
    60
        const int sz_plane         = w * h;
slouken@11574
    61
        const int sz_plane_chroma  = ((w + 1) / 2) * ((h + 1) / 2);
slouken@11574
    62
        const int sz_plane_packed  = ((w + 1) / 2) * h;
slouken@11574
    63
        int dst_size = 0;     
slouken@11574
    64
        switch(format) 
slouken@11574
    65
        {
slouken@11574
    66
            case SDL_PIXELFORMAT_YV12: /**< Planar mode: Y + V + U  (3 planes) */
slouken@11574
    67
            case SDL_PIXELFORMAT_IYUV: /**< Planar mode: Y + U + V  (3 planes) */
slouken@11574
    68
                dst_size = sz_plane + sz_plane_chroma + sz_plane_chroma;
slouken@11574
    69
                break;
slouken@11574
    70
slouken@11574
    71
            case SDL_PIXELFORMAT_YUY2: /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */
slouken@11574
    72
            case SDL_PIXELFORMAT_UYVY: /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */
slouken@11574
    73
            case SDL_PIXELFORMAT_YVYU: /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */
slouken@11574
    74
                dst_size = 4 * sz_plane_packed;
slouken@11574
    75
                break;
slouken@11574
    76
slouken@11574
    77
            case SDL_PIXELFORMAT_NV12: /**< Planar mode: Y + U/V interleaved  (2 planes) */
slouken@11574
    78
            case SDL_PIXELFORMAT_NV21: /**< Planar mode: Y + V/U interleaved  (2 planes) */
slouken@11574
    79
                dst_size = sz_plane + sz_plane_chroma + sz_plane_chroma;
slouken@11574
    80
                break;
slouken@11574
    81
slouken@11574
    82
            default:
slouken@11574
    83
                SDL_assert(0 && "We should never get here (caught above)");
slouken@11574
    84
                break;
slouken@11574
    85
        }
slouken@11574
    86
        swdata->pixels = (Uint8 *) SDL_malloc(dst_size);
slouken@11702
    87
        if (!swdata->pixels) {
slouken@11702
    88
            SDL_SW_DestroyYUVTexture(swdata);
slouken@11702
    89
            SDL_OutOfMemory();
slouken@11702
    90
            return NULL;
slouken@11702
    91
        }
slouken@1895
    92
    }
slouken@1895
    93
slouken@11702
    94
    /* Find the pitch and offset values for the texture */
slouken@2781
    95
    switch (format) {
slouken@1965
    96
    case SDL_PIXELFORMAT_YV12:
slouken@1965
    97
    case SDL_PIXELFORMAT_IYUV:
slouken@2781
    98
        swdata->pitches[0] = w;
slouken@11574
    99
        swdata->pitches[1] = (swdata->pitches[0] + 1) / 2;
slouken@11574
   100
        swdata->pitches[2] = (swdata->pitches[0] + 1) / 2;
slouken@1895
   101
        swdata->planes[0] = swdata->pixels;
slouken@2786
   102
        swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
slouken@11574
   103
        swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * ((h + 1) / 2);
slouken@1895
   104
        break;
slouken@1965
   105
    case SDL_PIXELFORMAT_YUY2:
slouken@1965
   106
    case SDL_PIXELFORMAT_UYVY:
slouken@1965
   107
    case SDL_PIXELFORMAT_YVYU:
slouken@11574
   108
        swdata->pitches[0] = ((w + 1) / 2) * 4;
slouken@1895
   109
        swdata->planes[0] = swdata->pixels;
slouken@1895
   110
        break;
slouken@11574
   111
slouken@11574
   112
    case SDL_PIXELFORMAT_NV12:
slouken@11574
   113
    case SDL_PIXELFORMAT_NV21:
slouken@11574
   114
        swdata->pitches[0] = w;
slouken@11574
   115
        swdata->pitches[1] = 2 * ((swdata->pitches[0] + 1) / 2);
slouken@11574
   116
        swdata->planes[0] = swdata->pixels;
slouken@11574
   117
        swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
slouken@11574
   118
        break;
slouken@11574
   119
slouken@1895
   120
    default:
icculus@7487
   121
        SDL_assert(0 && "We should never get here (caught above)");
slouken@1895
   122
        break;
slouken@1895
   123
    }
slouken@1895
   124
slouken@1895
   125
    /* We're all done.. */
slouken@1895
   126
    return (swdata);
slouken@0
   127
}
slouken@0
   128
slouken@1895
   129
int
slouken@1895
   130
SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture * swdata, void **pixels,
slouken@1895
   131
                             int *pitch)
slouken@0
   132
{
slouken@1895
   133
    *pixels = swdata->planes[0];
slouken@1895
   134
    *pitch = swdata->pitches[0];
slouken@1895
   135
    return 0;
slouken@0
   136
}
slouken@0
   137
slouken@1895
   138
int
slouken@1895
   139
SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
slouken@1895
   140
                        const void *pixels, int pitch)
slouken@0
   141
{
slouken@2781
   142
    switch (swdata->format) {
slouken@1965
   143
    case SDL_PIXELFORMAT_YV12:
slouken@1965
   144
    case SDL_PIXELFORMAT_IYUV:
slouken@6136
   145
        if (rect->x == 0 && rect->y == 0 &&
slouken@6136
   146
            rect->w == swdata->w && rect->h == swdata->h) {
slouken@6136
   147
                SDL_memcpy(swdata->pixels, pixels,
slouken@11574
   148
                           (swdata->h * swdata->w) + 2* ((swdata->h + 1) /2) * ((swdata->w + 1) / 2));
slouken@6136
   149
        } else {
slouken@6136
   150
            Uint8 *src, *dst;
slouken@6136
   151
            int row;
slouken@6136
   152
            size_t length;
slouken@6136
   153
slouken@6136
   154
            /* Copy the Y plane */
slouken@6136
   155
            src = (Uint8 *) pixels;
slouken@6136
   156
            dst = swdata->pixels + rect->y * swdata->w + rect->x;
slouken@6136
   157
            length = rect->w;
slouken@6136
   158
            for (row = 0; row < rect->h; ++row) {
slouken@6136
   159
                SDL_memcpy(dst, src, length);
slouken@6136
   160
                src += pitch;
slouken@6136
   161
                dst += swdata->w;
slouken@6136
   162
            }
slouken@11574
   163
            
slouken@6136
   164
            /* Copy the next plane */
slouken@6136
   165
            src = (Uint8 *) pixels + rect->h * pitch;
slouken@6136
   166
            dst = swdata->pixels + swdata->h * swdata->w;
slouken@11574
   167
            dst += rect->y/2 * ((swdata->w + 1) / 2) + rect->x/2;
slouken@11574
   168
            length = (rect->w + 1) / 2;
slouken@11574
   169
            for (row = 0; row < (rect->h + 1)/2; ++row) {
slouken@6136
   170
                SDL_memcpy(dst, src, length);
slouken@11574
   171
                src += (pitch + 1)/2;
slouken@11574
   172
                dst += (swdata->w + 1)/2;
slouken@6136
   173
            }
slouken@6136
   174
slouken@6136
   175
            /* Copy the next plane */
slouken@11574
   176
            src = (Uint8 *) pixels + rect->h * pitch + ((rect->h + 1) / 2) * ((pitch + 1) / 2);
slouken@6136
   177
            dst = swdata->pixels + swdata->h * swdata->w +
slouken@11574
   178
                  ((swdata->h + 1)/2) * ((swdata->w+1) / 2);
slouken@11574
   179
            dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2;
slouken@11574
   180
            length = (rect->w + 1) / 2;
slouken@11574
   181
            for (row = 0; row < (rect->h + 1)/2; ++row) {
slouken@6136
   182
                SDL_memcpy(dst, src, length);
slouken@11574
   183
                src += (pitch + 1)/2;
slouken@11574
   184
                dst += (swdata->w + 1)/2;
slouken@6136
   185
            }
slouken@1895
   186
        }
slouken@1895
   187
        break;
slouken@1965
   188
    case SDL_PIXELFORMAT_YUY2:
slouken@1965
   189
    case SDL_PIXELFORMAT_UYVY:
slouken@1965
   190
    case SDL_PIXELFORMAT_YVYU:
slouken@1895
   191
        {
slouken@1895
   192
            Uint8 *src, *dst;
slouken@1895
   193
            int row;
slouken@1895
   194
            size_t length;
slouken@0
   195
slouken@1895
   196
            src = (Uint8 *) pixels;
slouken@1895
   197
            dst =
slouken@1895
   198
                swdata->planes[0] + rect->y * swdata->pitches[0] +
slouken@1895
   199
                rect->x * 2;
slouken@11574
   200
            length = 4 * ((rect->w + 1) / 2);
slouken@1895
   201
            for (row = 0; row < rect->h; ++row) {
slouken@1895
   202
                SDL_memcpy(dst, src, length);
slouken@1895
   203
                src += pitch;
slouken@1895
   204
                dst += swdata->pitches[0];
slouken@1895
   205
            }
slouken@1895
   206
        }
slouken@1895
   207
        break;
slouken@11574
   208
    case SDL_PIXELFORMAT_NV12:
slouken@11574
   209
    case SDL_PIXELFORMAT_NV21:
slouken@11574
   210
        {
slouken@11574
   211
            if (rect->x == 0 && rect->y == 0 && rect->w == swdata->w && rect->h == swdata->h) {
slouken@11574
   212
                SDL_memcpy(swdata->pixels, pixels,
slouken@11574
   213
                        (swdata->h * swdata->w) + 2* ((swdata->h + 1) /2) * ((swdata->w + 1) / 2));
slouken@11574
   214
            } else {
slouken@11574
   215
slouken@11574
   216
                Uint8 *src, *dst;
slouken@11574
   217
                int row;
slouken@11574
   218
                size_t length;
slouken@11574
   219
slouken@11574
   220
                /* Copy the Y plane */
slouken@11574
   221
                src = (Uint8 *) pixels;
slouken@11574
   222
                dst = swdata->pixels + rect->y * swdata->w + rect->x;
slouken@11574
   223
                length = rect->w;
slouken@11574
   224
                for (row = 0; row < rect->h; ++row) {
slouken@11574
   225
                    SDL_memcpy(dst, src, length);
slouken@11574
   226
                    src += pitch;
slouken@11574
   227
                    dst += swdata->w;
slouken@11574
   228
                }
slouken@11574
   229
                
slouken@11574
   230
                /* Copy the next plane */
slouken@11574
   231
                src = (Uint8 *) pixels + rect->h * pitch;
slouken@11574
   232
                dst = swdata->pixels + swdata->h * swdata->w;
slouken@11574
   233
                dst += 2 * ((rect->y + 1)/2) * ((swdata->w + 1) / 2) + 2 * (rect->x/2);
slouken@11574
   234
                length = 2 * ((rect->w + 1) / 2);
slouken@11574
   235
                for (row = 0; row < (rect->h + 1)/2; ++row) {
slouken@11574
   236
                    SDL_memcpy(dst, src, length);
slouken@11574
   237
                    src += 2 * ((pitch + 1)/2);
slouken@11574
   238
                    dst += 2 * ((swdata->w + 1)/2);
slouken@11574
   239
                }
slouken@11574
   240
            }
slouken@11574
   241
        }
slouken@1895
   242
    }
slouken@1895
   243
    return 0;
slouken@0
   244
}
slouken@0
   245
slouken@1895
   246
int
slouken@7759
   247
SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
slouken@7759
   248
                              const Uint8 *Yplane, int Ypitch,
slouken@7759
   249
                              const Uint8 *Uplane, int Upitch,
slouken@7759
   250
                              const Uint8 *Vplane, int Vpitch)
slouken@7759
   251
{
slouken@7777
   252
    const Uint8 *src;
slouken@7777
   253
    Uint8 *dst;
slouken@7759
   254
    int row;
slouken@7759
   255
    size_t length;
slouken@7759
   256
slouken@7759
   257
    /* Copy the Y plane */
slouken@7759
   258
    src = Yplane;
slouken@7759
   259
    dst = swdata->pixels + rect->y * swdata->w + rect->x;
slouken@7759
   260
    length = rect->w;
slouken@7759
   261
    for (row = 0; row < rect->h; ++row) {
slouken@7759
   262
        SDL_memcpy(dst, src, length);
slouken@7759
   263
        src += Ypitch;
slouken@7759
   264
        dst += swdata->w;
slouken@7759
   265
    }
slouken@7759
   266
slouken@7759
   267
    /* Copy the U plane */
slouken@7759
   268
    src = Uplane;
slouken@7759
   269
    if (swdata->format == SDL_PIXELFORMAT_IYUV) {
slouken@7759
   270
        dst = swdata->pixels + swdata->h * swdata->w;
slouken@7759
   271
    } else {
slouken@7759
   272
        dst = swdata->pixels + swdata->h * swdata->w +
slouken@11574
   273
              ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
slouken@7759
   274
    }
slouken@11574
   275
    dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2;
slouken@11574
   276
    length = (rect->w + 1) / 2;
slouken@11574
   277
    for (row = 0; row < (rect->h + 1)/2; ++row) {
slouken@7759
   278
        SDL_memcpy(dst, src, length);
slouken@7759
   279
        src += Upitch;
slouken@11574
   280
        dst += (swdata->w + 1)/2;
slouken@7759
   281
    }
slouken@7759
   282
slouken@7759
   283
    /* Copy the V plane */
slouken@7759
   284
    src = Vplane;
slouken@7759
   285
    if (swdata->format == SDL_PIXELFORMAT_YV12) {
slouken@7759
   286
        dst = swdata->pixels + swdata->h * swdata->w;
slouken@7759
   287
    } else {
slouken@7759
   288
        dst = swdata->pixels + swdata->h * swdata->w +
slouken@11574
   289
              ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
slouken@7759
   290
    }
slouken@11574
   291
    dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2;
slouken@11574
   292
    length = (rect->w + 1) / 2;
slouken@11574
   293
    for (row = 0; row < (rect->h + 1)/2; ++row) {
slouken@7759
   294
        SDL_memcpy(dst, src, length);
slouken@7759
   295
        src += Vpitch;
slouken@11574
   296
        dst += (swdata->w + 1)/2;
slouken@7759
   297
    }
slouken@7759
   298
    return 0;
slouken@7759
   299
}
slouken@7759
   300
slouken@7759
   301
int
slouken@1895
   302
SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
slouken@5156
   303
                      void **pixels, int *pitch)
slouken@0
   304
{
slouken@2781
   305
    switch (swdata->format) {
slouken@1965
   306
    case SDL_PIXELFORMAT_YV12:
slouken@1965
   307
    case SDL_PIXELFORMAT_IYUV:
slouken@11574
   308
    case SDL_PIXELFORMAT_NV12:
slouken@11574
   309
    case SDL_PIXELFORMAT_NV21:
slouken@1895
   310
        if (rect
slouken@2781
   311
            && (rect->x != 0 || rect->y != 0 || rect->w != swdata->w
slouken@2781
   312
                || rect->h != swdata->h)) {
icculus@7037
   313
            return SDL_SetError
slouken@11574
   314
                ("YV12, IYUV, NV12, NV21 textures only support full surface locks");
slouken@1895
   315
        }
slouken@1895
   316
        break;
slouken@1895
   317
    }
slouken@1895
   318
slouken@7332
   319
    if (rect) {
slouken@7332
   320
        *pixels = swdata->planes[0] + rect->y * swdata->pitches[0] + rect->x * 2;
slouken@7332
   321
    } else {
slouken@7332
   322
        *pixels = swdata->planes[0];
slouken@7332
   323
    }
slouken@1895
   324
    *pitch = swdata->pitches[0];
slouken@1895
   325
    return 0;
slouken@0
   326
}
slouken@1895
   327
slouken@1895
   328
void
slouken@1895
   329
SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture * swdata)
slouken@1895
   330
{
slouken@1895
   331
}
slouken@1895
   332
slouken@1895
   333
int
slouken@1895
   334
SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect,
slouken@1895
   335
                    Uint32 target_format, int w, int h, void *pixels,
slouken@1895
   336
                    int pitch)
slouken@1895
   337
{
slouken@1895
   338
    int stretch;
icculus@8643
   339
slouken@1895
   340
    /* Make sure we're set up to display in the desired format */
slouken@11702
   341
    if (target_format != swdata->target_format && swdata->display) {
slouken@11702
   342
        SDL_FreeSurface(swdata->display);
slouken@11702
   343
        swdata->display = NULL;
slouken@1895
   344
    }
slouken@1895
   345
slouken@1895
   346
    stretch = 0;
slouken@11702
   347
    if (srcrect->x || srcrect->y || srcrect->w < swdata->w || srcrect->h < swdata->h) {
slouken@1895
   348
        /* The source rectangle has been clipped.
slouken@1895
   349
           Using a scratch surface is easier than adding clipped
slouken@1895
   350
           source support to all the blitters, plus that would
slouken@1895
   351
           slow them down in the general unclipped case.
slouken@1895
   352
         */
slouken@1895
   353
        stretch = 1;
slouken@1895
   354
    } else if ((srcrect->w != w) || (srcrect->h != h)) {
slouken@11702
   355
        stretch = 1;
slouken@1895
   356
    }
slouken@1895
   357
    if (stretch) {
slouken@1895
   358
        int bpp;
slouken@1895
   359
        Uint32 Rmask, Gmask, Bmask, Amask;
slouken@1895
   360
slouken@1895
   361
        if (swdata->display) {
slouken@1895
   362
            swdata->display->w = w;
slouken@1895
   363
            swdata->display->h = h;
slouken@1895
   364
            swdata->display->pixels = pixels;
slouken@1895
   365
            swdata->display->pitch = pitch;
slouken@1895
   366
        } else {
slouken@1895
   367
            /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */
slouken@1895
   368
            SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask,
slouken@1895
   369
                                       &Bmask, &Amask);
slouken@1895
   370
            swdata->display =
slouken@1895
   371
                SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask,
slouken@1895
   372
                                         Gmask, Bmask, Amask);
slouken@1895
   373
            if (!swdata->display) {
slouken@1895
   374
                return (-1);
slouken@1895
   375
            }
slouken@1895
   376
        }
slouken@1895
   377
        if (!swdata->stretch) {
slouken@1895
   378
            /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */
slouken@1895
   379
            SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask,
slouken@1895
   380
                                       &Bmask, &Amask);
slouken@1895
   381
            swdata->stretch =
slouken@2781
   382
                SDL_CreateRGBSurface(0, swdata->w, swdata->h, bpp, Rmask,
slouken@1895
   383
                                     Gmask, Bmask, Amask);
slouken@1895
   384
            if (!swdata->stretch) {
slouken@1895
   385
                return (-1);
slouken@1895
   386
            }
slouken@1895
   387
        }
slouken@1895
   388
        pixels = swdata->stretch->pixels;
slouken@1895
   389
        pitch = swdata->stretch->pitch;
slouken@1895
   390
    }
slouken@11702
   391
    if (SDL_ConvertPixels(swdata->w, swdata->h, swdata->format,
slouken@11702
   392
                          swdata->planes[0], swdata->pitches[0], 
slouken@11702
   393
                          target_format, pixels, pitch) < 0) {
slouken@11702
   394
        return -1;
slouken@1895
   395
    }
slouken@1895
   396
    if (stretch) {
slouken@1895
   397
        SDL_Rect rect = *srcrect;
slouken@1895
   398
        SDL_SoftStretch(swdata->stretch, &rect, swdata->display, NULL);
slouken@1895
   399
    }
slouken@1895
   400
    return 0;
slouken@1895
   401
}
slouken@1895
   402
slouken@1895
   403
void
slouken@1895
   404
SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata)
slouken@1895
   405
{
slouken@1895
   406
    if (swdata) {
slouken@7719
   407
        SDL_free(swdata->pixels);
slouken@7720
   408
        SDL_FreeSurface(swdata->stretch);
slouken@7720
   409
        SDL_FreeSurface(swdata->display);
slouken@1895
   410
        SDL_free(swdata);
slouken@1895
   411
    }
slouken@1895
   412
}
slouken@1895
   413
slouken@1895
   414
/* vi: set ts=4 sw=4 expandtab: */