src/video/SDL_yuv_sw.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 17 Apr 2006 06:47:23 +0000
changeset 1643 51038e80ae59
parent 1428 5f52867ba65c
child 1644 8a858076f39d
permissions -rw-r--r--
More general fix for bug #189

The clipping is done at a higher level, and the low level functions are
passed clipped rectangles. Drivers which don't support source clipping
have not been changed, so the image will be squished instead of clipped,
but at least they will no longer crash when the destination rect was out
of bounds.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@0
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@0
    23
slouken@0
    24
/* This is the software implementation of the YUV video overlay support */
slouken@0
    25
slouken@0
    26
/* This code was derived from code carrying the following copyright notices:
slouken@0
    27
slouken@0
    28
 * Copyright (c) 1995 The Regents of the University of California.
slouken@0
    29
 * All rights reserved.
slouken@0
    30
 * 
slouken@0
    31
 * Permission to use, copy, modify, and distribute this software and its
slouken@0
    32
 * documentation for any purpose, without fee, and without written agreement is
slouken@0
    33
 * hereby granted, provided that the above copyright notice and the following
slouken@0
    34
 * two paragraphs appear in all copies of this software.
slouken@0
    35
 * 
slouken@0
    36
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
slouken@0
    37
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
slouken@0
    38
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
slouken@0
    39
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
slouken@0
    40
 * 
slouken@0
    41
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
slouken@0
    42
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
slouken@0
    43
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
slouken@0
    44
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
slouken@0
    45
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
slouken@0
    46
slouken@0
    47
 * Copyright (c) 1995 Erik Corry
slouken@0
    48
 * All rights reserved.
slouken@0
    49
 * 
slouken@0
    50
 * Permission to use, copy, modify, and distribute this software and its
slouken@0
    51
 * documentation for any purpose, without fee, and without written agreement is
slouken@0
    52
 * hereby granted, provided that the above copyright notice and the following
slouken@0
    53
 * two paragraphs appear in all copies of this software.
slouken@0
    54
 * 
slouken@0
    55
 * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
slouken@0
    56
 * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
slouken@0
    57
 * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED
slouken@0
    58
 * OF THE POSSIBILITY OF SUCH DAMAGE.
slouken@0
    59
 * 
slouken@0
    60
 * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
slouken@0
    61
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
slouken@0
    62
 * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
slouken@0
    63
 * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
slouken@0
    64
 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
slouken@0
    65
slouken@0
    66
 * Portions of this software Copyright (c) 1995 Brown University.
slouken@0
    67
 * All rights reserved.
slouken@0
    68
 * 
slouken@0
    69
 * Permission to use, copy, modify, and distribute this software and its
slouken@0
    70
 * documentation for any purpose, without fee, and without written agreement
slouken@0
    71
 * is hereby granted, provided that the above copyright notice and the
slouken@0
    72
 * following two paragraphs appear in all copies of this software.
slouken@0
    73
 * 
slouken@0
    74
 * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR
slouken@0
    75
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
slouken@0
    76
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN
slouken@0
    77
 * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
slouken@0
    78
 * 
slouken@0
    79
 * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
slouken@0
    80
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
slouken@0
    81
 * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
slouken@0
    82
 * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
slouken@0
    83
 * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
slouken@0
    84
 */
slouken@0
    85
slouken@0
    86
#include "SDL_video.h"
slouken@739
    87
#include "SDL_cpuinfo.h"
slouken@0
    88
#include "SDL_stretch_c.h"
slouken@0
    89
#include "SDL_yuvfuncs.h"
slouken@0
    90
#include "SDL_yuv_sw_c.h"
slouken@0
    91
slouken@0
    92
/* The functions used to manipulate software video overlays */
slouken@0
    93
static struct private_yuvhwfuncs sw_yuvfuncs = {
slouken@0
    94
	SDL_LockYUV_SW,
slouken@0
    95
	SDL_UnlockYUV_SW,
slouken@0
    96
	SDL_DisplayYUV_SW,
slouken@0
    97
	SDL_FreeYUV_SW
slouken@0
    98
};
slouken@0
    99
slouken@0
   100
/* RGB conversion lookup tables */
slouken@0
   101
struct private_yuvhwdata {
slouken@0
   102
	SDL_Surface *stretch;
slouken@0
   103
	SDL_Surface *display;
slouken@0
   104
	Uint8 *pixels;
slouken@0
   105
	int *colortab;
slouken@0
   106
	Uint32 *rgb_2_pix;
slouken@0
   107
	void (*Display1X)(int *colortab, Uint32 *rgb_2_pix,
slouken@0
   108
                          unsigned char *lum, unsigned char *cr,
slouken@0
   109
                          unsigned char *cb, unsigned char *out,
slouken@0
   110
                          int rows, int cols, int mod );
slouken@0
   111
	void (*Display2X)(int *colortab, Uint32 *rgb_2_pix,
slouken@0
   112
	                  unsigned char *lum, unsigned char *cr,
slouken@0
   113
                          unsigned char *cb, unsigned char *out,
slouken@0
   114
                          int rows, int cols, int mod );
slouken@0
   115
slouken@0
   116
	/* These are just so we don't have to allocate them separately */
slouken@0
   117
	Uint16 pitches[3];
slouken@0
   118
	Uint8 *planes[3];
slouken@0
   119
};
slouken@0
   120
slouken@0
   121
slouken@0
   122
/* The colorspace conversion functions */
slouken@0
   123
slouken@1413
   124
#if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/
slouken@0
   125
extern void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   126
                                     unsigned char *lum, unsigned char *cr,
slouken@0
   127
                                     unsigned char *cb, unsigned char *out,
slouken@0
   128
                                     int rows, int cols, int mod );
slouken@0
   129
extern void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   130
                                     unsigned char *lum, unsigned char *cr,
slouken@0
   131
                                     unsigned char *cb, unsigned char *out,
slouken@0
   132
                                     int rows, int cols, int mod );
slouken@1413
   133
#endif 
slouken@0
   134
slouken@0
   135
static void Color16DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   136
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   137
                                    unsigned char *cb, unsigned char *out,
slouken@0
   138
                                    int rows, int cols, int mod )
slouken@0
   139
{
slouken@0
   140
    unsigned short* row1;
slouken@0
   141
    unsigned short* row2;
slouken@0
   142
    unsigned char* lum2;
slouken@0
   143
    int x, y;
slouken@0
   144
    int cr_r;
slouken@0
   145
    int crb_g;
slouken@0
   146
    int cb_b;
slouken@0
   147
    int cols_2 = cols / 2;
slouken@0
   148
slouken@0
   149
    row1 = (unsigned short*) out;
slouken@0
   150
    row2 = row1 + cols + mod;
slouken@0
   151
    lum2 = lum + cols;
slouken@0
   152
slouken@0
   153
    mod += cols + mod;
slouken@0
   154
slouken@0
   155
    y = rows / 2;
slouken@0
   156
    while( y-- )
slouken@0
   157
    {
slouken@0
   158
        x = cols_2;
slouken@0
   159
        while( x-- )
slouken@0
   160
        {
slouken@0
   161
            register int L;
slouken@0
   162
slouken@0
   163
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   164
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   165
                               + colortab[ *cb + 2*256 ];
slouken@0
   166
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   167
            ++cr; ++cb;
slouken@0
   168
slouken@0
   169
            L = *lum++;
slouken@1428
   170
            *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
slouken@1428
   171
                                       rgb_2_pix[ L + crb_g ] |
slouken@1428
   172
                                       rgb_2_pix[ L + cb_b ]);
slouken@0
   173
slouken@0
   174
            L = *lum++;
slouken@1428
   175
            *row1++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
slouken@1428
   176
                                       rgb_2_pix[ L + crb_g ] |
slouken@1428
   177
                                       rgb_2_pix[ L + cb_b ]);
slouken@0
   178
slouken@0
   179
slouken@0
   180
            /* Now, do second row.  */
slouken@0
   181
slouken@0
   182
            L = *lum2++;
slouken@1428
   183
            *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
slouken@1428
   184
                                       rgb_2_pix[ L + crb_g ] |
slouken@1428
   185
                                       rgb_2_pix[ L + cb_b ]);
