aboutsummaryrefslogtreecommitdiff
path: root/graphics/yuv_to_rgb.cpp
diff options
context:
space:
mode:
authorD G Turner2011-10-10 01:54:33 +0100
committerD G Turner2012-04-08 03:28:58 +0100
commite1f95983923ffcb0624eef1fa6cf552eb54fe647 (patch)
tree579b26f9b2d61bab6aa92ab03e1c85f2bb46463c /graphics/yuv_to_rgb.cpp
parent93632681c0e23da9031c68785060f197100411a6 (diff)
downloadscummvm-rg350-e1f95983923ffcb0624eef1fa6cf552eb54fe647.tar.gz
scummvm-rg350-e1f95983923ffcb0624eef1fa6cf552eb54fe647.tar.bz2
scummvm-rg350-e1f95983923ffcb0624eef1fa6cf552eb54fe647.zip
GRAPHICS: Add YUV410 to RGB Conversion Functions, required for SVQ1.
Thanks to clone2727 for these.
Diffstat (limited to 'graphics/yuv_to_rgb.cpp')
-rw-r--r--graphics/yuv_to_rgb.cpp60
1 files changed, 60 insertions, 0 deletions
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<uint32>((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<typename PixelInt>
+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<uint16>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+ else
+ convertYUV410ToRGB<uint32>((byte *)dst->pixels, dst->pitch, lookup, ySrc, uSrc, vSrc, yWidth, yHeight, yPitch, uvPitch);
+}
+
} // End of namespace Graphics