src/video/SDL_yuv_sw.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. CPU_Flags
  2. CPU_Flags
  3. Color16DitherYV12Mod1X
  4. Color24DitherYV12Mod1X
  5. Color32DitherYV12Mod1X
  6. Color16DitherYV12Mod2X
  7. Color24DitherYV12Mod2X
  8. Color32DitherYV12Mod2X
  9. Color16DitherYUY2Mod1X
  10. Color24DitherYUY2Mod1X
  11. Color32DitherYUY2Mod1X
  12. Color16DitherYUY2Mod2X
  13. Color24DitherYUY2Mod2X
  14. Color32DitherYUY2Mod2X
  15. number_of_bits_set
  16. free_bits_at_bottom
  17. SDL_CreateYUV_SW
  18. SDL_LockYUV_SW
  19. SDL_UnlockYUV_SW
  20. SDL_DisplayYUV_SW
  21. SDL_FreeYUV_SW

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

/* [<][>][^][v][top][bottom][index][help] */