slouken@0
   186
slouken@0
   187
            L = *lum2++;
slouken@1428
   188
            *row2++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
slouken@1428
   189
                                       rgb_2_pix[ L + crb_g ] |
slouken@1428
   190
                                       rgb_2_pix[ L + cb_b ]);
slouken@0
   191
        }
slouken@0
   192
slouken@0
   193
        /*
slouken@0
   194
         * These values are at the start of the next line, (due
slouken@0
   195
         * to the ++'s above),but they need to be at the start
slouken@0
   196
         * of the line after that.
slouken@0
   197
         */
slouken@0
   198
        lum  += cols;
slouken@0
   199
        lum2 += cols;
slouken@0
   200
        row1 += mod;
slouken@0
   201
        row2 += mod;
slouken@0
   202
    }
slouken@0
   203
}
slouken@0
   204
slouken@0
   205
static void Color24DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   206
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   207
                                    unsigned char *cb, unsigned char *out,
slouken@0
   208
                                    int rows, int cols, int mod )
slouken@0
   209
{
slouken@0
   210
    unsigned int value;
slouken@0
   211
    unsigned char* row1;
slouken@0
   212
    unsigned char* row2;
slouken@0
   213
    unsigned char* lum2;
slouken@0
   214
    int x, y;
slouken@0
   215
    int cr_r;
slouken@0
   216
    int crb_g;
slouken@0
   217
    int cb_b;
slouken@0
   218
    int cols_2 = cols / 2;
slouken@0
   219
slouken@0
   220
    row1 = out;
slouken@0
   221
    row2 = row1 + cols*3 + mod*3;
slouken@0
   222
    lum2 = lum + cols;
slouken@0
   223
slouken@0
   224
    mod += cols + mod;
slouken@0
   225
    mod *= 3;
slouken@0
   226
slouken@0
   227
    y = rows / 2;
slouken@0
   228
    while( y-- )
slouken@0
   229
    {
slouken@0
   230
        x = cols_2;
slouken@0
   231
        while( x-- )
slouken@0
   232
        {
slouken@0
   233
            register int L;
slouken@0
   234
slouken@0
   235
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   236
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   237
                               + colortab[ *cb + 2*256 ];
slouken@0
   238
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   239
            ++cr; ++cb;
slouken@0
   240
slouken@0
   241
            L = *lum++;
slouken@0
   242
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   243
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   244
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   245
            *row1++ = (value      ) & 0xFF;
slouken@0
   246
            *row1++ = (value >>  8) & 0xFF;
slouken@0
   247
            *row1++ = (value >> 16) & 0xFF;
slouken@0
   248
slouken@0
   249
            L = *lum++;
slouken@0
   250
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   251
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   252
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   253
            *row1++ = (value      ) & 0xFF;
slouken@0
   254
            *row1++ = (value >>  8) & 0xFF;
slouken@0
   255
            *row1++ = (value >> 16) & 0xFF;
slouken@0
   256
slouken@0
   257
slouken@0
   258
            /* Now, do second row.  */
slouken@0
   259
slouken@0
   260
            L = *lum2++;
slouken@0
   261
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   262
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   263
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   264
            *row2++ = (value      ) & 0xFF;
slouken@0
   265
            *row2++ = (value >>  8) & 0xFF;
slouken@0
   266
            *row2++ = (value >> 16) & 0xFF;
slouken@0
   267
slouken@0
   268
            L = *lum2++;
slouken@0
   269
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   270
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   271
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   272
            *row2++ = (value      ) & 0xFF;
slouken@0
   273
            *row2++ = (value >>  8) & 0xFF;
slouken@0
   274
            *row2++ = (value >> 16) & 0xFF;
slouken@0
   275
        }
slouken@0
   276
slouken@0
   277
        /*
slouken@0
   278
         * These values are at the start of the next line, (due
slouken@0
   279
         * to the ++'s above),but they need to be at the start
slouken@0
   280
         * of the line after that.
slouken@0
   281
         */
slouken@0
   282
        lum  += cols;
slouken@0
   283
        lum2 += cols;
slouken@0
   284
        row1 += mod;
slouken@0
   285
        row2 += mod;
slouken@0
   286
    }
slouken@0
   287
}
slouken@0
   288
slouken@0
   289
static void Color32DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   290
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   291
                                    unsigned char *cb, unsigned char *out,
slouken@0
   292
                                    int rows, int cols, int mod )
slouken@0
   293
{
slouken@0
   294
    unsigned int* row1;
slouken@0
   295
    unsigned int* row2;
slouken@0
   296
    unsigned char* lum2;
slouken@0
   297
    int x, y;
slouken@0
   298
    int cr_r;
slouken@0
   299
    int crb_g;
slouken@0
   300
    int cb_b;
slouken@0
   301
    int cols_2 = cols / 2;
slouken@0
   302
slouken@0
   303
    row1 = (unsigned int*) out;
slouken@0
   304
    row2 = row1 + cols + mod;
slouken@0
   305
    lum2 = lum + cols;
slouken@0
   306
slouken@0
   307
    mod += cols + mod;
slouken@0
   308
slouken@0
   309
    y = rows / 2;
slouken@0
   310
    while( y-- )
slouken@0
   311
    {
slouken@0
   312
        x = cols_2;
slouken@0
   313
        while( x-- )
slouken@0
   314
        {
slouken@0
   315
            register int L;
slouken@0
   316
slouken@0
   317
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   318
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   319
                               + colortab[ *cb + 2*256 ];
slouken@0
   320
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   321
            ++cr; ++cb;
slouken@0
   322
slouken@0
   323
            L = *lum++;
slouken@0
   324
            *row1++ = (rgb_2_pix[ L + cr_r ] |
slouken@0
   325
                       rgb_2_pix[ L + crb_g ] |
slouken@0
   326
                       rgb_2_pix[ L + cb_b ]);
slouken@0
   327
slouken@0
   328
            L = *lum++;
slouken@0
   329
            *row1++ = (rgb_2_pix[ L + cr_r ] |
slouken@0
   330
                       rgb_2_pix[ L + crb_g ] |
slouken@0
   331
                       rgb_2_pix[ L + cb_b ]);
slouken@0
   332
slouken@0
   333
slouken@0
   334
            /* Now, do second row.  */
slouken@0
   335
slouken@0
   336
            L = *lum2++;
slouken@0
   337
            *row2++ = (rgb_2_pix[ L + cr_r ] |
slouken@0
   338
                       rgb_2_pix[ L + crb_g ] |
slouken@0
   339
                       rgb_2_pix[ L + cb_b ]);
slouken@0
   340
slouken@0
   341
            L = *lum2++;
slouken@0
   342
            *row2++ = (rgb_2_pix[ L + cr_r ] |
slouken@0
   343
                       rgb_2_pix[ L + crb_g ] |
slouken@0
   344
                       rgb_2_pix[ L + cb_b ]);
slouken@0
   345
        }
slouken@0
   346
slouken@0
   347
        /*
slouken@0
   348
         * These values are at the start of the next line, (due
slouken@0
   349
         * to the ++'s above),but they need to be at the start
slouken@0
   350
         * of the line after that.
slouken@0
   351
         */
slouken@0
   352
        lum  += cols;
slouken@0
   353
        lum2 += cols;
slouken@0
   354
        row1 += mod;
slouken@0
   355
        row2 += mod;
slouken@0
   356
    }
slouken@0
   357
}
slouken@0
   358
