From e1f95983923ffcb0624eef1fa6cf552eb54fe647 Mon Sep 17 00:00:00 2001 From: D G Turner Date: Mon, 10 Oct 2011 01:54:33 +0100 Subject: GRAPHICS: Add YUV410 to RGB Conversion Functions, required for SVQ1. Thanks to clone2727 for these. --- graphics/yuv_to_rgb.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ graphics/yuv_to_rgb.h | 14 ++++++++++++ 2 files changed, 74 insertions(+) (limited to 'graphics') diff --git a/graphics/yuv_to_rgb.cpp b/graphics/yuv_to_rgb.cpp index ac7f217fee..e0af267106 100644 --- a/graphics/yuv_to_rgb.cpp +++ b/graphics/yuv_to_rgb.cpp @@ -300,4 +300,64 @@ void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uS convertYUV420ToRGB((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); } +#define OUTPUT_4_PIXEL_COLUMN() \ + PUT_PIXEL(*ySrc, dstPtr); \ + PUT_PIXEL(*(ySrc + yPitch), dstPtr + dstPitch); \ + PUT_PIXEL(*(ySrc + (yPitch << 1)), dstPtr + dstPitch * 2); \ + PUT_PIXEL(*(ySrc + (yPitch * 3)), dstPtr + dstPitch * 3); \ + ySrc++; \ + dstPtr += sizeof(PixelInt) + +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) { + int quarterHeight = yHeight >> 2; + int quarterWidth = yWidth >> 2; + + // Keep the tables in pointers here to avoid a dereference on each pixel + const int16 *Cr_r_tab = lookup->_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; + const uint32 *rgbToPix = lookup->_rgbToPix; + + for (int h = 0; h < quarterHeight; h++) { + for (int w = 0; w < quarterWidth; w++) { + register const uint32 *L; + + int16 cr_r = Cr_r_tab[*vSrc]; + int16 crb_g = Cr_g_tab[*vSrc] + Cb_g_tab[*uSrc]; + int16 cb_b = Cb_b_tab[*uSrc]; + ++uSrc; + ++vSrc; + + OUTPUT_4_PIXEL_COLUMN(); + OUTPUT_4_PIXEL_COLUMN(); + OUTPUT_4_PIXEL_COLUMN(); + OUTPUT_4_PIXEL_COLUMN(); + } + + dstPtr += dstPitch * 3; + ySrc += (yPitch << 2) - yWidth; + uSrc += uvPitch - quarterWidth; + vSrc += uvPitch - quarterWidth; + } +} + +void convertYUV410ToRGB(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); + assert((yWidth & 3) == 0); + assert((yHeight & 3) == 0); + + const YUVToRGBLookup *lookup = YUVToRGBMan.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); + else + convertYUV410ToRGB((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch); +} + } // End of namespace Graphics diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h index 8e025042dc..52ab2ebdfb 100644 --- a/graphics/yuv_to_rgb.h +++ b/graphics/yuv_to_rgb.h @@ -64,6 +64,20 @@ void convertYUV444ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uS */ void convertYUV420ToRGB(Graphics::Surface *dst, const byte *ySrc, const byte *uSrc, const byte *vSrc, int yWidth, int yHeight, int yPitch, int uvPitch); +/** + * Convert a YUV410 image to an RGB surface + * + * @param dst the destination surface + * @param ySrc the source of the y component + * @param uSrc the source of the u component + * @param vSrc the source of the v component + * @param yWidth the width of the y surface (must be divisible by 4) + * @param yHeight the height of the y surface (must be divisible by 4) + * @param yPitch the pitch of the y surface + * @param uvPitch the pitch of the u and v surfaces + */ +void convertYUV410ToRGB(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