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