slouken@0
   359
/*
slouken@0
   360
 * In this function I make use of a nasty trick. The tables have the lower
slouken@0
   361
 * 16 bits replicated in the upper 16. This means I can write ints and get
slouken@0
   362
 * the horisontal doubling for free (almost).
slouken@0
   363
 */
slouken@0
   364
static void Color16DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   365
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   366
                                    unsigned char *cb, unsigned char *out,
slouken@0
   367
                                    int rows, int cols, int mod )
slouken@0
   368
{
slouken@0
   369
    unsigned int* row1 = (unsigned int*) out;
slouken@0
   370
    const int next_row = cols+(mod/2);
slouken@0
   371
    unsigned int* row2 = row1 + 2*next_row;
slouken@0
   372
    unsigned char* lum2;
slouken@0
   373
    int x, y;
slouken@0
   374
    int cr_r;
slouken@0
   375
    int crb_g;
slouken@0
   376
    int cb_b;
slouken@0
   377
    int cols_2 = cols / 2;
slouken@0
   378
slouken@0
   379
    lum2 = lum + cols;
slouken@0
   380
slouken@0
   381
    mod = (next_row * 3) + (mod/2);
slouken@0
   382
slouken@0
   383
    y = rows / 2;
slouken@0
   384
    while( y-- )
slouken@0
   385
    {
slouken@0
   386
        x = cols_2;
slouken@0
   387
        while( x-- )
slouken@0
   388
        {
slouken@0
   389
            register int L;
slouken@0
   390
slouken@0
   391
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   392
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   393
                               + colortab[ *cb + 2*256 ];
slouken@0
   394
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   395
            ++cr; ++cb;
slouken@0
   396
slouken@0
   397
            L = *lum++;
slouken@0
   398
            row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] |
slouken@0
   399
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   400
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   401
            row1++;
slouken@0
   402
slouken@0
   403
            L = *lum++;
slouken@0
   404
            row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] |
slouken@0
   405
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   406
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   407
            row1++;
slouken@0
   408
slouken@0
   409
slouken@0
   410
            /* Now, do second row. */
slouken@0
   411
slouken@0
   412
            L = *lum2++;
slouken@0
   413
            row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] |
slouken@0
   414
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   415
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   416
            row2++;
slouken@0
   417
slouken@0
   418
            L = *lum2++;
slouken@0
   419
            row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] |
slouken@0
   420
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   421
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   422
            row2++;
slouken@0
   423
        }
slouken@0
   424
slouken@0
   425
        /*
slouken@0
   426
         * These values are at the start of the next line, (due
slouken@0
   427
         * to the ++'s above),but they need to be at the start
slouken@0
   428
         * of the line after that.
slouken@0
   429
         */
slouken@0
   430
        lum  += cols;
slouken@0
   431
        lum2 += cols;
slouken@0
   432
        row1 += mod;
slouken@0
   433
        row2 += mod;
slouken@0
   434
    }
slouken@0
   435
}
slouken@0
   436
slouken@0
   437
static void Color24DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   438
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   439
                                    unsigned char *cb, unsigned char *out,
slouken@0
   440
                                    int rows, int cols, int mod )
slouken@0
   441
{
slouken@0
   442
    unsigned int value;
slouken@0
   443
    unsigned char* row1 = out;
slouken@0
   444
    const int next_row = (cols*2 + mod) * 3;
slouken@0
   445
    unsigned char* row2 = row1 + 2*next_row;
slouken@0
   446
    unsigned char* lum2;
slouken@0
   447
    int x, y;
slouken@0
   448
    int cr_r;
slouken@0
   449
    int crb_g;
slouken@0
   450
    int cb_b;
slouken@0
   451
    int cols_2 = cols / 2;
slouken@0
   452
slouken@0
   453
    lum2 = lum + cols;
slouken@0
   454
slouken@0
   455
    mod = next_row*3 + mod*3;
slouken@0
   456
slouken@0
   457
    y = rows / 2;
slouken@0
   458
    while( y-- )
slouken@0
   459
    {
slouken@0
   460
        x = cols_2;
slouken@0
   461
        while( x-- )
slouken@0
   462
        {
slouken@0
   463
            register int L;
slouken@0
   464
slouken@0
   465
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   466
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   467
                               + colortab[ *cb + 2*256 ];
slouken@0
   468
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   469
            ++cr; ++cb;
slouken@0
   470
slouken@0
   471
            L = *lum++;
slouken@0
   472
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   473
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   474
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   475
            row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] =
slouken@0
   476
                     (value      ) & 0xFF;
slouken@0
   477
            row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] =
slouken@0
   478
                     (value >>  8) & 0xFF;
slouken@0
   479
            row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] =
slouken@0
   480
                     (value >> 16) & 0xFF;
slouken@0
   481
            row1 += 2*3;
slouken@0
   482
slouken@0
   483
            L = *lum++;
slouken@0
   484
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   485
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   486
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   487
            row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] =
slouken@0
   488
                     (value      ) & 0xFF;
slouken@0
   489
            row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] =
slouken@0
   490
                     (value >>  8) & 0xFF;
slouken@0
   491
            row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] =
slouken@0
   492
                     (value >> 16) & 0xFF;
slouken@0
   493
            row1 += 2*3;
slouken@0
   494
slouken@0
   495
slouken@0
   496
            /* Now, do second row. */
slouken@0
   497
slouken@0
   498
            L = *lum2++;
slouken@0
   499
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   500
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   501
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   502
            row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] =
slouken@0
   503
                     (value      ) & 0xFF;
slouken@0
   504
            row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] =
slouken@0
   505
                     (value >>  8) & 0xFF;
slouken@0
   506
            row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] =
slouken@0
   507
                     (value >> 16) & 0xFF;
slouken@0
   508
            row2 += 2*3;
slouken@0
   509
slouken@0
   510
            L = *lum2++;
slouken@0
   511
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   512
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   513
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   514
            row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] =
slouken@0
   515
                     (value      ) & 0xFF;
slouken@0
   516
            row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] =
slouken@0
   517
                     (value >>  8) & 0xFF;
slouken@0
   518
            row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] =
slouken@0
   519
                     (value >> 16) & 0xFF;
slouken@0
   520
            row2 += 2*3;
slouken@0
   521
        }
slouken@0
   522
slouken@0
   523
        /*
slouken@0
   524
         * These values are at the start of the next line, (due
slouken@0
   525
         * to the ++'s above),but they need to be at the start
slouken@0
   526
         * of the line after that.
slouken@0
   527
         */
slouken@0
   528
        lum  += cols;
slouken@0
   529
        lum2 += cols;
slouken@0
   530
        row1 += mod;
slouken@0
   531
        row2 += mod;
slouken@0
   532
    }
slouken@0
   533
}
slouken@0
   534
slouken@0
   535
static void Color32DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   536
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   537
                                    unsigned char *cb, unsigned char *out,
slouken@0
   538
                                    int rows, int cols, int mod )
