From 893a2b37ff651e69699879932fe70895a28951fa Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 17 Sep 2012 12:54:08 -0400 Subject: GRAPHICS: Rework YUV->RGB code a bit --- graphics/yuv_to_rgb.cpp | 112 ++++++++++++++++++------------------------------ 1 file changed, 42 insertions(+), 70 deletions(-) (limited to 'graphics/yuv_to_rgb.cpp') diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp index 78903d0cd8..1afd0d295b 100644 --- a/graphics/yuv_to_rgb.cpp +++ b/graphics/yuv_to_rgb.cpp @@ -83,10 +83,12 @@ // 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" +#include "graphics/yuv_to_rgb.h" + +namespace Common { +DECLARE_SINGLETON(Graphics::YUVToRGBManager); +} namespace Graphics { @@ -95,42 +97,18 @@ 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++) { + for (int 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); @@ -138,7 +116,7 @@ YUVToRGBLookup::YUVToRGBLookup(Graphics::PixelFormat format) { // 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++) { + for (int 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]; @@ -150,24 +128,28 @@ YUVToRGBLookup::YUVToRGBLookup(Graphics::PixelFormat format) { YUVToRGBLookup::~YUVToRGBLookup() { delete[] _rgbToPix; - delete[] _colorTab; } -class YUVToRGBManager : public Common::Singleton { -public: - const YUVToRGBLookup *getLookup(Graphics::PixelFormat format); +YUVToRGBManager::YUVToRGBManager() { + _lookup = 0; -private: - friend class Common::Singleton; - YUVToRGBManager(); - ~YUVToRGBManager(); + 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]; - Graphics::PixelFormat _lastFormat; - YUVToRGBLookup *_lookup; -}; + // Generate the tables for the display surface -YUVToRGBManager::YUVToRGBManager() { - _lookup = 0; + for (int i = 0; i < 256; i++) { + // Gamma correction (luminescence table) and chroma correction + // would be done here. See the Berkeley mpeg_play sources. + + int16 CR = (i - 128), CB = CR; + 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; + } } YUVToRGBManager::~YUVToRGBManager() { @@ -184,24 +166,14 @@ const YUVToRGBLookup *YUVToRGBManager::getLookup(Graphics::PixelFormat format) { return _lookup; } -} // End of namespace Graphics - -namespace Common { -DECLARE_SINGLETON(Graphics::YUVToRGBManager); -} - -#define YUVToRGBMan (Graphics::YUVToRGBManager::instance()) - -namespace Graphics { - #define PUT_PIXEL(s, d) \ L = &rgbToPix[(s)]; \ *((PixelInt *)(d)) = (L[cr_r] | L[crb_g] | L[cb_b]) template -void convertYUV444ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { +void convertYUV444ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup, int16 *colorTab, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { // Keep the tables in pointers here to avoid a dereference on each pixel - const int16 *Cr_r_tab = lookup->_colorTab; + const int16 *Cr_r_tab = colorTab; const int16 *Cr_g_tab = Cr_r_tab + 256; const int16 *Cb_g_tab = Cr_g_tab + 256; const int16 *Cb_b_tab = Cb_g_tab + 256; @@ -229,28 +201,28 @@ void convertYUV444ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup } } -void convertYUV444ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { +void YUVToRGBManager::convert444(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { // Sanity checks assert(dst && dst->pixels); assert(dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4); assert(ySrc && uSrc && vSrc); - const YUVToRGBLookup *lookup = YUVToRGBMan.getLookup(dst->format); + const YUVToRGBLookup *lookup = getLookup(dst->format); // Use a templated function to avoid an if check on every pixel if (dst->format.bytesPerPixel == 2) - convertYUV444ToRGB((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); + convertYUV444ToRGB((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); else - convertYUV444ToRGB((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); + convertYUV444ToRGB((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); } template -void convertYUV420ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { +void convertYUV420ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup, int16 *colorTab, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { int halfHeight = yHeight >> 1; int halfWidth = yWidth >> 1; // Keep the tables in pointers here to avoid a dereference on each pixel - const int16 *Cr_r_tab = lookup->_colorTab; + const int16 *Cr_r_tab = colorTab; const int16 *Cr_g_tab = Cr_r_tab + 256; const int16 *Cb_g_tab = Cr_g_tab + 256; const int16 *Cb_b_tab = Cb_g_tab + 256; @@ -283,7 +255,7 @@ void convertYUV420ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup } } -void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { +void YUVToRGBManager::convert420(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { // Sanity checks assert(dst && dst->pixels); assert(dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4); @@ -291,13 +263,13 @@ void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uS assert((yWidth & 1) == 0); assert((yHeight & 1) == 0); - const YUVToRGBLookup *lookup = YUVToRGBMan.getLookup(dst->format); + const YUVToRGBLookup *lookup = getLookup(dst->format); // Use a templated function to avoid an if check on every pixel if (dst->format.bytesPerPixel == 2) - convertYUV420ToRGB((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); + convertYUV420ToRGB((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); else - convertYUV420ToRGB((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); + convertYUV420ToRGB((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); } #define READ_QUAD(ptr, prefix) \ @@ -325,9 +297,9 @@ void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uS xDiff++ template -void convertYUV410ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { +void convertYUV410ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup, int16 *colorTab, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { // Keep the tables in pointers here to avoid a dereference on each pixel - const int16 *Cr_r_tab = lookup->_colorTab; + const int16 *Cr_r_tab = colorTab; const int16 *Cr_g_tab = Cr_r_tab + 256; const int16 *Cb_g_tab = Cr_g_tab + 256; const int16 *Cb_b_tab = Cb_g_tab + 256; @@ -368,7 +340,7 @@ void convertYUV410ToRGB(byte *dstPtr, int dstPitch, const YUVToRGBLookup *lookup #undef DO_INTERPOLATION #undef DO_YUV410_PIXEL -void convertYUV410ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { +void YUVToRGBManager::convert410(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch) { // Sanity checks assert(dst && dst->pixels); assert(dst->format.bytesPerPixel == 2 || dst->format.bytesPerPixel == 4); @@ -376,13 +348,13 @@ void convertYUV410ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uS assert((yWidth & 3) == 0); assert((yHeight & 3) == 0); - const YUVToRGBLookup *lookup = YUVToRGBMan.getLookup(dst->format); + const YUVToRGBLookup *lookup = getLookup(dst->format); // Use a templated function to avoid an if check on every pixel if (dst->format.bytesPerPixel == 2) - convertYUV410ToRGB((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); + convertYUV410ToRGB((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); else - convertYUV410ToRGB((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); + convertYUV410ToRGB((byte *)dst->pixels, dst->pitch, lookup, _colorTab, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); } } // End of namespace Graphics -- cgit v1.2.3