diff options
Diffstat (limited to '3rdparty/SDL2/src/render/SDL_yuv_sw.c')
-rw-r--r-- | 3rdparty/SDL2/src/render/SDL_yuv_sw.c | 1405 |
1 files changed, 0 insertions, 1405 deletions
diff --git a/3rdparty/SDL2/src/render/SDL_yuv_sw.c b/3rdparty/SDL2/src/render/SDL_yuv_sw.c deleted file mode 100644 index 7fc6b88654c..00000000000 --- a/3rdparty/SDL2/src/render/SDL_yuv_sw.c +++ /dev/null @@ -1,1405 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -/* This is the software implementation of the YUV texture support */ - -/* This code was derived from code carrying the following copyright notices: - - * Copyright (c) 1995 The Regents of the University of California. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF - * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - * Copyright (c) 1995 Erik Corry - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice and the following - * two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, - * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF - * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" - * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, - * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - * Portions of this software Copyright (c) 1995 Brown University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement - * is hereby granted, provided that the above copyright notice and the - * following two paragraphs appear in all copies of this software. - * - * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN - * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" - * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "SDL_assert.h" -#include "SDL_video.h" -#include "SDL_cpuinfo.h" -#include "SDL_yuv_sw_c.h" - - -/* The colorspace conversion functions */ - -#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES -extern void Color565DitherYV12MMX1X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod); -extern void ColorRGBDitherYV12MMX1X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod); -#endif - -static void -Color16DitherYV12Mod1X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned short *row1; - unsigned short *row2; - unsigned char *lum2; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - row1 = (unsigned short *) out; - row2 = row1 + cols + mod; - lum2 = lum + cols; - - mod += cols + mod; - - y = rows / 2; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - ++cr; - ++cb; - - L = *lum++; - *row1++ = (unsigned short) (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - - L = *lum++; - *row1++ = (unsigned short) (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - - - /* Now, do second row. */ - - L = *lum2++; - *row2++ = (unsigned short) (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - - L = *lum2++; - *row2++ = (unsigned short) (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - } - - /* - * These values are at the start of the next line, (due - * to the ++'s above),but they need to be at the start - * of the line after that. - */ - lum += cols; - lum2 += cols; - row1 += mod; - row2 += mod; - } -} - -static void -Color24DitherYV12Mod1X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int value; - unsigned char *row1; - unsigned char *row2; - unsigned char *lum2; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - row1 = out; - row2 = row1 + cols * 3 + mod * 3; - lum2 = lum + cols; - - mod += cols + mod; - mod *= 3; - - y = rows / 2; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - ++cr; - ++cb; - - L = *lum++; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - *row1++ = (value) & 0xFF; - *row1++ = (value >> 8) & 0xFF; - *row1++ = (value >> 16) & 0xFF; - - L = *lum++; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - *row1++ = (value) & 0xFF; - *row1++ = (value >> 8) & 0xFF; - *row1++ = (value >> 16) & 0xFF; - - - /* Now, do second row. */ - - L = *lum2++; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - *row2++ = (value) & 0xFF; - *row2++ = (value >> 8) & 0xFF; - *row2++ = (value >> 16) & 0xFF; - - L = *lum2++; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - *row2++ = (value) & 0xFF; - *row2++ = (value >> 8) & 0xFF; - *row2++ = (value >> 16) & 0xFF; - } - - /* - * These values are at the start of the next line, (due - * to the ++'s above),but they need to be at the start - * of the line after that. - */ - lum += cols; - lum2 += cols; - row1 += mod; - row2 += mod; - } -} - -static void -Color32DitherYV12Mod1X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int *row1; - unsigned int *row2; - unsigned char *lum2; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - row1 = (unsigned int *) out; - row2 = row1 + cols + mod; - lum2 = lum + cols; - - mod += cols + mod; - - y = rows / 2; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - ++cr; - ++cb; - - L = *lum++; - *row1++ = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - - L = *lum++; - *row1++ = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - - - /* Now, do second row. */ - - L = *lum2++; - *row2++ = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - - L = *lum2++; - *row2++ = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - } - - /* - * These values are at the start of the next line, (due - * to the ++'s above),but they need to be at the start - * of the line after that. - */ - lum += cols; - lum2 += cols; - row1 += mod; - row2 += mod; - } -} - -/* - * In this function I make use of a nasty trick. The tables have the lower - * 16 bits replicated in the upper 16. This means I can write ints and get - * the horisontal doubling for free (almost). - */ -static void -Color16DitherYV12Mod2X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int *row1 = (unsigned int *) out; - const int next_row = cols + (mod / 2); - unsigned int *row2 = row1 + 2 * next_row; - unsigned char *lum2; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - lum2 = lum + cols; - - mod = (next_row * 3) + (mod / 2); - - y = rows / 2; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - ++cr; - ++cb; - - L = *lum++; - row1[0] = row1[next_row] = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - row1++; - - L = *lum++; - row1[0] = row1[next_row] = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - row1++; - - - /* Now, do second row. */ - - L = *lum2++; - row2[0] = row2[next_row] = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - row2++; - - L = *lum2++; - row2[0] = row2[next_row] = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - row2++; - } - - /* - * These values are at the start of the next line, (due - * to the ++'s above),but they need to be at the start - * of the line after that. - */ - lum += cols; - lum2 += cols; - row1 += mod; - row2 += mod; - } -} - -static void -Color24DitherYV12Mod2X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int value; - unsigned char *row1 = out; - const int next_row = (cols * 2 + mod) * 3; - unsigned char *row2 = row1 + 2 * next_row; - unsigned char *lum2; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - lum2 = lum + cols; - - mod = next_row * 3 + mod * 3; - - y = rows / 2; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - ++cr; - ++cb; - - L = *lum++; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row1[0 + 0] = row1[3 + 0] = row1[next_row + 0] = - row1[next_row + 3 + 0] = (value) & 0xFF; - row1[0 + 1] = row1[3 + 1] = row1[next_row + 1] = - row1[next_row + 3 + 1] = (value >> 8) & 0xFF; - row1[0 + 2] = row1[3 + 2] = row1[next_row + 2] = - row1[next_row + 3 + 2] = (value >> 16) & 0xFF; - row1 += 2 * 3; - - L = *lum++; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row1[0 + 0] = row1[3 + 0] = row1[next_row + 0] = - row1[next_row + 3 + 0] = (value) & 0xFF; - row1[0 + 1] = row1[3 + 1] = row1[next_row + 1] = - row1[next_row + 3 + 1] = (value >> 8) & 0xFF; - row1[0 + 2] = row1[3 + 2] = row1[next_row + 2] = - row1[next_row + 3 + 2] = (value >> 16) & 0xFF; - row1 += 2 * 3; - - - /* Now, do second row. */ - - L = *lum2++; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row2[0 + 0] = row2[3 + 0] = row2[next_row + 0] = - row2[next_row + 3 + 0] = (value) & 0xFF; - row2[0 + 1] = row2[3 + 1] = row2[next_row + 1] = - row2[next_row + 3 + 1] = (value >> 8) & 0xFF; - row2[0 + 2] = row2[3 + 2] = row2[next_row + 2] = - row2[next_row + 3 + 2] = (value >> 16) & 0xFF; - row2 += 2 * 3; - - L = *lum2++; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row2[0 + 0] = row2[3 + 0] = row2[next_row + 0] = - row2[next_row + 3 + 0] = (value) & 0xFF; - row2[0 + 1] = row2[3 + 1] = row2[next_row + 1] = - row2[next_row + 3 + 1] = (value >> 8) & 0xFF; - row2[0 + 2] = row2[3 + 2] = row2[next_row + 2] = - row2[next_row + 3 + 2] = (value >> 16) & 0xFF; - row2 += 2 * 3; - } - - /* - * These values are at the start of the next line, (due - * to the ++'s above),but they need to be at the start - * of the line after that. - */ - lum += cols; - lum2 += cols; - row1 += mod; - row2 += mod; - } -} - -static void -Color32DitherYV12Mod2X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int *row1 = (unsigned int *) out; - const int next_row = cols * 2 + mod; - unsigned int *row2 = row1 + 2 * next_row; - unsigned char *lum2; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - lum2 = lum + cols; - - mod = (next_row * 3) + mod; - - y = rows / 2; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - ++cr; - ++cb; - - L = *lum++; - row1[0] = row1[1] = row1[next_row] = row1[next_row + 1] = - (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row1 += 2; - - L = *lum++; - row1[0] = row1[1] = row1[next_row] = row1[next_row + 1] = - (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row1 += 2; - - - /* Now, do second row. */ - - L = *lum2++; - row2[0] = row2[1] = row2[next_row] = row2[next_row + 1] = - (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row2 += 2; - - L = *lum2++; - row2[0] = row2[1] = row2[next_row] = row2[next_row + 1] = - (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row2 += 2; - } - - /* - * These values are at the start of the next line, (due - * to the ++'s above),but they need to be at the start - * of the line after that. - */ - lum += cols; - lum2 += cols; - row1 += mod; - row2 += mod; - } -} - -static void -Color16DitherYUY2Mod1X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned short *row; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - row = (unsigned short *) out; - - y = rows; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - cr += 4; - cb += 4; - - L = *lum; - lum += 2; - *row++ = (unsigned short) (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - - L = *lum; - lum += 2; - *row++ = (unsigned short) (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - - } - - row += mod; - } -} - -static void -Color24DitherYUY2Mod1X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int value; - unsigned char *row; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - row = (unsigned char *) out; - mod *= 3; - y = rows; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - cr += 4; - cb += 4; - - L = *lum; - lum += 2; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - *row++ = (value) & 0xFF; - *row++ = (value >> 8) & 0xFF; - *row++ = (value >> 16) & 0xFF; - - L = *lum; - lum += 2; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - *row++ = (value) & 0xFF; - *row++ = (value >> 8) & 0xFF; - *row++ = (value >> 16) & 0xFF; - - } - row += mod; - } -} - -static void -Color32DitherYUY2Mod1X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int *row; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - row = (unsigned int *) out; - y = rows; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - cr += 4; - cb += 4; - - L = *lum; - lum += 2; - *row++ = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - - L = *lum; - lum += 2; - *row++ = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - - - } - row += mod; - } -} - -/* - * In this function I make use of a nasty trick. The tables have the lower - * 16 bits replicated in the upper 16. This means I can write ints and get - * the horisontal doubling for free (almost). - */ -static void -Color16DitherYUY2Mod2X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int *row = (unsigned int *) out; - const int next_row = cols + (mod / 2); - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - - y = rows; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - cr += 4; - cb += 4; - - L = *lum; - lum += 2; - row[0] = row[next_row] = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - row++; - - L = *lum; - lum += 2; - row[0] = row[next_row] = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | - rgb_2_pix[L + cb_b]); - row++; - - } - row += next_row; - } -} - -static void -Color24DitherYUY2Mod2X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int value; - unsigned char *row = out; - const int next_row = (cols * 2 + mod) * 3; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - y = rows; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - cr += 4; - cb += 4; - - L = *lum; - lum += 2; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row[0 + 0] = row[3 + 0] = row[next_row + 0] = - row[next_row + 3 + 0] = (value) & 0xFF; - row[0 + 1] = row[3 + 1] = row[next_row + 1] = - row[next_row + 3 + 1] = (value >> 8) & 0xFF; - row[0 + 2] = row[3 + 2] = row[next_row + 2] = - row[next_row + 3 + 2] = (value >> 16) & 0xFF; - row += 2 * 3; - - L = *lum; - lum += 2; - value = (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row[0 + 0] = row[3 + 0] = row[next_row + 0] = - row[next_row + 3 + 0] = (value) & 0xFF; - row[0 + 1] = row[3 + 1] = row[next_row + 1] = - row[next_row + 3 + 1] = (value >> 8) & 0xFF; - row[0 + 2] = row[3 + 2] = row[next_row + 2] = - row[next_row + 3 + 2] = (value >> 16) & 0xFF; - row += 2 * 3; - - } - row += next_row; - } -} - -static void -Color32DitherYUY2Mod2X(int *colortab, Uint32 * rgb_2_pix, - unsigned char *lum, unsigned char *cr, - unsigned char *cb, unsigned char *out, - int rows, int cols, int mod) -{ - unsigned int *row = (unsigned int *) out; - const int next_row = cols * 2 + mod; - int x, y; - int cr_r; - int crb_g; - int cb_b; - int cols_2 = cols / 2; - mod += mod; - y = rows; - while (y--) { - x = cols_2; - while (x--) { - register int L; - - cr_r = 0 * 768 + 256 + colortab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + colortab[*cr + 1 * 256] - + colortab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + colortab[*cb + 3 * 256]; - cr += 4; - cb += 4; - - L = *lum; - lum += 2; - row[0] = row[1] = row[next_row] = row[next_row + 1] = - (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row += 2; - - L = *lum; - lum += 2; - row[0] = row[1] = row[next_row] = row[next_row + 1] = - (rgb_2_pix[L + cr_r] | - rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - row += 2; - - - } - - row += next_row; - } -} - -/* - * How many 1 bits are there in the Uint32. - * Low performance, do not call often. - */ -static int -number_of_bits_set(Uint32 a) -{ - if (!a) - return 0; - if (a & 1) - return 1 + number_of_bits_set(a >> 1); - return (number_of_bits_set(a >> 1)); -} - -/* - * How many 0 bits are there at least significant end of Uint32. - * Low performance, do not call often. - */ -static int -free_bits_at_bottom(Uint32 a) -{ - /* assume char is 8 bits */ - if (!a) - return sizeof(Uint32) * 8; - if (((Sint32) a) & 1l) - return 0; - return 1 + free_bits_at_bottom(a >> 1); -} - -static int -SDL_SW_SetupYUVDisplay(SDL_SW_YUVTexture * swdata, Uint32 target_format) -{ - Uint32 *r_2_pix_alloc; - Uint32 *g_2_pix_alloc; - Uint32 *b_2_pix_alloc; - int i; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - - if (!SDL_PixelFormatEnumToMasks - (target_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask) || bpp < 15) { - return SDL_SetError("Unsupported YUV destination format"); - } - - swdata->target_format = target_format; - r_2_pix_alloc = &swdata->rgb_2_pix[0 * 768]; - g_2_pix_alloc = &swdata->rgb_2_pix[1 * 768]; - b_2_pix_alloc = &swdata->rgb_2_pix[2 * 768]; - - /* - * Set up entries 0-255 in rgb-to-pixel value tables. - */ - for (i = 0; i < 256; ++i) { - r_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(Rmask)); - r_2_pix_alloc[i + 256] <<= free_bits_at_bottom(Rmask); - r_2_pix_alloc[i + 256] |= Amask; - g_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(Gmask)); - g_2_pix_alloc[i + 256] <<= free_bits_at_bottom(Gmask); - g_2_pix_alloc[i + 256] |= Amask; - b_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(Bmask)); - b_2_pix_alloc[i + 256] <<= free_bits_at_bottom(Bmask); - b_2_pix_alloc[i + 256] |= Amask; - } - - /* - * If we have 16-bit output depth, then we double the value - * in the top word. This means that we can write out both - * pixels in the pixel doubling mode with one op. It is - * harmless in the normal case as storing a 32-bit value - * through a short pointer will lose the top bits anyway. - */ - if (SDL_BYTESPERPIXEL(target_format) == 2) { - for (i = 0; i < 256; ++i) { - r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 16; - g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 16; - b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 16; - } - } - - /* - * Spread out the values we have to the rest of the array so that - * we do not need to check for overflow. - */ - for (i = 0; i < 256; ++i) { - r_2_pix_alloc[i] = r_2_pix_alloc[256]; - r_2_pix_alloc[i + 512] = r_2_pix_alloc[511]; - g_2_pix_alloc[i] = g_2_pix_alloc[256]; - g_2_pix_alloc[i + 512] = g_2_pix_alloc[511]; - b_2_pix_alloc[i] = b_2_pix_alloc[256]; - b_2_pix_alloc[i + 512] = b_2_pix_alloc[511]; - } - - /* You have chosen wisely... */ - switch (swdata->format) { - case SDL_PIXELFORMAT_YV12: - case SDL_PIXELFORMAT_IYUV: - if (SDL_BYTESPERPIXEL(target_format) == 2) { -#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES - /* inline assembly functions */ - if (SDL_HasMMX() && (Rmask == 0xF800) && - (Gmask == 0x07E0) && (Bmask == 0x001F) - && (swdata->w & 15) == 0) { -/* printf("Using MMX 16-bit 565 dither\n"); */ - swdata->Display1X = Color565DitherYV12MMX1X; - } else { -/* printf("Using C 16-bit dither\n"); */ - swdata->Display1X = Color16DitherYV12Mod1X; - } -#else - swdata->Display1X = Color16DitherYV12Mod1X; -#endif - swdata->Display2X = Color16DitherYV12Mod2X; - } - if (SDL_BYTESPERPIXEL(target_format) == 3) { - swdata->Display1X = Color24DitherYV12Mod1X; - swdata->Display2X = Color24DitherYV12Mod2X; - } - if (SDL_BYTESPERPIXEL(target_format) == 4) { -#if (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES - /* inline assembly functions */ - if (SDL_HasMMX() && (Rmask == 0x00FF0000) && - (Gmask == 0x0000FF00) && - (Bmask == 0x000000FF) && (swdata->w & 15) == 0) { -/* printf("Using MMX 32-bit dither\n"); */ - swdata->Display1X = ColorRGBDitherYV12MMX1X; - } else { -/* printf("Using C 32-bit dither\n"); */ - swdata->Display1X = Color32DitherYV12Mod1X; - } -#else - swdata->Display1X = Color32DitherYV12Mod1X; -#endif - swdata->Display2X = Color32DitherYV12Mod2X; - } - break; - case SDL_PIXELFORMAT_YUY2: - case SDL_PIXELFORMAT_UYVY: - case SDL_PIXELFORMAT_YVYU: - if (SDL_BYTESPERPIXEL(target_format) == 2) { - swdata->Display1X = Color16DitherYUY2Mod1X; - swdata->Display2X = Color16DitherYUY2Mod2X; - } - if (SDL_BYTESPERPIXEL(target_format) == 3) { - swdata->Display1X = Color24DitherYUY2Mod1X; - swdata->Display2X = Color24DitherYUY2Mod2X; - } - if (SDL_BYTESPERPIXEL(target_format) == 4) { - swdata->Display1X = Color32DitherYUY2Mod1X; - swdata->Display2X = Color32DitherYUY2Mod2X; - } - break; - default: - /* We should never get here (caught above) */ - break; - } - - SDL_FreeSurface(swdata->display); - swdata->display = NULL; - return 0; -} - -SDL_SW_YUVTexture * -SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) -{ - SDL_SW_YUVTexture *swdata; - int *Cr_r_tab; - int *Cr_g_tab; - int *Cb_g_tab; - int *Cb_b_tab; - int i; - int CR, CB; - - switch (format) { - case SDL_PIXELFORMAT_YV12: - case SDL_PIXELFORMAT_IYUV: - case SDL_PIXELFORMAT_YUY2: - case SDL_PIXELFORMAT_UYVY: - case SDL_PIXELFORMAT_YVYU: - break; - default: - SDL_SetError("Unsupported YUV format"); - return NULL; - } - - swdata = (SDL_SW_YUVTexture *) SDL_calloc(1, sizeof(*swdata)); - if (!swdata) { - SDL_OutOfMemory(); - return NULL; - } - - swdata->format = format; - swdata->target_format = SDL_PIXELFORMAT_UNKNOWN; - swdata->w = w; - swdata->h = h; - swdata->pixels = (Uint8 *) SDL_malloc(w * h * 2); - swdata->colortab = (int *) SDL_malloc(4 * 256 * sizeof(int)); - swdata->rgb_2_pix = (Uint32 *) SDL_malloc(3 * 768 * sizeof(Uint32)); - if (!swdata->pixels || !swdata->colortab || !swdata->rgb_2_pix) { - SDL_SW_DestroyYUVTexture(swdata); - SDL_OutOfMemory(); - return NULL; - } - - /* Generate the tables for the display surface */ - Cr_r_tab = &swdata->colortab[0 * 256]; - Cr_g_tab = &swdata->colortab[1 * 256]; - Cb_g_tab = &swdata->colortab[2 * 256]; - Cb_b_tab = &swdata->colortab[3 * 256]; - for (i = 0; i < 256; i++) { - /* Gamma correction (luminescence table) and chroma correction - would be done here. See the Berkeley mpeg_play sources. - */ - CB = CR = (i - 128); - Cr_r_tab[i] = (int) ((0.419 / 0.299) * CR); - Cr_g_tab[i] = (int) (-(0.299 / 0.419) * CR); - Cb_g_tab[i] = (int) (-(0.114 / 0.331) * CB); - Cb_b_tab[i] = (int) ((0.587 / 0.331) * CB); - } - - /* Find the pitch and offset values for the overlay */ - switch (format) { - case SDL_PIXELFORMAT_YV12: - case SDL_PIXELFORMAT_IYUV: - swdata->pitches[0] = w; - swdata->pitches[1] = swdata->pitches[0] / 2; - swdata->pitches[2] = swdata->pitches[0] / 2; - swdata->planes[0] = swdata->pixels; - swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h; - swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * h / 2; - break; - case SDL_PIXELFORMAT_YUY2: - case SDL_PIXELFORMAT_UYVY: - case SDL_PIXELFORMAT_YVYU: - swdata->pitches[0] = w * 2; - swdata->planes[0] = swdata->pixels; - break; - default: - SDL_assert(0 && "We should never get here (caught above)"); - break; - } - - /* We're all done.. */ - return (swdata); -} - -int -SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture * swdata, void **pixels, - int *pitch) -{ - *pixels = swdata->planes[0]; - *pitch = swdata->pitches[0]; - return 0; -} - -int -SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, - const void *pixels, int pitch) -{ - switch (swdata->format) { - case SDL_PIXELFORMAT_YV12: - case SDL_PIXELFORMAT_IYUV: - if (rect->x == 0 && rect->y == 0 && - rect->w == swdata->w && rect->h == swdata->h) { - SDL_memcpy(swdata->pixels, pixels, - (swdata->h * swdata->w) + (swdata->h * swdata->w) / 2); - } else { - Uint8 *src, *dst; - int row; - size_t length; - - /* Copy the Y plane */ - src = (Uint8 *) pixels; - dst = swdata->pixels + rect->y * swdata->w + rect->x; - length = rect->w; - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += pitch; - dst += swdata->w; - } - - /* Copy the next plane */ - src = (Uint8 *) pixels + rect->h * pitch; - dst = swdata->pixels + swdata->h * swdata->w; - dst += rect->y/2 * swdata->w/2 + rect->x/2; - length = rect->w / 2; - for (row = 0; row < rect->h/2; ++row) { - SDL_memcpy(dst, src, length); - src += pitch/2; - dst += swdata->w/2; - } - - /* Copy the next plane */ - src = (Uint8 *) pixels + rect->h * pitch + (rect->h * pitch) / 4; - dst = swdata->pixels + swdata->h * swdata->w + - (swdata->h * swdata->w) / 4; - dst += rect->y/2 * swdata->w/2 + rect->x/2; - length = rect->w / 2; - for (row = 0; row < rect->h/2; ++row) { - SDL_memcpy(dst, src, length); - src += pitch/2; - dst += swdata->w/2; - } - } - break; - case SDL_PIXELFORMAT_YUY2: - case SDL_PIXELFORMAT_UYVY: - case SDL_PIXELFORMAT_YVYU: - { - Uint8 *src, *dst; - int row; - size_t length; - - src = (Uint8 *) pixels; - dst = - swdata->planes[0] + rect->y * swdata->pitches[0] + - rect->x * 2; - length = rect->w * 2; - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += pitch; - dst += swdata->pitches[0]; - } - } - break; - } - return 0; -} - -int -SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, - const Uint8 *Yplane, int Ypitch, - const Uint8 *Uplane, int Upitch, - const Uint8 *Vplane, int Vpitch) -{ - const Uint8 *src; - Uint8 *dst; - int row; - size_t length; - - /* Copy the Y plane */ - src = Yplane; - dst = swdata->pixels + rect->y * swdata->w + rect->x; - length = rect->w; - for (row = 0; row < rect->h; ++row) { - SDL_memcpy(dst, src, length); - src += Ypitch; - dst += swdata->w; - } - - /* Copy the U plane */ - src = Uplane; - if (swdata->format == SDL_PIXELFORMAT_IYUV) { - dst = swdata->pixels + swdata->h * swdata->w; - } else { - dst = swdata->pixels + swdata->h * swdata->w + - (swdata->h * swdata->w) / 4; - } - dst += rect->y/2 * swdata->w/2 + rect->x/2; - length = rect->w / 2; - for (row = 0; row < rect->h/2; ++row) { - SDL_memcpy(dst, src, length); - src += Upitch; - dst += swdata->w/2; - } - - /* Copy the V plane */ - src = Vplane; - if (swdata->format == SDL_PIXELFORMAT_YV12) { - dst = swdata->pixels + swdata->h * swdata->w; - } else { - dst = swdata->pixels + swdata->h * swdata->w + - (swdata->h * swdata->w) / 4; - } - dst += rect->y/2 * swdata->w/2 + rect->x/2; - length = rect->w / 2; - for (row = 0; row < rect->h/2; ++row) { - SDL_memcpy(dst, src, length); - src += Vpitch; - dst += swdata->w/2; - } - return 0; -} - -int -SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, - void **pixels, int *pitch) -{ - switch (swdata->format) { - case SDL_PIXELFORMAT_YV12: - case SDL_PIXELFORMAT_IYUV: - if (rect - && (rect->x != 0 || rect->y != 0 || rect->w != swdata->w - || rect->h != swdata->h)) { - return SDL_SetError - ("YV12 and IYUV textures only support full surface locks"); - } - break; - } - - if (rect) { - *pixels = swdata->planes[0] + rect->y * swdata->pitches[0] + rect->x * 2; - } else { - *pixels = swdata->planes[0]; - } - *pitch = swdata->pitches[0]; - return 0; -} - -void -SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture * swdata) -{ -} - -int -SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect, - Uint32 target_format, int w, int h, void *pixels, - int pitch) -{ - const int targetbpp = SDL_BYTESPERPIXEL(target_format); - int stretch; - int scale_2x; - Uint8 *lum, *Cr, *Cb; - int mod; - - if (targetbpp == 0) { - return SDL_SetError("Invalid target pixel format"); - } - - /* Make sure we're set up to display in the desired format */ - if (target_format != swdata->target_format) { - if (SDL_SW_SetupYUVDisplay(swdata, target_format) < 0) { - return -1; - } - } - - stretch = 0; - scale_2x = 0; - if (srcrect->x || srcrect->y || srcrect->w < swdata->w - || srcrect->h < swdata->h) { - /* The source rectangle has been clipped. - Using a scratch surface is easier than adding clipped - source support to all the blitters, plus that would - slow them down in the general unclipped case. - */ - stretch = 1; - } else if ((srcrect->w != w) || (srcrect->h != h)) { - if ((w == 2 * srcrect->w) && (h == 2 * srcrect->h)) { - scale_2x = 1; - } else { - stretch = 1; - } - } - if (stretch) { - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - - if (swdata->display) { - swdata->display->w = w; - swdata->display->h = h; - swdata->display->pixels = pixels; - swdata->display->pitch = pitch; - } else { - /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */ - SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask, - &Bmask, &Amask); - swdata->display = - SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask, - Gmask, Bmask, Amask); - if (!swdata->display) { - return (-1); - } - } - if (!swdata->stretch) { - /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */ - SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask, - &Bmask, &Amask); - swdata->stretch = - SDL_CreateRGBSurface(0, swdata->w, swdata->h, bpp, Rmask, - Gmask, Bmask, Amask); - if (!swdata->stretch) { - return (-1); - } - } - pixels = swdata->stretch->pixels; - pitch = swdata->stretch->pitch; - } - switch (swdata->format) { - case SDL_PIXELFORMAT_YV12: - lum = swdata->planes[0]; - Cr = swdata->planes[1]; - Cb = swdata->planes[2]; - break; - case SDL_PIXELFORMAT_IYUV: - lum = swdata->planes[0]; - Cr = swdata->planes[2]; - Cb = swdata->planes[1]; - break; - case SDL_PIXELFORMAT_YUY2: - lum = swdata->planes[0]; - Cr = lum + 3; - Cb = lum + 1; - break; - case SDL_PIXELFORMAT_UYVY: - lum = swdata->planes[0] + 1; - Cr = lum + 1; - Cb = lum - 1; - break; - case SDL_PIXELFORMAT_YVYU: - lum = swdata->planes[0]; - Cr = lum + 1; - Cb = lum + 3; - break; - default: - return SDL_SetError("Unsupported YUV format in copy"); - } - mod = (pitch / targetbpp); - - if (scale_2x) { - mod -= (swdata->w * 2); - swdata->Display2X(swdata->colortab, swdata->rgb_2_pix, - lum, Cr, Cb, pixels, swdata->h, swdata->w, mod); - } else { - mod -= swdata->w; - swdata->Display1X(swdata->colortab, swdata->rgb_2_pix, - lum, Cr, Cb, pixels, swdata->h, swdata->w, mod); - } - if (stretch) { - SDL_Rect rect = *srcrect; - SDL_SoftStretch(swdata->stretch, &rect, swdata->display, NULL); - } - return 0; -} - -void -SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata) -{ - if (swdata) { - SDL_free(swdata->pixels); - SDL_free(swdata->colortab); - SDL_free(swdata->rgb_2_pix); - SDL_FreeSurface(swdata->stretch); - SDL_FreeSurface(swdata->display); - SDL_free(swdata); - } -} - -/* vi: set ts=4 sw=4 expandtab: */ |