slouken@0
   539
{
slouken@0
   540
    unsigned int* row1 = (unsigned int*) out;
slouken@0
   541
    const int next_row = cols*2+mod;
slouken@0
   542
    unsigned int* row2 = row1 + 2*next_row;
slouken@0
   543
    unsigned char* lum2;
slouken@0
   544
    int x, y;
slouken@0
   545
    int cr_r;
slouken@0
   546
    int crb_g;
slouken@0
   547
    int cb_b;
slouken@0
   548
    int cols_2 = cols / 2;
slouken@0
   549
slouken@0
   550
    lum2 = lum + cols;
slouken@0
   551
slouken@0
   552
    mod = (next_row * 3) + mod;
slouken@0
   553
slouken@0
   554
    y = rows / 2;
slouken@0
   555
    while( y-- )
slouken@0
   556
    {
slouken@0
   557
        x = cols_2;
slouken@0
   558
        while( x-- )
slouken@0
   559
        {
slouken@0
   560
            register int L;
slouken@0
   561
slouken@0
   562
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   563
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   564
                               + colortab[ *cb + 2*256 ];
slouken@0
   565
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   566
            ++cr; ++cb;
slouken@0
   567
slouken@0
   568
            L = *lum++;
slouken@0
   569
            row1[0] = row1[1] = row1[next_row] = row1[next_row+1] =
slouken@0
   570
                                       (rgb_2_pix[ L + cr_r ] |
slouken@0
   571
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   572
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   573
            row1 += 2;
slouken@0
   574
slouken@0
   575
            L = *lum++;
slouken@0
   576
            row1[0] = row1[1] = row1[next_row] = row1[next_row+1] =
slouken@0
   577
                                       (rgb_2_pix[ L + cr_r ] |
slouken@0
   578
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   579
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   580
            row1 += 2;
slouken@0
   581
slouken@0
   582
slouken@0
   583
            /* Now, do second row. */
slouken@0
   584
slouken@0
   585
            L = *lum2++;
slouken@0
   586
            row2[0] = row2[1] = row2[next_row] = row2[next_row+1] =
slouken@0
   587
                                       (rgb_2_pix[ L + cr_r ] |
slouken@0
   588
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   589
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   590
            row2 += 2;
slouken@0
   591
slouken@0
   592
            L = *lum2++;
slouken@0
   593
            row2[0] = row2[1] = row2[next_row] = row2[next_row+1] =
slouken@0
   594
                                       (rgb_2_pix[ L + cr_r ] |
slouken@0
   595
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   596
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   597
            row2 += 2;
slouken@0
   598
        }
slouken@0
   599
slouken@0
   600
        /*
slouken@0
   601
         * These values are at the start of the next line, (due
slouken@0
   602
         * to the ++'s above),but they need to be at the start
slouken@0
   603
         * of the line after that.
slouken@0
   604
         */
slouken@0
   605
        lum  += cols;
slouken@0
   606
        lum2 += cols;
slouken@0
   607
        row1 += mod;
slouken@0
   608
        row2 += mod;
slouken@0
   609
    }
slouken@0
   610
}
slouken@0
   611
slouken@0
   612
static void Color16DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   613
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   614
                                    unsigned char *cb, unsigned char *out,
slouken@0
   615
                                    int rows, int cols, int mod )
slouken@0
   616
{
slouken@0
   617
    unsigned short* row;
slouken@0
   618
    int x, y;
slouken@0
   619
    int cr_r;
slouken@0
   620
    int crb_g;
slouken@0
   621
    int cb_b;
slouken@0
   622
    int cols_2 = cols / 2;
slouken@0
   623
slouken@0
   624
    row = (unsigned short*) out;
slouken@0
   625
slouken@0
   626
    y = rows;
slouken@0
   627
    while( y-- )
slouken@0
   628
    {
slouken@0
   629
        x = cols_2;
slouken@0
   630
        while( x-- )
slouken@0
   631
        {
slouken@0
   632
            register int L;
slouken@0
   633
slouken@0
   634
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   635
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   636
                               + colortab[ *cb + 2*256 ];
slouken@0
   637
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   638
            cr += 4; cb += 4;
slouken@0
   639
slouken@0
   640
            L = *lum; lum += 2;
slouken@1428
   641
            *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
slouken@1428
   642
                                      rgb_2_pix[ L + crb_g ] |
slouken@1428
   643
                                      rgb_2_pix[ L + cb_b ]);
slouken@0
   644
slouken@0
   645
            L = *lum; lum += 2;
slouken@1428
   646
            *row++ = (unsigned short)(rgb_2_pix[ L + cr_r ] |
slouken@1428
   647
                                      rgb_2_pix[ L + crb_g ] |
slouken@1428
   648
                                      rgb_2_pix[ L + cb_b ]);
slouken@0
   649
slouken@0
   650
        }
slouken@0
   651
slouken@0
   652
        row += mod;
slouken@0
   653
    }
slouken@0
   654
}
slouken@0
   655
slouken@0
   656
static void Color24DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   657
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   658
                                    unsigned char *cb, unsigned char *out,
slouken@0
   659
                                    int rows, int cols, int mod )
slouken@0
   660
{
slouken@0
   661
    unsigned int value;
slouken@0
   662
    unsigned char* row;
slouken@0
   663
    int x, y;
slouken@0
   664
    int cr_r;
slouken@0
   665
    int crb_g;
slouken@0
   666
    int cb_b;
slouken@0
   667
    int cols_2 = cols / 2;
slouken@0
   668
slouken@0
   669
    row = (unsigned char*) out;
slouken@0
   670
    mod *= 3;
slouken@0
   671
    y = rows;
slouken@0
   672
    while( y-- )
slouken@0
   673
    {
slouken@0
   674
        x = cols_2;
slouken@0
   675
        while( x-- )
slouken@0
   676
        {
slouken@0
   677
            register int L;
slouken@0
   678
slouken@0
   679
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   680
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   681
                               + colortab[ *cb + 2*256 ];
slouken@0
   682
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   683
            cr += 4; cb += 4;
slouken@0
   684
slouken@0
   685
            L = *lum; lum += 2;
slouken@0
   686
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   687
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   688
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   689
            *row++ = (value      ) & 0xFF;
slouken@0
   690
            *row++ = (value >>  8) & 0xFF;
slouken@0
   691
            *row++ = (value >> 16) & 0xFF;
slouken@0
   692
slouken@0
   693
            L = *lum; lum += 2;
slouken@0
   694
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   695
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   696
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   697
            *row++ = (value      ) & 0xFF;
slouken@0
   698
            *row++ = (value >>  8) & 0xFF;
slouken@0
   699
            *row++ = (value >> 16) & 0xFF;
slouken@0
   700
slouken@0
   701
        }
slouken@0
   702
        row += mod;
slouken@0
   703
    }
slouken@0
   704
}
slouken@0
   705
slouken@0
   706
static void Color32DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   707
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   708
                                    unsigned char *cb, unsigned char *out,
slouken@0
   709
                                    int rows, int cols, int mod )
slouken@0
   710
{
slouken@0
   711
    unsigned int* row;
slouken@0
   712
    int x, y;
slouken@0
   713
    int cr_r;
slouken@0
   714
    int crb_g;
slouken@0
   715
    int cb_b;
slouken@0
   716
    int cols_2 = cols / 2;
slouken@0
   717
slouken@0
   718
    row = (unsigned int*) out;
slouken@0
   719
    y = rows;
slouken@0
   720
    while( y-- )
slouken@0
   721
    {
slouken@0
   722
        x = cols_2;
slouken@0
   723
        while( x-- )
slouken@0
   724
        {
slouken@0
   725
            register int L;
slouken@0
   726
slouken@0
   727
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   728
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   729
                               + colortab[ *cb + 2*256 ];
slouken@0
   730
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   731
            cr += 4; cb += 4;
slouken@0
   732
slouken@0
   733
            L = *lum; lum += 2;
slouken@0
   734
            *row++ = (rgb_2_pix[ L + cr_r ] |
slouken@0
   735
                       rgb_2_pix[ L + crb_g ] |
slouken@0
   736
                       rgb_2_pix[ L + cb_b ]);
slouken@0
   737
slouken@0
   738
            L = *lum; lum += 2;
slouken@0
   739
            *row++ = (rgb_2_pix[ L + cr_r ] |
slouken@0
   740
                       rgb_2_pix[ L + crb_g ] |
slouken@0
   741
                       rgb_2_pix[ L + cb_b ]);
slouken@0
   742
slouken@0
   743
slouken@0
   744
        }
slouken@0
   745
        row += mod;
slouken@0
   746
    }
slouken@0
   747
}
slouken@0
   748
