From 0addffbfd3952f766e7f839c210465c9c34b94bd Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 17 May 2011 18:05:40 -0400 Subject: GRAPHICS: Add a YUV to RGB table lookup for use with Theora Based on the video/mpeg_player.* one, which is based on lots of other things (too many to name, go see the file) --- graphics/module.mk | 3 +- graphics/yuv_to_rgb.cpp | 240 ++++++++++++++++++++++++++++++++++++++++++++++++ graphics/yuv_to_rgb.h | 40 ++++++++ 3 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 graphics/yuv_to_rgb.cpp create mode 100644 graphics/yuv_to_rgb.h (limited to 'graphics') diff --git a/graphics/module.mk b/graphics/module.mk index 59621dc525..a9051c868a 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -25,7 +25,8 @@ MODULE_OBJS := \ thumbnail.o \ VectorRenderer.o \ VectorRendererSpec.o \ - wincursor.o + wincursor.o \ + yuv_to_rgb.o ifdef USE_SCALERS MODULE_OBJS += \ diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp new file mode 100644 index 0000000000..b1107a7475 --- /dev/null +++ b/graphics/yuv_to_rgb.cpp @@ -0,0 +1,240 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +// The YUV to RGB conversion code is derived from SDL's YUV overlay code, which +// in turn appears to be derived from mpeg_play. The following copyright +// notices have been included in accordance with the original license. Please +// note that the term "software" in this context only applies to the +// buildLookup() and plotYUV*() functions below. + +// 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 "common/scummsys.h" +#include "common/singleton.h" + +#include "graphics/surface.h" + +namespace Graphics { + +class YUVToRGBLookup { +public: + YUVToRGBLookup(Graphics::PixelFormat format); + ~YUVToRGBLookup(); + + int16 *_colorTab; + uint32 *_rgbToPix; +}; + +YUVToRGBLookup::YUVToRGBLookup(Graphics::PixelFormat format) { + _colorTab = new int16[4 * 256]; // 2048 bytes + + int16 *Cr_r_tab = &_colorTab[0 * 256]; + int16 *Cr_g_tab = &_colorTab[1 * 256]; + int16 *Cb_g_tab = &_colorTab[2 * 256]; + int16 *Cb_b_tab = &_colorTab[3 * 256]; + + _rgbToPix = new uint32[3 * 768]; // 9216 bytes + + uint32 *r_2_pix_alloc = &_rgbToPix[0 * 768]; + uint32 *g_2_pix_alloc = &_rgbToPix[1 * 768]; + uint32 *b_2_pix_alloc = &_rgbToPix[2 * 768]; + + int16 CR, CB; + int i; + + // Generate the tables for the display surface + + for (i = 0; i < 256; i++) { + // Gamma correction (luminescence table) and chroma correction + // would be done here. See the Berkeley mpeg_play sources. + + CR = CB = (i - 128); + Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR) + 0 * 768 + 256; + Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR) + 1 * 768 + 256; + Cb_g_tab[i] = (int16) (-(0.114 / 0.331) * CB); + Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB) + 2 * 768 + 256; + } + + // Set up entries 0-255 in rgb-to-pixel value tables. + for (i = 0; i < 256; i++) { + r_2_pix_alloc[i + 256] = format.RGBToColor(i, 0, 0); + g_2_pix_alloc[i + 256] = format.RGBToColor(0, i, 0); + b_2_pix_alloc[i + 256] = format.RGBToColor(0, 0, i); + } + + // 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]; + } +} + +YUVToRGBLookup::~YUVToRGBLookup() { + delete[] _rgbToPix; + delete[] _colorTab; +} + +class YUVToRGBManager : public Common::Singleton { +public: + const YUVToRGBLookup *getLookup(Graphics::PixelFormat format); + +private: + friend class Common::Singleton; + YUVToRGBManager(); + ~YUVToRGBManager(); + + Graphics::PixelFormat _lastFormat; + YUVToRGBLookup *_lookup; +}; + +YUVToRGBManager::YUVToRGBManager() { + _lookup = 0; +} + +YUVToRGBManager::~YUVToRGBManager() { + delete _lookup; +} + +const YUVToRGBLookup *YUVToRGBManager::getLookup(Graphics::PixelFormat format) { + if (_lastFormat == format) + return _lookup; + + delete _lookup; + _lookup = new YUVToRGBLookup(format); + _lastFormat = format; + return _lookup; +} + +} // End of namespace Graphics + +DECLARE_SINGLETON(Graphics::YUVToRGBManager); + +#define YUVToRGBMan (Graphics::YUVToRGBManager::instance()) + +namespace Graphics { + +#define PUT_PIXEL(s, d) \ + L = &lookup->_rgbToPix[(s)]; \ + if (dst->format.bytesPerPixel == 2) \ + *((uint16 *)(d)) = (L[cr_r] | L[crb_g] | L[cb_b]); \ + else \ + *((uint32 *)(d)) = (L[cr_r] | L[crb_g] | L[cb_b]) + +void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { + const YUVToRGBLookup *lookup = YUVToRGBMan.getLookup(dst->format); + + byte *dstPtr = (byte *)dst->pixels; + + int halfHeight = yHeight >> 1; + int halfWidth = yWidth >> 1; + + for (int h = 0; h < halfHeight; h++) { + for (int w = 0; w < halfWidth; w++) { + register uint32 *L; + + int16 cr_r = lookup->_colorTab[*vSrc + 0 * 256]; + int16 crb_g = lookup->_colorTab[*vSrc + 1 * 256] + lookup->_colorTab[*uSrc + 2 * 256]; + int16 cb_b = lookup->_colorTab[*uSrc + 3 * 256]; + ++uSrc; + ++vSrc; + + PUT_PIXEL(*ySrc, dstPtr); + PUT_PIXEL(*(ySrc + yPitch), dstPtr + dst->pitch); + ySrc++; + dstPtr += dst->format.bytesPerPixel; + PUT_PIXEL(*ySrc, dstPtr); + PUT_PIXEL(*(ySrc + yPitch), dstPtr + dst->pitch); + ySrc++; + dstPtr += dst->format.bytesPerPixel; + } + + dstPtr += dst->pitch; + ySrc += (yPitch << 1) - yWidth; + uSrc += uvPitch - halfWidth; + vSrc += uvPitch - halfWidth; + } +} + +} // End of namespace Graphics diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h new file mode 100644 index 0000000000..30f64ee570 --- /dev/null +++ b/graphics/yuv_to_rgb.h @@ -0,0 +1,40 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef GRAPHICS_YUV_TO_RGB_H +#define GRAPHICS_YUV_TO_RGB_H + +#include "common/scummsys.h" +#include "graphics/surface.h" + +namespace Graphics { + +struct Surface; + +void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch); + +} // End of namespace Graphics + +#endif -- cgit v1.2.3