slouken@0
   749
/*
slouken@0
   750
 * In this function I make use of a nasty trick. The tables have the lower
slouken@0
   751
 * 16 bits replicated in the upper 16. This means I can write ints and get
slouken@0
   752
 * the horisontal doubling for free (almost).
slouken@0
   753
 */
slouken@0
   754
static void Color16DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   755
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   756
                                    unsigned char *cb, unsigned char *out,
slouken@0
   757
                                    int rows, int cols, int mod )
slouken@0
   758
{
slouken@0
   759
    unsigned int* row = (unsigned int*) out;
slouken@0
   760
    const int next_row = cols+(mod/2);
slouken@0
   761
    int x, y;
slouken@0
   762
    int cr_r;
slouken@0
   763
    int crb_g;
slouken@0
   764
    int cb_b;
slouken@0
   765
    int cols_2 = cols / 2;
slouken@0
   766
slouken@0
   767
    y = rows;
slouken@0
   768
    while( y-- )
slouken@0
   769
    {
slouken@0
   770
        x = cols_2;
slouken@0
   771
        while( x-- )
slouken@0
   772
        {
slouken@0
   773
            register int L;
slouken@0
   774
slouken@0
   775
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   776
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   777
                               + colortab[ *cb + 2*256 ];
slouken@0
   778
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   779
            cr += 4; cb += 4;
slouken@0
   780
slouken@0
   781
            L = *lum; lum += 2;
slouken@0
   782
            row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] |
slouken@0
   783
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   784
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   785
            row++;
slouken@0
   786
slouken@0
   787
            L = *lum; lum += 2;
slouken@0
   788
            row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] |
slouken@0
   789
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   790
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   791
            row++;
slouken@0
   792
slouken@0
   793
        }
slouken@0
   794
        row += next_row;
slouken@0
   795
    }
slouken@0
   796
}
slouken@0
   797
slouken@0
   798
static void Color24DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   799
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   800
                                    unsigned char *cb, unsigned char *out,
slouken@0
   801
                                    int rows, int cols, int mod )
slouken@0
   802
{
slouken@0
   803
    unsigned int value;
slouken@0
   804
    unsigned char* row = out;
slouken@0
   805
    const int next_row = (cols*2 + mod) * 3;
slouken@0
   806
    int x, y;
slouken@0
   807
    int cr_r;
slouken@0
   808
    int crb_g;
slouken@0
   809
    int cb_b;
slouken@0
   810
    int cols_2 = cols / 2;
slouken@0
   811
    y = rows;
slouken@0
   812
    while( y-- )
slouken@0
   813
    {
slouken@0
   814
        x = cols_2;
slouken@0
   815
        while( x-- )
slouken@0
   816
        {
slouken@0
   817
            register int L;
slouken@0
   818
slouken@0
   819
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   820
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   821
                               + colortab[ *cb + 2*256 ];
slouken@0
   822
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   823
            cr += 4; cb += 4;
slouken@0
   824
slouken@0
   825
            L = *lum; lum += 2;
slouken@0
   826
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   827
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   828
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   829
            row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] =
slouken@0
   830
                     (value      ) & 0xFF;
slouken@0
   831
            row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] =
slouken@0
   832
                     (value >>  8) & 0xFF;
slouken@0
   833
            row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] =
slouken@0
   834
                     (value >> 16) & 0xFF;
slouken@0
   835
            row += 2*3;
slouken@0
   836
slouken@0
   837
            L = *lum; lum += 2;
slouken@0
   838
            value = (rgb_2_pix[ L + cr_r ] |
slouken@0
   839
                     rgb_2_pix[ L + crb_g ] |
slouken@0
   840
                     rgb_2_pix[ L + cb_b ]);
slouken@0
   841
            row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] =
slouken@0
   842
                     (value      ) & 0xFF;
slouken@0
   843
            row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] =
slouken@0
   844
                     (value >>  8) & 0xFF;
slouken@0
   845
            row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] =
slouken@0
   846
                     (value >> 16) & 0xFF;
slouken@0
   847
            row += 2*3;
slouken@0
   848
slouken@0
   849
        }
slouken@0
   850
        row += next_row;
slouken@0
   851
    }
slouken@0
   852
}
slouken@0
   853
slouken@0
   854
static void Color32DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix,
slouken@0
   855
                                    unsigned char *lum, unsigned char *cr,
slouken@0
   856
                                    unsigned char *cb, unsigned char *out,
slouken@0
   857
                                    int rows, int cols, int mod )
slouken@0
   858
{
slouken@0
   859
    unsigned int* row = (unsigned int*) out;
slouken@0
   860
    const int next_row = cols*2+mod;
slouken@0
   861
    int x, y;
slouken@0
   862
    int cr_r;
slouken@0
   863
    int crb_g;
slouken@0
   864
    int cb_b;
slouken@0
   865
    int cols_2 = cols / 2;
slouken@0
   866
    mod+=mod;
slouken@0
   867
    y = rows;
slouken@0
   868
    while( y-- )
slouken@0
   869
    {
slouken@0
   870
        x = cols_2;
slouken@0
   871
        while( x-- )
slouken@0
   872
        {
slouken@0
   873
            register int L;
slouken@0
   874
slouken@0
   875
            cr_r   = 0*768+256 + colortab[ *cr + 0*256 ];
slouken@0
   876
            crb_g  = 1*768+256 + colortab[ *cr + 1*256 ]
slouken@0
   877
                               + colortab[ *cb + 2*256 ];
slouken@0
   878
            cb_b   = 2*768+256 + colortab[ *cb + 3*256 ];
slouken@0
   879
            cr += 4; cb += 4;
slouken@0
   880
slouken@0
   881
            L = *lum; lum += 2;
slouken@0
   882
            row[0] = row[1] = row[next_row] = row[next_row+1] =
slouken@0
   883
                                       (rgb_2_pix[ L + cr_r ] |
slouken@0
   884
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   885
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   886
            row += 2;
slouken@0
   887
slouken@0
   888
            L = *lum; lum += 2;
slouken@0
   889
            row[0] = row[1] = row[next_row] = row[next_row+1] =
slouken@0
   890
                                       (rgb_2_pix[ L + cr_r ] |
slouken@0
   891
                                        rgb_2_pix[ L + crb_g ] |
slouken@0
   892
                                        rgb_2_pix[ L + cb_b ]);
slouken@0
   893
            row += 2;
slouken@0
   894
slouken@0
   895
slouken@0
   896
        }
slouken@0
   897
slouken@0
   898
        row += next_row;
slouken@0
   899
    }
slouken@0
   900
}
slouken@0
   901
slouken@0
   902
/*
slouken@0
   903
 * How many 1 bits are there in the Uint32.
slouken@0
   904
 * Low performance, do not call often.
slouken@0
   905
 */
slouken@0
   906
static int number_of_bits_set( Uint32 a )
slouken@0
   907
{
slouken@0
   908
    if(!a) return 0;
slouken@0
   909
    if(a & 1) return 1 + number_of_bits_set(a >> 1);
slouken@0
   910
    return(number_of_bits_set(a >> 1));
slouken@0
   911
}
slouken@0
   912
slouken@0
   913
/*
slouken@0
   914
 * How many 0 bits are there at least significant end of Uint32.
slouken@0
   915
 * Low performance, do not call often.
slouken@0
   916
 */
slouken@0
   917
static int free_bits_at_bottom( Uint32 a )
slouken@0
   918
{
slouken@0
   919
      /* assume char is 8 bits */
slouken@0
   920
    if(!a) return sizeof(Uint32) * 8;
slouken@0
   921
    if(((Sint32)a) & 1l) return 0;
slouken@0
   922
    return 1 + free_bits_at_bottom ( a >> 1);
slouken@0
   923
}
slouken@0
   924
slouken@0
   925
slouken@0
   926
SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
slouken@0
   927
{
slouken@0
   928
	SDL_Overlay *overlay;
slouken@0
   929
	struct private_yuvhwdata *swdata;
slouken@0
   930
	int *Cr_r_tab;
slouken@0
   931
	int *Cr_g_tab;
slouken@0
   932
	int *Cb_g_tab;
slouken@0
   933
	int *Cb_b_tab;
slouken@0
   934
	Uint32 *r_2_pix_alloc;
slouken@0
   935
	Uint32 *g_2_pix_alloc;
slouken@0
   936
	Uint32 *b_2_pix_alloc;
slouken@739
   937
	int i;
slouken@0
   938
	int CR, CB;
slouken@0
   939
	Uint32 Rmask, Gmask, Bmask;
slouken@0
   940
slouken@0
   941
	/* Only RGB packed pixel conversion supported */
slouken@0
   942
	if ( (display->format->BytesPerPixel != 2) &&
slouken@0
   943
	     (display->format->BytesPerPixel != 3) &&
slouken@0
   944
	     (display->format->BytesPerPixel != 4) ) {
slouken@0
   945
		SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces");
slouken@0
   946
		return(NULL);
slouken@0
   947
	}
slouken@0
   948
slouken@0
   949
	/* Verify that we support the format */
slouken@0
   950
	switch (format) {
slouken@0
   951
	    case SDL_YV12_OVERLAY:
slouken@0
   952
	    case SDL_IYUV_OVERLAY:
slouken@0
   953
	    case SDL_YUY2_OVERLAY:
slouken@0
   954
	    case SDL_UYVY_OVERLAY:
slouken@0
   955
	    case SDL_YVYU_OVERLAY:
slouken@0
   956
		break;
slouken@0
   957
	    default:
slouken@0
   958
		SDL_SetError("Unsupported YUV format");
slouken@0
   959
		return(NULL);
slouken@0
   960
	}
slouken@0
   961
slouken@0
   962
	/* Create the overlay structure */
slouken@1336
   963
	overlay = (SDL_Overlay *)SDL_malloc(sizeof *overlay);
slouken@0
   964
	if ( overlay == NULL ) {
slouken@0
   965
		SDL_OutOfMemory();
slouken@0
   966
		return(NULL);
slouken@0
   967
	}
slouken@1336
   968
	SDL_memset(overlay, 0, (sizeof *overlay));
slouken@0
   969
slouken@0
   970
	/* Fill in the basic members */
slouken@0
   971
	overlay->format = format;
slouken@0
   972
	overlay->w = width;
slouken@0
   973
	overlay->h = height;
slouken@0
   974
slouken@0
   975
	/* Set up the YUV surface function structure */
slouken@0
   976
	overlay->hwfuncs = &sw_yuvfuncs;
slouken@0
   977
slouken@0
   978
	/* Create the pixel data and lookup tables */
slouken@1336
   979
	swdata = (struct private_yuvhwdata *)SDL_malloc(sizeof *swdata);
slouken@0
   980
	overlay->hwdata = swdata;
slouken@0
   981
	if ( swdata == NULL ) {
slouken@0
   982
		SDL_OutOfMemory();
slouken@0
   983
		SDL_FreeYUVOverlay(overlay);
slouken@0
   984
		return(NULL);
slouken@0
   985
	}
slouken@0
   986
	swdata->stretch = NULL;
slouken@0
   987
	swdata->display = display;
slouken@1336
   988
	swdata->pixels = (Uint8 *) SDL_malloc(width*height*2);
slouken@1336
   989
	swdata->colortab = (int *)SDL_malloc(4*256*sizeof(int));
slouken@0
   990
	Cr_r_tab = &swdata->colortab[0*256];
slouken@0
   991
	Cr_g_tab = &swdata->colortab[1*256];
slouken@0
   992
	Cb_g_tab = &swdata->colortab[2*256];
slouken@0
   993
	Cb_b_tab = &swdata->colortab[3*256];
slouken@1336
   994
	swdata->rgb_2_pix = (Uint32 *)SDL_malloc(3*768*sizeof(Uint32));
slouken@0
   995
	r_2_pix_alloc = &swdata->rgb_2_pix[0*768];
slouken@0
   996
	g_2_pix_alloc = &swdata->rgb_2_pix[1*768];
slouken@0
   997
	b_2_pix_alloc = &swdata->rgb_2_pix[2*768];
slouken@0
   998
	if ( ! swdata->pixels || ! swdata->colortab || ! swdata->rgb_2_pix ) {
slouken@0
   999
		SDL_OutOfMemory();
slouken@0
  1000
		SDL_FreeYUVOverlay(overlay);
slouken@0
  1001
		return(NULL);
slouken@0
  1002
	}
slouken@0
  1003
slouken@0
  1004
	/* Generate the tables for the display surface */
slouken@0
  1005
	for (i=0; i<256; i++) {
slouken@0
  1006
		/* Gamma correction (luminescence table) and chroma correction
slouken@0
  1007
		   would be done here.  See the Berkeley mpeg_play sources.
slouken@0
  1008
		*/
slouken@0
  1009
		CB = CR = (i-128);
slouken@0
  1010
		Cr_r_tab[i] = (int) ( (0.419/0.299) * CR);
slouken@0
  1011
		Cr_g_tab[i] = (int) (-(0.299/0.419) * CR);
slouken@0
  1012
		Cb_g_tab[i] = (int) (-(0.114/0.331) * CB); 
slouken@0
  1013
		Cb_b_tab[i] = (int) ( (0.587/0.331) * CB);
slouken@0
  1014
	}
slouken@0
  1015
slouken@0
  1016
	/* 
slouken@0
  1017
	 * Set up entries 0-255 in rgb-to-pixel value tables.
slouken@0
  1018
	 */
slouken@0
  1019
	Rmask = display->format->Rmask;
slouken@0
  1020
	Gmask = display->format->Gmask;
slouken@0
  1021
	Bmask = display->format->Bmask;
slouken@0
  1022
	for ( i=0; i<256; ++i ) {
slouken@0
  1023
		r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask));
slouken@0
  1024
		r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask);
slouken@0
  1025
		g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask));
slouken@0
  1026
		g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask);
slouken@0
  1027
		b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask));
slouken@0
  1028
		b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask);
slouken@0
  1029
	}
slouken@0
  1030
slouken@0
  1031
	/*
slouken@0
  1032
	 * If we have 16-bit output depth, then we double the value
slouken@0
  1033
	 * in the top word. This means that we can write out both
slouken@0
  1034
	 * pixels in the pixel doubling mode with one op. It is 
slouken@0
  1035
	 * harmless in the normal case as storing a 32-bit value
slouken@0
  1036
	 * through a short pointer will lose the top bits anyway.
slouken@0
  1037
	 */
slouken@0
  1038
	if( display->format->BytesPerPixel == 2 ) {
slouken@0
  1039
		for ( i=0; i<256; ++i ) {
slouken@0
  1040
			r_2_pix_alloc[i+256] |= (r_2_pix_alloc[i+256]) << 16;
slouken@0
  1041
			g_2_pix_alloc[i+256] |= (g_2_pix_alloc[i+256]) << 16;
slouken@0
  1042
			b_2_pix_alloc[i+256] |= (b_2_pix_alloc[i+256]) << 16;
slouken@0
  1043
		}
slouken@0
  1044
	}
slouken@0
  1045
slouken@0
  1046
	/*
slouken@0
  1047
	 * Spread out the values we have to the rest of the array so that
slouken@0
  1048
	 * we do not need to check for overflow.
slouken@0
  1049
	 */
slouken@0
  1050
	for ( i=0; i<256; ++i ) {
slouken@0
  1051
		r_2_pix_alloc[i] = r_2_pix_alloc[256];
slouken@0
  1052
		r_2_pix_alloc[i+512] = r_2_pix_alloc[511];
slouken@0
  1053
		g_2_pix_alloc[i] = g_2_pix_alloc[256];
slouken@0
  1054
		g_2_pix_alloc[i+512] = g_2_pix_alloc[511];
slouken@0
  1055
		b_2_pix_alloc[i] = b_2_pix_alloc[256];
slouken@0
  1056
		b_2_pix_alloc[i+512] = b_2_pix_alloc[511];
slouken@0
  1057
	}
slouken@0
  1058
slouken@0
  1059
	/* You have chosen wisely... */
slouken@0
  1060
	switch (format) {
slouken@0
  1061
	    case SDL_YV12_OVERLAY:
slouken@0
  1062
	    case SDL_IYUV_OVERLAY:
slouken@0
  1063
		if ( display->format->BytesPerPixel == 2 ) {
slouken@1413
  1064
#if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/
slouken@0
  1065
			/* inline assembly functions */
slouken@739
  1066
			if ( SDL_HasMMX() && (Rmask == 0xF800) &&
slouken@739
  1067
			                     (Gmask == 0x07E0) &&
slouken@739
  1068
				             (Bmask == 0x001F) &&
slouken@739
  1069
			                     (width & 15) == 0) {
slouken@0
  1070
/*printf("Using MMX 16-bit 565 dither\n");*/
slouken@0
  1071
				swdata->Display1X = Color565DitherYV12MMX1X;
slouken@0
  1072
			} else {
slouken@0
  1073
/*printf("Using C 16-bit dither\n");*/
slouken@0
  1074
				swdata->Display1X = Color16DitherYV12Mod1X;
slouken@0
  1075
			}
slouken@0
  1076
#else
slouken@0
  1077
			swdata->Display1X = Color16DitherYV12Mod1X;
slouken@0
  1078
#endif
slouken@0
  1079
			swdata->Display2X = Color16DitherYV12Mod2X;
slouken@0
  1080
		}
slouken@0
  1081
		if ( display->format->BytesPerPixel == 3 ) {
slouken@0
  1082
			swdata->Display1X = Color24DitherYV12Mod1X;
slouken@0
  1083
			swdata->Display2X = Color24DitherYV12Mod2X;
slouken@0
  1084
		}
slouken@0
  1085
		if ( display->format->BytesPerPixel == 4 ) {
slouken@1413
  1086
#if 0 /*defined(__GNUC__) && defined(__i386__) && SDL_ASSEMBLY_ROUTINES*/
slouken@0
  1087
			/* inline assembly functions */
slouken@739
  1088
			if ( SDL_HasMMX() && (Rmask == 0x00FF0000) &&
slouken@739
  1089
			                     (Gmask == 0x0000FF00) &&
slouken@739
  1090
				             (Bmask == 0x000000FF) && 
slouken@739
  1091
			                     (width & 15) == 0) {
slouken@0
  1092
/*printf("Using MMX 32-bit dither\n");*/
slouken@0
  1093
				swdata->Display1X = ColorRGBDitherYV12MMX1X;
slouken@0
  1094
			} else {
slouken@0
  1095
/*printf("Using C 32-bit dither\n");*/
slouken@0
  1096
				swdata->Display1X = Color32DitherYV12Mod1X;
slouken@0
  1097
			}
slouken@0
  1098
#else
slouken@0
  1099
			swdata->Display1X = Color32DitherYV12Mod1X;
slouken@0
  1100
#endif
slouken@0
  1101
			swdata->Display2X = Color32DitherYV12Mod2X;
slouken@0
  1102
		}
slouken@0
  1103
		break;
slouken@0
  1104
	    case SDL_YUY2_OVERLAY:
slouken@0
  1105
	    case SDL_UYVY_OVERLAY:
slouken@0
  1106
	    case SDL_YVYU_OVERLAY:
slouken@0
  1107
		if ( display->format->BytesPerPixel == 2 ) {
slouken@0
  1108
			swdata->Display1X = Color16DitherYUY2Mod1X;
slouken@0
  1109
			swdata->Display2X = Color16DitherYUY2Mod2X;
slouken@0
  1110
		}
slouken@0
  1111
		if ( display->format->BytesPerPixel == 3 ) {
slouken@0
  1112
			swdata->Display1X = Color24DitherYUY2Mod1X;
slouken@0
  1113
			swdata->Display2X = Color24DitherYUY2Mod2X;
slouken@0
  1114
		}
slouken@0
  1115
		if ( display->format->BytesPerPixel == 4 ) {
slouken@0
  1116
			swdata->Display1X = Color32DitherYUY2Mod1X;
slouken@0
  1117
			swdata->Display2X = Color32DitherYUY2Mod2X;
slouken@0
  1118
		}
slouken@0
  1119
		break;
slouken@0
  1120
	    default:
slouken@0
  1121
		/* We should never get here (caught above) */
slouken@0
  1122
		break;
slouken@0
  1123
	}
slouken@0
  1124
slouken@0
  1125
	/* Find the pitch and offset values for the overlay */
slouken@0
  1126
	overlay->pitches = swdata->pitches;
slouken@0
  1127
	overlay->pixels = swdata->planes;
slouken@0
  1128
	switch (format) {
slouken@0
  1129
	    case SDL_YV12_OVERLAY:
slouken@0
  1130
	    case SDL_IYUV_OVERLAY:
slouken@0
  1131
		overlay->pitches[0] = overlay->w;
slouken@0
  1132
		overlay->pitches[1] = overlay->pitches[0] / 2;
slouken@0
  1133
		overlay->pitches[2] = overlay->pitches[0] / 2;
slouken@0
  1134
	        overlay->pixels[0] = swdata->pixels;
slouken@0
  1135
	        overlay->pixels[1] = overlay->pixels[0] +
slouken@0
  1136
		                     overlay->pitches[0] * overlay->h;
slouken@0
  1137
	        overlay->pixels[2] = overlay->pixels[1] +
slouken@0
  1138
		                     overlay->pitches[1] * overlay->h / 2;
slouken@0
  1139
		overlay->planes = 3;
slouken@0
  1140
		break;
slouken@0
  1141
	    case SDL_YUY2_OVERLAY:
slouken@0
  1142
	    case SDL_UYVY_OVERLAY:
slouken@0
  1143
	    case SDL_YVYU_OVERLAY:
slouken@0
  1144
		overlay->pitches[0] = overlay->w*2;
slouken@0
  1145
	        overlay->pixels[0] = swdata->pixels;
slouken@0
  1146
		overlay->planes = 1;
slouken@0
  1147
		break;
slouken@0
  1148
	    default:
slouken@0
  1149
		/* We should never get here (caught above) */
slouken@0
  1150
		break;
slouken@0
  1151
	}
slouken@0
  1152
slouken@0
  1153
	/* We're all done.. */
slouken@0
  1154
	return(overlay);
slouken@0
  1155
}
slouken@0
  1156
slouken@0
  1157
int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay)
slouken@0
  1158
{
slouken@0
  1159
	return(0);
slouken@0
  1160
}
slouken@0
  1161
slouken@0
  1162
void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay)
slouken@0
  1163
{
slouken@0
  1164
	return;
slouken@0
  1165
}
slouken@0
  1166
slouken@1643
  1167
int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst)
slouken@0
  1168
{
slouken@0
  1169
	struct private_yuvhwdata *swdata;
slouken@1643
  1170
	int stretch;
slouken@1643
  1171
	int scale_2x;
slouken@0
  1172
	SDL_Surface *display;
slouken@0
  1173
	Uint8 *lum, *Cr, *Cb;
slouken@1643
  1174
	Uint8 *dstp;
slouken@0
  1175
	int mod;
slouken@0
  1176
slouken@0
  1177
	swdata = overlay->hwdata;
slouken@1643
  1178
	stretch = 0;
slouken@0
  1179
	scale_2x = 0;
slouken@1643
  1180
	if ( src->x || src->y || src->w < overlay->w || src->h < overlay->h ) {
slouken@1643
  1181
		stretch = 1;
slouken@1643
  1182
	} else if ( (src->w != dst->w) || (src->h != dst->h) ) {
slouken@1643
  1183
		if ( (dst->w == 2*src->w) &&
slouken@1643
  1184
		     (dst->h == 2*src->h) ) {
slouken@0
  1185
			scale_2x = 1;
slouken@0
  1186
		} else {
slouken@1643
  1187
			stretch = 1;
slouken@0
  1188
		}
slouken@0
  1189
	}
slouken@0
  1190
	if ( stretch ) {
slouken@1643
  1191
		if ( ! swdata->stretch ) {
slouken@1643
  1192
			display = swdata->display;
slouken@1643
  1193
			swdata->stretch = SDL_CreateRGBSurface(
slouken@1643
  1194
				SDL_SWSURFACE,
slouken@1643
  1195
				overlay->w, overlay->h,
slouken@1643
  1196
				display->format->BitsPerPixel,
slouken@1643
  1197
				display->format->Rmask,
slouken@1643
  1198
				display->format->Gmask,
slouken@1643
  1199
				display->format->Bmask, 0);
slouken@1643
  1200
			if ( ! swdata->stretch ) {
slouken@1643
  1201
				return(-1);
slouken@1643
  1202
			}
slouken@1643
  1203
		}
slouken@1643
  1204
		display = swdata->stretch;
slouken@0
  1205
	} else {
slouken@0
  1206
		display = swdata->display;
slouken@0
  1207
	}
slouken@0
  1208
	switch (overlay->format) {
slouken@0
  1209
	    case SDL_YV12_OVERLAY:
slouken@0
  1210
		lum = overlay->pixels[0];
slouken@0
  1211
		Cr =  overlay->pixels[1];
slouken@0
  1212
		Cb =  overlay->pixels[2];
slouken@0
  1213
		break;
slouken@0
  1214
	    case SDL_IYUV_OVERLAY:
slouken@0
  1215
		lum = overlay->pixels[0];
slouken@0
  1216
		Cr =  overlay->pixels[2];
slouken@0
  1217
		Cb =  overlay->pixels[1];
slouken@0
  1218
		break;
slouken@0
  1219
	    case SDL_YUY2_OVERLAY:
slouken@0
  1220
		lum = overlay->pixels[0];
slouken@0
  1221
		Cr = lum + 3;
slouken@0
  1222
		Cb = lum + 1;
slouken@0
  1223
		break;
slouken@0
  1224
	    case SDL_UYVY_OVERLAY:
slouken@0
  1225
		lum = overlay->pixels[0]+1;
slouken@0
  1226
		Cr = lum + 1;
slouken@0
  1227
		Cb = lum - 1;
slouken@0
  1228
		break;
slouken@0
  1229
	    case SDL_YVYU_OVERLAY:
slouken@0
  1230
		lum = overlay->pixels[0];
slouken@0
  1231
		Cr = lum + 1;
slouken@0
  1232
		Cb = lum + 3;
slouken@0
  1233
		break;
slouken@0
  1234
	    default:
slouken@292
  1235
		SDL_SetError("Unsupported YUV format in blit");
slouken@0
  1236
		return(-1);
slouken@0
  1237
	}
slouken@0
  1238
	if ( SDL_MUSTLOCK(display) ) {
slouken@0
  1239
        	if ( SDL_LockSurface(display) < 0 ) {
slouken@0
  1240
			return(-1);
slouken@0
  1241
		}
slouken@0
  1242
	}
slouken@0
  1243
	if ( stretch ) {
slouken@1643
  1244
		dstp = (Uint8 *)swdata->stretch->pixels;
slouken@0
  1245
	} else {
slouken@1643
  1246
		dstp = (Uint8 *)display->pixels
slouken@1643
  1247
			+ dst->x * display->format->BytesPerPixel
slouken@1643
  1248
			+ dst->y * display->pitch;
slouken@0
  1249
	}
slouken@0
  1250
	mod = (display->pitch / display->format->BytesPerPixel);
slouken@0
  1251
slouken@0
  1252
	if ( scale_2x ) {
slouken@0
  1253
		mod -= (overlay->w * 2);
slouken@0
  1254
		swdata->Display2X(swdata->colortab, swdata->rgb_2_pix,
slouken@1643
  1255
		                  lum, Cr, Cb, dstp, overlay->h, overlay->w, mod);
slouken@0
  1256
	} else {
slouken@0
  1257
		mod -= overlay->w;
slouken@0
  1258
		swdata->Display1X(swdata->colortab, swdata->rgb_2_pix,
slouken@1643
  1259
		                  lum, Cr, Cb, dstp, overlay->h, overlay->w, mod);
slouken@0
  1260
	}
slouken@0
  1261
	if ( SDL_MUSTLOCK(display) ) {
slouken@0
  1262
		SDL_UnlockSurface(display);
slouken@0
  1263
	}
slouken@0
  1264
	if ( stretch ) {
slouken@0
  1265
		display = swdata->display;
slouken@1643
  1266
		SDL_SoftStretch(swdata->stretch, src, display, dst);
slouken@0
  1267
	}
slouken@1643
  1268
	SDL_UpdateRects(display, 1, dst);
slouken@0
  1269
slouken@0
  1270
	return(0);
slouken@0
  1271
}
slouken@0
  1272
slouken@0
  1273
void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay)
slouken@0
  1274
{
slouken@0
  1275
	struct private_yuvhwdata *swdata;
slouken@0
  1276
slouken@0
  1277
	swdata = overlay->hwdata;
slouken@0
  1278
	if ( swdata ) {
slouken@9
  1279
		if ( swdata->stretch ) {
slouken@9
  1280
			SDL_FreeSurface(swdata->stretch);
slouken@9
  1281
		}
slouken@0
  1282
		if ( swdata->pixels ) {
slouken@1336
  1283
			SDL_free(swdata->pixels);
slouken@0
  1284
		}
slouken@0
  1285
		if ( swdata->colortab ) {
slouken@1336
  1286
			SDL_free(swdata->colortab);
slouken@0
  1287
		}
slouken@0
  1288
		if ( swdata->rgb_2_pix ) {
slouken@1336
  1289
			SDL_free(swdata->rgb_2_pix);
slouken@0
  1290
		}
slouken@1336
  1291
		SDL_free(swdata);
slouken@0
  1292
	}
slouken@0
  1293
}